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

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

Issue 14320040: Revert 194356 "views: Finally get rid of the deprecated Menu2 API." (Closed) Base URL: svn://svn.chromium.org/chrome/
Patch Set: 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 | « trunk/src/ui/views/controls/menu/native_menu_win.h ('k') | trunk/src/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"
28 #include "ui/views/controls/menu/menu_config.h" 29 #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<NativeMenuWin> submenu; 57 scoped_ptr<Menu2> 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_ == MENU_ACTION_NONE) 155 if (root_menu->menu_action_ == MenuWrapper::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
413 void NativeMenuWin::RunMenuAt(const gfx::Point& point, int alignment) { 416 void NativeMenuWin::RunMenuAt(const gfx::Point& point, int alignment) {
414 CreateHostWindow(); 417 CreateHostWindow();
415 UpdateStates(); 418 UpdateStates();
416 UINT flags = TPM_LEFTBUTTON | TPM_RIGHTBUTTON | TPM_RECURSE; 419 UINT flags = TPM_LEFTBUTTON | TPM_RIGHTBUTTON | TPM_RECURSE;
417 flags |= GetAlignmentFlags(alignment); 420 flags |= GetAlignmentFlags(alignment);
418 menu_action_ = MENU_ACTION_NONE; 421 menu_action_ = MENU_ACTION_NONE;
419 422
420 // Set a hook function so we can listen for keyboard events while the 423 // Set a hook function so we can listen for keyboard events while the
421 // menu is open, and store a pointer to this object in a static 424 // menu is open, and store a pointer to this object in a static
422 // variable so the hook has access to it (ugly, but it's the 425 // 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
459 } 462 }
460 // Send MenuClosed after we schedule the select, otherwise MenuClosed is 463 // Send MenuClosed after we schedule the select, otherwise MenuClosed is
461 // processed after the select (MenuClosed posts a delayed task too). 464 // processed after the select (MenuClosed posts a delayed task too).
462 model_->MenuClosed(); 465 model_->MenuClosed();
463 } 466 }
464 467
465 void NativeMenuWin::CancelMenu() { 468 void NativeMenuWin::CancelMenu() {
466 EndMenu(); 469 EndMenu();
467 } 470 }
468 471
469 void NativeMenuWin::Rebuild(MenuInsertionDelegate* delegate) { 472 void NativeMenuWin::Rebuild(InsertionDelegate* delegate) {
470 ResetNativeMenu(); 473 ResetNativeMenu();
471 items_.clear(); 474 items_.clear();
472 475
473 owner_draw_ = model_->HasIcons() || owner_draw_; 476 owner_draw_ = model_->HasIcons() || owner_draw_;
474 first_item_index_ = delegate ? delegate->GetInsertionIndex(menu_) : 0; 477 first_item_index_ = delegate ? delegate->GetInsertionIndex(menu_) : 0;
475 for (int menu_index = first_item_index_; 478 for (int menu_index = first_item_index_;
476 menu_index < first_item_index_ + model_->GetItemCount(); ++menu_index) { 479 menu_index < first_item_index_ + model_->GetItemCount(); ++menu_index) {
477 int model_index = menu_index - first_item_index_; 480 int model_index = menu_index - first_item_index_;
478 if (model_->GetTypeAt(model_index) == ui::MenuModel::TYPE_SEPARATOR) 481 if (model_->GetTypeAt(model_index) == ui::MenuModel::TYPE_SEPARATOR)
479 AddSeparatorItemAt(menu_index, model_index); 482 AddSeparatorItemAt(menu_index, model_index);
480 else 483 else
481 AddMenuItemAt(menu_index, model_index); 484 AddMenuItemAt(menu_index, model_index);
482 } 485 }
483 } 486 }
484 487
485 void NativeMenuWin::UpdateStates() { 488 void NativeMenuWin::UpdateStates() {
486 // A depth-first walk of the menu items, updating states. 489 // A depth-first walk of the menu items, updating states.
487 int model_index = 0; 490 int model_index = 0;
488 std::vector<ItemData*>::const_iterator it; 491 std::vector<ItemData*>::const_iterator it;
489 for (it = items_.begin(); it != items_.end(); ++it, ++model_index) { 492 for (it = items_.begin(); it != items_.end(); ++it, ++model_index) {
490 int menu_index = model_index + first_item_index_; 493 int menu_index = model_index + first_item_index_;
491 SetMenuItemState(menu_index, model_->IsEnabledAt(model_index), 494 SetMenuItemState(menu_index, model_->IsEnabledAt(model_index),
492 model_->IsItemCheckedAt(model_index), false); 495 model_->IsItemCheckedAt(model_index), false);
493 if (model_->IsItemDynamicAt(model_index)) { 496 if (model_->IsItemDynamicAt(model_index)) {
494 // TODO(atwilson): Update the icon as well (http://crbug.com/66508). 497 // TODO(atwilson): Update the icon as well (http://crbug.com/66508).
495 SetMenuItemLabel(menu_index, model_index, 498 SetMenuItemLabel(menu_index, model_index,
496 model_->GetLabelAt(model_index)); 499 model_->GetLabelAt(model_index));
497 } 500 }
498 NativeMenuWin* submenu = (*it)->submenu.get(); 501 Menu2* submenu = (*it)->submenu.get();
499 if (submenu) 502 if (submenu)
500 submenu->UpdateStates(); 503 submenu->UpdateStates();
501 } 504 }
502 } 505 }
503 506
504 HMENU NativeMenuWin::GetNativeMenu() const { 507 HMENU NativeMenuWin::GetNativeMenu() const {
505 return menu_; 508 return menu_;
506 } 509 }
507 510
508 NativeMenuWin::MenuAction NativeMenuWin::GetMenuAction() const { 511 NativeMenuWin::MenuAction NativeMenuWin::GetMenuAction() const {
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
619 mii.fMask = MIIM_FTYPE | MIIM_ID | MIIM_DATA; 622 mii.fMask = MIIM_FTYPE | MIIM_ID | MIIM_DATA;
620 if (!owner_draw_) 623 if (!owner_draw_)
621 mii.fType = MFT_STRING; 624 mii.fType = MFT_STRING;
622 else 625 else
623 mii.fType = MFT_OWNERDRAW; 626 mii.fType = MFT_OWNERDRAW;
624 627
625 ItemData* item_data = new ItemData; 628 ItemData* item_data = new ItemData;
626 item_data->label = string16(); 629 item_data->label = string16();
627 ui::MenuModel::ItemType type = model_->GetTypeAt(model_index); 630 ui::MenuModel::ItemType type = model_->GetTypeAt(model_index);
628 if (type == ui::MenuModel::TYPE_SUBMENU) { 631 if (type == ui::MenuModel::TYPE_SUBMENU) {
629 item_data->submenu.reset( 632 item_data->submenu.reset(new Menu2(model_->GetSubmenuModelAt(model_index)));
630 new NativeMenuWin(model_->GetSubmenuModelAt(model_index), NULL));
631 mii.fMask |= MIIM_SUBMENU; 633 mii.fMask |= MIIM_SUBMENU;
632 mii.hSubMenu = item_data->submenu->GetNativeMenu(); 634 mii.hSubMenu = item_data->submenu->GetNativeMenu();
633 GetNativeMenuWinFromHMENU(mii.hSubMenu)->parent_ = this; 635 GetNativeMenuWinFromHMENU(mii.hSubMenu)->parent_ = this;
634 } else { 636 } else {
635 if (type == ui::MenuModel::TYPE_RADIO) 637 if (type == ui::MenuModel::TYPE_RADIO)
636 mii.fType |= MFT_RADIOCHECK; 638 mii.fType |= MFT_RADIOCHECK;
637 mii.wID = model_->GetCommandIdAt(model_index); 639 mii.wID = model_->GetCommandIdAt(model_index);
638 } 640 }
639 item_data->native_menu_win = this; 641 item_data->native_menu_win = this;
640 item_data->model_index = model_index; 642 item_data->model_index = model_index;
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
708 items_[model_index]->label = formatted; 710 items_[model_index]->label = formatted;
709 711
710 // Give Windows a pointer to the label string. 712 // Give Windows a pointer to the label string.
711 mii->fMask |= MIIM_STRING; 713 mii->fMask |= MIIM_STRING;
712 mii->dwTypeData = 714 mii->dwTypeData =
713 const_cast<wchar_t*>(items_[model_index]->label.c_str()); 715 const_cast<wchar_t*>(items_[model_index]->label.c_str());
714 } 716 }
715 717
716 UINT NativeMenuWin::GetAlignmentFlags(int alignment) const { 718 UINT NativeMenuWin::GetAlignmentFlags(int alignment) const {
717 UINT alignment_flags = TPM_TOPALIGN; 719 UINT alignment_flags = TPM_TOPALIGN;
718 if (alignment == ALIGN_TOPLEFT) 720 if (alignment == Menu2::ALIGN_TOPLEFT)
719 alignment_flags |= TPM_LEFTALIGN; 721 alignment_flags |= TPM_LEFTALIGN;
720 else if (alignment == ALIGN_TOPRIGHT) 722 else if (alignment == Menu2::ALIGN_TOPRIGHT)
721 alignment_flags |= TPM_RIGHTALIGN; 723 alignment_flags |= TPM_RIGHTALIGN;
722 return alignment_flags; 724 return alignment_flags;
723 } 725 }
724 726
725 void NativeMenuWin::ResetNativeMenu() { 727 void NativeMenuWin::ResetNativeMenu() {
726 if (IsWindow(system_menu_for_)) { 728 if (IsWindow(system_menu_for_)) {
727 if (menu_) 729 if (menu_)
728 GetSystemMenu(system_menu_for_, TRUE); 730 GetSystemMenu(system_menu_for_, TRUE);
729 menu_ = GetSystemMenu(system_menu_for_, FALSE); 731 menu_ = GetSystemMenu(system_menu_for_, FALSE);
730 } else { 732 } else {
(...skipping 13 matching lines...) Expand all
744 } 746 }
745 747
746 void NativeMenuWin::CreateHostWindow() { 748 void NativeMenuWin::CreateHostWindow() {
747 // This only gets called from RunMenuAt, and as such there is only ever one 749 // This only gets called from RunMenuAt, and as such there is only ever one
748 // host window per menu hierarchy, no matter how many NativeMenuWin objects 750 // host window per menu hierarchy, no matter how many NativeMenuWin objects
749 // exist wrapping submenus. 751 // exist wrapping submenus.
750 if (!host_window_.get()) 752 if (!host_window_.get())
751 host_window_.reset(new MenuHostWindow(this)); 753 host_window_.reset(new MenuHostWindow(this));
752 } 754 }
753 755
756 ////////////////////////////////////////////////////////////////////////////////
757 // MenuWrapper, public:
758
759 // static
760 MenuWrapper* MenuWrapper::CreateWrapper(ui::MenuModel* model) {
761 return new NativeMenuWin(model, NULL);
762 }
763
754 } // namespace views 764 } // namespace views
OLDNEW
« no previous file with comments | « trunk/src/ui/views/controls/menu/native_menu_win.h ('k') | trunk/src/ui/views/views.gyp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698