1// Copyright 2013 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#ifndef CHROME_BROWSER_STATUS_ICONS_STATUS_ICON_MENU_MODEL_H_
6#define CHROME_BROWSER_STATUS_ICONS_STATUS_ICON_MENU_MODEL_H_
7
8#include <map>
9
10#include "base/memory/weak_ptr.h"
11#include "base/observer_list.h"
12#include "ui/base/models/simple_menu_model.h"
13
14namespace gfx {
15class Image;
16}
17
18class StatusIconMenuModelTest;
19
20// StatusIconMenuModel contains the state of the SimpleMenuModel as well as that
21// of its delegate. This is done so that we can easily identify when the menu
22// model state has changed and can tell the status icon to update the menu. This
23// is necessary some platforms which do not notify us before showing the menu
24// (like Ubuntu Unity).
25class StatusIconMenuModel
26    : public ui::SimpleMenuModel,
27      public ui::SimpleMenuModel::Delegate,
28      public base::SupportsWeakPtr<StatusIconMenuModel> {
29 public:
30  class Delegate {
31   public:
32    // Notifies the delegate that the item with the specified command id was
33    // visually highlighted within the menu.
34    virtual void CommandIdHighlighted(int command_id);
35
36    // Performs the action associates with the specified command id.
37    // The passed |event_flags| are the flags from the event which issued this
38    // command and they can be examined to find modifier keys.
39    virtual void ExecuteCommand(int command_id, int event_flags) = 0;
40
41   protected:
42    virtual ~Delegate() {}
43  };
44
45  class Observer {
46   public:
47    // Invoked when the menu model has changed.
48    virtual void OnMenuStateChanged() {}
49
50   protected:
51    virtual ~Observer() {}
52  };
53
54  // The Delegate can be NULL.
55  explicit StatusIconMenuModel(Delegate* delegate);
56  virtual ~StatusIconMenuModel();
57
58  // Methods for seting the state of specific command ids.
59  void SetCommandIdChecked(int command_id, bool checked);
60  void SetCommandIdEnabled(int command_id, bool enabled);
61  void SetCommandIdVisible(int command_id, bool visible);
62
63  // Sets the accelerator for the specified command id.
64  void SetAcceleratorForCommandId(
65      int command_id, const ui::Accelerator* accelerator);
66
67  // Calling any of these "change" methods will mark the menu item as "dynamic"
68  // (see menu_model.h:IsItemDynamicAt) which many platforms take as a cue to
69  // refresh the label, sublabel and icon of the menu item each time the menu is
70  // shown.
71  void ChangeLabelForCommandId(int command_id, const base::string16& label);
72  void ChangeSublabelForCommandId(
73      int command_id, const base::string16& sublabel);
74  void ChangeIconForCommandId(int command_id, const gfx::Image& icon);
75
76  void AddObserver(Observer* observer);
77  void RemoveObserver(Observer* observer);
78
79  // Overridden from ui::SimpleMenuModel::Delegate:
80  virtual bool IsCommandIdChecked(int command_id) const OVERRIDE;
81  virtual bool IsCommandIdEnabled(int command_id) const OVERRIDE;
82  virtual bool IsCommandIdVisible(int command_id) const OVERRIDE;
83  virtual bool GetAcceleratorForCommandId(
84      int command_id, ui::Accelerator* accelerator) OVERRIDE;
85  virtual bool IsItemForCommandIdDynamic(int command_id) const OVERRIDE;
86  virtual base::string16 GetLabelForCommandId(int command_id) const OVERRIDE;
87  virtual base::string16 GetSublabelForCommandId(int command_id) const OVERRIDE;
88  virtual bool GetIconForCommandId(int command_id, gfx::Image* icon) const
89      OVERRIDE;
90
91 protected:
92  // Overriden from ui::SimpleMenuModel:
93  virtual void MenuItemsChanged() OVERRIDE;
94
95  void NotifyMenuStateChanged();
96
97  void set_delegate(Delegate* delegate) { delegate_ = delegate; }
98  Delegate* delegate() { return delegate_; }
99
100 private:
101  // Overridden from ui::SimpleMenuModel::Delegate:
102  virtual void CommandIdHighlighted(int command_id) OVERRIDE;
103  virtual void ExecuteCommand(int command_id, int event_flags) OVERRIDE;
104
105  struct ItemState;
106
107  // Map the properties to the command id (used as key).
108  typedef std::map<int, ItemState> ItemStateMap;
109
110  ItemStateMap item_states_;
111
112  ObserverList<Observer> observer_list_;
113
114  Delegate* delegate_;
115
116  DISALLOW_COPY_AND_ASSIGN(StatusIconMenuModel);
117};
118
119#endif  // CHROME_BROWSER_STATUS_ICONS_STATUS_ICON_MENU_MODEL_H_
120