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

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

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

Powered by Google App Engine
This is Rietveld 408576698