From dfaf91821dc8c0653a668a0cff6e1296a218401b Mon Sep 17 00:00:00 2001 From: Adam Barth Date: Fri, 25 Mar 2016 10:54:40 -0700 Subject: [PATCH] Add support for mouse events The Material Gallery is now fully interactive. --- sky/services/pointer/pointer.mojom | 2 + sky/shell/platform/glfw/window_impl.cc | 76 +++++++++++++++++++++++++- sky/shell/platform/glfw/window_impl.h | 3 + 3 files changed, 80 insertions(+), 1 deletion(-) diff --git a/sky/services/pointer/pointer.mojom b/sky/services/pointer/pointer.mojom index 3ee49596c..d279a55ee 100644 --- a/sky/services/pointer/pointer.mojom +++ b/sky/services/pointer/pointer.mojom @@ -5,6 +5,8 @@ [DartPackage="sky_services"] module pointer; +// See https://github.com/flutter/engine/blob/master/sky/specs/pointer.md + enum PointerType { DOWN, UP, diff --git a/sky/shell/platform/glfw/window_impl.cc b/sky/shell/platform/glfw/window_impl.cc index 3d47a3997..9231de250 100644 --- a/sky/shell/platform/glfw/window_impl.cc +++ b/sky/shell/platform/glfw/window_impl.cc @@ -21,11 +21,20 @@ void OnWindowSizeChanged(GLFWwindow* window, int width, int height) { ToImpl(window)->UpdateViewportMetrics(width, height); } +void OnMouseButtonChanged(GLFWwindow* window, int button, int action, int mods) { + ToImpl(window)->DispatchMouseButtonEvent(button, action, mods); +} + +void OnCursorPosChanged(GLFWwindow* window, double x, double y) { + ToImpl(window)->DispatchMouseMoveEvent(x, y); +} + } // namespace WindowImpl::WindowImpl(GLFWwindow* window) : window_(window), - shell_view_(new ShellView(Shell::Shared())) { + shell_view_(new ShellView(Shell::Shared())), + buttons_(0) { glfwSetWindowUserPointer(window_, this); auto platform_view = static_cast(shell_view_->view()); @@ -38,6 +47,7 @@ WindowImpl::WindowImpl(GLFWwindow* window) UpdateViewportMetrics(width, height); glfwSetWindowSizeCallback(window_, OnWindowSizeChanged); + glfwSetMouseButtonCallback(window_, OnMouseButtonChanged); } WindowImpl::~WindowImpl() { @@ -61,5 +71,69 @@ void WindowImpl::UpdateViewportMetrics(int width, int height) { engine_->OnViewportMetricsChanged(metrics.Pass()); } +void WindowImpl::DispatchMouseButtonEvent(int button, int action, int mods) { + pointer::PointerType type; + if (action == GLFW_PRESS) { + if (!buttons_) { + type = pointer::PointerType::DOWN; + glfwSetCursorPosCallback(window_, OnCursorPosChanged); + } else { + type = pointer::PointerType::MOVE; + } + // GLFW's button order matches what we want: + // https://github.com/flutter/engine/blob/master/sky/specs/pointer.md + // http://www.glfw.org/docs/3.2/group__buttons.html + buttons_ |= 1 << button; + } else if (action == GLFW_RELEASE) { + buttons_ &= ~(1 << button); + if (!buttons_) { + type = pointer::PointerType::UP; + glfwSetCursorPosCallback(window_, nullptr); + } else { + type = pointer::PointerType::MOVE; + } + } else { + DLOG(INFO) << "Unknown mouse action: " << action; + return; + } + + double x = 0.f, y = 0.f; + glfwGetCursorPos(window_, &x, &y); + + base::TimeDelta time_stamp = base::TimeTicks::Now() - base::TimeTicks(); + + auto pointer_data = pointer::Pointer::New(); + pointer_data->time_stamp = time_stamp.InMicroseconds(); + pointer_data->type = type; + pointer_data->kind = pointer::PointerKind::MOUSE; + pointer_data->x = x; + pointer_data->y = y; + pointer_data->buttons = buttons_; + pointer_data->pressure = 1.0; + pointer_data->pressure_max = 1.0; + + auto pointer_packet = pointer::PointerPacket::New(); + pointer_packet->pointers.push_back(pointer_data.Pass()); + engine_->OnPointerPacket(pointer_packet.Pass()); +} + +void WindowImpl::DispatchMouseMoveEvent(double x, double y) { + base::TimeDelta time_stamp = base::TimeTicks::Now() - base::TimeTicks(); + + auto pointer_data = pointer::Pointer::New(); + pointer_data->time_stamp = time_stamp.InMicroseconds(); + pointer_data->type = pointer::PointerType::MOVE; + pointer_data->kind = pointer::PointerKind::MOUSE; + pointer_data->x = x; + pointer_data->y = y; + pointer_data->buttons = buttons_; + pointer_data->pressure = 1.0; + pointer_data->pressure_max = 1.0; + + auto pointer_packet = pointer::PointerPacket::New(); + pointer_packet->pointers.push_back(pointer_data.Pass()); + engine_->OnPointerPacket(pointer_packet.Pass()); +} + } // namespace shell } // namespace sky diff --git a/sky/shell/platform/glfw/window_impl.h b/sky/shell/platform/glfw/window_impl.h index efaad0cd9..7adebe10f 100644 --- a/sky/shell/platform/glfw/window_impl.h +++ b/sky/shell/platform/glfw/window_impl.h @@ -24,11 +24,14 @@ class WindowImpl { const std::string& bundle_path); void UpdateViewportMetrics(int width, int height); + void DispatchMouseButtonEvent(int button, int action, int mods); + void DispatchMouseMoveEvent(double x, double y); private: GLFWwindow* window_; std::unique_ptr shell_view_; sky::SkyEnginePtr engine_; + int buttons_; DISALLOW_COPY_AND_ASSIGN(WindowImpl); }; -- GitLab