Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / ui / views / controls / menu / menu_controller.h
index a834459..dd1485d 100644 (file)
 
 #include "base/compiler_specific.h"
 #include "base/memory/scoped_ptr.h"
-#include "base/message_loop/message_pump_dispatcher.h"
 #include "base/timer/timer.h"
+#include "ui/events/event.h"
 #include "ui/events/event_constants.h"
+#include "ui/events/platform/platform_event_dispatcher.h"
+#include "ui/views/controls/menu/menu_config.h"
 #include "ui/views/controls/menu/menu_delegate.h"
-#include "ui/views/controls/menu/menu_item_view.h"
 #include "ui/views/widget/widget_observer.h"
 
-namespace ui {
-class NativeTheme;
-class OSExchangeData;
+namespace base {
+class MessagePumpDispatcher;
 }
 namespace gfx {
 class Screen;
 }
+namespace ui {
+class NativeTheme;
+class OSExchangeData;
+class ScopedEventDispatcher;
+}
 namespace views {
 
 class MenuButton;
 class MenuHostRootView;
+class MenuItemView;
+class MenuMessageLoop;
 class MouseEvent;
 class SubmenuView;
 class View;
 
 namespace internal {
 class MenuControllerDelegate;
+class MenuEventDispatcher;
+class MenuMessagePumpDispatcher;
 class MenuRunnerImpl;
 }
 
@@ -45,8 +54,7 @@ class MenuRunnerImpl;
 // MenuController is used internally by the various menu classes to manage
 // showing, selecting and drag/drop for menus. All relevant events are
 // forwarded to the MenuController from SubmenuView and MenuHost.
-class VIEWS_EXPORT MenuController : public base::MessagePumpDispatcher,
-                                    public WidgetObserver {
+class VIEWS_EXPORT MenuController : public WidgetObserver {
  public:
   // Enumeration of how the menu should exit.
   enum ExitType {
@@ -74,18 +82,29 @@ class VIEWS_EXPORT MenuController : public base::MessagePumpDispatcher,
                     MenuButton* button,
                     MenuItemView* root,
                     const gfx::Rect& bounds,
-                    MenuItemView::AnchorPosition position,
+                    MenuAnchorPosition position,
                     bool context_menu,
+                    bool is_nested_drag,
                     int* event_flags);
 
   // Whether or not Run blocks.
   bool IsBlockingRun() const { return blocking_run_; }
 
+  bool in_nested_run() const { return !menu_stack_.empty(); }
+
   // Whether or not drag operation is in progress.
   bool drag_in_progress() const { return drag_in_progress_; }
 
+  // Whether the MenuController initiated the drag in progress. False if there
+  // is no drag in progress.
+  bool did_initiate_drag() const { return did_initiate_drag_; }
+
+  // Returns the owner of child windows.
+  // WARNING: this may be NULL.
+  Widget* owner() { return owner_; }
+
   // Get the anchor position wich is used to show this menu.
-  MenuItemView::AnchorPosition GetAnchorPosition() { return state_.anchor; }
+  MenuAnchorPosition GetAnchorPosition() { return state_.anchor; }
 
   // Cancels the current Run. See ExitType for a description of what happens
   // with the various parameters.
@@ -101,7 +120,7 @@ class VIEWS_EXPORT MenuController : public base::MessagePumpDispatcher,
   // Returns the time from the event which closed the menu - or 0.
   base::TimeDelta closing_event_time() const { return closing_event_time_; }
 
-  void set_accept_on_f4(bool accept_on_f4) { accept_on_f4_ = accept_on_f4; }
+  void set_is_combobox(bool is_combobox) { is_combobox_ = is_combobox; }
 
   // Various events, forwarded from the submenu.
   //
@@ -112,9 +131,7 @@ class VIEWS_EXPORT MenuController : public base::MessagePumpDispatcher,
   void OnMouseReleased(SubmenuView* source, const ui::MouseEvent& event);
   void OnMouseMoved(SubmenuView* source, const ui::MouseEvent& event);
   void OnMouseEntered(SubmenuView* source, const ui::MouseEvent& event);
-#if defined(USE_AURA)
   bool OnMouseWheel(SubmenuView* source, const ui::MouseWheelEvent& event);
-#endif
   void OnGestureEvent(SubmenuView* source, ui::GestureEvent* event);
 
   bool GetDropFormats(
@@ -132,6 +149,15 @@ class VIEWS_EXPORT MenuController : public base::MessagePumpDispatcher,
   void OnDragEnteredScrollButton(SubmenuView* source, bool is_up);
   void OnDragExitedScrollButton(SubmenuView* source);
 
+  // Called by the Widget when a drag is about to start on a child view. This
+  // could be initiated by one of our MenuItemViews, or could be through another
+  // child View.
+  void OnDragWillStart();
+
+  // Called by the Widget when the drag has completed. |should_close|
+  // corresponds to whether or not the menu should close.
+  void OnDragComplete(bool should_close);
+
   // Update the submenu's selection based on the current mouse location
   void UpdateSubmenuSelection(SubmenuView* source);
 
@@ -139,10 +165,16 @@ class VIEWS_EXPORT MenuController : public base::MessagePumpDispatcher,
   virtual void OnWidgetDestroying(Widget* widget) OVERRIDE;
 
   // Only used for testing.
+  bool IsCancelAllTimerRunningForTest();
+
+  // Only used for testing.
   static void TurnOffMenuSelectionHoldForTest();
 
  private:
+  friend class internal::MenuEventDispatcher;
+  friend class internal::MenuMessagePumpDispatcher;
   friend class internal::MenuRunnerImpl;
+  friend class MenuControllerTest;
   friend class MenuHostRootView;
   friend class MenuItemView;
   friend class SubmenuView;
@@ -194,7 +226,7 @@ class VIEWS_EXPORT MenuController : public base::MessagePumpDispatcher,
     gfx::Rect initial_bounds;
 
     // Position of the initial menu.
-    MenuItemView::AnchorPosition anchor;
+    MenuAnchorPosition anchor;
 
     // The direction child menus have opened in.
     std::list<bool> open_leading;
@@ -253,10 +285,6 @@ class VIEWS_EXPORT MenuController : public base::MessagePumpDispatcher,
                                  const ui::LocatedEvent& event);
   void StartDrag(SubmenuView* source, const gfx::Point& location);
 
-  // Dispatcher method. This returns true if the menu was canceled, or
-  // if the message is such that the menu should be closed.
-  virtual bool Dispatch(const base::NativeEvent& event) OVERRIDE;
-
   // Key processing. The return value of this is returned from Dispatch.
   // In other words, if this returns false (which happens if escape was
   // pressed, or a matching mnemonic was found) the message loop returns.
@@ -279,7 +307,7 @@ class VIEWS_EXPORT MenuController : public base::MessagePumpDispatcher,
   SendAcceleratorResultType SendAcceleratorToHotTrackedView();
 
   void UpdateInitialLocation(const gfx::Rect& bounds,
-                             MenuItemView::AnchorPosition position,
+                             MenuAnchorPosition position,
                              bool context_menu);
 
   // Invoked when the user accepts the selected item. This is only used
@@ -468,9 +496,12 @@ class VIEWS_EXPORT MenuController : public base::MessagePumpDispatcher,
   void SetActiveMouseView(View* view);
   View* GetActiveMouseView();
 
-  // Sets exit type.
+  // Sets exit type. Calling this can terminate the active nested message-loop.
   void SetExitType(ExitType type);
 
+  // Terminates the current nested message-loop.
+  void TerminateNestedMessageLoop();
+
   // Returns true if SetExitType() should quit the message loop.
   bool ShouldQuitNow() const;
 
@@ -544,6 +575,11 @@ class VIEWS_EXPORT MenuController : public base::MessagePumpDispatcher,
   // True when drag operation is in progress.
   bool drag_in_progress_;
 
+  // True when the drag operation in progress was initiated by the
+  // MenuController for a child MenuItemView (as opposed to initiated separately
+  // by a child View).
+  bool did_initiate_drag_;
+
   // Location the mouse was pressed at. Used to detect d&d.
   gfx::Point press_pt_;
 
@@ -584,12 +620,15 @@ class VIEWS_EXPORT MenuController : public base::MessagePumpDispatcher,
   // screen coordinates). Otherwise this will be (0, 0).
   gfx::Point menu_start_mouse_press_loc_;
 
-  // Whether the menu should accept on F4, like Windows native Combobox menus.
-  bool accept_on_f4_;
+  // Controls behavior differences between a combobox and other types of menu
+  // (like a context menu).
+  bool is_combobox_;
 
   // Set to true if the menu item was selected by touch.
   bool item_selected_by_touch_;
 
+  scoped_ptr<MenuMessageLoop> message_loop_;
+
   DISALLOW_COPY_AND_ASSIGN(MenuController);
 };