1424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
2424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)// found in the LICENSE file.
4424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
5424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#ifndef CHROME_BROWSER_STATUS_ICONS_STATUS_ICON_MENU_MODEL_H_
6424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#define CHROME_BROWSER_STATUS_ICONS_STATUS_ICON_MENU_MODEL_H_
7424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
8424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include <map>
9424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
10424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "base/memory/weak_ptr.h"
11424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "base/observer_list.h"
12424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "ui/base/models/simple_menu_model.h"
13424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
14424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)namespace gfx {
15424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)class Image;
16424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)}
17424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
18424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)class StatusIconMenuModelTest;
19424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
20424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)// StatusIconMenuModel contains the state of the SimpleMenuModel as well as that
21424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)// of its delegate. This is done so that we can easily identify when the menu
22424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)// model state has changed and can tell the status icon to update the menu. This
23424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)// is necessary some platforms which do not notify us before showing the menu
24424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)// (like Ubuntu Unity).
25424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)class StatusIconMenuModel
26424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    : public ui::SimpleMenuModel,
27424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      public ui::SimpleMenuModel::Delegate,
28424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      public base::SupportsWeakPtr<StatusIconMenuModel> {
29424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) public:
30424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  class Delegate {
31424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)   public:
32424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    // Notifies the delegate that the item with the specified command id was
33424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    // visually highlighted within the menu.
34424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    virtual void CommandIdHighlighted(int command_id);
35424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
36424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    // Performs the action associates with the specified command id.
37424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    // The passed |event_flags| are the flags from the event which issued this
38424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    // command and they can be examined to find modifier keys.
39424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    virtual void ExecuteCommand(int command_id, int event_flags) = 0;
40424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
41424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)   protected:
42424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    virtual ~Delegate() {}
43424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  };
44424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
45424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  class Observer {
46424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)   public:
47424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    // Invoked when the menu model has changed.
48424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    virtual void OnMenuStateChanged() {}
49424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
50424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)   protected:
51424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    virtual ~Observer() {}
52424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  };
53424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
54424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // The Delegate can be NULL.
55424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  explicit StatusIconMenuModel(Delegate* delegate);
56424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  virtual ~StatusIconMenuModel();
57424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
58424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // Methods for seting the state of specific command ids.
59424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  void SetCommandIdChecked(int command_id, bool checked);
60424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  void SetCommandIdEnabled(int command_id, bool enabled);
61424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  void SetCommandIdVisible(int command_id, bool visible);
62424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
63424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // Sets the accelerator for the specified command id.
64424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  void SetAcceleratorForCommandId(
65424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      int command_id, const ui::Accelerator* accelerator);
66424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
67424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // Calling any of these "change" methods will mark the menu item as "dynamic"
68424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // (see menu_model.h:IsItemDynamicAt) which many platforms take as a cue to
69424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // refresh the label, sublabel and icon of the menu item each time the menu is
70424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // shown.
71424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  void ChangeLabelForCommandId(int command_id, const base::string16& label);
72424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  void ChangeSublabelForCommandId(
73424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      int command_id, const base::string16& sublabel);
74424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  void ChangeIconForCommandId(int command_id, const gfx::Image& icon);
75424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
76424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  void AddObserver(Observer* observer);
77424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  void RemoveObserver(Observer* observer);
78424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
79424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // Overridden from ui::SimpleMenuModel::Delegate:
80424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  virtual bool IsCommandIdChecked(int command_id) const OVERRIDE;
81424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  virtual bool IsCommandIdEnabled(int command_id) const OVERRIDE;
82424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  virtual bool IsCommandIdVisible(int command_id) const OVERRIDE;
83424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  virtual bool GetAcceleratorForCommandId(
84424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      int command_id, ui::Accelerator* accelerator) OVERRIDE;
85424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  virtual bool IsItemForCommandIdDynamic(int command_id) const OVERRIDE;
86424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  virtual base::string16 GetLabelForCommandId(int command_id) const OVERRIDE;
87424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  virtual base::string16 GetSublabelForCommandId(int command_id) const OVERRIDE;
88424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  virtual bool GetIconForCommandId(int command_id, gfx::Image* icon) const
89424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      OVERRIDE;
90424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
91424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) protected:
92424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // Overriden from ui::SimpleMenuModel:
93424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  virtual void MenuItemsChanged() OVERRIDE;
94424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
95424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  void NotifyMenuStateChanged();
96424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
97424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  void set_delegate(Delegate* delegate) { delegate_ = delegate; }
98424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  Delegate* delegate() { return delegate_; }
99424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
100424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) private:
101424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // Overridden from ui::SimpleMenuModel::Delegate:
102424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  virtual void CommandIdHighlighted(int command_id) OVERRIDE;
103424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  virtual void ExecuteCommand(int command_id, int event_flags) OVERRIDE;
104424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
105424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  struct ItemState;
106424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
107424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // Map the properties to the command id (used as key).
108424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  typedef std::map<int, ItemState> ItemStateMap;
109424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
110424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  ItemStateMap item_states_;
111424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
112424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  ObserverList<Observer> observer_list_;
113424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
114424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  Delegate* delegate_;
115424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
116424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(StatusIconMenuModel);
117424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)};
118424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
119424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#endif  // CHROME_BROWSER_STATUS_ICONS_STATUS_ICON_MENU_MODEL_H_
120