I have fairly recently joined a team developing juce based plugins which use png images for all aspects of the GUI.
My predecessor had used a simple system that got a scale factor by using Desktop::getInstance().getDisplays().getMainDisplay()->scale and then created the GUI using a set of either 100% or 200% images depending on the scale factor.
We have only very recently moved to using juce 6, where getMainDisplay is replaced with getPrimaryDisplay, which always returns 1.0 on Windows because of changes in win32_Windowing.
It is possible to workaround this by calculating a scale from the global dpi to keep our basic method working, but it is far from ideal.
I have found setScaleFactor in AudioProcessorEditor which seems like a better approach to use, but I think this is only called via VST wrappers?
So, my question is, what is the best way to determine the scale factor for either a ‘primary’ monitor, or the current monitor, that will work with all wrapper types on both Mac and Windows?
We are currently overhauling our supporting code framework alongside the move to juce 6, so we could also consider a more sophisticated method of dynamically switching assets when a plugin is dragged between monitors and/or also support non-integer scale factors between 1 and 2, so any other suggestions are very welcome.
Thank you for any help, even if it is just to point me towards some obvious documentation I have missed
It’s the host’s responsibility to communicate the scale factor to the plug-in and, especially on Windows where multi-monitor scale factor support at the OS-level is ropey at the best of times, plug-ins should not interfere with this by trying to calculate the actual scale factor of the display.
When running as a plug-in,
Display::scale will always be 1.0 and editor scaling is handled via the plug-in wrappers which call
AudioProcessorEditor::setScaleFactor(). This applies a transform to the top-level editor and scales it to the host scale so if you want to get the scale factor that has been set by the host you can use
Component::getApproximateScaleFactorForComponent() on your editor.
Thanks for your reply Ed, I made a quick test plugin and tried it in Reaper on Windows and getApproximateScaleFactorForComponent() does return the expected 1 on a normal monitor and 2 on a 4k monitor.
However on a Mac using an AU in Logic it always returns 1. Can you confirm that setScaleFactor should be set through AU and AAX wrappers on both Mac and Windows as we are looking for a universal solution?
Sorry to bump my own post but I have just finished another piece of work and am going to focus on this again. There are two separate questions so I will try to make them concise and see if @ed95 or anyone else has an answer to either:
getApproximateScaleFactor works for VST3 plugins, what is the equivalent ‘officially approved’ way to get a scale for either the current monitor or main monitor, in AU and AAX plugins.
The transform applied to the editor when the user alters the size of the host plugin window seems like an excellent solution for VST3 plugins, what is the equivalent method for AU and AAX plugins?
I will be very grateful for any replies. I can probably work out a way to do these things from the bottom up, but my boss is very keen for us to do it the ‘right’ way as we are in the middle of some fairly major updates to the way we produce plugins.
Sorry for not replying earlier, I missed this one.
The scaling transform is only required for hiDPI Windows plug-ins where the scaling is not handled by the OS. In non-hiDPI situations Windows will automatically bitmap scale the UI and on macOS the scale factor is handled internally by the OS and you only ever “see” the logical pixels, so don’t have to deal with physical pixels + scale factors. Therefore in AU plug-ins and macOS AAX plug-ins the UI will be automatically scaled and you don’t need to upres images and, as far as I am aware, there is no hiDPI support for AAX plug-ins on Windows so they will be bitmap-scaled by the OS.