@@ -38,27 +38,24 @@ void TextInputModel::SetText(const std::string& text) {
3838 std::wstring_convert<std::codecvt_utf8_utf16<char16_t >, char16_t >
3939 utf16_converter;
4040 text_ = utf16_converter.from_bytes (text);
41- selection_base_ = 0 ;
42- selection_extent_ = 0 ;
41+ selection_ = TextRange (0 );
4342}
4443
4544bool TextInputModel::SetSelection (size_t base, size_t extent) {
46- auto max_pos = text_.length ();
45+ size_t max_pos = text_.length ();
4746 if (base > max_pos || extent > max_pos) {
4847 return false ;
4948 }
50- selection_base_ = base;
51- selection_extent_ = extent;
49+ selection_ = TextRange (base, extent);
5250 return true ;
5351}
5452
5553bool TextInputModel::DeleteSelected () {
56- if (selection_base_ == selection_extent_ ) {
54+ if (selection_. collapsed () ) {
5755 return false ;
5856 }
59- text_.erase (selection_start (), selection_end () - selection_start ());
60- selection_base_ = selection_start ();
61- selection_extent_ = selection_base_;
57+ text_.erase (selection_.start (), selection_.length ());
58+ selection_ = TextRange (selection_.start ());
6259 return true ;
6360}
6461
@@ -78,9 +75,9 @@ void TextInputModel::AddCodePoint(char32_t c) {
7875
7976void TextInputModel::AddText (const std::u16string& text) {
8077 DeleteSelected ();
81- text_. insert (selection_extent_, text );
82- selection_extent_ += text. length ( );
83- selection_base_ = selection_extent_ ;
78+ size_t position = selection_. position ( );
79+ text_. insert (position, text );
80+ selection_ = TextRange (position + text. length ()) ;
8481}
8582
8683void TextInputModel::AddText (const std::string& text) {
@@ -90,38 +87,36 @@ void TextInputModel::AddText(const std::string& text) {
9087}
9188
9289bool TextInputModel::Backspace () {
93- // If there's a selection, delete it.
9490 if (DeleteSelected ()) {
9591 return true ;
9692 }
97- // There 's no selection; delete the preceding codepoint.
98- if (selection_base_ != 0 ) {
99- int count = IsTrailingSurrogate (text_. at (selection_base_ - 1 )) ? 2 : 1 ;
100- text_.erase (selection_base_ - count, count) ;
101- selection_base_ -= count;
102- selection_extent_ = selection_base_ ;
93+ // If there 's no selection, delete the preceding codepoint.
94+ size_t position = selection_. position ();
95+ if (position != 0 ) {
96+ int count = IsTrailingSurrogate ( text_.at (position - 1 )) ? 2 : 1 ;
97+ text_. erase (position - count, count) ;
98+ selection_ = TextRange (position - count) ;
10399 return true ;
104100 }
105101 return false ;
106102}
107103
108104bool TextInputModel::Delete () {
109- // If there's a selection, delete it.
110105 if (DeleteSelected ()) {
111106 return true ;
112107 }
113- // There 's no selection; delete the following codepoint.
114- if (selection_base_ != text_. length ()) {
115- int count = IsLeadingSurrogate ( text_.at (selection_base_ )) ? 2 : 1 ;
116- text_.erase (selection_base_, count) ;
117- selection_extent_ = selection_base_ ;
108+ // If there 's no selection, delete the preceding codepoint.
109+ size_t position = selection_. position ();
110+ if (position != text_.length ( )) {
111+ int count = IsLeadingSurrogate ( text_.at (position)) ? 2 : 1 ;
112+ text_. erase (position, count) ;
118113 return true ;
119114 }
120115 return false ;
121116}
122117
123118bool TextInputModel::DeleteSurrounding (int offset_from_cursor, int count) {
124- auto start = selection_extent_ ;
119+ size_t start = selection_. extent () ;
125120 if (offset_from_cursor < 0 ) {
126121 for (int i = 0 ; i < -offset_from_cursor; i++) {
127122 // If requested start is before the available text then reduce the
@@ -150,65 +145,53 @@ bool TextInputModel::DeleteSurrounding(int offset_from_cursor, int count) {
150145 text_.erase (start, end - start);
151146
152147 // Cursor moves only if deleted area is before it.
153- if (offset_from_cursor <= 0 ) {
154- selection_base_ = start;
155- }
156-
157- // Clear selection.
158- selection_extent_ = selection_base_;
148+ selection_ = TextRange (offset_from_cursor <= 0 ? start : selection_.start ());
159149
160150 return true ;
161151}
162152
163153bool TextInputModel::MoveCursorToBeginning () {
164- if (selection_base_ == 0 && selection_extent_ == 0 )
154+ if (selection_. collapsed () && selection_. position () == 0 )
165155 return false ;
166-
167- selection_base_ = 0 ;
168- selection_extent_ = 0 ;
156+ selection_ = TextRange (0 );
169157 return true ;
170158}
171159
172160bool TextInputModel::MoveCursorToEnd () {
173- auto max_pos = text_.length ();
174- if (selection_base_ == max_pos && selection_extent_ == max_pos)
161+ size_t max_pos = text_.length ();
162+ if (selection_. collapsed () && selection_. position () == max_pos)
175163 return false ;
176-
177- selection_base_ = max_pos;
178- selection_extent_ = max_pos;
164+ selection_ = TextRange (max_pos);
179165 return true ;
180166}
181167
182168bool TextInputModel::MoveCursorForward () {
183- // If about to move set to the end of the highlight (when not selecting).
184- if (selection_base_ != selection_extent_) {
185- selection_base_ = selection_end ();
186- selection_extent_ = selection_base_;
169+ // If there's a selection, move to the end of the selection.
170+ if (!selection_.collapsed ()) {
171+ selection_ = TextRange (selection_.end ());
187172 return true ;
188173 }
189- // If not at the end , move the extent forward.
190- if (selection_extent_ != text_. length ()) {
191- int count = IsLeadingSurrogate ( text_.at (selection_base_ )) ? 2 : 1 ;
192- selection_base_ += count ;
193- selection_extent_ = selection_base_ ;
174+ // Otherwise , move the cursor forward.
175+ size_t position = selection_. position ();
176+ if (position != text_.length ( )) {
177+ int count = IsLeadingSurrogate (text_. at (position)) ? 2 : 1 ;
178+ selection_ = TextRange (position + count) ;
194179 return true ;
195180 }
196181 return false ;
197182}
198183
199184bool TextInputModel::MoveCursorBack () {
200- // If about to move set to the beginning of the highlight
201- // (when not selecting).
202- if (selection_base_ != selection_extent_) {
203- selection_base_ = selection_start ();
204- selection_extent_ = selection_base_;
185+ // If there's a selection, move to the beginning of the selection.
186+ if (!selection_.collapsed ()) {
187+ selection_ = TextRange (selection_.start ());
205188 return true ;
206189 }
207- // If not at the start , move the beginning backward.
208- if (selection_base_ != 0 ) {
209- int count = IsTrailingSurrogate (text_. at (selection_base_ - 1 )) ? 2 : 1 ;
210- selection_base_ -= count ;
211- selection_extent_ = selection_base_ ;
190+ // Otherwise , move the cursor backward.
191+ size_t position = selection_. position ();
192+ if (position != 0 ) {
193+ int count = IsTrailingSurrogate (text_. at (position - 1 )) ? 2 : 1 ;
194+ selection_ = TextRange (position - count) ;
212195 return true ;
213196 }
214197 return false ;
@@ -221,9 +204,9 @@ std::string TextInputModel::GetText() const {
221204}
222205
223206int TextInputModel::GetCursorOffset () const {
224- // Measure the length of the current text up to the cursor .
207+ // Measure the length of the current text up to the selection extent .
225208 // There is probably a much more efficient way of doing this.
226- auto leading_text = text_.substr (0 , selection_extent_ );
209+ auto leading_text = text_.substr (0 , selection_. extent () );
227210 std::wstring_convert<std::codecvt_utf8_utf16<char16_t >, char16_t >
228211 utf8_converter;
229212 return utf8_converter.to_bytes (leading_text).size ();
0 commit comments