summaryrefslogtreecommitdiffstats
path: root/ui
diff options
context:
space:
mode:
authorskuhne@chromium.org <skuhne@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-05-25 01:43:59 +0000
committerskuhne@chromium.org <skuhne@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-05-25 01:43:59 +0000
commit2acc98979768ed4b3d59524c8780465741c7f024 (patch)
treeaf82f2a74cac18eacca27e546aea50333d09a29d /ui
parentb1872fe9e72ab28341008be0c38501722b7aeb1a (diff)
downloadchromium_src-2acc98979768ed4b3d59524c8780465741c7f024.zip
chromium_src-2acc98979768ed4b3d59524c8780465741c7f024.tar.gz
chromium_src-2acc98979768ed4b3d59524c8780465741c7f024.tar.bz2
Allowing menu creator to suppress scrollable menus if they do not fit on the screen at a certain location
BUG=128815 TEST=none Review URL: https://chromiumcodereview.appspot.com/10430003 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@138963 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ui')
-rw-r--r--ui/views/controls/menu/menu_controller.cc55
1 files changed, 43 insertions, 12 deletions
diff --git a/ui/views/controls/menu/menu_controller.cc b/ui/views/controls/menu/menu_controller.cc
index a09333c..4fec2c9 100644
--- a/ui/views/controls/menu/menu_controller.cc
+++ b/ui/views/controls/menu/menu_controller.cc
@@ -1540,20 +1540,51 @@ gfx::Rect MenuController::CalculateMenuBounds(MenuItemView* item,
} else if (!state_.monitor_bounds.IsEmpty() &&
y + pref.height() > state_.monitor_bounds.bottom() &&
item->actual_menu_position() != MenuItemView::POSITION_OVER_BOUNDS) {
- // The menu doesn't fit on screen. The menu position with
- // respect to the bounds will be preserved if it has already
- // been drawn. On the first drawing if the first location is
- // above the half way point then show from the mouse location to
- // bottom of screen, otherwise show from the top of the screen
- // to the location of the mouse. While odd, this behavior
- // matches IE.
- if (item->actual_menu_position() == MenuItemView::POSITION_BELOW_BOUNDS ||
- (item->actual_menu_position() == MenuItemView::POSITION_BEST_FIT &&
- y < (state_.monitor_bounds.y() +
- state_.monitor_bounds.height() / 2))) {
+ // The menu doesn't fit fully below the button on the screen. The menu
+ // position with respect to the bounds will be preserved if it has
+ // already been drawn. When the requested positioning is below the bounds
+ // it will shrink the menu to make it fit below.
+ // If the requested positioning is best fit, it will first try to fit the
+ // menu below. If that does not fit it will try to place it above. If
+ // that will not fit it will place it at the bottom of the work area and
+ // moving it off the initial_bounds region to avoid overlap.
+ // In all other requested position styles it will be flipped above and
+ // the height will be shrunken to the usable height.
+ if (item->actual_menu_position() == MenuItemView::POSITION_BELOW_BOUNDS) {
pref.set_height(std::min(pref.height(),
state_.monitor_bounds.bottom() - y));
- item->set_actual_menu_position(MenuItemView::POSITION_BELOW_BOUNDS);
+ } else if (item->actual_menu_position() ==
+ MenuItemView::POSITION_BEST_FIT) {
+ if (state_.monitor_bounds.y() + pref.height() <
+ state_.initial_bounds.y()) {
+ // Flipping upwards if there is enough space.
+ y = state_.initial_bounds.y() - pref.height();
+ item->set_actual_menu_position(MenuItemView::POSITION_ABOVE_BOUNDS);
+ } else {
+ // The user prefers to move the menu a bit around in order to get the
+ // best fit and to avoid showing scroll elements.
+ y = state_.monitor_bounds.bottom() - pref.height();
+ item->set_actual_menu_position(MenuItemView::POSITION_BELOW_BOUNDS);
+ // The menu should never overlap the owning button. So move it.
+ // We use the anchor view style to determine the preferred position
+ // relative to the owning button.
+ if (state_.anchor == MenuItemView::TOPLEFT) {
+ // The menu starts with the same x coordinate as the owning button.
+ if (x + state_.initial_bounds.width() + pref.width() >
+ state_.monitor_bounds.right())
+ x -= pref.width(); // Move the menu to the left of the button.
+ else
+ x += state_.initial_bounds.width(); // Move the menu right.
+ } else {
+ // The menu should end with the same x coordinate as the owning
+ // button.
+ if (state_.monitor_bounds.x() >
+ state_.initial_bounds.x() - pref.width())
+ x = state_.initial_bounds.right(); // Move right of the button.
+ else
+ x = state_.initial_bounds.x() - pref.width(); // Move left.
+ }
+ }
} else {
pref.set_height(std::min(pref.height(),
state_.initial_bounds.y() - state_.monitor_bounds.y()));