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

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

Issue 10829176: Update drop down menu look & feel (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: png crush Created 8 years, 4 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 | Annotate | Revision Log
« no previous file with comments | « ui/views/controls/menu/menu_controller.h ('k') | ui/views/controls/menu/menu_item_view.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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/run_loop.h" 9 #include "base/run_loop.h"
10 #include "base/time.h" 10 #include "base/time.h"
(...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after
270 MenuItemView* MenuController::Run(Widget* parent, 270 MenuItemView* MenuController::Run(Widget* parent,
271 MenuButton* button, 271 MenuButton* button,
272 MenuItemView* root, 272 MenuItemView* root,
273 const gfx::Rect& bounds, 273 const gfx::Rect& bounds,
274 MenuItemView::AnchorPosition position, 274 MenuItemView::AnchorPosition position,
275 int* result_mouse_event_flags) { 275 int* result_mouse_event_flags) {
276 exit_type_ = EXIT_NONE; 276 exit_type_ = EXIT_NONE;
277 possible_drag_ = false; 277 possible_drag_ = false;
278 drag_in_progress_ = false; 278 drag_in_progress_ = false;
279 279
280 // We need to drop the first mouse release event when the menu has been
281 // layed out over the bounds.
282 drop_first_release_event_ =
283 root->GetRequestedMenuPosition() == MenuItemView::POSITION_OVER_BOUNDS;
284
285 bool nested_menu = showing_; 280 bool nested_menu = showing_;
286 if (showing_) { 281 if (showing_) {
287 // Only support nesting of blocking_run menus, nesting of 282 // Only support nesting of blocking_run menus, nesting of
288 // blocking/non-blocking shouldn't be needed. 283 // blocking/non-blocking shouldn't be needed.
289 DCHECK(blocking_run_); 284 DCHECK(blocking_run_);
290 285
291 // We're already showing, push the current state. 286 // We're already showing, push the current state.
292 menu_stack_.push_back(state_); 287 menu_stack_.push_back(state_);
293 288
294 // The context menu should be owned by the same parent. 289 // The context menu should be owned by the same parent.
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after
466 ShowSiblingMenu(source, event.location()); 461 ShowSiblingMenu(source, event.location());
467 } 462 }
468 UpdateActiveMouseView(source, event, mouse_menu); 463 UpdateActiveMouseView(source, event, mouse_menu);
469 } 464 }
470 465
471 void MenuController::OnMouseReleased(SubmenuView* source, 466 void MenuController::OnMouseReleased(SubmenuView* source,
472 const ui::MouseEvent& event) { 467 const ui::MouseEvent& event) {
473 if (!blocking_run_) 468 if (!blocking_run_)
474 return; 469 return;
475 470
476 // We must ignore the first release event when it occured within the original
477 // bounds.
478 if (drop_first_release_event_ && (event.flags() & ui::EF_LEFT_MOUSE_BUTTON)) {
479 drop_first_release_event_ = false;
480 gfx::Point loc(event.location());
481 View::ConvertPointToScreen(source->GetScrollViewContainer(), &loc);
482 DCHECK(!state_.initial_bounds.IsEmpty());
483 if (state_.initial_bounds.Contains(loc))
484 return;
485 }
486 drop_first_release_event_ = false;
487
488 DCHECK(state_.item); 471 DCHECK(state_.item);
489 possible_drag_ = false; 472 possible_drag_ = false;
490 DCHECK(blocking_run_); 473 DCHECK(blocking_run_);
491 MenuPart part = GetMenuPart(source, event.location()); 474 MenuPart part = GetMenuPart(source, event.location());
492 if (event.IsRightMouseButton() && (part.type == MenuPart::MENU_ITEM && 475 if (event.IsRightMouseButton() && (part.type == MenuPart::MENU_ITEM &&
493 part.menu)) { 476 part.menu)) {
494 if (ShowContextMenu(part.menu, source, event)) 477 if (ShowContextMenu(part.menu, source, event))
495 return; 478 return;
496 } 479 }
497 480
(...skipping 287 matching lines...) Expand 10 before | Expand all | Expand 10 after
785 menu_item->GetType() != MenuItemView::SUBMENU)) { 768 menu_item->GetType() != MenuItemView::SUBMENU)) {
786 menu_item->GetWidget()->NotifyAccessibilityEvent( 769 menu_item->GetWidget()->NotifyAccessibilityEvent(
787 menu_item, ui::AccessibilityTypes::EVENT_FOCUS, true); 770 menu_item, ui::AccessibilityTypes::EVENT_FOCUS, true);
788 } 771 }
789 } 772 }
790 773
791 void MenuController::SetSelectionOnPointerDown(SubmenuView* source, 774 void MenuController::SetSelectionOnPointerDown(SubmenuView* source,
792 const ui::LocatedEvent& event) { 775 const ui::LocatedEvent& event) {
793 if (!blocking_run_) 776 if (!blocking_run_)
794 return; 777 return;
795 drop_first_release_event_ = false;
796 778
797 DCHECK(!active_mouse_view_); 779 DCHECK(!active_mouse_view_);
798 780
799 MenuPart part = GetMenuPart(source, event.location()); 781 MenuPart part = GetMenuPart(source, event.location());
800 if (part.is_scroll()) 782 if (part.is_scroll())
801 return; // Ignore presses on scroll buttons. 783 return; // Ignore presses on scroll buttons.
802 784
803 // When this menu is opened through a touch event, a simulated right-click 785 // When this menu is opened through a touch event, a simulated right-click
804 // is sent before the menu appears. Ignore it. 786 // is sent before the menu appears. Ignore it.
805 if ((event.flags() & ui::EF_RIGHT_MOUSE_BUTTON) && 787 if ((event.flags() & ui::EF_RIGHT_MOUSE_BUTTON) &&
(...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after
1042 default: 1024 default:
1043 break; 1025 break;
1044 } 1026 }
1045 return true; 1027 return true;
1046 } 1028 }
1047 1029
1048 MenuController::MenuController(bool blocking, 1030 MenuController::MenuController(bool blocking,
1049 internal::MenuControllerDelegate* delegate) 1031 internal::MenuControllerDelegate* delegate)
1050 : blocking_run_(blocking), 1032 : blocking_run_(blocking),
1051 showing_(false), 1033 showing_(false),
1052 drop_first_release_event_(false),
1053 exit_type_(EXIT_NONE), 1034 exit_type_(EXIT_NONE),
1054 did_capture_(false), 1035 did_capture_(false),
1055 result_(NULL), 1036 result_(NULL),
1056 result_mouse_event_flags_(0), 1037 result_mouse_event_flags_(0),
1057 drop_target_(NULL), 1038 drop_target_(NULL),
1058 drop_position_(MenuDelegate::DROP_UNKNOWN), 1039 drop_position_(MenuDelegate::DROP_UNKNOWN),
1059 owner_(NULL), 1040 owner_(NULL),
1060 #if defined(USE_AURA) 1041 #if defined(USE_AURA)
1061 root_window_(NULL), 1042 root_window_(NULL),
1062 #endif 1043 #endif
(...skipping 485 matching lines...) Expand 10 before | Expand all | Expand 10 after
1548 bool prefer_leading, 1529 bool prefer_leading,
1549 bool* is_leading) { 1530 bool* is_leading) {
1550 DCHECK(item); 1531 DCHECK(item);
1551 1532
1552 SubmenuView* submenu = item->GetSubmenu(); 1533 SubmenuView* submenu = item->GetSubmenu();
1553 DCHECK(submenu); 1534 DCHECK(submenu);
1554 1535
1555 gfx::Size pref = submenu->GetScrollViewContainer()->GetPreferredSize(); 1536 gfx::Size pref = submenu->GetScrollViewContainer()->GetPreferredSize();
1556 1537
1557 // Don't let the menu go too wide. 1538 // Don't let the menu go too wide.
1558 if (item->actual_menu_position() != MenuItemView::POSITION_OVER_BOUNDS) 1539 pref.set_width(std::min(pref.width(),
1559 pref.set_width(std::min(pref.width(),
1560 item->GetDelegate()->GetMaxWidthForMenu(item))); 1540 item->GetDelegate()->GetMaxWidthForMenu(item)));
1561 if (!state_.monitor_bounds.IsEmpty()) 1541 if (!state_.monitor_bounds.IsEmpty())
1562 pref.set_width(std::min(pref.width(), state_.monitor_bounds.width())); 1542 pref.set_width(std::min(pref.width(), state_.monitor_bounds.width()));
1563 1543
1564 // Assume we can honor prefer_leading. 1544 // Assume we can honor prefer_leading.
1565 *is_leading = prefer_leading; 1545 *is_leading = prefer_leading;
1566 1546
1567 int x, y; 1547 int x, y;
1568 1548
1569 if (!item->GetParentMenuItem()) { 1549 if (!item->GetParentMenuItem()) {
1570 // First item, position relative to initial location. 1550 // First item, position relative to initial location.
1571 x = state_.initial_bounds.x(); 1551 x = state_.initial_bounds.x();
1572 if (item->actual_menu_position() == MenuItemView::POSITION_OVER_BOUNDS) 1552 y = state_.initial_bounds.bottom();
1573 y = state_.initial_bounds.y();
1574 else
1575 y = state_.initial_bounds.bottom();
1576 if (state_.anchor == MenuItemView::TOPRIGHT) 1553 if (state_.anchor == MenuItemView::TOPRIGHT)
1577 x = x + state_.initial_bounds.width() - pref.width(); 1554 x = x + state_.initial_bounds.width() - pref.width();
1578 1555
1579 if (!state_.monitor_bounds.IsEmpty() && 1556 if (!state_.monitor_bounds.IsEmpty() &&
1580 pref.height() > state_.monitor_bounds.height() && 1557 y + pref.height() > state_.monitor_bounds.bottom()) {
1581 item->actual_menu_position() == MenuItemView::POSITION_OVER_BOUNDS) {
1582 // Handle very tall menus.
1583 pref.set_height(state_.monitor_bounds.height());
1584 y = state_.monitor_bounds.y();
1585 } else if (!state_.monitor_bounds.IsEmpty() &&
1586 y + pref.height() > state_.monitor_bounds.bottom() &&
1587 item->actual_menu_position() != MenuItemView::POSITION_OVER_BOUNDS) {
1588 // The menu doesn't fit fully below the button on the screen. The menu 1558 // The menu doesn't fit fully below the button on the screen. The menu
1589 // position with respect to the bounds will be preserved if it has 1559 // position with respect to the bounds will be preserved if it has
1590 // already been drawn. When the requested positioning is below the bounds 1560 // already been drawn. When the requested positioning is below the bounds
1591 // it will shrink the menu to make it fit below. 1561 // it will shrink the menu to make it fit below.
1592 // If the requested positioning is best fit, it will first try to fit the 1562 // If the requested positioning is best fit, it will first try to fit the
1593 // menu below. If that does not fit it will try to place it above. If 1563 // menu below. If that does not fit it will try to place it above. If
1594 // that will not fit it will place it at the bottom of the work area and 1564 // that will not fit it will place it at the bottom of the work area and
1595 // moving it off the initial_bounds region to avoid overlap. 1565 // moving it off the initial_bounds region to avoid overlap.
1596 // In all other requested position styles it will be flipped above and 1566 // In all other requested position styles it will be flipped above and
1597 // the height will be shrunken to the usable height. 1567 // the height will be shrunken to the usable height.
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
1642 pref.set_height(std::min(pref.height(), 1612 pref.set_height(std::min(pref.height(),
1643 state_.initial_bounds.y() - state_.monitor_bounds.y())); 1613 state_.initial_bounds.y() - state_.monitor_bounds.y()));
1644 y = state_.initial_bounds.y() - pref.height(); 1614 y = state_.initial_bounds.y() - pref.height();
1645 item->set_actual_menu_position(MenuItemView::POSITION_ABOVE_BOUNDS); 1615 item->set_actual_menu_position(MenuItemView::POSITION_ABOVE_BOUNDS);
1646 } 1616 }
1647 } else if (item->actual_menu_position() == 1617 } else if (item->actual_menu_position() ==
1648 MenuItemView::POSITION_ABOVE_BOUNDS) { 1618 MenuItemView::POSITION_ABOVE_BOUNDS) {
1649 pref.set_height(std::min(pref.height(), 1619 pref.set_height(std::min(pref.height(),
1650 state_.initial_bounds.y() - state_.monitor_bounds.y())); 1620 state_.initial_bounds.y() - state_.monitor_bounds.y()));
1651 y = state_.initial_bounds.y() - pref.height(); 1621 y = state_.initial_bounds.y() - pref.height();
1652 } else if (item->actual_menu_position() ==
1653 MenuItemView::POSITION_OVER_BOUNDS) {
1654 // Center vertically assuming all items have the same height.
1655 int middle = state_.initial_bounds.y() - pref.height() / 2;
1656 if (submenu->GetMenuItemCount() > 0)
1657 middle += submenu->GetMenuItemAt(0)->GetPreferredSize().height() / 2;
1658 y = std::max(state_.monitor_bounds.y(), middle);
1659 if (y + pref.height() > state_.monitor_bounds.bottom())
1660 y = state_.monitor_bounds.bottom() - pref.height();
1661 } else { 1622 } else {
1662 item->set_actual_menu_position(MenuItemView::POSITION_BELOW_BOUNDS); 1623 item->set_actual_menu_position(MenuItemView::POSITION_BELOW_BOUNDS);
1663 } 1624 }
1664 } else { 1625 } else {
1665 // Not the first menu; position it relative to the bounds of the menu 1626 // Not the first menu; position it relative to the bounds of the menu
1666 // item. 1627 // item.
1667 gfx::Point item_loc; 1628 gfx::Point item_loc;
1668 View::ConvertPointToScreen(item, &item_loc); 1629 View::ConvertPointToScreen(item, &item_loc);
1669 1630
1670 // We must make sure we take into account the UI layout. If the layout is 1631 // We must make sure we take into account the UI layout. If the layout is
(...skipping 472 matching lines...) Expand 10 before | Expand all | Expand 10 after
2143 2104
2144 #if defined(USE_AURA) 2105 #if defined(USE_AURA)
2145 void MenuController::OnWindowActivated(aura::Window* active, 2106 void MenuController::OnWindowActivated(aura::Window* active,
2146 aura::Window* old_active) { 2107 aura::Window* old_active) {
2147 if (!drag_in_progress_) 2108 if (!drag_in_progress_)
2148 Cancel(EXIT_ALL); 2109 Cancel(EXIT_ALL);
2149 } 2110 }
2150 #endif 2111 #endif
2151 2112
2152 } // namespace views 2113 } // namespace views
OLDNEW
« no previous file with comments | « ui/views/controls/menu/menu_controller.h ('k') | ui/views/controls/menu/menu_item_view.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698