| @@ -201,19 +201,41 @@ struct Component::ComponentHelpers | |||||
| } | } | ||||
| template <typename PointOrRect> | template <typename PointOrRect> | ||||
| 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; | return scale != 1.0f ? pos / scale : pos; | ||||
| } | } | ||||
| template <typename PointOrRect> | template <typename PointOrRect> | ||||
| 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; | return scale != 1.0f ? pos * scale : pos; | ||||
| } | } | ||||
| template <typename PointOrRect> | |||||
| static PointOrRect unscaledScreenPosToScaled (PointOrRect pos) noexcept | |||||
| { | |||||
| return unscaledScreenPosToScaled (Desktop::getInstance().getGlobalScaleFactor(), pos); | |||||
| } | |||||
| template <typename PointOrRect> | |||||
| static PointOrRect scaledScreenPosToUnscaled (PointOrRect pos) noexcept | |||||
| { | |||||
| return scaledScreenPosToUnscaled (Desktop::getInstance().getGlobalScaleFactor(), pos); | |||||
| } | |||||
| template <typename PointOrRect> | |||||
| static PointOrRect unscaledScreenPosToScaled (const Component& comp, PointOrRect pos) noexcept | |||||
| { | |||||
| return unscaledScreenPosToScaled (comp.getDesktopScaleFactor(), pos); | |||||
| } | |||||
| template <typename PointOrRect> | |||||
| 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 | // converts an unscaled position within a peer to the local position within that peer's component | ||||
| template <typename PointOrRect> | template <typename PointOrRect> | ||||
| static PointOrRect rawPeerPositionToLocal (const Component& comp, PointOrRect pos) noexcept | static PointOrRect rawPeerPositionToLocal (const Component& comp, PointOrRect pos) noexcept | ||||
| @@ -221,7 +243,7 @@ struct Component::ComponentHelpers | |||||
| if (comp.isTransformed()) | if (comp.isTransformed()) | ||||
| pos = pos.transformedBy (comp.getTransform().inverted()); | 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 | // 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()) | if (comp.isTransformed()) | ||||
| pos = pos.transformedBy (comp.getTransform()); | pos = pos.transformedBy (comp.getTransform()); | ||||
| return scaledScreenPosToUnscaled (pos); | |||||
| return scaledScreenPosToUnscaled (comp, pos); | |||||
| } | } | ||||
| template <typename PointOrRect> | template <typename PointOrRect> | ||||
| @@ -243,7 +265,7 @@ struct Component::ComponentHelpers | |||||
| if (comp.isOnDesktop()) | if (comp.isOnDesktop()) | ||||
| { | { | ||||
| if (ComponentPeer* peer = comp.getPeer()) | if (ComponentPeer* peer = comp.getPeer()) | ||||
| pointInParentSpace = unscaledScreenPosToScaled (peer->globalToLocal (scaledScreenPosToUnscaled (pointInParentSpace))); | |||||
| pointInParentSpace = unscaledScreenPosToScaled (comp, peer->globalToLocal (scaledScreenPosToUnscaled (pointInParentSpace))); | |||||
| else | else | ||||
| jassertfalse; | jassertfalse; | ||||
| } | } | ||||
| @@ -261,7 +283,7 @@ struct Component::ComponentHelpers | |||||
| if (comp.isOnDesktop()) | if (comp.isOnDesktop()) | ||||
| { | { | ||||
| if (ComponentPeer* peer = comp.getPeer()) | if (ComponentPeer* peer = comp.getPeer()) | ||||
| pointInLocalSpace = unscaledScreenPosToScaled (peer->localToGlobal (scaledScreenPosToUnscaled (pointInLocalSpace))); | |||||
| pointInLocalSpace = unscaledScreenPosToScaled (peer->localToGlobal (scaledScreenPosToUnscaled (comp, pointInLocalSpace))); | |||||
| else | else | ||||
| jassertfalse; | jassertfalse; | ||||
| } | } | ||||
| @@ -697,6 +719,8 @@ void Component::userTriedToCloseWindow() | |||||
| void Component::minimisationStateChanged (bool) {} | void Component::minimisationStateChanged (bool) {} | ||||
| float Component::getDesktopScaleFactor() const { return Desktop::getInstance().getGlobalScaleFactor(); } | |||||
| //============================================================================== | //============================================================================== | ||||
| void Component::setOpaque (const bool shouldBeOpaque) | void Component::setOpaque (const bool shouldBeOpaque) | ||||
| { | { | ||||
| @@ -1830,7 +1854,8 @@ void Component::internalRepaintUnchecked (const Rectangle<int>& area, const bool | |||||
| CHECK_MESSAGE_MANAGER_IS_LOCKED | CHECK_MESSAGE_MANAGER_IS_LOCKED | ||||
| if (ComponentPeer* const peer = getPeer()) | 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)); | : area)); | ||||
| } | } | ||||
| else | else | ||||
| @@ -215,6 +215,15 @@ public: | |||||
| */ | */ | ||||
| virtual void minimisationStateChanged (bool isNowMinimised); | 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. | /** Brings the component to the front of its siblings. | ||||
| @@ -1241,6 +1250,8 @@ public: | |||||
| */ | */ | ||||
| static Component* JUCE_CALLTYPE getCurrentlyFocusedComponent() noexcept; | static Component* JUCE_CALLTYPE getCurrentlyFocusedComponent() noexcept; | ||||
| static void JUCE_CALLTYPE unfocusAllComponents(); | |||||
| //============================================================================== | //============================================================================== | ||||
| /** Tries to move the keyboard focus to one of this component's siblings. | /** 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 | // This is included here to cause an error if you use or overload it - it has been deprecated in | ||||
| // favour of contains (Point<int>) | // favour of contains (Point<int>) | ||||
| void contains (int, int); | |||||
| void contains (int, int) JUCE_DELETED_FUNCTION; | |||||
| #endif | #endif | ||||
| protected: | protected: | ||||
| @@ -62,17 +62,19 @@ public: | |||||
| if (ComponentPeer* const peer = comp.getPeer()) | if (ComponentPeer* const peer = comp.getPeer()) | ||||
| { | { | ||||
| pos = peer->globalToLocal (pos); | 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<int> screenPos) | Component* findComponentAt (Point<int> screenPos) | ||||
| { | { | ||||
| if (ComponentPeer* const peer = getPeer()) | if (ComponentPeer* const peer = getPeer()) | ||||
| { | { | ||||
| Point<int> relativePos (Component::ComponentHelpers::unscaledScreenPosToScaled (peer->globalToLocal (screenPos))); | |||||
| Point<int> relativePos (Component::ComponentHelpers::unscaledScreenPosToScaled (peer->getComponent(), | |||||
| peer->globalToLocal (screenPos))); | |||||
| Component& comp = peer->getComponent(); | Component& comp = peer->getComponent(); | ||||
| // (the contains() call is needed to test for overlapping desktop windows) | // (the contains() call is needed to test for overlapping desktop windows) | ||||
| @@ -2097,18 +2097,18 @@ private: | |||||
| { | { | ||||
| if (isConstrainedNativeWindow()) | if (isConstrainedNativeWindow()) | ||||
| { | { | ||||
| Desktop& desktop = Desktop::getInstance(); | |||||
| Rectangle<int> pos (rectangleFromRECT (r) / desktop.getGlobalScaleFactor()); | |||||
| const float scale = getComponent().getDesktopScaleFactor(); | |||||
| Rectangle<int> pos (rectangleFromRECT (r) / scale); | |||||
| const Rectangle<int> current (windowBorder.addedTo (component.getBounds())); | const Rectangle<int> current (windowBorder.addedTo (component.getBounds())); | ||||
| constrainer->checkBounds (pos, 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_TOP || wParam == WMSZ_TOPLEFT || wParam == WMSZ_TOPRIGHT, | ||||
| wParam == WMSZ_LEFT || wParam == WMSZ_TOPLEFT || wParam == WMSZ_BOTTOMLEFT, | wParam == WMSZ_LEFT || wParam == WMSZ_TOPLEFT || wParam == WMSZ_BOTTOMLEFT, | ||||
| wParam == WMSZ_BOTTOM || wParam == WMSZ_BOTTOMLEFT || wParam == WMSZ_BOTTOMRIGHT, | wParam == WMSZ_BOTTOM || wParam == WMSZ_BOTTOMLEFT || wParam == WMSZ_BOTTOMRIGHT, | ||||
| wParam == WMSZ_RIGHT || wParam == WMSZ_TOPRIGHT || wParam == WMSZ_BOTTOMRIGHT); | wParam == WMSZ_RIGHT || wParam == WMSZ_TOPRIGHT || wParam == WMSZ_BOTTOMRIGHT); | ||||
| pos *= desktop.getGlobalScaleFactor(); | |||||
| pos *= scale; | |||||
| r.left = pos.getX(); | r.left = pos.getX(); | ||||
| r.top = pos.getY(); | r.top = pos.getY(); | ||||
| r.right = pos.getRight(); | r.right = pos.getRight(); | ||||
| @@ -2125,19 +2125,19 @@ private: | |||||
| if ((wp.flags & (SWP_NOMOVE | SWP_NOSIZE)) != (SWP_NOMOVE | SWP_NOSIZE) | if ((wp.flags & (SWP_NOMOVE | SWP_NOSIZE)) != (SWP_NOMOVE | SWP_NOSIZE) | ||||
| && ! Component::isMouseButtonDownAnywhere()) | && ! Component::isMouseButtonDownAnywhere()) | ||||
| { | { | ||||
| Desktop& desktop = Desktop::getInstance(); | |||||
| const float scale = getComponent().getDesktopScaleFactor(); | |||||
| Rectangle<int> pos (wp.x, wp.y, wp.cx, wp.cy); | Rectangle<int> pos (wp.x, wp.y, wp.cx, wp.cy); | ||||
| pos /= desktop.getGlobalScaleFactor(); | |||||
| pos /= scale; | |||||
| const Rectangle<int> current (windowBorder.addedTo (component.getBounds())); | const Rectangle<int> current (windowBorder.addedTo (component.getBounds())); | ||||
| constrainer->checkBounds (pos, current, | constrainer->checkBounds (pos, current, | ||||
| desktop.getDisplays().getTotalBounds (true), | |||||
| Desktop::getInstance().getDisplays().getTotalBounds (true), | |||||
| pos.getY() != current.getY() && pos.getBottom() == current.getBottom(), | pos.getY() != current.getY() && pos.getBottom() == current.getBottom(), | ||||
| pos.getX() != current.getX() && pos.getRight() == current.getRight(), | pos.getX() != current.getX() && pos.getRight() == current.getRight(), | ||||
| pos.getY() == current.getY() && pos.getBottom() != current.getBottom(), | pos.getY() == current.getY() && pos.getBottom() != current.getBottom(), | ||||
| pos.getX() == current.getX() && pos.getRight() != current.getRight()); | pos.getX() == current.getX() && pos.getRight() != current.getRight()); | ||||
| pos *= desktop.getGlobalScaleFactor(); | |||||
| pos *= scale; | |||||
| wp.x = pos.getX(); | wp.x = pos.getX(); | ||||
| wp.y = pos.getY(); | wp.y = pos.getY(); | ||||
| wp.cx = pos.getWidth(); | wp.cx = pos.getWidth(); | ||||
| @@ -76,7 +76,7 @@ bool ComponentPeer::isValidPeer (const ComponentPeer* const peer) noexcept | |||||
| void ComponentPeer::updateBounds() | 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()) | if (component.isTransformed()) | ||||
| g.addTransform (component.getTransform()); | g.addTransform (component.getTransform()); | ||||
| float masterScale = Desktop::getInstance().masterScaleFactor; | |||||
| const float masterScale = component.getDesktopScaleFactor(); | |||||
| if (masterScale != 1.0f) | if (masterScale != 1.0f) | ||||
| g.addTransform (AffineTransform::scale (masterScale)); | g.addTransform (AffineTransform::scale (masterScale)); | ||||
| @@ -402,7 +402,7 @@ Rectangle<int> ComponentPeer::globalToLocal (const Rectangle<int>& screenPositio | |||||
| Rectangle<int> ComponentPeer::getAreaCoveredBy (Component& subComponent) const | Rectangle<int> ComponentPeer::getAreaCoveredBy (Component& subComponent) const | ||||
| { | { | ||||
| return Component::ComponentHelpers::scaledScreenPosToUnscaled | return Component::ComponentHelpers::scaledScreenPosToUnscaled | ||||
| (component.getLocalArea (&subComponent, subComponent.getLocalBounds())); | |||||
| (component, component.getLocalArea (&subComponent, subComponent.getLocalBounds())); | |||||
| } | } | ||||
| //============================================================================== | //============================================================================== | ||||
| @@ -193,11 +193,14 @@ public: | |||||
| if (wrapperWindow != 0) | if (wrapperWindow != 0) | ||||
| { | { | ||||
| jassert (getTopLevelComponent()->getDesktopScaleFactor() == 1.0f); | |||||
| Rectangle<int> screenBounds (getScreenBounds() * Desktop::getInstance().getGlobalScaleFactor()); | |||||
| Rect wr; | 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); | SetWindowBounds (wrapperWindow, kWindowContentRgn, &wr); | ||||