diff options
author | msw@chromium.org <msw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-08-09 03:48:50 +0000 |
---|---|---|
committer | msw@chromium.org <msw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-08-09 03:48:50 +0000 |
commit | ec7f48d579d31ef2407236463b5bd710e85c8305 (patch) | |
tree | 47c8104ce090326e12cc9a3e16fd76db6d38c4f2 /ui | |
parent | 62f6b6dd33f442836bbbb2e2ef255a8ba1d30f62 (diff) | |
download | chromium_src-ec7f48d579d31ef2407236463b5bd710e85c8305.zip chromium_src-ec7f48d579d31ef2407236463b5bd710e85c8305.tar.gz chromium_src-ec7f48d579d31ef2407236463b5bd710e85c8305.tar.bz2 |
Rename GetLeft/RightCursorPosition to GetLeft/RightSelectionModel.
Discard selection from the the GetLeft/RightSelectionModel return value.
Update the cursor properly on edits.
BUG=90426
TEST=--use-pure-views cursor movement, position after editing.
Review URL: http://codereview.chromium.org/7598014
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@95945 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ui')
-rw-r--r-- | ui/gfx/render_text.cc | 129 | ||||
-rw-r--r-- | ui/gfx/render_text.h | 23 |
2 files changed, 69 insertions, 83 deletions
diff --git a/ui/gfx/render_text.cc b/ui/gfx/render_text.cc index 9a72d9a..fce00b5 100644 --- a/ui/gfx/render_text.cc +++ b/ui/gfx/render_text.cc @@ -182,64 +182,52 @@ void RenderText::SetCursorPosition(const size_t position) { SelectionModel sel(selection_model()); sel.set_selection_start(position); sel.set_selection_end(position); + sel.set_caret_pos(GetIndexOfPreviousGrapheme(position)); + sel.set_caret_placement(SelectionModel::TRAILING); SetSelectionModel(sel); } void RenderText::MoveCursorLeft(BreakType break_type, bool select) { - if (break_type == LINE_BREAK) { - SelectionModel selection(GetSelectionStart(), 0, - 0, SelectionModel::LEADING); - if (!select) - selection.set_selection_start(selection.selection_end()); - MoveCursorTo(selection); - return; - } - SelectionModel position = selection_model_; + SelectionModel position(selection_model()); + position.set_selection_start(GetCursorPosition()); // Cancelling a selection moves to the edge of the selection. - if (!EmptySelection() && !select) { + if (break_type != LINE_BREAK && !EmptySelection() && !select) { // Use the selection start if it is left of the selection end. SelectionModel selection_start(GetSelectionStart(), GetSelectionStart(), - GetSelectionStart(), SelectionModel::LEADING); + SelectionModel::LEADING); if (GetCursorBounds(selection_start, false).x() < GetCursorBounds(position, false).x()) position = selection_start; - // If |move_by_word|, use the nearest word boundary left of the selection. + // For word breaks, use the nearest word boundary left of the selection. if (break_type == WORD_BREAK) - position = GetLeftCursorPosition(position, true); + position = GetLeftSelectionModel(position, break_type); } else { - position = GetLeftCursorPosition(position, break_type == WORD_BREAK); + position = GetLeftSelectionModel(position, break_type); } - if (!select) - position.set_selection_start(position.selection_end()); + if (select) + position.set_selection_start(GetSelectionStart()); MoveCursorTo(position); } void RenderText::MoveCursorRight(BreakType break_type, bool select) { - if (break_type == LINE_BREAK) { - SelectionModel selection(GetSelectionStart(), text().length(), - text().length(), SelectionModel::PREVIOUS_GRAPHEME_TRAILING); - if (!select) - selection.set_selection_start(selection.selection_end()); - MoveCursorTo(selection); - return; - } - SelectionModel position = selection_model_; + SelectionModel position(selection_model()); + position.set_selection_start(GetCursorPosition()); // Cancelling a selection moves to the edge of the selection. - if (!EmptySelection() && !select) { + if (break_type != LINE_BREAK && !EmptySelection() && !select) { // Use the selection start if it is right of the selection end. SelectionModel selection_start(GetSelectionStart(), GetSelectionStart(), - GetSelectionStart(), SelectionModel::LEADING); + SelectionModel::LEADING); if (GetCursorBounds(selection_start, false).x() > GetCursorBounds(position, false).x()) position = selection_start; - // If |move_by_word|, use the nearest word boundary right of the selection. + // For word breaks, use the nearest word boundary right of the selection. if (break_type == WORD_BREAK) - position = GetRightCursorPosition(position, true); + position = GetRightSelectionModel(position, break_type); } else { - position = GetRightCursorPosition(position, break_type == WORD_BREAK); + position = GetRightSelectionModel(position, break_type); } - if (!select) - position.set_selection_start(position.selection_end()); + if (select) + position.set_selection_start(GetSelectionStart()); MoveCursorTo(position); } @@ -253,8 +241,6 @@ bool RenderText::MoveCursorTo(const Point& point, bool select) { SelectionModel selection = FindCursorPosition(point); if (select) selection.set_selection_start(GetSelectionStart()); - else - selection.set_selection_start(selection.selection_end()); return MoveCursorTo(selection); } @@ -267,7 +253,9 @@ bool RenderText::IsPointInSelection(const Point& point) { } void RenderText::ClearSelection() { - SetCursorPosition(GetCursorPosition()); + SelectionModel sel(selection_model()); + sel.set_selection_start(GetCursorPosition()); + SetSelectionModel(sel); } void RenderText::SelectAll() { @@ -503,15 +491,15 @@ RenderText::RenderText() display_offset_() { } -SelectionModel RenderText::GetLeftCursorPosition(const SelectionModel& current, - bool move_by_word) { - size_t position = current.selection_end(); - SelectionModel left = current; - if (!move_by_word) { - left.set_selection_end(std::max(static_cast<long>(position - 1), - static_cast<long>(0))); - return left; - } +SelectionModel RenderText::GetLeftSelectionModel(const SelectionModel& current, + BreakType break_type) { + if (break_type == LINE_BREAK) + return SelectionModel(0, 0, SelectionModel::LEADING); + size_t pos = std::max(static_cast<long>(current.selection_end() - 1), + static_cast<long>(0)); + if (break_type == CHARACTER_BREAK) + return SelectionModel(pos, pos, SelectionModel::LEADING); + // Notes: We always iterate words from the begining. // This is probably fast enough for our usage, but we may // want to modify WordIterator so that it can start from the @@ -519,59 +507,54 @@ SelectionModel RenderText::GetLeftCursorPosition(const SelectionModel& current, base::i18n::BreakIterator iter(text(), base::i18n::BreakIterator::BREAK_WORD); bool success = iter.Init(); DCHECK(success); - if (!success) { - left.set_selection_end(position); - return left; - } - int last = 0; + if (!success) + return current; while (iter.Advance()) { if (iter.IsWord()) { size_t begin = iter.pos() - iter.GetString().length(); - if (begin == position) { + if (begin == current.selection_end()) { // The cursor is at the beginning of a word. // Move to previous word. break; - } else if (iter.pos() >= position) { + } else if (iter.pos() >= current.selection_end()) { // The cursor is in the middle or at the end of a word. // Move to the top of current word. - last = begin; + pos = begin; break; } else { - last = iter.pos() - iter.GetString().length(); + pos = iter.pos() - iter.GetString().length(); } } } - left.set_selection_end(last); - return left; + return SelectionModel(pos, pos, SelectionModel::LEADING); } -SelectionModel RenderText::GetRightCursorPosition(const SelectionModel& current, - bool move_by_word) { - size_t position = current.selection_end(); - SelectionModel right = current; - - if (!move_by_word) { - right.set_selection_end(std::min(position + 1, text().length())); - return right; - } +SelectionModel RenderText::GetRightSelectionModel(const SelectionModel& current, + BreakType break_type) { + if (break_type == LINE_BREAK) + return SelectionModel(text().length(), + GetIndexOfPreviousGrapheme(text().length()), SelectionModel::TRAILING); + size_t pos = std::min(current.selection_end() + 1, text().length()); + if (break_type == CHARACTER_BREAK) + return SelectionModel(pos, pos, SelectionModel::LEADING); base::i18n::BreakIterator iter(text(), base::i18n::BreakIterator::BREAK_WORD); bool success = iter.Init(); DCHECK(success); - if (!success) { - right.set_selection_end(position); - return right; - } - size_t pos = 0; + if (!success) + return current; while (iter.Advance()) { pos = iter.pos(); - if (iter.IsWord() && pos > position) { + if (iter.IsWord() && pos > current.selection_end()) break; - } } - right.set_selection_end(pos); - return right; + return SelectionModel(pos, pos, SelectionModel::LEADING); +} + +size_t RenderText::GetIndexOfPreviousGrapheme(size_t position) const { + // TODO(msw): Handle complex script. + return std::max(static_cast<int>(position - 1), static_cast<int>(0)); } void RenderText::ApplyCompositionAndSelectionStyles( diff --git a/ui/gfx/render_text.h b/ui/gfx/render_text.h index 8a4f1d1..d90be42 100644 --- a/ui/gfx/render_text.h +++ b/ui/gfx/render_text.h @@ -49,7 +49,10 @@ struct UI_EXPORT StyleRange { typedef std::vector<StyleRange> StyleRanges; -// TODO(msw): Distinguish between logical character and glyph? +// TODO(msw): Distinguish between logical character stops and glyph stops? +// CHARACTER_BREAK cursor movements should stop at neighboring characters. +// WORD_BREAK cursor movements should stop at the nearest word boundaries. +// LINE_BREAK cursor movements should stop at the text ends as shown on screen. enum BreakType { CHARACTER_BREAK, WORD_BREAK, @@ -186,9 +189,6 @@ class UI_EXPORT RenderText { // Moves the cursor left or right. Cursor movement is visual, meaning that // left and right are relative to screen, not the directionality of the text. // If |select| is false, the selection range is emptied at the new position. - // If |break_type| is CHARACTER_BREAK, move to the neighboring character. - // If |break_type| is WORD_BREAK, move to the nearest word boundary. - // If |break_type| is LINE_BREAK, move to text edge as shown on screen. void MoveCursorLeft(BreakType break_type, bool select); void MoveCursorRight(BreakType break_type, bool select); @@ -263,12 +263,15 @@ class UI_EXPORT RenderText { const StyleRanges& style_ranges() const { return style_ranges_; } - // Get the cursor position that visually neighbors |position|. - // If |move_by_word| is true, return the neighboring word delimiter position. - virtual SelectionModel GetLeftCursorPosition(const SelectionModel& current, - bool move_by_word); - virtual SelectionModel GetRightCursorPosition(const SelectionModel& current, - bool move_by_word); + // Get the selection model that visually neighbors |position| by |break_type|. + // The returned value represents a cursor/caret position without a selection. + virtual SelectionModel GetLeftSelectionModel(const SelectionModel& current, + BreakType break_type); + virtual SelectionModel GetRightSelectionModel(const SelectionModel& current, + BreakType break_type); + + // Get the logical index of the grapheme preceeding the argument |position|. + virtual size_t GetIndexOfPreviousGrapheme(size_t position) const; // Apply composition style (underline) to composition range and selection // style (foreground) to selection range. |