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

Side by Side Diff: ui/views/controls/textfield/textfield.cc

Issue 2345183002: Views: Draw Textfield selected text in gray when top-level Widget loses focus.
Patch Set: Fix lifetime issues with BorderView's widget_ and address review comments. Created 4 years, 1 month 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/views/controls/textfield/textfield.h" 5 #include "ui/views/controls/textfield/textfield.h"
6 6
7 #include <string> 7 #include <string>
8 #include <utility> 8 #include <utility>
9 9
10 #include "base/strings/utf_string_conversions.h" 10 #include "base/strings/utf_string_conversions.h"
(...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after
233 read_only_(false), 233 read_only_(false),
234 default_width_in_chars_(0), 234 default_width_in_chars_(0),
235 use_default_text_color_(true), 235 use_default_text_color_(true),
236 use_default_background_color_(true), 236 use_default_background_color_(true),
237 use_default_selection_text_color_(true), 237 use_default_selection_text_color_(true),
238 use_default_selection_background_color_(true), 238 use_default_selection_background_color_(true),
239 text_color_(SK_ColorBLACK), 239 text_color_(SK_ColorBLACK),
240 background_color_(SK_ColorWHITE), 240 background_color_(SK_ColorWHITE),
241 selection_text_color_(SK_ColorWHITE), 241 selection_text_color_(SK_ColorWHITE),
242 selection_background_color_(SK_ColorBLUE), 242 selection_background_color_(SK_ColorBLUE),
243 focus_manager_(nullptr),
243 placeholder_text_color_(kDefaultPlaceholderTextColor), 244 placeholder_text_color_(kDefaultPlaceholderTextColor),
244 invalid_(false), 245 invalid_(false),
245 text_input_type_(ui::TEXT_INPUT_TYPE_TEXT), 246 text_input_type_(ui::TEXT_INPUT_TYPE_TEXT),
246 text_input_flags_(0), 247 text_input_flags_(0),
247 performing_user_action_(false), 248 performing_user_action_(false),
248 skip_input_method_cancel_composition_(false), 249 skip_input_method_cancel_composition_(false),
249 drop_cursor_visible_(false), 250 drop_cursor_visible_(false),
250 initiating_drag_(false), 251 initiating_drag_(false),
251 selection_controller_(this), 252 selection_controller_(this),
252 drag_start_display_offset_(0), 253 drag_start_display_offset_(0),
(...skipping 17 matching lines...) Expand all
270 AddAccelerator(ui::Accelerator(ui::VKEY_X, ui::EF_CONTROL_DOWN)); 271 AddAccelerator(ui::Accelerator(ui::VKEY_X, ui::EF_CONTROL_DOWN));
271 AddAccelerator(ui::Accelerator(ui::VKEY_C, ui::EF_CONTROL_DOWN)); 272 AddAccelerator(ui::Accelerator(ui::VKEY_C, ui::EF_CONTROL_DOWN));
272 AddAccelerator(ui::Accelerator(ui::VKEY_V, ui::EF_CONTROL_DOWN)); 273 AddAccelerator(ui::Accelerator(ui::VKEY_V, ui::EF_CONTROL_DOWN));
273 } 274 }
274 275
275 Textfield::~Textfield() { 276 Textfield::~Textfield() {
276 if (GetInputMethod()) { 277 if (GetInputMethod()) {
277 // The textfield should have been blurred before destroy. 278 // The textfield should have been blurred before destroy.
278 DCHECK(this != GetInputMethod()->GetTextInputClient()); 279 DCHECK(this != GetInputMethod()->GetTextInputClient());
279 } 280 }
281 DCHECK(!focus_manager_);
280 } 282 }
281 283
282 void Textfield::SetReadOnly(bool read_only) { 284 void Textfield::SetReadOnly(bool read_only) {
283 // Update read-only without changing the focusable state (or active, etc.). 285 // Update read-only without changing the focusable state (or active, etc.).
284 read_only_ = read_only; 286 read_only_ = read_only;
285 if (GetInputMethod()) 287 if (GetInputMethod())
286 GetInputMethod()->OnTextInputTypeChanged(this); 288 GetInputMethod()->OnTextInputTypeChanged(this);
287 SetColor(GetTextColor()); 289 SetColor(GetTextColor());
288 UpdateBackgroundColor(); 290 UpdateBackgroundColor();
289 } 291 }
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
417 SkColor Textfield::GetSelectionBackgroundColor() const { 419 SkColor Textfield::GetSelectionBackgroundColor() const {
418 return use_default_selection_background_color_ ? 420 return use_default_selection_background_color_ ?
419 GetNativeTheme()->GetSystemColor( 421 GetNativeTheme()->GetSystemColor(
420 ui::NativeTheme::kColorId_TextfieldSelectionBackgroundFocused) : 422 ui::NativeTheme::kColorId_TextfieldSelectionBackgroundFocused) :
421 selection_background_color_; 423 selection_background_color_;
422 } 424 }
423 425
424 void Textfield::SetSelectionBackgroundColor(SkColor color) { 426 void Textfield::SetSelectionBackgroundColor(SkColor color) {
425 selection_background_color_ = color; 427 selection_background_color_ = color;
426 use_default_selection_background_color_ = false; 428 use_default_selection_background_color_ = false;
427 GetRenderText()->set_selection_background_focused_color( 429 GetRenderText()->set_selection_background_color(
428 GetSelectionBackgroundColor()); 430 GetSelectionBackgroundColor());
429 SchedulePaint(); 431 SchedulePaint();
430 } 432 }
431 433
432 void Textfield::UseDefaultSelectionBackgroundColor() { 434 void Textfield::UseDefaultSelectionBackgroundColor() {
433 use_default_selection_background_color_ = true; 435 use_default_selection_background_color_ = true;
434 GetRenderText()->set_selection_background_focused_color( 436 GetRenderText()->set_selection_background_color(
435 GetSelectionBackgroundColor()); 437 GetSelectionBackgroundColor());
436 SchedulePaint(); 438 SchedulePaint();
437 } 439 }
438 440
441 SkColor Textfield::GetUnfocusedSelectionBackgroundColor() const {
msw 2016/11/09 02:08:53 Inline this or make a file-local function, it's no
442 return GetNativeTheme()->GetSystemColor(
443 ui::NativeTheme::kColorId_TextfieldSelectionBackgroundUnfocused);
444 }
445
439 bool Textfield::GetCursorEnabled() const { 446 bool Textfield::GetCursorEnabled() const {
440 return GetRenderText()->cursor_enabled(); 447 return GetRenderText()->cursor_enabled();
441 } 448 }
442 449
443 void Textfield::SetCursorEnabled(bool enabled) { 450 void Textfield::SetCursorEnabled(bool enabled) {
444 GetRenderText()->SetCursorEnabled(enabled); 451 GetRenderText()->SetCursorEnabled(enabled);
445 } 452 }
446 453
447 const gfx::FontList& Textfield::GetFontList() const { 454 const gfx::FontList& Textfield::GetFontList() const {
448 return GetRenderText()->font_list(); 455 return GetRenderText()->font_list();
(...skipping 485 matching lines...) Expand 10 before | Expand all | Expand 10 after
934 touch_selection_controller_->SelectionChanged(); 941 touch_selection_controller_->SelectionChanged();
935 } 942 }
936 943
937 void Textfield::OnEnabledChanged() { 944 void Textfield::OnEnabledChanged() {
938 View::OnEnabledChanged(); 945 View::OnEnabledChanged();
939 if (GetInputMethod()) 946 if (GetInputMethod())
940 GetInputMethod()->OnTextInputTypeChanged(this); 947 GetInputMethod()->OnTextInputTypeChanged(this);
941 SchedulePaint(); 948 SchedulePaint();
942 } 949 }
943 950
951 void Textfield::ViewHierarchyChanged(
952 const ViewHierarchyChangedDetails& details) {
953 if (details.parent->Contains(this) && details.move_view == nullptr)
msw 2016/11/09 02:08:53 Can you explain what's happening here? Shouldn't t
954 ObserveWidgetFocusChanges(details.is_add);
955 }
956
957 void Textfield::NativeViewHierarchyChanged() {
958 ObserveWidgetFocusChanges(true);
msw 2016/11/09 02:08:53 Add a comment explaining why this is necessary; Th
959 }
960
944 void Textfield::OnPaint(gfx::Canvas* canvas) { 961 void Textfield::OnPaint(gfx::Canvas* canvas) {
945 OnPaintBackground(canvas); 962 OnPaintBackground(canvas);
946 PaintTextAndCursor(canvas); 963 PaintTextAndCursor(canvas);
947 OnPaintBorder(canvas); 964 OnPaintBorder(canvas);
948 } 965 }
949 966
950 void Textfield::OnFocus() { 967 void Textfield::OnFocus() {
951 GetRenderText()->set_focused(true); 968 GetRenderText()->set_focused(true);
952 if (ShouldShowCursor()) 969 if (ShouldShowCursor())
953 GetRenderText()->set_cursor_visible(true); 970 GetRenderText()->set_cursor_visible(true);
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
987 gfx::Point Textfield::GetKeyboardContextMenuLocation() { 1004 gfx::Point Textfield::GetKeyboardContextMenuLocation() {
988 return GetCaretBounds().bottom_right(); 1005 return GetCaretBounds().bottom_right();
989 } 1006 }
990 1007
991 void Textfield::OnNativeThemeChanged(const ui::NativeTheme* theme) { 1008 void Textfield::OnNativeThemeChanged(const ui::NativeTheme* theme) {
992 gfx::RenderText* render_text = GetRenderText(); 1009 gfx::RenderText* render_text = GetRenderText();
993 render_text->SetColor(GetTextColor()); 1010 render_text->SetColor(GetTextColor());
994 UpdateBackgroundColor(); 1011 UpdateBackgroundColor();
995 render_text->set_cursor_color(GetTextColor()); 1012 render_text->set_cursor_color(GetTextColor());
996 render_text->set_selection_color(GetSelectionTextColor()); 1013 render_text->set_selection_color(GetSelectionTextColor());
997 render_text->set_selection_background_focused_color( 1014 if (HasFocus()) {
msw 2016/11/09 02:08:53 optional nit: use an inlined ternary or something
998 GetSelectionBackgroundColor()); 1015 render_text->set_selection_background_color(GetSelectionBackgroundColor());
1016 } else {
1017 render_text->set_selection_background_color(
1018 GetUnfocusedSelectionBackgroundColor());
1019 }
999 } 1020 }
1000 1021
1001 //////////////////////////////////////////////////////////////////////////////// 1022 ////////////////////////////////////////////////////////////////////////////////
1002 // Textfield, TextfieldModel::Delegate overrides: 1023 // Textfield, TextfieldModel::Delegate overrides:
1003 1024
1004 void Textfield::OnCompositionTextConfirmedOrCleared() { 1025 void Textfield::OnCompositionTextConfirmedOrCleared() {
1005 if (!skip_input_method_cancel_composition_) 1026 if (!skip_input_method_cancel_composition_)
1006 GetInputMethod()->CancelComposition(this); 1027 GetInputMethod()->CancelComposition(this);
1007 } 1028 }
1008 1029
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
1065 return drag_operations; 1086 return drag_operations;
1066 } 1087 }
1067 1088
1068 bool Textfield::CanStartDragForView(View* sender, 1089 bool Textfield::CanStartDragForView(View* sender,
1069 const gfx::Point& press_pt, 1090 const gfx::Point& press_pt,
1070 const gfx::Point& p) { 1091 const gfx::Point& p) {
1071 return initiating_drag_ && GetRenderText()->IsPointInSelection(press_pt); 1092 return initiating_drag_ && GetRenderText()->IsPointInSelection(press_pt);
1072 } 1093 }
1073 1094
1074 //////////////////////////////////////////////////////////////////////////////// 1095 ////////////////////////////////////////////////////////////////////////////////
1096 // Textfield, FocusChangeListener overrides:
1097
1098 void Textfield::OnWillChangeFocus(View* focus_before, View* focus_after) {
msw 2016/11/09 02:08:53 It's really unfortunate that we can't do this via
tapted 2016/11/11 00:10:39 I think this would be inconsistent with the WebCon
1099 if (focus_before != this && focus_after != this)
1100 return;
1101
1102 SkColor selection_bg_color = focus_after
1103 ? GetSelectionBackgroundColor()
1104 : GetUnfocusedSelectionBackgroundColor();
1105
1106 // Selection is drawn if |this| has focus, or the Widget loses activation, but
1107 // not if another View in this Widget is gaining focus.
1108 GetRenderText()->set_draw_text_selection(focus_after == this || !focus_after);
1109 GetRenderText()->set_selection_background_color(selection_bg_color);
msw 2016/11/09 02:08:53 Should we SchedulePaint after this, just in case t
1110 }
1111
1112 void Textfield::OnDidChangeFocus(View* focused_before, View* focused_now) {}
1113
1114 ////////////////////////////////////////////////////////////////////////////////
1075 // Textfield, WordLookupClient overrides: 1115 // Textfield, WordLookupClient overrides:
1076 1116
1077 bool Textfield::GetDecoratedWordAtPoint(const gfx::Point& point, 1117 bool Textfield::GetDecoratedWordAtPoint(const gfx::Point& point,
1078 gfx::DecoratedText* decorated_word, 1118 gfx::DecoratedText* decorated_word,
1079 gfx::Point* baseline_point) { 1119 gfx::Point* baseline_point) {
1080 return GetRenderText()->GetDecoratedWordAtPoint(point, decorated_word, 1120 return GetRenderText()->GetDecoratedWordAtPoint(point, decorated_word,
1081 baseline_point); 1121 baseline_point);
1082 } 1122 }
1083 1123
1084 //////////////////////////////////////////////////////////////////////////////// 1124 ////////////////////////////////////////////////////////////////////////////////
(...skipping 746 matching lines...) Expand 10 before | Expand all | Expand 10 after
1831 #if defined(OS_LINUX) && !defined(OS_CHROMEOS) 1871 #if defined(OS_LINUX) && !defined(OS_CHROMEOS)
1832 if (text_input_type_ != ui::TEXT_INPUT_TYPE_PASSWORD) { 1872 if (text_input_type_ != ui::TEXT_INPUT_TYPE_PASSWORD) {
1833 ui::ScopedClipboardWriter(ui::CLIPBOARD_TYPE_SELECTION) 1873 ui::ScopedClipboardWriter(ui::CLIPBOARD_TYPE_SELECTION)
1834 .WriteText(GetSelectedText()); 1874 .WriteText(GetSelectedText());
1835 if (controller_) 1875 if (controller_)
1836 controller_->OnAfterCutOrCopy(ui::CLIPBOARD_TYPE_SELECTION); 1876 controller_->OnAfterCutOrCopy(ui::CLIPBOARD_TYPE_SELECTION);
1837 } 1877 }
1838 #endif 1878 #endif
1839 } 1879 }
1840 1880
1881 void Textfield::ObserveWidgetFocusChanges(bool add_as_listener) {
1882 if (focus_manager_) {
1883 focus_manager_->RemoveFocusChangeListener(this);
1884 focus_manager_ = nullptr;
1885 }
1886
1887 if (add_as_listener) {
1888 focus_manager_ = GetFocusManager();
msw 2016/11/09 02:08:53 Should this early-return up top if |focus_manager_
1889 if (!focus_manager_) {
1890 // |focus_manager_| will be null if GetWidget() is null (not currently in
1891 // a Widget), or if the Widget's FocusManager is null and there is no
1892 // parent Widget yet (e.g. TYPE_CONTROL Widgets). In the latter case, a
1893 // call to NativeViewHierarchyChanged() should follow.
1894 return;
1895 }
1896 focus_manager_->AddFocusChangeListener(this);
1897 }
1898 }
1899
1841 void Textfield::UpdateBackgroundColor() { 1900 void Textfield::UpdateBackgroundColor() {
1842 const SkColor color = GetBackgroundColor(); 1901 const SkColor color = GetBackgroundColor();
1843 if (ui::MaterialDesignController::IsSecondaryUiMaterial()) { 1902 if (ui::MaterialDesignController::IsSecondaryUiMaterial()) {
1844 set_background(Background::CreateBackgroundPainter( 1903 set_background(Background::CreateBackgroundPainter(
1845 true, Painter::CreateSolidRoundRectPainter( 1904 true, Painter::CreateSolidRoundRectPainter(
1846 color, FocusableBorder::kCornerRadiusDp))); 1905 color, FocusableBorder::kCornerRadiusDp)));
1847 } else { 1906 } else {
1848 set_background(Background::CreateSolidBackground(color)); 1907 set_background(Background::CreateSolidBackground(color));
1849 } 1908 }
1850 // Disable subpixel rendering when the background color is transparent 1909 // Disable subpixel rendering when the background color is transparent
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after
2048 } 2107 }
2049 2108
2050 void Textfield::OnCursorBlinkTimerFired() { 2109 void Textfield::OnCursorBlinkTimerFired() {
2051 DCHECK(ShouldBlinkCursor()); 2110 DCHECK(ShouldBlinkCursor());
2052 gfx::RenderText* render_text = GetRenderText(); 2111 gfx::RenderText* render_text = GetRenderText();
2053 render_text->set_cursor_visible(!render_text->cursor_visible()); 2112 render_text->set_cursor_visible(!render_text->cursor_visible());
2054 RepaintCursor(); 2113 RepaintCursor();
2055 } 2114 }
2056 2115
2057 } // namespace views 2116 } // namespace views
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698