Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(20)

Side by Side Diff: ui/views/controls/menu/menu_item_view.cc

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
Patch Set: Added support for icon views (view used instead of icon in a menu item). Created 8 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "ui/views/controls/menu/menu_item_view.h" 5 #include "ui/views/controls/menu/menu_item_view.h"
6 6
7 #include "base/i18n/case_conversion.h" 7 #include "base/i18n/case_conversion.h"
8 #include "base/stl_util.h" 8 #include "base/stl_util.h"
9 #include "base/utf_string_conversions.h" 9 #include "base/utf_string_conversions.h"
10 #include "grit/ui_strings.h" 10 #include "grit/ui_strings.h"
11 #include "ui/base/accessibility/accessible_view_state.h" 11 #include "ui/base/accessibility/accessible_view_state.h"
12 #include "ui/base/l10n/l10n_util.h" 12 #include "ui/base/l10n/l10n_util.h"
13 #include "ui/base/models/menu_model.h" 13 #include "ui/base/models/menu_model.h"
14 #include "ui/gfx/canvas.h" 14 #include "ui/gfx/canvas.h"
15 #include "ui/views/controls/button/menu_button.h" 15 #include "ui/views/controls/button/menu_button.h"
16 #include "ui/views/controls/image_view.h"
16 #include "ui/views/controls/menu/menu_config.h" 17 #include "ui/views/controls/menu/menu_config.h"
17 #include "ui/views/controls/menu/menu_controller.h" 18 #include "ui/views/controls/menu/menu_controller.h"
18 #include "ui/views/controls/menu/menu_separator.h" 19 #include "ui/views/controls/menu/menu_separator.h"
19 #include "ui/views/controls/menu/submenu_view.h" 20 #include "ui/views/controls/menu/submenu_view.h"
20 21
21 namespace views { 22 namespace views {
22 23
23 namespace { 24 namespace {
24 25
25 // EmptyMenuMenuItem --------------------------------------------------------- 26 // EmptyMenuMenuItem ---------------------------------------------------------
(...skipping 30 matching lines...) Expand all
56 // MenuItemView --------------------------------------------------------------- 57 // MenuItemView ---------------------------------------------------------------
57 58
58 // static 59 // static
59 const int MenuItemView::kMenuItemViewID = 1001; 60 const int MenuItemView::kMenuItemViewID = 1001;
60 61
61 // static 62 // static
62 const int MenuItemView::kEmptyMenuItemViewID = 63 const int MenuItemView::kEmptyMenuItemViewID =
63 MenuItemView::kMenuItemViewID + 1; 64 MenuItemView::kMenuItemViewID + 1;
64 65
65 // static 66 // static
67 int MenuItemView::icon_area_width_ = 0;
68
69 // static
66 int MenuItemView::label_start_; 70 int MenuItemView::label_start_;
67 71
68 // static 72 // static
69 int MenuItemView::item_right_margin_; 73 int MenuItemView::item_right_margin_;
70 74
71 // static 75 // static
72 int MenuItemView::pref_menu_height_; 76 int MenuItemView::pref_menu_height_;
73 77
74 // static 78 // static
75 const char MenuItemView::kViewClassName[] = "views/MenuItemView"; 79 const char MenuItemView::kViewClassName[] = "views/MenuItemView";
76 80
77 MenuItemView::MenuItemView(MenuDelegate* delegate) 81 MenuItemView::MenuItemView(MenuDelegate* delegate)
78 : delegate_(delegate), 82 : delegate_(delegate),
79 controller_(NULL), 83 controller_(NULL),
80 canceled_(false), 84 canceled_(false),
81 parent_menu_item_(NULL), 85 parent_menu_item_(NULL),
82 type_(SUBMENU), 86 type_(SUBMENU),
83 selected_(false), 87 selected_(false),
84 command_(0), 88 command_(0),
85 submenu_(NULL), 89 submenu_(NULL),
86 has_mnemonics_(false), 90 has_mnemonics_(false),
87 show_mnemonics_(false), 91 show_mnemonics_(false),
88 has_icons_(false), 92 has_icons_(false),
93 icon_view_(NULL),
89 top_margin_(-1), 94 top_margin_(-1),
90 bottom_margin_(-1), 95 bottom_margin_(-1),
91 requested_menu_position_(POSITION_BEST_FIT), 96 requested_menu_position_(POSITION_BEST_FIT),
92 actual_menu_position_(requested_menu_position_), 97 actual_menu_position_(requested_menu_position_),
93 use_right_margin_(true) { 98 use_right_margin_(true) {
94 // NOTE: don't check the delegate for NULL, UpdateMenuPartSizes supplies a 99 // NOTE: don't check the delegate for NULL, UpdateMenuPartSizes supplies a
95 // NULL delegate. 100 // NULL delegate.
96 Init(NULL, 0, SUBMENU, delegate); 101 Init(NULL, 0, SUBMENU, delegate);
97 } 102 }
98 103
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
212 DCHECK_GE(submenu_->child_count(), index); 217 DCHECK_GE(submenu_->child_count(), index);
213 if (type == SEPARATOR) { 218 if (type == SEPARATOR) {
214 submenu_->AddChildViewAt(new MenuSeparator(), index); 219 submenu_->AddChildViewAt(new MenuSeparator(), index);
215 return NULL; 220 return NULL;
216 } 221 }
217 MenuItemView* item = new MenuItemView(this, item_id, type); 222 MenuItemView* item = new MenuItemView(this, item_id, type);
218 if (label.empty() && GetDelegate()) 223 if (label.empty() && GetDelegate())
219 item->SetTitle(GetDelegate()->GetLabel(item_id)); 224 item->SetTitle(GetDelegate()->GetLabel(item_id));
220 else 225 else
221 item->SetTitle(label); 226 item->SetTitle(label);
222 item->SetIcon(icon); 227 if (!icon.empty())
228 item->SetIcon(icon);
223 if (type == SUBMENU) 229 if (type == SUBMENU)
224 item->CreateSubmenu(); 230 item->CreateSubmenu();
225 submenu_->AddChildViewAt(item, index); 231 submenu_->AddChildViewAt(item, index);
226 return item; 232 return item;
227 } 233 }
228 234
229 void MenuItemView::RemoveMenuItemAt(int index) { 235 void MenuItemView::RemoveMenuItemAt(int index) {
230 DCHECK(submenu_); 236 DCHECK(submenu_);
231 DCHECK_LE(0, index); 237 DCHECK_LE(0, index);
232 DCHECK_GT(submenu_->child_count(), index); 238 DCHECK_GT(submenu_->child_count(), index);
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
353 item->tooltip_ = tooltip; 359 item->tooltip_ = tooltip;
354 } 360 }
355 361
356 void MenuItemView::SetIcon(const gfx::ImageSkia& icon, int item_id) { 362 void MenuItemView::SetIcon(const gfx::ImageSkia& icon, int item_id) {
357 MenuItemView* item = GetMenuItemByID(item_id); 363 MenuItemView* item = GetMenuItemByID(item_id);
358 DCHECK(item); 364 DCHECK(item);
359 item->SetIcon(icon); 365 item->SetIcon(icon);
360 } 366 }
361 367
362 void MenuItemView::SetIcon(const gfx::ImageSkia& icon) { 368 void MenuItemView::SetIcon(const gfx::ImageSkia& icon) {
363 icon_ = icon; 369 if (icon.empty()) {
370 SetIconView(NULL);
371 return;
372 }
373
374 ImageView* icon_view = new ImageView();
375 icon_view->SetImage(&icon);
376 SetIconView(icon_view);
377 }
378
379 void MenuItemView::SetIconView(View* icon_view) {
380 if (icon_view_) {
381 RemoveChildView(icon_view_);
382 delete icon_view_;
383 icon_view_ = NULL;
384 }
385 if (icon_view) {
386 AddChildView(icon_view);
387 icon_view_ = icon_view;
388 }
364 SchedulePaint(); 389 SchedulePaint();
365 } 390 }
366 391
392 View* MenuItemView::GetIconView() {
393 return icon_view_;
394 }
395
367 void MenuItemView::OnPaint(gfx::Canvas* canvas) { 396 void MenuItemView::OnPaint(gfx::Canvas* canvas) {
368 PaintButton(canvas, PB_NORMAL); 397 PaintButton(canvas, PB_NORMAL);
369 } 398 }
370 399
371 gfx::Size MenuItemView::GetPreferredSize() { 400 gfx::Size MenuItemView::GetPreferredSize() {
372 if (pref_size_.IsEmpty()) 401 if (pref_size_.IsEmpty())
373 pref_size_ = CalculatePreferredSize(); 402 pref_size_ = CalculatePreferredSize();
374 return pref_size_; 403 return pref_size_;
375 } 404 }
376 405
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
474 if (IsContainer()) { 503 if (IsContainer()) {
475 View* child = child_at(0); 504 View* child = child_at(0);
476 gfx::Size size = child->GetPreferredSize(); 505 gfx::Size size = child->GetPreferredSize();
477 child->SetBounds(0, GetTopMargin(), size.width(), size.height()); 506 child->SetBounds(0, GetTopMargin(), size.width(), size.height());
478 } else { 507 } else {
479 // Child views are laid out right aligned and given the full height. To 508 // Child views are laid out right aligned and given the full height. To
480 // right align start with the last view and progress to the first. 509 // right align start with the last view and progress to the first.
481 int x = width() - (use_right_margin_ ? item_right_margin_ : 0); 510 int x = width() - (use_right_margin_ ? item_right_margin_ : 0);
482 for (int i = child_count() - 1; i >= 0; --i) { 511 for (int i = child_count() - 1; i >= 0; --i) {
483 View* child = child_at(i); 512 View* child = child_at(i);
513 if (icon_view_ && (icon_view_ == child))
514 continue;
484 int width = child->GetPreferredSize().width(); 515 int width = child->GetPreferredSize().width();
485 child->SetBounds(x - width, 0, width, height()); 516 child->SetBounds(x - width, 0, width, height());
486 x -= width - kChildXPadding; 517 x -= width - kChildXPadding;
487 } 518 }
519 // Position icon_view
520 const MenuConfig& config = MenuConfig::instance();
521 if (icon_view_) {
522 icon_view_->SizeToPreferredSize();
523 gfx::Size size = icon_view_->GetPreferredSize();
524 int x = config.item_left_margin + (icon_area_width_ - size.width()) / 2;
525 int y = (height() + GetTopMargin() - GetBottomMargin() -
526 size.height()) / 2;
527 icon_view_->SetPosition(gfx::Point(x, y));
528 }
488 } 529 }
489 } 530 }
490 531
491 int MenuItemView::GetAcceleratorTextWidth() { 532 int MenuItemView::GetAcceleratorTextWidth() {
492 string16 text = GetAcceleratorText(); 533 string16 text = GetAcceleratorText();
493 return text.empty() ? 0 : GetFont().GetStringWidth(text); 534 return text.empty() ? 0 : GetFont().GetStringWidth(text);
494 } 535 }
495 536
496 void MenuItemView::SetMargins(int top_margin, int bottom_margin) { 537 void MenuItemView::SetMargins(int top_margin, int bottom_margin) {
497 top_margin_ = top_margin; 538 top_margin_ = top_margin;
(...skipping 10 matching lines...) Expand all
508 controller_(NULL), 549 controller_(NULL),
509 canceled_(false), 550 canceled_(false),
510 parent_menu_item_(parent), 551 parent_menu_item_(parent),
511 type_(type), 552 type_(type),
512 selected_(false), 553 selected_(false),
513 command_(command), 554 command_(command),
514 submenu_(NULL), 555 submenu_(NULL),
515 has_mnemonics_(false), 556 has_mnemonics_(false),
516 show_mnemonics_(false), 557 show_mnemonics_(false),
517 has_icons_(false), 558 has_icons_(false),
559 icon_view_(NULL),
518 top_margin_(-1), 560 top_margin_(-1),
519 bottom_margin_(-1), 561 bottom_margin_(-1),
520 requested_menu_position_(POSITION_BEST_FIT), 562 requested_menu_position_(POSITION_BEST_FIT),
521 actual_menu_position_(requested_menu_position_) { 563 actual_menu_position_(requested_menu_position_) {
522 Init(parent, command, type, NULL); 564 Init(parent, command, type, NULL);
523 } 565 }
524 566
525 MenuItemView::~MenuItemView() { 567 MenuItemView::~MenuItemView() {
526 delete submenu_; 568 delete submenu_;
527 STLDeleteElements(&removed_items_); 569 STLDeleteElements(&removed_items_);
528 } 570 }
529 571
530 std::string MenuItemView::GetClassName() const { 572 std::string MenuItemView::GetClassName() const {
531 return kViewClassName; 573 return kViewClassName;
532 } 574 }
533 575
534 // Calculates all sizes that we can from the OS. 576 // Calculates all sizes that we can from the OS.
535 // 577 //
536 // This is invoked prior to Running a menu. 578 // This is invoked prior to Running a menu.
537 void MenuItemView::UpdateMenuPartSizes(bool has_icons) { 579 void MenuItemView::UpdateMenuPartSizes() {
sky 2012/06/26 21:54:21 has_icons is set on the root and expected to perco
yefimt 2012/06/26 22:50:19 It used to take has_icons because function was sta
538 MenuConfig::Reset(); 580 MenuConfig::Reset();
539 const MenuConfig& config = MenuConfig::instance(); 581 const MenuConfig& config = MenuConfig::instance();
540 582
541 item_right_margin_ = config.label_to_arrow_padding + config.arrow_width + 583 item_right_margin_ = config.label_to_arrow_padding + config.arrow_width +
542 config.arrow_to_edge_padding; 584 config.arrow_to_edge_padding;
585 icon_area_width_ = config.check_width;
586 if (has_icons_) {
587 for (int i = 0; i < submenu_->GetMenuItemCount(); ++i) {
588 MenuItemView* menu_item = submenu_->GetMenuItemAt(i);
589 if (menu_item->GetIconView())
590 icon_area_width_ = std::max(icon_area_width_,
591 menu_item->GetIconView()->GetPreferredSize().width());
592 }
593 }
543 594
544 if (config.always_use_icon_to_label_padding) 595 if (config.always_use_icon_to_label_padding)
545 label_start_ = config.item_left_margin + config.check_width + 596 label_start_ = config.item_left_margin + icon_area_width_ +
546 config.icon_to_label_padding; 597 config.icon_to_label_padding;
547 else 598 else
548 // If there are no icons don't pad by the icon to label padding. This 599 // If there are no icons don't pad by the icon to label padding. This
549 // makes us look close to system menus. 600 // makes us look close to system menus.
550 label_start_ = config.item_left_margin + config.check_width + 601 label_start_ = config.item_left_margin + icon_area_width_ +
551 (has_icons ? config.icon_to_label_padding : 0); 602 (has_icons_ ? config.icon_to_label_padding : 0);
552 603
553 if (config.render_gutter) 604 if (config.render_gutter)
554 label_start_ += config.gutter_width + config.gutter_to_label; 605 label_start_ += config.gutter_width + config.gutter_to_label;
555 606
556 MenuItemView menu_item(NULL); 607 MenuItemView menu_item(NULL);
557 menu_item.SetTitle(ASCIIToUTF16("blah")); // Text doesn't matter here. 608 menu_item.SetTitle(ASCIIToUTF16("blah")); // Text doesn't matter here.
558 pref_menu_height_ = menu_item.GetPreferredSize().height(); 609 pref_menu_height_ = menu_item.GetPreferredSize().height();
559 } 610 }
560 611
561 void MenuItemView::Init(MenuItemView* parent, 612 void MenuItemView::Init(MenuItemView* parent,
(...skipping 30 matching lines...) Expand all
592 canceled_ = false; 643 canceled_ = false;
593 644
594 has_mnemonics_ = has_mnemonics; 645 has_mnemonics_ = has_mnemonics;
595 show_mnemonics_ = has_mnemonics && show_mnemonics; 646 show_mnemonics_ = has_mnemonics && show_mnemonics;
596 647
597 AddEmptyMenus(); 648 AddEmptyMenus();
598 649
599 if (!MenuController::GetActiveInstance()) { 650 if (!MenuController::GetActiveInstance()) {
600 // Only update the menu size if there are no menus showing, otherwise 651 // Only update the menu size if there are no menus showing, otherwise
601 // things may shift around. 652 // things may shift around.
602 UpdateMenuPartSizes(has_icons_); 653 UpdateMenuPartSizes();
603 } 654 }
604 } 655 }
605 656
606 int MenuItemView::GetDrawStringFlags() { 657 int MenuItemView::GetDrawStringFlags() {
607 int flags = 0; 658 int flags = 0;
608 if (base::i18n::IsRTL()) 659 if (base::i18n::IsRTL())
609 flags |= gfx::Canvas::TEXT_ALIGN_RIGHT; 660 flags |= gfx::Canvas::TEXT_ALIGN_RIGHT;
610 else 661 else
611 flags |= gfx::Canvas::TEXT_ALIGN_LEFT; 662 flags |= gfx::Canvas::TEXT_ALIGN_LEFT;
612 663
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
728 if (!has_children()) 779 if (!has_children())
729 return gfx::Size(); 780 return gfx::Size();
730 781
731 if (IsContainer()) { 782 if (IsContainer()) {
732 View* child = child_at(0); 783 View* child = child_at(0);
733 return child->GetPreferredSize(); 784 return child->GetPreferredSize();
734 } 785 }
735 786
736 int width = 0; 787 int width = 0;
737 for (int i = 0; i < child_count(); ++i) { 788 for (int i = 0; i < child_count(); ++i) {
789 View* child = child_at(i);
790 if (icon_view_ && (icon_view_ == child))
791 continue;
738 if (i) 792 if (i)
739 width += kChildXPadding; 793 width += kChildXPadding;
740 width += child_at(i)->GetPreferredSize().width(); 794 width += child->GetPreferredSize().width();
741 } 795 }
742 // Return a height of 0 to indicate that we should use the title height 796 int height = 0;
743 // instead. 797 if (icon_view_)
744 return gfx::Size(width, 0); 798 height = icon_view_->GetPreferredSize().height();
799
800 // If there is no icon view it returns a height of 0 to indicate that
801 // we should use the title height instead.
802 return gfx::Size(width, height);
745 } 803 }
746 804
747 gfx::Size MenuItemView::CalculatePreferredSize() { 805 gfx::Size MenuItemView::CalculatePreferredSize() {
748 gfx::Size child_size = GetChildPreferredSize(); 806 gfx::Size child_size = GetChildPreferredSize();
749 if (IsContainer()) { 807 if (IsContainer()) {
750 return gfx::Size( 808 return gfx::Size(
751 child_size.width(), 809 child_size.width(),
752 child_size.height() + GetBottomMargin() + GetTopMargin()); 810 child_size.height() + GetBottomMargin() + GetTopMargin());
753 } 811 }
754 812
(...skipping 18 matching lines...) Expand all
773 ui::Accelerator accelerator; 831 ui::Accelerator accelerator;
774 return (GetDelegate() && 832 return (GetDelegate() &&
775 GetDelegate()->GetAccelerator(GetCommand(), &accelerator)) ? 833 GetDelegate()->GetAccelerator(GetCommand(), &accelerator)) ?
776 accelerator.GetShortcutText() : string16(); 834 accelerator.GetShortcutText() : string16();
777 } 835 }
778 836
779 bool MenuItemView::IsContainer() const { 837 bool MenuItemView::IsContainer() const {
780 // Let the first child take over |this| when we only have one child and no 838 // Let the first child take over |this| when we only have one child and no
781 // title. Note that what child_count() returns is the number of children, 839 // title. Note that what child_count() returns is the number of children,
782 // not the number of menu items. 840 // not the number of menu items.
783 return child_count() == 1 && title_.empty(); 841 return child_count() == 1 && title_.empty();
sky 2012/06/26 21:54:21 I believe you need to update this. Once you do tha
yefimt 2012/06/26 22:50:19 Done.
784 } 842 }
785 843
844 bool MenuItemView::HasNonIconChildViews() {
845 return child_count() > (icon_view_ ? 1 : 0);
846 }
847
786 } // namespace views 848 } // namespace views
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698