Dynamic DPI scaling (#1980)

* DPI scaling
 1. Add the ability to query the operating system's DPI scaling values
 2. Expose those values through a new Lua function
 3. Add an asset that sets the CEF gui and the Dashboard font sizes and placements based on the DPI scaling
 4. Add that new asset into the base_blank asset
* Add message when including the dpiscaling
This commit is contained in:
Alexander Bock
2022-04-08 13:28:18 +02:00
committed by GitHub
parent 1cd84a64f7
commit 6eba57730f
6 changed files with 82 additions and 2 deletions

View File

@@ -28,6 +28,7 @@
#include <openspace/engine/openspaceengine.h>
#include <openspace/engine/windowdelegate.h>
#include <openspace/interaction/joystickinputstate.h>
#include <openspace/scripting/scriptengine.h>
#include <openspace/util/keys.h>
#include <ghoul/ghoul.h>
#include <ghoul/filesystem/filesystem.h>
@@ -810,6 +811,36 @@ void setSgctDelegateFunctions() {
vec2 scale = currentWindow->scale();
return glm::vec2(scale.x, scale.y);
};
sgctDelegate.osDpiScaling = []() {
ZoneScoped
// Detect which DPI scaling to use
// 1. If there is a GUI window, use the GUI window's content scale value
const Window* dpiWindow = nullptr;
for (const std::unique_ptr<Window>& window : Engine::instance().windows()) {
if (window->hasTag("GUI")) {
dpiWindow = window.get();
break;
}
}
// 2. If there isn't a GUI window, use the first window's value
if (!dpiWindow) {
dpiWindow = Engine::instance().windows().front().get();
}
glm::vec2 scale = glm::vec2(1.f, 1.f);
glfwGetWindowContentScale(dpiWindow->windowHandle(), &scale.x, &scale.y);
if (scale.x != scale.y) {
LWARNING(fmt::format(
"Non-square window scaling detected ({0}x{1}), using {0}x{0} instead",
scale.x, scale.y
));
}
return scale.x;
};
sgctDelegate.hasGuiWindow = []() {
ZoneScoped

View File

@@ -5,13 +5,16 @@ local propertyHelper = asset.require("util/property_helper")
-- Specifying which other assets should be loaded in this scene
asset.require("spice/base")
-- Load default key bindings applicable to most scenes
asset.require("dashboard/default_dashboard")
-- Load default key bindings applicable to most scenes
asset.require("util/default_keybindings")
-- Load web gui
local webGui = asset.require("util/webgui")
-- Scale the different UI components based on the operating system's DPI scaling value
asset.require("util/dpiscaling")
local toggle_trails = {
Identifier = "os_default.toggle_trails",
Name = "Toggle Trails",

View File

@@ -0,0 +1,37 @@
asset.onInitialize(function ()
local scale = openspace.dpiScaling()
openspace.printInfo("Setting the DPI scaling factor to " .. tostring(scale))
if openspace.modules.isLoaded("CefWebGui") then
openspace.setPropertyValueSingle(
"Modules.CefWebGui.GuiScale",
openspace.getPropertyValue("Modules.CefWebGui.GuiScale") * scale
)
end
local dashboards = openspace.getProperty("Dashboard.*.FontSize");
for _, v in ipairs(dashboards) do
openspace.setPropertyValueSingle(
v,
openspace.getPropertyValue(v) * scale
)
end
local offset = openspace.getPropertyValue("Dashboard.StartPositionOffset")
openspace.setPropertyValueSingle(
"Dashboard.StartPositionOffset",
{ offset[1] * scale, offset[2] * scale }
)
end)
asset.meta = {
Name = "DPI Scaling",
Version = "1.0",
Description = [[ Retrieves the DPI scaling from the operating system and applies it to
a few selected places to make them scale better on "large resolution but small size"
monitors ]],
Author = "OpenSpace Team",
URL = "http://openspaceproject.com",
License = "MIT license"
}

View File

@@ -64,6 +64,8 @@ struct WindowDelegate {
glm::vec2 (*dpiScaling)() = []() { return glm::vec2(1.f); };
float (*osDpiScaling)() = []() { return 1.f; };
bool (*hasGuiWindow)() = []() { return false; };
bool (*isGuiWindow)() = []() { return false; };

View File

@@ -1072,7 +1072,8 @@ scripting::LuaLibrary RenderEngine::luaLibrary() {
{
codegen::lua::AddScreenSpaceRenderable,
codegen::lua::RemoveScreenSpaceRenderable,
codegen::lua::TakeScreenshot
codegen::lua::TakeScreenshot,
codegen::lua::DpiScaling
}
};
}

View File

@@ -67,6 +67,12 @@ namespace {
return static_cast<int>(screenshotNumber);
}
// Extracts the DPI scaling for either the GUI window or if there is no dedicated GUI
// window, the first window.
[[codegen::luawrap]] float dpiScaling() {
return openspace::global::windowDelegate->osDpiScaling();
}
#include "renderengine_lua_codegen.cpp"
} // namespace