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 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