| 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 |