Chromium Code Reviews| Index: ui/views/controls/textfield/textfield.cc |
| diff --git a/ui/views/controls/textfield/textfield.cc b/ui/views/controls/textfield/textfield.cc |
| index 107bea8e0249824f2ad2639d1bceadab55bd6502..f0202410ffcb519cecf71d5d8d549b04bf5d3918 100644 |
| --- a/ui/views/controls/textfield/textfield.cc |
| +++ b/ui/views/controls/textfield/textfield.cc |
| @@ -251,6 +251,7 @@ Textfield::Textfield() |
| background_color_(SK_ColorWHITE), |
| selection_text_color_(SK_ColorWHITE), |
| selection_background_color_(SK_ColorBLUE), |
| + change_selection_background_color_on_next_blur_(false), |
| placeholder_text_color_(kDefaultPlaceholderTextColor), |
| text_input_type_(ui::TEXT_INPUT_TYPE_TEXT), |
| text_input_flags_(0), |
| @@ -278,6 +279,10 @@ Textfield::Textfield() |
| } |
| Textfield::~Textfield() { |
| + FocusManager* focus_manager = GetFocusManager(); |
|
tapted
2016/10/13 06:21:35
comment why this might be null?
Patti Lor
2016/10/24 02:43:17
Done.
|
| + if (focus_manager) |
| + focus_manager->RemoveFocusChangeListener(this); |
| + |
| if (GetInputMethod()) { |
| // The textfield should have been blurred before destroy. |
| DCHECK(this != GetInputMethod()->GetTextInputClient()); |
| @@ -428,18 +433,23 @@ SkColor Textfield::GetSelectionBackgroundColor() const { |
| void Textfield::SetSelectionBackgroundColor(SkColor color) { |
| selection_background_color_ = color; |
| use_default_selection_background_color_ = false; |
| - GetRenderText()->set_selection_background_focused_color( |
| + GetRenderText()->set_selection_background_color( |
| GetSelectionBackgroundColor()); |
| SchedulePaint(); |
| } |
| void Textfield::UseDefaultSelectionBackgroundColor() { |
| use_default_selection_background_color_ = true; |
| - GetRenderText()->set_selection_background_focused_color( |
| + GetRenderText()->set_selection_background_color( |
| GetSelectionBackgroundColor()); |
| SchedulePaint(); |
| } |
| +SkColor Textfield::GetUnfocusedSelectionBackgroundColor() const { |
| + return GetNativeTheme()->GetSystemColor( |
| + ui::NativeTheme::kColorId_TextfieldSelectionBackgroundUnfocused); |
| +} |
| + |
| bool Textfield::GetCursorEnabled() const { |
| return GetRenderText()->cursor_enabled(); |
| } |
| @@ -536,7 +546,7 @@ bool Textfield::HasTextBeingDragged() { |
| } |
| //////////////////////////////////////////////////////////////////////////////// |
| -// Textfield, View overrides: |
| +// Textfield, View: |
| gfx::Insets Textfield::GetInsets() const { |
| gfx::Insets insets = View::GetInsets(); |
| @@ -586,10 +596,18 @@ bool Textfield::OnMousePressed(const ui::MouseEvent& event) { |
| initiating_drag_ = false; |
| switch (aggregated_clicks_) { |
| case 0: |
| - if (GetRenderText()->IsPointInSelection(event.location())) |
| + if (GetRenderText()->IsPointInSelection(event.location())) { |
| initiating_drag_ = true; |
| - else |
| + // If this isn't actually a mouse drag (determined later in |
| + // OnMouseReleased()), the selection should be cleared before being |
| + // drawn. But if it does turn out to be a mouse drag (determined |
| + // later in OnMouseDragged()), the selection needs to be kept for |
| + // dragging. Don't draw the text selection til it's known for sure. |
| + if (!GetSelectedRange().is_empty()) |
| + GetRenderText()->set_draw_text_selection(false); |
| + } else { |
| MoveCursorTo(event.location(), event.IsShiftDown()); |
| + } |
| break; |
| case 1: |
| SelectWordAt(event.location()); |
| @@ -624,6 +642,9 @@ bool Textfield::OnMousePressed(const ui::MouseEvent& event) { |
| bool Textfield::OnMouseDragged(const ui::MouseEvent& event) { |
| last_drag_location_ = event.location(); |
| + // Follow up from setting this to false in OnMousePressed() - it's safe to |
| + // draw the selection now that it's determined this is a drag. |
| + GetRenderText()->set_draw_text_selection(true); |
| // Don't adjust the cursor on a potential drag and drop. |
| if (initiating_drag_ || !event.IsOnlyLeftMouseButton()) |
| @@ -650,8 +671,12 @@ void Textfield::OnMouseReleased(const ui::MouseEvent& event) { |
| OnBeforeUserAction(); |
| drag_selection_timer_.Stop(); |
| // Cancel suspected drag initiations, the user was clicking in the selection. |
| - if (initiating_drag_) |
| + if (initiating_drag_) { |
| MoveCursorTo(event.location(), false); |
| + // Follow up from setting this to false in OnMousePressed() - it's safe to |
| + // draw the selection now that it's determined this is just a click. |
| + GetRenderText()->set_draw_text_selection(true); |
| + } |
| initiating_drag_ = false; |
| UpdateSelectionClipboard(); |
| OnAfterUserAction(); |
| @@ -981,6 +1006,18 @@ void Textfield::OnEnabledChanged() { |
| SchedulePaint(); |
| } |
| +void Textfield::ViewHierarchyChanged( |
| + const ViewHierarchyChangedDetails& details) { |
| + FocusManager* focus_manager = GetFocusManager(); |
| + if (details.parent->Contains(this) && details.move_view == nullptr && |
| + focus_manager) { |
| + if (details.is_add) |
| + focus_manager->AddFocusChangeListener(this); |
| + else |
| + focus_manager->RemoveFocusChangeListener(this); |
| + } |
| +} |
| + |
| void Textfield::OnPaint(gfx::Canvas* canvas) { |
| OnPaintBackground(canvas); |
| PaintTextAndCursor(canvas); |
| @@ -989,6 +1026,8 @@ void Textfield::OnPaint(gfx::Canvas* canvas) { |
| void Textfield::OnFocus() { |
| GetRenderText()->set_focused(true); |
| + GetRenderText()->set_selection_background_color( |
| + GetSelectionBackgroundColor()); |
| if (ShouldShowCursor()) |
| GetRenderText()->set_cursor_visible(true); |
| if (GetInputMethod()) |
| @@ -1013,6 +1052,15 @@ void Textfield::OnBlur() { |
| RepaintCursor(); |
| } |
| + if (change_selection_background_color_on_next_blur_) { |
| + // This being set means the entire Widget has now lost focus. Check that. |
| + DCHECK(GetFocusManager()->GetFocusedView() == nullptr); |
| + change_selection_background_color_on_next_blur_ = false; |
| + GetRenderText()->set_selection_background_color( |
| + GetUnfocusedSelectionBackgroundColor()); |
| + GetRenderText()->set_draw_text_selection(true); |
| + } |
| + |
| DestroyTouchSelection(); |
| if (use_focus_ring_) |
| @@ -1031,12 +1079,15 @@ void Textfield::OnNativeThemeChanged(const ui::NativeTheme* theme) { |
| UpdateBackgroundColor(); |
| render_text->set_cursor_color(GetTextColor()); |
| render_text->set_selection_color(GetSelectionTextColor()); |
| - render_text->set_selection_background_focused_color( |
| - GetSelectionBackgroundColor()); |
| + if (HasFocus()) |
| + render_text->set_selection_background_color(GetSelectionBackgroundColor()); |
| + else |
|
tapted
2016/10/13 06:21:35
needs curlies (both parts)
Patti Lor
2016/10/24 02:43:17
Done.
|
| + render_text->set_selection_background_color( |
| + GetUnfocusedSelectionBackgroundColor()); |
| } |
| //////////////////////////////////////////////////////////////////////////////// |
| -// Textfield, TextfieldModel::Delegate overrides: |
| +// Textfield, TextfieldModel::Delegate: |
| void Textfield::OnCompositionTextConfirmedOrCleared() { |
| if (!skip_input_method_cancel_composition_) |
| @@ -1044,7 +1095,7 @@ void Textfield::OnCompositionTextConfirmedOrCleared() { |
| } |
| //////////////////////////////////////////////////////////////////////////////// |
| -// Textfield, ContextMenuController overrides: |
| +// Textfield, ContextMenuController: |
| void Textfield::ShowContextMenuForView(View* source, |
| const gfx::Point& point, |
| @@ -1058,7 +1109,7 @@ void Textfield::ShowContextMenuForView(View* source, |
| } |
| //////////////////////////////////////////////////////////////////////////////// |
| -// Textfield, DragController overrides: |
| +// Textfield, DragController: |
| void Textfield::WriteDragDataForView(View* sender, |
| const gfx::Point& press_pt, |
| @@ -1109,6 +1160,24 @@ bool Textfield::CanStartDragForView(View* sender, |
| } |
| //////////////////////////////////////////////////////////////////////////////// |
| +// Textfield, FocusChangeListener: |
| + |
| +void Textfield::OnWillChangeFocus(View* focus_before, View* focus_after) { |
| + // If this was the last focused View before switching Widgets, draw the text |
| + // selection grayed out. |
| + if (focus_before == this && focus_after == nullptr) |
| + change_selection_background_color_on_next_blur_ = true; |
|
tapted
2016/10/13 06:21:35
what happens if we try to gray it out immediately?
Patti Lor
2016/10/24 02:43:17
Ah, I think that variable was there from your sugg
|
| + // If another View in the same widget is focused, don't draw the selection. |
| + else if (focus_before == this && focus_after != nullptr) |
|
tapted
2016/10/13 06:21:35
needs curlies due to comments
Patti Lor
2016/10/24 02:43:17
Done.
|
| + GetRenderText()->set_draw_text_selection(false); |
| + // This is focused now, draw the text selection. |
| + else if (focus_after == this) |
| + GetRenderText()->set_draw_text_selection(true); |
| +} |
| + |
| +void Textfield::OnDidChangeFocus(View* focused_before, View* focused_now) {} |
| + |
| +//////////////////////////////////////////////////////////////////////////////// |
| // Textfield, WordLookupClient overrides: |
| bool Textfield::GetDecoratedWordAtPoint(const gfx::Point& point, |
| @@ -1119,7 +1188,7 @@ bool Textfield::GetDecoratedWordAtPoint(const gfx::Point& point, |
| } |
| //////////////////////////////////////////////////////////////////////////////// |
| -// Textfield, ui::TouchEditable overrides: |
| +// Textfield, ui::TouchEditable: |
| void Textfield::SelectRect(const gfx::Point& start, const gfx::Point& end) { |
| if (GetTextInputType() == ui::TEXT_INPUT_TYPE_NONE) |
| @@ -1202,7 +1271,7 @@ void Textfield::DestroyTouchSelection() { |
| } |
| //////////////////////////////////////////////////////////////////////////////// |
| -// Textfield, ui::SimpleMenuModel::Delegate overrides: |
| +// Textfield, ui::SimpleMenuModel::Delegate: |
| bool Textfield::IsCommandIdChecked(int command_id) const { |
| return true; |
| @@ -1247,7 +1316,7 @@ void Textfield::ExecuteCommand(int command_id, int event_flags) { |
| } |
| //////////////////////////////////////////////////////////////////////////////// |
| -// Textfield, ui::TextInputClient overrides: |
| +// Textfield, ui::TextInputClient: |
| void Textfield::SetCompositionText(const ui::CompositionText& composition) { |
| if (GetTextInputType() == ui::TEXT_INPUT_TYPE_NONE) |