15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/controls/menu/menu_item_view.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/i18n/case_conversion.h" 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/stl_util.h" 9868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h" 102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "grit/ui_resources.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/ui_strings.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/accessibility/accessible_view_state.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/l10n/l10n_util.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/models/menu_model.h" 152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/base/resource/resource_bundle.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/canvas.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/image/image.h" 182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/native_theme/common_theme.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/controls/button/menu_button.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/controls/image_view.h" 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/controls/menu/menu_config.h" 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/controls/menu/menu_controller.h" 232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/views/controls/menu/menu_image_util.h" 242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/views/controls/menu/menu_scroll_view_container.h" 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/controls/menu/menu_separator.h" 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/controls/menu/submenu_view.h" 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/widget/widget.h" 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace views { 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// EmptyMenuMenuItem --------------------------------------------------------- 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// EmptyMenuMenuItem is used when a menu has no menu items. EmptyMenuMenuItem 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// is itself a MenuItemView, but it uses a different ID so that it isn't 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// identified as a MenuItemView. 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class EmptyMenuMenuItem : public MenuItemView { 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) explicit EmptyMenuMenuItem(MenuItemView* parent) 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : MenuItemView(parent, 0, EMPTY) { 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Set this so that we're not identified as a normal menu item. 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) set_id(kEmptyMenuItemViewID); 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetTitle(l10n_util::GetStringUTF16(IDS_APP_MENU_EMPTY_SUBMENU)); 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetEnabled(false); 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual bool GetTooltipText(const gfx::Point& p, 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string16* tooltip) const OVERRIDE { 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Empty menu items shouldn't have a tooltip. 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(EmptyMenuMenuItem); 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Padding between child views. 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const int kChildXPadding = 8; 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// MenuItemView --------------------------------------------------------------- 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int MenuItemView::kMenuItemViewID = 1001; 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int MenuItemView::kEmptyMenuItemViewID = 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MenuItemView::kMenuItemViewID + 1; 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int MenuItemView::icon_area_width_ = 0; 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int MenuItemView::label_start_; 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int MenuItemView::item_right_margin_; 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int MenuItemView::pref_menu_height_; 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 8690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)const char MenuItemView::kViewClassName[] = "MenuItemView"; 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)MenuItemView::MenuItemView(MenuDelegate* delegate) 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : delegate_(delegate), 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) controller_(NULL), 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) canceled_(false), 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parent_menu_item_(NULL), 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type_(SUBMENU), 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) selected_(false), 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) command_(0), 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) submenu_(NULL), 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) has_mnemonics_(false), 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) show_mnemonics_(false), 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) has_icons_(false), 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) icon_view_(NULL), 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) top_margin_(-1), 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bottom_margin_(-1), 1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) left_icon_margin_(0), 1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) right_icon_margin_(0), 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) requested_menu_position_(POSITION_BEST_FIT), 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) actual_menu_position_(requested_menu_position_), 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) use_right_margin_(true) { 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // NOTE: don't check the delegate for NULL, UpdateMenuPartSizes() supplies a 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // NULL delegate. 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Init(NULL, 0, SUBMENU, delegate); 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MenuItemView::ChildPreferredSizeChanged(View* child) { 1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) invalidate_dimensions(); 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PreferredSizeChanged(); 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool MenuItemView::GetTooltipText(const gfx::Point& p, 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string16* tooltip) const { 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *tooltip = tooltip_; 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!tooltip->empty()) 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (GetType() == SEPARATOR) 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const MenuController* controller = GetMenuController(); 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!controller || controller->exit_type() != MenuController::EXIT_NONE) { 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Either the menu has been closed or we're in the process of closing the 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // menu. Don't attempt to query the delegate as it may no longer be valid. 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const MenuItemView* root_menu_item = GetRootMenuItem(); 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (root_menu_item->canceled_) { 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(sky): if |canceled_| is true, controller->exit_type() should be 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // something other than EXIT_NONE, but crash reports seem to indicate 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // otherwise. Figure out why this is needed. 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const MenuDelegate* delegate = GetDelegate(); 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(delegate); 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Point location(p); 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ConvertPointToScreen(this, &location); 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *tooltip = delegate->GetTooltipText(command_, location); 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return !tooltip->empty(); 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MenuItemView::GetAccessibleState(ui::AccessibleViewState* state) { 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) state->role = ui::AccessibilityTypes::ROLE_MENUITEM; 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string16 item_text; 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (IsContainer()) { 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The first child is taking over, just use its accessible name instead of 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |title_|. 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) View* child = child_at(0); 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ui::AccessibleViewState state; 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) child->GetAccessibleState(&state); 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) item_text = state.name; 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) item_text = title_; 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1647dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch state->name = GetAccessibleNameForMenuItem(item_text, GetMinorText()); 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (GetType()) { 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case SUBMENU: 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) state->state |= ui::AccessibilityTypes::STATE_HASPOPUP; 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case CHECKBOX: 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case RADIO: 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) state->state |= GetDelegate()->IsItemChecked(GetCommand()) ? 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ui::AccessibilityTypes::STATE_CHECKED : 0; 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case NORMAL: 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case SEPARATOR: 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case EMPTY: 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // No additional accessibility states currently for these menu states. 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool MenuItemView::IsBubble(MenuItemView::AnchorPosition anchor) { 1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return anchor == MenuItemView::BUBBLE_LEFT || 1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) anchor == MenuItemView::BUBBLE_RIGHT || 1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) anchor == MenuItemView::BUBBLE_ABOVE || 1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) anchor == MenuItemView::BUBBLE_BELOW; 1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)string16 MenuItemView::GetAccessibleNameForMenuItem( 1937dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch const string16& item_text, const string16& minor_text) { 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string16 accessible_name = item_text; 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Filter out the "&" for accessibility clients. 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t index = 0; 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char16 amp = '&'; 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while ((index = accessible_name.find(amp, index)) != string16::npos && 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) index + 1 < accessible_name.length()) { 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) accessible_name.replace(index, accessible_name.length() - index, 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) accessible_name.substr(index + 1)); 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Special case for "&&" (escaped for "&"). 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (accessible_name[index] == '&') 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++index; 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2097dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // Append subtext. 2107dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (!minor_text.empty()) { 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) accessible_name.push_back(' '); 2127dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch accessible_name.append(minor_text); 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return accessible_name; 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MenuItemView::Cancel() { 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (controller_ && !canceled_) { 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) canceled_ = true; 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) controller_->Cancel(MenuController::EXIT_ALL); 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)MenuItemView* MenuItemView::AddMenuItemAt( 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int index, 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int item_id, 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const string16& label, 2297dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch const string16& sublabel, 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const gfx::ImageSkia& icon, 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Type type, 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ui::MenuSeparatorType separator_style) { 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_NE(type, EMPTY); 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_LE(0, index); 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!submenu_) 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateSubmenu(); 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_GE(submenu_->child_count(), index); 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (type == SEPARATOR) { 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) submenu_->AddChildViewAt(new MenuSeparator(this, separator_style), index); 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MenuItemView* item = new MenuItemView(this, item_id, type); 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (label.empty() && GetDelegate()) 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) item->SetTitle(GetDelegate()->GetLabel(item_id)); 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) item->SetTitle(label); 2477dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch item->SetSubtitle(sublabel); 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!icon.isNull()) 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) item->SetIcon(icon); 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (type == SUBMENU) 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) item->CreateSubmenu(); 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) submenu_->AddChildViewAt(item, index); 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return item; 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MenuItemView::RemoveMenuItemAt(int index) { 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(submenu_); 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_LE(0, index); 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_GT(submenu_->child_count(), index); 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) View* item = submenu_->child_at(index); 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(item); 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) submenu_->RemoveChildView(item); 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // RemoveChildView() does not delete the item, which is a good thing 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // in case a submenu is being displayed while items are being removed. 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Deletion will be done by ChildrenChanged() or at destruction. 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) removed_items_.push_back(item); 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)MenuItemView* MenuItemView::AppendMenuItem(int item_id, 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const string16& label, 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Type type) { 2747dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return AppendMenuItemImpl(item_id, label, string16(), gfx::ImageSkia(), type, 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ui::NORMAL_SEPARATOR); 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)MenuItemView* MenuItemView::AppendSubMenu(int item_id, 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const string16& label) { 2807dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return AppendMenuItemImpl(item_id, label, string16(), gfx::ImageSkia(), 2817dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch SUBMENU, ui::NORMAL_SEPARATOR); 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)MenuItemView* MenuItemView::AppendSubMenuWithIcon(int item_id, 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const string16& label, 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const gfx::ImageSkia& icon) { 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return AppendMenuItemImpl( 2887dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch item_id, label, string16(), icon, SUBMENU, ui::NORMAL_SEPARATOR); 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)MenuItemView* MenuItemView::AppendMenuItemWithLabel(int item_id, 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const string16& label) { 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return AppendMenuItem(item_id, label, NORMAL); 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)MenuItemView* MenuItemView::AppendDelegateMenuItem(int item_id) { 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return AppendMenuItem(item_id, string16(), NORMAL); 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MenuItemView::AppendSeparator() { 3017dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch AppendMenuItemImpl(0, string16(), string16(), gfx::ImageSkia(), SEPARATOR, 3027dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch ui::NORMAL_SEPARATOR); 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)MenuItemView* MenuItemView::AppendMenuItemWithIcon(int item_id, 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const string16& label, 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const gfx::ImageSkia& icon) { 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return AppendMenuItemImpl( 3097dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch item_id, label, string16(), icon, NORMAL, ui::NORMAL_SEPARATOR); 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)MenuItemView* MenuItemView::AppendMenuItemFromModel(ui::MenuModel* model, 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int index, 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int id) { 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Image icon; 3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) model->GetIconAt(index, &icon); 3177dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch string16 label, sublabel; 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ui::MenuSeparatorType separator_style = ui::NORMAL_SEPARATOR; 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MenuItemView::Type type; 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ui::MenuModel::ItemType menu_type = model->GetTypeAt(index); 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (menu_type) { 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ui::MenuModel::TYPE_COMMAND: 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type = MenuItemView::NORMAL; 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) label = model->GetLabelAt(index); 3257dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch sublabel = model->GetSublabelAt(index); 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ui::MenuModel::TYPE_CHECK: 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type = MenuItemView::CHECKBOX; 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) label = model->GetLabelAt(index); 3307dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch sublabel = model->GetSublabelAt(index); 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ui::MenuModel::TYPE_RADIO: 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type = MenuItemView::RADIO; 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) label = model->GetLabelAt(index); 3357dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch sublabel = model->GetSublabelAt(index); 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ui::MenuModel::TYPE_SEPARATOR: 3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) icon = gfx::Image(); 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type = MenuItemView::SEPARATOR; 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) separator_style = model->GetSeparatorTypeAt(index); 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ui::MenuModel::TYPE_SUBMENU: 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type = MenuItemView::SUBMENU; 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) label = model->GetLabelAt(index); 3457dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch sublabel = model->GetSublabelAt(index); 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type = MenuItemView::NORMAL; 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return AppendMenuItemImpl(id, 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) label, 3557dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch sublabel, 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) icon.IsEmpty() ? gfx::ImageSkia() : *icon.ToImageSkia(), 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type, 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) separator_style); 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)MenuItemView* MenuItemView::AppendMenuItemImpl( 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int item_id, 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const string16& label, 3647dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch const string16& sublabel, 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const gfx::ImageSkia& icon, 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Type type, 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ui::MenuSeparatorType separator_style) { 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int index = submenu_ ? submenu_->child_count() : 0; 3697dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return AddMenuItemAt(index, item_id, label, sublabel, icon, type, 3707dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch separator_style); 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SubmenuView* MenuItemView::CreateSubmenu() { 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!submenu_) 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) submenu_ = new SubmenuView(this); 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return submenu_; 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool MenuItemView::HasSubmenu() const { 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (submenu_ != NULL); 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SubmenuView* MenuItemView::GetSubmenu() const { 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return submenu_; 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MenuItemView::SetTitle(const string16& title) { 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) title_ = title; 3892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) invalidate_dimensions(); // Triggers preferred size recalculation. 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3927dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid MenuItemView::SetSubtitle(const string16& subtitle) { 3937dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch subtitle_ = subtitle; 3947dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch invalidate_dimensions(); // Triggers preferred size recalculation. 3957dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 3967dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MenuItemView::SetSelected(bool selected) { 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) selected_ = selected; 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SchedulePaint(); 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MenuItemView::SetTooltip(const string16& tooltip, int item_id) { 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MenuItemView* item = GetMenuItemByID(item_id); 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(item); 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) item->tooltip_ = tooltip; 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MenuItemView::SetIcon(const gfx::ImageSkia& icon, int item_id) { 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MenuItemView* item = GetMenuItemByID(item_id); 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(item); 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) item->SetIcon(icon); 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MenuItemView::SetIcon(const gfx::ImageSkia& icon) { 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (icon.isNull()) { 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetIconView(NULL); 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ImageView* icon_view = new ImageView(); 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) icon_view->SetImage(&icon); 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetIconView(icon_view); 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MenuItemView::SetIconView(View* icon_view) { 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (icon_view_) { 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RemoveChildView(icon_view_); 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete icon_view_; 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) icon_view_ = NULL; 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (icon_view) { 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddChildView(icon_view); 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) icon_view_ = icon_view; 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Layout(); 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SchedulePaint(); 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MenuItemView::OnPaint(gfx::Canvas* canvas) { 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PaintButton(canvas, PB_NORMAL); 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gfx::Size MenuItemView::GetPreferredSize() { 4442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const MenuItemDimensions& dimensions(GetDimensions()); 4452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return gfx::Size(dimensions.standard_width + dimensions.children_width, 4462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) dimensions.height); 4472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const MenuItemView::MenuItemDimensions& MenuItemView::GetDimensions() { 4502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!is_dimensions_valid()) 4512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) dimensions_ = CalculateDimensions(); 4522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(is_dimensions_valid()); 4532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return dimensions_; 4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)MenuController* MenuItemView::GetMenuController() { 4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return GetRootMenuItem()->controller_; 4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const MenuController* MenuItemView::GetMenuController() const { 4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return GetRootMenuItem()->controller_; 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)MenuDelegate* MenuItemView::GetDelegate() { 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return GetRootMenuItem()->delegate_; 4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const MenuDelegate* MenuItemView::GetDelegate() const { 4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return GetRootMenuItem()->delegate_; 4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)MenuItemView* MenuItemView::GetRootMenuItem() { 4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return const_cast<MenuItemView*>( 4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static_cast<const MenuItemView*>(this)->GetRootMenuItem()); 4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const MenuItemView* MenuItemView::GetRootMenuItem() const { 4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const MenuItemView* item = this; 4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (const MenuItemView* parent = GetParentMenuItem(); parent; 4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parent = item->GetParentMenuItem()) 4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) item = parent; 4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return item; 4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)char16 MenuItemView::GetMnemonic() { 4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!GetRootMenuItem()->has_mnemonics_) 4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t index = 0; 4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) do { 4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) index = title_.find('&', index); 4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (index != string16::npos) { 4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (index + 1 != title_.size() && title_[index + 1] != '&') { 4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char16 char_array[] = { title_[index + 1], 0 }; 4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(jshin): What about Turkish locale? See http://crbug.com/81719. 4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If the mnemonic is capital I and the UI language is Turkish, 4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // lowercasing it results in 'small dotless i', which is different 4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // from a 'dotted i'. Similar issues may exist for az and lt locales. 4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return base::i18n::ToLower(char_array)[0]; 5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) index++; 5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } while (index != string16::npos); 5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)MenuItemView* MenuItemView::GetMenuItemByID(int id) { 5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (GetCommand() == id) 5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return this; 5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!HasSubmenu()) 5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < GetSubmenu()->child_count(); ++i) { 5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) View* child = GetSubmenu()->child_at(i); 5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (child->id() == MenuItemView::kMenuItemViewID) { 5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MenuItemView* result = static_cast<MenuItemView*>(child)-> 5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetMenuItemByID(id); 5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (result) 5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return result; 5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MenuItemView::ChildrenChanged() { 5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MenuController* controller = GetMenuController(); 5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (controller) { 5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Handles the case where we were empty and are no longer empty. 5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RemoveEmptyMenus(); 5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Handles the case where we were not empty, but now are. 5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddEmptyMenus(); 5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) controller->MenuChildrenChanged(this); 5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (submenu_) { 5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Force a paint and layout. This handles the case of the top 5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // level window's size remaining the same, resulting in no 5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // change to the submenu's size and no layout. 5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) submenu_->Layout(); 5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) submenu_->SchedulePaint(); 5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Update the menu selection after layout. 5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) controller->UpdateSubmenuSelection(submenu_); 5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) STLDeleteElements(&removed_items_); 5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MenuItemView::Layout() { 5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!has_children()) 5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (IsContainer()) { 5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) View* child = child_at(0); 5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Size size = child->GetPreferredSize(); 5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) child->SetBounds(0, GetTopMargin(), size.width(), size.height()); 5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Child views are laid out right aligned and given the full height. To 5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // right align start with the last view and progress to the first. 5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int x = width() - (use_right_margin_ ? item_right_margin_ : 0); 5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = child_count() - 1; i >= 0; --i) { 5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) View* child = child_at(i); 5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (icon_view_ && (icon_view_ == child)) 5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int width = child->GetPreferredSize().width(); 5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) child->SetBounds(x - width, 0, width, height()); 5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) x -= width - kChildXPadding; 5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Position |icon_view|. 5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const MenuConfig& config = GetMenuConfig(); 5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (icon_view_) { 5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) icon_view_->SizeToPreferredSize(); 5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Size size = icon_view_->GetPreferredSize(); 5742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int x = config.item_left_margin + left_icon_margin_ + 5752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (icon_area_width_ - size.width()) / 2; 5762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (type_ == CHECKBOX || type_ == RADIO) 5772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) x = label_start_; 5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int y = 5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (height() + GetTopMargin() - GetBottomMargin() - size.height()) / 2; 5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) icon_view_->SetPosition(gfx::Point(x, y)); 5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MenuItemView::SetMargins(int top_margin, int bottom_margin) { 5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) top_margin_ = top_margin; 5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bottom_margin_ = bottom_margin; 5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) invalidate_dimensions(); 5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const MenuConfig& MenuItemView::GetMenuConfig() const { 5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const MenuController* controller = GetMenuController(); 5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (controller) 5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return controller->menu_config_; 5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return MenuConfig::instance(NULL); 5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)MenuItemView::MenuItemView(MenuItemView* parent, 6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int command, 6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MenuItemView::Type type) 6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : delegate_(NULL), 6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) controller_(NULL), 6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) canceled_(false), 6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parent_menu_item_(parent), 6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type_(type), 6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) selected_(false), 6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) command_(command), 6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) submenu_(NULL), 6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) has_mnemonics_(false), 6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) show_mnemonics_(false), 6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) has_icons_(false), 6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) icon_view_(NULL), 6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) top_margin_(-1), 6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bottom_margin_(-1), 6162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) left_icon_margin_(0), 6172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) right_icon_margin_(0), 6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) requested_menu_position_(POSITION_BEST_FIT), 6192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) actual_menu_position_(requested_menu_position_), 6202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) use_right_margin_(true) { 6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Init(parent, command, type, NULL); 6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)MenuItemView::~MenuItemView() { 6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete submenu_; 6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) STLDeleteElements(&removed_items_); 6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 629b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)const char* MenuItemView::GetClassName() const { 6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return kViewClassName; 6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Calculates all sizes that we can from the OS. 6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This is invoked prior to Running a menu. 6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MenuItemView::UpdateMenuPartSizes() { 6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const MenuConfig& config = GetMenuConfig(); 6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) item_right_margin_ = config.label_to_arrow_padding + config.arrow_width + 6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) config.arrow_to_edge_padding; 6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) icon_area_width_ = config.check_width; 6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (has_icons_) 6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) icon_area_width_ = std::max(icon_area_width_, GetMaxIconViewWidth()); 6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) label_start_ = config.item_left_margin + icon_area_width_; 6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int padding = 0; 6472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (config.always_use_icon_to_label_padding) { 6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) padding = config.icon_to_label_padding; 6492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else if (config.render_gutter) { 6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) padding = config.item_left_margin; 6512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 6522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) padding = (has_icons_ || HasChecksOrRadioButtons()) ? 6532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) config.icon_to_label_padding : 0; 6542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) label_start_ += padding; 6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (config.render_gutter) 6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) label_start_ += config.gutter_width + config.gutter_to_label; 6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EmptyMenuMenuItem menu_item(this); 6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) menu_item.set_controller(GetMenuController()); 6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pref_menu_height_ = menu_item.GetPreferredSize().height(); 6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MenuItemView::Init(MenuItemView* parent, 6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int command, 6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MenuItemView::Type type, 6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MenuDelegate* delegate) { 6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delegate_ = delegate; 6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) controller_ = NULL; 6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) canceled_ = false; 6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parent_menu_item_ = parent; 6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type_ = type; 6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) selected_ = false; 6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) command_ = command; 6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) submenu_ = NULL; 6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) show_mnemonics_ = false; 6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Assign our ID, this allows SubmenuItemView to find MenuItemViews. 6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) set_id(kMenuItemViewID); 6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) has_icons_ = false; 6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Don't request enabled status from the root menu item as it is just 6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // a container for real items. EMPTY items will be disabled. 6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MenuDelegate* root_delegate = GetDelegate(); 6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (parent && type != EMPTY && root_delegate) 6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetEnabled(root_delegate->IsCommandEnabled(command)); 6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MenuItemView::PrepareForRun(bool is_first_menu, 6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool has_mnemonics, 6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool show_mnemonics) { 6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Currently we only support showing the root. 6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!parent_menu_item_); 6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Force us to have a submenu. 6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateSubmenu(); 6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) actual_menu_position_ = requested_menu_position_; 6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) canceled_ = false; 6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) has_mnemonics_ = has_mnemonics; 7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) show_mnemonics_ = has_mnemonics && show_mnemonics; 7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddEmptyMenus(); 7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (is_first_menu) { 7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Only update the menu size if there are no menus showing, otherwise 7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // things may shift around. 7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UpdateMenuPartSizes(); 7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int MenuItemView::GetDrawStringFlags() { 7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int flags = 0; 7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (base::i18n::IsRTL()) 7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) flags |= gfx::Canvas::TEXT_ALIGN_RIGHT; 7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) flags |= gfx::Canvas::TEXT_ALIGN_LEFT; 7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (GetRootMenuItem()->has_mnemonics_) { 7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (GetMenuConfig().show_mnemonics || GetRootMenuItem()->show_mnemonics_) { 7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) flags |= gfx::Canvas::SHOW_PREFIX; 7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) flags |= gfx::Canvas::HIDE_PREFIX; 7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return flags; 7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const gfx::Font& MenuItemView::GetFont() { 7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const MenuDelegate* delegate = GetDelegate(); 7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (delegate) { 7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const gfx::Font* font = delegate->GetLabelFont(GetCommand()); 7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (font) 7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return *font; 7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return GetMenuConfig().font; 7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MenuItemView::AddEmptyMenus() { 7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(HasSubmenu()); 7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!submenu_->has_children()) { 7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) submenu_->AddChildViewAt(new EmptyMenuMenuItem(this), 0); 7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0, item_count = submenu_->GetMenuItemCount(); i < item_count; 7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++i) { 7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MenuItemView* child = submenu_->GetMenuItemAt(i); 7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (child->HasSubmenu()) 7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) child->AddEmptyMenus(); 7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MenuItemView::RemoveEmptyMenus() { 7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(HasSubmenu()); 7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Iterate backwards as we may end up removing views, which alters the child 7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // view count. 7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = submenu_->child_count() - 1; i >= 0; --i) { 7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) View* child = submenu_->child_at(i); 7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (child->id() == MenuItemView::kMenuItemViewID) { 7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MenuItemView* menu_item = static_cast<MenuItemView*>(child); 7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (menu_item->HasSubmenu()) 7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) menu_item->RemoveEmptyMenus(); 7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (child->id() == EmptyMenuMenuItem::kEmptyMenuItemViewID) { 7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) submenu_->RemoveChildView(child); 7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete child; 7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) child = NULL; 7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MenuItemView::AdjustBoundsForRTLUI(gfx::Rect* rect) const { 7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rect->set_x(GetMirroredXForRect(*rect)); 7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void MenuItemView::PaintButton(gfx::Canvas* canvas, PaintButtonMode mode) { 7762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const MenuConfig& config = GetMenuConfig(); 7772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool render_selection = 7782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (mode == PB_NORMAL && IsSelected() && 7792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) parent_menu_item_->GetSubmenu()->GetShowSelection(this) && 7802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (NonIconChildViewsCount() == 0)); 7812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int icon_x = config.item_left_margin + left_icon_margin_; 7832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int top_margin = GetTopMargin(); 7842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int bottom_margin = GetBottomMargin(); 7852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int icon_y = top_margin + (height() - config.item_top_margin - 7862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bottom_margin - config.check_height) / 2; 7872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int icon_height = config.check_height; 7882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int available_height = height() - top_margin - bottom_margin; 7892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MenuDelegate *delegate = GetDelegate(); 7902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Render the background. As MenuScrollViewContainer draws the background, we 7912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // only need the background when we want it to look different, as when we're 7922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // selected. 7932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ui::NativeTheme* native_theme = GetNativeTheme(); 7942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SkColor override_color; 7952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (delegate && delegate->GetBackgroundColor(GetCommand(), 7962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) render_selection, 7972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &override_color)) { 7982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) canvas->DrawColor(override_color); 7992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else if (render_selection) { 800c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) gfx::Rect item_bounds(0, 0, width(), height()); 801c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) AdjustBoundsForRTLUI(&item_bounds); 802b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 803b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) native_theme->Paint(canvas->sk_canvas(), 804b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) ui::NativeTheme::kMenuItemBackground, 805b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) ui::NativeTheme::kHovered, 806b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) item_bounds, 807b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) ui::NativeTheme::ExtraParams()); 8082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 8092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 8102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Render the check. 8112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (type_ == CHECKBOX && delegate->IsItemChecked(GetCommand())) { 8122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const gfx::ImageSkia* check = GetMenuCheckImage(); 8132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Don't use config.check_width here as it's padded 8142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // to force more padding (AURA). 8152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Rect check_bounds(icon_x, icon_y, check->width(), icon_height); 8162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) AdjustBoundsForRTLUI(&check_bounds); 8172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) canvas->DrawImageInt(*check, check_bounds.x(), check_bounds.y()); 8182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else if (type_ == RADIO) { 8192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const gfx::ImageSkia* image = 8202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GetRadioButtonImage(delegate->IsItemChecked(GetCommand())); 8212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Rect radio_bounds(icon_x, 8222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) top_margin + 8232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (height() - top_margin - bottom_margin - 8242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) image->height()) / 2, 8252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) image->width(), 8262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) image->height()); 8272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) AdjustBoundsForRTLUI(&radio_bounds); 8282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) canvas->DrawImageInt(*image, radio_bounds.x(), radio_bounds.y()); 8292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 8302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 8312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Render the foreground. 832c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ui::NativeTheme::ColorId color_id = 833c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ui::NativeTheme::kColorId_DisabledMenuItemForegroundColor; 834c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (enabled()) { 835c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) color_id = render_selection ? 836c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ui::NativeTheme::kColorId_SelectedMenuItemForegroundColor: 837c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ui::NativeTheme::kColorId_EnabledMenuItemForegroundColor; 838c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 839c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SkColor fg_color = native_theme->GetSystemColor(color_id); 8402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SkColor override_foreground_color; 8412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (delegate && delegate->GetForegroundColor(GetCommand(), 8422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) render_selection, 8432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &override_foreground_color)) 8442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) fg_color = override_foreground_color; 8452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 8462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const gfx::Font& font = GetFont(); 8477dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch int accel_width = parent_menu_item_->GetSubmenu()->max_minor_text_width(); 848c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int label_start = GetLabelStartForThisItem(); 8492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 8502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int width = this->width() - label_start - accel_width - 8512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (!delegate || 8522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) delegate->ShouldReserveSpaceForSubmenuIndicator() ? 8532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) item_right_margin_ : config.arrow_to_edge_padding); 8542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Rect text_bounds(label_start, top_margin, width, available_height); 8552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) text_bounds.set_x(GetMirroredXForRect(text_bounds)); 8562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int flags = GetDrawStringFlags(); 8572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (mode == PB_FOR_DRAG) 8582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) flags |= gfx::Canvas::NO_SUBPIXEL_RENDERING; 8592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) canvas->DrawStringInt(title(), font, fg_color, 8602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) text_bounds.x(), text_bounds.y(), text_bounds.width(), 8612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) text_bounds.height(), flags); 8622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 8637dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch PaintMinorText(canvas, render_selection); 8642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 8652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Render the submenu indicator (arrow). 8662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (HasSubmenu()) { 8672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Rect arrow_bounds(this->width() - config.arrow_width - 8682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) config.arrow_to_edge_padding, 8692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) top_margin + (available_height - 8702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) config.arrow_width) / 2, 8712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) config.arrow_width, height()); 8722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) AdjustBoundsForRTLUI(&arrow_bounds); 8732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) canvas->DrawImageInt(*GetSubmenuArrowImage(), 8742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) arrow_bounds.x(), arrow_bounds.y()); 8752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 8762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 8772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 8787dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid MenuItemView::PaintMinorText(gfx::Canvas* canvas, 8797dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch bool render_selection) { 8807dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch string16 minor_text = GetMinorText(); 8817dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (minor_text.empty()) 8825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 8835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const gfx::Font& font = GetFont(); 8855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int available_height = height() - GetTopMargin() - GetBottomMargin(); 8865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int max_accel_width = 8877dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch parent_menu_item_->GetSubmenu()->max_minor_text_width(); 8885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const MenuConfig& config = GetMenuConfig(); 8895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int accel_right_margin = config.align_arrow_and_shortcut ? 8905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) config.arrow_to_edge_padding : item_right_margin_; 8915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Rect accel_bounds(width() - accel_right_margin - max_accel_width, 8925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetTopMargin(), max_accel_width, available_height); 8935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) accel_bounds.set_x(GetMirroredXForRect(accel_bounds)); 8945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int flags = GetDrawStringFlags(); 8955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) flags &= ~(gfx::Canvas::TEXT_ALIGN_RIGHT | gfx::Canvas::TEXT_ALIGN_LEFT); 8965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (base::i18n::IsRTL()) 8975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) flags |= gfx::Canvas::TEXT_ALIGN_LEFT; 8985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 8995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) flags |= gfx::Canvas::TEXT_ALIGN_RIGHT; 9005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) canvas->DrawStringInt( 9017dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch minor_text, 902c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) font, 903c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GetNativeTheme()->GetSystemColor(render_selection ? 904c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ui::NativeTheme::kColorId_SelectedMenuItemForegroundColor : 90590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ui::NativeTheme::kColorId_ButtonDisabledColor), 906c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) accel_bounds.x(), 907c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) accel_bounds.y(), 908c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) accel_bounds.width(), 909c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) accel_bounds.height(), 910c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) flags); 9115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MenuItemView::DestroyAllMenuHosts() { 9145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!HasSubmenu()) 9155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 9165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) submenu_->Close(); 9185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0, item_count = submenu_->GetMenuItemCount(); i < item_count; 9195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++i) { 9205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) submenu_->GetMenuItemAt(i)->DestroyAllMenuHosts(); 9215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int MenuItemView::GetTopMargin() { 9255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (top_margin_ >= 0) 9265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return top_margin_; 9275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MenuItemView* root = GetRootMenuItem(); 9295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return root && root->has_icons_ 9305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ? GetMenuConfig().item_top_margin : 9315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetMenuConfig().item_no_icon_top_margin; 9325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int MenuItemView::GetBottomMargin() { 9355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (bottom_margin_ >= 0) 9365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return bottom_margin_; 9375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MenuItemView* root = GetRootMenuItem(); 9395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return root && root->has_icons_ 9405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ? GetMenuConfig().item_bottom_margin : 9415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetMenuConfig().item_no_icon_bottom_margin; 9425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gfx::Size MenuItemView::GetChildPreferredSize() { 9455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!has_children()) 9465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return gfx::Size(); 9475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (IsContainer()) { 9495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) View* child = child_at(0); 9505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return child->GetPreferredSize(); 9515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int width = 0; 9545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < child_count(); ++i) { 9555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) View* child = child_at(i); 9565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (icon_view_ && (icon_view_ == child)) 9575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 9585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (i) 9595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) width += kChildXPadding; 9605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) width += child->GetPreferredSize().width(); 9615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int height = 0; 9635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (icon_view_) 9645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) height = icon_view_->GetPreferredSize().height(); 9655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If there is no icon view it returns a height of 0 to indicate that 9675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // we should use the title height instead. 9685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return gfx::Size(width, height); 9695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)MenuItemView::MenuItemDimensions MenuItemView::CalculateDimensions() { 9725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Size child_size = GetChildPreferredSize(); 9735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MenuItemDimensions dimensions; 9755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Get the container height. 9765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dimensions.children_width = child_size.width(); 9772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) dimensions.height = child_size.height(); 9782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Adjust item content height if menu has both items with and without icons. 9792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // This way all menu items will have the same height. 9802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!icon_view_ && GetRootMenuItem()->has_icons()) { 9812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) dimensions.height = std::max(dimensions.height, 9822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GetMenuConfig().check_height); 9832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 9842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) dimensions.height += GetBottomMargin() + GetTopMargin(); 9855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // In case of a container, only the container size needs to be filled. 9875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (IsContainer()) 9885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return dimensions; 9895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Determine the length of the label text. 9915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const gfx::Font& font = GetFont(); 9922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 9932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Get Icon margin overrides for this particular item. 9942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const MenuDelegate* delegate = GetDelegate(); 9952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (delegate) { 9962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) delegate->GetHorizontalIconMargins(command_, 9972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) icon_area_width_, 9982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &left_icon_margin_, 9992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &right_icon_margin_); 10002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 10012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) left_icon_margin_ = 0; 10022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) right_icon_margin_ = 0; 10032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1004c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int label_start = GetLabelStartForThisItem(); 10052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 10062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) dimensions.standard_width = font.GetStringWidth(title_) + label_start + 10075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) item_right_margin_; 10087dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // Determine the length of the right-side text. 10097dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch string16 minor_text = GetMinorText(); 10107dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch dimensions.minor_text_width = 10117dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch minor_text.empty() ? 0 : GetFont().GetStringWidth(minor_text); 10125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Determine the height to use. 10145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dimensions.height = std::max(dimensions.height, 10155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) font.GetHeight() + GetBottomMargin() + GetTopMargin()); 10165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dimensions.height = std::max(dimensions.height, 10175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetMenuConfig().item_min_height); 10185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return dimensions; 10195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1021c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)int MenuItemView::GetLabelStartForThisItem() { 1022c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int label_start = label_start_ + left_icon_margin_ + right_icon_margin_; 1023c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if ((type_ == CHECKBOX || type_ == RADIO) && icon_view_) { 1024c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) label_start += icon_view_->size().width() + 1025c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GetMenuConfig().icon_to_label_padding; 1026c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 1027c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return label_start; 1028c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 1029c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 10307dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochstring16 MenuItemView::GetMinorText() { 10315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (id() == kEmptyMenuItemViewID) { 10325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Don't query the delegate for menus that represent no children. 10335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return string16(); 10345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ui::Accelerator accelerator; 10377dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (GetMenuConfig().show_accelerators && GetDelegate() && GetCommand() && 10387dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch GetDelegate()->GetAccelerator(GetCommand(), &accelerator)) { 10397dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return accelerator.GetShortcutText(); 10407dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 10417dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 10427dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return subtitle_; 10435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool MenuItemView::IsContainer() const { 10465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Let the first child take over |this| when we only have one child and no 10475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // title. 10485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (NonIconChildViewsCount() == 1) && title_.empty(); 10495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int MenuItemView::NonIconChildViewsCount() const { 10525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Note that what child_count() returns is the number of children, 10535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // not the number of menu items. 10545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return child_count() - (icon_view_ ? 1 : 0); 10555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int MenuItemView::GetMaxIconViewWidth() const { 10585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int width = 0; 10595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < submenu_->GetMenuItemCount(); ++i) { 10605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MenuItemView* menu_item = submenu_->GetMenuItemAt(i); 10615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int temp_width = 0; 10625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (menu_item->HasSubmenu()) { 10635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) temp_width = menu_item->GetMaxIconViewWidth(); 10645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (menu_item->icon_view()) { 10655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) temp_width = menu_item->icon_view()->GetPreferredSize().width(); 10665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) width = std::max(width, temp_width); 10685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return width; 10705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool MenuItemView::HasChecksOrRadioButtons() const { 10732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (int i = 0; i < submenu_->GetMenuItemCount(); ++i) { 10742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MenuItemView* menu_item = submenu_->GetMenuItemAt(i); 10752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (menu_item->HasSubmenu()) { 10762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (menu_item->HasChecksOrRadioButtons()) 10772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 10782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 10792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const Type& type = menu_item->GetType(); 10802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (type == CHECKBOX || type == RADIO) 10812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 10822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 10832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 10842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 10852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 10862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 10875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace views 1088