From a2e8f6af90fb879d43d5fa58f51415fabe1c1490 Mon Sep 17 00:00:00 2001 From: Bixilon Date: Thu, 26 Jan 2023 21:28:17 +0100 Subject: [PATCH] gui: scale gui with system scale --- .../minosoft/gui/rendering/gui/GUIRenderer.kt | 16 +++-- .../system/window/glfw/GLFWWindow.kt | 60 ++++++++++++------- 2 files changed, 47 insertions(+), 29 deletions(-) diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/gui/GUIRenderer.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/gui/GUIRenderer.kt index f0d6dadd3..fb5b4a2c9 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/gui/GUIRenderer.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/gui/GUIRenderer.kt @@ -15,9 +15,11 @@ package de.bixilon.minosoft.gui.rendering.gui import de.bixilon.kotlinglm.GLM import de.bixilon.kotlinglm.mat4x4.Mat4 +import de.bixilon.kotlinglm.vec2.Vec2 import de.bixilon.kotlinglm.vec2.Vec2d import de.bixilon.kotlinglm.vec2.Vec2i import de.bixilon.kutil.latch.CountUpAndDownLatch +import de.bixilon.kutil.observer.DataObserver.Companion.observe import de.bixilon.kutil.observer.DataObserver.Companion.observed import de.bixilon.minosoft.config.key.KeyCodes import de.bixilon.minosoft.gui.rendering.RenderContext @@ -79,6 +81,7 @@ class GUIRenderer( shader.load() connection.events.listen { recalculateMatrices(it.size) } + context.window::systemScale.observe(this) { recalculateMatrices(systemScale = it) } profile::scale.observeRendering(this) { recalculateMatrices(scale = it) } gui.postInit() @@ -87,8 +90,8 @@ class GUIRenderer( dragged.postInit() } - private fun recalculateMatrices(windowSize: Vec2i = context.window.size, scale: Float = profile.scale) { - scaledSize = windowSize.scale(scale) + private fun recalculateMatrices(windowSize: Vec2i = context.window.size, scale: Float = profile.scale, systemScale: Vec2 = context.window.systemScale) { + scaledSize = windowSize.scale(systemScale, scale) matrix = GLM.ortho(0.0f, scaledSize.x.toFloat(), scaledSize.y.toFloat(), 0.0f) matrixChange = true @@ -145,16 +148,17 @@ class GUIRenderer( } } - fun Vec2i.scale(scale: Float = profile.scale): Vec2i { + fun Vec2i.scale(systemScale: Vec2 = context.window.systemScale, scale: Float = profile.scale): Vec2i { val output = Vec2i(this) + val totalScale = systemScale * scale // ToDo: This is just a dirty workaround and does not fix the problem at all - while (output.x % scale.toInt() != 0) { + while (output.x % totalScale.x.toInt() != 0) { output.x++ } - while (output.y % scale.toInt() != 0) { + while (output.y % totalScale.y.toInt() != 0) { output.y++ } - return output / scale + return output / totalScale } fun isKeyDown(vararg keyCodes: KeyCodes): Boolean { diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/system/window/glfw/GLFWWindow.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/system/window/glfw/GLFWWindow.kt index f5660f64a..4656057e2 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/system/window/glfw/GLFWWindow.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/system/window/glfw/GLFWWindow.kt @@ -80,29 +80,6 @@ class GLFWWindow( field = value } - override val systemScale: Vec2 - get() { - val x = FloatArray(1) - val y = FloatArray(1) - glfwGetWindowContentScale(window, x, y) - return Vec2(x[0], y[0]) - } - - private fun scalePosition(position: Vec2i): Vec2i { - if (!PlatformInfo.OS.needsWindowScaling) return position - return position / systemScale - } - - private fun unscalePosition(position: Vec2i): Vec2i { - if (!PlatformInfo.OS.needsWindowScaling) return position - return position * systemScale - } - - private fun unscalePosition(position: Vec2d): Vec2d { - if (!PlatformInfo.OS.needsWindowScaling) return position - return position * systemScale - } - private var _size = Vec2i(DEFAULT_WINDOW_SIZE) override var size: Vec2i @@ -249,6 +226,9 @@ class GLFWWindow( glfwSetWindowFocusCallback(window, this::onFocusChange) glfwSetWindowIconifyCallback(window, this::onIconify) glfwSetScrollCallback(window, this::onScroll) + glfwSetWindowContentScaleCallback(window, this::onWindowScale) + + pollWindowScale() when (PlatformInfo.OS) { OSTypes.MAC -> { @@ -300,6 +280,40 @@ class GLFWWindow( glfwWindowHint(GLFW_OPENGL_PROFILE, if (coreProfile) GLFW_OPENGL_CORE_PROFILE else GLFW_OPENGL_ANY_PROFILE) } + + override var systemScale by observed(Vec2(1.0f)) + + private fun scalePosition(position: Vec2i): Vec2i { + if (!PlatformInfo.OS.needsWindowScaling) return position + return position / systemScale + } + + private fun unscalePosition(position: Vec2i): Vec2i { + if (!PlatformInfo.OS.needsWindowScaling) return position + return position * systemScale + } + + private fun unscalePosition(position: Vec2d): Vec2d { + if (!PlatformInfo.OS.needsWindowScaling) return position + return position * systemScale + } + + + private fun pollWindowScale() { + val x = FloatArray(1) + val y = FloatArray(1) + glfwGetWindowContentScale(window, x, y) + onWindowScale(window, x[0], y[0]) + } + + private fun onWindowScale(window: Long, x: Float, y: Float) { + if (window != this.window) { + return + } + val scale = Vec2(x, y) + this.systemScale = scale + } + override var focused by observed(false) private fun onFocusChange(window: Long, focused: Boolean) {