OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "ui/views/controls/menu/native_menu_win.h" | 5 #include "ui/views/controls/menu/native_menu_win.h" |
6 | 6 |
7 #include "base/logging.h" | 7 #include "base/logging.h" |
8 #include "base/stl_util.h" | 8 #include "base/memory/ptr_util.h" |
9 #include "base/strings/string_util.h" | 9 #include "base/strings/string_util.h" |
10 #include "ui/base/accelerators/accelerator.h" | 10 #include "ui/base/accelerators/accelerator.h" |
11 #include "ui/base/l10n/l10n_util.h" | 11 #include "ui/base/l10n/l10n_util.h" |
12 #include "ui/base/l10n/l10n_util_win.h" | 12 #include "ui/base/l10n/l10n_util_win.h" |
13 #include "ui/base/models/menu_model.h" | 13 #include "ui/base/models/menu_model.h" |
14 #include "ui/views/controls/menu/menu_insertion_delegate_win.h" | 14 #include "ui/views/controls/menu/menu_insertion_delegate_win.h" |
15 | 15 |
16 namespace views { | 16 namespace views { |
17 | 17 |
18 struct NativeMenuWin::ItemData { | 18 struct NativeMenuWin::ItemData { |
(...skipping 19 matching lines...) Expand all Loading... |
38 mi.fMask = MIM_MENUDATA | MIM_STYLE; | 38 mi.fMask = MIM_MENUDATA | MIM_STYLE; |
39 GetMenuInfo(hmenu, &mi); | 39 GetMenuInfo(hmenu, &mi); |
40 return reinterpret_cast<NativeMenuWin*>(mi.dwMenuData); | 40 return reinterpret_cast<NativeMenuWin*>(mi.dwMenuData); |
41 } | 41 } |
42 | 42 |
43 //////////////////////////////////////////////////////////////////////////////// | 43 //////////////////////////////////////////////////////////////////////////////// |
44 // NativeMenuWin, public: | 44 // NativeMenuWin, public: |
45 | 45 |
46 NativeMenuWin::NativeMenuWin(ui::MenuModel* model, HWND system_menu_for) | 46 NativeMenuWin::NativeMenuWin(ui::MenuModel* model, HWND system_menu_for) |
47 : model_(model), | 47 : model_(model), |
48 menu_(NULL), | 48 menu_(nullptr), |
49 owner_draw_(l10n_util::NeedOverrideDefaultUIFont(NULL, NULL) && | 49 owner_draw_(l10n_util::NeedOverrideDefaultUIFont(nullptr, nullptr) && |
50 !system_menu_for), | 50 !system_menu_for), |
51 system_menu_for_(system_menu_for), | 51 system_menu_for_(system_menu_for), |
52 first_item_index_(0), | 52 first_item_index_(0), |
53 parent_(NULL), | 53 parent_(nullptr), |
54 destroyed_flag_(NULL) { | 54 destroyed_flag_(nullptr) {} |
55 } | |
56 | 55 |
57 NativeMenuWin::~NativeMenuWin() { | 56 NativeMenuWin::~NativeMenuWin() { |
58 if (destroyed_flag_) | 57 if (destroyed_flag_) |
59 *destroyed_flag_ = true; | 58 *destroyed_flag_ = true; |
60 base::STLDeleteContainerPointers(items_.begin(), items_.end()); | 59 items_.clear(); |
61 DestroyMenu(menu_); | 60 DestroyMenu(menu_); |
62 } | 61 } |
63 | 62 |
64 //////////////////////////////////////////////////////////////////////////////// | 63 //////////////////////////////////////////////////////////////////////////////// |
65 // NativeMenuWin, MenuWrapper implementation: | 64 // NativeMenuWin, MenuWrapper implementation: |
66 | 65 |
67 void NativeMenuWin::Rebuild(MenuInsertionDelegateWin* delegate) { | 66 void NativeMenuWin::Rebuild(MenuInsertionDelegateWin* delegate) { |
68 ResetNativeMenu(); | 67 ResetNativeMenu(); |
69 items_.clear(); | 68 items_.clear(); |
70 | 69 |
71 owner_draw_ = model_->HasIcons() || owner_draw_; | 70 owner_draw_ = model_->HasIcons() || owner_draw_; |
72 first_item_index_ = delegate ? delegate->GetInsertionIndex(menu_) : 0; | 71 first_item_index_ = delegate ? delegate->GetInsertionIndex(menu_) : 0; |
73 for (int menu_index = first_item_index_; | 72 for (int menu_index = first_item_index_; |
74 menu_index < first_item_index_ + model_->GetItemCount(); ++menu_index) { | 73 menu_index < first_item_index_ + model_->GetItemCount(); ++menu_index) { |
75 int model_index = menu_index - first_item_index_; | 74 int model_index = menu_index - first_item_index_; |
76 if (model_->GetTypeAt(model_index) == ui::MenuModel::TYPE_SEPARATOR) | 75 if (model_->GetTypeAt(model_index) == ui::MenuModel::TYPE_SEPARATOR) |
77 AddSeparatorItemAt(menu_index, model_index); | 76 AddSeparatorItemAt(menu_index, model_index); |
78 else | 77 else |
79 AddMenuItemAt(menu_index, model_index); | 78 AddMenuItemAt(menu_index, model_index); |
80 } | 79 } |
81 } | 80 } |
82 | 81 |
83 void NativeMenuWin::UpdateStates() { | 82 void NativeMenuWin::UpdateStates() { |
84 // A depth-first walk of the menu items, updating states. | 83 // A depth-first walk of the menu items, updating states. |
85 int model_index = 0; | 84 int model_index = 0; |
86 std::vector<ItemData*>::const_iterator it; | 85 std::vector<ItemData*>::const_iterator it; |
87 for (it = items_.begin(); it != items_.end(); ++it, ++model_index) { | 86 for (auto it = items_.begin(); it != items_.end(); ++it, ++model_index) { |
88 int menu_index = model_index + first_item_index_; | 87 int menu_index = model_index + first_item_index_; |
89 SetMenuItemState(menu_index, model_->IsEnabledAt(model_index), | 88 SetMenuItemState(menu_index, model_->IsEnabledAt(model_index), |
90 model_->IsItemCheckedAt(model_index), false); | 89 model_->IsItemCheckedAt(model_index), false); |
91 if (model_->IsItemDynamicAt(model_index)) { | 90 if (model_->IsItemDynamicAt(model_index)) { |
92 // TODO(atwilson): Update the icon as well (http://crbug.com/66508). | 91 // TODO(atwilson): Update the icon as well (http://crbug.com/66508). |
93 SetMenuItemLabel(menu_index, model_index, | 92 SetMenuItemLabel(menu_index, model_index, |
94 model_->GetLabelAt(model_index)); | 93 model_->GetLabelAt(model_index)); |
95 } | 94 } |
96 NativeMenuWin* submenu = (*it)->submenu.get(); | 95 NativeMenuWin* submenu = (*it)->submenu.get(); |
97 if (submenu) | 96 if (submenu) |
(...skipping 14 matching lines...) Expand all Loading... |
112 | 111 |
113 void NativeMenuWin::AddMenuItemAt(int menu_index, int model_index) { | 112 void NativeMenuWin::AddMenuItemAt(int menu_index, int model_index) { |
114 MENUITEMINFO mii = {0}; | 113 MENUITEMINFO mii = {0}; |
115 mii.cbSize = sizeof(mii); | 114 mii.cbSize = sizeof(mii); |
116 mii.fMask = MIIM_FTYPE | MIIM_ID | MIIM_DATA; | 115 mii.fMask = MIIM_FTYPE | MIIM_ID | MIIM_DATA; |
117 if (!owner_draw_) | 116 if (!owner_draw_) |
118 mii.fType = MFT_STRING; | 117 mii.fType = MFT_STRING; |
119 else | 118 else |
120 mii.fType = MFT_OWNERDRAW; | 119 mii.fType = MFT_OWNERDRAW; |
121 | 120 |
122 ItemData* item_data = new ItemData; | 121 std::unique_ptr<ItemData> item_data = base::MakeUnique<ItemData>(); |
123 item_data->label = base::string16(); | 122 item_data->label = base::string16(); |
124 ui::MenuModel::ItemType type = model_->GetTypeAt(model_index); | 123 ui::MenuModel::ItemType type = model_->GetTypeAt(model_index); |
125 if (type == ui::MenuModel::TYPE_SUBMENU) { | 124 if (type == ui::MenuModel::TYPE_SUBMENU) { |
126 item_data->submenu.reset( | 125 item_data->submenu = base::MakeUnique<NativeMenuWin>( |
127 new NativeMenuWin(model_->GetSubmenuModelAt(model_index), nullptr)); | 126 model_->GetSubmenuModelAt(model_index), nullptr); |
128 item_data->submenu->Rebuild(nullptr); | 127 item_data->submenu->Rebuild(nullptr); |
129 mii.fMask |= MIIM_SUBMENU; | 128 mii.fMask |= MIIM_SUBMENU; |
130 mii.hSubMenu = item_data->submenu->menu_; | 129 mii.hSubMenu = item_data->submenu->menu_; |
131 GetNativeMenuWinFromHMENU(mii.hSubMenu)->parent_ = this; | 130 GetNativeMenuWinFromHMENU(mii.hSubMenu)->parent_ = this; |
132 } else { | 131 } else { |
133 if (type == ui::MenuModel::TYPE_RADIO) | 132 if (type == ui::MenuModel::TYPE_RADIO) |
134 mii.fType |= MFT_RADIOCHECK; | 133 mii.fType |= MFT_RADIOCHECK; |
135 mii.wID = model_->GetCommandIdAt(model_index); | 134 mii.wID = model_->GetCommandIdAt(model_index); |
136 } | 135 } |
137 item_data->native_menu_win = this; | 136 item_data->native_menu_win = this; |
138 item_data->model_index = model_index; | 137 item_data->model_index = model_index; |
139 items_.insert(items_.begin() + model_index, item_data); | 138 mii.dwItemData = reinterpret_cast<ULONG_PTR>(item_data.get()); |
140 mii.dwItemData = reinterpret_cast<ULONG_PTR>(item_data); | 139 items_.insert(items_.begin() + model_index, std::move(item_data)); |
141 UpdateMenuItemInfoForString(&mii, model_index, | 140 UpdateMenuItemInfoForString(&mii, model_index, |
142 model_->GetLabelAt(model_index)); | 141 model_->GetLabelAt(model_index)); |
143 InsertMenuItem(menu_, menu_index, TRUE, &mii); | 142 InsertMenuItem(menu_, menu_index, TRUE, &mii); |
144 } | 143 } |
145 | 144 |
146 void NativeMenuWin::AddSeparatorItemAt(int menu_index, int model_index) { | 145 void NativeMenuWin::AddSeparatorItemAt(int menu_index, int model_index) { |
147 MENUITEMINFO mii = {0}; | 146 MENUITEMINFO mii = {0}; |
148 mii.cbSize = sizeof(mii); | 147 mii.cbSize = sizeof(mii); |
149 mii.fMask = MIIM_FTYPE; | 148 mii.fMask = MIIM_FTYPE; |
150 mii.fType = MFT_SEPARATOR; | 149 mii.fType = MFT_SEPARATOR; |
151 // Insert a dummy entry into our label list so we can index directly into it | 150 // Insert a dummy entry into our label list so we can index directly into it |
152 // using item indices if need be. | 151 // using item indices if need be. |
153 items_.insert(items_.begin() + model_index, new ItemData); | 152 items_.insert(items_.begin() + model_index, base::MakeUnique<ItemData>()); |
154 InsertMenuItem(menu_, menu_index, TRUE, &mii); | 153 InsertMenuItem(menu_, menu_index, TRUE, &mii); |
155 } | 154 } |
156 | 155 |
157 void NativeMenuWin::SetMenuItemState(int menu_index, bool enabled, bool checked, | 156 void NativeMenuWin::SetMenuItemState(int menu_index, bool enabled, bool checked, |
158 bool is_default) { | 157 bool is_default) { |
159 if (IsSeparatorItemAt(menu_index)) | 158 if (IsSeparatorItemAt(menu_index)) |
160 return; | 159 return; |
161 | 160 |
162 UINT state = enabled ? MFS_ENABLED : MFS_DISABLED; | 161 UINT state = enabled ? MFS_ENABLED : MFS_DISABLED; |
163 if (checked) | 162 if (checked) |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
226 MENUINFO mi = {0}; | 225 MENUINFO mi = {0}; |
227 mi.cbSize = sizeof(mi); | 226 mi.cbSize = sizeof(mi); |
228 mi.fMask = MIM_STYLE | MIM_MENUDATA; | 227 mi.fMask = MIM_STYLE | MIM_MENUDATA; |
229 mi.dwStyle = MNS_NOTIFYBYPOS; | 228 mi.dwStyle = MNS_NOTIFYBYPOS; |
230 mi.dwMenuData = reinterpret_cast<ULONG_PTR>(this); | 229 mi.dwMenuData = reinterpret_cast<ULONG_PTR>(this); |
231 SetMenuInfo(menu_, &mi); | 230 SetMenuInfo(menu_, &mi); |
232 } | 231 } |
233 } | 232 } |
234 | 233 |
235 } // namespace views | 234 } // namespace views |
OLD | NEW |