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/strings/utf_string_conversions.h" | 9 #include "base/strings/utf_string_conversions.h" |
10 #include "grit/ui_resources.h" | 10 #include "grit/ui_resources.h" |
11 #include "grit/ui_strings.h" | 11 #include "grit/ui_strings.h" |
12 #include "ui/base/accessibility/accessible_view_state.h" | 12 #include "ui/base/accessibility/accessible_view_state.h" |
13 #include "ui/base/l10n/l10n_util.h" | 13 #include "ui/base/l10n/l10n_util.h" |
14 #include "ui/base/models/menu_model.h" | 14 #include "ui/base/models/menu_model.h" |
15 #include "ui/base/resource/resource_bundle.h" | 15 #include "ui/base/resource/resource_bundle.h" |
16 #include "ui/gfx/canvas.h" | 16 #include "ui/gfx/canvas.h" |
| 17 #include "ui/gfx/geometry/rect.h" |
| 18 #include "ui/gfx/geometry/vector2d.h" |
17 #include "ui/gfx/image/image.h" | 19 #include "ui/gfx/image/image.h" |
| 20 #include "ui/gfx/text_utils.h" |
18 #include "ui/native_theme/common_theme.h" | 21 #include "ui/native_theme/common_theme.h" |
19 #include "ui/views/controls/button/menu_button.h" | 22 #include "ui/views/controls/button/menu_button.h" |
20 #include "ui/views/controls/image_view.h" | 23 #include "ui/views/controls/image_view.h" |
21 #include "ui/views/controls/menu/menu_config.h" | 24 #include "ui/views/controls/menu/menu_config.h" |
22 #include "ui/views/controls/menu/menu_controller.h" | 25 #include "ui/views/controls/menu/menu_controller.h" |
23 #include "ui/views/controls/menu/menu_image_util.h" | 26 #include "ui/views/controls/menu/menu_image_util.h" |
24 #include "ui/views/controls/menu/menu_scroll_view_container.h" | 27 #include "ui/views/controls/menu/menu_scroll_view_container.h" |
25 #include "ui/views/controls/menu/menu_separator.h" | 28 #include "ui/views/controls/menu/menu_separator.h" |
26 #include "ui/views/controls/menu/submenu_view.h" | 29 #include "ui/views/controls/menu/submenu_view.h" |
27 #include "ui/views/widget/widget.h" | 30 #include "ui/views/widget/widget.h" |
(...skipping 651 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
679 if (GetRootMenuItem()->has_mnemonics_) { | 682 if (GetRootMenuItem()->has_mnemonics_) { |
680 if (GetMenuConfig().show_mnemonics || GetRootMenuItem()->show_mnemonics_) { | 683 if (GetMenuConfig().show_mnemonics || GetRootMenuItem()->show_mnemonics_) { |
681 flags |= gfx::Canvas::SHOW_PREFIX; | 684 flags |= gfx::Canvas::SHOW_PREFIX; |
682 } else { | 685 } else { |
683 flags |= gfx::Canvas::HIDE_PREFIX; | 686 flags |= gfx::Canvas::HIDE_PREFIX; |
684 } | 687 } |
685 } | 688 } |
686 return flags; | 689 return flags; |
687 } | 690 } |
688 | 691 |
689 const gfx::Font& MenuItemView::GetFont() { | 692 const gfx::FontList& MenuItemView::GetFontList() { |
690 const MenuDelegate* delegate = GetDelegate(); | 693 const MenuDelegate* delegate = GetDelegate(); |
691 if (delegate) { | 694 if (delegate) { |
692 const gfx::Font* font = delegate->GetLabelFont(GetCommand()); | 695 const gfx::FontList* font_list = delegate->GetLabelFontList(GetCommand()); |
693 if (font) | 696 if (font_list) |
694 return *font; | 697 return *font_list; |
695 } | 698 } |
696 return GetMenuConfig().font; | 699 return GetMenuConfig().font_list; |
697 } | 700 } |
698 | 701 |
699 void MenuItemView::AddEmptyMenus() { | 702 void MenuItemView::AddEmptyMenus() { |
700 DCHECK(HasSubmenu()); | 703 DCHECK(HasSubmenu()); |
701 if (!submenu_->has_children()) { | 704 if (!submenu_->has_children()) { |
702 submenu_->AddChildViewAt(new EmptyMenuMenuItem(this), 0); | 705 submenu_->AddChildViewAt(new EmptyMenuMenuItem(this), 0); |
703 } else { | 706 } else { |
704 for (int i = 0, item_count = submenu_->GetMenuItemCount(); i < item_count; | 707 for (int i = 0, item_count = submenu_->GetMenuItemCount(); i < item_count; |
705 ++i) { | 708 ++i) { |
706 MenuItemView* child = submenu_->GetMenuItemAt(i); | 709 MenuItemView* child = submenu_->GetMenuItemAt(i); |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
796 ui::NativeTheme::kColorId_SelectedMenuItemForegroundColor: | 799 ui::NativeTheme::kColorId_SelectedMenuItemForegroundColor: |
797 ui::NativeTheme::kColorId_EnabledMenuItemForegroundColor; | 800 ui::NativeTheme::kColorId_EnabledMenuItemForegroundColor; |
798 } | 801 } |
799 SkColor fg_color = native_theme->GetSystemColor(color_id); | 802 SkColor fg_color = native_theme->GetSystemColor(color_id); |
800 SkColor override_foreground_color; | 803 SkColor override_foreground_color; |
801 if (delegate && delegate->GetForegroundColor(GetCommand(), | 804 if (delegate && delegate->GetForegroundColor(GetCommand(), |
802 render_selection, | 805 render_selection, |
803 &override_foreground_color)) | 806 &override_foreground_color)) |
804 fg_color = override_foreground_color; | 807 fg_color = override_foreground_color; |
805 | 808 |
806 const gfx::Font& font = GetFont(); | 809 const gfx::FontList& font_list = GetFontList(); |
807 int accel_width = parent_menu_item_->GetSubmenu()->max_minor_text_width(); | 810 int accel_width = parent_menu_item_->GetSubmenu()->max_minor_text_width(); |
808 int label_start = GetLabelStartForThisItem(); | 811 int label_start = GetLabelStartForThisItem(); |
809 | 812 |
810 int width = this->width() - label_start - accel_width - | 813 int width = this->width() - label_start - accel_width - |
811 (!delegate || | 814 (!delegate || |
812 delegate->ShouldReserveSpaceForSubmenuIndicator() ? | 815 delegate->ShouldReserveSpaceForSubmenuIndicator() ? |
813 item_right_margin_ : config.arrow_to_edge_padding); | 816 item_right_margin_ : config.arrow_to_edge_padding); |
814 gfx::Rect text_bounds(label_start, top_margin, width, | 817 gfx::Rect text_bounds(label_start, top_margin, width, |
815 subtitle_.empty() ? available_height | 818 subtitle_.empty() ? available_height |
816 : available_height / 2); | 819 : available_height / 2); |
817 text_bounds.set_x(GetMirroredXForRect(text_bounds)); | 820 text_bounds.set_x(GetMirroredXForRect(text_bounds)); |
818 int flags = GetDrawStringFlags(); | 821 int flags = GetDrawStringFlags(); |
819 if (mode == PB_FOR_DRAG) | 822 if (mode == PB_FOR_DRAG) |
820 flags |= gfx::Canvas::NO_SUBPIXEL_RENDERING; | 823 flags |= gfx::Canvas::NO_SUBPIXEL_RENDERING; |
821 canvas->DrawStringInt(title(), font, fg_color, | 824 canvas->DrawStringRectWithFlags(title(), font_list, fg_color, text_bounds, |
822 text_bounds.x(), text_bounds.y(), text_bounds.width(), | 825 flags); |
823 text_bounds.height(), flags); | |
824 if (!subtitle_.empty()) { | 826 if (!subtitle_.empty()) { |
825 canvas->DrawStringInt( | 827 canvas->DrawStringRectWithFlags( |
826 subtitle_, | 828 subtitle_, |
827 font, | 829 font_list, |
828 GetNativeTheme()->GetSystemColor( | 830 GetNativeTheme()->GetSystemColor( |
829 ui::NativeTheme::kColorId_ButtonDisabledColor), | 831 ui::NativeTheme::kColorId_ButtonDisabledColor), |
830 text_bounds.x(), | 832 text_bounds + gfx::Vector2d(0, font_list.GetHeight()), |
831 text_bounds.y() + GetFont().GetHeight(), | |
832 text_bounds.width(), | |
833 text_bounds.height(), | |
834 flags); | 833 flags); |
835 } | 834 } |
836 | 835 |
837 PaintMinorText(canvas, render_selection); | 836 PaintMinorText(canvas, render_selection); |
838 | 837 |
839 // Render the submenu indicator (arrow). | 838 // Render the submenu indicator (arrow). |
840 if (HasSubmenu()) { | 839 if (HasSubmenu()) { |
841 gfx::Rect arrow_bounds(this->width() - config.arrow_width - | 840 gfx::Rect arrow_bounds(this->width() - config.arrow_width - |
842 config.arrow_to_edge_padding, | 841 config.arrow_to_edge_padding, |
843 top_margin + (available_height - | 842 top_margin + (available_height - |
844 config.arrow_width) / 2, | 843 config.arrow_width) / 2, |
845 config.arrow_width, height()); | 844 config.arrow_width, height()); |
846 AdjustBoundsForRTLUI(&arrow_bounds); | 845 AdjustBoundsForRTLUI(&arrow_bounds); |
847 canvas->DrawImageInt(GetSubmenuArrowImage(IsSelected()), | 846 canvas->DrawImageInt(GetSubmenuArrowImage(IsSelected()), |
848 arrow_bounds.x(), arrow_bounds.y()); | 847 arrow_bounds.x(), arrow_bounds.y()); |
849 } | 848 } |
850 } | 849 } |
851 | 850 |
852 void MenuItemView::PaintMinorText(gfx::Canvas* canvas, | 851 void MenuItemView::PaintMinorText(gfx::Canvas* canvas, |
853 bool render_selection) { | 852 bool render_selection) { |
854 base::string16 minor_text = GetMinorText(); | 853 base::string16 minor_text = GetMinorText(); |
855 if (minor_text.empty()) | 854 if (minor_text.empty()) |
856 return; | 855 return; |
857 | 856 |
858 const gfx::Font& font = GetFont(); | |
859 int available_height = height() - GetTopMargin() - GetBottomMargin(); | 857 int available_height = height() - GetTopMargin() - GetBottomMargin(); |
860 int max_accel_width = | 858 int max_accel_width = |
861 parent_menu_item_->GetSubmenu()->max_minor_text_width(); | 859 parent_menu_item_->GetSubmenu()->max_minor_text_width(); |
862 const MenuConfig& config = GetMenuConfig(); | 860 const MenuConfig& config = GetMenuConfig(); |
863 int accel_right_margin = config.align_arrow_and_shortcut ? | 861 int accel_right_margin = config.align_arrow_and_shortcut ? |
864 config.arrow_to_edge_padding : item_right_margin_; | 862 config.arrow_to_edge_padding : item_right_margin_; |
865 gfx::Rect accel_bounds(width() - accel_right_margin - max_accel_width, | 863 gfx::Rect accel_bounds(width() - accel_right_margin - max_accel_width, |
866 GetTopMargin(), max_accel_width, available_height); | 864 GetTopMargin(), max_accel_width, available_height); |
867 accel_bounds.set_x(GetMirroredXForRect(accel_bounds)); | 865 accel_bounds.set_x(GetMirroredXForRect(accel_bounds)); |
868 int flags = GetDrawStringFlags(); | 866 int flags = GetDrawStringFlags(); |
869 flags &= ~(gfx::Canvas::TEXT_ALIGN_RIGHT | gfx::Canvas::TEXT_ALIGN_LEFT); | 867 flags &= ~(gfx::Canvas::TEXT_ALIGN_RIGHT | gfx::Canvas::TEXT_ALIGN_LEFT); |
870 if (base::i18n::IsRTL()) | 868 if (base::i18n::IsRTL()) |
871 flags |= gfx::Canvas::TEXT_ALIGN_LEFT; | 869 flags |= gfx::Canvas::TEXT_ALIGN_LEFT; |
872 else | 870 else |
873 flags |= gfx::Canvas::TEXT_ALIGN_RIGHT; | 871 flags |= gfx::Canvas::TEXT_ALIGN_RIGHT; |
874 canvas->DrawStringInt( | 872 canvas->DrawStringRectWithFlags( |
875 minor_text, | 873 minor_text, |
876 font, | 874 GetFontList(), |
877 GetNativeTheme()->GetSystemColor(render_selection ? | 875 GetNativeTheme()->GetSystemColor(render_selection ? |
878 ui::NativeTheme::kColorId_SelectedMenuItemForegroundColor : | 876 ui::NativeTheme::kColorId_SelectedMenuItemForegroundColor : |
879 ui::NativeTheme::kColorId_ButtonDisabledColor), | 877 ui::NativeTheme::kColorId_ButtonDisabledColor), |
880 accel_bounds.x(), | 878 accel_bounds, |
881 accel_bounds.y(), | |
882 accel_bounds.width(), | |
883 accel_bounds.height(), | |
884 flags); | 879 flags); |
885 } | 880 } |
886 | 881 |
887 void MenuItemView::DestroyAllMenuHosts() { | 882 void MenuItemView::DestroyAllMenuHosts() { |
888 if (!HasSubmenu()) | 883 if (!HasSubmenu()) |
889 return; | 884 return; |
890 | 885 |
891 submenu_->Close(); | 886 submenu_->Close(); |
892 for (int i = 0, item_count = submenu_->GetMenuItemCount(); i < item_count; | 887 for (int i = 0, item_count = submenu_->GetMenuItemCount(); i < item_count; |
893 ++i) { | 888 ++i) { |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
955 dimensions.height = std::max(dimensions.height, | 950 dimensions.height = std::max(dimensions.height, |
956 GetMenuConfig().check_height); | 951 GetMenuConfig().check_height); |
957 } | 952 } |
958 dimensions.height += GetBottomMargin() + GetTopMargin(); | 953 dimensions.height += GetBottomMargin() + GetTopMargin(); |
959 | 954 |
960 // In case of a container, only the container size needs to be filled. | 955 // In case of a container, only the container size needs to be filled. |
961 if (IsContainer()) | 956 if (IsContainer()) |
962 return dimensions; | 957 return dimensions; |
963 | 958 |
964 // Determine the length of the label text. | 959 // Determine the length of the label text. |
965 const gfx::Font& font = GetFont(); | 960 const gfx::FontList& font_list = GetFontList(); |
966 | 961 |
967 // Get Icon margin overrides for this particular item. | 962 // Get Icon margin overrides for this particular item. |
968 const MenuDelegate* delegate = GetDelegate(); | 963 const MenuDelegate* delegate = GetDelegate(); |
969 if (delegate) { | 964 if (delegate) { |
970 delegate->GetHorizontalIconMargins(command_, | 965 delegate->GetHorizontalIconMargins(command_, |
971 icon_area_width_, | 966 icon_area_width_, |
972 &left_icon_margin_, | 967 &left_icon_margin_, |
973 &right_icon_margin_); | 968 &right_icon_margin_); |
974 } else { | 969 } else { |
975 left_icon_margin_ = 0; | 970 left_icon_margin_ = 0; |
976 right_icon_margin_ = 0; | 971 right_icon_margin_ = 0; |
977 } | 972 } |
978 int label_start = GetLabelStartForThisItem(); | 973 int label_start = GetLabelStartForThisItem(); |
979 | 974 |
980 int string_width = font.GetStringWidth(title_); | 975 int string_width = gfx::GetStringWidth(title_, font_list); |
981 if (!subtitle_.empty()) | 976 if (!subtitle_.empty()) { |
982 string_width = std::max(string_width, font.GetStringWidth(subtitle_)); | 977 string_width = std::max(string_width, |
| 978 gfx::GetStringWidth(subtitle_, font_list)); |
| 979 } |
983 | 980 |
984 dimensions.standard_width = string_width + label_start + | 981 dimensions.standard_width = string_width + label_start + |
985 item_right_margin_; | 982 item_right_margin_; |
986 // Determine the length of the right-side text. | 983 // Determine the length of the right-side text. |
987 base::string16 minor_text = GetMinorText(); | 984 base::string16 minor_text = GetMinorText(); |
988 dimensions.minor_text_width = | 985 dimensions.minor_text_width = |
989 minor_text.empty() ? 0 : GetFont().GetStringWidth(minor_text); | 986 minor_text.empty() ? 0 : gfx::GetStringWidth(minor_text, font_list); |
990 | 987 |
991 // Determine the height to use. | 988 // Determine the height to use. |
| 989 dimensions.height = |
| 990 std::max(dimensions.height, |
| 991 (subtitle_.empty() ? 0 : font_list.GetHeight()) + |
| 992 font_list.GetHeight() + GetBottomMargin() + GetTopMargin()); |
992 dimensions.height = std::max(dimensions.height, | 993 dimensions.height = std::max(dimensions.height, |
993 (subtitle_.empty() ? 0 : font.GetHeight()) + | 994 GetMenuConfig().item_min_height); |
994 font.GetHeight() + GetBottomMargin() + GetTopMargin()); | |
995 dimensions.height = std::max(dimensions.height, | |
996 GetMenuConfig().item_min_height); | |
997 return dimensions; | 995 return dimensions; |
998 } | 996 } |
999 | 997 |
1000 int MenuItemView::GetLabelStartForThisItem() { | 998 int MenuItemView::GetLabelStartForThisItem() { |
1001 int label_start = label_start_ + left_icon_margin_ + right_icon_margin_; | 999 int label_start = label_start_ + left_icon_margin_ + right_icon_margin_; |
1002 if ((type_ == CHECKBOX || type_ == RADIO) && icon_view_) { | 1000 if ((type_ == CHECKBOX || type_ == RADIO) && icon_view_) { |
1003 label_start += icon_view_->size().width() + | 1001 label_start += icon_view_->size().width() + |
1004 GetMenuConfig().icon_to_label_padding; | 1002 GetMenuConfig().icon_to_label_padding; |
1005 } | 1003 } |
1006 return label_start; | 1004 return label_start; |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1062 } else { | 1060 } else { |
1063 const Type& type = menu_item->GetType(); | 1061 const Type& type = menu_item->GetType(); |
1064 if (type == CHECKBOX || type == RADIO) | 1062 if (type == CHECKBOX || type == RADIO) |
1065 return true; | 1063 return true; |
1066 } | 1064 } |
1067 } | 1065 } |
1068 return false; | 1066 return false; |
1069 } | 1067 } |
1070 | 1068 |
1071 } // namespace views | 1069 } // namespace views |
OLD | NEW |