OLD | NEW |
---|---|
(Empty) | |
1 // Copyright (c) 2010 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 "views/controls/menu/native_menu_x.h" | |
6 | |
7 #include "base/logging.h" | |
8 #include "base/utf_string_conversions.h" | |
9 #include "gfx/canvas_skia.h" | |
10 #include "gfx/skia_util.h" | |
11 #include "views/controls/menu/menu_2.h" | |
12 #include "views/controls/menu/submenu_view.h" | |
13 | |
14 namespace views { | |
15 | |
16 NativeMenuX::NativeMenuX(Menu2* menu) | |
17 : model_(menu->model()), | |
18 ALLOW_THIS_IN_INITIALIZER_LIST(root_(new MenuItemView(this))) { | |
19 } | |
20 | |
21 NativeMenuX::~NativeMenuX() { | |
22 delete root_; | |
sky
2010/11/22 17:06:15
Use scoped_ptr
sadrul
2010/11/22 18:48:22
Done.
| |
23 } | |
24 | |
25 // MenuWrapper implementation: | |
26 void NativeMenuX::RunMenuAt(const gfx::Point& point, int alignment) { | |
27 UpdateStates(); | |
28 root_->RunMenuAt(NULL, NULL, gfx::Rect(point, gfx::Size()), | |
29 alignment == Menu2::ALIGN_TOPLEFT ? MenuItemView::TOPLEFT : | |
30 MenuItemView::TOPRIGHT, true); | |
31 } | |
32 | |
33 void NativeMenuX::CancelMenu() { | |
34 NOTIMPLEMENTED(); | |
35 } | |
36 | |
37 void NativeMenuX::Rebuild() { | |
38 if (SubmenuView* submenu = root_->GetSubmenu()) { | |
39 submenu->RemoveAllChildViews(true); | |
40 } | |
41 AddMenuItemsFromModel(root_, model_); | |
42 } | |
43 | |
44 void NativeMenuX::UpdateStates() { | |
45 SubmenuView* submenu = root_->CreateSubmenu(); | |
46 UpdateMenuFromModel(submenu, model_); | |
47 } | |
48 | |
49 gfx::NativeMenu NativeMenuX::GetNativeMenu() const { | |
50 NOTIMPLEMENTED(); | |
51 return NULL; | |
52 } | |
53 | |
54 MenuWrapper::MenuAction NativeMenuX::GetMenuAction() const { | |
55 NOTIMPLEMENTED(); | |
56 return MENU_ACTION_NONE; | |
57 } | |
58 | |
59 void NativeMenuX::AddMenuListener(MenuListener* listener) { | |
60 NOTIMPLEMENTED(); | |
61 } | |
62 | |
63 void NativeMenuX::RemoveMenuListener(MenuListener* listener) { | |
64 NOTIMPLEMENTED(); | |
65 } | |
66 | |
67 void NativeMenuX::SetMinimumWidth(int width) { | |
68 NOTIMPLEMENTED(); | |
69 } | |
70 | |
71 // MenuDelegate implementation | |
72 | |
73 bool NativeMenuX::IsItemChecked(int cmd) const { | |
74 int index; | |
75 menus::MenuModel* model = model_; | |
76 if (!menus::MenuModel::GetModelAndIndexForCommandId(cmd, &model, &index)) | |
77 return false; | |
78 return model->IsItemCheckedAt(index); | |
79 } | |
80 | |
81 bool NativeMenuX::IsCommandEnabled(int cmd) const { | |
82 int index; | |
83 menus::MenuModel* model = model_; | |
84 if (!menus::MenuModel::GetModelAndIndexForCommandId(cmd, &model, &index)) | |
85 return false; | |
86 return model->IsEnabledAt(index); | |
87 } | |
88 | |
89 void NativeMenuX::ExecuteCommand(int cmd) { | |
90 int index; | |
91 menus::MenuModel* model = model_; | |
92 if (!menus::MenuModel::GetModelAndIndexForCommandId(cmd, &model, &index)) | |
93 return; | |
94 model->ActivatedAt(index); | |
95 } | |
96 | |
97 bool NativeMenuX::GetAccelerator(int id, views::Accelerator* accelerator) { | |
98 int index; | |
99 menus::MenuModel* model = model_; | |
100 if (!menus::MenuModel::GetModelAndIndexForCommandId(id, &model, &index)) | |
101 return false; | |
102 | |
103 menus::Accelerator menu_accelerator; | |
104 if (!model->GetAcceleratorAt(index, &menu_accelerator)) | |
105 return false; | |
106 | |
107 *accelerator = views::Accelerator(menu_accelerator.GetKeyCode(), | |
108 menu_accelerator.modifiers()); | |
109 return true; | |
110 } | |
111 | |
112 // private | |
113 void NativeMenuX::AddMenuItemsFromModel(MenuItemView* parent, | |
114 menus::MenuModel* model) { | |
115 for (int i = 0; i < model->GetItemCount(); ++i) { | |
116 menus::MenuModel::ItemType menu_type = model->GetTypeAt(i); | |
sky
2010/11/22 17:06:15
Offset by GetFirstItemIndex.
sadrul
2010/11/22 18:48:22
Done.
| |
117 MenuItemView::Type type; | |
118 std::wstring label; | |
119 | |
120 switch (menu_type) { | |
121 case menus::MenuModel::TYPE_COMMAND: | |
sky
2010/11/22 17:06:15
Move the code that converts from menus::MenuModel:
sadrul
2010/11/22 18:48:22
Added MenuItemView::AppendMenuItemFromModel to do
| |
122 type = MenuItemView::NORMAL; | |
123 label = UTF16ToWide(model->GetLabelAt(i)); | |
124 break; | |
125 case menus::MenuModel::TYPE_CHECK: | |
126 type = MenuItemView::CHECKBOX; | |
127 label = UTF16ToWide(model->GetLabelAt(i)); | |
128 break; | |
129 case menus::MenuModel::TYPE_RADIO: | |
130 type = MenuItemView::RADIO; | |
131 label = UTF16ToWide(model->GetLabelAt(i)); | |
132 break; | |
133 case menus::MenuModel::TYPE_SEPARATOR: | |
134 type = MenuItemView::SEPARATOR; | |
135 break; | |
136 case menus::MenuModel::TYPE_SUBMENU: | |
137 type = MenuItemView::SUBMENU; | |
138 label = UTF16ToWide(model->GetLabelAt(i)); | |
139 break; | |
140 default: | |
141 NOTREACHED(); | |
142 type = MenuItemView::NORMAL; | |
143 break; | |
144 } | |
145 | |
146 MenuItemView* child = parent->AppendMenuItemImpl(model->GetCommandIdAt(i), | |
147 label, SkBitmap(), type); | |
148 | |
149 if (type == MenuItemView::SUBMENU) { | |
150 AddMenuItemsFromModel(child, model->GetSubmenuModelAt(i)); | |
151 } | |
152 } | |
153 } | |
154 | |
155 void NativeMenuX::UpdateMenuFromModel(SubmenuView* menu, | |
156 menus::MenuModel* model) { | |
sky
2010/11/22 17:06:15
spacing is off.
sadrul
2010/11/22 18:48:22
Done.
| |
157 for (int i = 0, sep = 0; i < model->GetItemCount(); ++i) { | |
158 if (model->GetTypeAt(i) == menus::MenuModel::TYPE_SEPARATOR) { | |
sky
2010/11/22 17:06:15
Don't you need to offset by model->GetFirstItemInd
sadrul
2010/11/22 18:48:22
Done.
| |
159 ++sep; | |
160 continue; | |
161 } | |
162 | |
163 // The submenu excludes the separators when counting the menu-items | |
164 // in it. So exclude the number of separators to get the correct index. | |
165 MenuItemView* mitem = menu->GetMenuItemAt(i - sep); | |
166 mitem->SetVisible(model->IsVisibleAt(i)); | |
167 mitem->SetEnabled(model->IsEnabledAt(i)); | |
168 if (model->IsLabelDynamicAt(i)) { | |
169 mitem->SetTitle(UTF16ToWide(model->GetLabelAt(i))); | |
170 } | |
171 | |
172 SkBitmap icon; | |
173 if (model->GetIconAt(i, &icon)) { | |
174 mitem->SetIcon(icon); | |
175 } | |
176 | |
177 if (model->GetTypeAt(i) == menus::MenuModel::TYPE_SUBMENU) { | |
178 DCHECK(mitem->HasSubmenu()); | |
179 UpdateMenuFromModel(mitem->GetSubmenu(), model->GetSubmenuModelAt(i)); | |
180 } | |
181 } | |
182 } | |
183 | |
184 // MenuWrapper, public: | |
185 | |
186 // static | |
187 MenuWrapper* MenuWrapper::CreateWrapper(Menu2* menu) { | |
188 return new NativeMenuX(menu); | |
189 } | |
190 | |
191 } // namespace views | |
OLD | NEW |