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