diff --git a/modules/juce_gui_basics/components/juce_Component.cpp b/modules/juce_gui_basics/components/juce_Component.cpp index 299dbafb8c..f59f32a554 100644 --- a/modules/juce_gui_basics/components/juce_Component.cpp +++ b/modules/juce_gui_basics/components/juce_Component.cpp @@ -201,19 +201,41 @@ struct Component::ComponentHelpers } template - static PointOrRect unscaledScreenPosToScaled (PointOrRect pos) noexcept + static PointOrRect unscaledScreenPosToScaled (float scale, PointOrRect pos) noexcept { - const float scale = Desktop::getInstance().masterScaleFactor; return scale != 1.0f ? pos / scale : pos; } template - static PointOrRect scaledScreenPosToUnscaled (PointOrRect pos) noexcept + static PointOrRect scaledScreenPosToUnscaled (float scale, PointOrRect pos) noexcept { - const float scale = Desktop::getInstance().masterScaleFactor; return scale != 1.0f ? pos * scale : pos; } + template + static PointOrRect unscaledScreenPosToScaled (PointOrRect pos) noexcept + { + return unscaledScreenPosToScaled (Desktop::getInstance().getGlobalScaleFactor(), pos); + } + + template + static PointOrRect scaledScreenPosToUnscaled (PointOrRect pos) noexcept + { + return scaledScreenPosToUnscaled (Desktop::getInstance().getGlobalScaleFactor(), pos); + } + + template + static PointOrRect unscaledScreenPosToScaled (const Component& comp, PointOrRect pos) noexcept + { + return unscaledScreenPosToScaled (comp.getDesktopScaleFactor(), pos); + } + + template + static PointOrRect scaledScreenPosToUnscaled (const Component& comp, PointOrRect pos) noexcept + { + return scaledScreenPosToUnscaled (comp.getDesktopScaleFactor(), pos); + } + // converts an unscaled position within a peer to the local position within that peer's component template static PointOrRect rawPeerPositionToLocal (const Component& comp, PointOrRect pos) noexcept @@ -221,7 +243,7 @@ struct Component::ComponentHelpers if (comp.isTransformed()) pos = pos.transformedBy (comp.getTransform().inverted()); - return unscaledScreenPosToScaled (pos); + return unscaledScreenPosToScaled (comp, pos); } // converts a position within a peer's component to the unscaled position within the peer @@ -231,7 +253,7 @@ struct Component::ComponentHelpers if (comp.isTransformed()) pos = pos.transformedBy (comp.getTransform()); - return scaledScreenPosToUnscaled (pos); + return scaledScreenPosToUnscaled (comp, pos); } template @@ -243,7 +265,7 @@ struct Component::ComponentHelpers if (comp.isOnDesktop()) { if (ComponentPeer* peer = comp.getPeer()) - pointInParentSpace = unscaledScreenPosToScaled (peer->globalToLocal (scaledScreenPosToUnscaled (pointInParentSpace))); + pointInParentSpace = unscaledScreenPosToScaled (comp, peer->globalToLocal (scaledScreenPosToUnscaled (pointInParentSpace))); else jassertfalse; } @@ -261,7 +283,7 @@ struct Component::ComponentHelpers if (comp.isOnDesktop()) { if (ComponentPeer* peer = comp.getPeer()) - pointInLocalSpace = unscaledScreenPosToScaled (peer->localToGlobal (scaledScreenPosToUnscaled (pointInLocalSpace))); + pointInLocalSpace = unscaledScreenPosToScaled (peer->localToGlobal (scaledScreenPosToUnscaled (comp, pointInLocalSpace))); else jassertfalse; } @@ -697,6 +719,8 @@ void Component::userTriedToCloseWindow() void Component::minimisationStateChanged (bool) {} +float Component::getDesktopScaleFactor() const { return Desktop::getInstance().getGlobalScaleFactor(); } + //============================================================================== void Component::setOpaque (const bool shouldBeOpaque) { @@ -1830,7 +1854,8 @@ void Component::internalRepaintUnchecked (const Rectangle& area, const bool CHECK_MESSAGE_MANAGER_IS_LOCKED if (ComponentPeer* const peer = getPeer()) - peer->repaint (ComponentHelpers::scaledScreenPosToUnscaled (affineTransform != nullptr ? area.transformedBy (*affineTransform) + peer->repaint (ComponentHelpers::scaledScreenPosToUnscaled (*this, + affineTransform != nullptr ? area.transformedBy (*affineTransform) : area)); } else diff --git a/modules/juce_gui_basics/components/juce_Component.h b/modules/juce_gui_basics/components/juce_Component.h index 1962ffc0b3..7f81da3932 100644 --- a/modules/juce_gui_basics/components/juce_Component.h +++ b/modules/juce_gui_basics/components/juce_Component.h @@ -215,6 +215,15 @@ public: */ virtual void minimisationStateChanged (bool isNowMinimised); + /** Returns the default scale factor to use for this component when it is placed + on the desktop. + The default implementation of this method just returns the value from + Desktop::getGlobalScaleFactor(), but it can be overridden if a particular component + has different requirements. The method only used if this component is added + to the desktop - it has no effect for child components. + */ + virtual float getDesktopScaleFactor() const; + //============================================================================== /** Brings the component to the front of its siblings. @@ -1241,6 +1250,8 @@ public: */ static Component* JUCE_CALLTYPE getCurrentlyFocusedComponent() noexcept; + static void JUCE_CALLTYPE unfocusAllComponents(); + //============================================================================== /** Tries to move the keyboard focus to one of this component's siblings. @@ -2334,7 +2345,7 @@ private: // This is included here to cause an error if you use or overload it - it has been deprecated in // favour of contains (Point) - void contains (int, int); + void contains (int, int) JUCE_DELETED_FUNCTION; #endif protected: diff --git a/modules/juce_gui_basics/mouse/juce_MouseInputSource.cpp b/modules/juce_gui_basics/mouse/juce_MouseInputSource.cpp index 5725c382ce..cb16e2d612 100644 --- a/modules/juce_gui_basics/mouse/juce_MouseInputSource.cpp +++ b/modules/juce_gui_basics/mouse/juce_MouseInputSource.cpp @@ -62,17 +62,19 @@ public: if (ComponentPeer* const peer = comp.getPeer()) { pos = peer->globalToLocal (pos); - return comp.getLocalPoint (&peer->getComponent(), Component::ComponentHelpers::unscaledScreenPosToScaled (pos)); + Component& peerComp = peer->getComponent(); + return comp.getLocalPoint (&peerComp, Component::ComponentHelpers::unscaledScreenPosToScaled (peerComp, pos)); } - return comp.getLocalPoint (nullptr, Component::ComponentHelpers::unscaledScreenPosToScaled (pos)); + return comp.getLocalPoint (nullptr, Component::ComponentHelpers::unscaledScreenPosToScaled (comp, pos)); } Component* findComponentAt (Point screenPos) { if (ComponentPeer* const peer = getPeer()) { - Point relativePos (Component::ComponentHelpers::unscaledScreenPosToScaled (peer->globalToLocal (screenPos))); + Point relativePos (Component::ComponentHelpers::unscaledScreenPosToScaled (peer->getComponent(), + peer->globalToLocal (screenPos))); Component& comp = peer->getComponent(); // (the contains() call is needed to test for overlapping desktop windows) diff --git a/modules/juce_gui_basics/native/juce_win32_Windowing.cpp b/modules/juce_gui_basics/native/juce_win32_Windowing.cpp index d5d1d70e5a..19ecd05cb8 100644 --- a/modules/juce_gui_basics/native/juce_win32_Windowing.cpp +++ b/modules/juce_gui_basics/native/juce_win32_Windowing.cpp @@ -2097,18 +2097,18 @@ private: { if (isConstrainedNativeWindow()) { - Desktop& desktop = Desktop::getInstance(); - Rectangle pos (rectangleFromRECT (r) / desktop.getGlobalScaleFactor()); + const float scale = getComponent().getDesktopScaleFactor(); + Rectangle pos (rectangleFromRECT (r) / scale); const Rectangle current (windowBorder.addedTo (component.getBounds())); constrainer->checkBounds (pos, windowBorder.addedTo (component.getBounds()), - desktop.getDisplays().getTotalBounds (true), + Desktop::getInstance().getDisplays().getTotalBounds (true), wParam == WMSZ_TOP || wParam == WMSZ_TOPLEFT || wParam == WMSZ_TOPRIGHT, wParam == WMSZ_LEFT || wParam == WMSZ_TOPLEFT || wParam == WMSZ_BOTTOMLEFT, wParam == WMSZ_BOTTOM || wParam == WMSZ_BOTTOMLEFT || wParam == WMSZ_BOTTOMRIGHT, wParam == WMSZ_RIGHT || wParam == WMSZ_TOPRIGHT || wParam == WMSZ_BOTTOMRIGHT); - pos *= desktop.getGlobalScaleFactor(); + pos *= scale; r.left = pos.getX(); r.top = pos.getY(); r.right = pos.getRight(); @@ -2125,19 +2125,19 @@ private: if ((wp.flags & (SWP_NOMOVE | SWP_NOSIZE)) != (SWP_NOMOVE | SWP_NOSIZE) && ! Component::isMouseButtonDownAnywhere()) { - Desktop& desktop = Desktop::getInstance(); + const float scale = getComponent().getDesktopScaleFactor(); Rectangle pos (wp.x, wp.y, wp.cx, wp.cy); - pos /= desktop.getGlobalScaleFactor(); + pos /= scale; const Rectangle current (windowBorder.addedTo (component.getBounds())); constrainer->checkBounds (pos, current, - desktop.getDisplays().getTotalBounds (true), + Desktop::getInstance().getDisplays().getTotalBounds (true), pos.getY() != current.getY() && pos.getBottom() == current.getBottom(), pos.getX() != current.getX() && pos.getRight() == current.getRight(), pos.getY() == current.getY() && pos.getBottom() != current.getBottom(), pos.getX() == current.getX() && pos.getRight() != current.getRight()); - pos *= desktop.getGlobalScaleFactor(); + pos *= scale; wp.x = pos.getX(); wp.y = pos.getY(); wp.cx = pos.getWidth(); diff --git a/modules/juce_gui_basics/windows/juce_ComponentPeer.cpp b/modules/juce_gui_basics/windows/juce_ComponentPeer.cpp index 681599905e..b79162ad88 100644 --- a/modules/juce_gui_basics/windows/juce_ComponentPeer.cpp +++ b/modules/juce_gui_basics/windows/juce_ComponentPeer.cpp @@ -76,7 +76,7 @@ bool ComponentPeer::isValidPeer (const ComponentPeer* const peer) noexcept void ComponentPeer::updateBounds() { - setBounds (Component::ComponentHelpers::scaledScreenPosToUnscaled (component.getBoundsInParent()), false); + setBounds (Component::ComponentHelpers::scaledScreenPosToUnscaled (component, component.getBoundsInParent()), false); } //============================================================================== @@ -111,7 +111,7 @@ void ComponentPeer::handlePaint (LowLevelGraphicsContext& contextToPaintTo) if (component.isTransformed()) g.addTransform (component.getTransform()); - float masterScale = Desktop::getInstance().masterScaleFactor; + const float masterScale = component.getDesktopScaleFactor(); if (masterScale != 1.0f) g.addTransform (AffineTransform::scale (masterScale)); @@ -402,7 +402,7 @@ Rectangle ComponentPeer::globalToLocal (const Rectangle& screenPositio Rectangle ComponentPeer::getAreaCoveredBy (Component& subComponent) const { return Component::ComponentHelpers::scaledScreenPosToUnscaled - (component.getLocalArea (&subComponent, subComponent.getLocalBounds())); + (component, component.getLocalArea (&subComponent, subComponent.getLocalBounds())); } //============================================================================== diff --git a/modules/juce_gui_extra/native/juce_mac_CarbonViewWrapperComponent.h b/modules/juce_gui_extra/native/juce_mac_CarbonViewWrapperComponent.h index 76379eeef3..81b4ae5dd7 100644 --- a/modules/juce_gui_extra/native/juce_mac_CarbonViewWrapperComponent.h +++ b/modules/juce_gui_extra/native/juce_mac_CarbonViewWrapperComponent.h @@ -193,11 +193,14 @@ public: if (wrapperWindow != 0) { + jassert (getTopLevelComponent()->getDesktopScaleFactor() == 1.0f); + Rectangle screenBounds (getScreenBounds() * Desktop::getInstance().getGlobalScaleFactor()); + Rect wr; - wr.left = (short) getScreenX(); - wr.top = (short) getScreenY(); - wr.right = (short) (wr.left + getWidth()); - wr.bottom = (short) (wr.top + getHeight()); + wr.left = (short) screenBounds.getX(); + wr.top = (short) screenBounds.getY(); + wr.right = (short) screenBounds.getRight(); + wr.bottom = (short) screenBounds.getBottom(); SetWindowBounds (wrapperWindow, kWindowContentRgn, &wr);