OLD | NEW |
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" |
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
212 const string16& label, | 212 const string16& label, |
213 const gfx::ImageSkia& icon, | 213 const gfx::ImageSkia& icon, |
214 Type type, | 214 Type type, |
215 ui::MenuSeparatorType separator_style) { | 215 ui::MenuSeparatorType separator_style) { |
216 DCHECK_NE(type, EMPTY); | 216 DCHECK_NE(type, EMPTY); |
217 DCHECK_LE(0, index); | 217 DCHECK_LE(0, index); |
218 if (!submenu_) | 218 if (!submenu_) |
219 CreateSubmenu(); | 219 CreateSubmenu(); |
220 DCHECK_GE(submenu_->child_count(), index); | 220 DCHECK_GE(submenu_->child_count(), index); |
221 if (type == SEPARATOR) { | 221 if (type == SEPARATOR) { |
222 submenu_->AddChildViewAt(new MenuSeparator(separator_style), index); | 222 submenu_->AddChildViewAt(new MenuSeparator(this, separator_style), index); |
223 return NULL; | 223 return NULL; |
224 } | 224 } |
225 MenuItemView* item = new MenuItemView(this, item_id, type); | 225 MenuItemView* item = new MenuItemView(this, item_id, type); |
226 if (label.empty() && GetDelegate()) | 226 if (label.empty() && GetDelegate()) |
227 item->SetTitle(GetDelegate()->GetLabel(item_id)); | 227 item->SetTitle(GetDelegate()->GetLabel(item_id)); |
228 else | 228 else |
229 item->SetTitle(label); | 229 item->SetTitle(label); |
230 if (!icon.isNull()) | 230 if (!icon.isNull()) |
231 item->SetIcon(icon); | 231 item->SetIcon(icon); |
232 if (type == SUBMENU) | 232 if (type == SUBMENU) |
(...skipping 290 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
523 int x = width() - (use_right_margin_ ? item_right_margin_ : 0); | 523 int x = width() - (use_right_margin_ ? item_right_margin_ : 0); |
524 for (int i = child_count() - 1; i >= 0; --i) { | 524 for (int i = child_count() - 1; i >= 0; --i) { |
525 View* child = child_at(i); | 525 View* child = child_at(i); |
526 if (icon_view_ && (icon_view_ == child)) | 526 if (icon_view_ && (icon_view_ == child)) |
527 continue; | 527 continue; |
528 int width = child->GetPreferredSize().width(); | 528 int width = child->GetPreferredSize().width(); |
529 child->SetBounds(x - width, 0, width, height()); | 529 child->SetBounds(x - width, 0, width, height()); |
530 x -= width - kChildXPadding; | 530 x -= width - kChildXPadding; |
531 } | 531 } |
532 // Position |icon_view|. | 532 // Position |icon_view|. |
533 const MenuConfig& config = MenuConfig::instance(); | 533 const MenuConfig& config = GetMenuConfig(); |
534 if (icon_view_) { | 534 if (icon_view_) { |
535 icon_view_->SizeToPreferredSize(); | 535 icon_view_->SizeToPreferredSize(); |
536 gfx::Size size = icon_view_->GetPreferredSize(); | 536 gfx::Size size = icon_view_->GetPreferredSize(); |
537 int x = config.item_left_margin + (icon_area_width_ - size.width()) / 2; | 537 int x = config.item_left_margin + (icon_area_width_ - size.width()) / 2; |
538 int y = | 538 int y = |
539 (height() + GetTopMargin() - GetBottomMargin() - size.height()) / 2; | 539 (height() + GetTopMargin() - GetBottomMargin() - size.height()) / 2; |
540 icon_view_->SetPosition(gfx::Point(x, y)); | 540 icon_view_->SetPosition(gfx::Point(x, y)); |
541 } | 541 } |
542 } | 542 } |
543 } | 543 } |
544 | 544 |
545 void MenuItemView::SetMargins(int top_margin, int bottom_margin) { | 545 void MenuItemView::SetMargins(int top_margin, int bottom_margin) { |
546 top_margin_ = top_margin; | 546 top_margin_ = top_margin; |
547 bottom_margin_ = bottom_margin; | 547 bottom_margin_ = bottom_margin; |
548 | 548 |
549 // invalidate GetPreferredSize() cache | 549 // invalidate GetPreferredSize() cache |
550 pref_size_.SetSize(0,0); | 550 pref_size_.SetSize(0,0); |
551 } | 551 } |
552 | 552 |
| 553 const MenuConfig& MenuItemView::GetMenuConfig() const { |
| 554 const MenuItemView* root_menu_item = GetRootMenuItem(); |
| 555 if (root_menu_item->menu_config_.get()) |
| 556 return *(root_menu_item->menu_config_); |
| 557 |
| 558 return MenuConfig::instance(); |
| 559 } |
| 560 |
553 MenuItemView::MenuItemView(MenuItemView* parent, | 561 MenuItemView::MenuItemView(MenuItemView* parent, |
554 int command, | 562 int command, |
555 MenuItemView::Type type) | 563 MenuItemView::Type type) |
556 : delegate_(NULL), | 564 : delegate_(NULL), |
557 controller_(NULL), | 565 controller_(NULL), |
558 canceled_(false), | 566 canceled_(false), |
559 parent_menu_item_(parent), | 567 parent_menu_item_(parent), |
560 type_(type), | 568 type_(type), |
561 selected_(false), | 569 selected_(false), |
562 command_(command), | 570 command_(command), |
(...skipping 16 matching lines...) Expand all Loading... |
579 | 587 |
580 std::string MenuItemView::GetClassName() const { | 588 std::string MenuItemView::GetClassName() const { |
581 return kViewClassName; | 589 return kViewClassName; |
582 } | 590 } |
583 | 591 |
584 // Calculates all sizes that we can from the OS. | 592 // Calculates all sizes that we can from the OS. |
585 // | 593 // |
586 // This is invoked prior to Running a menu. | 594 // This is invoked prior to Running a menu. |
587 void MenuItemView::UpdateMenuPartSizes() { | 595 void MenuItemView::UpdateMenuPartSizes() { |
588 MenuConfig::Reset(); | 596 MenuConfig::Reset(); |
589 const MenuConfig& config = MenuConfig::instance(); | 597 const MenuConfig& config = GetMenuConfig(); |
590 | 598 |
591 item_right_margin_ = config.label_to_arrow_padding + config.arrow_width + | 599 item_right_margin_ = config.label_to_arrow_padding + config.arrow_width + |
592 config.arrow_to_edge_padding; | 600 config.arrow_to_edge_padding; |
593 icon_area_width_ = config.check_width; | 601 icon_area_width_ = config.check_width; |
594 if (has_icons_) | 602 if (has_icons_) |
595 icon_area_width_ = std::max(icon_area_width_, GetMaxIconViewWidth()); | 603 icon_area_width_ = std::max(icon_area_width_, GetMaxIconViewWidth()); |
596 | 604 |
597 if (config.always_use_icon_to_label_padding) | 605 if (config.always_use_icon_to_label_padding) |
598 label_start_ = config.item_left_margin + icon_area_width_ + | 606 label_start_ = config.item_left_margin + icon_area_width_ + |
599 config.icon_to_label_padding; | 607 config.icon_to_label_padding; |
600 else | 608 else |
601 // If there are no icons don't pad by the icon to label padding. This | 609 // If there are no icons don't pad by the icon to label padding. This |
602 // makes us look close to system menus. | 610 // makes us look close to system menus. |
603 label_start_ = config.item_left_margin + icon_area_width_ + | 611 label_start_ = config.item_left_margin + icon_area_width_ + |
604 (has_icons_ ? config.icon_to_label_padding : 0); | 612 (has_icons_ ? config.icon_to_label_padding : 0); |
605 | 613 |
606 if (config.render_gutter) | 614 if (config.render_gutter) |
607 label_start_ += config.gutter_width + config.gutter_to_label; | 615 label_start_ += config.gutter_width + config.gutter_to_label; |
608 | 616 |
609 MenuItemView menu_item(NULL); | 617 EmptyMenuMenuItem menu_item(this); |
610 menu_item.SetTitle(ASCIIToUTF16("blah")); // Text doesn't matter here. | |
611 pref_menu_height_ = menu_item.GetPreferredSize().height(); | 618 pref_menu_height_ = menu_item.GetPreferredSize().height(); |
612 } | 619 } |
613 | 620 |
614 void MenuItemView::Init(MenuItemView* parent, | 621 void MenuItemView::Init(MenuItemView* parent, |
615 int command, | 622 int command, |
616 MenuItemView::Type type, | 623 MenuItemView::Type type, |
617 MenuDelegate* delegate) { | 624 MenuDelegate* delegate) { |
618 delegate_ = delegate; | 625 delegate_ = delegate; |
619 controller_ = NULL; | 626 controller_ = NULL; |
620 canceled_ = false; | 627 canceled_ = false; |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
657 } | 664 } |
658 | 665 |
659 int MenuItemView::GetDrawStringFlags() { | 666 int MenuItemView::GetDrawStringFlags() { |
660 int flags = 0; | 667 int flags = 0; |
661 if (base::i18n::IsRTL()) | 668 if (base::i18n::IsRTL()) |
662 flags |= gfx::Canvas::TEXT_ALIGN_RIGHT; | 669 flags |= gfx::Canvas::TEXT_ALIGN_RIGHT; |
663 else | 670 else |
664 flags |= gfx::Canvas::TEXT_ALIGN_LEFT; | 671 flags |= gfx::Canvas::TEXT_ALIGN_LEFT; |
665 | 672 |
666 if (has_mnemonics_) { | 673 if (has_mnemonics_) { |
667 if (MenuConfig::instance().show_mnemonics || | 674 if (GetMenuConfig().show_mnemonics || GetRootMenuItem()->show_mnemonics_) { |
668 GetRootMenuItem()->show_mnemonics_) { | |
669 flags |= gfx::Canvas::SHOW_PREFIX; | 675 flags |= gfx::Canvas::SHOW_PREFIX; |
670 } else { | 676 } else { |
671 flags |= gfx::Canvas::HIDE_PREFIX; | 677 flags |= gfx::Canvas::HIDE_PREFIX; |
672 } | 678 } |
673 } | 679 } |
674 return flags; | 680 return flags; |
675 } | 681 } |
676 | 682 |
677 const gfx::Font& MenuItemView::GetFont() { | 683 const gfx::Font& MenuItemView::GetFont() { |
678 // Check for item-specific font. | 684 // Check for item-specific font. |
679 const MenuDelegate* delegate = GetDelegate(); | 685 const MenuDelegate* delegate = GetDelegate(); |
680 return delegate ? | 686 return delegate ? |
681 delegate->GetLabelFont(GetCommand()) : MenuConfig::instance().font; | 687 delegate->GetLabelFont(GetCommand()) : GetMenuConfig().font; |
682 } | 688 } |
683 | 689 |
684 void MenuItemView::AddEmptyMenus() { | 690 void MenuItemView::AddEmptyMenus() { |
685 DCHECK(HasSubmenu()); | 691 DCHECK(HasSubmenu()); |
686 if (!submenu_->has_children()) { | 692 if (!submenu_->has_children()) { |
687 submenu_->AddChildViewAt(new EmptyMenuMenuItem(this), 0); | 693 submenu_->AddChildViewAt(new EmptyMenuMenuItem(this), 0); |
688 } else { | 694 } else { |
689 for (int i = 0, item_count = submenu_->GetMenuItemCount(); i < item_count; | 695 for (int i = 0, item_count = submenu_->GetMenuItemCount(); i < item_count; |
690 ++i) { | 696 ++i) { |
691 MenuItemView* child = submenu_->GetMenuItemAt(i); | 697 MenuItemView* child = submenu_->GetMenuItemAt(i); |
(...skipping 27 matching lines...) Expand all Loading... |
719 | 725 |
720 void MenuItemView::PaintAccelerator(gfx::Canvas* canvas) { | 726 void MenuItemView::PaintAccelerator(gfx::Canvas* canvas) { |
721 string16 accel_text = GetAcceleratorText(); | 727 string16 accel_text = GetAcceleratorText(); |
722 if (accel_text.empty()) | 728 if (accel_text.empty()) |
723 return; | 729 return; |
724 | 730 |
725 const gfx::Font& font = GetFont(); | 731 const gfx::Font& font = GetFont(); |
726 int available_height = height() - GetTopMargin() - GetBottomMargin(); | 732 int available_height = height() - GetTopMargin() - GetBottomMargin(); |
727 int max_accel_width = | 733 int max_accel_width = |
728 parent_menu_item_->GetSubmenu()->max_accelerator_width(); | 734 parent_menu_item_->GetSubmenu()->max_accelerator_width(); |
729 const MenuConfig& config = MenuConfig::instance(); | 735 const MenuConfig& config = GetMenuConfig(); |
730 int accel_right_margin = config.align_arrow_and_shortcut ? | 736 int accel_right_margin = config.align_arrow_and_shortcut ? |
731 config.arrow_to_edge_padding : item_right_margin_; | 737 config.arrow_to_edge_padding : item_right_margin_; |
732 gfx::Rect accel_bounds(width() - accel_right_margin - max_accel_width, | 738 gfx::Rect accel_bounds(width() - accel_right_margin - max_accel_width, |
733 GetTopMargin(), max_accel_width, available_height); | 739 GetTopMargin(), max_accel_width, available_height); |
734 accel_bounds.set_x(GetMirroredXForRect(accel_bounds)); | 740 accel_bounds.set_x(GetMirroredXForRect(accel_bounds)); |
735 int flags = GetRootMenuItem()->GetDrawStringFlags() | | 741 int flags = GetRootMenuItem()->GetDrawStringFlags() | |
736 gfx::Canvas::TEXT_VALIGN_MIDDLE; | 742 gfx::Canvas::TEXT_VALIGN_MIDDLE; |
737 flags &= ~(gfx::Canvas::TEXT_ALIGN_RIGHT | gfx::Canvas::TEXT_ALIGN_LEFT); | 743 flags &= ~(gfx::Canvas::TEXT_ALIGN_RIGHT | gfx::Canvas::TEXT_ALIGN_LEFT); |
738 if (base::i18n::IsRTL()) | 744 if (base::i18n::IsRTL()) |
739 flags |= gfx::Canvas::TEXT_ALIGN_LEFT; | 745 flags |= gfx::Canvas::TEXT_ALIGN_LEFT; |
(...skipping 16 matching lines...) Expand all Loading... |
756 submenu_->GetMenuItemAt(i)->DestroyAllMenuHosts(); | 762 submenu_->GetMenuItemAt(i)->DestroyAllMenuHosts(); |
757 } | 763 } |
758 } | 764 } |
759 | 765 |
760 int MenuItemView::GetTopMargin() { | 766 int MenuItemView::GetTopMargin() { |
761 if (top_margin_ >= 0) | 767 if (top_margin_ >= 0) |
762 return top_margin_; | 768 return top_margin_; |
763 | 769 |
764 MenuItemView* root = GetRootMenuItem(); | 770 MenuItemView* root = GetRootMenuItem(); |
765 return root && root->has_icons_ | 771 return root && root->has_icons_ |
766 ? MenuConfig::instance().item_top_margin : | 772 ? GetMenuConfig().item_top_margin : |
767 MenuConfig::instance().item_no_icon_top_margin; | 773 GetMenuConfig().item_no_icon_top_margin; |
768 } | 774 } |
769 | 775 |
770 int MenuItemView::GetBottomMargin() { | 776 int MenuItemView::GetBottomMargin() { |
771 if (bottom_margin_ >= 0) | 777 if (bottom_margin_ >= 0) |
772 return bottom_margin_; | 778 return bottom_margin_; |
773 | 779 |
774 MenuItemView* root = GetRootMenuItem(); | 780 MenuItemView* root = GetRootMenuItem(); |
775 return root && root->has_icons_ | 781 return root && root->has_icons_ |
776 ? MenuConfig::instance().item_bottom_margin : | 782 ? GetMenuConfig().item_bottom_margin : |
777 MenuConfig::instance().item_no_icon_bottom_margin; | 783 GetMenuConfig().item_no_icon_bottom_margin; |
778 } | 784 } |
779 | 785 |
780 gfx::Size MenuItemView::GetChildPreferredSize() { | 786 gfx::Size MenuItemView::GetChildPreferredSize() { |
781 if (!has_children()) | 787 if (!has_children()) |
782 return gfx::Size(); | 788 return gfx::Size(); |
783 | 789 |
784 if (IsContainer()) { | 790 if (IsContainer()) { |
785 View* child = child_at(0); | 791 View* child = child_at(0); |
786 return child->GetPreferredSize(); | 792 return child->GetPreferredSize(); |
787 } | 793 } |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
822 item_right_margin_; | 828 item_right_margin_; |
823 // Determine the length of the accelerator text. | 829 // Determine the length of the accelerator text. |
824 string16 text = GetAcceleratorText(); | 830 string16 text = GetAcceleratorText(); |
825 dimensions.accelerator_width = | 831 dimensions.accelerator_width = |
826 text.empty() ? 0 : GetFont().GetStringWidth(text); | 832 text.empty() ? 0 : GetFont().GetStringWidth(text); |
827 | 833 |
828 // Determine the height to use. | 834 // Determine the height to use. |
829 dimensions.height = std::max(dimensions.height, | 835 dimensions.height = std::max(dimensions.height, |
830 font.GetHeight() + GetBottomMargin() + GetTopMargin()); | 836 font.GetHeight() + GetBottomMargin() + GetTopMargin()); |
831 dimensions.height = std::max(dimensions.height, | 837 dimensions.height = std::max(dimensions.height, |
832 MenuConfig::instance().item_min_height); | 838 GetMenuConfig().item_min_height); |
833 return dimensions; | 839 return dimensions; |
834 } | 840 } |
835 | 841 |
836 gfx::Size MenuItemView::CalculatePreferredSize() { | 842 gfx::Size MenuItemView::CalculatePreferredSize() { |
837 MenuItemView::MenuItemDimensions dimensions = GetPreferredDimensions(); | 843 MenuItemView::MenuItemDimensions dimensions = GetPreferredDimensions(); |
838 return gfx::Size(dimensions.standard_width + dimensions.children_width, | 844 return gfx::Size(dimensions.standard_width + dimensions.children_width, |
839 dimensions.height); | 845 dimensions.height); |
840 } | 846 } |
841 | 847 |
842 string16 MenuItemView::GetAcceleratorText() { | 848 string16 MenuItemView::GetAcceleratorText() { |
843 if (id() == kEmptyMenuItemViewID) { | 849 if (id() == kEmptyMenuItemViewID) { |
844 // Don't query the delegate for menus that represent no children. | 850 // Don't query the delegate for menus that represent no children. |
845 return string16(); | 851 return string16(); |
846 } | 852 } |
847 | 853 |
848 if(!MenuConfig::instance().show_accelerators) | 854 if(!GetMenuConfig().show_accelerators) |
849 return string16(); | 855 return string16(); |
850 | 856 |
851 ui::Accelerator accelerator; | 857 ui::Accelerator accelerator; |
852 return (GetDelegate() && | 858 return (GetDelegate() && |
853 GetDelegate()->GetAccelerator(GetCommand(), &accelerator)) ? | 859 GetDelegate()->GetAccelerator(GetCommand(), &accelerator)) ? |
854 accelerator.GetShortcutText() : string16(); | 860 accelerator.GetShortcutText() : string16(); |
855 } | 861 } |
856 | 862 |
857 bool MenuItemView::IsContainer() const { | 863 bool MenuItemView::IsContainer() const { |
858 // Let the first child take over |this| when we only have one child and no | 864 // Let the first child take over |this| when we only have one child and no |
(...skipping 16 matching lines...) Expand all Loading... |
875 temp_width = menu_item->GetMaxIconViewWidth(); | 881 temp_width = menu_item->GetMaxIconViewWidth(); |
876 } else if (menu_item->icon_view()) { | 882 } else if (menu_item->icon_view()) { |
877 temp_width = menu_item->icon_view()->GetPreferredSize().width(); | 883 temp_width = menu_item->icon_view()->GetPreferredSize().width(); |
878 } | 884 } |
879 width = std::max(width, temp_width); | 885 width = std::max(width, temp_width); |
880 } | 886 } |
881 return width; | 887 return width; |
882 } | 888 } |
883 | 889 |
884 } // namespace views | 890 } // namespace views |
OLD | NEW |