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 3 // found in the LICENSE file. 4 5 #include "ui/views/examples/menu_example.h" 6 7 #include <set> 8 9 #include "base/strings/utf_string_conversions.h" 10 #include "ui/base/models/simple_menu_model.h" 11 #include "ui/views/controls/button/menu_button.h" 12 #include "ui/views/controls/button/menu_button_listener.h" 13 #include "ui/views/controls/menu/menu_runner.h" 14 #include "ui/views/layout/fill_layout.h" 15 #include "ui/views/view.h" 16 #include "ui/views/widget/widget.h" 17 18 namespace views { 19 namespace examples { 20 21 namespace { 22 23 class ExampleMenuModel : public ui::SimpleMenuModel, 24 public ui::SimpleMenuModel::Delegate { 25 public: 26 ExampleMenuModel(); 27 28 // Overridden from ui::SimpleMenuModel::Delegate: 29 virtual bool IsCommandIdChecked(int command_id) const OVERRIDE; 30 virtual bool IsCommandIdEnabled(int command_id) const OVERRIDE; 31 virtual bool GetAcceleratorForCommandId( 32 int command_id, 33 ui::Accelerator* accelerator) OVERRIDE; 34 virtual void ExecuteCommand(int command_id, int event_flags) OVERRIDE; 35 36 private: 37 enum GroupID { 38 GROUP_MAKE_DECISION, 39 }; 40 41 enum CommandID { 42 COMMAND_DO_SOMETHING, 43 COMMAND_SELECT_ASCII, 44 COMMAND_SELECT_UTF8, 45 COMMAND_SELECT_UTF16, 46 COMMAND_CHECK_APPLE, 47 COMMAND_CHECK_ORANGE, 48 COMMAND_CHECK_KIWI, 49 COMMAND_GO_HOME, 50 }; 51 52 scoped_ptr<ui::SimpleMenuModel> submenu_; 53 std::set<int> checked_fruits_; 54 int current_encoding_command_id_; 55 56 DISALLOW_COPY_AND_ASSIGN(ExampleMenuModel); 57 }; 58 59 class ExampleMenuButton : public MenuButton, public MenuButtonListener { 60 public: 61 explicit ExampleMenuButton(const string16& test); 62 virtual ~ExampleMenuButton(); 63 64 private: 65 // Overridden from MenuButtonListener: 66 virtual void OnMenuButtonClicked(View* source, 67 const gfx::Point& point) OVERRIDE; 68 69 ui::SimpleMenuModel* GetMenuModel(); 70 71 scoped_ptr<ExampleMenuModel> menu_model_; 72 scoped_ptr<MenuRunner> menu_runner_; 73 74 DISALLOW_COPY_AND_ASSIGN(ExampleMenuButton); 75 }; 76 77 // ExampleMenuModel --------------------------------------------------------- 78 79 ExampleMenuModel::ExampleMenuModel() 80 : ui::SimpleMenuModel(this), 81 current_encoding_command_id_(COMMAND_SELECT_ASCII) { 82 AddItem(COMMAND_DO_SOMETHING, ASCIIToUTF16("Do Something")); 83 AddSeparator(ui::NORMAL_SEPARATOR); 84 AddRadioItem(COMMAND_SELECT_ASCII, ASCIIToUTF16("ASCII"), 85 GROUP_MAKE_DECISION); 86 AddRadioItem(COMMAND_SELECT_UTF8, ASCIIToUTF16("UTF-8"), 87 GROUP_MAKE_DECISION); 88 AddRadioItem(COMMAND_SELECT_UTF16, ASCIIToUTF16("UTF-16"), 89 GROUP_MAKE_DECISION); 90 AddSeparator(ui::NORMAL_SEPARATOR); 91 AddCheckItem(COMMAND_CHECK_APPLE, ASCIIToUTF16("Apple")); 92 AddCheckItem(COMMAND_CHECK_ORANGE, ASCIIToUTF16("Orange")); 93 AddCheckItem(COMMAND_CHECK_KIWI, ASCIIToUTF16("Kiwi")); 94 AddSeparator(ui::NORMAL_SEPARATOR); 95 AddItem(COMMAND_GO_HOME, ASCIIToUTF16("Go Home")); 96 97 submenu_.reset(new ui::SimpleMenuModel(this)); 98 submenu_->AddItem(COMMAND_DO_SOMETHING, ASCIIToUTF16("Do Something 2")); 99 AddSubMenu(0, ASCIIToUTF16("Submenu"), submenu_.get()); 100 } 101 102 bool ExampleMenuModel::IsCommandIdChecked(int command_id) const { 103 // Radio items. 104 if (command_id == current_encoding_command_id_) 105 return true; 106 107 // Check items. 108 if (checked_fruits_.find(command_id) != checked_fruits_.end()) 109 return true; 110 111 return false; 112 } 113 114 bool ExampleMenuModel::IsCommandIdEnabled(int command_id) const { 115 // All commands are enabled except for COMMAND_GO_HOME. 116 return command_id != COMMAND_GO_HOME; 117 } 118 119 bool ExampleMenuModel::GetAcceleratorForCommandId( 120 int command_id, 121 ui::Accelerator* accelerator) { 122 // We don't use this in the example. 123 return false; 124 } 125 126 void ExampleMenuModel::ExecuteCommand(int command_id, int event_flags) { 127 switch (command_id) { 128 case COMMAND_DO_SOMETHING: { 129 LOG(INFO) << "Done something"; 130 break; 131 } 132 133 // Radio items. 134 case COMMAND_SELECT_ASCII: { 135 current_encoding_command_id_ = COMMAND_SELECT_ASCII; 136 LOG(INFO) << "Selected ASCII"; 137 break; 138 } 139 case COMMAND_SELECT_UTF8: { 140 current_encoding_command_id_ = COMMAND_SELECT_UTF8; 141 LOG(INFO) << "Selected UTF-8"; 142 break; 143 } 144 case COMMAND_SELECT_UTF16: { 145 current_encoding_command_id_ = COMMAND_SELECT_UTF16; 146 LOG(INFO) << "Selected UTF-16"; 147 break; 148 } 149 150 // Check items. 151 case COMMAND_CHECK_APPLE: 152 case COMMAND_CHECK_ORANGE: 153 case COMMAND_CHECK_KIWI: { 154 // Print what fruit is checked. 155 const char* checked_fruit = ""; 156 if (command_id == COMMAND_CHECK_APPLE) 157 checked_fruit = "Apple"; 158 else if (command_id == COMMAND_CHECK_ORANGE) 159 checked_fruit = "Orange"; 160 else if (command_id == COMMAND_CHECK_KIWI) 161 checked_fruit = "Kiwi"; 162 163 // Update the check status. 164 std::set<int>::iterator iter = checked_fruits_.find(command_id); 165 if (iter == checked_fruits_.end()) { 166 DVLOG(1) << "Checked " << checked_fruit; 167 checked_fruits_.insert(command_id); 168 } else { 169 DVLOG(1) << "Unchecked " << checked_fruit; 170 checked_fruits_.erase(iter); 171 } 172 break; 173 } 174 } 175 } 176 177 // ExampleMenuButton ----------------------------------------------------------- 178 179 ExampleMenuButton::ExampleMenuButton(const string16& test) 180 : MenuButton(NULL, test, this, true) { 181 } 182 183 ExampleMenuButton::~ExampleMenuButton() { 184 } 185 186 void ExampleMenuButton::OnMenuButtonClicked(View* source, 187 const gfx::Point& point) { 188 menu_runner_.reset(new MenuRunner(GetMenuModel())); 189 190 if (menu_runner_->RunMenuAt(source->GetWidget()->GetTopLevelWidget(), this, 191 gfx::Rect(point, gfx::Size()), MenuItemView::TOPRIGHT, 192 ui::MENU_SOURCE_NONE, MenuRunner::HAS_MNEMONICS) == 193 MenuRunner::MENU_DELETED) 194 return; 195 } 196 197 ui::SimpleMenuModel* ExampleMenuButton::GetMenuModel() { 198 if (!menu_model_.get()) 199 menu_model_.reset(new ExampleMenuModel); 200 return menu_model_.get(); 201 } 202 203 } // namespace 204 205 MenuExample::MenuExample() : ExampleBase("Menu") { 206 } 207 208 MenuExample::~MenuExample() { 209 } 210 211 void MenuExample::CreateExampleView(View* container) { 212 // We add a button to open a menu. 213 ExampleMenuButton* menu_button = new ExampleMenuButton( 214 ASCIIToUTF16("Open a menu")); 215 container->SetLayoutManager(new FillLayout); 216 container->AddChildView(menu_button); 217 } 218 219 } // namespace examples 220 } // namespace views 221