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

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

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

Powered by Google App Engine
This is Rietveld 408576698