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

Side by Side Diff: mash/wm/move_loop.cc

Issue 1459653002: Gets mustash frames looking like that of ash (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: update test Created 5 years, 1 month 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
« no previous file with comments | « mash/wm/move_loop.h ('k') | mash/wm/move_loop_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2015 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 "mash/wm/move_loop.h"
6
7 #include "base/auto_reset.h"
8 #include "components/mus/public/cpp/window.h"
9 #include "components/mus/public/interfaces/input_event_constants.mojom.h"
10 #include "mash/wm/property_util.h"
11 #include "ui/gfx/geometry/point_conversions.h"
12 #include "ui/gfx/geometry/rect.h"
13
14 namespace {
15
16 gfx::Point EventLocationToPoint(const mus::mojom::Event& event) {
17 return gfx::ToFlooredPoint(gfx::PointF(event.pointer_data->location->x,
18 event.pointer_data->location->y));
19 }
20
21 gfx::Point EventScreenLocationToPoint(const mus::mojom::Event& event) {
22 return gfx::ToFlooredPoint(
23 gfx::PointF(event.pointer_data->location->screen_x,
24 event.pointer_data->location->screen_y));
25 }
26
27 mus::mojom::EventFlags MouseOnlyEventFlags(mus::mojom::EventFlags flags) {
28 return static_cast<mus::mojom::EventFlags>(
29 flags & (mus::mojom::EVENT_FLAGS_LEFT_MOUSE_BUTTON |
30 mus::mojom::EVENT_FLAGS_MIDDLE_MOUSE_BUTTON |
31 mus::mojom::EVENT_FLAGS_RIGHT_MOUSE_BUTTON));
32 }
33
34 gfx::Rect ClientAreaBounds(const mus::Window* window) {
35 gfx::Rect client_area(window->bounds().size());
36 client_area.Inset(window->client_area());
37 return client_area;
38 }
39
40 } // namespace
41
42 MoveLoop::~MoveLoop() {
43 if (target_)
44 target_->RemoveObserver(this);
45 }
46
47 // static
48 scoped_ptr<MoveLoop> MoveLoop::Create(mus::Window* target,
49 const mus::mojom::Event& event) {
50 DCHECK_EQ(event.action, mus::mojom::EVENT_TYPE_POINTER_DOWN);
51 const gfx::Point location(EventLocationToPoint(event));
52 if (!gfx::Rect(target->bounds().size()).Contains(location) ||
53 ClientAreaBounds(target).Contains(location)) {
54 return nullptr;
55 }
56
57 // Start a move on left mouse, or any other type of pointer.
58 if (event.pointer_data->kind == mus::mojom::POINTER_KIND_MOUSE &&
59 MouseOnlyEventFlags(event.flags) !=
60 mus::mojom::EVENT_FLAGS_LEFT_MOUSE_BUTTON) {
61 return nullptr;
62 }
63
64 Type type;
65 HorizontalLocation h_loc;
66 VerticalLocation v_loc;
67 DetermineType(target, location, &type, &h_loc, &v_loc);
68
69 return make_scoped_ptr(new MoveLoop(target, event, type, h_loc, v_loc));
70 }
71
72 MoveLoop::MoveResult MoveLoop::Move(const mus::mojom::Event& event) {
73 switch (event.action) {
74 case mus::mojom::EVENT_TYPE_POINTER_CANCEL:
75 if (event.pointer_data->pointer_id == pointer_id_) {
76 if (target_)
77 Revert();
78 return MoveResult::DONE;
79 }
80 return MoveResult::CONTINUE;
81
82 case mus::mojom::EVENT_TYPE_POINTER_MOVE:
83 if (target_ && event.pointer_data->pointer_id == pointer_id_)
84 MoveImpl(event);
85 return MoveResult::CONTINUE;
86
87 case mus::mojom::EVENT_TYPE_POINTER_UP:
88 if (event.pointer_data->pointer_id == pointer_id_) {
89 // TODO(sky): need to support changed_flags.
90 if (target_)
91 MoveImpl(event);
92 return MoveResult::DONE;
93 }
94 return MoveResult::CONTINUE;
95
96 default:
97 break;
98 }
99
100 return MoveResult::CONTINUE;
101 }
102
103 MoveLoop::MoveLoop(mus::Window* target,
104 const mus::mojom::Event& event,
105 Type type,
106 HorizontalLocation h_loc,
107 VerticalLocation v_loc)
108 : target_(target),
109 type_(type),
110 h_loc_(h_loc),
111 v_loc_(v_loc),
112 pointer_id_(event.pointer_data->pointer_id),
113 initial_event_screen_location_(EventScreenLocationToPoint(event)),
114 initial_window_bounds_(target->bounds()),
115 initial_user_set_bounds_(GetWindowUserSetBounds(target)),
116 changing_bounds_(false) {
117 target->AddObserver(this);
118 }
119
120 // static
121 void MoveLoop::DetermineType(mus::Window* target,
122 const gfx::Point& location,
123 Type* type,
124 HorizontalLocation* h_loc,
125 VerticalLocation* v_loc) {
126 *h_loc = HorizontalLocation::OTHER;
127 *v_loc = VerticalLocation::OTHER;
128 const int resize_size = static_cast<int>(
129 kResizeSize *
130 std::max(1.f, target->viewport_metrics().device_pixel_ratio));
131
132 const gfx::Rect client_area(ClientAreaBounds(target));
133 if (location.x() < client_area.x())
134 *h_loc = HorizontalLocation::LEFT;
135 else if (location.x() >= client_area.right())
136 *h_loc = HorizontalLocation::RIGHT;
137 else
138 *h_loc = HorizontalLocation::OTHER;
139
140 if (location.y() < resize_size)
141 *v_loc = VerticalLocation::TOP;
142 else if (location.y() >= client_area.bottom())
143 *v_loc = VerticalLocation::BOTTOM;
144 else
145 *v_loc = VerticalLocation::OTHER;
146
147 if (*v_loc == VerticalLocation::OTHER && location.y() >= resize_size &&
148 *h_loc == HorizontalLocation::OTHER) {
149 *type = Type::MOVE;
150 return;
151 }
152 *type = Type::RESIZE;
153 DCHECK(*h_loc != HorizontalLocation::OTHER ||
154 *v_loc != VerticalLocation::OTHER);
155 }
156
157 void MoveLoop::MoveImpl(const mus::mojom::Event& event) {
158 const gfx::Vector2d delta =
159 EventScreenLocationToPoint(event) - initial_event_screen_location_;
160 const gfx::Rect new_bounds(DetermineBoundsFromDelta(delta));
161 base::AutoReset<bool> resetter(&changing_bounds_, true);
162 target_->SetBounds(new_bounds);
163 SetWindowUserSetBounds(target_, new_bounds);
164 }
165
166 void MoveLoop::Cancel() {
167 target_->RemoveObserver(this);
168 target_ = nullptr;
169 }
170
171 void MoveLoop::Revert() {
172 base::AutoReset<bool> resetter(&changing_bounds_, true);
173 target_->SetBounds(initial_window_bounds_);
174 SetWindowUserSetBounds(target_, initial_user_set_bounds_);
175 }
176
177 gfx::Rect MoveLoop::DetermineBoundsFromDelta(const gfx::Vector2d& delta) {
178 if (type_ == Type::MOVE) {
179 return gfx::Rect(initial_window_bounds_.origin() + delta,
180 initial_window_bounds_.size());
181 }
182
183 // TODO(sky): support better min sizes, make sure doesn't get bigger than
184 // screen and max. Also make sure keep some portion on screen.
185 gfx::Rect bounds(initial_window_bounds_);
186 if (h_loc_ == HorizontalLocation::LEFT) {
187 const int x = std::min(bounds.right() - 1, bounds.x() + delta.x());
188 const int width = bounds.right() - x;
189 bounds.set_x(x);
190 bounds.set_width(width);
191 } else if (h_loc_ == HorizontalLocation::RIGHT) {
192 bounds.set_width(std::max(1, bounds.width() + delta.x()));
193 }
194
195 if (v_loc_ == VerticalLocation::TOP) {
196 const int y = std::min(bounds.bottom() - 1, bounds.y() + delta.y());
197 const int height = bounds.bottom() - y;
198 bounds.set_y(y);
199 bounds.set_height(height);
200 } else if (v_loc_ == VerticalLocation::BOTTOM) {
201 bounds.set_height(std::max(1, bounds.height() + delta.y()));
202 }
203
204 return bounds;
205 }
206
207 void MoveLoop::OnTreeChanged(const TreeChangeParams& params) {
208 if (params.target == target_)
209 Cancel();
210 }
211
212 void MoveLoop::OnWindowBoundsChanged(mus::Window* window,
213 const gfx::Rect& old_bounds,
214 const gfx::Rect& new_bounds) {
215 DCHECK_EQ(window, target_);
216 if (!changing_bounds_)
217 Cancel();
218 }
219
220 void MoveLoop::OnWindowVisibilityChanged(mus::Window* window) {
221 DCHECK_EQ(window, target_);
222 Cancel();
223 }
OLDNEW
« no previous file with comments | « mash/wm/move_loop.h ('k') | mash/wm/move_loop_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698