| 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_MENU_RUNNER_H_ | |
| 6 #define UI_VIEWS_CONTROLS_MENU_MENU_RUNNER_H_ | |
| 7 | |
| 8 #include "base/basictypes.h" | |
| 9 #include "base/compiler_specific.h" | |
| 10 #include "base/memory/scoped_ptr.h" | |
| 11 #include "ui/base/ui_base_types.h" | |
| 12 #include "ui/views/controls/menu/menu_types.h" | |
| 13 #include "ui/views/views_export.h" | |
| 14 | |
| 15 namespace base { | |
| 16 class TimeDelta; | |
| 17 } | |
| 18 | |
| 19 namespace gfx { | |
| 20 class Rect; | |
| 21 } | |
| 22 | |
| 23 namespace ui { | |
| 24 class MenuModel; | |
| 25 } | |
| 26 | |
| 27 namespace views { | |
| 28 | |
| 29 class MenuButton; | |
| 30 class MenuItemView; | |
| 31 class MenuModelAdapter; | |
| 32 class MenuRunnerHandler; | |
| 33 class Widget; | |
| 34 | |
| 35 namespace internal { | |
| 36 class DisplayChangeListener; | |
| 37 class MenuRunnerImplInterface; | |
| 38 } | |
| 39 | |
| 40 namespace test { | |
| 41 class MenuRunnerTestAPI; | |
| 42 } | |
| 43 | |
| 44 // MenuRunner is responsible for showing (running) the menu and additionally | |
| 45 // owning the MenuItemView. RunMenuAt() runs a nested message loop. It is safe | |
| 46 // to delete MenuRunner at any point, but MenuRunner internally only deletes the | |
| 47 // MenuItemView *after* the nested message loop completes. If MenuRunner is | |
| 48 // deleted while the menu is showing the delegate of the menu is reset. This is | |
| 49 // done to ensure delegates aren't notified after they may have been deleted. | |
| 50 // | |
| 51 // NOTE: while you can delete a MenuRunner at any point, the nested message loop | |
| 52 // won't return immediately. This means if you delete the object that owns | |
| 53 // the MenuRunner while the menu is running, your object is effectively still | |
| 54 // on the stack. A return value of MENU_DELETED indicated this. In most cases | |
| 55 // if RunMenuAt() returns MENU_DELETED, you should return immediately. | |
| 56 // | |
| 57 // Similarly you should avoid creating MenuRunner on the stack. Doing so means | |
| 58 // MenuRunner may not be immediately destroyed if your object is destroyed, | |
| 59 // resulting in possible callbacks to your now deleted object. Instead you | |
| 60 // should define MenuRunner as a scoped_ptr in your class so that when your | |
| 61 // object is destroyed MenuRunner initiates the proper cleanup and ensures your | |
| 62 // object isn't accessed again. | |
| 63 class VIEWS_EXPORT MenuRunner { | |
| 64 public: | |
| 65 enum RunTypes { | |
| 66 // The menu has mnemonics. | |
| 67 HAS_MNEMONICS = 1 << 0, | |
| 68 | |
| 69 // The menu is a nested context menu. For example, click a folder on the | |
| 70 // bookmark bar, then right click an entry to get its context menu. | |
| 71 IS_NESTED = 1 << 1, | |
| 72 | |
| 73 // Used for showing a menu during a drop operation. This does NOT block the | |
| 74 // caller, instead the delegate is notified when the menu closes via the | |
| 75 // DropMenuClosed method. | |
| 76 FOR_DROP = 1 << 2, | |
| 77 | |
| 78 // The menu is a context menu (not necessarily nested), for example right | |
| 79 // click on a link on a website in the browser. | |
| 80 CONTEXT_MENU = 1 << 3, | |
| 81 | |
| 82 // The menu should behave like a Windows native Combobox dropdow menu. | |
| 83 // This behavior includes accepting the pending item and closing on F4. | |
| 84 COMBOBOX = 1 << 4, | |
| 85 | |
| 86 // A child view is performing a drag-and-drop operation, so the menu should | |
| 87 // stay open (even if it doesn't receive drag updated events). In this case, | |
| 88 // the caller is responsible for closing the menu upon completion of the | |
| 89 // drag-and-drop. | |
| 90 NESTED_DRAG = 1 << 5, | |
| 91 }; | |
| 92 | |
| 93 enum RunResult { | |
| 94 // Indicates RunMenuAt is returning because the MenuRunner was deleted. | |
| 95 MENU_DELETED, | |
| 96 | |
| 97 // Indicates RunMenuAt returned and MenuRunner was not deleted. | |
| 98 NORMAL_EXIT | |
| 99 }; | |
| 100 | |
| 101 // Creates a new MenuRunner. | |
| 102 // |run_types| is a bitmask of RunTypes. | |
| 103 MenuRunner(ui::MenuModel* menu_model, int32 run_types); | |
| 104 MenuRunner(MenuItemView* menu, int32 run_types); | |
| 105 ~MenuRunner(); | |
| 106 | |
| 107 // Runs the menu. If this returns MENU_DELETED the method is returning | |
| 108 // because the MenuRunner was deleted. | |
| 109 // Typically callers should NOT do any processing if this returns | |
| 110 // MENU_DELETED. | |
| 111 // If |anchor| uses a |BUBBLE_..| type, the bounds will get determined by | |
| 112 // using |bounds| as the thing to point at in screen coordinates. | |
| 113 RunResult RunMenuAt(Widget* parent, | |
| 114 MenuButton* button, | |
| 115 const gfx::Rect& bounds, | |
| 116 MenuAnchorPosition anchor, | |
| 117 ui::MenuSourceType source_type) WARN_UNUSED_RESULT; | |
| 118 | |
| 119 // Returns true if we're in a nested message loop running the menu. | |
| 120 bool IsRunning() const; | |
| 121 | |
| 122 // Hides and cancels the menu. This does nothing if the menu is not open. | |
| 123 void Cancel(); | |
| 124 | |
| 125 // Returns the time from the event which closed the menu - or 0. | |
| 126 base::TimeDelta closing_event_time() const; | |
| 127 | |
| 128 private: | |
| 129 friend class test::MenuRunnerTestAPI; | |
| 130 | |
| 131 // Sets an implementation of RunMenuAt. This is intended to be used at test. | |
| 132 void SetRunnerHandler(scoped_ptr<MenuRunnerHandler> runner_handler); | |
| 133 | |
| 134 const int32 run_types_; | |
| 135 | |
| 136 // We own this. No scoped_ptr because it is destroyed by calling Release(). | |
| 137 internal::MenuRunnerImplInterface* impl_; | |
| 138 | |
| 139 // An implementation of RunMenuAt. This is usually NULL and ignored. If this | |
| 140 // is not NULL, this implementation will be used. | |
| 141 scoped_ptr<MenuRunnerHandler> runner_handler_; | |
| 142 | |
| 143 scoped_ptr<internal::DisplayChangeListener> display_change_listener_; | |
| 144 | |
| 145 DISALLOW_COPY_AND_ASSIGN(MenuRunner); | |
| 146 }; | |
| 147 | |
| 148 namespace internal { | |
| 149 | |
| 150 // DisplayChangeListener is intended to listen for changes in the display size | |
| 151 // and cancel the menu. DisplayChangeListener is created when the menu is | |
| 152 // shown. | |
| 153 class DisplayChangeListener { | |
| 154 public: | |
| 155 virtual ~DisplayChangeListener() {} | |
| 156 | |
| 157 // Creates the platform specified DisplayChangeListener, or NULL if there | |
| 158 // isn't one. Caller owns the returned value. | |
| 159 static DisplayChangeListener* Create(Widget* parent, | |
| 160 MenuRunner* runner); | |
| 161 | |
| 162 protected: | |
| 163 DisplayChangeListener() {} | |
| 164 }; | |
| 165 | |
| 166 } // namespace internal | |
| 167 | |
| 168 } // namespace views | |
| 169 | |
| 170 #endif // UI_VIEWS_CONTROLS_MENU_MENU_RUNNER_H_ | |
| OLD | NEW |