1 // Scintilla source code edit control
3 ** Classes maintaining the selection.
5 // Copyright 2009 by Neil Hodgson <neilh@scintilla.org>
6 // The License.txt file describes the conditions under which this software may be distributed.
11 namespace Scintilla::Internal
{
13 class SelectionPosition
{
14 Sci::Position position
;
15 Sci::Position virtualSpace
;
17 explicit SelectionPosition(Sci::Position position_
= Sci::invalidPosition
, Sci::Position virtualSpace_
=0) noexcept
: position(position_
), virtualSpace(virtualSpace_
) {
18 PLATFORM_ASSERT(virtualSpace
< 800000000);
22 void Reset() noexcept
{
26 void MoveForInsertDelete(bool insertion
, Sci::Position startChange
, Sci::Position length
, bool moveForEqual
) noexcept
;
27 bool operator ==(const SelectionPosition
&other
) const noexcept
{
28 return position
== other
.position
&& virtualSpace
== other
.virtualSpace
;
30 bool operator <(const SelectionPosition
&other
) const noexcept
;
31 bool operator >(const SelectionPosition
&other
) const noexcept
;
32 bool operator <=(const SelectionPosition
&other
) const noexcept
;
33 bool operator >=(const SelectionPosition
&other
) const noexcept
;
34 Sci::Position
Position() const noexcept
{
37 void SetPosition(Sci::Position position_
) noexcept
{
41 Sci::Position
VirtualSpace() const noexcept
{
44 void SetVirtualSpace(Sci::Position virtualSpace_
) noexcept
{
45 PLATFORM_ASSERT(virtualSpace_
< 800000000);
46 if (virtualSpace_
>= 0)
47 virtualSpace
= virtualSpace_
;
49 void Add(Sci::Position increment
) noexcept
{
50 position
= position
+ increment
;
52 bool IsValid() const noexcept
{
57 // Ordered range to make drawing simpler
58 struct SelectionSegment
{
59 SelectionPosition start
;
60 SelectionPosition end
;
61 SelectionSegment() noexcept
: start(), end() {
63 SelectionSegment(SelectionPosition a
, SelectionPosition b
) noexcept
{
72 bool Empty() const noexcept
{
75 Sci::Position
Length() const noexcept
{
76 return end
.Position() - start
.Position();
78 void Extend(SelectionPosition p
) noexcept
{
84 SelectionSegment
Subtract(Sci::Position increment
) const noexcept
{
85 SelectionSegment
ret(start
, end
);
86 ret
.start
.Add(-increment
);
87 ret
.end
.Add(-increment
);
92 struct SelectionRange
{
93 SelectionPosition caret
;
94 SelectionPosition anchor
;
96 SelectionRange() noexcept
: caret(), anchor() {
98 explicit SelectionRange(SelectionPosition single
) noexcept
: caret(single
), anchor(single
) {
100 explicit SelectionRange(Sci::Position single
) noexcept
: caret(single
), anchor(single
) {
102 SelectionRange(SelectionPosition caret_
, SelectionPosition anchor_
) noexcept
: caret(caret_
), anchor(anchor_
) {
104 SelectionRange(Sci::Position caret_
, Sci::Position anchor_
) noexcept
: caret(caret_
), anchor(anchor_
) {
106 bool Empty() const noexcept
{
107 return anchor
== caret
;
109 Sci::Position
Length() const noexcept
;
110 // Sci::Position Width() const; // Like Length but takes virtual space into account
111 bool operator ==(const SelectionRange
&other
) const noexcept
{
112 return caret
== other
.caret
&& anchor
== other
.anchor
;
114 bool operator <(const SelectionRange
&other
) const noexcept
{
115 return caret
< other
.caret
|| ((caret
== other
.caret
) && (anchor
< other
.anchor
));
117 void Reset() noexcept
{
121 void ClearVirtualSpace() noexcept
{
122 anchor
.SetVirtualSpace(0);
123 caret
.SetVirtualSpace(0);
125 void MoveForInsertDelete(bool insertion
, Sci::Position startChange
, Sci::Position length
) noexcept
;
126 bool Contains(Sci::Position pos
) const noexcept
;
127 bool Contains(SelectionPosition sp
) const noexcept
;
128 bool ContainsCharacter(Sci::Position posCharacter
) const noexcept
;
129 SelectionSegment
Intersect(SelectionSegment check
) const noexcept
;
130 SelectionPosition
Start() const noexcept
{
131 return (anchor
< caret
) ? anchor
: caret
;
133 SelectionPosition
End() const noexcept
{
134 return (anchor
< caret
) ? caret
: anchor
;
136 void Swap() noexcept
;
137 bool Trim(SelectionRange range
) noexcept
;
138 // If range is all virtual collapse to start of virtual space
139 void MinimizeVirtualSpace() noexcept
;
142 // Deliberately an enum rather than an enum class to allow treating as bool
143 enum InSelection
{ inNone
, inMain
, inAdditional
};
146 std::vector
<SelectionRange
> ranges
;
147 std::vector
<SelectionRange
> rangesSaved
;
148 SelectionRange rangeRectangular
;
153 enum class SelTypes
{ none
, stream
, rectangle
, lines
, thin
};
157 bool IsRectangular() const noexcept
;
158 Sci::Position
MainCaret() const noexcept
;
159 Sci::Position
MainAnchor() const noexcept
;
160 SelectionRange
&Rectangular() noexcept
;
161 SelectionSegment
Limits() const noexcept
;
162 // This is for when you want to move the caret in response to a
163 // user direction command - for rectangular selections, use the range
164 // that covers all selected text otherwise return the main selection.
165 SelectionSegment
LimitsForRectangularElseMain() const;
166 size_t Count() const noexcept
;
167 size_t Main() const noexcept
;
168 void SetMain(size_t r
) noexcept
;
169 SelectionRange
&Range(size_t r
) noexcept
;
170 const SelectionRange
&Range(size_t r
) const noexcept
;
171 SelectionRange
&RangeMain() noexcept
;
172 const SelectionRange
&RangeMain() const noexcept
;
173 SelectionPosition
Start() const noexcept
;
174 bool MoveExtends() const noexcept
;
175 void SetMoveExtends(bool moveExtends_
) noexcept
;
176 bool Empty() const noexcept
;
177 SelectionPosition
Last() const noexcept
;
178 Sci::Position
Length() const noexcept
;
179 void MovePositions(bool insertion
, Sci::Position startChange
, Sci::Position length
) noexcept
;
180 void TrimSelection(SelectionRange range
) noexcept
;
181 void TrimOtherSelections(size_t r
, SelectionRange range
) noexcept
;
182 void SetSelection(SelectionRange range
);
183 void AddSelection(SelectionRange range
);
184 void AddSelectionWithoutTrim(SelectionRange range
);
185 void DropSelection(size_t r
);
186 void DropAdditionalRanges();
187 void TentativeSelection(SelectionRange range
);
188 void CommitTentative() noexcept
;
189 InSelection
RangeType(size_t r
) const noexcept
;
190 InSelection
CharacterInSelection(Sci::Position posCharacter
) const noexcept
;
191 InSelection
InSelectionForEOL(Sci::Position pos
) const noexcept
;
192 Sci::Position
VirtualSpaceFor(Sci::Position pos
) const noexcept
;
194 void RemoveDuplicates();
195 void RotateMain() noexcept
;
196 bool Tentative() const noexcept
{ return tentativeMain
; }
197 std::vector
<SelectionRange
> RangesCopy() const {