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/trace_event/trace_event.h" | 10 #include "base/trace_event/trace_event.h" |
| (...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 244 read_only_(false), | 244 read_only_(false), |
| 245 default_width_in_chars_(0), | 245 default_width_in_chars_(0), |
| 246 use_default_text_color_(true), | 246 use_default_text_color_(true), |
| 247 use_default_background_color_(true), | 247 use_default_background_color_(true), |
| 248 use_default_selection_text_color_(true), | 248 use_default_selection_text_color_(true), |
| 249 use_default_selection_background_color_(true), | 249 use_default_selection_background_color_(true), |
| 250 text_color_(SK_ColorBLACK), | 250 text_color_(SK_ColorBLACK), |
| 251 background_color_(SK_ColorWHITE), | 251 background_color_(SK_ColorWHITE), |
| 252 selection_text_color_(SK_ColorWHITE), | 252 selection_text_color_(SK_ColorWHITE), |
| 253 selection_background_color_(SK_ColorBLUE), | 253 selection_background_color_(SK_ColorBLUE), |
| 254 focus_manager_(nullptr), | |
| 254 placeholder_text_color_(kDefaultPlaceholderTextColor), | 255 placeholder_text_color_(kDefaultPlaceholderTextColor), |
| 255 invalid_(false), | 256 invalid_(false), |
| 256 text_input_type_(ui::TEXT_INPUT_TYPE_TEXT), | 257 text_input_type_(ui::TEXT_INPUT_TYPE_TEXT), |
| 257 text_input_flags_(0), | 258 text_input_flags_(0), |
| 258 performing_user_action_(false), | 259 performing_user_action_(false), |
| 259 skip_input_method_cancel_composition_(false), | 260 skip_input_method_cancel_composition_(false), |
| 260 drop_cursor_visible_(false), | 261 drop_cursor_visible_(false), |
| 261 initiating_drag_(false), | 262 initiating_drag_(false), |
| 262 aggregated_clicks_(0), | 263 aggregated_clicks_(0), |
| 263 drag_start_display_offset_(0), | 264 drag_start_display_offset_(0), |
| 264 touch_handles_hidden_due_to_scroll_(false), | 265 touch_handles_hidden_due_to_scroll_(false), |
| 265 use_focus_ring_(ui::MaterialDesignController::IsSecondaryUiMaterial()), | 266 use_focus_ring_(ui::MaterialDesignController::IsSecondaryUiMaterial()), |
| 266 weak_ptr_factory_(this) { | 267 weak_ptr_factory_(this) { |
| 267 set_context_menu_controller(this); | 268 set_context_menu_controller(this); |
| 268 set_drag_controller(this); | 269 set_drag_controller(this); |
| 269 GetRenderText()->SetFontList(GetDefaultFontList()); | 270 GetRenderText()->SetFontList(GetDefaultFontList()); |
| 270 View::SetBorder(std::unique_ptr<Border>(new FocusableBorder())); | 271 View::SetBorder(std::unique_ptr<Border>(new FocusableBorder())); |
| 271 SetFocusBehavior(FocusBehavior::ALWAYS); | 272 SetFocusBehavior(FocusBehavior::ALWAYS); |
| 272 | 273 |
| 273 // These allow BrowserView to pass edit commands from the Chrome menu to us | 274 // These allow BrowserView to pass edit commands from the Chrome menu to us |
| 274 // when we're focused by simply asking the FocusManager to | 275 // when we're focused by simply asking the FocusManager to |
| 275 // ProcessAccelerator() with the relevant accelerators. | 276 // ProcessAccelerator() with the relevant accelerators. |
| 276 AddAccelerator(ui::Accelerator(ui::VKEY_X, ui::EF_CONTROL_DOWN)); | 277 AddAccelerator(ui::Accelerator(ui::VKEY_X, ui::EF_CONTROL_DOWN)); |
| 277 AddAccelerator(ui::Accelerator(ui::VKEY_C, ui::EF_CONTROL_DOWN)); | 278 AddAccelerator(ui::Accelerator(ui::VKEY_C, ui::EF_CONTROL_DOWN)); |
| 278 AddAccelerator(ui::Accelerator(ui::VKEY_V, ui::EF_CONTROL_DOWN)); | 279 AddAccelerator(ui::Accelerator(ui::VKEY_V, ui::EF_CONTROL_DOWN)); |
| 279 } | 280 } |
| 280 | 281 |
| 281 Textfield::~Textfield() { | 282 Textfield::~Textfield() { |
| 283 // If not currently attached to a Widget, |focus_manager_| would be null. | |
| 284 if (focus_manager_) { | |
| 285 // The Textfield may still be listening to focus changes if the Textfield is | |
| 286 // destroyed by its controller from OnKey events. | |
| 287 focus_manager_->RemoveFocusChangeListener(this); | |
| 288 focus_manager_ = nullptr; | |
| 289 } | |
| 282 if (GetInputMethod()) { | 290 if (GetInputMethod()) { |
| 283 // The textfield should have been blurred before destroy. | 291 // The textfield should have been blurred before destroy. |
| 284 DCHECK(this != GetInputMethod()->GetTextInputClient()); | 292 DCHECK(this != GetInputMethod()->GetTextInputClient()); |
| 285 } | 293 } |
| 286 } | 294 } |
| 287 | 295 |
| 288 void Textfield::SetReadOnly(bool read_only) { | 296 void Textfield::SetReadOnly(bool read_only) { |
| 289 // Update read-only without changing the focusable state (or active, etc.). | 297 // Update read-only without changing the focusable state (or active, etc.). |
| 290 read_only_ = read_only; | 298 read_only_ = read_only; |
| 291 if (GetInputMethod()) | 299 if (GetInputMethod()) |
| (...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 422 SkColor Textfield::GetSelectionBackgroundColor() const { | 430 SkColor Textfield::GetSelectionBackgroundColor() const { |
| 423 return use_default_selection_background_color_ ? | 431 return use_default_selection_background_color_ ? |
| 424 GetNativeTheme()->GetSystemColor( | 432 GetNativeTheme()->GetSystemColor( |
| 425 ui::NativeTheme::kColorId_TextfieldSelectionBackgroundFocused) : | 433 ui::NativeTheme::kColorId_TextfieldSelectionBackgroundFocused) : |
| 426 selection_background_color_; | 434 selection_background_color_; |
| 427 } | 435 } |
| 428 | 436 |
| 429 void Textfield::SetSelectionBackgroundColor(SkColor color) { | 437 void Textfield::SetSelectionBackgroundColor(SkColor color) { |
| 430 selection_background_color_ = color; | 438 selection_background_color_ = color; |
| 431 use_default_selection_background_color_ = false; | 439 use_default_selection_background_color_ = false; |
| 432 GetRenderText()->set_selection_background_focused_color( | 440 GetRenderText()->set_selection_background_color( |
| 433 GetSelectionBackgroundColor()); | 441 GetSelectionBackgroundColor()); |
| 434 SchedulePaint(); | 442 SchedulePaint(); |
| 435 } | 443 } |
| 436 | 444 |
| 437 void Textfield::UseDefaultSelectionBackgroundColor() { | 445 void Textfield::UseDefaultSelectionBackgroundColor() { |
| 438 use_default_selection_background_color_ = true; | 446 use_default_selection_background_color_ = true; |
| 439 GetRenderText()->set_selection_background_focused_color( | 447 GetRenderText()->set_selection_background_color( |
| 440 GetSelectionBackgroundColor()); | 448 GetSelectionBackgroundColor()); |
| 441 SchedulePaint(); | 449 SchedulePaint(); |
| 442 } | 450 } |
| 443 | 451 |
| 452 SkColor Textfield::GetUnfocusedSelectionBackgroundColor() const { | |
| 453 return GetNativeTheme()->GetSystemColor( | |
| 454 ui::NativeTheme::kColorId_TextfieldSelectionBackgroundUnfocused); | |
| 455 } | |
| 456 | |
| 444 bool Textfield::GetCursorEnabled() const { | 457 bool Textfield::GetCursorEnabled() const { |
| 445 return GetRenderText()->cursor_enabled(); | 458 return GetRenderText()->cursor_enabled(); |
| 446 } | 459 } |
| 447 | 460 |
| 448 void Textfield::SetCursorEnabled(bool enabled) { | 461 void Textfield::SetCursorEnabled(bool enabled) { |
| 449 GetRenderText()->SetCursorEnabled(enabled); | 462 GetRenderText()->SetCursorEnabled(enabled); |
| 450 } | 463 } |
| 451 | 464 |
| 452 const gfx::FontList& Textfield::GetFontList() const { | 465 const gfx::FontList& Textfield::GetFontList() const { |
| 453 return GetRenderText()->font_list(); | 466 return GetRenderText()->font_list(); |
| (...skipping 534 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 988 touch_selection_controller_->SelectionChanged(); | 1001 touch_selection_controller_->SelectionChanged(); |
| 989 } | 1002 } |
| 990 | 1003 |
| 991 void Textfield::OnEnabledChanged() { | 1004 void Textfield::OnEnabledChanged() { |
| 992 View::OnEnabledChanged(); | 1005 View::OnEnabledChanged(); |
| 993 if (GetInputMethod()) | 1006 if (GetInputMethod()) |
| 994 GetInputMethod()->OnTextInputTypeChanged(this); | 1007 GetInputMethod()->OnTextInputTypeChanged(this); |
| 995 SchedulePaint(); | 1008 SchedulePaint(); |
| 996 } | 1009 } |
| 997 | 1010 |
| 1011 void Textfield::ViewHierarchyChanged( | |
| 1012 const ViewHierarchyChangedDetails& details) { | |
| 1013 // Textfields only care about focus changes if the entire Widget has lost | |
| 1014 // focus, so don't bother listening if there is no Widget. | |
| 1015 if (!GetWidget()) | |
| 1016 return; | |
| 1017 | |
| 1018 if (details.parent->Contains(this) && details.move_view == nullptr) { | |
| 1019 if (details.is_add) { | |
| 1020 FocusManager* focus_manager = GetFocusManager(); | |
| 1021 // There should never be two different FocusManagers for the same Widget | |
| 1022 // at the same time. | |
| 1023 DCHECK(!focus_manager_ && focus_manager); | |
| 1024 focus_manager_ = focus_manager; | |
| 1025 focus_manager_->AddFocusChangeListener(this); | |
| 1026 } else { | |
| 1027 DCHECK(focus_manager_); | |
| 1028 focus_manager_->RemoveFocusChangeListener(this); | |
| 1029 focus_manager_ = nullptr; | |
| 1030 } | |
| 1031 } | |
| 1032 } | |
| 1033 | |
| 998 void Textfield::OnPaint(gfx::Canvas* canvas) { | 1034 void Textfield::OnPaint(gfx::Canvas* canvas) { |
| 999 OnPaintBackground(canvas); | 1035 OnPaintBackground(canvas); |
| 1000 PaintTextAndCursor(canvas); | 1036 PaintTextAndCursor(canvas); |
| 1001 OnPaintBorder(canvas); | 1037 OnPaintBorder(canvas); |
| 1002 } | 1038 } |
| 1003 | 1039 |
| 1004 void Textfield::OnFocus() { | 1040 void Textfield::OnFocus() { |
| 1005 GetRenderText()->set_focused(true); | 1041 GetRenderText()->set_focused(true); |
| 1042 GetRenderText()->set_selection_background_color( | |
| 1043 GetSelectionBackgroundColor()); | |
|
tapted
2016/10/24 06:04:16
Can this move to OnWillChangeFocus? Just to keep t
Patti Lor
2016/10/27 00:17:27
Done.
| |
| 1006 if (ShouldShowCursor()) | 1044 if (ShouldShowCursor()) |
| 1007 GetRenderText()->set_cursor_visible(true); | 1045 GetRenderText()->set_cursor_visible(true); |
| 1008 if (GetInputMethod()) | 1046 if (GetInputMethod()) |
| 1009 GetInputMethod()->SetFocusedTextInputClient(this); | 1047 GetInputMethod()->SetFocusedTextInputClient(this); |
| 1010 OnCaretBoundsChanged(); | 1048 OnCaretBoundsChanged(); |
| 1011 if (ShouldBlinkCursor()) | 1049 if (ShouldBlinkCursor()) |
| 1012 StartBlinkingCursor(); | 1050 StartBlinkingCursor(); |
| 1013 if (use_focus_ring_) { | 1051 if (use_focus_ring_) { |
| 1014 FocusRing::Install(this, invalid_ | 1052 FocusRing::Install(this, invalid_ |
| 1015 ? ui::NativeTheme::kColorId_AlertSeverityHigh | 1053 ? ui::NativeTheme::kColorId_AlertSeverityHigh |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 1041 gfx::Point Textfield::GetKeyboardContextMenuLocation() { | 1079 gfx::Point Textfield::GetKeyboardContextMenuLocation() { |
| 1042 return GetCaretBounds().bottom_right(); | 1080 return GetCaretBounds().bottom_right(); |
| 1043 } | 1081 } |
| 1044 | 1082 |
| 1045 void Textfield::OnNativeThemeChanged(const ui::NativeTheme* theme) { | 1083 void Textfield::OnNativeThemeChanged(const ui::NativeTheme* theme) { |
| 1046 gfx::RenderText* render_text = GetRenderText(); | 1084 gfx::RenderText* render_text = GetRenderText(); |
| 1047 render_text->SetColor(GetTextColor()); | 1085 render_text->SetColor(GetTextColor()); |
| 1048 UpdateBackgroundColor(); | 1086 UpdateBackgroundColor(); |
| 1049 render_text->set_cursor_color(GetTextColor()); | 1087 render_text->set_cursor_color(GetTextColor()); |
| 1050 render_text->set_selection_color(GetSelectionTextColor()); | 1088 render_text->set_selection_color(GetSelectionTextColor()); |
| 1051 render_text->set_selection_background_focused_color( | 1089 if (HasFocus()) { |
| 1052 GetSelectionBackgroundColor()); | 1090 render_text->set_selection_background_color(GetSelectionBackgroundColor()); |
| 1091 } else { | |
| 1092 render_text->set_selection_background_color( | |
| 1093 GetUnfocusedSelectionBackgroundColor()); | |
| 1094 } | |
| 1053 } | 1095 } |
| 1054 | 1096 |
| 1055 //////////////////////////////////////////////////////////////////////////////// | 1097 //////////////////////////////////////////////////////////////////////////////// |
| 1056 // Textfield, TextfieldModel::Delegate overrides: | 1098 // Textfield, TextfieldModel::Delegate overrides: |
| 1057 | 1099 |
| 1058 void Textfield::OnCompositionTextConfirmedOrCleared() { | 1100 void Textfield::OnCompositionTextConfirmedOrCleared() { |
| 1059 if (!skip_input_method_cancel_composition_) | 1101 if (!skip_input_method_cancel_composition_) |
| 1060 GetInputMethod()->CancelComposition(this); | 1102 GetInputMethod()->CancelComposition(this); |
| 1061 } | 1103 } |
| 1062 | 1104 |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1119 return drag_operations; | 1161 return drag_operations; |
| 1120 } | 1162 } |
| 1121 | 1163 |
| 1122 bool Textfield::CanStartDragForView(View* sender, | 1164 bool Textfield::CanStartDragForView(View* sender, |
| 1123 const gfx::Point& press_pt, | 1165 const gfx::Point& press_pt, |
| 1124 const gfx::Point& p) { | 1166 const gfx::Point& p) { |
| 1125 return initiating_drag_ && GetRenderText()->IsPointInSelection(press_pt); | 1167 return initiating_drag_ && GetRenderText()->IsPointInSelection(press_pt); |
| 1126 } | 1168 } |
| 1127 | 1169 |
| 1128 //////////////////////////////////////////////////////////////////////////////// | 1170 //////////////////////////////////////////////////////////////////////////////// |
| 1171 // Textfield, FocusChangeListener overrides: | |
| 1172 | |
| 1173 void Textfield::OnWillChangeFocus(View* focus_before, View* focus_after) { | |
| 1174 // If this was the last focused View before switching Widgets, draw the text | |
| 1175 // selection grayed out. | |
| 1176 if (focus_before == this && focus_after == nullptr) { | |
| 1177 GetRenderText()->set_selection_background_color( | |
| 1178 GetUnfocusedSelectionBackgroundColor()); | |
| 1179 GetRenderText()->set_draw_text_selection(true); | |
| 1180 } // If another View in the same Widget is focused, don't draw the selection. | |
| 1181 else if (focus_before == this && focus_after != nullptr) { | |
|
tapted
2016/10/24 06:04:16
nit: we usually have the `else` on the same line a
Patti Lor
2016/10/27 00:17:27
Done, thanks!
| |
| 1182 GetRenderText()->set_draw_text_selection(false); | |
| 1183 } // This is focused now, draw the text selection. | |
| 1184 else if (focus_after == this) { | |
| 1185 GetRenderText()->set_draw_text_selection(true); | |
| 1186 } | |
| 1187 } | |
| 1188 | |
| 1189 void Textfield::OnDidChangeFocus(View* focused_before, View* focused_now) {} | |
| 1190 | |
| 1191 // On Windows and Linux, on Widget destruction, Textfields inside a TYPE_CONTROL | |
| 1192 // Widget will be destroyed after the FocusManager. Make sure to remove this | |
|
tapted
2016/10/24 03:11:19
It might be a bug that Mac is different here, or w
Patti Lor
2016/10/27 00:17:27
Yes - OnViewHierarchyChanged will get called befor
| |
| 1193 // Textfield as an observer before the FocusManager is destroyed. | |
| 1194 #if !defined(OS_MACOSX) | |
| 1195 void Textfield::OnFocusManagerDestroying() { | |
| 1196 if (!focus_manager_) | |
| 1197 return; | |
| 1198 | |
| 1199 focus_manager_->RemoveFocusChangeListener(this); | |
| 1200 focus_manager_ = nullptr; | |
| 1201 } | |
| 1202 #endif | |
| 1203 | |
| 1204 //////////////////////////////////////////////////////////////////////////////// | |
| 1129 // Textfield, WordLookupClient overrides: | 1205 // Textfield, WordLookupClient overrides: |
| 1130 | 1206 |
| 1131 bool Textfield::GetDecoratedWordAtPoint(const gfx::Point& point, | 1207 bool Textfield::GetDecoratedWordAtPoint(const gfx::Point& point, |
| 1132 gfx::DecoratedText* decorated_word, | 1208 gfx::DecoratedText* decorated_word, |
| 1133 gfx::Point* baseline_point) { | 1209 gfx::Point* baseline_point) { |
| 1134 return GetRenderText()->GetDecoratedWordAtPoint(point, decorated_word, | 1210 return GetRenderText()->GetDecoratedWordAtPoint(point, decorated_word, |
| 1135 baseline_point); | 1211 baseline_point); |
| 1136 } | 1212 } |
| 1137 | 1213 |
| 1138 //////////////////////////////////////////////////////////////////////////////// | 1214 //////////////////////////////////////////////////////////////////////////////// |
| (...skipping 966 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2105 } | 2181 } |
| 2106 | 2182 |
| 2107 void Textfield::OnCursorBlinkTimerFired() { | 2183 void Textfield::OnCursorBlinkTimerFired() { |
| 2108 DCHECK(ShouldBlinkCursor()); | 2184 DCHECK(ShouldBlinkCursor()); |
| 2109 gfx::RenderText* render_text = GetRenderText(); | 2185 gfx::RenderText* render_text = GetRenderText(); |
| 2110 render_text->set_cursor_visible(!render_text->cursor_visible()); | 2186 render_text->set_cursor_visible(!render_text->cursor_visible()); |
| 2111 RepaintCursor(); | 2187 RepaintCursor(); |
| 2112 } | 2188 } |
| 2113 | 2189 |
| 2114 } // namespace views | 2190 } // namespace views |
| OLD | NEW |