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