 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..a15ccc03bf85ad6da71b4ce5b3275ad68c7a6481 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" | 
| @@ -62,6 +63,12 @@ const int MenuItemView::kMenuItemViewID = 1001; | 
| const int MenuItemView::kEmptyMenuItemViewID = | 
| MenuItemView::kMenuItemViewID + 1; | 
| +//static | 
| 
sky
2012/06/20 21:52:40
// static
 
yefimt
2012/06/22 22:14:40
With GetIcon() gone we dont need an empty icon any
 | 
| +gfx::ImageSkia MenuItemView::empty_icon_; | 
| + | 
| +// static | 
| +int MenuItemView::icon_width_ = 0; | 
| + | 
| // static | 
| int MenuItemView::label_start_; | 
| @@ -86,6 +93,7 @@ MenuItemView::MenuItemView(MenuDelegate* delegate) | 
| has_mnemonics_(false), | 
| show_mnemonics_(false), | 
| has_icons_(false), | 
| + icon_view_type_(NONE), | 
| top_margin_(-1), | 
| bottom_margin_(-1), | 
| requested_menu_position_(POSITION_BEST_FIT), | 
| @@ -219,7 +227,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,10 +369,45 @@ void MenuItemView::SetIcon(const gfx::ImageSkia& icon, int item_id) { | 
| } | 
| void MenuItemView::SetIcon(const gfx::ImageSkia& icon) { | 
| - icon_ = icon; | 
| + if (icon_view_type_ == IMAGE_VIEW) { | 
| 
sky
2012/06/20 21:52:40
Make this always create a new ImageView, unless th
 
yefimt
2012/06/22 22:14:40
Done.
 | 
| + View* view = GetIconView(); | 
| + static_cast<ImageView*>(view)->SetImage(&icon); | 
| + return; | 
| + } | 
| + | 
| + ImageView* icon_view = new ImageView(); | 
| + icon_view->SetImage(&icon); | 
| + SetIconView(icon_view); | 
| + icon_view_type_ = IMAGE_VIEW; | 
| +} | 
| + | 
| +const gfx::ImageSkia& MenuItemView::GetIcon() { | 
| + if (icon_view_type_ != IMAGE_VIEW) | 
| + return empty_icon_; | 
| + | 
| + View* view = GetIconView(); | 
| + return static_cast<ImageView*>(view)->GetImage(); | 
| +} | 
| + | 
| +void MenuItemView::SetIconView(View* icon_view) { | 
| + DCHECK(icon_view); | 
| + View* child_view = GetIconView(); | 
| + if (child_view) { | 
| + RemoveChildView(child_view); | 
| + delete child_view; | 
| + } | 
| + AddChildViewAt(icon_view, 0); | 
| + icon_view_type_ = SOME_VIEW; | 
| SchedulePaint(); | 
| } | 
| +View* MenuItemView::GetIconView() { | 
| + if (icon_view_type_ == NONE) | 
| + return NULL; | 
| + | 
| + return child_at(0); | 
| +} | 
| + | 
| void MenuItemView::OnPaint(gfx::Canvas* canvas) { | 
| PaintButton(canvas, PB_NORMAL); | 
| } | 
| @@ -479,12 +523,24 @@ void MenuItemView::Layout() { | 
| // Child views are laid out right aligned and given the full height. To | 
| // right align start with the last view and progress to the first. | 
| int x = width() - (use_right_margin_ ? item_right_margin_ : 0); | 
| - for (int i = child_count() - 1; i >= 0; --i) { | 
| + int first_non_icon_view = (icon_view_type_ != NONE) ? 1 : 0; | 
| 
sky
2012/06/20 21:52:40
I don't like assuming the icon_view is always firs
 
yefimt
2012/06/22 22:14:40
Done.
 | 
| + for (int i = child_count() - 1; i >= first_non_icon_view; --i) { | 
| View* child = child_at(i); | 
| 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_type_ != NONE) { | 
| + View* child = child_at(0); | 
| + child->SizeToPreferredSize(); | 
| + gfx::Size size = child->GetPreferredSize(); | 
| + int x = config.item_left_margin + (icon_width_ - size.width()) / 2; | 
| + int y = (height() + GetTopMargin() - GetBottomMargin() - | 
| + size.height()) / 2; | 
| + child->SetPosition(gfx::Point(x, y)); | 
| + } | 
| } | 
| } | 
| @@ -501,6 +557,18 @@ void MenuItemView::SetMargins(int top_margin, int bottom_margin) { | 
| pref_size_.SetSize(0,0); | 
| } | 
| +Border* MenuItemView::GetMenuBorder() { | 
| + return Border::CreateEmptyBorder( | 
| + MenuConfig::instance().submenu_vertical_margin_size, | 
| + MenuConfig::instance().submenu_horizontal_margin_size, | 
| + MenuConfig::instance().submenu_vertical_margin_size, | 
| + MenuConfig::instance().submenu_horizontal_margin_size); | 
| +} | 
| + | 
| +Background* MenuItemView::GetMenuBackground() { | 
| + return NULL; | 
| +} | 
| + | 
| MenuItemView::MenuItemView(MenuItemView* parent, | 
| int command, | 
| MenuItemView::Type type) | 
| @@ -515,6 +583,7 @@ MenuItemView::MenuItemView(MenuItemView* parent, | 
| has_mnemonics_(false), | 
| show_mnemonics_(false), | 
| has_icons_(false), | 
| + icon_view_type_(NONE), | 
| top_margin_(-1), | 
| bottom_margin_(-1), | 
| requested_menu_position_(POSITION_BEST_FIT), | 
| @@ -534,21 +603,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_width_ = config.check_width; | 
| + if (has_icons_) { | 
| + for (int i = 0; i < submenu_->GetMenuItemCount(); ++i) { | 
| + MenuItemView* menu_item = submenu_->GetMenuItemAt(i); | 
| + if (menu_item->icon_view_type_ != NONE) | 
| + icon_width_ = std::max(icon_width_, | 
| + menu_item->child_at(0)->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_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_width_ + | 
| + (has_icons_ ? config.icon_to_label_padding : 0); | 
| if (config.render_gutter) | 
| label_start_ += config.gutter_width + config.gutter_to_label; | 
| @@ -599,7 +677,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(); | 
| } | 
| } | 
| @@ -734,14 +812,20 @@ gfx::Size MenuItemView::GetChildPreferredSize() { | 
| } | 
| int width = 0; | 
| - for (int i = 0; i < child_count(); ++i) { | 
| + int i = (icon_view_type_ != NONE) ? 1 : 0; | 
| + for (; i < child_count(); ++i) { | 
| if (i) | 
| width += kChildXPadding; | 
| - width += child_at(i)->GetPreferredSize().width(); | 
| + gfx::Size size = child_at(i)->GetPreferredSize(); | 
| 
sky
2012/06/20 21:52:40
revert to old here.
 
yefimt
2012/06/22 22:14:40
Done.
 | 
| + width += size.width(); | 
| } | 
| + int height = 0; | 
| + if (icon_view_type_ != NONE) | 
| + height = child_at(0)->GetPreferredSize().height(); | 
| + | 
| // Return a height of 0 to indicate that we should use the title height | 
| 
sky
2012/06/20 21:52:40
Update this comment.
 
yefimt
2012/06/22 22:14:40
Done.
 | 
| // instead. | 
| - return gfx::Size(width, 0); | 
| + return gfx::Size(width, height); | 
| } | 
| gfx::Size MenuItemView::CalculatePreferredSize() { | 
| @@ -783,4 +867,8 @@ bool MenuItemView::IsContainer() const { | 
| return child_count() == 1 && title_.empty(); | 
| } | 
| +bool MenuItemView::HasNonIconChildViews() { | 
| + return child_count() > ((icon_view_type_ != NONE) ? 1 : 0); | 
| +} | 
| + | 
| } // namespace views |