Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(510)

Side by Side Diff: ui/gfx/render_text.cc

Issue 1989143002: MacViews: Correct behavior of move and select commands when selection direction changes. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@move_commands
Patch Set: Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 <limits.h> 7 #include <limits.h>
8 8
9 #include <algorithm> 9 #include <algorithm>
10 #include <climits> 10 #include <climits>
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after
198 range = break_list->GetRange(current_break); 198 range = break_list->GetRange(current_break);
199 if (range.end() < break_list->max() && 199 if (range.end() < break_list->max() &&
200 !render_text->IsValidCursorIndex(range.end())) { 200 !render_text->IsValidCursorIndex(range.end())) {
201 range.set_end( 201 range.set_end(
202 render_text->IndexOfAdjacentGrapheme(range.end(), CURSOR_FORWARD)); 202 render_text->IndexOfAdjacentGrapheme(range.end(), CURSOR_FORWARD));
203 break_list->ApplyValue(current_break->second, range); 203 break_list->ApplyValue(current_break->second, range);
204 } 204 }
205 } 205 }
206 } 206 }
207 207
208 // Merges |range1| and |range2|, with the directionality of the result same as
209 // |range2|. |range1| and |range2| must at least share a point.
210 gfx::Range MergeRangesWithDirection(const Range& range1, const Range& range2) {
211 DCHECK(!(range1.GetMax() < range2.GetMin() ||
212 range2.GetMax() < range1.GetMin()));
213 const uint32_t min = std::min(range1.GetMin(), range2.GetMin());
214 const uint32_t max = std::max(range1.GetMax(), range2.GetMax());
215 bool reversed =
216 range2.is_empty() ? !range1.is_reversed() : range2.is_reversed();
217 return reversed ? Range(max, min) : Range(min, max);
218 }
219
208 } // namespace 220 } // namespace
209 221
210 namespace internal { 222 namespace internal {
211 223
212 // Value of |underline_thickness_| that indicates that underline metrics have 224 // Value of |underline_thickness_| that indicates that underline metrics have
213 // not been set explicitly. 225 // not been set explicitly.
214 const SkScalar kUnderlineMetricsNotSet = -1.0f; 226 const SkScalar kUnderlineMetricsNotSet = -1.0f;
215 227
216 SkiaTextRenderer::SkiaTextRenderer(Canvas* canvas) 228 SkiaTextRenderer::SkiaTextRenderer(Canvas* canvas)
217 : canvas_(canvas), 229 : canvas_(canvas),
(...skipping 379 matching lines...) Expand 10 before | Expand all | Expand 10 after
597 } 609 }
598 } 610 }
599 } 611 }
600 612
601 void RenderText::SetCursorPosition(size_t position) { 613 void RenderText::SetCursorPosition(size_t position) {
602 MoveCursorTo(position, false); 614 MoveCursorTo(position, false);
603 } 615 }
604 616
605 void RenderText::MoveCursor(BreakType break_type, 617 void RenderText::MoveCursor(BreakType break_type,
606 VisualCursorDirection direction, 618 VisualCursorDirection direction,
607 bool select) { 619 bool select,
620 SelectionReversedBehavior select_behavior) {
621 // |select_behavior| is not relevant for CHARACTER_BREAK. Verify
622 // |select_behavior| has the default value for this case.
623 if (break_type == CHARACTER_BREAK)
624 DCHECK_EQ(SELECTION_DEFAULT, select_behavior);
625
626 if (break_type == WORD_BREAK)
627 DCHECK_NE(SELECTION_EXTEND, select_behavior);
628
608 SelectionModel cursor(cursor_position(), selection_model_.caret_affinity()); 629 SelectionModel cursor(cursor_position(), selection_model_.caret_affinity());
609 // Cancelling a selection moves to the edge of the selection. 630 // Cancelling a selection moves to the edge of the selection.
610 if (break_type != LINE_BREAK && !selection().is_empty() && !select) { 631 if (break_type != LINE_BREAK && !selection().is_empty() && !select) {
611 SelectionModel selection_start = GetSelectionModelForSelectionStart(); 632 SelectionModel selection_start = GetSelectionModelForSelectionStart();
612 int start_x = GetCursorBounds(selection_start, true).x(); 633 int start_x = GetCursorBounds(selection_start, true).x();
613 int cursor_x = GetCursorBounds(cursor, true).x(); 634 int cursor_x = GetCursorBounds(cursor, true).x();
614 // Use the selection start if it is left (when |direction| is CURSOR_LEFT) 635 // Use the selection start if it is left (when |direction| is CURSOR_LEFT)
615 // or right (when |direction| is CURSOR_RIGHT) of the selection end. 636 // or right (when |direction| is CURSOR_RIGHT) of the selection end.
616 if (direction == CURSOR_RIGHT ? start_x > cursor_x : start_x < cursor_x) 637 if (direction == CURSOR_RIGHT ? start_x > cursor_x : start_x < cursor_x)
617 cursor = selection_start; 638 cursor = selection_start;
618 // Use the nearest word boundary in the proper |direction| for word breaks. 639 // Use the nearest word boundary in the proper |direction| for word breaks.
619 if (break_type == WORD_BREAK) 640 if (break_type == WORD_BREAK)
620 cursor = GetAdjacentSelectionModel(cursor, break_type, direction); 641 cursor = GetAdjacentSelectionModel(cursor, break_type, direction);
621 // Use an adjacent selection model if the cursor is not at a valid position. 642 // Use an adjacent selection model if the cursor is not at a valid position.
622 if (!IsValidCursorIndex(cursor.caret_pos())) 643 if (!IsValidCursorIndex(cursor.caret_pos()))
623 cursor = GetAdjacentSelectionModel(cursor, CHARACTER_BREAK, direction); 644 cursor = GetAdjacentSelectionModel(cursor, CHARACTER_BREAK, direction);
624 } else { 645 } else {
625 cursor = GetAdjacentSelectionModel(cursor, break_type, direction); 646 cursor = GetAdjacentSelectionModel(cursor, break_type, direction);
626 } 647 }
627 if (select) 648 if (select) {
628 cursor.set_selection_start(selection().start()); 649 cursor.set_selection_start(selection().start());
650
651 // cursor now corresponds to the new selection. Take |select_behavior| into
652 // account.
653 bool selection_direction_changed =
654 !selection().is_empty() && !cursor.selection().is_empty() &&
655 selection().is_reversed() != cursor.selection().is_reversed();
656
657 if (select_behavior == SELECTION_EXTEND)
tapted 2016/05/20 06:47:36 nit: needs curlies
karandeepb 2016/05/24 07:47:14 Done.
658 cursor = SelectionModel(
659 MergeRangesWithDirection(selection(), cursor.selection()),
660 selection_model_.caret_affinity());
661 else if (selection_direction_changed && select_behavior == SELECTION_CARET)
662 cursor = SelectionModel(selection().start(),
663 selection_model_.caret_affinity());
664 }
665
629 MoveCursorTo(cursor); 666 MoveCursorTo(cursor);
630 } 667 }
631 668
632 bool RenderText::MoveCursorTo(const SelectionModel& model) { 669 bool RenderText::MoveCursorTo(const SelectionModel& model) {
633 // Enforce valid selection model components. 670 // Enforce valid selection model components.
634 size_t text_length = text().length(); 671 size_t text_length = text().length();
635 Range range(std::min(model.selection().start(), 672 Range range(std::min(model.selection().start(),
636 static_cast<uint32_t>(text_length)), 673 static_cast<uint32_t>(text_length)),
637 std::min(model.caret_pos(), text_length)); 674 std::min(model.caret_pos(), text_length));
638 // The current model only supports caret positions at valid cursor indices. 675 // The current model only supports caret positions at valid cursor indices.
(...skipping 920 matching lines...) Expand 10 before | Expand all | Expand 10 after
1559 1596
1560 SetDisplayOffset(display_offset_.x() + delta_x); 1597 SetDisplayOffset(display_offset_.x() + delta_x);
1561 } 1598 }
1562 1599
1563 void RenderText::DrawSelection(Canvas* canvas) { 1600 void RenderText::DrawSelection(Canvas* canvas) {
1564 for (const Rect& s : GetSubstringBounds(selection())) 1601 for (const Rect& s : GetSubstringBounds(selection()))
1565 canvas->FillRect(s, selection_background_focused_color_); 1602 canvas->FillRect(s, selection_background_focused_color_);
1566 } 1603 }
1567 1604
1568 } // namespace gfx 1605 } // namespace gfx
OLDNEW
« no previous file with comments | « ui/gfx/render_text.h ('k') | ui/gfx/text_constants.h » ('j') | ui/gfx/text_constants.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698