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