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.
5 #ifndef UI_VIEWS_CONTROLS_MENU_MENU_RUNNER_H_
6 #define UI_VIEWS_CONTROLS_MENU_MENU_RUNNER_H_
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"
31 class MenuModelAdapter
;
32 class MenuRunnerHandler
;
36 class DisplayChangeListener
;
41 class MenuRunnerTestAPI
;
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.
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.
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
{
66 // The menu has mnemonics.
67 HAS_MNEMONICS
= 1 << 0,
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.
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.
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,
82 // The menu should behave like a Windows native Combobox dropdow menu.
83 // This behavior includes accepting the pending item and closing on F4.
88 // Indicates RunMenuAt is returning because the MenuRunner was deleted.
91 // Indicates RunMenuAt returned and MenuRunner was not deleted.
95 // Creates a new MenuRunner.
96 // |run_types| is a bitmask of RunTypes.
97 MenuRunner(ui::MenuModel
* menu_model
, int32 run_types
);
98 MenuRunner(MenuItemView
* menu
, int32 run_types
);
101 // Runs the menu. If this returns MENU_DELETED the method is returning
102 // because the MenuRunner was deleted.
103 // Typically callers should NOT do any processing if this returns
105 // If |anchor| uses a |BUBBLE_..| type, the bounds will get determined by
106 // using |bounds| as the thing to point at in screen coordinates.
107 RunResult
RunMenuAt(Widget
* parent
,
109 const gfx::Rect
& bounds
,
110 MenuAnchorPosition anchor
,
111 ui::MenuSourceType source_type
) WARN_UNUSED_RESULT
;
113 // Returns true if we're in a nested message loop running the menu.
114 bool IsRunning() const;
116 // Hides and cancels the menu. This does nothing if the menu is not open.
119 // Returns the time from the event which closed the menu - or 0.
120 base::TimeDelta
closing_event_time() const;
123 friend class test::MenuRunnerTestAPI
;
125 // Sets an implementation of RunMenuAt. This is intended to be used at test.
126 void SetRunnerHandler(scoped_ptr
<MenuRunnerHandler
> runner_handler
);
128 const int32 run_types_
;
129 scoped_ptr
<MenuModelAdapter
> menu_model_adapter_
;
131 internal::MenuRunnerImpl
* holder_
;
133 // An implementation of RunMenuAt. This is usually NULL and ignored. If this
134 // is not NULL, this implementation will be used.
135 scoped_ptr
<MenuRunnerHandler
> runner_handler_
;
137 scoped_ptr
<internal::DisplayChangeListener
> display_change_listener_
;
139 DISALLOW_COPY_AND_ASSIGN(MenuRunner
);
144 // DisplayChangeListener is intended to listen for changes in the display size
145 // and cancel the menu. DisplayChangeListener is created when the menu is
147 class DisplayChangeListener
{
149 virtual ~DisplayChangeListener() {}
151 // Creates the platform specified DisplayChangeListener, or NULL if there
152 // isn't one. Caller owns the returned value.
153 static DisplayChangeListener
* Create(Widget
* parent
,
157 DisplayChangeListener() {}
160 } // namespace internal
164 #endif // UI_VIEWS_CONTROLS_MENU_MENU_RUNNER_H_