| 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 |