blob: b2268e0e88a65f7782aad6ff2d43fc12b9d7931e [file] [log] [blame]
// 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