@@ -30,30 +30,31 @@ bool IsTrailingSurrogate(char32_t code_point) {
30
30
31
31
} // namespace
32
32
33
- TextInputModel::TextInputModel ()
34
- : selection_base_(text_.begin()), selection_extent_(text_.begin()) {}
33
+ TextInputModel::TextInputModel () = default ;
35
34
36
35
TextInputModel::~TextInputModel () = default ;
37
36
38
37
void TextInputModel::SetText (const std::string& text) {
39
38
std::wstring_convert<std::codecvt_utf8_utf16<char16_t >, char16_t >
40
39
utf16_converter;
41
40
text_ = utf16_converter.from_bytes (text);
42
- selection_base_ = text_. begin () ;
43
- selection_extent_ = selection_base_ ;
41
+ selection_base_ = 0 ;
42
+ selection_extent_ = 0 ;
44
43
}
45
44
46
45
bool TextInputModel::SetSelection (size_t base, size_t extent) {
47
- if (base > text_.size () || extent > text_.size ()) {
46
+ auto max_pos = text_.length ();
47
+ if (base > max_pos || extent > max_pos) {
48
48
return false ;
49
49
}
50
- selection_base_ = text_. begin () + base;
51
- selection_extent_ = text_. begin () + extent;
50
+ selection_base_ = base;
51
+ selection_extent_ = extent;
52
52
return true ;
53
53
}
54
54
55
55
void TextInputModel::DeleteSelected () {
56
- selection_base_ = text_.erase (selection_start (), selection_end ());
56
+ text_.erase (selection_start (), selection_end () - selection_start ());
57
+ selection_base_ = selection_start ();
57
58
selection_extent_ = selection_base_;
58
59
}
59
60
@@ -75,7 +76,7 @@ void TextInputModel::AddText(const std::u16string& text) {
75
76
if (selection_base_ != selection_extent_) {
76
77
DeleteSelected ();
77
78
}
78
- selection_extent_ = text_.insert (selection_extent_, text. begin (), text. end () );
79
+ text_.insert (selection_extent_, text);
79
80
selection_extent_ += text.length ();
80
81
selection_base_ = selection_extent_;
81
82
}
@@ -87,27 +88,32 @@ void TextInputModel::AddText(const std::string& text) {
87
88
}
88
89
89
90
bool TextInputModel::Backspace () {
91
+ // If there's a selection, delete it.
90
92
if (selection_base_ != selection_extent_) {
91
93
DeleteSelected ();
92
94
return true ;
93
95
}
94
- if (selection_base_ != text_.begin ()) {
95
- int count = IsTrailingSurrogate (*(selection_base_ - 1 )) ? 2 : 1 ;
96
- selection_base_ = text_.erase (selection_base_ - count, selection_base_);
96
+ // There's no selection; delete the preceding codepoint.
97
+ if (selection_base_ != 0 ) {
98
+ int count = IsTrailingSurrogate (text_.at (selection_base_ - 1 )) ? 2 : 1 ;
99
+ text_.erase (selection_base_ - count, count);
100
+ selection_base_ -= count;
97
101
selection_extent_ = selection_base_;
98
102
return true ;
99
103
}
100
- return false ; // No edits happened.
104
+ return false ;
101
105
}
102
106
103
107
bool TextInputModel::Delete () {
108
+ // If there's a selection, delete it.
104
109
if (selection_base_ != selection_extent_) {
105
110
DeleteSelected ();
106
111
return true ;
107
112
}
108
- if (selection_base_ != text_.end ()) {
109
- int count = IsLeadingSurrogate (*selection_base_) ? 2 : 1 ;
110
- selection_base_ = text_.erase (selection_base_, selection_base_ + count);
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);
111
117
selection_extent_ = selection_base_;
112
118
return true ;
113
119
}
@@ -120,32 +126,32 @@ bool TextInputModel::DeleteSurrounding(int offset_from_cursor, int count) {
120
126
for (int i = 0 ; i < -offset_from_cursor; i++) {
121
127
// If requested start is before the available text then reduce the
122
128
// number of characters to delete.
123
- if (start == text_. begin () ) {
129
+ if (start == 0 ) {
124
130
count = i;
125
131
break ;
126
132
}
127
- start -= IsTrailingSurrogate (* (start - 1 )) ? 2 : 1 ;
133
+ start -= IsTrailingSurrogate (text_. at (start - 1 )) ? 2 : 1 ;
128
134
}
129
135
} else {
130
- for (int i = 0 ; i < offset_from_cursor && start != text_.end (); i++) {
131
- start += IsLeadingSurrogate (* start) ? 2 : 1 ;
136
+ for (int i = 0 ; i < offset_from_cursor && start != text_.length (); i++) {
137
+ start += IsLeadingSurrogate (text_. at ( start) ) ? 2 : 1 ;
132
138
}
133
139
}
134
140
135
141
auto end = start;
136
- for (int i = 0 ; i < count && end != text_.end (); i++) {
137
- end += IsLeadingSurrogate (* start) ? 2 : 1 ;
142
+ for (int i = 0 ; i < count && end != text_.length (); i++) {
143
+ end += IsLeadingSurrogate (text_. at ( start) ) ? 2 : 1 ;
138
144
}
139
145
140
146
if (start == end) {
141
147
return false ;
142
148
}
143
149
144
- auto new_base = text_.erase (start, end);
150
+ text_.erase (start, end - start );
145
151
146
152
// Cursor moves only if deleted area is before it.
147
153
if (offset_from_cursor <= 0 ) {
148
- selection_base_ = new_base ;
154
+ selection_base_ = start ;
149
155
}
150
156
151
157
// Clear selection.
@@ -155,22 +161,21 @@ bool TextInputModel::DeleteSurrounding(int offset_from_cursor, int count) {
155
161
}
156
162
157
163
bool TextInputModel::MoveCursorToBeginning () {
158
- if (selection_base_ == text_. begin () && selection_extent_ == text_. begin () )
164
+ if (selection_base_ == 0 && selection_extent_ == 0 )
159
165
return false ;
160
166
161
- selection_base_ = text_.begin ();
162
- selection_extent_ = text_.begin ();
163
-
167
+ selection_base_ = 0 ;
168
+ selection_extent_ = 0 ;
164
169
return true ;
165
170
}
166
171
167
172
bool TextInputModel::MoveCursorToEnd () {
168
- if (selection_base_ == text_.end () && selection_extent_ == text_.end ())
173
+ auto max_pos = text_.length ();
174
+ if (selection_base_ == max_pos && selection_extent_ == max_pos)
169
175
return false ;
170
176
171
- selection_base_ = text_.end ();
172
- selection_extent_ = text_.end ();
173
-
177
+ selection_base_ = max_pos;
178
+ selection_extent_ = max_pos;
174
179
return true ;
175
180
}
176
181
@@ -182,8 +187,8 @@ bool TextInputModel::MoveCursorForward() {
182
187
return true ;
183
188
}
184
189
// If not at the end, move the extent forward.
185
- if (selection_extent_ != text_.end ()) {
186
- int count = IsLeadingSurrogate (* selection_base_) ? 2 : 1 ;
190
+ if (selection_extent_ != text_.length ()) {
191
+ int count = IsLeadingSurrogate (text_. at ( selection_base_) ) ? 2 : 1 ;
187
192
selection_base_ += count;
188
193
selection_extent_ = selection_base_;
189
194
return true ;
@@ -200,8 +205,8 @@ bool TextInputModel::MoveCursorBack() {
200
205
return true ;
201
206
}
202
207
// If not at the start, move the beginning backward.
203
- if (selection_base_ != text_. begin () ) {
204
- int count = IsTrailingSurrogate (* (selection_base_ - 1 )) ? 2 : 1 ;
208
+ if (selection_base_ != 0 ) {
209
+ int count = IsTrailingSurrogate (text_. at (selection_base_ - 1 )) ? 2 : 1 ;
205
210
selection_base_ -= count;
206
211
selection_extent_ = selection_base_;
207
212
return true ;
@@ -218,7 +223,7 @@ std::string TextInputModel::GetText() const {
218
223
int TextInputModel::GetCursorOffset () const {
219
224
// Measure the length of the current text up to the cursor.
220
225
// There is probably a much more efficient way of doing this.
221
- auto leading_text = text_.substr (0 , selection_extent_ - text_. begin () );
226
+ auto leading_text = text_.substr (0 , selection_extent_);
222
227
std::wstring_convert<std::codecvt_utf8_utf16<char16_t >, char16_t >
223
228
utf8_converter;
224
229
return utf8_converter.to_bytes (leading_text).size ();
0 commit comments