From 050877bcb0a8cb1b7f3cd8bc6ed98fa35a6fec68 Mon Sep 17 00:00:00 2001 From: quadbyte Date: Tue, 12 Aug 2025 23:46:35 -0400 Subject: [PATCH] Reverted the labeled NSlider, which tends to trigger hard crashes when opening the settings --- Modules/Demo/DemoPanel.qml | 31 +++-- Modules/Settings/SettingsPanel.qml | 8 +- Modules/Settings/Tabs/Wallpaper.qml | 84 ++++++------ Widgets/NSlider.qml | 192 +++++++++------------------- 4 files changed, 123 insertions(+), 192 deletions(-) diff --git a/Modules/Demo/DemoPanel.qml b/Modules/Demo/DemoPanel.qml index 3a9b303..29139e3 100644 --- a/Modules/Demo/DemoPanel.qml +++ b/Modules/Demo/DemoPanel.qml @@ -43,7 +43,7 @@ NLoader { NText { text: "DemoPanel" color: Colors.accentPrimary - font.pointSize: Style.fontSizeXL* scaling + font.pointSize: Style.fontSizeXL * scaling font.weight: Style.fontWeightBold Layout.alignment: Qt.AlignHCenter } @@ -60,22 +60,27 @@ NLoader { color: Colors.accentSecondary font.weight: Style.fontWeightBold } + NText { + text: `${Math.round(Scaling.overrideScale * 100)}%` + Layout.alignment: Qt.AlignVCenter + } RowLayout { spacing: Style.marginSmall * scaling NSlider { - label: "Scaling" - description: "Scaling goes brrrr" - valueSuffix: "%" - from: 60 - to: 180 - stepSize: 1 - value: Scaling.overrideScale * 100 - implicitWidth: bgRect.width * 0.75 - onPressedChanged: function (pressed, value) { - Scaling.overrideEnabled = true - Scaling.overrideScale = value / 100 - } + id: scaleSlider + from: 0.6 + to: 1.8 + stepSize: 0.01 + value: Scaling.overrideScale + implicitWidth: bgRect.width * 0.75 + onMoved: { + } + onPressedChanged: { + Scaling.overrideScale = value + Scaling.overrideEnabled = true + } + } NIconButton { icon: "refresh" fontPointSize: Style.fontSizeLarge * scaling diff --git a/Modules/Settings/SettingsPanel.qml b/Modules/Settings/SettingsPanel.qml index 856c2b6..2d965dc 100644 --- a/Modules/Settings/SettingsPanel.qml +++ b/Modules/Settings/SettingsPanel.qml @@ -10,13 +10,15 @@ import qs.Widgets NLoader { id: root + readonly property real scaling: Scaling.scale(screen) + content: Component { NPanel { id: panel WlrLayershell.keyboardFocus: WlrKeyboardFocus.OnDemand - readonly property real scaling: Scaling.scale(screen) + property int currentTabIndex: 0 property var tabsModel: [{ "label": "General", @@ -74,8 +76,8 @@ NLoader { border.color: Colors.backgroundTertiary border.width: Math.max(1, Style.borderMedium * scaling) layer.enabled: true - width: (screen.width / 2) * scaling - height: (screen.height / 2) * scaling + width: (screen.width * 0.5) * scaling + height: (screen.height * 0.5) * scaling anchors.centerIn: parent MouseArea { diff --git a/Modules/Settings/Tabs/Wallpaper.qml b/Modules/Settings/Tabs/Wallpaper.qml index 59eb6bf..32d0f5c 100644 --- a/Modules/Settings/Tabs/Wallpaper.qml +++ b/Modules/Settings/Tabs/Wallpaper.qml @@ -116,20 +116,20 @@ ColumnLayout { } // Wallpaper Interval - NSlider { - label: "Wallpaper Interval" - description: "How often to change wallpapers automatically (in seconds)" - valueSuffix: "s" - from: 10 - to: 900 - stepSize: 10 - value: Settings.data.wallpaper.randomInterval - onPressedChanged: function (pressed, value) { - Settings.data.wallpaper.randomInterval = Math.round(value) - } - cutoutColor: Colors.backgroundPrimary - Layout.fillWidth: true - } + // NSlider { + // label: "Wallpaper Interval" + // description: "How often to change wallpapers automatically (in seconds)" + // valueSuffix: "s" + // from: 10 + // to: 900 + // stepSize: 10 + // value: Settings.data.wallpaper.randomInterval + // onPressedChanged: function (pressed, value) { + // Settings.data.wallpaper.randomInterval = Math.round(value) + // } + // cutoutColor: Colors.backgroundPrimary + // Layout.fillWidth: true + // } } NDivider { @@ -229,36 +229,36 @@ ColumnLayout { } // Transition FPS - NSlider { - label: "Transition FPS" - description: "Frames per second for transition animations" - valueSuffix: " FPS" - from: 30 - to: 500 - stepSize: 5 - value: Settings.data.wallpaper.swww.transitionFps - onPressedChanged: function (pressed, value) { - Settings.data.wallpaper.swww.transitionFps = Math.round(value) - } - cutoutColor: Colors.backgroundPrimary - Layout.fillWidth: true - } + // NSlider { + // label: "Transition FPS" + // description: "Frames per second for transition animations" + // valueSuffix: " FPS" + // from: 30 + // to: 500 + // stepSize: 5 + // value: Settings.data.wallpaper.swww.transitionFps + // onPressedChanged: function (pressed, value) { + // Settings.data.wallpaper.swww.transitionFps = Math.round(value) + // } + // cutoutColor: Colors.backgroundPrimary + // Layout.fillWidth: true + // } // Transition Duration - NSlider { - label: "Transition Duration" - description: "Duration of transition animations in seconds" - valueSuffix: "s" - from: 0.25 - to: 10 - stepSize: 0.05 - value: Settings.data.wallpaper.swww.transitionDuration - onPressedChanged: function (pressed, value) { - Settings.data.wallpaper.swww.transitionDuration = value - } - cutoutColor: Colors.backgroundPrimary - Layout.fillWidth: true - } + // NSlider { + // label: "Transition Duration" + // description: "Duration of transition animations in seconds" + // valueSuffix: "s" + // from: 0.25 + // to: 10 + // stepSize: 0.05 + // value: Settings.data.wallpaper.swww.transitionDuration + // onPressedChanged: function (pressed, value) { + // Settings.data.wallpaper.swww.transitionDuration = value + // } + // cutoutColor: Colors.backgroundPrimary + // Layout.fillWidth: true + // } } } } diff --git a/Widgets/NSlider.qml b/Widgets/NSlider.qml index 8075473..2d77f3e 100644 --- a/Widgets/NSlider.qml +++ b/Widgets/NSlider.qml @@ -1,10 +1,9 @@ import QtQuick import QtQuick.Controls import QtQuick.Effects -import QtQuick.Layouts import qs.Services -ColumnLayout { +Slider { id: root readonly property real scaling: Scaling.scale(screen) @@ -12,156 +11,81 @@ ColumnLayout { readonly property real trackHeight: knobDiameter * 0.5 readonly property real cutoutExtra: Style.baseWidgetSize * 0.1 * scaling - property string label: "" - property string description: "" - property string valueSuffix: "" - property real from: 0.0 - property real to: 1.0 - property real stepSize: 0.01 - property real value: 0.0 - // Optional color to cut the track beneath the knob (should match surrounding background) property var cutoutColor property var screen property bool snapAlways: true - signal pressedChanged(bool pressed, real value) - signal moved(real value) + snapMode: snapAlways ? Slider.SnapAlways : Slider.SnapOnRelease + implicitHeight: Math.max(trackHeight, knobDiameter) - Layout.fillWidth: true - spacing: Style.marginSmall * scaling + background: Rectangle { + x: root.leftPadding + y: root.topPadding + root.availableHeight / 2 - height / 2 + implicitWidth: Style.sliderWidth + implicitHeight: trackHeight + width: root.availableWidth + height: implicitHeight + radius: height / 2 + color: Colors.surfaceVariant - RowLayout { - Layout.fillWidth: true - - ColumnLayout { - spacing: Style.marginTiniest * scaling - - NText { - text: label - font.pointSize: Style.fontSizeMedium * scaling - font.weight: Style.fontWeightBold - color: Colors.textPrimary - Layout.fillWidth: true - } - - NText { - text: description - font.pointSize: Style.fontSizeSmall * scaling - color: Colors.textSecondary - wrapMode: Text.WordWrap - } + Rectangle { + id: activeTrack + width: root.visualPosition * parent.width + height: parent.height + color: Colors.accentPrimary + radius: parent.radius } - NText { - text: { - var v - if (Number.isInteger(value)) { - v = value - } else { - v = value.toFixed(2) - } - - if (valueSuffix != "") { - return v + valueSuffix - } else { - return v - } - } - font.pointSize: Style.fontSizeMedium * scaling - font.weight: Style.fontWeightBold - color: Colors.textPrimary - Layout.alignment: Qt.AlignBottom | Qt.AlignRight + // Circular cutout + Rectangle { + id: knobCutout + width: knobDiameter + cutoutExtra + height: knobDiameter + cutoutExtra + radius: width / 2 + color: root.cutoutColor !== undefined ? root.cutoutColor : Colors.backgroundPrimary + x: Math.max(0, Math.min(parent.width - width, + root.visualPosition * (parent.width - root.knobDiameter) - cutoutExtra / 2)) + y: (parent.height - height) / 2 } } - Slider { - id: slider + handle: Item { + width: knob.implicitWidth + height: knob.implicitHeight + x: root.leftPadding + root.visualPosition * (root.availableWidth - width) + y: root.topPadding + root.availableHeight / 2 - height / 2 - Layout.fillWidth: true - from: root.from - to: root.to - stepSize: root.stepSize - value: root.value - snapMode: snapAlways ? Slider.SnapAlways : Slider.SnapOnRelease - implicitWidth: root.width - implicitHeight: Math.max(trackHeight, knobDiameter) - onPressedChanged: { - root.pressedChanged(slider.pressed, slider.value) - } - onMoved: { - root.value = slider.value - root.moved(value) + // Subtle shadow for a more polished look (keeps theme colors) + MultiEffect { + anchors.fill: knob + source: knob + shadowEnabled: true + shadowColor: Colors.shadow + shadowOpacity: 0.25 + shadowHorizontalOffset: 0 + shadowVerticalOffset: 1 + shadowBlur: 8 } - background: Rectangle { - x: slider.leftPadding - y: slider.topPadding + slider.availableHeight / 2 - height / 2 - implicitWidth: Style.sliderWidth - implicitHeight: trackHeight - width: slider.availableWidth - height: implicitHeight - radius: height / 2 - color: Colors.surfaceVariant + Rectangle { + id: knob + implicitWidth: knobDiameter + implicitHeight: knobDiameter + radius: width * 0.5 + color: root.pressed ? Colors.surfaceVariant : Colors.surface + border.color: Colors.accentPrimary + border.width: Math.max(1, Style.borderThick * scaling) + // Press feedback halo (using accent color, low opacity) Rectangle { - id: activeTrack - width: slider.visualPosition * parent.width - height: parent.height - color: Colors.accentPrimary - radius: parent.radius - } - - // Circular cutout - Rectangle { - id: knobCutout - width: knobDiameter + cutoutExtra - height: knobDiameter + cutoutExtra + anchors.centerIn: parent + width: parent.width + 8 * scaling + height: parent.height + 8 * scaling radius: width / 2 - color: slider.cutoutColor !== undefined ? slider.cutoutColor : Colors.backgroundPrimary - x: Math.max(0, Math.min(parent.width - width, - slider.visualPosition * (parent.width - knobDiameter) - cutoutExtra / 2)) - y: (parent.height - height) / 2 - } - } - - handle: Item { - width: knob.implicitWidth - height: knob.implicitHeight - x: slider.leftPadding + slider.visualPosition * (slider.availableWidth - width) - y: slider.topPadding + slider.availableHeight / 2 - height / 2 - - // Subtle shadow for a more polished look (keeps theme colors) - MultiEffect { - anchors.fill: knob - source: knob - shadowEnabled: true - shadowColor: Colors.shadow - shadowOpacity: 0.25 - shadowHorizontalOffset: 0 - shadowVerticalOffset: 1 - shadowBlur: 8 - } - - Rectangle { - id: knob - implicitWidth: knobDiameter - implicitHeight: knobDiameter - radius: width * 0.5 - color: slider.pressed ? Colors.surfaceVariant : Colors.surface - border.color: Colors.accentPrimary - border.width: Math.max(1, Style.borderThick * scaling) - - // Press feedback halo (using accent color, low opacity) - Rectangle { - anchors.centerIn: parent - width: parent.width + 8 * scaling - height: parent.height + 8 * scaling - radius: width / 2 - color: Colors.accentPrimary - opacity: slider.pressed ? 0.16 : 0.0 - } + color: Colors.accentPrimary + opacity: root.pressed ? 0.16 : 0.0 } } } -} +} \ No newline at end of file