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

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 focus changing to other Views. Created 4 years, 2 months 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 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)
« ui/views/controls/textfield/textfield.h ('K') | « ui/views/controls/textfield/textfield.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698