Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 |
| OLD | NEW |