| // Copyright 2016 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "mash/simple_wm/move_event_handler.h" |
| |
| #include "mash/simple_wm/move_loop.h" |
| #include "services/ui/public/interfaces/cursor.mojom.h" |
| #include "ui/aura/mus/window_port_mus.h" |
| #include "ui/aura/window.h" |
| #include "ui/aura/window_delegate.h" |
| #include "ui/base/hit_test.h" |
| #include "ui/events/event.h" |
| |
| namespace simple_wm { |
| namespace { |
| |
| ui::mojom::Cursor CursorForWindowComponent(int window_component) { |
| switch (window_component) { |
| case HTBOTTOM: |
| return ui::mojom::Cursor::SOUTH_RESIZE; |
| case HTBOTTOMLEFT: |
| return ui::mojom::Cursor::SOUTH_WEST_RESIZE; |
| case HTBOTTOMRIGHT: |
| return ui::mojom::Cursor::SOUTH_EAST_RESIZE; |
| case HTLEFT: |
| return ui::mojom::Cursor::WEST_RESIZE; |
| case HTRIGHT: |
| return ui::mojom::Cursor::EAST_RESIZE; |
| case HTTOP: |
| return ui::mojom::Cursor::NORTH_RESIZE; |
| case HTTOPLEFT: |
| return ui::mojom::Cursor::NORTH_WEST_RESIZE; |
| case HTTOPRIGHT: |
| return ui::mojom::Cursor::NORTH_EAST_RESIZE; |
| default: |
| return ui::mojom::Cursor::CURSOR_NULL; |
| } |
| } |
| |
| } // namespace |
| |
| MoveEventHandler::MoveEventHandler(aura::Window* window) |
| : window_(window) { |
| window_->AddObserver(this); |
| window_->AddPreTargetHandler(this); |
| } |
| |
| MoveEventHandler::~MoveEventHandler() { |
| Detach(); |
| } |
| |
| void MoveEventHandler::ProcessLocatedEvent(ui::LocatedEvent* event) { |
| const bool had_move_loop = move_loop_.get() != nullptr; |
| DCHECK(event->IsMouseEvent() || event->IsTouchEvent()); |
| |
| // This event handler can receive mouse events like ET_MOUSE_CAPTURE_CHANGED |
| // that cannot be converted to PointerEvents. Ignore them because they aren't |
| // needed for move handling. |
| if (!ui::PointerEvent::CanConvertFrom(*event)) |
| return; |
| |
| // TODO(moshayedi): no need for this once MoveEventHandler directly receives |
| // pointer events. |
| std::unique_ptr<ui::PointerEvent> pointer_event; |
| if (event->IsMouseEvent()) |
| pointer_event.reset(new ui::PointerEvent(*event->AsMouseEvent())); |
| else |
| pointer_event.reset(new ui::PointerEvent(*event->AsTouchEvent())); |
| |
| if (move_loop_) { |
| if (move_loop_->Move(*pointer_event.get()) == MoveLoop::DONE) |
| move_loop_.reset(); |
| } else if (pointer_event->type() == ui::ET_POINTER_DOWN) { |
| const int ht_location = |
| GetNonClientComponentForEvent(pointer_event.get()); |
| if (ht_location != HTNOWHERE) |
| move_loop_ = MoveLoop::Create(window_, ht_location, *pointer_event.get()); |
| } else if (pointer_event->type() == ui::ET_POINTER_MOVED) { |
| const int ht_location = GetNonClientComponentForEvent(pointer_event.get()); |
| aura::WindowPortMus::Get(window_)->SetPredefinedCursor( |
| CursorForWindowComponent(ht_location)); |
| } |
| if (had_move_loop || move_loop_) |
| event->SetHandled(); |
| } |
| |
| int MoveEventHandler::GetNonClientComponentForEvent( |
| const ui::LocatedEvent* event) { |
| return window_->delegate()->GetNonClientComponent(event->location()); |
| } |
| |
| void MoveEventHandler::Detach() { |
| window_->RemoveObserver(this); |
| window_->RemovePreTargetHandler(this); |
| window_ = nullptr; |
| } |
| |
| void MoveEventHandler::OnMouseEvent(ui::MouseEvent* event) { |
| ProcessLocatedEvent(event); |
| } |
| |
| void MoveEventHandler::OnTouchEvent(ui::TouchEvent* event) { |
| ProcessLocatedEvent(event); |
| } |
| |
| void MoveEventHandler::OnCancelMode(ui::CancelModeEvent* event) { |
| if (!move_loop_) |
| return; |
| |
| move_loop_->Revert(); |
| move_loop_.reset(); |
| event->SetHandled(); |
| } |
| |
| void MoveEventHandler::OnWindowDestroying(aura::Window* window) { |
| DCHECK_EQ(window_, window); |
| Detach(); |
| } |
| |
| } // namespace simple_wm |