| 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 |