From ce6de4261eca90b23a4b63bda57646b8ae2bbfe8 Mon Sep 17 00:00:00 2001 From: Manuel Martin Date: Fri, 10 Apr 2020 01:43:50 +0200 Subject: [PATCH] Support for dragging outside the widget bounds (#2745) * Support for scrolling outside the widget bounds * Resize fix --- app/src/main/cpp/BrowserWorld.cpp | 60 +++++++++++++++++++------------ app/src/main/cpp/Cylinder.cpp | 6 ++-- app/src/main/cpp/Widget.cpp | 6 ++-- app/src/main/cpp/Widget.h | 2 +- 4 files changed, 45 insertions(+), 29 deletions(-) diff --git a/app/src/main/cpp/BrowserWorld.cpp b/app/src/main/cpp/BrowserWorld.cpp index 154507eed..801ff556e 100644 --- a/app/src/main/cpp/BrowserWorld.cpp +++ b/app/src/main/cpp/BrowserWorld.cpp @@ -391,26 +391,47 @@ BrowserWorld::State::UpdateControllers(bool& aRelayoutWidgets) { vrb::Vector hitPoint; vrb::Vector hitNormal; - for (const WidgetPtr& widget: widgets) { - if (resizingWidget && resizingWidget->IsResizingActive() && resizingWidget != widget) { - // Don't interact with other widgets when resizing gesture is active. - continue; - } - if (movingWidget && movingWidget->GetWidget() != widget) { - // Don't interact with other widgets when moving gesture is active. - continue; - } + const bool pressed = controller.buttonState & ControllerDelegate::BUTTON_TRIGGER || + controller.buttonState & ControllerDelegate::BUTTON_TOUCHPAD; + const bool wasPressed = controller.lastButtonState & ControllerDelegate::BUTTON_TRIGGER || + controller.lastButtonState & ControllerDelegate::BUTTON_TOUCHPAD; + + bool isResizing = resizingWidget && resizingWidget->IsResizingActive(); + bool isDragging = pressed && wasPressed && controller.widget && !isResizing; + if (isDragging) { + WidgetPtr widget = GetWidget(controller.widget); vrb::Vector result; vrb::Vector normal; float distance = 0.0f; bool isInWidget = false; - const bool clamp = !widget->IsResizing() && !movingWidget; - if (widget->TestControllerIntersection(start, direction, result, normal, clamp, isInWidget, distance)) { - if (isInWidget && (distance < hitDistance)) { - hitWidget = widget; - hitDistance = distance; - hitPoint = result; - hitNormal = normal; + if (widget->TestControllerIntersection(start, direction, result, normal, false, isInWidget, distance)) { + hitWidget = widget; + hitPoint = result; + hitNormal = normal; + } + + } else { + for (const WidgetPtr& widget: widgets) { + if (isResizing && resizingWidget != widget) { + // Don't interact with other widgets when resizing gesture is active. + continue; + } + if (movingWidget && movingWidget->GetWidget() != widget) { + // Don't interact with other widgets when moving gesture is active. + continue; + } + vrb::Vector result; + vrb::Vector normal; + float distance = 0.0f; + bool isInWidget = false; + const bool clamp = !widget->IsResizing() && !movingWidget; + if (widget->TestControllerIntersection(start, direction, result, normal, clamp, isInWidget, distance)) { + if (isInWidget && (distance < hitDistance)) { + hitWidget = widget; + hitDistance = distance; + hitPoint = result; + hitNormal = normal; + } } } } @@ -432,11 +453,6 @@ BrowserWorld::State::UpdateControllers(bool& aRelayoutWidgets) { } } - const bool pressed = controller.buttonState & ControllerDelegate::BUTTON_TRIGGER || - controller.buttonState & ControllerDelegate::BUTTON_TOUCHPAD; - const bool wasPressed = controller.lastButtonState & ControllerDelegate::BUTTON_TRIGGER || - controller.lastButtonState & ControllerDelegate::BUTTON_TOUCHPAD; - if (movingWidget && movingWidget->IsMoving(controller.index)) { if (!pressed && wasPressed) { movingWidget->EndMoving(); @@ -468,7 +484,7 @@ BrowserWorld::State::UpdateControllers(bool& aRelayoutWidgets) { } } else if (hitWidget) { float theX = 0.0f, theY = 0.0f; - hitWidget->ConvertToWidgetCoordinates(hitPoint, theX, theY); + hitWidget->ConvertToWidgetCoordinates(hitPoint, theX, theY, !isDragging); const uint32_t handle = hitWidget->GetHandle(); if (!pressed && wasPressed) { controller.inDeadZone = true; diff --git a/app/src/main/cpp/Cylinder.cpp b/app/src/main/cpp/Cylinder.cpp index ac0d05765..a20ac6bd1 100644 --- a/app/src/main/cpp/Cylinder.cpp +++ b/app/src/main/cpp/Cylinder.cpp @@ -482,10 +482,10 @@ Cylinder::ConvertToQuadCoordinates(const vrb::Vector& point, float& aX, float& a if (ratioX < 0.0f) { ratioX = 0.0f; } - - aX = ratioX * m.textureWidth; - aY = ratioY * m.textureHeight; } + + aX = ratioX * m.textureWidth; + aY = ratioY * m.textureHeight; } void diff --git a/app/src/main/cpp/Widget.cpp b/app/src/main/cpp/Widget.cpp index 46efad20b..f9a51b054 100644 --- a/app/src/main/cpp/Widget.cpp +++ b/app/src/main/cpp/Widget.cpp @@ -338,12 +338,12 @@ Widget::TestControllerIntersection(const vrb::Vector& aStartPoint, const vrb::Ve } void -Widget::ConvertToWidgetCoordinates(const vrb::Vector& point, float& aX, float& aY) const { +Widget::ConvertToWidgetCoordinates(const vrb::Vector& point, float& aX, float& aY, bool aClamp) const { bool clamp = !m.resizing; if (m.quad) { - m.quad->ConvertToQuadCoordinates(point, aX, aY, clamp); + m.quad->ConvertToQuadCoordinates(point, aX, aY, clamp && aClamp); } else { - m.cylinder->ConvertToQuadCoordinates(point, aX, aY, clamp); + m.cylinder->ConvertToQuadCoordinates(point, aX, aY, clamp && aClamp); } } diff --git a/app/src/main/cpp/Widget.h b/app/src/main/cpp/Widget.h index 6e79bd43c..17e2e0120 100644 --- a/app/src/main/cpp/Widget.h +++ b/app/src/main/cpp/Widget.h @@ -53,7 +53,7 @@ class Widget { void GetWorldSize(float& aWidth, float& aHeight) const; bool TestControllerIntersection(const vrb::Vector& aStartPoint, const vrb::Vector& aDirection, vrb::Vector& aResult, vrb::Vector& aNormal, const bool aClamp, bool& aIsInWidget, float& aDistance) const; - void ConvertToWidgetCoordinates(const vrb::Vector& aPoint, float& aX, float& aY) const; + void ConvertToWidgetCoordinates(const vrb::Vector& aPoint, float& aX, float& aY, bool aClamp = true) const; vrb::Vector ConvertToWorldCoordinates(const vrb::Vector& aLocalPoint) const; vrb::Vector ConvertToWorldCoordinates(const float aWidgetX, const float aWidgetY) const; const vrb::Matrix GetTransform() const;