Merge branch 'dev' of github.com:Ly-sec/Noctalia into dev
This commit is contained in:
commit
54b531586a
6 changed files with 97 additions and 103 deletions
45
Components/ThemedSlider.qml
Normal file
45
Components/ThemedSlider.qml
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import qs.Settings
|
||||
|
||||
// Reusable themed slider styled like the sliders in Wallpaper.qml
|
||||
Slider {
|
||||
id: slider
|
||||
|
||||
// Optional monitor screen for scaling context
|
||||
property var screen
|
||||
// Convenience flag mirroring Wallpaper sliders
|
||||
property bool snapAlways: true
|
||||
|
||||
snapMode: snapAlways ? Slider.SnapAlways : Slider.SnapOnRelease
|
||||
|
||||
background: Rectangle {
|
||||
x: slider.leftPadding
|
||||
y: slider.topPadding + slider.availableHeight / 2 - height / 2
|
||||
implicitWidth: 200
|
||||
implicitHeight: 4 * Theme.scale(screen)
|
||||
width: slider.availableWidth
|
||||
height: implicitHeight
|
||||
radius: height / 2
|
||||
color: Theme.surfaceVariant
|
||||
|
||||
Rectangle {
|
||||
width: slider.visualPosition * parent.width
|
||||
height: parent.height
|
||||
color: Theme.accentPrimary
|
||||
radius: parent.radius
|
||||
}
|
||||
}
|
||||
|
||||
handle: Rectangle {
|
||||
x: slider.leftPadding + slider.visualPosition * (slider.availableWidth - width)
|
||||
y: slider.topPadding + slider.availableHeight / 2 - height / 2
|
||||
implicitWidth: 20 * Theme.scale(screen)
|
||||
implicitHeight: 20 * Theme.scale(screen)
|
||||
radius: width / 2
|
||||
color: slider.pressed ? Theme.surfaceVariant : Theme.surface
|
||||
border.color: Theme.accentPrimary
|
||||
border.width: 2 * Theme.scale(screen)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -7,6 +7,8 @@ import qs.Settings
|
|||
ColumnLayout {
|
||||
id: root
|
||||
|
||||
property var screen
|
||||
|
||||
property string label: ""
|
||||
property string description: ""
|
||||
property bool value: false
|
||||
|
|
|
|||
|
|
@ -82,6 +82,7 @@ Singleton {
|
|||
property var barMonitors: [] // Array of monitor names to show the bar on
|
||||
property var dockMonitors: [] // Array of monitor names to show the dock on
|
||||
property var notificationMonitors: [] // Array of monitor names to show notifications on, "*" means all monitors
|
||||
property var monitorScaleOverrides: {} // Map of monitor name -> scale override (e.g., 0.8..2.0). When set, Theme.scale() returns this value
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -13,7 +13,16 @@ Singleton {
|
|||
|
||||
// Automatic scaling based on screen width
|
||||
function scale(currentScreen) {
|
||||
if (currentScreen.width != 0) {
|
||||
// Per-monitor override from settings
|
||||
try {
|
||||
const overrides = Settings.settings.monitorScaleOverrides || {};
|
||||
if (currentScreen && currentScreen.name && overrides[currentScreen.name] !== undefined) {
|
||||
return overrides[currentScreen.name];
|
||||
}
|
||||
} catch (e) {
|
||||
// ignore
|
||||
}
|
||||
if (currentScreen && currentScreen.width != 0) {
|
||||
var ratio = currentScreen.width / designScreenWidth;
|
||||
// Limit the final scale range between [0.8...2]
|
||||
return Math.max(0.8, Math.min(2.0, ratio));
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import QtQuick.Layouts
|
|||
import Quickshell
|
||||
import qs.Components
|
||||
import qs.Settings
|
||||
import qs.Components
|
||||
|
||||
ColumnLayout {
|
||||
id: root
|
||||
|
|
@ -417,6 +418,38 @@ ColumnLayout {
|
|||
Settings.settings.notificationMonitors = monitors;
|
||||
}
|
||||
}
|
||||
|
||||
// Scale slider
|
||||
ColumnLayout {
|
||||
Layout.fillWidth: true
|
||||
spacing: 4 * Theme.scale(screen)
|
||||
Text { text: "Scale"; color: Theme.textSecondary; font.pixelSize: 10 * Theme.scale(screen) }
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
spacing: 8 * Theme.scale(screen)
|
||||
// Value read from settings override, default to Theme.scale(modelData)
|
||||
property real currentValue: (Settings.settings.monitorScaleOverrides && Settings.settings.monitorScaleOverrides[monitorCard.monitorName] !== undefined) ? Settings.settings.monitorScaleOverrides[monitorCard.monitorName] : Theme.scale(modelData)
|
||||
// Reusable slider component (exact style from Wallpaper.qml)
|
||||
ThemedSlider {
|
||||
id: scaleSlider
|
||||
Layout.fillWidth: true
|
||||
screen: modelData
|
||||
from: 0.8
|
||||
to: 2.0
|
||||
stepSize: 0.05
|
||||
snapAlways: true
|
||||
value: parent.currentValue
|
||||
onValueChanged: {
|
||||
let overrides = Settings.settings.monitorScaleOverrides || {};
|
||||
overrides = Object.assign({}, overrides);
|
||||
overrides[monitorCard.monitorName] = value;
|
||||
Settings.settings.monitorScaleOverrides = overrides;
|
||||
parent.currentValue = value;
|
||||
}
|
||||
}
|
||||
Text { text: parent.currentValue.toFixed(2); font.pixelSize: 12 * Theme.scale(screen); color: Theme.textPrimary; width: 36 }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -197,49 +197,17 @@ ColumnLayout {
|
|||
|
||||
}
|
||||
|
||||
Slider {
|
||||
ThemedSlider {
|
||||
id: intervalSlider
|
||||
|
||||
Layout.fillWidth: true
|
||||
from: 10
|
||||
to: 900
|
||||
stepSize: 10
|
||||
value: Settings.settings.wallpaperInterval
|
||||
snapMode: Slider.SnapAlways
|
||||
snapAlways: true
|
||||
onMoved: {
|
||||
Settings.settings.wallpaperInterval = Math.round(value);
|
||||
}
|
||||
|
||||
background: Rectangle {
|
||||
x: intervalSlider.leftPadding
|
||||
y: intervalSlider.topPadding + intervalSlider.availableHeight / 2 - height / 2
|
||||
implicitWidth: 200
|
||||
implicitHeight: 4
|
||||
width: intervalSlider.availableWidth
|
||||
height: implicitHeight
|
||||
radius: 2
|
||||
color: Theme.surfaceVariant
|
||||
|
||||
Rectangle {
|
||||
width: intervalSlider.visualPosition * parent.width
|
||||
height: parent.height
|
||||
color: Theme.accentPrimary
|
||||
radius: 2
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
handle: Rectangle {
|
||||
x: intervalSlider.leftPadding + intervalSlider.visualPosition * (intervalSlider.availableWidth - width)
|
||||
y: intervalSlider.topPadding + intervalSlider.availableHeight / 2 - height / 2
|
||||
implicitWidth: 20
|
||||
implicitHeight: 20
|
||||
radius: 10
|
||||
color: intervalSlider.pressed ? Theme.surfaceVariant : Theme.surface
|
||||
border.color: Theme.accentPrimary
|
||||
border.width: 2
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -529,49 +497,17 @@ ColumnLayout {
|
|||
|
||||
}
|
||||
|
||||
Slider {
|
||||
ThemedSlider {
|
||||
id: fpsSlider
|
||||
|
||||
Layout.fillWidth: true
|
||||
from: 30
|
||||
to: 500
|
||||
stepSize: 5
|
||||
value: Settings.settings.transitionFps
|
||||
snapMode: Slider.SnapAlways
|
||||
snapAlways: true
|
||||
onMoved: {
|
||||
Settings.settings.transitionFps = Math.round(value);
|
||||
}
|
||||
|
||||
background: Rectangle {
|
||||
x: fpsSlider.leftPadding
|
||||
y: fpsSlider.topPadding + fpsSlider.availableHeight / 2 - height / 2
|
||||
implicitWidth: 200
|
||||
implicitHeight: 4
|
||||
width: fpsSlider.availableWidth
|
||||
height: implicitHeight
|
||||
radius: 2
|
||||
color: Theme.surfaceVariant
|
||||
|
||||
Rectangle {
|
||||
width: fpsSlider.visualPosition * parent.width
|
||||
height: parent.height
|
||||
color: Theme.accentPrimary
|
||||
radius: 2
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
handle: Rectangle {
|
||||
x: fpsSlider.leftPadding + fpsSlider.visualPosition * (fpsSlider.availableWidth - width)
|
||||
y: fpsSlider.topPadding + fpsSlider.availableHeight / 2 - height / 2
|
||||
implicitWidth: 20
|
||||
implicitHeight: 20
|
||||
radius: 10
|
||||
color: fpsSlider.pressed ? Theme.surfaceVariant : Theme.surface
|
||||
border.color: Theme.accentPrimary
|
||||
border.width: 2
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -612,49 +548,17 @@ ColumnLayout {
|
|||
|
||||
}
|
||||
|
||||
Slider {
|
||||
ThemedSlider {
|
||||
id: durationSlider
|
||||
|
||||
Layout.fillWidth: true
|
||||
from: 0.25
|
||||
to: 10
|
||||
stepSize: 0.05
|
||||
value: Settings.settings.transitionDuration
|
||||
snapMode: Slider.SnapAlways
|
||||
snapAlways: true
|
||||
onMoved: {
|
||||
Settings.settings.transitionDuration = value;
|
||||
}
|
||||
|
||||
background: Rectangle {
|
||||
x: durationSlider.leftPadding
|
||||
y: durationSlider.topPadding + durationSlider.availableHeight / 2 - height / 2
|
||||
implicitWidth: 200
|
||||
implicitHeight: 4
|
||||
width: durationSlider.availableWidth
|
||||
height: implicitHeight
|
||||
radius: 2
|
||||
color: Theme.surfaceVariant
|
||||
|
||||
Rectangle {
|
||||
width: durationSlider.visualPosition * parent.width
|
||||
height: parent.height
|
||||
color: Theme.accentPrimary
|
||||
radius: 2
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
handle: Rectangle {
|
||||
x: durationSlider.leftPadding + durationSlider.visualPosition * (durationSlider.availableWidth - width)
|
||||
y: durationSlider.topPadding + durationSlider.availableHeight / 2 - height / 2
|
||||
implicitWidth: 20
|
||||
implicitHeight: 20
|
||||
radius: 10
|
||||
color: durationSlider.pressed ? Theme.surfaceVariant : Theme.surface
|
||||
border.color: Theme.accentPrimary
|
||||
border.width: 2
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue