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)#include "chrome/browser/status_icons/status_icon_menu_model.h"
6424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
7424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "base/bind.h"
8424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "base/message_loop/message_loop.h"
9424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "ui/base/accelerators/accelerator.h"
10424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "ui/base/l10n/l10n_util.h"
11424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "ui/gfx/image/image.h"
12424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
13424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)struct StatusIconMenuModel::ItemState {
14424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  ItemState()
15424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      : checked(false),
16424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)        enabled(true),
17424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)        visible(true),
18424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)        is_dynamic(false) {}
19424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  bool checked;
20424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  bool enabled;
21424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  bool visible;
22424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  bool is_dynamic;
23424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  ui::Accelerator accelerator;
24424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  base::string16 label;
25424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  base::string16 sublabel;
26424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  gfx::Image icon;
27424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)};
28424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
29424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
30424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)// StatusIconMenuModel::Delegate, public:
31424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
32424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)void StatusIconMenuModel::Delegate::CommandIdHighlighted(int command_id) {
33424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)}
34424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
35424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
36424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)// StatusIconMenuModel, public:
37424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
38424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)StatusIconMenuModel::StatusIconMenuModel(Delegate* delegate)
39424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    : ui::SimpleMenuModel(this), delegate_(delegate) {
40424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)}
41424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
42424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)StatusIconMenuModel::~StatusIconMenuModel() {
43424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)}
44424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
45424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)void StatusIconMenuModel::SetCommandIdChecked(int command_id, bool checked) {
46424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  item_states_[command_id].checked = checked;
47424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  NotifyMenuStateChanged();
48424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)}
49424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
50424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)void StatusIconMenuModel::SetCommandIdEnabled(int command_id, bool enabled) {
51424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  item_states_[command_id].enabled = enabled;
52424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  NotifyMenuStateChanged();
53424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)}
54424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
55424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)void StatusIconMenuModel::SetCommandIdVisible(int command_id, bool visible) {
56424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  item_states_[command_id].visible = visible;
57424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  NotifyMenuStateChanged();
58424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)}
59424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
60424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)void StatusIconMenuModel::SetAcceleratorForCommandId(
61424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    int command_id, const ui::Accelerator* accelerator) {
62424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  item_states_[command_id].accelerator = *accelerator;
63424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  NotifyMenuStateChanged();
64424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)}
65424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
66424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)void StatusIconMenuModel::ChangeLabelForCommandId(int command_id,
67424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)                                                  const base::string16& label) {
68424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  item_states_[command_id].is_dynamic = true;
69424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  item_states_[command_id].label = label;
70424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  NotifyMenuStateChanged();
71424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)}
72424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
73424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)void StatusIconMenuModel::ChangeSublabelForCommandId(
74424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    int command_id, const base::string16& sublabel) {
75424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  item_states_[command_id].is_dynamic = true;
76424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  item_states_[command_id].sublabel = sublabel;
77424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  NotifyMenuStateChanged();
78424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)}
79424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
80424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)void StatusIconMenuModel::ChangeIconForCommandId(
81424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    int command_id, const gfx::Image& icon) {
82424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  item_states_[command_id].is_dynamic = true;
83424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  item_states_[command_id].icon = icon;
84424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  NotifyMenuStateChanged();
85424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)}
86424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
87424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)void StatusIconMenuModel::AddObserver(Observer* observer) {
88424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  observer_list_.AddObserver(observer);
89424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)}
90424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
91424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)void StatusIconMenuModel::RemoveObserver(Observer* observer) {
92424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  observer_list_.RemoveObserver(observer);
93424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)}
94424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
95424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)bool StatusIconMenuModel::IsCommandIdChecked(int command_id) const {
96424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  ItemStateMap::const_iterator iter = item_states_.find(command_id);
97424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  if (iter != item_states_.end())
98424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    return iter->second.checked;
99424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  return false;
100424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)}
101424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
102424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)bool StatusIconMenuModel::IsCommandIdEnabled(int command_id) const {
103424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  ItemStateMap::const_iterator iter = item_states_.find(command_id);
104424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  if (iter != item_states_.end())
105424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    return iter->second.enabled;
106424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  return true;
107424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)}
108424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
109424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)bool StatusIconMenuModel::IsCommandIdVisible(int command_id) const {
110424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  ItemStateMap::const_iterator iter = item_states_.find(command_id);
111424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  if (iter != item_states_.end())
112424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    return iter->second.visible;
113424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  return true;
114424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)}
115424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
116424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)bool StatusIconMenuModel::GetAcceleratorForCommandId(
117424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    int command_id, ui::Accelerator* accelerator) {
118424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  ItemStateMap::const_iterator iter = item_states_.find(command_id);
119424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  if (iter != item_states_.end() &&
120424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      iter->second.accelerator.key_code() != ui::VKEY_UNKNOWN) {
121424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    *accelerator = iter->second.accelerator;
122424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    return true;
123424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  }
124424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  return false;
125424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)}
126424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
127424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)bool StatusIconMenuModel::IsItemForCommandIdDynamic(int command_id) const {
128424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  ItemStateMap::const_iterator iter = item_states_.find(command_id);
129424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  if (iter != item_states_.end())
130424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    return iter->second.is_dynamic;
131424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  return false;
132424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)}
133424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
134424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)base::string16 StatusIconMenuModel::GetLabelForCommandId(int command_id) const {
135424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  ItemStateMap::const_iterator iter = item_states_.find(command_id);
136424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  if (iter != item_states_.end())
137424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    return iter->second.label;
138424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  return base::string16();
139424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)}
140424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
141424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)base::string16 StatusIconMenuModel::GetSublabelForCommandId(
142424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    int command_id) const {
143424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  ItemStateMap::const_iterator iter = item_states_.find(command_id);
144424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  if (iter != item_states_.end())
145424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    return iter->second.sublabel;
146424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  return base::string16();
147424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)}
148424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
149424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)bool StatusIconMenuModel::GetIconForCommandId(int command_id,
150424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)                                              gfx::Image* image_skia) const {
151424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  ItemStateMap::const_iterator iter = item_states_.find(command_id);
152424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  if (iter != item_states_.end() && !iter->second.icon.IsEmpty()) {
153424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    *image_skia = iter->second.icon;
154424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    return true;
155424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  }
156424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  return false;
157424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)}
158424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
159424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
160424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)// StatusIconMenuModel, protected:
161424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
162424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)void StatusIconMenuModel::MenuItemsChanged() {
163424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  NotifyMenuStateChanged();
164424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)}
165424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
166424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)void StatusIconMenuModel::NotifyMenuStateChanged() {
167424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  FOR_EACH_OBSERVER(Observer, observer_list_, OnMenuStateChanged());
168424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)}
169424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
170424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
171424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)// StatusIconMenuModel, private:
172424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
173424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)void StatusIconMenuModel::CommandIdHighlighted(int command_id) {
174424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  if (delegate_)
175424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    delegate_->CommandIdHighlighted(command_id);
176424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)}
177424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
178424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)void StatusIconMenuModel::ExecuteCommand(int command_id, int event_flags) {
179424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  if (delegate_)
180424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    delegate_->ExecuteCommand(command_id, event_flags);
181424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)}
182