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