From eb6e579f0a43b0000bb30cfd6151cea6a4a4338e Mon Sep 17 00:00:00 2001 From: reuk Date: Mon, 21 Feb 2022 18:18:17 +0000 Subject: [PATCH] ComponentPeer: Correctly scale drag and drop coordinates to account for global scale --- .../components/juce_Component.cpp | 12 ++++++++ .../mouse/juce_MouseInputSource.cpp | 30 ++++++------------- .../native/juce_mac_NSViewComponentPeer.mm | 23 +++++--------- .../native/juce_win32_Windowing.cpp | 5 ++-- .../native/x11/juce_linux_X11_DragAndDrop.cpp | 7 +++-- 5 files changed, 36 insertions(+), 41 deletions(-) diff --git a/modules/juce_gui_basics/components/juce_Component.cpp b/modules/juce_gui_basics/components/juce_Component.cpp index ecb0599f7a..691fbbaead 100644 --- a/modules/juce_gui_basics/components/juce_Component.cpp +++ b/modules/juce_gui_basics/components/juce_Component.cpp @@ -275,6 +275,18 @@ struct ScalingHelpers static Rectangle subtractPosition (Rectangle p, const Component& c) noexcept { return p - c.getPosition(); } static Point subtractPosition (Point p, const Component& c) noexcept { return p - c.getPosition().toFloat(); } static Rectangle subtractPosition (Rectangle p, const Component& c) noexcept { return p - c.getPosition().toFloat(); } + + static Point screenPosToLocalPos (Component& comp, Point pos) + { + if (auto* peer = comp.getPeer()) + { + pos = peer->globalToLocal (pos); + auto& peerComp = peer->getComponent(); + return comp.getLocalPoint (&peerComp, unscaledScreenPosToScaled (peerComp, pos)); + } + + return comp.getLocalPoint (nullptr, unscaledScreenPosToScaled (comp, pos)); + } }; static const char colourPropertyPrefix[] = "jcclr_"; diff --git a/modules/juce_gui_basics/mouse/juce_MouseInputSource.cpp b/modules/juce_gui_basics/mouse/juce_MouseInputSource.cpp index b76e9ea7b7..a8ed7b02bb 100644 --- a/modules/juce_gui_basics/mouse/juce_MouseInputSource.cpp +++ b/modules/juce_gui_basics/mouse/juce_MouseInputSource.cpp @@ -57,18 +57,6 @@ public: return lastPeer; } - static Point screenPosToLocalPos (Component& comp, Point pos) - { - if (auto* peer = comp.getPeer()) - { - pos = peer->globalToLocal (pos); - auto& peerComp = peer->getComponent(); - return comp.getLocalPoint (&peerComp, ScalingHelpers::unscaledScreenPosToScaled (peerComp, pos)); - } - - return comp.getLocalPoint (nullptr, ScalingHelpers::unscaledScreenPosToScaled (comp, pos)); - } - Component* findComponentAt (Point screenPos) { if (auto* peer = getPeer()) @@ -106,7 +94,7 @@ public: //============================================================================== #if JUCE_DUMP_MOUSE_EVENTS #define JUCE_MOUSE_EVENT_DBG(desc, screenPos) DBG ("Mouse " << desc << " #" << index \ - << ": " << screenPosToLocalPos (comp, screenPos).toString() \ + << ": " << ScalingHelpers::screenPosToLocalPos (comp, screenPos).toString() \ << " - Comp: " << String::toHexString ((pointer_sized_int) &comp)); #else #define JUCE_MOUSE_EVENT_DBG(desc, screenPos) @@ -115,26 +103,26 @@ public: void sendMouseEnter (Component& comp, const PointerState& pointerState, Time time) { JUCE_MOUSE_EVENT_DBG ("enter", pointerState.position) - comp.internalMouseEnter (MouseInputSource (this), screenPosToLocalPos (comp, pointerState.position), time); + comp.internalMouseEnter (MouseInputSource (this), ScalingHelpers::screenPosToLocalPos (comp, pointerState.position), time); } void sendMouseExit (Component& comp, const PointerState& pointerState, Time time) { JUCE_MOUSE_EVENT_DBG ("exit", pointerState.position) - comp.internalMouseExit (MouseInputSource (this), screenPosToLocalPos (comp, pointerState.position), time); + comp.internalMouseExit (MouseInputSource (this), ScalingHelpers::screenPosToLocalPos (comp, pointerState.position), time); } void sendMouseMove (Component& comp, const PointerState& pointerState, Time time) { JUCE_MOUSE_EVENT_DBG ("move", pointerState.position) - comp.internalMouseMove (MouseInputSource (this), screenPosToLocalPos (comp, pointerState.position), time); + comp.internalMouseMove (MouseInputSource (this), ScalingHelpers::screenPosToLocalPos (comp, pointerState.position), time); } void sendMouseDown (Component& comp, const PointerState& pointerState, Time time) { JUCE_MOUSE_EVENT_DBG ("down", pointerState.position) comp.internalMouseDown (MouseInputSource (this), - pointerState.withPosition (screenPosToLocalPos (comp, pointerState.position)), + pointerState.withPosition (ScalingHelpers::screenPosToLocalPos (comp, pointerState.position)), time); } @@ -142,7 +130,7 @@ public: { JUCE_MOUSE_EVENT_DBG ("drag", pointerState.position) comp.internalMouseDrag (MouseInputSource (this), - pointerState.withPosition (screenPosToLocalPos (comp, pointerState.position)), + pointerState.withPosition (ScalingHelpers::screenPosToLocalPos (comp, pointerState.position)), time); } @@ -150,7 +138,7 @@ public: { JUCE_MOUSE_EVENT_DBG ("up", pointerState.position) comp.internalMouseUp (MouseInputSource (this), - pointerState.withPosition (screenPosToLocalPos (comp, pointerState.position)), + pointerState.withPosition (ScalingHelpers::screenPosToLocalPos (comp, pointerState.position)), time, oldMods); } @@ -158,13 +146,13 @@ public: void sendMouseWheel (Component& comp, Point screenPos, Time time, const MouseWheelDetails& wheel) { JUCE_MOUSE_EVENT_DBG ("wheel", screenPos) - comp.internalMouseWheel (MouseInputSource (this), screenPosToLocalPos (comp, screenPos), time, wheel); + comp.internalMouseWheel (MouseInputSource (this), ScalingHelpers::screenPosToLocalPos (comp, screenPos), time, wheel); } void sendMagnifyGesture (Component& comp, Point screenPos, Time time, float amount) { JUCE_MOUSE_EVENT_DBG ("magnify", screenPos) - comp.internalMagnifyGesture (MouseInputSource (this), screenPosToLocalPos (comp, screenPos), time, amount); + comp.internalMagnifyGesture (MouseInputSource (this), ScalingHelpers::screenPosToLocalPos (comp, screenPos), time, amount); } //============================================================================== diff --git a/modules/juce_gui_basics/native/juce_mac_NSViewComponentPeer.mm b/modules/juce_gui_basics/native/juce_mac_NSViewComponentPeer.mm index d8f4ea4ba8..902e8f13a1 100644 --- a/modules/juce_gui_basics/native/juce_mac_NSViewComponentPeer.mm +++ b/modules/juce_gui_basics/native/juce_mac_NSViewComponentPeer.mm @@ -1458,7 +1458,7 @@ public: return [NSArray arrayWithObjects: type, (NSString*) kPasteboardTypeFileURLPromise, NSPasteboardTypeString, nil]; } - BOOL sendDragCallback (const int type, id sender) + BOOL sendDragCallback (bool (ComponentPeer::* callback) (const DragInfo&), id sender) { NSPasteboard* pasteboard = [sender draggingPasteboard]; NSString* contentType = [pasteboard availableTypeFromArray: getSupportedDragTypes()]; @@ -1466,9 +1466,10 @@ public: if (contentType == nil) return false; - NSPoint p = [view convertPoint: [sender draggingLocation] fromView: nil]; + const auto p = localToGlobal (convertToPointFloat ([view convertPoint: [sender draggingLocation] fromView: nil])); + ComponentPeer::DragInfo dragInfo; - dragInfo.position.setXY ((int) p.x, (int) p.y); + dragInfo.position = ScalingHelpers::screenPosToLocalPos (component, p).roundToInt(); if (contentType == NSPasteboardTypeString) dragInfo.text = nsStringToJuce ([pasteboard stringForType: NSPasteboardTypeString]); @@ -1476,15 +1477,7 @@ public: dragInfo.files = getDroppedFiles (pasteboard, contentType); if (! dragInfo.isEmpty()) - { - switch (type) - { - case 0: return handleDragMove (dragInfo); - case 1: return handleDragExit (dragInfo); - case 2: return handleDragDrop (dragInfo); - default: jassertfalse; break; - } - } + return (this->*callback) (dragInfo); return false; } @@ -2217,7 +2210,7 @@ private: static NSDragOperation draggingUpdated (id self, SEL, id sender) { if (auto* owner = getOwner (self)) - if (owner->sendDragCallback (0, sender)) + if (owner->sendDragCallback (&NSViewComponentPeer::handleDragMove, sender)) return NSDragOperationGeneric; return NSDragOperationNone; @@ -2230,7 +2223,7 @@ private: static void draggingExited (id self, SEL, id sender) { - callOnOwner (self, &NSViewComponentPeer::sendDragCallback, 1, sender); + callOnOwner (self, &NSViewComponentPeer::sendDragCallback, &NSViewComponentPeer::handleDragExit, sender); } static BOOL prepareForDragOperation (id, SEL, id) @@ -2241,7 +2234,7 @@ private: static BOOL performDragOperation (id self, SEL, id sender) { auto* owner = getOwner (self); - return owner != nullptr && owner->sendDragCallback (2, sender); + return owner != nullptr && owner->sendDragCallback (&NSViewComponentPeer::handleDragDrop, sender); } static void concludeDragOperation (id, SEL, id) {} diff --git a/modules/juce_gui_basics/native/juce_win32_Windowing.cpp b/modules/juce_gui_basics/native/juce_win32_Windowing.cpp index bdac3da7d8..4ffc09d9a8 100644 --- a/modules/juce_gui_basics/native/juce_win32_Windowing.cpp +++ b/modules/juce_gui_basics/native/juce_win32_Windowing.cpp @@ -2000,8 +2000,9 @@ public: private: Point getMousePos (POINTL mousePos) const { - return peer.getComponent().getLocalPoint (nullptr, convertPhysicalScreenPointToLogical (pointFromPOINT ({ mousePos.x, mousePos.y }), - (HWND) peer.getNativeHandle()).toFloat()); + const auto originalPos = pointFromPOINT ({ mousePos.x, mousePos.y }); + const auto logicalPos = convertPhysicalScreenPointToLogical (originalPos, peer.hwnd); + return ScalingHelpers::screenPosToLocalPos (peer.component, logicalPos.toFloat()); } struct DroppedData diff --git a/modules/juce_gui_basics/native/x11/juce_linux_X11_DragAndDrop.cpp b/modules/juce_gui_basics/native/x11/juce_linux_X11_DragAndDrop.cpp index 3a5c9f27af..3e24e1f26c 100644 --- a/modules/juce_gui_basics/native/x11/juce_linux_X11_DragAndDrop.cpp +++ b/modules/juce_gui_basics/native/x11/juce_linux_X11_DragAndDrop.cpp @@ -156,9 +156,10 @@ public: if (windowH == 0) windowH = (::Window) peer->getNativeHandle(); - auto dropPos = Desktop::getInstance().getDisplays().physicalToLogical (Point ((int) clientMsg.data.l[2] >> 16, - (int) clientMsg.data.l[2] & 0xffff)); - dropPos -= peer->getBounds().getPosition(); + const auto displays = Desktop::getInstance().getDisplays(); + const auto logicalPos = displays.physicalToLogical (Point ((int) clientMsg.data.l[2] >> 16, + (int) clientMsg.data.l[2] & 0xffff)); + const auto dropPos = ScalingHelpers::screenPosToLocalPos (peer->getComponent(), logicalPos.toFloat()).roundToInt(); const auto& atoms = getAtoms();