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 {
|
ColumnLayout {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
|
property var screen
|
||||||
|
|
||||||
property string label: ""
|
property string label: ""
|
||||||
property string description: ""
|
property string description: ""
|
||||||
property bool value: false
|
property bool value: false
|
||||||
|
|
|
||||||
|
|
@ -82,6 +82,7 @@ Singleton {
|
||||||
property var barMonitors: [] // Array of monitor names to show the bar on
|
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 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 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
|
// Automatic scaling based on screen width
|
||||||
function scale(currentScreen) {
|
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;
|
var ratio = currentScreen.width / designScreenWidth;
|
||||||
// Limit the final scale range between [0.8...2]
|
// Limit the final scale range between [0.8...2]
|
||||||
return Math.max(0.8, Math.min(2.0, ratio));
|
return Math.max(0.8, Math.min(2.0, ratio));
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ import QtQuick.Layouts
|
||||||
import Quickshell
|
import Quickshell
|
||||||
import qs.Components
|
import qs.Components
|
||||||
import qs.Settings
|
import qs.Settings
|
||||||
|
import qs.Components
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
id: root
|
id: root
|
||||||
|
|
@ -417,6 +418,38 @@ ColumnLayout {
|
||||||
Settings.settings.notificationMonitors = monitors;
|
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
|
id: intervalSlider
|
||||||
|
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
from: 10
|
from: 10
|
||||||
to: 900
|
to: 900
|
||||||
stepSize: 10
|
stepSize: 10
|
||||||
value: Settings.settings.wallpaperInterval
|
value: Settings.settings.wallpaperInterval
|
||||||
snapMode: Slider.SnapAlways
|
snapAlways: true
|
||||||
onMoved: {
|
onMoved: {
|
||||||
Settings.settings.wallpaperInterval = Math.round(value);
|
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
|
id: fpsSlider
|
||||||
|
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
from: 30
|
from: 30
|
||||||
to: 500
|
to: 500
|
||||||
stepSize: 5
|
stepSize: 5
|
||||||
value: Settings.settings.transitionFps
|
value: Settings.settings.transitionFps
|
||||||
snapMode: Slider.SnapAlways
|
snapAlways: true
|
||||||
onMoved: {
|
onMoved: {
|
||||||
Settings.settings.transitionFps = Math.round(value);
|
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
|
id: durationSlider
|
||||||
|
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
from: 0.25
|
from: 0.25
|
||||||
to: 10
|
to: 10
|
||||||
stepSize: 0.05
|
stepSize: 0.05
|
||||||
value: Settings.settings.transitionDuration
|
value: Settings.settings.transitionDuration
|
||||||
snapMode: Slider.SnapAlways
|
snapAlways: true
|
||||||
onMoved: {
|
onMoved: {
|
||||||
Settings.settings.transitionDuration = value;
|
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