Home | History | Annotate | Download | only in examples
      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