Home | History | Annotate | Download | only in caption_buttons
      1 // Copyright 2013 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 ASH_WM_CAPTION_BUTTONS_FRAME_MAXIMIZE_BUTTON_H_
      6 #define ASH_WM_CAPTION_BUTTONS_FRAME_MAXIMIZE_BUTTON_H_
      7 
      8 #include "ash/ash_export.h"
      9 #include "ash/wm/caption_buttons/caption_button_types.h"
     10 #include "ash/wm/caption_buttons/frame_caption_button.h"
     11 #include "ash/wm/workspace/snap_types.h"
     12 #include "base/memory/scoped_ptr.h"
     13 #include "base/observer_list.h"
     14 #include "base/timer/timer.h"
     15 #include "ui/aura/window_observer.h"
     16 #include "ui/views/widget/widget_observer.h"
     17 
     18 namespace views {
     19 class Widget;
     20 }
     21 
     22 namespace ash {
     23 class FrameMaximizeButtonObserver;
     24 
     25 namespace internal {
     26 class PhantomWindowController;
     27 class SnapSizer;
     28 }
     29 
     30 class MaximizeBubbleController;
     31 
     32 // Button used for the maximize control on the frame. Handles snapping logic.
     33 class ASH_EXPORT FrameMaximizeButton : public FrameCaptionButton,
     34                                        public views::WidgetObserver,
     35                                        public aura::WindowObserver {
     36  public:
     37   FrameMaximizeButton(views::ButtonListener* listener,
     38                       views::Widget* frame);
     39   virtual ~FrameMaximizeButton();
     40 
     41   void AddObserver(FrameMaximizeButtonObserver* observer);
     42   void RemoveObserver(FrameMaximizeButtonObserver* observer);
     43 
     44   // Updates |snap_type_| based on a a given snap type. This is used by
     45   // external hover events from the button menu.
     46   void SnapButtonHovered(SnapType type);
     47 
     48   // The user clicked the |type| button and the action needs to be performed,
     49   // which will at the same time close the window.
     50   void ExecuteSnapAndCloseMenu(SnapType type);
     51 
     52   // Called by the MaximizeBubbleController when the maximize bubble is shown.
     53   void OnMaximizeBubbleShown(views::Widget* bubble);
     54 
     55   // Remove the maximize menu from the screen (and destroy it).
     56   void DestroyMaximizeMenu();
     57 
     58   // Returns true when the user clicks and drags the button.
     59   bool is_snap_enabled() const { return is_snap_enabled_; }
     60 
     61   // WindowObserver overrides:
     62   virtual void OnWindowBoundsChanged(aura::Window* window,
     63                                      const gfx::Rect& old_bounds,
     64                                      const gfx::Rect& new_bounds) OVERRIDE;
     65   virtual void OnWindowPropertyChanged(aura::Window* window,
     66                                        const void* key,
     67                                        intptr_t old) OVERRIDE;
     68   virtual void OnWindowDestroying(aura::Window* window) OVERRIDE;
     69 
     70   // WidgetObserver overrides:
     71   virtual void OnWidgetActivationChanged(views::Widget* widget,
     72                                         bool active) OVERRIDE;
     73 
     74   // ImageButton overrides:
     75   virtual bool OnMousePressed(const ui::MouseEvent& event) OVERRIDE;
     76   virtual void OnMouseEntered(const ui::MouseEvent& event) OVERRIDE;
     77   virtual void OnMouseExited(const ui::MouseEvent& event) OVERRIDE;
     78   virtual bool OnMouseDragged(const ui::MouseEvent& event) OVERRIDE;
     79   virtual void OnMouseReleased(const ui::MouseEvent& event) OVERRIDE;
     80   virtual void OnMouseCaptureLost() OVERRIDE;
     81 
     82   // ui::EventHandler overrides:
     83   virtual void OnGestureEvent(ui::GestureEvent* event) OVERRIDE;
     84 
     85   // views::View overwrite:
     86   virtual void SetVisible(bool visible) OVERRIDE;
     87 
     88   // Unit test overwrite: Change the UI delay used for the bubble show up.
     89   void set_bubble_appearance_delay_ms(int bubble_appearance_delay_ms) {
     90     bubble_appearance_delay_ms_ = bubble_appearance_delay_ms;
     91   }
     92 
     93   // Unit test accessor for the maximize bubble.
     94   MaximizeBubbleController* maximizer() { return maximizer_.get(); }
     95 
     96   // Unit test to see if phantom window is open.
     97   bool phantom_window_open() { return phantom_window_.get() != NULL; }
     98 
     99  private:
    100   class EscapeEventFilter;
    101 
    102   // Initializes the snap-gesture based on the event. This should only be called
    103   // when the event is confirmed to have started a snap gesture.
    104   void ProcessStartEvent(const ui::LocatedEvent& event);
    105 
    106   // Updates the snap-state based on the current event. This should only be
    107   // called after the snap gesture has already started.
    108   void ProcessUpdateEvent(const ui::LocatedEvent& event);
    109 
    110   // Returns true if the window was snapped. Returns false otherwise.
    111   bool ProcessEndEvent(const ui::LocatedEvent& event);
    112 
    113   // Cancels snap behavior. If |keep_menu_open| is set, a possibly opened
    114   // bubble help will remain open.
    115   void Cancel(bool keep_menu_open);
    116 
    117   // Installs/uninstalls an EventFilter to track when escape is pressed.
    118   void InstallEventFilter();
    119   void UninstallEventFilter();
    120 
    121   // Updates the snap position from the event location. This is invoked by
    122   // |update_timer_|.
    123   void UpdateSnapFromEventLocation();
    124 
    125   // Updates |snap_type_| based on a mouse drag. If |select_default| is set,
    126   // the single button click default setting of the snap sizer should be used.
    127   // Set |is_touch| to true to make touch snapping at the corners possible.
    128   void UpdateSnap(const gfx::Point& location,
    129                   bool select_default,
    130                   bool is_touch);
    131 
    132   // Returns the type of snap based on the specified location.
    133   SnapType SnapTypeForLocation(const gfx::Point& location) const;
    134 
    135   // Returns the bounds of the resulting window for the specified type.
    136   gfx::Rect ScreenBoundsForType(SnapType type,
    137                                 const internal::SnapSizer& snap_sizer) const;
    138 
    139   // Converts location to screen coordinates and returns it. These are the
    140   // coordinates used by the SnapSizer.
    141   gfx::Point LocationForSnapSizer(const gfx::Point& location) const;
    142 
    143   // Snaps the window to the current snap position.
    144   void Snap(internal::SnapSizer* snap_sizer);
    145 
    146   // Determine the maximize type of this window.
    147   MaximizeBubbleFrameState GetMaximizeBubbleFrameState() const;
    148 
    149   // Widget that the maximize button acts on. This is different than the widget
    150   // which contains the button in the case of AppNonClientFrameViewAsh.
    151   views::Widget* frame_;
    152 
    153   // True if we have put observers on |frame_|.
    154   bool observing_frame_;
    155 
    156   // Renders the snap position.
    157   scoped_ptr<internal::PhantomWindowController> phantom_window_;
    158 
    159   // Is snapping enabled? Set on press so that in drag we know whether we
    160   // should show the snap locations.
    161   bool is_snap_enabled_;
    162 
    163   // Did the user drag far enough to trigger snapping?
    164   bool exceeded_drag_threshold_;
    165 
    166   // Location of the press.
    167   gfx::Point press_location_;
    168 
    169   // True if the press was triggered by a gesture/touch.
    170   bool press_is_gesture_;
    171 
    172   // Current snap type.
    173   SnapType snap_type_;
    174 
    175   scoped_ptr<internal::SnapSizer> snap_sizer_;
    176 
    177   scoped_ptr<EscapeEventFilter> escape_event_filter_;
    178 
    179   base::OneShotTimer<FrameMaximizeButton> update_timer_;
    180 
    181   scoped_ptr<MaximizeBubbleController> maximizer_;
    182 
    183   // The delay of the bubble appearance.
    184   int bubble_appearance_delay_ms_;
    185 
    186   ObserverList<FrameMaximizeButtonObserver> observer_list_;
    187 
    188   DISALLOW_COPY_AND_ASSIGN(FrameMaximizeButton);
    189 };
    190 
    191 }  // namespace ash
    192 
    193 #endif  // ASH_WM_CAPTION_BUTTONS_FRAME_MAXIMIZE_BUTTON_H_
    194