OLD | NEW |
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 1538 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1549 pref.set_width(std::min(pref.width(), | 1549 pref.set_width(std::min(pref.width(), |
1550 item->GetDelegate()->GetMaxWidthForMenu(item))); | 1550 item->GetDelegate()->GetMaxWidthForMenu(item))); |
1551 if (!state_.monitor_bounds.IsEmpty()) | 1551 if (!state_.monitor_bounds.IsEmpty()) |
1552 pref.set_width(std::min(pref.width(), state_.monitor_bounds.width())); | 1552 pref.set_width(std::min(pref.width(), state_.monitor_bounds.width())); |
1553 | 1553 |
1554 // Assume we can honor prefer_leading. | 1554 // Assume we can honor prefer_leading. |
1555 *is_leading = prefer_leading; | 1555 *is_leading = prefer_leading; |
1556 | 1556 |
1557 int x, y; | 1557 int x, y; |
1558 | 1558 |
| 1559 const MenuConfig& menu_config = item->GetMenuConfig(); |
| 1560 |
1559 if (!item->GetParentMenuItem()) { | 1561 if (!item->GetParentMenuItem()) { |
1560 // First item, position relative to initial location. | 1562 // First item, position relative to initial location. |
1561 x = state_.initial_bounds.x(); | 1563 x = state_.initial_bounds.x(); |
1562 | 1564 |
1563 // Offsets for context menu prevent menu items being selected by | 1565 // Offsets for context menu prevent menu items being selected by |
1564 // simply opening the menu (bug 142992). | 1566 // simply opening the menu (bug 142992). |
1565 if (MenuConfig::instance().offset_context_menus && state_.context_menu) | 1567 if (menu_config.offset_context_menus && state_.context_menu) |
1566 x += 1; | 1568 x += 1; |
1567 | 1569 |
1568 y = state_.initial_bounds.bottom(); | 1570 y = state_.initial_bounds.bottom(); |
1569 if (state_.anchor == MenuItemView::TOPRIGHT) { | 1571 if (state_.anchor == MenuItemView::TOPRIGHT) { |
1570 x = x + state_.initial_bounds.width() - pref.width(); | 1572 x = x + state_.initial_bounds.width() - pref.width(); |
1571 if (MenuConfig::instance().offset_context_menus && state_.context_menu) | 1573 if (menu_config.offset_context_menus && state_.context_menu) |
1572 x -= 1; | 1574 x -= 1; |
1573 } else if (state_.anchor == MenuItemView::BOTTOMCENTER) { | 1575 } else if (state_.anchor == MenuItemView::BOTTOMCENTER) { |
1574 x = x - (pref.width() - state_.initial_bounds.width()) / 2; | 1576 x = x - (pref.width() - state_.initial_bounds.width()) / 2; |
1575 y = std::max(0, state_.initial_bounds.y() - pref.height()); | 1577 y = std::max(0, state_.initial_bounds.y() - pref.height()); |
1576 } | 1578 } |
1577 | 1579 |
1578 if (!state_.monitor_bounds.IsEmpty() && | 1580 if (!state_.monitor_bounds.IsEmpty() && |
1579 y + pref.height() > state_.monitor_bounds.bottom()) { | 1581 y + pref.height() > state_.monitor_bounds.bottom()) { |
1580 // The menu doesn't fit fully below the button on the screen. The menu | 1582 // The menu doesn't fit fully below the button on the screen. The menu |
1581 // position with respect to the bounds will be preserved if it has | 1583 // position with respect to the bounds will be preserved if it has |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1638 } | 1640 } |
1639 } else if (item->actual_menu_position() == | 1641 } else if (item->actual_menu_position() == |
1640 MenuItemView::POSITION_ABOVE_BOUNDS) { | 1642 MenuItemView::POSITION_ABOVE_BOUNDS) { |
1641 pref.set_height(std::min(pref.height(), | 1643 pref.set_height(std::min(pref.height(), |
1642 state_.initial_bounds.y() - state_.monitor_bounds.y())); | 1644 state_.initial_bounds.y() - state_.monitor_bounds.y())); |
1643 y = state_.initial_bounds.y() - pref.height(); | 1645 y = state_.initial_bounds.y() - pref.height(); |
1644 } else { | 1646 } else { |
1645 item->set_actual_menu_position(MenuItemView::POSITION_BELOW_BOUNDS); | 1647 item->set_actual_menu_position(MenuItemView::POSITION_BELOW_BOUNDS); |
1646 } | 1648 } |
1647 if (state_.monitor_bounds.width() != 0 && | 1649 if (state_.monitor_bounds.width() != 0 && |
1648 MenuConfig::instance().offset_context_menus && state_.context_menu) { | 1650 menu_config.offset_context_menus && state_.context_menu) { |
1649 if (x + pref.width() > state_.monitor_bounds.right()) | 1651 if (x + pref.width() > state_.monitor_bounds.right()) |
1650 x = state_.initial_bounds.x() - pref.width() - 1; | 1652 x = state_.initial_bounds.x() - pref.width() - 1; |
1651 if (x < state_.monitor_bounds.x()) | 1653 if (x < state_.monitor_bounds.x()) |
1652 x = state_.monitor_bounds.x(); | 1654 x = state_.monitor_bounds.x(); |
1653 } | 1655 } |
1654 } else { | 1656 } else { |
1655 // Not the first menu; position it relative to the bounds of the menu | 1657 // Not the first menu; position it relative to the bounds of the menu |
1656 // item. | 1658 // item. |
1657 gfx::Point item_loc; | 1659 gfx::Point item_loc; |
1658 View::ConvertPointToScreen(item, &item_loc); | 1660 View::ConvertPointToScreen(item, &item_loc); |
1659 | 1661 |
1660 // We must make sure we take into account the UI layout. If the layout is | 1662 // We must make sure we take into account the UI layout. If the layout is |
1661 // RTL, then a 'leading' menu is positioned to the left of the parent menu | 1663 // RTL, then a 'leading' menu is positioned to the left of the parent menu |
1662 // item and not to the right. | 1664 // item and not to the right. |
1663 bool layout_is_rtl = base::i18n::IsRTL(); | 1665 bool layout_is_rtl = base::i18n::IsRTL(); |
1664 bool create_on_the_right = (prefer_leading && !layout_is_rtl) || | 1666 bool create_on_the_right = (prefer_leading && !layout_is_rtl) || |
1665 (!prefer_leading && layout_is_rtl); | 1667 (!prefer_leading && layout_is_rtl); |
1666 int submenu_horizontal_inset = | 1668 int submenu_horizontal_inset = menu_config.submenu_horizontal_inset; |
1667 MenuConfig::instance().submenu_horizontal_inset; | |
1668 | 1669 |
1669 if (create_on_the_right) { | 1670 if (create_on_the_right) { |
1670 x = item_loc.x() + item->width() - submenu_horizontal_inset; | 1671 x = item_loc.x() + item->width() - submenu_horizontal_inset; |
1671 if (state_.monitor_bounds.width() != 0 && | 1672 if (state_.monitor_bounds.width() != 0 && |
1672 x + pref.width() > state_.monitor_bounds.right()) { | 1673 x + pref.width() > state_.monitor_bounds.right()) { |
1673 if (layout_is_rtl) | 1674 if (layout_is_rtl) |
1674 *is_leading = true; | 1675 *is_leading = true; |
1675 else | 1676 else |
1676 *is_leading = false; | 1677 *is_leading = false; |
1677 x = item_loc.x() - pref.width() + submenu_horizontal_inset; | 1678 x = item_loc.x() - pref.width() + submenu_horizontal_inset; |
1678 } | 1679 } |
1679 } else { | 1680 } else { |
1680 x = item_loc.x() - pref.width() + submenu_horizontal_inset; | 1681 x = item_loc.x() - pref.width() + submenu_horizontal_inset; |
1681 if (state_.monitor_bounds.width() != 0 && x < state_.monitor_bounds.x()) { | 1682 if (state_.monitor_bounds.width() != 0 && x < state_.monitor_bounds.x()) { |
1682 if (layout_is_rtl) | 1683 if (layout_is_rtl) |
1683 *is_leading = false; | 1684 *is_leading = false; |
1684 else | 1685 else |
1685 *is_leading = true; | 1686 *is_leading = true; |
1686 x = item_loc.x() + item->width() - submenu_horizontal_inset; | 1687 x = item_loc.x() + item->width() - submenu_horizontal_inset; |
1687 } | 1688 } |
1688 } | 1689 } |
1689 y = item_loc.y() - MenuConfig::instance().submenu_vertical_margin_size; | 1690 y = item_loc.y() - menu_config.submenu_vertical_margin_size; |
1690 if (state_.monitor_bounds.width() != 0) { | 1691 if (state_.monitor_bounds.width() != 0) { |
1691 pref.set_height(std::min(pref.height(), state_.monitor_bounds.height())); | 1692 pref.set_height(std::min(pref.height(), state_.monitor_bounds.height())); |
1692 if (y + pref.height() > state_.monitor_bounds.bottom()) | 1693 if (y + pref.height() > state_.monitor_bounds.bottom()) |
1693 y = state_.monitor_bounds.bottom() - pref.height(); | 1694 y = state_.monitor_bounds.bottom() - pref.height(); |
1694 if (y < state_.monitor_bounds.y()) | 1695 if (y < state_.monitor_bounds.y()) |
1695 y = state_.monitor_bounds.y(); | 1696 y = state_.monitor_bounds.y(); |
1696 } | 1697 } |
1697 } | 1698 } |
1698 | 1699 |
1699 if (state_.monitor_bounds.width() != 0) { | 1700 if (state_.monitor_bounds.width() != 0) { |
(...skipping 428 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2128 | 2129 |
2129 #if defined(USE_AURA) | 2130 #if defined(USE_AURA) |
2130 void MenuController::OnWindowActivated(aura::Window* active, | 2131 void MenuController::OnWindowActivated(aura::Window* active, |
2131 aura::Window* old_active) { | 2132 aura::Window* old_active) { |
2132 if (!drag_in_progress_) | 2133 if (!drag_in_progress_) |
2133 Cancel(EXIT_ALL); | 2134 Cancel(EXIT_ALL); |
2134 } | 2135 } |
2135 #endif | 2136 #endif |
2136 | 2137 |
2137 } // namespace views | 2138 } // namespace views |
OLD | NEW |