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

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

Issue 14264004: Re-land: NativeTextfieldViews: Show the drop cursor when dragging text (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: 4 Created 7 years, 8 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 <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 593 matching lines...) Expand 10 before | Expand all | Expand 10 after
604 Rect clip_rect(display_rect()); 604 Rect clip_rect(display_rect());
605 clip_rect.Inset(ShadowValue::GetMargin(text_shadows_)); 605 clip_rect.Inset(ShadowValue::GetMargin(text_shadows_));
606 606
607 canvas->Save(); 607 canvas->Save();
608 canvas->ClipRect(clip_rect); 608 canvas->ClipRect(clip_rect);
609 } 609 }
610 610
611 if (!text().empty()) 611 if (!text().empty())
612 DrawSelection(canvas); 612 DrawSelection(canvas);
613 613
614 DrawCursor(canvas); 614 if (cursor_enabled() && cursor_visible() && focused())
615 DrawCursor(canvas, selection_model_);
615 616
616 if (!text().empty()) 617 if (!text().empty())
617 DrawVisualText(canvas); 618 DrawVisualText(canvas);
618 619
619 if (clip_to_display_rect()) 620 if (clip_to_display_rect())
620 canvas->Restore(); 621 canvas->Restore();
621 } 622 }
622 623
624 void RenderText::DrawCursor(Canvas* canvas, const SelectionModel& position) {
625 // Paint cursor. Replace cursor is drawn as rectangle for now.
626 // TODO(msw): Draw a better cursor with a better indication of association.
627 canvas->FillRect(GetCursorBounds(position, true), cursor_color_);
628 }
629
623 void RenderText::DrawSelectedText(Canvas* canvas) { 630 void RenderText::DrawSelectedText(Canvas* canvas) {
624 EnsureLayout(); 631 EnsureLayout();
625 const std::vector<Rect> sel = GetSubstringBounds(selection()); 632 const std::vector<Rect> sel = GetSubstringBounds(selection());
626 for (size_t i = 0; i < sel.size(); ++i) { 633 for (size_t i = 0; i < sel.size(); ++i) {
627 canvas->Save(); 634 canvas->Save();
628 canvas->ClipRect(sel[i]); 635 canvas->ClipRect(sel[i]);
629 DrawVisualText(canvas); 636 DrawVisualText(canvas);
630 canvas->Restore(); 637 canvas->Restore();
631 } 638 }
632 } 639 }
633 640
634 Rect RenderText::GetCursorBounds(const SelectionModel& caret, 641 Rect RenderText::GetCursorBounds(const SelectionModel& caret,
635 bool insert_mode) { 642 bool insert_mode) {
636 EnsureLayout(); 643 EnsureLayout();
637 644
638 size_t caret_pos = caret.caret_pos(); 645 size_t caret_pos = caret.caret_pos();
646 DCHECK(IsCursorablePosition(caret_pos));
639 // In overtype mode, ignore the affinity and always indicate that we will 647 // In overtype mode, ignore the affinity and always indicate that we will
640 // overtype the next character. 648 // overtype the next character.
641 LogicalCursorDirection caret_affinity = 649 LogicalCursorDirection caret_affinity =
642 insert_mode ? caret.caret_affinity() : CURSOR_FORWARD; 650 insert_mode ? caret.caret_affinity() : CURSOR_FORWARD;
643 int x = 0, width = 1, height = 0; 651 int x = 0, width = 1, height = 0;
644 if (caret_pos == (caret_affinity == CURSOR_BACKWARD ? 0 : text().length())) { 652 if (caret_pos == (caret_affinity == CURSOR_BACKWARD ? 0 : text().length())) {
645 // The caret is attached to the boundary. Always return a 1-dip width caret, 653 // The caret is attached to the boundary. Always return a 1-dip width caret,
646 // since there is nothing to overtype. 654 // since there is nothing to overtype.
647 Size size = GetStringSize(); 655 Size size = GetStringSize();
648 if ((GetTextDirection() == base::i18n::RIGHT_TO_LEFT) == (caret_pos == 0)) 656 if ((GetTextDirection() == base::i18n::RIGHT_TO_LEFT) == (caret_pos == 0))
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
699 if (sel.is_empty()) 707 if (sel.is_empty())
700 return selection_model_; 708 return selection_model_;
701 return SelectionModel(sel.start(), 709 return SelectionModel(sel.start(),
702 sel.is_reversed() ? CURSOR_BACKWARD : CURSOR_FORWARD); 710 sel.is_reversed() ? CURSOR_BACKWARD : CURSOR_FORWARD);
703 } 711 }
704 712
705 void RenderText::SetTextShadows(const ShadowValues& shadows) { 713 void RenderText::SetTextShadows(const ShadowValues& shadows) {
706 text_shadows_ = shadows; 714 text_shadows_ = shadows;
707 } 715 }
708 716
717 // static
718 bool RenderText::RangeContainsCaret(const ui::Range& range,
719 size_t caret_pos,
720 LogicalCursorDirection caret_affinity) {
721 // NB: exploits unsigned wraparound (WG14/N1124 section 6.2.5 paragraph 9).
722 size_t adjacent = (caret_affinity == CURSOR_BACKWARD) ?
723 caret_pos - 1 : caret_pos + 1;
724 return range.Contains(ui::Range(caret_pos, adjacent));
725 }
726
709 RenderText::RenderText() 727 RenderText::RenderText()
710 : horizontal_alignment_(base::i18n::IsRTL() ? ALIGN_RIGHT : ALIGN_LEFT), 728 : horizontal_alignment_(base::i18n::IsRTL() ? ALIGN_RIGHT : ALIGN_LEFT),
711 directionality_mode_(DIRECTIONALITY_FROM_TEXT), 729 directionality_mode_(DIRECTIONALITY_FROM_TEXT),
712 text_direction_(base::i18n::UNKNOWN_DIRECTION), 730 text_direction_(base::i18n::UNKNOWN_DIRECTION),
713 cursor_enabled_(true), 731 cursor_enabled_(true),
714 cursor_visible_(false), 732 cursor_visible_(false),
715 insert_mode_(true), 733 insert_mode_(true),
716 cursor_color_(kDefaultColor), 734 cursor_color_(kDefaultColor),
717 selection_color_(kDefaultColor), 735 selection_color_(kDefaultColor),
718 selection_background_focused_color_(kDefaultSelectionBackgroundColor), 736 selection_background_focused_color_(kDefaultSelectionBackgroundColor),
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after
873 text_rect, left_part, right_part, colors_.breaks().front().second); 891 text_rect, left_part, right_part, colors_.breaks().front().second);
874 if (shader) 892 if (shader)
875 renderer->SetShader(shader.get(), display_rect()); 893 renderer->SetShader(shader.get(), display_rect());
876 } 894 }
877 895
878 void RenderText::ApplyTextShadows(internal::SkiaTextRenderer* renderer) { 896 void RenderText::ApplyTextShadows(internal::SkiaTextRenderer* renderer) {
879 skia::RefPtr<SkDrawLooper> looper = CreateShadowDrawLooper(text_shadows_); 897 skia::RefPtr<SkDrawLooper> looper = CreateShadowDrawLooper(text_shadows_);
880 renderer->SetDrawLooper(looper.get()); 898 renderer->SetDrawLooper(looper.get());
881 } 899 }
882 900
883 // static
884 bool RenderText::RangeContainsCaret(const ui::Range& range,
885 size_t caret_pos,
886 LogicalCursorDirection caret_affinity) {
887 // NB: exploits unsigned wraparound (WG14/N1124 section 6.2.5 paragraph 9).
888 size_t adjacent = (caret_affinity == CURSOR_BACKWARD) ?
889 caret_pos - 1 : caret_pos + 1;
890 return range.Contains(ui::Range(caret_pos, adjacent));
891 }
892
893 void RenderText::MoveCursorTo(size_t position, bool select) { 901 void RenderText::MoveCursorTo(size_t position, bool select) {
894 size_t cursor = std::min(position, text().length()); 902 size_t cursor = std::min(position, text().length());
895 if (IsCursorablePosition(cursor)) 903 if (IsCursorablePosition(cursor))
896 SetSelectionModel(SelectionModel( 904 SetSelectionModel(SelectionModel(
897 ui::Range(select ? selection().start() : cursor, cursor), 905 ui::Range(select ? selection().start() : cursor, cursor),
898 (cursor == 0) ? CURSOR_FORWARD : CURSOR_BACKWARD)); 906 (cursor == 0) ? CURSOR_FORWARD : CURSOR_BACKWARD));
899 } 907 }
900 908
901 void RenderText::UpdateObscuredText() { 909 void RenderText::UpdateObscuredText() {
902 if (!obscured_) 910 if (!obscured_)
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
956 } 964 }
957 965
958 void RenderText::DrawSelection(Canvas* canvas) { 966 void RenderText::DrawSelection(Canvas* canvas) {
959 const SkColor color = focused() ? selection_background_focused_color_ : 967 const SkColor color = focused() ? selection_background_focused_color_ :
960 selection_background_unfocused_color_; 968 selection_background_unfocused_color_;
961 const std::vector<Rect> sel = GetSubstringBounds(selection()); 969 const std::vector<Rect> sel = GetSubstringBounds(selection());
962 for (std::vector<Rect>::const_iterator i = sel.begin(); i < sel.end(); ++i) 970 for (std::vector<Rect>::const_iterator i = sel.begin(); i < sel.end(); ++i)
963 canvas->FillRect(*i, color); 971 canvas->FillRect(*i, color);
964 } 972 }
965 973
966 void RenderText::DrawCursor(Canvas* canvas) {
967 // Paint cursor. Replace cursor is drawn as rectangle for now.
968 // TODO(msw): Draw a better cursor with a better indication of association.
969 if (cursor_enabled() && cursor_visible() && focused()) {
970 canvas->FillRect(GetUpdatedCursorBounds(),
971 insert_mode_ ? cursor_color_ : selection_background_unfocused_color_);
972 }
973 }
974
975 } // namespace gfx 974 } // namespace gfx
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698