From 65e6fd1fade972a7a73ea37c0efa2973da9d08a7 Mon Sep 17 00:00:00 2001 From: Philip Trettner <Philip.Trettner@rwth-aachen.de> Date: Tue, 15 Aug 2017 12:29:03 +0200 Subject: [PATCH] Added double/multi click support --- glfw/glow-extras/glfw/GlfwApp.cc | 129 ++++++++++++++++++++----------- glfw/glow-extras/glfw/GlfwApp.hh | 17 +++- 2 files changed, 99 insertions(+), 47 deletions(-) diff --git a/glfw/glow-extras/glfw/GlfwApp.cc b/glfw/glow-extras/glfw/GlfwApp.cc index 0a92b76..2f2b85a 100644 --- a/glfw/glow-extras/glfw/GlfwApp.cc +++ b/glfw/glow-extras/glfw/GlfwApp.cc @@ -94,11 +94,16 @@ void GlfwApp::render(float elapsedSeconds) { if (mUseDefaultRendering) { - mPipeline->render([this, elapsedSeconds](const pipeline::RenderPass &pass) { renderPass(pass, elapsedSeconds); }); + mPipeline->render([this, elapsedSeconds](const pipeline::RenderPass &pass) + { + renderPass(pass, elapsedSeconds); + }); } } -void GlfwApp::renderPass(const pipeline::RenderPass &pass, float elapsedSeconds) {} +void GlfwApp::renderPass(const pipeline::RenderPass &pass, float elapsedSeconds) +{ +} void GlfwApp::onResize(int w, int h) { @@ -109,7 +114,9 @@ void GlfwApp::onResize(int w, int h) } } -void GlfwApp::onClose() {} +void GlfwApp::onClose() +{ +} bool GlfwApp::onKey(int key, int scancode, int action, int mods) { @@ -185,7 +192,7 @@ bool GlfwApp::onMousePosition(double x, double y) return false; } -bool GlfwApp::onMouseButton(double x, double y, int button, int action, int mods) +bool GlfwApp::onMouseButton(double x, double y, int button, int action, int mods, int clickCount) { if (button == GLFW_MOUSE_BUTTON_LEFT && action == GLFW_RELEASE) mMouseLeft = false; @@ -200,6 +207,9 @@ bool GlfwApp::onMouseButton(double x, double y, int button, int action, int mods if (button == GLFW_MOUSE_BUTTON_RIGHT && action == GLFW_PRESS) mMouseRight = true; + if (button == GLFW_MOUSE_BUTTON_MIDDLE && action == GLFW_PRESS && clickCount > 1) + onResetView(); // reset view + return false; } @@ -250,9 +260,28 @@ bool GlfwApp::onFileDrop(const std::vector<std::string> &files) void GlfwApp::onResetView() { + mCamera->setPosition(-mCamera->getForwardDirection() * mCamera->getLookAtDistance()); mCamera->setTarget({0, 0, 0}, {0, 1, 0}); } +void GlfwApp::internalOnMouseButton(double x, double y, int button, int action, int mods) +{ + // check double click + if (distance(mClickPos, glm::vec2(x, y)) > 5) // too far + mClickCount = 0; + if (mClickTimer.getTimeDiffInSecondsD() > mDoubleClickTime) // too slow + mClickCount = 0; + if (mClickButton != button) // wrong button + mClickCount = 0; + + mClickTimer.restart(); + mClickButton = button; + mClickPos = {x, y}; + mClickCount++; + + onMouseButton(x, y, button, action, mods, mClickCount); +} + static std::string thousandSep(size_t val) { auto s = std::to_string(val); @@ -314,46 +343,58 @@ int GlfwApp::run(int argc, char *argv[]) // input callbacks { - glfwSetKeyCallback(mWindow, [](GLFWwindow *win, int key, int scancode, int action, int mods) { - currApp->onKey(key, scancode, action, mods); - }); - glfwSetCharModsCallback( - mWindow, [](GLFWwindow *win, unsigned int codepoint, int mods) { currApp->onChar(codepoint, mods); }); - glfwSetMouseButtonCallback(mWindow, [](GLFWwindow *win, int button, int action, int mods) { - currApp->onMouseButton(currApp->mMouseX, currApp->mMouseY, button, action, mods); - }); - glfwSetCursorEnterCallback(mWindow, [](GLFWwindow *win, int entered) { - if (entered) - currApp->onMouseEnter(); - else - currApp->onMouseExit(); - }); - - glfwSetCursorPosCallback(mWindow, [](GLFWwindow *win, double x, double y) { - currApp->mMouseX = x; - currApp->mMouseY = y; - currApp->onMousePosition(x, y); - }); - glfwSetScrollCallback(mWindow, [](GLFWwindow *win, double sx, double sy) { currApp->onMouseScroll(sx, sy); }); - glfwSetFramebufferSizeCallback(mWindow, [](GLFWwindow *win, int w, int h) { - currApp->mWindowWidth = w; - currApp->mWindowHeight = h; - - currApp->onResize(w, h); - TwWindowSize(w, h); - }); - glfwSetWindowFocusCallback(mWindow, [](GLFWwindow *win, int focused) { - if (focused) - currApp->onFocusGain(); - else - currApp->onFocusLost(); - }); - glfwSetDropCallback(mWindow, [](GLFWwindow *win, int count, const char **paths) { - std::vector<std::string> files; - for (auto i = 0; i < count; ++i) - files.push_back(paths[i]); - currApp->onFileDrop(files); - }); + glfwSetKeyCallback(mWindow, [](GLFWwindow *win, int key, int scancode, int action, int mods) + { + currApp->onKey(key, scancode, action, mods); + }); + glfwSetCharModsCallback(mWindow, [](GLFWwindow *win, unsigned int codepoint, int mods) + { + currApp->onChar(codepoint, mods); + }); + glfwSetMouseButtonCallback(mWindow, [](GLFWwindow *win, int button, int action, int mods) + { + currApp->internalOnMouseButton(currApp->mMouseX, currApp->mMouseY, button, action, mods); + }); + glfwSetCursorEnterCallback(mWindow, [](GLFWwindow *win, int entered) + { + if (entered) + currApp->onMouseEnter(); + else + currApp->onMouseExit(); + }); + + glfwSetCursorPosCallback(mWindow, [](GLFWwindow *win, double x, double y) + { + currApp->mMouseX = x; + currApp->mMouseY = y; + currApp->onMousePosition(x, y); + }); + glfwSetScrollCallback(mWindow, [](GLFWwindow *win, double sx, double sy) + { + currApp->onMouseScroll(sx, sy); + }); + glfwSetFramebufferSizeCallback(mWindow, [](GLFWwindow *win, int w, int h) + { + currApp->mWindowWidth = w; + currApp->mWindowHeight = h; + + currApp->onResize(w, h); + TwWindowSize(w, h); + }); + glfwSetWindowFocusCallback(mWindow, [](GLFWwindow *win, int focused) + { + if (focused) + currApp->onFocusGain(); + else + currApp->onFocusLost(); + }); + glfwSetDropCallback(mWindow, [](GLFWwindow *win, int count, const char **paths) + { + std::vector<std::string> files; + for (auto i = 0; i < count; ++i) + files.push_back(paths[i]); + currApp->onFileDrop(files); + }); } // init app diff --git a/glfw/glow-extras/glfw/GlfwApp.hh b/glfw/glow-extras/glfw/GlfwApp.hh index c63aa25..b6c1bdd 100644 --- a/glfw/glow-extras/glfw/GlfwApp.hh +++ b/glfw/glow-extras/glfw/GlfwApp.hh @@ -8,6 +8,8 @@ #include <glow/common/shared.hh> #include <glow/fwd.hh> +#include <glow-extras/timing/PerformanceTimer.hh> + struct GLFWwindow; struct CTwBar; typedef struct CTwBar TwBar; // structure CTwBar is not exposed. @@ -100,6 +102,12 @@ private: double mCurrentTime = 0.0; ///< current frame time (starts with 0) + double mDoubleClickTime = 0.35f; ///< max number of seconds for multi clicks + int mClickCount = 0; ///< current click count + int mClickButton = -1; ///< last clicked button + glm::vec2 mClickPos; ///< last clicked position + timing::SystemTimer mClickTimer; ///< click timing + // Default graphics private: camera::SharedGenericCamera mCamera; ///< default camera @@ -136,6 +144,7 @@ public: GLOW_PROPERTY(OutputStatsInterval); GLOW_PROPERTY(QueryStats); GLOW_PROPERTY(UseDefaultRendering); + GLOW_PROPERTY(DoubleClickTime); float getCurrentTime() const { return mCurrentTime; } double getCurrentTimeD() const { return mCurrentTime; } GLOW_GETTER(Camera); @@ -151,7 +160,6 @@ public: glm::vec2 getMousePosition() const { return {mMouseX, mMouseY}; } GLFWwindow* window() const { return mWindow; } TwBar* tweakbar() const { return mTweakbar; } - public: /// sets the current clipboard content void setClipboardString(std::string const& s) const; @@ -178,8 +186,8 @@ protected: virtual bool onChar(unsigned int codepoint, int mods); /// Called whenever the mouse position changes virtual bool onMousePosition(double x, double y); - /// Called whenever a mouse button is pressed - virtual bool onMouseButton(double x, double y, int button, int action, int mods); + /// Called whenever a mouse button is pressed (clickCount is 1 for single clicks, 2 for double, 3+ for multi) + virtual bool onMouseButton(double x, double y, int button, int action, int mods, int clickCount); /// Called whenever the mouse is scrolled virtual bool onMouseScroll(double sx, double sy); /// Called whenever the mouse enters the window @@ -196,6 +204,9 @@ protected: /// Called when view should be reset virtual void onResetView(); +private: + void internalOnMouseButton(double x, double y, int button, int action, int mods); + public: /// Initializes GLFW and GLOW, and runs until window is closed int run(int argc, char* argv[]); -- GitLab