// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "ui/views/examples/menu_example.h" #include <set> #include "base/strings/utf_string_conversions.h" #include "ui/base/models/simple_menu_model.h" #include "ui/views/controls/button/menu_button.h" #include "ui/views/controls/button/menu_button_listener.h" #include "ui/views/controls/menu/menu_runner.h" #include "ui/views/layout/fill_layout.h" #include "ui/views/view.h" #include "ui/views/widget/widget.h" using base::ASCIIToUTF16; namespace views { namespace examples { namespace { class ExampleMenuModel : public ui::SimpleMenuModel, public ui::SimpleMenuModel::Delegate { public: ExampleMenuModel(); // ui::SimpleMenuModel::Delegate: virtual bool IsCommandIdChecked(int command_id) const OVERRIDE; virtual bool IsCommandIdEnabled(int command_id) const OVERRIDE; virtual bool GetAcceleratorForCommandId( int command_id, ui::Accelerator* accelerator) OVERRIDE; virtual void ExecuteCommand(int command_id, int event_flags) OVERRIDE; private: enum GroupID { GROUP_MAKE_DECISION, }; enum CommandID { COMMAND_DO_SOMETHING, COMMAND_SELECT_ASCII, COMMAND_SELECT_UTF8, COMMAND_SELECT_UTF16, COMMAND_CHECK_APPLE, COMMAND_CHECK_ORANGE, COMMAND_CHECK_KIWI, COMMAND_GO_HOME, }; scoped_ptr<ui::SimpleMenuModel> submenu_; std::set<int> checked_fruits_; int current_encoding_command_id_; DISALLOW_COPY_AND_ASSIGN(ExampleMenuModel); }; class ExampleMenuButton : public MenuButton, public MenuButtonListener { public: explicit ExampleMenuButton(const base::string16& test); virtual ~ExampleMenuButton(); private: // MenuButtonListener: virtual void OnMenuButtonClicked(View* source, const gfx::Point& point) OVERRIDE; ui::SimpleMenuModel* GetMenuModel(); scoped_ptr<ExampleMenuModel> menu_model_; scoped_ptr<MenuRunner> menu_runner_; DISALLOW_COPY_AND_ASSIGN(ExampleMenuButton); }; // ExampleMenuModel --------------------------------------------------------- ExampleMenuModel::ExampleMenuModel() : ui::SimpleMenuModel(this), current_encoding_command_id_(COMMAND_SELECT_ASCII) { AddItem(COMMAND_DO_SOMETHING, ASCIIToUTF16("Do Something")); AddSeparator(ui::NORMAL_SEPARATOR); AddRadioItem(COMMAND_SELECT_ASCII, ASCIIToUTF16("ASCII"), GROUP_MAKE_DECISION); AddRadioItem(COMMAND_SELECT_UTF8, ASCIIToUTF16("UTF-8"), GROUP_MAKE_DECISION); AddRadioItem(COMMAND_SELECT_UTF16, ASCIIToUTF16("UTF-16"), GROUP_MAKE_DECISION); AddSeparator(ui::NORMAL_SEPARATOR); AddCheckItem(COMMAND_CHECK_APPLE, ASCIIToUTF16("Apple")); AddCheckItem(COMMAND_CHECK_ORANGE, ASCIIToUTF16("Orange")); AddCheckItem(COMMAND_CHECK_KIWI, ASCIIToUTF16("Kiwi")); AddSeparator(ui::NORMAL_SEPARATOR); AddItem(COMMAND_GO_HOME, ASCIIToUTF16("Go Home")); submenu_.reset(new ui::SimpleMenuModel(this)); submenu_->AddItem(COMMAND_DO_SOMETHING, ASCIIToUTF16("Do Something 2")); AddSubMenu(0, ASCIIToUTF16("Submenu"), submenu_.get()); } bool ExampleMenuModel::IsCommandIdChecked(int command_id) const { // Radio items. if (command_id == current_encoding_command_id_) return true; // Check items. if (checked_fruits_.find(command_id) != checked_fruits_.end()) return true; return false; } bool ExampleMenuModel::IsCommandIdEnabled(int command_id) const { // All commands are enabled except for COMMAND_GO_HOME. return command_id != COMMAND_GO_HOME; } bool ExampleMenuModel::GetAcceleratorForCommandId( int command_id, ui::Accelerator* accelerator) { // We don't use this in the example. return false; } void ExampleMenuModel::ExecuteCommand(int command_id, int event_flags) { switch (command_id) { case COMMAND_DO_SOMETHING: { VLOG(0) << "Done something"; break; } // Radio items. case COMMAND_SELECT_ASCII: { current_encoding_command_id_ = COMMAND_SELECT_ASCII; VLOG(0) << "Selected ASCII"; break; } case COMMAND_SELECT_UTF8: { current_encoding_command_id_ = COMMAND_SELECT_UTF8; VLOG(0) << "Selected UTF-8"; break; } case COMMAND_SELECT_UTF16: { current_encoding_command_id_ = COMMAND_SELECT_UTF16; VLOG(0) << "Selected UTF-16"; break; } // Check items. case COMMAND_CHECK_APPLE: case COMMAND_CHECK_ORANGE: case COMMAND_CHECK_KIWI: { // Print what fruit is checked. const char* checked_fruit = ""; if (command_id == COMMAND_CHECK_APPLE) checked_fruit = "Apple"; else if (command_id == COMMAND_CHECK_ORANGE) checked_fruit = "Orange"; else if (command_id == COMMAND_CHECK_KIWI) checked_fruit = "Kiwi"; // Update the check status. std::set<int>::iterator iter = checked_fruits_.find(command_id); if (iter == checked_fruits_.end()) { DVLOG(1) << "Checked " << checked_fruit; checked_fruits_.insert(command_id); } else { DVLOG(1) << "Unchecked " << checked_fruit; checked_fruits_.erase(iter); } break; } } } // ExampleMenuButton ----------------------------------------------------------- ExampleMenuButton::ExampleMenuButton(const base::string16& test) : MenuButton(NULL, test, this, true) { } ExampleMenuButton::~ExampleMenuButton() { } void ExampleMenuButton::OnMenuButtonClicked(View* source, const gfx::Point& point) { menu_runner_.reset(new MenuRunner(GetMenuModel())); if (menu_runner_->RunMenuAt(source->GetWidget()->GetTopLevelWidget(), this, gfx::Rect(point, gfx::Size()), MENU_ANCHOR_TOPRIGHT, ui::MENU_SOURCE_NONE, MenuRunner::HAS_MNEMONICS) == MenuRunner::MENU_DELETED) { return; } } ui::SimpleMenuModel* ExampleMenuButton::GetMenuModel() { if (!menu_model_.get()) menu_model_.reset(new ExampleMenuModel); return menu_model_.get(); } } // namespace MenuExample::MenuExample() : ExampleBase("Menu") { } MenuExample::~MenuExample() { } void MenuExample::CreateExampleView(View* container) { // We add a button to open a menu. ExampleMenuButton* menu_button = new ExampleMenuButton( ASCIIToUTF16("Open a menu")); container->SetLayoutManager(new FillLayout); container->AddChildView(menu_button); } } // namespace examples } // namespace views