Chromium Code Reviews| 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 |