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

Side by Side Diff: ui/views/controls/menu/menu_controller.cc

Issue 1661673004: Enables hot-tracking for overflow extension buttons in the app menu (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Restores hot-tracking of extension buttons in app menu with MD (comments) Created 4 years, 10 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 unified diff | Download patch
OLDNEW
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/menu/menu_controller.h" 5 #include "ui/views/controls/menu/menu_controller.h"
6 6
7 #include "base/i18n/case_conversion.h" 7 #include "base/i18n/case_conversion.h"
8 #include "base/i18n/rtl.h" 8 #include "base/i18n/rtl.h"
9 #include "base/macros.h" 9 #include "base/macros.h"
10 #include "base/strings/utf_string_conversions.h" 10 #include "base/strings/utf_string_conversions.h"
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
63 // that the finger does not obscure the menu. 63 // that the finger does not obscure the menu.
64 static const int kCenteredContextMenuYOffset = -15; 64 static const int kCenteredContextMenuYOffset = -15;
65 65
66 namespace views { 66 namespace views {
67 67
68 namespace { 68 namespace {
69 69
70 // When showing context menu on mouse down, the user might accidentally select 70 // When showing context menu on mouse down, the user might accidentally select
71 // the menu item on the subsequent mouse up. To prevent this, we add the 71 // the menu item on the subsequent mouse up. To prevent this, we add the
72 // following delay before the user is able to select an item. 72 // following delay before the user is able to select an item.
73 static int menu_selection_hold_time_ms = kMinimumMsPressedToActivate; 73 static int menu_selection_hold_time_ms = kMinimumMsPressedToActivate;
Peter Kasting 2016/02/16 21:36:15 Nit: While here: Can you remove the unnecessary "s
varkha 2016/02/17 17:52:00 Done. I have also moved other constants into the a
74 74
75 // The spacing offset for the bubble tip. 75 // The spacing offset for the bubble tip.
76 const int kBubbleTipSizeLeftRight = 12; 76 const int kBubbleTipSizeLeftRight = 12;
77 const int kBubbleTipSizeTopBottom = 11; 77 const int kBubbleTipSizeTopBottom = 11;
78 78
79 // The maximum distance (in DIPS) that the mouse can be moved before it should 79 // The maximum distance (in DIPS) that the mouse can be moved before it should
80 // trigger a mouse menu item activation (regardless of how long the menu has 80 // trigger a mouse menu item activation (regardless of how long the menu has
81 // been showing). 81 // been showing).
82 const float kMaximumLengthMovedToActivate = 4.0f; 82 const float kMaximumLengthMovedToActivate = 4.0f;
83 83
(...skipping 23 matching lines...) Expand all
107 } 107 }
108 108
109 for (int i = 0; i < view->child_count(); ++i) { 109 for (int i = 0; i < view->child_count(); ++i) {
110 CustomButton* hot_view = GetFirstHotTrackedView(view->child_at(i)); 110 CustomButton* hot_view = GetFirstHotTrackedView(view->child_at(i));
111 if (hot_view) 111 if (hot_view)
112 return hot_view; 112 return hot_view;
113 } 113 }
114 return NULL; 114 return NULL;
115 } 115 }
116 116
117 CustomButton* OtherHotTrackedButton(View* view, CustomButton* hot_button) {
Peter Kasting 2016/02/16 21:36:15 Nit: Add comment explaining what this function doe
varkha 2016/02/17 17:52:00 Done, PTAL if this is OK.
118 if (!view)
119 return nullptr;
120 CustomButton* button = CustomButton::AsCustomButton(view);
121 if (button && button != hot_button && button->IsHotTracked())
122 return button;
123
124 for (int i = 0; i < view->child_count(); ++i) {
125 button = OtherHotTrackedButton(view->child_at(i), hot_button);
126 if (button)
127 return button;
128 }
129 return nullptr;
130 }
131
117 // Recurses through the child views of |view| returning the first view starting 132 // Recurses through the child views of |view| returning the first view starting
118 // at |start| that is focusable. A value of -1 for |start| indicates to start at 133 // at |start| that is focusable. A value of -1 for |start| indicates to start at
119 // the first view (if |forward| is false, iterating starts at the last view). If 134 // the first view (if |forward| is false, iterating starts at the last view). If
120 // |forward| is true the children are considered first to last, otherwise last 135 // |forward| is true the children are considered first to last, otherwise last
121 // to first. 136 // to first.
122 static View* GetFirstFocusableView(View* view, int start, bool forward) { 137 static View* GetFirstFocusableView(View* view, int start, bool forward) {
123 if (forward) { 138 if (forward) {
124 for (int i = start == -1 ? 0 : start; i < view->child_count(); ++i) { 139 for (int i = start == -1 ? 0 : start; i < view->child_count(); ++i) {
125 View* deepest = GetFirstFocusableView(view->child_at(i), -1, forward); 140 View* deepest = GetFirstFocusableView(view->child_at(i), -1, forward);
126 if (deepest) 141 if (deepest)
(...skipping 805 matching lines...) Expand 10 before | Expand all | Expand 10 after
932 BuildPathsAndCalculateDiff(pending_state_.item, menu_item, &current_path, 947 BuildPathsAndCalculateDiff(pending_state_.item, menu_item, &current_path,
933 &new_path, &paths_differ_at); 948 &new_path, &paths_differ_at);
934 949
935 size_t current_size = current_path.size(); 950 size_t current_size = current_path.size();
936 size_t new_size = new_path.size(); 951 size_t new_size = new_path.size();
937 952
938 bool pending_item_changed = pending_state_.item != menu_item; 953 bool pending_item_changed = pending_state_.item != menu_item;
939 if (pending_item_changed && pending_state_.item) { 954 if (pending_item_changed && pending_state_.item) {
940 CustomButton* button = GetFirstHotTrackedView(pending_state_.item); 955 CustomButton* button = GetFirstHotTrackedView(pending_state_.item);
941 if (button) 956 if (button)
942 button->SetHotTracked(false); 957 SetHotTrackedButton(button, false);
958 }
959 CustomButton* new_hot_button = OtherHotTrackedButton(menu_item, hot_button_);
960 if (new_hot_button) {
961 if (hot_button_)
962 SetHotTrackedButton(hot_button_, false);
963 SetHotTrackedButton(new_hot_button, true);
943 } 964 }
944 965
945 // Notify the old path it isn't selected. 966 // Notify the old path it isn't selected.
946 MenuDelegate* current_delegate = 967 MenuDelegate* current_delegate =
947 current_path.empty() ? NULL : current_path.front()->GetDelegate(); 968 current_path.empty() ? NULL : current_path.front()->GetDelegate();
948 for (size_t i = paths_differ_at; i < current_size; ++i) { 969 for (size_t i = paths_differ_at; i < current_size; ++i) {
949 if (current_delegate && 970 if (current_delegate &&
950 current_path[i]->GetType() == MenuItemView::SUBMENU) { 971 current_path[i]->GetType() == MenuItemView::SUBMENU) {
951 current_delegate->WillHideMenu(current_path[i]); 972 current_delegate->WillHideMenu(current_path[i]);
952 } 973 }
(...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after
1184 drop_target_(NULL), 1205 drop_target_(NULL),
1185 drop_position_(MenuDelegate::DROP_UNKNOWN), 1206 drop_position_(MenuDelegate::DROP_UNKNOWN),
1186 owner_(NULL), 1207 owner_(NULL),
1187 possible_drag_(false), 1208 possible_drag_(false),
1188 drag_in_progress_(false), 1209 drag_in_progress_(false),
1189 did_initiate_drag_(false), 1210 did_initiate_drag_(false),
1190 valid_drop_coordinates_(false), 1211 valid_drop_coordinates_(false),
1191 last_drop_operation_(MenuDelegate::DROP_UNKNOWN), 1212 last_drop_operation_(MenuDelegate::DROP_UNKNOWN),
1192 showing_submenu_(false), 1213 showing_submenu_(false),
1193 active_mouse_view_id_(ViewStorage::GetInstance()->CreateStorageID()), 1214 active_mouse_view_id_(ViewStorage::GetInstance()->CreateStorageID()),
1215 hot_button_(nullptr),
1194 delegate_(delegate), 1216 delegate_(delegate),
1195 message_loop_depth_(0), 1217 message_loop_depth_(0),
1196 closing_event_time_(base::TimeDelta()), 1218 closing_event_time_(base::TimeDelta()),
1197 menu_start_time_(base::TimeTicks()), 1219 menu_start_time_(base::TimeTicks()),
1198 async_run_(false), 1220 async_run_(false),
1199 is_combobox_(false), 1221 is_combobox_(false),
1200 item_selected_by_touch_(false), 1222 item_selected_by_touch_(false),
1201 current_mouse_event_target_(nullptr), 1223 current_mouse_event_target_(nullptr),
1202 current_mouse_pressed_state_(0), 1224 current_mouse_pressed_state_(0),
1203 message_loop_(MenuMessageLoop::Create()) { 1225 message_loop_(MenuMessageLoop::Create()) {
(...skipping 15 matching lines...) Expand all
1219 message_loop_->Run(this, owner_, nested_menu); 1241 message_loop_->Run(this, owner_, nested_menu);
1220 } 1242 }
1221 1243
1222 bool MenuController::SendAcceleratorToHotTrackedView() { 1244 bool MenuController::SendAcceleratorToHotTrackedView() {
1223 CustomButton* hot_view = GetFirstHotTrackedView(pending_state_.item); 1245 CustomButton* hot_view = GetFirstHotTrackedView(pending_state_.item);
1224 if (!hot_view) 1246 if (!hot_view)
1225 return false; 1247 return false;
1226 1248
1227 ui::Accelerator accelerator(ui::VKEY_RETURN, ui::EF_NONE); 1249 ui::Accelerator accelerator(ui::VKEY_RETURN, ui::EF_NONE);
1228 hot_view->AcceleratorPressed(accelerator); 1250 hot_view->AcceleratorPressed(accelerator);
1229 CustomButton* button = static_cast<CustomButton*>(hot_view); 1251 SetHotTrackedButton(hot_view, true);
1230 button->SetHotTracked(true);
1231 return true; 1252 return true;
1232 } 1253 }
1233 1254
1234 void MenuController::UpdateInitialLocation(const gfx::Rect& bounds, 1255 void MenuController::UpdateInitialLocation(const gfx::Rect& bounds,
1235 MenuAnchorPosition position, 1256 MenuAnchorPosition position,
1236 bool context_menu) { 1257 bool context_menu) {
1237 pending_state_.context_menu = context_menu; 1258 pending_state_.context_menu = context_menu;
1238 pending_state_.initial_bounds = bounds; 1259 pending_state_.initial_bounds = bounds;
1239 if (bounds.height() > 1) { 1260 if (bounds.height() > 1) {
1240 // Inset the bounds slightly, otherwise drag coordinates don't line up 1261 // Inset the bounds slightly, otherwise drag coordinates don't line up
(...skipping 741 matching lines...) Expand 10 before | Expand all | Expand 10 after
1982 void MenuController::IncrementSelection( 2003 void MenuController::IncrementSelection(
1983 SelectionIncrementDirectionType direction) { 2004 SelectionIncrementDirectionType direction) {
1984 MenuItemView* item = pending_state_.item; 2005 MenuItemView* item = pending_state_.item;
1985 DCHECK(item); 2006 DCHECK(item);
1986 if (pending_state_.submenu_open && item->HasSubmenu() && 2007 if (pending_state_.submenu_open && item->HasSubmenu() &&
1987 item->GetSubmenu()->IsShowing()) { 2008 item->GetSubmenu()->IsShowing()) {
1988 // A menu is selected and open, but none of its children are selected, 2009 // A menu is selected and open, but none of its children are selected,
1989 // select the first menu item that is visible and enabled. 2010 // select the first menu item that is visible and enabled.
1990 if (item->GetSubmenu()->GetMenuItemCount()) { 2011 if (item->GetSubmenu()->GetMenuItemCount()) {
1991 MenuItemView* to_select = FindInitialSelectableMenuItem(item, direction); 2012 MenuItemView* to_select = FindInitialSelectableMenuItem(item, direction);
1992 if (to_select) 2013 SetInitialHotTrackedView(to_select, direction);
1993 SetSelection(to_select, SELECTION_DEFAULT);
1994 return; 2014 return;
1995 } 2015 }
1996 } 2016 }
1997 2017
1998 if (item->has_children()) { 2018 if (item->has_children()) {
1999 CustomButton* button = GetFirstHotTrackedView(item); 2019 CustomButton* button = GetFirstHotTrackedView(item);
2000 if (button) { 2020 if (button) {
2001 button->SetHotTracked(false); 2021 SetHotTrackedButton(button, false);
2002 View* to_make_hot = GetNextFocusableView( 2022 View* hot_view = GetNextFocusableView(
2003 item, button, direction == INCREMENT_SELECTION_DOWN); 2023 item, button, direction == INCREMENT_SELECTION_DOWN);
2004 CustomButton* button_hot = CustomButton::AsCustomButton(to_make_hot); 2024 CustomButton* hot_button = CustomButton::AsCustomButton(hot_view);
2005 if (button_hot) { 2025 if (hot_button) {
2006 button_hot->SetHotTracked(true); 2026 SetHotTrackedButton(hot_button, true);
2007 return; 2027 return;
2008 } 2028 }
2009 } else { 2029 } else {
2010 View* to_make_hot = 2030 View* hot_view =
2011 GetInitialFocusableView(item, direction == INCREMENT_SELECTION_DOWN); 2031 GetInitialFocusableView(item, direction == INCREMENT_SELECTION_DOWN);
2012 CustomButton* button_hot = CustomButton::AsCustomButton(to_make_hot); 2032 CustomButton* hot_button = CustomButton::AsCustomButton(hot_view);
2013 if (button_hot) { 2033 if (hot_button) {
2014 button_hot->SetHotTracked(true); 2034 SetHotTrackedButton(hot_button, true);
2015 return; 2035 return;
2016 } 2036 }
2017 } 2037 }
2018 } 2038 }
2019 2039
2020 MenuItemView* parent = item->GetParentMenuItem(); 2040 MenuItemView* parent = item->GetParentMenuItem();
2021 if (parent) { 2041 if (parent) {
2022 int parent_count = parent->GetSubmenu()->GetMenuItemCount(); 2042 int parent_count = parent->GetSubmenu()->GetMenuItemCount();
2023 if (parent_count > 1) { 2043 if (parent_count > 1) {
2024 for (int i = 0; i < parent_count; ++i) { 2044 for (int i = 0; i < parent_count; ++i) {
2025 if (parent->GetSubmenu()->GetMenuItemAt(i) == item) { 2045 if (parent->GetSubmenu()->GetMenuItemAt(i) == item) {
2026 MenuItemView* to_select = 2046 MenuItemView* to_select =
2027 FindNextSelectableMenuItem(parent, i, direction); 2047 FindNextSelectableMenuItem(parent, i, direction);
2028 if (!to_select) 2048 SetInitialHotTrackedView(to_select, direction);
2029 break;
2030 SetSelection(to_select, SELECTION_DEFAULT);
2031 View* to_make_hot = GetInitialFocusableView(
2032 to_select, direction == INCREMENT_SELECTION_DOWN);
2033 CustomButton* button_hot = CustomButton::AsCustomButton(to_make_hot);
2034 if (button_hot)
2035 button_hot->SetHotTracked(true);
2036 break; 2049 break;
2037 } 2050 }
2038 } 2051 }
2039 } 2052 }
2040 } 2053 }
2041 } 2054 }
2042 2055
2043 MenuItemView* MenuController::FindInitialSelectableMenuItem( 2056 MenuItemView* MenuController::FindInitialSelectableMenuItem(
2044 MenuItemView* parent, 2057 MenuItemView* parent,
2045 SelectionIncrementDirectionType direction) { 2058 SelectionIncrementDirectionType direction) {
(...skipping 544 matching lines...) Expand 10 before | Expand all | Expand 10 after
2590 pending_state_.item->GetParentMenuItem() && 2603 pending_state_.item->GetParentMenuItem() &&
2591 (!pending_state_.item->HasSubmenu() || 2604 (!pending_state_.item->HasSubmenu() ||
2592 !pending_state_.item->GetSubmenu()->IsShowing())) { 2605 !pending_state_.item->GetSubmenu()->IsShowing())) {
2593 // On exit if the user hasn't selected an item with a submenu, move the 2606 // On exit if the user hasn't selected an item with a submenu, move the
2594 // selection back to the parent menu item. 2607 // selection back to the parent menu item.
2595 SetSelection(pending_state_.item->GetParentMenuItem(), 2608 SetSelection(pending_state_.item->GetParentMenuItem(),
2596 SELECTION_OPEN_SUBMENU); 2609 SELECTION_OPEN_SUBMENU);
2597 } 2610 }
2598 } 2611 }
2599 2612
2613 void MenuController::SetHotTrackedButton(CustomButton* hot_button,
2614 bool is_hot_tracked) {
2615 DCHECK(hot_button);
2616 hot_button->SetHotTracked(is_hot_tracked);
2617 DCHECK(is_hot_tracked || (hot_button_ == hot_button));
2618 hot_button_ = is_hot_tracked ? hot_button : nullptr;
2619 }
2620
2621 void MenuController::SetInitialHotTrackedView(
2622 MenuItemView* item,
2623 SelectionIncrementDirectionType direction) {
2624 if (!item)
2625 return;
2626 SetSelection(item, SELECTION_DEFAULT);
2627 View* hot_view =
2628 GetInitialFocusableView(item, direction == INCREMENT_SELECTION_DOWN);
2629 CustomButton* hot_button = CustomButton::AsCustomButton(hot_view);
2630 if (hot_button)
2631 SetHotTrackedButton(hot_button, true);
2632 return;
Peter Kasting 2016/02/16 21:36:15 Nit: Unnecessary statement
varkha 2016/02/17 17:52:00 Done.
2633 }
2634
2600 } // namespace views 2635 } // namespace views
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698