OLD | NEW |
---|---|
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "ui/gfx/render_text.h" | 5 #include "ui/gfx/render_text.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/i18n/break_iterator.h" | 9 #include "base/i18n/break_iterator.h" |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
168 size_t start = sel.selection_start(); | 168 size_t start = sel.selection_start(); |
169 size_t end = sel.selection_end(); | 169 size_t end = sel.selection_end(); |
170 selection_model_.set_selection_start(std::min(start, text().length())); | 170 selection_model_.set_selection_start(std::min(start, text().length())); |
171 selection_model_.set_selection_end(std::min(end, text().length())); | 171 selection_model_.set_selection_end(std::min(end, text().length())); |
172 selection_model_.set_caret_pos(std::min(sel.caret_pos(), text().length())); | 172 selection_model_.set_caret_pos(std::min(sel.caret_pos(), text().length())); |
173 selection_model_.set_caret_placement(sel.caret_placement()); | 173 selection_model_.set_caret_placement(sel.caret_placement()); |
174 | 174 |
175 cached_bounds_and_offset_valid_ = false; | 175 cached_bounds_and_offset_valid_ = false; |
176 } | 176 } |
177 | 177 |
178 void RenderText::ToggleInsertMode() { | |
179 insert_mode_ = !insert_mode_; | |
180 cached_bounds_and_offset_valid_ = false; | |
181 } | |
182 | |
178 void RenderText::SetDisplayRect(const Rect& r) { | 183 void RenderText::SetDisplayRect(const Rect& r) { |
179 display_rect_ = r; | 184 display_rect_ = r; |
180 cached_bounds_and_offset_valid_ = false; | 185 cached_bounds_and_offset_valid_ = false; |
181 } | 186 } |
182 | 187 |
183 size_t RenderText::GetCursorPosition() const { | 188 size_t RenderText::GetCursorPosition() const { |
184 return selection_model_.selection_end(); | 189 return selection_model_.selection_end(); |
185 } | 190 } |
186 | 191 |
187 void RenderText::SetCursorPosition(const size_t position) { | 192 void RenderText::SetCursorPosition(size_t position) { |
188 SelectionModel sel(selection_model()); | 193 MoveCursorTo(position, false); |
189 sel.set_selection_start(position); | |
190 sel.set_selection_end(position); | |
191 sel.set_caret_pos(GetIndexOfPreviousGrapheme(position)); | |
192 sel.set_caret_placement(SelectionModel::TRAILING); | |
193 SetSelectionModel(sel); | |
194 } | 194 } |
195 | 195 |
196 void RenderText::MoveCursorLeft(BreakType break_type, bool select) { | 196 void RenderText::MoveCursorLeft(BreakType break_type, bool select) { |
197 SelectionModel position(selection_model()); | 197 SelectionModel position(selection_model()); |
198 position.set_selection_start(GetCursorPosition()); | 198 position.set_selection_start(GetCursorPosition()); |
199 // Cancelling a selection moves to the edge of the selection. | 199 // Cancelling a selection moves to the edge of the selection. |
200 if (break_type != LINE_BREAK && !EmptySelection() && !select) { | 200 if (break_type != LINE_BREAK && !EmptySelection() && !select) { |
201 // Use the selection start if it is left of the selection end. | 201 // Use the selection start if it is left of the selection end. |
202 SelectionModel selection_start(GetSelectionStart(), GetSelectionStart(), | 202 SelectionModel selection_start(GetSelectionStart(), GetSelectionStart(), |
203 SelectionModel::LEADING); | 203 SelectionModel::LEADING); |
(...skipping 26 matching lines...) Expand all Loading... | |
230 if (break_type == WORD_BREAK) | 230 if (break_type == WORD_BREAK) |
231 position = GetRightSelectionModel(position, break_type); | 231 position = GetRightSelectionModel(position, break_type); |
232 } else { | 232 } else { |
233 position = GetRightSelectionModel(position, break_type); | 233 position = GetRightSelectionModel(position, break_type); |
234 } | 234 } |
235 if (select) | 235 if (select) |
236 position.set_selection_start(GetSelectionStart()); | 236 position.set_selection_start(GetSelectionStart()); |
237 MoveCursorTo(position); | 237 MoveCursorTo(position); |
238 } | 238 } |
239 | 239 |
240 void RenderText::MoveCursorTo(size_t position, bool select) { | |
241 size_t caret_pos = GetIndexOfPreviousGrapheme(position); | |
242 SelectionModel::CaretPlacement placement = (caret_pos == position) ? | |
243 SelectionModel::LEADING : SelectionModel::TRAILING; | |
244 size_t selection_start = select ? GetSelectionStart() : position; | |
245 SelectionModel sel(selection_start, position, caret_pos, placement); | |
246 SetSelectionModel(sel); | |
xji
2011/08/18 22:47:54
hmm... the functionality seems different from prev
msw
2011/08/19 10:55:30
This has been reincarnated as a convenience functi
xji
2011/08/19 17:38:13
make sense.
but I think for complex script, say f
msw
2011/08/19 18:03:33
Interesting, I wonder how that works with the IMEs
| |
247 } | |
248 | |
240 bool RenderText::MoveCursorTo(const SelectionModel& selection) { | 249 bool RenderText::MoveCursorTo(const SelectionModel& selection) { |
241 bool changed = !selection.Equals(selection_model_); | 250 bool changed = !selection.Equals(selection_model_); |
242 SetSelectionModel(selection); | 251 SetSelectionModel(selection); |
243 return changed; | 252 return changed; |
244 } | 253 } |
245 | 254 |
246 bool RenderText::MoveCursorTo(const Point& point, bool select) { | 255 bool RenderText::MoveCursorTo(const Point& point, bool select) { |
247 SelectionModel selection = FindCursorPosition(point); | 256 SelectionModel selection = FindCursorPosition(point); |
248 if (select) | 257 if (select) |
249 selection.set_selection_start(GetSelectionStart()); | 258 selection.set_selection_start(GetSelectionStart()); |
250 return MoveCursorTo(selection); | 259 return MoveCursorTo(selection); |
251 } | 260 } |
252 | 261 |
253 bool RenderText::IsPointInSelection(const Point& point) { | 262 bool RenderText::IsPointInSelection(const Point& point) { |
263 if (EmptySelection()) | |
264 return false; | |
254 // TODO(xji): should this check whether the point is inside the visual | 265 // TODO(xji): should this check whether the point is inside the visual |
255 // selection bounds? In case of "abcFED", if "ED" is selected, |point| points | 266 // selection bounds? In case of "abcFED", if "ED" is selected, |point| points |
256 // to the right half of 'c', is the point in selection? | 267 // to the right half of 'c', is the point in selection? |
257 size_t pos = FindCursorPosition(point).selection_end(); | 268 size_t pos = FindCursorPosition(point).selection_end(); |
258 return (pos >= MinOfSelection() && pos < MaxOfSelection()); | 269 return (pos >= MinOfSelection() && pos < MaxOfSelection()); |
259 } | 270 } |
260 | 271 |
261 void RenderText::ClearSelection() { | 272 void RenderText::ClearSelection() { |
262 SelectionModel sel(selection_model()); | 273 SelectionModel sel(selection_model()); |
263 sel.set_selection_start(GetCursorPosition()); | 274 sel.set_selection_start(GetCursorPosition()); |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
301 } | 312 } |
302 | 313 |
303 // Now we move selection_end_ to end of selection. Selection boundary | 314 // Now we move selection_end_ to end of selection. Selection boundary |
304 // is defined as the position where we have alpha-num character on one side | 315 // is defined as the position where we have alpha-num character on one side |
305 // and non-alpha-num char on the other side. | 316 // and non-alpha-num char on the other side. |
306 for (; cursor_position < text().length(); cursor_position++) { | 317 for (; cursor_position < text().length(); cursor_position++) { |
307 if (IsPositionAtWordSelectionBoundary(cursor_position)) | 318 if (IsPositionAtWordSelectionBoundary(cursor_position)) |
308 break; | 319 break; |
309 } | 320 } |
310 | 321 |
311 SelectionModel sel(selection_model()); | 322 MoveCursorTo(selection_start, false); |
312 sel.set_selection_start(selection_start); | 323 MoveCursorTo(cursor_position, true); |
xji
2011/08/18 22:47:54
why this change?
msw
2011/08/19 10:55:30
Convenience of built-in checking for s previous gr
| |
313 sel.set_selection_end(cursor_position); | |
314 sel.set_caret_pos(GetIndexOfPreviousGrapheme(cursor_position)); | |
315 sel.set_caret_placement(SelectionModel::TRAILING); | |
316 SetSelectionModel(sel); | |
317 } | 324 } |
318 | 325 |
319 const ui::Range& RenderText::GetCompositionRange() const { | 326 const ui::Range& RenderText::GetCompositionRange() const { |
320 return composition_range_; | 327 return composition_range_; |
321 } | 328 } |
322 | 329 |
323 void RenderText::SetCompositionRange(const ui::Range& composition_range) { | 330 void RenderText::SetCompositionRange(const ui::Range& composition_range) { |
324 CHECK(!composition_range.IsValid() || | 331 CHECK(!composition_range.IsValid() || |
325 ui::Range(0, text_.length()).Contains(composition_range)); | 332 ui::Range(0, text_.length()).Contains(composition_range)); |
326 composition_range_.set_end(composition_range.end()); | 333 composition_range_.set_end(composition_range.end()); |
(...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
582 } | 589 } |
583 | 590 |
584 void RenderText::UpdateCachedBoundsAndOffset() { | 591 void RenderText::UpdateCachedBoundsAndOffset() { |
585 if (cached_bounds_and_offset_valid_) | 592 if (cached_bounds_and_offset_valid_) |
586 return; | 593 return; |
587 // First, set the valid flag true to calculate the current cursor bounds using | 594 // First, set the valid flag true to calculate the current cursor bounds using |
588 // the stale |display_offset_|. Applying |delta_offset| at the end of this | 595 // the stale |display_offset_|. Applying |delta_offset| at the end of this |
589 // function will set |cursor_bounds_| and |display_offset_| to correct values. | 596 // function will set |cursor_bounds_| and |display_offset_| to correct values. |
590 cached_bounds_and_offset_valid_ = true; | 597 cached_bounds_and_offset_valid_ = true; |
591 cursor_bounds_ = GetCursorBounds(selection_model_, insert_mode_); | 598 cursor_bounds_ = GetCursorBounds(selection_model_, insert_mode_); |
592 cursor_bounds_.set_width(std::max(cursor_bounds_.width(), 1)); | |
593 // Update |display_offset_| to ensure the current cursor is visible. | 599 // Update |display_offset_| to ensure the current cursor is visible. |
594 int display_width = display_rect_.width(); | 600 int display_width = display_rect_.width(); |
595 int string_width = GetStringWidth(); | 601 int string_width = GetStringWidth(); |
596 int delta_offset = 0; | 602 int delta_offset = 0; |
597 if (string_width < display_width) { | 603 if (string_width < display_width) { |
598 // Show all text whenever the text fits to the size. | 604 // Show all text whenever the text fits to the size. |
599 delta_offset = -display_offset_.x(); | 605 delta_offset = -display_offset_.x(); |
600 } else if (cursor_bounds_.right() > display_rect_.right()) { | 606 } else if (cursor_bounds_.right() > display_rect_.right()) { |
601 // Pan to show the cursor when it overflows to the right, | 607 // Pan to show the cursor when it overflows to the right, |
602 delta_offset = display_rect_.right() - cursor_bounds_.right(); | 608 delta_offset = display_rect_.right() - cursor_bounds_.right(); |
603 } else if (cursor_bounds_.x() < display_rect_.x()) { | 609 } else if (cursor_bounds_.x() < display_rect_.x()) { |
604 // Pan to show the cursor when it overflows to the left. | 610 // Pan to show the cursor when it overflows to the left. |
605 delta_offset = display_rect_.x() - cursor_bounds_.x(); | 611 delta_offset = display_rect_.x() - cursor_bounds_.x(); |
606 } | 612 } |
607 display_offset_.Offset(delta_offset, 0); | 613 display_offset_.Offset(delta_offset, 0); |
608 cursor_bounds_.Offset(delta_offset, 0); | 614 cursor_bounds_.Offset(delta_offset, 0); |
609 } | 615 } |
610 | 616 |
611 } // namespace gfx | 617 } // namespace gfx |
OLD | NEW |