Chromium Code Reviews| 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 |
| +gfx::ImageSkia MenuItemView::empty_icon_; |
| + |
| +// static |
| +int MenuItemView::icon_width_ = 0; |
|
Aaron Boodman
2012/06/21 08:15:30
Having this stuff be static is really weird, but I
|
| + |
| // 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) { |
| + 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; |
|
Aaron Boodman
2012/06/21 08:15:30
If you have an icon_view_ member, you can remove t
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(); |
| + 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 |
| // 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 |