 Chromium Code Reviews
 Chromium Code Reviews Issue 10532171:
  Added support for icon views (view used instead of icon in a menu item).  (Closed) 
  Base URL: svn://svn.chromium.org/chrome/trunk/src
    
  
    Issue 10532171:
  Added support for icon views (view used instead of icon in a menu item).  (Closed) 
  Base URL: svn://svn.chromium.org/chrome/trunk/src| Index: ui/views/controls/menu/menu_item_view.cc | 
| diff --git a/ui/views/controls/menu/menu_item_view.cc b/ui/views/controls/menu/menu_item_view.cc | 
| index b5f81117e569010cab74e08c60ef3a17419eb70f..c0c5aaf546fbad93f264d9d8daca0b82b5ef603f 100644 | 
| --- a/ui/views/controls/menu/menu_item_view.cc | 
| +++ b/ui/views/controls/menu/menu_item_view.cc | 
| @@ -13,6 +13,7 @@ | 
| #include "ui/base/models/menu_model.h" | 
| #include "ui/gfx/canvas.h" | 
| #include "ui/views/controls/button/menu_button.h" | 
| +#include "ui/views/controls/image_view.h" | 
| #include "ui/views/controls/menu/menu_config.h" | 
| #include "ui/views/controls/menu/menu_controller.h" | 
| #include "ui/views/controls/menu/menu_separator.h" | 
| @@ -63,6 +64,9 @@ const int MenuItemView::kEmptyMenuItemViewID = | 
| MenuItemView::kMenuItemViewID + 1; | 
| // static | 
| +int MenuItemView::icon_area_width_ = 0; | 
| + | 
| +// static | 
| int MenuItemView::label_start_; | 
| // static | 
| @@ -86,6 +90,7 @@ MenuItemView::MenuItemView(MenuDelegate* delegate) | 
| has_mnemonics_(false), | 
| show_mnemonics_(false), | 
| has_icons_(false), | 
| + icon_view_(NULL), | 
| top_margin_(-1), | 
| bottom_margin_(-1), | 
| requested_menu_position_(POSITION_BEST_FIT), | 
| @@ -219,7 +224,8 @@ MenuItemView* MenuItemView::AddMenuItemAt(int index, | 
| item->SetTitle(GetDelegate()->GetLabel(item_id)); | 
| else | 
| item->SetTitle(label); | 
| - item->SetIcon(icon); | 
| + if (!icon.empty()) | 
| + item->SetIcon(icon); | 
| if (type == SUBMENU) | 
| item->CreateSubmenu(); | 
| submenu_->AddChildViewAt(item, index); | 
| @@ -360,7 +366,26 @@ void MenuItemView::SetIcon(const gfx::ImageSkia& icon, int item_id) { | 
| } | 
| void MenuItemView::SetIcon(const gfx::ImageSkia& icon) { | 
| - icon_ = icon; | 
| + if (icon.empty()) { | 
| + SetIconView(NULL); | 
| + return; | 
| + } | 
| + | 
| + ImageView* icon_view = new ImageView(); | 
| + icon_view->SetImage(&icon); | 
| + SetIconView(icon_view); | 
| +} | 
| + | 
| +void MenuItemView::SetIconView(View* icon_view) { | 
| + if (icon_view_) { | 
| + RemoveChildView(icon_view_); | 
| + delete icon_view_; | 
| + icon_view_ = NULL; | 
| + } | 
| + if (icon_view) { | 
| + AddChildView(icon_view); | 
| + icon_view_ = icon_view; | 
| + } | 
| SchedulePaint(); | 
| } | 
| @@ -481,10 +506,22 @@ void MenuItemView::Layout() { | 
| int x = width() - (use_right_margin_ ? item_right_margin_ : 0); | 
| for (int i = child_count() - 1; i >= 0; --i) { | 
| View* child = child_at(i); | 
| + if (icon_view_ && (icon_view_ == child)) | 
| + continue; | 
| int width = child->GetPreferredSize().width(); | 
| child->SetBounds(x - width, 0, width, height()); | 
| x -= width - kChildXPadding; | 
| } | 
| + // Position icon_view | 
| + const MenuConfig& config = MenuConfig::instance(); | 
| + if (icon_view_) { | 
| + icon_view_->SizeToPreferredSize(); | 
| + gfx::Size size = icon_view_->GetPreferredSize(); | 
| + int x = config.item_left_margin + (icon_area_width_ - size.width()) / 2; | 
| + int y = (height() + GetTopMargin() - GetBottomMargin() - | 
| + size.height()) / 2; | 
| + icon_view_->SetPosition(gfx::Point(x, y)); | 
| + } | 
| } | 
| } | 
| @@ -515,6 +552,7 @@ MenuItemView::MenuItemView(MenuItemView* parent, | 
| has_mnemonics_(false), | 
| show_mnemonics_(false), | 
| has_icons_(false), | 
| + icon_view_(NULL), | 
| top_margin_(-1), | 
| bottom_margin_(-1), | 
| requested_menu_position_(POSITION_BEST_FIT), | 
| @@ -534,21 +572,30 @@ std::string MenuItemView::GetClassName() const { | 
| // Calculates all sizes that we can from the OS. | 
| // | 
| // This is invoked prior to Running a menu. | 
| -void MenuItemView::UpdateMenuPartSizes(bool has_icons) { | 
| +void MenuItemView::UpdateMenuPartSizes() { | 
| MenuConfig::Reset(); | 
| const MenuConfig& config = MenuConfig::instance(); | 
| item_right_margin_ = config.label_to_arrow_padding + config.arrow_width + | 
| config.arrow_to_edge_padding; | 
| + icon_area_width_ = config.check_width; | 
| + if (has_icons_) { | 
| + for (int i = 0; i < submenu_->GetMenuItemCount(); ++i) { | 
| 
sky
2012/06/26 23:49:54
This needs to recurse through submenus.
 
yefimt
2012/06/27 22:48:12
Done.
 | 
| + MenuItemView* menu_item = submenu_->GetMenuItemAt(i); | 
| + if (menu_item->icon_view()) | 
| + icon_area_width_ = std::max(icon_area_width_, | 
| + menu_item->icon_view()->GetPreferredSize().width()); | 
| + } | 
| + } | 
| if (config.always_use_icon_to_label_padding) | 
| - label_start_ = config.item_left_margin + config.check_width + | 
| + label_start_ = config.item_left_margin + icon_area_width_ + | 
| config.icon_to_label_padding; | 
| else | 
| // If there are no icons don't pad by the icon to label padding. This | 
| // makes us look close to system menus. | 
| - label_start_ = config.item_left_margin + config.check_width + | 
| - (has_icons ? config.icon_to_label_padding : 0); | 
| + label_start_ = config.item_left_margin + icon_area_width_ + | 
| + (has_icons_ ? config.icon_to_label_padding : 0); | 
| if (config.render_gutter) | 
| label_start_ += config.gutter_width + config.gutter_to_label; | 
| @@ -599,7 +646,7 @@ void MenuItemView::PrepareForRun(bool has_mnemonics, bool show_mnemonics) { | 
| if (!MenuController::GetActiveInstance()) { | 
| // Only update the menu size if there are no menus showing, otherwise | 
| // things may shift around. | 
| - UpdateMenuPartSizes(has_icons_); | 
| + UpdateMenuPartSizes(); | 
| } | 
| } | 
| @@ -735,13 +782,20 @@ gfx::Size MenuItemView::GetChildPreferredSize() { | 
| int width = 0; | 
| for (int i = 0; i < child_count(); ++i) { | 
| + View* child = child_at(i); | 
| + if (icon_view_ && (icon_view_ == child)) | 
| + continue; | 
| if (i) | 
| width += kChildXPadding; | 
| - width += child_at(i)->GetPreferredSize().width(); | 
| + width += child->GetPreferredSize().width(); | 
| } | 
| - // Return a height of 0 to indicate that we should use the title height | 
| - // instead. | 
| - return gfx::Size(width, 0); | 
| + int height = 0; | 
| + if (icon_view_) | 
| + height = icon_view_->GetPreferredSize().height(); | 
| + | 
| + // If there is no icon view it returns a height of 0 to indicate that | 
| + // we should use the title height instead. | 
| + return gfx::Size(width, height); | 
| } | 
| gfx::Size MenuItemView::CalculatePreferredSize() { | 
| @@ -778,9 +832,14 @@ string16 MenuItemView::GetAcceleratorText() { | 
| bool MenuItemView::IsContainer() const { | 
| // Let the first child take over |this| when we only have one child and no | 
| - // title. Note that what child_count() returns is the number of children, | 
| + // title. | 
| + return NonIconChildViewsCount() == 1 && title_.empty(); | 
| +} | 
| + | 
| +int MenuItemView::NonIconChildViewsCount() const { | 
| + // Note that what child_count() returns is the number of children, | 
| // not the number of menu items. | 
| - return child_count() == 1 && title_.empty(); | 
| + return child_count() - (icon_view_ ? 1 : 0); | 
| } | 
| } // namespace views |