xref: /MusicPlayer2/scintilla/src/Selection.h (revision 8af74909132ed5e696cb05b6689ae4baf14c1c96)
1*8af74909SZhong Yang // Scintilla source code edit control
2*8af74909SZhong Yang /** @file Selection.h
3*8af74909SZhong Yang  ** Classes maintaining the selection.
4*8af74909SZhong Yang  **/
5*8af74909SZhong Yang // Copyright 2009 by Neil Hodgson <[email protected]>
6*8af74909SZhong Yang // The License.txt file describes the conditions under which this software may be distributed.
7*8af74909SZhong Yang 
8*8af74909SZhong Yang #ifndef SELECTION_H
9*8af74909SZhong Yang #define SELECTION_H
10*8af74909SZhong Yang 
11*8af74909SZhong Yang namespace Scintilla {
12*8af74909SZhong Yang 
13*8af74909SZhong Yang class SelectionPosition {
14*8af74909SZhong Yang 	Sci::Position position;
15*8af74909SZhong Yang 	Sci::Position virtualSpace;
16*8af74909SZhong Yang public:
position(position_)17*8af74909SZhong Yang 	explicit SelectionPosition(Sci::Position position_=INVALID_POSITION, Sci::Position virtualSpace_=0) noexcept : position(position_), virtualSpace(virtualSpace_) {
18*8af74909SZhong Yang 		PLATFORM_ASSERT(virtualSpace < 800000);
19*8af74909SZhong Yang 		if (virtualSpace < 0)
20*8af74909SZhong Yang 			virtualSpace = 0;
21*8af74909SZhong Yang 	}
Reset()22*8af74909SZhong Yang 	void Reset() noexcept {
23*8af74909SZhong Yang 		position = 0;
24*8af74909SZhong Yang 		virtualSpace = 0;
25*8af74909SZhong Yang 	}
26*8af74909SZhong Yang 	void MoveForInsertDelete(bool insertion, Sci::Position startChange, Sci::Position length, bool moveForEqual) noexcept;
27*8af74909SZhong Yang 	bool operator ==(const SelectionPosition &other) const noexcept {
28*8af74909SZhong Yang 		return position == other.position && virtualSpace == other.virtualSpace;
29*8af74909SZhong Yang 	}
30*8af74909SZhong Yang 	bool operator <(const SelectionPosition &other) const noexcept;
31*8af74909SZhong Yang 	bool operator >(const SelectionPosition &other) const noexcept;
32*8af74909SZhong Yang 	bool operator <=(const SelectionPosition &other) const noexcept;
33*8af74909SZhong Yang 	bool operator >=(const SelectionPosition &other) const noexcept;
Position()34*8af74909SZhong Yang 	Sci::Position Position() const noexcept {
35*8af74909SZhong Yang 		return position;
36*8af74909SZhong Yang 	}
SetPosition(Sci::Position position_)37*8af74909SZhong Yang 	void SetPosition(Sci::Position position_) noexcept {
38*8af74909SZhong Yang 		position = position_;
39*8af74909SZhong Yang 		virtualSpace = 0;
40*8af74909SZhong Yang 	}
VirtualSpace()41*8af74909SZhong Yang 	Sci::Position VirtualSpace() const noexcept {
42*8af74909SZhong Yang 		return virtualSpace;
43*8af74909SZhong Yang 	}
SetVirtualSpace(Sci::Position virtualSpace_)44*8af74909SZhong Yang 	void SetVirtualSpace(Sci::Position virtualSpace_) noexcept {
45*8af74909SZhong Yang 		PLATFORM_ASSERT(virtualSpace_ < 800000);
46*8af74909SZhong Yang 		if (virtualSpace_ >= 0)
47*8af74909SZhong Yang 			virtualSpace = virtualSpace_;
48*8af74909SZhong Yang 	}
Add(Sci::Position increment)49*8af74909SZhong Yang 	void Add(Sci::Position increment) noexcept {
50*8af74909SZhong Yang 		position = position + increment;
51*8af74909SZhong Yang 	}
IsValid()52*8af74909SZhong Yang 	bool IsValid() const noexcept {
53*8af74909SZhong Yang 		return position >= 0;
54*8af74909SZhong Yang 	}
55*8af74909SZhong Yang };
56*8af74909SZhong Yang 
57*8af74909SZhong Yang // Ordered range to make drawing simpler
58*8af74909SZhong Yang struct SelectionSegment {
59*8af74909SZhong Yang 	SelectionPosition start;
60*8af74909SZhong Yang 	SelectionPosition end;
SelectionSegmentSelectionSegment61*8af74909SZhong Yang 	SelectionSegment() noexcept : start(), end() {
62*8af74909SZhong Yang 	}
SelectionSegmentSelectionSegment63*8af74909SZhong Yang 	SelectionSegment(SelectionPosition a, SelectionPosition b) noexcept {
64*8af74909SZhong Yang 		if (a < b) {
65*8af74909SZhong Yang 			start = a;
66*8af74909SZhong Yang 			end = b;
67*8af74909SZhong Yang 		} else {
68*8af74909SZhong Yang 			start = b;
69*8af74909SZhong Yang 			end = a;
70*8af74909SZhong Yang 		}
71*8af74909SZhong Yang 	}
EmptySelectionSegment72*8af74909SZhong Yang 	bool Empty() const noexcept {
73*8af74909SZhong Yang 		return start == end;
74*8af74909SZhong Yang 	}
LengthSelectionSegment75*8af74909SZhong Yang 	Sci::Position Length() const noexcept {
76*8af74909SZhong Yang 		return end.Position() - start.Position();
77*8af74909SZhong Yang 	}
ExtendSelectionSegment78*8af74909SZhong Yang 	void Extend(SelectionPosition p) noexcept {
79*8af74909SZhong Yang 		if (start > p)
80*8af74909SZhong Yang 			start = p;
81*8af74909SZhong Yang 		if (end < p)
82*8af74909SZhong Yang 			end = p;
83*8af74909SZhong Yang 	}
84*8af74909SZhong Yang };
85*8af74909SZhong Yang 
86*8af74909SZhong Yang struct SelectionRange {
87*8af74909SZhong Yang 	SelectionPosition caret;
88*8af74909SZhong Yang 	SelectionPosition anchor;
89*8af74909SZhong Yang 
SelectionRangeSelectionRange90*8af74909SZhong Yang 	SelectionRange() noexcept : caret(), anchor() {
91*8af74909SZhong Yang 	}
SelectionRangeSelectionRange92*8af74909SZhong Yang 	explicit SelectionRange(SelectionPosition single) noexcept : caret(single), anchor(single) {
93*8af74909SZhong Yang 	}
SelectionRangeSelectionRange94*8af74909SZhong Yang 	explicit SelectionRange(Sci::Position single) noexcept : caret(single), anchor(single) {
95*8af74909SZhong Yang 	}
SelectionRangeSelectionRange96*8af74909SZhong Yang 	SelectionRange(SelectionPosition caret_, SelectionPosition anchor_) noexcept : caret(caret_), anchor(anchor_) {
97*8af74909SZhong Yang 	}
SelectionRangeSelectionRange98*8af74909SZhong Yang 	SelectionRange(Sci::Position caret_, Sci::Position anchor_) noexcept : caret(caret_), anchor(anchor_) {
99*8af74909SZhong Yang 	}
EmptySelectionRange100*8af74909SZhong Yang 	bool Empty() const noexcept {
101*8af74909SZhong Yang 		return anchor == caret;
102*8af74909SZhong Yang 	}
103*8af74909SZhong Yang 	Sci::Position Length() const noexcept;
104*8af74909SZhong Yang 	// Sci::Position Width() const;	// Like Length but takes virtual space into account
105*8af74909SZhong Yang 	bool operator ==(const SelectionRange &other) const noexcept {
106*8af74909SZhong Yang 		return caret == other.caret && anchor == other.anchor;
107*8af74909SZhong Yang 	}
108*8af74909SZhong Yang 	bool operator <(const SelectionRange &other) const noexcept {
109*8af74909SZhong Yang 		return caret < other.caret || ((caret == other.caret) && (anchor < other.anchor));
110*8af74909SZhong Yang 	}
ResetSelectionRange111*8af74909SZhong Yang 	void Reset() noexcept {
112*8af74909SZhong Yang 		anchor.Reset();
113*8af74909SZhong Yang 		caret.Reset();
114*8af74909SZhong Yang 	}
ClearVirtualSpaceSelectionRange115*8af74909SZhong Yang 	void ClearVirtualSpace() noexcept {
116*8af74909SZhong Yang 		anchor.SetVirtualSpace(0);
117*8af74909SZhong Yang 		caret.SetVirtualSpace(0);
118*8af74909SZhong Yang 	}
119*8af74909SZhong Yang 	void MoveForInsertDelete(bool insertion, Sci::Position startChange, Sci::Position length) noexcept;
120*8af74909SZhong Yang 	bool Contains(Sci::Position pos) const noexcept;
121*8af74909SZhong Yang 	bool Contains(SelectionPosition sp) const noexcept;
122*8af74909SZhong Yang 	bool ContainsCharacter(Sci::Position posCharacter) const noexcept;
123*8af74909SZhong Yang 	SelectionSegment Intersect(SelectionSegment check) const noexcept;
StartSelectionRange124*8af74909SZhong Yang 	SelectionPosition Start() const noexcept {
125*8af74909SZhong Yang 		return (anchor < caret) ? anchor : caret;
126*8af74909SZhong Yang 	}
EndSelectionRange127*8af74909SZhong Yang 	SelectionPosition End() const noexcept {
128*8af74909SZhong Yang 		return (anchor < caret) ? caret : anchor;
129*8af74909SZhong Yang 	}
130*8af74909SZhong Yang 	void Swap() noexcept;
131*8af74909SZhong Yang 	bool Trim(SelectionRange range) noexcept;
132*8af74909SZhong Yang 	// If range is all virtual collapse to start of virtual space
133*8af74909SZhong Yang 	void MinimizeVirtualSpace() noexcept;
134*8af74909SZhong Yang };
135*8af74909SZhong Yang 
136*8af74909SZhong Yang class Selection {
137*8af74909SZhong Yang 	std::vector<SelectionRange> ranges;
138*8af74909SZhong Yang 	std::vector<SelectionRange> rangesSaved;
139*8af74909SZhong Yang 	SelectionRange rangeRectangular;
140*8af74909SZhong Yang 	size_t mainRange;
141*8af74909SZhong Yang 	bool moveExtends;
142*8af74909SZhong Yang 	bool tentativeMain;
143*8af74909SZhong Yang public:
144*8af74909SZhong Yang 	enum selTypes { noSel, selStream, selRectangle, selLines, selThin };
145*8af74909SZhong Yang 	selTypes selType;
146*8af74909SZhong Yang 
147*8af74909SZhong Yang 	Selection();
148*8af74909SZhong Yang 	~Selection();
149*8af74909SZhong Yang 	bool IsRectangular() const noexcept;
150*8af74909SZhong Yang 	Sci::Position MainCaret() const noexcept;
151*8af74909SZhong Yang 	Sci::Position MainAnchor() const noexcept;
152*8af74909SZhong Yang 	SelectionRange &Rectangular() noexcept;
153*8af74909SZhong Yang 	SelectionSegment Limits() const noexcept;
154*8af74909SZhong Yang 	// This is for when you want to move the caret in response to a
155*8af74909SZhong Yang 	// user direction command - for rectangular selections, use the range
156*8af74909SZhong Yang 	// that covers all selected text otherwise return the main selection.
157*8af74909SZhong Yang 	SelectionSegment LimitsForRectangularElseMain() const;
158*8af74909SZhong Yang 	size_t Count() const noexcept;
159*8af74909SZhong Yang 	size_t Main() const noexcept;
160*8af74909SZhong Yang 	void SetMain(size_t r) noexcept;
161*8af74909SZhong Yang 	SelectionRange &Range(size_t r) noexcept;
162*8af74909SZhong Yang 	const SelectionRange &Range(size_t r) const noexcept;
163*8af74909SZhong Yang 	SelectionRange &RangeMain() noexcept;
164*8af74909SZhong Yang 	const SelectionRange &RangeMain() const noexcept;
165*8af74909SZhong Yang 	SelectionPosition Start() const noexcept;
166*8af74909SZhong Yang 	bool MoveExtends() const noexcept;
167*8af74909SZhong Yang 	void SetMoveExtends(bool moveExtends_) noexcept;
168*8af74909SZhong Yang 	bool Empty() const noexcept;
169*8af74909SZhong Yang 	SelectionPosition Last() const noexcept;
170*8af74909SZhong Yang 	Sci::Position Length() const noexcept;
171*8af74909SZhong Yang 	void MovePositions(bool insertion, Sci::Position startChange, Sci::Position length) noexcept;
172*8af74909SZhong Yang 	void TrimSelection(SelectionRange range) noexcept;
173*8af74909SZhong Yang 	void TrimOtherSelections(size_t r, SelectionRange range) noexcept;
174*8af74909SZhong Yang 	void SetSelection(SelectionRange range);
175*8af74909SZhong Yang 	void AddSelection(SelectionRange range);
176*8af74909SZhong Yang 	void AddSelectionWithoutTrim(SelectionRange range);
177*8af74909SZhong Yang 	void DropSelection(size_t r);
178*8af74909SZhong Yang 	void DropAdditionalRanges();
179*8af74909SZhong Yang 	void TentativeSelection(SelectionRange range);
180*8af74909SZhong Yang 	void CommitTentative() noexcept;
181*8af74909SZhong Yang 	int CharacterInSelection(Sci::Position posCharacter) const noexcept;
182*8af74909SZhong Yang 	int InSelectionForEOL(Sci::Position pos) const noexcept;
183*8af74909SZhong Yang 	Sci::Position VirtualSpaceFor(Sci::Position pos) const noexcept;
184*8af74909SZhong Yang 	void Clear();
185*8af74909SZhong Yang 	void RemoveDuplicates();
186*8af74909SZhong Yang 	void RotateMain() noexcept;
Tentative()187*8af74909SZhong Yang 	bool Tentative() const noexcept { return tentativeMain; }
RangesCopy()188*8af74909SZhong Yang 	std::vector<SelectionRange> RangesCopy() const {
189*8af74909SZhong Yang 		return ranges;
190*8af74909SZhong Yang 	}
191*8af74909SZhong Yang };
192*8af74909SZhong Yang 
193*8af74909SZhong Yang }
194*8af74909SZhong Yang 
195*8af74909SZhong Yang #endif
196