OLD | NEW |
| (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 "components/mus/ws/move_loop.h" | |
6 | |
7 #include "base/auto_reset.h" | |
8 #include "components/mus/ws/server_window.h" | |
9 #include "ui/gfx/geometry/point_conversions.h" | |
10 #include "ui/gfx/geometry/rect.h" | |
11 #include "ui/mojo/events/input_event_constants.mojom.h" | |
12 | |
13 namespace mus { | |
14 namespace ws { | |
15 namespace { | |
16 | |
17 gfx::Point EventLocationToPoint(const mojo::Event& event) { | |
18 return gfx::ToFlooredPoint(gfx::PointF(event.pointer_data->location->x, | |
19 event.pointer_data->location->y)); | |
20 } | |
21 | |
22 gfx::Point EventScreenLocationToPoint(const mojo::Event& event) { | |
23 return gfx::ToFlooredPoint( | |
24 gfx::PointF(event.pointer_data->location->screen_x, | |
25 event.pointer_data->location->screen_y)); | |
26 } | |
27 | |
28 mojo::EventFlags MouseOnlyEventFlags(mojo::EventFlags flags) { | |
29 return static_cast<mojo::EventFlags>(flags & | |
30 (mojo::EVENT_FLAGS_LEFT_MOUSE_BUTTON | | |
31 mojo::EVENT_FLAGS_MIDDLE_MOUSE_BUTTON | | |
32 mojo::EVENT_FLAGS_RIGHT_MOUSE_BUTTON)); | |
33 } | |
34 | |
35 } // namespace | |
36 | |
37 MoveLoop::~MoveLoop() { | |
38 if (target_) | |
39 target_->RemoveObserver(this); | |
40 } | |
41 | |
42 // static | |
43 scoped_ptr<MoveLoop> MoveLoop::Create(ServerWindow* target, | |
44 const mojo::Event& event) { | |
45 DCHECK(event.action == mojo::EVENT_TYPE_POINTER_DOWN); | |
46 const gfx::Point location(EventLocationToPoint(event)); | |
47 if (!target->parent() || !target->parent()->is_draggable_window_container() || | |
48 !gfx::Rect(target->bounds().size()).Contains(location) || | |
49 target->client_area().Contains(location)) { | |
50 return nullptr; | |
51 } | |
52 | |
53 // Start a move on left mouse, or any other type of pointer. | |
54 if (event.pointer_data->kind == mojo::POINTER_KIND_MOUSE && | |
55 MouseOnlyEventFlags(event.flags) != mojo::EVENT_FLAGS_LEFT_MOUSE_BUTTON) { | |
56 return nullptr; | |
57 } | |
58 | |
59 return make_scoped_ptr(new MoveLoop(target, event)); | |
60 } | |
61 | |
62 MoveLoop::MoveResult MoveLoop::Move(const mojo::Event& event) { | |
63 switch (event.action) { | |
64 case mojo::EVENT_TYPE_POINTER_CANCEL: | |
65 if (event.pointer_data->pointer_id == pointer_id_) { | |
66 if (target_) | |
67 Revert(); | |
68 return MoveResult::DONE; | |
69 } | |
70 return MoveResult::CONTINUE; | |
71 | |
72 case mojo::EVENT_TYPE_POINTER_MOVE: | |
73 if (target_ && event.pointer_data->pointer_id == pointer_id_) | |
74 MoveImpl(event); | |
75 return MoveResult::CONTINUE; | |
76 | |
77 case mojo::EVENT_TYPE_POINTER_UP: | |
78 if (event.pointer_data->pointer_id == pointer_id_) { | |
79 // TODO(sky): need to support changed_flags. | |
80 if (target_) | |
81 MoveImpl(event); | |
82 return MoveResult::DONE; | |
83 } | |
84 return MoveResult::CONTINUE; | |
85 | |
86 default: | |
87 break; | |
88 } | |
89 | |
90 return MoveResult::CONTINUE; | |
91 } | |
92 | |
93 MoveLoop::MoveLoop(ServerWindow* target, const mojo::Event& event) | |
94 : target_(target), | |
95 pointer_id_(event.pointer_data->pointer_id), | |
96 initial_event_screen_location_(EventScreenLocationToPoint(event)), | |
97 initial_window_bounds_(target->bounds()), | |
98 changing_bounds_(false) { | |
99 target->AddObserver(this); | |
100 } | |
101 | |
102 void MoveLoop::MoveImpl(const mojo::Event& event) { | |
103 const gfx::Vector2d delta = | |
104 EventScreenLocationToPoint(event) - initial_event_screen_location_; | |
105 const gfx::Rect new_bounds(initial_window_bounds_.origin() + delta, | |
106 initial_window_bounds_.size()); | |
107 base::AutoReset<bool> resetter(&changing_bounds_, true); | |
108 target_->SetBounds(new_bounds); | |
109 } | |
110 | |
111 void MoveLoop::Cancel() { | |
112 target_->RemoveObserver(this); | |
113 target_ = nullptr; | |
114 } | |
115 | |
116 void MoveLoop::Revert() { | |
117 base::AutoReset<bool> resetter(&changing_bounds_, true); | |
118 target_->SetBounds(initial_window_bounds_); | |
119 } | |
120 | |
121 void MoveLoop::OnWindowHierarchyChanged(ServerWindow* window, | |
122 ServerWindow* new_parent, | |
123 ServerWindow* old_parent) { | |
124 DCHECK_EQ(window, target_); | |
125 Cancel(); | |
126 } | |
127 | |
128 void MoveLoop::OnWindowBoundsChanged(ServerWindow* window, | |
129 const gfx::Rect& old_bounds, | |
130 const gfx::Rect& new_bounds) { | |
131 DCHECK_EQ(window, target_); | |
132 if (!changing_bounds_) | |
133 Cancel(); | |
134 } | |
135 | |
136 void MoveLoop::OnWindowVisibilityChanged(ServerWindow* window) { | |
137 DCHECK_EQ(window, target_); | |
138 Cancel(); | |
139 } | |
140 | |
141 } // namespace ws | |
142 } // namespace mus | |
OLD | NEW |