mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-01-09 23:34:20 +00:00
ComponentPeer: Add method for overriding native scale factor
This commit is contained in:
parent
6648e13fa6
commit
b4c28db765
3 changed files with 98 additions and 22 deletions
|
|
@ -106,7 +106,7 @@ public:
|
|||
updateScaleFactorFromNewBounds (bounds, false);
|
||||
|
||||
auto physicalBounds = parentWindow == 0 ? Desktop::getInstance().getDisplays().logicalToPhysical (bounds)
|
||||
: bounds * currentScaleFactor;
|
||||
: bounds * getPlatformScaleFactor();
|
||||
|
||||
WeakReference<Component> deletionChecker (&component);
|
||||
|
||||
|
|
@ -140,14 +140,14 @@ public:
|
|||
{
|
||||
auto physicalParentPosition = XWindowSystem::getInstance()->getPhysicalParentScreenPosition();
|
||||
auto parentPosition = parentWindow == 0 ? Desktop::getInstance().getDisplays().physicalToLogical (physicalParentPosition)
|
||||
: physicalParentPosition / currentScaleFactor;
|
||||
: physicalParentPosition / getPlatformScaleFactor();
|
||||
|
||||
auto screenBounds = parentWindow == 0 ? bounds
|
||||
: bounds.translated (parentPosition.x, parentPosition.y);
|
||||
|
||||
if (physical)
|
||||
return parentWindow == 0 ? Desktop::getInstance().getDisplays().logicalToPhysical (screenBounds.getTopLeft())
|
||||
: screenBounds.getTopLeft() * currentScaleFactor;
|
||||
: screenBounds.getTopLeft() * getPlatformScaleFactor();
|
||||
|
||||
return screenBounds.getTopLeft();
|
||||
}
|
||||
|
|
@ -270,7 +270,7 @@ public:
|
|||
if (trueIfInAChildWindow)
|
||||
return true;
|
||||
|
||||
return XWindowSystem::getInstance()->contains (windowH, localPos * currentScaleFactor);
|
||||
return XWindowSystem::getInstance()->contains (windowH, localPos * getPlatformScaleFactor());
|
||||
}
|
||||
|
||||
void toFront (bool makeActive) override
|
||||
|
|
@ -332,7 +332,24 @@ public:
|
|||
|
||||
double getPlatformScaleFactor() const noexcept override
|
||||
{
|
||||
return currentScaleFactor;
|
||||
return scaleFactorOverride.value_or (currentScaleFactor);
|
||||
}
|
||||
|
||||
void setCustomPlatformScaleFactor (std::optional<double> scaleIn) override
|
||||
{
|
||||
const auto prev = getPlatformScaleFactor();
|
||||
scaleFactorOverride = scaleIn;
|
||||
const auto next = getPlatformScaleFactor();
|
||||
|
||||
if (approximatelyEqual (prev, next))
|
||||
return;
|
||||
|
||||
scaleFactorListeners.call ([&] (ScaleFactorListener& l) { l.nativeScaleFactorChanged (next); });
|
||||
}
|
||||
|
||||
std::optional<double> getCustomPlatformScaleFactor() const override
|
||||
{
|
||||
return scaleFactorOverride;
|
||||
}
|
||||
|
||||
void setAlpha (float) override {}
|
||||
|
|
@ -386,7 +403,7 @@ public:
|
|||
updateScaleFactorFromNewBounds (physicalBounds, true);
|
||||
|
||||
bounds = parentWindow == 0 ? Desktop::getInstance().getDisplays().physicalToLogical (physicalBounds)
|
||||
: physicalBounds / currentScaleFactor;
|
||||
: physicalBounds / getPlatformScaleFactor();
|
||||
|
||||
updateVBlankTimer();
|
||||
}
|
||||
|
|
@ -403,7 +420,7 @@ public:
|
|||
windowBorder = [&]()
|
||||
{
|
||||
if (auto unscaledBorderSize = XWindowSystem::getInstance()->getBorderSize (windowH))
|
||||
return OptionalBorderSize { (*unscaledBorderSize).multipliedBy (1.0 / currentScaleFactor) };
|
||||
return OptionalBorderSize { (*unscaledBorderSize).multipliedBy (1.0 / getPlatformScaleFactor()) };
|
||||
|
||||
return OptionalBorderSize {};
|
||||
}();
|
||||
|
|
@ -460,7 +477,7 @@ private:
|
|||
|
||||
void repaint (Rectangle<int> area)
|
||||
{
|
||||
regionsNeedingRepaint.add (area * peer.currentScaleFactor);
|
||||
regionsNeedingRepaint.add (area * peer.getPlatformScaleFactor());
|
||||
}
|
||||
|
||||
void performAnyPendingRepaintsNow()
|
||||
|
|
@ -511,7 +528,7 @@ private:
|
|||
auto context = peer.getComponent().getLookAndFeel()
|
||||
.createGraphicsContext (image, -totalArea.getPosition(), adjustedList);
|
||||
|
||||
context->addTransform (AffineTransform::scale ((float) peer.currentScaleFactor));
|
||||
context->addTransform (AffineTransform::scale ((float) peer.getPlatformScaleFactor()));
|
||||
peer.handlePaint (*context);
|
||||
}
|
||||
|
||||
|
|
@ -607,6 +624,7 @@ private:
|
|||
Rectangle<int> bounds;
|
||||
ComponentPeer::OptionalBorderSize windowBorder;
|
||||
bool fullScreen = false, isAlwaysOnTop = false;
|
||||
std::optional<double> scaleFactorOverride;
|
||||
double currentScaleFactor = 1.0;
|
||||
Array<Component*> glRepaintListeners;
|
||||
ScopedWindowAssociation association;
|
||||
|
|
|
|||
|
|
@ -558,7 +558,8 @@ static Rectangle<ValueType> convertLogicalScreenRectangleToPhysical (Rectangle<V
|
|||
return r;
|
||||
}
|
||||
|
||||
static Point<int> convertPhysicalScreenPointToLogical (Point<int> p, HWND h) noexcept
|
||||
template <typename ValueType>
|
||||
static Point<ValueType> convertPhysicalScreenPointToLogical (Point<ValueType> p, HWND h) noexcept
|
||||
{
|
||||
if (isPerMonitorDPIAwareWindow (h))
|
||||
return Desktop::getInstance().getDisplays().physicalToLogical (p, getCurrentDisplayFromScaleFactor (h));
|
||||
|
|
@ -566,7 +567,8 @@ static Point<int> convertPhysicalScreenPointToLogical (Point<int> p, HWND h) noe
|
|||
return p;
|
||||
}
|
||||
|
||||
static Point<int> convertLogicalScreenPointToPhysical (Point<int> p, HWND h) noexcept
|
||||
template <typename ValueType>
|
||||
static Point<ValueType> convertLogicalScreenPointToPhysical (Point<ValueType> p, HWND h) noexcept
|
||||
{
|
||||
if (isPerMonitorDPIAwareWindow (h))
|
||||
return Desktop::getInstance().getDisplays().logicalToPhysical (p, getCurrentDisplayFromScaleFactor (h));
|
||||
|
|
@ -1471,8 +1473,19 @@ public:
|
|||
return convertPhysicalScreenPointToLogical (getClientRectInScreen().getPosition(), hwnd);
|
||||
}
|
||||
|
||||
Point<float> localToGlobal (Point<float> relativePosition) override { return relativePosition + getScreenPosition().toFloat(); }
|
||||
Point<float> globalToLocal (Point<float> screenPosition) override { return screenPosition - getScreenPosition().toFloat(); }
|
||||
Point<float> localToGlobal (Point<float> relativePosition) override
|
||||
{
|
||||
const auto localPhysical = relativePosition * getPlatformScaleFactor();
|
||||
const auto physical = localPhysical + getClientRectInScreen().getPosition().toFloat();
|
||||
return convertPhysicalScreenPointToLogical (physical, hwnd);
|
||||
}
|
||||
|
||||
Point<float> globalToLocal (Point<float> screenPosition) override
|
||||
{
|
||||
const auto physical = convertLogicalScreenPointToPhysical (screenPosition, hwnd);
|
||||
const auto localPhysical = physical - getClientRectInScreen().getPosition().toFloat();
|
||||
return localPhysical / getPlatformScaleFactor();
|
||||
}
|
||||
|
||||
using ComponentPeer::localToGlobal;
|
||||
using ComponentPeer::globalToLocal;
|
||||
|
|
@ -1578,12 +1591,13 @@ public:
|
|||
|
||||
bool contains (Point<int> localPos, bool trueIfInAChildWindow) const override
|
||||
{
|
||||
auto r = convertPhysicalScreenRectangleToLogical (D2DUtilities::toRectangle (getWindowScreenRect (hwnd)), hwnd);
|
||||
const auto localPhysical = localPos.toFloat() / getPlatformScaleFactor();
|
||||
auto r = D2DUtilities::toRectangle (getWindowScreenRect (hwnd)).toFloat();
|
||||
|
||||
if (! r.withZeroOrigin().contains (localPos))
|
||||
if (! r.withZeroOrigin().contains (localPhysical))
|
||||
return false;
|
||||
|
||||
const auto screenPos = convertLogicalScreenPointToPhysical (localPos + getScreenPosition(), hwnd);
|
||||
const auto screenPos = (localPhysical + getClientRectInScreen().getPosition().toFloat()).roundToInt();
|
||||
|
||||
auto w = WindowFromPoint (D2DUtilities::toPOINT (screenPos));
|
||||
return w == hwnd || (trueIfInAChildWindow && (IsChild (hwnd, w) != 0));
|
||||
|
|
@ -1596,7 +1610,7 @@ public:
|
|||
|
||||
BorderSize<int> getFrameSize() const override
|
||||
{
|
||||
return findPhysicalBorderSize().value_or (BorderSize<int>{}).multipliedBy (1.0 / scaleFactor);
|
||||
return findPhysicalBorderSize().value_or (BorderSize<int>{}).multipliedBy (1.0 / getPlatformScaleFactor());
|
||||
}
|
||||
|
||||
bool setAlwaysOnTop (bool alwaysOnTop) override
|
||||
|
|
@ -1993,7 +2007,7 @@ public:
|
|||
return peer->doKeyUp (msg.wParam);
|
||||
}
|
||||
|
||||
double getPlatformScaleFactor() const noexcept override
|
||||
double getPlatformScaleFactorWithoutOverride() const noexcept
|
||||
{
|
||||
#if ! JUCE_WIN_PER_MONITOR_DPI_AWARE
|
||||
return 1.0;
|
||||
|
|
@ -2013,6 +2027,31 @@ public:
|
|||
#endif
|
||||
}
|
||||
|
||||
double getPlatformScaleFactor() const noexcept override
|
||||
{
|
||||
if (scaleFactorOverride.has_value())
|
||||
return *scaleFactorOverride;
|
||||
|
||||
return getPlatformScaleFactorWithoutOverride();
|
||||
}
|
||||
|
||||
void setCustomPlatformScaleFactor (std::optional<double> scaleIn) override
|
||||
{
|
||||
const auto prev = getPlatformScaleFactor();
|
||||
scaleFactorOverride = scaleIn;
|
||||
const auto next = getPlatformScaleFactor();
|
||||
|
||||
if (approximatelyEqual (prev, next))
|
||||
return;
|
||||
|
||||
scaleFactorListeners.call ([&] (ScaleFactorListener& l) { l.nativeScaleFactorChanged (next); });
|
||||
}
|
||||
|
||||
std::optional<double> getCustomPlatformScaleFactor() const override
|
||||
{
|
||||
return scaleFactorOverride;
|
||||
}
|
||||
|
||||
static void getLastError()
|
||||
{
|
||||
TCHAR messageBuffer[256] = {};
|
||||
|
|
@ -2065,7 +2104,6 @@ public:
|
|||
}
|
||||
|
||||
bool hasTitleBar() const { return (styleFlags & windowHasTitleBar) != 0; }
|
||||
double getScaleFactor() const { return scaleFactor; }
|
||||
|
||||
private:
|
||||
HWND hwnd, parentToAddTo;
|
||||
|
|
@ -2083,6 +2121,7 @@ private:
|
|||
#endif
|
||||
|
||||
double scaleFactor = 1.0;
|
||||
std::optional<double> scaleFactorOverride;
|
||||
bool inDpiChange = 0, inHandlePositionChanged = 0;
|
||||
HMONITOR currentMonitor = nullptr;
|
||||
|
||||
|
|
@ -4264,8 +4303,8 @@ private:
|
|||
{
|
||||
if (auto parentHwnd = GetParent (hwnd))
|
||||
{
|
||||
auto parentRect = convertPhysicalScreenRectangleToLogical (D2DUtilities::toRectangle (getWindowScreenRect (parentHwnd)), hwnd);
|
||||
newBounds.translate (parentRect.getX(), parentRect.getY());
|
||||
const auto parentRect = convertPhysicalScreenRectangleToLogical (D2DUtilities::toRectangle (getWindowScreenRect (parentHwnd)), hwnd);
|
||||
newBounds += parentRect.getPosition();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -5787,7 +5826,7 @@ static const Displays::Display* getCurrentDisplayFromScaleFactor (HWND hwnd)
|
|||
const auto scaleToLookFor = [&]
|
||||
{
|
||||
if (auto* peer = HWNDComponentPeer::getOwnerOfWindow (hwnd))
|
||||
return peer->getPlatformScaleFactor();
|
||||
return peer->getPlatformScaleFactorWithoutOverride();
|
||||
|
||||
return getScaleFactorForWindow (hwnd);
|
||||
}();
|
||||
|
|
|
|||
|
|
@ -544,6 +544,25 @@ public:
|
|||
*/
|
||||
virtual double getPlatformScaleFactor() const noexcept { return 1.0; }
|
||||
|
||||
/** On Windows and Linux, calling this with a non-null optional will override whatever scale
|
||||
factor the platform has specified for this window. The new scale factor will persist even
|
||||
in the case that the platform attempts to set a new scale! Pass a null optional to revert
|
||||
back to the platform-provided scale.
|
||||
|
||||
This is intended for use by plugin wrappers, where hosts may attempt to set a scale factor
|
||||
different from the platform scale. You should never need to call this directly.
|
||||
*/
|
||||
virtual void setCustomPlatformScaleFactor (std::optional<double>) {}
|
||||
|
||||
/** Returns the custom scale factor set using setCustomPlatformScaleFactor(), if any.
|
||||
|
||||
If a custom scale factor has been set, getPlatformScaleFactor() will always return that
|
||||
value, effectively overriding any scale factor requested by the system.
|
||||
Otherwise, if the custom platform scale factor is nullopt, then the system will update the
|
||||
scale factor automatically.
|
||||
*/
|
||||
virtual std::optional<double> getCustomPlatformScaleFactor() const { return {}; }
|
||||
|
||||
/** On platforms that support it, this will update the window's titlebar in some
|
||||
way to indicate that the window's document needs saving.
|
||||
*/
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue