| OLD | NEW |
| (Empty) |
| 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 | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #ifndef UI_VIEWS_CONTROLS_MENU_NATIVE_MENU_WIN_H_ | |
| 6 #define UI_VIEWS_CONTROLS_MENU_NATIVE_MENU_WIN_H_ | |
| 7 | |
| 8 #include <vector> | |
| 9 | |
| 10 #include "base/basictypes.h" | |
| 11 #include "base/compiler_specific.h" | |
| 12 #include "base/memory/scoped_ptr.h" | |
| 13 #include "base/memory/weak_ptr.h" | |
| 14 #include "base/observer_list.h" | |
| 15 #include "base/strings/string16.h" | |
| 16 #include "ui/views/controls/menu/menu_wrapper.h" | |
| 17 #include "ui/views/views_export.h" | |
| 18 | |
| 19 namespace ui { | |
| 20 class MenuModel; | |
| 21 } | |
| 22 | |
| 23 namespace views { | |
| 24 | |
| 25 // A Windows implementation of MenuWrapper. | |
| 26 // TODO(beng): rename to MenuWin once the old class is dead. | |
| 27 class VIEWS_EXPORT NativeMenuWin : public MenuWrapper { | |
| 28 public: | |
| 29 // Construct a NativeMenuWin, with a model and delegate. If |system_menu_for| | |
| 30 // is non-NULL, the NativeMenuWin wraps the system menu for that window. | |
| 31 // The caller owns the model and the delegate. | |
| 32 NativeMenuWin(ui::MenuModel* model, HWND system_menu_for); | |
| 33 virtual ~NativeMenuWin(); | |
| 34 | |
| 35 // Overridden from MenuWrapper: | |
| 36 virtual void RunMenuAt(const gfx::Point& point, int alignment) override; | |
| 37 virtual void CancelMenu() override; | |
| 38 virtual void Rebuild(MenuInsertionDelegateWin* delegate) override; | |
| 39 virtual void UpdateStates() override; | |
| 40 virtual HMENU GetNativeMenu() const override; | |
| 41 virtual MenuAction GetMenuAction() const override; | |
| 42 virtual void AddMenuListener(MenuListener* listener) override; | |
| 43 virtual void RemoveMenuListener(MenuListener* listener) override; | |
| 44 virtual void SetMinimumWidth(int width) override; | |
| 45 | |
| 46 private: | |
| 47 // IMPORTANT: Note about indices. | |
| 48 // Functions in this class deal in two index spaces: | |
| 49 // 1. menu_index - the index of an item within the actual Windows | |
| 50 // native menu. | |
| 51 // 2. model_index - the index of the item within our model. | |
| 52 // These two are most often but not always the same value! The | |
| 53 // notable exception is when this object is used to wrap the | |
| 54 // Windows System Menu. In this instance, the model indices start | |
| 55 // at 0, but the insertion index into the existing menu is not. | |
| 56 // It is important to take this into consideration when editing the | |
| 57 // code in the functions in this class. | |
| 58 | |
| 59 struct HighlightedMenuItemInfo; | |
| 60 | |
| 61 // Returns true if the item at the specified index is a separator. | |
| 62 bool IsSeparatorItemAt(int menu_index) const; | |
| 63 | |
| 64 // Add items. See note above about indices. | |
| 65 void AddMenuItemAt(int menu_index, int model_index); | |
| 66 void AddSeparatorItemAt(int menu_index, int model_index); | |
| 67 | |
| 68 // Sets the state of the item at the specified index. | |
| 69 void SetMenuItemState(int menu_index, | |
| 70 bool enabled, | |
| 71 bool checked, | |
| 72 bool is_default); | |
| 73 | |
| 74 // Sets the label of the item at the specified index. | |
| 75 void SetMenuItemLabel(int menu_index, | |
| 76 int model_index, | |
| 77 const base::string16& label); | |
| 78 | |
| 79 // Updates the local data structure with the correctly formatted version of | |
| 80 // |label| at the specified model_index, and adds string data to |mii| if | |
| 81 // the menu is not owner-draw. That's a mouthful. This function exists because | |
| 82 // of the peculiarities of the Windows menu API. | |
| 83 void UpdateMenuItemInfoForString(MENUITEMINFO* mii, | |
| 84 int model_index, | |
| 85 const base::string16& label); | |
| 86 | |
| 87 // Returns the alignment flags to be passed to TrackPopupMenuEx, based on the | |
| 88 // supplied alignment and the UI text direction. | |
| 89 UINT GetAlignmentFlags(int alignment) const; | |
| 90 | |
| 91 // Resets the native menu stored in |menu_| by destroying any old menu then | |
| 92 // creating a new empty one. | |
| 93 void ResetNativeMenu(); | |
| 94 | |
| 95 // Creates the host window that receives notifications from the menu. | |
| 96 void CreateHostWindow(); | |
| 97 | |
| 98 // Callback from task to notify menu it was selected. | |
| 99 void DelayedSelect(); | |
| 100 | |
| 101 // Given a menu that's currently popped-up, find the currently highlighted | |
| 102 // item. Returns true if a highlighted item was found. | |
| 103 static bool GetHighlightedMenuItemInfo(HMENU menu, | |
| 104 HighlightedMenuItemInfo* info); | |
| 105 | |
| 106 // Hook to receive keyboard events while the menu is open. | |
| 107 static LRESULT CALLBACK MenuMessageHook( | |
| 108 int n_code, WPARAM w_param, LPARAM l_param); | |
| 109 | |
| 110 // Our attached model and delegate. | |
| 111 ui::MenuModel* model_; | |
| 112 | |
| 113 HMENU menu_; | |
| 114 | |
| 115 // True if the contents of menu items in this menu are drawn by the menu host | |
| 116 // window, rather than Windows. | |
| 117 bool owner_draw_; | |
| 118 | |
| 119 // An object that collects all of the data associated with an individual menu | |
| 120 // item. | |
| 121 struct ItemData; | |
| 122 std::vector<ItemData*> items_; | |
| 123 | |
| 124 // The window that receives notifications from the menu. | |
| 125 class MenuHostWindow; | |
| 126 friend MenuHostWindow; | |
| 127 scoped_ptr<MenuHostWindow> host_window_; | |
| 128 | |
| 129 // The HWND this menu is the system menu for, or NULL if the menu is not a | |
| 130 // system menu. | |
| 131 HWND system_menu_for_; | |
| 132 | |
| 133 // The index of the first item in the model in the menu. | |
| 134 int first_item_index_; | |
| 135 | |
| 136 // The action that took place during the call to RunMenuAt. | |
| 137 MenuAction menu_action_; | |
| 138 | |
| 139 // A list of listeners to call when the menu opens. | |
| 140 ObserverList<MenuListener> listeners_; | |
| 141 | |
| 142 // Keep track of whether the listeners have already been called at least | |
| 143 // once. | |
| 144 bool listeners_called_; | |
| 145 | |
| 146 // See comment in MenuMessageHook for details on these. | |
| 147 NativeMenuWin* menu_to_select_; | |
| 148 int position_to_select_; | |
| 149 base::WeakPtrFactory<NativeMenuWin> menu_to_select_factory_; | |
| 150 | |
| 151 // If we're a submenu, this is our parent. | |
| 152 NativeMenuWin* parent_; | |
| 153 | |
| 154 // If non-null the destructor sets this to true. This is set to non-null while | |
| 155 // the menu is showing. It is used to detect if the menu was deleted while | |
| 156 // running. | |
| 157 bool* destroyed_flag_; | |
| 158 | |
| 159 // Ugly: a static pointer to the instance of this class that currently | |
| 160 // has a menu open, because our hook function that receives keyboard | |
| 161 // events doesn't have a mechanism to get a user data pointer. | |
| 162 static NativeMenuWin* open_native_menu_win_; | |
| 163 | |
| 164 DISALLOW_COPY_AND_ASSIGN(NativeMenuWin); | |
| 165 }; | |
| 166 | |
| 167 } // namespace views | |
| 168 | |
| 169 #endif // UI_VIEWS_CONTROLS_MENU_NATIVE_MENU_WIN_H_ | |
| OLD | NEW |