Drive: Add BatchableRequest subclass.
[chromium-blink-merge.git] / ui / base / models / simple_menu_model.cc
blob336fd4139a85095ab464e0c33d4dc52a91f09082
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.
5 #include "ui/base/models/simple_menu_model.h"
7 #include "base/bind.h"
8 #include "base/message_loop/message_loop.h"
9 #include "ui/base/l10n/l10n_util.h"
10 #include "ui/gfx/image/image.h"
12 namespace ui {
14 const int kSeparatorId = -1;
16 struct SimpleMenuModel::Item {
17 int command_id;
18 base::string16 label;
19 base::string16 sublabel;
20 base::string16 minor_text;
21 gfx::Image icon;
22 ItemType type;
23 int group_id;
24 MenuModel* submenu;
25 ButtonMenuItemModel* button_model;
26 MenuSeparatorType separator_type;
29 ////////////////////////////////////////////////////////////////////////////////
30 // SimpleMenuModel::Delegate, public:
32 bool SimpleMenuModel::Delegate::IsCommandIdVisible(int command_id) const {
33 return true;
36 bool SimpleMenuModel::Delegate::IsItemForCommandIdDynamic(
37 int command_id) const {
38 return false;
41 base::string16 SimpleMenuModel::Delegate::GetLabelForCommandId(
42 int command_id) const {
43 return base::string16();
46 base::string16 SimpleMenuModel::Delegate::GetSublabelForCommandId(
47 int command_id) const {
48 return base::string16();
51 base::string16 SimpleMenuModel::Delegate::GetMinorTextForCommandId(
52 int command_id) const {
53 return base::string16();
56 bool SimpleMenuModel::Delegate::GetIconForCommandId(
57 int command_id, gfx::Image* image_skia) const {
58 return false;
61 void SimpleMenuModel::Delegate::CommandIdHighlighted(int command_id) {
64 void SimpleMenuModel::Delegate::ExecuteCommand(
65 int command_id, int event_flags) {
66 ExecuteCommand(command_id, event_flags);
69 void SimpleMenuModel::Delegate::MenuWillShow(SimpleMenuModel* /*source*/) {
72 void SimpleMenuModel::Delegate::MenuClosed(SimpleMenuModel* /*source*/) {
75 ////////////////////////////////////////////////////////////////////////////////
76 // SimpleMenuModel, public:
78 SimpleMenuModel::SimpleMenuModel(Delegate* delegate)
79 : delegate_(delegate),
80 menu_model_delegate_(NULL),
81 method_factory_(this) {
84 SimpleMenuModel::~SimpleMenuModel() {
87 void SimpleMenuModel::AddItem(int command_id, const base::string16& label) {
88 Item item = { command_id, label, base::string16(), base::string16(),
89 gfx::Image(), TYPE_COMMAND, -1, NULL, NULL, NORMAL_SEPARATOR };
90 AppendItem(item);
93 void SimpleMenuModel::AddItemWithStringId(int command_id, int string_id) {
94 AddItem(command_id, l10n_util::GetStringUTF16(string_id));
97 void SimpleMenuModel::AddCheckItem(int command_id,
98 const base::string16& label) {
99 Item item = { command_id, label, base::string16(), base::string16(),
100 gfx::Image(), TYPE_CHECK, -1, NULL, NULL, NORMAL_SEPARATOR };
101 AppendItem(item);
104 void SimpleMenuModel::AddCheckItemWithStringId(int command_id, int string_id) {
105 AddCheckItem(command_id, l10n_util::GetStringUTF16(string_id));
108 void SimpleMenuModel::AddRadioItem(int command_id,
109 const base::string16& label,
110 int group_id) {
111 Item item = { command_id, label, base::string16(), base::string16(),
112 gfx::Image(), TYPE_RADIO, group_id, NULL, NULL,
113 NORMAL_SEPARATOR };
114 AppendItem(item);
117 void SimpleMenuModel::AddRadioItemWithStringId(int command_id, int string_id,
118 int group_id) {
119 AddRadioItem(command_id, l10n_util::GetStringUTF16(string_id), group_id);
122 void SimpleMenuModel::AddSeparator(MenuSeparatorType separator_type) {
123 if (items_.empty()) {
124 if (separator_type == NORMAL_SEPARATOR) {
125 return;
127 DCHECK_EQ(SPACING_SEPARATOR, separator_type);
128 } else if (items_.back().type == TYPE_SEPARATOR) {
129 DCHECK_EQ(NORMAL_SEPARATOR, separator_type);
130 DCHECK_EQ(NORMAL_SEPARATOR, items_.back().separator_type);
131 return;
133 #if !defined(USE_AURA)
134 if (separator_type == SPACING_SEPARATOR)
135 NOTIMPLEMENTED();
136 #endif
137 Item item = { kSeparatorId, base::string16(), base::string16(),
138 base::string16(), gfx::Image(), TYPE_SEPARATOR, -1, NULL, NULL,
139 separator_type };
140 AppendItem(item);
143 void SimpleMenuModel::RemoveTrailingSeparators() {
144 while (!items_.empty() && items_.back().type == TYPE_SEPARATOR)
145 items_.pop_back();
146 MenuItemsChanged();
149 void SimpleMenuModel::AddButtonItem(int command_id,
150 ButtonMenuItemModel* model) {
151 Item item = { command_id, base::string16(), base::string16(),
152 base::string16(), gfx::Image(), TYPE_BUTTON_ITEM, -1, NULL,
153 model, NORMAL_SEPARATOR };
154 AppendItem(item);
157 void SimpleMenuModel::AddSubMenu(int command_id,
158 const base::string16& label,
159 MenuModel* model) {
160 Item item = { command_id, label, base::string16(), base::string16(),
161 gfx::Image(), TYPE_SUBMENU, -1, model, NULL, NORMAL_SEPARATOR };
162 AppendItem(item);
165 void SimpleMenuModel::AddSubMenuWithStringId(int command_id,
166 int string_id, MenuModel* model) {
167 AddSubMenu(command_id, l10n_util::GetStringUTF16(string_id), model);
170 void SimpleMenuModel::InsertItemAt(int index,
171 int command_id,
172 const base::string16& label) {
173 Item item = { command_id, label, base::string16(), base::string16(),
174 gfx::Image(), TYPE_COMMAND, -1, NULL, NULL, NORMAL_SEPARATOR };
175 InsertItemAtIndex(item, index);
178 void SimpleMenuModel::InsertItemWithStringIdAt(
179 int index, int command_id, int string_id) {
180 InsertItemAt(index, command_id, l10n_util::GetStringUTF16(string_id));
183 void SimpleMenuModel::InsertSeparatorAt(int index,
184 MenuSeparatorType separator_type) {
185 #if !defined(USE_AURA)
186 if (separator_type != NORMAL_SEPARATOR) {
187 NOTIMPLEMENTED();
189 #endif
190 Item item = { kSeparatorId, base::string16(), base::string16(),
191 base::string16(), gfx::Image(), TYPE_SEPARATOR, -1, NULL, NULL,
192 separator_type };
193 InsertItemAtIndex(item, index);
196 void SimpleMenuModel::InsertCheckItemAt(int index,
197 int command_id,
198 const base::string16& label) {
199 Item item = { command_id, label, base::string16(), base::string16(),
200 gfx::Image(), TYPE_CHECK, -1, NULL, NULL, NORMAL_SEPARATOR };
201 InsertItemAtIndex(item, index);
204 void SimpleMenuModel::InsertCheckItemWithStringIdAt(
205 int index, int command_id, int string_id) {
206 InsertCheckItemAt(index, command_id, l10n_util::GetStringUTF16(string_id));
209 void SimpleMenuModel::InsertRadioItemAt(int index,
210 int command_id,
211 const base::string16& label,
212 int group_id) {
213 Item item = { command_id, label, base::string16(), base::string16(),
214 gfx::Image(), TYPE_RADIO, group_id, NULL, NULL,
215 NORMAL_SEPARATOR };
216 InsertItemAtIndex(item, index);
219 void SimpleMenuModel::InsertRadioItemWithStringIdAt(
220 int index, int command_id, int string_id, int group_id) {
221 InsertRadioItemAt(
222 index, command_id, l10n_util::GetStringUTF16(string_id), group_id);
225 void SimpleMenuModel::InsertSubMenuAt(int index,
226 int command_id,
227 const base::string16& label,
228 MenuModel* model) {
229 Item item = { command_id, label, base::string16(), base::string16(),
230 gfx::Image(), TYPE_SUBMENU, -1, model, NULL,
231 NORMAL_SEPARATOR };
232 InsertItemAtIndex(item, index);
235 void SimpleMenuModel::InsertSubMenuWithStringIdAt(
236 int index, int command_id, int string_id, MenuModel* model) {
237 InsertSubMenuAt(index, command_id, l10n_util::GetStringUTF16(string_id),
238 model);
241 void SimpleMenuModel::RemoveItemAt(int index) {
242 items_.erase(items_.begin() + ValidateItemIndex(index));
243 MenuItemsChanged();
246 void SimpleMenuModel::SetIcon(int index, const gfx::Image& icon) {
247 items_[ValidateItemIndex(index)].icon = icon;
248 MenuItemsChanged();
251 void SimpleMenuModel::SetSublabel(int index, const base::string16& sublabel) {
252 items_[ValidateItemIndex(index)].sublabel = sublabel;
253 MenuItemsChanged();
256 void SimpleMenuModel::SetMinorText(int index,
257 const base::string16& minor_text) {
258 items_[ValidateItemIndex(index)].minor_text = minor_text;
261 void SimpleMenuModel::Clear() {
262 items_.clear();
263 MenuItemsChanged();
266 int SimpleMenuModel::GetIndexOfCommandId(int command_id) {
267 for (ItemVector::iterator i = items_.begin(); i != items_.end(); ++i) {
268 if (i->command_id == command_id)
269 return static_cast<int>(std::distance(items_.begin(), i));
271 return -1;
274 ////////////////////////////////////////////////////////////////////////////////
275 // SimpleMenuModel, MenuModel implementation:
277 bool SimpleMenuModel::HasIcons() const {
278 for (ItemVector::const_iterator i = items_.begin(); i != items_.end(); ++i) {
279 if (!i->icon.IsEmpty())
280 return true;
283 return false;
286 int SimpleMenuModel::GetItemCount() const {
287 return static_cast<int>(items_.size());
290 MenuModel::ItemType SimpleMenuModel::GetTypeAt(int index) const {
291 return items_[ValidateItemIndex(index)].type;
294 ui::MenuSeparatorType SimpleMenuModel::GetSeparatorTypeAt(int index) const {
295 return items_[ValidateItemIndex(index)].separator_type;
298 int SimpleMenuModel::GetCommandIdAt(int index) const {
299 return items_[ValidateItemIndex(index)].command_id;
302 base::string16 SimpleMenuModel::GetLabelAt(int index) const {
303 if (IsItemDynamicAt(index))
304 return delegate_->GetLabelForCommandId(GetCommandIdAt(index));
305 return items_[ValidateItemIndex(index)].label;
308 base::string16 SimpleMenuModel::GetSublabelAt(int index) const {
309 if (IsItemDynamicAt(index))
310 return delegate_->GetSublabelForCommandId(GetCommandIdAt(index));
311 return items_[ValidateItemIndex(index)].sublabel;
314 base::string16 SimpleMenuModel::GetMinorTextAt(int index) const {
315 if (IsItemDynamicAt(index))
316 return delegate_->GetMinorTextForCommandId(GetCommandIdAt(index));
317 return items_[ValidateItemIndex(index)].minor_text;
320 bool SimpleMenuModel::IsItemDynamicAt(int index) const {
321 if (delegate_)
322 return delegate_->IsItemForCommandIdDynamic(GetCommandIdAt(index));
323 return false;
326 bool SimpleMenuModel::GetAcceleratorAt(int index,
327 ui::Accelerator* accelerator) const {
328 if (delegate_) {
329 return delegate_->GetAcceleratorForCommandId(GetCommandIdAt(index),
330 accelerator);
332 return false;
335 bool SimpleMenuModel::IsItemCheckedAt(int index) const {
336 if (!delegate_)
337 return false;
338 MenuModel::ItemType item_type = GetTypeAt(index);
339 return (item_type == TYPE_CHECK || item_type == TYPE_RADIO) ?
340 delegate_->IsCommandIdChecked(GetCommandIdAt(index)) : false;
343 int SimpleMenuModel::GetGroupIdAt(int index) const {
344 return items_[ValidateItemIndex(index)].group_id;
347 bool SimpleMenuModel::GetIconAt(int index, gfx::Image* icon) {
348 if (IsItemDynamicAt(index))
349 return delegate_->GetIconForCommandId(GetCommandIdAt(index), icon);
351 ValidateItemIndex(index);
352 if (items_[index].icon.IsEmpty())
353 return false;
355 *icon = items_[index].icon;
356 return true;
359 ButtonMenuItemModel* SimpleMenuModel::GetButtonMenuItemAt(int index) const {
360 return items_[ValidateItemIndex(index)].button_model;
363 bool SimpleMenuModel::IsEnabledAt(int index) const {
364 int command_id = GetCommandIdAt(index);
365 if (!delegate_ || command_id == kSeparatorId || GetButtonMenuItemAt(index))
366 return true;
367 return delegate_->IsCommandIdEnabled(command_id);
370 bool SimpleMenuModel::IsVisibleAt(int index) const {
371 int command_id = GetCommandIdAt(index);
372 if (!delegate_ || command_id == kSeparatorId || GetButtonMenuItemAt(index))
373 return true;
374 return delegate_->IsCommandIdVisible(command_id);
377 void SimpleMenuModel::HighlightChangedTo(int index) {
378 if (delegate_)
379 delegate_->CommandIdHighlighted(GetCommandIdAt(index));
382 void SimpleMenuModel::ActivatedAt(int index) {
383 if (delegate_)
384 delegate_->ExecuteCommand(GetCommandIdAt(index), 0);
387 void SimpleMenuModel::ActivatedAt(int index, int event_flags) {
388 if (delegate_)
389 delegate_->ExecuteCommand(GetCommandIdAt(index), event_flags);
392 MenuModel* SimpleMenuModel::GetSubmenuModelAt(int index) const {
393 return items_[ValidateItemIndex(index)].submenu;
396 void SimpleMenuModel::MenuWillShow() {
397 if (delegate_)
398 delegate_->MenuWillShow(this);
401 void SimpleMenuModel::MenuClosed() {
402 // Due to how menus work on the different platforms, ActivatedAt will be
403 // called after this. It's more convenient for the delegate to be called
404 // afterwards though, so post a task.
405 base::MessageLoop::current()->PostTask(
406 FROM_HERE,
407 base::Bind(&SimpleMenuModel::OnMenuClosed, method_factory_.GetWeakPtr()));
410 void SimpleMenuModel::SetMenuModelDelegate(
411 ui::MenuModelDelegate* menu_model_delegate) {
412 menu_model_delegate_ = menu_model_delegate;
415 MenuModelDelegate* SimpleMenuModel::GetMenuModelDelegate() const {
416 return menu_model_delegate_;
419 void SimpleMenuModel::OnMenuClosed() {
420 if (delegate_)
421 delegate_->MenuClosed(this);
424 ////////////////////////////////////////////////////////////////////////////////
425 // SimpleMenuModel, Protected:
427 void SimpleMenuModel::MenuItemsChanged() {
430 ////////////////////////////////////////////////////////////////////////////////
431 // SimpleMenuModel, Private:
433 int SimpleMenuModel::ValidateItemIndex(int index) const {
434 CHECK_GE(index, 0);
435 CHECK_LT(static_cast<size_t>(index), items_.size());
436 return index;
439 void SimpleMenuModel::AppendItem(const Item& item) {
440 ValidateItem(item);
441 items_.push_back(item);
442 MenuItemsChanged();
445 void SimpleMenuModel::InsertItemAtIndex(const Item& item, int index) {
446 ValidateItem(item);
447 items_.insert(items_.begin() + index, item);
448 MenuItemsChanged();
451 void SimpleMenuModel::ValidateItem(const Item& item) {
452 #ifndef NDEBUG
453 if (item.type == TYPE_SEPARATOR) {
454 DCHECK_EQ(item.command_id, kSeparatorId);
455 } else {
456 DCHECK_GE(item.command_id, 0);
458 #endif // NDEBUG
461 } // namespace ui