Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(715)

Side by Side Diff: ash/wm/caption_buttons/alternate_frame_size_button.cc

Issue 168943006: Keep the size button pressed when the user hovers the snap left or snap right button (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "ash/wm/caption_buttons/alternate_frame_size_button.h" 5 #include "ash/wm/caption_buttons/alternate_frame_size_button.h"
6 6
7 #include "ash/metrics/user_metrics_recorder.h" 7 #include "ash/metrics/user_metrics_recorder.h"
8 #include "ash/screen_util.h" 8 #include "ash/screen_util.h"
9 #include "ash/shell.h" 9 #include "ash/shell.h"
10 #include "ash/touch/touch_uma.h" 10 #include "ash/touch/touch_uma.h"
11 #include "ash/wm/window_state.h" 11 #include "ash/wm/window_state.h"
12 #include "ash/wm/workspace/phantom_window_controller.h" 12 #include "ash/wm/workspace/phantom_window_controller.h"
13 #include "ash/wm/workspace/snap_sizer.h" 13 #include "ash/wm/workspace/snap_sizer.h"
14 #include "ui/gfx/vector2d.h" 14 #include "ui/gfx/vector2d.h"
15 #include "ui/views/widget/widget.h" 15 #include "ui/views/widget/widget.h"
16 16
17 namespace { 17 namespace {
18 18
19 // The default delay between the user pressing the size button and the buttons 19 // The default delay between the user pressing the size button and the buttons
20 // adjacent to the size button morphing into buttons for snapping left and 20 // adjacent to the size button morphing into buttons for snapping left and
21 // right. 21 // right.
22 const int kSetButtonsToSnapModeDelayMs = 150; 22 const int kSetButtonsToSnapModeDelayMs = 150;
23 23
24 // The amount that a user can overshoot the snap left / snap right button and 24 // The amount that a user can overshoot one of the caption buttons while in
25 // keep the snap left / snap right button pressed. 25 // "snap mode" and keep the button hovered/pressed.
26 const int kPressedHitBoundsExpandX = 200; 26 const int kMaxOvershootX = 200;
27 const int kPressedHitBoundsExpandY = 50; 27 const int kMaxOvershootY = 50;
28
29 // Returns true if a mouse drag while in "snap mode" at |location_in_screen|
30 // would hover/press |button| or keep it hovered/pressed.
31 bool HitTestButton(const ash::FrameCaptionButton* button,
32 const gfx::Point& location_in_screen) {
33 gfx::Rect expanded_bounds_in_screen = button->GetBoundsInScreen();
34 if (button->state() == views::Button::STATE_HOVERED ||
35 button->state() == views::Button::STATE_PRESSED) {
36 expanded_bounds_in_screen.Inset(-kMaxOvershootX, -kMaxOvershootY);
37 }
38 return expanded_bounds_in_screen.Contains(location_in_screen);
39 }
28 40
29 } // namespace 41 } // namespace
30 42
31 namespace ash { 43 namespace ash {
32 44
33 AlternateFrameSizeButton::AlternateFrameSizeButton( 45 AlternateFrameSizeButton::AlternateFrameSizeButton(
34 views::ButtonListener* listener, 46 views::ButtonListener* listener,
35 views::Widget* frame, 47 views::Widget* frame,
36 AlternateFrameSizeButtonDelegate* delegate) 48 AlternateFrameSizeButtonDelegate* delegate)
37 : FrameCaptionButton(listener, CAPTION_BUTTON_ICON_MAXIMIZE_RESTORE), 49 : FrameCaptionButton(listener, CAPTION_BUTTON_ICON_MAXIMIZE_RESTORE),
(...skipping 14 matching lines...) Expand all
52 if (IsTriggerableEvent(event) && 64 if (IsTriggerableEvent(event) &&
53 !in_snap_mode_ && 65 !in_snap_mode_ &&
54 delegate_->IsMinimizeButtonVisible()) { 66 delegate_->IsMinimizeButtonVisible()) {
55 StartSetButtonsToSnapModeTimer(event); 67 StartSetButtonsToSnapModeTimer(event);
56 } 68 }
57 FrameCaptionButton::OnMousePressed(event); 69 FrameCaptionButton::OnMousePressed(event);
58 return true; 70 return true;
59 } 71 }
60 72
61 bool AlternateFrameSizeButton::OnMouseDragged(const ui::MouseEvent& event) { 73 bool AlternateFrameSizeButton::OnMouseDragged(const ui::MouseEvent& event) {
62 UpdatePressedButton(event); 74 UpdateSnapType(event);
63 FrameCaptionButton::OnMouseDragged(event); 75 // By default a FrameCaptionButton reverts to STATE_NORMAL once the mouse
76 // leaves its bounds. Skip FrameCaptionButton's handling when
77 // |in_snap_mode_| == true because we want different behavior.
78 if (!in_snap_mode_)
79 FrameCaptionButton::OnMouseDragged(event);
64 return true; 80 return true;
65 } 81 }
66 82
67 void AlternateFrameSizeButton::OnMouseReleased(const ui::MouseEvent& event) { 83 void AlternateFrameSizeButton::OnMouseReleased(const ui::MouseEvent& event) {
68 if (!IsTriggerableEvent(event) || !CommitSnap(event)) 84 if (!IsTriggerableEvent(event) || !CommitSnap(event))
69 FrameCaptionButton::OnMouseReleased(event); 85 FrameCaptionButton::OnMouseReleased(event);
70 } 86 }
71 87
72 void AlternateFrameSizeButton::OnMouseCaptureLost() { 88 void AlternateFrameSizeButton::OnMouseCaptureLost() {
73 SetButtonsToNormalMode(AlternateFrameSizeButtonDelegate::ANIMATE_YES); 89 SetButtonsToNormalMode(AlternateFrameSizeButtonDelegate::ANIMATE_YES);
74 FrameCaptionButton::OnMouseCaptureLost(); 90 FrameCaptionButton::OnMouseCaptureLost();
75 } 91 }
76 92
93 void AlternateFrameSizeButton::OnMouseMoved(const ui::MouseEvent& event) {
94 // Ignore any synthetic mouse moves during a drag.
95 if (!in_snap_mode_)
96 FrameCaptionButton::OnMouseMoved(event);
97 }
98
77 void AlternateFrameSizeButton::OnGestureEvent(ui::GestureEvent* event) { 99 void AlternateFrameSizeButton::OnGestureEvent(ui::GestureEvent* event) {
78 if (event->details().touch_points() > 1) { 100 if (event->details().touch_points() > 1) {
79 SetButtonsToNormalMode(AlternateFrameSizeButtonDelegate::ANIMATE_YES); 101 SetButtonsToNormalMode(AlternateFrameSizeButtonDelegate::ANIMATE_YES);
80 return; 102 return;
81 } 103 }
82 104
83 if (event->type() == ui::ET_GESTURE_TAP_DOWN) { 105 if (event->type() == ui::ET_GESTURE_TAP_DOWN) {
84 StartSetButtonsToSnapModeTimer(*event); 106 StartSetButtonsToSnapModeTimer(*event);
85 // Go through FrameCaptionButton's handling so that the button gets pressed. 107 // Go through FrameCaptionButton's handling so that the button gets pressed.
86 FrameCaptionButton::OnGestureEvent(event); 108 FrameCaptionButton::OnGestureEvent(event);
87 return; 109 return;
88 } 110 }
89 111
90 if (event->type() == ui::ET_GESTURE_SCROLL_BEGIN || 112 if (event->type() == ui::ET_GESTURE_SCROLL_BEGIN ||
91 event->type() == ui::ET_GESTURE_SCROLL_UPDATE) { 113 event->type() == ui::ET_GESTURE_SCROLL_UPDATE) {
92 UpdatePressedButton(*event); 114 UpdateSnapType(*event);
93 event->SetHandled(); 115 event->SetHandled();
94 return; 116 return;
95 } 117 }
96 118
97 if (event->type() == ui::ET_GESTURE_TAP || 119 if (event->type() == ui::ET_GESTURE_TAP ||
98 event->type() == ui::ET_GESTURE_SCROLL_END || 120 event->type() == ui::ET_GESTURE_SCROLL_END ||
99 event->type() == ui::ET_SCROLL_FLING_START || 121 event->type() == ui::ET_SCROLL_FLING_START ||
100 event->type() == ui::ET_GESTURE_END) { 122 event->type() == ui::ET_GESTURE_END) {
101 if (CommitSnap(*event)) { 123 if (CommitSnap(*event)) {
102 if (event->type() == ui::ET_GESTURE_TAP) { 124 if (event->type() == ui::ET_GESTURE_TAP) {
(...skipping 24 matching lines...) Expand all
127 149
128 void AlternateFrameSizeButton::SetButtonsToSnapMode() { 150 void AlternateFrameSizeButton::SetButtonsToSnapMode() {
129 if (in_snap_mode_) 151 if (in_snap_mode_)
130 return; 152 return;
131 in_snap_mode_ = true; 153 in_snap_mode_ = true;
132 delegate_->SetButtonIcons(CAPTION_BUTTON_ICON_LEFT_SNAPPED, 154 delegate_->SetButtonIcons(CAPTION_BUTTON_ICON_LEFT_SNAPPED,
133 CAPTION_BUTTON_ICON_RIGHT_SNAPPED, 155 CAPTION_BUTTON_ICON_RIGHT_SNAPPED,
134 AlternateFrameSizeButtonDelegate::ANIMATE_YES); 156 AlternateFrameSizeButtonDelegate::ANIMATE_YES);
135 } 157 }
136 158
137 void AlternateFrameSizeButton::UpdatePressedButton( 159 void AlternateFrameSizeButton::UpdateSnapType(const ui::LocatedEvent& event) {
138 const ui::LocatedEvent& event) {
139 if (!in_snap_mode_) { 160 if (!in_snap_mode_) {
140 // Set the buttons adjacent to the size button to snap left and right early 161 // Set the buttons adjacent to the size button to snap left and right early
141 // if the user drags past the drag threshold. 162 // if the user drags past the drag threshold.
142 // |set_buttons_to_snap_mode_timer_| is checked to avoid entering the snap 163 // |set_buttons_to_snap_mode_timer_| is checked to avoid entering the snap
143 // mode as a result of an unsupported drag type (e.g. only the right mouse 164 // mode as a result of an unsupported drag type (e.g. only the right mouse
144 // button is pressed). 165 // button is pressed).
145 gfx::Vector2d delta( 166 gfx::Vector2d delta(
146 event.location() - set_buttons_to_snap_mode_timer_event_location_); 167 event.location() - set_buttons_to_snap_mode_timer_event_location_);
147 if (!set_buttons_to_snap_mode_timer_.IsRunning() || 168 if (!set_buttons_to_snap_mode_timer_.IsRunning() ||
148 !views::View::ExceededDragThreshold(delta)) { 169 !views::View::ExceededDragThreshold(delta)) {
149 return; 170 return;
150 } 171 }
151 SetButtonsToSnapMode(); 172 SetButtonsToSnapMode();
152 } 173 }
153 174
154 gfx::Point event_location_in_screen(event.location()); 175 gfx::Point event_location_in_screen(event.location());
155 views::View::ConvertPointToScreen(this, &event_location_in_screen); 176 views::View::ConvertPointToScreen(this, &event_location_in_screen);
177 const FrameCaptionButton* to_hover =
178 GetButtonToHover(event_location_in_screen);
179 bool press_size_button =
180 to_hover || HitTestButton(this, event_location_in_screen);
181 delegate_->SetHoveredAndPressedButtons(
182 to_hover, press_size_button ? this : NULL);
156 183
157 gfx::Insets pressed_button_hittest_insets(-kPressedHitBoundsExpandY,
158 -kPressedHitBoundsExpandX,
159 -kPressedHitBoundsExpandY,
160 -kPressedHitBoundsExpandX);
161 const FrameCaptionButton* pressed_button = delegate_->PressButtonAt(
162 event_location_in_screen, pressed_button_hittest_insets);
163 snap_type_ = SNAP_NONE; 184 snap_type_ = SNAP_NONE;
164 if (pressed_button) { 185 if (to_hover) {
165 switch (pressed_button->icon()) { 186 switch (to_hover->icon()) {
166 case CAPTION_BUTTON_ICON_LEFT_SNAPPED: 187 case CAPTION_BUTTON_ICON_LEFT_SNAPPED:
167 snap_type_ = SNAP_LEFT; 188 snap_type_ = SNAP_LEFT;
168 break; 189 break;
169 case CAPTION_BUTTON_ICON_RIGHT_SNAPPED: 190 case CAPTION_BUTTON_ICON_RIGHT_SNAPPED:
170 snap_type_ = SNAP_RIGHT; 191 snap_type_ = SNAP_RIGHT;
171 break; 192 break;
172 case CAPTION_BUTTON_ICON_MAXIMIZE_RESTORE: 193 case CAPTION_BUTTON_ICON_MAXIMIZE_RESTORE:
173 // snap_type_ = SNAP_NONE
174 break;
175 case CAPTION_BUTTON_ICON_MINIMIZE: 194 case CAPTION_BUTTON_ICON_MINIMIZE:
176 case CAPTION_BUTTON_ICON_CLOSE: 195 case CAPTION_BUTTON_ICON_CLOSE:
177 case CAPTION_BUTTON_ICON_COUNT: 196 case CAPTION_BUTTON_ICON_COUNT:
178 NOTREACHED(); 197 NOTREACHED();
179 break; 198 break;
180 } 199 }
181 } 200 }
182 201
183 if (snap_type_ == SNAP_LEFT || snap_type_ == SNAP_RIGHT) { 202 if (snap_type_ == SNAP_LEFT || snap_type_ == SNAP_RIGHT) {
184 if (!phantom_window_controller_.get()) { 203 if (!phantom_window_controller_.get()) {
185 phantom_window_controller_.reset( 204 phantom_window_controller_.reset(
186 new internal::PhantomWindowController(frame_->GetNativeWindow())); 205 new internal::PhantomWindowController(frame_->GetNativeWindow()));
187 } 206 }
188 207
189 using internal::SnapSizer; 208 using internal::SnapSizer;
190 SnapSizer snap_sizer(wm::GetWindowState(frame_->GetNativeWindow()), 209 SnapSizer snap_sizer(wm::GetWindowState(frame_->GetNativeWindow()),
191 gfx::Point(), 210 gfx::Point(),
192 snap_type_ == SNAP_LEFT ? 211 snap_type_ == SNAP_LEFT ?
193 SnapSizer::LEFT_EDGE : SnapSizer::RIGHT_EDGE, 212 SnapSizer::LEFT_EDGE : SnapSizer::RIGHT_EDGE,
194 SnapSizer::OTHER_INPUT); 213 SnapSizer::OTHER_INPUT);
195 phantom_window_controller_->Show(ScreenUtil::ConvertRectToScreen( 214 phantom_window_controller_->Show(ScreenUtil::ConvertRectToScreen(
196 frame_->GetNativeView()->parent(), 215 frame_->GetNativeView()->parent(),
197 snap_sizer.target_bounds())); 216 snap_sizer.target_bounds()));
198 } else { 217 } else {
199 phantom_window_controller_.reset(); 218 phantom_window_controller_.reset();
200 } 219 }
201 } 220 }
202 221
222 const FrameCaptionButton* AlternateFrameSizeButton::GetButtonToHover(
223 const gfx::Point& event_location_in_screen) const {
224 const FrameCaptionButton* closest_button = delegate_->GetButtonClosestTo(
225 event_location_in_screen);
226 if ((closest_button->icon() == CAPTION_BUTTON_ICON_LEFT_SNAPPED ||
227 closest_button->icon() == CAPTION_BUTTON_ICON_RIGHT_SNAPPED) &&
228 HitTestButton(closest_button, event_location_in_screen)) {
229 return closest_button;
230 }
231 return NULL;
232 }
233
203 bool AlternateFrameSizeButton::CommitSnap(const ui::LocatedEvent& event) { 234 bool AlternateFrameSizeButton::CommitSnap(const ui::LocatedEvent& event) {
204 // The position of |event| may be different than the position of the previous 235 // The position of |event| may be different than the position of the previous
205 // event. 236 // event.
206 UpdatePressedButton(event); 237 UpdateSnapType(event);
207 238
208 if (in_snap_mode_ && 239 if (in_snap_mode_ &&
209 (snap_type_ == SNAP_LEFT || snap_type_ == SNAP_RIGHT)) { 240 (snap_type_ == SNAP_LEFT || snap_type_ == SNAP_RIGHT)) {
210 using internal::SnapSizer; 241 using internal::SnapSizer;
211 SnapSizer::SnapWindow(ash::wm::GetWindowState(frame_->GetNativeWindow()), 242 SnapSizer::SnapWindow(ash::wm::GetWindowState(frame_->GetNativeWindow()),
212 snap_type_ == SNAP_LEFT ? 243 snap_type_ == SNAP_LEFT ?
213 SnapSizer::LEFT_EDGE : SnapSizer::RIGHT_EDGE); 244 SnapSizer::LEFT_EDGE : SnapSizer::RIGHT_EDGE);
214 ash::Shell::GetInstance()->metrics()->RecordUserMetricsAction( 245 ash::Shell::GetInstance()->metrics()->RecordUserMetricsAction(
215 snap_type_ == SNAP_LEFT ? 246 snap_type_ == SNAP_LEFT ?
216 ash::UMA_WINDOW_MAXIMIZE_BUTTON_MAXIMIZE_LEFT : 247 ash::UMA_WINDOW_MAXIMIZE_BUTTON_MAXIMIZE_LEFT :
217 ash::UMA_WINDOW_MAXIMIZE_BUTTON_MAXIMIZE_RIGHT); 248 ash::UMA_WINDOW_MAXIMIZE_BUTTON_MAXIMIZE_RIGHT);
218 SetButtonsToNormalMode(AlternateFrameSizeButtonDelegate::ANIMATE_NO); 249 SetButtonsToNormalMode(AlternateFrameSizeButtonDelegate::ANIMATE_NO);
219 return true; 250 return true;
220 } 251 }
221 SetButtonsToNormalMode(AlternateFrameSizeButtonDelegate::ANIMATE_YES); 252 SetButtonsToNormalMode(AlternateFrameSizeButtonDelegate::ANIMATE_YES);
222 return false; 253 return false;
223 } 254 }
224 255
225 void AlternateFrameSizeButton::SetButtonsToNormalMode( 256 void AlternateFrameSizeButton::SetButtonsToNormalMode(
226 AlternateFrameSizeButtonDelegate::Animate animate) { 257 AlternateFrameSizeButtonDelegate::Animate animate) {
227 in_snap_mode_ = false; 258 in_snap_mode_ = false;
228 snap_type_ = SNAP_NONE; 259 snap_type_ = SNAP_NONE;
229 set_buttons_to_snap_mode_timer_.Stop(); 260 set_buttons_to_snap_mode_timer_.Stop();
230 delegate_->SetButtonsToNormal(animate); 261 delegate_->SetButtonsToNormal(animate);
231 phantom_window_controller_.reset(); 262 phantom_window_controller_.reset();
232 } 263 }
233 264
234 } // namespace ash 265 } // namespace ash
OLDNEW
« no previous file with comments | « ash/wm/caption_buttons/alternate_frame_size_button.h ('k') | ash/wm/caption_buttons/alternate_frame_size_button_delegate.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698