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

Unified 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 DCHECKs. 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 side-by-side diff with in-line comments
Download patch
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())

Powered by Google App Engine
This is Rietveld 408576698