Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(702)

Side by Side Diff: ui/views/controls/menu/native_menu_win.cc

Issue 14150005: views: Finally get rid of the deprecated Menu2 API. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rm comment Created 7 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « ui/views/controls/menu/native_menu_win.h ('k') | ui/views/views.gyp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 <Windowsx.h> 7 #include <Windowsx.h>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/logging.h" 10 #include "base/logging.h"
11 #include "base/message_loop.h" 11 #include "base/message_loop.h"
12 #include "base/stl_util.h" 12 #include "base/stl_util.h"
13 #include "base/string_util.h" 13 #include "base/string_util.h"
14 #include "base/win/wrapped_window_proc.h" 14 #include "base/win/wrapped_window_proc.h"
15 #include "ui/base/accelerators/accelerator.h" 15 #include "ui/base/accelerators/accelerator.h"
16 #include "ui/base/keycodes/keyboard_codes.h" 16 #include "ui/base/keycodes/keyboard_codes.h"
17 #include "ui/base/l10n/l10n_util.h" 17 #include "ui/base/l10n/l10n_util.h"
18 #include "ui/base/l10n/l10n_util_win.h" 18 #include "ui/base/l10n/l10n_util_win.h"
19 #include "ui/base/models/menu_model.h" 19 #include "ui/base/models/menu_model.h"
20 #include "ui/base/win/hwnd_util.h" 20 #include "ui/base/win/hwnd_util.h"
21 #include "ui/gfx/canvas.h" 21 #include "ui/gfx/canvas.h"
22 #include "ui/gfx/font.h" 22 #include "ui/gfx/font.h"
23 #include "ui/gfx/image/image.h" 23 #include "ui/gfx/image/image.h"
24 #include "ui/gfx/image/image_skia.h" 24 #include "ui/gfx/image/image_skia.h"
25 #include "ui/gfx/rect.h" 25 #include "ui/gfx/rect.h"
26 #include "ui/native_theme/native_theme.h" 26 #include "ui/native_theme/native_theme.h"
27 #include "ui/native_theme/native_theme_win.h" 27 #include "ui/native_theme/native_theme_win.h"
28 #include "ui/views/controls/menu/menu_2.h"
29 #include "ui/views/controls/menu/menu_config.h" 28 #include "ui/views/controls/menu/menu_config.h"
29 #include "ui/views/controls/menu/menu_insertion_delegate.h"
30 #include "ui/views/controls/menu/menu_listener.h" 30 #include "ui/views/controls/menu/menu_listener.h"
31 31
32 using ui::NativeTheme; 32 using ui::NativeTheme;
33 33
34 namespace views { 34 namespace views {
35 35
36 // The width of an icon, including the pixels between the icon and 36 // The width of an icon, including the pixels between the icon and
37 // the item label. 37 // the item label.
38 static const int kIconWidth = 23; 38 static const int kIconWidth = 23;
39 // Margins between the top of the item and the label. 39 // Margins between the top of the item and the label.
40 static const int kItemTopMargin = 3; 40 static const int kItemTopMargin = 3;
41 // Margins between the bottom of the item and the label. 41 // Margins between the bottom of the item and the label.
42 static const int kItemBottomMargin = 4; 42 static const int kItemBottomMargin = 4;
43 // Margins between the left of the item and the icon. 43 // Margins between the left of the item and the icon.
44 static const int kItemLeftMargin = 4; 44 static const int kItemLeftMargin = 4;
45 // Margins between the right of the item and the label. 45 // Margins between the right of the item and the label.
46 static const int kItemRightMargin = 10; 46 static const int kItemRightMargin = 10;
47 // The width for displaying the sub-menu arrow. 47 // The width for displaying the sub-menu arrow.
48 static const int kArrowWidth = 10; 48 static const int kArrowWidth = 10;
49 49
50 struct NativeMenuWin::ItemData { 50 struct NativeMenuWin::ItemData {
51 // The Windows API requires that whoever creates the menus must own the 51 // The Windows API requires that whoever creates the menus must own the
52 // strings used for labels, and keep them around for the lifetime of the 52 // strings used for labels, and keep them around for the lifetime of the
53 // created menu. So be it. 53 // created menu. So be it.
54 string16 label; 54 string16 label;
55 55
56 // Someone needs to own submenus, it may as well be us. 56 // Someone needs to own submenus, it may as well be us.
57 scoped_ptr<Menu2> submenu; 57 scoped_ptr<NativeMenuWin> submenu;
58 58
59 // We need a pointer back to the containing menu in various circumstances. 59 // We need a pointer back to the containing menu in various circumstances.
60 NativeMenuWin* native_menu_win; 60 NativeMenuWin* native_menu_win;
61 61
62 // The index of the item within the menu's model. 62 // The index of the item within the menu's model.
63 int model_index; 63 int model_index;
64 }; 64 };
65 65
66 // Returns the NativeMenuWin for a particular HMENU. 66 // Returns the NativeMenuWin for a particular HMENU.
67 static NativeMenuWin* GetNativeMenuWinFromHMENU(HMENU hmenu) { 67 static NativeMenuWin* GetNativeMenuWinFromHMENU(HMENU hmenu) {
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
145 // Called when the user selects a specific item. 145 // Called when the user selects a specific item.
146 void OnMenuCommand(int position, HMENU menu) { 146 void OnMenuCommand(int position, HMENU menu) {
147 NativeMenuWin* menu_win = GetNativeMenuWinFromHMENU(menu); 147 NativeMenuWin* menu_win = GetNativeMenuWinFromHMENU(menu);
148 ui::MenuModel* model = menu_win->model_; 148 ui::MenuModel* model = menu_win->model_;
149 NativeMenuWin* root_menu = menu_win; 149 NativeMenuWin* root_menu = menu_win;
150 while (root_menu->parent_) 150 while (root_menu->parent_)
151 root_menu = root_menu->parent_; 151 root_menu = root_menu->parent_;
152 152
153 // Only notify the model if it didn't already send out notification. 153 // Only notify the model if it didn't already send out notification.
154 // See comment in MenuMessageHook for details. 154 // See comment in MenuMessageHook for details.
155 if (root_menu->menu_action_ == MenuWrapper::MENU_ACTION_NONE) 155 if (root_menu->menu_action_ == MENU_ACTION_NONE)
156 model->ActivatedAt(position); 156 model->ActivatedAt(position);
157 } 157 }
158 158
159 // Called as the user moves their mouse or arrows through the contents of the 159 // Called as the user moves their mouse or arrows through the contents of the
160 // menu. 160 // menu.
161 void OnMenuSelect(WPARAM w_param, HMENU menu) { 161 void OnMenuSelect(WPARAM w_param, HMENU menu) {
162 if (!menu) 162 if (!menu)
163 return; // menu is null when closing on XP. 163 return; // menu is null when closing on XP.
164 164
165 int position = GetMenuItemIndexFromWPARAM(menu, w_param); 165 int position = GetMenuItemIndexFromWPARAM(menu, w_param);
(...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after
403 destroyed_flag_(NULL) { 403 destroyed_flag_(NULL) {
404 } 404 }
405 405
406 NativeMenuWin::~NativeMenuWin() { 406 NativeMenuWin::~NativeMenuWin() {
407 if (destroyed_flag_) 407 if (destroyed_flag_)
408 *destroyed_flag_ = true; 408 *destroyed_flag_ = true;
409 STLDeleteContainerPointers(items_.begin(), items_.end()); 409 STLDeleteContainerPointers(items_.begin(), items_.end());
410 DestroyMenu(menu_); 410 DestroyMenu(menu_);
411 } 411 }
412 412
413 ////////////////////////////////////////////////////////////////////////////////
414 // NativeMenuWin, MenuWrapper implementation:
415
416 void NativeMenuWin::RunMenuAt(const gfx::Point& point, int alignment) { 413 void NativeMenuWin::RunMenuAt(const gfx::Point& point, int alignment) {
417 CreateHostWindow(); 414 CreateHostWindow();
418 UpdateStates(); 415 UpdateStates();
419 UINT flags = TPM_LEFTBUTTON | TPM_RIGHTBUTTON | TPM_RECURSE; 416 UINT flags = TPM_LEFTBUTTON | TPM_RIGHTBUTTON | TPM_RECURSE;
420 flags |= GetAlignmentFlags(alignment); 417 flags |= GetAlignmentFlags(alignment);
421 menu_action_ = MENU_ACTION_NONE; 418 menu_action_ = MENU_ACTION_NONE;
422 419
423 // Set a hook function so we can listen for keyboard events while the 420 // Set a hook function so we can listen for keyboard events while the
424 // menu is open, and store a pointer to this object in a static 421 // menu is open, and store a pointer to this object in a static
425 // variable so the hook has access to it (ugly, but it's the 422 // variable so the hook has access to it (ugly, but it's the
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
462 } 459 }
463 // Send MenuClosed after we schedule the select, otherwise MenuClosed is 460 // Send MenuClosed after we schedule the select, otherwise MenuClosed is
464 // processed after the select (MenuClosed posts a delayed task too). 461 // processed after the select (MenuClosed posts a delayed task too).
465 model_->MenuClosed(); 462 model_->MenuClosed();
466 } 463 }
467 464
468 void NativeMenuWin::CancelMenu() { 465 void NativeMenuWin::CancelMenu() {
469 EndMenu(); 466 EndMenu();
470 } 467 }
471 468
472 void NativeMenuWin::Rebuild(InsertionDelegate* delegate) { 469 void NativeMenuWin::Rebuild(MenuInsertionDelegate* delegate) {
473 ResetNativeMenu(); 470 ResetNativeMenu();
474 items_.clear(); 471 items_.clear();
475 472
476 owner_draw_ = model_->HasIcons() || owner_draw_; 473 owner_draw_ = model_->HasIcons() || owner_draw_;
477 first_item_index_ = delegate ? delegate->GetInsertionIndex(menu_) : 0; 474 first_item_index_ = delegate ? delegate->GetInsertionIndex(menu_) : 0;
478 for (int menu_index = first_item_index_; 475 for (int menu_index = first_item_index_;
479 menu_index < first_item_index_ + model_->GetItemCount(); ++menu_index) { 476 menu_index < first_item_index_ + model_->GetItemCount(); ++menu_index) {
480 int model_index = menu_index - first_item_index_; 477 int model_index = menu_index - first_item_index_;
481 if (model_->GetTypeAt(model_index) == ui::MenuModel::TYPE_SEPARATOR) 478 if (model_->GetTypeAt(model_index) == ui::MenuModel::TYPE_SEPARATOR)
482 AddSeparatorItemAt(menu_index, model_index); 479 AddSeparatorItemAt(menu_index, model_index);
483 else 480 else
484 AddMenuItemAt(menu_index, model_index); 481 AddMenuItemAt(menu_index, model_index);
485 } 482 }
486 } 483 }
487 484
488 void NativeMenuWin::UpdateStates() { 485 void NativeMenuWin::UpdateStates() {
489 // A depth-first walk of the menu items, updating states. 486 // A depth-first walk of the menu items, updating states.
490 int model_index = 0; 487 int model_index = 0;
491 std::vector<ItemData*>::const_iterator it; 488 std::vector<ItemData*>::const_iterator it;
492 for (it = items_.begin(); it != items_.end(); ++it, ++model_index) { 489 for (it = items_.begin(); it != items_.end(); ++it, ++model_index) {
493 int menu_index = model_index + first_item_index_; 490 int menu_index = model_index + first_item_index_;
494 SetMenuItemState(menu_index, model_->IsEnabledAt(model_index), 491 SetMenuItemState(menu_index, model_->IsEnabledAt(model_index),
495 model_->IsItemCheckedAt(model_index), false); 492 model_->IsItemCheckedAt(model_index), false);
496 if (model_->IsItemDynamicAt(model_index)) { 493 if (model_->IsItemDynamicAt(model_index)) {
497 // TODO(atwilson): Update the icon as well (http://crbug.com/66508). 494 // TODO(atwilson): Update the icon as well (http://crbug.com/66508).
498 SetMenuItemLabel(menu_index, model_index, 495 SetMenuItemLabel(menu_index, model_index,
499 model_->GetLabelAt(model_index)); 496 model_->GetLabelAt(model_index));
500 } 497 }
501 Menu2* submenu = (*it)->submenu.get(); 498 NativeMenuWin* submenu = (*it)->submenu.get();
502 if (submenu) 499 if (submenu)
503 submenu->UpdateStates(); 500 submenu->UpdateStates();
504 } 501 }
505 } 502 }
506 503
507 HMENU NativeMenuWin::GetNativeMenu() const { 504 HMENU NativeMenuWin::GetNativeMenu() const {
508 return menu_; 505 return menu_;
509 } 506 }
510 507
511 NativeMenuWin::MenuAction NativeMenuWin::GetMenuAction() const { 508 NativeMenuWin::MenuAction NativeMenuWin::GetMenuAction() const {
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
622 mii.fMask = MIIM_FTYPE | MIIM_ID | MIIM_DATA; 619 mii.fMask = MIIM_FTYPE | MIIM_ID | MIIM_DATA;
623 if (!owner_draw_) 620 if (!owner_draw_)
624 mii.fType = MFT_STRING; 621 mii.fType = MFT_STRING;
625 else 622 else
626 mii.fType = MFT_OWNERDRAW; 623 mii.fType = MFT_OWNERDRAW;
627 624
628 ItemData* item_data = new ItemData; 625 ItemData* item_data = new ItemData;
629 item_data->label = string16(); 626 item_data->label = string16();
630 ui::MenuModel::ItemType type = model_->GetTypeAt(model_index); 627 ui::MenuModel::ItemType type = model_->GetTypeAt(model_index);
631 if (type == ui::MenuModel::TYPE_SUBMENU) { 628 if (type == ui::MenuModel::TYPE_SUBMENU) {
632 item_data->submenu.reset(new Menu2(model_->GetSubmenuModelAt(model_index))); 629 item_data->submenu.reset(
630 new NativeMenuWin(model_->GetSubmenuModelAt(model_index), NULL));
tfarina 2013/04/18 19:01:29 Mike, I think we need to pass |this| here to avoid
tfarina 2013/04/18 21:29:50 Sorry, I'm wrong, the second parameter of NativeMe
633 mii.fMask |= MIIM_SUBMENU; 631 mii.fMask |= MIIM_SUBMENU;
634 mii.hSubMenu = item_data->submenu->GetNativeMenu(); 632 mii.hSubMenu = item_data->submenu->GetNativeMenu();
635 GetNativeMenuWinFromHMENU(mii.hSubMenu)->parent_ = this; 633 GetNativeMenuWinFromHMENU(mii.hSubMenu)->parent_ = this;
636 } else { 634 } else {
637 if (type == ui::MenuModel::TYPE_RADIO) 635 if (type == ui::MenuModel::TYPE_RADIO)
638 mii.fType |= MFT_RADIOCHECK; 636 mii.fType |= MFT_RADIOCHECK;
639 mii.wID = model_->GetCommandIdAt(model_index); 637 mii.wID = model_->GetCommandIdAt(model_index);
640 } 638 }
641 item_data->native_menu_win = this; 639 item_data->native_menu_win = this;
642 item_data->model_index = model_index; 640 item_data->model_index = model_index;
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
710 items_[model_index]->label = formatted; 708 items_[model_index]->label = formatted;
711 709
712 // Give Windows a pointer to the label string. 710 // Give Windows a pointer to the label string.
713 mii->fMask |= MIIM_STRING; 711 mii->fMask |= MIIM_STRING;
714 mii->dwTypeData = 712 mii->dwTypeData =
715 const_cast<wchar_t*>(items_[model_index]->label.c_str()); 713 const_cast<wchar_t*>(items_[model_index]->label.c_str());
716 } 714 }
717 715
718 UINT NativeMenuWin::GetAlignmentFlags(int alignment) const { 716 UINT NativeMenuWin::GetAlignmentFlags(int alignment) const {
719 UINT alignment_flags = TPM_TOPALIGN; 717 UINT alignment_flags = TPM_TOPALIGN;
720 if (alignment == Menu2::ALIGN_TOPLEFT) 718 if (alignment == ALIGN_TOPLEFT)
721 alignment_flags |= TPM_LEFTALIGN; 719 alignment_flags |= TPM_LEFTALIGN;
722 else if (alignment == Menu2::ALIGN_TOPRIGHT) 720 else if (alignment == ALIGN_TOPRIGHT)
723 alignment_flags |= TPM_RIGHTALIGN; 721 alignment_flags |= TPM_RIGHTALIGN;
724 return alignment_flags; 722 return alignment_flags;
725 } 723 }
726 724
727 void NativeMenuWin::ResetNativeMenu() { 725 void NativeMenuWin::ResetNativeMenu() {
728 if (IsWindow(system_menu_for_)) { 726 if (IsWindow(system_menu_for_)) {
729 if (menu_) 727 if (menu_)
730 GetSystemMenu(system_menu_for_, TRUE); 728 GetSystemMenu(system_menu_for_, TRUE);
731 menu_ = GetSystemMenu(system_menu_for_, FALSE); 729 menu_ = GetSystemMenu(system_menu_for_, FALSE);
732 } else { 730 } else {
(...skipping 13 matching lines...) Expand all
746 } 744 }
747 745
748 void NativeMenuWin::CreateHostWindow() { 746 void NativeMenuWin::CreateHostWindow() {
749 // This only gets called from RunMenuAt, and as such there is only ever one 747 // This only gets called from RunMenuAt, and as such there is only ever one
750 // host window per menu hierarchy, no matter how many NativeMenuWin objects 748 // host window per menu hierarchy, no matter how many NativeMenuWin objects
751 // exist wrapping submenus. 749 // exist wrapping submenus.
752 if (!host_window_.get()) 750 if (!host_window_.get())
753 host_window_.reset(new MenuHostWindow(this)); 751 host_window_.reset(new MenuHostWindow(this));
754 } 752 }
755 753
756 ////////////////////////////////////////////////////////////////////////////////
757 // MenuWrapper, public:
758
759 // static
760 MenuWrapper* MenuWrapper::CreateWrapper(ui::MenuModel* model) {
761 return new NativeMenuWin(model, NULL);
762 }
763
764 } // namespace views 754 } // namespace views
OLDNEW
« no previous file with comments | « ui/views/controls/menu/native_menu_win.h ('k') | ui/views/views.gyp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698