From 1c2abc80d77cf8c92877fb6d7c0f76285ef3cab3 Mon Sep 17 00:00:00 2001 From: reuk Date: Mon, 24 May 2021 14:50:04 +0100 Subject: [PATCH] Component: Ensure getScreenPosition result is in terms of the logical coordinate space of the screen Previously, getScreenPosition would return a result in the component's coordinate space if it was called on a component that was not directly or indirectly on the desktop. This behaviour is surprising and difficult to program around. This change should ensure that the result is always in the screen's coordinate space. --- .../components/juce_Component.cpp | 53 ++++++++++--------- 1 file changed, 27 insertions(+), 26 deletions(-) diff --git a/modules/juce_gui_basics/components/juce_Component.cpp b/modules/juce_gui_basics/components/juce_Component.cpp index 176c13d09d..250df2064b 100644 --- a/modules/juce_gui_basics/components/juce_Component.cpp +++ b/modules/juce_gui_basics/components/juce_Component.cpp @@ -329,47 +329,48 @@ struct Component::ComponentHelpers } template - static PointOrRect convertFromParentSpace (const Component& comp, PointOrRect pointInParentSpace) + static PointOrRect convertFromParentSpace (const Component& comp, const PointOrRect pointInParentSpace) { - if (comp.affineTransform != nullptr) - pointInParentSpace = pointInParentSpace.transformedBy (comp.affineTransform->inverted()); + const auto transformed = comp.affineTransform != nullptr ? pointInParentSpace.transformedBy (comp.affineTransform->inverted()) + : pointInParentSpace; if (comp.isOnDesktop()) { if (auto* peer = comp.getPeer()) - pointInParentSpace = ScalingHelpers::unscaledScreenPosToScaled - (comp, peer->globalToLocal (ScalingHelpers::scaledScreenPosToUnscaled (pointInParentSpace))); - else - jassertfalse; - } - else - { - pointInParentSpace = ScalingHelpers::subtractPosition (pointInParentSpace, comp); + return ScalingHelpers::unscaledScreenPosToScaled (comp, peer->globalToLocal (ScalingHelpers::scaledScreenPosToUnscaled (transformed))); + + jassertfalse; + return transformed; } - return pointInParentSpace; + if (comp.getParentComponent() == nullptr) + return ScalingHelpers::subtractPosition (ScalingHelpers::unscaledScreenPosToScaled (comp, ScalingHelpers::scaledScreenPosToUnscaled (transformed)), comp); + + return ScalingHelpers::subtractPosition (transformed, comp); } template - static PointOrRect convertToParentSpace (const Component& comp, PointOrRect pointInLocalSpace) + static PointOrRect convertToParentSpace (const Component& comp, const PointOrRect pointInLocalSpace) { - if (comp.isOnDesktop()) + const auto preTransform = [&] { - if (auto* peer = comp.getPeer()) - pointInLocalSpace = ScalingHelpers::unscaledScreenPosToScaled - (peer->localToGlobal (ScalingHelpers::scaledScreenPosToUnscaled (comp, pointInLocalSpace))); - else + if (comp.isOnDesktop()) + { + if (auto* peer = comp.getPeer()) + return ScalingHelpers::unscaledScreenPosToScaled (peer->localToGlobal (ScalingHelpers::scaledScreenPosToUnscaled (comp, pointInLocalSpace))); + jassertfalse; - } - else - { - pointInLocalSpace = ScalingHelpers::addPosition (pointInLocalSpace, comp); - } + return pointInLocalSpace; + } + + if (comp.getParentComponent() == nullptr) + return ScalingHelpers::unscaledScreenPosToScaled (ScalingHelpers::scaledScreenPosToUnscaled (comp, ScalingHelpers::addPosition (pointInLocalSpace, comp))); - if (comp.affineTransform != nullptr) - pointInLocalSpace = pointInLocalSpace.transformedBy (*comp.affineTransform); + return ScalingHelpers::addPosition (pointInLocalSpace, comp); + }(); - return pointInLocalSpace; + return comp.affineTransform != nullptr ? preTransform.transformedBy (*comp.affineTransform) + : preTransform; } template