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 2ab27564ee4b4354f377bcfe825d7b0d4949d4b7..7ec42e57aeae82c7cbfc8cf868bdf2467885cc92 100644 |
| --- a/ui/views/controls/textfield/textfield.cc |
| +++ b/ui/views/controls/textfield/textfield.cc |
| @@ -238,6 +238,7 @@ Textfield::Textfield() |
| background_color_(SK_ColorWHITE), |
| selection_text_color_(SK_ColorWHITE), |
| selection_background_color_(SK_ColorBLUE), |
| + focus_manager_(nullptr), |
| placeholder_text_color_(kDefaultPlaceholderTextColor), |
| invalid_(false), |
| text_input_type_(ui::TEXT_INPUT_TYPE_TEXT), |
| @@ -275,6 +276,7 @@ Textfield::~Textfield() { |
| // The textfield should have been blurred before destroy. |
| DCHECK(this != GetInputMethod()->GetTextInputClient()); |
| } |
| + DCHECK(!focus_manager_); |
| } |
| void Textfield::SetReadOnly(bool read_only) { |
| @@ -422,18 +424,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(); |
| } |
| @@ -927,6 +934,30 @@ void Textfield::OnEnabledChanged() { |
| SchedulePaint(); |
| } |
| +void Textfield::ViewHierarchyChanged( |
| + const ViewHierarchyChangedDetails& details) { |
| + // Textfields only care about focus changes if the entire Widget has lost |
| + // focus, so don't bother listening if there is no Widget. |
| + if (!GetWidget()) |
|
tapted
2016/11/02 03:59:14
actually I think this `if` can be omitted. -- we c
Patti Lor
2016/11/07 05:34:26
Done.
tapted
2016/11/07 06:14:50
ping? (this should be redundant with the changes i
Patti Lor
2016/11/08 01:47:31
Oops, thank you - forgot to reapply the latest pat
|
| + return; |
| + |
| + if (details.parent->Contains(this) && details.move_view == nullptr) |
| + AddOrRemoveAsFocusChangeListener(details.is_add); |
| +} |
| + |
| +void Textfield::NativeViewHierarchyChanged() { |
| + if (!GetWidget()) { |
|
tapted
2016/11/02 03:59:14
same here. In fact I think we can just make this e
Patti Lor
2016/11/07 05:34:26
Done.
|
| + focus_manager_ = nullptr; |
| + return; |
| + } |
| + |
| + // Update the focus manager if it's changed. |
| + if (focus_manager_ != GetFocusManager()) { |
| + AddOrRemoveAsFocusChangeListener(false); |
| + AddOrRemoveAsFocusChangeListener(true); |
|
tapted
2016/11/02 03:45:06
I think calling with `true` should always behave a
Patti Lor
2016/11/07 05:34:26
Done.
|
| + } |
| +} |
| + |
| void Textfield::OnPaint(gfx::Canvas* canvas) { |
| OnPaintBackground(canvas); |
| PaintTextAndCursor(canvas); |
| @@ -980,8 +1011,12 @@ 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 { |
| + render_text->set_selection_background_color( |
| + GetUnfocusedSelectionBackgroundColor()); |
| + } |
| } |
| //////////////////////////////////////////////////////////////////////////////// |
| @@ -1058,6 +1093,25 @@ bool Textfield::CanStartDragForView(View* sender, |
| } |
| //////////////////////////////////////////////////////////////////////////////// |
| +// Textfield, FocusChangeListener overrides: |
| + |
| +void Textfield::OnWillChangeFocus(View* focus_before, View* focus_after) { |
| + if (focus_before != this && focus_after != this) |
| + return; |
| + |
| + SkColor selection_bg_color = focus_after |
| + ? GetSelectionBackgroundColor() |
| + : GetUnfocusedSelectionBackgroundColor(); |
| + |
| + // Selection is drawn if |this| has focus, or the Widget loses activation, but |
| + // not if another View in this Widget is gaining focus. |
| + GetRenderText()->set_draw_text_selection(focus_after == this || !focus_after); |
| + GetRenderText()->set_selection_background_color(selection_bg_color); |
| +} |
| + |
| +void Textfield::OnDidChangeFocus(View* focused_before, View* focused_now) {} |
| + |
| +//////////////////////////////////////////////////////////////////////////////// |
| // Textfield, WordLookupClient overrides: |
| bool Textfield::GetDecoratedWordAtPoint(const gfx::Point& point, |
| @@ -1824,6 +1878,19 @@ void Textfield::UpdateSelectionClipboard() { |
| #endif |
| } |
| +void Textfield::AddOrRemoveAsFocusChangeListener(bool add_as_listener) { |
| + if (add_as_listener) { |
| + FocusManager* focus_manager = GetFocusManager(); |
| + if (!focus_manager) |
| + return; |
|
tapted
2016/11/02 03:45:06
Comment when this can occur?
tapted
2016/11/02 03:59:14
(btw, I'm guessing this can occur only when Widget
Patti Lor
2016/11/07 05:34:26
Yeah, this happens when there's a TYPE_CONTROL Wid
|
| + focus_manager_ = focus_manager; |
| + focus_manager_->AddFocusChangeListener(this); |
| + } else if (focus_manager_) { |
|
tapted
2016/11/02 03:45:06
I think this block can just go at the start of the
Patti Lor
2016/11/07 05:34:26
Done.
|
| + focus_manager_->RemoveFocusChangeListener(this); |
| + focus_manager_ = nullptr; |
| + } |
| +} |
| + |
| void Textfield::AccessibilitySetValue(const base::string16& new_value, |
| bool clear_first) { |
| if (read_only()) |