OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 "views/controls/menu/menu_item_view.h" | 5 #include "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 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
132 const MenuDelegate* delegate = GetDelegate(); | 132 const MenuDelegate* delegate = GetDelegate(); |
133 CHECK(delegate); | 133 CHECK(delegate); |
134 gfx::Point location(p); | 134 gfx::Point location(p); |
135 ConvertPointToScreen(this, &location); | 135 ConvertPointToScreen(this, &location); |
136 *tooltip = delegate->GetTooltipText(command_, location); | 136 *tooltip = delegate->GetTooltipText(command_, location); |
137 return !tooltip->empty(); | 137 return !tooltip->empty(); |
138 } | 138 } |
139 | 139 |
140 void MenuItemView::GetAccessibleState(ui::AccessibleViewState* state) { | 140 void MenuItemView::GetAccessibleState(ui::AccessibleViewState* state) { |
141 state->role = ui::AccessibilityTypes::ROLE_MENUITEM; | 141 state->role = ui::AccessibilityTypes::ROLE_MENUITEM; |
142 state->name = accessible_name_; | 142 |
| 143 string16 item_text; |
| 144 if (FirstChildTakesOver()) { |
| 145 // The first child is taking over, just use its accessible name instead of |
| 146 // |title_|. |
| 147 View* child = child_at(0); |
| 148 ui::AccessibleViewState state; |
| 149 child->GetAccessibleState(&state); |
| 150 item_text = state.name; |
| 151 } else { |
| 152 item_text = title_; |
| 153 } |
| 154 state->name = GetAccessibleNameForMenuItem(item_text, GetAcceleratorText()); |
| 155 |
143 switch (GetType()) { | 156 switch (GetType()) { |
144 case SUBMENU: | 157 case SUBMENU: |
145 state->state |= ui::AccessibilityTypes::STATE_HASPOPUP; | 158 state->state |= ui::AccessibilityTypes::STATE_HASPOPUP; |
146 break; | 159 break; |
147 case CHECKBOX: | 160 case CHECKBOX: |
148 case RADIO: | 161 case RADIO: |
149 state->state |= GetDelegate()->IsItemChecked(GetCommand()) ? | 162 state->state |= GetDelegate()->IsItemChecked(GetCommand()) ? |
150 ui::AccessibilityTypes::STATE_CHECKED : 0; | 163 ui::AccessibilityTypes::STATE_CHECKED : 0; |
151 break; | 164 break; |
152 case NORMAL: | 165 case NORMAL: |
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
323 bool MenuItemView::HasSubmenu() const { | 336 bool MenuItemView::HasSubmenu() const { |
324 return (submenu_ != NULL); | 337 return (submenu_ != NULL); |
325 } | 338 } |
326 | 339 |
327 SubmenuView* MenuItemView::GetSubmenu() const { | 340 SubmenuView* MenuItemView::GetSubmenu() const { |
328 return submenu_; | 341 return submenu_; |
329 } | 342 } |
330 | 343 |
331 void MenuItemView::SetTitle(const string16& title) { | 344 void MenuItemView::SetTitle(const string16& title) { |
332 title_ = title; | 345 title_ = title; |
333 accessible_name_ = GetAccessibleNameForMenuItem(title_, GetAcceleratorText()); | |
334 pref_size_.SetSize(0, 0); // Triggers preferred size recalculation. | 346 pref_size_.SetSize(0, 0); // Triggers preferred size recalculation. |
335 } | 347 } |
336 | 348 |
337 void MenuItemView::SetSelected(bool selected) { | 349 void MenuItemView::SetSelected(bool selected) { |
338 selected_ = selected; | 350 selected_ = selected; |
339 SchedulePaint(); | 351 SchedulePaint(); |
340 } | 352 } |
341 | 353 |
342 void MenuItemView::SetTooltip(const string16& tooltip, int item_id) { | 354 void MenuItemView::SetTooltip(const string16& tooltip, int item_id) { |
343 MenuItemView* item = GetMenuItemByID(item_id); | 355 MenuItemView* item = GetMenuItemByID(item_id); |
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
454 } | 466 } |
455 } | 467 } |
456 | 468 |
457 STLDeleteElements(&removed_items_); | 469 STLDeleteElements(&removed_items_); |
458 } | 470 } |
459 | 471 |
460 void MenuItemView::Layout() { | 472 void MenuItemView::Layout() { |
461 if (!has_children()) | 473 if (!has_children()) |
462 return; | 474 return; |
463 | 475 |
464 if (child_count() == 1 && title_.empty()) { | 476 if (FirstChildTakesOver()) { |
465 // We only have one child and no title so let the view take over all the | |
466 // space. | |
467 View* child = child_at(0); | 477 View* child = child_at(0); |
468 gfx::Size size = child->GetPreferredSize(); | 478 gfx::Size size = child->GetPreferredSize(); |
469 child->SetBounds(0, GetTopMargin(), size.width(), size.height()); | 479 child->SetBounds(0, GetTopMargin(), size.width(), size.height()); |
470 } else { | 480 } else { |
471 // Child views are laid out right aligned and given the full height. To | 481 // Child views are laid out right aligned and given the full height. To |
472 // right align start with the last view and progress to the first. | 482 // right align start with the last view and progress to the first. |
473 for (int i = child_count() - 1, x = width() - item_right_margin_; i >= 0; | 483 for (int i = child_count() - 1, x = width() - item_right_margin_; i >= 0; |
474 --i) { | 484 --i) { |
475 View* child = child_at(i); | 485 View* child = child_at(i); |
476 int width = child->GetPreferredSize().width(); | 486 int width = child->GetPreferredSize().width(); |
(...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
708 MenuItemView* root = GetRootMenuItem(); | 718 MenuItemView* root = GetRootMenuItem(); |
709 return root && root->has_icons_ | 719 return root && root->has_icons_ |
710 ? MenuConfig::instance().item_bottom_margin : | 720 ? MenuConfig::instance().item_bottom_margin : |
711 MenuConfig::instance().item_no_icon_bottom_margin; | 721 MenuConfig::instance().item_no_icon_bottom_margin; |
712 } | 722 } |
713 | 723 |
714 gfx::Size MenuItemView::GetChildPreferredSize() { | 724 gfx::Size MenuItemView::GetChildPreferredSize() { |
715 if (!has_children()) | 725 if (!has_children()) |
716 return gfx::Size(); | 726 return gfx::Size(); |
717 | 727 |
718 if (title_.empty() && child_count() == 1) { | 728 if (FirstChildTakesOver()) { |
719 View* child = child_at(0); | 729 View* child = child_at(0); |
720 return child->GetPreferredSize(); | 730 return child->GetPreferredSize(); |
721 } | 731 } |
722 | 732 |
723 int width = 0; | 733 int width = 0; |
724 for (int i = 0; i < child_count(); ++i) { | 734 for (int i = 0; i < child_count(); ++i) { |
725 if (i) | 735 if (i) |
726 width += kChildXPadding; | 736 width += kChildXPadding; |
727 width += child_at(i)->GetPreferredSize().width(); | 737 width += child_at(i)->GetPreferredSize().width(); |
728 } | 738 } |
729 // Return a height of 0 to indicate that we should use the title height | 739 // Return a height of 0 to indicate that we should use the title height |
730 // instead. | 740 // instead. |
731 return gfx::Size(width, 0); | 741 return gfx::Size(width, 0); |
732 } | 742 } |
733 | 743 |
734 gfx::Size MenuItemView::CalculatePreferredSize() { | 744 gfx::Size MenuItemView::CalculatePreferredSize() { |
735 gfx::Size child_size = GetChildPreferredSize(); | 745 gfx::Size child_size = GetChildPreferredSize(); |
736 if (child_count() == 1 && title_.empty()) { | 746 if (FirstChildTakesOver()) { |
737 return gfx::Size( | 747 return gfx::Size( |
738 child_size.width(), | 748 child_size.width(), |
739 child_size.height() + GetBottomMargin() + GetTopMargin()); | 749 child_size.height() + GetBottomMargin() + GetTopMargin()); |
740 } | 750 } |
741 | 751 |
742 const gfx::Font& font = GetFont(); | 752 const gfx::Font& font = GetFont(); |
743 #if defined(TOUCH_UI) | 753 #if defined(TOUCH_UI) |
744 int height = std::max(font.GetHeight(), kMinItemHeightTouch); | 754 int height = std::max(font.GetHeight(), kMinItemHeightTouch); |
745 #else | 755 #else |
746 int height = font.GetHeight(); | 756 int height = font.GetHeight(); |
(...skipping 13 matching lines...) Expand all Loading... |
760 | 770 |
761 if(!MenuConfig::instance().show_accelerators) | 771 if(!MenuConfig::instance().show_accelerators) |
762 return string16(); | 772 return string16(); |
763 | 773 |
764 Accelerator accelerator; | 774 Accelerator accelerator; |
765 return (GetDelegate() && | 775 return (GetDelegate() && |
766 GetDelegate()->GetAccelerator(GetCommand(), &accelerator)) ? | 776 GetDelegate()->GetAccelerator(GetCommand(), &accelerator)) ? |
767 accelerator.GetShortcutText() : string16(); | 777 accelerator.GetShortcutText() : string16(); |
768 } | 778 } |
769 | 779 |
| 780 bool MenuItemView::FirstChildTakesOver() const { |
| 781 // Let the first child take over |this| when we only have one child and no |
| 782 // title. Note that what child_count() returns is the number of children, |
| 783 // not the number of menu items. |
| 784 return child_count() == 1 && title_.empty(); |
| 785 } |
| 786 |
770 } // namespace views | 787 } // namespace views |
OLD | NEW |