1 /** @file Decoration.cxx
2 ** Visual elements added over text.
4 // Copyright 1998-2007 by Neil Hodgson <neilh@scintilla.org>
5 // The License.txt file describes the conditions under which this software may be distributed.
20 #include "Scintilla.h"
22 #include "SplitVector.h"
23 #include "Partitioning.h"
24 #include "RunStyles.h"
25 #include "Decoration.h"
28 using namespace Scintilla
;
31 Decoration::Decoration(int indicator_
) : indicator(indicator_
) {
34 Decoration::~Decoration() {
37 bool Decoration::Empty() const {
38 return (rs
.Runs() == 1) && (rs
.AllSameAs(0));
41 DecorationList::DecorationList() : currentIndicator(0), currentValue(1), current(nullptr),
42 lengthDocument(0), clickNotified(false) {
45 DecorationList::~DecorationList() {
49 Decoration
*DecorationList::DecorationFromIndicator(int indicator
) {
50 for (const std::unique_ptr
<Decoration
> &deco
: decorationList
) {
51 if (deco
->Indicator() == indicator
) {
58 Decoration
*DecorationList::Create(int indicator
, int length
) {
59 currentIndicator
= indicator
;
60 std::unique_ptr
<Decoration
> decoNew(new Decoration(indicator
));
61 decoNew
->rs
.InsertSpace(0, length
);
63 std::vector
<std::unique_ptr
<Decoration
>>::iterator it
= std::lower_bound(
64 decorationList
.begin(), decorationList
.end(), decoNew
,
65 [](const std::unique_ptr
<Decoration
> &a
, const std::unique_ptr
<Decoration
> &b
) {
66 return a
->Indicator() < b
->Indicator();
68 std::vector
<std::unique_ptr
<Decoration
>>::iterator itAdded
=
69 decorationList
.insert(it
, std::move(decoNew
));
73 return itAdded
->get();
76 void DecorationList::Delete(int indicator
) {
77 decorationList
.erase(std::remove_if(decorationList
.begin(), decorationList
.end(),
78 [=](const std::unique_ptr
<Decoration
> &deco
) {
79 return deco
->Indicator() == indicator
;
80 }), decorationList
.end());
85 void DecorationList::SetCurrentIndicator(int indicator
) {
86 currentIndicator
= indicator
;
87 current
= DecorationFromIndicator(indicator
);
91 void DecorationList::SetCurrentValue(int value
) {
92 currentValue
= value
? value
: 1;
95 bool DecorationList::FillRange(int &position
, int value
, int &fillLength
) {
97 current
= DecorationFromIndicator(currentIndicator
);
99 current
= Create(currentIndicator
, lengthDocument
);
102 const bool changed
= current
->rs
.FillRange(position
, value
, fillLength
);
103 if (current
->Empty()) {
104 Delete(currentIndicator
);
109 void DecorationList::InsertSpace(int position
, int insertLength
) {
110 const bool atEnd
= position
== lengthDocument
;
111 lengthDocument
+= insertLength
;
112 for (const std::unique_ptr
<Decoration
> &deco
: decorationList
) {
113 deco
->rs
.InsertSpace(position
, insertLength
);
115 deco
->rs
.FillRange(position
, 0, insertLength
);
120 void DecorationList::DeleteRange(int position
, int deleteLength
) {
121 lengthDocument
-= deleteLength
;
122 for (const std::unique_ptr
<Decoration
> &deco
: decorationList
) {
123 deco
->rs
.DeleteRange(position
, deleteLength
);
126 if (decorationList
.size() != decorationView
.size()) {
127 // One or more empty decorations deleted so update view.
133 void DecorationList::DeleteLexerDecorations() {
134 decorationList
.erase(std::remove_if(decorationList
.begin(), decorationList
.end(),
135 [=](const std::unique_ptr
<Decoration
> &deco
) {
136 return deco
->Indicator() < INDIC_CONTAINER
;
137 }), decorationList
.end());
142 void DecorationList::DeleteAnyEmpty() {
143 if (lengthDocument
== 0) {
144 decorationList
.clear();
146 decorationList
.erase(std::remove_if(decorationList
.begin(), decorationList
.end(),
147 [=](const std::unique_ptr
<Decoration
> &deco
) {
148 return deco
->Empty();
149 }), decorationList
.end());
153 void DecorationList::SetView() {
154 decorationView
.clear();
155 for (const std::unique_ptr
<Decoration
> &deco
: decorationList
) {
156 decorationView
.push_back(deco
.get());
160 int DecorationList::AllOnFor(int position
) const {
162 for (const std::unique_ptr
<Decoration
> &deco
: decorationList
) {
163 if (deco
->rs
.ValueAt(position
)) {
164 if (deco
->Indicator() < INDIC_IME
) {
165 mask
|= 1 << deco
->Indicator();
172 int DecorationList::ValueAt(int indicator
, int position
) {
173 const Decoration
*deco
= DecorationFromIndicator(indicator
);
175 return deco
->rs
.ValueAt(position
);
180 int DecorationList::Start(int indicator
, int position
) {
181 const Decoration
*deco
= DecorationFromIndicator(indicator
);
183 return deco
->rs
.StartRun(position
);
188 int DecorationList::End(int indicator
, int position
) {
189 const Decoration
*deco
= DecorationFromIndicator(indicator
);
191 return deco
->rs
.EndRun(position
);