From c8f4599ff19e568a7507675593082bc1891b3af5 Mon Sep 17 00:00:00 2001 From: quadbyte Date: Sat, 9 Aug 2025 13:12:13 -0400 Subject: [PATCH] Scaling service --- Modules/Bar/Bar.qml | 11 +++++++-- Services/Scaling.qml | 44 ++++++++++++++++++++++++++++++++++ Theme/Theme.qml | 38 ----------------------------- Widgets/NoctaliaIconButton.qml | 36 ++++++++++++++++++++++++++++ Widgets/NoctaliaToggle.qml | 9 ++++--- 5 files changed, 95 insertions(+), 43 deletions(-) create mode 100644 Services/Scaling.qml create mode 100644 Widgets/NoctaliaIconButton.qml diff --git a/Modules/Bar/Bar.qml b/Modules/Bar/Bar.qml index 47fb6c1..f479d2d 100644 --- a/Modules/Bar/Bar.qml +++ b/Modules/Bar/Bar.qml @@ -1,5 +1,7 @@ import QtQuick import Quickshell +import QtQuick.Controls +import QtQuick.Layouts import qs.Widgets import qs.Theme @@ -27,7 +29,12 @@ PanelWindow { layer.enabled: true } - // Just testing - NoctaliaToggle {} + RowLayout { + // Just testing + NoctaliaToggle { + label: "Label" + description: "Description" + } + } } } diff --git a/Services/Scaling.qml b/Services/Scaling.qml new file mode 100644 index 0000000..5e646de --- /dev/null +++ b/Services/Scaling.qml @@ -0,0 +1,44 @@ +pragma Singleton + +import Quickshell + +Singleton { + id: root + + // Design reference resolution (for scale = 1.0) + readonly property int designScreenWidth: 2560 + readonly property int designScreenHeight: 1440 + + // Automatic, orientation-agnostic scaling + function scale(currentScreen) { + return 1.0 + // // 1) Per-monitor override wins + // try { + // const overrides = Settings.settings.monitorScaleOverrides || {}; + // if (currentScreen && currentScreen.name && overrides[currentScreen.name] !== undefined) { + // const overrideValue = overrides[currentScreen.name] + // if (isFinite(overrideValue)) return overrideValue + // } + // } catch (e) { + // // ignore + // } + + // // 2) Fallback: scale by diagonal pixel count relative to design resolution + // try { + // const w = Math.max(1, currentScreen ? (currentScreen.width || 0) : 0) + // const h = Math.max(1, currentScreen ? (currentScreen.height || 0) : 0) + // if (w > 1 && h > 1) { + // const diag = Math.sqrt(w * w + h * h) + // const baseDiag = Math.sqrt(designScreenWidth * designScreenWidth + designScreenHeight * designScreenHeight) + // const ratio = diag / baseDiag + // // Clamp to a reasonable range for UI legibility + // return Math.max(0.9, Math.min(1.6, ratio)) + // } + // } catch (e) { + // // ignore and fall through + // } + + // // 3) Safe default + // return 1.0 + } +} diff --git a/Theme/Theme.qml b/Theme/Theme.qml index 93a9f2a..bf1829f 100644 --- a/Theme/Theme.qml +++ b/Theme/Theme.qml @@ -1,4 +1,3 @@ -// Theme.qml pragma Singleton import QtQuick @@ -47,43 +46,6 @@ Singleton { // Font Properties property string fontFamily: "Roboto" // Family for all text - // Design reference resolution (for scale = 1.0) - readonly property int designScreenWidth: 2560 - readonly property int designScreenHeight: 1440 - - // Automatic, orientation-agnostic scaling - function scale(currentScreen) { - return 1.0 - // // 1) Per-monitor override wins - // try { - // const overrides = Settings.settings.monitorScaleOverrides || {}; - // if (currentScreen && currentScreen.name && overrides[currentScreen.name] !== undefined) { - // const overrideValue = overrides[currentScreen.name] - // if (isFinite(overrideValue)) return overrideValue - // } - // } catch (e) { - // // ignore - // } - - // // 2) Fallback: scale by diagonal pixel count relative to design resolution - // try { - // const w = Math.max(1, currentScreen ? (currentScreen.width || 0) : 0) - // const h = Math.max(1, currentScreen ? (currentScreen.height || 0) : 0) - // if (w > 1 && h > 1) { - // const diag = Math.sqrt(w * w + h * h) - // const baseDiag = Math.sqrt(designScreenWidth * designScreenWidth + designScreenHeight * designScreenHeight) - // const ratio = diag / baseDiag - // // Clamp to a reasonable range for UI legibility - // return Math.max(0.9, Math.min(1.6, ratio)) - // } - // } catch (e) { - // // ignore and fall through - // } - - // // 3) Safe default - // return 1.0 - } - function applyOpacity(color, opacity) { return color.replace("#", "#" + opacity) } diff --git a/Widgets/NoctaliaIconButton.qml b/Widgets/NoctaliaIconButton.qml new file mode 100644 index 0000000..bed7259 --- /dev/null +++ b/Widgets/NoctaliaIconButton.qml @@ -0,0 +1,36 @@ +import QtQuick +import Quickshell +import Quickshell.Widgets +import qs.Settings + +MouseArea { + id: root + property string icon + property bool enabled: true + property bool hovering: false + property real size: 32 + cursorShape: Qt.PointingHandCursor + implicitWidth: size + implicitHeight: size + + hoverEnabled: true + onEntered: hovering = true + onExited: hovering = false + + Rectangle { + anchors.fill: parent + radius: 8 + color: root.hovering ? Theme.accentPrimary : "transparent" + } + Text { + id: iconText + anchors.centerIn: parent + text: root.icon + font.family: "Material Symbols Outlined" + font.pixelSize: 24 * Theme.scale(screen) + color: root.hovering ? Theme.onAccent : Theme.textPrimary + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + opacity: root.enabled ? 1.0 : 0.5 + } +} diff --git a/Widgets/NoctaliaToggle.qml b/Widgets/NoctaliaToggle.qml index 26701cd..8b7b76b 100644 --- a/Widgets/NoctaliaToggle.qml +++ b/Widgets/NoctaliaToggle.qml @@ -1,19 +1,21 @@ import QtQuick import QtQuick.Controls import QtQuick.Layouts +import qs.Services import qs.Theme + RowLayout { id: root // Local scale convenience with safe fallback readonly property real scale: (typeof screen !== 'undefined' - && screen) ? Theme.scale(screen) : 1.0 + && screen) ? Scaling.scale(screen) : 1.0 property string label: "" property string description: "" property bool value: false - property var onToggled: function () {} + property var onToggled: function (value: bool) {} Layout.fillWidth: true @@ -69,7 +71,8 @@ RowLayout { anchors.fill: parent cursorShape: Qt.PointingHandCursor onClicked: { - root.onToggled() + value = !value; + root.onToggled(value); } } }