Commit 09b0ad28 authored by Jess Zeisloft's avatar Jess Zeisloft Committed by Commit Bot

Turn off highlight of MenuItemView when mouse exits on a drag

Modified MenuController::OnMouseDragged to turn off highlight of a
MenuItemView when the mouse exits on a drag. This fixes a small visual
bug where the highlight would turn off when the mouse was released and
subsequently moved.

Bug: 553438
Change-Id: Ib6448954870d8709af222d30f4c431036bdfb975
Reviewed-on: https://chromium-review.googlesource.com/550261
Commit-Queue: Jess Zeisloft <jzeisloft@google.com>
Reviewed-by: default avatarSadrul Chowdhury <sadrul@chromium.org>
Reviewed-by: default avatarJonathan Ross <jonross@chromium.org>
Cr-Commit-Position: refs/heads/master@{#487264}
parent d252c196
...@@ -627,7 +627,17 @@ bool MenuController::OnMouseDragged(SubmenuView* source, ...@@ -627,7 +627,17 @@ bool MenuController::OnMouseDragged(SubmenuView* source,
SetSelection(part.menu ? part.menu : state_.item, SELECTION_OPEN_SUBMENU); SetSelection(part.menu ? part.menu : state_.item, SELECTION_OPEN_SUBMENU);
} }
} else if (part.type == MenuPart::NONE) { } else if (part.type == MenuPart::NONE) {
ShowSiblingMenu(source, event.location()); // If there is a sibling menu, show it. Otherwise, if the user has selected
// a menu item with no accompanying sibling menu or submenu, move selection
// back to the parent menu item.
if (!ShowSiblingMenu(source, event.location())) {
if (!part.is_scroll() && pending_state_.item &&
pending_state_.item->GetParentMenuItem() &&
!pending_state_.item->SubmenuIsShowing()) {
SetSelection(pending_state_.item->GetParentMenuItem(),
SELECTION_OPEN_SUBMENU);
}
}
} }
UpdateActiveMouseView(source, event, mouse_menu); UpdateActiveMouseView(source, event, mouse_menu);
...@@ -1329,8 +1339,7 @@ void MenuController::OnKeyDown(ui::KeyboardCode key_code) { ...@@ -1329,8 +1339,7 @@ void MenuController::OnKeyDown(ui::KeyboardCode key_code) {
case ui::VKEY_ESCAPE: case ui::VKEY_ESCAPE:
if (!state_.item->GetParentMenuItem() || if (!state_.item->GetParentMenuItem() ||
(!state_.item->GetParentMenuItem()->GetParentMenuItem() && (!state_.item->GetParentMenuItem()->GetParentMenuItem() &&
(!state_.item->HasSubmenu() || (!state_.item->SubmenuIsShowing()))) {
!state_.item->GetSubmenu()->IsShowing()))) {
// User pressed escape and current menu has no submenus. If we are // User pressed escape and current menu has no submenus. If we are
// nested, close the current menu on the stack. Otherwise fully exit the // nested, close the current menu on the stack. Otherwise fully exit the
// menu. // menu.
...@@ -1633,7 +1642,7 @@ MenuController::MenuPart MenuController::GetMenuPartByScreenCoordinateUsingMenu( ...@@ -1633,7 +1642,7 @@ MenuController::MenuPart MenuController::GetMenuPartByScreenCoordinateUsingMenu(
const gfx::Point& screen_loc) { const gfx::Point& screen_loc) {
MenuPart part; MenuPart part;
for (; item; item = item->GetParentMenuItem()) { for (; item; item = item->GetParentMenuItem()) {
if (item->HasSubmenu() && item->GetSubmenu()->IsShowing() && if (item->SubmenuIsShowing() &&
GetMenuPartByScreenCoordinateImpl(item->GetSubmenu(), screen_loc, GetMenuPartByScreenCoordinateImpl(item->GetSubmenu(), screen_loc,
&part)) { &part)) {
return part; return part;
...@@ -1764,8 +1773,7 @@ void MenuController::CommitPendingSelection() { ...@@ -1764,8 +1773,7 @@ void MenuController::CommitPendingSelection() {
} else { } else {
state_.submenu_open = false; state_.submenu_open = false;
} }
} else if (state_.item->HasSubmenu() && } else if (state_.item->SubmenuIsShowing()) {
state_.item->GetSubmenu()->IsShowing()) {
state_.item->GetSubmenu()->Hide(); state_.item->GetSubmenu()->Hide();
} }
...@@ -1775,7 +1783,7 @@ void MenuController::CommitPendingSelection() { ...@@ -1775,7 +1783,7 @@ void MenuController::CommitPendingSelection() {
bool found = false; bool found = false;
for (MenuItemView* item = state_.item; item && !found; for (MenuItemView* item = state_.item; item && !found;
item = item->GetParentMenuItem()) { item = item->GetParentMenuItem()) {
found = (item->HasSubmenu() && item->GetSubmenu()->IsShowing() && found = (item->SubmenuIsShowing() &&
item->GetSubmenu() == scroll_task_->submenu()); item->GetSubmenu() == scroll_task_->submenu());
} }
if (!found) if (!found)
...@@ -2184,8 +2192,7 @@ void MenuController::IncrementSelection( ...@@ -2184,8 +2192,7 @@ void MenuController::IncrementSelection(
SelectionIncrementDirectionType direction) { SelectionIncrementDirectionType direction) {
MenuItemView* item = pending_state_.item; MenuItemView* item = pending_state_.item;
DCHECK(item); DCHECK(item);
if (pending_state_.submenu_open && item->HasSubmenu() && if (pending_state_.submenu_open && item->SubmenuIsShowing()) {
item->GetSubmenu()->IsShowing()) {
// A menu is selected and open, but none of its children are selected, // A menu is selected and open, but none of its children are selected,
// select the first menu item that is visible and enabled. // select the first menu item that is visible and enabled.
if (item->GetSubmenu()->GetMenuItemCount()) { if (item->GetSubmenu()->GetMenuItemCount()) {
...@@ -2278,7 +2285,7 @@ void MenuController::CloseSubmenu() { ...@@ -2278,7 +2285,7 @@ void MenuController::CloseSubmenu() {
DCHECK(item); DCHECK(item);
if (!item->GetParentMenuItem()) if (!item->GetParentMenuItem())
return; return;
if (item->HasSubmenu() && item->GetSubmenu()->IsShowing()) if (item->SubmenuIsShowing())
SetSelection(item, SELECTION_UPDATE_IMMEDIATELY); SetSelection(item, SELECTION_UPDATE_IMMEDIATELY);
else if (item->GetParentMenuItem()->GetParentMenuItem()) else if (item->GetParentMenuItem()->GetParentMenuItem())
SetSelection(item->GetParentMenuItem(), SELECTION_UPDATE_IMMEDIATELY); SetSelection(item->GetParentMenuItem(), SELECTION_UPDATE_IMMEDIATELY);
...@@ -2346,7 +2353,7 @@ void MenuController::SelectByChar(base::char16 character) { ...@@ -2346,7 +2353,7 @@ void MenuController::SelectByChar(base::char16 character) {
base::char16 char_array[] = { character, 0 }; base::char16 char_array[] = { character, 0 };
base::char16 key = base::i18n::ToLower(char_array)[0]; base::char16 key = base::i18n::ToLower(char_array)[0];
MenuItemView* item = pending_state_.item; MenuItemView* item = pending_state_.item;
if (!item->HasSubmenu() || !item->GetSubmenu()->IsShowing()) if (!item->SubmenuIsShowing())
item = item->GetParentMenuItem(); item = item->GetParentMenuItem();
DCHECK(item); DCHECK(item);
DCHECK(item->HasSubmenu()); DCHECK(item->HasSubmenu());
...@@ -2672,8 +2679,7 @@ void MenuController::HandleMouseLocation(SubmenuView* source, ...@@ -2672,8 +2679,7 @@ void MenuController::HandleMouseLocation(SubmenuView* source,
SetSelection(part.menu, SELECTION_OPEN_SUBMENU); SetSelection(part.menu, SELECTION_OPEN_SUBMENU);
} else if (!part.is_scroll() && pending_state_.item && } else if (!part.is_scroll() && pending_state_.item &&
pending_state_.item->GetParentMenuItem() && pending_state_.item->GetParentMenuItem() &&
(!pending_state_.item->HasSubmenu() || !pending_state_.item->SubmenuIsShowing()) {
!pending_state_.item->GetSubmenu()->IsShowing())) {
// On exit if the user hasn't selected an item with a submenu, move the // On exit if the user hasn't selected an item with a submenu, move the
// selection back to the parent menu item. // selection back to the parent menu item.
SetSelection(pending_state_.item->GetParentMenuItem(), SetSelection(pending_state_.item->GetParentMenuItem(),
......
...@@ -1417,6 +1417,47 @@ TEST_F(MenuControllerTest, RepostEventToEmptyMenuItem) { ...@@ -1417,6 +1417,47 @@ TEST_F(MenuControllerTest, RepostEventToEmptyMenuItem) {
EXPECT_EQ(menu_controller_delegate(), GetCurrentDelegate()); EXPECT_EQ(menu_controller_delegate(), GetCurrentDelegate());
} }
// Drag the mouse from an external view into a menu
// When the mouse leaves the menu while still in the process of dragging
// the menu item view highlight should turn off
TEST_F(MenuControllerTest, DragFromViewIntoMenuAndExit) {
SubmenuView* sub_menu = menu_item()->GetSubmenu();
MenuItemView* first_item = sub_menu->GetMenuItemAt(0);
std::unique_ptr<View> drag_view = base::MakeUnique<View>();
drag_view->SetBoundsRect(gfx::Rect(0, 500, 100, 100));
sub_menu->ShowAt(owner(), gfx::Rect(0, 0, 100, 100), false);
gfx::Point press_location(drag_view->bounds().CenterPoint());
gfx::Point drag_location(first_item->bounds().CenterPoint());
gfx::Point release_location(200, 50);
// Begin drag on an external view
ui::MouseEvent press_event(ui::ET_MOUSE_PRESSED, press_location,
press_location, ui::EventTimeForNow(),
ui::EF_LEFT_MOUSE_BUTTON, 0);
drag_view->OnMousePressed(press_event);
// Drag into a menu item
ui::MouseEvent drag_event_enter(ui::ET_MOUSE_DRAGGED, drag_location,
drag_location, ui::EventTimeForNow(),
ui::EF_LEFT_MOUSE_BUTTON, 0);
ProcessMouseDragged(sub_menu, drag_event_enter);
EXPECT_TRUE(first_item->IsSelected());
// Drag out of the menu item
ui::MouseEvent drag_event_exit(ui::ET_MOUSE_DRAGGED, release_location,
release_location, ui::EventTimeForNow(),
ui::EF_LEFT_MOUSE_BUTTON, 0);
ProcessMouseDragged(sub_menu, drag_event_exit);
EXPECT_FALSE(first_item->IsSelected());
// Complete drag with release
ui::MouseEvent release_event(ui::ET_MOUSE_RELEASED, release_location,
release_location, ui::EventTimeForNow(),
ui::EF_LEFT_MOUSE_BUTTON, 0);
ProcessMouseReleased(sub_menu, release_event);
}
#endif // defined(USE_AURA) #endif // defined(USE_AURA)
} // namespace test } // namespace test
......
...@@ -347,6 +347,10 @@ SubmenuView* MenuItemView::GetSubmenu() const { ...@@ -347,6 +347,10 @@ SubmenuView* MenuItemView::GetSubmenu() const {
return submenu_; return submenu_;
} }
bool MenuItemView::SubmenuIsShowing() const {
return HasSubmenu() && GetSubmenu()->IsShowing();
}
void MenuItemView::SetTitle(const base::string16& title) { void MenuItemView::SetTitle(const base::string16& title) {
title_ = title; title_ = title;
invalidate_dimensions(); // Triggers preferred size recalculation. invalidate_dimensions(); // Triggers preferred size recalculation.
......
...@@ -222,6 +222,9 @@ class VIEWS_EXPORT MenuItemView : public View { ...@@ -222,6 +222,9 @@ class VIEWS_EXPORT MenuItemView : public View {
// Returns the view containing child menu items. // Returns the view containing child menu items.
virtual SubmenuView* GetSubmenu() const; virtual SubmenuView* GetSubmenu() const;
// Returns true if this menu item has a submenu and it is showing
virtual bool SubmenuIsShowing() const;
// Returns the parent menu item. // Returns the parent menu item.
MenuItemView* GetParentMenuItem() { return parent_menu_item_; } MenuItemView* GetParentMenuItem() { return parent_menu_item_; }
const MenuItemView* GetParentMenuItem() const { return parent_menu_item_; } const MenuItemView* GetParentMenuItem() const { return parent_menu_item_; }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment