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

Side by Side Diff: ash/common/frame/caption_buttons/frame_size_button.cc

Issue 2734653002: chromeos: Move files in //ash/common to //ash (Closed)
Patch Set: fix a11y tests, fix docs Created 3 years, 9 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
OLDNEW
(Empty)
1 // Copyright 2014 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 #include "ash/common/frame/caption_buttons/frame_size_button.h"
6
7 #include "ash/common/wm/window_positioning_utils.h"
8 #include "ash/common/wm/window_state.h"
9 #include "ash/common/wm/wm_event.h"
10 #include "ash/common/wm/workspace/phantom_window_controller.h"
11 #include "ash/common/wm_shell.h"
12 #include "ash/common/wm_window.h"
13 #include "base/i18n/rtl.h"
14 #include "ui/gfx/geometry/vector2d.h"
15 #include "ui/views/widget/widget.h"
16
17 namespace ash {
18
19 namespace {
20
21 // The default delay between the user pressing the size button and the buttons
22 // adjacent to the size button morphing into buttons for snapping left and
23 // right.
24 const int kSetButtonsToSnapModeDelayMs = 150;
25
26 // The amount that a user can overshoot one of the caption buttons while in
27 // "snap mode" and keep the button hovered/pressed.
28 const int kMaxOvershootX = 200;
29 const int kMaxOvershootY = 50;
30
31 // Returns true if a mouse drag while in "snap mode" at |location_in_screen|
32 // would hover/press |button| or keep it hovered/pressed.
33 bool HitTestButton(const FrameCaptionButton* button,
34 const gfx::Point& location_in_screen) {
35 gfx::Rect expanded_bounds_in_screen = button->GetBoundsInScreen();
36 if (button->state() == views::Button::STATE_HOVERED ||
37 button->state() == views::Button::STATE_PRESSED) {
38 expanded_bounds_in_screen.Inset(-kMaxOvershootX, -kMaxOvershootY);
39 }
40 return expanded_bounds_in_screen.Contains(location_in_screen);
41 }
42
43 } // namespace
44
45 FrameSizeButton::FrameSizeButton(views::ButtonListener* listener,
46 views::Widget* frame,
47 FrameSizeButtonDelegate* delegate)
48 : FrameCaptionButton(listener, CAPTION_BUTTON_ICON_MAXIMIZE_RESTORE),
49 frame_(frame),
50 delegate_(delegate),
51 set_buttons_to_snap_mode_delay_ms_(kSetButtonsToSnapModeDelayMs),
52 in_snap_mode_(false),
53 snap_type_(SNAP_NONE) {}
54
55 FrameSizeButton::~FrameSizeButton() {}
56
57 bool FrameSizeButton::OnMousePressed(const ui::MouseEvent& event) {
58 // The minimize and close buttons are set to snap left and right when snapping
59 // is enabled. Do not enable snapping if the minimize button is not visible.
60 // The close button is always visible.
61 if (IsTriggerableEvent(event) && !in_snap_mode_ &&
62 delegate_->IsMinimizeButtonVisible()) {
63 StartSetButtonsToSnapModeTimer(event);
64 }
65 FrameCaptionButton::OnMousePressed(event);
66 return true;
67 }
68
69 bool FrameSizeButton::OnMouseDragged(const ui::MouseEvent& event) {
70 UpdateSnapType(event);
71 // By default a FrameCaptionButton reverts to STATE_NORMAL once the mouse
72 // leaves its bounds. Skip FrameCaptionButton's handling when
73 // |in_snap_mode_| == true because we want different behavior.
74 if (!in_snap_mode_)
75 FrameCaptionButton::OnMouseDragged(event);
76 return true;
77 }
78
79 void FrameSizeButton::OnMouseReleased(const ui::MouseEvent& event) {
80 if (!IsTriggerableEvent(event) || !CommitSnap(event))
81 FrameCaptionButton::OnMouseReleased(event);
82 }
83
84 void FrameSizeButton::OnMouseCaptureLost() {
85 SetButtonsToNormalMode(FrameSizeButtonDelegate::ANIMATE_YES);
86 FrameCaptionButton::OnMouseCaptureLost();
87 }
88
89 void FrameSizeButton::OnMouseMoved(const ui::MouseEvent& event) {
90 // Ignore any synthetic mouse moves during a drag.
91 if (!in_snap_mode_)
92 FrameCaptionButton::OnMouseMoved(event);
93 }
94
95 void FrameSizeButton::OnGestureEvent(ui::GestureEvent* event) {
96 if (event->details().touch_points() > 1) {
97 SetButtonsToNormalMode(FrameSizeButtonDelegate::ANIMATE_YES);
98 return;
99 }
100
101 if (event->type() == ui::ET_GESTURE_TAP_DOWN) {
102 StartSetButtonsToSnapModeTimer(*event);
103 // Go through FrameCaptionButton's handling so that the button gets pressed.
104 FrameCaptionButton::OnGestureEvent(event);
105 return;
106 }
107
108 if (event->type() == ui::ET_GESTURE_SCROLL_BEGIN ||
109 event->type() == ui::ET_GESTURE_SCROLL_UPDATE) {
110 UpdateSnapType(*event);
111 event->SetHandled();
112 return;
113 }
114
115 if (event->type() == ui::ET_GESTURE_TAP ||
116 event->type() == ui::ET_GESTURE_SCROLL_END ||
117 event->type() == ui::ET_SCROLL_FLING_START ||
118 event->type() == ui::ET_GESTURE_END) {
119 if (CommitSnap(*event)) {
120 event->SetHandled();
121 return;
122 }
123 }
124
125 FrameCaptionButton::OnGestureEvent(event);
126 }
127
128 void FrameSizeButton::StartSetButtonsToSnapModeTimer(
129 const ui::LocatedEvent& event) {
130 set_buttons_to_snap_mode_timer_event_location_ = event.location();
131 if (set_buttons_to_snap_mode_delay_ms_ == 0) {
132 AnimateButtonsToSnapMode();
133 } else {
134 set_buttons_to_snap_mode_timer_.Start(
135 FROM_HERE,
136 base::TimeDelta::FromMilliseconds(set_buttons_to_snap_mode_delay_ms_),
137 this, &FrameSizeButton::AnimateButtonsToSnapMode);
138 }
139 }
140
141 void FrameSizeButton::AnimateButtonsToSnapMode() {
142 SetButtonsToSnapMode(FrameSizeButtonDelegate::ANIMATE_YES);
143 }
144
145 void FrameSizeButton::SetButtonsToSnapMode(
146 FrameSizeButtonDelegate::Animate animate) {
147 in_snap_mode_ = true;
148
149 // When using a right-to-left layout the close button is left of the size
150 // button and the minimize button is right of the size button.
151 if (base::i18n::IsRTL()) {
152 delegate_->SetButtonIcons(CAPTION_BUTTON_ICON_RIGHT_SNAPPED,
153 CAPTION_BUTTON_ICON_LEFT_SNAPPED, animate);
154 } else {
155 delegate_->SetButtonIcons(CAPTION_BUTTON_ICON_LEFT_SNAPPED,
156 CAPTION_BUTTON_ICON_RIGHT_SNAPPED, animate);
157 }
158 }
159
160 void FrameSizeButton::UpdateSnapType(const ui::LocatedEvent& event) {
161 if (!in_snap_mode_) {
162 // Set the buttons adjacent to the size button to snap left and right early
163 // if the user drags past the drag threshold.
164 // |set_buttons_to_snap_mode_timer_| is checked to avoid entering the snap
165 // mode as a result of an unsupported drag type (e.g. only the right mouse
166 // button is pressed).
167 gfx::Vector2d delta(event.location() -
168 set_buttons_to_snap_mode_timer_event_location_);
169 if (!set_buttons_to_snap_mode_timer_.IsRunning() ||
170 !views::View::ExceededDragThreshold(delta)) {
171 return;
172 }
173 AnimateButtonsToSnapMode();
174 }
175
176 gfx::Point event_location_in_screen(event.location());
177 views::View::ConvertPointToScreen(this, &event_location_in_screen);
178 const FrameCaptionButton* to_hover =
179 GetButtonToHover(event_location_in_screen);
180 bool press_size_button =
181 to_hover || HitTestButton(this, event_location_in_screen);
182
183 if (to_hover) {
184 // Progress the minimize and close icon morph animations to the end if they
185 // are in progress.
186 SetButtonsToSnapMode(FrameSizeButtonDelegate::ANIMATE_NO);
187 }
188
189 delegate_->SetHoveredAndPressedButtons(to_hover,
190 press_size_button ? this : NULL);
191
192 snap_type_ = SNAP_NONE;
193 if (to_hover) {
194 switch (to_hover->icon()) {
195 case CAPTION_BUTTON_ICON_LEFT_SNAPPED:
196 snap_type_ = SNAP_LEFT;
197 break;
198 case CAPTION_BUTTON_ICON_RIGHT_SNAPPED:
199 snap_type_ = SNAP_RIGHT;
200 break;
201 case CAPTION_BUTTON_ICON_MAXIMIZE_RESTORE:
202 case CAPTION_BUTTON_ICON_MINIMIZE:
203 case CAPTION_BUTTON_ICON_CLOSE:
204 case CAPTION_BUTTON_ICON_BACK:
205 case CAPTION_BUTTON_ICON_LOCATION:
206 case CAPTION_BUTTON_ICON_COUNT:
207 NOTREACHED();
208 break;
209 }
210 }
211
212 if (snap_type_ == SNAP_LEFT || snap_type_ == SNAP_RIGHT) {
213 WmWindow* window = WmWindow::Get(frame_->GetNativeWindow());
214 if (!phantom_window_controller_.get())
215 phantom_window_controller_.reset(new PhantomWindowController(window));
216 gfx::Rect phantom_bounds_in_parent =
217 (snap_type_ == SNAP_LEFT)
218 ? wm::GetDefaultLeftSnappedWindowBoundsInParent(window)
219 : wm::GetDefaultRightSnappedWindowBoundsInParent(window);
220 phantom_window_controller_->Show(
221 window->GetParent()->ConvertRectToScreen(phantom_bounds_in_parent));
222 } else {
223 phantom_window_controller_.reset();
224 }
225 }
226
227 const FrameCaptionButton* FrameSizeButton::GetButtonToHover(
228 const gfx::Point& event_location_in_screen) const {
229 const FrameCaptionButton* closest_button =
230 delegate_->GetButtonClosestTo(event_location_in_screen);
231 if ((closest_button->icon() == CAPTION_BUTTON_ICON_LEFT_SNAPPED ||
232 closest_button->icon() == CAPTION_BUTTON_ICON_RIGHT_SNAPPED) &&
233 HitTestButton(closest_button, event_location_in_screen)) {
234 return closest_button;
235 }
236 return NULL;
237 }
238
239 bool FrameSizeButton::CommitSnap(const ui::LocatedEvent& event) {
240 // The position of |event| may be different than the position of the previous
241 // event.
242 UpdateSnapType(event);
243
244 if (in_snap_mode_ && (snap_type_ == SNAP_LEFT || snap_type_ == SNAP_RIGHT)) {
245 WmWindow* window = WmWindow::Get(frame_->GetNativeWindow());
246 wm::WindowState* window_state = window->GetWindowState();
247 const wm::WMEvent snap_event(snap_type_ == SNAP_LEFT
248 ? wm::WM_EVENT_SNAP_LEFT
249 : wm::WM_EVENT_SNAP_RIGHT);
250 window_state->OnWMEvent(&snap_event);
251 WmShell::Get()->RecordUserMetricsAction(
252 snap_type_ == SNAP_LEFT ? UMA_WINDOW_MAXIMIZE_BUTTON_MAXIMIZE_LEFT
253 : UMA_WINDOW_MAXIMIZE_BUTTON_MAXIMIZE_RIGHT);
254 SetButtonsToNormalMode(FrameSizeButtonDelegate::ANIMATE_NO);
255 return true;
256 }
257 SetButtonsToNormalMode(FrameSizeButtonDelegate::ANIMATE_YES);
258 return false;
259 }
260
261 void FrameSizeButton::SetButtonsToNormalMode(
262 FrameSizeButtonDelegate::Animate animate) {
263 in_snap_mode_ = false;
264 snap_type_ = SNAP_NONE;
265 set_buttons_to_snap_mode_timer_.Stop();
266 delegate_->SetButtonsToNormal(animate);
267 phantom_window_controller_.reset();
268 }
269
270 } // namespace ash
OLDNEW
« no previous file with comments | « ash/common/frame/caption_buttons/frame_size_button.h ('k') | ash/common/frame/caption_buttons/frame_size_button_delegate.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698