summaryrefslogtreecommitdiffstats
path: root/views/controls
diff options
context:
space:
mode:
authorsky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-06-09 22:46:50 +0000
committersky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-06-09 22:46:50 +0000
commit440d8dba5acdec78133af93ca788a9e995fedb49 (patch)
tree994f2a5206ed93f3c79bb4ac57a7e63aa5d5fc37 /views/controls
parent02a46a3c1f824675fe72f5fe6a7b95694452a1eb (diff)
downloadchromium_src-440d8dba5acdec78133af93ca788a9e995fedb49.zip
chromium_src-440d8dba5acdec78133af93ca788a9e995fedb49.tar.gz
chromium_src-440d8dba5acdec78133af93ca788a9e995fedb49.tar.bz2
Adds support for showing accelerators in bookmark menus.
BUG=45734 TEST=none Review URL: http://codereview.chromium.org/2742003 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@49335 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'views/controls')
-rw-r--r--views/controls/menu/menu_config.h42
-rw-r--r--views/controls/menu/menu_delegate.h6
-rw-r--r--views/controls/menu/menu_item_view.cc42
-rw-r--r--views/controls/menu/menu_item_view.h10
-rw-r--r--views/controls/menu/menu_item_view_gtk.cc5
-rw-r--r--views/controls/menu/menu_item_view_win.cc5
-rw-r--r--views/controls/menu/submenu_view.cc17
-rw-r--r--views/controls/menu/submenu_view.h7
8 files changed, 110 insertions, 24 deletions
diff --git a/views/controls/menu/menu_config.h b/views/controls/menu/menu_config.h
index adcf851..cd41fea 100644
--- a/views/controls/menu/menu_config.h
+++ b/views/controls/menu/menu_config.h
@@ -12,24 +12,26 @@ namespace views {
// Layout type information for menu items. Use the instance() method to obtain
// the MenuConfig for the current platform.
struct MenuConfig {
- MenuConfig() : item_top_margin(3),
- item_bottom_margin(4),
- item_no_icon_top_margin(1),
- item_no_icon_bottom_margin(3),
- item_left_margin(4),
- label_to_arrow_padding(10),
- arrow_to_edge_padding(5),
- icon_to_label_padding(8),
- gutter_to_label(5),
- check_width(16),
- check_height(16),
- arrow_height(9),
- arrow_width(9),
- gutter_width(0),
- separator_height(6),
- render_gutter(false),
- show_mnemonics(false),
- scroll_arrow_height(3) {
+ MenuConfig()
+ : item_top_margin(3),
+ item_bottom_margin(4),
+ item_no_icon_top_margin(1),
+ item_no_icon_bottom_margin(3),
+ item_left_margin(4),
+ label_to_arrow_padding(10),
+ arrow_to_edge_padding(5),
+ icon_to_label_padding(8),
+ gutter_to_label(5),
+ check_width(16),
+ check_height(16),
+ arrow_height(9),
+ arrow_width(9),
+ gutter_width(0),
+ separator_height(6),
+ render_gutter(false),
+ show_mnemonics(false),
+ scroll_arrow_height(3),
+ label_to_accelerator_padding(10) {
}
// Resets the single shared MenuConfig instance. The next time instance() is
@@ -94,6 +96,10 @@ struct MenuConfig {
// Height of the scroll arrow.
int scroll_arrow_height;
+ // Padding between the label and accelerator. Only used if there is an
+ // accelerator.
+ int label_to_accelerator_padding;
+
private:
// Creates and configures a new MenuConfig as appropriate for the current
// platform.
diff --git a/views/controls/menu/menu_delegate.h b/views/controls/menu/menu_delegate.h
index 2ad1feb..a06b4a0 100644
--- a/views/controls/menu/menu_delegate.h
+++ b/views/controls/menu/menu_delegate.h
@@ -55,6 +55,12 @@ class MenuDelegate : Controller {
return std::wstring();
}
+ // If there is an accelerator for the menu item with id |id| it is set in
+ // |accelerator| and true is returned.
+ virtual bool GetAccelerator(int id, Accelerator* accelerator) {
+ return false;
+ }
+
// Shows the context menu with the specified id. This is invoked when the
// user does the appropriate gesture to show a context menu. The id
// identifies the id of the menu to show the context menu for.
diff --git a/views/controls/menu/menu_item_view.cc b/views/controls/menu/menu_item_view.cc
index f2e269d..ca224c2 100644
--- a/views/controls/menu/menu_item_view.cc
+++ b/views/controls/menu/menu_item_view.cc
@@ -7,6 +7,7 @@
#include "app/l10n_util.h"
#include "gfx/canvas.h"
#include "grit/app_strings.h"
+#include "views/controls/button/text_button.h"
#include "views/controls/menu/menu_config.h"
#include "views/controls/menu/menu_controller.h"
#include "views/controls/menu/menu_separator.h"
@@ -24,8 +25,8 @@ namespace {
class EmptyMenuMenuItem : public MenuItemView {
public:
- explicit EmptyMenuMenuItem(MenuItemView* parent) :
- MenuItemView(parent, 0, NORMAL) {
+ explicit EmptyMenuMenuItem(MenuItemView* parent)
+ : MenuItemView(parent, 0, NORMAL) {
SetTitle(l10n_util::GetString(IDS_APP_MENU_EMPTY_SUBMENU));
// Set this so that we're not identified as a normal menu item.
SetID(kEmptyMenuItemViewID);
@@ -312,6 +313,11 @@ void MenuItemView::Layout() {
}
}
+int MenuItemView::GetAcceleratorTextWidth() {
+ std::wstring text = GetAcceleratorText();
+ return text.empty() ? 0 : MenuConfig::instance().font.GetStringWidth(text);
+}
+
MenuItemView::MenuItemView(MenuItemView* parent,
int command,
MenuItemView::Type type) {
@@ -452,6 +458,31 @@ void MenuItemView::AdjustBoundsForRTLUI(gfx::Rect* rect) const {
rect->set_x(MirroredLeftPointForRect(*rect));
}
+void MenuItemView::PaintAccelerator(gfx::Canvas* canvas) {
+ std::wstring accel_text = GetAcceleratorText();
+ if (accel_text.empty())
+ return;
+
+ const gfx::Font& font = MenuConfig::instance().font;
+ int available_height = height() - GetTopMargin() - GetBottomMargin();
+ int max_accel_width =
+ parent_menu_item_->GetSubmenu()->max_accelerator_width();
+ gfx::Rect accel_bounds(width() - item_right_margin_ - max_accel_width,
+ GetTopMargin(), max_accel_width, available_height);
+ accel_bounds.set_x(MirroredLeftPointForRect(accel_bounds));
+ int flags = GetRootMenuItem()->GetDrawStringFlags() |
+ gfx::Canvas::TEXT_VALIGN_MIDDLE;
+ flags &= ~(gfx::Canvas::TEXT_ALIGN_RIGHT | gfx::Canvas::TEXT_ALIGN_LEFT);
+ if (base::i18n::IsRTL())
+ flags |= gfx::Canvas::TEXT_ALIGN_LEFT;
+ else
+ flags |= gfx::Canvas::TEXT_ALIGN_RIGHT;
+ canvas->DrawStringInt(
+ accel_text, font, TextButton::kDisabledColor, accel_bounds.x(),
+ accel_bounds.y(), accel_bounds.width(), accel_bounds.height(),
+ flags);
+}
+
void MenuItemView::DestroyAllMenuHosts() {
if (!HasSubmenu())
return;
@@ -491,4 +522,11 @@ int MenuItemView::GetChildPreferredWidth() {
return width;
}
+std::wstring MenuItemView::GetAcceleratorText() {
+ Accelerator accelerator;
+ return (GetDelegate() &&
+ GetDelegate()->GetAccelerator(GetCommand(), &accelerator)) ?
+ accelerator.GetShortcutText() : std::wstring();
+}
+
} // namespace views
diff --git a/views/controls/menu/menu_item_view.h b/views/controls/menu/menu_item_view.h
index c04c341..69d850e 100644
--- a/views/controls/menu/menu_item_view.h
+++ b/views/controls/menu/menu_item_view.h
@@ -246,6 +246,10 @@ class MenuItemView : public View {
// Sizes any child views.
virtual void Layout();
+ // Returns the amount of space needed to accomodate the accelerator. The
+ // space needed for the accelerator is NOT included in the preferred width.
+ int GetAcceleratorTextWidth();
+
protected:
// Creates a MenuItemView. This is used by the various AddXXX methods.
MenuItemView(MenuItemView* parent, int command, Type type);
@@ -289,10 +293,16 @@ class MenuItemView : public View {
// are not rendered.
void Paint(gfx::Canvas* canvas, bool for_drag);
+ // Paints the accelerator.
+ void PaintAccelerator(gfx::Canvas* canvas);
+
// Destroys the window used to display this menu and recursively destroys
// the windows used to display all descendants.
void DestroyAllMenuHosts();
+ // Returns the accelerator text.
+ std::wstring GetAcceleratorText();
+
// Returns the various margins.
int GetTopMargin();
int GetBottomMargin();
diff --git a/views/controls/menu/menu_item_view_gtk.cc b/views/controls/menu/menu_item_view_gtk.cc
index 3f0a830..74255d1 100644
--- a/views/controls/menu/menu_item_view_gtk.cc
+++ b/views/controls/menu/menu_item_view_gtk.cc
@@ -72,9 +72,10 @@ void MenuItemView::Paint(gfx::Canvas* canvas, bool for_drag) {
SkColor fg_color =
IsEnabled() ? TextButton::kEnabledColor : TextButton::kDisabledColor;
#endif
- int width = this->width() - item_right_margin_ - label_start_;
const gfx::Font& font = GetChildViewCount() > 0 ?
MenuConfig::instance().font_with_controls : MenuConfig::instance().font;
+ int accel_width = parent_menu_item_->GetSubmenu()->max_accelerator_width();
+ int width = this->width() - item_right_margin_ - label_start_ - accel_width;
gfx::Rect text_bounds(label_start_, top_margin +
(available_height - font.height()) / 2, width,
font.height());
@@ -84,6 +85,8 @@ void MenuItemView::Paint(gfx::Canvas* canvas, bool for_drag) {
text_bounds.height(),
GetRootMenuItem()->GetDrawStringFlags());
+ PaintAccelerator(canvas);
+
// Render the icon.
if (icon_.width() > 0) {
gfx::Rect icon_bounds(config.item_left_margin,
diff --git a/views/controls/menu/menu_item_view_win.cc b/views/controls/menu/menu_item_view_win.cc
index 4a90c28..90e9755f 100644
--- a/views/controls/menu/menu_item_view_win.cc
+++ b/views/controls/menu/menu_item_view_win.cc
@@ -95,9 +95,10 @@ void MenuItemView::Paint(gfx::Canvas* canvas, bool for_drag) {
SkColor fg_color = NativeTheme::instance()->GetThemeColorWithDefault(
NativeTheme::MENU, MENU_POPUPITEM, state, TMT_TEXTCOLOR,
default_sys_color);
- int width = this->width() - item_right_margin_ - label_start_;
const gfx::Font& font = GetChildViewCount() > 0 ?
MenuConfig::instance().font_with_controls : MenuConfig::instance().font;
+ int accel_width = parent_menu_item_->GetSubmenu()->max_accelerator_width();
+ int width = this->width() - item_right_margin_ - label_start_ - accel_width;
gfx::Rect text_bounds(label_start_, top_margin, width, font.height());
text_bounds.set_x(MirroredLeftPointForRect(text_bounds));
if (for_drag) {
@@ -116,6 +117,8 @@ void MenuItemView::Paint(gfx::Canvas* canvas, bool for_drag) {
GetRootMenuItem()->GetDrawStringFlags());
}
+ PaintAccelerator(canvas);
+
if (icon_.width() > 0) {
gfx::Rect icon_bounds(config.item_left_margin,
top_margin + (height() - top_margin -
diff --git a/views/controls/menu/submenu_view.cc b/views/controls/menu/submenu_view.cc
index 52c9101..d7cf64c 100644
--- a/views/controls/menu/submenu_view.cc
+++ b/views/controls/menu/submenu_view.cc
@@ -5,6 +5,7 @@
#include "views/controls/menu/submenu_view.h"
#include "gfx/canvas.h"
+#include "views/controls/menu/menu_config.h"
#include "views/controls/menu/menu_controller.h"
#include "views/controls/menu/menu_host.h"
#include "views/controls/menu/menu_scroll_view_container.h"
@@ -26,7 +27,8 @@ SubmenuView::SubmenuView(MenuItemView* parent)
host_(NULL),
drop_item_(NULL),
drop_position_(MenuDelegate::DROP_NONE),
- scroll_view_container_(NULL) {
+ scroll_view_container_(NULL),
+ max_accelerator_width_(0) {
DCHECK(parent);
// We'll delete ourselves, otherwise the ScrollView would delete us on close.
set_parent_owned(false);
@@ -91,6 +93,7 @@ gfx::Size SubmenuView::GetPreferredSize() {
if (GetChildViewCount() == 0)
return gfx::Size();
+ max_accelerator_width_ = 0;
int max_width = 0;
int height = 0;
for (int i = 0; i < GetChildViewCount(); ++i) {
@@ -98,9 +101,19 @@ gfx::Size SubmenuView::GetPreferredSize() {
gfx::Size child_pref_size = child->GetPreferredSize();
max_width = std::max(max_width, child_pref_size.width());
height += child_pref_size.height();
+ if (child->GetID() == MenuItemView::kMenuItemViewID) {
+ MenuItemView* menu = static_cast<MenuItemView*>(child);
+ max_accelerator_width_ =
+ std::max(max_accelerator_width_, menu->GetAcceleratorTextWidth());
+ }
+ }
+ if (max_accelerator_width_ > 0) {
+ max_accelerator_width_ +=
+ MenuConfig::instance().label_to_accelerator_padding;
}
gfx::Insets insets = GetInsets();
- return gfx::Size(max_width + insets.width(), height + insets.height());
+ return gfx::Size(max_width + max_accelerator_width_ + insets.width(),
+ height + insets.height());
}
void SubmenuView::DidChangeBounds(const gfx::Rect& previous,
diff --git a/views/controls/menu/submenu_view.h b/views/controls/menu/submenu_view.h
index afef314..62d8aa6 100644
--- a/views/controls/menu/submenu_view.h
+++ b/views/controls/menu/submenu_view.h
@@ -125,6 +125,10 @@ class SubmenuView : public View {
// references to the MenuHost as the MenuHost is about to be deleted.
void MenuHostDestroyed();
+ // Max width of accelerators in child menu items. This doesn't include
+ // children's children, only direct children.
+ int max_accelerator_width() const { return max_accelerator_width_; }
+
// Padding around the edges of the submenu.
static const int kSubmenuBorderSize;
@@ -159,6 +163,9 @@ class SubmenuView : public View {
// Ancestor of the SubmenuView, lazily created.
MenuScrollViewContainer* scroll_view_container_;
+ // See description above getter.
+ int max_accelerator_width_;
+
DISALLOW_COPY_AND_ASSIGN(SubmenuView);
};