diff --git a/.gitea/workflows/python.yml b/.gitea/workflows/python.yml index 2baf3ed..011ba51 100644 --- a/.gitea/workflows/python.yml +++ b/.gitea/workflows/python.yml @@ -97,7 +97,7 @@ jobs: py3-pip python3 -m venv .venv . .venv/bin/activate - pip install --no-cache-dir basedpyright + pip install --no-cache-dir basedpyright typer pillow materialyoucolor jinja2 - name: Type check run: | diff --git a/CMakeLists.txt b/CMakeLists.txt index 88f0e3c..bcf8318 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -155,7 +155,7 @@ if("plugin" IN_LIST ENABLE_MODULES) endif() if("shell" IN_LIST ENABLE_MODULES) - foreach(dir assets scripts Components Config Modules Daemons Drawers Effects Helpers Paths) + foreach(dir assets scripts Components Services Modules Daemons Drawers Effects Helpers Paths) install(DIRECTORY ${dir} DESTINATION "${INSTALL_QSCONFDIR}") endforeach() diff --git a/Components/AnchorAnim.qml b/Components/AnchorAnim.qml index 147caf2..ff6657f 100644 --- a/Components/AnchorAnim.qml +++ b/Components/AnchorAnim.qml @@ -1,5 +1,5 @@ import QtQuick -import qs.Config +import ZShell.Config AnchorAnimation { enum Type { @@ -20,32 +20,32 @@ AnchorAnimation { duration: { if (type < AnchorAnim.StandardSmall || type > AnchorAnim.SlowSpatial) - return Appearance.anim.durations.expressiveDefaultSpatial; + return Tokens.anim.durations.expressiveDefaultSpatial; if (type == AnchorAnim.FastSpatial) - return Appearance.anim.durations.expressiveFastSpatial; + return Tokens.anim.durations.expressiveFastSpatial; if (type == AnchorAnim.DefaultSpatial) - return Appearance.anim.durations.expressiveDefaultSpatial; + return Tokens.anim.durations.expressiveDefaultSpatial; if (type == AnchorAnim.SlowSpatial) - return Appearance.anim.durations.large; + return Tokens.anim.durations.large; const types = ["small", "normal", "large", "extraLarge"]; const idx = type % 4; - return Appearance.anim.durations[types[idx]]; + return Tokens.anim.durations[types[idx]]; } easing.bezierCurve: { if (type == AnchorAnim.FastSpatial) - return Appearance.anim.curves.expressiveFastSpatial; + return Tokens.anim.curves.expressiveFastSpatial; if (type == AnchorAnim.DefaultSpatial) - return Appearance.anim.curves.expressiveDefaultSpatial; + return Tokens.anim.curves.expressiveDefaultSpatial; if (type == AnchorAnim.SlowSpatial) - return Appearance.anim.curves.expressiveSlowSpatial; + return Tokens.anim.curves.expressiveSlowSpatial; if (type >= AnchorAnim.StandardSmall && type <= AnchorAnim.StandardExtraLarge) - return Appearance.anim.curves.standard; + return Tokens.anim.curves.standard; if (type >= AnchorAnim.EmphasizedSmall && type <= AnchorAnim.EmphasizedExtraLarge) - return Appearance.anim.curves.emphasized; + return Tokens.anim.curves.emphasized; - return Appearance.anim.curves.expressiveDefaultSpatial; + return Tokens.anim.curves.expressiveDefaultSpatial; } } diff --git a/Components/Anim.qml b/Components/Anim.qml index 6dc33c6..a4f6568 100644 --- a/Components/Anim.qml +++ b/Components/Anim.qml @@ -1,5 +1,5 @@ import QtQuick -import qs.Config +import ZShell.Config NumberAnimation { enum Type { @@ -23,41 +23,41 @@ NumberAnimation { duration: { if (type < Anim.StandardSmall || type > Anim.SlowEffects) - return Appearance.anim.durations.normal; + return Tokens.anim.durations.normal; if (type === Anim.FastSpatial) - return Appearance.anim.durations.expressiveFastSpatial; + return Tokens.anim.durations.expressiveFastSpatial; if (type === Anim.DefaultSpatial) - return Appearance.anim.durations.expressiveDefaultSpatial; + return Tokens.anim.durations.expressiveDefaultSpatial; if (type === Anim.SlowSpatial) - return Appearance.anim.durations.large; + return Tokens.anim.durations.large; if (type === Anim.FastEffects) - return Appearance.anim.durations.expressiveFastEffects; + return Tokens.anim.durations.expressiveFastEffects; if (type === Anim.DefaultEffects) - return Appearance.anim.durations.expressiveEffects; + return Tokens.anim.durations.expressiveEffects; if (type === Anim.SlowEffects) - return Appearance.anim.durations.expressiveSlowEffects; + return Tokens.anim.durations.expressiveSlowEffects; const types = ["small", "normal", "large", "extraLarge"]; const idx = type % 4; - return Appearance.anim.durations[types[idx]]; + return Tokens.anim.durations[types[idx]]; } easing.bezierCurve: { if (type === Anim.FastSpatial) - return Appearance.anim.curves.expressiveFastSpatial; + return Tokens.anim.curves.expressiveFastSpatial; if (type === Anim.DefaultSpatial) - return Appearance.anim.curves.expressiveDefaultSpatial; + return Tokens.anim.curves.expressiveDefaultSpatial; if (type === Anim.SlowSpatial) - return Appearance.anim.curves.expressiveSlowSpatial; + return Tokens.anim.curves.expressiveSlowSpatial; if (type === Anim.FastEffects) - return Appearance.anim.curves.expressiveFastEffects; + return Tokens.anim.curves.expressiveFastEffects; if (type === Anim.DefaultEffects) - return Appearance.anim.curves.expressiveDefaultEffects; + return Tokens.anim.curves.expressiveDefaultEffects; if (type === Anim.SlowEffects) - return Appearance.anim.curves.expressiveSlowEffects; + return Tokens.anim.curves.expressiveSlowEffects; if (type >= Anim.EmphasizedSmall && type <= Anim.EmphasizedExtraLarge) - return Appearance.anim.curves.emphasized; - return Appearance.anim.curves.standard; + return Tokens.anim.curves.emphasized; + return Tokens.anim.curves.standard; } } diff --git a/Components/BaseStyledSlider.qml b/Components/BaseStyledSlider.qml index efdacad..ac14d1d 100644 --- a/Components/BaseStyledSlider.qml +++ b/Components/BaseStyledSlider.qml @@ -1,11 +1,12 @@ import QtQuick import QtQuick.Templates -import qs.Config +import ZShell.Config +import qs.Services Slider { id: root - property color color: DynamicColors.palette.m3secondary + property color color: Colors.palette.m3secondary required property string icon property bool initialized: false readonly property bool isHorizontal: orientation === Qt.Horizontal @@ -19,9 +20,9 @@ Slider { background: CustomRect { id: groove - color: DynamicColors.layer(DynamicColors.palette.m3surfaceContainer, 2) + color: Colors.layer(Colors.palette.m3surfaceContainer, 2) height: root.availableHeight - radius: Appearance.rounding.full + radius: Tokens.rounding.full width: root.availableWidth x: root.leftPadding y: root.topPadding @@ -62,8 +63,8 @@ Slider { id: rect anchors.fill: parent - color: DynamicColors.palette.m3inverseSurface - radius: Appearance.rounding.full + color: Colors.palette.m3inverseSurface + radius: Tokens.rounding.full MouseArea { id: handleInteraction @@ -82,12 +83,12 @@ Slider { function update(): void { animate = !moving; binding.when = moving; - font.pointSize = moving ? Appearance.font.size.small : Appearance.font.size.larger; - font.family = moving ? Appearance.font.family.sans : Appearance.font.family.material; + font.pointSize = moving ? Tokens.font.size.small : Tokens.font.size.larger; + font.family = moving ? Config.appearance.font.family.sans : Config.appearance.font.family.material; } anchors.centerIn: parent - color: DynamicColors.palette.m3inverseOnSurface + color: Colors.palette.m3inverseOnSurface text: root.icon onMovingChanged: anim.restart() @@ -105,8 +106,8 @@ Slider { id: anim Anim { - duration: Appearance.anim.durations.normal / 2 - easing.bezierCurve: Appearance.anim.curves.standardAccel + duration: Tokens.anim.durations.normal / 2 + easing.bezierCurve: Tokens.anim.curves.standardAccel property: "scale" target: icon to: 0 @@ -117,8 +118,8 @@ Slider { } Anim { - duration: Appearance.anim.durations.normal / 2 - easing.bezierCurve: Appearance.anim.curves.standardDecel + duration: Tokens.anim.durations.normal / 2 + easing.bezierCurve: Tokens.anim.curves.standardDecel property: "scale" target: icon to: 1 @@ -129,7 +130,7 @@ Slider { } Behavior on value { Anim { - duration: Appearance.anim.durations.large + duration: Tokens.anim.durations.large } } diff --git a/Components/ButtonBase.qml b/Components/ButtonBase.qml index 58f7aca..2e17634 100644 --- a/Components/ButtonBase.qml +++ b/Components/ButtonBase.qml @@ -1,5 +1,6 @@ import QtQuick -import qs.Config +import ZShell.Config +import qs.Services CustomRect { id: root @@ -13,14 +14,14 @@ CustomRect { property color activeColor property color activeOnColor property bool checked - property real checkedRadius: Appearance.rounding.medium + property real checkedRadius: Tokens.rounding.medium property real defaultRadius: Math.min(width, height) / 2 - property color disabledColor: Qt.alpha(DynamicColors.palette.m3onSurface, 0.1) - property color disabledOnColor: Qt.alpha(DynamicColors.palette.m3onSurface, 0.38) + property color disabledColor: Qt.alpha(Colors.palette.m3onSurface, 0.1) + property color disabledOnColor: Qt.alpha(Colors.palette.m3onSurface, 0.38) property bool fillWidth property font font: ({ - family: Appearance.font.family.sans, - pointSize: Appearance.font.size.larger, + family: Config.appearance.font.family.sans, + pointSize: Tokens.font.size.larger, bold: false }) property real horizontalPadding: padding @@ -35,7 +36,7 @@ CustomRect { readonly property color onColor: !enabled ? disabledOnColor : internalChecked ? activeOnColor : inactiveOnColor property real padding readonly property alias pressed: stateLayer.pressed - property real pressedRadius: Appearance.rounding.smallest + property real pressedRadius: Tokens.rounding.smallest readonly property alias radiusAnim: radiusAnim property bool radiusMorph: true property alias shapeMorph: stateLayer.shapeMorph @@ -53,7 +54,7 @@ CustomRect { if (internalChecked) return checkedRadius; if (isRound) - return (height || implicitHeight) / 2 * Math.min(1, Appearance.rounding.scale); + return (height || implicitHeight) / 2 * Math.min(1, Tokens.rounding.scale); return defaultRadius; } diff --git a/Components/CAnim.qml b/Components/CAnim.qml index d5be385..231741f 100644 --- a/Components/CAnim.qml +++ b/Components/CAnim.qml @@ -1,8 +1,63 @@ import QtQuick -import qs.Config +import ZShell.Config ColorAnimation { - duration: MaterialEasing.standardTime - easing.bezierCurve: MaterialEasing.standard - easing.type: Easing.BezierSpline + enum Type { + StandardSmall = 0, + Standard, + StandardLarge, + StandardExtraLarge, + EmphasizedSmall, + Emphasized, + EmphasizedLarge, + EmphasizedExtraLarge, + FastSpatial, + DefaultSpatial, + SlowSpatial, + FastEffects, + DefaultEffects, + SlowEffects + } + + property int type: CAnim.DefaultSpatial + + duration: { + if (type < CAnim.StandardSmall || type > Anim.SlowEffects) + return Tokens.anim.durations.normal; + + if (type === CAnim.FastSpatial) + return Tokens.anim.durations.expressiveFastSpatial; + if (type === CAnim.DefaultSpatial) + return Tokens.anim.durations.expressiveDefaultSpatial; + if (type === CAnim.SlowSpatial) + return Tokens.anim.durations.large; + if (type === CAnim.FastEffects) + return Tokens.anim.durations.expressiveFastEffects; + if (type === CAnim.DefaultEffects) + return Tokens.anim.durations.expressiveEffects; + if (type === CAnim.SlowEffects) + return Tokens.anim.durations.expressiveSlowEffects; + + const types = ["small", "normal", "large", "extraLarge"]; + const idx = type % 4; + return Tokens.anim.durations[types[idx]]; + } + easing.bezierCurve: { + if (type === CAnim.FastSpatial) + return Tokens.anim.curves.expressiveFastSpatial; + if (type === CAnim.DefaultSpatial) + return Tokens.anim.curves.expressiveDefaultSpatial; + if (type === CAnim.SlowSpatial) + return Tokens.anim.curves.expressiveSlowSpatial; + if (type === CAnim.FastEffects) + return Tokens.anim.curves.expressiveFastEffects; + if (type === CAnim.DefaultEffects) + return Tokens.anim.curves.expressiveDefaultEffects; + if (type === CAnim.SlowEffects) + return Tokens.anim.curves.expressiveSlowEffects; + + if (type >= CAnim.EmphasizedSmall && type <= Anim.EmphasizedExtraLarge) + return Tokens.anim.curves.emphasized; + return Tokens.anim.curves.standard; + } } diff --git a/Components/CircularIndicator.qml b/Components/CircularIndicator.qml index 54bc5bd..0bffb7a 100644 --- a/Components/CircularIndicator.qml +++ b/Components/CircularIndicator.qml @@ -1,7 +1,8 @@ +import ZShell.Config +import ZShell.Internal import QtQuick import QtQuick.Templates -import ZShell.Internal -import qs.Config +import qs.Services BusyIndicator { id: root @@ -17,12 +18,12 @@ BusyIndicator { } property int animState - property color bgColor: DynamicColors.palette.m3secondaryContainer - property color fgColor: DynamicColors.palette.m3primary - property real implicitSize: Appearance.font.size.medium * 3 + property color bgColor: Colors.palette.m3secondaryContainer + property color fgColor: Colors.palette.m3primary + property real implicitSize: Tokens.font.size.normal * 3 property real internalStrokeWidth: strokeWidth readonly property alias progress: manager.progress - property real strokeWidth: Appearance.padding.extraSmall + property real strokeWidth: Tokens.padding.small * 0.8 property alias type: manager.indeterminateAnimationType implicitHeight: implicitSize @@ -51,7 +52,7 @@ BusyIndicator { } transitions: Transition { Anim { - duration: manager.completeEndDuration * Appearance.anim.durations.scale + duration: manager.completeEndDuration * Tokens.anim.durations.scale properties: "opacity,internalStrokeWidth" type: Anim.DefaultEffects } @@ -78,7 +79,7 @@ BusyIndicator { } NumberAnimation { - duration: manager.duration * Appearance.anim.durations.scale + duration: manager.duration * Tokens.anim.durations.scale from: 0 loops: Animation.Infinite property: "progress" @@ -88,7 +89,7 @@ BusyIndicator { } NumberAnimation { - duration: manager.completeEndDuration * Appearance.anim.durations.scale + duration: manager.completeEndDuration * Tokens.anim.durations.scale from: 0 property: "completeEndProgress" running: root.animState === CircularIndicator.Completing diff --git a/Components/CircularProgress.qml b/Components/CircularProgress.qml index 9b22cda..a463552 100644 --- a/Components/CircularProgress.qml +++ b/Components/CircularProgress.qml @@ -3,24 +3,25 @@ pragma ComponentBehavior: Bound import QtQuick import QtQuick.Shapes import ZShell.Components -import qs.Config +import ZShell.Config +import qs.Services Item { id: root readonly property real arcRadius: (size - padding - strokeWidth * (1 + waveAmplitude * 2)) / 2 - property color bgColor: DynamicColors.palette.m3secondaryContainer + property color bgColor: Colors.palette.m3secondaryContainer property real clampedVal: Math.max(1 / 360, Math.min(1, isNaN(value) ? 0 : value)) readonly property real dotAngleRad: (startAngle + sweepAngle - gapAngle * (sweepAngle < 360 ? 0 : 1)) * Math.PI / 180 - property color fgColor: DynamicColors.palette.m3primary + property color fgColor: Colors.palette.m3primary readonly property real gapAngle: ((spacing + strokeWidth) / (arcRadius || 1)) * (180 / Math.PI) property alias hasEndIndicator: dot.active property real implicitSize property int padding: 0 readonly property real size: Math.min(width, height) - property int spacing: Appearance.spacing.small + property int spacing: Tokens.spacing.small property int startAngle: -90 - property int strokeWidth: Appearance.padding.small + property int strokeWidth: Tokens.padding.small property int sweepAngle: 360 readonly property real thickness: strokeWidth * (1 + waveAmplitude) * 2 property real value @@ -110,7 +111,7 @@ Item { implicitHeight: Math.min(1, remainingArc.sweepAngle) * Math.min(4, root.strokeWidth) implicitWidth: Math.min(1, remainingArc.sweepAngle) * Math.min(4, root.strokeWidth) opacity: Math.min(1, remainingArc.sweepAngle) - radius: Appearance.rounding.full + radius: Tokens.rounding.full } } } diff --git a/Components/ColorArcPicker.qml b/Components/ColorArcPicker.qml index b200bfb..0a14f32 100644 --- a/Components/ColorArcPicker.qml +++ b/Components/ColorArcPicker.qml @@ -1,7 +1,8 @@ pragma ComponentBehavior: Bound import QtQuick -import qs.Config +import ZShell.Config +import qs.Services Item { id: root @@ -18,9 +19,9 @@ Item { property real lastChromaticHue: 0 readonly property real radius: (Math.min(width, height) - handleSize) / 2 readonly property int segmentCount: 240 - readonly property color thumbColor: DynamicColors.palette.m3inverseSurface - readonly property color thumbContentColor: DynamicColors.palette.m3inverseOnSurface - readonly property color trackColor: DynamicColors.layer(DynamicColors.palette.m3surfaceContainer, 2) + readonly property color thumbColor: Colors.palette.m3inverseSurface + readonly property color thumbContentColor: Colors.palette.m3inverseOnSurface + readonly property color trackColor: Colors.layer(Colors.palette.m3surfaceContainer, 2) function hueToAngle(hue) { return arcStartAngle + arcSweep * hue; @@ -153,8 +154,8 @@ Item { anchors.centerIn: parent color: root.drawing?.drawingState.penColor implicitHeight: implicitWidth - implicitWidth: canvas.height - root.handleSize - Appearance.padding.extraLarge * 2 - radius: Appearance.rounding.full + implicitWidth: canvas.height - root.handleSize - Tokens.padding.extraLarge * 2 + radius: Tokens.rounding.full Behavior on color { enabled: false diff --git a/Components/CustomCheckbox.qml b/Components/CustomCheckbox.qml index a00d407..2366010 100644 --- a/Components/CustomCheckbox.qml +++ b/Components/CustomCheckbox.qml @@ -1,6 +1,7 @@ import QtQuick import QtQuick.Controls -import qs.Config +import ZShell.Config +import qs.Services CheckBox { id: control @@ -18,14 +19,14 @@ CheckBox { indicator: CustomRect { // x: control.leftPadding // y: parent.implicitHeight / 2 - implicitHeight / 2 - border.color: control.checked ? DynamicColors.palette.m3primary : "transparent" - color: DynamicColors.palette.m3surfaceVariant + border.color: control.checked ? Colors.palette.m3primary : "transparent" + color: Colors.palette.m3surfaceVariant implicitHeight: control.checkHeight implicitWidth: control.checkWidth - radius: Appearance.rounding.smallest / 2 + radius: Tokens.rounding.smallest / 2 CustomRect { - color: DynamicColors.palette.m3primary + color: Colors.palette.m3primary implicitHeight: control.checkHeight - (y * 2) implicitWidth: control.checkWidth - (x * 2) radius: 3 diff --git a/Components/CustomProgressBar.qml b/Components/CustomProgressBar.qml index b0e7a4f..c9666f5 100644 --- a/Components/CustomProgressBar.qml +++ b/Components/CustomProgressBar.qml @@ -5,7 +5,8 @@ import QtQuick.Templates import ZShell import ZShell.Components import ZShell.Internal -import qs.Config +import ZShell.Config +import qs.Services ProgressBar { id: root @@ -16,8 +17,8 @@ ProgressBar { Stopped } - property color bgColor: DynamicColors.palette.m3secondaryContainer - property color fgColor: DynamicColors.palette.m3primary + property color bgColor: Colors.palette.m3secondaryContainer + property color fgColor: Colors.palette.m3primary property int indeterminateAnimState: CustomProgressBar.Stopped property real waveAmplitude: 0.5 property int waveDuration: 1000 @@ -64,7 +65,7 @@ ProgressBar { LinearIndicatorManager { id: manager - gap: Appearance.spacing.extraSmall + gap: Tokens.spacing.extraSmall Anim on completeEndProgress { duration: manager.completeEndDuration @@ -94,7 +95,7 @@ ProgressBar { id: remaining anchors.right: parent.right - implicitWidth: parent.width - wave.implicitWidth - Appearance.spacing.extraSmall + implicitWidth: parent.width - wave.implicitWidth - Tokens.spacing.extraSmall } Line { @@ -106,7 +107,7 @@ ProgressBar { color: root.fgColor implicitHeight: implicitSize implicitWidth: implicitSize - radius: Appearance.rounding.full + radius: Tokens.rounding.full Behavior on implicitSize { Anim { @@ -200,7 +201,7 @@ ProgressBar { color: root.bgColor implicitHeight: parent.height implicitWidth: bounds.y - bounds.x - radius: Appearance.rounding.full + radius: Tokens.rounding.full x: bounds.x } component Wave: WavyLine { diff --git a/Components/CustomRadioButton.qml b/Components/CustomRadioButton.qml index 67204d1..aca7899 100644 --- a/Components/CustomRadioButton.qml +++ b/Components/CustomRadioButton.qml @@ -1,11 +1,12 @@ import QtQuick import QtQuick.Templates -import qs.Config +import ZShell.Config +import qs.Services RadioButton { id: root - font.pointSize: Appearance.font.size.normal + font.pointSize: Tokens.font.size.normal implicitHeight: Math.max(implicitIndicatorHeight, implicitContentHeight) implicitWidth: implicitIndicatorWidth + implicitContentWidth + contentItem.anchors.leftMargin @@ -20,12 +21,12 @@ RadioButton { id: outerCircle anchors.verticalCenter: parent.verticalCenter - border.color: root.checked ? DynamicColors.palette.m3primary : DynamicColors.palette.m3onSurfaceVariant + border.color: root.checked ? Colors.palette.m3primary : Colors.palette.m3onSurfaceVariant border.width: 2 color: "transparent" implicitHeight: 16 implicitWidth: 16 - radius: Appearance.rounding.full + radius: Tokens.rounding.full Behavior on border.color { CAnim { @@ -34,7 +35,7 @@ RadioButton { StateLayer { anchors.margins: -7 - color: root.checked ? DynamicColors.palette.m3onSurface : DynamicColors.palette.m3primary + color: root.checked ? Colors.palette.m3onSurface : Colors.palette.m3primary z: -1 onClicked: { @@ -44,10 +45,10 @@ RadioButton { CustomRect { anchors.centerIn: parent - color: Qt.alpha(DynamicColors.palette.m3primary, root.checked ? 1 : 0) + color: Qt.alpha(Colors.palette.m3primary, root.checked ? 1 : 0) implicitHeight: 8 implicitWidth: 8 - radius: Appearance.rounding.full + radius: Tokens.rounding.full } } } diff --git a/Components/CustomScrollBar.qml b/Components/CustomScrollBar.qml index e938599..0159df0 100644 --- a/Components/CustomScrollBar.qml +++ b/Components/CustomScrollBar.qml @@ -1,7 +1,8 @@ import QtQuick import QtQuick.Templates import qs.Helpers -import qs.Config +import ZShell.Config +import qs.Services ScrollBar { id: root @@ -17,7 +18,7 @@ ScrollBar { readonly property real travelScale: root.rawTravel > 0 ? root.effectiveTravel / root.rawTravel : 0 enabled: !Visibilities.getForActive().isDrawing - implicitWidth: Appearance.padding.extraSmall * 2 + implicitWidth: Tokens.padding.extraSmall * 2 contentItem: Item { } @@ -51,15 +52,15 @@ ScrollBar { anchors.right: parent.right anchors.top: parent.top implicitWidth: handle.implicitWidth - radius: Appearance.rounding.full + radius: Tokens.rounding.full CustomRect { id: handle anchors.right: parent.right - color: DynamicColors.palette.m3secondary + color: Colors.palette.m3secondary implicitHeight: root.height * root.effectiveSize - implicitWidth: fullMouse.pressed || fullMouse.containsMouse ? Appearance.padding.extraSmall * 2 : Appearance.padding.extraSmall + implicitWidth: fullMouse.pressed || fullMouse.containsMouse ? Tokens.padding.extraSmall * 2 : Tokens.padding.extraSmall opacity: { if (!root.enabled) return 0; @@ -73,7 +74,7 @@ ScrollBar { return 0.6; return 0; } - radius: Appearance.rounding.full + radius: Tokens.rounding.full y: root.reversed ? root.height * (1 + root.nonAnimY) * root.travelScale : root.height * root.nonAnimY * root.travelScale Behavior on implicitWidth { diff --git a/Components/CustomSlider.qml b/Components/CustomSlider.qml index f7be430..755d21f 100644 --- a/Components/CustomSlider.qml +++ b/Components/CustomSlider.qml @@ -5,20 +5,21 @@ import QtQuick.Templates import ZShell.Components import ZShell import qs.Components -import qs.Config +import ZShell.Config +import qs.Services Slider { id: root property bool animateWave - property color bgColor: enabled ? DynamicColors.palette.m3secondaryContainer : Qt.alpha(DynamicColors.palette.m3onSurface, 0.1) - property color fgColor: enabled ? DynamicColors.palette.m3primary : Qt.alpha(DynamicColors.palette.m3onSurface, 0.38) + property color bgColor: enabled ? Colors.palette.m3secondaryContainer : Qt.alpha(Colors.palette.m3onSurface, 0.1) + property color fgColor: enabled ? Colors.palette.m3primary : Qt.alpha(Colors.palette.m3onSurface, 0.38) property real filledWidth property alias inset: inset - property color insetColor: enabled ? (inset.attached ? DynamicColors.palette.m3onSecondaryContainer : DynamicColors.palette.m3onPrimary) : DynamicColors.palette.m3onSurface + property color insetColor: enabled ? (inset.attached ? Colors.palette.m3onSecondaryContainer : Colors.palette.m3onPrimary) : Colors.palette.m3onSurface property string insetIcon: "" property real pos: visualPosition - property int radius: Appearance.rounding.small + property int radius: Tokens.rounding.small property int waveDuration: 1000 property real waveFrequency: 6 property bool wavy @@ -35,15 +36,15 @@ Slider { id: remaining anchors.left: handle.right - anchors.leftMargin: Appearance.spacing.extraSmall + anchors.leftMargin: Tokens.spacing.extraSmall anchors.right: parent.right anchors.verticalCenter: parent.verticalCenter - bottomLeftRadius: Appearance.rounding.extraSmall / 2 + bottomLeftRadius: Tokens.rounding.extraSmall / 2 color: root.bgColor implicitHeight: parent.height * (parent.height <= 12 ? opacity : Math.min(opacity * 2, 1)) opacity: Math.min(width, 12) / 12 radius: root.radius - topLeftRadius: Appearance.rounding.extraSmall / 2 + topLeftRadius: Tokens.rounding.extraSmall / 2 } CustomRect { @@ -54,14 +55,14 @@ Slider { implicitHeight: 4 * remaining.opacity implicitWidth: implicitHeight opacity: remaining.opacity - radius: Appearance.rounding.full + radius: Tokens.rounding.full } CustomRect { id: handle anchors.left: filled.right - anchors.leftMargin: Appearance.spacing.extraSmall + anchors.leftMargin: Tokens.spacing.extraSmall anchors.verticalCenter: parent.verticalCenter color: root.fgColor implicitHeight: { @@ -70,7 +71,7 @@ Slider { return parent.height * (mouse.pressed ? lerp(3.5, 1.5) : lerp(3, 1.2)); } implicitWidth: 4 - radius: Appearance.rounding.full + radius: Tokens.rounding.full Behavior on implicitHeight { Anim { @@ -91,17 +92,17 @@ Slider { MaterialIcon { id: inset - readonly property bool attached: root.width ? (root.width - handle.implicitWidth - handle.anchors.leftMargin) * root.pos < inset.paintedWidth + Appearance.spacing.extraSmall * 2 : false + readonly property bool attached: root.width ? (root.width - handle.implicitWidth - handle.anchors.leftMargin) * root.pos < inset.paintedWidth + Tokens.spacing.extraSmall * 2 : false property real dockT: attached ? 1 : 0 anchors.bottom: parent.bottom anchors.top: parent.top color: root.insetColor - font.pixelSize: Appearance.font.size.smaller * 2 + font.pixelSize: Tokens.font.size.smaller * 2 text: root.insetIcon verticalAlignment: Text.AlignVCenter visible: !root.wavy && root.insetIcon !== "" - x: Appearance.spacing.extraSmall + dockT * (handle.x + Appearance.spacing.small) + x: Tokens.spacing.extraSmall + dockT * (handle.x + Tokens.spacing.small) Behavior on dockT { Anim { @@ -113,12 +114,12 @@ Slider { id: lineComp CustomRect { - bottomRightRadius: Appearance.rounding.extraSmall / 2 + bottomRightRadius: Tokens.rounding.extraSmall / 2 color: root.fgColor implicitHeight: root.height implicitWidth: root.filledWidth radius: root.radius - topRightRadius: Appearance.rounding.extraSmall / 2 + topRightRadius: Tokens.rounding.extraSmall / 2 } } diff --git a/Components/CustomSpinBox.qml b/Components/CustomSpinBox.qml index 0b8f9bd..ee46fbc 100644 --- a/Components/CustomSpinBox.qml +++ b/Components/CustomSpinBox.qml @@ -1,6 +1,7 @@ import QtQuick import QtQuick.Templates -import qs.Config +import ZShell.Config +import qs.Services DoubleSpinBox { id: root @@ -29,36 +30,36 @@ DoubleSpinBox { editable: true implicitHeight: Math.max(up.indicator.implicitHeight, down.indicator.implicitHeight, contentItem.implicitHeight) + topPadding + bottomPadding implicitWidth: contentItem.implicitWidth + leftPadding + rightPadding - leftPadding: up.indicator.implicitWidth + Appearance.spacing.extraSmall / 2 - rightPadding: down.indicator.implicitWidth + Appearance.spacing.extraSmall / 2 - spacing: Appearance.spacing.small + leftPadding: up.indicator.implicitWidth + Tokens.spacing.extraSmall / 2 + rightPadding: down.indicator.implicitWidth + Tokens.spacing.extraSmall / 2 + spacing: Tokens.spacing.small contentItem: TextFieldBase { horizontalAlignment: TextField.AlignHCenter implicitWidth: 65 inputMethodHints: Qt.ImhFormattedNumbersOnly - leftPadding: Appearance.padding.larger + leftPadding: Tokens.padding.larger readOnly: !root.editable - rightPadding: Appearance.padding.larger + rightPadding: Tokens.padding.larger text: root.textFromValue(root.value, root.locale) validator: root.validator background: CustomRect { - color: DynamicColors.layer(DynamicColors.palette.m3surfaceContainerHighest, root.cLayer) - radius: Appearance.rounding.extraSmall + color: Colors.layer(Colors.palette.m3surfaceContainerHighest, root.cLayer) + radius: Tokens.rounding.extraSmall } } down.indicator: IconButton { id: downButton - bottomRightRadius: pressed ? Appearance.rounding.small : Appearance.rounding.extraSmall - color: enabled ? DynamicColors.layer(DynamicColors.palette.m3surfaceContainerHighest, root.cLayer) : disabledColor - disabledColor: Qt.alpha(DynamicColors.palette.m3surfaceContainerHighest, 0.4) + bottomRightRadius: pressed ? Tokens.rounding.small : Tokens.rounding.extraSmall + color: enabled ? Colors.layer(Colors.palette.m3surfaceContainerHighest, root.cLayer) : disabledColor + disabledColor: Qt.alpha(Colors.palette.m3surfaceContainerHighest, 0.4) icon: "remove" isRound: true label.anchors.horizontalCenterOffset: pressed ? 0 : 2 - padding: Appearance.padding.extraSmall - topRightRadius: pressed ? Appearance.rounding.small : Appearance.rounding.extraSmall + padding: Tokens.padding.extraSmall + topRightRadius: pressed ? Tokens.rounding.small : Tokens.rounding.extraSmall type: IconButton.Text Behavior on bottomRightRadius { @@ -81,14 +82,14 @@ DoubleSpinBox { id: upButton anchors.right: parent.right - bottomLeftRadius: pressed ? Appearance.rounding.small : Appearance.rounding.extraSmall - color: enabled ? DynamicColors.layer(DynamicColors.palette.m3surfaceContainerHighest, root.cLayer) : disabledColor - disabledColor: Qt.alpha(DynamicColors.palette.m3surfaceContainerHighest, 0.4) + bottomLeftRadius: pressed ? Tokens.rounding.small : Tokens.rounding.extraSmall + color: enabled ? Colors.layer(Colors.palette.m3surfaceContainerHighest, root.cLayer) : disabledColor + disabledColor: Qt.alpha(Colors.palette.m3surfaceContainerHighest, 0.4) icon: "add" isRound: true label.anchors.horizontalCenterOffset: pressed ? 0 : -2 - padding: Appearance.padding.extraSmall - topLeftRadius: pressed ? Appearance.rounding.small : Appearance.rounding.extraSmall + padding: Tokens.padding.extraSmall + topLeftRadius: pressed ? Tokens.rounding.small : Tokens.rounding.extraSmall type: IconButton.Text Behavior on bottomLeftRadius { diff --git a/Components/CustomSplitButton.qml b/Components/CustomSplitButton.qml index 6d90166..6d965b0 100644 --- a/Components/CustomSplitButton.qml +++ b/Components/CustomSplitButton.qml @@ -1,6 +1,7 @@ import QtQuick import QtQuick.Layouts -import qs.Config +import ZShell.Config +import qs.Services Row { id: root @@ -11,14 +12,14 @@ Row { } property alias active: menu.active - property color color: type == CustomSplitButton.Filled ? DynamicColors.palette.m3primary : DynamicColors.palette.m3secondaryContainer - property color disabledColor: Qt.alpha(DynamicColors.palette.m3onSurface, 0.1) - property color disabledTextColor: Qt.alpha(DynamicColors.palette.m3onSurface, 0.38) + property color color: type == CustomSplitButton.Filled ? Colors.palette.m3primary : Colors.palette.m3secondaryContainer + property color disabledColor: Qt.alpha(Colors.palette.m3onSurface, 0.1) + property color disabledTextColor: Qt.alpha(Colors.palette.m3onSurface, 0.38) readonly property alias expandBtn: expandBtn property alias expanded: menu.expanded property string fallbackIcon property string fallbackText - property real horizontalPadding: Appearance.padding.larger + property real horizontalPadding: Tokens.padding.larger readonly property alias iconLabel: iconLabel readonly property alias label: label readonly property alias menu: menu @@ -26,20 +27,20 @@ Row { property bool menuOnTop property real minLeftWidth readonly property alias stateLayer: stateLayer - property color textColor: type == CustomSplitButton.Filled ? DynamicColors.palette.m3onPrimary : DynamicColors.palette.m3onSecondaryContainer + property color textColor: type == CustomSplitButton.Filled ? Colors.palette.m3onPrimary : Colors.palette.m3onSecondaryContainer readonly property alias textRow: textRow property int type: CustomSplitButton.Filled - property real verticalPadding: Appearance.padding.small + property real verticalPadding: Tokens.padding.small - spacing: Math.floor(Appearance.spacing.extraSmall) + spacing: Math.floor(Tokens.spacing.extraSmall) CustomRect { - bottomRightRadius: Appearance.rounding.small / 2 + bottomRightRadius: Tokens.rounding.small / 2 color: !root.enabled ? root.disabledColor : root.color implicitHeight: expandBtn.implicitHeight implicitWidth: Math.max(root.minLeftWidth, textRow.implicitWidth + root.horizontalPadding * 2) - radius: implicitHeight / 2 * Math.min(1, Appearance.rounding.scale) - topRightRadius: Appearance.rounding.small / 2 + radius: implicitHeight / 2 * Math.min(1, Tokens.rounding.scale) + topRightRadius: Tokens.rounding.small / 2 StateLayer { id: stateLayer @@ -57,7 +58,7 @@ Row { anchors.centerIn: parent anchors.horizontalCenterOffset: Math.floor(root.verticalPadding / 4) - spacing: Appearance.spacing.small + spacing: Tokens.spacing.small MaterialIcon { id: iconLabel @@ -91,13 +92,13 @@ Row { CustomRect { id: expandBtn - property real rad: root.expanded ? implicitHeight / 2 * Math.min(1, Appearance.rounding.scale) : Appearance.rounding.small / 2 + property real rad: root.expanded ? implicitHeight / 2 * Math.min(1, Tokens.rounding.scale) : Tokens.rounding.small / 2 bottomLeftRadius: rad color: !root.enabled ? root.disabledColor : root.color implicitHeight: expandIcon.implicitHeight + root.verticalPadding * 2 implicitWidth: implicitHeight - radius: implicitHeight / 2 * Math.min(1, Appearance.rounding.scale) + radius: implicitHeight / 2 * Math.min(1, Tokens.rounding.scale) topLeftRadius: rad Behavior on rad { @@ -141,7 +142,7 @@ Row { attachSideY: root.menuOnTop ? Menu.Top : Menu.Bottom attachTo: expandBtn - marginY: Appearance.spacing.small * (root.menuOnTop ? -1 : 1) + marginY: Tokens.spacing.small * (root.menuOnTop ? -1 : 1) thisSideY: root.menuOnTop ? Menu.Bottom : Menu.Top } } diff --git a/Components/CustomSplitButtonRow.qml b/Components/CustomSplitButtonRow.qml index 11f0c3b..5631606 100644 --- a/Components/CustomSplitButtonRow.qml +++ b/Components/CustomSplitButtonRow.qml @@ -2,7 +2,8 @@ pragma ComponentBehavior: Bound import QtQuick import QtQuick.Layouts -import qs.Config +import ZShell.Config +import qs.Services Item { id: root @@ -21,7 +22,7 @@ Item { anchors.left: parent.left anchors.right: parent.right clip: false - implicitHeight: row.implicitHeight + Appearance.padding.smaller * 2 + implicitHeight: row.implicitHeight + Tokens.padding.smaller * 2 opacity: shouldBeActive ? 1 : 0 scale: shouldBeActive ? 1 : 0.8 z: splitButton.menu.implicitHeight > 0 ? expandedZ : 1 @@ -39,15 +40,15 @@ Item { id: row anchors.left: parent.left - anchors.margins: Appearance.padding.small + anchors.margins: Tokens.padding.small anchors.right: parent.right anchors.verticalCenter: parent.verticalCenter - spacing: Appearance.spacing.normal + spacing: Tokens.spacing.normal CustomText { Layout.fillWidth: true - color: root.enabled ? DynamicColors.palette.m3onSurface : DynamicColors.palette.m3onSurfaceVariant - font.pointSize: Appearance.font.size.larger + color: root.enabled ? Colors.palette.m3onSurface : Colors.palette.m3onSurfaceVariant + font.pointSize: Tokens.font.size.larger text: root.label } diff --git a/Components/CustomSwitch.qml b/Components/CustomSwitch.qml index e715f15..e41e773 100644 --- a/Components/CustomSwitch.qml +++ b/Components/CustomSwitch.qml @@ -1,7 +1,8 @@ import QtQuick import QtQuick.Shapes import QtQuick.Templates -import qs.Config +import ZShell.Config +import qs.Services Switch { id: root @@ -12,20 +13,20 @@ Switch { implicitWidth: implicitIndicatorWidth indicator: CustomRect { - color: root.checked && root.enabled ? DynamicColors.palette.m3primary : DynamicColors.layer(DynamicColors.palette.m3surfaceContainerHighest, root.cLayer) - implicitHeight: Appearance.font.size.medium + Appearance.padding.normal * 2 + color: root.checked && root.enabled ? Colors.palette.m3primary : Colors.layer(Colors.palette.m3surfaceContainerHighest, root.cLayer) + implicitHeight: Tokens.font.size.medium + Tokens.padding.normal * 2 implicitWidth: implicitHeight * 1.7 - radius: Appearance.rounding.full + radius: Tokens.rounding.full CustomRect { readonly property real nonAnimWidth: root.pressed ? implicitHeight * 1.2 : implicitHeight anchors.verticalCenter: parent.verticalCenter - color: root.checked && root.enabled ? DynamicColors.palette.m3onPrimary : DynamicColors.layer(DynamicColors.palette.m3outline, root.cLayer + 1) - implicitHeight: parent.implicitHeight - Appearance.padding.extraSmall + color: root.checked && root.enabled ? Colors.palette.m3onPrimary : Colors.layer(Colors.palette.m3outline, root.cLayer + 1) + implicitHeight: parent.implicitHeight - Tokens.padding.extraSmall implicitWidth: nonAnimWidth - radius: Appearance.rounding.full - x: root.checked ? parent.implicitWidth - nonAnimWidth - Appearance.padding.extraSmall / 2 : Appearance.padding.extraSmall / 2 + radius: Tokens.rounding.full + x: root.checked ? parent.implicitWidth - nonAnimWidth - Tokens.padding.extraSmall / 2 : Tokens.padding.extraSmall / 2 Behavior on implicitWidth { Anim { @@ -40,7 +41,7 @@ Switch { CustomRect { anchors.fill: parent - color: root.checked && root.enabled ? DynamicColors.palette.m3primary : DynamicColors.palette.m3onSurface + color: root.checked && root.enabled ? Colors.palette.m3primary : Colors.palette.m3onSurface opacity: root.pressed ? 0.1 : root.hovered ? 0.08 : 0 radius: parent.radius @@ -91,7 +92,7 @@ Switch { anchors.centerIn: parent asynchronous: true - height: parent.implicitHeight - Appearance.padding.larger + height: parent.implicitHeight - Tokens.padding.larger preferredRendererType: Shape.CurveRenderer width: height @@ -117,8 +118,8 @@ Switch { fillColor: "transparent" startX: icon.start1.x startY: icon.start1.y - strokeColor: root.checked && root.enabled ? DynamicColors.palette.m3primary : DynamicColors.palette.m3surfaceContainerHighest - strokeWidth: Appearance.font.size.larger * 0.15 + strokeColor: root.checked && root.enabled ? Colors.palette.m3primary : Colors.palette.m3surfaceContainerHighest + strokeWidth: Tokens.font.size.larger * 0.15 Behavior on strokeColor { CAnim { @@ -151,7 +152,7 @@ Switch { } component PropAnim: PropertyAnimation { - duration: Appearance.anim.durations.expressiveFastSpatial - easing.bezierCurve: Appearance.anim.curves.expressiveFastSpatial + duration: Tokens.anim.durations.expressiveFastSpatial + easing.bezierCurve: Tokens.anim.curves.expressiveFastSpatial } } diff --git a/Components/CustomText.qml b/Components/CustomText.qml index 8966a79..08ae9ee 100644 --- a/Components/CustomText.qml +++ b/Components/CustomText.qml @@ -1,7 +1,8 @@ pragma ComponentBehavior: Bound import QtQuick -import qs.Config +import ZShell.Config +import qs.Services Text { id: root @@ -12,10 +13,10 @@ Text { property string animateProp: "scale" property real animateTo: 1 - color: DynamicColors.palette.m3onSurface - font.family: Appearance.font.family.sans - font.pointSize: Appearance.font.size.normal - linkColor: DynamicColors.palette.m3onPrimaryFixedVariant + color: Colors.palette.m3onSurface + font.family: Config.appearance.font.family.sans + font.pointSize: Tokens.font.size.normal + linkColor: Colors.palette.m3onPrimaryFixedVariant renderType: Text.NativeRendering textFormat: Text.PlainText diff --git a/Components/CustomTextField.qml b/Components/CustomTextField.qml index 023f265..d9b19c2 100644 --- a/Components/CustomTextField.qml +++ b/Components/CustomTextField.qml @@ -2,7 +2,8 @@ pragma ComponentBehavior: Bound import QtQuick import QtQuick.Shapes -import qs.Config +import ZShell.Config +import qs.Services TextFieldBase { id: root @@ -16,27 +17,27 @@ TextFieldBase { readonly property string effectiveSupportingText: isError && errorText ? errorText : supportingText property bool emptyIsValid: true property string errorText - readonly property int filledOffset: type === CustomTextField.Filled ? Appearance.spacing.small : 0 - readonly property int horizontalPadding: Appearance.padding.large + readonly property int filledOffset: type === CustomTextField.Filled ? Tokens.spacing.small : 0 + readonly property int horizontalPadding: Tokens.padding.large property bool isError property string leadingIcon readonly property int leadingOffset: leadingIcon ? leadingIconLoader.width + leadingIconLoader.anchors.leftMargin : 0 - property int radius: Appearance.rounding.small + property int radius: Tokens.rounding.small property alias sLayer: stateLayer readonly property real smallFontScale: smallFontSize / font.pointSize - property int smallFontSize: Appearance.font.size.small + property int smallFontSize: Tokens.font.size.small property string supportingText - readonly property int supportingTextOffset: effectiveSupportingText ? supportingTextLoader.height + Appearance.spacing.extraSmall : 0 + readonly property int supportingTextOffset: effectiveSupportingText ? supportingTextLoader.height + Tokens.spacing.extraSmall : 0 property string trailingIcon readonly property int trailingOffset: trailingIcon ? trailingIconLoader.width + trailingIconLoader.anchors.rightMargin : 0 property int type: CustomTextField.Outlined readonly property bool valid: !validate || (!text && emptyIsValid) || (validate instanceof RegExp ? validate.test(text) : !!validate(text)) property var validate // Regex or function - bottomPadding: Appearance.padding.large + supportingTextOffset - filledOffset + bottomPadding: Tokens.padding.large + supportingTextOffset - filledOffset leftPadding: horizontalPadding + leadingOffset rightPadding: horizontalPadding + trailingOffset - topPadding: Appearance.padding.large + filledOffset + topPadding: Tokens.padding.large + filledOffset background: Loader { anchors.bottomMargin: root.supportingTextOffset @@ -81,9 +82,9 @@ TextFieldBase { anchors.left: parent.left anchors.leftMargin: root.leftPadding - anchors.topMargin: Appearance.padding.extraSmall + anchors.topMargin: Tokens.padding.extraSmall anchors.verticalCenter: parent.verticalCenter - color: root.isError ? DynamicColors.palette.m3error : (root.activeFocus ? DynamicColors.palette.m3primary : root.text ? DynamicColors.palette.m3outline : root.placeholderTextColor) + color: root.isError ? Colors.palette.m3error : (root.activeFocus ? Colors.palette.m3primary : root.text ? Colors.palette.m3outline : root.placeholderTextColor) font.family: root.font.family font.pointSize: root.font.pointSize font.variableAxes: root.font.variableAxes @@ -129,8 +130,8 @@ TextFieldBase { } AnchorAnim { - duration: Appearance.anim.durations.expressiveEffects - easing.bezierCurve: Appearance.anim.curves.expressiveEffects + duration: Tokens.anim.durations.expressiveEffects + easing.bezierCurve: Tokens.anim.curves.expressiveEffects } } } @@ -140,12 +141,12 @@ TextFieldBase { active: root.leadingIcon anchors.left: parent.left - anchors.leftMargin: Appearance.padding.larger + anchors.leftMargin: Tokens.padding.normal anchors.verticalCenter: parent.verticalCenter sourceComponent: MaterialIcon { - color: DynamicColors.palette.m3onSurfaceVariant - font.pointSize: Appearance.font.size.larger + color: Colors.palette.m3onSurfaceVariant + font.pointSize: Tokens.font.size.larger text: root.leadingIcon } } @@ -155,11 +156,11 @@ TextFieldBase { active: root.trailingIcon anchors.right: parent.right - anchors.rightMargin: Appearance.padding.normal + anchors.rightMargin: Tokens.padding.normal anchors.verticalCenter: parent.verticalCenter sourceComponent: MaterialIcon { - color: DynamicColors.palette.m3onSurfaceVariant + color: Colors.palette.m3onSurfaceVariant text: root.trailingIcon } } @@ -174,8 +175,8 @@ TextFieldBase { anchors.leftMargin: root.horizontalPadding sourceComponent: CustomText { - color: root.isError ? DynamicColors.palette.m3error : DynamicColors.palette.m3onSurfaceVariant - font.pointSize: Appearance.font.size.small + color: root.isError ? Colors.palette.m3error : Colors.palette.m3onSurfaceVariant + font.pointSize: Tokens.font.size.small text: root.effectiveSupportingText } } @@ -197,14 +198,14 @@ TextFieldBase { id: path readonly property real inset: strokeWidth / 2 - readonly property real outlineGap: placeholder.width * root.smallFontScale + Appearance.spacing.small * 2 + readonly property real outlineGap: placeholder.width * root.smallFontScale + Tokens.spacing.small * 2 property real outlineGapScale: root.activeFocus || root.text ? 1 : 0 capStyle: ShapePath.RoundCap fillColor: "transparent" startX: path.inset + root.horizontalPadding - root.clampedRadius + path.outlineGap * (1 - path.outlineGapScale) / 2 + path.outlineGap * path.outlineGapScale startY: path.inset - strokeColor: root.isError ? DynamicColors.palette.m3error : (root.activeFocus ? DynamicColors.palette.m3primary : DynamicColors.palette.m3outline) + strokeColor: root.isError ? Colors.palette.m3error : (root.activeFocus ? Colors.palette.m3primary : Colors.palette.m3outline) strokeWidth: root.activeFocus ? 2 : 1 Behavior on outlineGapScale { @@ -281,7 +282,7 @@ TextFieldBase { id: filledComp CustomRect { - color: root.activeFocus ? DynamicColors.tPalette.m3surfaceContainerHighest : DynamicColors.tPalette.m3surfaceContainerHigh + color: root.activeFocus ? Colors.tPalette.m3surfaceContainerHighest : Colors.tPalette.m3surfaceContainerHigh topLeftRadius: root.clampedRadius topRightRadius: root.clampedRadius @@ -289,7 +290,7 @@ TextFieldBase { anchors.bottom: parent.bottom anchors.left: parent.left anchors.right: parent.right - color: root.isError ? DynamicColors.palette.m3error : (root.activeFocus ? DynamicColors.palette.m3primary : DynamicColors.palette.m3outline) + color: root.isError ? Colors.palette.m3error : (root.activeFocus ? Colors.palette.m3primary : Colors.palette.m3outline) implicitHeight: root.activeFocus ? 2 : 1 Behavior on implicitHeight { diff --git a/Components/CustomTextInput.qml b/Components/CustomTextInput.qml index 25b1eed..7f6e0d2 100644 --- a/Components/CustomTextInput.qml +++ b/Components/CustomTextInput.qml @@ -1,15 +1,16 @@ import QtQuick import QtQuick.Controls -import qs.Config +import ZShell.Config +import qs.Services TextInput { renderType: Text.NativeRendering - selectedTextColor: DynamicColors.palette.m3onSecondaryContainer - selectionColor: DynamicColors.tPalette.colSecondaryContainer + selectedTextColor: Colors.palette.m3onSecondaryContainer + selectionColor: Colors.tPalette.colSecondaryContainer font { - family: Appearance?.font.family.sans ?? "sans-serif" + family: Config.appearance?.font.family.sans ?? "sans-serif" hintingPreference: Font.PreferFullHinting - pixelSize: Appearance?.font.size.normal ?? 15 + pixelSize: Config.appearance?.font.size.normal ?? 15 } } diff --git a/Components/Elevation.qml b/Components/Elevation.qml index bdef51e..31d330d 100644 --- a/Components/Elevation.qml +++ b/Components/Elevation.qml @@ -1,13 +1,14 @@ import QtQuick import QtQuick.Effects -import qs.Config +import ZShell.Config +import qs.Services RectangularShadow { property real dp: [0, 1, 3, 6, 8, 12][level] property int level blur: (dp * 5) ** 0.7 - color: Qt.alpha(DynamicColors.palette.m3shadow, 0.7) + color: Qt.alpha(Colors.palette.m3shadow, 0.7) offset.y: dp / 2 spread: -dp * 0.3 + (dp * 0.1) ** 2 diff --git a/Components/FadeImage.qml b/Components/FadeImage.qml index b72a203..79617aa 100644 --- a/Components/FadeImage.qml +++ b/Components/FadeImage.qml @@ -1,6 +1,6 @@ import QtQuick import Quickshell -import qs.Config +import ZShell.Config Image { id: root diff --git a/Components/FilledSlider.qml b/Components/FilledSlider.qml index d38d1cb..d901662 100644 --- a/Components/FilledSlider.qml +++ b/Components/FilledSlider.qml @@ -1,5 +1,5 @@ import QtQuick -import qs.Config +import ZShell.Config BaseStyledSlider { id: root diff --git a/Components/GradientSlider.qml b/Components/GradientSlider.qml index c19f161..ea60509 100644 --- a/Components/GradientSlider.qml +++ b/Components/GradientSlider.qml @@ -1,5 +1,5 @@ import QtQuick -import qs.Config +import ZShell.Config BaseStyledSlider { id: root diff --git a/Components/IconButton.qml b/Components/IconButton.qml index eef84fd..e853aaa 100644 --- a/Components/IconButton.qml +++ b/Components/IconButton.qml @@ -1,5 +1,6 @@ import QtQuick -import qs.Config +import ZShell.Config +import qs.Services ButtonBase { id: root @@ -7,8 +8,8 @@ ButtonBase { property alias icon: label.text readonly property alias label: label - activeColor: type === IconButton.Filled ? DynamicColors.palette.m3primary : DynamicColors.palette.m3secondary - activeOnColor: type === IconButton.Filled ? DynamicColors.palette.m3onPrimary : type === IconButton.Tonal ? DynamicColors.palette.m3onSecondary : DynamicColors.palette.m3primary + activeColor: type === IconButton.Filled ? Colors.palette.m3primary : Colors.palette.m3secondary + activeOnColor: type === IconButton.Filled ? Colors.palette.m3onPrimary : type === IconButton.Tonal ? Colors.palette.m3onSecondary : Colors.palette.m3primary implicitHeight: { const h = label.implicitHeight + padding * 2; if (h % 2 !== 0) @@ -18,15 +19,15 @@ ButtonBase { implicitWidth: implicitHeight inactiveColor: { if (!isToggle && type === IconButton.Filled) - return DynamicColors.palette.m3primary; - return type === IconButton.Filled ? DynamicColors.tPalette.m3surfaceContainer : DynamicColors.palette.m3secondaryContainer; + return Colors.palette.m3primary; + return type === IconButton.Filled ? Colors.tPalette.m3surfaceContainer : Colors.palette.m3secondaryContainer; } inactiveOnColor: { if (!isToggle && type === IconButton.Filled) - return DynamicColors.palette.m3onPrimary; - return type === IconButton.Tonal ? DynamicColors.palette.m3onSecondaryContainer : DynamicColors.palette.m3onSurfaceVariant; + return Colors.palette.m3onPrimary; + return type === IconButton.Tonal ? Colors.palette.m3onSecondaryContainer : Colors.palette.m3onSurfaceVariant; } - padding: type === IconButton.Text ? Appearance.padding.extraSmall / 2 : Appearance.padding.small + padding: type === IconButton.Text ? Tokens.padding.extraSmall / 2 : Tokens.padding.small MaterialIcon { id: label diff --git a/Components/IconTextButton.qml b/Components/IconTextButton.qml index 0aa93bf..b8c1b3b 100644 --- a/Components/IconTextButton.qml +++ b/Components/IconTextButton.qml @@ -1,6 +1,7 @@ import QtQuick import QtQuick.Layouts -import qs.Config +import ZShell.Config +import qs.Services ButtonBase { id: root @@ -10,34 +11,34 @@ ButtonBase { readonly property alias label: label property alias text: label.text - activeColor: type === TextButton.Filled ? DynamicColors.palette.m3primary : DynamicColors.palette.m3secondary + activeColor: type === TextButton.Filled ? Colors.palette.m3primary : Colors.palette.m3secondary activeOnColor: { if (type === TextButton.Text) - return DynamicColors.palette.m3primary; - return type === TextButton.Filled ? DynamicColors.palette.m3onPrimary : DynamicColors.palette.m3onSecondary; + return Colors.palette.m3primary; + return type === TextButton.Filled ? Colors.palette.m3onPrimary : Colors.palette.m3onSecondary; } - horizontalPadding: Appearance.padding.larger + horizontalPadding: Tokens.padding.larger implicitHeight: row.implicitHeight + verticalPadding * 2 implicitWidth: row.implicitWidth + horizontalPadding * 2 inactiveColor: { if (!isToggle && type === TextButton.Filled) - return DynamicColors.palette.m3primary; - return type === TextButton.Filled ? DynamicColors.tPalette.m3surfaceContainer : DynamicColors.palette.m3secondaryContainer; + return Colors.palette.m3primary; + return type === TextButton.Filled ? Colors.tPalette.m3surfaceContainer : Colors.palette.m3secondaryContainer; } inactiveOnColor: { if (!isToggle && type === TextButton.Filled) - return DynamicColors.palette.m3onPrimary; + return Colors.palette.m3onPrimary; if (type === TextButton.Text) - return DynamicColors.palette.m3primary; - return type === TextButton.Filled ? DynamicColors.palette.m3onSurface : DynamicColors.palette.m3onSecondaryContainer; + return Colors.palette.m3primary; + return type === TextButton.Filled ? Colors.palette.m3onSurface : Colors.palette.m3onSecondaryContainer; } - verticalPadding: Appearance.padding.small + verticalPadding: Tokens.padding.small RowLayout { id: row anchors.centerIn: parent - spacing: Appearance.spacing.small + spacing: Tokens.spacing.small MaterialIcon { id: iconLabel diff --git a/Components/LoadingIndicator.qml b/Components/LoadingIndicator.qml index 94ac1d5..2e1132a 100644 --- a/Components/LoadingIndicator.qml +++ b/Components/LoadingIndicator.qml @@ -1,7 +1,8 @@ import QtQuick import Quickshell import M3Shapes -import qs.Config +import ZShell.Config +import qs.Services MaterialShape { id: root @@ -48,7 +49,7 @@ MaterialShape { return [pos, vel]; } - color: DynamicColors.palette.m3primary + color: Colors.palette.m3primary implicitSize: 38 toShape: shapes[0] diff --git a/Components/MarqueeText.qml b/Components/MarqueeText.qml index 427d381..5f1322c 100644 --- a/Components/MarqueeText.qml +++ b/Components/MarqueeText.qml @@ -1,12 +1,13 @@ import QtQuick -import qs.Config +import ZShell.Config +import qs.Services Item { id: root property alias anim: marqueeAnim property bool animate: false - property color color: DynamicColors.palette.m3onSurface + property color color: Colors.palette.m3onSurface property int fadeStrengthAnimMs: 180 property real fadeStrengthIdle: 0.0 property real fadeStrengthMoving: 1.0 diff --git a/Components/MaterialIcon.qml b/Components/MaterialIcon.qml index 23df7f9..0e81d10 100644 --- a/Components/MaterialIcon.qml +++ b/Components/MaterialIcon.qml @@ -1,11 +1,12 @@ -import qs.Config +import ZShell.Config +import qs.Services CustomText { id: root readonly property list allowed: [20, 24, 40, 48] property real fill: 0 - property int grade: DynamicColors.light ? 0 : -25 + property int grade: Colors.light ? 0 : -25 readonly property int opsz: clampOpsz(optical) property int optical: fontInfo.pixelSize @@ -16,7 +17,7 @@ CustomText { } font.family: "Material Symbols Rounded" - font.pointSize: Appearance.font.size.larger + font.pointSize: Tokens.font.size.larger font.variableAxes: ({ FILL: fill, GRAD: grade, diff --git a/Components/Menu.qml b/Components/Menu.qml index 2d24a0d..449e6de 100644 --- a/Components/Menu.qml +++ b/Components/Menu.qml @@ -3,8 +3,9 @@ pragma ComponentBehavior: Bound import QtQuick import QtQuick.Layouts import Quickshell -import qs.Config +import ZShell.Config import qs.Drawers +import qs.Services MouseArea { id: root @@ -77,7 +78,7 @@ MouseArea { implicitHeight: column.implicitHeight + column.anchors.margins * 2 implicitWidth: Math.max(200, column.implicitWidth + column.anchors.margins * 2) level: 2 - radius: Appearance.rounding.medium + radius: Tokens.rounding.medium x: { watcher.transform; const item = root.attachTo; @@ -107,15 +108,15 @@ MouseArea { CustomRect { anchors.fill: parent - color: DynamicColors.palette.m3surfaceContainerLow + color: Colors.palette.m3surfaceContainerLow radius: parent.radius ColumnLayout { id: column anchors.fill: parent - anchors.margins: Appearance.padding.extraSmall - spacing: Appearance.spacing.extraSmall + anchors.margins: Tokens.padding.extraSmall + spacing: Tokens.spacing.extraSmall Repeater { id: repeater @@ -130,10 +131,10 @@ MouseArea { required property MenuItem modelData Layout.fillWidth: true - color: Qt.alpha(DynamicColors.palette.m3tertiaryContainer, active ? 1 : 0) - implicitHeight: menuOptionRow.implicitHeight + Appearance.padding.larger * 2 - implicitWidth: menuOptionRow.implicitWidth + Appearance.padding.larger * 2 - radius: Appearance.rounding.small + color: Qt.alpha(Colors.palette.m3tertiaryContainer, active ? 1 : 0) + implicitHeight: menuOptionRow.implicitHeight + Tokens.padding.larger * 2 + implicitWidth: menuOptionRow.implicitWidth + Tokens.padding.larger * 2 + radius: Tokens.rounding.small Behavior on radius { Anim { @@ -141,7 +142,7 @@ MouseArea { } StateLayer { - color: item.active ? DynamicColors.palette.m3onTertiaryContainer : DynamicColors.palette.m3onSurface + color: item.active ? Colors.palette.m3onTertiaryContainer : Colors.palette.m3onSurface enabled: root.expanded onClicked: { @@ -156,19 +157,19 @@ MouseArea { id: menuOptionRow anchors.fill: parent - anchors.margins: Appearance.padding.larger - spacing: Appearance.spacing.small + anchors.margins: Tokens.padding.larger + spacing: Tokens.spacing.small MaterialIcon { Layout.alignment: Qt.AlignVCenter - color: item.active ? DynamicColors.palette.m3onTertiaryContainer : DynamicColors.palette.m3onSurfaceVariant + color: item.active ? Colors.palette.m3onTertiaryContainer : Colors.palette.m3onSurfaceVariant text: item.modelData.icon } CustomText { Layout.alignment: Qt.AlignVCenter Layout.fillWidth: true - color: item.active ? DynamicColors.palette.m3onTertiaryContainer : DynamicColors.palette.m3onSurface + color: item.active ? Colors.palette.m3onTertiaryContainer : Colors.palette.m3onSurface text: item.modelData.text } @@ -179,7 +180,7 @@ MouseArea { visible: active sourceComponent: MaterialIcon { - color: item.active ? DynamicColors.palette.m3onTertiaryContainer : DynamicColors.palette.m3onSurfaceVariant + color: item.active ? Colors.palette.m3onTertiaryContainer : Colors.palette.m3onSurfaceVariant text: item.modelData.trailingIcon } } diff --git a/Components/SearchBar.qml b/Components/SearchBar.qml index c8727fa..ba44e1a 100644 --- a/Components/SearchBar.qml +++ b/Components/SearchBar.qml @@ -1,5 +1,6 @@ import QtQuick -import qs.Config +import ZShell.Config +import qs.Services TextFieldBase { id: root @@ -8,17 +9,17 @@ TextFieldBase { readonly property alias clearIcon: clearIcon readonly property alias searchIcon: searchIcon - bottomPadding: Appearance.padding.large - leftPadding: searchIcon.width + searchIcon.anchors.leftMargin + Appearance.spacing.small - rightPadding: clearIcon.width + clearIcon.anchors.rightMargin + Appearance.spacing.small - topPadding: Appearance.padding.large + bottomPadding: Tokens.padding.large + leftPadding: searchIcon.width + searchIcon.anchors.leftMargin + Tokens.spacing.small + rightPadding: clearIcon.width + clearIcon.anchors.rightMargin + Tokens.spacing.small + topPadding: Tokens.padding.large background: CustomRect { id: bg anchors.fill: parent - color: DynamicColors.tPalette.m3surfaceContainer - radius: Appearance.rounding.full + color: Colors.tPalette.m3surfaceContainer + radius: Tokens.rounding.full StateLayer { id: stateLayer @@ -58,10 +59,10 @@ TextFieldBase { id: searchIcon anchors.left: parent.left - anchors.leftMargin: Appearance.padding.large + anchors.leftMargin: Tokens.padding.large anchors.verticalCenter: parent.verticalCenter - color: DynamicColors.palette.m3onSurfaceVariant - font.pointSize: Appearance.font.size.large + color: Colors.palette.m3onSurfaceVariant + font.pointSize: Tokens.font.size.large text: "search" } @@ -69,12 +70,12 @@ TextFieldBase { id: clearIcon anchors.right: parent.right - anchors.rightMargin: Appearance.padding.larger + anchors.rightMargin: Tokens.padding.larger anchors.verticalCenter: parent.verticalCenter enabled: root.text icon: "clear" opacity: root.text ? 1 : 0 - radius: Appearance.rounding.full + radius: Tokens.rounding.full radiusMorph: false stateLayer.hoverEnabled: enabled type: IconButton.Text diff --git a/Components/StateLayer.qml b/Components/StateLayer.qml index 2a5d8c8..99bb429 100644 --- a/Components/StateLayer.qml +++ b/Components/StateLayer.qml @@ -3,7 +3,8 @@ import QtQuick.Shapes import ZShell import ZShell.Components import qs.Helpers -import qs.Config +import ZShell.Config +import qs.Services MouseArea { id: root @@ -79,8 +80,8 @@ MouseArea { id: rippleAnim alwaysRunToEnd: true - duration: Appearance.anim.durations.expressiveSlowEffects * 2 - easing.bezierCurve: Appearance.anim.curves.standard + duration: Tokens.anim.durations.expressiveSlowEffects * 2 + easing.bezierCurve: Tokens.anim.curves.standard property: "circleRadius" target: root to: root.endRadius @@ -101,7 +102,7 @@ MouseArea { anchors.fill: parent bottomLeftRadius: root.parent?.bottomLeftRadius ?? radius ?? 0 bottomRightRadius: root.parent?.bottomRightRadius ?? radius ?? 0 - color: DynamicColors.palette.m3onSurface + color: Colors.palette.m3onSurface opacity: root.stateOpacity // Pick up radius from parent if it has one (parent can be anything with radius props) // qmllint disable missing-property diff --git a/Components/TextButton.qml b/Components/TextButton.qml index c016bf1..63773df 100644 --- a/Components/TextButton.qml +++ b/Components/TextButton.qml @@ -1,5 +1,6 @@ import QtQuick -import qs.Config +import ZShell.Config +import qs.Services ButtonBase { id: root @@ -7,28 +8,28 @@ ButtonBase { readonly property alias label: label property alias text: label.text - activeColor: type === TextButton.Filled ? DynamicColors.palette.m3primary : DynamicColors.palette.m3secondary + activeColor: type === TextButton.Filled ? Colors.palette.m3primary : Colors.palette.m3secondary activeOnColor: { if (type === TextButton.Text) - return DynamicColors.palette.m3primary; - return type === TextButton.Filled ? DynamicColors.palette.m3onPrimary : DynamicColors.palette.m3onSecondary; + return Colors.palette.m3primary; + return type === TextButton.Filled ? Colors.palette.m3onPrimary : Colors.palette.m3onSecondary; } - horizontalPadding: Appearance.padding.normal + horizontalPadding: Tokens.padding.normal implicitHeight: label.implicitHeight + verticalPadding * 2 implicitWidth: label.implicitWidth + horizontalPadding * 2 inactiveColor: { if (!isToggle && type === TextButton.Filled) - return DynamicColors.palette.m3primary; - return type === TextButton.Filled ? DynamicColors.tPalette.m3surfaceContainer : DynamicColors.palette.m3secondaryContainer; + return Colors.palette.m3primary; + return type === TextButton.Filled ? Colors.tPalette.m3surfaceContainer : Colors.palette.m3secondaryContainer; } inactiveOnColor: { if (!isToggle && type === TextButton.Filled) - return DynamicColors.palette.m3onPrimary; + return Colors.palette.m3onPrimary; if (type === TextButton.Text) - return DynamicColors.palette.m3primary; - return type === TextButton.Filled ? DynamicColors.palette.m3onSurface : DynamicColors.palette.m3onSecondaryContainer; + return Colors.palette.m3primary; + return type === TextButton.Filled ? Colors.palette.m3onSurface : Colors.palette.m3onSecondaryContainer; } - verticalPadding: Appearance.padding.small + verticalPadding: Tokens.padding.small CustomText { id: label diff --git a/Components/TextFieldBase.qml b/Components/TextFieldBase.qml index 8854c42..d13983f 100644 --- a/Components/TextFieldBase.qml +++ b/Components/TextFieldBase.qml @@ -1,19 +1,20 @@ import QtQuick import QtQuick.Templates -import qs.Config +import ZShell.Config +import qs.Services TextField { id: root - color: DynamicColors.palette.m3onSurface + color: Colors.palette.m3onSurface cursorVisible: !readOnly - font.pointSize: Appearance.font.size.small + font.pointSize: Tokens.font.size.small implicitHeight: contentHeight + topPadding + bottomPadding implicitWidth: contentWidth + leftPadding + rightPadding - placeholderTextColor: DynamicColors.palette.m3onSurfaceVariant // No anim cause placeholder is custom + placeholderTextColor: Colors.palette.m3onSurfaceVariant // No anim cause placeholder is custom renderType: echoMode === TextField.Password ? TextField.QtRendering : TextField.NativeRendering selectedTextColor: color - selectionColor: Qt.alpha(DynamicColors.palette.m3primary, 0.4) + selectionColor: Qt.alpha(Colors.palette.m3primary, 0.4) verticalAlignment: TextInput.AlignVCenter Behavior on color { @@ -32,10 +33,10 @@ TextField { property bool disableBlink - color: DynamicColors.palette.m3primary + color: Colors.palette.m3primary implicitHeight: root.cursorRectangle.height implicitWidth: 1.5 - radius: Appearance.rounding.large + radius: Tokens.rounding.large x: root.cursorRectangle.x y: root.cursorRectangle.y @@ -46,7 +47,7 @@ TextField { } Behavior on x { Anim { - duration: Appearance.anim.durations.expressiveFastEffects + duration: Tokens.anim.durations.expressiveFastEffects easing.bezierCurve: [0.2, 1, 0.21, 1, 1, 1] } } diff --git a/Components/Toast/ToastItem.qml b/Components/Toast/ToastItem.qml index a726087..997cd06 100644 --- a/Components/Toast/ToastItem.qml +++ b/Components/Toast/ToastItem.qml @@ -2,7 +2,8 @@ import ZShell import QtQuick import QtQuick.Layouts import qs.Components -import qs.Config +import ZShell.Config +import qs.Services CustomRect { id: root @@ -12,27 +13,27 @@ CustomRect { anchors.left: parent.left anchors.right: parent.right border.color: { - let colour = DynamicColors.palette.m3outlineVariant; + let colour = Colors.palette.m3outlineVariant; if (root.modelData.type === Toast.Success) - colour = DynamicColors.palette.m3success; + colour = Colors.palette.m3success; if (root.modelData.type === Toast.Warning) - colour = DynamicColors.palette.m3secondaryContainer; + colour = Colors.palette.m3secondaryContainer; if (root.modelData.type === Toast.Error) - colour = DynamicColors.palette.m3error; + colour = Colors.palette.m3error; return Qt.alpha(colour, 0.3); } border.width: 1 color: { if (root.modelData.type === Toast.Success) - return DynamicColors.palette.m3successContainer; + return Colors.palette.m3successContainer; if (root.modelData.type === Toast.Warning) - return DynamicColors.palette.m3secondary; + return Colors.palette.m3secondary; if (root.modelData.type === Toast.Error) - return DynamicColors.palette.m3errorContainer; - return DynamicColors.palette.m3surface; + return Colors.palette.m3errorContainer; + return Colors.palette.m3surface; } - implicitHeight: layout.implicitHeight + Appearance.padding.smaller * 2 - radius: Appearance.rounding.normal + implicitHeight: layout.implicitHeight + Tokens.padding.smaller * 2 + radius: Tokens.rounding.normal Behavior on border.color { CAnim { @@ -51,24 +52,24 @@ CustomRect { id: layout anchors.fill: parent - anchors.leftMargin: Appearance.padding.normal - anchors.margins: Appearance.padding.smaller - anchors.rightMargin: Appearance.padding.normal - spacing: Appearance.spacing.normal + anchors.leftMargin: Tokens.padding.normal + anchors.margins: Tokens.padding.smaller + anchors.rightMargin: Tokens.padding.normal + spacing: Tokens.spacing.normal CustomRect { color: { if (root.modelData.type === Toast.Success) - return DynamicColors.palette.m3success; + return Colors.palette.m3success; if (root.modelData.type === Toast.Warning) - return DynamicColors.palette.m3secondaryContainer; + return Colors.palette.m3secondaryContainer; if (root.modelData.type === Toast.Error) - return DynamicColors.palette.m3error; - return DynamicColors.palette.m3surfaceContainerHigh; + return Colors.palette.m3error; + return Colors.palette.m3surfaceContainerHigh; } - implicitHeight: icon.implicitHeight + Appearance.padding.smaller * 2 + implicitHeight: icon.implicitHeight + Tokens.padding.smaller * 2 implicitWidth: implicitHeight - radius: Appearance.rounding.normal + radius: Tokens.rounding.normal MaterialIcon { id: icon @@ -76,14 +77,14 @@ CustomRect { anchors.centerIn: parent color: { if (root.modelData.type === Toast.Success) - return DynamicColors.palette.m3onSuccess; + return Colors.palette.m3onSuccess; if (root.modelData.type === Toast.Warning) - return DynamicColors.palette.m3onSecondaryContainer; + return Colors.palette.m3onSecondaryContainer; if (root.modelData.type === Toast.Error) - return DynamicColors.palette.m3onError; - return DynamicColors.palette.m3onSurfaceVariant; + return Colors.palette.m3onError; + return Colors.palette.m3onSurfaceVariant; } - font.pointSize: Math.round(Appearance.font.size.large * 1.2) + font.pointSize: Math.round(Tokens.font.size.large * 1.2) text: root.modelData.icon } } @@ -98,15 +99,15 @@ CustomRect { Layout.fillWidth: true color: { if (root.modelData.type === Toast.Success) - return DynamicColors.palette.m3onSuccessContainer; + return Colors.palette.m3onSuccessContainer; if (root.modelData.type === Toast.Warning) - return DynamicColors.palette.m3onSecondary; + return Colors.palette.m3onSecondary; if (root.modelData.type === Toast.Error) - return DynamicColors.palette.m3onErrorContainer; - return DynamicColors.palette.m3onSurface; + return Colors.palette.m3onErrorContainer; + return Colors.palette.m3onSurface; } elide: Text.ElideRight - font.pointSize: Appearance.font.size.normal + font.pointSize: Tokens.font.size.normal text: root.modelData.title } @@ -114,12 +115,12 @@ CustomRect { Layout.fillWidth: true color: { if (root.modelData.type === Toast.Success) - return DynamicColors.palette.m3onSuccessContainer; + return Colors.palette.m3onSuccessContainer; if (root.modelData.type === Toast.Warning) - return DynamicColors.palette.m3onSecondary; + return Colors.palette.m3onSecondary; if (root.modelData.type === Toast.Error) - return DynamicColors.palette.m3onErrorContainer; - return DynamicColors.palette.m3onSurface; + return Colors.palette.m3onErrorContainer; + return Colors.palette.m3onSurface; } elide: Text.ElideRight opacity: 0.8 diff --git a/Components/Toast/Toasts.qml b/Components/Toast/Toasts.qml index e2fbde6..feab2e8 100644 --- a/Components/Toast/Toasts.qml +++ b/Components/Toast/Toasts.qml @@ -4,13 +4,13 @@ import ZShell import Quickshell import QtQuick import qs.Components -import qs.Config +import ZShell.Config Item { id: root property bool flag - readonly property int spacing: Appearance.spacing.small + readonly property int spacing: Tokens.spacing.small implicitHeight: { let h = -spacing; @@ -21,7 +21,7 @@ Item { } return h; } - implicitWidth: Config.utilities.sizes.toastWidth - Appearance.padding.normal * 2 + implicitWidth: Config.utilities.sizes.toastWidth - Tokens.padding.normal * 2 Repeater { id: repeater @@ -81,8 +81,8 @@ Item { Behavior on anchors.bottomMargin { Anim { - duration: Appearance.anim.durations.expressiveDefaultSpatial - easing.bezierCurve: Appearance.anim.curves.expressiveDefaultSpatial + duration: Tokens.anim.durations.expressiveDefaultSpatial + easing.bezierCurve: Tokens.anim.curves.expressiveDefaultSpatial } } Behavior on opacity { @@ -104,8 +104,8 @@ Item { Anim { id: initAnim - duration: Appearance.anim.durations.expressiveDefaultSpatial - easing.bezierCurve: Appearance.anim.curves.expressiveDefaultSpatial + duration: Tokens.anim.durations.expressiveDefaultSpatial + easing.bezierCurve: Tokens.anim.curves.expressiveDefaultSpatial from: 0 properties: "opacity,scale" target: toast diff --git a/Components/WavyTopRect.qml b/Components/WavyTopRect.qml index b0dee4c..90052f3 100644 --- a/Components/WavyTopRect.qml +++ b/Components/WavyTopRect.qml @@ -1,12 +1,13 @@ import QtQuick import QtQuick.Shapes -import qs.Config +import ZShell.Config +import qs.Services Shape { id: root property real amplitude: 3 - property color color: DynamicColors.palette.m3surfaceContainer + property color color: Colors.palette.m3surfaceContainer readonly property real waveHeight: amplitude * 2 property int waves: 4 diff --git a/Config/AccentColor.qml b/Config/AccentColor.qml deleted file mode 100644 index 82a0157..0000000 --- a/Config/AccentColor.qml +++ /dev/null @@ -1,13 +0,0 @@ -import Quickshell.Io - -JsonObject { - property Accents accents: Accents { - } - - component Accents: JsonObject { - property string primary: "#4080ff" - property string primaryAlt: "#60a0ff" - property string warning: "#ff6b6b" - property string warningAlt: "#ff8787" - } -} diff --git a/Config/Appearance.qml b/Config/Appearance.qml deleted file mode 100644 index 7be277e..0000000 --- a/Config/Appearance.qml +++ /dev/null @@ -1,13 +0,0 @@ -pragma Singleton - -import Quickshell - -Singleton { - readonly property AppearanceConf.Anim anim: Config.appearance.anim - readonly property AppearanceConf.Deform deform: Config.appearance.deform - readonly property AppearanceConf.FontStuff font: Config.appearance.font - readonly property AppearanceConf.Padding padding: Config.appearance.padding - readonly property AppearanceConf.Rounding rounding: Config.appearance.rounding - readonly property AppearanceConf.Spacing spacing: Config.appearance.spacing - readonly property AppearanceConf.Transparency transparency: Config.appearance.transparency -} diff --git a/Config/AppearanceConf.qml b/Config/AppearanceConf.qml deleted file mode 100644 index e2f3d07..0000000 --- a/Config/AppearanceConf.qml +++ /dev/null @@ -1,116 +0,0 @@ -import Quickshell.Io - -JsonObject { - property Anim anim: Anim { - } - property Deform deform: Deform { - } - property FontStuff font: FontStuff { - } - property Padding padding: Padding { - } - property Rounding rounding: Rounding { - } - property Spacing spacing: Spacing { - } - property Transparency transparency: Transparency { - } - - component Anim: JsonObject { - property AnimCurves curves: AnimCurves { - } - property AnimDurations durations: AnimDurations { - } - property real mediaGifSpeedAdjustment: 300 - property real sessionGifSpeed: 0.7 - } - component AnimCurves: JsonObject { - property list emphasized: [0.05, 0, 2 / 15, 0.06, 1 / 6, 0.4, 5 / 24, 0.82, 0.25, 1, 1, 1] - property list emphasizedAccel: [0.3, 0, 0.8, 0.15, 1, 1] - property list emphasizedDecel: [0.05, 0.7, 0.1, 1, 1, 1] - property list expressiveDefaultEffects: [0.34, 0.8, 0.34, 1, 1, 1] - property list expressiveDefaultSpatial: [0.38, 1.21, 0.22, 1, 1, 1] - property list expressiveEffects: [0.34, 0.8, 0.34, 1, 1, 1] - property list expressiveFastEffects: [0.31, 0.94, 0.34, 1, 1, 1] - property list expressiveFastSpatial: [0.42, 1.67, 0.21, 0.9, 1, 1] - property list expressiveSlowEffects: [0.34, 0.88, 0.34, 1, 1, 1] - property list expressiveSlowSpatial: [0.39, 1.29, 0.35, 0.98, 1, 1] - property list standard: [0.2, 0, 0, 1, 1, 1] - property list standardAccel: [0.3, 0, 1, 1, 1, 1] - property list standardDecel: [0, 0, 0, 1, 1, 1] - } - component AnimDurations: JsonObject { - property int expressiveDefaultSpatial: 500 * scale - property int expressiveEffects: 200 * scale - property int expressiveFastEffects: 150 * scale - property int expressiveFastSpatial: 350 * scale - property int expressiveSlowEffects: 300 * scale - property int extraLarge: 1000 * scale - property int large: 600 * scale - property int normal: 400 * scale - property real scale: 1 - property int small: 200 * scale - } - component Deform: JsonObject { - property real scale: 1 - } - component FontFamily: JsonObject { - property string clock: "Rubik" - property string material: "Material Symbols Rounded" - property string mono: "CaskaydiaCove NF" - property string sans: "Segoe UI Variable Text" - } - component FontSize: JsonObject { - property int extraLarge: 28 * scale - property int large: 18 * scale - property int larger: 16 * scale - property int medium: 14 * scale - property int normal: 13 * scale - property real scale: 1 - property int small: 11 * scale - property int smaller: 12 * scale - } - component FontStuff: JsonObject { - property FontFamily family: FontFamily { - } - property FontSize size: FontSize { - } - } - component Padding: JsonObject { - property int extraLarge: 28 * scale - property int extraLargeIncreased: 32 * scale - property int extraSmall: 4 * scale - property int large: 16 * scale - property int largeIncreased: 20 * scale - property int larger: 12 * scale - property int normal: 8 * scale - property real scale: 1 - property int small: 5 * scale - property int smaller: 7 * scale - property int smallest: 2 * scale - } - component Rounding: JsonObject { - property int extraSmall: 4 * scale - property int full: 1000 * scale - property int large: 24 * scale - property int medium: 16 * scale - property int normal: 18 * scale - property real scale: 1 - property int small: 12 * scale - property int smallest: 8 * scale - } - component Spacing: JsonObject { - property int extraSmall: 4 * scale - property int large: 20 * scale - property int larger: 16 * scale - property int normal: 12 * scale - property real scale: 1 - property int small: 8 * scale - property int smaller: 10 * scale - } - component Transparency: JsonObject { - property real base: 0.85 - property bool enabled: false - property real layers: 0.4 - } -} diff --git a/Config/BackgroundConfig.qml b/Config/BackgroundConfig.qml deleted file mode 100644 index 10e7691..0000000 --- a/Config/BackgroundConfig.qml +++ /dev/null @@ -1,14 +0,0 @@ -import Quickshell.Io -import qs.Config - -JsonObject { - property bool enabled: true - property int wallFadeDuration: MaterialEasing.standardTime - property real alignX: 0.5 - property real alignY: 0.5 - property real zoom: 1.0 - property real sourceClipX: 0 - property real sourceClipY: 0 - property real sourceClipW: 0 - property real sourceClipH: 0 -} diff --git a/Config/BarConfig.qml b/Config/BarConfig.qml deleted file mode 100644 index e0b6ac0..0000000 --- a/Config/BarConfig.qml +++ /dev/null @@ -1,81 +0,0 @@ -import Quickshell.Io - -JsonObject { - property bool autoHide: false - property int border: 8 - property list entries: [ - { - id: "workspaces", - enabled: true - }, - { - id: "media", - enabled: true - }, - { - id: "resources", - enabled: true - }, - { - id: "updates", - enabled: true - }, - { - id: "spacer", - enabled: true - }, - { - id: "activeWindow", - enabled: true - }, - { - id: "spacer", - enabled: true - }, - { - id: "hyprsunset", - enabled: true - }, - { - id: "tray", - enabled: true - }, - { - id: "clock", - enabled: true - }, - { - id: "notifBell", - enabled: true - }, - ] - property int height: 34 - property bool hideWhenNotif: false - property Popouts popouts: Popouts { - } - property int rounding: 8 - property int smoothing: 32 - property Tray tray: Tray { - } - - component Popouts: JsonObject { - property bool activeWindow: true - property bool audio: true - property bool clock: true - property bool network: true - property bool resources: true - property bool tray: true - property bool upower: true - } - component Tray: JsonObject { - property bool recolorIcons: false - property bool showAudio: true - property bool showBluetooth: false - property bool showMicrophone: true - property bool showNetwork: false - property bool showOnHover: false - property bool showPower: true - property bool showWifi: false - property int trayIconSize: 24 - } -} diff --git a/Config/ClipboardConfig.qml b/Config/ClipboardConfig.qml deleted file mode 100644 index 4867301..0000000 --- a/Config/ClipboardConfig.qml +++ /dev/null @@ -1,15 +0,0 @@ -import Quickshell.Io - -JsonObject { - property bool enabled: true - property int maxEntriesShown: 10 - property Sizes sizes: Sizes { - } - - component Sizes: JsonObject { - property int itemHeight: 60 - property int minPreviewWidth: 200 - property int previewWidth: 500 - property int width: 500 - } -} diff --git a/Config/Colors.qml b/Config/Colors.qml deleted file mode 100644 index 3b99070..0000000 --- a/Config/Colors.qml +++ /dev/null @@ -1,13 +0,0 @@ -import Quickshell.Io - -JsonObject { - property Presets presets: Presets { - } - property string schemeType: "vibrant" - - component Presets: JsonObject { - property string accent: "" - property string name: "" - property string variant: "" - } -} diff --git a/Config/Config.qml b/Config/Config.qml deleted file mode 100644 index 6d22849..0000000 --- a/Config/Config.qml +++ /dev/null @@ -1,186 +0,0 @@ -pragma Singleton - -import Quickshell -import Quickshell.Io -import ZShell -import QtQuick -import qs.Helpers -import qs.Paths - -Singleton { - id: root - - property alias appearance: adapter.appearance - property alias background: adapter.background - property alias bar: adapter.bar - property alias clipboard: adapter.clipboard - property alias colors: adapter.colors - property alias dashboard: adapter.dashboard - property alias dock: adapter.dock - property alias general: adapter.general - property alias launcher: adapter.launcher - property alias lock: adapter.lock - property bool migratingLegacyBar: false - property alias notifs: adapter.notifs - property alias osd: adapter.osd - property alias overview: adapter.overview - property bool recentlySaved: false - property alias screenshot: adapter.screenshot - property alias services: adapter.services - property alias sidebar: adapter.sidebar - property alias utilities: adapter.utilities - - function applyLegacyBarConfig(legacy): void { - const tray = legacy.tray ?? {}; - const popouts = legacy.popouts ?? {}; - - bar.autoHide = pick(legacy.autoHide, bar.autoHide); - bar.hideWhenNotif = pick(legacy.hideWhenNotif, bar.hideWhenNotif); - bar.rounding = pick(legacy.rounding, bar.rounding); - bar.border = pick(legacy.border, bar.border); - bar.smoothing = pick(legacy.smoothing, bar.smoothing); - bar.height = pick(legacy.height, bar.height); - bar.tray.trayIconSize = pick(tray.trayIconSize, bar.tray.trayIconSize); - bar.popouts.tray = pick(popouts.tray, bar.popouts.tray); - bar.popouts.audio = pick(popouts.audio, bar.popouts.audio); - bar.popouts.activeWindow = pick(popouts.activeWindow, bar.popouts.activeWindow); - bar.popouts.resources = pick(popouts.resources, bar.popouts.resources); - bar.popouts.clock = pick(popouts.clock, bar.popouts.clock); - bar.popouts.network = pick(popouts.network, bar.popouts.network); - bar.popouts.upower = pick(popouts.upower, bar.popouts.upower); - bar.entries = pick(legacy.entries, bar.entries); - } - - function migrateLegacyBarConfig(raw): bool { - if (raw.bar !== undefined || raw.barConfig === undefined) - return false; - - migratingLegacyBar = true; - applyLegacyBarConfig(raw.barConfig); - migratingLegacyBar = false; - return true; - } - - function pick(value, fallback) { - return value === undefined ? fallback : value; - } - - function save(): void { - saveTimer.restart(); - recentlySaved = true; - recentSaveCooldown.restart(); - } - - function saveNoToast(): void { - saveTimer.restart(); - } - - ElapsedTimer { - id: timer - } - - Timer { - id: saveTimer - - interval: 500 - - onTriggered: { - timer.restart(); - fileView.writeAdapter(); - } - } - - Timer { - id: recentSaveCooldown - - interval: 2000 - - onTriggered: { - root.recentlySaved = false; - } - } - - FileView { - id: fileView - - path: `${Paths.config}/config.json` - watchChanges: true - - onAdapterUpdated: { - if (!root.migratingLegacyBar) - root.save(); - } - onFileChanged: { - if (!root.recentlySaved) { - timer.restart(); - reload(); - } else { - reload(); - } - } - onLoadFailed: err => { - if (err !== FileViewError.FileNotFound) - Toaster.toast(qsTr("Failed to read config"), FileViewError.toString(err), "settings_alert", Toast.Warning); - } - onLoaded: { - ModeScheduler.checkStartup(); - Hyprsunset.checkStartup(); - try { - const raw = JSON.parse(text()); - const migrated = root.migrateLegacyBarConfig(raw); - if (migrated) - root.save(); - - const elapsed = timer.elapsedMs(); - - if (adapter.utilities.toasts.configLoaded && !root.recentlySaved) { - Toaster.toast(qsTr("Config loaded"), qsTr("Config loaded in %1ms").arg(elapsed), "rule_settings"); - } else if (adapter.utilities.toasts.configLoaded && root.recentlySaved) { - Toaster.toast(qsTr("Config saved"), qsTr("Config reloaded in %1ms").arg(elapsed), "settings_alert"); - } - } catch (e) { - Toaster.toast(qsTr("Failed to load config"), e.message, "settings_alert", Toast.Error); - } - } - onSaveFailed: err => Toaster.toast(qsTr("Failed to save config"), FileViewError.toString(err), "settings_alert", Toast.Error) - - JsonAdapter { - id: adapter - - property AppearanceConf appearance: AppearanceConf { - } - property BackgroundConfig background: BackgroundConfig { - } - property BarConfig bar: BarConfig { - } - property ClipboardConfig clipboard: ClipboardConfig { - } - property Colors colors: Colors { - } - property DashboardConfig dashboard: DashboardConfig { - } - property DockConfig dock: DockConfig { - } - property General general: General { - } - property Launcher launcher: Launcher { - } - property LockConf lock: LockConf { - } - property NotifConfig notifs: NotifConfig { - } - property Osd osd: Osd { - } - property Overview overview: Overview { - } - property Screenshot screenshot: Screenshot { - } - property Services services: Services { - } - property SidebarConfig sidebar: SidebarConfig { - } - property UtilConfig utilities: UtilConfig { - } - } - } -} diff --git a/Config/DashboardConfig.qml b/Config/DashboardConfig.qml deleted file mode 100644 index 7bd7fe4..0000000 --- a/Config/DashboardConfig.qml +++ /dev/null @@ -1,37 +0,0 @@ -import Quickshell.Io - -JsonObject { - property bool enabled: true - property int mediaUpdateInterval: 500 - property Performance performance: Performance { - } - property int resourceUpdateInterval: 1000 - property Sizes sizes: Sizes { - } - - component Performance: JsonObject { - property bool enabled: true - property bool showBattery: true - property bool showCpu: true - property bool showGpu: true - property bool showMemory: true - property bool showNetwork: true - property bool showStorage: true - property bool showVram: true - } - component Sizes: JsonObject { - readonly property int dateTimeWidth: 110 - readonly property int infoIconSize: 25 - readonly property int infoWidth: 200 - readonly property int mediaCoverArtSize: 150 - readonly property int mediaProgressSweep: 180 - readonly property int mediaProgressThickness: 8 - readonly property int mediaVisualizerSize: 200 - readonly property int mediaWidth: 200 - readonly property int resourceProgessThickness: 10 - readonly property int resourceSize: 200 - readonly property int tabIndicatorHeight: 3 - readonly property int tabIndicatorSpacing: 5 - readonly property int weatherWidth: 250 - } -} diff --git a/Config/DockConfig.qml b/Config/DockConfig.qml deleted file mode 100644 index 6b364f2..0000000 --- a/Config/DockConfig.qml +++ /dev/null @@ -1,10 +0,0 @@ -import Quickshell.Io - -JsonObject { - property bool enabled: false - property real height: 60 - property bool hoverToReveal: true - property list ignoredAppRegexes: [] - property list pinnedApps: ["org.kde.dolphin", "kitty",] - property bool pinnedOnStartup: false -} diff --git a/Config/General.qml b/Config/General.qml deleted file mode 100644 index 2223ad7..0000000 --- a/Config/General.qml +++ /dev/null @@ -1,68 +0,0 @@ -import Quickshell.Io -import Quickshell - -JsonObject { - property Apps apps: Apps { - } - property Battery battery: Battery { - } - property Color color: Color { - } - property string dateFormat: "ddd d MMM - hh:mm:ss" - property bool desktopIcons: false - property Idle idle: Idle { - } - property string logo: "" - property bool showOverFullscreen: true - property string wallpaperPath: Quickshell.env("HOME") + "/Pictures/Wallpapers" - - component Apps: JsonObject { - property list archiver: ["ark"] - property list audio: ["pavucontrol"] - property list document: ["libreoffice"] - property list editor: ["kate"] - property list explorer: ["dolphin"] - property list image: ["imv"] - property list playback: ["mpv"] - property list terminal: ["kitty"] - } - component Battery: JsonObject { - property int critPerc: 5 - property list popupThresholds: [ - { - perc: 20, - name: qsTr("Low battery"), - message: qsTr("Battery is low"), - icon: "battery_android_frame_2" - }, - ] - } - component Color: JsonObject { - property int hyprsunsetTemp: 5000 - property string mode: "dark" - property bool neovimColors: false - property bool scheduleDark: false - property int scheduleDarkEnd: 0 - property int scheduleDarkStart: 0 - property bool scheduleHyprsunset: false - property int scheduleHyprsunsetEnd: 0 - property int scheduleHyprsunsetStart: 0 - property bool schemeGeneration: true - property bool smart: false - } - component Idle: JsonObject { - property list timeouts: [ - { - name: "Lock", - timeout: 180, - idleAction: "lock" - }, - { - name: "Screen", - timeout: 300, - idleAction: "dpms off", - activeAction: "dpms on" - } - ] - } -} diff --git a/Config/IdleTimeout.qml b/Config/IdleTimeout.qml deleted file mode 100644 index c1db937..0000000 --- a/Config/IdleTimeout.qml +++ /dev/null @@ -1,15 +0,0 @@ -import Quickshell.Io - -JsonObject { - property list timeouts: [ - { - timeout: 180, - idleAction: "lock" - }, - { - timeout: 300, - idleAction: "dpms off", - activeAction: "dpms on" - } - ] -} diff --git a/Config/Launcher.qml b/Config/Launcher.qml deleted file mode 100644 index d746bbd..0000000 --- a/Config/Launcher.qml +++ /dev/null @@ -1,114 +0,0 @@ -import Quickshell.Io - -JsonObject { - property string actionPrefix: ">" - property list actions: [ - { - name: "Calculator", - icon: "calculate", - description: "Do simple math equations", - command: ["autocomplete", "calc"], - enabled: true, - dangerous: false - }, - { - name: "Light", - icon: "light_mode", - description: "Change to light mode", - command: ["setMode", "light"], - enabled: true, - dangerous: false - }, - { - name: "Dark", - icon: "dark_mode", - description: "Change to dark mode", - command: ["setMode", "dark"], - enabled: true, - dangerous: false - }, - { - name: "Wallpaper", - icon: "image", - description: "Change the current wallpaper", - command: ["autocomplete", "wallpaper"], - enabled: true, - dangerous: false - }, - { - name: "Variant", - icon: "colors", - description: "Change the current scheme variant", - command: ["autocomplete", "variant"], - enabled: true, - dangerous: false - }, - { - name: "Shutdown", - icon: "power_settings_new", - description: "Shutdown the system", - command: ["systemctl", "poweroff"], - enabled: true, - dangerous: true - }, - { - name: "Reboot", - icon: "cached", - description: "Reboot the system", - command: ["systemctl", "reboot"], - enabled: true, - dangerous: true - }, - { - name: "Logout", - icon: "logout", - description: "Log out of the current session", - command: ["loginctl", "terminate-user", ""], - enabled: true, - dangerous: true - }, - { - name: "Lock", - icon: "lock", - description: "Lock the current session", - command: ["loginctl", "lock-session"], - enabled: true, - dangerous: false - }, - { - name: "Sleep", - icon: "bedtime", - description: "Suspend then hibernate", - command: ["systemctl", "suspend-then-hibernate"], - enabled: true, - dangerous: false - }, - ] - property int dragThreshold: 50 - property bool enableDangerousActions: false - property bool enabled: true - property list favoriteApps: [] - property list hiddenApps: [] - property int maxAppsShown: 10 - property int maxWallpapers: 7 - property Sizes sizes: Sizes { - } - property string specialPrefix: "@" - property UseFuzzy useFuzzy: UseFuzzy { - } - property bool uwsm: true - - component Sizes: JsonObject { - property int itemHeight: 50 - property int itemWidth: 600 - property int wallpaperHeight: 200 - property int wallpaperWidth: 280 - } - component UseFuzzy: JsonObject { - property bool actions: false - property bool apps: false - property bool schemes: false - property bool variants: false - property bool wallpapers: false - } -} diff --git a/Config/LockConf.qml b/Config/LockConf.qml deleted file mode 100644 index 87a4f4e..0000000 --- a/Config/LockConf.qml +++ /dev/null @@ -1,18 +0,0 @@ -import Quickshell.Io - -JsonObject { - property int blurAmount: 40 - property bool enableFprint: true - property int maxFprintTries: 3 - property bool recolorLogo: false - property bool showNotifContent: false - property bool showNotifIcon: true - property Sizes sizes: Sizes { - } - - component Sizes: JsonObject { - property int centerWidth: 600 - property real heightMult: 0.7 - property real ratio: 16 / 9 - } -} diff --git a/Config/MaterialEasing.qml b/Config/MaterialEasing.qml deleted file mode 100644 index a43a8df..0000000 --- a/Config/MaterialEasing.qml +++ /dev/null @@ -1,26 +0,0 @@ -pragma Singleton -import Quickshell - -Singleton { - id: root - - readonly property list emphasized: [0.05, 0, 2 / 15, 0.06, 1 / 6, 0.4, 5 / 24, 0.82, 0.25, 1, 1, 1] - readonly property list emphasizedAccel: [0.3, 0, 0.8, 0.15, 1, 1] - readonly property int emphasizedAccelTime: 200 * scale - readonly property list emphasizedDecel: [0.05, 0.7, 0.1, 1, 1, 1] - readonly property int emphasizedDecelTime: 400 * scale - readonly property int emphasizedTime: 500 * scale - readonly property list expressiveDefaultSpatial: [0.38, 1.21, 0.22, 1.00, 1, 1] - readonly property int expressiveDefaultSpatialTime: 500 * scale - readonly property list expressiveEffects: [0.34, 0.80, 0.34, 1.00, 1, 1] - readonly property int expressiveEffectsTime: 200 * scale - readonly property list expressiveFastSpatial: [0.42, 1.67, 0.21, 0.90, 1, 1] - readonly property int expressiveFastSpatialTime: 350 * scale - property real scale: Appearance.anim.durations.scale - readonly property list standard: [0.2, 0, 0, 1, 1, 1] - readonly property list standardAccel: [0.3, 0, 1, 1, 1, 1] - readonly property int standardAccelTime: 200 * scale - readonly property list standardDecel: [0, 0, 0, 1, 1, 1] - readonly property int standardDecelTime: 250 * scale - readonly property int standardTime: 300 * scale -} diff --git a/Config/NotifConfig.qml b/Config/NotifConfig.qml deleted file mode 100644 index 01e8b69..0000000 --- a/Config/NotifConfig.qml +++ /dev/null @@ -1,21 +0,0 @@ -import Quickshell.Io - -JsonObject { - property bool actionOnClick: false - property int appNotifCooldown: 0 - property real clearThreshold: 0.3 - property int defaultExpireTimeout: 5000 - property int expandThreshold: 20 - property bool expire: true - property int groupPreviewNum: 3 - property bool openExpanded: false - property bool showInFullscreen: true - property Sizes sizes: Sizes { - } - - component Sizes: JsonObject { - property int badge: 20 - property int image: 41 - property int width: 400 - } -} diff --git a/Config/Osd.qml b/Config/Osd.qml deleted file mode 100644 index 79da85b..0000000 --- a/Config/Osd.qml +++ /dev/null @@ -1,16 +0,0 @@ -import Quickshell.Io - -JsonObject { - property bool allMonBrightness: false - property bool enableBrightness: true - property bool enableMicrophone: true - property bool enabled: true - property int hideDelay: 3000 - property Sizes sizes: Sizes { - } - - component Sizes: JsonObject { - property int sliderHeight: 150 - property int sliderWidth: 30 - } -} diff --git a/Config/Overview.qml b/Config/Overview.qml deleted file mode 100644 index 5e1a615..0000000 --- a/Config/Overview.qml +++ /dev/null @@ -1,8 +0,0 @@ -import Quickshell.Io - -JsonObject { - property int columns: 5 - property bool enable: false - property int rows: 2 - property real scale: 0.16 -} diff --git a/Config/Screenshot.qml b/Config/Screenshot.qml deleted file mode 100644 index cd6dd49..0000000 --- a/Config/Screenshot.qml +++ /dev/null @@ -1,13 +0,0 @@ -import Quickshell.Io - -JsonObject { - property bool enable_pp: true - property string mode: "manual" - property real radius: 12.0 - property bool rounding: false - property bool shadow: true - property real shadow_blur: 22.0 - property list shadow_color: [0, 0, 0, 160] - property real shadow_offset_x: 5.0 - property real shadow_offset_y: 5.0 -} diff --git a/Config/Services.qml b/Config/Services.qml deleted file mode 100644 index 9645d1d..0000000 --- a/Config/Services.qml +++ /dev/null @@ -1,23 +0,0 @@ -import Quickshell.Io -import QtQuick - -JsonObject { - property real audioIncrement: 0.1 - property real brightnessIncrement: 0.1 - property bool ddcutilService: false - property string defaultPlayer: "Spotify" - property string gpuType: "" - property real maxVolume: 1.0 - property real minBrightness: 0.01 - property list playerAliases: [ - { - "from": "com.github.th_ch.youtube_music", - "to": "YT Music" - } - ] - property bool updates: true - property bool useFahrenheit: false - property bool useTwelveHourClock: Qt.locale().timeFormat(Locale.ShortFormat).toLowerCase().includes("a") - property int visualizerBars: 30 - property string weatherLocation: "" -} diff --git a/Config/SidebarConfig.qml b/Config/SidebarConfig.qml deleted file mode 100644 index e064090..0000000 --- a/Config/SidebarConfig.qml +++ /dev/null @@ -1,12 +0,0 @@ -import Quickshell.Io - -JsonObject { - property int dragThreshold: 30 - property bool enabled: true - property Sizes sizes: Sizes { - } - - component Sizes: JsonObject { - property int width: 430 - } -} diff --git a/Config/Transparency.qml b/Config/Transparency.qml deleted file mode 100644 index e687cfb..0000000 --- a/Config/Transparency.qml +++ /dev/null @@ -1,7 +0,0 @@ -import Quickshell.Io - -JsonObject { - property real base: 0.85 - property bool enabled: false - property real layers: 0.4 -} diff --git a/Config/UtilConfig.qml b/Config/UtilConfig.qml deleted file mode 100644 index c4a2087..0000000 --- a/Config/UtilConfig.qml +++ /dev/null @@ -1,35 +0,0 @@ -import Quickshell.Io - -JsonObject { - property bool enabled: true - property int maxToasts: 4 - property Sizes sizes: Sizes { - } - property Toasts toasts: Toasts { - } - property Vpn vpn: Vpn { - } - - component Sizes: JsonObject { - property int toastWidth: 430 - property int width: 430 - } - component Toasts: JsonObject { - property bool audioInputChanged: true - property bool audioOutputChanged: true - property bool capsLockChanged: true - property bool chargingChanged: true - property bool configLoaded: true - property bool dndChanged: true - property bool gameModeChanged: true - property bool kbLayoutChanged: true - property bool kbLimit: true - property bool nowPlaying: false - property bool numLockChanged: true - property bool vpnChanged: true - } - component Vpn: JsonObject { - property bool enabled: false - property list provider: ["netbird"] - } -} diff --git a/Config/WorkspaceWidget.qml b/Config/WorkspaceWidget.qml deleted file mode 100644 index 10a6969..0000000 --- a/Config/WorkspaceWidget.qml +++ /dev/null @@ -1,6 +0,0 @@ -import Quickshell.Io - -JsonObject { - property string inactiveTextColor: "white" - property string textColor: "black" -} diff --git a/Daemons/Audio.qml b/Daemons/Audio.qml index fddb283..beac345 100644 --- a/Daemons/Audio.qml +++ b/Daemons/Audio.qml @@ -5,7 +5,7 @@ import ZShell import Quickshell import Quickshell.Services.Pipewire import QtQuick -import qs.Config +import ZShell.Config Singleton { id: root diff --git a/Daemons/BatteryService.qml b/Daemons/BatteryService.qml index 00ccd98..e2a4149 100644 --- a/Daemons/BatteryService.qml +++ b/Daemons/BatteryService.qml @@ -2,7 +2,7 @@ import Quickshell import Quickshell.Services.UPower import QtQuick import ZShell -import qs.Config +import ZShell.Config import qs.Components.Toast import qs.Helpers diff --git a/Daemons/NotifServer.qml b/Daemons/NotifServer.qml index 66b6206..0f8f305 100644 --- a/Daemons/NotifServer.qml +++ b/Daemons/NotifServer.qml @@ -11,7 +11,7 @@ import qs.Components import qs.Modules import qs.Helpers import qs.Paths -import qs.Config +import ZShell.Config Singleton { id: root diff --git a/Drawers/Exclusions.qml b/Drawers/Exclusions.qml index 3373e34..c1b3190 100644 --- a/Drawers/Exclusions.qml +++ b/Drawers/Exclusions.qml @@ -2,7 +2,7 @@ pragma ComponentBehavior: Bound import Quickshell import QtQuick -import qs.Config +import ZShell.Config import qs.Components Scope { diff --git a/Drawers/Interactions.qml b/Drawers/Interactions.qml index f9d591d..b5dcc65 100644 --- a/Drawers/Interactions.qml +++ b/Drawers/Interactions.qml @@ -1,7 +1,7 @@ import Quickshell import QtQuick import qs.Components -import qs.Config +import ZShell.Config import qs.Helpers import qs.Modules as BarPopouts diff --git a/Drawers/Panels.qml b/Drawers/Panels.qml index 8a587be..1a24491 100644 --- a/Drawers/Panels.qml +++ b/Drawers/Panels.qml @@ -14,7 +14,7 @@ import qs.Modules.Settings as Settings import qs.Modules.Drawing as Drawing import qs.Modules.Dock as Dock import qs.Modules.Clipboard as Clipboard -import qs.Config +import ZShell.Config Item { id: root @@ -108,7 +108,7 @@ Item { id: toasts anchors.bottom: sidebar.visible ? parent.bottom : utilities.top - anchors.margins: Appearance.padding.normal + anchors.margins: Tokens.padding.normal anchors.right: sidebar.left } @@ -155,8 +155,8 @@ Item { Behavior on offsetScale { Anim { - duration: Appearance.anim.durations.expressiveDefaultSpatial - easing.bezierCurve: Appearance.anim.curves.expressiveDefaultSpatial + duration: Tokens.anim.durations.expressiveDefaultSpatial + easing.bezierCurve: Tokens.anim.curves.expressiveDefaultSpatial } } diff --git a/Drawers/Windows.qml b/Drawers/Windows.qml index 3993c72..43e4d47 100644 --- a/Drawers/Windows.qml +++ b/Drawers/Windows.qml @@ -12,9 +12,10 @@ import qs.Modules.SysTray.Popouts.Network as N import qs.Daemons import qs.Components import qs.Modules.Bar -import qs.Config +import ZShell.Config import qs.Helpers import qs.Drawers +import qs.Services CustomWindow { id: root @@ -51,7 +52,7 @@ CustomWindow { property var root: Quickshell.shellDir readonly property real sdfBorderOffset: 2 * fsTransitionProg readonly property real shadowOpacity: 0.7 * (1 - fsTransitionProg) - property color surfaceColor: DynamicColors.tPalette.m3surface + property color surfaceColor: Colors.tPalette.m3surface WlrLayershell.exclusionMode: ExclusionMode.Ignore WlrLayershell.keyboardFocus: visibilities.launcher || visibilities.settings ? WlrKeyboardFocus.OnDemand : WlrKeyboardFocus.None @@ -189,7 +190,7 @@ CustomWindow { layer.effect: MultiEffect { blurMax: 32 - shadowColor: Qt.alpha(DynamicColors.palette.m3shadow, Math.max(0, root.shadowOpacity)) + shadowColor: Qt.alpha(Colors.palette.m3shadow, Math.max(0, root.shadowOpacity)) shadowEnabled: true } @@ -220,7 +221,7 @@ CustomWindow { implicitHeight: panels.dashboard.height * (1 + extraHeight) implicitWidth: panels.dashboard.width panel: panels.dashboardWrapper - radius: Appearance.rounding.normal + radius: Tokens.rounding.normal x: panels.dashboardWrapper.x + panels.dashboard.x + root.borderThickness y: panels.dashboardWrapper.y + panels.dashboard.y + bar.implicitHeight - panels.dashboard.height * extraHeight } @@ -233,7 +234,7 @@ CustomWindow { deformAmount: 0.06 implicitHeight: panels.launcher.height * (1 + extraHeight) panel: panels.launcher - radius: Appearance.rounding.smallest + 5 + radius: Tokens.rounding.smallest + 5 y: panels.launcher.y + bar.implicitHeight } @@ -263,7 +264,7 @@ CustomWindow { id: notifsBg panel: panels.notifications - radius: Appearance.rounding.normal + radius: Tokens.rounding.normal } PanelBg { @@ -284,7 +285,7 @@ CustomWindow { implicitHeight: panels.popouts.height * (1 + extraHeight) implicitWidth: panels.popouts.width panel: panels.popoutsWrapper - radius: panels.popouts.current?.panelRadius ?? Appearance.rounding.normal + radius: panels.popouts.current?.panelRadius ?? Tokens.rounding.normal x: panels.popoutsWrapper.x + panels.popouts.x + root.borderThickness y: panels.popoutsWrapper.y + panels.popouts.y + bar.implicitHeight - panels.popouts.height * extraHeight @@ -301,7 +302,7 @@ CustomWindow { implicitHeight: panels.resources.height implicitWidth: panels.resources.width panel: panels.resourcesWrapper - radius: Appearance.rounding.large + radius: Tokens.rounding.large x: panels.resourcesWrapper.x + panels.resources.x + root.borderThickness y: panels.resourcesWrapper.y + panels.resources.y + bar.implicitHeight } @@ -311,7 +312,7 @@ CustomWindow { deformAmount: 0.03 panel: panels.settings - radius: Appearance.rounding.large + Appearance.padding.normal + radius: Tokens.rounding.large + Tokens.padding.normal } PanelBg { @@ -319,7 +320,7 @@ CustomWindow { deformAmount: 0.08 panel: panels.dock - radius: Appearance.rounding.normal + radius: Tokens.rounding.normal } PanelBg { @@ -327,7 +328,7 @@ CustomWindow { deformAmount: 0.08 panel: panels.drawing - radius: Appearance.rounding.normal + radius: Tokens.rounding.normal } PanelBg { @@ -452,7 +453,7 @@ CustomWindow { group: blobGroup implicitHeight: panel.height implicitWidth: panel.width - radius: Appearance.rounding.smallest + radius: Tokens.rounding.smallest x: panel.x + root.borderThickness y: panel.y + bar.implicitHeight } diff --git a/Greeter/Center.qml b/Greeter/Center.qml index 713aa5f..9dafdcd 100644 --- a/Greeter/Center.qml +++ b/Greeter/Center.qml @@ -2,10 +2,10 @@ pragma ComponentBehavior: Bound import QtQuick import QtQuick.Layouts -import qs.Paths +import ZShell.Config import qs.Components import qs.Helpers -import qs.Config +import qs.Services ColumnLayout { id: root @@ -18,61 +18,61 @@ ColumnLayout { Layout.fillHeight: true Layout.fillWidth: false Layout.preferredWidth: centerWidth - spacing: Appearance.spacing.large * 2 + spacing: Tokens.spacing.large * 2 RowLayout { Layout.alignment: Qt.AlignHCenter - spacing: Appearance.spacing.small + spacing: Tokens.spacing.small CustomText { Layout.alignment: Qt.AlignVCenter - color: DynamicColors.palette.m3secondary + color: Colors.palette.m3secondary font.bold: true - font.family: Appearance.font.family.clock - font.pointSize: Math.floor(Appearance.font.size.extraLarge * 3 * root.centerScale) + font.family: Config.appearance.font.family.clock + font.pointSize: Math.floor(Tokens.font.size.extraLarge * 3 * root.centerScale) text: Time.hourStr } CustomText { Layout.alignment: Qt.AlignVCenter - color: DynamicColors.palette.m3primary + color: Colors.palette.m3primary font.bold: true - font.family: Appearance.font.family.clock - font.pointSize: Math.floor(Appearance.font.size.extraLarge * 3 * root.centerScale) + font.family: Config.appearance.font.family.clock + font.pointSize: Math.floor(Tokens.font.size.extraLarge * 3 * root.centerScale) text: ":" } CustomText { Layout.alignment: Qt.AlignVCenter - color: DynamicColors.palette.m3secondary + color: Colors.palette.m3secondary font.bold: true - font.family: Appearance.font.family.clock - font.pointSize: Math.floor(Appearance.font.size.extraLarge * 3 * root.centerScale) + font.family: Config.appearance.font.family.clock + font.pointSize: Math.floor(Tokens.font.size.extraLarge * 3 * root.centerScale) text: Time.minuteStr } } CustomText { Layout.alignment: Qt.AlignHCenter - Layout.topMargin: -Appearance.padding.large * 2 - color: DynamicColors.palette.m3tertiary + Layout.topMargin: -Tokens.padding.large * 2 + color: Colors.palette.m3tertiary font.bold: true - font.family: Appearance.font.family.mono - font.pointSize: Math.floor(Appearance.font.size.extraLarge * root.centerScale) + font.family: Config.appearance.font.family.mono + font.pointSize: Math.floor(Tokens.font.size.extraLarge * root.centerScale) text: Time.format("dddd, d MMMM yyyy") } CustomClippingRect { Layout.alignment: Qt.AlignHCenter - Layout.topMargin: Appearance.spacing.large * 2 - color: DynamicColors.tPalette.m3surfaceContainer + Layout.topMargin: Tokens.spacing.large * 2 + color: Colors.tPalette.m3surfaceContainer implicitHeight: root.centerWidth / 2 implicitWidth: root.centerWidth / 2 - radius: Appearance.rounding.full + radius: Tokens.rounding.full MaterialIcon { anchors.centerIn: parent - color: DynamicColors.palette.m3onSurfaceVariant + color: Colors.palette.m3onSurfaceVariant font.pointSize: Math.floor(root.centerWidth / 4) text: "person" } @@ -87,9 +87,9 @@ ColumnLayout { CustomText { Layout.alignment: Qt.AlignHCenter - color: DynamicColors.palette.m3onSurfaceVariant - font.family: Appearance.font.family.mono - font.pointSize: Appearance.font.size.normal + color: Colors.palette.m3onSurfaceVariant + font.family: Config.appearance.font.family.mono + font.pointSize: Tokens.font.size.normal font.weight: 600 text: root.greeter.username visible: text.length > 0 @@ -97,11 +97,11 @@ ColumnLayout { CustomRect { Layout.alignment: Qt.AlignHCenter - color: DynamicColors.tPalette.m3surfaceContainer + color: Colors.tPalette.m3surfaceContainer focus: true - implicitHeight: input.implicitHeight + Appearance.padding.small * 2 + implicitHeight: input.implicitHeight + Tokens.padding.small * 2 implicitWidth: root.centerWidth * 0.8 - radius: Appearance.rounding.full + radius: Tokens.rounding.full Keys.onPressed: event => { if (root.greeter.launching) @@ -130,11 +130,11 @@ ColumnLayout { id: input anchors.fill: parent - anchors.margins: Appearance.padding.small - spacing: Appearance.spacing.normal + anchors.margins: Tokens.padding.small + spacing: Tokens.spacing.normal Item { - implicitHeight: statusIcon.implicitHeight + Appearance.padding.small * 2 + implicitHeight: statusIcon.implicitHeight + Tokens.padding.small * 2 implicitWidth: implicitHeight MaterialIcon { @@ -142,7 +142,7 @@ ColumnLayout { anchors.centerIn: parent animate: true - color: root.greeter.errorMessage ? DynamicColors.palette.m3error : DynamicColors.palette.m3onSurface + color: root.greeter.errorMessage ? Colors.palette.m3error : Colors.palette.m3onSurface opacity: root.greeter.launching ? 0 : 1 text: { if (root.greeter.errorMessage) @@ -173,13 +173,13 @@ ColumnLayout { } CustomRect { - color: root.greeter.buffer && !root.greeter.launching ? DynamicColors.palette.m3primary : DynamicColors.layer(DynamicColors.palette.m3surfaceContainerHigh, 2) - implicitHeight: enterIcon.implicitHeight + Appearance.padding.small * 2 + color: root.greeter.buffer && !root.greeter.launching ? Colors.palette.m3primary : Colors.layer(Colors.palette.m3surfaceContainerHigh, 2) + implicitHeight: enterIcon.implicitHeight + Tokens.padding.small * 2 implicitWidth: implicitHeight - radius: Appearance.rounding.full + radius: Tokens.rounding.full StateLayer { - color: root.greeter.buffer && !root.greeter.launching ? DynamicColors.palette.m3onPrimary : DynamicColors.palette.m3onSurface + color: root.greeter.buffer && !root.greeter.launching ? Colors.palette.m3onPrimary : Colors.palette.m3onSurface onClicked: { root.greeter.submit(); @@ -190,7 +190,7 @@ ColumnLayout { id: enterIcon anchors.centerIn: parent - color: root.greeter.buffer && !root.greeter.launching ? DynamicColors.palette.m3onPrimary : DynamicColors.palette.m3onSurface + color: root.greeter.buffer && !root.greeter.launching ? Colors.palette.m3onPrimary : Colors.palette.m3onSurface font.weight: 500 text: root.greeter.launching ? "hourglass_top" : "arrow_forward" } @@ -200,7 +200,7 @@ ColumnLayout { Item { Layout.fillWidth: true - Layout.topMargin: -Appearance.spacing.large + Layout.topMargin: -Tokens.spacing.large implicitHeight: Math.max(message.implicitHeight, stateMessage.implicitHeight) Behavior on implicitHeight { @@ -236,8 +236,8 @@ ColumnLayout { anchors.left: parent.left anchors.right: parent.right animateProp: "opacity" - color: DynamicColors.palette.m3onSurfaceVariant - font.family: Appearance.font.family.mono + color: Colors.palette.m3onSurfaceVariant + font.family: Config.appearance.font.family.mono horizontalAlignment: Qt.AlignHCenter lineHeight: 1.2 opacity: shouldBeVisible && !message.msg ? 1 : 0 @@ -291,9 +291,9 @@ ColumnLayout { anchors.left: parent.left anchors.right: parent.right - color: isError ? DynamicColors.palette.m3error : DynamicColors.palette.m3primary - font.family: Appearance.font.family.mono - font.pointSize: Appearance.font.size.small + color: isError ? Colors.palette.m3error : Colors.palette.m3primary + font.family: Config.appearance.font.family.mono + font.pointSize: Tokens.font.size.small horizontalAlignment: Qt.AlignHCenter opacity: 0 scale: 0.7 @@ -363,14 +363,14 @@ ColumnLayout { id: exitAnim Anim { - duration: Appearance.anim.durations.large + duration: Tokens.anim.durations.large property: "scale" target: message to: 0.7 } Anim { - duration: Appearance.anim.durations.large + duration: Tokens.anim.durations.large property: "opacity" target: message to: 0 @@ -380,7 +380,7 @@ ColumnLayout { } component FlashAnim: NumberAnimation { - duration: Appearance.anim.durations.small + duration: Tokens.anim.durations.small easing.type: Easing.Linear property: "opacity" target: message diff --git a/Greeter/Components/Anim.qml b/Greeter/Components/Anim.qml index 0b02612..5cc8554 100644 --- a/Greeter/Components/Anim.qml +++ b/Greeter/Components/Anim.qml @@ -1,5 +1,5 @@ import QtQuick -import qs.Config +import ZShell.Config NumberAnimation { enum Type { @@ -23,41 +23,41 @@ NumberAnimation { duration: { if (type < Anim.StandardSmall || type > Anim.SlowEffects) - return Appearance.anim.durations.normal; + return Tokens.anim.durations.normal; if (type === Anim.FastSpatial) - return Appearance.anim.durations.expressiveFastSpatial; + return Tokens.anim.durations.expressiveFastSpatial; if (type === Anim.DefaultSpatial) - return Appearance.anim.durations.expressiveDefaultSpatial; + return Tokens.anim.durations.expressiveDefaultSpatial; if (type === Anim.SlowSpatial) - return Appearance.anim.durations.large; + return Tokens.anim.durations.large; if (type === Anim.FastEffects) - return Appearance.anim.durations.expressiveFastEffects; + return Tokens.anim.durations.expressiveFastEffects; if (type === Anim.DefaultEffects) - return Appearance.anim.durations.expressiveEffects; + return Tokens.anim.durations.expressiveEffects; if (type === Anim.SlowEffects) - return Appearance.anim.durations.expressiveSlowEffects; + return Tokens.anim.durations.expressiveSlowEffects; const types = ["small", "normal", "large", "extraLarge"]; const idx = type % 4; // 0-7 are the 4 standard types - return Appearance.anim.durations[types[idx]]; + return Tokens.anim.durations[types[idx]]; } easing.bezierCurve: { if (type === Anim.FastSpatial) - return Appearance.anim.curves.expressiveFastSpatial; + return Tokens.anim.curves.expressiveFastSpatial; if (type === Anim.DefaultSpatial) - return Appearance.anim.curves.expressiveDefaultSpatial; + return Tokens.anim.curves.expressiveDefaultSpatial; if (type === Anim.SlowSpatial) - return Appearance.anim.curves.expressiveSlowSpatial; + return Tokens.anim.curves.expressiveSlowSpatial; if (type === Anim.FastEffects) - return Appearance.anim.curves.expressiveFastEffects; + return Tokens.anim.curves.expressiveFastEffects; if (type === Anim.DefaultEffects) - return Appearance.anim.curves.expressiveDefaultEffects; + return Tokens.anim.curves.expressiveDefaultEffects; if (type === Anim.SlowEffects) - return Appearance.anim.curves.expressiveSlowEffects; + return Tokens.anim.curves.expressiveSlowEffects; if (type >= Anim.EmphasizedSmall && type <= Anim.EmphasizedExtraLarge) - return Appearance.anim.curves.emphasized; - return Appearance.anim.curves.standard; + return Tokens.anim.curves.emphasized; + return Tokens.anim.curves.standard; } } diff --git a/Greeter/Components/AnimatedTabIndexPair.qml b/Greeter/Components/AnimatedTabIndexPair.qml deleted file mode 100644 index d8fb656..0000000 --- a/Greeter/Components/AnimatedTabIndexPair.qml +++ /dev/null @@ -1,24 +0,0 @@ -import QtQuick - -QtObject { - id: root - - property real idx1: index - property int idx1Duration: 100 - property real idx2: index - property int idx2Duration: 300 - required property int index - - Behavior on idx1 { - NumberAnimation { - duration: root.idx1Duration - easing.type: Easing.OutSine - } - } - Behavior on idx2 { - NumberAnimation { - duration: root.idx2Duration - easing.type: Easing.OutSine - } - } -} diff --git a/Greeter/Components/BaseStyledSlider.qml b/Greeter/Components/BaseStyledSlider.qml deleted file mode 100644 index 48c8f33..0000000 --- a/Greeter/Components/BaseStyledSlider.qml +++ /dev/null @@ -1,165 +0,0 @@ -import QtQuick -import QtQuick.Templates -import qs.Config - -Slider { - id: root - - property color color: DynamicColors.palette.m3secondary - required property string icon - property bool initialized: false - readonly property bool isHorizontal: orientation === Qt.Horizontal - readonly property bool isVertical: orientation === Qt.Vertical - property real multiplier: 100 - property real oldValue - - // Wrapper components can inject their own track visuals here. - property Component trackContent - - // Keep current behavior for existing usages. - orientation: Qt.Vertical - - background: CustomRect { - id: groove - - color: DynamicColors.layer(DynamicColors.palette.m3surfaceContainer, 2) - height: root.availableHeight - radius: Appearance.rounding.full - width: root.availableWidth - x: root.leftPadding - y: root.topPadding - - Loader { - id: trackLoader - - anchors.fill: parent - sourceComponent: root.trackContent - - onLoaded: { - if (!item) - return; - - item.rootSlider = root; - item.groove = groove; - item.handleItem = handle; - } - } - } - handle: Item { - id: handle - - property alias moving: icon.moving - - implicitHeight: Math.min(root.width, root.height) - implicitWidth: Math.min(root.width, root.height) - x: root.isHorizontal ? root.leftPadding + root.visualPosition * (root.availableWidth - width) : root.leftPadding + (root.availableWidth - width) / 2 - y: root.isVertical ? root.topPadding + root.visualPosition * (root.availableHeight - height) : root.topPadding + (root.availableHeight - height) / 2 - - Elevation { - anchors.fill: parent - level: handleInteraction.containsMouse ? 2 : 1 - radius: rect.radius - } - - CustomRect { - id: rect - - anchors.fill: parent - color: DynamicColors.palette.m3inverseSurface - radius: Appearance.rounding.full - - MouseArea { - id: handleInteraction - - acceptedButtons: Qt.NoButton - anchors.fill: parent - cursorShape: Qt.PointingHandCursor - hoverEnabled: true - } - - MaterialIcon { - id: icon - - property bool moving - - function update(): void { - animate = !moving; - binding.when = moving; - font.pointSize = moving ? Appearance.font.size.small : Appearance.font.size.larger; - font.family = moving ? Appearance.font.family.sans : Appearance.font.family.material; - } - - anchors.centerIn: parent - color: DynamicColors.palette.m3inverseOnSurface - text: root.icon - - onMovingChanged: anim.restart() - - Binding { - id: binding - - property: "text" - target: icon - value: Math.round(root.value * root.multiplier) - when: false - } - - SequentialAnimation { - id: anim - - Anim { - duration: Appearance.anim.durations.normal / 2 - easing.bezierCurve: Appearance.anim.curves.standardAccel - property: "scale" - target: icon - to: 0 - } - - ScriptAction { - script: icon.update() - } - - Anim { - duration: Appearance.anim.durations.normal / 2 - easing.bezierCurve: Appearance.anim.curves.standardDecel - property: "scale" - target: icon - to: 1 - } - } - } - } - } - Behavior on value { - Anim { - duration: Appearance.anim.durations.large - } - } - - onPressedChanged: handle.moving = pressed - onValueChanged: { - if (!initialized) { - initialized = true; - oldValue = value; - return; - } - - if (Math.abs(value - oldValue) < 0.01) - return; - - oldValue = value; - handle.moving = true; - stateChangeDelay.restart(); - } - - Timer { - id: stateChangeDelay - - interval: 500 - - onTriggered: { - if (!root.pressed) - handle.moving = false; - } - } -} diff --git a/Greeter/Components/CAnim.qml b/Greeter/Components/CAnim.qml index d5be385..231741f 100644 --- a/Greeter/Components/CAnim.qml +++ b/Greeter/Components/CAnim.qml @@ -1,8 +1,63 @@ import QtQuick -import qs.Config +import ZShell.Config ColorAnimation { - duration: MaterialEasing.standardTime - easing.bezierCurve: MaterialEasing.standard - easing.type: Easing.BezierSpline + enum Type { + StandardSmall = 0, + Standard, + StandardLarge, + StandardExtraLarge, + EmphasizedSmall, + Emphasized, + EmphasizedLarge, + EmphasizedExtraLarge, + FastSpatial, + DefaultSpatial, + SlowSpatial, + FastEffects, + DefaultEffects, + SlowEffects + } + + property int type: CAnim.DefaultSpatial + + duration: { + if (type < CAnim.StandardSmall || type > Anim.SlowEffects) + return Tokens.anim.durations.normal; + + if (type === CAnim.FastSpatial) + return Tokens.anim.durations.expressiveFastSpatial; + if (type === CAnim.DefaultSpatial) + return Tokens.anim.durations.expressiveDefaultSpatial; + if (type === CAnim.SlowSpatial) + return Tokens.anim.durations.large; + if (type === CAnim.FastEffects) + return Tokens.anim.durations.expressiveFastEffects; + if (type === CAnim.DefaultEffects) + return Tokens.anim.durations.expressiveEffects; + if (type === CAnim.SlowEffects) + return Tokens.anim.durations.expressiveSlowEffects; + + const types = ["small", "normal", "large", "extraLarge"]; + const idx = type % 4; + return Tokens.anim.durations[types[idx]]; + } + easing.bezierCurve: { + if (type === CAnim.FastSpatial) + return Tokens.anim.curves.expressiveFastSpatial; + if (type === CAnim.DefaultSpatial) + return Tokens.anim.curves.expressiveDefaultSpatial; + if (type === CAnim.SlowSpatial) + return Tokens.anim.curves.expressiveSlowSpatial; + if (type === CAnim.FastEffects) + return Tokens.anim.curves.expressiveFastEffects; + if (type === CAnim.DefaultEffects) + return Tokens.anim.curves.expressiveDefaultEffects; + if (type === CAnim.SlowEffects) + return Tokens.anim.curves.expressiveSlowEffects; + + if (type >= CAnim.EmphasizedSmall && type <= Anim.EmphasizedExtraLarge) + return Tokens.anim.curves.emphasized; + return Tokens.anim.curves.standard; + } } diff --git a/Greeter/Components/CircularIndicator.qml b/Greeter/Components/CircularIndicator.qml index 662c571..94112e9 100644 --- a/Greeter/Components/CircularIndicator.qml +++ b/Greeter/Components/CircularIndicator.qml @@ -1,7 +1,8 @@ -import qs.Config +import ZShell.Config import ZShell.Internal import QtQuick import QtQuick.Templates +import qs.Services BusyIndicator { id: root @@ -17,12 +18,12 @@ BusyIndicator { } property int animState - property color bgColour: DynamicColors.palette.m3secondaryContainer - property color fgColour: DynamicColors.palette.m3primary - property real implicitSize: Appearance.font.size.normal * 3 + property color bgColor: Colors.palette.m3secondaryContainer + property color fgColor: Colors.palette.m3primary + property real implicitSize: Tokens.font.size.normal * 3 property real internalStrokeWidth: strokeWidth readonly property alias progress: manager.progress - property real strokeWidth: Appearance.padding.small * 0.8 + property real strokeWidth: Tokens.padding.small * 0.8 property alias type: manager.indeterminateAnimationType implicitHeight: implicitSize @@ -31,8 +32,8 @@ BusyIndicator { contentItem: CircularProgress { anchors.fill: parent - bgColour: root.bgColour - fgColour: root.fgColour + bgColor: root.bgColor + fgColor: root.fgColor padding: root.padding rotation: manager.rotation startAngle: manager.startFraction * 360 @@ -50,7 +51,7 @@ BusyIndicator { } transitions: Transition { Anim { - duration: manager.completeEndDuration * Appearance.anim.durations.scale + duration: manager.completeEndDuration * Tokens.anim.durations.scale properties: "opacity,internalStrokeWidth" } } @@ -73,11 +74,10 @@ BusyIndicator { CircularIndicatorManager { id: manager - } NumberAnimation { - duration: manager.duration * Appearance.anim.durations.scale + duration: manager.duration * Tokens.anim.durations.scale from: 0 loops: Animation.Infinite property: "progress" @@ -87,7 +87,7 @@ BusyIndicator { } NumberAnimation { - duration: manager.completeEndDuration * Appearance.anim.durations.scale + duration: manager.completeEndDuration * Tokens.anim.durations.scale from: 0 property: "completeEndProgress" running: root.animState === CircularIndicator.Completing diff --git a/Greeter/Components/CircularProgress.qml b/Greeter/Components/CircularProgress.qml index fa1011c..a463552 100644 --- a/Greeter/Components/CircularProgress.qml +++ b/Greeter/Components/CircularProgress.qml @@ -1,66 +1,117 @@ +pragma ComponentBehavior: Bound + import QtQuick import QtQuick.Shapes -import qs.Config +import ZShell.Components +import ZShell.Config +import qs.Services -Shape { +Item { id: root - readonly property real arcRadius: (size - padding - strokeWidth) / 2 - property color bgColour: DynamicColors.palette.m3secondaryContainer - property color fgColour: DynamicColors.palette.m3primary + readonly property real arcRadius: (size - padding - strokeWidth * (1 + waveAmplitude * 2)) / 2 + property color bgColor: Colors.palette.m3secondaryContainer + property real clampedVal: Math.max(1 / 360, Math.min(1, isNaN(value) ? 0 : value)) + readonly property real dotAngleRad: (startAngle + sweepAngle - gapAngle * (sweepAngle < 360 ? 0 : 1)) * Math.PI / 180 + property color fgColor: Colors.palette.m3primary readonly property real gapAngle: ((spacing + strokeWidth) / (arcRadius || 1)) * (180 / Math.PI) + property alias hasEndIndicator: dot.active + property real implicitSize property int padding: 0 readonly property real size: Math.min(width, height) - property int spacing: Appearance.spacing.small + property int spacing: Tokens.spacing.small property int startAngle: -90 - property int strokeWidth: Appearance.padding.smaller - readonly property real vValue: value || 1 / 360 + property int strokeWidth: Tokens.padding.small + property int sweepAngle: 360 + readonly property real thickness: strokeWidth * (1 + waveAmplitude) * 2 property real value + property alias waveAmplitude: wave.amplitudeMultiplier + property alias waveDuration: waveProgAnim.duration + property alias waveFrequency: wave.frequency + property bool wavePaused + property bool wavy: false - asynchronous: true - preferredRendererType: Shape.CurveRenderer + implicitHeight: implicitSize + implicitWidth: implicitSize - ShapePath { - capStyle: Appearance.rounding.scale === 0 ? ShapePath.SquareCap : ShapePath.RoundCap - fillColor: "transparent" - strokeColor: root.bgColour - strokeWidth: root.strokeWidth + Shape { + asynchronous: true + opacity: Math.min(1, remainingArc.sweepAngle) + preferredRendererType: Shape.CurveRenderer - Behavior on strokeColor { - CAnim { - duration: Appearance.anim.durations.large + ShapePath { + capStyle: ShapePath.RoundCap + fillColor: "transparent" + strokeColor: root.bgColor + strokeWidth: Math.min(1, remainingArc.sweepAngle) * root.strokeWidth + + Behavior on strokeColor { + CAnim { + } } - } - PathAngleArc { - centerX: root.size / 2 - centerY: root.size / 2 - radiusX: root.arcRadius - radiusY: root.arcRadius - startAngle: root.startAngle + 360 * root.vValue + root.gapAngle - sweepAngle: Math.max(-root.gapAngle, 360 * (1 - root.vValue) - root.gapAngle * 2) + PathAngleArc { + id: remainingArc + + centerX: root.size / 2 + centerY: root.size / 2 + radiusX: root.arcRadius + radiusY: root.arcRadius + startAngle: root.startAngle + root.clampedVal * root.sweepAngle + root.gapAngle + sweepAngle: Math.max(1 / 360, root.sweepAngle * (1 - root.clampedVal) - root.gapAngle * (root.sweepAngle < 360 ? 1 : 2)) + } } } - ShapePath { - capStyle: Appearance.rounding.scale === 0 ? ShapePath.SquareCap : ShapePath.RoundCap - fillColor: "transparent" - strokeColor: root.fgColour - strokeWidth: root.strokeWidth + WavyLine { + id: wave - Behavior on strokeColor { - CAnim { - duration: Appearance.anim.durations.large + amplitudeMultiplier: root.wavy ? 0.5 : 0 + anchors.fill: parent + anchors.margins: -lineWidth * amplitudeMultiplier + color: root.fgColor + frequency: 8 + fullAngle: root.sweepAngle + lineWidth: root.strokeWidth + pathType: WavyLine.Arc + radius: root.arcRadius + startAngle: root.startAngle + value: root.clampedVal + + Behavior on amplitudeMultiplier { + Anim { + type: Anim.DefaultEffects } } + Behavior on color { + CAnim { + } + } + Anim on waveProgress { + id: waveProgAnim - PathAngleArc { - centerX: root.size / 2 - centerY: root.size / 2 - radiusX: root.arcRadius - radiusY: root.arcRadius - startAngle: root.startAngle - sweepAngle: 360 * root.vValue + duration: 2000 + easing.type: Easing.Linear + from: 0 + loops: Animation.Infinite + paused: root.wavePaused || wave.amplitudeMultiplier === 0 + running: true + to: 1 + } + } + + Loader { + id: dot + + x: root.size / 2 + root.arcRadius * Math.cos(root.dotAngleRad) - width / 2 + y: root.size / 2 + root.arcRadius * Math.sin(root.dotAngleRad) - height / 2 + + sourceComponent: CustomRect { + color: root.fgColor + implicitHeight: Math.min(1, remainingArc.sweepAngle) * Math.min(4, root.strokeWidth) + implicitWidth: Math.min(1, remainingArc.sweepAngle) * Math.min(4, root.strokeWidth) + opacity: Math.min(1, remainingArc.sweepAngle) + radius: Tokens.rounding.full } } } diff --git a/Greeter/Components/CollapsibleSection.qml b/Greeter/Components/CollapsibleSection.qml deleted file mode 100644 index 46e4753..0000000 --- a/Greeter/Components/CollapsibleSection.qml +++ /dev/null @@ -1,135 +0,0 @@ -import QtQuick -import QtQuick.Layouts -import qs.Config - -ColumnLayout { - id: root - - default property alias content: contentColumn.data - property string description: "" - property bool expanded: false - property bool nested: false - property bool showBackground: false - required property string title - - signal toggleRequested - - Layout.fillWidth: true - spacing: Appearance.spacing.small - - Item { - id: sectionHeaderItem - - Layout.fillWidth: true - Layout.preferredHeight: Math.max(titleRow.implicitHeight + Appearance.padding.normal * 2, 48) - - RowLayout { - id: titleRow - - anchors.left: parent.left - anchors.leftMargin: Appearance.padding.normal - anchors.right: parent.right - anchors.rightMargin: Appearance.padding.normal - anchors.verticalCenter: parent.verticalCenter - spacing: Appearance.spacing.normal - - CustomText { - font.pointSize: Appearance.font.size.larger - font.weight: 500 - text: root.title - } - - Item { - Layout.fillWidth: true - } - - MaterialIcon { - color: DynamicColors.palette.m3onSurfaceVariant - font.pointSize: Appearance.font.size.normal - rotation: root.expanded ? 180 : 0 - text: "expand_more" - - Behavior on rotation { - Anim { - duration: Appearance.anim.durations.small - easing.bezierCurve: Appearance.anim.curves.standard - } - } - } - } - - StateLayer { - anchors.fill: parent - color: DynamicColors.palette.m3onSurface - radius: Appearance.rounding.normal - showHoverBackground: false - - onClicked: { - root.toggleRequested(); - root.expanded = !root.expanded; - } - } - } - - Item { - id: contentWrapper - - Layout.fillWidth: true - Layout.preferredHeight: root.expanded ? (contentColumn.implicitHeight + Appearance.spacing.small * 2) : 0 - clip: true - - Behavior on Layout.preferredHeight { - Anim { - easing.bezierCurve: Appearance.anim.curves.standard - } - } - - CustomRect { - id: backgroundRect - - anchors.fill: parent - color: DynamicColors.transparency.enabled ? DynamicColors.layer(DynamicColors.palette.m3surfaceContainer, root.nested ? 3 : 2) : (root.nested ? DynamicColors.palette.m3surfaceContainerHigh : DynamicColors.palette.m3surfaceContainer) - opacity: root.showBackground && root.expanded ? 1.0 : 0.0 - radius: Appearance.rounding.normal - visible: root.showBackground - - Behavior on opacity { - Anim { - easing.bezierCurve: Appearance.anim.curves.standard - } - } - } - - ColumnLayout { - id: contentColumn - - anchors.bottomMargin: Appearance.spacing.small - anchors.left: parent.left - anchors.leftMargin: Appearance.padding.normal - anchors.right: parent.right - anchors.rightMargin: Appearance.padding.normal - opacity: root.expanded ? 1.0 : 0.0 - spacing: Appearance.spacing.small - y: Appearance.spacing.small - - Behavior on opacity { - Anim { - easing.bezierCurve: Appearance.anim.curves.standard - } - } - - CustomText { - id: descriptionText - - Layout.bottomMargin: root.description !== "" ? Appearance.spacing.small : 0 - Layout.fillWidth: true - Layout.topMargin: root.description !== "" ? Appearance.spacing.smaller : 0 - color: DynamicColors.palette.m3onSurfaceVariant - font.pointSize: Appearance.font.size.small - text: root.description - visible: root.description !== "" - wrapMode: Text.Wrap - } - } - } -} diff --git a/Greeter/Components/ColorArcPicker.qml b/Greeter/Components/ColorArcPicker.qml deleted file mode 100644 index c909511..0000000 --- a/Greeter/Components/ColorArcPicker.qml +++ /dev/null @@ -1,208 +0,0 @@ -pragma ComponentBehavior: Bound - -import QtQuick -import qs.Config - -Item { - id: root - - readonly property real arcStartAngle: 0.75 * Math.PI - readonly property real arcSweep: 1.5 * Math.PI - property real currentHue: 0 - property bool dragActive: false - required property var drawing - readonly property real handleAngle: hueToAngle(currentHue) - readonly property real handleCenterX: width / 2 + radius * Math.cos(handleAngle) - readonly property real handleCenterY: height / 2 + radius * Math.sin(handleAngle) - property real handleSize: 32 - property real lastChromaticHue: 0 - readonly property real radius: (Math.min(width, height) - handleSize) / 2 - readonly property int segmentCount: 240 - readonly property color thumbColor: DynamicColors.palette.m3inverseSurface - readonly property color thumbContentColor: DynamicColors.palette.m3inverseOnSurface - readonly property color trackColor: DynamicColors.layer(DynamicColors.palette.m3surfaceContainer, 2) - - function hueToAngle(hue) { - return arcStartAngle + arcSweep * hue; - } - - function normalizeAngle(angle) { - const tau = Math.PI * 2; - let a = angle % tau; - if (a < 0) - a += tau; - return a; - } - - function pointIsOnTrack(x, y) { - const cx = width / 2; - const cy = height / 2; - const dx = x - cx; - const dy = y - cy; - const distance = Math.sqrt(dx * dx + dy * dy); - - return distance >= radius - handleSize / 2 && distance <= radius + handleSize / 2; - } - - function syncFromPenColor() { - if (!drawing) - return; - - const c = drawing.penColor; - - if (c.hsvSaturation > 0) { - currentHue = c.hsvHue; - lastChromaticHue = c.hsvHue; - } else { - currentHue = lastChromaticHue; - } - - canvas.requestPaint(); - } - - function updateHueFromPoint(x, y, force = false) { - const cx = width / 2; - const cy = height / 2; - const dx = x - cx; - const dy = y - cy; - - const distance = Math.sqrt(dx * dx + dy * dy); - - if (!force && (distance < radius - handleSize / 2 || distance > radius + handleSize / 2)) - return; - - const angle = normalizeAngle(Math.atan2(dy, dx)); - const start = normalizeAngle(arcStartAngle); - - let relative = angle - start; - if (relative < 0) - relative += Math.PI * 2; - - if (relative > arcSweep) { - const gap = Math.PI * 2 - arcSweep; - relative = relative < arcSweep + gap / 2 ? arcSweep : 0; - } - - currentHue = relative / arcSweep; - lastChromaticHue = currentHue; - drawing.penColor = Qt.hsva(currentHue, drawing.penColor.hsvSaturation, drawing.penColor.hsvValue, drawing.penColor.a); - } - - implicitHeight: 180 - implicitWidth: 220 - - Component.onCompleted: syncFromPenColor() - onCurrentHueChanged: canvas.requestPaint() - onDrawingChanged: syncFromPenColor() - onHandleSizeChanged: canvas.requestPaint() - onHeightChanged: canvas.requestPaint() - onWidthChanged: canvas.requestPaint() - - Connections { - function onPenColorChanged() { - root.syncFromPenColor(); - } - - target: root.drawing - } - - Canvas { - id: canvas - - anchors.fill: parent - renderStrategy: Canvas.Threaded - renderTarget: Canvas.Image - - Component.onCompleted: requestPaint() - onPaint: { - const ctx = getContext("2d"); - ctx.reset(); - ctx.clearRect(0, 0, width, height); - - const cx = width / 2; - const cy = height / 2; - const radius = root.radius; - const trackWidth = root.handleSize; - - // Background track: always show the full hue spectrum - for (let i = 0; i < root.segmentCount; ++i) { - const t1 = i / root.segmentCount; - const t2 = (i + 1) / root.segmentCount; - const a1 = root.arcStartAngle + root.arcSweep * t1; - const a2 = root.arcStartAngle + root.arcSweep * t2; - - ctx.beginPath(); - ctx.arc(cx, cy, radius, a1, a2); - ctx.lineWidth = trackWidth; - ctx.lineCap = "round"; - ctx.strokeStyle = Qt.hsla(t1, 1.0, 0.5, 1.0); - ctx.stroke(); - } - } - } - - Item { - id: handle - - height: root.handleSize - width: root.handleSize - x: root.handleCenterX - width / 2 - y: root.handleCenterY - height / 2 - z: 1 - - Elevation { - anchors.fill: parent - level: handleHover.containsMouse ? 2 : 1 - radius: rect.radius - } - - Rectangle { - id: rect - - anchors.fill: parent - color: root.thumbColor - radius: width / 2 - - MouseArea { - id: handleHover - - acceptedButtons: Qt.NoButton - anchors.fill: parent - cursorShape: Qt.PointingHandCursor - hoverEnabled: true - } - - Rectangle { - anchors.centerIn: parent - color: root.drawing ? root.drawing.penColor : Qt.hsla(root.currentHue, 1.0, 0.5, 1.0) - height: width - radius: width / 2 - width: parent.width - 12 - } - } - } - - MouseArea { - id: dragArea - - acceptedButtons: Qt.LeftButton - anchors.fill: parent - hoverEnabled: true - - onCanceled: { - root.dragActive = false; - } - onPositionChanged: mouse => { - if ((mouse.buttons & Qt.LeftButton) && root.dragActive) - root.updateHueFromPoint(mouse.x, mouse.y, true); - } - onPressed: mouse => { - root.dragActive = root.pointIsOnTrack(mouse.x, mouse.y); - if (root.dragActive) - root.updateHueFromPoint(mouse.x, mouse.y); - } - onReleased: { - root.dragActive = false; - } - } -} diff --git a/Greeter/Components/ColoredIcon.qml b/Greeter/Components/ColoredIcon.qml deleted file mode 100644 index a4711c6..0000000 --- a/Greeter/Components/ColoredIcon.qml +++ /dev/null @@ -1,34 +0,0 @@ -pragma ComponentBehavior: Bound - -import ZShell -import Quickshell.Widgets -import QtQuick - -IconImage { - id: root - - required property color color - - asynchronous: true - layer.enabled: true - - layer.effect: Coloriser { - colorizationColor: root.color - sourceColor: analyser.dominantColour - } - - layer.onEnabledChanged: { - if (layer.enabled && status === Image.Ready) - analyser.requestUpdate(); - } - onStatusChanged: { - if (layer.enabled && status === Image.Ready) - analyser.requestUpdate(); - } - - ImageAnalyser { - id: analyser - - sourceItem: root - } -} diff --git a/Greeter/Components/Coloriser.qml b/Greeter/Components/Coloriser.qml deleted file mode 100644 index 77bdf8d..0000000 --- a/Greeter/Components/Coloriser.qml +++ /dev/null @@ -1,14 +0,0 @@ -import QtQuick -import QtQuick.Effects - -MultiEffect { - property color sourceColor: "black" - - brightness: 1 - sourceColor.hslLightness - colorization: 1 - - Behavior on colorizationColor { - CAnim { - } - } -} diff --git a/Greeter/Components/CustomAudioSlider.qml b/Greeter/Components/CustomAudioSlider.qml deleted file mode 100644 index f896d83..0000000 --- a/Greeter/Components/CustomAudioSlider.qml +++ /dev/null @@ -1,70 +0,0 @@ -import QtQuick -import QtQuick.Templates -import qs.Config - -Slider { - id: root - - property color nonPeakColor: DynamicColors.tPalette.m3primary - required property real peak - property color peakColor: DynamicColors.palette.m3primary - - background: Item { - CustomRect { - anchors.bottom: parent.bottom - anchors.bottomMargin: root.implicitHeight / 3 - anchors.left: parent.left - anchors.top: parent.top - anchors.topMargin: root.implicitHeight / 3 - bottomRightRadius: root.implicitHeight / 15 - color: root.nonPeakColor - implicitWidth: root.handle.x - root.implicitHeight - radius: Appearance.rounding.full - topRightRadius: root.implicitHeight / 15 - - CustomRect { - anchors.bottom: parent.bottom - anchors.left: parent.left - anchors.top: parent.top - bottomRightRadius: root.implicitHeight / 15 - color: root.peakColor - implicitWidth: parent.width * root.peak - radius: Appearance.rounding.full - topRightRadius: root.implicitHeight / 15 - - Behavior on implicitWidth { - Anim { - duration: 50 - } - } - } - } - - CustomRect { - anchors.bottom: parent.bottom - anchors.bottomMargin: root.implicitHeight / 3 - anchors.right: parent.right - anchors.top: parent.top - anchors.topMargin: root.implicitHeight / 3 - bottomLeftRadius: root.implicitHeight / 15 - color: DynamicColors.tPalette.m3surfaceContainer - implicitWidth: root.implicitWidth - root.handle.x - root.handle.implicitWidth - root.implicitHeight - radius: Appearance.rounding.full - topLeftRadius: root.implicitHeight / 15 - } - } - handle: CustomRect { - anchors.verticalCenter: parent.verticalCenter - color: DynamicColors.palette.m3primary - implicitHeight: 15 - implicitWidth: 5 - radius: Appearance.rounding.full - x: root.visualPosition * root.availableWidth - implicitWidth / 2 - - MouseArea { - acceptedButtons: Qt.NoButton - anchors.fill: parent - cursorShape: Qt.PointingHandCursor - } - } -} diff --git a/Greeter/Components/CustomBusyIndicator.qml b/Greeter/Components/CustomBusyIndicator.qml deleted file mode 100644 index 877db30..0000000 --- a/Greeter/Components/CustomBusyIndicator.qml +++ /dev/null @@ -1,69 +0,0 @@ -import QtQuick -import QtQuick.Controls.Basic - -BusyIndicator { - id: control - - property int busySize: 64 - property color color: delegate.color - - contentItem: Item { - implicitHeight: control.busySize - implicitWidth: control.busySize - - Item { - id: item - - height: control.busySize - opacity: control.running ? 1 : 0 - width: control.busySize - x: parent.width / 2 - (control.busySize / 2) - y: parent.height / 2 - (control.busySize / 2) - - Behavior on opacity { - OpacityAnimator { - duration: 250 - } - } - - RotationAnimator { - duration: 1250 - from: 0 - loops: Animation.Infinite - running: control.visible && control.running - target: item - to: 360 - } - - Repeater { - id: repeater - - model: 6 - - CustomRect { - id: delegate - - required property int index - - color: control.color - implicitHeight: 10 - implicitWidth: 10 - radius: 5 - x: item.width / 2 - width / 2 - y: item.height / 2 - height / 2 - - transform: [ - Translate { - y: -Math.min(item.width, item.height) * 0.5 + 5 - }, - Rotation { - angle: delegate.index / repeater.count * 360 - origin.x: 5 - origin.y: 5 - } - ] - } - } - } - } -} diff --git a/Greeter/Components/CustomButton.qml b/Greeter/Components/CustomButton.qml deleted file mode 100644 index b98710f..0000000 --- a/Greeter/Components/CustomButton.qml +++ /dev/null @@ -1,32 +0,0 @@ -import QtQuick -import QtQuick.Controls -import qs.Config - -Button { - id: control - - property color bgColor: DynamicColors.palette.m3primary - property int radius: Appearance.rounding.smallest / 2 - property color textColor: DynamicColors.palette.m3onPrimary - - background: CustomRect { - color: control.bgColor - opacity: control.enabled ? 1.0 : 0.5 - radius: control.radius - } - contentItem: CustomText { - color: control.textColor - horizontalAlignment: Text.AlignHCenter - opacity: control.enabled ? 1.0 : 0.5 - text: control.text - verticalAlignment: Text.AlignVCenter - } - - StateLayer { - radius: control.radius - - onClicked: { - control.clicked(); - } - } -} diff --git a/Greeter/Components/CustomCheckbox.qml b/Greeter/Components/CustomCheckbox.qml deleted file mode 100644 index a00d407..0000000 --- a/Greeter/Components/CustomCheckbox.qml +++ /dev/null @@ -1,37 +0,0 @@ -import QtQuick -import QtQuick.Controls -import qs.Config - -CheckBox { - id: control - - property int checkHeight: 20 - property int checkWidth: 20 - - contentItem: CustomText { - anchors.left: parent.left - anchors.leftMargin: control.checkWidth + control.leftPadding + 8 - anchors.verticalCenter: parent.verticalCenter - font.pointSize: control.font.pointSize - text: control.text - } - indicator: CustomRect { - // x: control.leftPadding - // y: parent.implicitHeight / 2 - implicitHeight / 2 - border.color: control.checked ? DynamicColors.palette.m3primary : "transparent" - color: DynamicColors.palette.m3surfaceVariant - implicitHeight: control.checkHeight - implicitWidth: control.checkWidth - radius: Appearance.rounding.smallest / 2 - - CustomRect { - color: DynamicColors.palette.m3primary - implicitHeight: control.checkHeight - (y * 2) - implicitWidth: control.checkWidth - (x * 2) - radius: 3 - visible: control.checked - x: 4 - y: 4 - } - } -} diff --git a/Greeter/Components/CustomComboBox.qml b/Greeter/Components/CustomComboBox.qml deleted file mode 100644 index 2a0186f..0000000 --- a/Greeter/Components/CustomComboBox.qml +++ /dev/null @@ -1,169 +0,0 @@ -pragma ComponentBehavior: Bound - -import QtQuick -import QtQuick.Layouts -import QtQuick.Controls -import qs.Config - -ComboBox { - id: root - - property int cornerRadius: Appearance.rounding.normal - property int fieldHeight: 42 - property bool filled: true - property real focusRingOpacity: 0.70 - property int hPadding: 16 - property int menuCornerRadius: 16 - property int menuRowHeight: 46 - property int menuVisibleRows: 7 - property bool preferPopupWindow: false - - hoverEnabled: true - implicitHeight: fieldHeight - implicitWidth: 240 - spacing: 8 - - // ---------- Field background (filled/outlined + state layers + focus ring) ---------- - background: Item { - anchors.fill: parent - - CustomRect { - id: container - - anchors.fill: parent - color: DynamicColors.palette.m3surfaceVariant - radius: root.cornerRadius - - StateLayer { - } - } - } - - // ---------- Content ---------- - contentItem: RowLayout { - anchors.fill: parent - anchors.leftMargin: root.hPadding - anchors.rightMargin: root.hPadding - spacing: 12 - - // Display text - CustomText { - Layout.fillWidth: true - color: root.enabled ? DynamicColors.palette.m3onSurface : DynamicColors.palette.m3onSurfaceVariant - elide: Text.ElideRight - font.pixelSize: 16 - font.weight: Font.Medium - text: root.currentText - verticalAlignment: Text.AlignVCenter - } - - // Indicator chevron (simple, replace with your icon system) - CustomText { - color: root.enabled ? DynamicColors.palette.m3onSurfaceVariant : DynamicColors.palette.m3onSurfaceVariant - rotation: root.popup.visible ? 180 : 0 - text: "▾" - transformOrigin: Item.Center - verticalAlignment: Text.AlignVCenter - - Behavior on rotation { - NumberAnimation { - duration: 140 - easing.type: Easing.OutCubic - } - } - } - } - popup: Popup { - id: p - - implicitHeight: list.contentItem.height + Appearance.padding.small * 2 - implicitWidth: root.width - modal: true - popupType: root.preferPopupWindow ? Popup.Window : Popup.Item - y: -list.currentIndex * (root.menuRowHeight + Appearance.spacing.small) - Appearance.padding.small - - background: CustomRect { - color: DynamicColors.palette.m3surface - radius: root.menuCornerRadius - } - contentItem: ListView { - id: list - - anchors.bottomMargin: Appearance.padding.small - anchors.fill: parent - anchors.topMargin: Appearance.padding.small - clip: true - currentIndex: root.currentIndex - model: root.delegateModel - spacing: Appearance.spacing.small - - delegate: CustomRect { - required property int index - required property var modelData - - anchors.horizontalCenter: parent.horizontalCenter - color: (index === root.currentIndex) ? DynamicColors.palette.m3primary : "transparent" - implicitHeight: root.menuRowHeight - implicitWidth: p.implicitWidth - Appearance.padding.small * 2 - radius: Appearance.rounding.normal - Appearance.padding.small - - RowLayout { - anchors.fill: parent - spacing: 10 - - CustomText { - Layout.fillWidth: true - color: DynamicColors.palette.m3onSurface - elide: Text.ElideRight - font.pixelSize: 15 - text: modelData - verticalAlignment: Text.AlignVCenter - } - - CustomText { - color: DynamicColors.palette.m3onSurfaceVariant - text: "✓" - verticalAlignment: Text.AlignVCenter - visible: index === root.currentIndex - } - } - - StateLayer { - onClicked: { - root.currentIndex = index; - p.close(); - } - } - } - } - - // Expressive-ish open/close motion: subtle scale+fade (tune to taste). :contentReference[oaicite:5]{index=5} - enter: Transition { - Anim { - from: 0 - property: "opacity" - to: 1 - } - - Anim { - from: 0.98 - property: "scale" - to: 1.0 - } - } - exit: Transition { - Anim { - from: 1 - property: "opacity" - to: 0 - } - } - - Elevation { - anchors.fill: parent - level: 2 - radius: root.menuCornerRadius - z: -1 - } - } -} diff --git a/Greeter/Components/CustomIcon.qml b/Greeter/Components/CustomIcon.qml deleted file mode 100644 index 8201305..0000000 --- a/Greeter/Components/CustomIcon.qml +++ /dev/null @@ -1,10 +0,0 @@ -pragma ComponentBehavior: Bound - -import Quickshell.Widgets -import QtQuick - -IconImage { - id: root - - asynchronous: true -} diff --git a/Greeter/Components/CustomRadioButton.qml b/Greeter/Components/CustomRadioButton.qml deleted file mode 100644 index 67204d1..0000000 --- a/Greeter/Components/CustomRadioButton.qml +++ /dev/null @@ -1,53 +0,0 @@ -import QtQuick -import QtQuick.Templates -import qs.Config - -RadioButton { - id: root - - font.pointSize: Appearance.font.size.normal - implicitHeight: Math.max(implicitIndicatorHeight, implicitContentHeight) - implicitWidth: implicitIndicatorWidth + implicitContentWidth + contentItem.anchors.leftMargin - - contentItem: CustomText { - anchors.left: outerCircle.right - anchors.leftMargin: 10 - anchors.verticalCenter: parent.verticalCenter - font.pointSize: root.font.pointSize - text: root.text - } - indicator: Rectangle { - id: outerCircle - - anchors.verticalCenter: parent.verticalCenter - border.color: root.checked ? DynamicColors.palette.m3primary : DynamicColors.palette.m3onSurfaceVariant - border.width: 2 - color: "transparent" - implicitHeight: 16 - implicitWidth: 16 - radius: Appearance.rounding.full - - Behavior on border.color { - CAnim { - } - } - - StateLayer { - anchors.margins: -7 - color: root.checked ? DynamicColors.palette.m3onSurface : DynamicColors.palette.m3primary - z: -1 - - onClicked: { - root.click(); - } - } - - CustomRect { - anchors.centerIn: parent - color: Qt.alpha(DynamicColors.palette.m3primary, root.checked ? 1 : 0) - implicitHeight: 8 - implicitWidth: 8 - radius: Appearance.rounding.full - } - } -} diff --git a/Greeter/Components/CustomScrollBar.qml b/Greeter/Components/CustomScrollBar.qml deleted file mode 100644 index 6597f99..0000000 --- a/Greeter/Components/CustomScrollBar.qml +++ /dev/null @@ -1,189 +0,0 @@ -import qs.Config -import QtQuick -import QtQuick.Templates - -ScrollBar { - id: root - - property bool _updatingFromFlickable: false - property bool _updatingFromUser: false - property bool animating - required property Flickable flickable - property real nonAnimPosition - property bool shouldBeActive - - implicitWidth: 8 - - contentItem: CustomRect { - anchors.left: parent.left - anchors.right: parent.right - color: DynamicColors.palette.m3secondary - opacity: { - if (root.size === 1) - return 0; - if (fullMouse.pressed) - return 1; - if (mouse.containsMouse) - return 0.8; - if (root.policy === ScrollBar.AlwaysOn || root.shouldBeActive) - return 0.6; - return 0; - } - radius: Appearance.rounding.full - - Behavior on opacity { - Anim { - } - } - - MouseArea { - id: mouse - - acceptedButtons: Qt.NoButton - anchors.fill: parent - cursorShape: Qt.PointingHandCursor - hoverEnabled: true - } - } - Behavior on position { - enabled: !fullMouse.pressed - - Anim { - } - } - - Component.onCompleted: { - if (flickable) { - const contentHeight = flickable.contentHeight; - const height = flickable.height; - if (contentHeight > height) { - nonAnimPosition = Math.max(0, Math.min(1, flickable.contentY / (contentHeight - height))); - } - } - } - onHoveredChanged: { - if (hovered) - shouldBeActive = true; - else - shouldBeActive = flickable.moving; - } - - // Sync nonAnimPosition with Qt's automatic position binding - onPositionChanged: { - if (_updatingFromUser) { - _updatingFromUser = false; - return; - } - if (position === nonAnimPosition) { - animating = false; - return; - } - if (!animating && !_updatingFromFlickable && !fullMouse.pressed) { - nonAnimPosition = position; - } - } - - // Sync nonAnimPosition with flickable when not animating - Connections { - function onContentYChanged() { - if (!animating && !fullMouse.pressed) { - _updatingFromFlickable = true; - const contentHeight = flickable.contentHeight; - const height = flickable.height; - if (contentHeight > height) { - nonAnimPosition = Math.max(0, Math.min(1, flickable.contentY / (contentHeight - height))); - } else { - nonAnimPosition = 0; - } - _updatingFromFlickable = false; - } - } - - target: flickable - } - - Connections { - function onMovingChanged(): void { - if (root.flickable.moving) - root.shouldBeActive = true; - else - hideDelay.restart(); - } - - target: root.flickable - } - - Timer { - id: hideDelay - - interval: 600 - - onTriggered: root.shouldBeActive = root.flickable.moving || root.hovered - } - - CustomMouseArea { - id: fullMouse - - function onWheel(event: WheelEvent): void { - root.animating = true; - root._updatingFromUser = true; - let newPos = root.nonAnimPosition; - if (event.angleDelta.y > 0) - newPos = Math.max(0, root.nonAnimPosition - 0.1); - else if (event.angleDelta.y < 0) - newPos = Math.min(1 - root.size, root.nonAnimPosition + 0.1); - root.nonAnimPosition = newPos; - // Update flickable position - // Map scrollbar position [0, 1-size] to contentY [0, maxContentY] - if (root.flickable) { - const contentHeight = root.flickable.contentHeight; - const height = root.flickable.height; - if (contentHeight > height) { - const maxContentY = contentHeight - height; - const maxPos = 1 - root.size; - const contentY = maxPos > 0 ? (newPos / maxPos) * maxContentY : 0; - root.flickable.contentY = Math.max(0, Math.min(maxContentY, contentY)); - } - } - } - - anchors.fill: parent - preventStealing: true - - onPositionChanged: event => { - root._updatingFromUser = true; - const newPos = Math.max(0, Math.min(1 - root.size, event.y / root.height - root.size / 2)); - root.nonAnimPosition = newPos; - // Update flickable position - // Map scrollbar position [0, 1-size] to contentY [0, maxContentY] - if (root.flickable) { - const contentHeight = root.flickable.contentHeight; - const height = root.flickable.height; - if (contentHeight > height) { - const maxContentY = contentHeight - height; - const maxPos = 1 - root.size; - const contentY = maxPos > 0 ? (newPos / maxPos) * maxContentY : 0; - root.flickable.contentY = Math.max(0, Math.min(maxContentY, contentY)); - } - } - } - onPressed: event => { - root.animating = true; - root._updatingFromUser = true; - const newPos = Math.max(0, Math.min(1 - root.size, event.y / root.height - root.size / 2)); - root.nonAnimPosition = newPos; - // Update flickable position - // Map scrollbar position [0, 1-size] to contentY [0, maxContentY] - if (root.flickable) { - const contentHeight = root.flickable.contentHeight; - const height = root.flickable.height; - if (contentHeight > height) { - const maxContentY = contentHeight - height; - const maxPos = 1 - root.size; - const contentY = maxPos > 0 ? (newPos / maxPos) * maxContentY : 0; - root.flickable.contentY = Math.max(0, Math.min(maxContentY, contentY)); - } - } - } - } -} diff --git a/Greeter/Components/CustomShortcut.qml b/Greeter/Components/CustomShortcut.qml deleted file mode 100644 index c60cbef..0000000 --- a/Greeter/Components/CustomShortcut.qml +++ /dev/null @@ -1,5 +0,0 @@ -import Quickshell.Hyprland - -GlobalShortcut { - appid: "zshell" -} diff --git a/Greeter/Components/CustomSlider.qml b/Greeter/Components/CustomSlider.qml deleted file mode 100644 index 3041698..0000000 --- a/Greeter/Components/CustomSlider.qml +++ /dev/null @@ -1,174 +0,0 @@ -pragma ComponentBehavior: Bound - -import QtQuick -import QtQuick.Templates -import ZShell.Components -import ZShell -import qs.Components -import qs.Config - -Slider { - id: root - - property bool animateWave - property color bgColor: enabled ? DynamicColors.palette.m3secondaryContainer : Qt.alpha(DynamicColors.palette.m3onSurface, 0.1) - property color fgColor: enabled ? DynamicColors.palette.m3primary : Qt.alpha(DynamicColors.palette.m3onSurface, 0.38) - property real filledWidth - property real pos: visualPosition - property int waveDuration: 1000 - property real waveFrequency: 6 - property bool wavy - - signal interaction(v: real) - - implicitHeight: 12 - implicitWidth: 200 - - contentItem: Item { - anchors.fill: parent - - CustomRect { - id: remaining - - anchors.left: handle.right - anchors.leftMargin: Appearance.spacing.extraSmall - anchors.right: parent.right - anchors.verticalCenter: parent.verticalCenter - bottomLeftRadius: Appearance.rounding.extraSmall / 2 - color: root.bgColor - implicitHeight: parent.height * (parent.height <= 12 ? opacity : Math.min(opacity * 2, 1)) - opacity: Math.min(width, 12) / 12 - radius: Appearance.rounding.small - topLeftRadius: Appearance.rounding.extraSmall / 2 - } - - CustomRect { - anchors.right: parent.right - anchors.rightMargin: 4 * remaining.opacity - anchors.verticalCenter: parent.verticalCenter - color: root.fgColor - implicitHeight: 4 * remaining.opacity - implicitWidth: implicitHeight - opacity: remaining.opacity - radius: Appearance.rounding.full - } - - CustomRect { - id: handle - - anchors.left: filled.right - anchors.leftMargin: Appearance.spacing.extraSmall - anchors.verticalCenter: parent.verticalCenter - color: root.fgColor - implicitHeight: { - const mult = parent.height <= 12 ? 3 : 1.2; - const pressMult = parent.height <= 12 ? 4 : 1.5; - return parent.height * (mouse.pressed ? pressMult : mult); - } - implicitWidth: 4 - radius: Appearance.rounding.full - - Behavior on implicitHeight { - Anim { - type: Anim.FastSpatial - } - } - } - - Loader { - id: filled - - anchors.left: parent.left - anchors.verticalCenter: parent.verticalCenter - asynchronous: true - sourceComponent: root.wavy ? waveComp : lineComp - } - - Component { - id: lineComp - - CustomRect { - bottomRightRadius: Appearance.rounding.extraSmall / 2 - color: root.fgColor - implicitHeight: root.height - implicitWidth: root.filledWidth - radius: Appearance.rounding.small - topRightRadius: Appearance.rounding.extraSmall / 2 - } - } - - Component { - id: waveComp - - WavyLine { - color: root.fgColor - frequency: root.waveFrequency - fullLength: root.width - handle.implicitWidth - handle.anchors.leftMargin - implicitHeight: lineWidth * amplitudeMultiplier * 2 + lineWidth - implicitWidth: root.filledWidth - lineWidth: root.height * 0.7 - startX: x - - Behavior on color { - CAnim { - } - } - Anim on waveProgress { - duration: root.waveDuration - easing.type: Easing.Linear - from: 0 - loops: Animation.Infinite - paused: !root.animateWave - running: true - to: 1 - } - } - } - } - Behavior on filledWidth { - id: widthBehavior - - Anim { - } - } - - Component.onCompleted: filledWidth = Qt.binding(() => (width - handle.implicitWidth - handle.anchors.leftMargin) * pos) - - Binding { - id: posBinding - - property: "pos" - target: root - value: ZUtils.clamp(mouse.pressStartPos + mouse.dragMovement, 0, 1) - when: mouse.pressed - } - - MouseArea { - id: mouse - - property real dragMovement - property real pressStartPos - property real pressStartX - - anchors.left: parent.left - anchors.right: parent.right - anchors.verticalCenter: parent.verticalCenter - implicitHeight: handle.implicitHeight - preventStealing: true - - onPositionChanged: e => { - dragMovement = (e.x - pressStartX) / width; - root.interaction(posBinding.value); - } - onPressed: e => { - widthBehavior.enabled = false; - pressStartX = e.x; - pressStartPos = root.visualPosition; - } - onReleased: e => { - root.interaction(posBinding.value); - widthBehavior.enabled = true; - dragMovement = 0; - } - } -} diff --git a/Greeter/Components/CustomSpinBox.qml b/Greeter/Components/CustomSpinBox.qml deleted file mode 100644 index 7526242..0000000 --- a/Greeter/Components/CustomSpinBox.qml +++ /dev/null @@ -1,168 +0,0 @@ -pragma ComponentBehavior: Bound - -import QtQuick -import QtQuick.Layouts -import qs.Config - -RowLayout { - id: root - - property string displayText: root.value.toString() - property bool isEditing: false - property real max: Infinity - property real min: -Infinity - property alias repeatRate: timer.interval - property real step: 1 - property real value - - signal valueModified(value: real) - - spacing: Appearance.spacing.small - - onValueChanged: { - if (!root.isEditing) { - root.displayText = root.value.toString(); - } - } - - CustomTextField { - id: textField - - color: root.enabled ? DynamicColors.palette.m3onSurface : Qt.alpha(DynamicColors.palette.m3onSurface, 0.5) - implicitHeight: upButton.implicitHeight - inputMethodHints: Qt.ImhFormattedNumbersOnly - leftPadding: Appearance.padding.normal - padding: Appearance.padding.small - rightPadding: Appearance.padding.normal - text: root.isEditing ? text : root.displayText - - background: CustomRect { - color: root.enabled ? DynamicColors.tPalette.m3surfaceContainerHigh : DynamicColors.tPalette.m3surfaceContainerLow - implicitWidth: 100 - radius: Appearance.rounding.full - } - validator: DoubleValidator { - bottom: root.min - decimals: root.step < 1 ? Math.max(1, Math.ceil(-Math.log10(root.step))) : 0 - top: root.max - } - - onAccepted: { - const numValue = parseFloat(text); - if (!isNaN(numValue)) { - const clampedValue = Math.max(root.min, Math.min(root.max, numValue)); - root.value = clampedValue; - root.displayText = clampedValue.toString(); - root.valueModified(clampedValue); - } else { - text = root.displayText; - } - root.isEditing = false; - } - onActiveFocusChanged: { - if (activeFocus) { - root.isEditing = true; - } else { - root.isEditing = false; - root.displayText = root.value.toString(); - } - } - onEditingFinished: { - if (text !== root.displayText) { - const numValue = parseFloat(text); - if (!isNaN(numValue)) { - const clampedValue = Math.max(root.min, Math.min(root.max, numValue)); - root.value = clampedValue; - root.displayText = clampedValue.toString(); - root.valueModified(clampedValue); - } else { - text = root.displayText; - } - } - root.isEditing = false; - } - } - - CustomRect { - id: upButton - - color: root.enabled ? DynamicColors.palette.m3primary : DynamicColors.layer(DynamicColors.palette.m3surfaceContainerHighest, 1) - implicitHeight: upIcon.implicitHeight + Appearance.padding.small * 2 - implicitWidth: implicitHeight - radius: Appearance.rounding.full - - StateLayer { - id: upState - - color: DynamicColors.palette.m3onPrimary - - onClicked: { - let newValue = Math.min(root.max, root.value + root.step); - // Round to avoid floating point precision errors - const decimals = root.step < 1 ? Math.max(1, Math.ceil(-Math.log10(root.step))) : 0; - newValue = Math.round(newValue * Math.pow(10, decimals)) / Math.pow(10, decimals); - root.value = newValue; - root.displayText = newValue.toString(); - root.valueModified(newValue); - } - onPressAndHold: timer.start() - onReleased: timer.stop() - } - - MaterialIcon { - id: upIcon - - anchors.centerIn: parent - color: root.enabled ? DynamicColors.palette.m3onPrimary : Qt.alpha(DynamicColors.palette.m3onSurface, 0.5) - text: "keyboard_arrow_up" - } - } - - CustomRect { - color: root.enabled ? DynamicColors.palette.m3primary : DynamicColors.layer(DynamicColors.palette.m3surfaceContainerHighest, 1) - implicitHeight: downIcon.implicitHeight + Appearance.padding.small * 2 - implicitWidth: implicitHeight - radius: Appearance.rounding.full - - StateLayer { - id: downState - - color: DynamicColors.palette.m3onPrimary - - onClicked: { - let newValue = Math.max(root.min, root.value - root.step); - // Round to avoid floating point precision errors - const decimals = root.step < 1 ? Math.max(1, Math.ceil(-Math.log10(root.step))) : 0; - newValue = Math.round(newValue * Math.pow(10, decimals)) / Math.pow(10, decimals); - root.value = newValue; - root.displayText = newValue.toString(); - root.valueModified(newValue); - } - onPressAndHold: timer.start() - onReleased: timer.stop() - } - - MaterialIcon { - id: downIcon - - anchors.centerIn: parent - color: root.enabled ? DynamicColors.palette.m3onPrimary : Qt.alpha(DynamicColors.palette.m3onSurface, 0.5) - text: "keyboard_arrow_down" - } - } - - Timer { - id: timer - - interval: 100 - repeat: true - triggeredOnStart: true - - onTriggered: { - if (upState.pressed) - upState.onClicked(); - else if (downState.pressed) - downState.onClicked(); - } - } -} diff --git a/Greeter/Components/CustomSplitButton.qml b/Greeter/Components/CustomSplitButton.qml deleted file mode 100644 index 76364cc..0000000 --- a/Greeter/Components/CustomSplitButton.qml +++ /dev/null @@ -1,148 +0,0 @@ -import QtQuick -import QtQuick.Layouts -import qs.Config - -Row { - id: root - - enum Type { - Filled, - Tonal - } - - property alias active: menu.active - property color colour: type == CustomSplitButton.Filled ? DynamicColors.palette.m3primary : DynamicColors.palette.m3secondaryContainer - property bool disabled - property color disabledColour: Qt.alpha(DynamicColors.palette.m3onSurface, 0.1) - property color disabledTextColour: Qt.alpha(DynamicColors.palette.m3onSurface, 0.38) - readonly property alias expandBtn: expandBtn - property alias expanded: menu.expanded - property string fallbackIcon - property string fallbackText - property real horizontalPadding: Appearance.padding.larger - readonly property alias iconLabel: iconLabel - readonly property alias label: label - readonly property alias menu: menu - property alias menuItems: menu.items - property bool menuOnTop - property real minLeftWidth - readonly property alias stateLayer: stateLayer - property color textColour: type == CustomSplitButton.Filled ? DynamicColors.palette.m3onPrimary : DynamicColors.palette.m3onSecondaryContainer - readonly property alias textRow: textRow - property int type: CustomSplitButton.Filled - property real verticalPadding: Appearance.padding.small - - spacing: Math.floor(Appearance.spacing.extraSmall) - - CustomRect { - bottomRightRadius: Appearance.rounding.small / 2 - color: root.disabled ? root.disabledColour : root.colour - implicitHeight: expandBtn.implicitHeight - implicitWidth: Math.max(root.minLeftWidth, textRow.implicitWidth + root.horizontalPadding * 2) - radius: implicitHeight / 2 * Math.min(1, Appearance.rounding.scale) - topRightRadius: Appearance.rounding.small / 2 - - StateLayer { - id: stateLayer - - bottomRightRadius: parent.bottomRightRadius - color: root.textColour - disabled: root.disabled - topRightRadius: parent.topRightRadius - - onClicked: root.active?.clicked() - } - - RowLayout { - id: textRow - - anchors.centerIn: parent - anchors.horizontalCenterOffset: Math.floor(root.verticalPadding / 4) - spacing: Appearance.spacing.small - - MaterialIcon { - id: iconLabel - - Layout.alignment: Qt.AlignVCenter - animate: true - color: root.disabled ? root.disabledTextColour : root.textColour - fill: 1 - text: root.active?.activeIcon ?? root.fallbackIcon - } - - CustomText { - id: label - - Layout.alignment: Qt.AlignVCenter - Layout.preferredWidth: implicitWidth - animate: true - clip: true - color: root.disabled ? root.disabledTextColour : root.textColour - text: root.active?.activeText ?? root.fallbackText - - Behavior on Layout.preferredWidth { - Anim { - type: Anim.Emphasized - } - } - } - } - } - - CustomRect { - id: expandBtn - - property real rad: root.expanded ? implicitHeight / 2 * Math.min(1, Appearance.rounding.scale) : Appearance.rounding.small / 2 - - bottomLeftRadius: rad - color: root.disabled ? root.disabledColour : root.colour - implicitHeight: expandIcon.implicitHeight + root.verticalPadding * 2 - implicitWidth: implicitHeight - radius: implicitHeight / 2 * Math.min(1, Appearance.rounding.scale) - topLeftRadius: rad - - Behavior on rad { - Anim { - } - } - - StateLayer { - id: expandStateLayer - - color: root.textColour - disabled: root.disabled - rect.bottomLeftRadius: parent.bottomLeftRadius - rect.topLeftRadius: parent.topLeftRadius - - onClicked: root.expanded = !root.expanded - } - - MaterialIcon { - id: expandIcon - - anchors.centerIn: parent - anchors.horizontalCenterOffset: root.expanded ? 0 : -Math.floor(root.verticalPadding / 4) - color: root.disabled ? root.disabledTextColour : root.textColour - rotation: root.expanded ? 180 : 0 - text: "expand_more" - - Behavior on anchors.horizontalCenterOffset { - Anim { - } - } - Behavior on rotation { - Anim { - } - } - } - } - - Menu { - id: menu - - attachSideY: root.menuOnTop ? Menu.Top : Menu.Bottom - attachTo: expandBtn - marginY: Appearance.spacing.small * (root.menuOnTop ? -1 : 1) - thisSideY: root.menuOnTop ? Menu.Bottom : Menu.Top - } -} diff --git a/Greeter/Components/CustomSplitButtonRow.qml b/Greeter/Components/CustomSplitButtonRow.qml deleted file mode 100644 index 11f0c3b..0000000 --- a/Greeter/Components/CustomSplitButtonRow.qml +++ /dev/null @@ -1,69 +0,0 @@ -pragma ComponentBehavior: Bound - -import QtQuick -import QtQuick.Layouts -import qs.Config - -Item { - id: root - - property alias active: splitButton.active - property alias buttonAlias: splitButton - property alias expanded: splitButton.expanded - property int expandedZ: 100 - required property string label - property alias menuItems: splitButton.menuItems - property bool shouldBeActive: true - property alias type: splitButton.type - - signal selected(item: MenuItem) - - anchors.left: parent.left - anchors.right: parent.right - clip: false - implicitHeight: row.implicitHeight + Appearance.padding.smaller * 2 - opacity: shouldBeActive ? 1 : 0 - scale: shouldBeActive ? 1 : 0.8 - z: splitButton.menu.implicitHeight > 0 ? expandedZ : 1 - - Behavior on opacity { - Anim { - } - } - Behavior on scale { - Anim { - } - } - - RowLayout { - id: row - - anchors.left: parent.left - anchors.margins: Appearance.padding.small - anchors.right: parent.right - anchors.verticalCenter: parent.verticalCenter - spacing: Appearance.spacing.normal - - CustomText { - Layout.fillWidth: true - color: root.enabled ? DynamicColors.palette.m3onSurface : DynamicColors.palette.m3onSurfaceVariant - font.pointSize: Appearance.font.size.larger - text: root.label - } - - CustomSplitButton { - id: splitButton - - enabled: root.enabled - type: CustomSplitButton.Filled - z: 2 - - menu.onItemSelected: item => { - root.selected(item); - } - stateLayer.onClicked: { - splitButton.expanded = !splitButton.expanded; - } - } - } -} diff --git a/Greeter/Components/CustomSwitch.qml b/Greeter/Components/CustomSwitch.qml deleted file mode 100644 index e715f15..0000000 --- a/Greeter/Components/CustomSwitch.qml +++ /dev/null @@ -1,157 +0,0 @@ -import QtQuick -import QtQuick.Shapes -import QtQuick.Templates -import qs.Config - -Switch { - id: root - - property int cLayer: 1 - - implicitHeight: implicitIndicatorHeight - implicitWidth: implicitIndicatorWidth - - indicator: CustomRect { - color: root.checked && root.enabled ? DynamicColors.palette.m3primary : DynamicColors.layer(DynamicColors.palette.m3surfaceContainerHighest, root.cLayer) - implicitHeight: Appearance.font.size.medium + Appearance.padding.normal * 2 - implicitWidth: implicitHeight * 1.7 - radius: Appearance.rounding.full - - CustomRect { - readonly property real nonAnimWidth: root.pressed ? implicitHeight * 1.2 : implicitHeight - - anchors.verticalCenter: parent.verticalCenter - color: root.checked && root.enabled ? DynamicColors.palette.m3onPrimary : DynamicColors.layer(DynamicColors.palette.m3outline, root.cLayer + 1) - implicitHeight: parent.implicitHeight - Appearance.padding.extraSmall - implicitWidth: nonAnimWidth - radius: Appearance.rounding.full - x: root.checked ? parent.implicitWidth - nonAnimWidth - Appearance.padding.extraSmall / 2 : Appearance.padding.extraSmall / 2 - - Behavior on implicitWidth { - Anim { - type: Anim.FastSpatial - } - } - Behavior on x { - Anim { - type: Anim.FastSpatial - } - } - - CustomRect { - anchors.fill: parent - color: root.checked && root.enabled ? DynamicColors.palette.m3primary : DynamicColors.palette.m3onSurface - opacity: root.pressed ? 0.1 : root.hovered ? 0.08 : 0 - radius: parent.radius - - Behavior on opacity { - Anim { - type: Anim.DefaultEffects - } - } - } - - Shape { - id: icon - - property point end1: { - if (root.pressed) { - if (root.checked) - return Qt.point(width * 0.4, height / 2); - return Qt.point(width * 0.8, height / 2); - } - if (root.checked) - return Qt.point(width * 0.4, height * 0.7); - return Qt.point(width * 0.85, height * 0.85); - } - property point end2: { - if (root.pressed) - return Qt.point(width * 0.8, height / 2); - if (root.checked) - return Qt.point(width * 0.85, height * 0.2); - return Qt.point(width * 0.85, height * 0.15); - } - property point start1: { - if (root.pressed) - return Qt.point(width * 0.2, height / 2); - if (root.checked) - return Qt.point(width * 0.15, height / 2); - return Qt.point(width * 0.15, height * 0.15); - } - property point start2: { - if (root.pressed) { - if (root.checked) - return Qt.point(width * 0.4, height / 2); - return Qt.point(width * 0.2, height / 2); - } - if (root.checked) - return Qt.point(width * 0.4, height * 0.7); - return Qt.point(width * 0.15, height * 0.85); - } - - anchors.centerIn: parent - asynchronous: true - height: parent.implicitHeight - Appearance.padding.larger - preferredRendererType: Shape.CurveRenderer - width: height - - Behavior on end1 { - PropAnim { - } - } - Behavior on end2 { - PropAnim { - } - } - Behavior on start1 { - PropAnim { - } - } - Behavior on start2 { - PropAnim { - } - } - - ShapePath { - capStyle: ShapePath.RoundCap - fillColor: "transparent" - startX: icon.start1.x - startY: icon.start1.y - strokeColor: root.checked && root.enabled ? DynamicColors.palette.m3primary : DynamicColors.palette.m3surfaceContainerHighest - strokeWidth: Appearance.font.size.larger * 0.15 - - Behavior on strokeColor { - CAnim { - } - } - - PathLine { - x: icon.end1.x - y: icon.end1.y - } - - PathMove { - x: icon.start2.x - y: icon.start2.y - } - - PathLine { - x: icon.end2.x - y: icon.end2.y - } - } - } - } - } - - MouseArea { - anchors.fill: parent - cursorShape: Qt.PointingHandCursor - enabled: false - } - - component PropAnim: PropertyAnimation { - duration: Appearance.anim.durations.expressiveFastSpatial - easing.bezierCurve: Appearance.anim.curves.expressiveFastSpatial - } -} diff --git a/Greeter/Components/CustomText.qml b/Greeter/Components/CustomText.qml index f4c1600..abd4952 100644 --- a/Greeter/Components/CustomText.qml +++ b/Greeter/Components/CustomText.qml @@ -1,7 +1,8 @@ pragma ComponentBehavior: Bound import QtQuick -import qs.Config +import ZShell.Config +import qs.Services Text { id: root @@ -12,10 +13,10 @@ Text { property string animateProp: "scale" property real animateTo: 1 - color: DynamicColors.palette.m3onSurface - font.family: Appearance.font.family.sans - font.pointSize: Appearance.font.size.normal - linkColor: DynamicColors.palette.m3onPrimaryFixedVariant + color: Colors.palette.m3onSurface + font.family: Config.appearance.font.family.sans + font.pointSize: Tokens.font.size.normal + linkColor: Colors.palette.m3onPrimaryFixedVariant renderType: Text.NativeRendering textFormat: Text.PlainText @@ -28,7 +29,6 @@ Text { SequentialAnimation { Anim { - easing.bezierCurve: MaterialEasing.standardAccel to: root.animateFrom } @@ -36,7 +36,6 @@ Text { } Anim { - easing.bezierCurve: MaterialEasing.standardDecel to: root.animateTo } } diff --git a/Greeter/Components/CustomTextField.qml b/Greeter/Components/CustomTextField.qml index 16c39a6..4edfe69 100644 --- a/Greeter/Components/CustomTextField.qml +++ b/Greeter/Components/CustomTextField.qml @@ -2,17 +2,18 @@ pragma ComponentBehavior: Bound import QtQuick import QtQuick.Controls -import qs.Config +import ZShell.Config +import qs.Services TextField { id: root background: null - color: DynamicColors.palette.m3onSurface + color: Colors.palette.m3onSurface cursorVisible: !readOnly - font.family: Appearance.font.family.sans - font.pointSize: Appearance.font.size.smaller - placeholderTextColor: DynamicColors.palette.m3outline + font.family: Config.appearance.font.family.sans + font.pointSize: Tokens.font.size.smaller + placeholderTextColor: Colors.palette.m3outline renderType: echoMode === TextField.Password ? TextField.QtRendering : TextField.NativeRendering Behavior on color { @@ -24,13 +25,13 @@ TextField { property bool disableBlink - color: DynamicColors.palette.m3primary + color: Colors.palette.m3primary implicitWidth: 2 - radius: Appearance.rounding.normal + radius: Tokens.rounding.normal Behavior on opacity { Anim { - duration: Appearance.anim.durations.small + duration: Tokens.anim.durations.small } } diff --git a/Greeter/Components/CustomTextInput.qml b/Greeter/Components/CustomTextInput.qml index 25b1eed..2a6dcc6 100644 --- a/Greeter/Components/CustomTextInput.qml +++ b/Greeter/Components/CustomTextInput.qml @@ -1,15 +1,16 @@ import QtQuick import QtQuick.Controls -import qs.Config +import ZShell.Config +import qs.Services TextInput { renderType: Text.NativeRendering - selectedTextColor: DynamicColors.palette.m3onSecondaryContainer - selectionColor: DynamicColors.tPalette.colSecondaryContainer + selectedTextColor: Colors.palette.m3onSecondaryContainer + selectionColor: Colors.tPalette.m3onSecondaryContainer font { - family: Appearance?.font.family.sans ?? "sans-serif" + family: Config.appearance?.font.family.sans ?? "sans-serif" hintingPreference: Font.PreferFullHinting - pixelSize: Appearance?.font.size.normal ?? 15 + pixelSize: Config.appearance?.font.size.normal ?? 15 } } diff --git a/Greeter/Components/CustomTooltip.qml b/Greeter/Components/CustomTooltip.qml deleted file mode 100644 index 59cb1ad..0000000 --- a/Greeter/Components/CustomTooltip.qml +++ /dev/null @@ -1,25 +0,0 @@ -import QtQuick -import QtQuick.Controls -import qs.Components - -ToolTip { - id: root - - property bool alternativeVisibleCondition: false - property bool extraVisibleCondition: true - readonly property bool internalVisibleCondition: (extraVisibleCondition && (parent.hovered === undefined || parent?.hovered)) || alternativeVisibleCondition - - background: null - horizontalPadding: 10 - verticalPadding: 5 - visible: internalVisibleCondition - - contentItem: CustomTooltipContent { - id: contentItem - - horizontalPadding: root.horizontalPadding - shown: root.internalVisibleCondition - text: root.text - verticalPadding: root.verticalPadding - } -} diff --git a/Greeter/Components/CustomTooltipContent.qml b/Greeter/Components/CustomTooltipContent.qml deleted file mode 100644 index 00a4270..0000000 --- a/Greeter/Components/CustomTooltipContent.qml +++ /dev/null @@ -1,54 +0,0 @@ -import QtQuick -import qs.Components -import qs.Config - -Item { - id: root - - property real horizontalPadding: 10 - property bool isVisible: backgroundRectangle.implicitHeight > 0 - property bool shown: false - required property string text - property real verticalPadding: 5 - - implicitHeight: tooltipTextObject.implicitHeight + 2 * root.verticalPadding - implicitWidth: tooltipTextObject.implicitWidth + 2 * root.horizontalPadding - - Rectangle { - id: backgroundRectangle - - clip: true - color: DynamicColors.tPalette.m3inverseSurface ?? "#3C4043" - implicitHeight: shown ? (tooltipTextObject.implicitHeight + 2 * root.verticalPadding) : 0 - implicitWidth: shown ? (tooltipTextObject.implicitWidth + 2 * root.horizontalPadding) : 0 - opacity: shown ? 1 : 0 - radius: Appearance.rounding.smallest - - Behavior on implicitHeight { - Anim { - } - } - Behavior on implicitWidth { - Anim { - } - } - Behavior on opacity { - Anim { - } - } - - anchors { - bottom: root.bottom - horizontalCenter: root.horizontalCenter - } - - CustomText { - id: tooltipTextObject - - anchors.centerIn: parent - color: DynamicColors.palette.m3inverseOnSurface ?? "#FFFFFF" - text: root.text - wrapMode: Text.Wrap - } - } -} diff --git a/Greeter/Components/Elevation.qml b/Greeter/Components/Elevation.qml index bdef51e..31d330d 100644 --- a/Greeter/Components/Elevation.qml +++ b/Greeter/Components/Elevation.qml @@ -1,13 +1,14 @@ import QtQuick import QtQuick.Effects -import qs.Config +import ZShell.Config +import qs.Services RectangularShadow { property real dp: [0, 1, 3, 6, 8, 12][level] property int level blur: (dp * 5) ** 0.7 - color: Qt.alpha(DynamicColors.palette.m3shadow, 0.7) + color: Qt.alpha(Colors.palette.m3shadow, 0.7) offset.y: dp / 2 spread: -dp * 0.3 + (dp * 0.1) ** 2 diff --git a/Greeter/Components/ExtraIndicator.qml b/Greeter/Components/ExtraIndicator.qml deleted file mode 100644 index 34315e7..0000000 --- a/Greeter/Components/ExtraIndicator.qml +++ /dev/null @@ -1,44 +0,0 @@ -import qs.Config -import QtQuick - -CustomRect { - required property int extra - - anchors.margins: 8 - anchors.right: parent.right - color: DynamicColors.palette.m3tertiary - implicitHeight: count.implicitHeight + 4 * 2 - implicitWidth: count.implicitWidth + 8 * 2 - opacity: extra > 0 ? 1 : 0 - radius: Appearance.rounding.smallest - scale: extra > 0 ? 1 : 0.5 - - Behavior on opacity { - Anim { - duration: MaterialEasing.expressiveEffectsTime - } - } - Behavior on scale { - Anim { - duration: MaterialEasing.expressiveEffectsTime - easing.bezierCurve: MaterialEasing.expressiveEffects - } - } - - Elevation { - anchors.fill: parent - level: 2 - opacity: parent.opacity - radius: parent.radius - z: -1 - } - - CustomText { - id: count - - anchors.centerIn: parent - animate: parent.opacity > 0 - color: DynamicColors.palette.m3onTertiary - text: qsTr("+%1").arg(parent.extra) - } -} diff --git a/Greeter/Components/FilledSlider.qml b/Greeter/Components/FilledSlider.qml deleted file mode 100644 index d38d1cb..0000000 --- a/Greeter/Components/FilledSlider.qml +++ /dev/null @@ -1,29 +0,0 @@ -import QtQuick -import qs.Config - -BaseStyledSlider { - id: root - - trackContent: Component { - Item { - property var groove - readonly property real handleHeight: handleItem ? handleItem.height : 0 - property var handleItem - readonly property real handleWidth: handleItem ? handleItem.width : 0 - - // Set by BaseStyledSlider's Loader - property var rootSlider - - anchors.fill: parent - - CustomRect { - color: rootSlider?.color - height: rootSlider?.isVertical ? handleHeight + (1 - rootSlider?.visualPosition) * (groove?.height - handleHeight) : groove?.height - radius: groove?.radius - width: rootSlider?.isHorizontal ? handleWidth + rootSlider?.visualPosition * (groove?.width - handleWidth) : groove?.width - x: rootSlider?.isHorizontal ? (rootSlider?.mirrored ? groove?.width - width : 0) : 0 - y: rootSlider?.isVertical ? groove?.height - height : 0 - } - } - } -} diff --git a/Greeter/Components/GradientSlider.qml b/Greeter/Components/GradientSlider.qml deleted file mode 100644 index c19f161..0000000 --- a/Greeter/Components/GradientSlider.qml +++ /dev/null @@ -1,47 +0,0 @@ -import QtQuick -import qs.Config - -BaseStyledSlider { - id: root - - property real alpha: 1.0 - property real brightness: 1.0 - property string channel: "saturation" - readonly property color currentColor: Qt.hsva(hue, channel === "saturation" ? value : saturation, channel === "brightness" ? value : brightness, alpha) - property real hue: 0.0 - property real saturation: 1.0 - - from: 0 - to: 1 - - trackContent: Component { - Item { - property var groove - property var handleItem - property var rootSlider - - anchors.fill: parent - - Rectangle { - anchors.fill: parent - antialiasing: true - color: "transparent" - radius: groove?.radius ?? 0 - - gradient: Gradient { - orientation: rootSlider?.isHorizontal ? Gradient.Horizontal : Gradient.Vertical - - GradientStop { - color: root.channel === "saturation" ? Qt.hsva(root.hue, 0.0, root.brightness, root.alpha) : Qt.hsva(root.hue, root.saturation, 0.0, root.alpha) - position: 0.0 - } - - GradientStop { - color: root.channel === "saturation" ? Qt.hsva(root.hue, 1.0, root.brightness, root.alpha) : Qt.hsva(root.hue, root.saturation, 1.0, root.alpha) - position: 1.0 - } - } - } - } - } -} diff --git a/Greeter/Components/HoverIconButton.qml b/Greeter/Components/HoverIconButton.qml deleted file mode 100644 index cd17ad0..0000000 --- a/Greeter/Components/HoverIconButton.qml +++ /dev/null @@ -1,33 +0,0 @@ -import QtQuick -import QtQuick.Controls -import qs.Config - -IconButton { - id: root - - required property bool shouldBeVisible - - opacity: 0 - scale: 0 - visible: root.scale > 0 - - Behavior on opacity { - Anim { - duration: Appearance.anim.durations.small - } - } - Behavior on scale { - Anim { - } - } - - onShouldBeVisibleChanged: { - if (root.shouldBeVisible) { - root.opacity = 1; - root.scale = 1; - } else { - root.opacity = 0; - root.scale = 0; - } - } -} diff --git a/Greeter/Components/IconButton.qml b/Greeter/Components/IconButton.qml deleted file mode 100644 index 22314f7..0000000 --- a/Greeter/Components/IconButton.qml +++ /dev/null @@ -1,79 +0,0 @@ -import qs.Config -import QtQuick - -CustomRect { - id: root - - enum Type { - Filled, - Tonal, - Text - } - - property color activeColour: type === IconButton.Filled ? DynamicColors.palette.m3primary : DynamicColors.palette.m3secondary - property color activeOnColour: type === IconButton.Filled ? DynamicColors.palette.m3onPrimary : type === IconButton.Tonal ? DynamicColors.palette.m3onSecondary : DynamicColors.palette.m3primary - property bool checked - property bool disabled - property color disabledColour: Qt.alpha(DynamicColors.palette.m3onSurface, 0.1) - property color disabledOnColour: Qt.alpha(DynamicColors.palette.m3onSurface, 0.38) - property alias font: label.font - property alias icon: label.text - property color inactiveColour: { - if (!toggle && type === IconButton.Filled) - return DynamicColors.palette.m3primary; - return type === IconButton.Filled ? DynamicColors.tPalette.m3surfaceContainer : DynamicColors.palette.m3secondaryContainer; - } - property color inactiveOnColour: { - if (!toggle && type === IconButton.Filled) - return DynamicColors.palette.m3onPrimary; - return type === IconButton.Tonal ? DynamicColors.palette.m3onSecondaryContainer : DynamicColors.palette.m3onSurfaceVariant; - } - property bool internalChecked - property alias label: label - property real padding: type === IconButton.Text ? 10 / 2 : 7 - property alias radiusAnim: radiusAnim - property alias stateLayer: stateLayer - property bool toggle - property int type: IconButton.Filled - - signal clicked - - color: type === IconButton.Text ? "transparent" : disabled ? disabledColour : internalChecked ? activeColour : inactiveColour - implicitHeight: label.implicitHeight + padding * 2 - implicitWidth: implicitHeight - radius: internalChecked ? 6 : (implicitHeight / 2 * Math.min(1, 1)) * Appearance.rounding.scale - - Behavior on radius { - Anim { - id: radiusAnim - } - } - - onCheckedChanged: internalChecked = checked - - StateLayer { - id: stateLayer - - color: root.internalChecked ? root.activeOnColour : root.inactiveOnColour - disabled: root.disabled - - onClicked: { - if (root.toggle) - root.internalChecked = !root.internalChecked; - root.clicked(); - } - } - - MaterialIcon { - id: label - - anchors.centerIn: parent - color: root.disabled ? root.disabledOnColour : root.internalChecked ? root.activeOnColour : root.inactiveOnColour - fill: !root.toggle || root.internalChecked ? 1 : 0 - - Behavior on fill { - Anim { - } - } - } -} diff --git a/Greeter/Components/MarqueeText.qml b/Greeter/Components/MarqueeText.qml deleted file mode 100644 index 427d381..0000000 --- a/Greeter/Components/MarqueeText.qml +++ /dev/null @@ -1,223 +0,0 @@ -import QtQuick -import qs.Config - -Item { - id: root - - property alias anim: marqueeAnim - property bool animate: false - property color color: DynamicColors.palette.m3onSurface - property int fadeStrengthAnimMs: 180 - property real fadeStrengthIdle: 0.0 - property real fadeStrengthMoving: 1.0 - property alias font: elideText.font - property int gap: 40 - property alias horizontalAlignment: elideText.horizontalAlignment - property bool leftFadeEnabled: false - property real leftFadeStrength: overflowing && leftFadeEnabled ? fadeStrengthMoving : fadeStrengthIdle - property int leftFadeWidth: 28 - property bool marqueeEnabled: true - readonly property bool overflowing: metrics.width > root.width - property int pauseMs: 1200 - property real pixelsPerSecond: 40 - property real rightFadeStrength: overflowing ? fadeStrengthMoving : fadeStrengthIdle - property int rightFadeWidth: 28 - property bool sliding: false - property alias text: elideText.text - - function durationForDistance(px): int { - return Math.max(1, Math.round(Math.abs(px) / root.pixelsPerSecond * 1000)); - } - - function resetMarquee() { - marqueeAnim.stop(); - strip.x = 0; - root.sliding = false; - root.leftFadeEnabled = false; - - if (root.marqueeEnabled && root.overflowing && root.visible) { - marqueeAnim.restart(); - } - } - - clip: true - implicitHeight: elideText.implicitHeight - - Behavior on leftFadeStrength { - Anim { - } - } - Behavior on rightFadeStrength { - Anim { - } - } - - onTextChanged: resetMarquee() - onVisibleChanged: if (!visible) - resetMarquee() - onWidthChanged: resetMarquee() - - TextMetrics { - id: metrics - - font: elideText.font - text: elideText.text - } - - CustomText { - id: elideText - - anchors.verticalCenter: parent.verticalCenter - animate: root.animate - animateProp: "scale,opacity" - color: root.color - elide: Text.ElideNone - visible: !root.overflowing - width: root.width - } - - Item { - id: marqueeViewport - - anchors.fill: parent - clip: true - layer.enabled: true - visible: root.overflowing - - layer.effect: OpacityMask { - maskSource: rightFadeMask - } - - Item { - id: strip - - anchors.verticalCenter: parent.verticalCenter - height: t1.implicitHeight - width: t1.width + root.gap + t2.width - x: 0 - - CustomText { - id: t1 - - animate: root.animate - animateProp: "opacity" - color: root.color - font.pointSize: elideText.font.pointSize - text: elideText.text - } - - CustomText { - id: t2 - - animate: root.animate - animateProp: "opacity" - color: root.color - font.pointSize: elideText.font.pointSize - text: t1.text - x: t1.width + root.gap - } - } - - SequentialAnimation { - id: marqueeAnim - - running: false - - onFinished: pauseTimer.restart() - - ScriptAction { - script: { - root.sliding = true; - root.leftFadeEnabled = true; - } - } - - Anim { - duration: root.durationForDistance(t1.width) - easing.bezierCurve: Easing.Linear - easing.type: Easing.Linear - from: 0 - property: "x" - target: strip - to: -t1.width - } - - ScriptAction { - script: { - root.leftFadeEnabled = false; - } - } - - Anim { - duration: root.durationForDistance(root.gap) - easing.bezierCurve: Easing.Linear - easing.type: Easing.Linear - from: -t1.width - property: "x" - target: strip - to: -(t1.width + root.gap) - } - - ScriptAction { - script: { - root.sliding = false; - strip.x = 0; - } - } - } - - Timer { - id: pauseTimer - - interval: root.pauseMs - repeat: false - running: true - - onTriggered: { - if (root.marqueeEnabled) - marqueeAnim.start(); - } - } - } - - Rectangle { - id: rightFadeMask - - readonly property real fadeStartPos: { - const w = Math.max(1, width); - return Math.max(0, Math.min(1, (w - root.rightFadeWidth) / w)); - } - readonly property real leftFadeEndPos: { - const w = Math.max(1, width); - return Math.max(0, Math.min(1, root.leftFadeWidth / w)); - } - - anchors.fill: marqueeViewport - layer.enabled: true - visible: false - - gradient: Gradient { - orientation: Gradient.Horizontal - - GradientStop { - color: Qt.rgba(1, 1, 1, 1.0 - root.leftFadeStrength) - position: 0.0 - } - - GradientStop { - color: Qt.rgba(1, 1, 1, 1.0) - position: rightFadeMask.leftFadeEndPos - } - - GradientStop { - color: Qt.rgba(1, 1, 1, 1.0) - position: rightFadeMask.fadeStartPos - } - - GradientStop { - color: Qt.rgba(1, 1, 1, 1.0 - root.rightFadeStrength) - position: 1.0 - } - } - } -} diff --git a/Greeter/Components/MaterialIcon.qml b/Greeter/Components/MaterialIcon.qml index 69da4e3..c518426 100644 --- a/Greeter/Components/MaterialIcon.qml +++ b/Greeter/Components/MaterialIcon.qml @@ -1,11 +1,12 @@ -import qs.Config +import ZShell.Config +import qs.Services CustomText { property real fill - property int grade: DynamicColors.light ? 0 : -25 + property int grade: Colors.light ? 0 : -25 font.family: "Material Symbols Rounded" - font.pointSize: Appearance.font.size.larger + font.pointSize: Tokens.font.size.larger font.variableAxes: ({ FILL: fill.toFixed(1), GRAD: grade, diff --git a/Greeter/Components/Menu.qml b/Greeter/Components/Menu.qml deleted file mode 100644 index a633a9c..0000000 --- a/Greeter/Components/Menu.qml +++ /dev/null @@ -1,175 +0,0 @@ -pragma ComponentBehavior: Bound - -import QtQuick -import QtQuick.Layouts -import Quickshell -import qs.Config -import qs.Drawers - -MouseArea { - id: root - - enum Side { - Top, - Bottom, - Left, - Right - } - - property MenuItem active: items[0] ?? null - property int attachSideX: Menu.Right - property int attachSideY: Menu.Bottom - required property Item attachTo - property bool expanded - property list items - property real marginX - property real marginY - property int thisSideX: Menu.Right - property int thisSideY: Menu.Top - - signal itemSelected(item: MenuItem) - - anchors.fill: parent - enabled: expanded - layer.enabled: opacity < 1 - opacity: expanded ? 1 : 0 - parent: { - const win = QsWindow.window; - const contentWin = win as Windows; - return contentWin ? contentWin.interactionWrapper : (win as QsWindow).contentItem; - } - - Behavior on opacity { - Anim { - type: Anim.DefaultEffects - } - } - - onClicked: expanded = false - - TransformWatcher { - id: watcher - - a: root.parent - b: root.attachTo - } - - Elevation { - id: menu - - implicitHeight: column.implicitHeight + column.anchors.margins * 2 - implicitWidth: Math.max(200, column.implicitWidth + column.anchors.margins * 2) - level: 2 - radius: Appearance.rounding.medium - x: { - watcher.transform; - const item = root.attachTo; - let off = root.attachSideX === Menu.Left ? 0 : item.width; - if (root.thisSideX === Menu.Right) - off -= width; - return item.mapToItem(root.parent, off, 0).x + root.marginX; - } - y: { - watcher.transform; - const item = root.attachTo; - let off = root.attachSideY === Menu.Top ? 0 : item.height; - if (root.thisSideY === Menu.Bottom) - off -= height; - return item.mapToItem(root.parent, 0, off).y + root.marginY; - } - - transform: Scale { - origin.y: root.thisSideY === Menu.Bottom ? menu.height : 0 - yScale: root.expanded ? 1 : 0.1 - - Behavior on yScale { - Anim { - } - } - } - - CustomRect { - anchors.fill: parent - color: DynamicColors.palette.m3surfaceContainerLow - radius: parent.radius - - ColumnLayout { - id: column - - anchors.fill: parent - anchors.margins: Appearance.padding.extraSmall - spacing: Appearance.spacing.extraSmall - - Repeater { - id: repeater - - model: root.items - - CustomRect { - id: item - - readonly property bool active: modelData === root.active - required property int index - required property MenuItem modelData - - Layout.fillWidth: true - color: Qt.alpha(DynamicColors.palette.m3tertiaryContainer, active ? 1 : 0) - implicitHeight: menuOptionRow.implicitHeight + Appearance.padding.larger * 2 - implicitWidth: menuOptionRow.implicitWidth + Appearance.padding.larger * 2 - radius: Appearance.rounding.small - - Behavior on radius { - Anim { - } - } - - StateLayer { - color: item.active ? DynamicColors.palette.m3onTertiaryContainer : DynamicColors.palette.m3onSurface - disabled: !root.expanded - - onClicked: { - root.itemSelected(item.modelData); - root.active = item.modelData; - item.modelData.clicked(); - root.expanded = false; - } - } - - RowLayout { - id: menuOptionRow - - anchors.fill: parent - anchors.margins: Appearance.padding.larger - spacing: Appearance.spacing.small - - MaterialIcon { - Layout.alignment: Qt.AlignVCenter - color: item.active ? DynamicColors.palette.m3onTertiaryContainer : DynamicColors.palette.m3onSurfaceVariant - text: item.modelData.icon - } - - CustomText { - Layout.alignment: Qt.AlignVCenter - Layout.fillWidth: true - color: item.active ? DynamicColors.palette.m3onTertiaryContainer : DynamicColors.palette.m3onSurface - text: item.modelData.text - } - - Loader { - Layout.alignment: Qt.AlignVCenter - active: item.modelData.trailingIcon.length > 0 - asynchronous: true - visible: active - - sourceComponent: MaterialIcon { - color: item.active ? DynamicColors.palette.m3onTertiaryContainer : DynamicColors.palette.m3onSurfaceVariant - text: item.modelData.trailingIcon - } - } - } - } - } - } - } - } -} diff --git a/Greeter/Components/MenuItem.qml b/Greeter/Components/MenuItem.qml deleted file mode 100644 index 2378dd9..0000000 --- a/Greeter/Components/MenuItem.qml +++ /dev/null @@ -1,12 +0,0 @@ -import QtQuick - -QtObject { - property string activeIcon: icon - property string activeText: text - property string icon - required property string text - property string trailingIcon - property var value - - signal clicked -} diff --git a/Greeter/Components/PathMenu.qml b/Greeter/Components/PathMenu.qml deleted file mode 100644 index 0e2d10d..0000000 --- a/Greeter/Components/PathMenu.qml +++ /dev/null @@ -1,76 +0,0 @@ -import QtQuick - -Path { - id: root - - required property real viewHeight - required property real viewWidth - - startX: root.viewWidth / 2 - startY: 0 - - PathAttribute { - name: "itemOpacity" - value: 0.25 - } - - PathLine { - x: root.viewWidth / 2 - y: root.viewHeight * (1 / 6) - } - - PathAttribute { - name: "itemOpacity" - value: 0.45 - } - - PathLine { - x: root.viewWidth / 2 - y: root.viewHeight * (2 / 6) - } - - PathAttribute { - name: "itemOpacity" - value: 0.70 - } - - PathLine { - x: root.viewWidth / 2 - y: root.viewHeight * (3 / 6) - } - - PathAttribute { - name: "itemOpacity" - value: 1.00 - } - - PathLine { - x: root.viewWidth / 2 - y: root.viewHeight * (4 / 6) - } - - PathAttribute { - name: "itemOpacity" - value: 0.70 - } - - PathLine { - x: root.viewWidth / 2 - y: root.viewHeight * (5 / 6) - } - - PathAttribute { - name: "itemOpacity" - value: 0.45 - } - - PathLine { - x: root.viewWidth / 2 - y: root.viewHeight - } - - PathAttribute { - name: "itemOpacity" - value: 0.25 - } -} diff --git a/Greeter/Components/PathViewMenu.qml b/Greeter/Components/PathViewMenu.qml deleted file mode 100644 index 111b236..0000000 --- a/Greeter/Components/PathViewMenu.qml +++ /dev/null @@ -1,180 +0,0 @@ -import QtQuick -import QtQuick.Effects -import qs.Config - -Elevation { - id: root - - required property int currentIndex - property bool expanded - required property int from - property color insideTextColor: DynamicColors.palette.m3onPrimary - property int itemHeight - property int listHeight: 200 - property color outsideTextColor: DynamicColors.palette.m3onSurfaceVariant - readonly property var spinnerModel: root.range(root.from, root.to) - required property int to - property Item triggerItem - - signal itemSelected(item: int) - - function range(first, last) { - let out = []; - for (let i = first; i <= last; ++i) - out.push(i); - return out; - } - - implicitHeight: root.expanded ? view.implicitHeight : 0 - level: root.expanded ? 2 : 0 - radius: itemHeight / 2 - visible: implicitHeight > 0 - z: root.expanded ? 100 : 0 - - Behavior on implicitHeight { - Anim { - } - } - - onExpandedChanged: { - if (!root.expanded) - root.itemSelected(view.currentIndex + 1); - } - - Component { - id: spinnerDelegate - - Item { - id: wrapper - - readonly property color delegateTextColor: wrapper.PathView.view ? wrapper.PathView.view.delegateTextColor : "white" - required property var modelData - - height: root.itemHeight - opacity: wrapper.PathView.itemOpacity - visible: wrapper.PathView.onPath - width: wrapper.PathView.view ? wrapper.PathView.view.width : 0 - z: wrapper.PathView.isCurrentItem ? 100 : Math.round(wrapper.PathView.itemScale * 100) - - CustomText { - anchors.centerIn: parent - color: wrapper.delegateTextColor - font.pointSize: Appearance.font.size.large - text: wrapper.modelData - } - } - } - - CustomClippingRect { - anchors.fill: parent - color: DynamicColors.palette.m3surfaceContainer - radius: parent.radius - z: root.z - - // Main visible spinner: normal/outside text color - PathView { - id: view - - property color delegateTextColor: root.outsideTextColor - - anchors.left: parent.left - anchors.right: parent.right - anchors.verticalCenter: parent.verticalCenter - clip: true - currentIndex: root.currentIndex - 1 - delegate: spinnerDelegate - dragMargin: width - highlightRangeMode: PathView.StrictlyEnforceRange - implicitHeight: root.listHeight - model: root.spinnerModel - pathItemCount: 7 - preferredHighlightBegin: 0.5 - preferredHighlightEnd: 0.5 - snapMode: PathView.SnapToItem - - path: PathMenu { - viewHeight: view.height - viewWidth: view.width - } - } - - // The selection rectangle itself - CustomRect { - id: selectionRect - - anchors.verticalCenter: parent.verticalCenter - color: DynamicColors.palette.m3primary - height: root.itemHeight - radius: root.itemHeight / 2 - width: parent.width - z: 2 - } - - // Hidden source: same PathView, but with the "inside selection" text color - Item { - id: selectedTextSource - - anchors.fill: parent - layer.enabled: true - visible: false - - PathView { - id: selectedTextView - - property color delegateTextColor: root.insideTextColor - - anchors.left: parent.left - anchors.right: parent.right - anchors.verticalCenter: parent.verticalCenter - clip: true - currentIndex: view.currentIndex - delegate: spinnerDelegate - dragMargin: view.dragMargin - highlightRangeMode: view.highlightRangeMode - implicitHeight: root.listHeight - interactive: false - model: view.model - - // Keep this PathView visually locked to the real one - offset: view.offset - pathItemCount: view.pathItemCount - preferredHighlightBegin: view.preferredHighlightBegin - preferredHighlightEnd: view.preferredHighlightEnd - snapMode: view.snapMode - - path: PathMenu { - viewHeight: selectedTextView.height - viewWidth: selectedTextView.width - } - } - } - - // Mask matching the selection rectangle - Item { - id: selectionMask - - anchors.fill: parent - layer.enabled: true - visible: false - - CustomRect { - color: "white" - height: selectionRect.height - radius: selectionRect.radius - width: selectionRect.width - x: selectionRect.x - y: selectionRect.y - } - } - - // Only show the "inside selection" text where the mask exists - MultiEffect { - anchors.fill: selectedTextSource - maskEnabled: true - maskInverted: false - maskSource: selectionMask - source: selectedTextSource - z: 3 - } - } -} diff --git a/Greeter/Components/Ref.qml b/Greeter/Components/Ref.qml deleted file mode 100644 index 14f03d6..0000000 --- a/Greeter/Components/Ref.qml +++ /dev/null @@ -1,8 +0,0 @@ -import QtQuick - -QtObject { - required property var service - - Component.onCompleted: service.refCount++ - Component.onDestruction: service.refCount-- -} diff --git a/Greeter/Components/SpinBoxRow.qml b/Greeter/Components/SpinBoxRow.qml deleted file mode 100644 index 6686ec7..0000000 --- a/Greeter/Components/SpinBoxRow.qml +++ /dev/null @@ -1,50 +0,0 @@ -import QtQuick -import QtQuick.Layouts -import qs.Config - -CustomRect { - id: root - - required property string label - required property real max - required property real min - property var onValueModified: function (value) {} - property real step: 1 - required property real value - - Layout.fillWidth: true - color: DynamicColors.layer(DynamicColors.palette.m3surfaceContainer, 2) - implicitHeight: row.implicitHeight + Appearance.padding.large * 2 - radius: Appearance.rounding.normal - - Behavior on implicitHeight { - Anim { - } - } - - RowLayout { - id: row - - anchors.left: parent.left - anchors.margins: Appearance.padding.large - anchors.right: parent.right - anchors.verticalCenter: parent.verticalCenter - spacing: Appearance.spacing.normal - - CustomText { - Layout.fillWidth: true - text: root.label - } - - CustomSpinBox { - max: root.max - min: root.min - step: root.step - value: root.value - - onValueModified: value => { - root.onValueModified(value); - } - } - } -} diff --git a/Greeter/Components/StateLayer.qml b/Greeter/Components/StateLayer.qml index aa41297..e228449 100644 --- a/Greeter/Components/StateLayer.qml +++ b/Greeter/Components/StateLayer.qml @@ -3,7 +3,8 @@ import QtQuick.Shapes import ZShell import ZShell.Components import qs.Helpers -import qs.Config +import ZShell.Config +import qs.Services MouseArea { id: root @@ -65,7 +66,6 @@ MouseArea { if (!(pressed || manualPressOverride) && circleRadius > endRadiusAtPress * 0.99 && !fadeAnim.running) fadeAnim.start(); } - onClicked: event => !disabled && onClicked(event) onManualPressOverrideChanged: { if (!(pressed || manualPressOverride) && circleRadius > endRadiusAtPress * 0.99 && !fadeAnim.running) fadeAnim.start(); @@ -80,8 +80,8 @@ MouseArea { id: rippleAnim alwaysRunToEnd: true - duration: Appearance.anim.durations.expressiveSlowEffects * 2 - easing.bezierCurve: Appearance.anim.curves.standard + duration: Tokens.anim.durations.expressiveSlowEffects * 2 + easing.bezierCurve: Tokens.anim.curves.standard property: "circleRadius" target: root to: root.endRadius @@ -102,7 +102,7 @@ MouseArea { anchors.fill: parent bottomLeftRadius: root.parent?.bottomLeftRadius ?? radius ?? 0 bottomRightRadius: root.parent?.bottomRightRadius ?? radius ?? 0 - color: DynamicColors.palette.m3onSurface + color: Colors.palette.m3onSurface opacity: root.stateOpacity // Pick up radius from parent if it has one (parent can be anything with radius props) // qmllint disable missing-property diff --git a/Greeter/Components/Toast/ToastItem.qml b/Greeter/Components/Toast/ToastItem.qml deleted file mode 100644 index a726087..0000000 --- a/Greeter/Components/Toast/ToastItem.qml +++ /dev/null @@ -1,131 +0,0 @@ -import ZShell -import QtQuick -import QtQuick.Layouts -import qs.Components -import qs.Config - -CustomRect { - id: root - - required property Toast modelData - - anchors.left: parent.left - anchors.right: parent.right - border.color: { - let colour = DynamicColors.palette.m3outlineVariant; - if (root.modelData.type === Toast.Success) - colour = DynamicColors.palette.m3success; - if (root.modelData.type === Toast.Warning) - colour = DynamicColors.palette.m3secondaryContainer; - if (root.modelData.type === Toast.Error) - colour = DynamicColors.palette.m3error; - return Qt.alpha(colour, 0.3); - } - border.width: 1 - color: { - if (root.modelData.type === Toast.Success) - return DynamicColors.palette.m3successContainer; - if (root.modelData.type === Toast.Warning) - return DynamicColors.palette.m3secondary; - if (root.modelData.type === Toast.Error) - return DynamicColors.palette.m3errorContainer; - return DynamicColors.palette.m3surface; - } - implicitHeight: layout.implicitHeight + Appearance.padding.smaller * 2 - radius: Appearance.rounding.normal - - Behavior on border.color { - CAnim { - } - } - - Elevation { - anchors.fill: parent - level: 3 - opacity: parent.opacity - radius: parent.radius - z: -1 - } - - RowLayout { - id: layout - - anchors.fill: parent - anchors.leftMargin: Appearance.padding.normal - anchors.margins: Appearance.padding.smaller - anchors.rightMargin: Appearance.padding.normal - spacing: Appearance.spacing.normal - - CustomRect { - color: { - if (root.modelData.type === Toast.Success) - return DynamicColors.palette.m3success; - if (root.modelData.type === Toast.Warning) - return DynamicColors.palette.m3secondaryContainer; - if (root.modelData.type === Toast.Error) - return DynamicColors.palette.m3error; - return DynamicColors.palette.m3surfaceContainerHigh; - } - implicitHeight: icon.implicitHeight + Appearance.padding.smaller * 2 - implicitWidth: implicitHeight - radius: Appearance.rounding.normal - - MaterialIcon { - id: icon - - anchors.centerIn: parent - color: { - if (root.modelData.type === Toast.Success) - return DynamicColors.palette.m3onSuccess; - if (root.modelData.type === Toast.Warning) - return DynamicColors.palette.m3onSecondaryContainer; - if (root.modelData.type === Toast.Error) - return DynamicColors.palette.m3onError; - return DynamicColors.palette.m3onSurfaceVariant; - } - font.pointSize: Math.round(Appearance.font.size.large * 1.2) - text: root.modelData.icon - } - } - - ColumnLayout { - Layout.fillWidth: true - spacing: 0 - - CustomText { - id: title - - Layout.fillWidth: true - color: { - if (root.modelData.type === Toast.Success) - return DynamicColors.palette.m3onSuccessContainer; - if (root.modelData.type === Toast.Warning) - return DynamicColors.palette.m3onSecondary; - if (root.modelData.type === Toast.Error) - return DynamicColors.palette.m3onErrorContainer; - return DynamicColors.palette.m3onSurface; - } - elide: Text.ElideRight - font.pointSize: Appearance.font.size.normal - text: root.modelData.title - } - - CustomText { - Layout.fillWidth: true - color: { - if (root.modelData.type === Toast.Success) - return DynamicColors.palette.m3onSuccessContainer; - if (root.modelData.type === Toast.Warning) - return DynamicColors.palette.m3onSecondary; - if (root.modelData.type === Toast.Error) - return DynamicColors.palette.m3onErrorContainer; - return DynamicColors.palette.m3onSurface; - } - elide: Text.ElideRight - opacity: 0.8 - text: root.modelData.message - textFormat: Text.StyledText - } - } - } -} diff --git a/Greeter/Components/Toast/Toasts.qml b/Greeter/Components/Toast/Toasts.qml deleted file mode 100644 index e2fbde6..0000000 --- a/Greeter/Components/Toast/Toasts.qml +++ /dev/null @@ -1,142 +0,0 @@ -pragma ComponentBehavior: Bound - -import ZShell -import Quickshell -import QtQuick -import qs.Components -import qs.Config - -Item { - id: root - - property bool flag - readonly property int spacing: Appearance.spacing.small - - implicitHeight: { - let h = -spacing; - for (let i = 0; i < repeater.count; i++) { - const item = repeater.itemAt(i) as ToastWrapper; - if (!item.modelData.closed && !item.previewHidden) - h += item.implicitHeight + spacing; - } - return h; - } - implicitWidth: Config.utilities.sizes.toastWidth - Appearance.padding.normal * 2 - - Repeater { - id: repeater - - model: ScriptModel { - values: { - const toasts = []; - let count = 0; - for (const toast of Toaster.toasts) { - toasts.push(toast); - if (!toast.closed) { - count++; - if (count > Config.utilities.maxToasts) - break; - } - } - return toasts; - } - - onValuesChanged: root.flagChanged() - } - - ToastWrapper { - } - } - - component ToastWrapper: MouseArea { - id: toast - - required property int index - required property Toast modelData - readonly property bool previewHidden: { - let extraHidden = 0; - for (let i = 0; i < index; i++) - if (Toaster.toasts[i].closed) - extraHidden++; - return index >= Config.utilities.maxToasts + extraHidden; - } - - acceptedButtons: Qt.LeftButton | Qt.MiddleButton | Qt.RightButton - anchors.bottom: parent.bottom - anchors.bottomMargin: { - root.flag; // Force update - let y = 0; - for (let i = 0; i < index; i++) { - const item = repeater.itemAt(i) as ToastWrapper; - if (item && !item.modelData.closed && !item.previewHidden) - y += item.implicitHeight + root.spacing; - } - return y; - } - anchors.left: parent.left - anchors.right: parent.right - implicitHeight: toastInner.implicitHeight - opacity: modelData.closed || previewHidden ? 0 : 1 - scale: modelData.closed || previewHidden ? 0.7 : 1 - - Behavior on anchors.bottomMargin { - Anim { - duration: Appearance.anim.durations.expressiveDefaultSpatial - easing.bezierCurve: Appearance.anim.curves.expressiveDefaultSpatial - } - } - Behavior on opacity { - Anim { - } - } - Behavior on scale { - Anim { - } - } - - Component.onCompleted: modelData.lock(this) - onClicked: modelData.close() - onPreviewHiddenChanged: { - if (initAnim.running && previewHidden) - initAnim.stop(); - } - - Anim { - id: initAnim - - duration: Appearance.anim.durations.expressiveDefaultSpatial - easing.bezierCurve: Appearance.anim.curves.expressiveDefaultSpatial - from: 0 - properties: "opacity,scale" - target: toast - to: 1 - - Component.onCompleted: running = !toast.previewHidden - } - - ParallelAnimation { - running: toast.modelData.closed - - onFinished: toast.modelData.unlock(toast) - onStarted: toast.anchors.bottomMargin = toast.anchors.bottomMargin - - Anim { - property: "opacity" - target: toast - to: 0 - } - - Anim { - property: "scale" - target: toast - to: 0.7 - } - } - - ToastItem { - id: toastInner - - modelData: toast.modelData - } - } -} diff --git a/Greeter/Config/AccentColor.qml b/Greeter/Config/AccentColor.qml deleted file mode 100644 index 82a0157..0000000 --- a/Greeter/Config/AccentColor.qml +++ /dev/null @@ -1,13 +0,0 @@ -import Quickshell.Io - -JsonObject { - property Accents accents: Accents { - } - - component Accents: JsonObject { - property string primary: "#4080ff" - property string primaryAlt: "#60a0ff" - property string warning: "#ff6b6b" - property string warningAlt: "#ff8787" - } -} diff --git a/Greeter/Config/Appearance.qml b/Greeter/Config/Appearance.qml deleted file mode 100644 index 7be277e..0000000 --- a/Greeter/Config/Appearance.qml +++ /dev/null @@ -1,13 +0,0 @@ -pragma Singleton - -import Quickshell - -Singleton { - readonly property AppearanceConf.Anim anim: Config.appearance.anim - readonly property AppearanceConf.Deform deform: Config.appearance.deform - readonly property AppearanceConf.FontStuff font: Config.appearance.font - readonly property AppearanceConf.Padding padding: Config.appearance.padding - readonly property AppearanceConf.Rounding rounding: Config.appearance.rounding - readonly property AppearanceConf.Spacing spacing: Config.appearance.spacing - readonly property AppearanceConf.Transparency transparency: Config.appearance.transparency -} diff --git a/Greeter/Config/AppearanceConf.qml b/Greeter/Config/AppearanceConf.qml deleted file mode 100644 index 859e0a3..0000000 --- a/Greeter/Config/AppearanceConf.qml +++ /dev/null @@ -1,114 +0,0 @@ -import Quickshell.Io - -JsonObject { - property Anim anim: Anim { - } - property Deform deform: Deform { - } - property FontStuff font: FontStuff { - } - property Padding padding: Padding { - } - property Rounding rounding: Rounding { - } - property Spacing spacing: Spacing { - } - property Transparency transparency: Transparency { - } - - component Anim: JsonObject { - property AnimCurves curves: AnimCurves { - } - property AnimDurations durations: AnimDurations { - } - property real mediaGifSpeedAdjustment: 300 - property real sessionGifSpeed: 0.7 - } - component AnimCurves: JsonObject { - property list emphasized: [0.05, 0, 2 / 15, 0.06, 1 / 6, 0.4, 5 / 24, 0.82, 0.25, 1, 1, 1] - property list emphasizedAccel: [0.3, 0, 0.8, 0.15, 1, 1] - property list emphasizedDecel: [0.05, 0.7, 0.1, 1, 1, 1] - property list expressiveDefaultEffects: [0.34, 0.8, 0.34, 1, 1, 1] - property list expressiveDefaultSpatial: [0.38, 1.21, 0.22, 1, 1, 1] - property list expressiveEffects: [0.34, 0.8, 0.34, 1, 1, 1] - property list expressiveFastEffects: [0.31, 0.94, 0.34, 1, 1, 1] - property list expressiveFastSpatial: [0.42, 1.67, 0.21, 0.9, 1, 1] - property list expressiveSlowEffects: [0.34, 0.88, 0.34, 1, 1, 1] - property list expressiveSlowSpatial: [0.39, 1.29, 0.35, 0.98, 1, 1] - property list standard: [0.2, 0, 0, 1, 1, 1] - property list standardAccel: [0.3, 0, 1, 1, 1, 1] - property list standardDecel: [0, 0, 0, 1, 1, 1] - } - component AnimDurations: JsonObject { - property int expressiveDefaultSpatial: 500 * scale - property int expressiveEffects: 200 * scale - property int expressiveFastEffects: 150 * scale - property int expressiveFastSpatial: 350 * scale - property int expressiveSlowEffects: 300 * scale - property int extraLarge: 1000 * scale - property int large: 600 * scale - property int normal: 400 * scale - property real scale: 1 - property int small: 200 * scale - } - component Deform: JsonObject { - property real scale: 1 - } - component FontFamily: JsonObject { - property string clock: "Rubik" - property string material: "Material Symbols Rounded" - property string mono: "CaskaydiaCove NF" - property string sans: "Segoe UI Variable Text" - } - component FontSize: JsonObject { - property int extraLarge: 28 * scale - property int large: 18 * scale - property int larger: 16 * scale - property int medium: 14 * scale - property int normal: 13 * scale - property real scale: 1 - property int small: 11 * scale - property int smaller: 12 * scale - } - component FontStuff: JsonObject { - property FontFamily family: FontFamily { - } - property FontSize size: FontSize { - } - } - component Padding: JsonObject { - property int extraLargeIncreased: 32 * scale - property int extraSmall: 4 * scale - property int large: 16 * scale - property int larger: 12 * scale - property int normal: 8 * scale - property real scale: 1 - property int small: 5 * scale - property int smaller: 7 * scale - property int smallest: 2 * scale - } - component Rounding: JsonObject { - property int extraSmall: 4 * scale - property int full: 1000 * scale - property int large: 24 * scale - property int medium: 16 * scale - property int normal: 18 * scale - property real scale: 1 - property int small: 12 * scale - property int smallest: 8 * scale - } - component Spacing: JsonObject { - property int extraSmall: 4 * scale - property int large: 20 * scale - property int larger: 16 * scale - property int normal: 12 * scale - property real scale: 1 - property int small: 8 * scale - property int smaller: 10 * scale - } - component Transparency: JsonObject { - property real base: 0.85 - property bool enabled: false - property real layers: 0.4 - } -} diff --git a/Greeter/Config/BackgroundConfig.qml b/Greeter/Config/BackgroundConfig.qml deleted file mode 100644 index 10e7691..0000000 --- a/Greeter/Config/BackgroundConfig.qml +++ /dev/null @@ -1,14 +0,0 @@ -import Quickshell.Io -import qs.Config - -JsonObject { - property bool enabled: true - property int wallFadeDuration: MaterialEasing.standardTime - property real alignX: 0.5 - property real alignY: 0.5 - property real zoom: 1.0 - property real sourceClipX: 0 - property real sourceClipY: 0 - property real sourceClipW: 0 - property real sourceClipH: 0 -} diff --git a/Greeter/Config/BarConfig.qml b/Greeter/Config/BarConfig.qml deleted file mode 100644 index 0f489ef..0000000 --- a/Greeter/Config/BarConfig.qml +++ /dev/null @@ -1,77 +0,0 @@ -import Quickshell.Io - -JsonObject { - property bool autoHide: false - property int border: 8 - property list entries: [ - { - id: "workspaces", - enabled: true - }, - { - id: "media", - enabled: true - }, - { - id: "resources", - enabled: true - }, - { - id: "updates", - enabled: true - }, - { - id: "spacer", - enabled: true - }, - { - id: "activeWindow", - enabled: true - }, - { - id: "spacer", - enabled: true - }, - { - id: "hyprsunset", - enabled: true - }, - { - id: "tray", - enabled: true - }, - { - id: "network", - enabled: false - }, - { - id: "clock", - enabled: true - }, - { - id: "notifBell", - enabled: true - }, - ] - property int height: 34 - property bool hideWhenNotif: false - property Popouts popouts: Popouts { - } - property int rounding: 8 - property int smoothing: 32 - property Tray tray: Tray { - } - - component Popouts: JsonObject { - property bool activeWindow: true - property bool audio: true - property bool clock: true - property bool network: true - property bool resources: true - property bool tray: true - property bool upower: true - } - component Tray: JsonObject { - property int trayIconSize: 24 - } -} diff --git a/Greeter/Config/Colors.qml b/Greeter/Config/Colors.qml deleted file mode 100644 index 3b99070..0000000 --- a/Greeter/Config/Colors.qml +++ /dev/null @@ -1,13 +0,0 @@ -import Quickshell.Io - -JsonObject { - property Presets presets: Presets { - } - property string schemeType: "vibrant" - - component Presets: JsonObject { - property string accent: "" - property string name: "" - property string variant: "" - } -} diff --git a/Greeter/Config/Config.qml b/Greeter/Config/Config.qml deleted file mode 100644 index decd07c..0000000 --- a/Greeter/Config/Config.qml +++ /dev/null @@ -1,474 +0,0 @@ -pragma Singleton - -import Quickshell -import Quickshell.Io -import ZShell -import QtQuick - -Singleton { - id: root - - property alias appearance: adapter.appearance - property alias background: adapter.background - property alias barConfig: adapter.barConfig - property alias colors: adapter.colors - property alias dashboard: adapter.dashboard - property alias dock: adapter.dock - property alias general: adapter.general - property alias launcher: adapter.launcher - property alias lock: adapter.lock - property alias notifs: adapter.notifs - property alias osd: adapter.osd - property alias overview: adapter.overview - property bool recentlySaved: false - property alias screenshot: adapter.screenshot - property alias services: adapter.services - property alias sidebar: adapter.sidebar - property alias utilities: adapter.utilities - - function save(): void { - saveTimer.restart(); - recentlySaved = true; - recentSaveCooldown.restart(); - } - - function saveNoToast(): void { - saveTimer.restart(); - } - - function serializeAppearance(): var { - return { - rounding: { - scale: appearance.rounding.scale - }, - spacing: { - scale: appearance.spacing.scale - }, - padding: { - scale: appearance.padding.scale - }, - deform: { - scale: appearance.deform.scale - }, - font: { - family: { - sans: appearance.font.family.sans, - mono: appearance.font.family.mono, - material: appearance.font.family.material, - clock: appearance.font.family.clock - }, - size: { - scale: appearance.font.size.scale - } - }, - anim: { - mediaGifSpeedAdjustment: appearance.anim.mediaGifSpeedAdjustment, - sessionGifSpeed: appearance.anim.sessionGifSpeed, - durations: { - scale: appearance.anim.durations.scale - } - }, - transparency: { - enabled: appearance.transparency.enabled, - base: appearance.transparency.base, - layers: appearance.transparency.layers - } - }; - } - - function serializeBackground(): var { - return { - wallFadeDuration: background.wallFadeDuration, - enabled: background.enabled, - alignX: background.alignX, - sourceClipX: background.sourceClipX, - sourceClipY: background.sourceClipY, - sourceClipW: background.sourceClipW, - sourceClipH: background.sourceClipH, - alignY: background.alignY, - zoom: background.zoom - }; - } - - function serializeBar(): var { - return { - autoHide: barConfig.autoHide, - hideWhenNotif: barConfig.hideWhenNotif, - rounding: barConfig.rounding, - border: barConfig.border, - smoothing: barConfig.smoothing, - height: barConfig.height, - tray: { - trayIconSize: barConfig.tray.trayIconSize - }, - popouts: { - tray: barConfig.popouts.tray, - audio: barConfig.popouts.audio, - activeWindow: barConfig.popouts.activeWindow, - resources: barConfig.popouts.resources, - clock: barConfig.popouts.clock, - network: barConfig.popouts.network, - upower: barConfig.popouts.upower - }, - entries: barConfig.entries - }; - } - - function serializeColors(): var { - return { - schemeType: colors.schemeType, - presets: { - name: colors.presets.name, - variant: colors.presets.variant, - accent: colors.presets.accent - } - }; - } - - function serializeConfig(): var { - return { - barConfig: serializeBar(), - lock: serializeLock(), - general: serializeGeneral(), - services: serializeServices(), - notifs: serializeNotifs(), - sidebar: serializeSidebar(), - utilities: serializeUtilities(), - dashboard: serializeDashboard(), - appearance: serializeAppearance(), - osd: serializeOsd(), - background: serializeBackground(), - launcher: serializeLauncher(), - colors: serializeColors(), - dock: serializeDock(), - screenshot: serializeScreenshot() - }; - } - - function serializeDashboard(): var { - return { - enabled: dashboard.enabled, - mediaUpdateInterval: dashboard.mediaUpdateInterval, - resourceUpdateInterval: dashboard.resourceUpdateInterval, - dragThreshold: dashboard.dragThreshold, - performance: { - showBattery: dashboard.performance.showBattery, - showGpu: dashboard.performance.showGpu, - showCpu: dashboard.performance.showCpu, - showMemory: dashboard.performance.showMemory, - showStorage: dashboard.performance.showStorage, - showNetwork: dashboard.performance.showNetwork - }, - sizes: { - tabIndicatorHeight: dashboard.sizes.tabIndicatorHeight, - tabIndicatorSpacing: dashboard.sizes.tabIndicatorSpacing, - infoWidth: dashboard.sizes.infoWidth, - infoIconSize: dashboard.sizes.infoIconSize, - dateTimeWidth: dashboard.sizes.dateTimeWidth, - mediaWidth: dashboard.sizes.mediaWidth, - mediaProgressSweep: dashboard.sizes.mediaProgressSweep, - mediaProgressThickness: dashboard.sizes.mediaProgressThickness, - resourceProgessThickness: dashboard.sizes.resourceProgessThickness, - weatherWidth: dashboard.sizes.weatherWidth, - mediaCoverArtSize: dashboard.sizes.mediaCoverArtSize, - mediaVisualiserSize: dashboard.sizes.mediaVisualiserSize, - resourceSize: dashboard.sizes.resourceSize - } - }; - } - - function serializeDock(): var { - return { - enable: dock.enable, - height: dock.height, - hoverToReveal: dock.hoverToReveal, - pinnedApps: dock.pinnedApps, - pinnedOnStartup: dock.pinnedOnStartup, - ignoredAppRegexes: dock.ignoredAppRegexes - }; - } - - function serializeGeneral(): var { - return { - logo: general.logo, - wallpaperPath: general.wallpaperPath, - desktopIcons: general.desktopIcons, - dateFormat: general.dateFormat, - color: { - mode: general.color.mode, - smart: general.color.smart, - scheduleDark: general.color.scheduleDark, - scheduleHyprsunset: general.color.scheduleHyprsunset, - scheduleHyprsunsetStart: general.color.scheduleHyprsunsetStart, - hyprsunsetTemp: general.color.hyprsunsetTemp, - scheduleHyprsunsetEnd: general.color.scheduleHyprsunsetEnd, - schemeGeneration: general.color.schemeGeneration, - scheduleDarkStart: general.color.scheduleDarkStart, - scheduleDarkEnd: general.color.scheduleDarkEnd, - neovimColors: general.color.neovimColors - }, - apps: { - terminal: general.apps.terminal, - audio: general.apps.audio, - playback: general.apps.playback, - explorer: general.apps.explorer - }, - idle: { - timeouts: general.idle.timeouts - }, - battery: { - popupThresholds: general.battery.popupThresholds, - critPerc: general.battery.critPerc - } - }; - } - - function serializeLauncher(): var { - return { - maxAppsShown: launcher.maxAppsShown, - maxWallpapers: launcher.maxWallpapers, - uwsm: launcher.uwsm, - actionPrefix: launcher.actionPrefix, - specialPrefix: launcher.specialPrefix, - useFuzzy: { - apps: launcher.useFuzzy.apps, - actions: launcher.useFuzzy.actions, - schemes: launcher.useFuzzy.schemes, - variants: launcher.useFuzzy.variants, - wallpapers: launcher.useFuzzy.wallpapers - }, - sizes: { - itemWidth: launcher.sizes.itemWidth, - itemHeight: launcher.sizes.itemHeight, - wallpaperWidth: launcher.sizes.wallpaperWidth, - wallpaperHeight: launcher.sizes.wallpaperHeight - }, - actions: launcher.actions - }; - } - - function serializeLock(): var { - return { - recolorLogo: lock.recolorLogo, - enableFprint: lock.enableFprint, - showNotifContent: lock.showNotifContent, - showNotifIcon: lock.showNotifIcon, - maxFprintTries: lock.maxFprintTries, - blurAmount: lock.blurAmount, - sizes: { - heightMult: lock.sizes.heightMult, - ratio: lock.sizes.ratio, - centerWidth: lock.sizes.centerWidth - } - }; - } - - function serializeNotifs(): var { - return { - expire: notifs.expire, - defaultExpireTimeout: notifs.defaultExpireTimeout, - appNotifCooldown: notifs.appNotifCooldown, - clearThreshold: notifs.clearThreshold, - expandThreshold: notifs.expandThreshold, - actionOnClick: notifs.actionOnClick, - groupPreviewNum: notifs.groupPreviewNum, - sizes: { - width: notifs.sizes.width, - image: notifs.sizes.image, - badge: notifs.sizes.badge - } - }; - } - - function serializeOsd(): var { - return { - enabled: osd.enabled, - hideDelay: osd.hideDelay, - enableBrightness: osd.enableBrightness, - enableMicrophone: osd.enableMicrophone, - allMonBrightness: osd.allMonBrightness, - sizes: { - sliderWidth: osd.sizes.sliderWidth, - sliderHeight: osd.sizes.sliderHeight - } - }; - } - - function serializeScreenshot(): var { - return { - enable_pp: screenshot.enable_pp, - mode: screenshot.mode, - radius: screenshot.radius, - shadow: screenshot.shadow, - rounding: screenshot.rounding, - shadow_blur: screenshot.shadow_blur, - shadow_color: screenshot.shadow_color, - shadow_offset_x: screenshot.shadow_offset_x, - shadow_offset_y: screenshot.shadow_offset_y - }; - } - - function serializeServices(): var { - return { - weatherLocation: services.weatherLocation, - updates: services.updates, - useFahrenheit: services.useFahrenheit, - ddcutilService: services.ddcutilService, - useTwelveHourClock: services.useTwelveHourClock, - gpuType: services.gpuType, - audioIncrement: services.audioIncrement, - brightnessIncrement: services.brightnessIncrement, - maxVolume: services.maxVolume, - defaultPlayer: services.defaultPlayer, - playerAliases: services.playerAliases, - visualizerBars: services.visualizerBars - }; - } - - function serializeSidebar(): var { - return { - enabled: sidebar.enabled, - sizes: { - width: sidebar.sizes.width - } - }; - } - - function serializeUtilities(): var { - return { - enabled: utilities.enabled, - maxToasts: utilities.maxToasts, - sizes: { - width: utilities.sizes.width, - toastWidth: utilities.sizes.toastWidth - }, - toasts: { - configLoaded: utilities.toasts.configLoaded, - chargingChanged: utilities.toasts.chargingChanged, - gameModeChanged: utilities.toasts.gameModeChanged, - dndChanged: utilities.toasts.dndChanged, - audioOutputChanged: utilities.toasts.audioOutputChanged, - audioInputChanged: utilities.toasts.audioInputChanged, - capsLockChanged: utilities.toasts.capsLockChanged, - numLockChanged: utilities.toasts.numLockChanged, - kbLayoutChanged: utilities.toasts.kbLayoutChanged, - vpnChanged: utilities.toasts.vpnChanged, - nowPlaying: utilities.toasts.nowPlaying - }, - vpn: { - enabled: utilities.vpn.enabled, - provider: utilities.vpn.provider - } - }; - } - - ElapsedTimer { - id: timer - } - - Timer { - id: saveTimer - - interval: 500 - - onTriggered: { - timer.restart(); - try { - let config = {}; - try { - config = JSON.parse(fileView.text()); - } catch (e) { - config = {}; - } - - config = root.serializeConfig(); - - fileView.setText(JSON.stringify(config, null, 4)); - } catch (e) { - Toaster.toast(qsTr("Failed to serialize config"), e.message, "settings_alert", Toast.Error); - } - } - } - - Timer { - id: recentSaveCooldown - - interval: 2000 - - onTriggered: { - root.recentlySaved = false; - } - } - - FileView { - id: fileView - - path: "/etc/zshell-greeter/config.json" - watchChanges: true - - onFileChanged: { - if (!root.recentlySaved) { - timer.restart(); - reload(); - } else { - reload(); - } - } - onLoadFailed: err => { - if (err !== FileViewError.FileNotFound) - Toaster.toast(qsTr("Failed to read config"), FileViewError.toString(err), "settings_alert", Toast.Warning); - } - onLoaded: { - try { - JSON.parse(text()); - const elapsed = timer.elapsedMs(); - - if (adapter.utilities.toasts.configLoaded && !root.recentlySaved) { - Toaster.toast(qsTr("Config loaded"), qsTr("Config loaded in %1ms").arg(elapsed), "rule_settings"); - } else if (adapter.utilities.toasts.configLoaded && root.recentlySaved) { - Toaster.toast(qsTr("Config saved"), qsTr("Config reloaded in %1ms").arg(elapsed), "settings_alert"); - } - } catch (e) { - Toaster.toast(qsTr("Failed to load config"), e.message, "settings_alert", Toast.Error); - } - } - onSaveFailed: err => Toaster.toast(qsTr("Failed to save config"), FileViewError.toString(err), "settings_alert", Toast.Error) - - JsonAdapter { - id: adapter - - property AppearanceConf appearance: AppearanceConf { - } - property BackgroundConfig background: BackgroundConfig { - } - property BarConfig barConfig: BarConfig { - } - property Colors colors: Colors { - } - property DashboardConfig dashboard: DashboardConfig { - } - property DockConfig dock: DockConfig { - } - property General general: General { - } - property Launcher launcher: Launcher { - } - property LockConf lock: LockConf { - } - property NotifConfig notifs: NotifConfig { - } - property Osd osd: Osd { - } - property Overview overview: Overview { - } - property Screenshot screenshot: Screenshot { - } - property Services services: Services { - } - property SidebarConfig sidebar: SidebarConfig { - } - property UtilConfig utilities: UtilConfig { - } - } - } -} diff --git a/Greeter/Config/DashboardConfig.qml b/Greeter/Config/DashboardConfig.qml deleted file mode 100644 index 0b6a610..0000000 --- a/Greeter/Config/DashboardConfig.qml +++ /dev/null @@ -1,36 +0,0 @@ -import Quickshell.Io - -JsonObject { - property int dragThreshold: 50 - property bool enabled: true - property int mediaUpdateInterval: 500 - property Performance performance: Performance { - } - property int resourceUpdateInterval: 1000 - property Sizes sizes: Sizes { - } - - component Performance: JsonObject { - property bool showBattery: true - property bool showCpu: true - property bool showGpu: true - property bool showMemory: true - property bool showNetwork: true - property bool showStorage: true - } - component Sizes: JsonObject { - readonly property int dateTimeWidth: 110 - readonly property int infoIconSize: 25 - readonly property int infoWidth: 200 - readonly property int mediaCoverArtSize: 150 - readonly property int mediaProgressSweep: 180 - readonly property int mediaProgressThickness: 8 - readonly property int mediaVisualiserSize: 80 - readonly property int mediaWidth: 200 - readonly property int resourceProgessThickness: 10 - readonly property int resourceSize: 200 - readonly property int tabIndicatorHeight: 3 - readonly property int tabIndicatorSpacing: 5 - readonly property int weatherWidth: 250 - } -} diff --git a/Greeter/Config/DockConfig.qml b/Greeter/Config/DockConfig.qml deleted file mode 100644 index eeaf1de..0000000 --- a/Greeter/Config/DockConfig.qml +++ /dev/null @@ -1,10 +0,0 @@ -import Quickshell.Io - -JsonObject { - property bool enable: false - property real height: 60 - property bool hoverToReveal: true - property list ignoredAppRegexes: [] - property list pinnedApps: ["org.kde.dolphin", "kitty",] - property bool pinnedOnStartup: false -} diff --git a/Greeter/Config/General.qml b/Greeter/Config/General.qml deleted file mode 100644 index 45d3513..0000000 --- a/Greeter/Config/General.qml +++ /dev/null @@ -1,63 +0,0 @@ -import Quickshell.Io -import Quickshell - -JsonObject { - property Apps apps: Apps { - } - property Battery battery: Battery { - } - property Color color: Color { - } - property string dateFormat: "ddd d MMM - hh:mm:ss" - property bool desktopIcons: false - property Idle idle: Idle { - } - property string logo: "" - property string wallpaperPath: Quickshell.env("HOME") + "/Pictures/Wallpapers" - - component Apps: JsonObject { - property list audio: ["pavucontrol"] - property list explorer: ["dolphin"] - property list playback: ["mpv"] - property list terminal: ["kitty"] - } - component Battery: JsonObject { - property int critPerc: 5 - property list popupThresholds: [ - { - perc: 20, - name: qsTr("Low battery"), - message: qsTr("Battery is low"), - icon: "battery_android_frame_2" - }, - ] - } - component Color: JsonObject { - property int hyprsunsetTemp: 5000 - property string mode: "dark" - property bool neovimColors: false - property bool scheduleDark: false - property int scheduleDarkEnd: 0 - property int scheduleDarkStart: 0 - property bool scheduleHyprsunset: false - property int scheduleHyprsunsetEnd: 0 - property int scheduleHyprsunsetStart: 0 - property bool schemeGeneration: true - property bool smart: false - } - component Idle: JsonObject { - property list timeouts: [ - { - name: "Lock", - timeout: 180, - idleAction: "lock" - }, - { - name: "Screen", - timeout: 300, - idleAction: "dpms off", - activeAction: "dpms on" - } - ] - } -} diff --git a/Greeter/Config/IdleTimeout.qml b/Greeter/Config/IdleTimeout.qml deleted file mode 100644 index c1db937..0000000 --- a/Greeter/Config/IdleTimeout.qml +++ /dev/null @@ -1,15 +0,0 @@ -import Quickshell.Io - -JsonObject { - property list timeouts: [ - { - timeout: 180, - idleAction: "lock" - }, - { - timeout: 300, - idleAction: "dpms off", - activeAction: "dpms on" - } - ] -} diff --git a/Greeter/Config/Launcher.qml b/Greeter/Config/Launcher.qml deleted file mode 100644 index 5ab58cc..0000000 --- a/Greeter/Config/Launcher.qml +++ /dev/null @@ -1,109 +0,0 @@ -import Quickshell.Io - -JsonObject { - property string actionPrefix: ">" - property list actions: [ - { - name: "Calculator", - icon: "calculate", - description: "Do simple math equations", - command: ["autocomplete", "calc"], - enabled: true, - dangerous: false - }, - { - name: "Light", - icon: "light_mode", - description: "Change to light mode", - command: ["setMode", "light"], - enabled: true, - dangerous: false - }, - { - name: "Dark", - icon: "dark_mode", - description: "Change to dark mode", - command: ["setMode", "dark"], - enabled: true, - dangerous: false - }, - { - name: "Wallpaper", - icon: "image", - description: "Change the current wallpaper", - command: ["autocomplete", "wallpaper"], - enabled: true, - dangerous: false - }, - { - name: "Variant", - icon: "colors", - description: "Change the current scheme variant", - command: ["autocomplete", "variant"], - enabled: true, - dangerous: false - }, - { - name: "Shutdown", - icon: "power_settings_new", - description: "Shutdown the system", - command: ["systemctl", "poweroff"], - enabled: true, - dangerous: true - }, - { - name: "Reboot", - icon: "cached", - description: "Reboot the system", - command: ["systemctl", "reboot"], - enabled: true, - dangerous: true - }, - { - name: "Logout", - icon: "logout", - description: "Log out of the current session", - command: ["loginctl", "terminate-user", ""], - enabled: true, - dangerous: true - }, - { - name: "Lock", - icon: "lock", - description: "Lock the current session", - command: ["loginctl", "lock-session"], - enabled: true, - dangerous: false - }, - { - name: "Sleep", - icon: "bedtime", - description: "Suspend then hibernate", - command: ["systemctl", "suspend-then-hibernate"], - enabled: true, - dangerous: false - }, - ] - property int maxAppsShown: 10 - property int maxWallpapers: 7 - property Sizes sizes: Sizes { - } - property string specialPrefix: "@" - property UseFuzzy useFuzzy: UseFuzzy { - } - property bool uwsm: true - - component Sizes: JsonObject { - property int itemHeight: 50 - property int itemWidth: 600 - property int wallpaperHeight: 200 - property int wallpaperWidth: 280 - } - component UseFuzzy: JsonObject { - property bool actions: false - property bool apps: false - property bool schemes: false - property bool variants: false - property bool wallpapers: false - } -} diff --git a/Greeter/Config/LockConf.qml b/Greeter/Config/LockConf.qml deleted file mode 100644 index 87a4f4e..0000000 --- a/Greeter/Config/LockConf.qml +++ /dev/null @@ -1,18 +0,0 @@ -import Quickshell.Io - -JsonObject { - property int blurAmount: 40 - property bool enableFprint: true - property int maxFprintTries: 3 - property bool recolorLogo: false - property bool showNotifContent: false - property bool showNotifIcon: true - property Sizes sizes: Sizes { - } - - component Sizes: JsonObject { - property int centerWidth: 600 - property real heightMult: 0.7 - property real ratio: 16 / 9 - } -} diff --git a/Greeter/Config/MaterialEasing.qml b/Greeter/Config/MaterialEasing.qml deleted file mode 100644 index a43a8df..0000000 --- a/Greeter/Config/MaterialEasing.qml +++ /dev/null @@ -1,26 +0,0 @@ -pragma Singleton -import Quickshell - -Singleton { - id: root - - readonly property list emphasized: [0.05, 0, 2 / 15, 0.06, 1 / 6, 0.4, 5 / 24, 0.82, 0.25, 1, 1, 1] - readonly property list emphasizedAccel: [0.3, 0, 0.8, 0.15, 1, 1] - readonly property int emphasizedAccelTime: 200 * scale - readonly property list emphasizedDecel: [0.05, 0.7, 0.1, 1, 1, 1] - readonly property int emphasizedDecelTime: 400 * scale - readonly property int emphasizedTime: 500 * scale - readonly property list expressiveDefaultSpatial: [0.38, 1.21, 0.22, 1.00, 1, 1] - readonly property int expressiveDefaultSpatialTime: 500 * scale - readonly property list expressiveEffects: [0.34, 0.80, 0.34, 1.00, 1, 1] - readonly property int expressiveEffectsTime: 200 * scale - readonly property list expressiveFastSpatial: [0.42, 1.67, 0.21, 0.90, 1, 1] - readonly property int expressiveFastSpatialTime: 350 * scale - property real scale: Appearance.anim.durations.scale - readonly property list standard: [0.2, 0, 0, 1, 1, 1] - readonly property list standardAccel: [0.3, 0, 1, 1, 1, 1] - readonly property int standardAccelTime: 200 * scale - readonly property list standardDecel: [0, 0, 0, 1, 1, 1] - readonly property int standardDecelTime: 250 * scale - readonly property int standardTime: 300 * scale -} diff --git a/Greeter/Config/NotifConfig.qml b/Greeter/Config/NotifConfig.qml deleted file mode 100644 index 0a11d46..0000000 --- a/Greeter/Config/NotifConfig.qml +++ /dev/null @@ -1,20 +0,0 @@ -import Quickshell.Io - -JsonObject { - property bool actionOnClick: false - property int appNotifCooldown: 0 - property real clearThreshold: 0.3 - property int defaultExpireTimeout: 5000 - property int expandThreshold: 20 - property bool expire: true - property int groupPreviewNum: 3 - property bool openExpanded: false - property Sizes sizes: Sizes { - } - - component Sizes: JsonObject { - property int badge: 20 - property int image: 41 - property int width: 400 - } -} diff --git a/Greeter/Config/Osd.qml b/Greeter/Config/Osd.qml deleted file mode 100644 index 79da85b..0000000 --- a/Greeter/Config/Osd.qml +++ /dev/null @@ -1,16 +0,0 @@ -import Quickshell.Io - -JsonObject { - property bool allMonBrightness: false - property bool enableBrightness: true - property bool enableMicrophone: true - property bool enabled: true - property int hideDelay: 3000 - property Sizes sizes: Sizes { - } - - component Sizes: JsonObject { - property int sliderHeight: 150 - property int sliderWidth: 30 - } -} diff --git a/Greeter/Config/Overview.qml b/Greeter/Config/Overview.qml deleted file mode 100644 index 5e1a615..0000000 --- a/Greeter/Config/Overview.qml +++ /dev/null @@ -1,8 +0,0 @@ -import Quickshell.Io - -JsonObject { - property int columns: 5 - property bool enable: false - property int rows: 2 - property real scale: 0.16 -} diff --git a/Greeter/Config/Screenshot.qml b/Greeter/Config/Screenshot.qml deleted file mode 100644 index cd6dd49..0000000 --- a/Greeter/Config/Screenshot.qml +++ /dev/null @@ -1,13 +0,0 @@ -import Quickshell.Io - -JsonObject { - property bool enable_pp: true - property string mode: "manual" - property real radius: 12.0 - property bool rounding: false - property bool shadow: true - property real shadow_blur: 22.0 - property list shadow_color: [0, 0, 0, 160] - property real shadow_offset_x: 5.0 - property real shadow_offset_y: 5.0 -} diff --git a/Greeter/Config/Services.qml b/Greeter/Config/Services.qml deleted file mode 100644 index 4711120..0000000 --- a/Greeter/Config/Services.qml +++ /dev/null @@ -1,22 +0,0 @@ -import Quickshell.Io -import QtQuick - -JsonObject { - property real audioIncrement: 0.1 - property real brightnessIncrement: 0.1 - property bool ddcutilService: false - property string defaultPlayer: "Spotify" - property string gpuType: "" - property real maxVolume: 1.0 - property list playerAliases: [ - { - "from": "com.github.th_ch.youtube_music", - "to": "YT Music" - } - ] - property bool updates: true - property bool useFahrenheit: false - property bool useTwelveHourClock: Qt.locale().timeFormat(Locale.ShortFormat).toLowerCase().includes("a") - property int visualizerBars: 30 - property string weatherLocation: "" -} diff --git a/Greeter/Config/SidebarConfig.qml b/Greeter/Config/SidebarConfig.qml deleted file mode 100644 index 80800ce..0000000 --- a/Greeter/Config/SidebarConfig.qml +++ /dev/null @@ -1,11 +0,0 @@ -import Quickshell.Io - -JsonObject { - property bool enabled: true - property Sizes sizes: Sizes { - } - - component Sizes: JsonObject { - property int width: 430 - } -} diff --git a/Greeter/Config/Transparency.qml b/Greeter/Config/Transparency.qml deleted file mode 100644 index e687cfb..0000000 --- a/Greeter/Config/Transparency.qml +++ /dev/null @@ -1,7 +0,0 @@ -import Quickshell.Io - -JsonObject { - property real base: 0.85 - property bool enabled: false - property real layers: 0.4 -} diff --git a/Greeter/Config/UtilConfig.qml b/Greeter/Config/UtilConfig.qml deleted file mode 100644 index c4a2087..0000000 --- a/Greeter/Config/UtilConfig.qml +++ /dev/null @@ -1,35 +0,0 @@ -import Quickshell.Io - -JsonObject { - property bool enabled: true - property int maxToasts: 4 - property Sizes sizes: Sizes { - } - property Toasts toasts: Toasts { - } - property Vpn vpn: Vpn { - } - - component Sizes: JsonObject { - property int toastWidth: 430 - property int width: 430 - } - component Toasts: JsonObject { - property bool audioInputChanged: true - property bool audioOutputChanged: true - property bool capsLockChanged: true - property bool chargingChanged: true - property bool configLoaded: true - property bool dndChanged: true - property bool gameModeChanged: true - property bool kbLayoutChanged: true - property bool kbLimit: true - property bool nowPlaying: false - property bool numLockChanged: true - property bool vpnChanged: true - } - component Vpn: JsonObject { - property bool enabled: false - property list provider: ["netbird"] - } -} diff --git a/Greeter/Config/WorkspaceWidget.qml b/Greeter/Config/WorkspaceWidget.qml deleted file mode 100644 index 10a6969..0000000 --- a/Greeter/Config/WorkspaceWidget.qml +++ /dev/null @@ -1,6 +0,0 @@ -import Quickshell.Io - -JsonObject { - property string inactiveTextColor: "white" - property string textColor: "black" -} diff --git a/Greeter/Content.qml b/Greeter/Content.qml index f2f314a..2df68b6 100644 --- a/Greeter/Content.qml +++ b/Greeter/Content.qml @@ -2,7 +2,8 @@ import QtQuick import QtQuick.Layouts import qs.Components import qs.Helpers -import qs.Config +import ZShell.Config +import qs.Services RowLayout { id: root @@ -10,18 +11,18 @@ RowLayout { required property var greeter required property real screenHeight - spacing: Appearance.spacing.large * 2 + spacing: Tokens.spacing.large * 2 ColumnLayout { Layout.fillWidth: true - spacing: Appearance.spacing.normal + spacing: Tokens.spacing.normal CustomRect { Layout.fillWidth: true - color: DynamicColors.tPalette.m3surfaceContainer + color: Colors.tPalette.m3surfaceContainer implicitHeight: weather.implicitHeight - radius: Appearance.rounding.small - topLeftRadius: Appearance.rounding.large + radius: Tokens.rounding.small + topLeftRadius: Tokens.rounding.large WeatherInfo { id: weather @@ -33,9 +34,9 @@ RowLayout { CustomClippingRect { Layout.fillHeight: true Layout.fillWidth: true - bottomLeftRadius: Appearance.rounding.large - color: DynamicColors.tPalette.m3surfaceContainer - radius: Appearance.rounding.small + bottomLeftRadius: Tokens.rounding.large + color: Colors.tPalette.m3surfaceContainer + radius: Tokens.rounding.small UserDock { greeter: root.greeter @@ -50,15 +51,15 @@ RowLayout { ColumnLayout { Layout.fillWidth: true - spacing: Appearance.spacing.normal + spacing: Tokens.spacing.normal CustomRect { Layout.fillHeight: true Layout.fillWidth: true - bottomRightRadius: Appearance.rounding.large - color: DynamicColors.tPalette.m3surfaceContainer - radius: Appearance.rounding.small - topRightRadius: Appearance.rounding.large + bottomRightRadius: Tokens.rounding.large + color: Colors.tPalette.m3surfaceContainer + radius: Tokens.rounding.small + topRightRadius: Tokens.rounding.large SessionDock { greeter: root.greeter diff --git a/Greeter/GreeterSurface.qml b/Greeter/GreeterSurface.qml index c07f7e3..f28dc2a 100644 --- a/Greeter/GreeterSurface.qml +++ b/Greeter/GreeterSurface.qml @@ -4,9 +4,10 @@ import Quickshell import Quickshell.Wayland import QtQuick import QtQuick.Effects -import qs.Config +import ZShell.Config import qs.Helpers import qs.Components +import qs.Services Scope { id: root @@ -41,8 +42,8 @@ Scope { SequentialAnimation { ParallelAnimation { Anim { - duration: Appearance.anim.durations.expressiveFastSpatial - easing.bezierCurve: Appearance.anim.curves.expressiveFastSpatial + duration: Tokens.anim.durations.expressiveFastSpatial + easing.bezierCurve: Tokens.anim.curves.expressiveFastSpatial property: "scale" target: lockContent to: 1 @@ -63,8 +64,8 @@ Scope { } Anim { - duration: Appearance.anim.durations.expressiveDefaultSpatial - easing.bezierCurve: Appearance.anim.curves.expressiveDefaultSpatial + duration: Tokens.anim.durations.expressiveDefaultSpatial + easing.bezierCurve: Tokens.anim.curves.expressiveDefaultSpatial property: "scale" target: content to: 1 @@ -73,20 +74,20 @@ Scope { Anim { property: "radius" target: lockBg - to: Appearance.rounding.large * 1.5 + to: Tokens.rounding.large * 1.5 } Anim { - duration: Appearance.anim.durations.expressiveDefaultSpatial - easing.bezierCurve: Appearance.anim.curves.expressiveDefaultSpatial + duration: Tokens.anim.durations.expressiveDefaultSpatial + easing.bezierCurve: Tokens.anim.curves.expressiveDefaultSpatial property: "implicitWidth" target: lockContent to: (win.screen?.height ?? 0) * Config.lock.sizes.heightMult * Config.lock.sizes.ratio } Anim { - duration: Appearance.anim.durations.expressiveDefaultSpatial - easing.bezierCurve: Appearance.anim.curves.expressiveDefaultSpatial + duration: Tokens.anim.durations.expressiveDefaultSpatial + easing.bezierCurve: Tokens.anim.curves.expressiveDefaultSpatial property: "implicitHeight" target: lockContent to: (win.screen?.height ?? 0) * Config.lock.sizes.heightMult @@ -105,8 +106,8 @@ Scope { Item { id: lockContent - readonly property int radius: size / 4 * Appearance.rounding.scale - readonly property int size: lockIcon.implicitHeight + Appearance.padding.large * 4 + readonly property int radius: size / 4 * Tokens.rounding.scale + readonly property int size: lockIcon.implicitHeight + Tokens.padding.large * 4 anchors.centerIn: parent implicitHeight: size @@ -117,14 +118,14 @@ Scope { id: lockBg anchors.fill: parent - color: DynamicColors.palette.m3surface + color: Colors.palette.m3surface layer.enabled: true - opacity: DynamicColors.transparency.enabled ? DynamicColors.transparency.base : 1 + opacity: Colors.transparency.enabled ? Colors.transparency.base : 1 radius: lockContent.radius layer.effect: MultiEffect { blurMax: 15 - shadowColor: Qt.alpha(DynamicColors.palette.m3shadow, 0.7) + shadowColor: Qt.alpha(Colors.palette.m3shadow, 0.7) shadowEnabled: true } } @@ -134,7 +135,7 @@ Scope { anchors.centerIn: parent font.bold: true - font.pointSize: Appearance.font.size.extraLarge * 4 + font.pointSize: Tokens.font.size.extraLarge * 4 text: "lock" } @@ -143,11 +144,11 @@ Scope { anchors.centerIn: parent greeter: root.greeter - height: (win.screen?.height ?? 0) * Config.lock.sizes.heightMult - Appearance.padding.large * 2 + height: (win.screen?.height ?? 0) * Config.lock.sizes.heightMult - Tokens.padding.large * 2 opacity: 0 scale: 0 screenHeight: win.screen?.height ?? 1440 - width: (win.screen?.height ?? 0) * Config.lock.sizes.heightMult * Config.lock.sizes.ratio - Appearance.padding.large * 2 + width: (win.screen?.height ?? 0) * Config.lock.sizes.heightMult * Config.lock.sizes.ratio - Tokens.padding.large * 2 } } } diff --git a/Greeter/Helpers/Brightness.qml b/Greeter/Helpers/Brightness.qml deleted file mode 100644 index 5e2e7fb..0000000 --- a/Greeter/Helpers/Brightness.qml +++ /dev/null @@ -1,264 +0,0 @@ -pragma Singleton -pragma ComponentBehavior: Bound - -import Quickshell -import Quickshell.Io -import QtQuick -import qs.Config -import qs.Components - -Singleton { - id: root - - property bool appleDisplayPresent: false - property list ddcMonitors: [] - property list ddcServiceMon: [] - readonly property list monitors: variants.instances - - function decreaseBrightness(): void { - const monitor = getMonitor("active"); - if (monitor) - monitor.setBrightness(monitor.brightness - Config.services.brightnessIncrement); - } - - function getMonitor(query: string): var { - if (query === "active") { - return monitors.find(m => Hypr.monitorFor(m.modelData)?.focused); - } - - if (query.startsWith("model:")) { - const model = query.slice(6); - return monitors.find(m => m.modelData.model === model); - } - - if (query.startsWith("serial:")) { - const serial = query.slice(7); - return monitors.find(m => m.modelData.serialNumber === serial); - } - - if (query.startsWith("id:")) { - const id = parseInt(query.slice(3), 10); - return monitors.find(m => Hypr.monitorFor(m.modelData)?.id === id); - } - - return monitors.find(m => m.modelData.name === query); - } - - function getMonitorForScreen(screen: ShellScreen): var { - return monitors.find(m => m.modelData === screen); - } - - function increaseBrightness(): void { - const monitor = getMonitor("active"); - if (monitor) - monitor.setBrightness(monitor.brightness + Config.services.brightnessIncrement); - } - - onMonitorsChanged: { - ddcMonitors = []; - ddcServiceMon = []; - ddcServiceProc.running = true; - ddcProc.running = true; - } - - Variants { - id: variants - - model: Quickshell.screens - - Monitor { - } - } - - Process { - command: ["sh", "-c", "asdbctl get"] - running: true - - stdout: StdioCollector { - onStreamFinished: root.appleDisplayPresent = text.trim().length > 0 - } - } - - Process { - id: ddcProc - - command: ["ddcutil", "detect", "--brief"] - - stdout: StdioCollector { - onStreamFinished: root.ddcMonitors = text.trim().split("\n\n").filter(d => d.startsWith("Display ")).map(d => ({ - busNum: d.match(/I2C bus:[ ]*\/dev\/i2c-([0-9]+)/)[1], - connector: d.match(/DRM connector:\s+(.*)/)[1].replace(/^card\d+-/, "") // strip "card1-" - })) - } - } - - Process { - id: ddcServiceProc - - command: ["ddcutil-client", "detect"] - - // running: true - - stdout: StdioCollector { - onStreamFinished: { - const t = text.replace(/\r\n/g, "\n").trim(); - - const output = ("\n" + t).split(/\n(?=display:\s*\d+\s*\n)/).filter(b => b.startsWith("display:")).map(b => ({ - display: Number(b.match(/^display:\s*(\d+)/m)?.[1] ?? -1), - name: (b.match(/^\s*product_name:\s*(.*)$/m)?.[1] ?? "").trim() - })).filter(d => d.display > 0); - root.ddcServiceMon = output; - } - } - } - - CustomShortcut { - description: "Increase brightness" - name: "brightnessUp" - - onPressed: root.increaseBrightness() - } - - CustomShortcut { - description: "Decrease brightness" - name: "brightnessDown" - - onPressed: root.decreaseBrightness() - } - - IpcHandler { - function get(): real { - return getFor("active"); - } - - // Allows searching by active/model/serial/id/name - function getFor(query: string): real { - return root.getMonitor(query)?.brightness ?? -1; - } - - function set(value: string): string { - return setFor("active", value); - } - - // Handles brightness value like brightnessctl: 0.1, +0.1, 0.1-, 10%, +10%, 10%- - function setFor(query: string, value: string): string { - const monitor = root.getMonitor(query); - if (!monitor) - return "Invalid monitor: " + query; - - let targetBrightness; - if (value.endsWith("%-")) { - const percent = parseFloat(value.slice(0, -2)); - targetBrightness = monitor.brightness - (percent / 100); - } else if (value.startsWith("+") && value.endsWith("%")) { - const percent = parseFloat(value.slice(1, -1)); - targetBrightness = monitor.brightness + (percent / 100); - } else if (value.endsWith("%")) { - const percent = parseFloat(value.slice(0, -1)); - targetBrightness = percent / 100; - } else if (value.startsWith("+")) { - const increment = parseFloat(value.slice(1)); - targetBrightness = monitor.brightness + increment; - } else if (value.endsWith("-")) { - const decrement = parseFloat(value.slice(0, -1)); - targetBrightness = monitor.brightness - decrement; - } else if (value.includes("%") || value.includes("-") || value.includes("+")) { - return `Invalid brightness format: ${value}\nExpected: 0.1, +0.1, 0.1-, 10%, +10%, 10%-`; - } else { - targetBrightness = parseFloat(value); - } - - if (isNaN(targetBrightness)) - return `Failed to parse value: ${value}\nExpected: 0.1, +0.1, 0.1-, 10%, +10%, 10%-`; - - monitor.setBrightness(targetBrightness); - - return `Set monitor ${monitor.modelData.name} brightness to ${+monitor.brightness.toFixed(2)}`; - } - - target: "brightness" - } - - component Monitor: QtObject { - id: monitor - - property real brightness - readonly property string busNum: root.ddcMonitors.find(m => m.connector === modelData.name)?.busNum ?? "" - readonly property string displayNum: root.ddcServiceMon.find(m => m.name === modelData.model)?.display ?? "" - readonly property Process initProc: Process { - stdout: StdioCollector { - onStreamFinished: { - if (monitor.isDdcService) { - const output = text.split("\n").filter(o => o.startsWith("vcp_current_value:"))[0].split(":")[1]; - const val = parseInt(output.trim()); - monitor.brightness = val / 100; - } else if (monitor.isAppleDisplay) { - const val = parseInt(text.trim()); - monitor.brightness = val / 101; - } else { - const [, , , cur, max] = text.split(" "); - monitor.brightness = parseInt(cur) / parseInt(max); - } - } - } - } - readonly property bool isAppleDisplay: root.appleDisplayPresent && modelData.model.startsWith("StudioDisplay") - readonly property bool isDdc: root.ddcMonitors.some(m => m.connector === modelData.name) - readonly property bool isDdcService: Config.services.ddcutilService - required property ShellScreen modelData - property real queuedBrightness: NaN - readonly property Timer timer: Timer { - interval: 500 - - onTriggered: { - if (!isNaN(monitor.queuedBrightness)) { - monitor.setBrightness(monitor.queuedBrightness); - monitor.queuedBrightness = NaN; - } - } - } - - function initBrightness(): void { - if (isDdcService) - initProc.command = ["ddcutil-client", "-d", displayNum, "getvcp", "10"]; - else if (isAppleDisplay) - initProc.command = ["asdbctl", "get"]; - else if (isDdc) - initProc.command = ["ddcutil", "-b", busNum, "getvcp", "10", "--brief"]; - else - initProc.command = ["sh", "-c", "echo a b c $(brightnessctl g) $(brightnessctl m)"]; - - initProc.running = true; - } - - function setBrightness(value: real): void { - value = Math.max(0, Math.min(1, value)); - const rounded = Math.round(value * 100); - if (Math.round(brightness * 100) === rounded) - return; - - if ((isDdc || isDdcService) && timer.running) { - queuedBrightness = value; - return; - } - - brightness = value; - - if (isDdcService) - Quickshell.execDetached(["ddcutil-client", "-d", displayNum, "setvcp", "10", rounded]); - else if (isAppleDisplay) - Quickshell.execDetached(["asdbctl", "set", rounded]); - else if (isDdc) - Quickshell.execDetached(["ddcutil", "--disable-dynamic-sleep", "--sleep-multiplier", ".1", "--skip-ddc-checks", "-b", busNum, "setvcp", "10", rounded]); - else - Quickshell.execDetached(["brightnessctl", "s", `${rounded}%`]); - - if (isDdc || isDdcService) - timer.restart(); - } - - Component.onCompleted: initBrightness() - onBusNumChanged: initBrightness() - onDisplayNumChanged: initBrightness() - } -} diff --git a/Greeter/Helpers/Hypr.qml b/Greeter/Helpers/Hypr.qml index 2d3eb31..682b710 100644 --- a/Greeter/Helpers/Hypr.qml +++ b/Greeter/Helpers/Hypr.qml @@ -149,15 +149,7 @@ Singleton { target: "hypr" } - CustomShortcut { - name: "refreshDevices" - - onPressed: extras.refreshDevices() - onReleased: extras.refreshDevices() - } - HyprExtras { id: extras - } } diff --git a/Greeter/Helpers/Icons.qml b/Greeter/Helpers/Icons.qml index 32df434..2599449 100644 --- a/Greeter/Helpers/Icons.qml +++ b/Greeter/Helpers/Icons.qml @@ -1,6 +1,6 @@ pragma Singleton -import qs.Config +import ZShell.Config import Quickshell import Quickshell.Services.Notifications import QtQuick diff --git a/Greeter/Helpers/SystemInfo.qml b/Greeter/Helpers/SystemInfo.qml deleted file mode 100644 index c4e3565..0000000 --- a/Greeter/Helpers/SystemInfo.qml +++ /dev/null @@ -1,83 +0,0 @@ -pragma Singleton - -import qs.Config -import Quickshell -import Quickshell.Io -import QtQuick - -Singleton { - id: root - - property bool isDefaultLogo: true - property string osId - property list osIdLike - property string osLogo - property string osName - property string osPrettyName - readonly property string shell: Quickshell.env("SHELL").split("/").pop() - property string uptime - readonly property string user: Quickshell.env("USER") - readonly property string wm: Quickshell.env("XDG_CURRENT_DESKTOP") || Quickshell.env("XDG_SESSION_DESKTOP") - - FileView { - id: osRelease - - path: "/etc/os-release" - - onLoaded: { - const lines = text().split("\n"); - - const fd = key => lines.find(l => l.startsWith(`${key}=`))?.split("=")[1].replace(/"/g, "") ?? ""; - - root.osName = fd("NAME"); - root.osPrettyName = fd("PRETTY_NAME"); - root.osId = fd("ID"); - root.osIdLike = fd("ID_LIKE").split(" "); - - const logo = Quickshell.iconPath(fd("LOGO"), true); - if (Config.general.logo) { - root.osLogo = Quickshell.iconPath(Config.general.logo, true) || "file://" + Paths.absolutePath(Config.general.logo); - root.isDefaultLogo = false; - } else if (logo) { - root.osLogo = logo; - root.isDefaultLogo = false; - } - } - } - - Connections { - function onLogoChanged(): void { - osRelease.reload(); - } - - target: Config.general - } - - Timer { - interval: 15000 - repeat: true - running: true - - onTriggered: fileUptime.reload() - } - - FileView { - id: fileUptime - - path: "/proc/uptime" - - onLoaded: { - const up = parseInt(text().split(" ")[0] ?? 0); - - const hours = Math.floor(up / 3600); - const minutes = Math.floor((up % 3600) / 60); - - let str = ""; - if (hours > 0) - str += `${hours} hour${hours === 1 ? "" : "s"}`; - if (minutes > 0 || !str) - str += `${str ? ", " : ""}${minutes} minute${minutes === 1 ? "" : "s"}`; - root.uptime = str; - } - } -} diff --git a/Greeter/Helpers/Weather.qml b/Greeter/Helpers/Weather.qml index 480c119..2254405 100644 --- a/Greeter/Helpers/Weather.qml +++ b/Greeter/Helpers/Weather.qml @@ -3,7 +3,7 @@ pragma Singleton import Quickshell import QtQuick import ZShell -import qs.Config +import ZShell.Config Singleton { id: root diff --git a/Greeter/InputField.qml b/Greeter/InputField.qml index 9182b84..157f97f 100644 --- a/Greeter/InputField.qml +++ b/Greeter/InputField.qml @@ -3,9 +3,9 @@ pragma ComponentBehavior: Bound import Quickshell import QtQuick import QtQuick.Layouts +import ZShell.Config import qs.Components -import qs.Helpers -import qs.Config +import qs.Services Item { id: root @@ -38,9 +38,9 @@ Item { anchors.centerIn: parent animate: true - color: root.greeter.launching ? DynamicColors.palette.m3secondary : DynamicColors.palette.m3outline - font.family: Appearance.font.family.mono - font.pointSize: Appearance.font.size.normal + color: root.greeter.launching ? Colors.palette.m3secondary : Colors.palette.m3outline + font.family: Config.appearance.font.family.mono + font.pointSize: Tokens.font.size.normal opacity: root.buffer ? 0 : 1 text: { if (root.greeter.launching) @@ -62,10 +62,10 @@ Item { anchors.left: parent.left anchors.right: parent.right anchors.verticalCenter: parent.verticalCenter - color: DynamicColors.palette.m3onSurface + color: Colors.palette.m3onSurface elide: Text.ElideLeft - font.family: Appearance.font.family.mono - font.pointSize: Appearance.font.size.normal + font.family: Config.appearance.font.family.mono + font.pointSize: Tokens.font.size.normal horizontalAlignment: Qt.AlignHCenter opacity: root.greeter.echoResponse && root.buffer ? 1 : 0 text: root.buffer @@ -89,21 +89,21 @@ Item { anchors.centerIn: parent anchors.horizontalCenterOffset: implicitWidth > root.width ? -(implicitWidth - root.width) / 2 : 0 - implicitHeight: Appearance.font.size.normal + implicitHeight: Tokens.font.size.normal implicitWidth: fullWidth interactive: false opacity: root.greeter.echoResponse ? 0 : 1 orientation: Qt.Horizontal - spacing: Appearance.spacing.small / 2 + spacing: Tokens.spacing.small / 2 delegate: CustomRect { id: ch - color: DynamicColors.palette.m3onSurface + color: Colors.palette.m3onSurface implicitHeight: charList.implicitHeight implicitWidth: implicitHeight opacity: 0 - radius: Appearance.rounding.small / 2 + radius: Tokens.rounding.small / 2 scale: 0 Behavior on opacity { @@ -112,8 +112,8 @@ Item { } Behavior on scale { Anim { - duration: Appearance.anim.durations.expressiveFastSpatial - easing.bezierCurve: Appearance.anim.curves.expressiveFastSpatial + duration: Tokens.anim.durations.expressiveFastSpatial + easing.bezierCurve: Tokens.anim.curves.expressiveFastSpatial } } diff --git a/Greeter/Paths/Paths.qml b/Greeter/Paths/Paths.qml index 27131f1..3c6fa0e 100644 --- a/Greeter/Paths/Paths.qml +++ b/Greeter/Paths/Paths.qml @@ -2,7 +2,7 @@ pragma Singleton import ZShell import Quickshell -import qs.Config +import ZShell.Config Singleton { id: root diff --git a/Greeter/Config/DynamicColors.qml b/Greeter/Services/Colors.qml similarity index 89% rename from Greeter/Config/DynamicColors.qml rename to Greeter/Services/Colors.qml index 2b2be28..ee9d678 100644 --- a/Greeter/Config/DynamicColors.qml +++ b/Greeter/Services/Colors.qml @@ -3,8 +3,10 @@ pragma ComponentBehavior: Bound import Quickshell import Quickshell.Io +import Quickshell.Hyprland import QtQuick import ZShell +import ZShell.Config import qs.Helpers import qs.Paths @@ -79,6 +81,35 @@ Singleton { return Qt.hsla(c.hslHue, c.hslSaturation, 0.1, 1); } + function reloadHyprRules(): void { + const blur = transparency.enabled ? 1 : 0; + const alpha = transparency.base - 0.03; + + const rules = ` + hl.layer_rule({ + match = { namespace = "ZShell-Bar" }, + blur = ${blur} + }) + + hl.layer_rule({ + match = { namespace = "ZShell-Bar" }, + ignore_alpha = ${alpha} + }) + + hl.layer_rule({ + match = { namespace = "ZShell-Auth" }, + blur = ${blur} + }) + + hl.layer_rule({ + match = { namespace = "ZShell-Auth" }, + ignore_alpha = ${alpha} + }) + `; + + Hypr.extras.message(`eval ${rules}`); + } + function setMode(mode: string): void { Quickshell.execDetached(["zshell-cli", "scheme", "generate", "--mode", mode]); Config.general.color.mode = mode; @@ -89,6 +120,24 @@ Singleton { return Qt.rgba(c.g, c.r, c.b, c.a); } + Component.onCompleted: debounceTimer.triggered() + + Connections { + function onUsingLuaChanged(): void { + root.reloadHyprRules(); + } + + target: Hyprland + } + + Connections { + function onConfigReloaded(): void { + root.reloadHyprRules(); + } + + target: Hypr + } + FileView { path: "/etc/zshell-greeter/scheme.json" watchChanges: true @@ -97,6 +146,14 @@ Singleton { onLoaded: root.load(text(), false) } + Timer { + id: debounceTimer + + interval: 300 + + onTriggered: root.reloadHyprRules() + } + ImageAnalyser { id: analyser @@ -224,9 +281,9 @@ Singleton { readonly property color m3tertiary_paletteKeyColor: root.layer(root.palette.m3tertiary_paletteKeyColor) } component Transparency: QtObject { - readonly property real base: Math.max(0, Math.min(1, Appearance.transparency.base - (root.light ? 0.1 : 0))) - readonly property bool enabled: Appearance.transparency.enabled - readonly property real layers: Appearance.transparency.layers + readonly property real base: Math.max(0, Math.min(1, Config.appearance.transparency.base - (root.light ? 0.1 : 0))) + readonly property bool enabled: Config.appearance.transparency.enabled + readonly property real layers: Config.appearance.transparency.layers onBaseChanged: debounceTimer.restart() onEnabledChanged: debounceTimer.restart() diff --git a/Greeter/SessionDock.qml b/Greeter/SessionDock.qml index b4914ec..24d5fd5 100644 --- a/Greeter/SessionDock.qml +++ b/Greeter/SessionDock.qml @@ -2,9 +2,9 @@ pragma ComponentBehavior: Bound import QtQuick import QtQuick.Layouts +import ZShell.Config import qs.Components -import qs.Helpers -import qs.Config +import qs.Services ColumnLayout { id: root @@ -12,14 +12,14 @@ ColumnLayout { required property var greeter anchors.fill: parent - anchors.margins: Appearance.padding.large - spacing: Appearance.spacing.smaller + anchors.margins: Tokens.padding.large + spacing: Tokens.spacing.smaller CustomText { Layout.fillWidth: true - color: DynamicColors.palette.m3outline + color: Colors.palette.m3outline elide: Text.ElideRight - font.family: Appearance.font.family.mono + font.family: Config.appearance.font.family.mono font.weight: 500 text: root.greeter.sessions.length > 0 ? qsTr("%1 session%2").arg(root.greeter.sessions.length).arg(root.greeter.sessions.length === 1 ? "" : "s") : qsTr("Sessions") } @@ -28,7 +28,7 @@ ColumnLayout { Layout.fillHeight: true Layout.fillWidth: true color: "transparent" - radius: Appearance.rounding.small + radius: Tokens.rounding.small Loader { active: opacity > 0 @@ -37,24 +37,24 @@ ColumnLayout { Behavior on opacity { Anim { - duration: Appearance.anim.durations.extraLarge + duration: Tokens.anim.durations.extraLarge } } sourceComponent: ColumnLayout { - spacing: Appearance.spacing.large + spacing: Tokens.spacing.large MaterialIcon { Layout.alignment: Qt.AlignHCenter - color: DynamicColors.palette.m3outlineVariant - font.pointSize: Appearance.font.size.extraLarge * 2 + color: Colors.palette.m3outlineVariant + font.pointSize: Tokens.font.size.extraLarge * 2 text: "desktop_windows" } CustomText { Layout.alignment: Qt.AlignHCenter - color: DynamicColors.palette.m3outlineVariant - font.family: Appearance.font.family.mono - font.pointSize: Appearance.font.size.large + color: Colors.palette.m3outlineVariant + font.family: Config.appearance.font.family.mono + font.pointSize: Tokens.font.size.large font.weight: 500 text: qsTr("No Sessions Found") } @@ -69,7 +69,7 @@ ColumnLayout { currentIndex: root.greeter.sessionIndex highlightFollowsCurrentItem: false model: root.greeter.sessions - spacing: Appearance.spacing.small + spacing: Tokens.spacing.small delegate: CustomRect { id: session @@ -79,8 +79,8 @@ ColumnLayout { anchors.left: parent?.left anchors.right: parent?.right - implicitHeight: row.implicitHeight + Appearance.padding.normal * 2 - radius: Appearance.rounding.normal - Appearance.padding.smaller + implicitHeight: row.implicitHeight + Tokens.padding.normal * 2 + radius: Tokens.rounding.normal - Tokens.padding.smaller StateLayer { onClicked: { @@ -92,50 +92,50 @@ ColumnLayout { id: row anchors.fill: parent - anchors.margins: Appearance.padding.normal - spacing: Appearance.spacing.normal + anchors.margins: Tokens.padding.normal + spacing: Tokens.spacing.normal MaterialIcon { - color: session.index === sessions.currentIndex ? DynamicColors.palette.m3onPrimary : DynamicColors.palette.m3onSurfaceVariant - font.pointSize: Appearance.font.size.extraLarge + color: session.index === sessions.currentIndex ? Colors.palette.m3onPrimary : Colors.palette.m3onSurfaceVariant + font.pointSize: Tokens.font.size.extraLarge text: modelData.kind === "x11" ? "tv" : "desktop_windows" } ColumnLayout { Layout.fillWidth: true - spacing: Appearance.spacing.small / 2 + spacing: Tokens.spacing.small / 2 CustomText { Layout.fillWidth: true - color: session.index === sessions.currentIndex ? DynamicColors.palette.m3onPrimary : DynamicColors.palette.m3onSurface + color: session.index === sessions.currentIndex ? Colors.palette.m3onPrimary : Colors.palette.m3onSurface elide: Text.ElideRight - font.pointSize: Appearance.font.size.normal + font.pointSize: Tokens.font.size.normal font.weight: 600 text: modelData.name } CustomText { Layout.fillWidth: true - color: session.index === sessions.currentIndex ? DynamicColors.palette.m3onPrimaryFixedVariant : DynamicColors.palette.m3onSurfaceVariant + color: session.index === sessions.currentIndex ? Colors.palette.m3onPrimaryFixedVariant : Colors.palette.m3onSurfaceVariant elide: Text.ElideRight - font.family: Appearance.font.family.mono - font.pointSize: Appearance.font.size.small + font.family: Config.appearance.font.family.mono + font.pointSize: Tokens.font.size.small text: modelData.kind } } } } highlight: CustomRect { - color: DynamicColors.palette.m3primary + color: Colors.palette.m3primary implicitHeight: sessions.currentItem?.implicitHeight ?? 0 implicitWidth: sessions.width - radius: Appearance.rounding.normal - Appearance.padding.smaller + radius: Tokens.rounding.normal - Tokens.padding.smaller y: sessions.currentItem?.y ?? 0 Behavior on y { Anim { - duration: Appearance.anim.durations.small - easing.bezierCurve: Appearance.anim.curves.expressiveEffects + duration: Tokens.anim.durations.small + easing.bezierCurve: Tokens.anim.curves.expressiveEffects } } } diff --git a/Greeter/UserDock.qml b/Greeter/UserDock.qml index dd4d4c7..366842c 100644 --- a/Greeter/UserDock.qml +++ b/Greeter/UserDock.qml @@ -2,9 +2,10 @@ pragma ComponentBehavior: Bound import QtQuick import QtQuick.Layouts +import ZShell.Config import qs.Components import qs.Helpers -import qs.Config +import qs.Services ColumnLayout { id: root @@ -12,14 +13,14 @@ ColumnLayout { required property var greeter anchors.fill: parent - anchors.margins: Appearance.padding.large - spacing: Appearance.spacing.smaller + anchors.margins: Tokens.padding.large + spacing: Tokens.spacing.smaller CustomText { Layout.fillWidth: true - color: DynamicColors.palette.m3outline + color: Colors.palette.m3outline elide: Text.ElideRight - font.family: Appearance.font.family.mono + font.family: Config.appearance.font.family.mono font.weight: 500 text: root.greeter.users.length > 0 ? qsTr("%1 user%2").arg(root.greeter.users.length).arg(root.greeter.users.length === 1 ? "" : "s") : qsTr("Users") } @@ -28,7 +29,7 @@ ColumnLayout { Layout.fillHeight: true Layout.fillWidth: true color: "transparent" - radius: Appearance.rounding.small + radius: Tokens.rounding.small Loader { active: opacity > 0 @@ -37,25 +38,25 @@ ColumnLayout { Behavior on opacity { Anim { - duration: Appearance.anim.durations.extraLarge + duration: Tokens.anim.durations.extraLarge } } sourceComponent: ColumnLayout { - spacing: Appearance.spacing.large + spacing: Tokens.spacing.large MaterialIcon { Layout.alignment: Qt.AlignHCenter - color: DynamicColors.palette.m3outlineVariant + color: Colors.palette.m3outlineVariant fill: 1 - font.pointSize: Appearance.font.size.extraLarge * 2 + font.pointSize: Tokens.font.size.extraLarge * 2 text: "account_circle" } CustomText { Layout.alignment: Qt.AlignHCenter - color: DynamicColors.palette.m3outlineVariant - font.family: Appearance.font.family.mono - font.pointSize: Appearance.font.size.large + color: Colors.palette.m3outlineVariant + font.family: Config.appearance.font.family.mono + font.pointSize: Tokens.font.size.large font.weight: 500 text: qsTr("No Users Found") } @@ -70,7 +71,7 @@ ColumnLayout { currentIndex: root.greeter.selectedUser ? root.greeter.users.indexOf(root.greeter.selectedUser) : -1 highlightFollowsCurrentItem: false model: root.greeter.users - spacing: Appearance.spacing.small + spacing: Tokens.spacing.small delegate: CustomRect { id: user @@ -80,8 +81,8 @@ ColumnLayout { anchors.left: parent?.left anchors.right: parent?.right - implicitHeight: row.implicitHeight + Appearance.padding.normal * 2 - radius: Appearance.rounding.normal - Appearance.padding.smaller + implicitHeight: row.implicitHeight + Tokens.padding.normal * 2 + radius: Tokens.rounding.normal - Tokens.padding.smaller StateLayer { onClicked: { @@ -93,19 +94,19 @@ ColumnLayout { id: row anchors.fill: parent - anchors.margins: Appearance.padding.normal - spacing: Appearance.spacing.normal + anchors.margins: Tokens.padding.normal + spacing: Tokens.spacing.normal CustomClippingRect { Layout.preferredHeight: 50 Layout.preferredWidth: 50 - radius: Appearance.rounding.full + radius: Tokens.rounding.full MaterialIcon { anchors.centerIn: parent - color: user.index === users.currentIndex ? DynamicColors.palette.m3onPrimary : DynamicColors.palette.m3onSurfaceVariant + color: user.index === users.currentIndex ? Colors.palette.m3onPrimary : Colors.palette.m3onSurfaceVariant fill: 1 - font.pointSize: Appearance.font.size.extraLarge + font.pointSize: Tokens.font.size.extraLarge text: modelData.kind === "x11" ? "tv" : "account_circle" } @@ -117,13 +118,13 @@ ColumnLayout { ColumnLayout { Layout.fillWidth: true - spacing: Appearance.spacing.small / 2 + spacing: Tokens.spacing.small / 2 CustomText { Layout.fillWidth: true - color: user.index === users.currentIndex ? DynamicColors.palette.m3onPrimary : DynamicColors.palette.m3onSurface + color: user.index === users.currentIndex ? Colors.palette.m3onPrimary : Colors.palette.m3onSurface elide: Text.ElideRight - font.pointSize: Appearance.font.size.normal + font.pointSize: Tokens.font.size.normal font.weight: 600 text: modelData.username } @@ -131,16 +132,16 @@ ColumnLayout { } } highlight: CustomRect { - color: DynamicColors.palette.m3primary + color: Colors.palette.m3primary implicitHeight: users.currentItem?.implicitHeight ?? 0 implicitWidth: users.width - radius: Appearance.rounding.normal - Appearance.padding.smaller + radius: Tokens.rounding.normal - Tokens.padding.smaller y: users.currentItem?.y ?? 0 Behavior on y { Anim { - duration: Appearance.anim.durations.small - easing.bezierCurve: Appearance.anim.curves.expressiveEffects + duration: Tokens.anim.durations.small + easing.bezierCurve: Tokens.anim.curves.expressiveEffects } } } diff --git a/Greeter/UserImage.qml b/Greeter/UserImage.qml index 6d979b9..f49aee2 100644 --- a/Greeter/UserImage.qml +++ b/Greeter/UserImage.qml @@ -7,7 +7,7 @@ Item { ClippingRectangle { anchors.fill: parent - radius: Appearance.rounding.full + radius: Tokens.rounding.full Image { id: userImage diff --git a/Greeter/WeatherInfo.qml b/Greeter/WeatherInfo.qml index 56bcdb5..3a69bcd 100644 --- a/Greeter/WeatherInfo.qml +++ b/Greeter/WeatherInfo.qml @@ -2,9 +2,10 @@ pragma ComponentBehavior: Bound import QtQuick import QtQuick.Layouts +import ZShell.Config import qs.Components import qs.Helpers -import qs.Config +import qs.Services ColumnLayout { id: root @@ -12,20 +13,20 @@ ColumnLayout { required property int rootHeight anchors.left: parent.left - anchors.margins: Appearance.padding.large * 2 + anchors.margins: Tokens.padding.large * 2 anchors.right: parent.right - spacing: Appearance.spacing.small + spacing: Tokens.spacing.small Loader { Layout.alignment: Qt.AlignHCenter - Layout.bottomMargin: -Appearance.padding.large - Layout.topMargin: Appearance.padding.large * 2 + Layout.bottomMargin: -Tokens.padding.large + Layout.topMargin: Tokens.padding.large * 2 active: root.rootHeight > 610 visible: active sourceComponent: CustomText { - color: DynamicColors.palette.m3primary - font.pointSize: Appearance.font.size.extraLarge + color: Colors.palette.m3primary + font.pointSize: Tokens.font.size.extraLarge font.weight: 500 text: qsTr("Weather") } @@ -33,24 +34,24 @@ ColumnLayout { RowLayout { Layout.fillWidth: true - spacing: Appearance.spacing.large + spacing: Tokens.spacing.large MaterialIcon { animate: true - color: DynamicColors.palette.m3secondary - font.pointSize: Appearance.font.size.extraLarge * 2.5 + color: Colors.palette.m3secondary + font.pointSize: Tokens.font.size.extraLarge * 2.5 text: Weather.icon } ColumnLayout { - spacing: Appearance.spacing.small + spacing: Tokens.spacing.small CustomText { Layout.fillWidth: true animate: true - color: DynamicColors.palette.m3secondary + color: Colors.palette.m3secondary elide: Text.ElideRight - font.pointSize: Appearance.font.size.large + font.pointSize: Tokens.font.size.large font.weight: 500 text: Weather.description } @@ -58,27 +59,27 @@ ColumnLayout { CustomText { Layout.fillWidth: true animate: true - color: DynamicColors.palette.m3onSurfaceVariant + color: Colors.palette.m3onSurfaceVariant elide: Text.ElideRight - font.pointSize: Appearance.font.size.normal + font.pointSize: Tokens.font.size.normal text: qsTr("Humidity: %1%").arg(Weather.humidity) } } Loader { - Layout.rightMargin: Appearance.padding.smaller + Layout.rightMargin: Tokens.padding.smaller active: root.width > 400 visible: active sourceComponent: ColumnLayout { - spacing: Appearance.spacing.small + spacing: Tokens.spacing.small CustomText { Layout.fillWidth: true animate: true - color: DynamicColors.palette.m3primary + color: Colors.palette.m3primary elide: Text.ElideLeft - font.pointSize: Appearance.font.size.extraLarge + font.pointSize: Tokens.font.size.extraLarge font.weight: 500 horizontalAlignment: Text.AlignRight text: Weather.temp @@ -87,9 +88,9 @@ ColumnLayout { CustomText { Layout.fillWidth: true animate: true - color: DynamicColors.palette.m3outline + color: Colors.palette.m3outline elide: Text.ElideLeft - font.pointSize: Appearance.font.size.smaller + font.pointSize: Tokens.font.size.smaller horizontalAlignment: Text.AlignRight text: qsTr("Feels like: %1").arg(Weather.feelsLike) } @@ -100,14 +101,14 @@ ColumnLayout { Loader { id: forecastLoader - Layout.bottomMargin: Appearance.padding.large * 2 + Layout.bottomMargin: Tokens.padding.large * 2 Layout.fillWidth: true - Layout.topMargin: Appearance.spacing.smaller + Layout.topMargin: Tokens.spacing.smaller active: root.rootHeight > 820 visible: active sourceComponent: RowLayout { - spacing: Appearance.spacing.large + spacing: Tokens.spacing.large Repeater { model: { @@ -127,12 +128,12 @@ ColumnLayout { required property var modelData Layout.fillWidth: true - spacing: Appearance.spacing.small + spacing: Tokens.spacing.small CustomText { Layout.fillWidth: true - color: DynamicColors.palette.m3outline - font.pointSize: Appearance.font.size.larger + color: Colors.palette.m3outline + font.pointSize: Tokens.font.size.larger horizontalAlignment: Text.AlignHCenter text: { const hour = forecastHour.modelData?.hour ?? 0; @@ -142,15 +143,15 @@ ColumnLayout { MaterialIcon { Layout.alignment: Qt.AlignHCenter - font.pointSize: Appearance.font.size.extraLarge * 1.5 + font.pointSize: Tokens.font.size.extraLarge * 1.5 font.weight: 500 text: forecastHour.modelData?.icon ?? "cloud_alert" } CustomText { Layout.alignment: Qt.AlignHCenter - color: DynamicColors.palette.m3secondary - font.pointSize: Appearance.font.size.larger + color: Colors.palette.m3secondary + font.pointSize: Tokens.font.size.larger text: Config.services.useFahrenheit ? `${forecastHour.modelData?.tempF ?? 0}°F` : `${forecastHour.modelData?.tempC ?? 0}°C` } } diff --git a/Greeter/scripts/start-zshell-greeter b/Greeter/scripts/start-zshell-greeter index 0dd4f35..7429b63 100755 --- a/Greeter/scripts/start-zshell-greeter +++ b/Greeter/scripts/start-zshell-greeter @@ -7,7 +7,7 @@ export QT_WAYLAND_DISABLE_WINDOWDECORATION=1 export EGL_PLATFORM=gbm if command -v start-hyprland >/dev/null 2>&1; then - exec start-hyprland -- -c /etc/zshell-greeter/zshell-hyprland.conf + exec start-hyprland -- -c /etc/zshell-greeter/zshell-hyprland.lua else exec Hyprland -c /etc/zshell-greeter/zshell-hyprland.lua fi diff --git a/Helpers/Battery.qml b/Helpers/Battery.qml index 1ffb61f..2df72d9 100644 --- a/Helpers/Battery.qml +++ b/Helpers/Battery.qml @@ -2,7 +2,8 @@ pragma Singleton import Quickshell import Quickshell.Services.UPower -import qs.Config +import ZShell.Config +import qs.Services Singleton { id: root @@ -10,18 +11,18 @@ Singleton { readonly property var colors: { if (deviceState === UPowerDeviceState.Charging || deviceState === UPowerDeviceState.FullyCharged) return { - fg: DynamicColors.swapRG(DynamicColors.palette.m3error), - bg: DynamicColors.swapRG(DynamicColors.palette.m3onError) + fg: Colors.swapRG(Colors.palette.m3error), + bg: Colors.swapRG(Colors.palette.m3onError) }; else if (currentPerc <= 0.2) return { - fg: DynamicColors.palette.m3error, - bg: DynamicColors.palette.m3onError + fg: Colors.palette.m3error, + bg: Colors.palette.m3onError }; else return { - fg: DynamicColors.palette.m3onSurface, - bg: DynamicColors.palette.m3surface + fg: Colors.palette.m3onSurface, + bg: Colors.palette.m3surface }; } readonly property real currentPerc: UPower.displayDevice.percentage diff --git a/Helpers/Brightness.qml b/Helpers/Brightness.qml index 83b5fae..201a40a 100644 --- a/Helpers/Brightness.qml +++ b/Helpers/Brightness.qml @@ -4,7 +4,7 @@ pragma ComponentBehavior: Bound import Quickshell import Quickshell.Io import QtQuick -import qs.Config +import ZShell.Config import qs.Components Singleton { diff --git a/Helpers/ClipHistory.qml b/Helpers/ClipHistory.qml index fe38a37..0113e0f 100644 --- a/Helpers/ClipHistory.qml +++ b/Helpers/ClipHistory.qml @@ -4,7 +4,7 @@ pragma ComponentBehavior: Bound import QtQuick import Quickshell import Quickshell.Io -import qs.Config +import ZShell.Config import "../scripts/fuzzysort.js" as Fuzzy Singleton { diff --git a/Helpers/DockApps.qml b/Helpers/DockApps.qml index 1bdf96a..bf365f0 100644 --- a/Helpers/DockApps.qml +++ b/Helpers/DockApps.qml @@ -4,7 +4,7 @@ import QtQuick import Quickshell import Quickshell.Wayland import qs.Components -import qs.Config +import ZShell.Config Singleton { id: root diff --git a/Helpers/GameMode.qml b/Helpers/GameMode.qml index 19b3485..8f63bb9 100644 --- a/Helpers/GameMode.qml +++ b/Helpers/GameMode.qml @@ -4,7 +4,7 @@ import QtQuick import Quickshell import Quickshell.Io import ZShell -import qs.Config +import ZShell.Config Singleton { id: root diff --git a/Helpers/Hyprsunset.qml b/Helpers/Hyprsunset.qml index 1df7d9d..ca82be2 100644 --- a/Helpers/Hyprsunset.qml +++ b/Helpers/Hyprsunset.qml @@ -3,7 +3,7 @@ pragma Singleton import Quickshell import QtQuick import ZShell.Services -import qs.Config +import ZShell.Config Singleton { id: root diff --git a/Helpers/Icons.qml b/Helpers/Icons.qml index 4661700..f9eb586 100644 --- a/Helpers/Icons.qml +++ b/Helpers/Icons.qml @@ -1,6 +1,6 @@ pragma Singleton -import QtQuick +import ZShell.Config import Quickshell import Quickshell.Services.Notifications diff --git a/Helpers/ModeScheduler.qml b/Helpers/ModeScheduler.qml index 5a5815c..a45e15a 100644 --- a/Helpers/ModeScheduler.qml +++ b/Helpers/ModeScheduler.qml @@ -4,8 +4,9 @@ import Quickshell import QtQuick import qs.Modules import qs.Helpers -import qs.Config +import ZShell.Config import qs.Paths +import qs.Services Singleton { id: root @@ -55,10 +56,10 @@ Singleton { } if (isDarkTime) { - if (DynamicColors.light) + if (Colors.light) root.applyDarkMode(); } else { - if (!DynamicColors.light) + if (!Colors.light) root.applyLightMode(); } } @@ -86,10 +87,10 @@ Singleton { } if (isDarkTime) { - if (DynamicColors.light) + if (Colors.light) root.applyDarkMode(); } else { - if (!DynamicColors.light) + if (!Colors.light) root.applyLightMode(); } } diff --git a/Helpers/NetworkUsage.qml b/Helpers/NetworkUsage.qml index 49be574..b78c540 100644 --- a/Helpers/NetworkUsage.qml +++ b/Helpers/NetworkUsage.qml @@ -4,7 +4,7 @@ import QtQuick import Quickshell import Quickshell.Io import ZShell.Internal -import qs.Config +import ZShell.Config Singleton { id: root diff --git a/Helpers/Picker.qml b/Helpers/Picker.qml old mode 100644 new mode 100755 index f48951f..d19f29f --- a/Helpers/Picker.qml +++ b/Helpers/Picker.qml @@ -6,10 +6,12 @@ import Quickshell.Wayland import QtQuick import QtQuick.Effects import qs.Components -import qs.Config -import qs.Helpers +import ZShell.Config +import qs.Helpers.Picker +import qs.Paths +import qs.Services -MouseArea { +Item { id: root property list clients: { @@ -29,9 +31,11 @@ MouseArea { readonly property int cornerRadius: Hypr.options.decoration.rounding property real ex: screen.width property real ey: screen.height + property color inkColor: "#ff3b30" required property LazyLoader loader + property string mode: "select" property bool onClient - property real realBorderWidth: onClient ? (Hypr.options.general.border_size ?? 1) : 2 + property real realBorderWidth: 2 property real realRounding: onClient ? (Hypr.options.decoration.rounding ?? 0) : 0 property real rsx: Math.min(sx, ex) property real rsy: Math.min(sy, ey) @@ -48,6 +52,12 @@ MouseArea { property real sw: Math.abs(sx - ex) property real sx: 0 property real sy: 0 + property string tool: "move" + + function cancel(): void { + annotations.clearAll(); + closeAnim.start(); + } function checkClientRects(x: real, y: real): void { for (const client of clients) { @@ -71,24 +81,49 @@ MouseArea { } } - function save(): void { - const tmpfile = Qt.resolvedUrl(`/tmp/zshell-picker-${Quickshell.processId}-${Date.now()}.png`); + function enterEditMode(): void { + mode = "edit"; + tool = "move"; + } + + function save(copyToClipboard: bool): void { const rounding = root.cornerRadius > 0; const shadow_blur = root.shadowRange / root.shadowRenderPower; const r = Math.floor(root.shadowColor.r * 256); const g = Math.floor(root.shadowColor.g * 256); const b = Math.floor(root.shadowColor.b * 256); const a = Math.floor(root.shadowColor.a * 256); + const tmpfile = Qt.resolvedUrl(`/tmp/zshell-picker-${Quickshell.processId}-${Date.now()}.png`); const args = Config.screenshot.mode === "auto" ? ["--rounding", `${rounding}`, "--radius", root.cornerRadius, "--shadow", root.shadowEnabled, "--shadow-blur", `${shadow_blur}`, "--shadow-color", `${r},${g},${b},${a}`, "--shadow-offset-x", root.shadowOffset[0], "--shadow-offset-y", root.shadowOffset[1]] : []; - const cmd = Config.screenshot.enable_pp ? ["zshell-img-tools", "--scale", root.scaleRatio, ...args, "--image"] : ["swappy", "-f"]; - ZShellIo.saveItem(screencopy, tmpfile, Qt.rect(Math.ceil(rsx), Math.ceil(rsy), Math.floor(sw), Math.floor(sh)), path => Quickshell.execDetached([...cmd, path])); + const postCmd = Config.screenshot.enable_pp ? ["zshell-img-tools", "--scale", root.scaleRatio, ...args, "--image"] : null; + + overlay.visible = border.visible = false; + handles.visible = false; + toolbar.visible = false; + + ZShellIo.saveItem(captureLayer, tmpfile, Qt.rect(Math.ceil(rsx), Math.ceil(rsy), Math.floor(sw), Math.floor(sh)), path => { + const finalize = finalPath => { + if (copyToClipboard) { + Quickshell.execDetached(["sh", "-c", `wl-copy --type image/png < '${finalPath.replace(/'/g, `'\\''`)}'`]); + } + if (!copyToClipboard || Config.screenshot.saveOnCopy) { + const dest = `${Paths.screenshots}/zshell-${Date.now()}.png`; + Quickshell.execDetached(["sh", "-c", `mkdir -p "$(dirname '${dest}')" && cp '${path.replace(/'/g, `'\\''`)}' '${dest}'`]); + } + }; + + if (postCmd) { + Quickshell.execDetached(postCmd.concat([path])); + finalize(path); + } else { + finalize(path); + } + }); closeAnim.start(); } anchors.fill: parent - cursorShape: Qt.CrossCursor focus: true - hoverEnabled: true opacity: 0 Behavior on opacity { @@ -97,25 +132,25 @@ MouseArea { } } Behavior on rsx { - enabled: !root.pressed + enabled: !selectArea.pressed && root.mode === "select" ExAnim { } } Behavior on rsy { - enabled: !root.pressed + enabled: !selectArea.pressed && root.mode === "select" ExAnim { } } Behavior on sh { - enabled: !root.pressed + enabled: !selectArea.pressed && root.mode === "select" ExAnim { } } Behavior on sw { - enabled: !root.pressed + enabled: !selectArea.pressed && root.mode === "select" ExAnim { } @@ -123,8 +158,7 @@ MouseArea { Component.onCompleted: { Hypr.extras.refreshOptions(); - if (loader.freeze) - clients = clients; + screencopy.active = true; opacity = 1; @@ -144,48 +178,49 @@ MouseArea { ey = screen.height / 2 + 100; } } - Keys.onEscapePressed: closeAnim.start() - onClientsChanged: checkClientRects(mouseX, mouseY) - onPositionChanged: event => { - const x = event.x; - const y = event.y; - - if (pressed) { - onClient = false; - sx = ssx; - sy = ssy; - ex = x; - ey = y; - } else if (!saveTimer.running) { - checkClientRects(x, y); + Keys.onEscapePressed: root.mode === "edit" ? cancel() : closeAnim.start() + Keys.onPressed: e => { + if ((e.key == Qt.Key_C) && (e.modifiers & Qt.ControlModifier)) { + save(true); + e.accepted = true; + } else if ((e.key == Qt.Key_S) && (e.modifiers & Qt.ControlModifier)) { + save(false); + e.accepted = true; } } - onPressed: event => { - ssx = event.x; - ssy = event.y; + onClientsChanged: { + if (root.mode === "select") + checkClientRects(selectArea.mouseX, selectArea.mouseY); } - onReleased: { - if (closeAnim.running) - return; - if (root.loader.freeze) { - saveTimer.start(); - } else { - overlay.visible = border.visible = false; - screencopy.visible = false; - screencopy.active = true; - saveTimer.start(); + MouseArea { + id: selectArea + + anchors.fill: parent + cursorShape: Qt.CrossCursor + enabled: root.mode === "select" + hoverEnabled: true + visible: root.mode === "select" + + onPositionChanged: event => { + const x = event.x; + const y = event.y; + + if (pressed) { + root.onClient = false; + root.sx = root.ssx; + root.sy = root.ssy; + root.ex = x; + root.ey = y; + } else { + root.checkClientRects(x, y); + } } - } - - Timer { - id: saveTimer - - interval: 25 - repeat: false - running: false - - onTriggered: root.save() + onPressed: event => { + root.ssx = event.x; + root.ssy = event.y; + } + onReleased: root.enterEditMode() } SequentialAnimation { @@ -231,16 +266,38 @@ MouseArea { } } - Loader { - id: screencopy + Item { + id: captureLayer - active: root.loader.freeze anchors.fill: parent - asynchronous: true - sourceComponent: ScreencopyView { - captureSource: root.screen - paintCursor: false + Loader { + id: screencopy + + active: false + anchors.fill: parent + asynchronous: true + + sourceComponent: ScreencopyView { + captureSource: root.screen + paintCursor: false + } + } + + AnnotationCanvas { + id: annotations + + anchors.fill: parent + inkColor: root.inkColor + layer.enabled: true + tool: root.mode === "edit" && root.tool !== "move" ? root.tool : "none" + + layer.effect: MultiEffect { + maskEnabled: true + maskSource: selectionWrapper + maskSpreadAtMin: 1 + maskThresholdMin: 0.5 + } } } @@ -252,7 +309,7 @@ MouseArea { layer.enabled: true opacity: 0.3 radius: root.realRounding - visible: screencopy.item.hasContent || !root.loader.freeze + visible: screencopy.item?.hasContent ?? false layer.effect: MultiEffect { maskEnabled: true @@ -284,13 +341,13 @@ MouseArea { Rectangle { id: border - border.color: DynamicColors.palette.m3primary + border.color: Colors.palette.m3primary border.width: root.realBorderWidth color: "transparent" implicitHeight: selectionRect.implicitHeight + root.realBorderWidth * 2 implicitWidth: selectionRect.implicitWidth + root.realBorderWidth * 2 radius: root.realRounding > 0 ? root.realRounding + root.realBorderWidth : 0 - visible: screencopy.item.hasContent || !root.loader.freeze + visible: screencopy.item?.hasContent ?? false x: selectionRect.x - root.realBorderWidth y: selectionRect.y - root.realBorderWidth @@ -300,8 +357,51 @@ MouseArea { } } + SelectionHandles { + id: handles + + selH: root.sh + selW: root.sw + selX: root.rsx + selY: root.rsy + visible: root.mode === "edit" && root.tool === "move" + + onBoundsChanged: (x, y, w, h) => { + root.sx = x; + root.sy = y; + root.ex = x + w; + root.ey = y + h; + } + onMoveBy: (dx, dy) => { + const w = root.sw, h = root.sh; + let nx = root.rsx + dx, ny = root.rsy + dy; + nx = Math.max(0, Math.min(nx, root.screen.width - w)); + ny = Math.max(0, Math.min(ny, root.screen.height - h)); + root.sx = nx; + root.sy = ny; + root.ex = nx + w; + root.ey = ny + h; + } + } + + AnnotationToolbar { + id: toolbar + + inkColor: root.inkColor + tool: root.tool + visible: root.mode === "edit" + x: Math.max(8, Math.min(root.rsx + root.sw / 2 - width / 2, root.screen.width - width - 8)) + y: (root.rsy + root.sh + height + Tokens.padding.normal <= root.screen.height) ? root.rsy + root.sh + Tokens.padding.normal : (root.rsy - height - Tokens.padding.normal <= 0) ? root.rsy + root.sh - height - Tokens.padding.normal : root.rsy - height - Tokens.padding.normal + + onCancelRequested: root.cancel() + onClearRequested: annotations.clearAll() + onColorSelected: c => root.inkColor = c + onCopyRequested: root.save(true) + onSaveRequested: root.save(false) + onToolSelected: t => root.tool = t + onUndoRequested: annotations.undo() + } + component ExAnim: Anim { - duration: MaterialEasing.expressiveEffectsTime - easing.bezierCurve: MaterialEasing.expressiveEffects } } diff --git a/Helpers/Picker/AnnotationCanvas.qml b/Helpers/Picker/AnnotationCanvas.qml new file mode 100755 index 0000000..7ff98b0 --- /dev/null +++ b/Helpers/Picker/AnnotationCanvas.qml @@ -0,0 +1,143 @@ +pragma ComponentBehavior: Bound + +import QtQuick +import ZShell.Internal + +Item { + id: root + + property color inkColor: "#ff3b30" + property real inkWidth: 4 + property string tool: "none" + + signal changed + + function clearAll() { + committedCanvas.clear(); + previewCanvas.clear(); + changed(); + } + + function sampleShape(tool, x1, y1, x2, y2) { + const pts = []; + switch (tool) { + case "line": + pts.push([x1, y1], [x2, y2]); + break; + case "arrow": + { + const angle = Math.atan2(y2 - y1, x2 - x1); + const headLen = 14 + root.inkWidth * 2; + pts.push([x1, y1], [x2, y2]); + pts.push([x2 - headLen * Math.cos(angle - Math.PI / 6), y2 - headLen * Math.sin(angle - Math.PI / 6)]); + pts.push([x2, y2]); + pts.push([x2 - headLen * Math.cos(angle + Math.PI / 6), y2 - headLen * Math.sin(angle + Math.PI / 6)]); + break; + } + case "rect": + pts.push([x1, y1], [x2, y1], [x2, y2], [x1, y2], [x1, y1]); + break; + case "ellipse": + { + const cx = (x1 + x2) / 2, cy = (y1 + y2) / 2; + const rx = Math.abs(x2 - x1) / 2, ry = Math.abs(y2 - y1) / 2; + const perimeter = Math.PI * (3 * (rx + ry) - Math.sqrt((3 * rx + ry) * (rx + 3 * ry))); + const steps = Math.max(48, Math.min(256, Math.ceil(perimeter / 4))); + for (let i = 0; i <= steps; i++) { + const a = (i / steps) * Math.PI * 2; + pts.push([cx + rx * Math.cos(a), cy + ry * Math.sin(a)]); + } + break; + } + } + return pts; + } + + function undo() { + committedCanvas.undoLastGroup(); + changed(); + } + + anchors.fill: parent + + StrokeCanvas { + id: committedCanvas + + anchors.fill: parent + penColor: root.inkColor + penWidth: root.inkWidth + } + + StrokeCanvas { + id: previewCanvas + + anchors.fill: parent + penColor: root.inkColor + penWidth: root.inkWidth + } + + PointHandler { + id: drawHandler + + property real startX + property real startY + property bool started: false + + acceptedButtons: Qt.LeftButton | Qt.RightButton + enabled: root.tool !== "none" + + onActiveChanged: { + if (active) + return; + + if (root.tool === "pen") { + committedCanvas.endStroke(); + } else if (started) { + const pts = root.sampleShape(root.tool, startX, startY, point.position.x, point.position.y); + if (pts.length > 0) { + committedCanvas.beginStroke(pts[0][0], pts[0][1], true); + for (let i = 1; i < pts.length; i++) + committedCanvas.appendPoint(pts[i][0], pts[i][1]); + committedCanvas.endStroke(); + } + previewCanvas.clear(); + } + started = false; + root.changed(); + } + onPointChanged: { + if (!active) + return; + + if (point.pressedButtons & Qt.RightButton) { + root.clearAll(); + return; + } + + const x = point.position.x; + const y = point.position.y; + + if (root.tool === "pen") { + if (!started) { + started = true; + committedCanvas.beginStroke(x, y); + return; + } + committedCanvas.appendPoint(x, y); + return; + } + + if (!started) { + started = true; + startX = point.pressPosition.x; + startY = point.pressPosition.y; + } + const pts = root.sampleShape(root.tool, startX, startY, x, y); + if (pts.length > 0) { + previewCanvas.beginStroke(pts[0][0], pts[0][1], true); + for (let i = 1; i < pts.length; i++) + previewCanvas.appendPoint(pts[i][0], pts[i][1]); + } + } + } +} diff --git a/Helpers/Picker/AnnotationToolbar.qml b/Helpers/Picker/AnnotationToolbar.qml new file mode 100755 index 0000000..19fdbd0 --- /dev/null +++ b/Helpers/Picker/AnnotationToolbar.qml @@ -0,0 +1,185 @@ +pragma ComponentBehavior: Bound + +import ZShell.Components +import QtQuick +import QtQuick.Layouts +import qs.Components +import ZShell.Config +import qs.Services + +CustomRect { + id: root + + readonly property var colorPalette: ["#ff3b30", "#ff9500", "#ffcc00", "#34c759", "#0a84ff", "#af52de", "#ffffff", "#000000"] + property color inkColor: "#ff3b30" + property string tool: "move" + readonly property var toolList: [ + { + id: "move", + glyph: "arrows_output" + }, + { + id: "pen", + glyph: "draw" + }, + { + id: "line", + glyph: "diagonal_line" + }, + { + id: "arrow", + glyph: "arrow_outward" + }, + { + id: "rect", + glyph: "rectangle" + }, + { + id: "ellipse", + glyph: "circle" + } + ] + + signal cancelRequested + signal clearRequested + signal colorSelected(color c) + signal copyRequested + signal saveRequested + signal toolSelected(string tool) + signal undoRequested + + color: Colors.palette.m3surface + height: row.implicitHeight + Tokens.padding.normal * 2 + radius: Tokens.rounding.full + width: row.implicitWidth + Tokens.padding.normal * 2 + + RowLayout { + id: row + + anchors.centerIn: parent + spacing: 6 + + ButtonRow { + id: toolRow + + spacing: Tokens.spacing.extraSmall + + Repeater { + model: root.toolList + + delegate: IconButton { + id: tool + + required property var modelData + + color: root.tool === modelData.id ? "#3584e4" : "transparent" + icon: tool.modelData.glyph + inactiveColor: root.tool === modelData.id ? Colors.palette.m3primary : "transparent" + inactiveOnColor: root.tool === modelData.id ? Colors.palette.m3onPrimary : Colors.palette.m3onSurface + isRound: true + shapeMorph: true + shapeMorphExpansion: shapeMorph && pressed ? 12 : 0 + + onClicked: root.toolSelected(tool.modelData.id) + } + } + } + + CustomRect { + Layout.fillHeight: true + Layout.preferredWidth: 1 + color: Colors.palette.m3outlineVariant + } + + ButtonRow { + spacing: Tokens.spacing.extraSmall + + Repeater { + model: root.colorPalette + + delegate: IconButton { + readonly property real buttonSize: toolRow.implicitHeight - Tokens.padding.normal + required property color modelData + + fillWidth: false + font.pointSize: 0 + icon: "" + implicitHeight: buttonSize + implicitWidth: buttonSize + inactiveColor: modelData + inactiveOnColor: Colors.on(modelData) + isRound: true + shapeMorph: true + shapeMorphExpansion: pressed ? 12 : 0 + + onClicked: root.colorSelected(modelData) + } + } + } + + CustomRect { + Layout.fillHeight: true + Layout.preferredWidth: 1 + color: Colors.palette.m3outlineVariant + } + + ButtonRow { + spacing: Tokens.spacing.extraSmall + + IconButton { + icon: "undo" + inactiveColor: "transparent" + inactiveOnColor: Colors.palette.m3onSurface + isRound: true + shapeMorph: true + shapeMorphExpansion: pressed ? 12 : 0 + + onClicked: root.undoRequested() + } + + IconButton { + icon: "delete_history" + inactiveColor: "transparent" + inactiveOnColor: Colors.palette.m3onSurface + isRound: true + shapeMorph: true + shapeMorphExpansion: pressed ? 12 : 0 + + onClicked: root.clearRequested() + } + + IconButton { + icon: "content_copy" + inactiveColor: "transparent" + inactiveOnColor: Colors.palette.m3onSurface + isRound: true + shapeMorph: true + shapeMorphExpansion: pressed ? 12 : 0 + + onClicked: root.copyRequested() + } + + IconButton { + icon: "delete_forever" + inactiveColor: "transparent" + inactiveOnColor: Colors.palette.m3onSurface + isRound: true + shapeMorph: true + shapeMorphExpansion: pressed ? 12 : 0 + + onClicked: root.cancelRequested() + } + + IconButton { + icon: "check" + inactiveColor: "transparent" + inactiveOnColor: Colors.palette.m3onSurface + isRound: true + shapeMorph: true + shapeMorphExpansion: pressed ? 12 : 0 + + onClicked: root.saveRequested() + } + } + } +} diff --git a/Helpers/Picker/SelectionHandles.qml b/Helpers/Picker/SelectionHandles.qml new file mode 100755 index 0000000..eca4b0f --- /dev/null +++ b/Helpers/Picker/SelectionHandles.qml @@ -0,0 +1,183 @@ +pragma ComponentBehavior: Bound + +import QtQuick + +Item { + id: root + + property color handleBorder: "#3584e4" + property color handleFill: "white" + property real hs: 12 + property real minSize: 24 + required property real selH + required property real selW + required property real selX + required property real selY + + signal boundsChanged(x: real, y: real, w: real, h: real) + signal dragFinished + signal moveBy(dx: real, dy: real) + + height: selH + width: selW + x: selX + y: selY + + DragHandler { + id: moveHandler + + property real accumX: 0 + property real accumY: 0 + + target: null + + onActiveChanged: { + accumX = 0; + accumY = 0; + if (!active) + root.dragFinished(); + } + onTranslationChanged: { + const t = moveHandler.translation; + root.moveBy(t.x - accumX, t.y - accumY); + accumX = t.x; + accumY = t.y; + } + } + + Handle { + edge: "tl" + x: -root.hs / 2 + y: -root.hs / 2 + } + + Handle { + edge: "t" + x: root.width / 2 - root.hs / 2 + y: -root.hs / 2 + } + + Handle { + edge: "tr" + x: root.width - root.hs / 2 + y: -root.hs / 2 + } + + Handle { + edge: "r" + x: root.width - root.hs / 2 + y: root.height / 2 - root.hs / 2 + } + + Handle { + edge: "br" + x: root.width - root.hs / 2 + y: root.height - root.hs / 2 + } + + Handle { + edge: "b" + x: root.width / 2 - root.hs / 2 + y: root.height - root.hs / 2 + } + + Handle { + edge: "bl" + x: -root.hs / 2 + y: root.height - root.hs / 2 + } + + Handle { + edge: "l" + x: -root.hs / 2 + y: root.height / 2 - root.hs / 2 + } + + component Handle: Rectangle { + id: handle + + required property string edge + + border.color: root.handleBorder + border.width: 2 + color: root.handleFill + height: root.hs + radius: root.hs / 2 + width: root.hs + z: 10 + + HoverHandler { + cursorShape: { + switch (handle.edge) { + case "tl": + case "br": + return Qt.SizeFDiagCursor; + case "tr": + case "bl": + return Qt.SizeBDiagCursor; + case "t": + case "b": + return Qt.SizeVerCursor; + default: + return Qt.SizeHorCursor; + } + } + } + + DragHandler { + id: dh + + property real startH + property real startW + property real startX + property real startY + + grabPermissions: PointerHandler.CanTakeOverFromAnything | PointerHandler.TakeOverForbidden + target: null + + onActiveChanged: { + if (active) { + startX = root.x; + startY = root.y; + startW = root.width; + startH = root.height; + } else { + root.dragFinished(); + } + } + onTranslationChanged: { + const delta = dh.translation; + const e = handle.edge; + let nx = startX, ny = startY, nw = startW, nh = startH; + + if (e.includes("l")) { + nx = startX + delta.x; + nw = startW - delta.x; + } + if (e.includes("r")) { + nw = startW + delta.x; + } + if (e.includes("t")) { + ny = startY + delta.y; + nh = startH - delta.y; + } + if (e.includes("b")) { + nh = startH + delta.y; + } + + if (nw < root.minSize) { + if (e.includes("l")) + nx = startX + startW - root.minSize; + nw = root.minSize; + } + if (nh < root.minSize) { + if (e.includes("t")) + ny = startY + startH - root.minSize; + nh = root.minSize; + } + + root.boundsChanged(nx, ny, nw, nh); + } + } + } +} diff --git a/Helpers/Players.qml b/Helpers/Players.qml index d67d5f9..21c7148 100644 --- a/Helpers/Players.qml +++ b/Helpers/Players.qml @@ -6,7 +6,7 @@ import Quickshell.Io import Quickshell.Services.Mpris import ZShell import qs.Components -import qs.Config +import ZShell.Config Singleton { id: root @@ -33,7 +33,7 @@ Singleton { function getIdentity(player: MprisPlayer): string { if (!player) return ""; - const alias = Config.services.playerAliases.find(a => a.from === player.identity); + const alias = Config.services.playerAliases.values.find(a => a.from === player.identity); return alias?.to ?? player.identity; } diff --git a/Helpers/SystemInfo.qml b/Helpers/SystemInfo.qml index d0af2a9..cfa980f 100644 --- a/Helpers/SystemInfo.qml +++ b/Helpers/SystemInfo.qml @@ -3,7 +3,7 @@ pragma Singleton import QtQuick import Quickshell import Quickshell.Io -import qs.Config +import ZShell.Config import qs.Paths Singleton { diff --git a/Helpers/TaskbarApps.qml b/Helpers/TaskbarApps.qml index 8f3f78b..829ed15 100644 --- a/Helpers/TaskbarApps.qml +++ b/Helpers/TaskbarApps.qml @@ -3,7 +3,7 @@ pragma Singleton import QtQuick import Quickshell import Quickshell.Wayland -import qs.Config +import ZShell.Config Singleton { id: root diff --git a/Helpers/Time.qml b/Helpers/Time.qml index f7d75f1..551cbff 100644 --- a/Helpers/Time.qml +++ b/Helpers/Time.qml @@ -2,7 +2,7 @@ pragma Singleton import Quickshell import QtQuick -import qs.Config +import ZShell.Config Singleton { id: root @@ -20,7 +20,19 @@ Singleton { readonly property string timeStr: format("hh:mm:ss") function format(fmt: string): string { - return Qt.formatDateTime(clock.date, fmt); + return Qt.formatDateTime(clock.date, resolveFormat(fmt)); + } + + function resolveFormat(fmt: string): string { + if (!Config.services.useTwelveHourClock) + return fmt; + + let f = fmt.replace(/hh/g, "h"); + + if (/h/.test(f) && !/AP|ap/.test(f)) + f += " AP"; + + return f; } SystemClock { diff --git a/Helpers/Updates.qml b/Helpers/Updates.qml index cbb83bd..9281ec7 100644 --- a/Helpers/Updates.qml +++ b/Helpers/Updates.qml @@ -5,7 +5,7 @@ import QtQuick import Quickshell import Quickshell.Io import qs.Paths -import qs.Config +import ZShell.Config Singleton { id: root diff --git a/Helpers/Wallpapers.qml b/Helpers/Wallpapers.qml index 1e12dcc..1334f06 100644 --- a/Helpers/Wallpapers.qml +++ b/Helpers/Wallpapers.qml @@ -5,7 +5,7 @@ import Quickshell import Quickshell.Io import QtQuick import ZShell.Models -import qs.Config +import ZShell.Config import qs.Modules import qs.Helpers import qs.Paths diff --git a/Helpers/Weather.qml b/Helpers/Weather.qml index d0d47ce..ecf5e80 100644 --- a/Helpers/Weather.qml +++ b/Helpers/Weather.qml @@ -3,7 +3,7 @@ pragma Singleton import QtQuick import Quickshell import ZShell -import qs.Config +import ZShell.Config Singleton { id: root diff --git a/Modules/Bar/Bar.qml b/Modules/Bar/Bar.qml index 146897d..75fc616 100644 --- a/Modules/Bar/Bar.qml +++ b/Modules/Bar/Bar.qml @@ -4,24 +4,25 @@ import Quickshell import QtQuick import QtQuick.Layouts import qs.Modules -import qs.Config +import ZShell.Config import qs.Modules.SysTray import qs.Modules.Updates RowLayout { id: root + required property bool fullscreen required property Wrapper popouts required property ClipWrapper popoutsWrapper required property ShellScreen screen - required property bool fullscreen readonly property int vPadding: 6 required property PersistentProperties visibilities function checkPopout(x: real): void { - const ch = childAt(x, height / 2) as WrappedLoader; + const ch = childAt(x, height / 2) as EntryWrapper; + const id = ch?.entryId; - if (!ch || ch?.id === "spacer") { + if (!ch || id === undefined) { if (!popouts.currentName.startsWith("traymenu") || Config.bar.tray.showOnHover) popouts.hasCurrent = false; return; @@ -30,42 +31,50 @@ RowLayout { if (visibilities.sidebar || visibilities.dashboard || visibilities.resources || visibilities.settings) return; - if (ch.id === "tray") { - const tray = ch.item; - const localPos = tray.mapFromItem(root, x, height / 2); - const sub = tray.getHoveredSubItem(localPos.x, localPos.y); - if (sub) { - popouts.currentName = sub.id; + if (id === "statusIcons" && Config.bar.popouts.statusIcons) { + const items = (ch.item as StatusIcons).items; + const localX = mapToItem(items, x, 0).x; + const icon = items.childAt(localX, items.height / 2); + if (icon) { + popouts.currentName = icon.name; + popouts.currentCenter = Qt.binding(() => icon.mapToItem(root, icon.implicitWidth / 2, 0).x); + popouts.hasCurrent = true; + } + } else if (id === "tray" && Config.bar.popouts.tray && Config.bar.tray.showOnHover) { + const tray = ch.item as TrayIcons; + const layout = tray.layout; + const localX = mapToItem(layout, x, 0).x; + const trayItem = layout.childAt(localX, layout.height / 2); + + if (trayItem) { + const idx = trayItem.index; + popouts.currentName = `traymenu${idx}`; popouts.currentCenter = Qt.binding(() => { - const centerX = sub.item.mapToItem(root, sub.item.width / 2, 0).x; - return centerX; + const it = tray.items.itemAt(idx); + return it ? it.mapToItem(root, it.implicitWidth / 2, 0).x : popouts.currentCenter; }); popouts.hasCurrent = true; - return; } - if (!popouts.currentName.startsWith("traymenu") || Config.bar.tray.showOnHover) + if (!popouts.currentName.startsWith("traymenu")) popouts.hasCurrent = false; } - const id = ch.id; - const top = ch.x; - const item = ch.item; - const itemWidth = item.implicitWidth; - if (id === "updates") { popouts.currentName = "updates"; - popouts.currentCenter = Qt.binding(() => item.mapToItem(root, itemWidth / 2, 0).x); + popouts.currentCenter = Qt.binding(() => ch.item.mapToItem(root, (ch.item as Item).implicitWidth / 2, 0).x); popouts.hasCurrent = true; } } - spacing: Appearance.spacing.small + spacing: Tokens.spacing.small Repeater { id: repeater - model: Config.bar.entries + model: ScriptModel { + values: Config.bar.entries.values.filter(e => e.enabled) + } DelegateChooser { role: "id" @@ -73,8 +82,8 @@ RowLayout { DelegateChoice { roleValue: "hyprsunset" - delegate: WrappedLoader { - sourceComponent: HyprsunsetWidget { + delegate: EntryWrapper { + HyprsunsetWidget { visible: !root.fullscreen } } @@ -83,7 +92,7 @@ RowLayout { DelegateChoice { roleValue: "spacer" - delegate: WrappedLoader { + delegate: EntryWrapper { Layout.fillWidth: true } } @@ -91,8 +100,8 @@ RowLayout { DelegateChoice { roleValue: "workspaces" - delegate: WrappedLoader { - sourceComponent: Workspaces { + delegate: EntryWrapper { + Workspaces { screen: root.screen visible: !root.fullscreen } @@ -102,8 +111,8 @@ RowLayout { DelegateChoice { roleValue: "tray" - delegate: WrappedLoader { - sourceComponent: TrayWidget { + delegate: EntryWrapper { + TrayIcons { loader: root popouts: root.popouts visible: !root.fullscreen @@ -111,11 +120,20 @@ RowLayout { } } + DelegateChoice { + roleValue: "statusIcons" + + delegate: EntryWrapper { + StatusIcons { + } + } + } + DelegateChoice { roleValue: "resources" - delegate: WrappedLoader { - sourceComponent: Resources { + delegate: EntryWrapper { + Resources { visibilities: root.visibilities visible: !root.fullscreen } @@ -125,8 +143,8 @@ RowLayout { DelegateChoice { roleValue: "updates" - delegate: WrappedLoader { - sourceComponent: UpdatesWidget { + delegate: EntryWrapper { + UpdatesWidget { visible: !root.fullscreen } } @@ -135,8 +153,8 @@ RowLayout { DelegateChoice { roleValue: "notifBell" - delegate: WrappedLoader { - sourceComponent: NotifBell { + delegate: EntryWrapper { + NotifBell { popouts: root.popouts visibilities: root.visibilities visible: !root.fullscreen @@ -147,8 +165,8 @@ RowLayout { DelegateChoice { roleValue: "clock" - delegate: WrappedLoader { - sourceComponent: Clock { + delegate: EntryWrapper { + Clock { loader: root popouts: root.popouts visibilities: root.visibilities @@ -160,8 +178,8 @@ RowLayout { DelegateChoice { roleValue: "activeWindow" - delegate: WrappedLoader { - sourceComponent: WindowTitle { + delegate: EntryWrapper { + WindowTitle { bar: root visible: !root.fullscreen } @@ -171,8 +189,8 @@ RowLayout { DelegateChoice { roleValue: "media" - delegate: WrappedLoader { - sourceComponent: MediaWidget { + delegate: EntryWrapper { + MediaWidget { visible: !root.fullscreen } } @@ -180,34 +198,17 @@ RowLayout { } } - component WrappedLoader: Loader { - required property bool enabled - required property string id + component EntryWrapper: Item { + readonly property string entryId: modelData.id required property int index - - function findFirstEnabled(): Item { - const count = repeater.count; - for (let i = 0; i < count; i++) { - const item = repeater.itemAt(i); - if (item?.enabled) - return item; - } - return null; - } - - function findLastEnabled(): Item { - for (let i = repeater.count - 1; i >= 0; i--) { - const item = repeater.itemAt(i); - if (item?.enabled) - return item; - } - return null; - } + default property Item item + required property var modelData Layout.alignment: Qt.AlignVCenter - Layout.leftMargin: findFirstEnabled() === this ? root.vPadding : 0 - Layout.rightMargin: findLastEnabled() === this ? root.vPadding : 0 - active: enabled - visible: enabled + Layout.leftMargin: index === 0 ? root.vPadding : (entryId === "statusIcons") ? -root.spacing + Tokens.spacing.extraSmall : 0 + Layout.rightMargin: index === repeater.count - 1 ? root.vPadding : 0 + children: item + implicitHeight: item?.implicitHeight ?? 0 + implicitWidth: item?.implicitWidth ?? 0 } } diff --git a/Modules/Bar/BarLoader.qml b/Modules/Bar/BarLoader.qml index c20d7af..bec6c54 100644 --- a/Modules/Bar/BarLoader.qml +++ b/Modules/Bar/BarLoader.qml @@ -6,7 +6,7 @@ import QtQuick import QtQuick.Layouts import qs.Components import qs.Modules -import qs.Config +import ZShell.Config import qs.Helpers import qs.Modules.SysTray import qs.Modules.SysTray.Widgets @@ -18,7 +18,7 @@ Item { readonly property int exclusiveZone: Config.bar.autoHide ? Config.bar.border : contentHeight required property bool fullscreen property bool isHovered - readonly property int padding: Math.max(Appearance.padding.smaller, Config.bar.border) + readonly property int padding: Math.max(Tokens.padding.smaller, Config.bar.border) required property Wrapper popouts required property ClipWrapper popoutsWrapper required property ShellScreen screen @@ -47,8 +47,6 @@ Item { to: "visible" Anim { - duration: MaterialEasing.expressiveEffectsTime - easing.bezierCurve: MaterialEasing.expressiveEffects property: "implicitHeight" target: root } @@ -58,8 +56,6 @@ Item { to: "" Anim { - duration: MaterialEasing.expressiveEffectsTime - easing.bezierCurve: MaterialEasing.expressiveEffects property: "implicitHeight" target: root } diff --git a/Modules/Bar/Border.qml b/Modules/Bar/Border.qml index 5257d31..c67fa45 100644 --- a/Modules/Bar/Border.qml +++ b/Modules/Bar/Border.qml @@ -3,8 +3,9 @@ pragma ComponentBehavior: Bound import Quickshell import QtQuick import QtQuick.Effects -import qs.Config +import ZShell.Config import qs.Components +import qs.Services Item { id: root @@ -17,7 +18,7 @@ Item { CustomRect { anchors.fill: parent anchors.margins: -1 - color: DynamicColors.palette.m3surface + color: Colors.palette.m3surface layer.enabled: true layer.effect: MultiEffect { diff --git a/Modules/ClipWrapper.qml b/Modules/ClipWrapper.qml index 10fbd82..cf6f057 100644 --- a/Modules/ClipWrapper.qml +++ b/Modules/ClipWrapper.qml @@ -3,7 +3,7 @@ pragma ComponentBehavior: Bound import QtQuick import Quickshell import qs.Components -import qs.Config +import ZShell.Config Item { id: root diff --git a/Modules/Clipboard/Content.qml b/Modules/Clipboard/Content.qml index 152c552..b364e32 100644 --- a/Modules/Clipboard/Content.qml +++ b/Modules/Clipboard/Content.qml @@ -6,7 +6,8 @@ import QtQuick.Controls import QtQuick.Layouts import qs.Components import qs.Helpers -import qs.Config +import ZShell.Config +import qs.Services Item { id: root @@ -30,9 +31,9 @@ Item { anchors.left: parent.left anchors.right: entries.right anchors.top: parent.top - color: DynamicColors.tPalette.m3surfaceContainer + color: Colors.tPalette.m3surfaceContainer implicitHeight: 50 - radius: Appearance.rounding.full + radius: Tokens.rounding.full SearchBar { id: searchField @@ -41,7 +42,7 @@ Item { anchors.left: parent.left anchors.right: parent.right anchors.top: parent.top - color: DynamicColors.palette.m3onSurface + color: Colors.palette.m3onSurface placeholderText: "Search clipboard history..." Keys.onDownPressed: view.incrementCurrentIndex() @@ -58,10 +59,10 @@ Item { anchors.bottom: parent.bottom anchors.left: entries.right - anchors.leftMargin: Appearance.spacing.normal + anchors.leftMargin: Tokens.spacing.normal anchors.top: parent.top - color: DynamicColors.tPalette.m3surfaceContainer - implicitWidth: ClipHistory.previewIsImage ? Math.max(Math.min(imagePreview.sourceSize.width + Appearance.padding.large * 2, Config.clipboard.sizes.previewWidth), Config.clipboard.sizes.minPreviewWidth) : Math.max(Math.min(textPreviewColumn.width + textPreviewColumn.anchors.margins * 2, Config.clipboard.sizes.previewWidth), Config.clipboard.sizes.minPreviewWidth) + color: Colors.tPalette.m3surfaceContainer + implicitWidth: ClipHistory.previewIsImage ? Math.max(Math.min(imagePreview.sourceSize.width + Tokens.padding.large * 2, Config.clipboard.sizes.previewWidth), Config.clipboard.sizes.minPreviewWidth) : Math.max(Math.min(textPreviewColumn.width + textPreviewColumn.anchors.margins * 2, Config.clipboard.sizes.previewWidth), Config.clipboard.sizes.minPreviewWidth) radius: 25 Behavior on implicitWidth { @@ -74,7 +75,7 @@ Item { anchors.left: parent.left anchors.leftMargin: 0 - anchors.margins: Appearance.padding.normal + anchors.margins: Tokens.padding.normal anchors.top: parent.top visible: !ClipHistory.previewIsImage @@ -89,21 +90,21 @@ Item { required property int index required property var modelData - spacing: Appearance.spacing.normal + spacing: Tokens.spacing.normal CustomRect { - color: lineRow.index % 2 ? DynamicColors.tPalette.m3surfaceContainer : "transparent" - implicitHeight: lineText.paintedHeight + Appearance.padding.extraSmall * 2 + color: lineRow.index % 2 ? Colors.tPalette.m3surfaceContainer : "transparent" + implicitHeight: lineText.paintedHeight + Tokens.padding.extraSmall * 2 implicitWidth: 50 CustomText { id: number - anchors.margins: Appearance.padding.large + anchors.margins: Tokens.padding.large anchors.right: parent.right anchors.verticalCenter: parent.verticalCenter - color: DynamicColors.palette.m3onSurfaceVariant - font.pointSize: Appearance.font.size.small + color: Colors.palette.m3onSurfaceVariant + font.pointSize: Tokens.font.size.small text: lineRow.modelData.line } } @@ -113,7 +114,7 @@ Item { RowLayout { height: lineText.height - width: lineText.height + Appearance.spacing.extraSmall + width: lineText.height + Tokens.spacing.extraSmall Item { Layout.fillHeight: true @@ -121,10 +122,10 @@ Item { CustomRect { anchors.centerIn: parent - color: DynamicColors.tPalette.m3surfaceContainer + color: Colors.tPalette.m3surfaceContainer implicitHeight: parent.height / 8 implicitWidth: parent.height / 8 - radius: Appearance.rounding.full + radius: Tokens.rounding.full } } @@ -134,10 +135,10 @@ Item { CustomRect { anchors.centerIn: parent - color: DynamicColors.tPalette.m3surfaceContainer + color: Colors.tPalette.m3surfaceContainer implicitHeight: parent.height / 8 implicitWidth: parent.height / 8 - radius: Appearance.rounding.full + radius: Tokens.rounding.full } } @@ -147,10 +148,10 @@ Item { CustomRect { anchors.centerIn: parent - color: DynamicColors.tPalette.m3surfaceContainer + color: Colors.tPalette.m3surfaceContainer implicitHeight: parent.height / 8 implicitWidth: parent.height / 8 - radius: Appearance.rounding.full + radius: Tokens.rounding.full } } } @@ -159,8 +160,8 @@ Item { CustomText { id: lineText - color: DynamicColors.palette.m3onSurface - height: lineText.paintedHeight + Appearance.padding.extraSmall * 2 + color: Colors.palette.m3onSurface + height: lineText.paintedHeight + Tokens.padding.extraSmall * 2 text: lineRow.modelData.text.trim() verticalAlignment: Text.AlignVCenter wrapMode: Text.Wrap @@ -191,7 +192,7 @@ Item { anchors.bottom: parent.bottom anchors.left: parent.left anchors.top: search.bottom - anchors.topMargin: Appearance.spacing.normal + anchors.topMargin: Tokens.spacing.normal implicitWidth: Config.clipboard.sizes.width CustomListView { @@ -203,7 +204,7 @@ Item { highlightRangeMode: ListView.ApplyRange preferredHighlightBegin: 0 preferredHighlightEnd: height - spacing: Appearance.spacing.normal + spacing: Tokens.spacing.normal CustomScrollBar.vertical: CustomScrollBar { flickable: view @@ -217,7 +218,7 @@ Item { implicitHeight: root.itemHeight implicitWidth: view.width - radius: textLayer.pressed ? (Appearance.rounding.small / 2) : Appearance.rounding.small + radius: textLayer.pressed ? (Tokens.rounding.small / 2) : Tokens.rounding.small Behavior on radius { Anim { @@ -227,7 +228,7 @@ Item { RowLayout { anchors.fill: parent - spacing: Appearance.spacing.small + spacing: Tokens.spacing.small CustomClippingRect { id: textRect @@ -249,9 +250,9 @@ Item { id: icon anchors.left: parent.left - anchors.margins: Appearance.padding.normal + anchors.margins: Tokens.padding.normal anchors.verticalCenter: parent.verticalCenter - font.pointSize: Appearance.font.size.large + font.pointSize: Tokens.font.size.large text: clipItem.isImage ? "image" : "text_fields" } @@ -259,7 +260,7 @@ Item { id: text anchors.left: icon.right - anchors.margins: Appearance.spacing.normal + anchors.margins: Tokens.spacing.normal anchors.verticalCenter: parent.verticalCenter elide: Text.ElideRight text: clipItem.isImage ? qsTr("Image") : ClipHistory.displayText(clipItem.modelData) @@ -291,11 +292,11 @@ Item { IconButton { Layout.fillHeight: true - Layout.margins: Appearance.padding.normal + Layout.margins: Tokens.padding.normal Layout.preferredWidth: height icon: "delete" - inactiveColor: Qt.alpha(DynamicColors.palette.m3error, 0.8) - inactiveOnColor: DynamicColors.palette.m3onError + inactiveColor: Qt.alpha(Colors.palette.m3error, 0.8) + inactiveOnColor: Colors.palette.m3onError isToggle: false onClicked: ClipHistory.deleteEntry(clipItem.modelData) @@ -309,17 +310,17 @@ Item { } } highlight: CustomRect { - color: DynamicColors.palette.m3onSurface + color: Colors.palette.m3onSurface implicitHeight: view.currentItem?.height ?? 0 implicitWidth: view.width opacity: 0.08 - radius: Appearance.rounding.small + radius: Tokens.rounding.small y: view.currentItem?.y ?? 0 Behavior on y { Anim { - duration: Appearance.anim.durations.small - easing.bezierCurve: Appearance.anim.curves.expressiveEffects + duration: Tokens.anim.durations.small + easing.bezierCurve: Tokens.anim.curves.expressiveEffects } } } @@ -341,7 +342,7 @@ Item { CustomClippingWrapperRect { anchors.fill: parent child: view.contentItem - radius: Appearance.rounding.small + radius: Tokens.rounding.small } } } diff --git a/Modules/Clipboard/Wrapper.qml b/Modules/Clipboard/Wrapper.qml index fff295e..c9fe3a4 100644 --- a/Modules/Clipboard/Wrapper.qml +++ b/Modules/Clipboard/Wrapper.qml @@ -3,7 +3,7 @@ pragma ComponentBehavior: Bound import Quickshell import QtQuick import qs.Components -import qs.Config +import ZShell.Config Item { id: root @@ -15,15 +15,15 @@ Item { required property PersistentProperties visibilities anchors.bottomMargin: (-implicitHeight - 5) * offsetScale - implicitHeight: content.implicitHeight + Appearance.padding.normal * 2 - implicitWidth: content.implicitWidth + Appearance.padding.normal * 2 || 400 + implicitHeight: content.implicitHeight + Tokens.padding.normal * 2 + implicitWidth: content.implicitWidth + Tokens.padding.normal * 2 || 400 opacity: 1 - offsetScale visible: offsetScale < 1 Behavior on offsetScale { Anim { - duration: Appearance.anim.durations.expressiveDefaultSpatial - easing.bezierCurve: Appearance.anim.curves.expressiveDefaultSpatial + duration: Tokens.anim.durations.expressiveDefaultSpatial + easing.bezierCurve: Tokens.anim.curves.expressiveDefaultSpatial } } diff --git a/Modules/Clock.qml b/Modules/Clock.qml index fb668c0..f96fe16 100644 --- a/Modules/Clock.qml +++ b/Modules/Clock.qml @@ -1,10 +1,11 @@ import Quickshell import QtQuick import QtQuick.Layouts -import qs.Config +import ZShell.Config import qs.Modules import qs.Helpers import qs.Components +import qs.Services CustomRect { id: root @@ -13,17 +14,17 @@ CustomRect { required property Wrapper popouts required property PersistentProperties visibilities - color: visibilities.dashboard ? DynamicColors.palette.m3primary : DynamicColors.tPalette.m3surfaceContainer - implicitHeight: Config.bar.height + Appearance.padding.smallest * 2 - implicitWidth: timeText.contentWidth + Appearance.padding.normal * 2 - radius: Appearance.rounding.full + color: visibilities.dashboard ? Colors.palette.m3primary : Colors.tPalette.m3surfaceContainer + implicitHeight: Config.bar.height + Tokens.padding.smallest * 2 + implicitWidth: timeText.contentWidth + Tokens.padding.normal * 2 + radius: Tokens.rounding.full CustomText { id: timeText anchors.centerIn: parent - color: root.visibilities.dashboard ? DynamicColors.palette.m3onPrimary : DynamicColors.palette.m3onSurface - font: Appearance.font.family.mono // qmllint disable incompatible-type + color: root.visibilities.dashboard ? Colors.palette.m3onPrimary : Colors.palette.m3onSurface + font: Config.appearance.font.family.mono text: Time.dateStr Behavior on color { @@ -34,7 +35,7 @@ CustomRect { StateLayer { acceptedButtons: Qt.LeftButton - color: root.visibilities.dashboard ? DynamicColors.palette.m3onPrimary : DynamicColors.palette.m3onSurface + color: root.visibilities.dashboard ? Colors.palette.m3onPrimary : Colors.palette.m3onSurface onClicked: { root.visibilities.dashboard = !root.visibilities.dashboard; diff --git a/Modules/Content.qml b/Modules/Content.qml index d59852a..b536bb9 100644 --- a/Modules/Content.qml +++ b/Modules/Content.qml @@ -3,7 +3,7 @@ pragma ComponentBehavior: Bound import Quickshell import Quickshell.Services.SystemTray import QtQuick -import qs.Config +import ZShell.Config import qs.Components import qs.Modules.WSOverview import qs.Modules.SysTray.Popouts @@ -16,8 +16,8 @@ Item { readonly property Popout currentPopout: content.children.find(c => c.shouldBeActive) ?? null required property PopoutState popouts - implicitHeight: (currentPopout?.implicitHeight ?? 0) + Appearance.padding.small * 2 - implicitWidth: (currentPopout?.implicitWidth ?? 0) + Appearance.padding.small * 2 + implicitHeight: (currentPopout?.implicitHeight ?? 0) + Tokens.padding.small * 2 + implicitWidth: (currentPopout?.implicitWidth ?? 0) + Tokens.padding.small * 2 Item { id: content @@ -130,7 +130,6 @@ Item { SequentialAnimation { Anim { - duration: MaterialEasing.expressiveEffectsTime properties: "opacity,scale" } diff --git a/Modules/Dashboard/Content.qml b/Modules/Dashboard/Content.qml index 4678257..1bc0ca1 100644 --- a/Modules/Dashboard/Content.qml +++ b/Modules/Dashboard/Content.qml @@ -4,7 +4,7 @@ import Quickshell import Quickshell.Widgets import QtQuick import QtQuick.Layouts -import qs.Config +import ZShell.Config import qs.Components Item { @@ -20,14 +20,10 @@ Item { Behavior on implicitHeight { Anim { - duration: MaterialEasing.expressiveEffectsTime - easing.bezierCurve: MaterialEasing.expressiveEffects } } Behavior on implicitWidth { Anim { - duration: MaterialEasing.expressiveEffectsTime - easing.bezierCurve: MaterialEasing.expressiveEffects } } @@ -36,11 +32,11 @@ Item { anchors.bottom: parent.bottom anchors.left: parent.left - anchors.margins: Appearance.padding.smaller + anchors.margins: Tokens.padding.smaller anchors.right: parent.right anchors.top: parent.top color: "transparent" - radius: Appearance.rounding.normal - anchors.margins + radius: Tokens.rounding.normal - anchors.margins Item { id: view diff --git a/Modules/Dashboard/Dash.qml b/Modules/Dashboard/Dash.qml index 56066cb..998362d 100644 --- a/Modules/Dashboard/Dash.qml +++ b/Modules/Dashboard/Dash.qml @@ -4,19 +4,20 @@ import QtQuick.Layouts import qs.Helpers import qs.Components import qs.Modules -import qs.Config +import ZShell.Config import qs.Modules.Dashboard.Dash +import qs.Services GridLayout { id: root required property PersistentProperties dashState readonly property bool dashboardVisible: visibilities.dashboard - property int radius: Appearance.rounding.smallest + property int radius: Tokens.rounding.smallest required property PersistentProperties visibilities - columnSpacing: Appearance.spacing.smaller - rowSpacing: Appearance.spacing.smaller + columnSpacing: Tokens.spacing.smaller + rowSpacing: Tokens.spacing.smaller ParallelAnimation { id: openAnim @@ -117,6 +118,6 @@ GridLayout { } component Rect: CustomRect { - color: DynamicColors.tPalette.m3surfaceContainer + color: Colors.tPalette.m3surfaceContainer } } diff --git a/Modules/Dashboard/Dash/Calendar.qml b/Modules/Dashboard/Dash/Calendar.qml index 37a283b..daace24 100644 --- a/Modules/Dashboard/Dash/Calendar.qml +++ b/Modules/Dashboard/Dash/Calendar.qml @@ -5,7 +5,8 @@ import QtQuick import QtQuick.Controls import QtQuick.Layouts import qs.Components -import qs.Config +import ZShell.Config +import qs.Services CustomMouseArea { id: root @@ -120,18 +121,18 @@ CustomMouseArea { id: inner anchors.fill: parent - anchors.margins: Appearance.padding.large - spacing: Appearance.spacing.extraSmall + anchors.margins: Tokens.padding.large + spacing: Tokens.spacing.extraSmall RowLayout { id: monthNavigationRow Layout.fillWidth: true - spacing: Appearance.spacing.extraSmall + spacing: Tokens.spacing.extraSmall IconButton { icon: "chevron_left" - padding: Appearance.padding.small + padding: Tokens.padding.small type: IconButton.Text onClicked: root.dashState.currentDate = new Date(root.realCurrYear, root.realCurrMonth - 1, 1) @@ -140,16 +141,16 @@ CustomMouseArea { Item { Layout.fillHeight: true Layout.fillWidth: true - implicitHeight: monthYearDisplay1.implicitHeight + Appearance.padding.extraSmall * 2 - implicitWidth: monthYearDisplay1.implicitWidth + Appearance.padding.large * 2 + implicitHeight: monthYearDisplay1.implicitHeight + Tokens.padding.extraSmall * 2 + implicitWidth: monthYearDisplay1.implicitWidth + Tokens.padding.large * 2 StateLayer { - color: DynamicColors.palette.m3primary + color: Colors.palette.m3primary enabled: { const now = new Date(); return root.realCurrMonth !== now.getMonth() || root.realCurrYear !== now.getFullYear(); } - radius: pressed ? Appearance.rounding.small : Appearance.rounding.large + radius: pressed ? Tokens.rounding.small : Tokens.rounding.large Behavior on radius { Anim { @@ -171,7 +172,7 @@ CustomMouseArea { anchors.centerIn: parent // qmllint enable missing-property - color: DynamicColors.palette.m3primary + color: Colors.palette.m3primary // qmllint disable missing-property text: grid1.item ? grid1.item.title : "" @@ -187,7 +188,7 @@ CustomMouseArea { anchors.centerIn: parent // qmllint enable missing-property - color: DynamicColors.palette.m3primary + color: Colors.palette.m3primary // qmllint disable missing-property text: grid2.item ? grid2.item.title : "" @@ -202,7 +203,7 @@ CustomMouseArea { IconButton { icon: "chevron_right" - padding: Appearance.padding.small + padding: Tokens.padding.small type: IconButton.Text onClicked: root.dashState.currentDate = new Date(root.realCurrYear, root.realCurrMonth + 1, 1) @@ -218,7 +219,7 @@ CustomMouseArea { delegate: CustomText { required property var model - color: (model.day === 0) ? DynamicColors.palette.m3tertiary : DynamicColors.palette.m3onSurface + color: (model.day === 0) ? Colors.palette.m3tertiary : Colors.palette.m3onSurface horizontalAlignment: Text.AlignHCenter text: Qt.locale("en_US").standaloneDayName(model.day, Locale.ShortFormat) } @@ -258,7 +259,7 @@ CustomMouseArea { required property var model - implicitHeight: text.implicitHeight + Appearance.padding.normal * 2 + implicitHeight: text.implicitHeight + Tokens.padding.normal * 2 implicitWidth: implicitHeight CustomText { @@ -268,9 +269,9 @@ CustomMouseArea { color: { const dayOfWeek = dayItem.model.date.getDay(); if (dayOfWeek === 0) - return DynamicColors.palette.m3tertiary; + return Colors.palette.m3tertiary; - return DynamicColors.palette.m3onSurfaceVariant; + return Colors.palette.m3onSurfaceVariant; } horizontalAlignment: Text.AlignHCenter opacity: dayItem.model.today || dayItem.model.month === internalGrid.month ? 1 : 0.4 @@ -286,14 +287,14 @@ CustomMouseArea { readonly property Item todayItem: internalGrid.contentItem.children.find(c => c.model.today) ?? null clip: true - color: DynamicColors.palette.m3primary + color: Colors.palette.m3primary implicitHeight: width - implicitWidth: today ? (Math.max(today.implicitWidth, today.implicitHeight) - Appearance.padding.extraSmall) : 0 + implicitWidth: today ? (Math.max(today.implicitWidth, today.implicitHeight) - Tokens.padding.extraSmall) : 0 opacity: todayItem ? 1 : 0 - radius: Appearance.rounding.full + radius: Tokens.rounding.full scale: todayItem ? 1 : 0.7 x: today ? today.x + (today.width - implicitWidth) / 2 : 0 - y: today ? today.y + Appearance.padding.extraSmall / 2 : 0 + y: today ? today.y + Tokens.padding.extraSmall / 2 : 0 Behavior on opacity { Anim { @@ -320,11 +321,11 @@ CustomMouseArea { } Coloriser { - colorizationColor: DynamicColors.palette.m3onPrimary + colorizationColor: Colors.palette.m3onPrimary implicitHeight: internalGrid.height implicitWidth: internalGrid.width source: internalGrid - sourceColor: DynamicColors.palette.m3onSurface + sourceColor: Colors.palette.m3onSurface x: -todayIndicator.x y: -todayIndicator.y } diff --git a/Modules/Dashboard/Dash/DateTime.qml b/Modules/Dashboard/Dash/DateTime.qml index 3f95bd9..3a76d5c 100644 --- a/Modules/Dashboard/Dash/DateTime.qml +++ b/Modules/Dashboard/Dash/DateTime.qml @@ -3,8 +3,9 @@ pragma ComponentBehavior: Bound import QtQuick import QtQuick.Layouts import qs.Components -import qs.Config +import ZShell.Config import qs.Helpers +import qs.Services Item { id: root @@ -22,7 +23,7 @@ Item { CustomText { Layout.alignment: Qt.AlignHCenter Layout.bottomMargin: -(font.pointSize * 0.4) - color: DynamicColors.palette.m3secondary + color: Colors.palette.m3secondary font.family: "Rubik" font.pointSize: 18 font.weight: 600 @@ -31,7 +32,7 @@ Item { CustomText { Layout.alignment: Qt.AlignHCenter - color: DynamicColors.palette.m3primary + color: Colors.palette.m3primary font.family: "Rubik" font.pointSize: 18 * 0.9 text: "•••" @@ -40,7 +41,7 @@ Item { CustomText { Layout.alignment: Qt.AlignHCenter Layout.topMargin: -(font.pointSize * 0.4) - color: DynamicColors.palette.m3secondary + color: Colors.palette.m3secondary font.family: "Rubik" font.pointSize: 18 font.weight: 600 diff --git a/Modules/Dashboard/Dash/Media.qml b/Modules/Dashboard/Dash/Media.qml index 3dba6e8..67a2384 100644 --- a/Modules/Dashboard/Dash/Media.qml +++ b/Modules/Dashboard/Dash/Media.qml @@ -6,10 +6,11 @@ import QtQuick.Layouts import QtQuick.Shapes import QtQuick.Effects import ZShell.Services +import ZShell.Config import qs.Daemons import qs.Components -import qs.Config import qs.Helpers +import qs.Services Item { id: root @@ -18,7 +19,7 @@ Item { const active = Players.active; return active?.length ? (active.position % active.length) / active.length : 0; } - property int rowHeight: Appearance.padding.large + Config.dashboard.sizes.mediaProgressThickness + Appearance.spacing.small + property int rowHeight: Tokens.padding.large + Config.dashboard.sizes.mediaProgressThickness + Tokens.spacing.small anchors.left: parent.left anchors.right: parent.right @@ -26,7 +27,7 @@ Item { Behavior on playerProgress { Anim { - duration: Appearance.anim.durations.large + duration: Tokens.anim.durations.large } } @@ -47,7 +48,7 @@ Item { id: visualizer readonly property int bars: Config.services.visualizerBars - property color color: DynamicColors.palette.m3tertiary + property color color: Colors.palette.m3tertiary property color fillColor: Qt.alpha(color, 0.25) anchors.fill: layout @@ -117,7 +118,7 @@ Item { CustomRect { anchors.fill: visualizer - color: Qt.alpha(DynamicColors.palette.m3shadow, 0.2) + color: Qt.alpha(Colors.palette.m3shadow, 0.2) layer.enabled: true layer.effect: MultiEffect { maskEnabled: true @@ -129,9 +130,9 @@ Item { preferredRendererType: Shape.CurveRenderer ShapePath { - capStyle: Appearance.rounding.scale === 0 ? ShapePath.SquareCap : ShapePath.RoundCap + capStyle: Tokens.rounding.scale === 0 ? ShapePath.SquareCap : ShapePath.RoundCap fillColor: "transparent" - strokeColor: DynamicColors.layer(DynamicColors.palette.m3surfaceContainerHigh, 2) + strokeColor: Colors.layer(Colors.palette.m3surfaceContainerHigh, 2) strokeWidth: Config.dashboard.sizes.mediaProgressThickness Behavior on strokeColor { @@ -142,17 +143,17 @@ Item { PathAngleArc { centerX: cover.x + cover.width / 2 centerY: cover.y + cover.height / 2 - radiusX: (cover.width + Config.dashboard.sizes.mediaProgressThickness) / 2 + Appearance.spacing.small - radiusY: (cover.height + Config.dashboard.sizes.mediaProgressThickness) / 2 + Appearance.spacing.small + radiusX: (cover.width + Config.dashboard.sizes.mediaProgressThickness) / 2 + Tokens.spacing.small + radiusY: (cover.height + Config.dashboard.sizes.mediaProgressThickness) / 2 + Tokens.spacing.small startAngle: -90 - Config.dashboard.sizes.mediaProgressSweep / 2 sweepAngle: Config.dashboard.sizes.mediaProgressSweep } } ShapePath { - capStyle: Appearance.rounding.scale === 0 ? ShapePath.SquareCap : ShapePath.RoundCap + capStyle: Tokens.rounding.scale === 0 ? ShapePath.SquareCap : ShapePath.RoundCap fillColor: "transparent" - strokeColor: DynamicColors.palette.m3primary + strokeColor: Colors.palette.m3primary strokeWidth: Config.dashboard.sizes.mediaProgressThickness Behavior on strokeColor { @@ -163,8 +164,8 @@ Item { PathAngleArc { centerX: cover.x + cover.width / 2 centerY: cover.y + cover.height / 2 - radiusX: (cover.width + Config.dashboard.sizes.mediaProgressThickness) / 2 + Appearance.spacing.small - radiusY: (cover.height + Config.dashboard.sizes.mediaProgressThickness) / 2 + Appearance.spacing.small + radiusX: (cover.width + Config.dashboard.sizes.mediaProgressThickness) / 2 + Tokens.spacing.small + radiusY: (cover.height + Config.dashboard.sizes.mediaProgressThickness) / 2 + Tokens.spacing.small startAngle: -90 - Config.dashboard.sizes.mediaProgressSweep / 2 sweepAngle: Config.dashboard.sizes.mediaProgressSweep * root.playerProgress } @@ -182,17 +183,17 @@ Item { id: cover Layout.alignment: Qt.AlignLeft - Layout.bottomMargin: Appearance.padding.large + Config.dashboard.sizes.mediaProgressThickness + Appearance.spacing.small - Layout.leftMargin: Appearance.padding.large + Config.dashboard.sizes.mediaProgressThickness + Appearance.spacing.small + Layout.bottomMargin: Tokens.padding.large + Config.dashboard.sizes.mediaProgressThickness + Tokens.spacing.small + Layout.leftMargin: Tokens.padding.large + Config.dashboard.sizes.mediaProgressThickness + Tokens.spacing.small Layout.preferredHeight: Config.dashboard.sizes.mediaCoverArtSize Layout.preferredWidth: Config.dashboard.sizes.mediaCoverArtSize - Layout.topMargin: Appearance.padding.large + Config.dashboard.sizes.mediaProgressThickness + Appearance.spacing.small - color: DynamicColors.tPalette.m3surfaceContainerHigh + Layout.topMargin: Tokens.padding.large + Config.dashboard.sizes.mediaProgressThickness + Tokens.spacing.small + color: Colors.tPalette.m3surfaceContainerHigh radius: Infinity MaterialIcon { anchors.centerIn: parent - color: DynamicColors.palette.m3onSurfaceVariant + color: Colors.palette.m3onSurfaceVariant font.pointSize: (parent.width * 0.4) || 1 grade: 200 text: "art_track" @@ -219,12 +220,12 @@ Item { anchors.horizontalCenter: parent.horizontalCenter anchors.top: parent.top - color: DynamicColors.palette.m3primary - font.pointSize: Appearance.font.size.normal + color: Colors.palette.m3primary + font.pointSize: Tokens.font.size.normal horizontalAlignment: Text.AlignHCenter pauseMs: 4000 text: (Players.active?.trackTitle ?? qsTr("No media")) || qsTr("Unknown title") - width: parent.width - Appearance.padding.large * 4 + width: parent.width - Tokens.padding.large * 4 } MarqueeText { @@ -232,13 +233,13 @@ Item { anchors.horizontalCenter: parent.horizontalCenter anchors.top: title.bottom - anchors.topMargin: Appearance.spacing.small - color: DynamicColors.palette.m3outline - font.pointSize: Appearance.font.size.small + anchors.topMargin: Tokens.spacing.small + color: Colors.palette.m3outline + font.pointSize: Tokens.font.size.small horizontalAlignment: Text.AlignHCenter pauseMs: 4000 text: (Players.active?.trackAlbum ?? qsTr("No media")) || qsTr("Unknown album") - width: parent.width - Appearance.padding.large * 4 + width: parent.width - Tokens.padding.large * 4 } MarqueeText { @@ -246,12 +247,12 @@ Item { anchors.horizontalCenter: parent.horizontalCenter anchors.top: album.bottom - anchors.topMargin: Appearance.spacing.small - color: DynamicColors.palette.m3secondary + anchors.topMargin: Tokens.spacing.small + color: Colors.palette.m3secondary horizontalAlignment: Text.AlignHCenter pauseMs: 4000 text: (Players.active?.trackArtist ?? qsTr("No media")) || qsTr("Unknown artist") - width: parent.width - Appearance.padding.large * 4 + width: parent.width - Tokens.padding.large * 4 } RowLayout { @@ -259,8 +260,8 @@ Item { anchors.horizontalCenter: parent.horizontalCenter anchors.top: artist.bottom - anchors.topMargin: Appearance.spacing.smaller - spacing: Appearance.spacing.small + anchors.topMargin: Tokens.spacing.smaller + spacing: Tokens.spacing.small Control { function onClicked(): void { @@ -303,22 +304,22 @@ Item { function onClicked(): void { } - Layout.preferredWidth: implicitWidth + (controlState.pressed ? Appearance.padding.normal * 2 : 0) - color: canUse ? DynamicColors.palette[`m3${set_color.toLowerCase()}`] : DynamicColors.palette[`m3${set_color.toLowerCase()}Container`] + Layout.preferredWidth: implicitWidth + (controlState.pressed ? Tokens.padding.normal * 2 : 0) + color: canUse ? Colors.palette[`m3${set_color.toLowerCase()}`] : Colors.palette[`m3${set_color.toLowerCase()}Container`] implicitHeight: implicitWidth - implicitWidth: Math.max(icon.implicitHeight, icon.implicitHeight) + Appearance.padding.small - radius: Appearance.rounding.full + implicitWidth: Math.max(icon.implicitHeight, icon.implicitHeight) + Tokens.padding.small + radius: Tokens.rounding.full Behavior on Layout.preferredWidth { Anim { - duration: Appearance.anim.durations.expressiveFastSpatial - easing.bezierCurve: Appearance.anim.curves.expressiveFastSpatial + duration: Tokens.anim.durations.expressiveFastSpatial + easing.bezierCurve: Tokens.anim.curves.expressiveFastSpatial } } Behavior on radius { Anim { - duration: Appearance.anim.durations.expressiveFastSpatial - easing.bezierCurve: Appearance.anim.curves.expressiveFastSpatial + duration: Tokens.anim.durations.expressiveFastSpatial + easing.bezierCurve: Tokens.anim.curves.expressiveFastSpatial } } @@ -332,13 +333,13 @@ Item { StateLayer { id: controlState - color: control.canUse ? DynamicColors.palette[`m3on${control.set_color}`] : DynamicColors.palette[`m3on${control.set_color}Container`] + color: control.canUse ? Colors.palette[`m3on${control.set_color}`] : Colors.palette[`m3on${control.set_color}Container`] enabled: control.canUse onClicked: { control.onClicked(); } - // radius: Appearance.rounding.full + // radius: Tokens.rounding.full } MaterialIcon { @@ -347,9 +348,9 @@ Item { anchors.centerIn: parent anchors.verticalCenterOffset: font.pointSize * 0.05 animate: true - color: control.canUse ? DynamicColors.palette[`m3on${control.set_color}`] : DynamicColors.palette[`m3on${control.set_color}Container`] + color: control.canUse ? Colors.palette[`m3on${control.set_color}`] : Colors.palette[`m3on${control.set_color}Container`] fill: control.canUse ? 1 : 0 - font.pointSize: Appearance.font.size.large + font.pointSize: Tokens.font.size.large text: control.icon } } diff --git a/Modules/Dashboard/Dash/Resources.qml b/Modules/Dashboard/Dash/Resources.qml index 12c4096..b8dd377 100644 --- a/Modules/Dashboard/Dash/Resources.qml +++ b/Modules/Dashboard/Dash/Resources.qml @@ -1,9 +1,9 @@ import QtQuick import QtQuick.Layouts import ZShell.Services +import ZShell.Config import qs.Components -import qs.Helpers -import qs.Config +import qs.Services Item { id: root @@ -33,36 +33,36 @@ Item { anchors.bottom: parent.bottom anchors.horizontalCenter: parent.horizontalCenter - anchors.margins: Appearance.padding.large + anchors.margins: Tokens.padding.large anchors.top: parent.top - spacing: Appearance.spacing.normal + spacing: Tokens.spacing.normal Resource { - fgColor: DynamicColors.palette.m3primary + fgColor: Colors.palette.m3primary icon: "memory" value: Cpu.percentage } Resource { - fgColor: DynamicColors.palette.m3secondary + fgColor: Colors.palette.m3secondary icon: "memory_alt" value: Memory.percentage } Resource { - fgColor: DynamicColors.palette.m3tertiary + fgColor: Colors.palette.m3tertiary icon: "gamepad" value: Gpu.percentage } Resource { - fgColor: DynamicColors.palette.m3primary + fgColor: Colors.palette.m3primary icon: "host" value: Gpu.memoryUsed / Gpu.memoryTotal } Resource { - fgColor: DynamicColors.palette.m3secondary + fgColor: Colors.palette.m3secondary icon: "hard_disk" value: Storage.percentage } diff --git a/Modules/Dashboard/Dash/User.qml b/Modules/Dashboard/Dash/User.qml index 8109fb3..a1909cf 100644 --- a/Modules/Dashboard/Dash/User.qml +++ b/Modules/Dashboard/Dash/User.qml @@ -1,10 +1,10 @@ -import qs.Components -import qs.Config -import qs.Paths -import qs.Helpers -import qs.Modules import Quickshell import QtQuick +import ZShell.Config +import qs.Services +import qs.Components +import qs.Paths +import qs.Helpers Row { id: root @@ -15,10 +15,10 @@ Row { spacing: 12 CustomClippingRect { - color: DynamicColors.layer(DynamicColors.palette.m3surfaceContainerHigh, 2) + color: Colors.layer(Colors.palette.m3surfaceContainerHigh, 2) implicitHeight: info.implicitHeight implicitWidth: info.implicitHeight - radius: Appearance.rounding.smallest + radius: Tokens.rounding.smallest MaterialIcon { anchors.centerIn: parent @@ -53,7 +53,7 @@ Row { anchors.left: parent.left anchors.leftMargin: (Config.dashboard.sizes.infoIconSize - implicitWidth) / 2 - color: DynamicColors.palette.m3primary + color: Colors.palette.m3primary implicitSize: Math.floor(13 * 1.34) source: SystemInfo.osLogo } @@ -72,7 +72,7 @@ Row { } InfoLine { - colour: DynamicColors.palette.m3secondary + colour: Colors.palette.m3secondary icon: "select_window_2" text: SystemInfo.wm } @@ -80,7 +80,7 @@ Row { InfoLine { id: uptime - colour: DynamicColors.palette.m3tertiary + colour: Colors.palette.m3tertiary icon: "timer" text: qsTr("%1").arg(SystemInfo.uptime) } diff --git a/Modules/Dashboard/Dash/Weather.qml b/Modules/Dashboard/Dash/Weather.qml index 4592aeb..2ba59e6 100644 --- a/Modules/Dashboard/Dash/Weather.qml +++ b/Modules/Dashboard/Dash/Weather.qml @@ -1,7 +1,8 @@ import QtQuick import qs.Helpers import qs.Components -import qs.Config +import ZShell.Config +import qs.Services Item { id: root @@ -17,7 +18,7 @@ Item { anchors.left: parent.left anchors.verticalCenter: parent.verticalCenter animate: true - color: DynamicColors.palette.m3secondary + color: Colors.palette.m3secondary font.pointSize: 54 text: Weather.icon } @@ -26,15 +27,15 @@ Item { id: info anchors.left: icon.right - anchors.leftMargin: Appearance.spacing.large + anchors.leftMargin: Tokens.spacing.large anchors.verticalCenter: parent.verticalCenter spacing: 8 CustomText { anchors.horizontalCenter: parent.horizontalCenter animate: true - color: DynamicColors.palette.m3primary - font.pointSize: Appearance.font.size.extraLarge + color: Colors.palette.m3primary + font.pointSize: Tokens.font.size.extraLarge font.weight: 500 text: Weather.temp } diff --git a/Modules/Dashboard/Tabs.qml b/Modules/Dashboard/Tabs.qml index aed64b5..5225d23 100644 --- a/Modules/Dashboard/Tabs.qml +++ b/Modules/Dashboard/Tabs.qml @@ -1,13 +1,14 @@ pragma ComponentBehavior: Bound import qs.Components -import qs.Config +import ZShell.Config import qs.Helpers import qs.Modules import Quickshell import Quickshell.Widgets import QtQuick import QtQuick.Controls +import qs.Services Item { id: root @@ -81,9 +82,9 @@ Item { anchors.left: parent.left anchors.right: parent.right anchors.top: parent.top - color: DynamicColors.palette.m3primary + color: Colors.palette.m3primary implicitHeight: parent.implicitHeight * 2 - radius: Appearance.rounding.full + radius: Tokens.rounding.full } } @@ -93,7 +94,7 @@ Item { anchors.left: parent.left anchors.right: parent.right anchors.top: indicator.bottom - color: DynamicColors.palette.m3outlineVariant + color: Colors.palette.m3outlineVariant implicitHeight: 1 } @@ -158,8 +159,6 @@ Item { } Anim { - duration: MaterialEasing.expressiveEffectsTime - easing.bezierCurve: MaterialEasing.expressiveEffects from: 0 properties: "implicitWidth,implicitHeight" target: ripple @@ -167,8 +166,6 @@ Item { } Anim { - duration: MaterialEasing.expressiveEffectsTime - easing.bezierCurve: MaterialEasing.expressiveEffects easing.type: Easing.BezierSpline property: "opacity" target: ripple @@ -184,13 +181,13 @@ Item { anchors.verticalCenter: parent.verticalCenter color: "transparent" implicitHeight: parent.height + 8 * 2 - radius: Appearance.rounding.smallest + radius: Tokens.rounding.smallest CustomRect { id: stateLayer anchors.fill: parent - color: tab.current ? DynamicColors.palette.m3primary : DynamicColors.palette.m3onSurface + color: tab.current ? Colors.palette.m3primary : Colors.palette.m3onSurface opacity: mouse.pressed ? 0.1 : tab.hovered ? 0.08 : 0 Behavior on opacity { @@ -202,9 +199,9 @@ Item { CustomRect { id: ripple - color: tab.current ? DynamicColors.palette.m3primary : DynamicColors.palette.m3onSurface + color: tab.current ? Colors.palette.m3primary : Colors.palette.m3onSurface opacity: 0 - radius: Appearance.rounding.full + radius: Tokens.rounding.full transform: Translate { x: -ripple.width / 2 @@ -218,7 +215,7 @@ Item { anchors.bottom: label.top anchors.horizontalCenter: parent.horizontalCenter - color: tab.current ? DynamicColors.palette.m3primary : DynamicColors.palette.m3onSurfaceVariant + color: tab.current ? Colors.palette.m3primary : Colors.palette.m3onSurfaceVariant fill: tab.current ? 1 : 0 font.pointSize: 18 text: tab.iconName @@ -234,7 +231,7 @@ Item { anchors.bottom: parent.bottom anchors.horizontalCenter: parent.horizontalCenter - color: tab.current ? DynamicColors.palette.m3primary : DynamicColors.palette.m3onSurfaceVariant + color: tab.current ? Colors.palette.m3primary : Colors.palette.m3onSurfaceVariant text: tab.text } } diff --git a/Modules/Dashboard/Wrapper.qml b/Modules/Dashboard/Wrapper.qml index 26da1e5..9b401ba 100644 --- a/Modules/Dashboard/Wrapper.qml +++ b/Modules/Dashboard/Wrapper.qml @@ -3,7 +3,7 @@ pragma ComponentBehavior: Bound import Quickshell import QtQuick import qs.Components -import qs.Config +import ZShell.Config Item { id: root diff --git a/Modules/DesktopIcons/BackgroundContextMenu.qml b/Modules/DesktopIcons/BackgroundContextMenu.qml index a9eefa8..52934a2 100644 --- a/Modules/DesktopIcons/BackgroundContextMenu.qml +++ b/Modules/DesktopIcons/BackgroundContextMenu.qml @@ -4,9 +4,10 @@ import Quickshell import Quickshell.Widgets import Quickshell.Hyprland import qs.Components -import qs.Config +import ZShell.Config import qs.Paths import qs.Helpers +import qs.Services Item { id: root @@ -30,8 +31,8 @@ Item { x: root.menuX y: root.menuY - color: DynamicColors.tPalette.m3surface - radius: Appearance.rounding.normal + color: Colors.tPalette.m3surface + radius: Tokens.rounding.normal implicitWidth: menuLayout.implicitWidth + padding * 2 implicitHeight: menuLayout.implicitHeight + padding * 2 @@ -47,13 +48,13 @@ Item { CustomRect { Layout.preferredWidth: 200 radius: popupBackground.radius - popupBackground.padding - implicitHeight: openTerminalRow.implicitHeight + Appearance.padding.small * 2 + implicitHeight: openTerminalRow.implicitHeight + Tokens.padding.small * 2 RowLayout { id: openTerminalRow spacing: 8 anchors.fill: parent - anchors.leftMargin: Appearance.padding.smaller + anchors.leftMargin: Tokens.padding.smaller MaterialIcon { text: "terminal"; font.pointSize: 20 } CustomText { text: "Open terminal"; Layout.fillWidth: true } @@ -72,7 +73,7 @@ Item { CustomRect { Layout.fillWidth: true implicitHeight: 1 - color: DynamicColors.palette.m3outlineVariant + color: Colors.palette.m3outlineVariant Layout.topMargin: 4 Layout.bottomMargin: 4 } @@ -80,13 +81,13 @@ Item { CustomRect { Layout.fillWidth: true radius: popupBackground.radius - popupBackground.padding - implicitHeight: settingsRow.implicitHeight + Appearance.padding.small * 2 + implicitHeight: settingsRow.implicitHeight + Tokens.padding.small * 2 RowLayout { id: settingsRow spacing: 8 anchors.fill: parent - anchors.leftMargin: Appearance.padding.smaller + anchors.leftMargin: Tokens.padding.smaller MaterialIcon { text: "settings"; font.pointSize: 20 } CustomText { text: "ZShell settings"; Layout.fillWidth: true } @@ -106,7 +107,7 @@ Item { CustomRect { Layout.fillWidth: true implicitHeight: 1 - color: DynamicColors.palette.m3outlineVariant + color: Colors.palette.m3outlineVariant Layout.topMargin: 4 Layout.bottomMargin: 4 } @@ -114,13 +115,13 @@ Item { CustomRect { Layout.fillWidth: true radius: popupBackground.radius - popupBackground.padding - implicitHeight: logoutRow.implicitHeight + Appearance.padding.small * 2 + implicitHeight: logoutRow.implicitHeight + Tokens.padding.small * 2 RowLayout { id: logoutRow spacing: 8 anchors.fill: parent - anchors.leftMargin: Appearance.padding.smaller + anchors.leftMargin: Tokens.padding.smaller MaterialIcon { text: "logout"; font.pointSize: 20 } CustomText { text: "Logout"; Layout.fillWidth: true } @@ -139,7 +140,7 @@ Item { // CustomRect { // Layout.fillWidth: true // implicitHeight: 1 - // color: DynamicColors.palette.m3outlineVariant + // color: Colors.palette.m3outlineVariant // Layout.topMargin: 4 // Layout.bottomMargin: 4 // } @@ -147,13 +148,13 @@ Item { // CustomRect { // Layout.fillWidth: true // radius: popupBackground.radius - popupBackground.padding - // implicitHeight: desktopIconsRow.implicitHeight + Appearance.padding.small * 2 + // implicitHeight: desktopIconsRow.implicitHeight + Tokens.padding.small * 2 // // RowLayout { // id: desktopIconsRow // spacing: 8 // anchors.fill: parent - // anchors.leftMargin: Appearance.padding.smaller + // anchors.leftMargin: Tokens.padding.smaller // // MaterialIcon { text: Config.options.background.showDesktopIcons ? "visibility_off" : "visibility"; font.pointSize: 20 } // CustomText { text: Config.options.background.showDesktopIcons ? "Hide icons" : "Show icons"; Layout.fillWidth: true } diff --git a/Modules/DesktopIcons/DesktopIconContextMenu.qml b/Modules/DesktopIcons/DesktopIconContextMenu.qml index 78d5c8c..7244719 100644 --- a/Modules/DesktopIcons/DesktopIconContextMenu.qml +++ b/Modules/DesktopIcons/DesktopIconContextMenu.qml @@ -3,7 +3,8 @@ import QtQuick.Layouts import Quickshell import Quickshell.Widgets import qs.Components -import qs.Config +import ZShell.Config +import qs.Services Item { id: contextMenu @@ -42,13 +43,13 @@ Item { CustomClippingRect { id: popupBackground - readonly property real padding: Appearance.padding.small + readonly property real padding: Tokens.padding.small - color: DynamicColors.tPalette.m3surface + color: Colors.tPalette.m3surface implicitHeight: menuLayout.implicitHeight + padding * 2 implicitWidth: menuLayout.implicitWidth + padding * 2 opacity: contextMenu.visible ? 1 : 0 - radius: Appearance.rounding.normal + radius: Tokens.rounding.normal x: contextMenu.menuX y: contextMenu.menuY @@ -65,14 +66,14 @@ Item { CustomRect { Layout.preferredWidth: 160 - implicitHeight: openRow.implicitHeight + Appearance.padding.small * 2 + implicitHeight: openRow.implicitHeight + Tokens.padding.small * 2 radius: popupBackground.radius - popupBackground.padding RowLayout { id: openRow anchors.fill: parent - anchors.leftMargin: Appearance.padding.smaller + anchors.leftMargin: Tokens.padding.smaller spacing: 8 MaterialIcon { @@ -108,14 +109,14 @@ Item { CustomRect { Layout.fillWidth: true - implicitHeight: openWithRow.implicitHeight + Appearance.padding.small * 2 + implicitHeight: openWithRow.implicitHeight + Tokens.padding.small * 2 radius: popupBackground.radius - popupBackground.padding RowLayout { id: openWithRow anchors.fill: parent - anchors.leftMargin: Appearance.padding.smaller + anchors.leftMargin: Tokens.padding.smaller spacing: 8 MaterialIcon { @@ -147,20 +148,20 @@ Item { Layout.bottomMargin: 4 Layout.fillWidth: true Layout.topMargin: 4 - color: DynamicColors.palette.m3outlineVariant + color: Colors.palette.m3outlineVariant implicitHeight: 1 } CustomRect { Layout.fillWidth: true - implicitHeight: copyPathRow.implicitHeight + Appearance.padding.small * 2 + implicitHeight: copyPathRow.implicitHeight + Tokens.padding.small * 2 radius: popupBackground.radius - popupBackground.padding RowLayout { id: copyPathRow anchors.fill: parent - anchors.leftMargin: Appearance.padding.smaller + anchors.leftMargin: Tokens.padding.smaller spacing: 8 MaterialIcon { @@ -186,7 +187,7 @@ Item { CustomRect { Layout.fillWidth: true - implicitHeight: renameRow.implicitHeight + Appearance.padding.small * 2 + implicitHeight: renameRow.implicitHeight + Tokens.padding.small * 2 radius: popupBackground.radius - popupBackground.padding visible: contextMenu.targetPaths.length === 1 @@ -194,7 +195,7 @@ Item { id: renameRow anchors.fill: parent - anchors.leftMargin: Appearance.padding.smaller + anchors.leftMargin: Tokens.padding.smaller spacing: 8 MaterialIcon { @@ -222,31 +223,31 @@ Item { Layout.bottomMargin: 4 Layout.fillWidth: true Layout.topMargin: 4 - color: DynamicColors.palette.m3outlineVariant + color: Colors.palette.m3outlineVariant implicitHeight: 1 } CustomRect { Layout.fillWidth: true - implicitHeight: deleteRow.implicitHeight + Appearance.padding.small * 2 + implicitHeight: deleteRow.implicitHeight + Tokens.padding.small * 2 radius: popupBackground.radius - popupBackground.padding RowLayout { id: deleteRow anchors.fill: parent - anchors.leftMargin: Appearance.padding.smaller + anchors.leftMargin: Tokens.padding.smaller spacing: 8 MaterialIcon { - color: deleteButton.hovered ? DynamicColors.palette.m3onError : DynamicColors.palette.m3error + color: deleteButton.hovered ? Colors.palette.m3onError : Colors.palette.m3error font.pointSize: 20 text: "delete" } CustomText { Layout.fillWidth: true - color: deleteButton.hovered ? DynamicColors.palette.m3onError : DynamicColors.palette.m3error + color: deleteButton.hovered ? Colors.palette.m3onError : Colors.palette.m3error text: "Move to trash" } } @@ -255,7 +256,7 @@ Item { id: deleteButton anchors.fill: parent - color: DynamicColors.tPalette.m3error + color: Colors.tPalette.m3error onClicked: { let cmd = ["gio", "trash"].concat(contextMenu.targetPaths); diff --git a/Modules/DesktopIcons/DesktopIconDelegate.qml b/Modules/DesktopIcons/DesktopIconDelegate.qml index 4a9d51a..28804e4 100644 --- a/Modules/DesktopIcons/DesktopIconDelegate.qml +++ b/Modules/DesktopIcons/DesktopIconDelegate.qml @@ -1,7 +1,7 @@ import QtQuick import Quickshell import Quickshell.Widgets -import qs.Config +import ZShell.Config import qs.Components import qs.Helpers @@ -205,7 +205,7 @@ Item { anchors.margins: 4 color: "white" opacity: root.iconsRoot.selectedIcons.includes(root.filePath) ? 0.2 : 0.0 - radius: Appearance.rounding.smallest + radius: Tokens.rounding.smallest Behavior on opacity { Anim { @@ -265,7 +265,7 @@ Item { anchors.margins: 4 color: "white" opacity: parent.containsMouse ? 0.1 : 0.0 - radius: Appearance.rounding.smallest + radius: Tokens.rounding.smallest Behavior on opacity { Anim { diff --git a/Modules/DesktopIcons/DesktopIcons.qml b/Modules/DesktopIcons/DesktopIcons.qml index c06f402..33ced2a 100644 --- a/Modules/DesktopIcons/DesktopIcons.qml +++ b/Modules/DesktopIcons/DesktopIcons.qml @@ -4,7 +4,8 @@ import QtQuick import Quickshell import ZShell.Services import qs.Helpers -import qs.Config +import ZShell.Config +import qs.Services import qs.Components import qs.Paths @@ -116,12 +117,12 @@ Item { fadeIn.start(); } - border.color: DynamicColors.palette.m3primary + border.color: Colors.palette.m3primary border.pixelAligned: true border.width: 1 - color: DynamicColors.tPalette.m3primary + color: Colors.tPalette.m3primary opacity: 0 - radius: Appearance.rounding.small + radius: Tokens.rounding.small visible: false z: 99 diff --git a/Modules/Dock/Content.qml b/Modules/Dock/Content.qml index 47b1d13..fd50fdc 100644 --- a/Modules/Dock/Content.qml +++ b/Modules/Dock/Content.qml @@ -6,7 +6,7 @@ import QtQml.Models import qs.Modules.Dock.Parts import qs.Components import qs.Helpers -import qs.Config +import ZShell.Config Item { id: root @@ -22,10 +22,10 @@ Item { property string draggedAppId: "" property var draggedModelData: null property bool dropAnimating: false - readonly property int padding: Appearance.padding.small + readonly property int padding: Tokens.padding.small required property var panels property var pendingCommitIds: [] - readonly property int rounding: Appearance.rounding.large + readonly property int rounding: Tokens.rounding.large required property ShellScreen screen required property PersistentProperties visibilities property var visualIds: [] @@ -119,7 +119,7 @@ Item { Anim { id: settleX - duration: Appearance.anim.durations.normal + duration: Tokens.anim.durations.normal property: "dragX" target: root } @@ -127,7 +127,7 @@ Item { Anim { id: settleY - duration: Appearance.anim.durations.normal + duration: Tokens.anim.durations.normal property: "dragY" target: root } @@ -247,7 +247,7 @@ Item { property bool enableAddAnimation: false anchors.left: parent.left - anchors.margins: Appearance.padding.small + anchors.margins: Tokens.padding.small anchors.top: parent.top boundsBehavior: Flickable.StopAtBounds height: Config.dock.height @@ -255,19 +255,19 @@ Item { interactive: !(root.dragActive || root.dropAnimating) model: visualModel orientation: ListView.Horizontal - spacing: Appearance.padding.smaller + spacing: Tokens.padding.smaller add: Transition { ParallelAnimation { Anim { - duration: dockRow.enableAddAnimation ? Appearance.anim.durations.normal : 0 + duration: dockRow.enableAddAnimation ? Tokens.anim.durations.normal : 0 from: 0 property: "opacity" to: 1 } Anim { - duration: dockRow.enableAddAnimation ? Appearance.anim.durations.normal : 0 + duration: dockRow.enableAddAnimation ? Tokens.anim.durations.normal : 0 from: 0.5 property: "scale" to: 1 @@ -276,13 +276,13 @@ Item { } displaced: Transition { Anim { - duration: Appearance.anim.durations.small + duration: Tokens.anim.durations.small properties: "x,y" } } move: Transition { Anim { - duration: Appearance.anim.durations.small + duration: Tokens.anim.durations.small properties: "x,y" } } diff --git a/Modules/Dock/Parts/DockAppButton.qml b/Modules/Dock/Parts/DockAppButton.qml index c7e79b9..265fd44 100644 --- a/Modules/Dock/Parts/DockAppButton.qml +++ b/Modules/Dock/Parts/DockAppButton.qml @@ -4,7 +4,8 @@ import Quickshell import Quickshell.Widgets import qs.Components import qs.Helpers -import qs.Config +import ZShell.Config +import qs.Services CustomRect { id: root @@ -22,7 +23,7 @@ CustomRect { implicitHeight: Config.dock.height implicitWidth: isSeparator ? 1 : implicitHeight - radius: Appearance.rounding.normal - Appearance.padding.small + radius: Tokens.rounding.normal - Tokens.padding.small Loader { active: !isSeparator @@ -47,10 +48,10 @@ CustomRect { delegate: Rectangle { required property int index - color: appIsActive ? DynamicColors.palette.m3primary : DynamicColors.tPalette.m3primary + color: appIsActive ? Colors.palette.m3primary : Colors.tPalette.m3primary implicitHeight: root.countDotHeight implicitWidth: (appToplevel?.toplevels.length <= 3) ? root.countDotWidth : root.countDotHeight // Circles when too many - radius: Appearance.rounding.full + radius: Tokens.rounding.full } } } diff --git a/Modules/Dock/Parts/DockSeparator.qml b/Modules/Dock/Parts/DockSeparator.qml index b535412..973d9db 100644 --- a/Modules/Dock/Parts/DockSeparator.qml +++ b/Modules/Dock/Parts/DockSeparator.qml @@ -1,12 +1,13 @@ import QtQuick import QtQuick.Layouts import qs.Components -import qs.Config +import ZShell.Config +import qs.Services CustomRect { - Layout.bottomMargin: dockRow.padding + Appearance.rounding.normal + Layout.bottomMargin: dockRow.padding + Tokens.rounding.normal Layout.fillHeight: true - Layout.topMargin: dockRow.padding + Appearance.rounding.normal - color: DynamicColors.palette.m3outlineVariant + Layout.topMargin: dockRow.padding + Tokens.rounding.normal + color: Colors.palette.m3outlineVariant implicitWidth: 1 } diff --git a/Modules/Dock/Wrapper.qml b/Modules/Dock/Wrapper.qml index 24f530a..49eaea0 100644 --- a/Modules/Dock/Wrapper.qml +++ b/Modules/Dock/Wrapper.qml @@ -3,7 +3,7 @@ pragma ComponentBehavior: Bound import Quickshell import QtQuick import qs.Components -import qs.Config +import ZShell.Config Item { id: root @@ -23,8 +23,8 @@ Item { Behavior on offsetScale { Anim { - duration: Appearance.anim.durations.expressiveDefaultSpatial - easing.bezierCurve: Appearance.anim.curves.expressiveDefaultSpatial + duration: Tokens.anim.durations.expressiveDefaultSpatial + easing.bezierCurve: Tokens.anim.curves.expressiveDefaultSpatial } } diff --git a/Modules/Drawing/Content.qml b/Modules/Drawing/Content.qml index 6ed0190..4a83e7b 100644 --- a/Modules/Drawing/Content.qml +++ b/Modules/Drawing/Content.qml @@ -2,8 +2,9 @@ pragma ComponentBehavior: Bound import QtQuick import ZShell.Components -import qs.Config +import ZShell.Config import qs.Components +import qs.Services Item { id: root @@ -32,8 +33,8 @@ Item { drawing.drawingState.penColor = Qt.hsva(huePicker.currentHue, saturationSlider.value, brightnessSlider.value, drawing.drawingState.penColor.a); } - implicitHeight: column.height + Appearance.padding.larger * 2 - implicitWidth: huePicker.implicitWidth + Appearance.padding.normal * 2 + implicitHeight: column.height + Tokens.padding.larger * 2 + implicitWidth: huePicker.implicitWidth + Tokens.padding.normal * 2 Component.onCompleted: syncFromPenColor() @@ -96,7 +97,7 @@ Item { anchors.left: parent.left anchors.right: parent.right - spacing: Appearance.spacing.normal + spacing: Tokens.spacing.normal Repeater { model: root.colors1 @@ -112,7 +113,7 @@ Item { anchors.left: parent.left anchors.right: parent.right - spacing: Appearance.spacing.normal + spacing: Tokens.spacing.normal Repeater { model: root.colors2 @@ -140,14 +141,14 @@ Item { ButtonRow { anchors.left: parent.left anchors.right: parent.right - spacing: Appearance.spacing.small + spacing: Tokens.spacing.small IconTextButton { fillWidth: true - font.pointSize: Appearance.font.size.normal + font.pointSize: Tokens.font.size.normal icon: "close" - inactiveColor: DynamicColors.palette.m3error - inactiveOnColor: DynamicColors.palette.m3onError + inactiveColor: Colors.palette.m3error + inactiveOnColor: Colors.palette.m3onError isRound: true shapeMorph: true text: "Exit" @@ -157,10 +158,10 @@ Item { IconTextButton { fillWidth: true - font.pointSize: Appearance.font.size.normal + font.pointSize: Tokens.font.size.normal icon: "ink_eraser" - inactiveColor: DynamicColors.layer(DynamicColors.palette.m3surfaceContainerHighest, 2) - inactiveOnColor: DynamicColors.palette.m3onSurfaceVariant + inactiveColor: Colors.layer(Colors.palette.m3surfaceContainerHighest, 2) + inactiveOnColor: Colors.palette.m3onSurfaceVariant isRound: true shapeMorph: true text: "Clear" @@ -171,7 +172,7 @@ Item { } IconButton { - anchors.margins: Appearance.padding.normal + anchors.margins: Tokens.padding.normal anchors.right: parent.right anchors.top: parent.top checked: root.wrapper.pinned @@ -192,12 +193,12 @@ Item { required property ButtonRow row fillWidth: false - font.pointSize: Appearance.font.size.normal + font.pointSize: Tokens.font.size.normal icon: "" implicitHeight: buttonSize implicitWidth: buttonSize inactiveColor: modelData - inactiveOnColor: DynamicColors.on(modelData) + inactiveOnColor: Colors.on(modelData) isRound: true shapeMorph: true shapeMorphExpansion: pressed ? 12 : 0 diff --git a/Modules/Drawing/Wrapper.qml b/Modules/Drawing/Wrapper.qml index cbc56ae..352d62c 100644 --- a/Modules/Drawing/Wrapper.qml +++ b/Modules/Drawing/Wrapper.qml @@ -4,7 +4,7 @@ import Quickshell import QtQuick import qs.Components import qs.Helpers -import qs.Config +import ZShell.Config import qs.Daemons Item { @@ -48,14 +48,14 @@ Item { Behavior on implicitWidth { Anim { - duration: Appearance.anim.durations.expressiveDefaultSpatial - easing.bezierCurve: Appearance.anim.curves.expressiveDefaultSpatial + duration: Tokens.anim.durations.expressiveDefaultSpatial + easing.bezierCurve: Tokens.anim.curves.expressiveDefaultSpatial } } Behavior on offsetScale { Anim { - duration: Appearance.anim.durations.expressiveDefaultSpatial - easing.bezierCurve: Appearance.anim.curves.expressiveDefaultSpatial + duration: Tokens.anim.durations.expressiveDefaultSpatial + easing.bezierCurve: Tokens.anim.curves.expressiveDefaultSpatial } } @@ -78,7 +78,7 @@ Item { } } sourceComponent: MaterialIcon { - font.pointSize: Appearance.font.size.larger + font.pointSize: Tokens.font.size.larger text: "arrow_forward_ios" } } diff --git a/Modules/HyprsunsetWidget.qml b/Modules/HyprsunsetWidget.qml index 4a2ad27..d4daee3 100644 --- a/Modules/HyprsunsetWidget.qml +++ b/Modules/HyprsunsetWidget.qml @@ -1,17 +1,18 @@ import QtQuick import qs.Components import qs.Helpers -import qs.Config +import ZShell.Config +import qs.Services CustomRect { id: root property bool tempEnabled: Hyprsunset.enabled - color: root.tempEnabled ? DynamicColors.palette.m3primary : DynamicColors.tPalette.m3surfaceContainer - implicitHeight: Config.bar.height + Appearance.padding.smallest * 2 + color: root.tempEnabled ? Colors.palette.m3primary : Colors.tPalette.m3surfaceContainer + implicitHeight: Config.bar.height + Tokens.padding.smallest * 2 implicitWidth: implicitHeight - radius: Appearance.rounding.full + radius: Tokens.rounding.full StateLayer { onClicked: { @@ -23,7 +24,7 @@ CustomRect { MaterialIcon { anchors.centerIn: parent animate: true - color: root.tempEnabled ? DynamicColors.palette.m3onPrimary : DynamicColors.palette.m3onSurface + color: root.tempEnabled ? Colors.palette.m3onPrimary : Colors.palette.m3onSurface fill: root.tempEnabled ? 1 : 0 text: root.tempEnabled ? "lightbulb" : "light_off" diff --git a/Modules/Launcher/AppList.qml b/Modules/Launcher/AppList.qml index fc98b53..497bbec 100644 --- a/Modules/Launcher/AppList.qml +++ b/Modules/Launcher/AppList.qml @@ -5,7 +5,8 @@ import QtQuick import qs.Modules.Launcher.Services import qs.Modules.Launcher.Items import qs.Components -import qs.Config +import ZShell.Config +import qs.Services CustomListView { id: root @@ -19,7 +20,7 @@ CustomListView { orientation: Qt.Vertical preferredHighlightBegin: 0 preferredHighlightEnd: height - spacing: Appearance.spacing.small + spacing: Tokens.spacing.small state: { const text = search.text; const prefix = Config.launcher.actionPrefix; @@ -49,7 +50,7 @@ CustomListView { } addDisplaced: Transition { Anim { - duration: Appearance.anim.durations.small + duration: Tokens.anim.durations.small property: "y" } @@ -69,17 +70,17 @@ CustomListView { } } highlight: CustomRect { - color: DynamicColors.palette.m3onSurface + color: Colors.palette.m3onSurface implicitHeight: root.currentItem?.implicitHeight ?? 0 implicitWidth: root.width opacity: 0.08 - radius: Appearance.rounding.smallest + radius: Tokens.rounding.smallest y: root.currentItem?.y ?? 0 Behavior on y { Anim { - duration: Appearance.anim.durations.small - easing.bezierCurve: Appearance.anim.curves.expressiveEffects + duration: Tokens.anim.durations.small + easing.bezierCurve: Tokens.anim.curves.expressiveEffects } } } @@ -145,8 +146,8 @@ CustomListView { SequentialAnimation { ParallelAnimation { Anim { - duration: Appearance.anim.durations.small - easing.bezierCurve: Appearance.anim.curves.expressiveEffects + duration: Tokens.anim.durations.small + easing.bezierCurve: Tokens.anim.curves.expressiveEffects from: 1 property: "opacity" target: root @@ -154,8 +155,8 @@ CustomListView { } Anim { - duration: Appearance.anim.durations.small - easing.bezierCurve: Appearance.anim.curves.expressiveEffects + duration: Tokens.anim.durations.small + easing.bezierCurve: Tokens.anim.curves.expressiveEffects from: 1 property: "scale" target: root @@ -170,8 +171,8 @@ CustomListView { ParallelAnimation { Anim { - duration: Appearance.anim.durations.small - easing.bezierCurve: Appearance.anim.curves.expressiveEffects + duration: Tokens.anim.durations.small + easing.bezierCurve: Tokens.anim.curves.expressiveEffects from: 0 property: "opacity" target: root @@ -179,8 +180,8 @@ CustomListView { } Anim { - duration: Appearance.anim.durations.small - easing.bezierCurve: Appearance.anim.curves.expressiveEffects + duration: Tokens.anim.durations.small + easing.bezierCurve: Tokens.anim.curves.expressiveEffects from: 0.9 property: "scale" target: root diff --git a/Modules/Launcher/Content.qml b/Modules/Launcher/Content.qml index 3fafb77..88d776b 100644 --- a/Modules/Launcher/Content.qml +++ b/Modules/Launcher/Content.qml @@ -5,15 +5,16 @@ import QtQuick import qs.Modules.Launcher.Services import qs.Components import qs.Helpers -import qs.Config +import ZShell.Config +import qs.Services Item { id: root required property real maxHeight - readonly property int padding: Appearance.padding.small + readonly property int padding: Tokens.padding.small required property var panels - readonly property int rounding: Appearance.rounding.large + readonly property int rounding: Tokens.rounding.large required property PersistentProperties visibilities implicitHeight: search.height + listWrapper.height + padding * 2 @@ -48,9 +49,9 @@ Item { anchors.left: parent.left anchors.margins: root.padding anchors.right: parent.right - bottomPadding: Appearance.padding.larger + bottomPadding: Tokens.padding.larger placeholderText: qsTr("Type \"%1\" for commands").arg(Config.launcher.actionPrefix) - topPadding: Appearance.padding.larger + topPadding: Tokens.padding.larger Component.onCompleted: forceActiveFocus() Keys.onDownPressed: list.currentList?.decrementCurrentIndex() @@ -77,7 +78,7 @@ Item { const currentItem = list.currentList?.currentItem; if (currentItem) { if (list.showWallpapers) { - if (DynamicColors.scheme === "dynamic" && currentItem.modelData.path !== Wallpapers.actualCurrent) + if (Colors.scheme === "dynamic" && currentItem.modelData.path !== Wallpapers.actualCurrent) Wallpapers.previewColourLock = true; Wallpapers.setWallpaper(currentItem.modelData.path); root.visibilities.launcher = false; diff --git a/Modules/Launcher/ContentList.qml b/Modules/Launcher/ContentList.qml index 6b62f2e..af5122a 100644 --- a/Modules/Launcher/ContentList.qml +++ b/Modules/Launcher/ContentList.qml @@ -6,7 +6,8 @@ import qs.Paths import qs.Modules import qs.Components import qs.Helpers -import qs.Config +import ZShell.Config +import qs.Services Item { id: root @@ -30,22 +31,22 @@ Item { enabled: root.visibilities.launcher Anim { - duration: Appearance.anim.durations.small - easing.bezierCurve: Appearance.anim.curves.expressiveEffects + duration: Tokens.anim.durations.small + easing.bezierCurve: Tokens.anim.curves.expressiveEffects } } Behavior on implicitWidth { enabled: root.visibilities.launcher Anim { - duration: Appearance.anim.durations.small - easing.bezierCurve: Appearance.anim.curves.expressiveEffects + duration: Tokens.anim.durations.small + easing.bezierCurve: Tokens.anim.curves.expressiveEffects } } Behavior on state { SequentialAnimation { Anim { - duration: Appearance.anim.durations.small + duration: Tokens.anim.durations.small from: 1 property: "opacity" target: root @@ -56,7 +57,7 @@ Item { } Anim { - duration: Appearance.anim.durations.small + duration: Tokens.anim.durations.small from: 0 property: "opacity" target: root @@ -124,9 +125,9 @@ Item { anchors.horizontalCenter: parent.horizontalCenter anchors.verticalCenter: parent.verticalCenter opacity: root.currentList?.count === 0 ? 1 : 0 - padding: Appearance.padding.large + padding: Tokens.padding.large scale: root.currentList?.count === 0 ? 1 : 0.5 - spacing: Appearance.spacing.normal + spacing: Tokens.spacing.normal Behavior on opacity { Anim { @@ -139,8 +140,8 @@ Item { MaterialIcon { anchors.verticalCenter: parent.verticalCenter - color: DynamicColors.palette.m3onSurfaceVariant - font.pointSize: Appearance.font.size.extraLarge + color: Colors.palette.m3onSurfaceVariant + font.pointSize: Tokens.font.size.extraLarge text: root.state === "wallpapers" ? "wallpaper_slideshow" : "manage_search" } @@ -148,15 +149,15 @@ Item { anchors.verticalCenter: parent.verticalCenter CustomText { - color: DynamicColors.palette.m3onSurfaceVariant - font.pointSize: Appearance.font.size.larger + color: Colors.palette.m3onSurfaceVariant + font.pointSize: Tokens.font.size.larger font.weight: 500 text: root.state === "wallpapers" ? qsTr("No wallpapers found") : qsTr("No results") } CustomText { - color: DynamicColors.palette.m3onSurfaceVariant - font.pointSize: Appearance.font.size.normal + color: Colors.palette.m3onSurfaceVariant + font.pointSize: Tokens.font.size.normal text: root.state === "wallpapers" && Wallpapers.list.length === 0 ? qsTr("Try putting some wallpapers in %1").arg(Paths.shortenHome(Paths.wallsdir)) : qsTr("Try searching for something else") } } diff --git a/Modules/Launcher/Items/ActionItem.qml b/Modules/Launcher/Items/ActionItem.qml index f2da657..5c0230b 100644 --- a/Modules/Launcher/Items/ActionItem.qml +++ b/Modules/Launcher/Items/ActionItem.qml @@ -2,7 +2,8 @@ import QtQuick import qs.Modules.Launcher.Services import qs.Components import qs.Helpers -import qs.Config +import ZShell.Config +import qs.Services Item { id: root @@ -15,7 +16,7 @@ Item { implicitHeight: Config.launcher.sizes.itemHeight StateLayer { - radius: Appearance.rounding.smallest + radius: Tokens.rounding.smallest onClicked: { root.modelData?.onClicked(root.list); @@ -24,21 +25,21 @@ Item { Item { anchors.fill: parent - anchors.leftMargin: Appearance.padding.larger - anchors.margins: Appearance.padding.smaller - anchors.rightMargin: Appearance.padding.larger + anchors.leftMargin: Tokens.padding.larger + anchors.margins: Tokens.padding.smaller + anchors.rightMargin: Tokens.padding.larger MaterialIcon { id: icon anchors.verticalCenter: parent.verticalCenter - font.pointSize: Appearance.font.size.extraLarge + font.pointSize: Tokens.font.size.extraLarge text: root.modelData?.icon ?? "" } Item { anchors.left: icon.right - anchors.leftMargin: Appearance.spacing.normal + anchors.leftMargin: Tokens.spacing.normal anchors.verticalCenter: icon.verticalCenter implicitHeight: name.implicitHeight + desc.implicitHeight implicitWidth: parent.width - icon.width @@ -46,7 +47,7 @@ Item { CustomText { id: name - font.pointSize: Appearance.font.size.normal + font.pointSize: Tokens.font.size.normal text: root.modelData?.name ?? "" } @@ -54,11 +55,11 @@ Item { id: desc anchors.top: name.bottom - color: DynamicColors.palette.m3outline + color: Colors.palette.m3outline elide: Text.ElideRight - font.pointSize: Appearance.font.size.small + font.pointSize: Tokens.font.size.small text: root.modelData?.desc ?? "" - width: root.width - icon.width - Appearance.rounding.normal * 2 + width: root.width - icon.width - Tokens.rounding.normal * 2 } } } diff --git a/Modules/Launcher/Items/AppItem.qml b/Modules/Launcher/Items/AppItem.qml index 0123c13..db216d2 100644 --- a/Modules/Launcher/Items/AppItem.qml +++ b/Modules/Launcher/Items/AppItem.qml @@ -4,8 +4,9 @@ import QtQuick import qs.Modules.Launcher.Services import qs.Components import qs.Helpers -import qs.Config +import ZShell.Config import qs.Modules +import qs.Services Item { id: root @@ -18,7 +19,7 @@ Item { implicitHeight: Config.launcher.sizes.itemHeight StateLayer { - radius: Appearance.rounding.smallest + radius: Tokens.rounding.smallest onClicked: { Apps.launch(root.modelData); @@ -28,9 +29,9 @@ Item { Item { anchors.fill: parent - anchors.leftMargin: Appearance.padding.larger - anchors.margins: Appearance.padding.smaller - anchors.rightMargin: Appearance.padding.larger + anchors.leftMargin: Tokens.padding.larger + anchors.margins: Tokens.padding.smaller + anchors.rightMargin: Tokens.padding.larger IconImage { id: icon @@ -42,7 +43,7 @@ Item { Item { anchors.left: icon.right - anchors.leftMargin: Appearance.spacing.normal + anchors.leftMargin: Tokens.spacing.normal anchors.verticalCenter: icon.verticalCenter implicitHeight: name.implicitHeight + comment.implicitHeight implicitWidth: parent.width - icon.width @@ -50,7 +51,7 @@ Item { CustomText { id: name - font.pointSize: Appearance.font.size.normal + font.pointSize: Tokens.font.size.normal text: root.modelData?.name ?? "" } @@ -58,11 +59,11 @@ Item { id: comment anchors.top: name.bottom - color: DynamicColors.palette.m3outline + color: Colors.palette.m3outline elide: Text.ElideRight - font.pointSize: Appearance.font.size.small + font.pointSize: Tokens.font.size.small text: (root.modelData?.comment || root.modelData?.genericName || root.modelData?.name) ?? "" - width: root.width - icon.width - Appearance.rounding.normal * 2 + width: root.width - icon.width - Tokens.rounding.normal * 2 } } @@ -75,7 +76,7 @@ Item { asynchronous: true sourceComponent: MaterialIcon { - color: DynamicColors.palette.m3primary + color: Colors.palette.m3primary fill: 1 text: "favorite" } diff --git a/Modules/Launcher/Items/CalcItem.qml b/Modules/Launcher/Items/CalcItem.qml index 1b1f077..27c4fcb 100644 --- a/Modules/Launcher/Items/CalcItem.qml +++ b/Modules/Launcher/Items/CalcItem.qml @@ -5,7 +5,8 @@ import QtQuick.Layouts import qs.Components import qs.Modules import qs.Helpers -import qs.Config +import ZShell.Config +import qs.Services Item { id: root @@ -23,7 +24,7 @@ Item { implicitHeight: Config.launcher.sizes.itemHeight StateLayer { - radius: Appearance.rounding.smallest + radius: Tokens.rounding.smallest onClicked: { root.onClicked(); @@ -32,14 +33,14 @@ Item { RowLayout { anchors.left: parent.left - anchors.margins: Appearance.padding.larger + anchors.margins: Tokens.padding.larger anchors.right: parent.right anchors.verticalCenter: parent.verticalCenter - spacing: Appearance.spacing.normal + spacing: Tokens.spacing.normal MaterialIcon { Layout.alignment: Qt.AlignVCenter - font.pointSize: Appearance.font.size.extraLarge + font.pointSize: Tokens.font.size.extraLarge text: "function" } @@ -50,10 +51,10 @@ Item { Layout.fillWidth: true color: { if (text.includes("error: ") || text.includes("warning: ")) - return DynamicColors.palette.m3error; + return Colors.palette.m3error; if (!root.math) - return DynamicColors.palette.m3onSurfaceVariant; - return DynamicColors.palette.m3onSurface; + return Colors.palette.m3onSurfaceVariant; + return Colors.palette.m3onSurface; } elide: Text.ElideLeft text: root.math.length > 0 ? Qalculator.eval(root.math) : qsTr("Type an expression to calculate") @@ -62,21 +63,21 @@ Item { CustomRect { Layout.alignment: Qt.AlignVCenter clip: true - color: DynamicColors.palette.m3tertiary - implicitHeight: Math.max(label.implicitHeight, icon.implicitHeight) + Appearance.padding.small * 2 - implicitWidth: (stateLayer.containsMouse ? label.implicitWidth + label.anchors.rightMargin : 0) + icon.implicitWidth + Appearance.padding.normal * 2 - radius: Appearance.rounding.normal + color: Colors.palette.m3tertiary + implicitHeight: Math.max(label.implicitHeight, icon.implicitHeight) + Tokens.padding.small * 2 + implicitWidth: (stateLayer.containsMouse ? label.implicitWidth + label.anchors.rightMargin : 0) + icon.implicitWidth + Tokens.padding.normal * 2 + radius: Tokens.rounding.normal Behavior on implicitWidth { Anim { - easing.bezierCurve: Appearance.anim.curves.expressiveEffects + easing.bezierCurve: Tokens.anim.curves.expressiveEffects } } StateLayer { id: stateLayer - color: DynamicColors.palette.m3onTertiary + color: Colors.palette.m3onTertiary onClicked: { Quickshell.execDetached(["app2unit", "--", ...Config.general.apps.terminal, "fish", "-C", `exec qalc -i '${root.math}'`]); @@ -88,10 +89,10 @@ Item { id: label anchors.right: icon.left - anchors.rightMargin: Appearance.spacing.small + anchors.rightMargin: Tokens.spacing.small anchors.verticalCenter: parent.verticalCenter - color: DynamicColors.palette.m3onTertiary - font.pointSize: Appearance.font.size.normal + color: Colors.palette.m3onTertiary + font.pointSize: Tokens.font.size.normal opacity: stateLayer.containsMouse ? 1 : 0 text: qsTr("Open in calculator") @@ -105,10 +106,10 @@ Item { id: icon anchors.right: parent.right - anchors.rightMargin: Appearance.padding.normal + anchors.rightMargin: Tokens.padding.normal anchors.verticalCenter: parent.verticalCenter - color: DynamicColors.palette.m3onTertiary - font.pointSize: Appearance.font.size.large + color: Colors.palette.m3onTertiary + font.pointSize: Tokens.font.size.large text: "open_in_new" } } diff --git a/Modules/Launcher/Items/VariantItem.qml b/Modules/Launcher/Items/VariantItem.qml index 0351199..988bc9c 100644 --- a/Modules/Launcher/Items/VariantItem.qml +++ b/Modules/Launcher/Items/VariantItem.qml @@ -1,7 +1,8 @@ import QtQuick import qs.Components import qs.Modules.Launcher.Services -import qs.Config +import ZShell.Config +import qs.Services Item { id: root @@ -14,7 +15,7 @@ Item { implicitHeight: Config.launcher.sizes.itemHeight StateLayer { - radius: Appearance.rounding.smallest + radius: Tokens.rounding.smallest onClicked: { root.modelData?.onClicked(root.list); @@ -23,36 +24,36 @@ Item { Item { anchors.fill: parent - anchors.leftMargin: Appearance.padding.larger - anchors.margins: Appearance.padding.smaller - anchors.rightMargin: Appearance.padding.larger + anchors.leftMargin: Tokens.padding.larger + anchors.margins: Tokens.padding.smaller + anchors.rightMargin: Tokens.padding.larger MaterialIcon { id: icon anchors.verticalCenter: parent.verticalCenter - font.pointSize: Appearance.font.size.extraLarge + font.pointSize: Tokens.font.size.extraLarge text: root.modelData?.icon ?? "" } Column { anchors.left: icon.right - anchors.leftMargin: Appearance.spacing.larger + anchors.leftMargin: Tokens.spacing.larger anchors.verticalCenter: icon.verticalCenter spacing: 0 - width: parent.width - icon.width - anchors.leftMargin - (current.active ? current.width + Appearance.spacing.normal : 0) + width: parent.width - icon.width - anchors.leftMargin - (current.active ? current.width + Tokens.spacing.normal : 0) CustomText { - font.pointSize: Appearance.font.size.normal + font.pointSize: Tokens.font.size.normal text: root.modelData?.name ?? "" } CustomText { anchors.left: parent.left anchors.right: parent.right - color: DynamicColors.palette.m3outline + color: Colors.palette.m3outline elide: Text.ElideRight - font.pointSize: Appearance.font.size.small + font.pointSize: Tokens.font.size.small text: root.modelData?.description ?? "" } } @@ -65,8 +66,8 @@ Item { anchors.verticalCenter: parent.verticalCenter sourceComponent: MaterialIcon { - color: DynamicColors.palette.m3onSurfaceVariant - font.pointSize: Appearance.font.size.large + color: Colors.palette.m3onSurfaceVariant + font.pointSize: Tokens.font.size.large text: "check" } } diff --git a/Modules/Launcher/Items/WallpaperItem.qml b/Modules/Launcher/Items/WallpaperItem.qml index 024633c..138f175 100644 --- a/Modules/Launcher/Items/WallpaperItem.qml +++ b/Modules/Launcher/Items/WallpaperItem.qml @@ -3,8 +3,9 @@ import Quickshell import QtQuick import qs.Components import qs.Helpers -import qs.Config +import ZShell.Config import qs.Modules +import qs.Services Item { id: root @@ -12,8 +13,8 @@ Item { required property FileSystemEntry modelData required property PersistentProperties visibilities - implicitHeight: image.height + label.height + Appearance.spacing.small / 2 + Appearance.padding.large + Appearance.padding.normal - implicitWidth: image.width + Appearance.padding.larger * 2 + implicitHeight: image.height + label.height + Tokens.spacing.small / 2 + Tokens.padding.large + Tokens.padding.normal + implicitWidth: image.width + Tokens.padding.larger * 2 opacity: 0 scale: 0.5 z: PathView.z ?? 0 @@ -33,7 +34,7 @@ Item { } StateLayer { - radius: Appearance.rounding.normal + radius: Tokens.rounding.normal onClicked: { Wallpapers.setWallpaper(root.modelData.path); @@ -57,16 +58,16 @@ Item { id: image anchors.horizontalCenter: parent.horizontalCenter - color: DynamicColors.tPalette.m3surfaceContainer + color: Colors.tPalette.m3surfaceContainer implicitHeight: implicitWidth / 16 * 9 implicitWidth: Config.launcher.sizes.wallpaperWidth - radius: Appearance.rounding.small - y: Appearance.padding.large + radius: Tokens.rounding.small + y: Tokens.padding.large MaterialIcon { anchors.centerIn: parent - color: DynamicColors.tPalette.m3outline - font.pointSize: Appearance.font.size.extraLarge * 2 + color: Colors.tPalette.m3outline + font.pointSize: Tokens.font.size.extraLarge * 2 font.weight: 600 text: "image" } @@ -84,12 +85,12 @@ Item { anchors.horizontalCenter: parent.horizontalCenter anchors.top: image.bottom - anchors.topMargin: Appearance.spacing.small / 2 + anchors.topMargin: Tokens.spacing.small / 2 elide: Text.ElideRight - font.pointSize: Appearance.font.size.normal + font.pointSize: Tokens.font.size.normal horizontalAlignment: Text.AlignHCenter renderType: Text.QtRendering text: root.modelData.relativePath - width: image.width - Appearance.padding.normal * 2 + width: image.width - Tokens.padding.normal * 2 } } diff --git a/Modules/Launcher/Services/Actions.qml b/Modules/Launcher/Services/Actions.qml index 25a1b26..80df3fc 100644 --- a/Modules/Launcher/Services/Actions.qml +++ b/Modules/Launcher/Services/Actions.qml @@ -2,9 +2,10 @@ pragma Singleton import qs.Modules.Launcher import qs.Helpers -import qs.Config +import ZShell.Config import Quickshell import QtQuick +import qs.Services Searcher { id: root @@ -19,7 +20,7 @@ Searcher { Variants { id: variants - model: Config.launcher.actions.filter(a => (a.enabled ?? true) && (Config.launcher.enableDangerousActions || !(a.dangerous ?? false))) + model: Config.launcher.actions.values.filter(a => (a.enabled ?? true) && (Config.launcher.enableDangerousActions || !(a.dangerous ?? false))) Action { } @@ -42,7 +43,7 @@ Searcher { list.search.text = `${Config.launcher.actionPrefix}${command[1]} `; } else if (command[0] === "setMode" && command.length > 1) { list.visibilities.launcher = false; - DynamicColors.setMode(command[1]); + Colors.setMode(command[1]); } else { list.visibilities.launcher = false; Quickshell.execDetached(command); diff --git a/Modules/Launcher/Services/Apps.qml b/Modules/Launcher/Services/Apps.qml index d137223..e3169d0 100644 --- a/Modules/Launcher/Services/Apps.qml +++ b/Modules/Launcher/Services/Apps.qml @@ -2,7 +2,7 @@ pragma Singleton import ZShell import Quickshell -import qs.Config +import ZShell.Config import qs.Helpers import qs.Paths diff --git a/Modules/Launcher/Services/SchemeVariants.qml b/Modules/Launcher/Services/SchemeVariants.qml index 486e8d7..27ba36d 100644 --- a/Modules/Launcher/Services/SchemeVariants.qml +++ b/Modules/Launcher/Services/SchemeVariants.qml @@ -3,7 +3,7 @@ pragma Singleton import Quickshell import QtQuick import qs.Modules.Launcher -import qs.Config +import ZShell.Config import qs.Helpers Searcher { diff --git a/Modules/Launcher/WallpaperList.qml b/Modules/Launcher/WallpaperList.qml index 735191f..d01938e 100644 --- a/Modules/Launcher/WallpaperList.qml +++ b/Modules/Launcher/WallpaperList.qml @@ -4,14 +4,14 @@ import Quickshell import QtQuick import qs.Components import qs.Helpers -import qs.Config +import ZShell.Config import qs.Modules.Launcher.Items PathView { id: root required property var content - readonly property int itemWidth: Config.launcher.sizes.wallpaperWidth * 0.9 + Appearance.padding.larger * 2 + readonly property int itemWidth: Config.launcher.sizes.wallpaperWidth * 0.9 + Tokens.padding.larger * 2 readonly property int numItems: { const screen = QsWindow.window?.screen; if (!screen) diff --git a/Modules/Launcher/Wrapper.qml b/Modules/Launcher/Wrapper.qml index 1df7f68..be63791 100644 --- a/Modules/Launcher/Wrapper.qml +++ b/Modules/Launcher/Wrapper.qml @@ -3,7 +3,7 @@ pragma ComponentBehavior: Bound import Quickshell import QtQuick import qs.Components -import qs.Config +import ZShell.Config import qs.Modules.Launcher.Services Item { @@ -11,7 +11,7 @@ Item { property int contentHeight readonly property real maxHeight: { - let max = screen.height - Appearance.spacing.large * 2; + let max = screen.height - Tokens.spacing.large * 2; if (visibilities.resources && panels.resourcesWrapper.x + panels.resourcesWrapper.width > root.x) max -= panels.resources.nonAnimHeight; if (panels.popouts.hasCurrent) @@ -33,8 +33,8 @@ Item { Behavior on offsetScale { Anim { - duration: Appearance.anim.durations.expressiveDefaultSpatial - easing.bezierCurve: Appearance.anim.curves.expressiveDefaultSpatial + duration: Tokens.anim.durations.expressiveDefaultSpatial + easing.bezierCurve: Tokens.anim.curves.expressiveDefaultSpatial } } diff --git a/Modules/Lock/Center.qml b/Modules/Lock/Center.qml index 4507bae..8e3bdf6 100644 --- a/Modules/Lock/Center.qml +++ b/Modules/Lock/Center.qml @@ -5,8 +5,9 @@ import QtQuick.Layouts import qs.Paths import qs.Components import qs.Helpers -import qs.Config +import ZShell.Config import qs.Modules +import qs.Services ColumnLayout { id: root @@ -18,61 +19,61 @@ ColumnLayout { Layout.fillHeight: true Layout.fillWidth: false Layout.preferredWidth: centerWidth - spacing: Appearance.spacing.large * 2 + spacing: Tokens.spacing.large * 2 RowLayout { Layout.alignment: Qt.AlignHCenter - spacing: Appearance.spacing.small + spacing: Tokens.spacing.small CustomText { Layout.alignment: Qt.AlignVCenter - color: DynamicColors.palette.m3secondary + color: Colors.palette.m3secondary font.bold: true font.family: Appearance.font.family.clock - font.pointSize: Math.floor(Appearance.font.size.extraLarge * 3 * root.centerScale) + font.pointSize: Math.floor(Tokens.font.size.extraLarge * 3 * root.centerScale) text: Time.hourStr } CustomText { Layout.alignment: Qt.AlignVCenter - color: DynamicColors.palette.m3primary + color: Colors.palette.m3primary font.bold: true font.family: Appearance.font.family.clock - font.pointSize: Math.floor(Appearance.font.size.extraLarge * 3 * root.centerScale) + font.pointSize: Math.floor(Tokens.font.size.extraLarge * 3 * root.centerScale) text: ":" } CustomText { Layout.alignment: Qt.AlignVCenter - color: DynamicColors.palette.m3secondary + color: Colors.palette.m3secondary font.bold: true font.family: Appearance.font.family.clock - font.pointSize: Math.floor(Appearance.font.size.extraLarge * 3 * root.centerScale) + font.pointSize: Math.floor(Tokens.font.size.extraLarge * 3 * root.centerScale) text: Time.minuteStr } } CustomText { Layout.alignment: Qt.AlignHCenter - Layout.topMargin: -Appearance.padding.large * 2 - color: DynamicColors.palette.m3tertiary + Layout.topMargin: -Tokens.padding.large * 2 + color: Colors.palette.m3tertiary font.bold: true font.family: Appearance.font.family.mono - font.pointSize: Math.floor(Appearance.font.size.extraLarge * root.centerScale) + font.pointSize: Math.floor(Tokens.font.size.extraLarge * root.centerScale) text: Time.format("dddd, d MMMM yyyy") } CustomClippingRect { Layout.alignment: Qt.AlignHCenter - Layout.topMargin: Appearance.spacing.large * 2 - color: DynamicColors.tPalette.m3surfaceContainer + Layout.topMargin: Tokens.spacing.large * 2 + color: Colors.tPalette.m3surfaceContainer implicitHeight: root.centerWidth / 2 implicitWidth: root.centerWidth / 2 - radius: Appearance.rounding.full + radius: Tokens.rounding.full MaterialIcon { anchors.centerIn: parent - color: DynamicColors.palette.m3onSurfaceVariant + color: Colors.palette.m3onSurfaceVariant font.pointSize: Math.floor(root.centerWidth / 4) text: "person" } @@ -87,11 +88,11 @@ ColumnLayout { CustomRect { Layout.alignment: Qt.AlignHCenter - color: DynamicColors.tPalette.m3surfaceContainer + color: Colors.tPalette.m3surfaceContainer focus: true - implicitHeight: input.implicitHeight + Appearance.padding.small * 2 + implicitHeight: input.implicitHeight + Tokens.padding.small * 2 implicitWidth: root.centerWidth * 0.8 - radius: Appearance.rounding.full + radius: Tokens.rounding.full Keys.onPressed: event => { if (root.lock.unlocking) @@ -120,11 +121,11 @@ ColumnLayout { id: input anchors.fill: parent - anchors.margins: Appearance.padding.small - spacing: Appearance.spacing.normal + anchors.margins: Tokens.padding.small + spacing: Tokens.spacing.normal Item { - implicitHeight: fprintIcon.implicitHeight + Appearance.padding.small * 2 + implicitHeight: fprintIcon.implicitHeight + Tokens.padding.small * 2 implicitWidth: implicitHeight MaterialIcon { @@ -132,7 +133,7 @@ ColumnLayout { anchors.centerIn: parent animate: true - color: root.lock.pam.fprint.tries >= Config.lock.maxFprintTries ? DynamicColors.palette.m3error : DynamicColors.palette.m3onSurface + color: root.lock.pam.fprint.tries >= Config.lock.maxFprintTries ? Colors.palette.m3error : Colors.palette.m3onSurface opacity: root.lock.pam.passwd.active ? 0 : 1 text: { if (root.lock.pam.fprint.tries >= Config.lock.maxFprintTries) @@ -161,13 +162,13 @@ ColumnLayout { } CustomRect { - color: root.lock.pam.buffer ? DynamicColors.palette.m3primary : DynamicColors.layer(DynamicColors.palette.m3surfaceContainerHigh, 2) - implicitHeight: enterIcon.implicitHeight + Appearance.padding.small * 2 + color: root.lock.pam.buffer ? Colors.palette.m3primary : Colors.layer(Colors.palette.m3surfaceContainerHigh, 2) + implicitHeight: enterIcon.implicitHeight + Tokens.padding.small * 2 implicitWidth: implicitHeight - radius: Appearance.rounding.full + radius: Tokens.rounding.full StateLayer { - color: root.lock.pam.buffer ? DynamicColors.palette.m3onPrimary : DynamicColors.palette.m3onSurface + color: root.lock.pam.buffer ? Colors.palette.m3onPrimary : Colors.palette.m3onSurface onClicked: { root.lock.pam.passwd.start(); @@ -178,7 +179,7 @@ ColumnLayout { id: enterIcon anchors.centerIn: parent - color: root.lock.pam.buffer ? DynamicColors.palette.m3onPrimary : DynamicColors.palette.m3onSurface + color: root.lock.pam.buffer ? Colors.palette.m3onPrimary : Colors.palette.m3onSurface font.weight: 500 text: "arrow_forward" } @@ -188,7 +189,7 @@ ColumnLayout { Item { Layout.fillWidth: true - Layout.topMargin: -Appearance.spacing.large + Layout.topMargin: -Tokens.spacing.large implicitHeight: Math.max(message.implicitHeight, stateMessage.implicitHeight) Behavior on implicitHeight { @@ -224,7 +225,7 @@ ColumnLayout { anchors.left: parent.left anchors.right: parent.right animateProp: "opacity" - color: DynamicColors.palette.m3onSurfaceVariant + color: Colors.palette.m3onSurfaceVariant font.family: Appearance.font.family.mono horizontalAlignment: Qt.AlignHCenter lineHeight: 1.2 @@ -293,9 +294,9 @@ ColumnLayout { anchors.left: parent.left anchors.right: parent.right - color: DynamicColors.palette.m3error + color: Colors.palette.m3error font.family: Appearance.font.family.mono - font.pointSize: Appearance.font.size.small + font.pointSize: Tokens.font.size.small horizontalAlignment: Qt.AlignHCenter opacity: 0 scale: 0.7 @@ -365,14 +366,14 @@ ColumnLayout { id: exitAnim Anim { - duration: Appearance.anim.durations.large + duration: Tokens.anim.durations.large property: "scale" target: message to: 0.7 } Anim { - duration: Appearance.anim.durations.large + duration: Tokens.anim.durations.large property: "opacity" target: message to: 0 @@ -382,7 +383,7 @@ ColumnLayout { } component FlashAnim: NumberAnimation { - duration: Appearance.anim.durations.small + duration: Tokens.anim.durations.small easing.type: Easing.Linear property: "opacity" target: message diff --git a/Modules/Lock/Content.qml b/Modules/Lock/Content.qml index 77a32f5..3367a23 100644 --- a/Modules/Lock/Content.qml +++ b/Modules/Lock/Content.qml @@ -2,7 +2,8 @@ import QtQuick import QtQuick.Layouts import qs.Components import qs.Helpers -import qs.Config +import ZShell.Config +import qs.Services CustomClippingRect { id: root @@ -11,17 +12,17 @@ CustomClippingRect { implicitHeight: layout.implicitHeight implicitWidth: layout.implicitWidth - radius: Appearance.rounding.large + radius: Tokens.rounding.large RowLayout { id: layout anchors.fill: parent - spacing: Appearance.spacing.large * 2 + spacing: Tokens.spacing.large * 2 ColumnLayout { Layout.fillWidth: true - spacing: Appearance.spacing.normal + spacing: Tokens.spacing.normal WeatherInfo { id: weather @@ -51,15 +52,15 @@ CustomClippingRect { ColumnLayout { Layout.fillWidth: true - spacing: Appearance.spacing.normal + spacing: Tokens.spacing.normal CustomRect { Layout.fillHeight: true Layout.fillWidth: true - bottomRightRadius: Appearance.rounding.large - color: DynamicColors.tPalette.m3surfaceContainer - radius: Appearance.rounding.small - topRightRadius: Appearance.rounding.large + bottomRightRadius: Tokens.rounding.large + color: Colors.tPalette.m3surfaceContainer + radius: Tokens.rounding.small + topRightRadius: Tokens.rounding.large NotifDock { lock: root.lock diff --git a/Modules/Lock/Fetch.qml b/Modules/Lock/Fetch.qml deleted file mode 100644 index 32ff10c..0000000 --- a/Modules/Lock/Fetch.qml +++ /dev/null @@ -1,161 +0,0 @@ -pragma ComponentBehavior: Bound - -import Quickshell.Services.UPower -import QtQuick -import QtQuick.Layouts -import qs.Modules -import qs.Components -import qs.Helpers -import qs.Config - -ColumnLayout { - id: root - - anchors.fill: parent - anchors.margins: Appearance.padding.large * 2 - anchors.topMargin: Appearance.padding.large - spacing: Appearance.spacing.small - - RowLayout { - Layout.fillHeight: false - Layout.fillWidth: true - spacing: Appearance.spacing.normal - - CustomRect { - color: DynamicColors.palette.m3primary - implicitHeight: prompt.implicitHeight + Appearance.padding.normal * 2 - implicitWidth: prompt.implicitWidth + Appearance.padding.normal * 2 - radius: Appearance.rounding.small - - MonoText { - id: prompt - - anchors.centerIn: parent - color: DynamicColors.palette.m3onPrimary - font.pointSize: root.width > 400 ? Appearance.font.size.larger : Appearance.font.size.normal - text: ">" - } - } - - MonoText { - Layout.fillWidth: true - elide: Text.ElideRight - font.pointSize: root.width > 400 ? Appearance.font.size.larger : Appearance.font.size.normal - text: "caelestiafetch.sh" - } - - WrappedLoader { - Layout.fillHeight: true - active: !iconLoader.active - - sourceComponent: OsLogo { - } - } - } - - RowLayout { - Layout.fillHeight: false - Layout.fillWidth: true - spacing: height * 0.15 - - WrappedLoader { - id: iconLoader - - Layout.fillHeight: true - active: root.width > 320 - - sourceComponent: OsLogo { - } - } - - ColumnLayout { - Layout.bottomMargin: Appearance.padding.normal - Layout.fillWidth: true - Layout.leftMargin: iconLoader.active ? 0 : width * 0.1 - Layout.topMargin: Appearance.padding.normal - spacing: Appearance.spacing.normal - - WrappedLoader { - Layout.fillWidth: true - active: !batLoader.active && root.height > 200 - - sourceComponent: FetchText { - text: `OS : ${SystemInfo.osPrettyName || SysInfo.osName}` - } - } - - WrappedLoader { - Layout.fillWidth: true - active: root.height > (batLoader.active ? 200 : 110) - - sourceComponent: FetchText { - text: `WM : ${SystemInfo.wm}` - } - } - - WrappedLoader { - Layout.fillWidth: true - active: !batLoader.active || root.height > 110 - - sourceComponent: FetchText { - text: `USER: ${SystemInfo.user}` - } - } - - FetchText { - text: `UP : ${SystemInfo.uptime}` - } - - WrappedLoader { - id: batLoader - - Layout.fillWidth: true - active: UPower.displayDevice.isLaptopBattery - - sourceComponent: FetchText { - text: `BATT: ${[UPowerDeviceState.Charging, UPowerDeviceState.FullyCharged, UPowerDeviceState.PendingCharge].includes(UPower.displayDevice.state) ? "(+) " : ""}${Math.round(UPower.displayDevice.percentage * 100)}%` - } - } - } - } - - WrappedLoader { - Layout.alignment: Qt.AlignHCenter - active: root.height > 180 - - sourceComponent: RowLayout { - spacing: Appearance.spacing.large - - Repeater { - model: Math.max(0, Math.min(8, root.width / (Appearance.font.size.larger * 2 + Appearance.spacing.large))) - - CustomRect { - required property int index - - color: DynamicColors.palette[`term${index}`] - implicitHeight: Appearance.font.size.larger * 2 - implicitWidth: implicitHeight - radius: Appearance.rounding.small - } - } - } - } - - component FetchText: MonoText { - Layout.fillWidth: true - elide: Text.ElideRight - font.pointSize: root.width > 400 ? Appearance.font.size.larger : Appearance.font.size.normal - } - component MonoText: CustomText { - font.family: Appearance.font.family.mono - } - component OsLogo: ColoredIcon { - color: DynamicColors.palette.m3primary - implicitSize: height - layer.enabled: Config.lock.recolorLogo || SystemInfo.isDefaultLogo - source: SystemInfo.osLogo - } - component WrappedLoader: Loader { - visible: active - } -} diff --git a/Modules/Lock/IdleMonitors.qml b/Modules/Lock/IdleMonitors.qml index a26cceb..df2f1b0 100644 --- a/Modules/Lock/IdleMonitors.qml +++ b/Modules/Lock/IdleMonitors.qml @@ -3,7 +3,7 @@ pragma ComponentBehavior: Bound import Quickshell import Quickshell.Wayland import ZShell.Internal -import qs.Config +import ZShell.Config import qs.Helpers Scope { diff --git a/Modules/Lock/InputField.qml b/Modules/Lock/InputField.qml index dedf7bd..3c2349d 100644 --- a/Modules/Lock/InputField.qml +++ b/Modules/Lock/InputField.qml @@ -6,7 +6,8 @@ import QtQuick.Layouts import qs.Modules import qs.Components import qs.Helpers -import qs.Config +import ZShell.Config +import qs.Services Item { id: root @@ -39,9 +40,9 @@ Item { anchors.centerIn: parent animate: true - color: root.pam.passwd.active ? DynamicColors.palette.m3secondary : DynamicColors.palette.m3outline + color: root.pam.passwd.active ? Colors.palette.m3secondary : Colors.palette.m3outline font.family: Appearance.font.family.mono - font.pointSize: Appearance.font.size.normal + font.pointSize: Tokens.font.size.normal opacity: root.buffer ? 0 : 1 text: { if (root.pam.passwd.active) @@ -70,20 +71,20 @@ Item { anchors.centerIn: parent anchors.horizontalCenterOffset: implicitWidth > root.width ? -(implicitWidth - root.width) / 2 : 0 - implicitHeight: Appearance.font.size.normal + implicitHeight: Tokens.font.size.normal implicitWidth: fullWidth interactive: false orientation: Qt.Horizontal - spacing: Appearance.spacing.small / 2 + spacing: Tokens.spacing.small / 2 delegate: CustomRect { id: ch - color: DynamicColors.palette.m3onSurface + color: Colors.palette.m3onSurface implicitHeight: charList.implicitHeight implicitWidth: implicitHeight opacity: 0 - radius: Appearance.rounding.small / 2 + radius: Tokens.rounding.small / 2 scale: 0 Behavior on opacity { @@ -92,8 +93,8 @@ Item { } Behavior on scale { Anim { - duration: Appearance.anim.durations.expressiveFastSpatial - easing.bezierCurve: Appearance.anim.curves.expressiveFastSpatial + duration: Tokens.anim.durations.expressiveFastSpatial + easing.bezierCurve: Tokens.anim.curves.expressiveFastSpatial } } diff --git a/Modules/Lock/LockSurface.qml b/Modules/Lock/LockSurface.qml index aecb5be..d70640a 100644 --- a/Modules/Lock/LockSurface.qml +++ b/Modules/Lock/LockSurface.qml @@ -3,9 +3,10 @@ pragma ComponentBehavior: Bound import Quickshell.Wayland import QtQuick import QtQuick.Effects -import qs.Config +import ZShell.Config import qs.Helpers import qs.Components +import qs.Services WlSessionLockSurface { id: root @@ -29,8 +30,8 @@ WlSessionLockSurface { ParallelAnimation { Anim { - duration: Appearance.anim.durations.expressiveDefaultSpatial - easing.bezierCurve: Appearance.anim.curves.expressiveDefaultSpatial + duration: Tokens.anim.durations.expressiveDefaultSpatial + easing.bezierCurve: Tokens.anim.curves.expressiveDefaultSpatial properties: "implicitWidth,implicitHeight" target: lockContent to: lockContent.size @@ -43,22 +44,22 @@ WlSessionLockSurface { } Anim { - duration: Appearance.anim.durations.expressiveDefaultSpatial - easing.bezierCurve: Appearance.anim.curves.expressiveDefaultSpatial + duration: Tokens.anim.durations.expressiveDefaultSpatial + easing.bezierCurve: Tokens.anim.curves.expressiveDefaultSpatial property: "scale" target: content to: 0 } Anim { - duration: Appearance.anim.durations.small + duration: Tokens.anim.durations.small property: "opacity" target: content to: 0 } Anim { - duration: Appearance.anim.durations.large + duration: Tokens.anim.durations.large property: "opacity" target: lockIcon to: 1 @@ -66,7 +67,7 @@ WlSessionLockSurface { SequentialAnimation { PauseAnimation { - duration: Appearance.anim.durations.small + duration: Tokens.anim.durations.small } Anim { @@ -92,8 +93,8 @@ WlSessionLockSurface { SequentialAnimation { ParallelAnimation { Anim { - duration: Appearance.anim.durations.expressiveFastSpatial - easing.bezierCurve: Appearance.anim.curves.expressiveFastSpatial + duration: Tokens.anim.durations.expressiveFastSpatial + easing.bezierCurve: Tokens.anim.curves.expressiveFastSpatial property: "scale" target: lockContent to: 1 @@ -114,8 +115,8 @@ WlSessionLockSurface { } Anim { - duration: Appearance.anim.durations.expressiveDefaultSpatial - easing.bezierCurve: Appearance.anim.curves.expressiveDefaultSpatial + duration: Tokens.anim.durations.expressiveDefaultSpatial + easing.bezierCurve: Tokens.anim.curves.expressiveDefaultSpatial property: "scale" target: content to: 1 @@ -124,20 +125,20 @@ WlSessionLockSurface { Anim { property: "radius" target: lockBg - to: Appearance.rounding.large * 1.5 + to: Tokens.rounding.large * 1.5 } Anim { - duration: Appearance.anim.durations.expressiveDefaultSpatial - easing.bezierCurve: Appearance.anim.curves.expressiveDefaultSpatial + duration: Tokens.anim.durations.expressiveDefaultSpatial + easing.bezierCurve: Tokens.anim.curves.expressiveDefaultSpatial property: "implicitWidth" target: lockContent to: (root.screen?.height ?? 0) * Config.lock.sizes.heightMult * Config.lock.sizes.ratio } Anim { - duration: Appearance.anim.durations.expressiveDefaultSpatial - easing.bezierCurve: Appearance.anim.curves.expressiveDefaultSpatial + duration: Tokens.anim.durations.expressiveDefaultSpatial + easing.bezierCurve: Tokens.anim.curves.expressiveDefaultSpatial property: "implicitHeight" target: lockContent to: (root.screen?.height ?? 0) * Config.lock.sizes.heightMult @@ -184,8 +185,8 @@ WlSessionLockSurface { property int positionIndex: 0 readonly property var positions: [Qt.point(0, 0), Qt.point(4, 0), Qt.point(4, 4), Qt.point(0, 4), Qt.point(-4, 4), Qt.point(-4, 0), Qt.point(-4, -4), Qt.point(0, -4), Qt.point(4, -4),] - readonly property int radius: size / 4 * Appearance.rounding.scale - readonly property int size: lockIcon.implicitHeight + Appearance.padding.large * 4 + readonly property int radius: size / 4 * Tokens.rounding.scale + readonly property int size: lockIcon.implicitHeight + Tokens.padding.large * 4 anchors.centerIn: parent anchors.horizontalCenterOffset: positions[positionIndex].x @@ -219,14 +220,14 @@ WlSessionLockSurface { id: lockBg anchors.fill: parent - color: DynamicColors.palette.m3surface + color: Colors.palette.m3surface layer.enabled: true - opacity: DynamicColors.transparency.enabled ? DynamicColors.transparency.base : 1 + opacity: Colors.transparency.enabled ? Colors.transparency.base : 1 radius: lockContent.radius layer.effect: MultiEffect { blurMax: 15 - shadowColor: Qt.alpha(DynamicColors.palette.m3shadow, 0.7) + shadowColor: Qt.alpha(Colors.palette.m3shadow, 0.7) shadowEnabled: true } } @@ -236,7 +237,7 @@ WlSessionLockSurface { anchors.centerIn: parent font.bold: true - font.pointSize: Appearance.font.size.extraLarge * 4 + font.pointSize: Tokens.font.size.extraLarge * 4 text: "lock" } @@ -244,11 +245,11 @@ WlSessionLockSurface { id: content anchors.centerIn: parent - height: (root.screen?.height ?? 0) * Config.lock.sizes.heightMult - Appearance.padding.large * 2 + height: (root.screen?.height ?? 0) * Config.lock.sizes.heightMult - Tokens.padding.large * 2 lock: root opacity: 0 scale: 0 - width: (root.screen?.height ?? 0) * Config.lock.sizes.heightMult * Config.lock.sizes.ratio - Appearance.padding.large * 2 + width: (root.screen?.height ?? 0) * Config.lock.sizes.heightMult * Config.lock.sizes.ratio - Tokens.padding.large * 2 } } } diff --git a/Modules/Lock/Media.qml b/Modules/Lock/Media.qml index 505e3ed..6426e1c 100644 --- a/Modules/Lock/Media.qml +++ b/Modules/Lock/Media.qml @@ -3,17 +3,18 @@ import QtQuick.Layouts import Quickshell import ZShell.Components import qs.Components -import qs.Config +import ZShell.Config import qs.Helpers +import qs.Services CustomClippingRect { id: root required property var lock - color: DynamicColors.tPalette.m3surfaceContainer + color: Colors.tPalette.m3surfaceContainer implicitHeight: layout.implicitHeight + layout.anchors.margins * 2 - radius: Appearance.rounding.small + radius: Tokens.rounding.small FadeImage { id: image @@ -37,7 +38,7 @@ CustomClippingRect { CustomRect { anchors.fill: parent - color: DynamicColors.palette.m3surface + color: Colors.palette.m3surface opacity: 0.7 } } @@ -46,17 +47,17 @@ CustomClippingRect { id: layout anchors.left: parent.left - anchors.margins: Appearance.padding.extraLarge + anchors.margins: Tokens.padding.extraLarge anchors.right: parent.right anchors.verticalCenter: parent.verticalCenter - spacing: Appearance.spacing.extraSmall + spacing: Tokens.spacing.extraSmall CustomText { Layout.fillWidth: true animate: true - color: DynamicColors.palette.m3primary + color: Colors.palette.m3primary elide: Text.ElideRight - font.pointSize: Appearance.font.size.medium + font.pointSize: Tokens.font.size.medium horizontalAlignment: Text.AlignHCenter text: (Players.active?.trackTitle ?? qsTr("Nothing playing")) || qsTr("Unknown track") } @@ -64,17 +65,17 @@ CustomClippingRect { CustomText { Layout.fillWidth: true animate: true - color: DynamicColors.palette.m3onSurfaceVariant + color: Colors.palette.m3onSurfaceVariant elide: Text.ElideRight - font.pointSize: Appearance.font.size.small + font.pointSize: Tokens.font.size.small horizontalAlignment: Text.AlignHCenter text: (Players.active?.trackArtist ?? qsTr("Try playing some music!")) || qsTr("Unknown artist") } ButtonRow { Layout.alignment: Qt.AlignHCenter - Layout.topMargin: Appearance.spacing.small - spacing: Appearance.spacing.extraSmall + Layout.topMargin: Tokens.spacing.small + spacing: Tokens.spacing.extraSmall IconButton { enabled: Players.active?.canGoPrevious @@ -90,7 +91,7 @@ CustomClippingRect { checked: Players.active?.isPlaying ?? false enabled: Players.active?.canTogglePlaying icon: Players.active?.isPlaying ? "pause" : "play_arrow" - implicitWidth: implicitHeight + Appearance.padding.largeIncreased * 2 + implicitWidth: implicitHeight + Tokens.padding.largeIncreased * 2 isRound: true shapeMorph: true diff --git a/Modules/Lock/NotifDock.qml b/Modules/Lock/NotifDock.qml index 15f4c90..5a743ae 100644 --- a/Modules/Lock/NotifDock.qml +++ b/Modules/Lock/NotifDock.qml @@ -7,8 +7,9 @@ import QtQuick.Layouts import qs.Modules import qs.Components import qs.Helpers -import qs.Config +import ZShell.Config import qs.Daemons +import qs.Services ColumnLayout { id: root @@ -16,12 +17,12 @@ ColumnLayout { required property var lock anchors.fill: parent - anchors.margins: Appearance.padding.large - spacing: Appearance.spacing.smaller + anchors.margins: Tokens.padding.large + spacing: Tokens.spacing.smaller CustomText { Layout.fillWidth: true - color: DynamicColors.palette.m3outline + color: Colors.palette.m3outline elide: Text.ElideRight font.family: Appearance.font.family.mono font.weight: 500 @@ -34,7 +35,7 @@ ColumnLayout { Layout.fillHeight: true Layout.fillWidth: true color: "transparent" - radius: Appearance.rounding.small + radius: Tokens.rounding.small Loader { active: opacity > 0 @@ -43,11 +44,11 @@ ColumnLayout { Behavior on opacity { Anim { - duration: Appearance.anim.durations.extraLarge + duration: Tokens.anim.durations.extraLarge } } sourceComponent: ColumnLayout { - spacing: Appearance.spacing.large + spacing: Tokens.spacing.large Image { asynchronous: true @@ -58,15 +59,15 @@ ColumnLayout { layer.effect: Coloriser { brightness: 1 - colorizationColor: DynamicColors.palette.m3outlineVariant + colorizationColor: Colors.palette.m3outlineVariant } } CustomText { Layout.alignment: Qt.AlignHCenter - color: DynamicColors.palette.m3outlineVariant + color: Colors.palette.m3outlineVariant font.family: Appearance.font.family.mono - font.pointSize: Appearance.font.size.large + font.pointSize: Tokens.font.size.large font.weight: 500 text: qsTr("No Notifications") } @@ -76,7 +77,7 @@ ColumnLayout { CustomListView { anchors.fill: parent clip: true - spacing: Appearance.spacing.small + spacing: Tokens.spacing.small add: Transition { Anim { @@ -86,8 +87,8 @@ ColumnLayout { } Anim { - duration: Appearance.anim.durations.expressiveDefaultSpatial - easing.bezierCurve: Appearance.anim.curves.expressiveDefaultSpatial + duration: Tokens.anim.durations.expressiveDefaultSpatial + easing.bezierCurve: Tokens.anim.curves.expressiveDefaultSpatial from: 0 property: "scale" to: 1 @@ -102,8 +103,8 @@ ColumnLayout { } Anim { - duration: Appearance.anim.durations.expressiveDefaultSpatial - easing.bezierCurve: Appearance.anim.curves.expressiveDefaultSpatial + duration: Tokens.anim.durations.expressiveDefaultSpatial + easing.bezierCurve: Tokens.anim.curves.expressiveDefaultSpatial property: "y" } } @@ -120,8 +121,8 @@ ColumnLayout { } Anim { - duration: Appearance.anim.durations.expressiveDefaultSpatial - easing.bezierCurve: Appearance.anim.curves.expressiveDefaultSpatial + duration: Tokens.anim.durations.expressiveDefaultSpatial + easing.bezierCurve: Tokens.anim.curves.expressiveDefaultSpatial property: "y" } } diff --git a/Modules/Lock/NotifGroup.qml b/Modules/Lock/NotifGroup.qml index e79628b..e0a61ce 100644 --- a/Modules/Lock/NotifGroup.qml +++ b/Modules/Lock/NotifGroup.qml @@ -8,8 +8,9 @@ import QtQuick.Layouts import qs.Modules import qs.Components import qs.Helpers -import qs.Config +import ZShell.Config import qs.Daemons +import qs.Services CustomRect { id: root @@ -24,14 +25,14 @@ CustomRect { anchors.left: parent?.left anchors.right: parent?.right clip: true - color: root.urgency === "critical" ? DynamicColors.palette.m3secondaryContainer : DynamicColors.layer(DynamicColors.palette.m3surfaceContainerHigh, 2) - implicitHeight: content.implicitHeight + Appearance.padding.normal * 2 - radius: Appearance.rounding.normal + color: root.urgency === "critical" ? Colors.palette.m3secondaryContainer : Colors.layer(Colors.palette.m3surfaceContainerHigh, 2) + implicitHeight: content.implicitHeight + Tokens.padding.normal * 2 + radius: Tokens.rounding.normal Behavior on implicitHeight { Anim { - duration: Appearance.anim.durations.expressiveDefaultSpatial - easing.bezierCurve: Appearance.anim.curves.expressiveDefaultSpatial + duration: Tokens.anim.durations.expressiveDefaultSpatial + easing.bezierCurve: Tokens.anim.curves.expressiveDefaultSpatial } } @@ -39,10 +40,10 @@ CustomRect { id: content anchors.left: parent.left - anchors.margins: Appearance.padding.normal + anchors.margins: Tokens.padding.normal anchors.right: parent.right anchors.top: parent.top - spacing: Appearance.spacing.normal + spacing: Tokens.spacing.normal Item { Layout.alignment: Qt.AlignLeft | Qt.AlignTop @@ -67,7 +68,7 @@ CustomRect { id: appIconComp ColoredIcon { - color: root.urgency === "critical" ? DynamicColors.palette.m3onError : root.urgency === "low" ? DynamicColors.palette.m3onSurface : DynamicColors.palette.m3onSecondaryContainer + color: root.urgency === "critical" ? Colors.palette.m3onError : root.urgency === "low" ? Colors.palette.m3onSurface : Colors.palette.m3onSecondaryContainer implicitSize: Math.round(Config.notifs.sizes.image * 0.6) layer.enabled: root.appIcon.endsWith("symbolic") source: Quickshell.iconPath(root.appIcon) @@ -78,16 +79,16 @@ CustomRect { id: materialIconComp MaterialIcon { - color: root.urgency === "critical" ? DynamicColors.palette.m3onError : root.urgency === "low" ? DynamicColors.palette.m3onSurface : DynamicColors.palette.m3onSecondaryContainer - font.pointSize: Appearance.font.size.large + color: root.urgency === "critical" ? Colors.palette.m3onError : root.urgency === "low" ? Colors.palette.m3onSurface : Colors.palette.m3onSecondaryContainer + font.pointSize: Tokens.font.size.large text: Icons.getNotifIcon(root.notifs[0]?.summary, root.urgency) } } ClippingRectangle { anchors.fill: parent - color: root.urgency === "critical" ? DynamicColors.palette.m3error : root.urgency === "low" ? DynamicColors.layer(DynamicColors.palette.m3surfaceContainerHighest, 3) : DynamicColors.palette.m3secondaryContainer - radius: Appearance.rounding.full + color: root.urgency === "critical" ? Colors.palette.m3error : root.urgency === "low" ? Colors.layer(Colors.palette.m3surfaceContainerHighest, 3) : Colors.palette.m3secondaryContainer + radius: Tokens.rounding.full Loader { anchors.centerIn: parent @@ -101,14 +102,14 @@ CustomRect { anchors.right: parent.right sourceComponent: CustomRect { - color: root.urgency === "critical" ? DynamicColors.palette.m3error : root.urgency === "low" ? DynamicColors.palette.m3surfaceContainerHighest : DynamicColors.palette.m3secondaryContainer + color: root.urgency === "critical" ? Colors.palette.m3error : root.urgency === "low" ? Colors.palette.m3surfaceContainerHighest : Colors.palette.m3secondaryContainer implicitHeight: Config.notifs.sizes.badge implicitWidth: Config.notifs.sizes.badge - radius: Appearance.rounding.full + radius: Tokens.rounding.full ColoredIcon { anchors.centerIn: parent - color: root.urgency === "critical" ? DynamicColors.palette.m3onError : root.urgency === "low" ? DynamicColors.palette.m3onSurface : DynamicColors.palette.m3onSecondaryContainer + color: root.urgency === "critical" ? Colors.palette.m3onError : root.urgency === "low" ? Colors.palette.m3onSurface : Colors.palette.m3onSecondaryContainer implicitSize: Math.round(Config.notifs.sizes.badge * 0.6) layer.enabled: root.appIcon.endsWith("symbolic") source: Quickshell.iconPath(root.appIcon) @@ -118,38 +119,38 @@ CustomRect { } ColumnLayout { - Layout.bottomMargin: -Appearance.padding.small / 2 - (root.expanded ? 0 : spacing) + Layout.bottomMargin: -Tokens.padding.small / 2 - (root.expanded ? 0 : spacing) Layout.fillWidth: true - Layout.topMargin: -Appearance.padding.small - spacing: Math.round(Appearance.spacing.small / 2) + Layout.topMargin: -Tokens.padding.small + spacing: Math.round(Tokens.spacing.small / 2) RowLayout { Layout.bottomMargin: -parent.spacing Layout.fillWidth: true - spacing: Appearance.spacing.smaller + spacing: Tokens.spacing.smaller CustomText { Layout.fillWidth: true - color: DynamicColors.palette.m3onSurfaceVariant + color: Colors.palette.m3onSurfaceVariant elide: Text.ElideRight - font.pointSize: Appearance.font.size.small + font.pointSize: Tokens.font.size.small text: root.modelData } CustomText { animate: true - color: DynamicColors.palette.m3outline - font.pointSize: Appearance.font.size.small + color: Colors.palette.m3outline + font.pointSize: Tokens.font.size.small text: root.notifs[0]?.timeStr ?? "" } CustomRect { Layout.preferredWidth: root.notifs.length > Config.notifs.groupPreviewNum ? implicitWidth : 0 - color: root.urgency === "critical" ? DynamicColors.palette.m3error : DynamicColors.layer(DynamicColors.palette.m3surfaceContainerHighest, 2) - implicitHeight: groupCount.implicitHeight + Appearance.padding.small - implicitWidth: expandBtn.implicitWidth + Appearance.padding.smaller * 2 + color: root.urgency === "critical" ? Colors.palette.m3error : Colors.layer(Colors.palette.m3surfaceContainerHighest, 2) + implicitHeight: groupCount.implicitHeight + Tokens.padding.small + implicitWidth: expandBtn.implicitWidth + Tokens.padding.smaller * 2 opacity: root.notifs.length > Config.notifs.groupPreviewNum ? 1 : 0 - radius: Appearance.rounding.full + radius: Tokens.rounding.full Behavior on Layout.preferredWidth { Anim { @@ -161,7 +162,7 @@ CustomRect { } StateLayer { - color: root.urgency === "critical" ? DynamicColors.palette.m3onError : DynamicColors.palette.m3onSurface + color: root.urgency === "critical" ? Colors.palette.m3onError : Colors.palette.m3onSurface onClicked: { root.expanded = !root.expanded; @@ -172,22 +173,22 @@ CustomRect { id: expandBtn anchors.centerIn: parent - spacing: Appearance.spacing.small / 2 + spacing: Tokens.spacing.small / 2 CustomText { id: groupCount - Layout.leftMargin: Appearance.padding.small / 2 + Layout.leftMargin: Tokens.padding.small / 2 animate: true - color: root.urgency === "critical" ? DynamicColors.palette.m3onError : DynamicColors.palette.m3onSurface - font.pointSize: Appearance.font.size.small + color: root.urgency === "critical" ? Colors.palette.m3onError : Colors.palette.m3onSurface + font.pointSize: Tokens.font.size.small text: root.notifs.length } MaterialIcon { - Layout.rightMargin: -Appearance.padding.small / 2 + Layout.rightMargin: -Tokens.padding.small / 2 animate: true - color: root.urgency === "critical" ? DynamicColors.palette.m3onError : DynamicColors.palette.m3onSurface + color: root.urgency === "critical" ? Colors.palette.m3onError : Colors.palette.m3onSurface text: root.expanded ? "expand_less" : "expand_more" } } @@ -283,13 +284,13 @@ CustomRect { required property NotifServer.Notif modelData Layout.fillWidth: true - color: root.urgency === "critical" ? DynamicColors.palette.m3onSecondaryContainer : DynamicColors.palette.m3onSurface + color: root.urgency === "critical" ? Colors.palette.m3onSecondaryContainer : Colors.palette.m3onSurface text: { if (!Config.lock.showNotifContent) return "Unlock to view"; const summary = modelData.summary.replace(/\n/g, " "); const body = modelData.body.replace(/\n/g, " "); - const color = root.urgency === "critical" ? DynamicColors.palette.m3secondary : DynamicColors.palette.m3outline; + const color = root.urgency === "critical" ? Colors.palette.m3secondary : Colors.palette.m3outline; if (metrics.text === metrics.elidedText) return `${summary} ${body}`; diff --git a/Modules/Lock/Pam.qml b/Modules/Lock/Pam.qml index 64edbd4..89094d1 100644 --- a/Modules/Lock/Pam.qml +++ b/Modules/Lock/Pam.qml @@ -3,7 +3,7 @@ import Quickshell.Io import Quickshell.Wayland import Quickshell.Services.Pam import QtQuick -import qs.Config +import ZShell.Config Scope { id: root diff --git a/Modules/Lock/Resources.qml b/Modules/Lock/Resources.qml index 4dbccf2..0924921 100644 --- a/Modules/Lock/Resources.qml +++ b/Modules/Lock/Resources.qml @@ -4,9 +4,10 @@ import QtQuick import QtQuick.Layouts import M3Shapes import ZShell.Services +import ZShell.Config import qs.Components -import qs.Config import qs.Effects +import qs.Services CustomRect { id: root @@ -16,9 +17,9 @@ CustomRect { return 1 + Math.pow(Math.abs(diff), 0.8) * Math.sign(diff); } - color: DynamicColors.tPalette.m3surfaceContainer + color: Colors.tPalette.m3surfaceContainer implicitHeight: layout.implicitHeight + layout.anchors.margins * 2 - radius: Appearance.rounding.small + radius: Tokens.rounding.small ServiceRef { service: Cpu @@ -36,25 +37,25 @@ CustomRect { id: layout anchors.fill: parent - anchors.margins: Appearance.padding.large - spacing: Appearance.spacing.large + anchors.margins: Tokens.padding.large + spacing: Tokens.spacing.large Resource { id: cpu - fgColor: DynamicColors.palette.m3primary + fgColor: Colors.palette.m3primary icon: "memory" value: Cpu.percentage } Resource { - fgColor: DynamicColors.palette.m3tertiary + fgColor: Colors.palette.m3tertiary icon: "memory_alt" value: Memory.percentage } Resource { - fgColor: DynamicColors.palette.m3secondary + fgColor: Colors.palette.m3secondary icon: "hard_disk" value: Storage.percentage } @@ -76,7 +77,7 @@ CustomRect { MaterialIcon { anchors.centerIn: parent color: res.fgColor - font.pointSize: Appearance.font.size.extraLarge + font.pointSize: Tokens.font.size.extraLarge text: res.icon } } diff --git a/Modules/Lock/UserImage.qml b/Modules/Lock/UserImage.qml index a3fae8c..57133db 100644 --- a/Modules/Lock/UserImage.qml +++ b/Modules/Lock/UserImage.qml @@ -8,7 +8,7 @@ Item { ClippingRectangle { anchors.fill: parent - radius: Appearance.rounding.full + radius: Tokens.rounding.full Image { id: userImage diff --git a/Modules/Lock/Weather/BriefInfo.qml b/Modules/Lock/Weather/BriefInfo.qml index d6244c3..5030448 100644 --- a/Modules/Lock/Weather/BriefInfo.qml +++ b/Modules/Lock/Weather/BriefInfo.qml @@ -1,40 +1,41 @@ import QtQuick import QtQuick.Layouts import qs.Components -import qs.Config +import ZShell.Config import qs.Helpers +import qs.Services ColumnLayout { id: root required property int rootHeight - spacing: Appearance.spacing.extraSmall + spacing: Tokens.spacing.extraSmall CustomText { Layout.alignment: Qt.AlignHCenter animate: true - color: DynamicColors.palette.m3onSurfaceVariant - font.pointSize: Appearance.font.size.large + color: Colors.palette.m3onSurfaceVariant + font.pointSize: Tokens.font.size.large text: Weather.description } RowLayout { Layout.alignment: Qt.AlignHCenter - spacing: Appearance.spacing.small + spacing: Tokens.spacing.small CustomText { id: temp animate: true - color: DynamicColors.palette.m3primary - font.pointSize: Appearance.font.size.large + color: Colors.palette.m3primary + font.pointSize: Tokens.font.size.large text: Weather.temp } MaterialIcon { animate: true - color: DynamicColors.palette.m3secondary + color: Colors.palette.m3secondary text: Weather.icon } } @@ -42,8 +43,8 @@ ColumnLayout { CustomText { Layout.alignment: Qt.AlignHCenter animate: true - color: DynamicColors.palette.m3onSurfaceVariant - font.pointSize: Appearance.font.size.large + color: Colors.palette.m3onSurfaceVariant + font.pointSize: Tokens.font.size.large text: qsTr("Feels like %1").arg(Weather.temp) visible: root.rootHeight > 550 } @@ -51,8 +52,8 @@ ColumnLayout { CustomText { Layout.alignment: Qt.AlignHCenter animate: true - color: DynamicColors.palette.m3onSurfaceVariant - font.pointSize: Appearance.font.size.medium + color: Colors.palette.m3onSurfaceVariant + font.pointSize: Tokens.font.size.medium text: { const today = Weather.forecast[0]; return qsTr("High %1 • Low %2").arg(Weather.formatTemp(today?.maxTempC)).arg(Weather.formatTemp(today?.minTempC)); diff --git a/Modules/Lock/Weather/Forecast.qml b/Modules/Lock/Weather/Forecast.qml index 222c858..adc744e 100644 --- a/Modules/Lock/Weather/Forecast.qml +++ b/Modules/Lock/Weather/Forecast.qml @@ -4,33 +4,34 @@ import M3Shapes import ZShell import qs.Components import qs.Helpers -import qs.Config +import ZShell.Config +import qs.Services CustomRect { id: root - color: DynamicColors.layer(DynamicColors.palette.m3surfaceContainerHigh, 2) - implicitHeight: header.anchors.margins + header.implicitHeight + Appearance.spacing.small + layout.implicitHeight + layout.anchors.bottomMargin - radius: Appearance.rounding.small + color: Colors.layer(Colors.palette.m3surfaceContainerHigh, 2) + implicitHeight: header.anchors.margins + header.implicitHeight + Tokens.spacing.small + layout.implicitHeight + layout.anchors.bottomMargin + radius: Tokens.rounding.small RowLayout { id: header anchors.left: parent.left - anchors.margins: Appearance.padding.largeIncreased + anchors.margins: Tokens.padding.largeIncreased anchors.top: parent.top - spacing: Appearance.spacing.small + spacing: Tokens.spacing.small MaterialIcon { Layout.topMargin: Math.round(fontInfo.pointSize * 0.12) - font.pointSize: Appearance.font.size.medium + font.pointSize: Tokens.font.size.medium text: "schedule" } CustomText { id: title - font.pointSize: Appearance.font.size.medium + font.pointSize: Tokens.font.size.medium text: qsTr("Hourly forecast") } } @@ -39,14 +40,14 @@ CustomRect { id: layout anchors.bottom: parent.bottom - anchors.bottomMargin: Appearance.padding.largeIncreased + anchors.bottomMargin: Tokens.padding.largeIncreased anchors.left: parent.left - anchors.margins: Appearance.padding.large + anchors.margins: Tokens.padding.large anchors.right: parent.right implicitHeight: contentItem.childrenRect.height model: Weather.hourlyForecast orientation: VerticalFadeListView.Horizontal - spacing: Appearance.spacing.normal + spacing: Tokens.spacing.normal delegate: ColumnLayout { id: hour @@ -55,12 +56,12 @@ CustomRect { required property int index required property var modelData - spacing: Appearance.spacing.extraSmall + spacing: Tokens.spacing.extraSmall MaterialShape { Layout.alignment: Qt.AlignHCenter - color: Qt.alpha(DynamicColors.palette.m3primary, hour.index === 0 ? 1 : 0) - implicitSize: temp.implicitHeight + Appearance.padding.normal * 2 + color: Qt.alpha(Colors.palette.m3primary, hour.index === 0 ? 1 : 0) + implicitSize: temp.implicitHeight + Tokens.padding.normal * 2 shape: MaterialShape.Cookie4Sided Behavior on color { @@ -72,30 +73,30 @@ CustomRect { id: temp anchors.centerIn: parent - color: hour.index === 0 ? DynamicColors.palette.m3onPrimary : DynamicColors.palette.m3onSurface - font.pointSize: Appearance.font.size.medium + color: hour.index === 0 ? Colors.palette.m3onPrimary : Colors.palette.m3onSurface + font.pointSize: Tokens.font.size.medium text: Weather.formatTemp(hour.cond.tempC).slice(0, -1) // Remove C/F } } MaterialIcon { Layout.alignment: Qt.AlignHCenter - color: DynamicColors.palette.m3secondary - font.pointSize: Appearance.font.size.extraLarge + color: Colors.palette.m3secondary + font.pointSize: Tokens.font.size.extraLarge text: hour.cond.icon } CustomText { Layout.alignment: Qt.AlignHCenter - color: DynamicColors.palette.m3primary + color: Colors.palette.m3primary text: hour.cond.precipChance + "%" } CustomText { Layout.alignment: Qt.AlignHCenter - Layout.topMargin: Appearance.spacing.extraSmall - color: DynamicColors.palette.m3onSurfaceVariant - font.pointSize: Appearance.font.size.small + Layout.topMargin: Tokens.spacing.extraSmall + color: Colors.palette.m3onSurfaceVariant + font.pointSize: Tokens.font.size.small text: hour.index === 0 ? qsTr("Now") : Qt.formatDateTime(new Date(hour.cond.timestamp.replace("T", " ")), Config.services.useTwelveHourClock ? "ha" : "hh:00") } } diff --git a/Modules/Lock/WeatherInfo.qml b/Modules/Lock/WeatherInfo.qml index f7434ee..295f4c4 100644 --- a/Modules/Lock/WeatherInfo.qml +++ b/Modules/Lock/WeatherInfo.qml @@ -1,8 +1,9 @@ import QtQuick import qs.Modules.Lock.Weather -import qs.Config +import ZShell.Config import qs.Components import qs.Helpers +import qs.Services CustomRect { id: root @@ -10,14 +11,14 @@ CustomRect { required property int rootHeight readonly property bool showForecast: rootHeight >= 700 - color: DynamicColors.tPalette.m3surfaceContainer + color: Colors.tPalette.m3surfaceContainer implicitHeight: { const base = brief.implicitHeight + brief.anchors.topMargin; if (showForecast) - return base + Appearance.spacing.large + forecast.implicitHeight + forecast.anchors.margins; + return base + Tokens.spacing.large + forecast.implicitHeight + forecast.anchors.margins; return base + brief.anchors.topMargin; } - radius: Appearance.rounding.small + radius: Tokens.rounding.small Timer { interval: 900000 // 15 minutes @@ -33,7 +34,7 @@ CustomRect { anchors.horizontalCenter: parent.horizontalCenter anchors.top: parent.top - anchors.topMargin: Appearance.padding.extraLarge + anchors.topMargin: Tokens.padding.extraLarge rootHeight: root.rootHeight } @@ -43,7 +44,7 @@ CustomRect { active: root.showForecast anchors.bottom: parent.bottom anchors.left: parent.left - anchors.margins: Appearance.padding.large + anchors.margins: Tokens.padding.large anchors.right: parent.right asynchronous: true diff --git a/Modules/MediaWidget.qml b/Modules/MediaWidget.qml index 644446a..f7de773 100644 --- a/Modules/MediaWidget.qml +++ b/Modules/MediaWidget.qml @@ -2,8 +2,9 @@ import QtQuick import QtQuick.Layouts import qs.Components import qs.Daemons -import qs.Config +import ZShell.Config import qs.Helpers +import qs.Services CustomRect { id: root @@ -11,10 +12,10 @@ CustomRect { readonly property string currentMedia: (Players.active?.trackTitle ?? qsTr("No media")) || qsTr("Unknown title") readonly property int textWidth: Math.min(metrics.width, 200) - color: DynamicColors.tPalette.m3surfaceContainer - implicitHeight: Config.bar.height + Appearance.padding.smallest * 2 - implicitWidth: layout.implicitWidth + Appearance.padding.normal * 2 - radius: Appearance.rounding.full + color: Colors.tPalette.m3surfaceContainer + implicitHeight: Config.bar.height + Tokens.padding.smallest * 2 + implicitWidth: layout.implicitWidth + Tokens.padding.normal * 2 + radius: Tokens.rounding.full Behavior on implicitWidth { Anim { @@ -40,8 +41,8 @@ CustomRect { MaterialIcon { animate: true - color: Players.active?.isPlaying ? DynamicColors.palette.m3primary : DynamicColors.palette.m3onSurface - font.pointSize: Appearance.font.size.larger + color: Players.active?.isPlaying ? Colors.palette.m3primary : Colors.palette.m3onSurface + font.pointSize: Tokens.font.size.larger text: Players.active?.isPlaying ? "music_note" : "music_off" } @@ -50,8 +51,8 @@ CustomRect { Layout.preferredWidth: root.textWidth animate: true - color: Players.active?.isPlaying ? DynamicColors.palette.m3primary : DynamicColors.palette.m3onSurface - font.pointSize: Appearance.font.size.normal + color: Players.active?.isPlaying ? Colors.palette.m3primary : Colors.palette.m3onSurface + font.pointSize: Tokens.font.size.normal horizontalAlignment: Text.AlignHCenter marqueeEnabled: false pauseMs: 4000 diff --git a/Modules/NotifBell.qml b/Modules/NotifBell.qml index ba15f26..a5543e8 100644 --- a/Modules/NotifBell.qml +++ b/Modules/NotifBell.qml @@ -1,8 +1,9 @@ import Quickshell import QtQuick -import qs.Config +import ZShell.Config import qs.Daemons import qs.Components +import qs.Services CustomRect { id: root @@ -10,19 +11,19 @@ CustomRect { required property Wrapper popouts required property PersistentProperties visibilities - color: visibilities.sidebar ? DynamicColors.palette.m3primary : DynamicColors.tPalette.m3surfaceContainer - implicitHeight: Config.bar.height + Appearance.padding.smallest * 2 + color: visibilities.sidebar ? Colors.palette.m3primary : Colors.tPalette.m3surfaceContainer + implicitHeight: Config.bar.height + Tokens.padding.smallest * 2 implicitWidth: implicitHeight - radius: Appearance.rounding.full + radius: Tokens.rounding.full MaterialIcon { id: notificationCenterIcon anchors.centerIn: parent - color: root.visibilities.sidebar ? DynamicColors.palette.m3onPrimary : DynamicColors.palette.m3onSurface + color: root.visibilities.sidebar ? Colors.palette.m3onPrimary : Colors.palette.m3onSurface fill: root.visibilities.sidebar ? 1 : 0 font.family: "Material Symbols Rounded" - font.pointSize: Appearance.font.size.larger + font.pointSize: Tokens.font.size.larger text: NotifServer.list.length ? "\uf4fe" : "\ue7f4" Behavior on color { @@ -36,7 +37,7 @@ CustomRect { } StateLayer { - color: root.visibilities.sidebar ? DynamicColors.palette.m3onPrimary : DynamicColors.palette.m3onSurface + color: root.visibilities.sidebar ? Colors.palette.m3onPrimary : Colors.palette.m3onSurface onClicked: { root.visibilities.sidebar = !root.visibilities.sidebar; diff --git a/Modules/Notifications/Content.qml b/Modules/Notifications/Content.qml index 568f81e..5d27526 100644 --- a/Modules/Notifications/Content.qml +++ b/Modules/Notifications/Content.qml @@ -4,14 +4,14 @@ import Quickshell import Quickshell.Widgets import QtQuick import qs.Components -import qs.Config +import ZShell.Config import qs.Daemons import qs.Helpers Item { id: root - readonly property int padding: Appearance.padding.smaller + readonly property int padding: Tokens.padding.smaller required property Item panels required property PersistentProperties visibilities @@ -23,7 +23,7 @@ Item { if (count === 0) return 0; - let height = (count - 1) * Appearance.spacing.small; + let height = (count - 1) * Tokens.spacing.small; for (let i = 0; i < count; i++) height += (list.itemAtIndex(i) as NotifWrapper)?.nonAnimHeight ?? 0; @@ -31,13 +31,13 @@ Item { return 0; if (visibilities.osd) { - const h = panels.osd.y - Appearance.spacing.small * 2 - padding * 2; + const h = panels.osd.y - Tokens.spacing.small * 2 - padding * 2; if (height > h) height = h; } if (visibilities.session) { - const h = panels.session.y - Appearance.spacing.small * 2 - padding * 2; + const h = panels.session.y - Tokens.spacing.small * 2 - padding * 2; if (height > h) height = h; } @@ -55,7 +55,7 @@ Item { anchors.fill: parent anchors.margins: root.padding color: "transparent" - radius: Appearance.rounding.normal - root.padding + radius: Tokens.rounding.normal - root.padding CustomListView { id: list @@ -92,8 +92,8 @@ Item { } component Anim: NumberAnimation { - duration: Appearance.anim.durations.expressiveDefaultSpatial - easing.bezierCurve: Appearance.anim.curves.expressiveDefaultSpatial + duration: Tokens.anim.durations.expressiveDefaultSpatial + easing.bezierCurve: Tokens.anim.curves.expressiveDefaultSpatial } component NotifWrapper: Item { id: wrapper @@ -103,7 +103,7 @@ Item { required property NotifServer.Notif modelData readonly property alias nonAnimHeight: notif.nonAnimHeight - implicitHeight: notif.implicitHeight + (idx === 0 ? 0 : Appearance.spacing.small) + implicitHeight: notif.implicitHeight + (idx === 0 ? 0 : Tokens.spacing.small) implicitWidth: notif.implicitWidth ListView.onRemove: removeAnim.start() @@ -140,8 +140,6 @@ Item { } Anim { - duration: MaterialEasing.expressiveEffectsTime - easing.bezierCurve: MaterialEasing.expressiveEffects property: "x" target: notif to: (notif.x >= 0 ? Config.notifs.sizes.width : -Config.notifs.sizes.width) * 2 @@ -160,7 +158,7 @@ Item { color: "transparent" implicitHeight: notif.implicitHeight implicitWidth: notif.implicitWidth - radius: Appearance.rounding.small + radius: Tokens.rounding.small Notification { id: notif diff --git a/Modules/Notifications/Notification.qml b/Modules/Notifications/Notification.qml index fd4e9e0..f0ffc6a 100644 --- a/Modules/Notifications/Notification.qml +++ b/Modules/Notifications/Notification.qml @@ -7,8 +7,9 @@ import Quickshell.Services.Notifications import ZShell.Components import qs.Daemons import qs.Helpers -import qs.Config +import ZShell.Config import qs.Components +import qs.Services CustomRect { id: root @@ -17,16 +18,16 @@ CustomRect { readonly property bool hasAppIcon: modelData.appIcon.length > 0 readonly property bool hasImage: modelData.image.length > 0 required property NotifServer.Notif modelData - readonly property int nonAnimHeight: summary.implicitHeight + (root.expanded ? Appearance.spacing.extraSmall * 2 + appName.height + body.height + actions.height + actions.anchors.topMargin : bodyPreview.height) + inner.anchors.margins * 2 + readonly property int nonAnimHeight: summary.implicitHeight + (root.expanded ? Tokens.spacing.extraSmall * 2 + appName.height + body.height + actions.height + actions.anchors.topMargin : bodyPreview.height) + inner.anchors.margins * 2 - color: root.modelData.urgency === NotificationUrgency.Critical ? DynamicColors.palette.m3secondaryContainer : DynamicColors.tPalette.m3surfaceContainer + color: root.modelData.urgency === NotificationUrgency.Critical ? Colors.palette.m3secondaryContainer : Colors.tPalette.m3surfaceContainer implicitHeight: inner.implicitHeight - radius: Appearance.rounding.small + radius: Tokens.rounding.small x: implicitWidth Behavior on x { Anim { - easing.bezierCurve: Appearance.anim.curves.emphasizedDecel + easing.bezierCurve: Tokens.anim.curves.emphasizedDecel } } @@ -87,7 +88,7 @@ CustomRect { id: inner anchors.left: parent.left - anchors.margins: Appearance.padding.normal + anchors.margins: Tokens.padding.normal anchors.right: parent.right anchors.top: parent.top implicitHeight: root.nonAnimHeight @@ -109,10 +110,10 @@ CustomRect { width: Config.notifs.sizes.image sourceComponent: CustomClippingRect { - color: root.modelData.urgency === NotificationUrgency.Critical ? DynamicColors.palette.m3error : root.modelData.urgency === NotificationUrgency.Low ? DynamicColors.layer(DynamicColors.palette.m3surfaceContainerHighest, 2) : DynamicColors.palette.m3secondaryContainer + color: root.modelData.urgency === NotificationUrgency.Critical ? Colors.palette.m3error : root.modelData.urgency === NotificationUrgency.Low ? Colors.layer(Colors.palette.m3surfaceContainerHighest, 2) : Colors.palette.m3secondaryContainer implicitHeight: Config.notifs.sizes.image implicitWidth: Config.notifs.sizes.image - radius: Appearance.rounding.full + radius: Tokens.rounding.full Image { anchors.fill: parent @@ -139,10 +140,10 @@ CustomRect { asynchronous: true sourceComponent: CustomRect { - color: root.modelData.urgency === NotificationUrgency.Critical ? DynamicColors.palette.m3error : root.modelData.urgency === NotificationUrgency.Low ? DynamicColors.layer(DynamicColors.palette.m3surfaceContainerHighest, 2) : DynamicColors.palette.m3secondaryContainer + color: root.modelData.urgency === NotificationUrgency.Critical ? Colors.palette.m3error : root.modelData.urgency === NotificationUrgency.Low ? Colors.layer(Colors.palette.m3surfaceContainerHighest, 2) : Colors.palette.m3secondaryContainer implicitHeight: root.hasImage ? Config.notifs.sizes.badge : Config.notifs.sizes.image implicitWidth: root.hasImage ? Config.notifs.sizes.badge : Config.notifs.sizes.image - radius: Appearance.rounding.full + radius: Tokens.rounding.full Loader { id: icon @@ -155,7 +156,7 @@ CustomRect { sourceComponent: ColoredIcon { anchors.fill: parent - color: root.modelData.urgency === NotificationUrgency.Critical ? DynamicColors.palette.m3onError : root.modelData.urgency === NotificationUrgency.Low ? DynamicColors.palette.m3onSurface : DynamicColors.palette.m3onSecondaryContainer + color: root.modelData.urgency === NotificationUrgency.Critical ? Colors.palette.m3onError : root.modelData.urgency === NotificationUrgency.Low ? Colors.palette.m3onSurface : Colors.palette.m3onSecondaryContainer layer.enabled: root.modelData.appIcon.endsWith("symbolic") source: Quickshell.iconPath(root.modelData.appIcon) } @@ -168,7 +169,7 @@ CustomRect { asynchronous: true sourceComponent: MaterialIcon { - color: root.modelData.urgency === NotificationUrgency.Critical ? DynamicColors.palette.m3onError : root.modelData.urgency === NotificationUrgency.Low ? DynamicColors.palette.m3onSurface : DynamicColors.palette.m3onSecondaryContainer + color: root.modelData.urgency === NotificationUrgency.Critical ? Colors.palette.m3onError : root.modelData.urgency === NotificationUrgency.Low ? Colors.palette.m3onSurface : Colors.palette.m3onSecondaryContainer text: Icons.getNotifIcon(root.modelData.summary, root.modelData.urgency) } } @@ -188,7 +189,7 @@ CustomRect { capStyle: ShapePath.RoundCap fillColor: "transparent" - strokeColor: DynamicColors.palette.m3primary + strokeColor: Colors.palette.m3primary strokeWidth: 2 PathAngleArc { @@ -196,14 +197,14 @@ CustomRect { centerX: progressIndicator.width / 2 centerY: progressIndicator.height / 2 - radiusX: progressIndicator.width / 2 - Appearance.padding.extraSmall / 2 - radiusY: progressIndicator.height / 2 - Appearance.padding.extraSmall / 2 + radiusX: progressIndicator.width / 2 - Tokens.padding.extraSmall / 2 + radiusY: progressIndicator.height / 2 - Tokens.padding.extraSmall / 2 startAngle: -90 sweepAngle: ((root.modelData.hints.value ?? 0) / 100) * 360 Behavior on sweepAngle { Anim { - easing.bezierCurve: Appearance.anim.curves.emphasizedDecel + easing.bezierCurve: Tokens.anim.curves.emphasizedDecel } } } @@ -214,10 +215,10 @@ CustomRect { id: appName anchors.left: image.right - anchors.leftMargin: Appearance.spacing.small + anchors.leftMargin: Tokens.spacing.small anchors.top: parent.top animate: true - color: DynamicColors.palette.m3onSurfaceVariant + color: Colors.palette.m3onSurfaceVariant maximumLineCount: 1 opacity: root.expanded ? 1 : 0 text: appNameMetrics.elidedText @@ -233,7 +234,7 @@ CustomRect { id: appNameMetrics elide: Text.ElideRight - elideWidth: expandBtn.x - time.width - timeSep.width - summary.x - Appearance.spacing.small * 3 + elideWidth: expandBtn.x - time.width - timeSep.width - summary.x - Tokens.spacing.small * 3 font: appName.font text: root.modelData.appName } @@ -242,10 +243,10 @@ CustomRect { id: summary anchors.left: image.right - anchors.leftMargin: Appearance.spacing.small + anchors.leftMargin: Tokens.spacing.small anchors.top: parent.top animate: true - font.pointSize: Appearance.font.size.small + font.pointSize: Tokens.font.size.small height: implicitHeight maximumLineCount: 1 text: summaryMetrics.elidedText @@ -259,9 +260,9 @@ CustomRect { when: root.expanded PropertyChanges { - body.anchors.topMargin: Appearance.spacing.extraSmall - bodyPreview.anchors.topMargin: Appearance.spacing.extraSmall - summary.anchors.topMargin: Appearance.spacing.extraSmall + body.anchors.topMargin: Tokens.spacing.extraSmall + bodyPreview.anchors.topMargin: Tokens.spacing.extraSmall + summary.anchors.topMargin: Tokens.spacing.extraSmall summary.maximumLineCount: undefined } @@ -289,7 +290,7 @@ CustomRect { id: summaryMetrics elide: Text.ElideRight - elideWidth: expandBtn.x - time.width - timeSep.width - summary.x - Appearance.spacing.small * 3 + elideWidth: expandBtn.x - time.width - timeSep.width - summary.x - Tokens.spacing.small * 3 font: summary.font text: root.modelData.summary } @@ -298,9 +299,9 @@ CustomRect { id: timeSep anchors.left: summary.right - anchors.leftMargin: Appearance.spacing.small + anchors.leftMargin: Tokens.spacing.small anchors.top: parent.top - color: DynamicColors.palette.m3onSurfaceVariant + color: Colors.palette.m3onSurfaceVariant text: "•" states: State { @@ -322,11 +323,11 @@ CustomRect { id: time anchors.left: timeSep.right - anchors.leftMargin: Appearance.spacing.small + anchors.leftMargin: Tokens.spacing.small anchors.top: parent.top animate: true - color: DynamicColors.palette.m3onSurfaceVariant - font.pointSize: Appearance.font.size.small + color: Colors.palette.m3onSurfaceVariant + font.pointSize: Tokens.font.size.small horizontalAlignment: Text.AlignLeft text: root.modelData.timeStr } @@ -336,13 +337,13 @@ CustomRect { anchors.right: parent.right anchors.top: parent.top - anchors.topMargin: -Appearance.padding.extraSmall + anchors.topMargin: -Tokens.padding.extraSmall implicitHeight: expandIcon.implicitHeight implicitWidth: expandIcon.implicitHeight StateLayer { - color: root.modelData.urgency === NotificationUrgency.Critical ? DynamicColors.palette.m3onSecondaryContainer : DynamicColors.palette.m3onSurface - radius: Appearance.rounding.full + color: root.modelData.urgency === NotificationUrgency.Critical ? Colors.palette.m3onSecondaryContainer : Colors.palette.m3onSurface + radius: Tokens.rounding.full onClicked: root.expanded = !root.expanded } @@ -371,11 +372,11 @@ CustomRect { anchors.left: summary.left anchors.right: expandBtn.left - anchors.rightMargin: Appearance.spacing.small + anchors.rightMargin: Tokens.spacing.small anchors.top: summary.bottom animate: true - color: DynamicColors.palette.m3onSurfaceVariant - font.pointSize: Appearance.font.size.small + color: Colors.palette.m3onSurfaceVariant + font.pointSize: Tokens.font.size.small opacity: root.expanded ? 0 : 1 text: bodyPreviewMetrics.elidedText textFormat: Text.MarkdownText @@ -401,10 +402,10 @@ CustomRect { anchors.left: summary.left anchors.right: expandBtn.left - anchors.rightMargin: Appearance.spacing.small + anchors.rightMargin: Tokens.spacing.small anchors.top: summary.bottom animate: true - color: DynamicColors.palette.m3onSurfaceVariant + color: Colors.palette.m3onSurfaceVariant height: text ? implicitHeight : 0 opacity: root.expanded ? 1 : 0 text: root.modelData.body @@ -432,9 +433,9 @@ CustomRect { anchors.left: parent.left anchors.right: parent.right anchors.top: body.bottom - anchors.topMargin: Appearance.spacing.small + anchors.topMargin: Tokens.spacing.small opacity: root.expanded ? 1 : 0 - spacing: Appearance.spacing.extraSmall + spacing: Tokens.spacing.extraSmall Behavior on opacity { Anim { @@ -446,10 +447,10 @@ CustomRect { enabled: root.expanded fillWidth: root.modelData.actions.length === 0 icon: "close" - inactiveColor: root.modelData.urgency === NotificationUrgency.Critical ? DynamicColors.palette.m3secondary : DynamicColors.layer(DynamicColors.palette.m3surfaceContainerHighest, 2) - inactiveOnColor: root.modelData.urgency === NotificationUrgency.Critical ? DynamicColors.palette.m3onSecondary : DynamicColors.palette.m3onSurfaceVariant + inactiveColor: root.modelData.urgency === NotificationUrgency.Critical ? Colors.palette.m3secondary : Colors.layer(Colors.palette.m3surfaceContainerHighest, 2) + inactiveOnColor: root.modelData.urgency === NotificationUrgency.Critical ? Colors.palette.m3onSecondary : Colors.palette.m3onSurfaceVariant isRound: true - padding: Appearance.padding.extraSmall + padding: Tokens.padding.extraSmall shapeMorph: true onClicked: root.modelData.close() @@ -465,16 +466,16 @@ CustomRect { fillWidth: true font: { const f = Qt.font(font); - f.pointSize = Appearance.font.size.small; + f.pointSize = Tokens.font.size.small; return f; } implicitWidth: label.implicitWidth - inactiveColor: root.modelData.urgency === NotificationUrgency.Critical ? DynamicColors.palette.m3secondary : DynamicColors.layer(DynamicColors.palette.m3surfaceContainerHighest, 2) - inactiveOnColor: root.modelData.urgency === NotificationUrgency.Critical ? DynamicColors.palette.m3onSecondary : DynamicColors.palette.m3onSurfaceVariant + inactiveColor: root.modelData.urgency === NotificationUrgency.Critical ? Colors.palette.m3secondary : Colors.layer(Colors.palette.m3surfaceContainerHighest, 2) + inactiveOnColor: root.modelData.urgency === NotificationUrgency.Critical ? Colors.palette.m3onSecondary : Colors.palette.m3onSurfaceVariant isRound: true label.anchors.centerIn: undefined label.anchors.left: left - label.anchors.margins: Appearance.padding.normal + label.anchors.margins: Tokens.padding.normal label.anchors.right: right label.anchors.verticalCenter: verticalCenter label.elide: Text.ElideRight @@ -490,11 +491,11 @@ CustomRect { enabled: root.expanded fillWidth: root.modelData.actions.length === 0 icon: copyTimer.running ? "inventory" : "content_copy" - inactiveColor: root.modelData.urgency === NotificationUrgency.Critical ? DynamicColors.palette.m3secondary : DynamicColors.layer(DynamicColors.palette.m3surfaceContainerHighest, 2) - inactiveOnColor: root.modelData.urgency === NotificationUrgency.Critical ? DynamicColors.palette.m3onSecondary : DynamicColors.palette.m3onSurfaceVariant + inactiveColor: root.modelData.urgency === NotificationUrgency.Critical ? Colors.palette.m3secondary : Colors.layer(Colors.palette.m3surfaceContainerHighest, 2) + inactiveOnColor: root.modelData.urgency === NotificationUrgency.Critical ? Colors.palette.m3onSecondary : Colors.palette.m3onSurfaceVariant isRound: true label.animate: true - padding: Appearance.padding.extraSmall + padding: Tokens.padding.extraSmall shapeMorph: true onClicked: { diff --git a/Modules/Notifications/Sidebar/Content.qml b/Modules/Notifications/Sidebar/Content.qml index 6b3e7da..3f50c67 100644 --- a/Modules/Notifications/Sidebar/Content.qml +++ b/Modules/Notifications/Sidebar/Content.qml @@ -1,7 +1,8 @@ import qs.Components -import qs.Config +import ZShell.Config import QtQuick import QtQuick.Layouts +import qs.Services Item { id: root @@ -13,13 +14,13 @@ Item { id: layout anchors.fill: parent - spacing: Appearance.spacing.small + spacing: Tokens.spacing.small CustomRect { Layout.fillHeight: true Layout.fillWidth: true - color: DynamicColors.tPalette.m3surfaceContainerLow - radius: Appearance.rounding.smallest + color: Colors.tPalette.m3surfaceContainerLow + radius: Tokens.rounding.smallest NotifDock { props: root.props @@ -29,8 +30,8 @@ Item { CustomRect { Layout.fillWidth: true - Layout.topMargin: Appearance.padding.normal - layout.spacing - color: DynamicColors.tPalette.m3outlineVariant + Layout.topMargin: Tokens.padding.normal - layout.spacing + color: Colors.tPalette.m3outlineVariant implicitHeight: 1 } } diff --git a/Modules/Notifications/Sidebar/Notif.qml b/Modules/Notifications/Sidebar/Notif.qml index 53445e9..faebfaa 100644 --- a/Modules/Notifications/Sidebar/Notif.qml +++ b/Modules/Notifications/Sidebar/Notif.qml @@ -1,12 +1,13 @@ pragma ComponentBehavior: Bound import qs.Components -import qs.Config +import ZShell.Config import qs.Daemons import qs.Modules import Quickshell import QtQuick import QtQuick.Layouts +import qs.Services CustomRect { id: root @@ -19,7 +20,7 @@ CustomRect { required property var visibilities color: { - const c = root.modelData?.urgency === "critical" ? DynamicColors.palette.m3secondaryContainer : DynamicColors.layer(DynamicColors.palette.m3surfaceContainerHigh, 2); + const c = root.modelData?.urgency === "critical" ? Colors.palette.m3secondaryContainer : Colors.layer(Colors.palette.m3surfaceContainerHigh, 2); return expanded ? c : Qt.alpha(c, 0); } implicitHeight: nonAnimHeight @@ -28,8 +29,6 @@ CustomRect { Behavior on implicitHeight { Anim { - duration: MaterialEasing.expressiveEffectsTime - easing.bezierCurve: MaterialEasing.expressiveEffects } } states: State { @@ -63,7 +62,7 @@ CustomRect { anchors.left: parent.left anchors.top: parent.top - color: root.modelData?.urgency === "critical" ? DynamicColors.palette.m3onSecondaryContainer : DynamicColors.palette.m3onSurface + color: root.modelData?.urgency === "critical" ? Colors.palette.m3onSecondaryContainer : Colors.palette.m3onSurface elide: Text.ElideRight maximumLineCount: 1 text: root.modelData?.summary ?? "" @@ -90,7 +89,7 @@ CustomRect { shouldBeActive: !root.expanded sourceComponent: CustomText { - color: root.modelData?.urgency === "critical" ? DynamicColors.palette.m3secondary : DynamicColors.palette.m3outline + color: root.modelData?.urgency === "critical" ? Colors.palette.m3secondary : Colors.palette.m3outline elide: Text.ElideRight text: String(root.modelData?.body ?? "").replace(/\n/g, " ") textFormat: Text.StyledText @@ -106,7 +105,7 @@ CustomRect { sourceComponent: CustomText { animate: true - color: DynamicColors.palette.m3outline + color: Colors.palette.m3outline font.pointSize: 11 text: root.modelData?.timeStr ?? "" } @@ -130,7 +129,7 @@ CustomRect { id: body Layout.fillWidth: true - color: root.modelData?.urgency === "critical" ? DynamicColors.palette.m3secondary : DynamicColors.palette.m3onSurface + color: root.modelData?.urgency === "critical" ? Colors.palette.m3secondary : Colors.palette.m3onSurface text: String(root.modelData?.body ?? "").replace(/(.)\n(?!\n)/g, "$1\n\n") || qsTr("No body given") textFormat: Text.MarkdownText wrapMode: Text.WordWrap diff --git a/Modules/Notifications/Sidebar/NotifActionList.qml b/Modules/Notifications/Sidebar/NotifActionList.qml index 4d58aea..04877cd 100644 --- a/Modules/Notifications/Sidebar/NotifActionList.qml +++ b/Modules/Notifications/Sidebar/NotifActionList.qml @@ -1,13 +1,14 @@ pragma ComponentBehavior: Bound import qs.Components -import qs.Config +import ZShell.Config import qs.Modules import qs.Daemons import Quickshell import Quickshell.Widgets import QtQuick import QtQuick.Layouts +import qs.Services Item { id: root @@ -49,21 +50,17 @@ Item { Layout.fillHeight: true Layout.fillWidth: true Layout.preferredWidth: implicitWidth + (actionStateLayer.pressed ? 18 : 0) - color: DynamicColors.layer(DynamicColors.palette.m3surfaceContainerHighest, 4) + color: Colors.layer(Colors.palette.m3surfaceContainerHighest, 4) implicitHeight: actionInner.implicitHeight + 5 * 2 implicitWidth: actionInner.implicitWidth + 5 * 2 radius: actionStateLayer.pressed ? 6 / 2 : 6 Behavior on Layout.preferredWidth { Anim { - duration: MaterialEasing.expressiveEffectsTime - easing.bezierCurve: MaterialEasing.expressiveEffects } } Behavior on radius { Anim { - duration: MaterialEasing.expressiveEffectsTime - easing.bezierCurve: MaterialEasing.expressiveEffects } } @@ -105,7 +102,7 @@ Item { MaterialIcon { animate: action.modelData.isCopy ?? false - color: DynamicColors.palette.m3onSurfaceVariant + color: Colors.palette.m3onSurfaceVariant text: action.modelData.isCopy ? "content_copy" : "close" } } @@ -122,7 +119,7 @@ Item { id: textComp CustomText { - color: DynamicColors.palette.m3onSurfaceVariant + color: Colors.palette.m3onSurfaceVariant text: action.modelData.text } } diff --git a/Modules/Notifications/Sidebar/NotifDock.qml b/Modules/Notifications/Sidebar/NotifDock.qml index d7b45a1..8133940 100644 --- a/Modules/Notifications/Sidebar/NotifDock.qml +++ b/Modules/Notifications/Sidebar/NotifDock.qml @@ -1,13 +1,14 @@ pragma ComponentBehavior: Bound import qs.Components -import qs.Config +import ZShell.Config import qs.Modules import qs.Daemons import Quickshell import Quickshell.Widgets import QtQuick import QtQuick.Layouts +import qs.Services Item { id: root @@ -17,7 +18,7 @@ Item { required property var visibilities anchors.fill: parent - anchors.margins: Appearance.padding.normal + anchors.margins: Tokens.padding.normal Component.onCompleted: NotifServer.list.forEach(n => n.popup = false) @@ -36,7 +37,7 @@ Item { anchors.left: parent.left anchors.leftMargin: root.notifCount > 0 ? 0 : -width - titleText.anchors.leftMargin anchors.verticalCenter: parent.verticalCenter - color: DynamicColors.palette.m3outline + color: Colors.palette.m3outline font.family: "CaskaydiaCove NF" font.pointSize: 13 font.weight: 500 @@ -60,7 +61,7 @@ Item { anchors.leftMargin: 7 anchors.right: parent.right anchors.verticalCenter: parent.verticalCenter - color: DynamicColors.palette.m3outline + color: Colors.palette.m3outline elide: Text.ElideRight font.family: "CaskaydiaCove NF" font.pointSize: 13 @@ -87,7 +88,6 @@ Item { Behavior on opacity { Anim { - duration: MaterialEasing.expressiveEffectsTime } } sourceComponent: ColumnLayout { @@ -95,7 +95,7 @@ Item { CustomText { Layout.alignment: Qt.AlignHCenter - color: DynamicColors.palette.m3outlineVariant + color: Colors.palette.m3outlineVariant font.family: "CaskaydiaCove NF" font.pointSize: 18 font.weight: 500 @@ -156,20 +156,17 @@ Item { Loader { active: opacity > 0 anchors.bottom: parent.bottom - anchors.margins: Appearance.padding.normal + anchors.margins: Tokens.padding.normal anchors.right: parent.right opacity: root.notifCount > 0 ? 1 : 0 scale: root.notifCount > 0 ? 1 : 0.5 Behavior on opacity { Anim { - duration: MaterialEasing.expressiveEffectsTime } } Behavior on scale { Anim { - duration: MaterialEasing.expressiveEffectsTime - easing.bezierCurve: MaterialEasing.expressiveEffects } } sourceComponent: IconButton { @@ -178,7 +175,7 @@ Item { font.pointSize: Math.round(18 * 1.2) icon: "clear_all" padding: 8 - radius: Appearance.rounding.full + radius: Tokens.rounding.full onClicked: clearTimer.start() diff --git a/Modules/Notifications/Sidebar/NotifDockList.qml b/Modules/Notifications/Sidebar/NotifDockList.qml index d82dc82..30dfdf3 100644 --- a/Modules/Notifications/Sidebar/NotifDockList.qml +++ b/Modules/Notifications/Sidebar/NotifDockList.qml @@ -4,7 +4,7 @@ import Quickshell import QtQuick import ZShell.Components import qs.Components -import qs.Config +import ZShell.Config import qs.Modules import qs.Daemons @@ -21,8 +21,8 @@ LazyListView { cacheBuffer: 400 implicitHeight: contentHeight readyDelay: 1 - removeDuration: Appearance.anim.durations.normal - spacing: Appearance.spacing.small + removeDuration: Tokens.anim.durations.normal + spacing: Tokens.spacing.small useCustomViewport: true viewport: Qt.rect(0, container.contentY, width, container.height) @@ -59,22 +59,22 @@ LazyListView { } Behavior on scale { Anim { - duration: Appearance.anim.durations.expressiveDefaultSpatial - easing.bezierCurve: Appearance.anim.curves.expressiveDefaultSpatial + duration: Tokens.anim.durations.expressiveDefaultSpatial + easing.bezierCurve: Tokens.anim.curves.expressiveDefaultSpatial } } Behavior on x { Anim { - duration: Appearance.anim.durations.expressiveDefaultSpatial - easing.bezierCurve: Appearance.anim.curves.expressiveDefaultSpatial + duration: Tokens.anim.durations.expressiveDefaultSpatial + easing.bezierCurve: Tokens.anim.curves.expressiveDefaultSpatial } } Behavior on y { enabled: notif.LazyListView.ready Anim { - duration: Appearance.anim.durations.expressiveDefaultSpatial - easing.bezierCurve: Appearance.anim.curves.expressiveDefaultSpatial + duration: Tokens.anim.durations.expressiveDefaultSpatial + easing.bezierCurve: Tokens.anim.curves.expressiveDefaultSpatial } } @@ -153,8 +153,8 @@ LazyListView { Anim { id: contentYAnim - duration: Appearance.anim.durations.expressiveDefaultSpatial - easing.bezierCurve: Appearance.anim.curves.expressiveDefaultSpatial + duration: Tokens.anim.durations.expressiveDefaultSpatial + easing.bezierCurve: Tokens.anim.curves.expressiveDefaultSpatial property: "contentY" target: root.container } diff --git a/Modules/Notifications/Sidebar/NotifGroup.qml b/Modules/Notifications/Sidebar/NotifGroup.qml index c816a62..c0475c0 100644 --- a/Modules/Notifications/Sidebar/NotifGroup.qml +++ b/Modules/Notifications/Sidebar/NotifGroup.qml @@ -1,7 +1,7 @@ pragma ComponentBehavior: Bound import qs.Components -import qs.Config +import ZShell.Config import qs.Modules import qs.Daemons import qs.Helpers @@ -9,6 +9,7 @@ import Quickshell import Quickshell.Services.Notifications import QtQuick import QtQuick.Layouts +import qs.Services CustomRect { id: root @@ -41,9 +42,9 @@ CustomRect { anchors.left: parent?.left anchors.right: parent?.right clip: true - color: DynamicColors.layer(DynamicColors.palette.m3surfaceContainer, 2) + color: Colors.layer(Colors.palette.m3surfaceContainer, 2) implicitHeight: content.implicitHeight + 10 * 2 - radius: Appearance.rounding.smallest + radius: Tokens.rounding.smallest Component.onDestruction: { if (notifCount === 0 && expanded) @@ -91,7 +92,7 @@ CustomRect { id: materialIconComp MaterialIcon { - color: root.urgency === NotificationUrgency.Critical ? DynamicColors.palette.m3onError : root.urgency === NotificationUrgency.Low ? DynamicColors.palette.m3onSurface : DynamicColors.palette.m3onSecondaryContainer + color: root.urgency === NotificationUrgency.Critical ? Colors.palette.m3onError : root.urgency === NotificationUrgency.Low ? Colors.palette.m3onSurface : Colors.palette.m3onSecondaryContainer font.pointSize: 18 text: Icons.getNotifIcon(root.notifs[0]?.summary, root.urgency) } @@ -99,8 +100,8 @@ CustomRect { CustomClippingRect { anchors.fill: parent - color: root.urgency === NotificationUrgency.Critical ? DynamicColors.palette.m3error : root.urgency === NotificationUrgency.Low ? DynamicColors.layer(DynamicColors.palette.m3surfaceContainerHigh, 3) : DynamicColors.palette.m3secondaryContainer - radius: Appearance.rounding.full + color: root.urgency === NotificationUrgency.Critical ? Colors.palette.m3error : root.urgency === NotificationUrgency.Low ? Colors.layer(Colors.palette.m3surfaceContainerHigh, 3) : Colors.palette.m3secondaryContainer + radius: Tokens.rounding.full Loader { anchors.centerIn: parent @@ -114,10 +115,10 @@ CustomRect { anchors.right: parent.right sourceComponent: CustomRect { - color: root.urgency === NotificationUrgency.Critical ? DynamicColors.palette.m3error : root.urgency === NotificationUrgency.Low ? DynamicColors.palette.m3surfaceContainerHigh : DynamicColors.palette.m3secondaryContainer + color: root.urgency === NotificationUrgency.Critical ? Colors.palette.m3error : root.urgency === NotificationUrgency.Low ? Colors.palette.m3surfaceContainerHigh : Colors.palette.m3secondaryContainer implicitHeight: Config.notifs.sizes.badge implicitWidth: Config.notifs.sizes.badge - radius: Appearance.rounding.full + radius: Tokens.rounding.full CustomIcon { anchors.centerIn: parent @@ -151,7 +152,7 @@ CustomRect { CustomText { Layout.fillWidth: true - color: DynamicColors.palette.m3onSurfaceVariant + color: Colors.palette.m3onSurfaceVariant elide: Text.ElideRight font.pointSize: 11 text: root.modelData @@ -159,19 +160,19 @@ CustomRect { CustomText { animate: true - color: DynamicColors.palette.m3outline + color: Colors.palette.m3outline font.pointSize: 11 text: root.notifs.find(n => !n.closed)?.timeStr ?? "" } CustomRect { - color: root.urgency === NotificationUrgency.Critical ? DynamicColors.palette.m3error : DynamicColors.layer(DynamicColors.palette.m3surfaceContainerHigh, 3) - implicitHeight: groupCount.implicitHeight + Appearance.padding.small + color: root.urgency === NotificationUrgency.Critical ? Colors.palette.m3error : Colors.layer(Colors.palette.m3surfaceContainerHigh, 3) + implicitHeight: groupCount.implicitHeight + Tokens.padding.small implicitWidth: expandBtn.implicitWidth + 7 * 2 - radius: Appearance.rounding.full + radius: Tokens.rounding.full StateLayer { - color: root.urgency === NotificationUrgency.Critical ? DynamicColors.palette.m3onError : DynamicColors.palette.m3onSurface + color: root.urgency === NotificationUrgency.Critical ? Colors.palette.m3onError : Colors.palette.m3onSurface onClicked: { root.toggleExpand(!root.expanded); @@ -189,7 +190,7 @@ CustomRect { Layout.leftMargin: 10 / 2 animate: true - color: root.urgency === NotificationUrgency.Critical ? DynamicColors.palette.m3onError : DynamicColors.palette.m3onSurface + color: root.urgency === NotificationUrgency.Critical ? Colors.palette.m3onError : Colors.palette.m3onSurface font.pointSize: 11 text: root.notifCount } @@ -197,20 +198,16 @@ CustomRect { MaterialIcon { Layout.rightMargin: -10 / 2 // Layout.topMargin: root.expanded ? -Math.floor(7 / 2) : 0 - color: root.urgency === NotificationUrgency.Critical ? DynamicColors.palette.m3onError : DynamicColors.palette.m3onSurface + color: root.urgency === NotificationUrgency.Critical ? Colors.palette.m3onError : Colors.palette.m3onSurface rotation: root.expanded ? 180 : 0 text: "expand_more" Behavior on Layout.topMargin { Anim { - duration: MaterialEasing.expressiveEffectsTime - easing.bezierCurve: MaterialEasing.expressiveEffects } } Behavior on rotation { Anim { - duration: MaterialEasing.expressiveEffectsTime - easing.bezierCurve: MaterialEasing.expressiveEffects } } } diff --git a/Modules/Notifications/Sidebar/NotifGroupList.qml b/Modules/Notifications/Sidebar/NotifGroupList.qml index a86f3f7..822cf0c 100644 --- a/Modules/Notifications/Sidebar/NotifGroupList.qml +++ b/Modules/Notifications/Sidebar/NotifGroupList.qml @@ -5,7 +5,7 @@ import QtQuick import QtQuick.Layouts import ZShell.Components import qs.Components -import qs.Config +import ZShell.Config import qs.Modules import qs.Daemons @@ -25,8 +25,8 @@ LazyListView { cacheBuffer: 400 implicitHeight: contentHeight readyDelay: 1 - removeDuration: Appearance.anim.durations.normal - spacing: Math.round(Appearance.spacing.small / 2) + removeDuration: Tokens.anim.durations.normal + spacing: Math.round(Tokens.spacing.small / 2) useCustomViewport: true viewport: { tWatcher.transform; // mapToItem is not reactive so use this to trigger updates @@ -64,16 +64,12 @@ LazyListView { } Behavior on x { Anim { - duration: MaterialEasing.expressiveEffectsTime - easing.bezierCurve: MaterialEasing.expressiveEffects } } Behavior on y { enabled: notif.LazyListView.ready Anim { - duration: MaterialEasing.expressiveEffectsTime - easing.bezierCurve: MaterialEasing.expressiveEffects } } diff --git a/Modules/Notifications/Sidebar/Utils/Background.qml b/Modules/Notifications/Sidebar/Utils/Background.qml index df12728..f312b26 100644 --- a/Modules/Notifications/Sidebar/Utils/Background.qml +++ b/Modules/Notifications/Sidebar/Utils/Background.qml @@ -1,7 +1,8 @@ import qs.Components -import qs.Config +import ZShell.Config import QtQuick import QtQuick.Shapes +import qs.Services ShapePath { id: root @@ -12,7 +13,7 @@ ShapePath { required property var sidebar required property Wrapper wrapper - fillColor: DynamicColors.palette.m3surface + fillColor: Colors.palette.m3surface strokeWidth: -1 Behavior on fillColor { diff --git a/Modules/Notifications/Sidebar/Utils/Cards/Record.qml b/Modules/Notifications/Sidebar/Utils/Cards/Record.qml index 2cf99a7..8482efb 100644 --- a/Modules/Notifications/Sidebar/Utils/Cards/Record.qml +++ b/Modules/Notifications/Sidebar/Utils/Cards/Record.qml @@ -4,8 +4,9 @@ import Quickshell import QtQuick import QtQuick.Layouts import qs.Components -import qs.Config +import ZShell.Config import qs.Helpers +import qs.Services CustomRect { id: root @@ -14,29 +15,29 @@ CustomRect { required property PersistentProperties visibilities Layout.fillWidth: true - color: DynamicColors.tPalette.m3surfaceContainer + color: Colors.tPalette.m3surfaceContainer implicitHeight: layout.implicitHeight + layout.anchors.margins * 2 - radius: Appearance.rounding.smallest + radius: Tokens.rounding.smallest ColumnLayout { id: layout anchors.fill: parent - anchors.margins: Appearance.padding.large - spacing: Appearance.spacing.normal + anchors.margins: Tokens.padding.large + spacing: Tokens.spacing.normal RowLayout { - spacing: Appearance.spacing.normal + spacing: Tokens.spacing.normal z: 1 CustomRect { - color: Recorder.running ? DynamicColors.palette.m3secondary : DynamicColors.palette.m3secondaryContainer + color: Recorder.running ? Colors.palette.m3secondary : Colors.palette.m3secondaryContainer implicitHeight: { - const h = icon.implicitHeight + Appearance.padding.smaller * 2; + const h = icon.implicitHeight + Tokens.padding.smaller * 2; return h - (h % 2); } implicitWidth: implicitHeight - radius: Appearance.rounding.full + radius: Tokens.rounding.full MaterialIcon { id: icon @@ -44,8 +45,8 @@ CustomRect { anchors.centerIn: parent anchors.horizontalCenterOffset: -0.5 anchors.verticalCenterOffset: 1.5 - color: Recorder.running ? DynamicColors.palette.m3onSecondary : DynamicColors.palette.m3onSecondaryContainer - font.pointSize: Appearance.font.size.large + color: Recorder.running ? Colors.palette.m3onSecondary : Colors.palette.m3onSecondaryContainer + font.pointSize: Tokens.font.size.large text: "screen_record" } } @@ -57,15 +58,15 @@ CustomRect { CustomText { Layout.fillWidth: true elide: Text.ElideRight - font.pointSize: Appearance.font.size.normal + font.pointSize: Tokens.font.size.normal text: qsTr("Screen Recorder") } CustomText { Layout.fillWidth: true - color: DynamicColors.palette.m3onSurfaceVariant + color: Colors.palette.m3onSurfaceVariant elide: Text.ElideRight - font.pointSize: Appearance.font.size.small + font.pointSize: Tokens.font.size.small text: Recorder.paused ? qsTr("Recording paused") : Recorder.running ? qsTr("Recording running") : qsTr("Recording off") } } @@ -132,16 +133,16 @@ CustomRect { SequentialAnimation { ParallelAnimation { Anim { - duration: Appearance.anim.durations.small - easing.bezierCurve: Appearance.anim.curves.standardAccel + duration: Tokens.anim.durations.small + easing.bezierCurve: Tokens.anim.curves.standardAccel property: "scale" target: listOrControls to: 0.7 } Anim { - duration: Appearance.anim.durations.small - easing.bezierCurve: Appearance.anim.curves.standardAccel + duration: Tokens.anim.durations.small + easing.bezierCurve: Tokens.anim.curves.standardAccel property: "opacity" target: listOrControls to: 0 @@ -165,16 +166,16 @@ CustomRect { ParallelAnimation { Anim { - duration: Appearance.anim.durations.small - easing.bezierCurve: Appearance.anim.curves.standardDecel + duration: Tokens.anim.durations.small + easing.bezierCurve: Tokens.anim.curves.standardDecel property: "scale" target: listOrControls to: 1 } Anim { - duration: Appearance.anim.durations.small - easing.bezierCurve: Appearance.anim.curves.standardDecel + duration: Tokens.anim.durations.small + easing.bezierCurve: Tokens.anim.curves.standardDecel property: "opacity" target: listOrControls to: 1 @@ -198,13 +199,13 @@ CustomRect { id: recordingControls RowLayout { - spacing: Appearance.spacing.normal + spacing: Tokens.spacing.normal CustomRect { - color: Recorder.paused ? DynamicColors.palette.m3tertiary : DynamicColors.palette.m3error - implicitHeight: recText.implicitHeight + Appearance.padding.smaller * 2 - implicitWidth: recText.implicitWidth + Appearance.padding.normal * 2 - radius: Appearance.rounding.full + color: Recorder.paused ? Colors.palette.m3tertiary : Colors.palette.m3error + implicitHeight: recText.implicitHeight + Tokens.padding.smaller * 2 + implicitWidth: recText.implicitWidth + Tokens.padding.normal * 2 + radius: Tokens.rounding.full Behavior on implicitWidth { Anim { @@ -216,15 +217,15 @@ CustomRect { running: !Recorder.paused Anim { - duration: Appearance.anim.durations.large - easing.bezierCurve: Appearance.anim.curves.emphasizedAccel + duration: Tokens.anim.durations.large + easing.bezierCurve: Tokens.anim.curves.emphasizedAccel from: 1 to: 0 } Anim { - duration: Appearance.anim.durations.extraLarge - easing.bezierCurve: Appearance.anim.curves.emphasizedDecel + duration: Tokens.anim.durations.extraLarge + easing.bezierCurve: Tokens.anim.curves.emphasizedDecel from: 0 to: 1 } @@ -235,14 +236,14 @@ CustomRect { anchors.centerIn: parent animate: true - color: Recorder.paused ? DynamicColors.palette.m3onTertiary : DynamicColors.palette.m3onError + color: Recorder.paused ? Colors.palette.m3onTertiary : Colors.palette.m3onError font.family: Appearance.font.family.mono text: Recorder.paused ? "PAUSED" : "REC" } } CustomText { - font.pointSize: Appearance.font.size.normal + font.pointSize: Tokens.font.size.normal text: { const elapsed = Recorder.elapsed; @@ -266,7 +267,7 @@ CustomRect { IconButton { checked: Recorder.paused - font.pointSize: Appearance.font.size.large + font.pointSize: Tokens.font.size.large icon: Recorder.paused ? "play_arrow" : "pause" isToggle: true label.animate: true @@ -279,10 +280,10 @@ CustomRect { } IconButton { - font.pointSize: Appearance.font.size.large + font.pointSize: Tokens.font.size.large icon: "stop" - inactiveColor: DynamicColors.palette.m3error - inactiveOnColor: DynamicColors.palette.m3onError + inactiveColor: Colors.palette.m3error + inactiveOnColor: Colors.palette.m3onError onClicked: Recorder.stop() } diff --git a/Modules/Notifications/Sidebar/Utils/Cards/RecordingList.qml b/Modules/Notifications/Sidebar/Utils/Cards/RecordingList.qml index bb94fc9..23a46db 100644 --- a/Modules/Notifications/Sidebar/Utils/Cards/RecordingList.qml +++ b/Modules/Notifications/Sidebar/Utils/Cards/RecordingList.qml @@ -8,7 +8,8 @@ import ZShell.Models import qs.Components import qs.Helpers import qs.Paths -import qs.Config +import ZShell.Config +import qs.Services ColumnLayout { id: root @@ -25,18 +26,18 @@ ColumnLayout { onClicked: root.props.recordingListExpanded = !root.props.recordingListExpanded RowLayout { - spacing: Appearance.spacing.smaller + spacing: Tokens.spacing.smaller MaterialIcon { Layout.alignment: Qt.AlignVCenter - font.pointSize: Appearance.font.size.large + font.pointSize: Tokens.font.size.large text: "list" } CustomText { Layout.alignment: Qt.AlignVCenter Layout.fillWidth: true - font.pointSize: Appearance.font.size.normal + font.pointSize: Tokens.font.size.normal text: qsTr("Recordings") } @@ -54,9 +55,9 @@ ColumnLayout { id: list Layout.fillWidth: true - Layout.rightMargin: -Appearance.spacing.small + Layout.rightMargin: -Tokens.spacing.small clip: true - implicitHeight: (Appearance.font.size.larger + Appearance.padding.small) * (root.props.recordingListExpanded ? 10 : 3) + implicitHeight: (Tokens.font.size.larger + Tokens.padding.small) * (root.props.recordingListExpanded ? 10 : 3) CustomScrollBar.vertical: CustomScrollBar { flickable: list @@ -82,15 +83,15 @@ ColumnLayout { anchors.left: list.contentItem.left anchors.right: list.contentItem.right - anchors.rightMargin: Appearance.spacing.small - spacing: Appearance.spacing.small / 2 + anchors.rightMargin: Tokens.spacing.small + spacing: Tokens.spacing.small / 2 Component.onCompleted: baseName = modelData.baseName CustomText { Layout.fillWidth: true - Layout.rightMargin: Appearance.spacing.small / 2 - color: DynamicColors.palette.m3onSurfaceVariant + Layout.rightMargin: Tokens.spacing.small / 2 + color: Colors.palette.m3onSurfaceVariant elide: Text.ElideRight text: { const time = recording.baseName; @@ -165,13 +166,13 @@ ColumnLayout { } } sourceComponent: ColumnLayout { - spacing: Appearance.spacing.small + spacing: Tokens.spacing.small MaterialIcon { Layout.alignment: Qt.AlignHCenter Layout.preferredHeight: root.props.recordingListExpanded ? implicitHeight : 0 - color: DynamicColors.palette.m3outline - font.pointSize: Appearance.font.size.extraLarge + color: Colors.palette.m3outline + font.pointSize: Tokens.font.size.extraLarge opacity: root.props.recordingListExpanded ? 1 : 0 scale: root.props.recordingListExpanded ? 1 : 0 text: "scan_delete" @@ -191,12 +192,12 @@ ColumnLayout { } RowLayout { - spacing: Appearance.spacing.smaller + spacing: Tokens.spacing.smaller MaterialIcon { Layout.alignment: Qt.AlignHCenter Layout.preferredWidth: !root.props.recordingListExpanded ? implicitWidth : 0 - color: DynamicColors.palette.m3outline + color: Colors.palette.m3outline opacity: !root.props.recordingListExpanded ? 1 : 0 scale: !root.props.recordingListExpanded ? 1 : 0 text: "scan_delete" @@ -216,7 +217,7 @@ ColumnLayout { } CustomText { - color: DynamicColors.palette.m3outline + color: Colors.palette.m3outline text: qsTr("No recordings found") } } diff --git a/Modules/Notifications/Sidebar/Utils/Cards/Toggles.qml b/Modules/Notifications/Sidebar/Utils/Cards/Toggles.qml index 82af970..f3ee35e 100644 --- a/Modules/Notifications/Sidebar/Utils/Cards/Toggles.qml +++ b/Modules/Notifications/Sidebar/Utils/Cards/Toggles.qml @@ -4,9 +4,10 @@ import QtQuick import QtQuick.Layouts import ZShell.Components import qs.Components -import qs.Config +import ZShell.Config import qs.Helpers import qs.Daemons +import qs.Services CustomRect { id: root @@ -15,16 +16,16 @@ CustomRect { required property var visibilities Layout.fillWidth: true - color: DynamicColors.tPalette.m3surfaceContainer + color: Colors.tPalette.m3surfaceContainer implicitHeight: layout.implicitHeight + 18 * 2 - radius: Appearance.rounding.smallest + radius: Tokens.rounding.smallest ButtonRow { id: layout anchors.fill: parent anchors.margins: 18 - spacing: Appearance.spacing.extraSmall + spacing: Tokens.spacing.extraSmall Toggle { checked: Network.wifiEnabled diff --git a/Modules/Notifications/Sidebar/Utils/Content.qml b/Modules/Notifications/Sidebar/Utils/Content.qml index 348340a..ef15ec8 100644 --- a/Modules/Notifications/Sidebar/Utils/Content.qml +++ b/Modules/Notifications/Sidebar/Utils/Content.qml @@ -2,7 +2,7 @@ import Quickshell import QtQuick import QtQuick.Layouts import qs.Modules.Notifications.Sidebar.Utils.Cards -import qs.Config +import ZShell.Config Item { id: root diff --git a/Modules/Notifications/Sidebar/Utils/IdleInhibit.qml b/Modules/Notifications/Sidebar/Utils/IdleInhibit.qml index 69fe505..aee0c48 100644 --- a/Modules/Notifications/Sidebar/Utils/IdleInhibit.qml +++ b/Modules/Notifications/Sidebar/Utils/IdleInhibit.qml @@ -1,22 +1,21 @@ import qs.Components -import qs.Config +import ZShell.Config import qs.Helpers import QtQuick import QtQuick.Layouts +import qs.Services CustomRect { id: root Layout.fillWidth: true clip: true - color: DynamicColors.tPalette.m3surfaceContainer + color: Colors.tPalette.m3surfaceContainer implicitHeight: layout.implicitHeight + (IdleInhibitor.enabled ? activeChip.implicitHeight + activeChip.anchors.topMargin : 0) + 18 * 2 - radius: Appearance.rounding.smallest + radius: Tokens.rounding.smallest Behavior on implicitHeight { Anim { - duration: MaterialEasing.expressiveEffectsTime - easing.bezierCurve: MaterialEasing.expressiveEffects } } @@ -30,16 +29,16 @@ CustomRect { spacing: 10 CustomRect { - color: IdleInhibitor.enabled ? DynamicColors.palette.m3secondary : DynamicColors.palette.m3secondaryContainer + color: IdleInhibitor.enabled ? Colors.palette.m3secondary : Colors.palette.m3secondaryContainer implicitHeight: icon.implicitHeight + 7 * 2 implicitWidth: implicitHeight - radius: Appearance.rounding.full + radius: Tokens.rounding.full MaterialIcon { id: icon anchors.centerIn: parent - color: IdleInhibitor.enabled ? DynamicColors.palette.m3onSecondary : DynamicColors.palette.m3onSecondaryContainer + color: IdleInhibitor.enabled ? Colors.palette.m3onSecondary : Colors.palette.m3onSecondaryContainer font.pointSize: 18 text: "coffee" } @@ -58,7 +57,7 @@ CustomRect { CustomText { Layout.fillWidth: true - color: DynamicColors.palette.m3onSurfaceVariant + color: Colors.palette.m3onSurfaceVariant elide: Text.ElideRight font.pointSize: 11 text: IdleInhibitor.enabled ? qsTr("Preventing sleep mode") : qsTr("Normal power management") @@ -85,13 +84,10 @@ CustomRect { Behavior on anchors.bottomMargin { Anim { - duration: MaterialEasing.expressiveEffectsTime - easing.bezierCurve: MaterialEasing.expressiveEffects } } Behavior on opacity { Anim { - duration: MaterialEasing.expressiveEffectsTime } } Behavior on scale { @@ -99,16 +95,16 @@ CustomRect { } } sourceComponent: CustomRect { - color: DynamicColors.palette.m3primary + color: Colors.palette.m3primary implicitHeight: activeText.implicitHeight + 10 * 2 implicitWidth: activeText.implicitWidth + 10 * 2 - radius: Appearance.rounding.full + radius: Tokens.rounding.full CustomText { id: activeText anchors.centerIn: parent - color: DynamicColors.palette.m3onPrimary + color: Colors.palette.m3onPrimary font.pointSize: Math.round(11 * 0.9) text: qsTr("Active since %1").arg(Qt.formatTime(IdleInhibitor.enabledSince, Config.services.useTwelveHourClock ? "hh:mm a" : "hh:mm")) } diff --git a/Modules/Notifications/Sidebar/Utils/Wrapper.qml b/Modules/Notifications/Sidebar/Utils/Wrapper.qml index 81d7d00..a829f89 100644 --- a/Modules/Notifications/Sidebar/Utils/Wrapper.qml +++ b/Modules/Notifications/Sidebar/Utils/Wrapper.qml @@ -1,7 +1,7 @@ pragma ComponentBehavior: Bound import qs.Components -import qs.Config +import ZShell.Config import Quickshell import QtQuick @@ -30,8 +30,8 @@ Item { Behavior on offsetScale { Anim { - duration: Appearance.anim.durations.expressiveDefaultSpatial - easing.bezierCurve: Appearance.anim.curves.expressiveDefaultSpatial + duration: Tokens.anim.durations.expressiveDefaultSpatial + easing.bezierCurve: Tokens.anim.curves.expressiveDefaultSpatial } } diff --git a/Modules/Notifications/Sidebar/Wrapper.qml b/Modules/Notifications/Sidebar/Wrapper.qml index 22a952c..f8b9cb6 100644 --- a/Modules/Notifications/Sidebar/Wrapper.qml +++ b/Modules/Notifications/Sidebar/Wrapper.qml @@ -1,7 +1,7 @@ pragma ComponentBehavior: Bound import qs.Components -import qs.Config +import ZShell.Config import QtQuick Item { @@ -21,8 +21,8 @@ Item { Behavior on offsetScale { Anim { - duration: Appearance.anim.durations.expressiveDefaultSpatial - easing.bezierCurve: Appearance.anim.curves.expressiveDefaultSpatial + duration: Tokens.anim.durations.expressiveDefaultSpatial + easing.bezierCurve: Tokens.anim.curves.expressiveDefaultSpatial } } @@ -37,7 +37,7 @@ Item { anchors.top: parent.top sourceComponent: Content { - implicitWidth: Config.sidebar.sizes.width - Appearance.padding.smaller * 2 + implicitWidth: Config.sidebar.sizes.width - Tokens.padding.smaller * 2 props: root.props visibilities: root.visibilities } diff --git a/Modules/Notifications/Wrapper.qml b/Modules/Notifications/Wrapper.qml index 7f53293..03131f8 100644 --- a/Modules/Notifications/Wrapper.qml +++ b/Modules/Notifications/Wrapper.qml @@ -1,6 +1,6 @@ import QtQuick import qs.Components -import qs.Config +import ZShell.Config Item { id: root diff --git a/Modules/Osd/Content.qml b/Modules/Osd/Content.qml index 01a108b..67fb568 100644 --- a/Modules/Osd/Content.qml +++ b/Modules/Osd/Content.qml @@ -4,8 +4,9 @@ import QtQuick import QtQuick.Layouts import qs.Components import qs.Helpers -import qs.Config +import ZShell.Config import qs.Daemons +import qs.Services Item { id: root @@ -18,14 +19,14 @@ Item { required property var visibilities required property real volume - implicitHeight: layout.implicitHeight + Appearance.padding.small * 2 - implicitWidth: layout.implicitWidth + Appearance.padding.small * 2 + implicitHeight: layout.implicitHeight + Tokens.padding.small * 2 + implicitWidth: layout.implicitWidth + Tokens.padding.small * 2 ColumnLayout { id: layout anchors.centerIn: parent - spacing: Appearance.spacing.normal + spacing: Tokens.spacing.normal // Speaker volume CustomMouseArea { @@ -41,7 +42,7 @@ Item { FilledSlider { anchors.fill: parent - color: Audio.muted ? DynamicColors.palette.m3error : DynamicColors.palette.m3secondary + color: Audio.muted ? Colors.palette.m3error : Colors.palette.m3secondary icon: Icons.getVolumeIcon(value, root.muted) to: Config.services.maxVolume value: root.volume @@ -67,7 +68,7 @@ Item { FilledSlider { anchors.fill: parent - color: Audio.sourceMuted ? DynamicColors.palette.m3error : DynamicColors.palette.m3secondary + color: Audio.sourceMuted ? Colors.palette.m3error : Colors.palette.m3secondary icon: Icons.getMicVolumeIcon(value, root.sourceMuted) to: Config.services.maxVolume value: root.sourceVolume @@ -126,7 +127,7 @@ Item { Behavior on Layout.preferredHeight { Anim { - easing.bezierCurve: Appearance.anim.curves.emphasized + easing.bezierCurve: Tokens.anim.curves.emphasized } } Behavior on opacity { diff --git a/Modules/Osd/Wrapper.qml b/Modules/Osd/Wrapper.qml index 3d9c3c1..ec064b5 100644 --- a/Modules/Osd/Wrapper.qml +++ b/Modules/Osd/Wrapper.qml @@ -4,7 +4,7 @@ import Quickshell import QtQuick import qs.Components import qs.Helpers -import qs.Config +import ZShell.Config import qs.Daemons Item { @@ -38,8 +38,8 @@ Item { Behavior on offsetScale { Anim { - duration: Appearance.anim.durations.expressiveDefaultSpatial - easing.bezierCurve: Appearance.anim.curves.expressiveDefaultSpatial + duration: Tokens.anim.durations.expressiveDefaultSpatial + easing.bezierCurve: Tokens.anim.curves.expressiveDefaultSpatial } } diff --git a/Modules/Polkit/Polkit.qml b/Modules/Polkit/Polkit.qml index cb575e2..6c40cdc 100644 --- a/Modules/Polkit/Polkit.qml +++ b/Modules/Polkit/Polkit.qml @@ -8,7 +8,8 @@ import QtQuick.Layouts import QtQuick.Controls import qs.Components import qs.Modules -import qs.Config +import ZShell.Config +import qs.Services Scope { id: root @@ -43,7 +44,6 @@ Scope { Anim { id: openAnim - duration: MaterialEasing.expressiveEffectsTime property: "opacity" target: inputPanel to: 1 @@ -52,7 +52,6 @@ Scope { Anim { id: closeAnim - duration: MaterialEasing.expressiveEffectsTime property: "opacity" target: inputPanel to: 0 @@ -78,11 +77,11 @@ Scope { id: inputPanel anchors.centerIn: parent - color: DynamicColors.tPalette.m3surface + color: Colors.tPalette.m3surface implicitHeight: layout.childrenRect.height + 28 implicitWidth: layout.childrenRect.width + 32 opacity: 0 - radius: Appearance.rounding.small * 2 + radius: Tokens.rounding.small * 2 ColumnLayout { id: layout @@ -138,7 +137,7 @@ Scope { CustomText { Layout.alignment: Qt.AlignLeft Layout.preferredWidth: Math.min(600, contentWidth) - color: DynamicColors.tPalette.m3onSurfaceVariant + color: Colors.tPalette.m3onSurfaceVariant font.bold: true font.pointSize: 12 text: polkitAgent.flow?.supplementaryMessage || "No Additional Information" @@ -150,16 +149,16 @@ Scope { Layout.preferredHeight: 40 Layout.preferredWidth: contentColumn.implicitWidth - color: DynamicColors.palette.m3onSurfaceVariant + color: Colors.palette.m3onSurfaceVariant echoMode: polkitAgent.flow?.responseVisible ? TextInput.Normal : TextInput.Password placeholderText: polkitAgent.flow?.failed ? " Incorrect Password" : " Input Password" - placeholderTextColor: polkitAgent.flow?.failed ? DynamicColors.palette.m3onError : DynamicColors.tPalette.m3onSurfaceVariant + placeholderTextColor: polkitAgent.flow?.failed ? Colors.palette.m3onError : Colors.tPalette.m3onSurfaceVariant selectByMouse: true background: CustomRect { - color: (polkitAgent.flow?.failed && passInput.text === "") ? DynamicColors.palette.m3error : DynamicColors.tPalette.m3surfaceVariant + color: (polkitAgent.flow?.failed && passInput.text === "") ? Colors.palette.m3error : Colors.tPalette.m3surfaceVariant implicitHeight: 40 - radius: Appearance.rounding.smallest + radius: Tokens.rounding.smallest } onAccepted: okButton.clicked() @@ -188,7 +187,7 @@ Scope { Layout.fillWidth: true Layout.preferredHeight: implicitHeight clip: true - color: DynamicColors.tPalette.m3surfaceContainerLow + color: Colors.tPalette.m3surfaceContainerLow implicitHeight: 0 radius: 16 visible: true @@ -196,21 +195,18 @@ Scope { Behavior on open { ParallelAnimation { Anim { - duration: MaterialEasing.expressiveEffectsTime property: "implicitHeight" target: detailsPanel to: !detailsPanel.open ? textDetailsColumn.childrenRect.height + 16 : 0 } Anim { - duration: MaterialEasing.expressiveEffectsTime property: "opacity" target: textDetailsColumn to: !detailsPanel.open ? 1 : 0 } Anim { - duration: MaterialEasing.expressiveEffectsTime property: "scale" target: textDetailsColumn to: !detailsPanel.open ? 1 : 0.9 @@ -248,8 +244,8 @@ Scope { Layout.alignment: Qt.AlignLeft icon: "info" - inactiveColor: DynamicColors.palette.m3surfaceContainer - inactiveOnColor: DynamicColors.palette.m3onSurface + inactiveColor: Colors.palette.m3surfaceContainer + inactiveOnColor: Colors.palette.m3onSurface isRound: true shapeMorph: true text: "Details" @@ -267,16 +263,16 @@ Scope { ButtonRow { Layout.alignment: Qt.AlignRight - spacing: Appearance.spacing.normal + spacing: Tokens.spacing.normal IconTextButton { id: okButton enabled: passInput.text.length > 0 || !!polkitAgent.flow?.isResponseRequired - horizontalPadding: Appearance.padding.large + horizontalPadding: Tokens.padding.large icon: "check" - inactiveColor: DynamicColors.palette.m3primary - inactiveOnColor: DynamicColors.palette.m3onPrimary + inactiveColor: Colors.palette.m3primary + inactiveOnColor: Colors.palette.m3onPrimary isRound: true isToggle: false shapeMorph: true @@ -294,10 +290,10 @@ Scope { id: cancelButton enabled: passInput.text.length > 0 || !!polkitAgent.flow?.isResponseRequired - horizontalPadding: Appearance.padding.large + horizontalPadding: Tokens.padding.large icon: "close" - inactiveColor: DynamicColors.palette.m3surfaceContainer - inactiveOnColor: DynamicColors.palette.m3onSurface + inactiveColor: Colors.palette.m3surfaceContainer + inactiveOnColor: Colors.palette.m3onSurface isRound: true isToggle: false shapeMorph: true diff --git a/Modules/Resource.qml b/Modules/Resource.qml index 32a6b46..4da447e 100644 --- a/Modules/Resource.qml +++ b/Modules/Resource.qml @@ -2,12 +2,13 @@ import QtQuick import QtQuick.Layouts import QtQuick.Shapes import qs.Components -import qs.Config +import ZShell.Config +import qs.Services RowLayout { id: root - property color accentColor: warning ? DynamicColors.palette.m3error : mainColor + property color accentColor: warning ? Colors.palette.m3error : mainColor property real animatedPercentage: 0 readonly property real arcStartAngle: 0.75 * Math.PI readonly property real arcSweep: 1.5 * Math.PI @@ -16,12 +17,12 @@ RowLayout { required property color mainColor required property double percentage property bool shown: true - property color usageColor: warning ? DynamicColors.palette.m3error : mainColor + property color usageColor: warning ? Colors.palette.m3error : mainColor property bool warning: percentage * 100 >= warningThreshold property int warningThreshold: 80 percentage: 0 - spacing: Appearance.spacing.smaller + spacing: Tokens.spacing.smaller Behavior on animatedPercentage { Anim { @@ -41,15 +42,15 @@ RowLayout { Layout.preferredWidth: 16 color: root.iconColor - font.pointSize: Appearance.font.size.larger + font.pointSize: Tokens.font.size.larger text: root.icon } CustomClippingRect { - Layout.preferredHeight: root.height - Appearance.padding.small + Layout.preferredHeight: root.height - Tokens.padding.small Layout.preferredWidth: 4 - color: DynamicColors.layer(DynamicColors.palette.m3surfaceContainerHigh, 2) - radius: Appearance.rounding.full + color: Colors.layer(Colors.palette.m3surfaceContainerHigh, 2) + radius: Tokens.rounding.full CustomRect { id: fill diff --git a/Modules/Resources.qml b/Modules/Resources.qml index cf3ef24..e2d82ac 100644 --- a/Modules/Resources.qml +++ b/Modules/Resources.qml @@ -3,10 +3,10 @@ pragma ComponentBehavior: Bound import QtQuick import Quickshell import QtQuick.Layouts +import ZShell.Config import ZShell.Services -import qs.Helpers +import qs.Services import qs.Modules -import qs.Config import qs.Components CustomRect { @@ -15,13 +15,13 @@ CustomRect { required property PersistentProperties visibilities clip: true - color: visibilities.resources ? DynamicColors.palette.m3primary : DynamicColors.tPalette.m3surfaceContainer - implicitHeight: Config.bar.height + Appearance.padding.smallest * 2 - implicitWidth: rowLayout.implicitWidth + Appearance.padding.larger * 2 - radius: Appearance.rounding.full + color: visibilities.resources ? Colors.palette.m3primary : Colors.tPalette.m3surfaceContainer + implicitHeight: Config.bar.height + Tokens.padding.smallest * 2 + implicitWidth: rowLayout.implicitWidth + Tokens.padding.larger * 2 + radius: Tokens.rounding.full StateLayer { - color: root.visibilities.resources ? DynamicColors.palette.m3onPrimary : DynamicColors.palette.m3onSurface + color: root.visibilities.resources ? Colors.palette.m3onPrimary : Colors.palette.m3onSurface onClicked: root.visibilities.resources = !root.visibilities.resources } @@ -32,7 +32,7 @@ CustomRect { anchors.centerIn: parent anchors.horizontalCenterOffset: -2 implicitHeight: root.implicitHeight - spacing: Appearance.spacing.smaller + spacing: Tokens.spacing.smaller ServiceRef { service: Gpu @@ -50,8 +50,8 @@ CustomRect { Layout.alignment: Qt.AlignVCenter Layout.fillHeight: true icon: "memory" - iconColor: root.visibilities.resources ? DynamicColors.palette.m3onPrimary : DynamicColors.palette.m3onSurface - mainColor: root.visibilities.resources ? DynamicColors.palette.m3onPrimary : DynamicColors.palette.m3primary + iconColor: root.visibilities.resources ? Colors.palette.m3onPrimary : Colors.palette.m3onSurface + mainColor: root.visibilities.resources ? Colors.palette.m3onPrimary : Colors.palette.m3primary percentage: Cpu.percentage warningThreshold: 95 } @@ -59,8 +59,8 @@ CustomRect { Resource { Layout.fillHeight: true icon: "memory_alt" - iconColor: root.visibilities.resources ? DynamicColors.palette.m3onPrimary : DynamicColors.palette.m3onSurface - mainColor: root.visibilities.resources ? DynamicColors.palette.m3onPrimary : DynamicColors.palette.m3secondary + iconColor: root.visibilities.resources ? Colors.palette.m3onPrimary : Colors.palette.m3onSurface + mainColor: root.visibilities.resources ? Colors.palette.m3onPrimary : Colors.palette.m3secondary percentage: Memory.percentage warningThreshold: 80 } @@ -68,16 +68,16 @@ CustomRect { Resource { Layout.fillHeight: true icon: "gamepad" - iconColor: root.visibilities.resources ? DynamicColors.palette.m3onPrimary : DynamicColors.palette.m3onSurface - mainColor: root.visibilities.resources ? DynamicColors.palette.m3onPrimary : DynamicColors.palette.m3tertiary + iconColor: root.visibilities.resources ? Colors.palette.m3onPrimary : Colors.palette.m3onSurface + mainColor: root.visibilities.resources ? Colors.palette.m3onPrimary : Colors.palette.m3tertiary percentage: Gpu.percentage } Resource { Layout.fillHeight: true icon: "developer_board" - iconColor: root.visibilities.resources ? DynamicColors.palette.m3onPrimary : DynamicColors.palette.m3onSurface - mainColor: root.visibilities.resources ? DynamicColors.palette.m3onPrimary : DynamicColors.palette.m3primary + iconColor: root.visibilities.resources ? Colors.palette.m3onPrimary : Colors.palette.m3onSurface + mainColor: root.visibilities.resources ? Colors.palette.m3onPrimary : Colors.palette.m3primary percentage: Gpu.memoryUsed / Gpu.memoryTotal } } diff --git a/Modules/Resources/Cards/BatteryTank.qml b/Modules/Resources/Cards/BatteryTank.qml index 0e97349..04352cf 100644 --- a/Modules/Resources/Cards/BatteryTank.qml +++ b/Modules/Resources/Cards/BatteryTank.qml @@ -1,17 +1,18 @@ import QtQuick import QtQuick.Layouts import Quickshell.Services.UPower +import ZShell.Config import qs.Components -import qs.Config +import qs.Services CustomClippingRect { id: root property real animPerc: UPower.displayDevice.percentage - color: DynamicColors.palette.m3secondaryContainer + color: Colors.palette.m3secondaryContainer implicitWidth: 120 - radius: Appearance.rounding.large + radius: Tokens.rounding.large Behavior on animPerc { Anim { @@ -21,11 +22,11 @@ CustomClippingRect { Contents { id: layout - accentColor: DynamicColors.palette.m3primary + accentColor: Colors.palette.m3primary anchors.fill: parent - anchors.margins: Appearance.padding.larger - subTextColor: DynamicColors.palette.m3onSurfaceVariant - textColor: DynamicColors.palette.m3onSurface + anchors.margins: Tokens.padding.larger + subTextColor: Colors.palette.m3onSurfaceVariant + textColor: Colors.palette.m3onSurface } CustomRect { @@ -33,19 +34,19 @@ CustomClippingRect { anchors.left: parent.left anchors.right: parent.right clip: true - color: DynamicColors.palette.m3secondary + color: Colors.palette.m3secondary implicitHeight: parent.height * root.animPerc - radius: Appearance.rounding.extraSmall + radius: Tokens.rounding.extraSmall Contents { - accentColor: DynamicColors.palette.m3primaryContainer + accentColor: Colors.palette.m3primaryContainer anchors.bottom: parent.bottom anchors.left: parent.left anchors.margins: layout.anchors.margins anchors.right: parent.right height: layout.height - subTextColor: DynamicColors.palette.m3secondaryContainer - textColor: DynamicColors.palette.m3onSecondary + subTextColor: Colors.palette.m3secondaryContainer + textColor: Colors.palette.m3onSecondary } } @@ -60,7 +61,7 @@ CustomClippingRect { spacing: 0 MaterialIcon { - Layout.leftMargin: -Appearance.padding.extraSmall + Layout.leftMargin: -Tokens.padding.extraSmall color: contents.accentColor text: "battery_full" } @@ -101,10 +102,10 @@ CustomClippingRect { RowLayout { Layout.alignment: Qt.AlignRight - Layout.bottomMargin: -Appearance.padding.small - Layout.rightMargin: -Appearance.padding.extraSmall - Layout.topMargin: -Appearance.padding.extraSmall - spacing: Appearance.spacing.extraSmall + Layout.bottomMargin: -Tokens.padding.small + Layout.rightMargin: -Tokens.padding.extraSmall + Layout.topMargin: -Tokens.padding.extraSmall + spacing: Tokens.spacing.extraSmall MaterialIcon { color: contents.accentColor diff --git a/Modules/Resources/Cards/HeroCard.qml b/Modules/Resources/Cards/HeroCard.qml index efb23fa..0bfd785 100644 --- a/Modules/Resources/Cards/HeroCard.qml +++ b/Modules/Resources/Cards/HeroCard.qml @@ -1,7 +1,8 @@ import QtQuick import QtQuick.Layouts +import ZShell.Config import qs.Components -import qs.Config +import qs.Services CustomClippingRect { id: root @@ -13,10 +14,10 @@ CustomClippingRect { required property real temperature required property real usage - color: DynamicColors.tPalette.m3surfaceContainer - implicitHeight: Math.max(tempProg.implicitHeight + detailsRow.implicitHeight + Appearance.spacing.large, usageColumn.implicitHeight + usageLabel.implicitHeight) + Appearance.padding.large * 2 + color: Colors.tPalette.m3surfaceContainer + implicitHeight: Math.max(tempProg.implicitHeight + detailsRow.implicitHeight + Tokens.spacing.large, usageColumn.implicitHeight + usageLabel.implicitHeight) + Tokens.padding.large * 2 implicitWidth: 450 - radius: Appearance.rounding.large - Appearance.padding.normal + radius: Tokens.rounding.large - Tokens.padding.normal CustomRect { anchors.bottom: parent.bottom @@ -35,12 +36,12 @@ CustomClippingRect { id: tempProg anchors.left: parent.left - anchors.margins: Appearance.padding.large + anchors.margins: Tokens.padding.large anchors.top: parent.top fgColor: root.accent - implicitSize: Math.max(icon.implicitWidth, icon.implicitHeight) + Appearance.padding.larger * 2 - spacing: Appearance.spacing.extraSmall - strokeWidth: Appearance.padding.extraSmall + implicitSize: Math.max(icon.implicitWidth, icon.implicitHeight) + Tokens.padding.larger * 2 + spacing: Tokens.spacing.extraSmall + strokeWidth: Tokens.padding.extraSmall value: root.usage Behavior on clampedVal { @@ -59,10 +60,10 @@ CustomClippingRect { ColumnLayout { anchors.left: tempProg.right - anchors.margins: Appearance.spacing.large + anchors.margins: Tokens.spacing.large anchors.right: usageColumn.left anchors.verticalCenter: tempProg.verticalCenter - spacing: Appearance.spacing.extraSmall + spacing: Tokens.spacing.extraSmall CustomText { color: root.accent @@ -71,7 +72,7 @@ CustomClippingRect { CustomText { Layout.fillWidth: true - color: DynamicColors.palette.m3onSurfaceVariant + color: Colors.palette.m3onSurfaceVariant elide: Text.ElideRight text: root.subLabel } @@ -82,16 +83,16 @@ CustomClippingRect { anchors.bottom: parent.bottom anchors.left: parent.left - anchors.margins: Appearance.padding.largeIncreased - spacing: Appearance.spacing.extraSmall + anchors.margins: Tokens.padding.largeIncreased + spacing: Tokens.spacing.extraSmall RowLayout { - Layout.leftMargin: -Appearance.padding.extraSmall - spacing: Appearance.spacing.extraSmall + Layout.leftMargin: -Tokens.padding.extraSmall + spacing: Tokens.spacing.extraSmall MaterialIcon { Layout.topMargin: Math.round(fontInfo.pointSize * 0.08) - color: root.temperature > 90 ? DynamicColors.palette.m3error : root.accent + color: root.temperature > 90 ? Colors.palette.m3error : root.accent fill: 1 text: root.temperature > 90 ? "thermometer_alert" : "thermometer" } @@ -103,7 +104,7 @@ CustomClippingRect { CustomProgressBar { fgColor: root.accent - implicitHeight: Appearance.padding.small + implicitHeight: Tokens.padding.small indeterminate: isNaN(root.usage) || isNaN(root.temperature) value: root.temperature / 100 } @@ -112,7 +113,7 @@ CustomClippingRect { Column { id: usageColumn - anchors.margins: Appearance.padding.large + anchors.margins: Tokens.padding.large anchors.right: parent.right anchors.rightMargin: 32 anchors.verticalCenter: parent.verticalCenter @@ -122,15 +123,15 @@ CustomClippingRect { id: usageLabel anchors.right: parent.right - color: DynamicColors.palette.m3onSurfaceVariant - font.pointSize: Appearance.font.size.normal + color: Colors.palette.m3onSurfaceVariant + font.pointSize: Tokens.font.size.normal text: qsTr("Usage") } CustomText { anchors.right: parent.right color: root.accent - font.pointSize: Appearance.font.size.extraLarge + font.pointSize: Tokens.font.size.extraLarge font.weight: Font.Medium text: isNaN(root.usage) ? "...%" : Math.round(root.usage * 100) + "%" } diff --git a/Modules/Resources/Cards/MemoryCard.qml b/Modules/Resources/Cards/MemoryCard.qml index 3130d51..a96a67c 100644 --- a/Modules/Resources/Cards/MemoryCard.qml +++ b/Modules/Resources/Cards/MemoryCard.qml @@ -1,19 +1,20 @@ import QtQuick import QtQuick.Layouts import ZShell.Services +import ZShell.Config import qs.Components -import qs.Config +import qs.Services CustomRect { id: root - readonly property color accent: DynamicColors.palette.m3tertiary + readonly property color accent: Colors.palette.m3tertiary Layout.fillWidth: true - color: DynamicColors.tPalette.m3surfaceContainer - implicitHeight: layout.implicitHeight + Appearance.padding.large * 2 - implicitWidth: layout.implicitWidth + Appearance.padding.extraLargeIncreased * 2 - radius: Appearance.rounding.medium + color: Colors.tPalette.m3surfaceContainer + implicitHeight: layout.implicitHeight + Tokens.padding.large * 2 + implicitWidth: layout.implicitWidth + Tokens.padding.extraLargeIncreased * 2 + radius: Tokens.rounding.medium ServiceRef { service: Memory @@ -23,11 +24,11 @@ CustomRect { id: layout anchors.centerIn: parent - spacing: Appearance.spacing.extraSmall + spacing: Tokens.spacing.extraSmall RowLayout { - Layout.leftMargin: -Appearance.padding.extraSmall - spacing: Appearance.spacing.small + Layout.leftMargin: -Tokens.padding.extraSmall + spacing: Tokens.spacing.small MaterialIcon { color: root.accent @@ -42,9 +43,9 @@ CustomRect { CircularProgress { Layout.alignment: Qt.AlignHCenter - Layout.topMargin: Appearance.spacing.large + Layout.topMargin: Tokens.spacing.large fgColor: root.accent - implicitSize: usageColumn.implicitHeight + thickness + Appearance.padding.largeIncreased * 2 + implicitSize: usageColumn.implicitHeight + thickness + Tokens.padding.largeIncreased * 2 startAngle: -225 sweepAngle: 270 value: Memory.percentage @@ -58,19 +59,19 @@ CustomRect { id: usageColumn anchors.centerIn: parent - anchors.verticalCenterOffset: Appearance.padding.extraSmall + anchors.verticalCenterOffset: Tokens.padding.extraSmall spacing: 0 CustomText { Layout.alignment: Qt.AlignHCenter color: root.accent - font.pointSize: Appearance.font.size.large + font.pointSize: Tokens.font.size.large text: Math.round(Memory.percentage * 100) + "%" } CustomText { Layout.alignment: Qt.AlignHCenter - color: DynamicColors.palette.m3onSurfaceVariant + color: Colors.palette.m3onSurfaceVariant text: qsTr("Used") } } diff --git a/Modules/Resources/Cards/NetworkCard.qml b/Modules/Resources/Cards/NetworkCard.qml index 7ddb26b..e70d950 100644 --- a/Modules/Resources/Cards/NetworkCard.qml +++ b/Modules/Resources/Cards/NetworkCard.qml @@ -1,17 +1,18 @@ import QtQuick import QtQuick.Layouts import ZShell.Internal +import ZShell.Config import qs.Helpers import qs.Components -import qs.Config +import qs.Services CustomRect { id: root - color: DynamicColors.tPalette.m3surfaceContainer + color: Colors.tPalette.m3surfaceContainer implicitHeight: 220 implicitWidth: 300 - radius: Appearance.rounding.large - Appearance.padding.normal + radius: Tokens.rounding.large - Tokens.padding.normal Ref { service: NetworkUsage @@ -20,16 +21,16 @@ CustomRect { ColumnLayout { id: layout - anchors.bottomMargin: Appearance.padding.larger + anchors.bottomMargin: Tokens.padding.larger anchors.fill: parent - anchors.margins: Appearance.padding.large + anchors.margins: Tokens.padding.large spacing: 0 RowLayout { - spacing: Appearance.spacing.small + spacing: Tokens.spacing.small MaterialIcon { - color: DynamicColors.palette.m3primary + color: Colors.palette.m3primary text: "swap_vert" } @@ -39,10 +40,10 @@ CustomRect { } Item { - Layout.bottomMargin: Appearance.spacing.small + Layout.bottomMargin: Tokens.spacing.small Layout.fillHeight: true Layout.fillWidth: true - Layout.topMargin: Appearance.spacing.larger + Layout.topMargin: Tokens.spacing.larger SparklineItem { id: sparkline @@ -54,10 +55,10 @@ CustomRect { anchors.fill: parent historyLength: NetworkUsage.historyLength line1: NetworkUsage.uploadBuffer // qmllint disable missing-type - line1Color: DynamicColors.palette.m3secondary + line1Color: Colors.palette.m3secondary line1FillAlpha: 0.15 line2: NetworkUsage.downloadBuffer // qmllint disable missing-type - line2Color: DynamicColors.palette.m3tertiary + line2Color: Colors.palette.m3tertiary line2FillAlpha: 0.2 maxValue: smoothMax slideProgress: 1 @@ -101,7 +102,7 @@ CustomRect { // "Collecting data" placeholder CustomText { anchors.centerIn: parent - color: DynamicColors.palette.m3outline + color: Colors.palette.m3outline text: qsTr("Collecting data...") visible: NetworkUsage.downloadBuffer.count < 2 } @@ -110,15 +111,15 @@ CustomRect { // Download row RowLayout { Layout.fillWidth: true - spacing: Appearance.spacing.small + spacing: Tokens.spacing.small MaterialIcon { - color: DynamicColors.palette.m3tertiary + color: Colors.palette.m3tertiary text: "download" } CustomText { - color: DynamicColors.palette.m3onSurfaceVariant + color: Colors.palette.m3onSurfaceVariant text: qsTr("Download") } @@ -127,7 +128,7 @@ CustomRect { } CustomText { - color: DynamicColors.palette.m3tertiary + color: Colors.palette.m3tertiary text: { const fmt = NetworkUsage.formatBytes(NetworkUsage.downloadSpeed ?? 0); return fmt ? `${fmt.value.toFixed(1)} ${fmt.unit}` : "0.0 B/s"; @@ -138,15 +139,15 @@ CustomRect { // Upload row RowLayout { Layout.fillWidth: true - spacing: Appearance.spacing.small + spacing: Tokens.spacing.small MaterialIcon { - color: DynamicColors.palette.m3secondary + color: Colors.palette.m3secondary text: "upload" } CustomText { - color: DynamicColors.palette.m3onSurfaceVariant + color: Colors.palette.m3onSurfaceVariant text: qsTr("Upload") } @@ -155,7 +156,7 @@ CustomRect { } CustomText { - color: DynamicColors.palette.m3secondary + color: Colors.palette.m3secondary text: { const fmt = NetworkUsage.formatBytes(NetworkUsage.uploadSpeed ?? 0); return fmt ? `${fmt.value.toFixed(1)} ${fmt.unit}` : "0.0 B/s"; @@ -166,15 +167,15 @@ CustomRect { // Session totals RowLayout { Layout.fillWidth: true - spacing: Appearance.spacing.small + spacing: Tokens.spacing.small MaterialIcon { - color: DynamicColors.palette.m3onSurfaceVariant + color: Colors.palette.m3onSurfaceVariant text: "history" } CustomText { - color: DynamicColors.palette.m3onSurfaceVariant + color: Colors.palette.m3onSurfaceVariant text: qsTr("Total") } @@ -183,7 +184,7 @@ CustomRect { } CustomText { - color: DynamicColors.palette.m3onSurfaceVariant + color: Colors.palette.m3onSurfaceVariant text: { const down = NetworkUsage.formatBytesTotal(NetworkUsage.downloadTotal ?? 0); const up = NetworkUsage.formatBytesTotal(NetworkUsage.uploadTotal ?? 0); diff --git a/Modules/Resources/Cards/StorageCard.qml b/Modules/Resources/Cards/StorageCard.qml index 1a58283..a0a6927 100644 --- a/Modules/Resources/Cards/StorageCard.qml +++ b/Modules/Resources/Cards/StorageCard.qml @@ -2,19 +2,20 @@ import QtQuick import QtQuick.Layouts import Quickshell import ZShell.Services +import ZShell.Config import qs.Components -import qs.Config +import qs.Services CustomRect { id: root - readonly property color accent: DynamicColors.palette.m3secondary + readonly property color accent: Colors.palette.m3secondary readonly property real percentage: Storage.primaryDisk?.perc ?? 0 - color: DynamicColors.tPalette.m3surfaceContainer - implicitHeight: layout.implicitHeight + Appearance.padding.large * 2 + color: Colors.tPalette.m3surfaceContainer + implicitHeight: layout.implicitHeight + Tokens.padding.large * 2 implicitWidth: layout.implicitWidth + layout.anchors.margins * 2 - radius: Appearance.rounding.large - Appearance.padding.normal + radius: Tokens.rounding.large - Tokens.padding.normal ServiceRef { service: Storage @@ -24,7 +25,7 @@ CustomRect { id: layout anchors.left: parent.left - anchors.margins: Appearance.padding.small + anchors.margins: Tokens.padding.small anchors.right: parent.right anchors.verticalCenter: parent.verticalCenter spacing: 0 @@ -33,11 +34,11 @@ CustomRect { id: row Layout.alignment: Qt.AlignHCenter - spacing: Appearance.spacing.large + spacing: Tokens.spacing.large CircularProgress { fgColor: root.accent - implicitSize: usageColumn.implicitHeight + thickness + Appearance.padding.large * 2 + implicitSize: usageColumn.implicitHeight + thickness + Tokens.padding.large * 2 startAngle: -225 sweepAngle: 270 value: root.percentage @@ -56,27 +57,27 @@ CustomRect { MaterialIcon { Layout.alignment: Qt.AlignHCenter color: root.accent - font.pointSize: Appearance.font.size.medium + font.pointSize: Tokens.font.size.medium text: "hard_drive" } CustomText { Layout.alignment: Qt.AlignHCenter color: root.accent - font.pointSize: Appearance.font.size.large + font.pointSize: Tokens.font.size.large text: Math.round(root.percentage * 100) + "%" } CustomText { Layout.alignment: Qt.AlignHCenter - color: DynamicColors.palette.m3onSurfaceVariant + color: Colors.palette.m3onSurfaceVariant text: qsTr("Used") } } } ColumnLayout { - spacing: Appearance.spacing.extraSmall + spacing: Tokens.spacing.extraSmall CustomText { text: qsTr("Storage") diff --git a/Modules/Resources/Cards/VramCard.qml b/Modules/Resources/Cards/VramCard.qml index 4cee29e..4533a34 100644 --- a/Modules/Resources/Cards/VramCard.qml +++ b/Modules/Resources/Cards/VramCard.qml @@ -1,19 +1,20 @@ import QtQuick import QtQuick.Layouts import ZShell.Services +import ZShell.Config import qs.Components -import qs.Config +import qs.Services CustomRect { id: root - readonly property color accent: DynamicColors.palette.m3tertiary + readonly property color accent: Colors.palette.m3tertiary Layout.fillWidth: true - color: DynamicColors.tPalette.m3surfaceContainer - implicitHeight: layout.implicitHeight + Appearance.padding.large * 2 - implicitWidth: layout.implicitWidth + Appearance.padding.extraLargeIncreased - radius: Appearance.rounding.medium + color: Colors.tPalette.m3surfaceContainer + implicitHeight: layout.implicitHeight + Tokens.padding.large * 2 + implicitWidth: layout.implicitWidth + Tokens.padding.extraLargeIncreased + radius: Tokens.rounding.medium ServiceRef { service: Gpu @@ -23,11 +24,11 @@ CustomRect { id: layout anchors.centerIn: parent - spacing: Appearance.spacing.extraSmall + spacing: Tokens.spacing.extraSmall RowLayout { - Layout.leftMargin: -Appearance.padding.extraSmall - spacing: Appearance.spacing.small + Layout.leftMargin: -Tokens.padding.extraSmall + spacing: Tokens.spacing.small MaterialIcon { color: root.accent @@ -44,9 +45,9 @@ CustomRect { id: circularIndicator Layout.alignment: Qt.AlignHCenter - Layout.topMargin: Appearance.spacing.large + Layout.topMargin: Tokens.spacing.large fgColor: root.accent - implicitSize: usageColumn.implicitHeight + thickness + Appearance.padding.largeIncreased * 2 + implicitSize: usageColumn.implicitHeight + thickness + Tokens.padding.largeIncreased * 2 startAngle: -225 sweepAngle: 270 value: Gpu.memoryUsed / Gpu.memoryTotal @@ -60,19 +61,19 @@ CustomRect { id: usageColumn anchors.centerIn: parent - anchors.verticalCenterOffset: Appearance.padding.extraSmall + anchors.verticalCenterOffset: Tokens.padding.extraSmall spacing: 0 CustomText { Layout.alignment: Qt.AlignHCenter color: root.accent - font.pointSize: Appearance.font.size.large + font.pointSize: Tokens.font.size.large text: Math.round(circularIndicator.value * 100) + "%" } CustomText { Layout.alignment: Qt.AlignHCenter - color: DynamicColors.palette.m3onSurfaceVariant + color: Colors.palette.m3onSurfaceVariant text: qsTr("Used") } } diff --git a/Modules/Resources/Content.qml b/Modules/Resources/Content.qml index 359f1c4..8a4ba57 100644 --- a/Modules/Resources/Content.qml +++ b/Modules/Resources/Content.qml @@ -1,36 +1,36 @@ import QtQuick import QtQuick.Layouts import ZShell.Services +import ZShell.Config import qs.Modules.Resources.Cards import qs.Helpers -import qs.Components -import qs.Config +import qs.Services Item { id: root required property Wrapper wrapper - implicitHeight: content.implicitHeight + Appearance.padding.normal * 2 + implicitHeight: content.implicitHeight + Tokens.padding.normal * 2 implicitWidth: content.implicitWidth RowLayout { id: content anchors.left: parent.left - anchors.margins: Appearance.padding.normal + anchors.margins: Tokens.padding.normal anchors.right: parent.right anchors.verticalCenter: parent.verticalCenter - spacing: Appearance.spacing.larger + spacing: Tokens.spacing.larger ColumnLayout { id: mainColumn Layout.fillWidth: true - spacing: Appearance.spacing.normal + spacing: Tokens.spacing.normal RowLayout { - spacing: Appearance.spacing.normal + spacing: Tokens.spacing.normal visible: cpuCard.active || gpuCard.active WrappedLoader { @@ -39,7 +39,7 @@ Item { active: Config.dashboard.performance.showCpu sourceComponent: HeroCard { - accent: DynamicColors.palette.m3primary + accent: Colors.palette.m3primary icon: "memory" label: qsTr("CPU") subLabel: Cpu.name @@ -58,7 +58,7 @@ Item { active: Config.dashboard.performance.showGpu && Gpu.type !== Gpu.None sourceComponent: HeroCard { - accent: DynamicColors.palette.m3secondary + accent: Colors.palette.m3secondary icon: "desktop_windows" label: qsTr("GPU") subLabel: Gpu.name @@ -73,7 +73,7 @@ Item { } RowLayout { - spacing: Appearance.spacing.normal + spacing: Tokens.spacing.normal visible: storageCard.active || memoryCard.active || vramCard.active || networkCard1.active WrappedLoader { diff --git a/Modules/Resources/Wrapper.qml b/Modules/Resources/Wrapper.qml index 7c196e6..a0a9806 100644 --- a/Modules/Resources/Wrapper.qml +++ b/Modules/Resources/Wrapper.qml @@ -3,7 +3,7 @@ pragma ComponentBehavior: Bound import Quickshell import QtQuick import qs.Components -import qs.Config +import ZShell.Config Item { id: root @@ -22,8 +22,8 @@ Item { Behavior on offsetScale { Anim { - duration: Appearance.anim.durations.expressiveDefaultSpatial - easing.bezierCurve: Appearance.anim.curves.expressiveDefaultSpatial + duration: Tokens.anim.durations.expressiveDefaultSpatial + easing.bezierCurve: Tokens.anim.curves.expressiveDefaultSpatial } } diff --git a/Modules/Settings/Common/AudioDeviceList.qml b/Modules/Settings/Common/AudioDeviceList.qml index 0c38960..541b4bf 100644 --- a/Modules/Settings/Common/AudioDeviceList.qml +++ b/Modules/Settings/Common/AudioDeviceList.qml @@ -5,7 +5,8 @@ import QtQuick.Layouts import Quickshell import Quickshell.Services.Pipewire import qs.Components -import qs.Config +import ZShell.Config +import qs.Services ItemList { id: root @@ -31,9 +32,9 @@ ItemList { implicitHeight: deviceLayout.implicitHeight + deviceLayout.anchors.margins * 2 StateLayer { - bottomLeftRadius: device.index === root?.list.count - 1 ? Appearance.rounding.large : radius - bottomRightRadius: device.index === root?.list.count - 1 ? Appearance.rounding.large : radius - radius: Appearance.rounding.extraSmall + bottomLeftRadius: device.index === root?.list.count - 1 ? Tokens.rounding.large : radius + bottomRightRadius: device.index === root?.list.count - 1 ? Tokens.rounding.large : radius + radius: Tokens.rounding.extraSmall onClicked: root.selected(device.modelData) } @@ -42,24 +43,24 @@ ItemList { id: deviceLayout anchors.fill: parent - anchors.leftMargin: Appearance.padding.largeIncreased - anchors.margins: Appearance.padding.large - anchors.rightMargin: Appearance.padding.largeIncreased - spacing: Appearance.spacing.normal + anchors.leftMargin: Tokens.padding.largeIncreased + anchors.margins: Tokens.padding.large + anchors.rightMargin: Tokens.padding.largeIncreased + spacing: Tokens.spacing.normal CustomRect { - color: device.active ? DynamicColors.palette.m3primary : DynamicColors.palette.m3secondaryContainer - implicitHeight: devIcon.implicitHeight + Appearance.padding.normal * 2 + color: device.active ? Colors.palette.m3primary : Colors.palette.m3secondaryContainer + implicitHeight: devIcon.implicitHeight + Tokens.padding.normal * 2 implicitWidth: implicitHeight - radius: Appearance.rounding.full + radius: Tokens.rounding.full MaterialIcon { id: devIcon anchors.centerIn: parent - color: device.active ? DynamicColors.palette.m3onPrimary : DynamicColors.palette.m3onSecondaryContainer + color: device.active ? Colors.palette.m3onPrimary : Colors.palette.m3onSecondaryContainer fill: device.active ? 1 : 0 - font.pointSize: Appearance.font.size.large + font.pointSize: Tokens.font.size.large text: root.iconName Behavior on fill { @@ -72,13 +73,13 @@ ItemList { CustomText { Layout.fillWidth: true elide: Text.ElideRight - font.pointSize: Appearance.font.size.smaller + font.pointSize: Tokens.font.size.smaller text: device.modelData?.description || device.modelData?.name || qsTr("Unknown") } MaterialIcon { - color: DynamicColors.palette.m3primary - font.pointSize: Appearance.font.size.large + color: Colors.palette.m3primary + font.pointSize: Tokens.font.size.large opacity: device.active ? 1 : 0 text: "check" diff --git a/Modules/Settings/Common/BlobPopup.qml b/Modules/Settings/Common/BlobPopup.qml index 4cfd011..a80904d 100644 --- a/Modules/Settings/Common/BlobPopup.qml +++ b/Modules/Settings/Common/BlobPopup.qml @@ -1,7 +1,8 @@ import QtQuick import ZShell.Blobs import qs.Components -import qs.Config +import ZShell.Config +import qs.Services Item { id: root @@ -15,7 +16,7 @@ Item { property bool open property int padding property bool pressOverride - property int topMovement: Appearance.padding.large + property int topMovement: Tokens.padding.large implicitHeight: btn.implicitHeight * 0.9 implicitWidth: btn.implicitWidth * 0.9 @@ -29,9 +30,9 @@ Item { BlobGroup { id: blobGroup - color: DynamicColors.palette.m3surfaceContainerHighest + color: Colors.palette.m3surfaceContainerHighest cornerFill: false - smoothing: Appearance.rounding.medium + smoothing: Tokens.rounding.medium Behavior on color { CAnim { @@ -43,9 +44,9 @@ Item { id: btnRect anchors.fill: parent - anchors.margins: (!(btn.pressed || root.pressOverride) && (btn.containsMouse || root.hoverOverride) ? -Appearance.padding.extraSmall : 0) + (root.open ? -Appearance.padding.extraSmall : 0) + anchors.margins: (!(btn.pressed || root.pressOverride) && (btn.containsMouse || root.hoverOverride) ? -Tokens.padding.extraSmall : 0) + (root.open ? -Tokens.padding.extraSmall : 0) group: blobGroup - radius: root.open ? Appearance.rounding.large : Appearance.rounding.medium + radius: root.open ? Tokens.rounding.large : Tokens.rounding.medium Behavior on anchors.margins { Anim { @@ -67,14 +68,14 @@ Item { group: blobGroup implicitHeight: parent.height implicitWidth: parent.width - radius: Appearance.rounding.small + Appearance.padding.small + radius: Tokens.rounding.small + Tokens.padding.small states: State { name: "open" when: root.open PropertyChanges { - rect.anchors.rightMargin: root.width - Appearance.spacing.small + rect.anchors.rightMargin: root.width - Tokens.spacing.small rect.anchors.topMargin: -root.topMovement rect.implicitHeight: root.content.implicitHeight + root.padding * 2 rect.implicitWidth: root.content.implicitWidth + root.padding * 2 @@ -87,8 +88,8 @@ Item { } Anim { - duration: Appearance.anim.durations.expressiveFastEffects - easing.bezierCurve: Appearance.anim.curves.expressiveFastEffects + duration: Tokens.anim.durations.expressiveFastEffects + easing.bezierCurve: Tokens.anim.curves.expressiveFastEffects properties: "topMargin,implicitHeight" } @@ -111,7 +112,7 @@ Item { anchors.centerIn: parent cursorShape: Qt.PointingHandCursor hoverEnabled: true - implicitHeight: icon.implicitHeight + Appearance.padding.extraSmall * 2 + implicitHeight: icon.implicitHeight + Tokens.padding.extraSmall * 2 implicitWidth: implicitHeight onClicked: root.open = !root.open @@ -120,8 +121,8 @@ Item { id: icon anchors.centerIn: parent - color: DynamicColors.palette.m3onSurfaceVariant - font.pointSize: Appearance.font.size.medium + color: Colors.palette.m3onSurfaceVariant + font.pointSize: Tokens.font.size.medium text: "view_apps" } } diff --git a/Modules/Settings/Common/ConnectedRect.qml b/Modules/Settings/Common/ConnectedRect.qml index 8bb9829..ec422f9 100644 --- a/Modules/Settings/Common/ConnectedRect.qml +++ b/Modules/Settings/Common/ConnectedRect.qml @@ -1,6 +1,7 @@ import QtQuick import qs.Components -import qs.Config +import ZShell.Config +import qs.Services CustomRect { id: root @@ -13,11 +14,17 @@ CustomRect { flash.restart(); } - bottomLeftRadius: last ? Appearance.rounding.large : Appearance.rounding.extraSmall - bottomRightRadius: last ? Appearance.rounding.large : Appearance.rounding.extraSmall - color: DynamicColors.tPalette.m3surfaceContainer - topLeftRadius: first ? Appearance.rounding.large : Appearance.rounding.extraSmall - topRightRadius: first ? Appearance.rounding.large : Appearance.rounding.extraSmall + bottomLeftRadius: last ? Tokens.rounding.large : Tokens.rounding.extraSmall + bottomRightRadius: last ? Tokens.rounding.large : Tokens.rounding.extraSmall + color: Colors.tPalette.m3surfaceContainer + opacity: enabled && parent.enabled ? 1 : 0.5 + topLeftRadius: first ? Tokens.rounding.large : Tokens.rounding.extraSmall + topRightRadius: first ? Tokens.rounding.large : Tokens.rounding.extraSmall + + Behavior on opacity { + Anim { + } + } CustomRect { id: highlight @@ -25,7 +32,7 @@ CustomRect { anchors.fill: parent bottomLeftRadius: parent.bottomLeftRadius bottomRightRadius: parent.bottomRightRadius - color: DynamicColors.palette.m3primary + color: Colors.palette.m3primary opacity: 0 radius: parent.radius topLeftRadius: parent.topLeftRadius @@ -35,28 +42,28 @@ CustomRect { id: flash Anim { - duration: Appearance.anim.durations.small + duration: Tokens.anim.durations.small property: "opacity" target: highlight to: 0.2 } Anim { - duration: Appearance.anim.durations.normal + duration: Tokens.anim.durations.normal property: "opacity" target: highlight to: 0.08 } Anim { - duration: Appearance.anim.durations.small + duration: Tokens.anim.durations.small property: "opacity" target: highlight to: 0.2 } Anim { - duration: Appearance.anim.durations.extraLarge + duration: Tokens.anim.durations.extraLarge property: "opacity" target: highlight to: 0 diff --git a/Modules/Settings/Common/DialogRowButton.qml b/Modules/Settings/Common/DialogRowButton.qml new file mode 100644 index 0000000..e5f7fe9 --- /dev/null +++ b/Modules/Settings/Common/DialogRowButton.qml @@ -0,0 +1,250 @@ +pragma ComponentBehavior: Bound + +import QtQuick +import QtQuick.Layouts +import ZShell.Blobs +import qs.Components +import ZShell.Config +import qs.Services + +Item { + id: root + + property bool acceptAllowed: true + required property string acceptLabel + required property Component content + required property string header + property int horizontalContentMargin + required property string icon + required property string label + property bool open + property real openHeight: Math.min(rootParent.height * 0.8, 600) + property real openWidth: Math.min(rootParent.width * 0.8, 400) + required property Item rootParent + property bool separateContent + + signal accepted + signal cancelled + + function reparentWrapper(): void { + const newParent = open ? rootParent : root; + const pos = dialogWrapper.mapToItem(newParent, 0, 0); + dialogWrapper.parent = newParent; + dialogWrapper.x = pos.x; + dialogWrapper.y = pos.y; + } + + Layout.fillWidth: true + implicitHeight: openButton.implicitHeight + z: open || dialogTransition.running ? 2 : 0 + + BlobGroup { + id: blobGroup + + color: root.open ? Colors.palette.m3surfaceContainerHighest : Colors.tPalette.m3surfaceContainer + + Behavior on color { + CAnim { + } + } + } + + MouseArea { + id: backdrop + + anchors.fill: parent + enabled: false + hoverEnabled: enabled + parent: root.open ? root.rootParent : root + + onClicked: root.open = false + } + + Item { + id: dialogWrapper + + height: openButton.implicitHeight + width: root.width + z: 1 + + states: State { + name: "open" + when: root.open + + PropertyChanges { + backdrop.enabled: true + dialogBg.bottomLeftRadius: Tokens.rounding.large + dialogBg.bottomRightRadius: Tokens.rounding.large + dialogBg.radius: Tokens.rounding.large + dialogContent.opacity: 1 + dialogWrapper.height: root.openHeight + dialogWrapper.width: root.openWidth + dialogWrapper.x: (root.rootParent.width - root.openWidth) / 2 + dialogWrapper.y: (root.rootParent.height - root.openHeight) / 2 + elevation.opacity: 1 + openButton.opacity: 0 + } + } + transitions: Transition { + id: dialogTransition + + SequentialAnimation { + ScriptAction { + script: root.reparentWrapper() + } + + Anim { + properties: "x,y" + } + } + + PropertyAction { + property: "enabled" + } + + Anim { + properties: "opacity,radius,bottomLeftRadius,bottomRightRadius" + type: Anim.DefaultEffects + } + + Anim { + properties: "width,height" + } + } + + Elevation { + id: elevation + + anchors.fill: parent + bottomLeftRadius: dialogBg.bottomLeftRadius + bottomRightRadius: dialogBg.bottomRightRadius + level: 4 + opacity: 0 + radius: dialogBg.radius + + transform: Matrix4x4 { + matrix: dialogBg.deformMatrix + } + } + + BlobRect { + id: dialogBg + + anchors.fill: parent + bottomLeftRadius: Tokens.rounding.large + bottomRightRadius: Tokens.rounding.large + deformScale: 0 + group: blobGroup + opacity: blobGroup.color.a * (root.enabled ? 1 : 0.5) + radius: Tokens.rounding.extraSmall + } + + RowButton { + id: openButton + + anchors.left: parent.left + anchors.right: parent.right + color: "transparent" + height: Math.min(implicitHeight, parent.height) // Clamp to parent height due to overshoot anim + icon: root.icon + last: true + text: root.label + + transform: Matrix4x4 { + matrix: dialogBg.deformMatrix + } + + onClicked: root.open = true + } + + Loader { + id: dialogContent + + active: opacity > 0 + anchors.fill: parent + asynchronous: true + opacity: 0 + + sourceComponent: MouseArea { + onWheel: event => event.accepted = true + + ColumnLayout { + anchors.bottomMargin: Tokens.padding.largeIncreased + anchors.fill: parent + anchors.margins: Tokens.padding.extraLarge + spacing: 0 + + CustomText { + font.pointSize: Tokens.font.size.large + text: root.header + } + + Loader { + Layout.fillWidth: true + Layout.topMargin: Tokens.spacing.normal + active: root.separateContent + + sourceComponent: CustomRect { + color: Colors.palette.m3outline + implicitHeight: 1 + } + } + + Loader { + Layout.fillHeight: true + Layout.fillWidth: true + Layout.leftMargin: root.horizontalContentMargin + Layout.rightMargin: root.horizontalContentMargin + sourceComponent: root.content + } + + Loader { + Layout.bottomMargin: Tokens.spacing.normal + Layout.fillWidth: true + active: root.separateContent + + sourceComponent: CustomRect { + color: Colors.palette.m3outline + implicitHeight: 1 + } + } + + RowLayout { + Layout.alignment: Qt.AlignRight + spacing: Tokens.spacing.extraSmall + + TextButton { + horizontalPadding: Tokens.padding.largeIncreased + isRound: true + text: qsTr("Cancel") + type: TextButton.Text + verticalPadding: Tokens.padding.normal + + onClicked: { + root.cancelled(); + root.open = false; + } + } + + TextButton { + enabled: root.acceptAllowed + horizontalPadding: Tokens.padding.largeIncreased + isRound: true + text: root.acceptLabel + type: TextButton.Text + verticalPadding: Tokens.padding.normal + + onClicked: { + root.accepted(); + root.open = false; + } + } + } + } + } + transform: Matrix4x4 { + matrix: dialogBg.deformMatrix + } + } + } +} diff --git a/Modules/Settings/Common/DialogSelectButton.qml b/Modules/Settings/Common/DialogSelectButton.qml new file mode 100644 index 0000000..6a60648 --- /dev/null +++ b/Modules/Settings/Common/DialogSelectButton.qml @@ -0,0 +1,97 @@ +pragma ComponentBehavior: Bound + +import QtQuick +import ZShell.Config +import qs.Components +import qs.Services + +DialogRowButton { + id: root + + required property var model + property var selectedItem + + function keyFor(item: var): string { + return item.id; + } + + function labelFor(item: var): string { + return item.label; + } + + acceptAllowed: !!selectedItem + horizontalContentMargin: -Tokens.padding.small + separateContent: true + + content: Component { + VerticalFadeListView { + bottomMargin: Tokens.padding.large + model: root.model + spacing: 0 + topMargin: Tokens.padding.large + + delegate: CustomRect { + id: item + + required property var modelData + readonly property bool selected: root.selectedItem === root.keyFor(modelData) + + anchors.left: ListView.view.contentItem.left + anchors.margins: 1 // Gets cut off for some reason without this + anchors.right: ListView.view.contentItem.right + color: Qt.alpha(Colors.palette.m3tertiaryContainer, selected ? 1 : 0) + implicitHeight: label.implicitHeight + Tokens.padding.normal * 2 + radius: stateLayer.pressed ? Tokens.rounding.extraSmall : selected ? Tokens.rounding.large : Tokens.rounding.normal + + Behavior on radius { + Anim { + type: Anim.SlowEffects + } + } + + StateLayer { + id: stateLayer + + onClicked: root.selectedItem = root.keyFor(item.modelData) + } + + CustomText { + id: label + + anchors.left: parent.left + anchors.margins: Tokens.padding.large + anchors.right: item.selected ? checkIcon.left : parent.right + anchors.rightMargin: item.selected ? Tokens.spacing.normal : anchors.margins + anchors.verticalCenter: parent.verticalCenter + color: item.selected ? Colors.palette.m3onTertiaryContainer : Colors.palette.m3onSurface + elide: Text.ElideRight + font.pointSize: Tokens.font.size.smaller + text: root.labelFor(item.modelData) + } + + MaterialIcon { + id: checkIcon + + anchors.margins: Tokens.padding.large + anchors.right: parent.right + anchors.verticalCenter: parent.verticalCenter + color: Colors.palette.m3onTertiaryContainer + font.pointSize: Tokens.font.size.medium + opacity: item.selected ? 1 : 0 + text: "check" + + Behavior on opacity { + Anim { + type: Anim.SlowEffects + } + } + } + } + } + } + + onOpenChanged: { + if (open) + selectedItem = null; + } +} diff --git a/Modules/Settings/Common/InfoRow.qml b/Modules/Settings/Common/InfoRow.qml index 1a715ff..a635e73 100644 --- a/Modules/Settings/Common/InfoRow.qml +++ b/Modules/Settings/Common/InfoRow.qml @@ -3,13 +3,14 @@ pragma ComponentBehavior: Bound import QtQuick import QtQuick.Layouts import qs.Components -import qs.Config +import ZShell.Config +import qs.Services ConnectedRect { id: root property string icon - property color iconColor: DynamicColors.palette.m3onSurfaceVariant + property color iconColor: Colors.palette.m3onSurfaceVariant property alias label: label.text property Component leadingComponent: icon ? iconComp : null property string subtext @@ -23,7 +24,7 @@ ConnectedRect { MaterialIcon { color: root.iconColor - font.pointSize: Appearance.font.size.small + font.pointSize: Tokens.font.size.small text: root.icon } } @@ -32,10 +33,10 @@ ConnectedRect { id: rowLayout anchors.fill: parent - anchors.leftMargin: Appearance.padding.largeIncreased - anchors.margins: Appearance.padding.larger - anchors.rightMargin: Appearance.padding.largeIncreased - spacing: Appearance.spacing.small + anchors.leftMargin: Tokens.padding.largeIncreased + anchors.margins: Tokens.padding.larger + anchors.rightMargin: Tokens.padding.largeIncreased + spacing: Tokens.spacing.small Loader { active: root.leadingComponent @@ -52,14 +53,14 @@ ConnectedRect { Layout.fillWidth: true elide: Text.ElideRight - font.pointSize: Appearance.font.size.small + font.pointSize: Tokens.font.size.small } CustomText { Layout.fillWidth: true - color: DynamicColors.palette.m3outline + color: Colors.palette.m3outline elide: Text.ElideRight - font.pointSize: Appearance.font.size.small + font.pointSize: Tokens.font.size.small text: root.subtext visible: root.subtext } @@ -69,9 +70,9 @@ ConnectedRect { id: value Layout.maximumWidth: root.width / 2 - color: DynamicColors.palette.m3onSurfaceVariant + color: Colors.palette.m3onSurfaceVariant elide: Text.ElideRight - font.pointSize: Appearance.font.size.small + font.pointSize: Tokens.font.size.small horizontalAlignment: Text.AlignRight } } diff --git a/Modules/Settings/Common/ItemList.qml b/Modules/Settings/Common/ItemList.qml index 850f3aa..b5fcd41 100644 --- a/Modules/Settings/Common/ItemList.qml +++ b/Modules/Settings/Common/ItemList.qml @@ -3,7 +3,8 @@ pragma ComponentBehavior: Bound import QtQuick import QtQuick.Layouts import qs.Components -import qs.Config +import ZShell.Config +import qs.Services ConnectedRect { id: root @@ -18,8 +19,8 @@ ConnectedRect { Layout.fillWidth: true clip: true - color: DynamicColors.tPalette.m3surfaceContainer - implicitHeight: (showList && list.count > 0 ? list.contentHeight : placeholder.implicitHeight + Appearance.padding.extraLarge * 2) + extraHeight + color: Colors.tPalette.m3surfaceContainer + implicitHeight: (showList && list.count > 0 ? list.contentHeight : placeholder.implicitHeight + Tokens.padding.extraLarge * 2) + extraHeight Behavior on implicitHeight { Anim { @@ -39,21 +40,21 @@ ConnectedRect { } } sourceComponent: ColumnLayout { - spacing: Appearance.spacing.extraSmall + spacing: Tokens.spacing.extraSmall MaterialIcon { Layout.alignment: Qt.AlignHCenter animate: true - color: DynamicColors.palette.m3outline - font.pointSize: Appearance.font.size.large + color: Colors.palette.m3outline + font.pointSize: Tokens.font.size.large text: root.placeholderIcon } CustomText { Layout.alignment: Qt.AlignHCenter animate: true - color: DynamicColors.palette.m3outline - font.pointSize: Appearance.font.size.large + color: Colors.palette.m3outline + font.pointSize: Tokens.font.size.large text: root.placeholderText } } diff --git a/Modules/Settings/Common/ListEditor.qml b/Modules/Settings/Common/ListEditor.qml new file mode 100644 index 0000000..a380e94 --- /dev/null +++ b/Modules/Settings/Common/ListEditor.qml @@ -0,0 +1,319 @@ +pragma ComponentBehavior: Bound + +import QtQuick +import QtQuick.Layouts +import Quickshell +import ZShell.Config +import qs.Components +import qs.Services + +ListView { + id: root + + property bool first + property alias values: valuesModel.values + + signal itemMoved(from: int, to: int) + signal itemRemoved(index: int) + signal itemToggled(index: int, checked: bool) + + function dampOvershoot(overshoot: real, maxOvershoot: real): real { + return overshoot / (1 + overshoot / maxOvershoot); + } + + function labelFor(item: var): string { + return item.label; + } + + function toggledFor(item: var): bool { + return false; + } + + Layout.fillWidth: true + implicitHeight: contentHeight + interactive: false + spacing: Tokens.spacing.extraSmall / 2 + + add: Transition { + Anim { + from: 0 + properties: "opacity" + to: 1 + type: Anim.DefaultEffects + } + } + displaced: Transition { + Anim { + properties: "opacity" + to: 1 + type: Anim.DefaultEffects + } + + Anim { + properties: "y" + } + } + Behavior on implicitHeight { + Anim { + } + } + model: DelegateModel { + id: visualModel + + delegate: ListRow { + } + model: ScriptModel { + id: valuesModel + } + } + move: Transition { + Anim { + properties: "opacity" + to: 1 + type: Anim.DefaultEffects + } + + Anim { + properties: "y" + } + } + remove: Transition { + Anim { + properties: "opacity" + to: 0 + type: Anim.DefaultEffects + } + } + + component ListRow: Item { + id: item + + property bool held + property real lastMoveY + required property var modelData + property int pressIndex + property point pressPos + property real radiusLerpProg + property real topRadius: root?.first && DelegateModel.itemsIndex === 0 ? Tokens.rounding.large : Tokens.rounding.extraSmall + + function lerpRadius(a: real, b: real): real { + return a + (b - a) * radiusLerpProg; + } + + anchors.left: root?.contentItem.left + anchors.right: root?.contentItem.right + implicitHeight: row.implicitHeight + row.anchors.margins * 2 + state: held ? "held" : "" + z: held || returnAnim.running ? 1 : 0 + + states: State { + name: "held" + + PropertyChanges { + dragIcon.color: Colors.palette.m3onPrimaryContainer + elevation.opacity: 1 + item.radiusLerpProg: 1 + itemBg.color: Colors.palette.m3primaryContainer + label.color: Colors.palette.m3onPrimaryContainer + placeholder.opacity: 0.1 + } + } + Behavior on topRadius { + Anim { + type: Anim.DefaultEffects + } + } + transitions: Transition { + Anim { + properties: "opacity,radiusLerpProg" + type: Anim.SlowEffects + } + + PropertyAction { + properties: "color,inactiveOnColor" + } + } + + CustomRect { + id: placeholder + + anchors.fill: parent + color: Colors.palette.m3primary + opacity: 0 + radius: Tokens.rounding.extraSmall + topLeftRadius: item.topRadius + topRightRadius: item.topRadius + } + + MouseArea { + id: mouse + + anchors.fill: parent + preventStealing: true + + onPositionChanged: e => { + item.lastMoveY = item.y; + const absY = item.mapToItem(root.contentItem, 0, e.y).y; + + const swap = root.itemAt(0, absY); + if (!swap || swap === item) + return; + + const idx = item.DelegateModel.itemsIndex; + const swapIdx = swap.DelegateModel.itemsIndex; + visualModel.items.move(idx, swapIdx); + } + onPressed: e => { + returnAnim.stop(); + item.pressPos = Qt.point(e.x, e.y); + item.pressIndex = item.DelegateModel.itemsIndex; + item.lastMoveY = item.y; + item.held = true; + + itemContent.x = Qt.binding(() => { + if (!root) { + return 0; + } + + const maxOvershoot = Tokens.padding.extraLargeIncreased; + const x = mouse.mouseX - item.pressPos.x; + return root.dampOvershoot(Math.abs(x), maxOvershoot) * Math.sign(x); + }); + itemContent.y = Qt.binding(() => { + if (!root) + return 0; + + const maxOvershoot = Tokens.padding.extraLarge; + const yDiff = item.y - item.lastMoveY; // Extra offset if the y of the item changed between mouseY updates + const y = mouse.mouseY - item.pressPos.y - yDiff; + const absY = item.mapToItem(root.contentItem, 0, y).y; + const maxY = root.implicitHeight - item.implicitHeight; + if (absY < 0) + return y - absY - root.dampOvershoot(-absY, maxOvershoot); + if (absY > maxY) + return y - absY + maxY + root.dampOvershoot(absY - maxY, maxOvershoot); + return y; + }); + } + onReleased: e => { + // Break bindings + itemContent.x = itemContent.x; + itemContent.y = itemContent.y; + returnAnim.start(); + item.held = false; + + const idx = item.DelegateModel.itemsIndex; + if (idx !== item.pressIndex) + root.itemMoved(item.pressIndex, idx); + } + } + + Anim { + id: returnAnim + + properties: "x,y" + target: itemContent + to: 0 + } + + Item { + id: itemContent + + implicitHeight: item.implicitHeight + implicitWidth: item.width + + Elevation { + id: elevation + + anchors.fill: parent + level: 3 + opacity: 0 + radius: itemBg.radius + topLeftRadius: itemBg.topLeftRadius + topRightRadius: itemBg.topRightRadius + } + + CustomRect { + id: itemBg + + anchors.fill: parent + color: Colors.tPalette.m3surfaceContainer + radius: item.lerpRadius(Tokens.rounding.extraSmall, Tokens.rounding.large) + topLeftRadius: item.lerpRadius(item.topRadius, Tokens.rounding.large) + topRightRadius: item.lerpRadius(item.topRadius, Tokens.rounding.large) + } + + MouseArea { + id: stateLayer + + acceptedButtons: Qt.NoButton + anchors.fill: parent + cursorShape: mouse.pressed ? Qt.ClosedHandCursor : Qt.OpenHandCursor + hoverEnabled: true + + CustomRect { + anchors.fill: parent + color: Colors.palette.m3onSurface + opacity: parent.containsMouse && !item.held ? 0.08 : 0 + radius: itemBg.radius + topLeftRadius: itemBg.topLeftRadius + topRightRadius: itemBg.topRightRadius + + Behavior on opacity { + Anim { + type: Anim.DefaultEffects + } + } + } + } + + RowLayout { + id: row + + anchors.fill: parent + anchors.leftMargin: Tokens.padding.largeIncreased + anchors.margins: Tokens.padding.normal + anchors.rightMargin: Tokens.padding.large + spacing: Tokens.spacing.normal + + MaterialIcon { + id: dragIcon + + color: Qt.alpha(Colors.palette.m3onSurfaceVariant, enabledSwitch.checked ? 1 : 0.5) + font.pointSize: Tokens.font.size.medium + text: "drag_indicator" + } + + CustomText { + id: label + + Layout.fillWidth: true + color: Qt.alpha(Colors.palette.m3onSurface, enabledSwitch.checked ? 1 : 0.5) + elide: Text.ElideRight + font.pointSize: Tokens.font.size.smaller + text: root.labelFor(item.modelData) + } + + CustomSwitch { + id: enabledSwitch + + checked: root.toggledFor(item.modelData) + font.pointSize: Tokens.font.size.medium + + onToggled: root.itemToggled(item.DelegateModel.itemsIndex, checked) + } + + IconButton { + font.pointSize: Tokens.font.size.large + icon: "delete" + inactiveOnColor: Colors.palette.m3error + isRound: true + label.fill: 0 + type: IconButton.Text + + onClicked: root.itemRemoved(item.DelegateModel.itemsIndex) + } + } + } + } +} diff --git a/Modules/Settings/Common/Logo.qml b/Modules/Settings/Common/Logo.qml index 0a12879..ab46e88 100644 --- a/Modules/Settings/Common/Logo.qml +++ b/Modules/Settings/Common/Logo.qml @@ -1,7 +1,8 @@ import QtQuick import QtQuick.Shapes -import qs.Config +import ZShell.Config import qs.Components +import qs.Services Item { id: root @@ -31,12 +32,12 @@ Item { y2: shape.height GradientStop { - color: DynamicColors.palette.m3primary + color: Colors.palette.m3primary position: 0.0 } GradientStop { - color: DynamicColors.palette.m3tertiary + color: Colors.palette.m3tertiary position: 1.0 } } diff --git a/Modules/Settings/Common/NavRow.qml b/Modules/Settings/Common/NavRow.qml index 107d11a..667358e 100644 --- a/Modules/Settings/Common/NavRow.qml +++ b/Modules/Settings/Common/NavRow.qml @@ -3,7 +3,8 @@ pragma ComponentBehavior: Bound import QtQuick import QtQuick.Layouts import qs.Components -import qs.Config +import ZShell.Config +import qs.Services ConnectedRect { id: root @@ -25,16 +26,16 @@ ConnectedRect { id: navLayout anchors.fill: parent - anchors.leftMargin: Appearance.padding.largeIncreased - anchors.margins: Appearance.padding.normal - anchors.rightMargin: Appearance.padding.largeIncreased - spacing: Appearance.spacing.normal + anchors.leftMargin: Tokens.padding.largeIncreased + anchors.margins: Tokens.padding.normal + anchors.rightMargin: Tokens.padding.largeIncreased + spacing: Tokens.spacing.normal MaterialIcon { id: icon - color: DynamicColors.palette.m3onSurfaceVariant - font.pointSize: Appearance.font.size.large + color: Colors.palette.m3onSurfaceVariant + font.pointSize: Tokens.font.size.large } ColumnLayout { @@ -46,7 +47,7 @@ ConnectedRect { Layout.fillWidth: true elide: Text.ElideRight - font.pointSize: Appearance.font.size.small + font.pointSize: Tokens.font.size.small } CustomText { @@ -54,16 +55,16 @@ ConnectedRect { Layout.fillWidth: true animate: true - color: DynamicColors.palette.m3outline + color: Colors.palette.m3outline elide: Text.ElideRight - font.pointSize: Appearance.font.size.small + font.pointSize: Tokens.font.size.small visible: text } } MaterialIcon { - color: DynamicColors.palette.m3onSurfaceVariant - font.pointSize: Appearance.font.size.medium + color: Colors.palette.m3onSurfaceVariant + font.pointSize: Tokens.font.size.medium text: "chevron_right" } } diff --git a/Modules/Settings/Common/OverlayRow.qml b/Modules/Settings/Common/OverlayRow.qml index 94d36c6..abe0342 100644 --- a/Modules/Settings/Common/OverlayRow.qml +++ b/Modules/Settings/Common/OverlayRow.qml @@ -1,18 +1,19 @@ import QtQuick import QtQuick.Layouts -import qs.Config +import ZShell.Config import qs.Components import qs.Modules.Settings +import qs.Services ConnectedRect { id: root property alias checked: switchButton.checked - property int horizontalPadding: Appearance.padding.largeIncreased + property int horizontalPadding: Tokens.padding.largeIncreased required property Component popup property alias subtext: subtext.text property alias text: text.text - property int verticalPadding: Appearance.padding.normal + property int verticalPadding: Tokens.padding.normal signal clicked(checked: bool) @@ -25,20 +26,20 @@ ConnectedRect { anchors.left: parent.left anchors.leftMargin: root.horizontalPadding anchors.right: icon.left - anchors.rightMargin: Appearance.padding.normal + anchors.rightMargin: Tokens.padding.normal anchors.verticalCenter: parent.verticalCenter CustomText { id: text - font.pointSize: Appearance.font.size.smaller + font.pointSize: Tokens.font.size.smaller } CustomText { id: subtext - color: DynamicColors.palette.m3outline - font.pointSize: Appearance.font.size.small + color: Colors.palette.m3outline + font.pointSize: Tokens.font.size.small wrapMode: Text.WordWrap } } @@ -47,7 +48,7 @@ ConnectedRect { id: icon anchors.right: switchButton.left - anchors.rightMargin: Appearance.spacing.normal + anchors.rightMargin: Tokens.spacing.normal anchors.verticalCenter: parent.verticalCenter text: "open_in_new" } diff --git a/Modules/Settings/Common/PageBase.qml b/Modules/Settings/Common/PageBase.qml index 4bf164f..4bceec7 100644 --- a/Modules/Settings/Common/PageBase.qml +++ b/Modules/Settings/Common/PageBase.qml @@ -4,7 +4,8 @@ import QtQuick import QtQuick.Layouts import qs.Modules.Settings import qs.Components -import qs.Config +import ZShell.Config +import qs.Services ColumnLayout { id: root @@ -53,7 +54,7 @@ ColumnLayout { if (!row) return false; const pos = row.mapToItem(flickable.contentItem, 0, 0); - const inset = flickable.height * flickable.fadeAmount + Appearance.padding.large; + const inset = flickable.height * flickable.fadeAmount + Tokens.padding.large; const minY = -flickable.topMargin; const maxY = Math.max(minY, flickable.contentHeight + flickable.bottomMargin - flickable.height); const target = Math.max(minY, Math.min(pos.y - inset, maxY)); @@ -65,7 +66,7 @@ ColumnLayout { return true; } - spacing: Appearance.spacing.large + spacing: Tokens.spacing.large Component.onCompleted: applySearchAnchor() @@ -120,7 +121,7 @@ ColumnLayout { RowLayout { id: header - spacing: Appearance.spacing.large + spacing: Tokens.spacing.large Loader { active: root.isSubPage @@ -129,8 +130,8 @@ ColumnLayout { sourceComponent: IconButton { icon: "arrow_back" - inactiveColor: DynamicColors.tPalette.m3surfaceContainerHigh - inactiveOnColor: DynamicColors.palette.m3onSurfaceVariant + inactiveColor: Colors.tPalette.m3surfaceContainerHigh + inactiveOnColor: Colors.palette.m3onSurfaceVariant isRound: true type: IconButton.Tonal @@ -141,7 +142,7 @@ ColumnLayout { CustomText { Layout.fillWidth: true elide: Text.ElideRight - font.pointSize: Appearance.font.size.large + font.pointSize: Tokens.font.size.large text: root.title } } @@ -153,11 +154,11 @@ ColumnLayout { Layout.fillHeight: true Layout.fillWidth: true Layout.topMargin: -topMargin - bottomMargin: Appearance.padding.extraLarge + bottomMargin: Tokens.padding.extraLarge contentHeight: root.contentChild?.implicitHeight ?? 0 contentItem.children: [root.contentChild] fadeAmount: 0.1 - topMargin: Appearance.padding.large + topMargin: Tokens.padding.large Behavior on contentY { enabled: root.animateScroll diff --git a/Modules/Settings/Common/PopupRow.qml b/Modules/Settings/Common/PopupRow.qml index e9dd53e..50fff3f 100644 --- a/Modules/Settings/Common/PopupRow.qml +++ b/Modules/Settings/Common/PopupRow.qml @@ -2,8 +2,9 @@ import QtQuick import QtQuick.Layouts import Quickshell import qs.Components -import qs.Config +import ZShell.Config import qs.Drawers +import qs.Services ConnectedRect { id: root @@ -30,16 +31,16 @@ ConnectedRect { id: navLayout anchors.fill: parent - anchors.leftMargin: Appearance.padding.largeIncreased - anchors.margins: Appearance.padding.normal - anchors.rightMargin: Appearance.padding.largeIncreased - spacing: Appearance.spacing.normal + anchors.leftMargin: Tokens.padding.largeIncreased + anchors.margins: Tokens.padding.normal + anchors.rightMargin: Tokens.padding.largeIncreased + spacing: Tokens.spacing.normal MaterialIcon { id: icon - color: DynamicColors.palette.m3onSurfaceVariant - font.pointSize: Appearance.font.size.larger + color: Colors.palette.m3onSurfaceVariant + font.pointSize: Tokens.font.size.larger } ColumnLayout { @@ -51,7 +52,7 @@ ConnectedRect { Layout.fillWidth: true elide: Text.ElideRight - font.pointSize: Appearance.font.size.small + font.pointSize: Tokens.font.size.small } CustomText { @@ -59,9 +60,9 @@ ConnectedRect { Layout.fillWidth: true animate: true - color: DynamicColors.palette.m3outline + color: Colors.palette.m3outline elide: Text.ElideRight - font.pointSize: Appearance.font.size.small + font.pointSize: Tokens.font.size.small visible: text } } @@ -101,10 +102,10 @@ ConnectedRect { BlobPopup { id: popup - color: open || hovered || stateLayer.containsMouse ? DynamicColors.palette.m3secondaryContainer : DynamicColors.palette.m3surfaceContainerHighest + color: open || hovered || stateLayer.containsMouse ? Colors.palette.m3secondaryContainer : Colors.palette.m3surfaceContainerHighest content: root.content hoverOverride: stateLayer.containsMouse - padding: Appearance.padding.small + padding: Tokens.padding.small pressOverride: stateLayer.pressed x: { tWatcher.transform; diff --git a/Modules/Settings/Common/RowButton.qml b/Modules/Settings/Common/RowButton.qml new file mode 100644 index 0000000..e98f959 --- /dev/null +++ b/Modules/Settings/Common/RowButton.qml @@ -0,0 +1,94 @@ +pragma ComponentBehavior: Bound + +import QtQuick +import QtQuick.Layouts +import ZShell.Config +import qs.Components +import qs.Services + +ConnectedRect { + id: root + + property alias icon: iconLabel.text + readonly property alias iconLabel: iconLabel + readonly property alias label: label + property alias stateEnabled: stateLayer.enabled + readonly property alias subLabel: subLabel + property alias subtext: subLabel.text + property alias text: label.text + property string trailingIcon + + signal clicked(event: MouseEvent) + + Layout.fillWidth: true + implicitHeight: row.implicitHeight + Tokens.padding.normal * 2 + + StateLayer { + id: stateLayer + + onClicked: e => root.clicked(e) + } + + RowLayout { + id: row + + anchors.left: parent.left + anchors.margins: Tokens.padding.largeIncreased + anchors.right: parent.right + anchors.verticalCenter: parent.verticalCenter + opacity: root.enabled ? 1 : 0.5 + spacing: Tokens.spacing.normal + + Behavior on opacity { + Anim { + } + } + + MaterialIcon { + id: iconLabel + + color: Colors.palette.m3onSurfaceVariant + fill: 1 + font.pointSize: Tokens.font.size.medium + } + + Column { + id: column + + Layout.fillWidth: true + spacing: 0 + + CustomText { + id: label + + anchors.left: parent.left + anchors.right: parent.right + elide: Text.ElideRight + font.pointSize: Tokens.font.size.small + } + + CustomText { + id: subLabel + + anchors.left: parent.left + anchors.right: parent.right + color: Colors.palette.m3outline + elide: Text.ElideRight + font.pointSize: Tokens.font.size.small + visible: text + } + } + + Loader { + active: root.trailingIcon + asynchronous: true + visible: active + + sourceComponent: MaterialIcon { + color: Colors.palette.m3onSurfaceVariant + font.pointSize: Tokens.font.size.medium + text: root.trailingIcon + } + } + } +} diff --git a/Modules/Settings/Common/SectionHeader.qml b/Modules/Settings/Common/SectionHeader.qml index ffaeb06..4218032 100644 --- a/Modules/Settings/Common/SectionHeader.qml +++ b/Modules/Settings/Common/SectionHeader.qml @@ -1,16 +1,17 @@ import QtQuick import QtQuick.Layouts import qs.Components -import qs.Config +import ZShell.Config +import qs.Services CustomText { property bool first - Layout.bottomMargin: Appearance.spacing.extraSmall + Layout.bottomMargin: Tokens.spacing.extraSmall Layout.fillWidth: true - Layout.leftMargin: Appearance.padding.small - Layout.topMargin: first ? 0 : Appearance.spacing.large - ((parent as ColumnLayout).spacing ?? 0) - color: DynamicColors.palette.m3onSurfaceVariant + Layout.leftMargin: Tokens.padding.small + Layout.topMargin: first ? 0 : Tokens.spacing.large - ((parent as ColumnLayout).spacing ?? 0) + color: Colors.palette.m3onSurfaceVariant elide: Text.ElideRight - font.pointSize: Appearance.font.size.medium + font.pointSize: Tokens.font.size.medium } diff --git a/Modules/Settings/Common/SelectRow.qml b/Modules/Settings/Common/SelectRow.qml index 184a02b..01fa3b7 100644 --- a/Modules/Settings/Common/SelectRow.qml +++ b/Modules/Settings/Common/SelectRow.qml @@ -1,7 +1,8 @@ import QtQuick import QtQuick.Layouts import qs.Components -import qs.Config +import ZShell.Config +import qs.Services ConnectedRect { id: root @@ -25,10 +26,10 @@ ConnectedRect { id: rowLayout anchors.fill: parent - anchors.leftMargin: Appearance.padding.largeIncreased - anchors.margins: Appearance.padding.normal - anchors.rightMargin: Appearance.padding.largeIncreased - spacing: Appearance.spacing.small + anchors.leftMargin: Tokens.padding.largeIncreased + anchors.margins: Tokens.padding.normal + anchors.rightMargin: Tokens.padding.largeIncreased + spacing: Tokens.spacing.small ColumnLayout { Layout.fillWidth: true @@ -39,14 +40,14 @@ ConnectedRect { Layout.fillWidth: true elide: Text.ElideRight - font.pointSize: Appearance.font.size.smaller + font.pointSize: Tokens.font.size.smaller } CustomText { Layout.fillWidth: true - color: DynamicColors.palette.m3outline + color: Colors.palette.m3outline elide: Text.ElideRight - font.pointSize: Appearance.font.size.small + font.pointSize: Tokens.font.size.small text: root.subtext visible: root.subtext } diff --git a/Modules/Settings/Common/SliderRow.qml b/Modules/Settings/Common/SliderRow.qml index 0ba872b..237f300 100644 --- a/Modules/Settings/Common/SliderRow.qml +++ b/Modules/Settings/Common/SliderRow.qml @@ -3,7 +3,8 @@ pragma ComponentBehavior: Bound import QtQuick import QtQuick.Layouts import qs.Components -import qs.Config +import ZShell.Config +import qs.Services ConnectedRect { id: root @@ -22,31 +23,31 @@ ConnectedRect { id: rowLayout anchors.fill: parent - anchors.margins: Appearance.padding.largeIncreased - anchors.topMargin: Appearance.padding.large - spacing: Appearance.spacing.small + anchors.margins: Tokens.padding.largeIncreased + anchors.topMargin: Tokens.padding.large + spacing: Tokens.spacing.small ColumnLayout { Layout.fillWidth: true - spacing: Appearance.spacing.small + spacing: Tokens.spacing.small RowLayout { Layout.fillWidth: true - spacing: Appearance.spacing.small + spacing: Tokens.spacing.small CustomText { id: label Layout.fillWidth: true elide: Text.ElideRight - font.pointSize: Appearance.font.size.small + font.pointSize: Tokens.font.size.small } CustomText { id: valueLabel - color: DynamicColors.palette.m3outline - font.pointSize: Appearance.font.size.small + color: Colors.palette.m3outline + font.pointSize: Tokens.font.size.small } } @@ -60,7 +61,7 @@ ConnectedRect { } Layout.fillWidth: true - implicitHeight: Appearance.padding.larger * 3 + implicitHeight: Tokens.padding.larger * 3 CustomSlider { id: slider @@ -70,7 +71,7 @@ ConnectedRect { anchors.verticalCenter: parent.verticalCenter enabled: root.enabled implicitHeight: parent.implicitHeight - radius: Appearance.rounding.small + radius: Tokens.rounding.small value: root.value onInteraction: v => root.moved(v) diff --git a/Modules/Settings/Common/SpinRow.qml b/Modules/Settings/Common/SpinRow.qml index d104a3f..7530891 100644 --- a/Modules/Settings/Common/SpinRow.qml +++ b/Modules/Settings/Common/SpinRow.qml @@ -3,7 +3,8 @@ pragma ComponentBehavior: Bound import QtQuick import QtQuick.Layouts import qs.Components -import qs.Config +import ZShell.Config +import qs.Services ConnectedRect { id: root @@ -24,10 +25,10 @@ ConnectedRect { id: rowLayout anchors.fill: parent - anchors.leftMargin: Appearance.padding.largeIncreased - anchors.margins: Appearance.padding.normal - anchors.rightMargin: Appearance.padding.largeIncreased - spacing: Appearance.spacing.small + anchors.leftMargin: Tokens.padding.largeIncreased + anchors.margins: Tokens.padding.normal + anchors.rightMargin: Tokens.padding.largeIncreased + spacing: Tokens.spacing.small ColumnLayout { Layout.fillWidth: true @@ -38,14 +39,14 @@ ConnectedRect { Layout.fillWidth: true elide: Text.ElideRight - font.pointSize: Appearance.font.size.smaller + font.pointSize: Tokens.font.size.smaller } CustomText { Layout.fillWidth: true - color: DynamicColors.palette.m3outline + color: Colors.palette.m3outline elide: Text.ElideRight - font.pointSize: Appearance.font.size.small + font.pointSize: Tokens.font.size.small text: root.subtext visible: root.subtext } diff --git a/Modules/Settings/Common/StackPage.qml b/Modules/Settings/Common/StackPage.qml index 3bead7f..45fb1b6 100644 --- a/Modules/Settings/Common/StackPage.qml +++ b/Modules/Settings/Common/StackPage.qml @@ -2,12 +2,12 @@ import QtQuick import QtQuick.Controls import qs.Components import qs.Modules.Settings -import qs.Config +import ZShell.Config StackView { id: root - readonly property int animMovement: Appearance.padding.extraLarge * 2 + readonly property int animMovement: Tokens.padding.extraLarge * 2 default property list pages required property SettingsState sState @@ -33,7 +33,7 @@ StackView { } PauseAnimation { - duration: Appearance.anim.durations.expressiveEffects + duration: Tokens.anim.durations.expressiveEffects } ParallelAnimation { @@ -67,7 +67,7 @@ StackView { } PauseAnimation { - duration: Appearance.anim.durations.expressiveEffects + duration: Tokens.anim.durations.expressiveEffects } ParallelAnimation { diff --git a/Modules/Settings/Common/TimeInput.qml b/Modules/Settings/Common/TimeInput.qml index b806721..9e6044d 100644 --- a/Modules/Settings/Common/TimeInput.qml +++ b/Modules/Settings/Common/TimeInput.qml @@ -1,9 +1,10 @@ import QtQuick import QtQuick.Layouts import ZShell.Components -import qs.Config +import ZShell.Config import qs.Components import qs.Helpers +import qs.Services CustomClippingRect { id: root @@ -27,19 +28,19 @@ CustomClippingRect { return hour * 60 + minute; } - color: DynamicColors.palette.m3surfaceContainer + color: Colors.palette.m3surfaceContainer implicitHeight: column.implicitHeight + column.anchors.margins * 2 + buttonRow.implicitHeight + buttonRow.anchors.topMargin implicitWidth: column.implicitWidth + column.anchors.margins * 2 - radius: Appearance.rounding.large + radius: Tokens.rounding.large ColumnLayout { id: column anchors.left: parent.left - anchors.margins: Appearance.padding.largeIncreased + anchors.margins: Tokens.padding.largeIncreased anchors.right: parent.right anchors.top: parent.top - spacing: Appearance.spacing.normal + spacing: Tokens.spacing.normal CustomText { text: qsTr("Select time") @@ -51,14 +52,14 @@ CustomClippingRect { Layout.preferredHeight: 72 Layout.preferredWidth: 96 - color: startHourField.focus ? DynamicColors.palette.m3onPrimaryContainer : DynamicColors.palette.m3surfaceContainerHighest + color: startHourField.focus ? Colors.palette.m3onPrimaryContainer : Colors.palette.m3surfaceContainerHighest implicitHeight: 72 implicitWidth: 96 - radius: Appearance.rounding.small + radius: Tokens.rounding.small CustomRect { anchors.fill: parent - border.color: startHourField.focus ? DynamicColors.palette.m3primaryContainer : DynamicColors.palette.m3surfaceContainerHighest + border.color: startHourField.focus ? Colors.palette.m3primaryContainer : Colors.palette.m3surfaceContainerHighest border.width: startHourField.focus ? 2 : 0 radius: parent.radius - border.width @@ -83,7 +84,7 @@ CustomClippingRect { anchors.right: parent.right anchors.verticalCenter: parent.verticalCenter clip: true - color: focus ? DynamicColors.palette.m3primaryContainer : DynamicColors.palette.m3onSurface + color: focus ? Colors.palette.m3primaryContainer : Colors.palette.m3onSurface font.family: "Roboto" font.letterSpacing: -0.25 font.pixelSize: 56 @@ -161,7 +162,7 @@ CustomClippingRect { CustomText { id: startSeparator - font.pointSize: Appearance.font.size.extraLarge + font.pointSize: Tokens.font.size.extraLarge text: ":" } @@ -170,14 +171,14 @@ CustomClippingRect { Layout.preferredHeight: 72 Layout.preferredWidth: 96 - color: startMinuteField.focus ? DynamicColors.palette.m3onPrimaryContainer : DynamicColors.palette.m3surfaceContainerHighest + color: startMinuteField.focus ? Colors.palette.m3onPrimaryContainer : Colors.palette.m3surfaceContainerHighest implicitHeight: 72 implicitWidth: 96 - radius: Appearance.rounding.small + radius: Tokens.rounding.small CustomRect { anchors.fill: parent - border.color: startMinuteField.focus ? DynamicColors.palette.m3primaryContainer : DynamicColors.palette.m3surfaceContainerHighest + border.color: startMinuteField.focus ? Colors.palette.m3primaryContainer : Colors.palette.m3surfaceContainerHighest border.width: startMinuteField.focus ? 2 : 0 radius: parent.radius - border.width @@ -202,7 +203,7 @@ CustomClippingRect { anchors.right: parent.right anchors.verticalCenter: parent.verticalCenter clip: true - color: focus ? DynamicColors.palette.m3primaryContainer : DynamicColors.palette.m3onSurface + color: focus ? Colors.palette.m3primaryContainer : Colors.palette.m3onSurface font.family: "Roboto" font.letterSpacing: -0.25 font.pixelSize: 56 @@ -280,7 +281,7 @@ CustomClippingRect { Item { id: spacer - Layout.preferredWidth: Appearance.spacing.large + Layout.preferredWidth: Tokens.spacing.large } CustomRect { @@ -288,14 +289,14 @@ CustomClippingRect { Layout.preferredHeight: 72 Layout.preferredWidth: 96 - color: endHourField.focus ? DynamicColors.palette.m3onPrimaryContainer : DynamicColors.palette.m3surfaceContainerHighest + color: endHourField.focus ? Colors.palette.m3onPrimaryContainer : Colors.palette.m3surfaceContainerHighest implicitHeight: 72 implicitWidth: 96 - radius: Appearance.rounding.small + radius: Tokens.rounding.small CustomRect { anchors.fill: parent - border.color: endHourField.focus ? DynamicColors.palette.m3primaryContainer : DynamicColors.palette.m3surfaceContainerHighest + border.color: endHourField.focus ? Colors.palette.m3primaryContainer : Colors.palette.m3surfaceContainerHighest border.width: endHourField.focus ? 2 : 0 radius: parent.radius - border.width @@ -320,7 +321,7 @@ CustomClippingRect { anchors.right: parent.right anchors.verticalCenter: parent.verticalCenter clip: true - color: focus ? DynamicColors.palette.m3primaryContainer : DynamicColors.palette.m3onSurface + color: focus ? Colors.palette.m3primaryContainer : Colors.palette.m3onSurface font.family: "Roboto" font.letterSpacing: -0.25 font.pixelSize: 56 @@ -398,7 +399,7 @@ CustomClippingRect { CustomText { id: endSeparator - font.pointSize: Appearance.font.size.extraLarge + font.pointSize: Tokens.font.size.extraLarge text: ":" } @@ -407,14 +408,14 @@ CustomClippingRect { Layout.preferredHeight: 72 Layout.preferredWidth: 96 - color: endMinuteField.focus ? DynamicColors.palette.m3onPrimaryContainer : DynamicColors.palette.m3surfaceContainerHighest + color: endMinuteField.focus ? Colors.palette.m3onPrimaryContainer : Colors.palette.m3surfaceContainerHighest implicitHeight: 72 implicitWidth: 96 - radius: Appearance.rounding.small + radius: Tokens.rounding.small CustomRect { anchors.fill: parent - border.color: endMinuteField.focus ? DynamicColors.palette.m3primaryContainer : DynamicColors.palette.m3surfaceContainerHighest + border.color: endMinuteField.focus ? Colors.palette.m3primaryContainer : Colors.palette.m3surfaceContainerHighest border.width: endMinuteField.focus ? 2 : 0 radius: parent.radius - border.width @@ -439,7 +440,7 @@ CustomClippingRect { anchors.right: parent.right anchors.verticalCenter: parent.verticalCenter clip: true - color: focus ? DynamicColors.palette.m3primaryContainer : DynamicColors.palette.m3onSurface + color: focus ? Colors.palette.m3primaryContainer : Colors.palette.m3onSurface font.family: "Roboto" font.letterSpacing: -0.25 font.pixelSize: 56 @@ -533,10 +534,10 @@ CustomClippingRect { anchors.bottom: parent.bottom anchors.left: parent.left - anchors.margins: Appearance.padding.largeIncreased + anchors.margins: Tokens.padding.largeIncreased anchors.right: parent.right anchors.top: column.bottom - anchors.topMargin: Appearance.spacing.normal + anchors.topMargin: Tokens.spacing.normal Item { id: buttonSpacer @@ -545,13 +546,13 @@ CustomClippingRect { } ButtonRow { - spacing: Appearance.spacing.normal + spacing: Tokens.spacing.normal IconTextButton { - font.pointSize: Appearance.font.size.normal + font.pointSize: Tokens.font.size.normal icon: "close" - inactiveColor: DynamicColors.layer(DynamicColors.palette.m3surfaceContainerHighest, 2) - inactiveOnColor: DynamicColors.palette.m3onSurfaceVariant + inactiveColor: Colors.layer(Colors.palette.m3surfaceContainerHighest, 2) + inactiveOnColor: Colors.palette.m3onSurfaceVariant isRound: true isToggle: false shapeMorph: true @@ -562,7 +563,7 @@ CustomClippingRect { } IconTextButton { - font.pointSize: Appearance.font.size.normal + font.pointSize: Tokens.font.size.normal icon: "check" isRound: true isToggle: false diff --git a/Modules/Settings/Common/ToggleRow.qml b/Modules/Settings/Common/ToggleRow.qml index 77dd3e8..ea4252b 100644 --- a/Modules/Settings/Common/ToggleRow.qml +++ b/Modules/Settings/Common/ToggleRow.qml @@ -1,7 +1,8 @@ import QtQuick import QtQuick.Layouts import qs.Components -import qs.Config +import ZShell.Config +import qs.Services CustomSwitch { id: root @@ -18,13 +19,13 @@ CustomSwitch { Layout.fillWidth: true cLayer: 2 - horizontalPadding: Appearance.padding.largeIncreased + horizontalPadding: Tokens.padding.largeIncreased implicitHeight: Math.max(implicitContentHeight, implicitIndicatorHeight) + verticalPadding * 2 implicitWidth: implicitContentWidth + implicitIndicatorWidth + horizontalPadding * 2 indicator.anchors.right: right indicator.anchors.rightMargin: root.horizontalPadding indicator.anchors.verticalCenter: verticalCenter - verticalPadding: Appearance.padding.normal + verticalPadding: Tokens.padding.normal background: ConnectedRect { id: bg @@ -39,7 +40,7 @@ CustomSwitch { anchors.left: parent.left anchors.leftMargin: root.horizontalPadding anchors.right: root.indicator.left - anchors.rightMargin: Appearance.spacing.normal + anchors.rightMargin: Tokens.spacing.normal implicitHeight: column.implicitHeight implicitWidth: column.implicitWidth @@ -57,12 +58,14 @@ CustomSwitch { anchors.left: parent.left anchors.right: parent.right elide: Text.ElideRight - font: { - const f = Qt.font(label.font); - f.pointSize = Appearance.font.size.smaller; - return f; - } + font.pointSize: Tokens.font.size.smaller + opacity: root.enabled ? 1 : 0.5 text: root.text + + Behavior on opacity { + Anim { + } + } } CustomText { @@ -70,15 +73,17 @@ CustomSwitch { anchors.left: parent.left anchors.right: parent.right - color: DynamicColors.palette.m3outline + color: Colors.palette.m3outline elide: Text.ElideRight - font: { - const f = Qt.font(subtext.font); - f.pointSize = Appearance.font.size.small; - return f; - } + font.pointSize: Tokens.font.size.small + opacity: root.enabled ? 1 : 0.5 text: root.subtext visible: root.subtext + + Behavior on opacity { + Anim { + } + } } } } diff --git a/Modules/Settings/Common/WallItem.qml b/Modules/Settings/Common/WallItem.qml index ad2aa3b..c9356ac 100644 --- a/Modules/Settings/Common/WallItem.qml +++ b/Modules/Settings/Common/WallItem.qml @@ -4,7 +4,8 @@ import QtQuick import QtQuick.Layouts import Quickshell import qs.Components -import qs.Config +import ZShell.Config +import qs.Services Item { id: root @@ -22,15 +23,15 @@ Item { id: layout anchors.fill: parent - spacing: Appearance.spacing.small + spacing: Tokens.spacing.small CustomClippingRect { id: imgWrapper Layout.fillWidth: true - color: DynamicColors.tPalette.m3surfaceContainer + color: Colors.tPalette.m3surfaceContainer implicitHeight: width - radius: Appearance.rounding.large + radius: Tokens.rounding.large Loader { active: opacity > 0 @@ -42,10 +43,10 @@ Item { } } sourceComponent: CustomRect { - color: DynamicColors.palette.m3primaryContainer - implicitHeight: loadingIndicator.implicitSize + Appearance.padding.large * 2 - implicitWidth: loadingIndicator.implicitSize + Appearance.padding.large * 2 - radius: Appearance.rounding.full + color: Colors.palette.m3primaryContainer + implicitHeight: loadingIndicator.implicitSize + Tokens.padding.large * 2 + implicitWidth: loadingIndicator.implicitSize + Tokens.padding.large * 2 + radius: Tokens.rounding.full LoadingIndicator { id: loadingIndicator diff --git a/Modules/Settings/Common/WallpaperCropper.qml b/Modules/Settings/Common/WallpaperCropper.qml index fe7f970..a7b70c7 100644 --- a/Modules/Settings/Common/WallpaperCropper.qml +++ b/Modules/Settings/Common/WallpaperCropper.qml @@ -5,14 +5,15 @@ import QtQuick.Layouts import Quickshell import Quickshell.Hyprland import ZShell.Components -import qs.Config +import ZShell.Config import qs.Components import qs.Helpers +import qs.Services Item { id: wrapper - property int buttonRowHeight: Appearance.padding.large * 3 + property int buttonRowHeight: Tokens.padding.large * 3 property bool changesMade: false readonly property var currentScreen: screens.length > selectedScreenIndex ? screens[selectedScreenIndex] : null property var screens: [] @@ -99,7 +100,7 @@ Item { } IconButton { - anchors.margins: Appearance.padding.normal + anchors.margins: Tokens.padding.normal anchors.right: parent.right anchors.top: parent.top icon: "check" @@ -126,13 +127,13 @@ Item { id: screenSelector anchors.bottom: scaledImg.top - anchors.bottomMargin: Appearance.spacing.normal + anchors.bottomMargin: Tokens.spacing.normal anchors.left: parent.left - anchors.leftMargin: Appearance.padding.extraLarge * 2 + anchors.leftMargin: Tokens.padding.extraLarge * 2 anchors.right: parent.right - anchors.rightMargin: Appearance.padding.extraLarge * 2 + anchors.rightMargin: Tokens.padding.extraLarge * 2 anchors.top: parent.top - spacing: Appearance.spacing.small + spacing: Tokens.spacing.small Repeater { model: wrapper.screens @@ -143,8 +144,8 @@ Item { required property var modelData fillWidth: true - inactiveColor: isCurrent ? DynamicColors.palette.m3primary : Qt.alpha(DynamicColors.palette.m3surfaceContainer, 0.7) - inactiveOnColor: isCurrent ? DynamicColors.palette.m3onPrimary : Qt.alpha(DynamicColors.palette.m3onSurface, 0.7) + inactiveColor: isCurrent ? Colors.palette.m3primary : Qt.alpha(Colors.palette.m3surfaceContainer, 0.7) + inactiveOnColor: isCurrent ? Colors.palette.m3onPrimary : Qt.alpha(Colors.palette.m3onSurface, 0.7) isRound: true shapeMorph: true text: modelData.name @@ -166,11 +167,11 @@ Item { id: zoomSlider Layout.fillWidth: true - Layout.leftMargin: Appearance.padding.normal - Layout.preferredHeight: Appearance.padding.larger * 3 - Layout.rightMargin: Appearance.padding.normal + Layout.leftMargin: Tokens.padding.normal + Layout.preferredHeight: Tokens.padding.larger * 3 + Layout.rightMargin: Tokens.padding.normal from: 1.0 - implicitHeight: Appearance.padding.larger * 3 + implicitHeight: Tokens.padding.larger * 3 insetIcon: "crop" to: 5.0 value: cropRectLoader.item ? cropRectLoader.item.zoom : 1.0 @@ -189,11 +190,11 @@ Item { property real monitorScale: 1.0 anchors.bottom: sliderLayout.top - anchors.bottomMargin: Appearance.spacing.normal + anchors.bottomMargin: Tokens.spacing.normal anchors.left: parent.left anchors.right: parent.right anchors.top: parent.top - anchors.topMargin: wrapper.buttonRowHeight + Appearance.spacing.normal + anchors.topMargin: wrapper.buttonRowHeight + Tokens.spacing.normal // anchors.top: screenSelector.bottom asynchronous: true fillMode: Image.PreserveAspectFit @@ -279,7 +280,7 @@ Item { } } - border.color: DynamicColors.palette.m3primary + border.color: Colors.palette.m3primary border.width: 2 height: baseHeight / zoom opacity: 1 diff --git a/Modules/Settings/Content.qml b/Modules/Settings/Content.qml index 6230d21..6d26b24 100644 --- a/Modules/Settings/Content.qml +++ b/Modules/Settings/Content.qml @@ -3,12 +3,13 @@ pragma ComponentBehavior: Bound import QtQuick import ZShell.Blobs import qs.Components -import qs.Config +import ZShell.Config +import qs.Services CustomClippingRect { id: root - property color blobColor: DynamicColors.tPalette.m3surfaceContainerLow + property color blobColor: Colors.tPalette.m3surfaceContainerLow readonly property real ratio: 16.0 / 9.0 readonly property SettingsState sState: SettingsState { id: sState @@ -20,7 +21,7 @@ CustomClippingRect { implicitHeight: sState.screen.height * 0.7 implicitWidth: implicitHeight * ratio - radius: Appearance.rounding.large + Appearance.padding.normal + radius: Tokens.rounding.large + Tokens.padding.normal Behavior on blobColor { CAnim { @@ -35,18 +36,18 @@ CustomClippingRect { id: blobGroup color: root.blobColor - smoothing: Appearance.rounding.normal + smoothing: Tokens.rounding.normal } BlobInvertedRect { anchors.fill: parent - borderBottom: Appearance.padding.normal + borderBottom: Tokens.padding.normal borderLeft: navPane.width + navPane.anchors.margins * 2 - borderRight: Appearance.padding.normal - borderTop: Appearance.padding.normal + borderRight: Tokens.padding.normal + borderTop: Tokens.padding.normal group: blobGroup opacity: root.blobColor.a - radius: Appearance.rounding.large + radius: Tokens.rounding.large } NavPane { @@ -54,7 +55,7 @@ CustomClippingRect { anchors.bottom: parent.bottom anchors.left: parent.left - anchors.margins: Appearance.padding.large + anchors.margins: Tokens.padding.large anchors.top: parent.top sState: root.sState width: Math.min(600, Math.round(root.width / 3)) @@ -64,7 +65,7 @@ CustomClippingRect { anchors.bottom: parent.bottom anchors.left: navPane.right anchors.leftMargin: navPane.anchors.margins + anchors.margins - anchors.margins: Appearance.padding.extraLarge + anchors.margins: Tokens.padding.extraLarge anchors.right: parent.right anchors.top: parent.top sState: root.sState diff --git a/Modules/Settings/NavPane.qml b/Modules/Settings/NavPane.qml index ab5ffa6..6a8ba92 100644 --- a/Modules/Settings/NavPane.qml +++ b/Modules/Settings/NavPane.qml @@ -2,27 +2,28 @@ import QtQuick import QtQuick.Layouts import qs.Components import qs.Modules.Settings.NavPane -import qs.Config +import ZShell.Config +import qs.Services ColumnLayout { id: root required property SettingsState sState - spacing: Appearance.spacing.large + spacing: Tokens.spacing.large SearchBar { id: searchField Layout.fillWidth: true - bg.border.color: DynamicColors.palette.m3outlineVariant - bg.color: DynamicColors.tPalette.m3surfaceContainerLowest - clearIcon.font.pointSize: Appearance.font.size.large - clearIcon.padding: Appearance.padding.extraSmall - font.pointSize: Appearance.font.size.normal + bg.border.color: Colors.palette.m3outlineVariant + bg.color: Colors.tPalette.m3surfaceContainerLowest + clearIcon.font.pointSize: Tokens.font.size.large + clearIcon.padding: Tokens.padding.extraSmall + font.pointSize: Tokens.font.size.normal placeholderText: qsTr("Search settings") - searchIcon.anchors.leftMargin: Appearance.padding.largeIncreased - searchIcon.font.pointSize: Appearance.font.size.large + searchIcon.anchors.leftMargin: Tokens.padding.largeIncreased + searchIcon.font.pointSize: Tokens.font.size.large Behavior on bg.border.color { CAnim { diff --git a/Modules/Settings/NavPane/NavLocations.qml b/Modules/Settings/NavPane/NavLocations.qml index bb4d1a8..38c9e2c 100644 --- a/Modules/Settings/NavPane/NavLocations.qml +++ b/Modules/Settings/NavPane/NavLocations.qml @@ -4,8 +4,9 @@ import QtQuick import QtQuick.Layouts import Quickshell import qs.Components -import qs.Config +import ZShell.Config import qs.Modules.Settings +import qs.Services VerticalFadeFlickable { id: root @@ -38,10 +39,10 @@ VerticalFadeFlickable { readonly property string search: sState.searchText readonly property bool searching: search.length > 0 - bottomMargin: Appearance.padding.large + bottomMargin: Tokens.padding.large contentHeight: content.implicitHeight fadeAmount: 0.1 - topMargin: Appearance.padding.large + topMargin: Tokens.padding.large TapHandler { onTapped: root.focus = true @@ -52,7 +53,7 @@ VerticalFadeFlickable { anchors.left: parent.left anchors.right: parent.right - spacing: Appearance.spacing.extraSmall + spacing: Tokens.spacing.extraSmall Repeater { id: list @@ -69,16 +70,16 @@ VerticalFadeFlickable { required property var modelData Layout.fillWidth: true - Layout.topMargin: index !== 0 && isCategoryStart ? Appearance.spacing.small : 0 - bottomLeftRadius: stateLayer.pressed ? Appearance.rounding.medium : isCurrentPage ? Appearance.rounding.large : isCategoryEnd ? Appearance.rounding.normal : Appearance.rounding.extraSmall - bottomRightRadius: stateLayer.pressed ? Appearance.rounding.medium : isCurrentPage ? Appearance.rounding.large : isCategoryEnd ? Appearance.rounding.normal : Appearance.rounding.extraSmall - color: isCurrentPage ? DynamicColors.palette.m3secondaryContainer : DynamicColors.layer(DynamicColors.palette.m3surfaceContainerHigh, 2) + Layout.topMargin: index !== 0 && isCategoryStart ? Tokens.spacing.small : 0 + bottomLeftRadius: stateLayer.pressed ? Tokens.rounding.medium : isCurrentPage ? Tokens.rounding.large : isCategoryEnd ? Tokens.rounding.normal : Tokens.rounding.extraSmall + bottomRightRadius: stateLayer.pressed ? Tokens.rounding.medium : isCurrentPage ? Tokens.rounding.large : isCategoryEnd ? Tokens.rounding.normal : Tokens.rounding.extraSmall + color: isCurrentPage ? Colors.palette.m3secondaryContainer : Colors.layer(Colors.palette.m3surfaceContainerHigh, 2) implicitHeight: { const h = layout.implicitHeight + layout.anchors.margins * 2; return h % 2 === 0 ? h : h + 1; } - topLeftRadius: stateLayer.pressed ? Appearance.rounding.medium : isCurrentPage ? Appearance.rounding.large : isCategoryStart ? Appearance.rounding.normal : Appearance.rounding.extraSmall - topRightRadius: stateLayer.pressed ? Appearance.rounding.medium : isCurrentPage ? Appearance.rounding.large : isCategoryStart ? Appearance.rounding.normal : Appearance.rounding.extraSmall + topLeftRadius: stateLayer.pressed ? Tokens.rounding.medium : isCurrentPage ? Tokens.rounding.large : isCategoryStart ? Tokens.rounding.normal : Tokens.rounding.extraSmall + topRightRadius: stateLayer.pressed ? Tokens.rounding.medium : isCurrentPage ? Tokens.rounding.large : isCategoryStart ? Tokens.rounding.normal : Tokens.rounding.extraSmall RadiusBehavior on bottomLeftRadius { } @@ -105,23 +106,23 @@ VerticalFadeFlickable { id: layout anchors.fill: parent - anchors.margins: Appearance.padding.large - spacing: Appearance.spacing.small + anchors.margins: Tokens.padding.large + spacing: Tokens.spacing.small CustomRect { Layout.bottomMargin: -1 Layout.fillHeight: true Layout.topMargin: -1 - color: item.isCurrentPage ? DynamicColors.palette.m3primary : DynamicColors.palette.m3secondaryContainer + color: item.isCurrentPage ? Colors.palette.m3primary : Colors.palette.m3secondaryContainer implicitWidth: height - radius: Appearance.rounding.full + radius: Tokens.rounding.full MaterialIcon { anchors.centerIn: parent anchors.verticalCenterOffset: 1 - color: item.isCurrentPage ? DynamicColors.palette.m3onPrimary : DynamicColors.palette.m3onSecondaryContainer + color: item.isCurrentPage ? Colors.palette.m3onPrimary : Colors.palette.m3onSecondaryContainer fill: item.modelData.noFill ? 0 : 1 - font.pointSize: Appearance.font.size.large + font.pointSize: Tokens.font.size.large grade: 25 text: item.modelData.icon } @@ -139,7 +140,7 @@ VerticalFadeFlickable { CustomText { Layout.fillWidth: true - color: DynamicColors.palette.m3onSurfaceVariant + color: Colors.palette.m3onSurfaceVariant elide: Text.ElideRight text: item.modelData.description } @@ -152,7 +153,7 @@ VerticalFadeFlickable { id: resultList Layout.fillWidth: true - spacing: Appearance.padding.large + spacing: Tokens.padding.large add: Transition { Anim { @@ -186,26 +187,26 @@ VerticalFadeFlickable { required property int index required property var modelData - spacing: Appearance.spacing.small + spacing: Tokens.spacing.small width: resultList.width RowLayout { Layout.fillWidth: true - Layout.leftMargin: Appearance.padding.small - spacing: Appearance.spacing.small + Layout.leftMargin: Tokens.padding.small + spacing: Tokens.spacing.small MaterialIcon { - color: DynamicColors.palette.m3primary + color: Colors.palette.m3primary fill: 1 - font.pointSize: Appearance.font.size.large + font.pointSize: Tokens.font.size.large text: group.modelData.icon } CustomText { Layout.fillWidth: true - color: DynamicColors.palette.m3secondary + color: Colors.palette.m3secondary elide: Text.ElideRight - font.pointSize: Appearance.font.size.large + font.pointSize: Tokens.font.size.large text: group.modelData.page } } @@ -214,7 +215,7 @@ VerticalFadeFlickable { id: cardList Layout.fillWidth: true - spacing: Appearance.spacing.extraSmall / 2 + spacing: Tokens.spacing.extraSmall / 2 add: Transition { Anim { @@ -250,15 +251,15 @@ VerticalFadeFlickable { readonly property bool isLast: index === group.modelData.entries.length - 1 required property var modelData - bottomLeftRadius: layer.pressed ? Appearance.rounding.medium : isLast ? Appearance.rounding.large : Appearance.rounding.extraSmall - bottomRightRadius: layer.pressed ? Appearance.rounding.medium : isLast ? Appearance.rounding.large : Appearance.rounding.extraSmall - color: DynamicColors.layer(DynamicColors.palette.m3surfaceContainerHigh, 2) + bottomLeftRadius: layer.pressed ? Tokens.rounding.medium : isLast ? Tokens.rounding.large : Tokens.rounding.extraSmall + bottomRightRadius: layer.pressed ? Tokens.rounding.medium : isLast ? Tokens.rounding.large : Tokens.rounding.extraSmall + color: Colors.layer(Colors.palette.m3surfaceContainerHigh, 2) implicitHeight: { const h = resultLayout.implicitHeight + resultLayout.anchors.margins * 2; return h % 2 === 0 ? h : h + 1; } - topLeftRadius: layer.pressed ? Appearance.rounding.medium : isFirst ? Appearance.rounding.large : Appearance.rounding.extraSmall - topRightRadius: layer.pressed ? Appearance.rounding.medium : isFirst ? Appearance.rounding.large : Appearance.rounding.extraSmall + topLeftRadius: layer.pressed ? Tokens.rounding.medium : isFirst ? Tokens.rounding.large : Tokens.rounding.extraSmall + topRightRadius: layer.pressed ? Tokens.rounding.medium : isFirst ? Tokens.rounding.large : Tokens.rounding.extraSmall width: cardList.width RadiusBehavior on bottomLeftRadius { @@ -274,15 +275,15 @@ VerticalFadeFlickable { id: resultLayout anchors.fill: parent - anchors.margins: Appearance.padding.large - anchors.rightMargin: result.modelData.togglePath ? toggle.width + Appearance.padding.large * 2 : Appearance.padding.large - spacing: Appearance.spacing.small / 2 + anchors.margins: Tokens.padding.large + anchors.rightMargin: result.modelData.togglePath ? toggle.width + Tokens.padding.large * 2 : Tokens.padding.large + spacing: Tokens.spacing.small / 2 CustomText { Layout.fillWidth: true - color: DynamicColors.palette.m3onSurfaceVariant + color: Colors.palette.m3onSurfaceVariant elide: Text.ElideRight - font.pointSize: Appearance.font.size.small + font.pointSize: Tokens.font.size.small text: { const labels = result.modelData.crumbLabels.slice(1); const section = result.modelData.section; @@ -294,19 +295,19 @@ VerticalFadeFlickable { CustomText { Layout.fillWidth: true - color: DynamicColors.palette.m3onSurface + color: Colors.palette.m3onSurface elide: Text.ElideRight - font.pointSize: Appearance.font.size.medium - text: SettingsSearcher.highlight(result.modelData.title, root.search, DynamicColors.palette.m3primary) + font.pointSize: Tokens.font.size.medium + text: SettingsSearcher.highlight(result.modelData.title, root.search, Colors.palette.m3primary) textFormat: text.includes(" 0 } @@ -326,7 +327,7 @@ VerticalFadeFlickable { id: toggle anchors.right: parent.right - anchors.rightMargin: Appearance.padding.large + anchors.rightMargin: Tokens.padding.large anchors.verticalCenter: parent.verticalCenter cLayer: 3 checked: result.modelData.toggleValue @@ -346,9 +347,9 @@ VerticalFadeFlickable { CustomText { Layout.fillWidth: true - Layout.topMargin: Appearance.padding.large - color: DynamicColors.palette.m3onSurfaceVariant - font.pointSize: Appearance.font.size.medium + Layout.topMargin: Tokens.padding.large + color: Colors.palette.m3onSurfaceVariant + font.pointSize: Tokens.font.size.medium horizontalAlignment: Text.AlignHCenter text: qsTr("No matching settings") visible: root.searching && root.results.length === 0 diff --git a/Modules/Settings/PageCompRegistry.qml b/Modules/Settings/PageCompRegistry.qml index 39da282..22aa679 100644 --- a/Modules/Settings/PageCompRegistry.qml +++ b/Modules/Settings/PageCompRegistry.qml @@ -3,7 +3,7 @@ pragma Singleton import QtQuick import QtQuick.Layouts import qs.Components -import qs.Config +import ZShell.Config import qs.Modules.Settings.Common import qs.Modules.Settings.Pages import qs.Modules.Settings.Pages.Wallpaper @@ -12,6 +12,7 @@ import qs.Modules.Settings.Pages.Apps import qs.Modules.Settings.Pages.Panels import qs.Modules.Settings.Pages.Panels.Bar import qs.Modules.Settings.Pages.Services +import qs.Services QtObject { id: root @@ -172,24 +173,24 @@ QtObject { ColumnLayout { anchors.centerIn: parent - spacing: Appearance.padding.extraSmall + spacing: Tokens.padding.extraSmall MaterialIcon { Layout.alignment: Qt.AlignHCenter - color: DynamicColors.palette.m3outlineVariant - font.pointSize: Appearance.font.size.extraLarge + color: Colors.palette.m3outlineVariant + font.pointSize: Tokens.font.size.extraLarge text: "handyman" } CustomText { Layout.alignment: Qt.AlignHCenter - color: DynamicColors.palette.m3outlineVariant + color: Colors.palette.m3outlineVariant text: qsTr("Page under construction") } CustomText { Layout.alignment: Qt.AlignHCenter - color: DynamicColors.palette.m3outlineVariant + color: Colors.palette.m3outlineVariant text: qsTr("This page will be available in a future update.") } } diff --git a/Modules/Settings/PageRegistry.qml b/Modules/Settings/PageRegistry.qml index 3971d36..c6381c0 100644 --- a/Modules/Settings/PageRegistry.qml +++ b/Modules/Settings/PageRegistry.qml @@ -15,9 +15,9 @@ Singleton { category: "appearance" }, { - name: qsTr("Screenshot"), + name: qsTr("Screenshots"), icon: "screenshot_region", - description: qsTr("Set screenshot effects"), + description: qsTr("Set screenshot options and effects"), category: "appearance" }, diff --git a/Modules/Settings/Pages.qml b/Modules/Settings/Pages.qml index e85acd0..0f43de9 100644 --- a/Modules/Settings/Pages.qml +++ b/Modules/Settings/Pages.qml @@ -1,6 +1,6 @@ import QtQuick import qs.Components -import qs.Config +import ZShell.Config Item { id: root @@ -46,7 +46,7 @@ Item { Connections { function onCurrentPageIdxChanged(): void { switchAnim.complete(); - root.animOff = Appearance.padding.normal * (root.sState.currentPageIdx > root.lastPageIdx ? 1 : -1); + root.animOff = Tokens.padding.normal * (root.sState.currentPageIdx > root.lastPageIdx ? 1 : -1); switchAnim.start(); root.lastPageIdx = root.sState.currentPageIdx; } diff --git a/Modules/Settings/Pages/AboutPage.qml b/Modules/Settings/Pages/AboutPage.qml index 6299450..75c65b8 100644 --- a/Modules/Settings/Pages/AboutPage.qml +++ b/Modules/Settings/Pages/AboutPage.qml @@ -3,9 +3,10 @@ import QtQuick.Layouts import Quickshell.Io import ZShell import qs.Modules.Settings.Common -import qs.Config +import ZShell.Config import qs.Helpers import qs.Components +import qs.Services PageBase { id: root @@ -19,7 +20,7 @@ PageBase { ColumnLayout { anchors.horizontalCenter: parent.horizontalCenter anchors.top: parent.top - spacing: Appearance.spacing.extraSmall / 2 + spacing: Tokens.spacing.extraSmall / 2 width: root.cappedWidth Process { @@ -34,15 +35,15 @@ PageBase { ConnectedRect { Layout.fillWidth: true first: true - implicitHeight: hero.implicitHeight + Appearance.padding.extraLarge * 2 + implicitHeight: hero.implicitHeight + Tokens.padding.extraLarge * 2 last: true ColumnLayout { id: hero anchors.centerIn: parent - spacing: Appearance.spacing.small - width: parent.width - Appearance.padding.largeIncreased * 2 + spacing: Tokens.spacing.small + width: parent.width - Tokens.padding.largeIncreased * 2 Logo { Layout.alignment: Qt.AlignHCenter @@ -54,15 +55,15 @@ PageBase { CustomText { Layout.alignment: Qt.AlignHCenter - Layout.topMargin: Appearance.spacing.small - font.pointSize: Appearance.font.size.large + Layout.topMargin: Tokens.spacing.small + font.pointSize: Tokens.font.size.large text: "ZShell" } CustomText { Layout.alignment: Qt.AlignHCenter - color: DynamicColors.palette.m3onSurfaceVariant - font.pointSize: Appearance.font.size.medium + color: Colors.palette.m3onSurfaceVariant + font.pointSize: Tokens.font.size.medium text: ZUtils.version ? `v${ZUtils.version}` : "…" } } diff --git a/Modules/Settings/Pages/Apps/AllApps.qml b/Modules/Settings/Pages/Apps/AllApps.qml index 505ee57..f2501ac 100644 --- a/Modules/Settings/Pages/Apps/AllApps.qml +++ b/Modules/Settings/Pages/Apps/AllApps.qml @@ -5,9 +5,10 @@ import QtQuick.Layouts import Quickshell import Quickshell.Widgets import qs.Components -import qs.Config +import ZShell.Config import qs.Helpers import qs.Modules.Settings.Common +import qs.Services PageBase { id: root @@ -18,7 +19,7 @@ PageBase { ColumnLayout { anchors.horizontalCenter: parent.horizontalCenter anchors.top: parent.top - spacing: Appearance.spacing.extraSmall / 2 + spacing: Tokens.spacing.extraSmall / 2 width: root.cappedWidth Repeater { @@ -48,14 +49,14 @@ PageBase { id: appRow anchors.fill: parent - anchors.leftMargin: Appearance.padding.largeIncreased - anchors.margins: Appearance.padding.normal - anchors.rightMargin: Appearance.padding.largeIncreased - spacing: Appearance.spacing.small + anchors.leftMargin: Tokens.padding.largeIncreased + anchors.margins: Tokens.padding.normal + anchors.rightMargin: Tokens.padding.largeIncreased + spacing: Tokens.spacing.small IconImage { asynchronous: true - implicitSize: Math.round(Appearance.font.size.large * 1.8) + implicitSize: Math.round(Tokens.font.size.large * 1.8) source: Quickshell.iconPath(appItem.modelData.icon, "image-missing") } @@ -66,31 +67,31 @@ PageBase { CustomText { Layout.fillWidth: true elide: Text.ElideRight - font.pointSize: Appearance.font.size.small + font.pointSize: Tokens.font.size.small text: appItem.modelData.name } CustomText { Layout.fillWidth: true - color: DynamicColors.palette.m3outline + color: Colors.palette.m3outline elide: Text.ElideRight - font.pointSize: Appearance.font.size.small + font.pointSize: Tokens.font.size.small text: (appItem.modelData.comment || appItem.modelData.genericName) ?? "" visible: text } } MaterialIcon { - color: DynamicColors.palette.m3primary + color: Colors.palette.m3primary fill: 1 - font.pointSize: Appearance.font.size.small + font.pointSize: Tokens.font.size.small text: "favorite" visible: Strings.testRegexList(Config.launcher.favoriteApps, appItem.modelData.id) } MaterialIcon { - color: DynamicColors.palette.m3onSurfaceVariant - font.pointSize: Appearance.font.size.medium + color: Colors.palette.m3onSurfaceVariant + font.pointSize: Tokens.font.size.medium text: "chevron_right" } } diff --git a/Modules/Settings/Pages/Apps/AppInfo.qml b/Modules/Settings/Pages/Apps/AppInfo.qml index 8d3b903..bfb0fcf 100644 --- a/Modules/Settings/Pages/Apps/AppInfo.qml +++ b/Modules/Settings/Pages/Apps/AppInfo.qml @@ -3,9 +3,10 @@ import QtQuick.Layouts import Quickshell import Quickshell.Widgets import qs.Components -import qs.Config +import ZShell.Config import qs.Helpers import qs.Modules.Settings.Common +import qs.Services PageBase { id: root @@ -34,37 +35,37 @@ PageBase { ColumnLayout { anchors.horizontalCenter: parent.horizontalCenter anchors.top: parent.top - spacing: Appearance.spacing.extraSmall / 2 + spacing: Tokens.spacing.extraSmall / 2 width: root.cappedWidth // Header RowLayout { - Layout.bottomMargin: Appearance.spacing.large + Layout.bottomMargin: Tokens.spacing.large Layout.fillWidth: true - Layout.leftMargin: Appearance.padding.small - spacing: Appearance.spacing.large + Layout.leftMargin: Tokens.padding.small + spacing: Tokens.spacing.large IconImage { asynchronous: true - implicitSize: Math.round(Appearance.font.size.large * 3) + implicitSize: Math.round(Tokens.font.size.large * 3) source: Quickshell.iconPath(root.app?.icon, "image-missing") } ColumnLayout { Layout.fillWidth: true - spacing: Appearance.spacing.extraSmall / 2 + spacing: Tokens.spacing.extraSmall / 2 CustomText { Layout.fillWidth: true - font.pointSize: Appearance.font.size.medium + font.pointSize: Tokens.font.size.medium text: root.app?.name ?? "" wrapMode: Text.WordWrap } CustomText { Layout.fillWidth: true - color: DynamicColors.palette.m3outline - font.pointSize: Appearance.font.size.small + color: Colors.palette.m3outline + font.pointSize: Tokens.font.size.small text: (root.app?.comment || root.app?.genericName) ?? "" visible: text wrapMode: Text.WordWrap @@ -142,16 +143,16 @@ PageBase { id: rowLayout anchors.fill: parent - anchors.leftMargin: Appearance.padding.largeIncreased - anchors.margins: Appearance.padding.normal - anchors.rightMargin: Appearance.padding.largeIncreased - spacing: Appearance.spacing.small + anchors.leftMargin: Tokens.padding.largeIncreased + anchors.margins: Tokens.padding.normal + anchors.rightMargin: Tokens.padding.largeIncreased + spacing: Tokens.spacing.small CustomText { id: label Layout.alignment: Qt.AlignTop - font.pointSize: Appearance.font.size.small + font.pointSize: Tokens.font.size.small } Item { @@ -163,8 +164,8 @@ PageBase { Layout.fillWidth: true Layout.maximumWidth: implicitWidth + 1 // Whyyyyyyyyy - color: DynamicColors.palette.m3onSurfaceVariant - font.pointSize: Appearance.font.size.small + color: Colors.palette.m3onSurfaceVariant + font.pointSize: Tokens.font.size.small wrapMode: Text.WrapAtWordBoundaryOrAnywhere } } diff --git a/Modules/Settings/Pages/AppsPage.qml b/Modules/Settings/Pages/AppsPage.qml index 49be244..1642eb6 100644 --- a/Modules/Settings/Pages/AppsPage.qml +++ b/Modules/Settings/Pages/AppsPage.qml @@ -7,8 +7,9 @@ import Quickshell.Widgets import ZShell import qs.Helpers import qs.Components -import qs.Config +import ZShell.Config import qs.Modules.Settings.Common +import qs.Services PageBase { id: root @@ -18,7 +19,7 @@ PageBase { ColumnLayout { anchors.horizontalCenter: parent.horizontalCenter anchors.top: parent.top - spacing: Appearance.spacing.extraSmall / 2 + spacing: Tokens.spacing.extraSmall / 2 width: root.cappedWidth // Default applications @@ -85,7 +86,7 @@ PageBase { component DefaultRow: PopupRow { id: row - readonly property int popupHeight: root.flickable.height - y + root.flickable.contentY - Appearance.padding.large - Appearance.padding.extraLarge + readonly property int popupHeight: root.flickable.height - y + root.flickable.contentY - Tokens.padding.large - Tokens.padding.extraLarge signal selected(app: DesktopEntry) @@ -98,7 +99,7 @@ PageBase { p = p.parent; return p?.opacity < 1; } - popup.topMovement: Appearance.padding.large + popup.topMovement: Tokens.padding.large Loader { active: row.popup.animDriver > 0 @@ -126,7 +127,7 @@ PageBase { anchors.left: list.contentItem.left anchors.right: list.contentItem.right implicitHeight: itemLayout.implicitHeight + itemLayout.anchors.margins * 2 - radius: Appearance.rounding.small + radius: Tokens.rounding.small onClicked: { row.popup.open = false; @@ -137,12 +138,12 @@ PageBase { id: itemLayout anchors.fill: parent - anchors.margins: Appearance.padding.normal - spacing: Appearance.spacing.small + anchors.margins: Tokens.padding.normal + spacing: Tokens.spacing.small IconImage { asynchronous: true - implicitSize: Math.round(Appearance.font.size.large * 1.8) + implicitSize: Math.round(Tokens.font.size.large * 1.8) source: Quickshell.iconPath(appItem.modelData.icon, "image-missing") } @@ -153,24 +154,24 @@ PageBase { CustomText { Layout.fillWidth: true elide: Text.ElideRight - font.pointSize: Appearance.font.size.small + font.pointSize: Tokens.font.size.small text: appItem.modelData.name } CustomText { Layout.fillWidth: true - color: DynamicColors.palette.m3outline + color: Colors.palette.m3outline elide: Text.ElideRight - font.pointSize: Appearance.font.size.small + font.pointSize: Tokens.font.size.small text: (appItem.modelData.comment || appItem.modelData.genericName) ?? "" visible: text } } MaterialIcon { - color: DynamicColors.palette.m3primary + color: Colors.palette.m3primary fill: 1 - font.pointSize: Appearance.font.size.small + font.pointSize: Tokens.font.size.small text: "favorite" visible: Strings.testRegexList(Config.launcher.favoriteApps, appItem.modelData.id) } diff --git a/Modules/Settings/Pages/Audio/AppVolumes.qml b/Modules/Settings/Pages/Audio/AppVolumes.qml index b84fba8..4478887 100644 --- a/Modules/Settings/Pages/Audio/AppVolumes.qml +++ b/Modules/Settings/Pages/Audio/AppVolumes.qml @@ -7,8 +7,9 @@ import Quickshell.Services.Pipewire import qs.Modules.Settings.Common import qs.Helpers import qs.Components -import qs.Config +import ZShell.Config import qs.Daemons +import qs.Services PageBase { id: root @@ -19,15 +20,15 @@ PageBase { ColumnLayout { anchors.horizontalCenter: parent.horizontalCenter anchors.top: parent.top - spacing: Appearance.spacing.extraSmall / 2 + spacing: Tokens.spacing.extraSmall / 2 width: root.cappedWidth CustomText { - Layout.bottomMargin: Appearance.spacing.small + Layout.bottomMargin: Tokens.spacing.small Layout.fillWidth: true - Layout.leftMargin: Appearance.padding.small - color: DynamicColors.palette.m3outline - font.pointSize: Appearance.font.size.small + Layout.leftMargin: Tokens.padding.small + color: Colors.palette.m3outline + font.pointSize: Tokens.font.size.small text: qsTr("Adjust the volume of individual apps currently playing audio.") wrapMode: Text.WordWrap } @@ -35,10 +36,10 @@ PageBase { ItemList { id: streamList - color: list.count === 0 ? DynamicColors.tPalette.m3surfaceContainer : "transparent" + color: list.count === 0 ? Colors.tPalette.m3surfaceContainer : "transparent" first: true last: true - list.spacing: Appearance.spacing.extraSmall / 2 + list.spacing: Tokens.spacing.extraSmall / 2 placeholderIcon: "music_off" placeholderText: qsTr("No apps playing audio") showList: true diff --git a/Modules/Settings/Pages/AudioPage.qml b/Modules/Settings/Pages/AudioPage.qml index 050b23b..5577e73 100644 --- a/Modules/Settings/Pages/AudioPage.qml +++ b/Modules/Settings/Pages/AudioPage.qml @@ -3,10 +3,11 @@ pragma ComponentBehavior: Bound import QtQuick import QtQuick.Layouts import qs.Daemons -import qs.Config +import ZShell.Config import qs.Components import qs.Modules.Settings.Common import qs.Helpers +import qs.Services PageBase { id: root @@ -16,7 +17,7 @@ PageBase { ColumnLayout { anchors.horizontalCenter: parent.horizontalCenter anchors.top: parent.top - spacing: Appearance.spacing.extraSmall / 2 + spacing: Tokens.spacing.extraSmall / 2 width: root.cappedWidth // Output @@ -51,7 +52,7 @@ PageBase { // Input SliderRow { - Layout.topMargin: Appearance.spacing.large - parent.spacing + Layout.topMargin: Tokens.spacing.large - parent.spacing enabled: !Audio.sourceMuted first: true icon: Icons.getMicVolumeIcon(Audio.sourceVolume, Audio.sourceMuted) @@ -83,7 +84,7 @@ PageBase { // Per-app volumes ConnectedRect { Layout.fillWidth: true - Layout.topMargin: Appearance.spacing.large - parent.spacing + Layout.topMargin: Tokens.spacing.large - parent.spacing first: true implicitHeight: appLayout.implicitHeight + appLayout.anchors.margins * 2 last: true @@ -96,13 +97,13 @@ PageBase { id: appLayout anchors.fill: parent - anchors.leftMargin: Appearance.padding.largeIncreased - anchors.margins: Appearance.padding.normal - anchors.rightMargin: Appearance.padding.largeIncreased - spacing: Appearance.spacing.small + anchors.leftMargin: Tokens.padding.largeIncreased + anchors.margins: Tokens.padding.normal + anchors.rightMargin: Tokens.padding.largeIncreased + spacing: Tokens.spacing.small MaterialIcon { - font.pointSize: Appearance.font.size.medium + font.pointSize: Tokens.font.size.medium text: "tune" } @@ -113,23 +114,23 @@ PageBase { CustomText { Layout.fillWidth: true elide: Text.ElideRight - font.pointSize: Appearance.font.size.small + font.pointSize: Tokens.font.size.small text: qsTr("App volumes") } CustomText { Layout.fillWidth: true animate: true - color: DynamicColors.palette.m3outline + color: Colors.palette.m3outline elide: Text.ElideRight - font.pointSize: Appearance.font.size.small + font.pointSize: Tokens.font.size.small text: Audio.streams.length === 0 ? qsTr("No apps playing audio") : Audio.streams.length === 1 ? qsTr("1 app playing audio") : qsTr("%1 apps playing audio").arg(Audio.streams.length) } } MaterialIcon { - color: DynamicColors.palette.m3onSurfaceVariant - font.pointSize: Appearance.font.size.medium + color: Colors.palette.m3onSurfaceVariant + font.pointSize: Tokens.font.size.medium text: "chevron_right" } } diff --git a/Modules/Settings/Pages/NetworkPage.qml b/Modules/Settings/Pages/NetworkPage.qml new file mode 100644 index 0000000..eece6b2 --- /dev/null +++ b/Modules/Settings/Pages/NetworkPage.qml @@ -0,0 +1,239 @@ +pragma ComponentBehavior: Bound + +import QtQuick +import QtQuick.Layouts +import Quickshell +import qs.Modules.Settings.Common +import qs.Modules.SysTray.Popouts.Network +import qs.Components +import qs.Config +import qs.Helpers + +PageBase { + id: root + + title: qsTr("Network") + + ColumnLayout { + id: networkContent + + anchors.horizontalCenter: parent.horizontalCenter + anchors.top: parent.top + spacing: Appearance.spacing.extraSmall / 2 + width: root.cappedWidth + + Toggle { + Layout.preferredHeight: visible ? implicitHeight : 0 + checked: Network.wifiEnabled + first: true + last: connected.count === 0 + subtext: qsTr("Toggle WiFi device state") + text: checked ? qsTr("Enabled") : qsTr("Disabled") + + onToggled: Network.setWifi(checked) + } + + Repeater { + id: connected + + visible: Network.connectedNetworks.length > 0 + + model: ScriptModel { + values: [...Network.connectedNetworks].sort((a, b) => { + return b.signalStrength - a.signalStrength; + }) + } + + NetworkItem { + first: false + known: true + repeater: connected + } + } + } + + component NetworkItem: ConnectedRect { + id: networkItem + + readonly property bool connecting: Network.connectingNetwork === modelData + property int horizontalPadding: Appearance.padding.largeIncreased + required property int index + readonly property bool isSecure: Network.isSecure(modelData.security) + required property bool known + required property var modelData + required property Repeater repeater + + Layout.fillWidth: true + Layout.preferredHeight: visible ? rowLayout.implicitHeight + Appearance.padding.smaller * 2 : 0 + first: index === 0 + last: index === (repeater.count - 1) + radius: Appearance.rounding.small + + RowLayout { + id: rowLayout + + anchors.fill: parent + anchors.leftMargin: networkItem.horizontalPadding + anchors.rightMargin: networkItem.horizontalPadding + + Column { + id: column + + Layout.fillWidth: true + + CustomText { + Layout.fillWidth: true + Layout.leftMargin: Appearance.spacing.extraSmall + Layout.rightMargin: Appearance.spacing.extraSmall + color: networkItem.modelData.active ? DynamicColors.palette.m3primary : DynamicColors.palette.m3onSurface + elide: Text.ElideRight + text: networkItem.modelData.name + } + + CustomText { + id: subtext + + anchors.left: parent.left + anchors.right: parent.right + color: DynamicColors.palette.m3outline + elide: Text.ElideRight + font.pointSize: Appearance.font.size.small + text: qsTr("%1 strength").arg(Math.round(networkItem.modelData.signalStrength * 100) + "%") + } + } + + Item { + Layout.alignment: Qt.AlignRight + implicitHeight: icon.height + implicitWidth: icon.width + + MaterialIcon { + id: icon + + color: networkItem.modelData.active ? DynamicColors.palette.m3primary : DynamicColors.palette.m3onSurfaceVariant + font.pointSize: Appearance.font.size.large + opacity: networkItem.connecting ? 0 : 1 + text: Icons.getNetworkIcon(networkItem.modelData.signalStrength * 100, networkItem.isSecure) + + Behavior on opacity { + Anim { + } + } + } + + Loader { + active: opacity > 0 + anchors.fill: parent + opacity: networkItem.connecting ? 1 : 0 + + Behavior on opacity { + Anim { + } + } + sourceComponent: CircularIndicator { + bgColor: "transparent" + running: true + } + } + } + } + + StateLayer { + color: networkItem.modelData.active ? DynamicColors.palette.m3onPrimary : DynamicColors.palette.m3onSurface + + onClicked: { + if (networkItem.isSecure && !networkItem.known) { + PopupManager.requestOpen(Qt.resolvedUrl("Network/PSKOverlay.qml"), { + network: networkItem.modelData + }); + } else { + Network.requestConnect(networkItem.modelData); + } + } + } + } + component Spacer: Item { + id: spacer + + required property Repeater repeater + + Layout.preferredHeight: repeater.count > 0 ? Appearance.spacing.extraSmall : 0 + } + component Toggle: CustomSwitch { + id: toggleItem + + readonly property alias bg: bg + property alias first: bg.first + property alias last: bg.last + property string subtext + + Layout.fillWidth: true + cLayer: 2 + horizontalPadding: Appearance.padding.largeIncreased + implicitHeight: Math.max(implicitContentHeight, implicitIndicatorHeight) + verticalPadding * 2 + implicitWidth: implicitContentWidth + implicitIndicatorWidth + horizontalPadding * 2 + indicator.anchors.right: right + indicator.anchors.rightMargin: toggleItem.horizontalPadding + indicator.anchors.verticalCenter: verticalCenter + verticalPadding: Appearance.padding.normal + + background: ConnectedRect { + id: bg + + StateLayer { + id: stateLayer + + manualPressOverride: toggleItem.pressed + } + } + contentItem: Item { + anchors.left: parent.left + anchors.leftMargin: toggleItem.horizontalPadding + anchors.right: toggleItem.indicator.left + anchors.rightMargin: Appearance.spacing.normal + implicitHeight: column.implicitHeight + implicitWidth: column.implicitWidth + + Column { + id: column + + anchors.left: parent.left + anchors.right: parent.right + anchors.verticalCenter: parent.verticalCenter + spacing: 0 + + CustomText { + id: label + + anchors.left: parent.left + anchors.right: parent.right + elide: Text.ElideRight + font: { + const f = Qt.font(label.font); + f.pointSize = Appearance.font.size.smaller; + return f; + } + text: toggleItem.text + } + + CustomText { + id: subtext + + anchors.left: parent.left + anchors.right: parent.right + color: DynamicColors.palette.m3outline + elide: Text.ElideRight + font: { + const f = Qt.font(subtext.font); + f.pointSize = Appearance.font.size.small; + return f; + } + text: toggleItem.subtext + visible: toggleItem.subtext + } + } + } + + onPressed: stateLayer.press(stateLayer.mouseX, stateLayer.mouseY) + } +} diff --git a/Modules/Settings/Pages/Panels/Bar/BarClock.qml b/Modules/Settings/Pages/Panels/Bar/BarClock.qml index d1f7fb4..63461bd 100644 --- a/Modules/Settings/Pages/Panels/Bar/BarClock.qml +++ b/Modules/Settings/Pages/Panels/Bar/BarClock.qml @@ -1,7 +1,7 @@ pragma ComponentBehavior: Bound import QtQuick.Layouts -import qs.Config +import ZShell.Config import qs.Components import qs.Modules.Settings.Common @@ -41,11 +41,11 @@ PageBase { ColumnLayout { anchors.horizontalCenter: parent.horizontalCenter anchors.top: parent.top - spacing: Appearance.spacing.extraSmall / 2 + spacing: Tokens.spacing.extraSmall / 2 width: root.cappedWidth SelectRow { - Layout.topMargin: Appearance.spacing.extraSmall / 2 - parent.spacing + Layout.topMargin: Tokens.spacing.extraSmall / 2 - parent.spacing active: root.clockFormats.find(item => item.value === Config.general.dateFormat) first: true menuItems: root.clockFormats diff --git a/Modules/Settings/Pages/Panels/Bar/BarStatusIcons.qml b/Modules/Settings/Pages/Panels/Bar/BarStatusIcons.qml index 8a73337..2835082 100644 --- a/Modules/Settings/Pages/Panels/Bar/BarStatusIcons.qml +++ b/Modules/Settings/Pages/Panels/Bar/BarStatusIcons.qml @@ -1,19 +1,25 @@ -pragma ComponentBehavior: Bound - import QtQuick.Layouts -import qs.Config +import ZShell.Config import qs.Modules.Settings.Common PageBase { id: root + readonly property var builtinIcons: ({ + audio: qsTr("Speakers"), + microphone: qsTr("Microphone"), + power: qsTr("Battery"), + network: qsTr("Network"), + bluetooth: qsTr("Bluetooth") + }) + isSubPage: true title: qsTr("System icons") ColumnLayout { anchors.horizontalCenter: parent.horizontalCenter anchors.top: parent.top - spacing: Appearance.spacing.extraSmall / 2 + spacing: Tokens.spacing.extraSmall / 2 width: root.cappedWidth // Visible icons @@ -22,78 +28,70 @@ PageBase { text: qsTr("Visible icons") } - ToggleRow { - checked: Config.bar.tray.showAudio + ListEditor { + function labelFor(item: var): string { + const prettyName = root.builtinIcons[item.id]; + if (prettyName) + return prettyName; + const label = item.id.replace(/([A-Z])/g, " $1"); + return label.charAt(0).toUpperCase() + label.slice(1).toLowerCase(); + } + + function toggledFor(item: var): bool { + return item.enabled; + } + first: true - settingAnchor: "bar-status-speakers" - text: qsTr("Speakers") + values: Config.bar.tray.statusIcons.values + z: 1 - onToggled: Config.bar.tray.showAudio = checked + onItemMoved: (from, to) => Config.bar.tray.statusIcons.move(from, to) + onItemRemoved: index => Config.bar.tray.statusIcons.remove(index) + onItemToggled: (index, checked) => Config.bar.tray.statusIcons.at(index).enabled = checked } - ToggleRow { - checked: Config.bar.tray.showMicrophone - settingAnchor: "bar-status-mic" - text: qsTr("Microphone") + DialogSelectButton { + id: addItemContainer - onToggled: Config.bar.tray.showMicrophone = checked + acceptLabel: qsTr("Add") + enabled: Object.keys(model).length > 0 + header: qsTr("Add new entry") + icon: "add" + label: qsTr("Add entry") + model: { + const present = new Set(Config.bar.tray.statusIcons.values.map(item => item.id)); + return Object.keys(root.builtinIcons).filter(id => !present.has(id)).map(id => ({ + id: id, + label: root.builtinIcons[id] + })); + } + rootParent: root.flickable + + onAccepted: { + if (!selectedItem) + return; + + Config.bar.tray.statusIcons.insert({ + id: selectedItem, + enabled: true + }); + } } - ToggleRow { - checked: Config.bar.tray.showNetwork - text: qsTr("Network") - - onToggled: Config.bar.tray.showNetwork = checked - } - - //////// FOR LATER: - // - // ToggleRow { - // checked: Config.bar.tray.showWifi - // text: qsTr("Wi-Fi") - // - // onToggled: Config.bar.tray.showWifi = checked - // } - // - // ToggleRow { - // checked: Config.bar.tray.showBluetooth - // text: qsTr("Bluetooth") - // - // onToggled: Config.bar.tray.showBluetooth = checked - // } - - ToggleRow { - checked: Config.bar.tray.showPower - last: true - settingAnchor: "bar-status-power" - text: qsTr("Battery") - - onToggled: Config.bar.tray.showPower = checked - } - - // Behaviour + // Behavior SectionHeader { text: qsTr("Behavior") } ToggleRow { - checked: Config.bar.popouts.audio + checked: Config.bar.popouts.statusIcons first: true - settingAnchor: "bar-status-audio-popout" - subtext: qsTr("Show a details popout when hovering the audio icons") - text: qsTr("Audio popout on hover") - - onToggled: Config.bar.popouts.audio = checked - } - - ToggleRow { - checked: Config.bar.popouts.upower last: true - settingAnchor: "bar-status-power-popout" - subtext: qsTr("Show a details popout when hovering the power icon") - text: qsTr("Power popout on hover") + settingAnchor: "bar-status-popout-on-hover" + subtext: qsTr("Show a details popout when hovering the status icons") + text: qsTr("Popout on hover") - onToggled: Config.bar.popouts.upower = checked + onToggled: Config.bar.popouts.statusIcons = checked } ToggleRow { diff --git a/Modules/Settings/Pages/Panels/Bar/BarTray.qml b/Modules/Settings/Pages/Panels/Bar/BarTray.qml index 023640d..a4a7696 100644 --- a/Modules/Settings/Pages/Panels/Bar/BarTray.qml +++ b/Modules/Settings/Pages/Panels/Bar/BarTray.qml @@ -1,7 +1,7 @@ pragma ComponentBehavior: Bound import QtQuick.Layouts -import qs.Config +import ZShell.Config import qs.Modules.Settings.Common PageBase { @@ -13,7 +13,7 @@ PageBase { ColumnLayout { anchors.horizontalCenter: parent.horizontalCenter anchors.top: parent.top - spacing: Appearance.spacing.extraSmall / 2 + spacing: Tokens.spacing.extraSmall / 2 width: root.cappedWidth SpinRow { @@ -28,8 +28,18 @@ PageBase { onMoved: value => Config.bar.tray.trayIconSize = value } + ToggleRow { + checked: Config.bar.popouts.tray + settingAnchor: "bar-tray-enable-tray-popouts" + subtext: Config.bar.popouts.tray ? qsTr("Enabled") : qsTr("Disabled") + text: qsTr("Enable tray menu popouts") + + onToggled: Config.bar.popouts.tray = checked + } + ToggleRow { checked: Config.bar.tray.showOnHover + enabled: Config.bar.popouts.tray settingAnchor: "bar-tray-show-popout-on-hover" subtext: Config.bar.tray.showOnHover ? qsTr("Will show context menu on hover") : qsTr("Will show context menu on right-click") text: qsTr("Show popout on hover") diff --git a/Modules/Settings/Pages/Panels/BarPanel.qml b/Modules/Settings/Pages/Panels/BarPanel.qml index 9b344eb..7c78975 100644 --- a/Modules/Settings/Pages/Panels/BarPanel.qml +++ b/Modules/Settings/Pages/Panels/BarPanel.qml @@ -1,7 +1,7 @@ pragma ComponentBehavior: Bound import QtQuick.Layouts -import qs.Config +import ZShell.Config import qs.Modules.Settings.Common PageBase { @@ -13,7 +13,7 @@ PageBase { ColumnLayout { anchors.horizontalCenter: parent.horizontalCenter anchors.top: parent.top - spacing: Appearance.spacing.extraSmall / 2 + spacing: Tokens.spacing.extraSmall / 2 width: root.cappedWidth // Behavior diff --git a/Modules/Settings/Pages/Panels/DashboardPanel.qml b/Modules/Settings/Pages/Panels/DashboardPanel.qml index 1aa3f93..7657761 100644 --- a/Modules/Settings/Pages/Panels/DashboardPanel.qml +++ b/Modules/Settings/Pages/Panels/DashboardPanel.qml @@ -2,7 +2,7 @@ pragma ComponentBehavior: Bound import QtQuick import QtQuick.Layouts -import qs.Config +import ZShell.Config import qs.Components import qs.Modules.Settings.Common @@ -15,7 +15,7 @@ PageBase { ColumnLayout { anchors.horizontalCenter: parent.horizontalCenter anchors.top: parent.top - spacing: Appearance.spacing.extraSmall / 2 + spacing: Tokens.spacing.extraSmall / 2 width: root.cappedWidth // General diff --git a/Modules/Settings/Pages/Panels/LauncherPanel.qml b/Modules/Settings/Pages/Panels/LauncherPanel.qml index 8adcd25..3cc41f3 100644 --- a/Modules/Settings/Pages/Panels/LauncherPanel.qml +++ b/Modules/Settings/Pages/Panels/LauncherPanel.qml @@ -2,7 +2,7 @@ pragma ComponentBehavior: Bound import QtQuick import QtQuick.Layouts -import qs.Config +import ZShell.Config import qs.Components import qs.Modules.Settings.Common @@ -15,7 +15,7 @@ PageBase { ColumnLayout { anchors.horizontalCenter: parent.horizontalCenter anchors.top: parent.top - spacing: Appearance.spacing.extraSmall / 2 + spacing: Tokens.spacing.extraSmall / 2 width: root.cappedWidth // General diff --git a/Modules/Settings/Pages/Panels/ResourcesPanel.qml b/Modules/Settings/Pages/Panels/ResourcesPanel.qml index 9e41e3a..3638a48 100644 --- a/Modules/Settings/Pages/Panels/ResourcesPanel.qml +++ b/Modules/Settings/Pages/Panels/ResourcesPanel.qml @@ -2,7 +2,7 @@ pragma ComponentBehavior: Bound import QtQuick import QtQuick.Layouts -import qs.Config +import ZShell.Config import qs.Components import qs.Modules.Settings.Common @@ -15,7 +15,7 @@ PageBase { ColumnLayout { anchors.horizontalCenter: parent.horizontalCenter anchors.top: parent.top - spacing: Appearance.spacing.extraSmall / 2 + spacing: Tokens.spacing.extraSmall / 2 width: root.cappedWidth // General diff --git a/Modules/Settings/Pages/Panels/SidebarPanel.qml b/Modules/Settings/Pages/Panels/SidebarPanel.qml index cfa6795..9e899fa 100644 --- a/Modules/Settings/Pages/Panels/SidebarPanel.qml +++ b/Modules/Settings/Pages/Panels/SidebarPanel.qml @@ -2,7 +2,7 @@ pragma ComponentBehavior: Bound import QtQuick import QtQuick.Layouts -import qs.Config +import ZShell.Config import qs.Components import qs.Modules.Settings.Common @@ -15,7 +15,7 @@ PageBase { ColumnLayout { anchors.horizontalCenter: parent.horizontalCenter anchors.top: parent.top - spacing: Appearance.spacing.extraSmall / 2 + spacing: Tokens.spacing.extraSmall / 2 width: root.cappedWidth SectionHeader { diff --git a/Modules/Settings/Pages/PanelsPage.qml b/Modules/Settings/Pages/PanelsPage.qml index 30973d8..eeb33ba 100644 --- a/Modules/Settings/Pages/PanelsPage.qml +++ b/Modules/Settings/Pages/PanelsPage.qml @@ -1,5 +1,5 @@ import QtQuick.Layouts -import qs.Config +import ZShell.Config import qs.Modules.Settings.Common PageBase { @@ -10,7 +10,7 @@ PageBase { ColumnLayout { anchors.horizontalCenter: parent.horizontalCenter anchors.top: parent.top - spacing: Appearance.spacing.extraSmall / 2 + spacing: Tokens.spacing.extraSmall / 2 width: root.cappedWidth NavRow { diff --git a/Modules/Settings/Pages/ScreenshotPage.qml b/Modules/Settings/Pages/ScreenshotPage.qml index a97d47c..28f6180 100644 --- a/Modules/Settings/Pages/ScreenshotPage.qml +++ b/Modules/Settings/Pages/ScreenshotPage.qml @@ -5,23 +5,38 @@ import QtQuick.Layouts import ZShell.Components import qs.Helpers import qs.Components -import qs.Config +import ZShell.Config import qs.Modules.Settings import qs.Modules.Settings.Common PageBase { id: root - title: qsTr("Screenshot effects") + title: qsTr("Screenshots") ColumnLayout { anchors.horizontalCenter: parent.horizontalCenter anchors.top: parent.top - spacing: Appearance.spacing.extraSmall / 2 + spacing: Tokens.spacing.extraSmall / 2 width: root.cappedWidth SectionHeader { first: true + text: qsTr("Behavior") + } + + ToggleRow { + checked: Config.screenshot.saveOnCopy + first: true + last: true + settingAnchor: "screenshot-save-on-copy" + subtext: qsTr("Also save screenshot to disk when copying to clipboard") + text: qsTr("Save on copy") + + onToggled: Config.screenshot.saveOnCopy = checked + } + + SectionHeader { text: qsTr("Effects") } diff --git a/Modules/Settings/Pages/Services/NotificationsPage.qml b/Modules/Settings/Pages/Services/NotificationsPage.qml index e1e04d0..75e4387 100644 --- a/Modules/Settings/Pages/Services/NotificationsPage.qml +++ b/Modules/Settings/Pages/Services/NotificationsPage.qml @@ -1,6 +1,6 @@ import QtQuick import QtQuick.Layouts -import qs.Config +import ZShell.Config import qs.Components import qs.Modules.Settings.Common @@ -13,7 +13,7 @@ PageBase { ColumnLayout { anchors.horizontalCenter: parent.horizontalCenter anchors.top: parent.top - spacing: Appearance.spacing.extraSmall / 2 + spacing: Tokens.spacing.extraSmall / 2 width: root.cappedWidth // Notifications diff --git a/Modules/Settings/Pages/ServicesPage.qml b/Modules/Settings/Pages/ServicesPage.qml index 8751219..e179635 100644 --- a/Modules/Settings/Pages/ServicesPage.qml +++ b/Modules/Settings/Pages/ServicesPage.qml @@ -4,7 +4,7 @@ import Quickshell import ZShell.Services import qs.Components import qs.Helpers -import qs.Config +import ZShell.Config import qs.Modules.Settings.Common PageBase { @@ -43,7 +43,7 @@ PageBase { ColumnLayout { anchors.horizontalCenter: parent.horizontalCenter anchors.top: parent.top - spacing: Appearance.spacing.extraSmall / 2 + spacing: Tokens.spacing.extraSmall / 2 width: root.cappedWidth // Detected running players, used as default-player options diff --git a/Modules/Settings/Pages/Wallpaper/WallpaperSelect.qml b/Modules/Settings/Pages/Wallpaper/WallpaperSelect.qml index 72c98a0..8235079 100644 --- a/Modules/Settings/Pages/Wallpaper/WallpaperSelect.qml +++ b/Modules/Settings/Pages/Wallpaper/WallpaperSelect.qml @@ -6,8 +6,9 @@ import ZShell.Models import qs.Paths import qs.Helpers import qs.Components -import qs.Config +import ZShell.Config import qs.Modules.Settings.Common +import qs.Services PageBase { id: root @@ -19,20 +20,20 @@ PageBase { anchors.left: parent.left anchors.right: parent.right anchors.top: parent.top - spacing: Appearance.spacing.small + spacing: Tokens.spacing.small width: root.cappedWidth CustomText { - Layout.topMargin: Appearance.spacing.large - font.pointSize: Appearance.font.size.large + Layout.topMargin: Tokens.spacing.large + font.pointSize: Tokens.font.size.large text: qsTr("Wallpapers") } GridLayout { Layout.fillWidth: true - columnSpacing: Appearance.spacing.extraSmall + columnSpacing: Tokens.spacing.extraSmall columns: 4 - rowSpacing: Appearance.spacing.extraSmall + rowSpacing: Tokens.spacing.extraSmall visible: localWalls.count > 0 Repeater { @@ -91,25 +92,25 @@ PageBase { visible: active sourceComponent: CustomRect { - color: DynamicColors.tPalette.m3surfaceContainer - implicitHeight: noWallsLayout.implicitHeight + Appearance.padding.extraLarge * 3 - radius: Appearance.rounding.large + color: Colors.tPalette.m3surfaceContainer + implicitHeight: noWallsLayout.implicitHeight + Tokens.padding.extraLarge * 3 + radius: Tokens.rounding.large ColumnLayout { id: noWallsLayout anchors.centerIn: parent - spacing: Appearance.spacing.extraSmall + spacing: Tokens.spacing.extraSmall MaterialIcon { Layout.alignment: Qt.AlignHCenter - color: DynamicColors.palette.m3outline + color: Colors.palette.m3outline text: "hide_image" } CustomText { Layout.alignment: Qt.AlignHCenter - color: DynamicColors.palette.m3outline + color: Colors.palette.m3outline text: qsTr("No local wallpapers found") } } diff --git a/Modules/Settings/Pages/WallpaperPage.qml b/Modules/Settings/Pages/WallpaperPage.qml index 81abe9f..52e688c 100644 --- a/Modules/Settings/Pages/WallpaperPage.qml +++ b/Modules/Settings/Pages/WallpaperPage.qml @@ -5,9 +5,10 @@ import QtQuick.Layouts import ZShell.Components import qs.Helpers import qs.Components -import qs.Config +import ZShell.Config import qs.Modules.Settings import qs.Modules.Settings.Common +import qs.Services PageBase { id: root @@ -17,7 +18,7 @@ PageBase { ColumnLayout { anchors.horizontalCenter: parent.horizontalCenter anchors.top: parent.top - spacing: Appearance.spacing.large + spacing: Tokens.spacing.large width: root.cappedWidth Item { @@ -35,13 +36,13 @@ PageBase { IconTextButton { Layout.alignment: Qt.AlignHCenter enabled: Config.background.enabled - horizontalPadding: Appearance.padding.extraLarge + horizontalPadding: Tokens.padding.extraLarge icon: "wallpaper" isRound: true shapeMorph: true text: qsTr("Wallpapers") type: IconTextButton.Tonal - verticalPadding: Appearance.padding.normal + verticalPadding: Tokens.padding.normal onClicked: root.sState.openSubPage(1) // Wallpaper page } @@ -56,23 +57,23 @@ PageBase { } ToggleRow { - Layout.topMargin: Appearance.spacing.extraSmall / 2 - parent.spacing - checked: DynamicColors.transparency.enabled + Layout.topMargin: Tokens.spacing.extraSmall / 2 - parent.spacing + checked: Colors.transparency.enabled settingAnchor: "style-transparency" - subtext: qsTr("Base %1, layers %2").arg(DynamicColors.transparency.base).arg(DynamicColors.transparency.layers) + subtext: qsTr("Base %1, layers %2").arg(Colors.transparency.base).arg(Colors.transparency.layers) text: qsTr("Transparency") onToggled: Config.appearance.transparency.enabled = checked } ToggleRow { - Layout.topMargin: Appearance.spacing.extraSmall / 2 - parent.spacing - checked: !DynamicColors.light + Layout.topMargin: Tokens.spacing.extraSmall / 2 - parent.spacing + checked: !Colors.light last: true settingAnchor: "style-dark-theme" text: qsTr("Dark theme") - onToggled: DynamicColors.setMode(checked ? "dark" : "light") + onToggled: Colors.setMode(checked ? "dark" : "light") } OverlayRow { @@ -130,7 +131,7 @@ PageBase { return Qt.formatTime(d, "hh:mm AP"); } - Layout.topMargin: Appearance.spacing.extraSmall / 2 - parent.spacing + Layout.topMargin: Tokens.spacing.extraSmall / 2 - parent.spacing checked: Config.general.color.scheduleHyprsunset last: true settingAnchor: "style-schedule-hyprsunset" diff --git a/Modules/Settings/PopupOverlay.qml b/Modules/Settings/PopupOverlay.qml index e3f0aca..d18440e 100644 --- a/Modules/Settings/PopupOverlay.qml +++ b/Modules/Settings/PopupOverlay.qml @@ -1,6 +1,7 @@ import QtQuick -import qs.Config +import ZShell.Config import qs.Components +import qs.Services CustomRect { id: root @@ -9,7 +10,7 @@ CustomRect { readonly property var currentPopup: PopupManager.currentPopup property bool shouldBeVisible: loader.status === Loader.Ready - color: Qt.alpha(DynamicColors.palette.m3shadow, 0.3) + color: Qt.alpha(Colors.palette.m3shadow, 0.3) opacity: shouldBeVisible && !closing ? 1 : 0 visible: opacity > 0 diff --git a/Modules/Settings/SettingsSearcher.qml b/Modules/Settings/SettingsSearcher.qml index 9c41253..a180086 100644 --- a/Modules/Settings/SettingsSearcher.qml +++ b/Modules/Settings/SettingsSearcher.qml @@ -4,7 +4,7 @@ import "../../scripts/fzf.js" as Fzf import QtQuick import Quickshell import ZShell -import qs.Config +import ZShell.Config Singleton { id: root diff --git a/Modules/Settings/Wrapper.qml b/Modules/Settings/Wrapper.qml index cc5a9fb..12c48ca 100644 --- a/Modules/Settings/Wrapper.qml +++ b/Modules/Settings/Wrapper.qml @@ -1,7 +1,7 @@ import Quickshell import QtQuick import qs.Components -import qs.Config +import ZShell.Config import qs.Helpers Item { @@ -20,8 +20,8 @@ Item { Behavior on offsetScale { Anim { - duration: Appearance.anim.durations.expressiveDefaultSpatial - easing.bezierCurve: Appearance.anim.curves.expressiveDefaultSpatial + duration: Tokens.anim.durations.expressiveDefaultSpatial + easing.bezierCurve: Tokens.anim.curves.expressiveDefaultSpatial } } diff --git a/Modules/SysTray/Popouts/AudioPopout.qml b/Modules/SysTray/Popouts/AudioPopout.qml index 4dd9fb1..02d6b49 100644 --- a/Modules/SysTray/Popouts/AudioPopout.qml +++ b/Modules/SysTray/Popouts/AudioPopout.qml @@ -6,34 +6,33 @@ import Quickshell.Widgets import QtQuick import QtQuick.Layouts import QtQuick.Controls -import qs.Config +import ZShell.Config import qs.Components import qs.Daemons import qs.Helpers +import qs.Services Item { id: root - readonly property int rounding: Appearance.rounding.small - Appearance.padding.small + readonly property int rounding: Tokens.rounding.small - Tokens.padding.small readonly property int topMargin: 0 required property var wrapper - implicitHeight: vol.implicitHeight + Appearance.padding.small * 2 - implicitWidth: 500 + Appearance.padding.small * 2 + implicitHeight: vol.implicitHeight + Tokens.padding.small * 2 + implicitWidth: 500 + Tokens.padding.small * 2 CustomRect { anchors.left: parent.left anchors.right: parent.right anchors.top: parent.top - color: DynamicColors.tPalette.m3surfaceContainer + color: Colors.tPalette.m3surfaceContainer implicitHeight: parent.implicitHeight - radius: Appearance.rounding.small + radius: Tokens.rounding.small y: parent.y Behavior on implicitHeight { Anim { - duration: MaterialEasing.expressiveEffectsTime - easing.bezierCurve: MaterialEasing.expressiveEffects } } } @@ -42,7 +41,7 @@ Item { id: vol anchors.left: parent.left - anchors.margins: Appearance.padding.small + anchors.margins: Tokens.padding.small anchors.right: parent.right anchors.verticalCenter: parent.verticalCenter } @@ -52,17 +51,17 @@ Item { CustomRect { Layout.fillWidth: true - Layout.preferredHeight: 65 + Appearance.spacing.smaller * 2 + Layout.preferredHeight: 65 + Tokens.spacing.smaller * 2 Layout.topMargin: root.topMargin - color: DynamicColors.tPalette.m3surfaceContainer + color: Colors.tPalette.m3surfaceContainer radius: root.rounding ColumnLayout { - anchors.bottomMargin: Appearance.padding.smaller + anchors.bottomMargin: Tokens.padding.smaller anchors.fill: parent - anchors.leftMargin: Appearance.padding.larger - anchors.rightMargin: Appearance.padding.larger - anchors.topMargin: Appearance.padding.smaller + anchors.leftMargin: Tokens.padding.larger + anchors.rightMargin: Tokens.padding.larger + anchors.topMargin: Tokens.padding.smaller RowLayout { Layout.fillHeight: true @@ -76,27 +75,27 @@ Item { CustomText { Layout.alignment: Qt.AlignVCenter | Qt.AlignRight - color: Qt.alpha(DynamicColors.palette.m3onSurface, 0.7) + color: Qt.alpha(Colors.palette.m3onSurface, 0.7) font.bold: true text: qsTr("%1").arg(Audio.muted ? qsTr("Muted") : `${Math.round(Audio.volume * 100)}%`) } } RowLayout { - spacing: Appearance.spacing.large + spacing: Tokens.spacing.large CustomMouseArea { - Layout.bottomMargin: Appearance.padding.normal + Layout.bottomMargin: Tokens.padding.normal Layout.fillWidth: true - Layout.preferredHeight: Appearance.padding.larger * 3 + Layout.preferredHeight: Tokens.padding.larger * 3 CustomSlider { anchors.left: parent.left anchors.right: parent.right - bgColor: Audio.muted ? Qt.alpha(DynamicColors.palette.m3errorContainer, 0.5) : DynamicColors.palette.m3secondaryContainer - fgColor: Audio.muted ? DynamicColors.palette.m3error : DynamicColors.palette.m3primary + bgColor: Audio.muted ? Qt.alpha(Colors.palette.m3errorContainer, 0.5) : Colors.palette.m3secondaryContainer + fgColor: Audio.muted ? Colors.palette.m3error : Colors.palette.m3primary implicitHeight: parent.height - insetColor: Audio.muted ? (inset.attached ? DynamicColors.palette.m3onErrorContainer : DynamicColors.palette.m3onError) : (inset.attached ? DynamicColors.palette.m3onSecondaryContainer : DynamicColors.palette.m3onPrimary) + insetColor: Audio.muted ? (inset.attached ? Colors.palette.m3onErrorContainer : Colors.palette.m3onError) : (inset.attached ? Colors.palette.m3onSecondaryContainer : Colors.palette.m3onPrimary) insetIcon: Audio.muted || Audio.volume < 0.001 ? "volume_off" : "volume_up" value: Audio.volume @@ -110,7 +109,7 @@ Item { } CustomSwitch { - Layout.bottomMargin: Appearance.padding.normal + Layout.bottomMargin: Tokens.padding.normal checked: !Audio.muted onToggled: { @@ -125,9 +124,9 @@ Item { CustomClippingRect { Layout.fillWidth: true - Layout.preferredHeight: 65 + Appearance.spacing.smaller * 2 + Layout.preferredHeight: 65 + Tokens.spacing.smaller * 2 Layout.topMargin: root.topMargin - color: DynamicColors.tPalette.m3surfaceContainer + color: Colors.tPalette.m3surfaceContainer radius: root.rounding PwNodePeakMonitor { @@ -142,22 +141,21 @@ Item { anchors.bottom: parent.bottom anchors.left: parent.left anchors.top: parent.top - color: Qt.alpha(DynamicColors.palette.m3primary, 0.15) + color: Qt.alpha(Colors.palette.m3primary, 0.15) implicitWidth: parent.width * sourcePeak.peak Behavior on implicitWidth { Anim { - duration: MaterialEasing.expressiveEffectsTime } } } ColumnLayout { - anchors.bottomMargin: Appearance.padding.smaller + anchors.bottomMargin: Tokens.padding.smaller anchors.fill: parent - anchors.leftMargin: Appearance.padding.larger - anchors.rightMargin: Appearance.padding.larger - anchors.topMargin: Appearance.padding.smaller + anchors.leftMargin: Tokens.padding.larger + anchors.rightMargin: Tokens.padding.larger + anchors.topMargin: Tokens.padding.smaller RowLayout { Layout.fillHeight: true @@ -171,27 +169,27 @@ Item { CustomText { Layout.alignment: Qt.AlignVCenter | Qt.AlignRight - color: Qt.alpha(DynamicColors.palette.m3onSurface, 0.7) + color: Qt.alpha(Colors.palette.m3onSurface, 0.7) font.bold: true text: qsTr("%1").arg(Audio.sourceMuted ? qsTr("Muted") : `${Math.round(Audio.sourceVolume * 100)}%`) } } RowLayout { - spacing: Appearance.spacing.large + spacing: Tokens.spacing.large CustomMouseArea { - Layout.bottomMargin: Appearance.padding.normal + Layout.bottomMargin: Tokens.padding.normal Layout.fillWidth: true - Layout.preferredHeight: Appearance.padding.larger * 3 + Layout.preferredHeight: Tokens.padding.larger * 3 CustomSlider { anchors.left: parent.left anchors.right: parent.right - bgColor: Audio.sourceMuted ? Qt.alpha(DynamicColors.palette.m3errorContainer, 0.5) : DynamicColors.palette.m3secondaryContainer - fgColor: Audio.sourceMuted ? DynamicColors.palette.m3error : DynamicColors.palette.m3primary + bgColor: Audio.sourceMuted ? Qt.alpha(Colors.palette.m3errorContainer, 0.5) : Colors.palette.m3secondaryContainer + fgColor: Audio.sourceMuted ? Colors.palette.m3error : Colors.palette.m3primary implicitHeight: parent.height - insetColor: Audio.sourceMuted ? (inset.attached ? DynamicColors.palette.m3onErrorContainer : DynamicColors.palette.m3onError) : (inset.attached ? DynamicColors.palette.m3onSecondaryContainer : DynamicColors.palette.m3onPrimary) + insetColor: Audio.sourceMuted ? (inset.attached ? Colors.palette.m3onErrorContainer : Colors.palette.m3onError) : (inset.attached ? Colors.palette.m3onSecondaryContainer : Colors.palette.m3onPrimary) insetIcon: Audio.sourceMuted || Audio.sourceVolume < 0.001 ? "mic_off" : "mic" value: Audio.sourceVolume @@ -205,7 +203,7 @@ Item { } CustomSwitch { - Layout.bottomMargin: Appearance.padding.normal + Layout.bottomMargin: Tokens.padding.normal checked: !Audio.sourceMuted onToggled: { @@ -222,7 +220,7 @@ Item { Layout.fillWidth: true Layout.preferredHeight: 1 Layout.topMargin: root.topMargin - color: DynamicColors.tPalette.m3outline + color: Colors.tPalette.m3outline visible: appTracks.model.length > 0 } @@ -238,9 +236,9 @@ Item { required property var modelData Layout.fillWidth: true - Layout.preferredHeight: 65 + Appearance.spacing.smaller * 2 + Layout.preferredHeight: 65 + Tokens.spacing.smaller * 2 Layout.topMargin: root.topMargin - color: DynamicColors.tPalette.m3surfaceContainer + color: Colors.tPalette.m3surfaceContainer radius: root.rounding PwNodePeakMonitor { @@ -255,12 +253,11 @@ Item { anchors.bottom: parent.bottom anchors.left: parent.left anchors.top: parent.top - color: Qt.alpha(DynamicColors.palette.m3primary, 0.15) + color: Qt.alpha(Colors.palette.m3primary, 0.15) implicitWidth: parent.width * peak.peak Behavior on implicitWidth { Anim { - duration: MaterialEasing.expressiveEffectsTime } } } @@ -274,11 +271,11 @@ Item { } ColumnLayout { - anchors.bottomMargin: Appearance.padding.smaller + anchors.bottomMargin: Tokens.padding.smaller anchors.fill: parent - anchors.leftMargin: Appearance.padding.larger - anchors.rightMargin: Appearance.padding.larger - anchors.topMargin: Appearance.padding.smaller + anchors.leftMargin: Tokens.padding.larger + anchors.rightMargin: Tokens.padding.larger + anchors.topMargin: Tokens.padding.smaller RowLayout { Layout.fillHeight: true @@ -293,27 +290,27 @@ Item { CustomText { Layout.alignment: Qt.AlignVCenter | Qt.AlignRight - color: Qt.alpha(DynamicColors.palette.m3onSurface, 0.7) + color: Qt.alpha(Colors.palette.m3onSurface, 0.7) font.bold: true text: qsTr("%1").arg(appBox.modelData.audio.muted ? qsTr("Muted") : `${Math.round(appBox.modelData.audio.volume * 100)}%`) } } RowLayout { - spacing: Appearance.spacing.large + spacing: Tokens.spacing.large CustomMouseArea { - Layout.bottomMargin: Appearance.padding.normal + Layout.bottomMargin: Tokens.padding.normal Layout.fillWidth: true - Layout.preferredHeight: Appearance.padding.larger * 3 + Layout.preferredHeight: Tokens.padding.larger * 3 CustomSlider { anchors.left: parent.left anchors.right: parent.right - bgColor: appBox.modelData.audio.muted ? Qt.alpha(DynamicColors.palette.m3errorContainer, 0.5) : DynamicColors.palette.m3secondaryContainer - fgColor: appBox.modelData.audio.muted ? DynamicColors.palette.m3error : DynamicColors.palette.m3primary + bgColor: appBox.modelData.audio.muted ? Qt.alpha(Colors.palette.m3errorContainer, 0.5) : Colors.palette.m3secondaryContainer + fgColor: appBox.modelData.audio.muted ? Colors.palette.m3error : Colors.palette.m3primary implicitHeight: parent.height - insetColor: appBox.modelData.audio.muted ? (inset.attached ? DynamicColors.palette.m3onErrorContainer : DynamicColors.palette.m3onError) : (inset.attached ? DynamicColors.palette.m3onSecondaryContainer : DynamicColors.palette.m3onPrimary) + insetColor: appBox.modelData.audio.muted ? (inset.attached ? Colors.palette.m3onErrorContainer : Colors.palette.m3onError) : (inset.attached ? Colors.palette.m3onSecondaryContainer : Colors.palette.m3onPrimary) insetIcon: appBox.modelData.audio.muted || appBox.modelData.audio.volume < 0.001 ? "volume_off" : "volume_up" value: appBox.modelData.audio.volume @@ -327,7 +324,7 @@ Item { } CustomSwitch { - Layout.bottomMargin: Appearance.padding.normal + Layout.bottomMargin: Tokens.padding.normal checked: !appBox.modelData.audio.muted onToggled: { diff --git a/Modules/SysTray/Popouts/BluetoothPopout.qml b/Modules/SysTray/Popouts/BluetoothPopout.qml index bbea15d..d82bee1 100644 --- a/Modules/SysTray/Popouts/BluetoothPopout.qml +++ b/Modules/SysTray/Popouts/BluetoothPopout.qml @@ -6,9 +6,10 @@ import QtQml.Models import Quickshell import Quickshell.Bluetooth import ZShell.Components +import ZShell.Config +import qs.Services import qs.Components import qs.Helpers -import qs.Config CustomClippingRect { id: root @@ -20,13 +21,13 @@ CustomClippingRect { id: layout anchors.fill: parent - anchors.margins: Appearance.padding.larger - spacing: Appearance.spacing.extraSmall / 2 + anchors.margins: Tokens.padding.larger + spacing: Tokens.spacing.extraSmall / 2 CustomText { - Layout.rightMargin: Appearance.padding.extraSmall - Layout.topMargin: Appearance.padding.normal - font.pointSize: Appearance.font.size.large + Layout.rightMargin: Tokens.padding.extraSmall + Layout.topMargin: Tokens.padding.normal + font.pointSize: Tokens.font.size.large text: qsTr("Bluetooth") } @@ -68,7 +69,7 @@ CustomClippingRect { Layout.preferredHeight: contentHeight interactive: false section.property: "connected" - spacing: Appearance.spacing.extraSmall / 2 + spacing: Tokens.spacing.extraSmall / 2 add: Transition { Anim { @@ -142,19 +143,19 @@ CustomClippingRect { readonly property int connectedCount: rows.sortedConnected.length readonly property bool connecting: Network.connectingNetwork === modelData - property int horizontalPadding: Appearance.padding.largeIncreased + property int horizontalPadding: Tokens.padding.largeIncreased readonly property bool inConnectedGroup: index < connectedCount required property int index required property ListView list readonly property bool loading: modelData.state === BluetoothDeviceState.Connecting || modelData.state === BluetoothDeviceState.Disconnecting // qmllint disable unresolved-type required property BluetoothDevice modelData - property int verticalPadding: Appearance.padding.smaller + property int verticalPadding: Tokens.padding.smaller first: !inConnectedGroup && index === connectedCount + 1 implicitHeight: rowLayout.implicitHeight + verticalPadding * 2 last: inConnectedGroup ? index === connectedCount - 1 : index === list.count - 1 - radius: Appearance.rounding.small + radius: Tokens.rounding.small Timer { interval: 50 @@ -191,8 +192,8 @@ CustomClippingRect { CustomText { Layout.fillWidth: true - Layout.leftMargin: Appearance.spacing.extraSmall - Layout.rightMargin: Appearance.spacing.extraSmall + Layout.leftMargin: Tokens.spacing.extraSmall + Layout.rightMargin: Tokens.spacing.extraSmall elide: Text.ElideRight text: btItem.modelData.name } @@ -202,9 +203,9 @@ CustomClippingRect { anchors.left: parent.left anchors.right: parent.right - color: DynamicColors.palette.m3outline + color: Colors.palette.m3outline elide: Text.ElideRight - font.pointSize: Appearance.font.size.small + font.pointSize: Tokens.font.size.small text: btItem.modelData.connected ? (btItem.modelData.batteryAvailable ? qsTr("%1 battery left").arg(Math.round(btItem.modelData.battery * 100) + "%") : qsTr("Battery status unknown")) : btItem.modelData.address } } @@ -217,7 +218,7 @@ CustomClippingRect { MaterialIcon { id: icon - font.pointSize: Appearance.font.size.large + font.pointSize: Tokens.font.size.large opacity: btItem.connecting ? 0 : 1 text: btItem.modelData.batteryAvailable ? Icons.getBatteryIcon(btItem.modelData.battery) : "battery_unknown" visible: btItem.modelData.state === BluetoothDeviceState.Connected // qmllint disable unresolved-type @@ -245,10 +246,10 @@ CustomClippingRect { } ButtonRow { - spacing: Appearance.spacing.small + spacing: Tokens.spacing.small IconTextButton { - font.pointSize: Appearance.font.size.small + font.pointSize: Tokens.font.size.small icon: btItem.modelData.connected ? "link_off" : btItem.modelData.paired ? "link" : "add_link" text: btItem.modelData.connected ? qsTr("Disconnect") : btItem.modelData.paired ? qsTr("Connect") : qsTr("Pair") @@ -272,11 +273,11 @@ CustomClippingRect { property bool first property bool last - bottomLeftRadius: last ? Appearance.rounding.large : Appearance.rounding.extraSmall - bottomRightRadius: last ? Appearance.rounding.large : Appearance.rounding.extraSmall - color: DynamicColors.tPalette.m3surfaceContainer - topLeftRadius: first ? Appearance.rounding.large : Appearance.rounding.extraSmall - topRightRadius: first ? Appearance.rounding.large : Appearance.rounding.extraSmall + bottomLeftRadius: last ? Tokens.rounding.large : Tokens.rounding.extraSmall + bottomRightRadius: last ? Tokens.rounding.large : Tokens.rounding.extraSmall + color: Colors.tPalette.m3surfaceContainer + topLeftRadius: first ? Tokens.rounding.large : Tokens.rounding.extraSmall + topRightRadius: first ? Tokens.rounding.large : Tokens.rounding.extraSmall Behavior on bottomLeftRadius { Anim { @@ -296,16 +297,16 @@ CustomClippingRect { } } component StatusDivider: CustomText { - bottomPadding: Appearance.spacing.extraSmall - color: DynamicColors.palette.m3onSurfaceVariant - font.pointSize: Appearance.font.size.smaller + bottomPadding: Tokens.spacing.extraSmall + color: Colors.palette.m3onSurfaceVariant + font.pointSize: Tokens.font.size.smaller text: { const devices = Bluetooth.devices.values; // qmllint disable unresolved-type const connectedCount = devices.filter(d => d.connected).length; let available = qsTr("%1 device%2 available").arg(devices.length - connectedCount).arg(devices.length === 1 ? "" : "s"); return available; } - topPadding: Appearance.spacing.small + topPadding: Tokens.spacing.small } component Toggle: CustomSwitch { id: toggleItem @@ -317,13 +318,13 @@ CustomClippingRect { Layout.fillWidth: true cLayer: 2 - horizontalPadding: Appearance.padding.largeIncreased + horizontalPadding: Tokens.padding.largeIncreased implicitHeight: Math.max(implicitContentHeight, implicitIndicatorHeight) + verticalPadding * 2 implicitWidth: implicitContentWidth + implicitIndicatorWidth + horizontalPadding * 2 indicator.anchors.right: right indicator.anchors.rightMargin: toggleItem.horizontalPadding indicator.anchors.verticalCenter: verticalCenter - verticalPadding: Appearance.padding.normal + verticalPadding: Tokens.padding.normal background: ConnectedRect { id: bg @@ -338,7 +339,7 @@ CustomClippingRect { anchors.left: parent.left anchors.leftMargin: toggleItem.horizontalPadding anchors.right: toggleItem.indicator.left - anchors.rightMargin: Appearance.spacing.normal + anchors.rightMargin: Tokens.spacing.normal implicitHeight: column.implicitHeight implicitWidth: column.implicitWidth @@ -358,7 +359,7 @@ CustomClippingRect { elide: Text.ElideRight font: { const f = Qt.font(label.font); - f.pointSize = Appearance.font.size.smaller; + f.pointSize = Tokens.font.size.smaller; return f; } text: toggleItem.text @@ -369,11 +370,11 @@ CustomClippingRect { anchors.left: parent.left anchors.right: parent.right - color: DynamicColors.palette.m3outline + color: Colors.palette.m3outline elide: Text.ElideRight font: { const f = Qt.font(subtext.font); - f.pointSize = Appearance.font.size.small; + f.pointSize = Tokens.font.size.small; return f; } text: toggleItem.subtext diff --git a/Modules/SysTray/Popouts/Network/NetworkOverlay.qml b/Modules/SysTray/Popouts/Network/NetworkOverlay.qml index 29eca7a..ce70adc 100644 --- a/Modules/SysTray/Popouts/Network/NetworkOverlay.qml +++ b/Modules/SysTray/Popouts/Network/NetworkOverlay.qml @@ -1,6 +1,7 @@ import QtQuick +import ZShell.Config +import qs.Services import qs.Helpers -import qs.Config import qs.Components CustomRect { @@ -10,7 +11,7 @@ CustomRect { readonly property url currentPopup: PopupManager.currentPopup property bool shouldBeVisible: loader.status === Loader.Ready - color: Qt.alpha(DynamicColors.palette.m3shadow, 0.3) + color: Qt.alpha(Colors.palette.m3shadow, 0.3) opacity: shouldBeVisible && !closing ? 1 : 0 visible: opacity > 0 diff --git a/Modules/SysTray/Popouts/Network/PSKOverlay.qml b/Modules/SysTray/Popouts/Network/PSKOverlay.qml index b8f2fdc..267d0ac 100644 --- a/Modules/SysTray/Popouts/Network/PSKOverlay.qml +++ b/Modules/SysTray/Popouts/Network/PSKOverlay.qml @@ -2,7 +2,8 @@ import Quickshell import QtQuick import QtQuick.Layouts import ZShell.Components -import qs.Config +import ZShell.Config +import qs.Services import qs.Components import qs.Helpers @@ -11,27 +12,27 @@ CustomClippingRect { required property var network - color: DynamicColors.palette.m3surfaceContainer + color: Colors.palette.m3surfaceContainer implicitHeight: layout.implicitHeight + layout.anchors.margins * 2 implicitWidth: layout.implicitWidth + layout.anchors.margins * 2 - radius: Appearance.rounding.large + radius: Tokens.rounding.large ColumnLayout { id: layout anchors.fill: parent - anchors.margins: Appearance.padding.extraLarge - spacing: Appearance.spacing.normal + anchors.margins: Tokens.padding.extraLarge + spacing: Tokens.spacing.normal MaterialIcon { Layout.alignment: Qt.AlignHCenter - font.pointSize: Appearance.font.size.extraLarge * 2 + font.pointSize: Tokens.font.size.extraLarge * 2 text: "lock" } CustomText { Layout.alignment: Qt.AlignHCenter - color: DynamicColors.palette.m3onSurfaceVariant + color: Colors.palette.m3onSurfaceVariant text: qsTr("Connect to %1").arg(root.network.name) } @@ -52,14 +53,14 @@ CustomClippingRect { id: buttonRow Layout.fillWidth: true - spacing: Appearance.spacing.smaller + spacing: Tokens.spacing.smaller IconTextButton { fillWidth: true - font.pointSize: Appearance.font.size.normal + font.pointSize: Tokens.font.size.normal icon: "close" - inactiveColor: DynamicColors.layer(DynamicColors.palette.m3surfaceContainerHighest, 2) - inactiveOnColor: DynamicColors.palette.m3onSurfaceVariant + inactiveColor: Colors.layer(Colors.palette.m3surfaceContainerHighest, 2) + inactiveOnColor: Colors.palette.m3onSurfaceVariant isRound: true isToggle: false shapeMorph: true @@ -70,10 +71,10 @@ CustomClippingRect { IconTextButton { fillWidth: true - font.pointSize: Appearance.font.size.normal + font.pointSize: Tokens.font.size.normal icon: Network.connectingNetwork ? "" : "check" - inactiveColor: Network.connectingNetwork ? DynamicColors.palette.m3primaryContainer : Network.failedNetwork ? DynamicColors.palette.m3error : DynamicColors.palette.m3primary - inactiveOnColor: Network.connectingNetwork ? DynamicColors.palette.m3onPrimaryContainer : Network.failedNetwork ? DynamicColors.palette.m3onError : DynamicColors.palette.m3onPrimary + inactiveColor: Network.connectingNetwork ? Colors.palette.m3primaryContainer : Network.failedNetwork ? Colors.palette.m3error : Colors.palette.m3primary + inactiveOnColor: Network.connectingNetwork ? Colors.palette.m3onPrimaryContainer : Network.failedNetwork ? Colors.palette.m3onError : Colors.palette.m3onPrimary isRound: true isToggle: false shapeMorph: true @@ -92,7 +93,7 @@ CustomClippingRect { } sourceComponent: CircularIndicator { bgColor: "transparent" - implicitSize: buttonRow.height - Appearance.padding.normal + implicitSize: buttonRow.height - Tokens.padding.normal running: true } } diff --git a/Modules/SysTray/Popouts/NetworkPopout.qml b/Modules/SysTray/Popouts/NetworkPopout.qml index 3904f71..894dec3 100644 --- a/Modules/SysTray/Popouts/NetworkPopout.qml +++ b/Modules/SysTray/Popouts/NetworkPopout.qml @@ -3,9 +3,10 @@ pragma ComponentBehavior: Bound import QtQuick import QtQuick.Layouts import Quickshell +import ZShell.Config +import qs.Services import qs.Modules.SysTray.Popouts.Network import qs.Components -import qs.Config import qs.Helpers CustomClippingRect { @@ -16,7 +17,7 @@ CustomClippingRect { anchors.horizontalCenter: parent.horizontalCenter implicitHeight: networkPopContent.height + networks.implicitHeight + networkPopContent.anchors.margins + networks.anchors.margins * 2 implicitWidth: 500 + 8 * 2 - radius: (20 - Appearance.padding.small) * Appearance.rounding.scale + radius: (20 - Tokens.padding.small) * Tokens.rounding.scale Component.onCompleted: Network.active = true Component.onDestruction: Network.active = false @@ -25,15 +26,15 @@ CustomClippingRect { id: networkPopContent anchors.left: parent.left - anchors.margins: Appearance.padding.large + anchors.margins: Tokens.padding.large anchors.right: parent.right anchors.top: parent.top - spacing: Appearance.spacing.extraSmall / 2 + spacing: Tokens.spacing.extraSmall / 2 CustomText { Layout.preferredHeight: visible ? implicitHeight : 0 - Layout.rightMargin: Appearance.padding.extraSmall - font.pointSize: Appearance.font.size.large + Layout.rightMargin: Tokens.padding.extraSmall + font.pointSize: Tokens.font.size.large text: qsTr("Wifi") } @@ -72,10 +73,10 @@ CustomClippingRect { anchors.bottom: parent.bottom anchors.left: parent.left - anchors.margins: Appearance.padding.large + anchors.margins: Tokens.padding.large anchors.right: parent.right anchors.top: networkPopContent.bottom - spacing: Appearance.spacing.extraSmall / 2 + spacing: Tokens.spacing.extraSmall / 2 Spacer { repeater: known @@ -83,10 +84,10 @@ CustomClippingRect { } CustomText { - Layout.leftMargin: Appearance.padding.normal + Layout.leftMargin: Tokens.padding.normal Layout.preferredHeight: visible ? implicitHeight : 0 - color: DynamicColors.palette.m3onSurfaceVariant - font.pointSize: Appearance.font.size.small + color: Colors.palette.m3onSurfaceVariant + font.pointSize: Tokens.font.size.small text: Network.knownNetworks.length > 1 ? qsTr("%1 known networks available").arg(Network.knownNetworks.length) : qsTr("1 known network available") // qmllint disable missing-property visible: Network.knownNetworks.length > 0 } @@ -114,10 +115,10 @@ CustomClippingRect { } CustomText { - Layout.leftMargin: Appearance.padding.normal + Layout.leftMargin: Tokens.padding.normal Layout.preferredHeight: visible ? implicitHeight : 0 - color: DynamicColors.palette.m3onSurfaceVariant - font.pointSize: Appearance.font.size.small + color: Colors.palette.m3onSurfaceVariant + font.pointSize: Tokens.font.size.small text: Network.unknownNetworks.length > 1 ? qsTr("%1 networks available").arg(Network.unknownNetworks.length) : qsTr("1 network available") // qmllint disable missing-property visible: Network.unknownNetworks.length > 0 } @@ -148,17 +149,17 @@ CustomClippingRect { property bool first property bool last - bottomLeftRadius: last ? Appearance.rounding.large : Appearance.rounding.extraSmall - bottomRightRadius: last ? Appearance.rounding.large : Appearance.rounding.extraSmall - color: DynamicColors.tPalette.m3surfaceContainer - topLeftRadius: first ? Appearance.rounding.large : Appearance.rounding.extraSmall - topRightRadius: first ? Appearance.rounding.large : Appearance.rounding.extraSmall + bottomLeftRadius: last ? Tokens.rounding.large : Tokens.rounding.extraSmall + bottomRightRadius: last ? Tokens.rounding.large : Tokens.rounding.extraSmall + color: Colors.tPalette.m3surfaceContainer + topLeftRadius: first ? Tokens.rounding.large : Tokens.rounding.extraSmall + topRightRadius: first ? Tokens.rounding.large : Tokens.rounding.extraSmall } component NetworkItem: ConnectedRect { id: networkItem readonly property bool connecting: Network.connectingNetwork === modelData - property int horizontalPadding: Appearance.padding.largeIncreased + property int horizontalPadding: Tokens.padding.largeIncreased required property int index readonly property bool isSecure: Network.isSecure(modelData.security) required property bool known @@ -166,10 +167,10 @@ CustomClippingRect { required property Repeater repeater Layout.fillWidth: true - Layout.preferredHeight: visible ? rowLayout.implicitHeight + Appearance.padding.smaller * 2 : 0 + Layout.preferredHeight: visible ? rowLayout.implicitHeight + Tokens.padding.smaller * 2 : 0 first: index === 0 last: index === (repeater.count - 1) - radius: Appearance.rounding.small + radius: Tokens.rounding.small RowLayout { id: rowLayout @@ -185,9 +186,9 @@ CustomClippingRect { CustomText { Layout.fillWidth: true - Layout.leftMargin: Appearance.spacing.extraSmall - Layout.rightMargin: Appearance.spacing.extraSmall - color: networkItem.modelData.active ? DynamicColors.palette.m3primary : DynamicColors.palette.m3onSurface + Layout.leftMargin: Tokens.spacing.extraSmall + Layout.rightMargin: Tokens.spacing.extraSmall + color: networkItem.modelData.active ? Colors.palette.m3primary : Colors.palette.m3onSurface elide: Text.ElideRight text: networkItem.modelData.name } @@ -197,9 +198,9 @@ CustomClippingRect { anchors.left: parent.left anchors.right: parent.right - color: DynamicColors.palette.m3outline + color: Colors.palette.m3outline elide: Text.ElideRight - font.pointSize: Appearance.font.size.small + font.pointSize: Tokens.font.size.small text: qsTr("%1 strength").arg(Math.round(networkItem.modelData.signalStrength * 100) + "%") } } @@ -212,8 +213,8 @@ CustomClippingRect { MaterialIcon { id: icon - color: networkItem.modelData.active ? DynamicColors.palette.m3primary : DynamicColors.palette.m3onSurfaceVariant - font.pointSize: Appearance.font.size.large + color: networkItem.modelData.active ? Colors.palette.m3primary : Colors.palette.m3onSurfaceVariant + font.pointSize: Tokens.font.size.large opacity: networkItem.connecting ? 0 : 1 text: Icons.getNetworkIcon(networkItem.modelData.signalStrength * 100, networkItem.isSecure) @@ -241,7 +242,7 @@ CustomClippingRect { } StateLayer { - color: networkItem.modelData.active ? DynamicColors.palette.m3onPrimary : DynamicColors.palette.m3onSurface + color: networkItem.modelData.active ? Colors.palette.m3onPrimary : Colors.palette.m3onSurface onClicked: { if (networkItem.isSecure && !networkItem.known) { @@ -259,7 +260,7 @@ CustomClippingRect { required property Repeater repeater - Layout.preferredHeight: repeater.count > 0 ? Appearance.spacing.extraSmall : 0 + Layout.preferredHeight: repeater.count > 0 ? Tokens.spacing.extraSmall : 0 } component Toggle: CustomSwitch { id: toggleItem @@ -271,13 +272,13 @@ CustomClippingRect { Layout.fillWidth: true cLayer: 2 - horizontalPadding: Appearance.padding.largeIncreased + horizontalPadding: Tokens.padding.largeIncreased implicitHeight: Math.max(implicitContentHeight, implicitIndicatorHeight) + verticalPadding * 2 implicitWidth: implicitContentWidth + implicitIndicatorWidth + horizontalPadding * 2 indicator.anchors.right: right indicator.anchors.rightMargin: toggleItem.horizontalPadding indicator.anchors.verticalCenter: verticalCenter - verticalPadding: Appearance.padding.normal + verticalPadding: Tokens.padding.normal background: ConnectedRect { id: bg @@ -292,7 +293,7 @@ CustomClippingRect { anchors.left: parent.left anchors.leftMargin: toggleItem.horizontalPadding anchors.right: toggleItem.indicator.left - anchors.rightMargin: Appearance.spacing.normal + anchors.rightMargin: Tokens.spacing.normal implicitHeight: column.implicitHeight implicitWidth: column.implicitWidth @@ -312,7 +313,7 @@ CustomClippingRect { elide: Text.ElideRight font: { const f = Qt.font(label.font); - f.pointSize = Appearance.font.size.smaller; + f.pointSize = Tokens.font.size.smaller; return f; } text: toggleItem.text @@ -323,11 +324,11 @@ CustomClippingRect { anchors.left: parent.left anchors.right: parent.right - color: DynamicColors.palette.m3outline + color: Colors.palette.m3outline elide: Text.ElideRight font: { const f = Qt.font(subtext.font); - f.pointSize = Appearance.font.size.small; + f.pointSize = Tokens.font.size.small; return f; } text: toggleItem.subtext diff --git a/Modules/SysTray/Popouts/TrayMenuPopout.qml b/Modules/SysTray/Popouts/TrayMenuPopout.qml index 6f640e4..d1b49b8 100644 --- a/Modules/SysTray/Popouts/TrayMenuPopout.qml +++ b/Modules/SysTray/Popouts/TrayMenuPopout.qml @@ -8,13 +8,14 @@ import QtQuick.Controls import QtQuick.Effects import qs.Components import qs.Modules -import qs.Config +import ZShell.Config +import qs.Services StackView { id: root readonly property int itemHeight: 30 - readonly property int panelRadius: ((itemHeight / 2) + Appearance.padding.small) * Appearance.rounding.scale + readonly property int panelRadius: ((itemHeight / 2) + Tokens.padding.small) * Tokens.rounding.scale required property PopoutState popouts property int rootWidth: 0 required property QsMenuHandle trayItem @@ -55,7 +56,7 @@ StackView { opacity: shown ? 1 : 0 scale: shown ? 1 : 0.8 - spacing: Appearance.spacing.extraSmall + spacing: Tokens.spacing.extraSmall Behavior on opacity { Anim { @@ -87,12 +88,12 @@ StackView { required property QsMenuEntry modelData Layout.fillWidth: true - Layout.leftMargin: modelData.isSeparator ? Appearance.padding.normal : 0 - Layout.rightMargin: modelData.isSeparator ? Appearance.padding.normal : 0 - color: modelData.isSeparator ? DynamicColors.palette.m3outlineVariant : "transparent" + Layout.leftMargin: modelData.isSeparator ? Tokens.padding.normal : 0 + Layout.rightMargin: modelData.isSeparator ? Tokens.padding.normal : 0 + color: modelData.isSeparator ? Colors.palette.m3outlineVariant : "transparent" implicitHeight: modelData.isSeparator ? (visible ? 1 : 0) : childrenLoader.item.implicitHeight implicitWidth: childrenLoader.item?.implicitWidth ?? 0 - radius: Appearance.rounding.full + radius: Tokens.rounding.full visible: index !== (menuOpener.children.values.length - 1) ? true : (modelData.isSeparator ? false : true) Loader { @@ -103,7 +104,7 @@ StackView { asynchronous: true sourceComponent: Item { - property int iconWidth: icon.active ? icon.width + Appearance.spacing.normal + icon.anchors.rightMargin : 0 + property int iconWidth: icon.active ? icon.width + Tokens.spacing.normal + icon.anchors.rightMargin : 0 implicitHeight: root.itemHeight implicitWidth: label.width + label.anchors.leftMargin * 2 + iconWidth + (expand.item?.width ?? 0) @@ -150,7 +151,7 @@ StackView { MultiEffect { anchors.fill: iconImage colorization: 1.0 - colorizationColor: item.modelData.enabled ? DynamicColors.palette.m3onSurface : DynamicColors.palette.m3outline + colorizationColor: item.modelData.enabled ? Colors.palette.m3onSurface : Colors.palette.m3outline source: iconImage } } @@ -162,7 +163,7 @@ StackView { anchors.left: parent.left anchors.leftMargin: 10 anchors.verticalCenter: parent.verticalCenter - color: item.modelData.enabled ? DynamicColors.palette.m3onSurface : DynamicColors.palette.m3outline + color: item.modelData.enabled ? Colors.palette.m3onSurface : Colors.palette.m3outline text: item.modelData.text } @@ -175,7 +176,7 @@ StackView { asynchronous: true sourceComponent: MaterialIcon { - color: item.modelData.enabled ? DynamicColors.palette.m3onSurface : DynamicColors.palette.m3outline + color: item.modelData.enabled ? Colors.palette.m3onSurface : Colors.palette.m3outline text: "chevron_right" } } @@ -201,11 +202,11 @@ StackView { CustomRect { anchors.fill: parent - color: DynamicColors.palette.m3secondaryContainer - radius: Appearance.rounding.full + color: Colors.palette.m3secondaryContainer + radius: Tokens.rounding.full StateLayer { - color: DynamicColors.palette.m3onSecondaryContainer + color: Colors.palette.m3onSecondaryContainer radius: parent.radius onClicked: { @@ -221,13 +222,13 @@ StackView { MaterialIcon { anchors.verticalCenter: parent.verticalCenter - color: DynamicColors.palette.m3onSecondaryContainer + color: Colors.palette.m3onSecondaryContainer text: "chevron_left" } CustomText { anchors.verticalCenter: parent.verticalCenter - color: DynamicColors.palette.m3onSecondaryContainer + color: Colors.palette.m3onSecondaryContainer text: qsTr("Back") } } diff --git a/Modules/SysTray/Popouts/UPowerPopout.qml b/Modules/SysTray/Popouts/UPowerPopout.qml index 4ed3c7c..1ceec24 100644 --- a/Modules/SysTray/Popouts/UPowerPopout.qml +++ b/Modules/SysTray/Popouts/UPowerPopout.qml @@ -2,16 +2,17 @@ pragma ComponentBehavior: Bound import QtQuick import Quickshell.Services.UPower -import qs.Config +import ZShell.Config import qs.Helpers import qs.Components +import qs.Services Column { id: root - readonly property int panelRadius: ((profiles.height / 2) + Appearance.padding.small) * Appearance.rounding.scale + readonly property int panelRadius: ((profiles.height / 2) + Tokens.padding.small) * Tokens.rounding.scale - spacing: Appearance.spacing.normal + spacing: Tokens.spacing.normal Loader { active: Battery.isLaptop @@ -39,7 +40,7 @@ Column { } anchors.left: parent.left - anchors.leftMargin: Appearance.padding.normal + anchors.leftMargin: Tokens.padding.normal text: Battery.isLaptop ? qsTr("Time %1: %2").arg(Battery.onBattery ? "remaining" : "until charged").arg(Battery.onBattery ? formatSeconds(Battery.timeToEmpty, "Calculating...") : formatSeconds(Battery.timeToFull, "Fully charged!")) : qsTr("Power profile: %1").arg(PowerProfile.toString(PowerProfiles.profile)) } @@ -50,10 +51,10 @@ Column { height: active ? ((item as Item)?.implicitHeight ?? 0) : 0 sourceComponent: CustomRect { - color: DynamicColors.palette.m3error - implicitHeight: child.implicitHeight + Appearance.padding.large - implicitWidth: child.implicitWidth + Appearance.padding.larger * 2 - radius: Appearance.rounding.large + color: Colors.palette.m3error + implicitHeight: child.implicitHeight + Tokens.padding.large + implicitWidth: child.implicitWidth + Tokens.padding.larger * 2 + radius: Tokens.rounding.large Column { id: child @@ -62,18 +63,18 @@ Column { Row { anchors.horizontalCenter: parent.horizontalCenter - spacing: Appearance.spacing.small + spacing: Tokens.spacing.small MaterialIcon { anchors.verticalCenter: parent.verticalCenter anchors.verticalCenterOffset: -font.pointSize / 10 - color: DynamicColors.palette.m3onError + color: Colors.palette.m3onError text: "warning" } CustomText { anchors.verticalCenter: parent.verticalCenter - color: DynamicColors.palette.m3onError + color: Colors.palette.m3onError font.family: Appearance.font.family.mono text: qsTr("Performance Degraded") } @@ -81,14 +82,14 @@ Column { MaterialIcon { anchors.verticalCenter: parent.verticalCenter anchors.verticalCenterOffset: -font.pointSize / 10 - color: DynamicColors.palette.m3onError + color: Colors.palette.m3onError text: "warning" } } CustomText { anchors.horizontalCenter: parent.horizontalCenter - color: DynamicColors.palette.m3onError + color: Colors.palette.m3onError text: qsTr("Reason: %1").arg(PerformanceDegradationReason.toString(PowerProfiles.degradationReason)) } } @@ -108,16 +109,16 @@ Column { } anchors.horizontalCenter: parent.horizontalCenter - color: DynamicColors.tPalette.m3surfaceContainer - implicitHeight: indicator.height + Appearance.padding.extraSmall * 2 - implicitWidth: saver.implicitHeight + balance.implicitHeight + perf.implicitHeight + Appearance.padding.larger * 2 + Appearance.spacing.small * 8 - radius: Appearance.rounding.full + color: Colors.tPalette.m3surfaceContainer + implicitHeight: indicator.height + Tokens.padding.extraSmall * 2 + implicitWidth: saver.implicitHeight + balance.implicitHeight + perf.implicitHeight + Tokens.padding.larger * 2 + Tokens.spacing.small * 8 + radius: Tokens.rounding.full CustomRect { id: indicator - color: DynamicColors.palette.m3primary - radius: Appearance.rounding.full + color: Colors.palette.m3primary + radius: Tokens.rounding.full state: profiles.current states: [ @@ -153,7 +154,7 @@ Column { id: saver anchors.left: parent.left - anchors.leftMargin: Appearance.padding.extraSmall + anchors.leftMargin: Tokens.padding.extraSmall anchors.verticalCenter: parent.verticalCenter icon: "energy_savings_leaf" profile: PowerProfile.PowerSaver @@ -171,7 +172,7 @@ Column { id: perf anchors.right: parent.right - anchors.rightMargin: Appearance.padding.extraSmall + anchors.rightMargin: Tokens.padding.extraSmall anchors.verticalCenter: parent.verticalCenter icon: "bolt" profile: PowerProfile.Performance @@ -191,12 +192,12 @@ Column { required property string icon required property int profile - implicitHeight: icon.implicitHeight + Appearance.padding.small - implicitWidth: icon.implicitHeight + Appearance.padding.small + implicitHeight: icon.implicitHeight + Tokens.padding.small + implicitWidth: icon.implicitHeight + Tokens.padding.small StateLayer { - color: profiles.current === parent.icon ? DynamicColors.palette.m3onPrimary : DynamicColors.palette.m3onSurface - radius: Appearance.rounding.full + color: profiles.current === parent.icon ? Colors.palette.m3onPrimary : Colors.palette.m3onSurface + radius: Tokens.rounding.full onClicked: { PowerProfiles.profile = parent.profile; @@ -207,10 +208,10 @@ Column { id: icon anchors.centerIn: parent - color: profiles.current === text ? DynamicColors.palette.m3onPrimary : DynamicColors.palette.m3onSurface + color: profiles.current === text ? Colors.palette.m3onPrimary : Colors.palette.m3onSurface fill: profiles.current === text ? 1 : 0 - font.pointSize: Appearance.font.size.large * 2 - grade: DynamicColors.light ? 0 : (text === "balance" ? -25 : 0) + font.pointSize: Tokens.font.size.large * 2 + grade: Colors.light ? 0 : (text === "balance" ? -25 : 0) text: parent.icon Behavior on fill { diff --git a/Modules/SysTray/StatusIcons.qml b/Modules/SysTray/StatusIcons.qml new file mode 100644 index 0000000..3f92ae9 --- /dev/null +++ b/Modules/SysTray/StatusIcons.qml @@ -0,0 +1,151 @@ +pragma ComponentBehavior: Bound + +import Quickshell +import QtQuick +import QtQuick.Layouts +import qs.Helpers +import qs.Modules.SysTray.Widgets +import ZShell.Config +import qs.Components +import qs.Services + +CustomClippingRect { + id: root + + readonly property int firstPresent: { + const values = model.values; + for (let i = 0; i < values.length; i++) + if (!collapsed(values[i])) + return i; + return -1; + } + + // Index of the first/last entry that isn't collapsed, for edge margin gating + readonly property alias items: row + readonly property int lastPresent: { + const values = model.values; + for (let i = values.length - 1; i >= 0; i--) + if (!collapsed(values[i])) + return i; + return -1; + } + readonly property int spacing: Tokens.spacing.normal / 2 + + // Entries that can shrink to nothing, spacing included + function collapsed(entry: var): bool { + if (entry.id === "lockStatus") + return !Hypr.capsLock && !Hypr.numLock; + return false; + } + + bottomLeftRadius: Tokens.rounding.smallest / 2 + color: Colors.tPalette.m3surfaceContainer + implicitHeight: Config.bar.height + Tokens.padding.smallest * 2 + implicitWidth: row.implicitWidth + Tokens.padding.small * 2 + radius: Tokens.rounding.full + topLeftRadius: Tokens.rounding.smallest / 2 + + RowLayout { + id: row + + anchors.fill: parent + anchors.leftMargin: Tokens.padding.small + anchors.rightMargin: Tokens.padding.small + + Repeater { + model: ScriptModel { + id: model + + values: Config.bar.tray.statusIcons.values.filter(e => e.enabled) + } + + DelegateChooser { + role: "id" + + DelegateChoice { + roleValue: "audio" + + delegate: EntryWrapper { + name: "audio" + + AudioWidget { + } + } + } + + DelegateChoice { + roleValue: "microphone" + + delegate: EntryWrapper { + name: "audio" + + MicWidget { + } + } + } + + DelegateChoice { + roleValue: "bluetooth" + + delegate: EntryWrapper { + name: "bluetooth" + + BluetoothWidget { + } + } + } + + DelegateChoice { + roleValue: "network" + + delegate: EntryWrapper { + name: "network" + + NetworkWidget { + } + } + } + + DelegateChoice { + roleValue: "power" + + delegate: EntryWrapper { + name: "upower" + + UPowerWidget { + } + } + } + } + } + } + + component EntryWrapper: Item { + required property int index + default property Item item + property real leftGap: present && index !== root.lastPresent ? margin : 0 + property int margin: root.spacing / 2 + required property var modelData + property string name: modelData.id.toLowerCase() + readonly property bool present: !root.collapsed(modelData) + property real rightGap: present && index !== root.firstPresent ? margin : 0 + + Layout.alignment: Qt.AlignHCenter + Layout.leftMargin: Math.round(leftGap) + Layout.rightMargin: Math.round(rightGap) + children: item + implicitHeight: item?.implicitHeight ?? 0 + implicitWidth: item?.implicitWidth ?? 0 + + Behavior on leftGap { + Anim { + type: Anim.SlowEffects + } + } + Behavior on rightGap { + Anim { + type: Anim.SlowEffects + } + } + } +} diff --git a/Modules/SysTray/TrayIcons.qml b/Modules/SysTray/TrayIcons.qml new file mode 100644 index 0000000..c9e05e2 --- /dev/null +++ b/Modules/SysTray/TrayIcons.qml @@ -0,0 +1,54 @@ +pragma ComponentBehavior: Bound + +import QtQuick +import QtQuick.Layouts +import Quickshell.Services.SystemTray +import qs.Components +import ZShell.Config +import qs.Modules.SysTray.Widgets +import qs.Modules +import qs.Services + +CustomClippingRect { + id: root + + readonly property alias items: repeater + readonly property alias layout: sysRow + required property RowLayout loader + readonly property int padding: Tokens.padding.small + required property Wrapper popouts + + bottomRightRadius: Tokens.rounding.smallest / 2 + color: Colors.tPalette.m3surfaceContainer + implicitHeight: Config.bar.height + Tokens.padding.smallest * 2 + implicitWidth: sysRow.implicitWidth + Tokens.padding.small * 2 + radius: Tokens.rounding.full + topRightRadius: Tokens.rounding.smallest / 2 + + RowLayout { + id: sysRow + + anchors.centerIn: parent + spacing: 0 + + Repeater { + id: repeater + + model: SystemTray.items + + TrayItem { + id: trayItem + + required property int index + required property SystemTrayItem modelData + + implicitHeight: 34 + implicitWidth: 34 + ind: index + item: modelData + loader: root.loader + popouts: root.popouts + } + } + } +} diff --git a/Modules/SysTray/TrayItem.qml b/Modules/SysTray/TrayItem.qml index dc017c4..8c74abc 100644 --- a/Modules/SysTray/TrayItem.qml +++ b/Modules/SysTray/TrayItem.qml @@ -6,7 +6,8 @@ import Quickshell.Services.SystemTray import qs.Helpers import qs.Modules import qs.Components -import qs.Config +import ZShell.Config +import qs.Services Item { id: root @@ -45,14 +46,14 @@ Item { CustomRect { anchors.fill: parent anchors.margins: 3 - color: icon.layer.enabled && enabled && root.current ? DynamicColors.palette.m3primary : "transparent" + color: icon.layer.enabled && enabled && root.current ? Colors.palette.m3primary : "transparent" enabled: !Config.bar.tray.showOnHover - radius: Appearance.rounding.full + radius: Tokens.rounding.full StateLayer { acceptedButtons: Qt.LeftButton | Qt.RightButton anchors.fill: parent - color: icon.layer.enabled && root.current ? DynamicColors.palette.m3onPrimary : DynamicColors.palette.m3onSurface + color: icon.layer.enabled && root.current ? Colors.palette.m3onPrimary : Colors.palette.m3onSurface onClicked: mouse => { if (mouse.button === Qt.LeftButton) { @@ -77,7 +78,7 @@ Item { anchors.centerIn: parent antialiasing: true - color: root.current && !Config.bar.tray.showOnHover ? DynamicColors.palette.m3onPrimary : DynamicColors.palette.m3onSurface + color: root.current && !Config.bar.tray.showOnHover ? Colors.palette.m3onPrimary : Colors.palette.m3onSurface implicitSize: Config.bar.tray.trayIconSize * root.dpr layer.enabled: Config.bar.tray.recolorIcons scale: 1 / root.dpr diff --git a/Modules/SysTray/TrayWidget.qml b/Modules/SysTray/TrayWidget.qml index 977bdb2..e1bd36c 100644 --- a/Modules/SysTray/TrayWidget.qml +++ b/Modules/SysTray/TrayWidget.qml @@ -4,9 +4,10 @@ import QtQuick import QtQuick.Layouts import Quickshell.Services.SystemTray import qs.Components -import qs.Config +import ZShell.Config import qs.Modules.SysTray.Widgets import qs.Modules +import qs.Services RowLayout { id: root @@ -44,10 +45,10 @@ RowLayout { function getHoveredSubItem(localX, localY) { let modPos = mapToItem(sysTrayMod, localX, localY); if (sysTrayMod.contains(Qt.point(modPos.x, modPos.y))) { - let modRowPos = sysTrayMod.mapToItem(sysModRow, modPos.x, modPos.y); - let child = closestRowChild(sysModRow, modRowPos.x); + let modRowPos = sysTrayMod.mapToItem(sysIcons, modPos.x, modPos.y); + let child = closestRowChild(sysIcons, modRowPos.x); if (child) { - if (child.objectName === "audioWidget" && Config.bar.popouts.audio) + if (child.objectName === "audio" && Config.bar.popouts.audio) return { id: "audio", item: child @@ -57,7 +58,12 @@ RowLayout { id: "network", item: child }; - if (child.objectName === "upowerWidget" && Config.bar.popouts.upower) + if (child.objectName === "microphone" && Config.bar.popouts.audio) + return { + id: "audio", + item: child + }; + if (child.objectName === "upower" && Config.bar.popouts.upower) return { id: "upower", item: child @@ -85,19 +91,19 @@ RowLayout { return null; } - height: Config.bar.height + Appearance.padding.smallest * 2 - spacing: Appearance.padding.small - width: sysTray.implicitWidth + sysTrayMod.implicitWidth + Appearance.padding.small + height: Config.bar.height + Tokens.padding.smallest * 2 + spacing: Tokens.padding.small + width: sysTray.implicitWidth + sysTrayMod.implicitWidth + Tokens.padding.small CustomClippingRect { id: sysTray Layout.fillHeight: true - bottomRightRadius: Appearance.rounding.smallest / 2 - color: DynamicColors.tPalette.m3surfaceContainer - implicitWidth: sysRow.width + Appearance.padding.small * 2 - radius: Appearance.rounding.full - topRightRadius: Appearance.rounding.smallest / 2 + bottomRightRadius: Tokens.rounding.smallest / 2 + color: Colors.tPalette.m3surfaceContainer + implicitWidth: sysRow.width + Tokens.padding.small * 2 + radius: Tokens.rounding.full + topRightRadius: Tokens.rounding.smallest / 2 Row { id: sysRow @@ -131,43 +137,18 @@ RowLayout { id: sysTrayMod Layout.fillHeight: true - bottomLeftRadius: Appearance.rounding.smallest / 2 - color: DynamicColors.tPalette.m3surfaceContainer - implicitWidth: sysModRow.implicitWidth + Appearance.padding.smaller + Appearance.padding.normal - radius: Appearance.rounding.full - topLeftRadius: Appearance.rounding.smallest / 2 + bottomLeftRadius: Tokens.rounding.smallest / 2 + color: Colors.tPalette.m3surfaceContainer + implicitWidth: sysIcons.implicitWidth + Tokens.padding.smaller + Tokens.padding.normal + radius: Tokens.rounding.full + topLeftRadius: Tokens.rounding.smallest / 2 - RowLayout { - id: sysModRow + StatusIcons { + id: sysIcons anchors.fill: parent - anchors.leftMargin: Appearance.padding.smaller - anchors.rightMargin: Appearance.padding.normal - - AudioWidget { - Layout.fillHeight: true - Layout.rightMargin: hasContent ? Appearance.spacing.extraSmall / 2 : 0 - objectName: "audioWidget" - - Behavior on Layout.rightMargin { - Anim { - type: Anim.FastEffects - } - } - } - - NetworkWidget { - objectName: "networkWidget" - } - - BluetoothWidget { - objectName: "bluetoothWidget" - } - - UPowerWidget { - Layout.fillHeight: true - objectName: "upowerWidget" - } + anchors.leftMargin: Tokens.padding.smaller + anchors.rightMargin: Tokens.padding.normal } } } diff --git a/Modules/SysTray/Widgets/AudioWidget.qml b/Modules/SysTray/Widgets/AudioWidget.qml index 3ecac22..6f6661b 100644 --- a/Modules/SysTray/Widgets/AudioWidget.qml +++ b/Modules/SysTray/Widgets/AudioWidget.qml @@ -4,75 +4,29 @@ import Quickshell.Io import Quickshell.Services.Pipewire import qs.Daemons import qs.Modules -import qs.Config +import ZShell.Config import qs.Components +import qs.Services -RowLayout { - id: root +MaterialIcon { + id: speaker - property color barColor: DynamicColors.palette.m3primary - readonly property bool hasContent: mic.visible || speaker.visible - property color textColor: DynamicColors.palette.m3onSurface + animate: true + color: Audio.muted ? Colors.palette.m3error : Colors.palette.m3onSurface + fill: 1 + font.pointSize: Tokens.font.size.larger + text: Audio.muted ? "volume_off" : "volume_up" - width: hasContent ? implicitWidth : 0 - - MaterialIcon { - id: mic - - readonly property bool shouldBeVisible: Config.bar.tray.showMicrophone - - Layout.alignment: Qt.AlignVCenter - Layout.maximumWidth: shouldBeVisible ? implicitWidth : 0 - animate: true - color: (Audio.sourceMuted ?? false) ? DynamicColors.palette.m3error : root.textColor - fill: 1 - font.pointSize: Appearance.font.size.larger - opacity: shouldBeVisible ? 1 : 0 - scale: shouldBeVisible ? 1 : 0 - text: Audio.sourceMuted ? "mic_off" : "mic" - visible: opacity > 0 - - Behavior on Layout.maximumWidth { - Anim { - } - } - Behavior on opacity { - Anim { - } - } - Behavior on scale { - Anim { - } + Behavior on Layout.maximumWidth { + Anim { } } - - MaterialIcon { - id: speaker - - readonly property bool shouldBeVisible: Config.bar.tray.showAudio - - Layout.alignment: Qt.AlignVCenter - Layout.maximumWidth: shouldBeVisible ? implicitWidth : 0 - animate: true - color: Audio.muted ? DynamicColors.palette.m3error : root.textColor - fill: 1 - font.pointSize: Appearance.font.size.larger - opacity: shouldBeVisible ? 1 : 0 - scale: shouldBeVisible ? 1 : 0 - text: Audio.muted ? "volume_off" : "volume_up" - visible: opacity > 0 - - Behavior on Layout.maximumWidth { - Anim { - } + Behavior on opacity { + Anim { } - Behavior on opacity { - Anim { - } - } - Behavior on scale { - Anim { - } + } + Behavior on scale { + Anim { } } } diff --git a/Modules/SysTray/Widgets/BluetoothWidget.qml b/Modules/SysTray/Widgets/BluetoothWidget.qml index 8f43f8b..3cfaa1e 100644 --- a/Modules/SysTray/Widgets/BluetoothWidget.qml +++ b/Modules/SysTray/Widgets/BluetoothWidget.qml @@ -1,13 +1,14 @@ import QtQuick import QtQuick.Layouts -import qs.Config +import ZShell.Config +import qs.Services import qs.Components MaterialIcon { Layout.alignment: Qt.AlignVCenter animate: true - color: DynamicColors.palette.m3onSurface // Network.connected ? root.textColor : DynamicColors.palette.m3error + color: Colors.palette.m3onSurface // Network.connected ? root.textColor : Colors.palette.m3error fill: 1 - font.pointSize: Appearance.font.size.larger + font.pointSize: Tokens.font.size.larger text: "bluetooth" } diff --git a/Modules/SysTray/Widgets/MicWidget.qml b/Modules/SysTray/Widgets/MicWidget.qml new file mode 100644 index 0000000..07492e0 --- /dev/null +++ b/Modules/SysTray/Widgets/MicWidget.qml @@ -0,0 +1,32 @@ +import QtQuick +import QtQuick.Layouts +import Quickshell.Io +import Quickshell.Services.Pipewire +import qs.Daemons +import qs.Modules +import ZShell.Config +import qs.Components +import qs.Services + +MaterialIcon { + id: mic + + animate: true + color: (Audio.sourceMuted ?? false) ? Colors.palette.m3error : Colors.palette.m3onSurface + fill: 1 + font.pointSize: Tokens.font.size.larger + text: Audio.sourceMuted ? "mic_off" : "mic" + + Behavior on Layout.maximumWidth { + Anim { + } + } + Behavior on opacity { + Anim { + } + } + Behavior on scale { + Anim { + } + } +} diff --git a/Modules/SysTray/Widgets/NetworkWidget.qml b/Modules/SysTray/Widgets/NetworkWidget.qml index 3793fdd..76ba475 100644 --- a/Modules/SysTray/Widgets/NetworkWidget.qml +++ b/Modules/SysTray/Widgets/NetworkWidget.qml @@ -1,13 +1,14 @@ import QtQuick import QtQuick.Layouts -import qs.Config +import ZShell.Config +import qs.Services import qs.Components MaterialIcon { Layout.alignment: Qt.AlignVCenter animate: true - color: DynamicColors.palette.m3onSurface // Network.connected ? root.textColor : DynamicColors.palette.m3error + color: Colors.palette.m3onSurface // Network.connected ? root.textColor : Colors.palette.m3error fill: 1 - font.pointSize: Appearance.font.size.larger + font.pointSize: Tokens.font.size.larger text: "android_wifi_4_bar" } diff --git a/Modules/SysTray/Widgets/UPowerWidget.qml b/Modules/SysTray/Widgets/UPowerWidget.qml index 0c4b4c8..6cb2345 100644 --- a/Modules/SysTray/Widgets/UPowerWidget.qml +++ b/Modules/SysTray/Widgets/UPowerWidget.qml @@ -2,21 +2,14 @@ import Quickshell.Services.UPower import QtQuick import QtQuick.Layouts import qs.Components -import qs.Config +import ZShell.Config import qs.Helpers Item { id: root - readonly property bool shouldBeActive: Config.bar.tray.showPower - - Layout.preferredHeight: shouldBeActive ? implicitHeight : 0 - Layout.preferredWidth: shouldBeActive ? implicitWidth : 0 implicitHeight: Battery.isLaptop ? batteryIconLoader.item.implicitHeight : upowerIconLoader.item.implicitHeight implicitWidth: Battery.isLaptop ? batteryIconLoader.item.implicitWidth : upowerIconLoader.item.implicitWidth - opacity: shouldBeActive ? 1 : 0 - scale: shouldBeActive ? 1 : 0 - visible: opacity > 0 Behavior on Layout.preferredHeight { Anim { @@ -48,7 +41,7 @@ Item { property real batWidth: 30 property real nubHeight: 6 property real nubWidth: 2 - property real radius: Appearance.rounding.smallest / 2 + property real radius: Tokens.rounding.smallest / 2 spacing: 1 @@ -63,7 +56,7 @@ Item { CustomText { color: Battery.colors.fg - font.pointSize: Appearance.font.size.larger / 1.5 + font.pointSize: Tokens.font.size.larger / 1.5 font.weight: 800 height: track.height horizontalAlignment: Text.AlignHCenter diff --git a/Modules/Updates/UpdatesPopout.qml b/Modules/Updates/UpdatesPopout.qml index 1665777..a7aef14 100644 --- a/Modules/Updates/UpdatesPopout.qml +++ b/Modules/Updates/UpdatesPopout.qml @@ -3,22 +3,23 @@ pragma ComponentBehavior: Bound import QtQuick import QtQuick.Layouts import Quickshell -import qs.Config +import ZShell.Config import qs.Components import qs.Modules import qs.Helpers +import qs.Services CustomClippingRect { id: root readonly property bool hasUpdates: Object.keys(Updates.updates)?.length > 0 - readonly property int itemHeight: 50 + Appearance.padding.smaller * 2 + readonly property int itemHeight: 50 + Tokens.padding.smaller * 2 required property var wrapper - color: DynamicColors.tPalette.m3surfaceContainer - implicitHeight: hasUpdates ? updatesListLoader.item?.implicitHeight + Appearance.padding.small * 2 : noUpdatesLoader.item.height - implicitWidth: hasUpdates ? updatesListLoader.item?.contentWidth + Appearance.padding.small * 2 : noUpdatesLoader.item.width - radius: Appearance.rounding.small + color: Colors.tPalette.m3surfaceContainer + implicitHeight: hasUpdates ? updatesListLoader.item?.implicitHeight + Tokens.padding.small * 2 : noUpdatesLoader.item.height + implicitWidth: hasUpdates ? updatesListLoader.item?.contentWidth + Tokens.padding.small * 2 : noUpdatesLoader.item.width + radius: Tokens.rounding.small Loader { id: noUpdatesLoader @@ -37,8 +38,8 @@ CustomClippingRect { anchors.horizontalCenter: parent.horizontalCenter anchors.top: parent.top - color: DynamicColors.tPalette.m3onSurfaceVariant - font.pointSize: Appearance.font.size.extraLarge * 3 + color: Colors.tPalette.m3onSurfaceVariant + font.pointSize: Tokens.font.size.extraLarge * 3 horizontalAlignment: Text.AlignHCenter text: "check" } @@ -46,7 +47,7 @@ CustomClippingRect { CustomText { anchors.horizontalCenter: parent.horizontalCenter anchors.top: noUpdatesIcon.bottom - color: DynamicColors.tPalette.m3onSurfaceVariant + color: Colors.tPalette.m3onSurfaceVariant horizontalAlignment: Text.AlignHCenter text: qsTr("No updates available") verticalAlignment: Text.AlignVCenter @@ -69,7 +70,7 @@ CustomClippingRect { displayMarginEnd: root.itemHeight implicitHeight: Math.min(contentHeight, (root.itemHeight + spacing) * 5 - spacing) implicitWidth: contentWidth - spacing: Appearance.spacing.normal + spacing: Tokens.spacing.normal delegate: CustomRect { id: update @@ -79,18 +80,18 @@ CustomClippingRect { // anchors.left: parent.left // anchors.right: parent.right - color: DynamicColors.tPalette.m3surfaceContainer + color: Colors.tPalette.m3surfaceContainer implicitHeight: root.itemHeight implicitWidth: 600 - radius: Appearance.rounding.small - Appearance.padding.small + radius: Tokens.rounding.small - Tokens.padding.small RowLayout { anchors.fill: parent - anchors.leftMargin: Appearance.padding.smaller - anchors.rightMargin: Appearance.padding.smaller + anchors.leftMargin: Tokens.padding.smaller + anchors.rightMargin: Tokens.padding.smaller MaterialIcon { - font.pointSize: Appearance.font.size.large * 2 + font.pointSize: Tokens.font.size.large * 2 text: "package_2" } @@ -101,13 +102,13 @@ CustomClippingRect { Layout.fillWidth: true Layout.preferredHeight: 25 elide: Text.ElideRight - font.pointSize: Appearance.font.size.large + font.pointSize: Tokens.font.size.large text: update.sections[0] } CustomText { Layout.fillWidth: true - color: DynamicColors.palette.m3onSurfaceVariant + color: Colors.palette.m3onSurfaceVariant text: Updates.formatUpdateTime(update.modelData.timestamp) } } @@ -122,8 +123,8 @@ CustomClippingRect { Layout.fillHeight: true Layout.preferredWidth: 125 animate: true - color: DynamicColors.palette.m3tertiary - font.pointSize: Appearance.font.size.large + color: Colors.palette.m3tertiary + font.pointSize: Tokens.font.size.large horizontalAlignment: Text.AlignHCenter marqueeEnabled: true pauseMs: 4000 @@ -133,8 +134,8 @@ CustomClippingRect { MaterialIcon { Layout.fillHeight: true - color: DynamicColors.palette.m3secondary - font.pointSize: Appearance.font.size.extraLarge + color: Colors.palette.m3secondary + font.pointSize: Tokens.font.size.extraLarge horizontalAlignment: Text.AlignHCenter text: "arrow_right_alt" verticalAlignment: Text.AlignVCenter @@ -146,8 +147,8 @@ CustomClippingRect { Layout.fillHeight: true Layout.preferredWidth: 120 animate: true - color: DynamicColors.palette.m3primary - font.pointSize: Appearance.font.size.large + color: Colors.palette.m3primary + font.pointSize: Tokens.font.size.large horizontalAlignment: Text.AlignHCenter marqueeEnabled: true pauseMs: 4000 diff --git a/Modules/Updates/UpdatesWidget.qml b/Modules/Updates/UpdatesWidget.qml index 14be0cb..04bf907 100644 --- a/Modules/Updates/UpdatesWidget.qml +++ b/Modules/Updates/UpdatesWidget.qml @@ -3,33 +3,34 @@ import QtQuick.Layouts import qs.Components import qs.Modules import qs.Helpers -import qs.Config +import ZShell.Config +import qs.Services CustomRect { id: root property int countUpdates: Updates.availableUpdates - property color textColor: DynamicColors.palette.m3onSurface + property color textColor: Colors.palette.m3onSurface - color: DynamicColors.tPalette.m3surfaceContainer - implicitHeight: Config.bar.height + Appearance.padding.smallest * 2 - implicitWidth: contentRow.implicitWidth + Appearance.spacing.small * 2 - radius: Appearance.rounding.full + color: Colors.tPalette.m3surfaceContainer + implicitHeight: Config.bar.height + Tokens.padding.smallest * 2 + implicitWidth: contentRow.implicitWidth + Tokens.spacing.small * 2 + radius: Tokens.rounding.full RowLayout { id: contentRow anchors.centerIn: parent - spacing: Appearance.spacing.small + spacing: Tokens.spacing.small MaterialIcon { - font.pointSize: Appearance.font.size.larger + font.pointSize: Tokens.font.size.larger text: "package_2" } CustomText { color: root.textColor - font.pointSize: Appearance.font.size.normal + font.pointSize: Tokens.font.size.normal text: root.countUpdates } } diff --git a/Modules/WSOverview/OverviewPopout.qml b/Modules/WSOverview/OverviewPopout.qml index e3b8f3a..9f42165 100644 --- a/Modules/WSOverview/OverviewPopout.qml +++ b/Modules/WSOverview/OverviewPopout.qml @@ -3,10 +3,11 @@ import Quickshell.Hyprland import Quickshell.Wayland import QtQuick import QtQuick.Layouts -import qs.Config +import ZShell.Config import qs.Components import qs.Modules import qs.Helpers +import qs.Services Item { id: root @@ -36,7 +37,7 @@ Item { Layout.preferredWidth: 320 + 10 border.color: "white" border.width: 1 - radius: Appearance.rounding.smallest + radius: Tokens.rounding.smallest Repeater { model: workspacePreview.modelData.toplevels @@ -61,11 +62,11 @@ Item { anchors.margins: 5 CustomRect { - border.color: DynamicColors.tPalette.m3outline + border.color: Colors.tPalette.m3outline border.width: 1 implicitHeight: preview.appPosition.height implicitWidth: preview.appPosition.width - radius: Appearance.rounding.smallest / 2 + radius: Tokens.rounding.smallest / 2 x: preview.appPosition.x y: preview.appPosition.y - 3.4 diff --git a/Modules/Wallpaper/WallBackground.qml b/Modules/Wallpaper/WallBackground.qml index 32c58b7..a7851e1 100644 --- a/Modules/Wallpaper/WallBackground.qml +++ b/Modules/Wallpaper/WallBackground.qml @@ -5,7 +5,7 @@ import Quickshell.Hyprland import QtQuick import qs.Components import qs.Helpers -import qs.Config +import ZShell.Config import ZShell.Internal Item { diff --git a/Modules/Wallpaper/Wallpaper.qml b/Modules/Wallpaper/Wallpaper.qml index 476fd29..9de4551 100644 --- a/Modules/Wallpaper/Wallpaper.qml +++ b/Modules/Wallpaper/Wallpaper.qml @@ -1,7 +1,7 @@ import Quickshell import QtQuick import Quickshell.Wayland -import qs.Config +import ZShell.Config import qs.Modules.DesktopIcons Loader { diff --git a/Modules/WindowTitle.qml b/Modules/WindowTitle.qml index 88c4cc0..9258ef4 100644 --- a/Modules/WindowTitle.qml +++ b/Modules/WindowTitle.qml @@ -2,14 +2,15 @@ pragma ComponentBehavior: Bound import QtQuick import qs.Components -import qs.Config +import ZShell.Config import qs.Helpers +import qs.Services Item { id: root required property var bar - property color colour: DynamicColors.palette.m3primary + property color colour: Colors.palette.m3primary property Title current: text1 // readonly property int maxWidth: 300 readonly property int maxWidth: { @@ -26,19 +27,15 @@ Item { Behavior on implicitWidth { Anim { - duration: MaterialEasing.expressiveEffectsTime - easing.bezierCurve: MaterialEasing.expressiveEffects } } Title { id: text1 - } Title { id: text2 - } TextMetrics { @@ -47,7 +44,7 @@ Item { elide: Qt.ElideRight elideWidth: root.maxWidth font.family: "Rubik" - font.pointSize: Appearance.font.size.normal + font.pointSize: Tokens.font.size.normal text: Hypr.activeToplevel?.title ?? qsTr("Desktop") onElideWidthChanged: root.current.text = elidedText diff --git a/Modules/Workspaces.qml b/Modules/Workspaces.qml index 91420db..98c3ee9 100644 --- a/Modules/Workspaces.qml +++ b/Modules/Workspaces.qml @@ -5,13 +5,14 @@ import QtQuick.Controls import QtQuick.Effects import Quickshell import Quickshell.Hyprland -import qs.Config +import ZShell.Config import qs.Components +import qs.Services Item { id: root - property real activeWorkspaceMargin: Math.ceil(Appearance.padding.small / 2) + property real activeWorkspaceMargin: Math.ceil(Tokens.padding.small / 2) readonly property int effectiveActiveWorkspaceId: monitor?.activeWorkspace?.id ?? 1 readonly property HyprlandMonitor monitor: Hyprland.monitorFor(root.screen) required property ShellScreen screen @@ -21,7 +22,7 @@ Item { readonly property int workspacesShown: workspaces.length height: implicitHeight - implicitHeight: Config.bar.height + Appearance.padding.smaller * 2 + implicitHeight: Config.bar.height + Tokens.padding.smaller * 2 implicitWidth: (root.workspaceButtonWidth * root.workspacesShown) + root.activeWorkspaceMargin * 2 Behavior on implicitWidth { @@ -35,8 +36,8 @@ Item { anchors.left: parent.left anchors.right: parent.right anchors.verticalCenter: parent.verticalCenter - color: DynamicColors.tPalette.m3surfaceContainer - implicitHeight: root.implicitHeight - ((Appearance.padding.small - 1) * 2) + color: Colors.tPalette.m3surfaceContainer + implicitHeight: root.implicitHeight - ((Tokens.padding.small - 1) * 2) radius: height / 2 Grid { @@ -70,7 +71,7 @@ Item { CustomText { anchors.centerIn: parent - color: DynamicColors.palette.m3onSecondaryContainer + color: Colors.palette.m3onSecondaryContainer elide: Text.ElideRight horizontalAlignment: Text.AlignHCenter text: button.modelData.name @@ -95,10 +96,10 @@ Item { anchors.verticalCenter: parent.verticalCenter clip: true - color: DynamicColors.palette.m3primary + color: Colors.palette.m3primary implicitHeight: indicatorThickness implicitWidth: indicatorLength - radius: Appearance.rounding.full + radius: Tokens.rounding.full x: indicatorPosition AnimatedTabIndexPair { @@ -108,11 +109,11 @@ Item { } Coloriser { - colorizationColor: DynamicColors.palette.m3onPrimary + colorizationColor: Colors.palette.m3onPrimary implicitHeight: grid.height implicitWidth: grid.width source: grid - sourceColor: DynamicColors.palette.m3onSurface + sourceColor: Colors.palette.m3onSurface x: -indicator.x + 3 } } diff --git a/Modules/Wrapper.qml b/Modules/Wrapper.qml index 776585e..99f443c 100644 --- a/Modules/Wrapper.qml +++ b/Modules/Wrapper.qml @@ -3,13 +3,13 @@ import Quickshell.Wayland import Quickshell.Hyprland import QtQuick import qs.Components -import qs.Config +import ZShell.Config Item { id: root - property list animCurve: Appearance.anim.curves.expressiveDefaultSpatial - property int animLength: Appearance.anim.durations.expressiveDefaultSpatial + property list animCurve: Tokens.anim.curves.expressiveDefaultSpatial + property int animLength: Tokens.anim.durations.expressiveDefaultSpatial readonly property alias content: content readonly property Item current: (content.item as Content)?.current ?? null property real currentCenter diff --git a/Paths/Paths.qml b/Paths/Paths.qml index 4847062..f4b6ab5 100644 --- a/Paths/Paths.qml +++ b/Paths/Paths.qml @@ -2,7 +2,7 @@ pragma Singleton import ZShell import Quickshell -import qs.Config +import ZShell.Config Singleton { id: root @@ -17,6 +17,7 @@ Singleton { readonly property string notifimagecache: `${imagecache}/notifs` readonly property string pictures: Quickshell.env("XDG_PICTURES_DIR") || `${home}/Pictures` readonly property string recsdir: Quickshell.env("ZSHELL_RECORDINGS_DIR") || `${videos}/Recordings` + readonly property string screenshots: Quickshell.env("ZSHELL_SCREENSHOTS_DIR") || `${home}/Pictures/Screenshots` readonly property string state: `${Quickshell.env("XDG_STATE_HOME") || `${home}/.local/state`}/zshell` readonly property string videos: Quickshell.env("XDG_VIDEOS_DIR") || `${home}/Videos` readonly property string wallsdir: Quickshell.env("ZSHELL_WALLPAPERS_DIR") || absolutePath(Config.general.wallpaperPath) diff --git a/Plugins/ZShell/CMakeLists.txt b/Plugins/ZShell/CMakeLists.txt index ce7cdd6..d260f80 100644 --- a/Plugins/ZShell/CMakeLists.txt +++ b/Plugins/ZShell/CMakeLists.txt @@ -78,3 +78,4 @@ add_subdirectory(Internal) add_subdirectory(Services) add_subdirectory(Components) add_subdirectory(Blobs) +add_subdirectory(Config) diff --git a/Plugins/ZShell/Config/CMakeLists.txt b/Plugins/ZShell/Config/CMakeLists.txt new file mode 100644 index 0000000..0e46ebf --- /dev/null +++ b/Plugins/ZShell/Config/CMakeLists.txt @@ -0,0 +1,25 @@ +qml_module(ZShell-config + URI ZShell.Config + SOURCES + confignode.hpp confignode.cpp + configobject.hpp configobject.cpp + configlist.hpp configlist.cpp + config.hpp config.cpp + tokens.hpp + appearance.hpp + background.hpp + bar.hpp + clipboard.hpp + colors.hpp + dashboard.hpp + dock.hpp + general.hpp + launcher.hpp + lock.hpp + notifs.hpp + osd.hpp + screenshot.hpp + services.hpp + sidebar.hpp + utilities.hpp +) diff --git a/Plugins/ZShell/Config/appearance.hpp b/Plugins/ZShell/Config/appearance.hpp new file mode 100644 index 0000000..b4b0e5a --- /dev/null +++ b/Plugins/ZShell/Config/appearance.hpp @@ -0,0 +1,83 @@ +#pragma once + +#include "configobject.hpp" +#include + +namespace ZShell::config { + +class Anim : public ConfigObject { + Q_OBJECT + QML_ANONYMOUS + + CFG_PROPERTY(int, mediaGifSpeedAdjustment, 300) + CFG_PROPERTY(qreal, sessionGifSpeed, 0.7) + + public: + explicit Anim(QObject* parent = nullptr) : ConfigObject(parent) {} +}; + +class Deform : public ConfigObject { + Q_OBJECT + QML_ANONYMOUS + + CFG_PROPERTY(qreal, scale, 1) + + public: + explicit Deform(QObject* parent = nullptr) : ConfigObject(parent) {} +}; + +class FontFamily : public ConfigObject { + Q_OBJECT + QML_ANONYMOUS + + CFG_PROPERTY(QString, clock, QStringLiteral("Rubik")) + CFG_PROPERTY(QString, material, QStringLiteral("Material Symbols Rounded")) + CFG_PROPERTY(QString, mono, QStringLiteral("CaskaydiaCove NF")) + CFG_PROPERTY(QString, sans, QStringLiteral("Segoe UI Variable Text")) + + public: + explicit FontFamily(QObject* parent = nullptr) : ConfigObject(parent) {} +}; + +class Font : public ConfigObject { + Q_OBJECT + QML_ANONYMOUS + + CONFIG_SUBOBJECT(FontFamily, family) + + public: + explicit Font(QObject* parent = nullptr) + : ConfigObject(parent), m_family(new FontFamily(this)) {} +}; + +class Transparency : public ConfigObject { + Q_OBJECT + QML_ANONYMOUS + + CFG_PROPERTY(qreal, base, 0.85) + CFG_PROPERTY(bool, enabled, false) + CFG_PROPERTY(qreal, layers, 0.4) + + public: + explicit Transparency(QObject* parent = nullptr) : ConfigObject(parent) {} +}; + +class Appearance : public ConfigObject { + Q_OBJECT + QML_ANONYMOUS + + CONFIG_SUBOBJECT(Anim, anim) + CONFIG_SUBOBJECT(Deform, deform) + CONFIG_SUBOBJECT(Font, font) + CONFIG_SUBOBJECT(Transparency, transparency) + + public: + explicit Appearance(QObject* parent = nullptr) + : ConfigObject(parent) + , m_anim(new Anim(this)) + , m_deform(new Deform(this)) + , m_font(new Font(this)) + , m_transparency(new Transparency(this)) {} +}; + +} // namespace ZShell::config diff --git a/Plugins/ZShell/Config/background.hpp b/Plugins/ZShell/Config/background.hpp new file mode 100644 index 0000000..98331f8 --- /dev/null +++ b/Plugins/ZShell/Config/background.hpp @@ -0,0 +1,18 @@ +#pragma once +#include "configobject.hpp" +#include + +namespace ZShell::config { + +class Background : public ConfigObject { + Q_OBJECT + QML_ANONYMOUS + + CFG_PROPERTY(bool, enabled, true) + CFG_PROPERTY(int, wallFadeDuration, 300) + + public: + explicit Background(QObject* parent = nullptr) : ConfigObject(parent) {} +}; + +} // namespace ZShell::config diff --git a/Plugins/ZShell/Config/bar.hpp b/Plugins/ZShell/Config/bar.hpp new file mode 100644 index 0000000..fdb1c6c --- /dev/null +++ b/Plugins/ZShell/Config/bar.hpp @@ -0,0 +1,94 @@ +#pragma once + +#include "configlist.hpp" +#include "configobject.hpp" +#include + +namespace ZShell::config { + +class BarEntry : public ListEntry { + Q_OBJECT + QML_ANONYMOUS + + public: + explicit BarEntry(QObject* parent = nullptr) : ListEntry(parent) {} +}; + +class Popouts : public ConfigObject { + Q_OBJECT + QML_ANONYMOUS + + CFG_PROPERTY(bool, statusIcons, true) + CFG_PROPERTY(bool, tray, true) + + public: + explicit Popouts(QObject* parent = nullptr) : ConfigObject(parent) {} +}; + +class Tray : public ConfigObject { + Q_OBJECT + QML_ANONYMOUS + + CFG_PROPERTY(bool, recolorIcons, false) + CFG_PROPERTY(bool, showOnHover, true) + CFG_PROPERTY(int, trayIconSize, 24) + CONFIG_LIST( + EntryList, + statusIcons, + { + LIST_ENTRY(audio, true), + LIST_ENTRY(microphone, true), + LIST_ENTRY(bluetooth, false), + LIST_ENTRY(network, false), + LIST_ENTRY(wifi, false), + LIST_ENTRY(power, true), + }) + + public: + explicit Tray(QObject* parent = nullptr) : ConfigObject(parent) {} +}; + +class Bar : public ConfigObject { + Q_OBJECT + QML_ANONYMOUS + + CFG_PROPERTY(bool, autoHide, false) + CFG_PROPERTY(int, border, 4) + CFG_PROPERTY(bool, fullscreenReveal, true) + CFG_PROPERTY(int, height, 24) + CFG_PROPERTY(bool, hideWhenNotif, true) + CONFIG_SUBOBJECT(Popouts, popouts) + CFG_PROPERTY(int, revealDelay, 100) + CFG_PROPERTY(int, rounding, 14) + CFG_PROPERTY(int, smoothing, 32) + CONFIG_SUBOBJECT(Tray, tray) + CONFIG_LIST( + EntryList, + entries, + { + LIST_ENTRY(workspaces, true), + LIST_ENTRY(audio, true), + LIST_ENTRY(media, true), + LIST_ENTRY(resources, true), + LIST_ENTRY(updates, true), + LIST_ENTRY(dash, false), + LIST_ENTRY(spacer, true), + LIST_ENTRY(activeWindow, true), + LIST_ENTRY(spacer, true), + LIST_ENTRY(hyprsunset, true), + LIST_ENTRY(tray, true), + LIST_ENTRY(statusIcons, true), + LIST_ENTRY(network, false), + LIST_ENTRY(upower, true), + LIST_ENTRY(clock, true), + LIST_ENTRY(notifBell, true), + }) + + public: + explicit Bar(QObject* parent = nullptr) + : ConfigObject(parent) + , m_popouts(new Popouts(this)) + , m_tray(new Tray(this)) {} +}; + +} // namespace ZShell::config diff --git a/Plugins/ZShell/Config/clipboard.hpp b/Plugins/ZShell/Config/clipboard.hpp new file mode 100644 index 0000000..b2c0708 --- /dev/null +++ b/Plugins/ZShell/Config/clipboard.hpp @@ -0,0 +1,33 @@ +#pragma once +#include "configobject.hpp" +#include + +namespace ZShell::config { + +class ClipboardSizes : public ConfigObject { + Q_OBJECT + QML_ANONYMOUS + + CFG_PROPERTY(int, itemHeight, 60) + CFG_PROPERTY(int, minPreviewWidth, 200) + CFG_PROPERTY(int, previewWidth, 800) + CFG_PROPERTY(int, width, 500) + + public: + explicit ClipboardSizes(QObject* parent = nullptr) : ConfigObject(parent) {} +}; + +class Clipboard : public ConfigObject { + Q_OBJECT + QML_ANONYMOUS + + CFG_PROPERTY(bool, enabled, true) + CFG_PROPERTY(int, maxEntriesShown, 10) + CONFIG_SUBOBJECT(ClipboardSizes, sizes) + + public: + explicit Clipboard(QObject* parent = nullptr) + : ConfigObject(parent), m_sizes(new ClipboardSizes(this)) {} +}; + +} // namespace ZShell::config diff --git a/Plugins/ZShell/Config/colors.hpp b/Plugins/ZShell/Config/colors.hpp new file mode 100644 index 0000000..0554df6 --- /dev/null +++ b/Plugins/ZShell/Config/colors.hpp @@ -0,0 +1,31 @@ +#pragma once +#include "configobject.hpp" +#include + +namespace ZShell::config { + +class Presets : public ConfigObject { + Q_OBJECT + QML_ANONYMOUS + + CFG_PROPERTY(QString, accent, QString()) + CFG_PROPERTY(QString, name, QStringLiteral("Catppuccin")) + CFG_PROPERTY(QString, variant, QStringLiteral("latte")) + + public: + explicit Presets(QObject* parent = nullptr) : ConfigObject(parent) {} +}; + +class Colors : public ConfigObject { + Q_OBJECT + QML_ANONYMOUS + + CONFIG_SUBOBJECT(Presets, presets) + CFG_PROPERTY(QString, schemeType, QStringLiteral("fidelity")) + + public: + explicit Colors(QObject* parent = nullptr) + : ConfigObject(parent), m_presets(new Presets(this)) {} +}; + +} // namespace ZShell::config diff --git a/Plugins/ZShell/Config/config.cpp b/Plugins/ZShell/Config/config.cpp new file mode 100644 index 0000000..c0fcc9d --- /dev/null +++ b/Plugins/ZShell/Config/config.cpp @@ -0,0 +1,257 @@ +#include "config.hpp" + +#include "appearance.hpp" +#include "background.hpp" +#include "bar.hpp" +#include "clipboard.hpp" +#include "colors.hpp" +#include "dashboard.hpp" +#include "dock.hpp" +#include "general.hpp" +#include "launcher.hpp" +#include "lock.hpp" +#include "notifs.hpp" +#include "osd.hpp" +#include "screenshot.hpp" +#include "services.hpp" +#include "sidebar.hpp" +#include "utilities.hpp" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace ZShell::config { + +Config::Config(QObject* parent) + : ConfigObject(parent) + , m_appearance(new Appearance(this)) + , m_background(new Background(this)) + , m_bar(new Bar(this)) + , m_clipboard(new Clipboard(this)) + , m_colors(new Colors(this)) + , m_dashboard(new Dashboard(this)) + , m_dock(new Dock(this)) + , m_general(new General(this)) + , m_launcher(new Launcher(this)) + , m_lock(new Lock(this)) + , m_notifs(new Notifs(this)) + , m_osd(new Osd(this)) + , m_screenshot(new Screenshot(this)) + , m_services(new Services(this)) + , m_sidebar(new Sidebar(this)) + , m_utilities(new Utilities(this)) { + connect(this, &ConfigObject::propertiesChanged, this, &Config::scheduleSave); + + m_saveTimer.setSingleShot(true); + m_saveTimer.setInterval(300); + connect(&m_saveTimer, &QTimer::timeout, this, &Config::flushAsync); + + m_reloadTimer.setSingleShot(true); + m_reloadTimer.setInterval(50); + connect(&m_reloadTimer, &QTimer::timeout, this, &Config::reloadAsync); + + connect( + &m_watcher, + &QFileSystemWatcher::directoryChanged, + this, + &Config::onWatcherEvent); + + connect( + &m_watcher, + &QFileSystemWatcher::fileChanged, + this, + &Config::onWatcherEvent); + + loadSync(); + updateWatch(); + + m_firstLoadDone = true; +} + +Config* Config::create(QQmlEngine*, QJSEngine*) { + return new Config(); +} + +QString Config::filePath() const { + const QString dir = + QStandardPaths::writableLocation(QStandardPaths::ConfigLocation) + + QStringLiteral("/zshell"); + QDir().mkpath(dir); + return dir + QStringLiteral("/config.json"); +} + +void Config::loadSync() { + m_loading = true; + QFile f(filePath()); + if (f.open(QIODevice::ReadOnly)) { + const auto doc = QJsonDocument::fromJson(f.readAll()); + if (doc.isObject()) loadFromJson(QJsonValue(doc.object())); + } else { + qInfo() << "Config: no existing config at" << filePath() + << "- using defaults"; + } + m_loading = false; +} + +void Config::updateWatch() { + const QFileInfo info(filePath()); + + const QString dir = info.absolutePath(); + const QString file = info.absoluteFilePath(); + + if (!m_watcher.directories().contains(dir)) m_watcher.addPath(dir); + if (info.exists() && !m_watcher.files().contains(file)) + m_watcher.addPath(file); +} + +void Config::onWatcherEvent(const QString&) { + updateWatch(); + + const QFileInfo info(filePath()); + if (!info.exists()) return; + + QFile file(info.absoluteFilePath()); + if (!file.open(QIODevice::ReadOnly)) return; + + const QByteArray hash = + QCryptographicHash::hash(file.readAll(), QCryptographicHash::Sha256); + + { + QMutexLocker lock(&m_writeMutex); + + if (hash == m_lastWriteHash) return; + } + + m_reloadPending = true; + + if (!m_loading) m_reloadTimer.start(); +} + +void Config::loadAsync() { + m_loading = true; + + auto future = QtConcurrent::run([this]() { + QFile f(filePath()); + + if (f.open(QIODevice::ReadOnly)) { + const auto doc = QJsonDocument::fromJson(f.readAll()); + + if (doc.isObject()) { + QMetaObject::invokeMethod( + this, + [this, doc]() { + loadFromJson(QJsonValue(doc.object())); + m_loading = false; + + if (m_reloadPending) m_reloadTimer.start(); + }, + Qt::QueuedConnection); + } else { + QMetaObject::invokeMethod( + this, + [this]() { + m_loading = false; + + if (m_reloadPending) m_reloadTimer.start(); + }, + Qt::QueuedConnection); + } + } else { + qInfo() << "Config: failed to reload from" << filePath() + << "- using in-memory values"; + + QMetaObject::invokeMethod( + this, + [this]() { + m_loading = false; + + if (m_reloadPending) m_reloadTimer.start(); + }, + Qt::QueuedConnection); + } + }); + + m_loadFuture = future; +} + +void Config::load() { + if (!m_firstLoadDone) { + loadSync(); + } else { + loadAsync(); + } +} + +void Config::reloadAsync() { + if (m_loading) return; + + m_reloadPending = false; + loadAsync(); +} + +void Config::scheduleSave() { + if (m_loading) return; + m_saveTimer.start(); +} + +void Config::flushAsync() { + const QByteArray data = + QJsonDocument(toJson().toObject()).toJson(QJsonDocument::Indented); + + const QByteArray hash = + QCryptographicHash::hash(data, QCryptographicHash::Sha256); + + QThreadPool::globalInstance()->start([this, data, hash]() { + const bool success = writeAtomically(data); + + QMetaObject::invokeMethod( + this, + [this, success, hash]() { + if (!success) return; + + QMutexLocker lock(&m_writeMutex); + m_lastWriteHash = hash; + }, + Qt::QueuedConnection); + }); +} + +void Config::saveNow() { + m_saveTimer.stop(); + flushAsync(); +} + +bool Config::writeAtomically(const QByteArray& data) { + QSaveFile f(filePath()); + + if (!f.open(QIODevice::WriteOnly)) { + qWarning() << "Config: failed to open for atomic write:" + << f.errorString(); + return false; + } + + if (f.write(data) != data.size()) { + qWarning() << "Config: failed to write:" << f.errorString(); + return false; + } + + if (!f.commit()) { + qWarning() << "Config: commit failed:" << f.errorString(); + return false; + } + + return true; +} + +}; // namespace ZShell::config diff --git a/Plugins/ZShell/Config/config.hpp b/Plugins/ZShell/Config/config.hpp new file mode 100644 index 0000000..1a201f3 --- /dev/null +++ b/Plugins/ZShell/Config/config.hpp @@ -0,0 +1,107 @@ +#pragma once + +#include "configobject.hpp" + +#include +#include +#include +#include +#include +#include +#include + +class QQmlEngine; +class QJSEngine; + +namespace ZShell::config { + +class Appearance; +class Background; +class Bar; +class Clipboard; +class Colors; +class Dashboard; +class Dock; +class General; +class Launcher; +class Lock; +class Notifs; +class Osd; +class Screenshot; +class Services; +class Sidebar; +class Utilities; + +class Config : public ConfigObject { + Q_OBJECT + QML_ELEMENT + QML_SINGLETON + + Q_MOC_INCLUDE("appearance.hpp") + Q_MOC_INCLUDE("background.hpp") + Q_MOC_INCLUDE("bar.hpp") + Q_MOC_INCLUDE("clipboard.hpp") + Q_MOC_INCLUDE("colors.hpp") + Q_MOC_INCLUDE("dashboard.hpp") + Q_MOC_INCLUDE("dock.hpp") + Q_MOC_INCLUDE("general.hpp") + Q_MOC_INCLUDE("launcher.hpp") + Q_MOC_INCLUDE("lock.hpp") + Q_MOC_INCLUDE("notifs.hpp") + Q_MOC_INCLUDE("osd.hpp") + Q_MOC_INCLUDE("screenshot.hpp") + Q_MOC_INCLUDE("services.hpp") + Q_MOC_INCLUDE("sidebar.hpp") + Q_MOC_INCLUDE("utilities.hpp") + + CONFIG_SUBOBJECT(Appearance, appearance) + CONFIG_SUBOBJECT(Background, background) + CONFIG_SUBOBJECT(Bar, bar) + CONFIG_SUBOBJECT(Clipboard, clipboard) + CONFIG_SUBOBJECT(Colors, colors) + CONFIG_SUBOBJECT(Dashboard, dashboard) + CONFIG_SUBOBJECT(Dock, dock) + CONFIG_SUBOBJECT(General, general) + CONFIG_SUBOBJECT(Launcher, launcher) + CONFIG_SUBOBJECT(Lock, lock) + CONFIG_SUBOBJECT(Notifs, notifs) + CONFIG_SUBOBJECT(Osd, osd) + CONFIG_SUBOBJECT(Screenshot, screenshot) + CONFIG_SUBOBJECT(Services, services) + CONFIG_SUBOBJECT(Sidebar, sidebar) + CONFIG_SUBOBJECT(Utilities, utilities) + + public: + explicit Config(QObject* parent = nullptr); + static Config* create(QQmlEngine*, QJSEngine*); + + Q_INVOKABLE void load(); + Q_INVOKABLE void saveNow(); + Q_INVOKABLE void reloadAsync(); + + private Q_SLOTS: + void scheduleSave(); + void flushAsync(); + void onWatcherEvent(const QString& path); + + private: + QString filePath() const; + bool writeAtomically(const QByteArray& data); + void updateWatch(); + void loadSync(); + void loadAsync(); + + QTimer m_saveTimer; + QTimer m_reloadTimer; + QFileSystemWatcher m_watcher; + + QMutex m_writeMutex; + QByteArray m_lastWriteHash; + + bool m_reloadPending = false; + bool m_loading = false; + bool m_firstLoadDone = false; + QFuture m_loadFuture; +}; + +} // namespace ZShell::config diff --git a/Plugins/ZShell/Config/configlist.cpp b/Plugins/ZShell/Config/configlist.cpp new file mode 100644 index 0000000..ef60bbd --- /dev/null +++ b/Plugins/ZShell/Config/configlist.cpp @@ -0,0 +1,305 @@ +#include "configlist.hpp" + +#include +#include +#include +#include + +namespace ZShell::config { + +ConfigList::ConfigList(QObject* parent, const QVariantList& defaults) + : ConfigNode(parent), m_defaults(QJsonArray::fromVariantList(defaults)) {} + +int ConfigList::count() const { + return static_cast(m_items.size()); +} + +QVariantList ConfigList::values() const { + QVariantList vals; + vals.reserve(m_items.size()); + for (auto* const item : m_items) + vals.append(QVariant::fromValue(item)); + return vals; +} + +ConfigObject* ConfigList::itemAt(int index) const { + if (index < 0 || index >= m_items.size()) return nullptr; + + return m_items.at(index); +} + +const QList& ConfigList::items() const { + return m_items; +} + +void ConfigList::remove(int index) { + if (index < 0 || index >= m_items.size()) { + qCWarning(lcConfig) + << metaObject()->className() << "cannot remove index" << index + << "of" << count(); + return; + } + + destroyItem(m_items.takeAt(index)); + + m_loaded = true; + emit countChanged(); + emit valuesChanged(); + notifyChanged(); +} + +void ConfigList::move(int from, int to) { + if (from < 0 || from >= m_items.size() || to < 0 || to >= m_items.size()) { + qCWarning(lcConfig) << metaObject()->className() << "cannot move" + << from << "to" << to << "of" << count(); + return; + } + + if (from == to) return; + + m_items.move(from, to); + + m_loaded = true; + emit valuesChanged(); + notifyChanged(); +} + +void ConfigList::clear() { + if (m_items.isEmpty()) return; + + destroyItems(); + + m_loaded = true; + emit countChanged(); + emit valuesChanged(); + notifyChanged(); +} + +void ConfigList::loadFromJson(const QJsonValue& json) { + if (!json.isArray()) { + qCWarning( + lcConfig, + "Option '%s' must be a list, ignoring", + qUtf8Printable(propertyPath())); + m_rejectedJson = json; + return; + } + + m_rejectedJson = QJsonValue::Undefined; + populate(json.toArray()); + m_loaded = true; +} + +QJsonValue ConfigList::toJson() const { + if (m_loaded) return elementsToJson(); + + return m_rejectedJson; +} + +void ConfigList::clearLoadedKeys() { + m_loaded = false; + m_rejectedJson = QJsonValue::Undefined; +} + +QStringList ConfigList::unknownKeys() const { + QStringList keys; + + for (int i = 0; i < m_items.size(); ++i) { + const auto childKeys = m_items.at(i)->unknownKeys(); + for (const auto& childKey : childKeys) + keys.append(joinPath(QString("[%1]").arg(i), childKey)); + } + + return keys; +} + +void ConfigList::resyncFromGlobal() { + syncValuesFromGlobal(); +} + +ConfigObject* ConfigList::insertItem(const QVariantMap& props, int index) { + const auto pos = index < 0 || index > m_items.size() ? m_items.size() + : index; + + appendItem(QJsonObject::fromVariantMap(props)); + m_items.move(m_items.size() - 1, pos); + + auto* const item = m_items.at(pos); + const auto unknown = item->unknownKeys(); + for (const auto& key : unknown) + qCWarning(lcConfig) << "Unknown option" << key << "for" + << item->metaObject()->className(); + + m_loaded = true; + emit countChanged(); + emit valuesChanged(); + notifyChanged(); + + return item; +} + +QJsonArray ConfigList::elementsToJson() const { + QJsonArray arr; + + for (auto* const item : m_items) + arr.append(item->toJson().toObject()); + + return arr; +} + +void ConfigList::resetToDefaults() { + loadFromJsonQuietly(m_defaults); + m_loaded = false; +} + +void ConfigList::syncValuesFromGlobal() { + if (m_loaded) return; + + if (auto* const global = qobject_cast(m_global)) + populate(global->elementsToJson()); +} + +void ConfigList::onGlobalPropertiesChanged(const QMap&) { + syncValuesFromGlobal(); +} + +QString ConfigList::childPath(const ConfigNode* child) const { + for (int i = 0; i < m_items.size(); ++i) + if (m_items.at(i) == child) return QString("[%1]").arg(i); + + return {}; +} + +void ConfigList::populate(const QJsonArray& arr) { + const auto current = elementsToJson(); + if (current == arr) return; + + const auto old = m_items; + QList reused(old.size(), false); + + m_items.clear(); + m_items.reserve(arr.size()); + + for (int i = 0; i < arr.size(); ++i) { + auto match = + i < old.size() && !reused.at(i) && current.at(i) == arr.at(i) ? i + : -1; + + for (int j = 0; match < 0 && j < old.size(); ++j) + if (!reused.at(j) && current.at(j) == arr.at(i)) match = j; + + auto update = false; + for (int j = 0; match < 0 && j < old.size(); ++j) { + if (!reused.at(j) && + sameElement(old.at(j), current.at(j), arr.at(i))) { + match = j; + update = true; + } + } + + if (match < 0) { + appendItem(arr.at(i)); + continue; + } + + reused[match] = true; + + if (update) old.at(match)->loadFromJsonQuietly(arr.at(i)); + + m_items.append(old.at(match)); + } + + for (int i = 0; i < old.size(); ++i) + if (!reused.at(i)) destroyItem(old.at(i)); + + if (m_items.size() != old.size()) emit countChanged(); + + emit valuesChanged(); + + notifyChanged(); +} + +bool ConfigList::sameElement( + const ConfigObject* item, + const QJsonValue& current, + const QJsonValue& json) { + const auto keys = item->identityKeys(); + if (keys.isEmpty()) return false; + + const auto currentObj = current.toObject(); + const auto newObj = json.toObject(); + + if (currentObj.keys() != newObj.keys()) return false; + + for (const auto& key : keys) + if (!newObj.contains(key) || currentObj.value(key) != newObj.value(key)) + return false; + + return true; +} + +void ConfigList::appendItem(const QJsonValue& json) { + auto* const item = createItem(); + QQmlEngine::setObjectOwnership(item, QQmlEngine::CppOwnership); + + if (m_items.isEmpty()) rejectGlobalOnlyElement(item); + + item->loadFromJsonQuietly(json); + + connectItem(item); + + m_items.append(item); +} + +void ConfigList::rejectGlobalOnlyElement(const ConfigObject* item) const { + const auto keys = item->globalOnlyKeys(); + if (keys.isEmpty()) return; + + qCCritical( + lcConfig, + "%s declares global-only options (%s) which do not work inside a list, " + "use CONFIG_GLOBAL_LIST on %s instead", + item->metaObject()->className(), + qUtf8Printable(keys.join(", ")), + metaObject()->className()); +} + +void ConfigList::connectItem(ConfigNode* node) { + connect( + node, &ConfigNode::propertiesChanged, this, &ConfigList::onItemChanged); + + const auto children = node->childNodes(); + for (auto* const child : children) + connectItem(child); +} + +void ConfigList::disconnectItem(ConfigNode* node) { + node->disconnect(this); + + const auto children = node->childNodes(); + for (auto* const child : children) + disconnectItem(child); +} + +void ConfigList::destroyItems() { + for (auto* const item : std::as_const(m_items)) + destroyItem(item); + + m_items.clear(); +} + +void ConfigList::destroyItem(ConfigObject* item) { + disconnectItem(item); + item->deleteLater(); +} + +void ConfigList::onItemChanged() { + m_loaded = true; + notifyChanged(); +} + +void ConfigList::notifyChanged() { + notifyPropertyChanged("values", count()); +} + +} // namespace ZShell::config diff --git a/Plugins/ZShell/Config/configlist.hpp b/Plugins/ZShell/Config/configlist.hpp new file mode 100644 index 0000000..3ee24ba --- /dev/null +++ b/Plugins/ZShell/Config/configlist.hpp @@ -0,0 +1,141 @@ +#pragma once + +#include "configobject.hpp" + +#include +#include +#include +#include + +namespace ZShell::config { + +class ConfigList : public ConfigNode { + Q_OBJECT + QML_ANONYMOUS + + Q_PROPERTY(int count READ count NOTIFY countChanged) + Q_PROPERTY(QVariantList values READ values NOTIFY valuesChanged) + + public: + explicit ConfigList( + QObject* parent = nullptr, const QVariantList& defaults = {}); + + [[nodiscard]] int count() const; + [[nodiscard]] QVariantList values() const; + [[nodiscard]] ConfigObject* itemAt(int index) const; + [[nodiscard]] const QList& items() const; + + Q_INVOKABLE void remove(int index); + Q_INVOKABLE void move(int from, int to); + Q_INVOKABLE void clear(); + + void loadFromJson(const QJsonValue& json) override; + [[nodiscard]] QJsonValue toJson() const override; + void clearLoadedKeys() override; + [[nodiscard]] QStringList unknownKeys() const override; + void resyncFromGlobal() override; + + signals: + void countChanged(); + void valuesChanged(); + + protected: + virtual ConfigObject* createItem() = 0; + + void resetToDefaults(); + + ConfigObject* insertItem(const QVariantMap& props, int index = -1); + + [[nodiscard]] QJsonArray elementsToJson() const; + + void syncValuesFromGlobal() override; + void onGlobalPropertiesChanged( + const QMap& changed) override; + [[nodiscard]] QString childPath(const ConfigNode* child) const override; + + private: + void populate(const QJsonArray& arr); + static bool sameElement( + const ConfigObject* item, + const QJsonValue& current, + const QJsonValue& json); + void appendItem(const QJsonValue& json); + void destroyItems(); + void destroyItem(ConfigObject* item); + void rejectGlobalOnlyElement(const ConfigObject* item) const; + void connectItem(ConfigNode* node); + void disconnectItem(ConfigNode* node); + void onItemChanged(); + void notifyChanged(); + + QJsonArray m_defaults; + QList m_items; + bool m_loaded = false; + QJsonValue m_rejectedJson = QJsonValue::Undefined; +}; + +} // namespace ZShell::config + +#define CONFIG_LIST_TYPE(Element, Name) \ + class Name : public ZShell::config::ConfigList { \ + Q_OBJECT \ + QML_ANONYMOUS \ + \ + public: \ + explicit Name( \ + QObject* parent = nullptr, const QVariantList& defaults = {}) \ + : ZShell::config::ConfigList(parent, defaults) { \ + resetToDefaults(); \ + } \ + \ + Q_INVOKABLE ZShell::config::Element* at(int index) const { \ + return static_cast(itemAt(index)); \ + } \ + Q_INVOKABLE ZShell::config::Element* insert( \ + const QVariantMap& props, int index = -1) { \ + return static_cast( \ + insertItem(props, index)); \ + } \ + \ + protected: \ + [[nodiscard]] ZShell::config::ConfigObject* createItem() override { \ + return new ZShell::config::Element(this); \ + } \ + }; + + +#define CONFIG_LIST(Type, name, ...) \ + Q_PROPERTY(ZShell::config::Type* name READ name CONSTANT) \ + \ + public: \ + [[nodiscard]] Type* name() const { \ + return m_##name; \ + } \ + \ + private: \ + Type* m_##name = new Type(this __VA_OPT__(, __VA_ARGS__)); + + +namespace ZShell::config { + +class ListEntry : public ConfigObject { + Q_OBJECT + QML_ANONYMOUS + + CFG_PROPERTY(QString, id) + CFG_PROPERTY(bool, enabled, true) + + public: + explicit ListEntry(QObject* parent = nullptr) : ConfigObject(parent) {} + + [[nodiscard]] QStringList identityKeys() const override { + return {QStringLiteral("id")}; + } +}; + +CONFIG_LIST_TYPE(ListEntry, EntryList) + +} // namespace ZShell::config + +#define LIST_ENTRY(id, enabled) \ + vmap({{"id", QString::fromUtf8(#id)}, {"enabled", enabled}}) diff --git a/Plugins/ZShell/Config/confignode.cpp b/Plugins/ZShell/Config/confignode.cpp new file mode 100644 index 0000000..b120c6e --- /dev/null +++ b/Plugins/ZShell/Config/confignode.cpp @@ -0,0 +1,89 @@ +#include "confignode.hpp" + +#include +#include +#include +#include + +namespace ZShell::config { + +Q_LOGGING_CATEGORY(lcConfig, "zshell.config") + +ConfigNode::ConfigNode(QObject* parent) : QObject(parent) { + m_batchTimer = new QTimer(this); + m_batchTimer->setSingleShot(true); + m_batchTimer->setInterval(0); + connect( + m_batchTimer, &QTimer::timeout, this, &ConfigNode::emitBatchedChanges); +} + +void ConfigNode::loadFromJsonQuietly(const QJsonValue& json) { + setNotifySuppressed(true); + loadFromJson(json); + setNotifySuppressed(false); +} + +void ConfigNode::setNotifySuppressed(bool suppressed) { + m_suppressNotify = suppressed; + + const auto children = childNodes(); + for (auto* const child : children) + child->setNotifySuppressed(suppressed); +} + +QList ConfigNode::childNodes() const { + return {}; +} + +void ConfigNode::syncFromGlobal(ConfigNode* global) { + m_global = global; + resyncFromGlobal(); +} + +bool ConfigNode::isOverlay() const { + return m_global != nullptr && this != m_global; +} + +QString ConfigNode::propertyPath(const QString& name) const { + if (name.isEmpty()) return objectName(); + + QObject* const parentObj = parent(); + if (parentObj) { + if (auto* parentNode = qobject_cast(parentObj)) { + const auto childName = parentNode->childPath(this); + if (!childName.isEmpty()) { + return joinPath(parentNode->propertyPath(childName), name); + } + } + } + return name; +} + +int ConfigNode::basePropertyOffset() { + return QObject::staticMetaObject.propertyCount(); +} + +void ConfigNode::notifyPropertyChanged( + const QString& name, const QVariant& value) { + if (m_suppressNotify) return; + + m_pendingChanges[name] = value; + if (m_batchTimer && !m_batchTimer->isActive()) m_batchTimer->start(); +} + +QString ConfigNode::joinPath(const QString& parent, const QString& child) { + // List elements are addressed as parent[i], everything else as parent.child + if (child.startsWith(QLatin1Char('['))) return parent + child; + + return parent + QLatin1Char('.') + child; +} + +void ConfigNode::emitBatchedChanges() { + if (m_pendingChanges.isEmpty()) return; + + QMap changes = m_pendingChanges; + m_pendingChanges.clear(); + emit propertiesChanged(changes); +} + +} // namespace ZShell::config diff --git a/Plugins/ZShell/Config/confignode.hpp b/Plugins/ZShell/Config/confignode.hpp new file mode 100644 index 0000000..4316f34 --- /dev/null +++ b/Plugins/ZShell/Config/confignode.hpp @@ -0,0 +1,63 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +#include + +namespace ZShell::config { + +Q_DECLARE_LOGGING_CATEGORY(lcConfig) + +class ConfigNode : public QObject { + Q_OBJECT + + public: + explicit ConfigNode(QObject* parent = nullptr); + + virtual void loadFromJson(const QJsonValue& json) = 0; + void loadFromJsonQuietly(const QJsonValue& json); + [[nodiscard]] virtual QJsonValue toJson() const = 0; + + virtual void clearLoadedKeys() = 0; + [[nodiscard]] virtual QStringList unknownKeys() const = 0; + [[nodiscard]] virtual QList childNodes() const; + + void syncFromGlobal(ConfigNode* global); + virtual void resyncFromGlobal() = 0; + + [[nodiscard]] bool isOverlay() const; + [[nodiscard]] QString propertyPath(const QString& name = {}) const; + + [[nodiscard]] static int basePropertyOffset(); + + signals: + void propertiesChanged(const QMap& changed); + + protected: + virtual void syncValuesFromGlobal() = 0; + virtual void onGlobalPropertiesChanged( + const QMap& changed) = 0; + + [[nodiscard]] virtual QString childPath(const ConfigNode* child) const = 0; + + void notifyPropertyChanged(const QString& name, const QVariant& value); + + [[nodiscard]] static QString joinPath( + const QString& parent, const QString& child); + + ConfigNode* m_global = nullptr; + + private: + void setNotifySuppressed(bool suppressed); + void emitBatchedChanges(); + + QMap m_pendingChanges; + QTimer* m_batchTimer = nullptr; + bool m_suppressNotify = false; +}; + +} // namespace ZShell::config diff --git a/Plugins/ZShell/Config/configobject.cpp b/Plugins/ZShell/Config/configobject.cpp new file mode 100644 index 0000000..4fb0056 --- /dev/null +++ b/Plugins/ZShell/Config/configobject.cpp @@ -0,0 +1,270 @@ +#include "configobject.hpp" + +#include +#include +#include +#include + +namespace ZShell::config { + +ConfigObject::ConfigObject(QObject* parent) : ConfigNode(parent) {} + +void ConfigObject::loadFromJson(const QJsonValue& json) { + const auto obj = json.toObject(); + const auto* meta = metaObject(); + + QSet known; + + for (int i = basePropertyOffset(); i < meta->propertyCount(); ++i) { + auto prop = meta->property(i); + const auto key = QString::fromUtf8(prop.name()); + + known.insert(key); + + if (!obj.contains(key)) continue; + + const auto jsonVal = obj.value(key); + + if (prop.metaType().flags().testFlag(QMetaType::PointerToQObject)) { + if (auto* const node = prop.read(this).value()) { + node->loadFromJson(jsonVal); + continue; + } + } + + if (!prop.isWritable()) continue; + + if (prop.metaType().id() == QMetaType::QStringList) { + QStringList list; + const auto jsonArr = jsonVal.toArray(); + for (const auto& v : jsonArr) + list.append(v.toString()); + prop.write(this, QVariant::fromValue(list)); + m_loadedKeys.insert(key); + continue; + } + + if (prop.metaType().id() == QMetaType::QVariantList) { + prop.write(this, jsonVal.toVariant()); + m_loadedKeys.insert(key); + continue; + } + + prop.write(this, jsonVal.toVariant()); + m_loadedKeys.insert(key); + } + + m_extras = {}; + for (auto it = obj.begin(); it != obj.end(); ++it) { + if (!known.contains(it.key())) { + m_extras.insert(it.key(), it.value()); + } + } +} + +QJsonValue ConfigObject::toJson() const { + QJsonObject obj; + const auto* meta = metaObject(); + + for (int i = basePropertyOffset(); i < meta->propertyCount(); ++i) { + const auto prop = meta->property(i); + + if (!prop.isReadable()) continue; + + const auto key = QString::fromUtf8(prop.name()); + + const auto value = prop.read(this); + + if (prop.metaType().flags().testFlag(QMetaType::PointerToQObject)) { + if (auto* const node = value.value()) { + const auto childJson = node->toJson(); + if (!childJson.isUndefined()) obj.insert(key, childJson); + continue; + } + } + + if (!m_loadedKeys.contains(key)) continue; + + if (!prop.isWritable()) continue; + + if (prop.metaType().id() == QMetaType::QStringList) { + QJsonArray arr; + const auto strList = value.toStringList(); + for (const auto& s : strList) + arr.append(s); + obj.insert(key, arr); + continue; + } + + if (prop.metaType().id() == QMetaType::QVariantList) { + obj.insert(key, QJsonArray::fromVariantList(value.toList())); + continue; + } + + obj.insert(key, QJsonValue::fromVariant(value)); + } + + for (auto it = m_extras.begin(); it != m_extras.end(); ++it) + obj.insert(it.key(), it.value()); + + if (obj.isEmpty()) return QJsonValue::Undefined; + + return obj; +} + +void ConfigObject::clearLoadedKeys() { + m_loadedKeys.clear(); + m_extras = {}; + + const auto* meta = metaObject(); + for (int i = basePropertyOffset(); i < meta->propertyCount(); ++i) { + auto prop = meta->property(i); + if (auto* const node = prop.read(this).value()) + node->clearLoadedKeys(); + } +} + +QStringList ConfigObject::identityKeys() const { + return {}; +} + +QStringList ConfigObject::unknownKeys() const { + auto keys = m_extras.keys(); + + const auto* meta = metaObject(); + for (int i = basePropertyOffset(); i < meta->propertyCount(); ++i) { + const auto prop = meta->property(i); + auto* const node = prop.read(this).value(); + if (!node) continue; + + const auto childKeys = node->unknownKeys(); + for (const auto& childKey : childKeys) + keys.append(joinPath(QString::fromUtf8(prop.name()), childKey)); + } + + return keys; +} + +QList ConfigObject::childNodes() const { + QList nodes; + + const auto* meta = metaObject(); + for (int i = basePropertyOffset(); i < meta->propertyCount(); ++i) { + const auto prop = meta->property(i); + + if (auto* const node = prop.read(this).value()) + nodes.append(node); + } + + return nodes; +} + +void ConfigObject::syncValuesFromGlobal() { + const auto* meta = metaObject(); + + for (int i = basePropertyOffset(); i < meta->propertyCount(); ++i) { + auto prop = meta->property(i); + const auto key = QString::fromUtf8(prop.name()); + + if (auto* const node = prop.read(this).value()) { + if (auto* const globalNode = + prop.read(m_global).value()) + node->syncFromGlobal(globalNode); + continue; + } + + if (!prop.isWritable()) continue; + + if (!m_loadedKeys.contains(key)) { + auto val = prop.read(m_global); + prop.write(this, val); + m_loadedKeys.remove(key); + } + } +} + +void ConfigObject::resyncFromGlobal() { + if (!m_global) return; + + const auto* meta = metaObject(); + for (int i = basePropertyOffset(); i < meta->propertyCount(); ++i) { + auto prop = meta->property(i); + const auto key = QString::fromUtf8(prop.name()); + + if (auto* const node = prop.read(this).value()) { + node->resyncFromGlobal(); + continue; + } + + if (!prop.isWritable()) continue; + + if (!m_loadedKeys.contains(key)) { + prop.write(this, prop.read(m_global)); + m_loadedKeys.remove(key); + } + } +} + +bool ConfigObject::isPropertyLoaded(const QString& name) const { + return m_loadedKeys.contains(name); +} + +bool ConfigObject::isGlobalOnly(const QString& name) const { + return m_globalOnlyKeys.contains(name); +} + +QStringList ConfigObject::globalOnlyKeys() const { + return {m_globalOnlyKeys.begin(), m_globalOnlyKeys.end()}; +} + +void ConfigObject::resetOption(const QString& name) { + m_loadedKeys.remove(name); + + const int idx = metaObject()->indexOfProperty(name.toUtf8().constData()); + if (idx < 0) return; + + const auto prop = metaObject()->property(idx); + + if (auto* const node = prop.read(this).value()) { + node->clearLoadedKeys(); + node->resyncFromGlobal(); + return; + } + + if (m_global && prop.isWritable()) prop.write(this, prop.read(m_global)); +} + +void ConfigObject::onGlobalPropertiesChanged( + const QMap& changed) { + for (auto it = changed.begin(); it != changed.end(); ++it) { + if (m_loadedKeys.contains(it.key()) || isGlobalOnly(it.key())) continue; + + int idx = metaObject()->indexOfProperty(it.key().toUtf8().constData()); + if (idx >= 0) { + metaObject()->property(idx).write(this, it.value()); + m_loadedKeys.remove(it.key()); + } + } +} + +QString ConfigObject::childPath(const ConfigNode* child) const { + const auto* meta = metaObject(); + for (int i = basePropertyOffset(); i < meta->propertyCount(); ++i) { + const auto prop = meta->property(i); + + if (prop.read(this).value() == child) + return QString::fromUtf8(prop.name()); + } + + return {}; +} + +void ConfigObject::markPropertyLoaded(const QString& name) { + m_loadedKeys.insert(name); +} + +void ConfigObject::markGlobalOnly(const QString& name) { + m_globalOnlyKeys.insert(name); +} + +} // namespace ZShell::config diff --git a/Plugins/ZShell/Config/configobject.hpp b/Plugins/ZShell/Config/configobject.hpp new file mode 100644 index 0000000..4814e6f --- /dev/null +++ b/Plugins/ZShell/Config/configobject.hpp @@ -0,0 +1,100 @@ +#pragma once + +#include "confignode.hpp" + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace ZShell::config { + +inline QVariantMap vmap( + std::initializer_list> entries) { + QVariantMap map; + for (const auto& [key, value] : entries) + map.insert(key, value); + return map; +} + +#define CFG_PROPERTY(Type, name, ...) \ + Q_PROPERTY(Type name READ name WRITE set_##name NOTIFY name##Changed) \ + public: \ + [[nodiscard]] Type name() const { \ + return m_##name; \ + } \ + void set_##name(const Type& value) { \ + if (ConfigObject::updateMember(m_##name, value)) { \ + markPropertyLoaded(QStringLiteral(#name)); \ + Q_EMIT name##Changed(); \ + notifyPropertyChanged( \ + QStringLiteral(#name), QVariant::fromValue(m_##name)); \ + } \ + } \ + Q_SIGNAL void name##Changed(); \ + \ + private: \ + Type m_##name __VA_OPT__(= __VA_ARGS__); + +#define CONFIG_SUBOBJECT(Type, name) \ + Q_PROPERTY(ZShell::config::Type* name READ name CONSTANT) \ + \ + public: \ + [[nodiscard]] Type* name() const { \ + return m_##name; \ + } \ + \ + private: \ + Type* m_##name = nullptr; + +class ConfigObject : public ConfigNode { + Q_OBJECT + + public: + explicit ConfigObject(QObject* parent = nullptr); + + void loadFromJson(const QJsonValue& json) override; + [[nodiscard]] QJsonValue toJson() const override; + void clearLoadedKeys() override; + [[nodiscard]] QStringList unknownKeys() const override; + [[nodiscard]] QList childNodes() const override; + void resyncFromGlobal() override; + + [[nodiscard]] virtual QStringList identityKeys() const; + + [[nodiscard]] bool isPropertyLoaded(const QString& name) const; + [[nodiscard]] bool isGlobalOnly(const QString& name) const; + [[nodiscard]] QStringList globalOnlyKeys() const; + + Q_INVOKABLE void resetOption(const QString& name); + + template static bool updateMember(T& member, const T& value) { + if constexpr (std::is_floating_point_v) { + if (qFuzzyCompare(member + 1.0, value + 1.0)) return false; + } else { + if (member == value) return false; + } + member = value; + return true; + } + + protected: + void syncValuesFromGlobal() override; + void onGlobalPropertiesChanged( + const QMap& changed) override; + [[nodiscard]] QString childPath(const ConfigNode* child) const override; + + void markPropertyLoaded(const QString& name); + void markGlobalOnly(const QString& name); + + private: + QSet m_loadedKeys; + QSet m_globalOnlyKeys; + QJsonObject m_extras; +}; + +} // namespace ZShell::config diff --git a/Plugins/ZShell/Config/dashboard.hpp b/Plugins/ZShell/Config/dashboard.hpp new file mode 100644 index 0000000..97471b8 --- /dev/null +++ b/Plugins/ZShell/Config/dashboard.hpp @@ -0,0 +1,63 @@ +#pragma once +#include "configobject.hpp" +#include + +namespace ZShell::config { + +class Performance : public ConfigObject { + Q_OBJECT + QML_ANONYMOUS + + CFG_PROPERTY(bool, enabled, true) + CFG_PROPERTY(bool, showBattery, false) + CFG_PROPERTY(bool, showCpu, true) + CFG_PROPERTY(bool, showGpu, true) + CFG_PROPERTY(bool, showMemory, true) + CFG_PROPERTY(bool, showNetwork, true) + CFG_PROPERTY(bool, showStorage, true) + CFG_PROPERTY(bool, showVram, true) + + public: + explicit Performance(QObject* parent = nullptr) : ConfigObject(parent) {} +}; + +class DashboardSizes : public ConfigObject { + Q_OBJECT + QML_ANONYMOUS + + CFG_PROPERTY(int, dateTimeWidth, 110) + CFG_PROPERTY(int, infoIconSize, 25) + CFG_PROPERTY(int, infoWidth, 200) + CFG_PROPERTY(int, mediaCoverArtSize, 150) + CFG_PROPERTY(int, mediaProgressSweep, 180) + CFG_PROPERTY(int, mediaProgressThickness, 8) + CFG_PROPERTY(int, mediaVisualizerSize, 200) + CFG_PROPERTY(int, mediaWidth, 200) + CFG_PROPERTY(int, resourceProgessThickness, 10) + CFG_PROPERTY(int, resourceSize, 200) + CFG_PROPERTY(int, tabIndicatorHeight, 3) + CFG_PROPERTY(int, tabIndicatorSpacing, 5) + CFG_PROPERTY(int, weatherWidth, 250) + + public: + explicit DashboardSizes(QObject* parent = nullptr) : ConfigObject(parent) {} +}; + +class Dashboard : public ConfigObject { + Q_OBJECT + QML_ANONYMOUS + + CFG_PROPERTY(bool, enabled, true) + CFG_PROPERTY(int, mediaUpdateInterval, 2000) + CONFIG_SUBOBJECT(Performance, performance) + CFG_PROPERTY(int, resourceUpdateInterval, 1000) + CONFIG_SUBOBJECT(DashboardSizes, sizes) + + public: + explicit Dashboard(QObject* parent = nullptr) + : ConfigObject(parent) + , m_performance(new Performance(this)) + , m_sizes(new DashboardSizes(this)) {} +}; + +} // namespace ZShell::config diff --git a/Plugins/ZShell/Config/dock.hpp b/Plugins/ZShell/Config/dock.hpp new file mode 100644 index 0000000..817ce9a --- /dev/null +++ b/Plugins/ZShell/Config/dock.hpp @@ -0,0 +1,29 @@ +#pragma once +#include "configobject.hpp" +#include +#include + +namespace ZShell::config { + +class Dock : public ConfigObject { + Q_OBJECT + QML_ANONYMOUS + + CFG_PROPERTY(bool, enable, false) + CFG_PROPERTY(int, height, 80) + CFG_PROPERTY(bool, hoverToReveal, false) + CFG_PROPERTY(QStringList, ignoredAppRegexes, {}) + CFG_PROPERTY( + QStringList, + pinnedApps, + (QStringList{ + QStringLiteral("com.ayugram.desktop"), + QStringLiteral("com.obsproject.studio"), + QStringLiteral("librewolf")})) + CFG_PROPERTY(bool, pinnedOnStartup, false) + + public: + explicit Dock(QObject* parent = nullptr) : ConfigObject(parent) {} +}; + +} // namespace ZShell::config diff --git a/Plugins/ZShell/Config/general.hpp b/Plugins/ZShell/Config/general.hpp new file mode 100644 index 0000000..9d0f8fd --- /dev/null +++ b/Plugins/ZShell/Config/general.hpp @@ -0,0 +1,158 @@ +#pragma once +#include "configlist.hpp" +#include "configobject.hpp" +#include + +namespace ZShell::config { + +class BatteryThresholdEntry : public ConfigObject { + Q_OBJECT + QML_ANONYMOUS + + CFG_PROPERTY(QString, icon) + CFG_PROPERTY(QString, message) + CFG_PROPERTY(QString, name) + CFG_PROPERTY(int, perc) + + public: + explicit BatteryThresholdEntry(QObject* parent = nullptr) + : ConfigObject(parent) {} + + [[nodiscard]] QStringList identityKeys() const override { + return {QStringLiteral("perc")}; + } +}; + +CONFIG_LIST_TYPE(BatteryThresholdEntry, BatteryThresholdList) + +class IdleTimeoutEntry : public ConfigObject { + Q_OBJECT + QML_ANONYMOUS + + CFG_PROPERTY(QString, idleAction) + CFG_PROPERTY(QString, name) + CFG_PROPERTY(int, timeout) + + public: + explicit IdleTimeoutEntry(QObject* parent = nullptr) + : ConfigObject(parent) {} + + [[nodiscard]] QStringList identityKeys() const override { + return {QStringLiteral("name")}; + } +}; + +CONFIG_LIST_TYPE(IdleTimeoutEntry, IdleTimeoutList) + +class Apps : public ConfigObject { + Q_OBJECT + QML_ANONYMOUS + + CFG_PROPERTY(QStringList, archiver, {QStringLiteral("ark")}) + CFG_PROPERTY(QStringList, audio, {QStringLiteral("pavucontrol")}) + CFG_PROPERTY(QStringList, document, {QStringLiteral("libreoffice")}) + CFG_PROPERTY(QStringList, editor, {QStringLiteral("kate")}) + CFG_PROPERTY(QStringList, explorer, {QStringLiteral("dolphin")}) + CFG_PROPERTY(QStringList, image, {QStringLiteral("imv")}) + CFG_PROPERTY(QStringList, playback, {QStringLiteral("vlc")}) + CFG_PROPERTY(QStringList, terminal, {QStringLiteral("wezterm")}) + + public: + explicit Apps(QObject* parent = nullptr) : ConfigObject(parent) {} +}; + +class Battery : public ConfigObject { + Q_OBJECT + QML_ANONYMOUS + + CFG_PROPERTY(int, critPerc, 5) + CONFIG_LIST( + BatteryThresholdList, + popupThresholds, + { + vmap( + {{"icon", "battery_android_frame_2"}, + {"message", "Battery low"}, + {"name", "Low battery"}, + {"perc", 20}}), + vmap( + {{"icon", "battery_android_frame_2"}, + {"message", "Battery lower"}, + {"name", "Low battery"}, + {"perc", 15}}), + vmap( + {{"icon", "battery_android_frame_2"}, + {"message", "Battery lowest"}, + {"name", "Low battery"}, + {"perc", 10}}), + }) + + public: + explicit Battery(QObject* parent = nullptr) : ConfigObject(parent) {} +}; + +class ColorSettings : public ConfigObject { + Q_OBJECT + QML_ANONYMOUS + + CFG_PROPERTY(int, hyprsunsetTemp, 2600) + CFG_PROPERTY(QString, mode, QStringLiteral("dark")) + CFG_PROPERTY(bool, neovimColors, false) + CFG_PROPERTY(bool, scheduleDark, false) + CFG_PROPERTY(int, scheduleDarkEnd, 600) + CFG_PROPERTY(int, scheduleDarkStart, 1140) + CFG_PROPERTY(bool, scheduleHyprsunset, true) + CFG_PROPERTY(int, scheduleHyprsunsetEnd, 570) + CFG_PROPERTY(int, scheduleHyprsunsetStart, 1200) + CFG_PROPERTY(bool, schemeGeneration, true) + CFG_PROPERTY(bool, smart, false) + + public: + explicit ColorSettings(QObject* parent = nullptr) : ConfigObject(parent) {} +}; + +class Idle : public ConfigObject { + Q_OBJECT + QML_ANONYMOUS + + CONFIG_LIST( + IdleTimeoutList, + timeouts, + { + vmap( + {{"idleAction", QStringLiteral("lock")}, + {"name", QStringLiteral("Lock")}, + {"timeout", 180}}), + }) + + public: + explicit Idle(QObject* parent = nullptr) : ConfigObject(parent) {} +}; + +class General : public ConfigObject { + Q_OBJECT + QML_ANONYMOUS + + CONFIG_SUBOBJECT(Apps, apps) + CONFIG_SUBOBJECT(Battery, battery) + CONFIG_SUBOBJECT(ColorSettings, color) + CFG_PROPERTY(QString, dateFormat, QStringLiteral("ddd d MMM - hh:mm:ss")) + CFG_PROPERTY(bool, desktopIcons, true) + CONFIG_SUBOBJECT(Idle, idle) + CFG_PROPERTY(QString, logo, QString()) + CFG_PROPERTY(bool, showOverFullscreen, true) + CFG_PROPERTY( + QString, + wallpaperPath, + QStringLiteral("/mnt/IronWolf/SDImages/SWWW_Wals/")) + + public: + explicit General(QObject* parent = nullptr) + : ConfigObject(parent) + , m_apps(new Apps(this)) + , m_battery(new Battery(this)) + , m_color(new ColorSettings(this)) + , m_idle(new Idle(this)) {} +}; + +} // namespace ZShell::config diff --git a/Plugins/ZShell/Config/launcher.hpp b/Plugins/ZShell/Config/launcher.hpp new file mode 100644 index 0000000..24976ca --- /dev/null +++ b/Plugins/ZShell/Config/launcher.hpp @@ -0,0 +1,177 @@ +#pragma once +#include "configlist.hpp" +#include "configobject.hpp" +#include + +namespace ZShell::config { + +class LauncherActionEntry : public ConfigObject { + Q_OBJECT + QML_ANONYMOUS + + CFG_PROPERTY(QVariantList, command) + CFG_PROPERTY(bool, dangerous, false) + CFG_PROPERTY(QString, description) + CFG_PROPERTY(bool, enabled, true) + CFG_PROPERTY(QString, icon) + CFG_PROPERTY(QString, name) + + public: + explicit LauncherActionEntry(QObject* parent = nullptr) + : ConfigObject(parent) {} + + [[nodiscard]] QStringList identityKeys() const override { + return {QStringLiteral("name")}; + } +}; + +CONFIG_LIST_TYPE(LauncherActionEntry, LauncherActionList) + +class LauncherSizes : public ConfigObject { + Q_OBJECT + QML_ANONYMOUS + + CFG_PROPERTY(int, itemHeight, 50) + CFG_PROPERTY(int, itemWidth, 600) + CFG_PROPERTY(int, wallpaperHeight, 200) + CFG_PROPERTY(int, wallpaperWidth, 280) + + public: + explicit LauncherSizes(QObject* parent = nullptr) : ConfigObject(parent) {} +}; + +class UseFuzzy : public ConfigObject { + Q_OBJECT + QML_ANONYMOUS + + CFG_PROPERTY(bool, actions, true) + CFG_PROPERTY(bool, apps, true) + CFG_PROPERTY(bool, schemes, true) + CFG_PROPERTY(bool, variants, true) + CFG_PROPERTY(bool, wallpapers, true) + + public: + explicit UseFuzzy(QObject* parent = nullptr) : ConfigObject(parent) {} +}; + +class Launcher : public ConfigObject { + Q_OBJECT + QML_ANONYMOUS + + CFG_PROPERTY(QString, actionPrefix, QStringLiteral("<")) + CONFIG_LIST( + LauncherActionList, + actions, + { + vmap( + {{"command", QVariantList{"autocomplete", "calc"}}, + {"dangerous", false}, + {"description", "Do simple math equations"}, + {"enabled", true}, + {"icon", "calculate"}, + {"name", "Calculator"}}), + vmap( + {{"command", QVariantList{"setMode", "light"}}, + {"dangerous", false}, + {"description", "Change to light mode"}, + {"enabled", true}, + {"icon", "light_mode"}, + {"name", "Light"}}), + vmap( + {{"command", QVariantList{"setMode", "dark"}}, + {"dangerous", false}, + {"description", "Change to dark mode"}, + {"enabled", true}, + {"icon", "dark_mode"}, + {"name", "Dark"}}), + vmap( + {{"command", QVariantList{"autocomplete", "wallpaper"}}, + {"dangerous", false}, + {"description", "Change the current wallpaper"}, + {"enabled", true}, + {"icon", "image"}, + {"name", "Wallpaper"}}), + vmap( + {{"command", QVariantList{"autocomplete", "variant"}}, + {"dangerous", false}, + {"description", "Change the current scheme variant"}, + {"enabled", true}, + {"icon", "colors"}, + {"name", "Variant"}}), + vmap( + {{"command", QVariantList{"systemctl", "poweroff"}}, + {"dangerous", true}, + {"description", "Shutdown the system"}, + {"enabled", true}, + {"icon", "power_settings_new"}, + {"name", "Shutdown"}}), + vmap( + {{"command", QVariantList{"systemctl", "reboot"}}, + {"dangerous", true}, + {"description", "Reboot the system"}, + {"enabled", true}, + {"icon", "cached"}, + {"name", "Reboot"}}), + vmap( + {{"command", QVariantList{"loginctl", "terminate-user", ""}}, + {"dangerous", true}, + {"description", "Log out of the current session"}, + {"enabled", true}, + {"icon", "logout"}, + {"name", "Logout"}}), + vmap( + {{"command", QVariantList{"loginctl", "lock-session"}}, + {"dangerous", false}, + {"description", "Lock the current session"}, + {"enabled", true}, + {"icon", "lock"}, + {"name", "Lock"}}), + vmap( + {{"command", + QVariantList{"systemctl", "suspend-then-hibernate"}}, + {"dangerous", false}, + {"description", "Suspend then hibernate"}, + {"enabled", true}, + {"icon", "bedtime"}, + {"name", "Sleep"}}), + }) + CFG_PROPERTY(int, dragThreshold, 150) + CFG_PROPERTY(bool, enableDangerousActions, true) + CFG_PROPERTY(bool, enabled, true) + CFG_PROPERTY( + QStringList, + favoriteApps, + {QStringLiteral("Balatro"), + QStringLiteral("Slay the Spire 2"), + QStringLiteral("com.obsproject.Studio")}) + CFG_PROPERTY( + QStringList, + hiddenApps, + {QStringLiteral("zellij"), + QStringLiteral("vim"), + QStringLiteral("jshell-java-openjdk"), + QStringLiteral("jconsole-java-openjdk"), + QStringLiteral("jshell-java21-openjdk"), + QStringLiteral("jconsole-java21-openjdk"), + QStringLiteral("jshell-java17-openjdk"), + QStringLiteral("jconsole-java17-openjdk"), + QStringLiteral("org.neovim.nvim"), + QStringLiteral("avahi-discover"), + QStringLiteral("bvnc"), + QStringLiteral("bssh"), + QStringLiteral("nm-connection-editor")}) + CFG_PROPERTY(int, maxAppsShown, 18) + CFG_PROPERTY(int, maxWallpapers, 7) + CONFIG_SUBOBJECT(LauncherSizes, sizes) + CFG_PROPERTY(QString, specialPrefix, QStringLiteral("@")) + CONFIG_SUBOBJECT(UseFuzzy, useFuzzy) + CFG_PROPERTY(bool, uwsm, true) + + public: + explicit Launcher(QObject* parent = nullptr) + : ConfigObject(parent) + , m_sizes(new LauncherSizes(this)) + , m_useFuzzy(new UseFuzzy(this)) {} +}; + +} // namespace ZShell::config diff --git a/Plugins/ZShell/Config/lock.hpp b/Plugins/ZShell/Config/lock.hpp new file mode 100644 index 0000000..479f3ef --- /dev/null +++ b/Plugins/ZShell/Config/lock.hpp @@ -0,0 +1,36 @@ +#pragma once +#include "configobject.hpp" +#include + +namespace ZShell::config { + +class LockSizes : public ConfigObject { + Q_OBJECT + QML_ANONYMOUS + + CFG_PROPERTY(int, centerWidth, 600) + CFG_PROPERTY(qreal, heightMult, 0.7) + CFG_PROPERTY(qreal, ratio, 1.78) + + public: + explicit LockSizes(QObject* parent = nullptr) : ConfigObject(parent) {} +}; + +class Lock : public ConfigObject { + Q_OBJECT + QML_ANONYMOUS + + CFG_PROPERTY(int, blurAmount, 10) + CFG_PROPERTY(bool, enableFprint, true) + CFG_PROPERTY(int, maxFprintTries, 3) + CFG_PROPERTY(bool, recolorLogo, false) + CFG_PROPERTY(bool, showNotifContent, true) + CFG_PROPERTY(bool, showNotifIcon, true) + CONFIG_SUBOBJECT(LockSizes, sizes) + + public: + explicit Lock(QObject* parent = nullptr) + : ConfigObject(parent), m_sizes(new LockSizes(this)) {} +}; + +} // namespace ZShell::config diff --git a/Plugins/ZShell/Config/notifs.hpp b/Plugins/ZShell/Config/notifs.hpp new file mode 100644 index 0000000..b229f11 --- /dev/null +++ b/Plugins/ZShell/Config/notifs.hpp @@ -0,0 +1,39 @@ +#pragma once +#include "configobject.hpp" +#include + +namespace ZShell::config { + +class NotifsSizes : public ConfigObject { + Q_OBJECT + QML_ANONYMOUS + + CFG_PROPERTY(int, badge, 20) + CFG_PROPERTY(int, image, 41) + CFG_PROPERTY(int, width, 400) + + public: + explicit NotifsSizes(QObject* parent = nullptr) : ConfigObject(parent) {} +}; + +class Notifs : public ConfigObject { + Q_OBJECT + QML_ANONYMOUS + + CFG_PROPERTY(bool, actionOnClick, false) + CFG_PROPERTY(int, appNotifCooldown, 0) + CFG_PROPERTY(qreal, clearThreshold, 0.3) + CFG_PROPERTY(int, defaultExpireTimeout, 5000) + CFG_PROPERTY(int, expandThreshold, 20) + CFG_PROPERTY(bool, expire, true) + CFG_PROPERTY(int, groupPreviewNum, 5) + CFG_PROPERTY(bool, openExpanded, false) + CFG_PROPERTY(bool, showInFullscreen, false) + CONFIG_SUBOBJECT(NotifsSizes, sizes) + + public: + explicit Notifs(QObject* parent = nullptr) + : ConfigObject(parent), m_sizes(new NotifsSizes(this)) {} +}; + +} // namespace ZShell::config diff --git a/Plugins/ZShell/Config/osd.hpp b/Plugins/ZShell/Config/osd.hpp new file mode 100644 index 0000000..bb4bae3 --- /dev/null +++ b/Plugins/ZShell/Config/osd.hpp @@ -0,0 +1,34 @@ +#pragma once +#include "configobject.hpp" +#include + +namespace ZShell::config { + +class OsdSizes : public ConfigObject { + Q_OBJECT + QML_ANONYMOUS + + CFG_PROPERTY(int, sliderHeight, 150) + CFG_PROPERTY(int, sliderWidth, 30) + + public: + explicit OsdSizes(QObject* parent = nullptr) : ConfigObject(parent) {} +}; + +class Osd : public ConfigObject { + Q_OBJECT + QML_ANONYMOUS + + CFG_PROPERTY(bool, allMonBrightness, true) + CFG_PROPERTY(bool, enableBrightness, true) + CFG_PROPERTY(bool, enableMicrophone, true) + CFG_PROPERTY(bool, enabled, true) + CFG_PROPERTY(int, hideDelay, 3000) + CONFIG_SUBOBJECT(OsdSizes, sizes) + + public: + explicit Osd(QObject* parent = nullptr) + : ConfigObject(parent), m_sizes(new OsdSizes(this)) {} +}; + +} // namespace ZShell::config diff --git a/Plugins/ZShell/Config/screenshot.hpp b/Plugins/ZShell/Config/screenshot.hpp new file mode 100644 index 0000000..101ea41 --- /dev/null +++ b/Plugins/ZShell/Config/screenshot.hpp @@ -0,0 +1,27 @@ +#pragma once +#include "configobject.hpp" +#include +#include + +namespace ZShell::config { + +class Screenshot : public ConfigObject { + Q_OBJECT + QML_ANONYMOUS + + CFG_PROPERTY(bool, enable_pp, false) + CFG_PROPERTY(QString, mode, QStringLiteral("manual")) + CFG_PROPERTY(int, radius, 49) + CFG_PROPERTY(bool, rounding, false) + CFG_PROPERTY(bool, saveOnCopy, false) + CFG_PROPERTY(bool, shadow, true) + CFG_PROPERTY(int, shadow_blur, 0) + CFG_PROPERTY(QVariantList, shadow_color, (QVariantList{0, 0, 0, 160})) + CFG_PROPERTY(int, shadow_offset_x, 30) + CFG_PROPERTY(int, shadow_offset_y, 50) + + public: + explicit Screenshot(QObject* parent = nullptr) : ConfigObject(parent) {} +}; + +} // namespace ZShell::config diff --git a/Plugins/ZShell/Config/services.hpp b/Plugins/ZShell/Config/services.hpp new file mode 100644 index 0000000..45d2c2e --- /dev/null +++ b/Plugins/ZShell/Config/services.hpp @@ -0,0 +1,54 @@ +#pragma once +#include "configlist.hpp" +#include "configobject.hpp" + +namespace ZShell::config { + +class PlayerAliasEntry : public ConfigObject { + Q_OBJECT + QML_ANONYMOUS + + CFG_PROPERTY(QString, from) + CFG_PROPERTY(QString, to) + + public: + explicit PlayerAliasEntry(QObject* parent = nullptr) + : ConfigObject(parent) {} + + [[nodiscard]] QStringList identityKeys() const override { + return {QStringLiteral("from")}; + } +}; + +CONFIG_LIST_TYPE(PlayerAliasEntry, PlayerAliasList) + +class Services : public ConfigObject { + Q_OBJECT + QML_ANONYMOUS + + CFG_PROPERTY(qreal, audioIncrement, 0.1) + CFG_PROPERTY(qreal, brightnessIncrement, 0.1) + CFG_PROPERTY(bool, ddcutilService, true) + CFG_PROPERTY(QString, defaultPlayer, QStringLiteral("Spotify")) + CFG_PROPERTY(QString, gpuType, QStringLiteral("NVIDIA")) + CFG_PROPERTY(qreal, maxVolume, 1) + CFG_PROPERTY(qreal, minBrightness, 0.01) + CONFIG_LIST( + PlayerAliasList, + playerAliases, + { + vmap( + {{"from", QStringLiteral("com.github.th_ch.youtube_music")}, + {"to", QStringLiteral("YT Music")}}), + }) + CFG_PROPERTY(bool, updates, true) + CFG_PROPERTY(bool, useFahrenheit, false) + CFG_PROPERTY(bool, useTwelveHourClock, false) + CFG_PROPERTY(int, visualizerBars, 50) + CFG_PROPERTY(QString, weatherLocation, QString()) + + public: + explicit Services(QObject* parent = nullptr) : ConfigObject(parent) {} +}; + +} // namespace ZShell::config diff --git a/Plugins/ZShell/Config/sidebar.hpp b/Plugins/ZShell/Config/sidebar.hpp new file mode 100644 index 0000000..bd9840a --- /dev/null +++ b/Plugins/ZShell/Config/sidebar.hpp @@ -0,0 +1,30 @@ +#pragma once +#include "configobject.hpp" +#include + +namespace ZShell::config { + +class SidebarSizes : public ConfigObject { + Q_OBJECT + QML_ANONYMOUS + + CFG_PROPERTY(int, width, 520) + + public: + explicit SidebarSizes(QObject* parent = nullptr) : ConfigObject(parent) {} +}; + +class Sidebar : public ConfigObject { + Q_OBJECT + QML_ANONYMOUS + + CFG_PROPERTY(int, dragThreshold, 30) + CFG_PROPERTY(bool, enabled, true) + CONFIG_SUBOBJECT(SidebarSizes, sizes) + + public: + explicit Sidebar(QObject* parent = nullptr) + : ConfigObject(parent), m_sizes(new SidebarSizes(this)) {} +}; + +} // namespace ZShell::config diff --git a/Plugins/ZShell/Config/tokens.hpp b/Plugins/ZShell/Config/tokens.hpp new file mode 100644 index 0000000..79056c1 --- /dev/null +++ b/Plugins/ZShell/Config/tokens.hpp @@ -0,0 +1,221 @@ +#pragma once + +#include "configobject.hpp" + +#include +#include +#include + +namespace ZShell::config { + +class AppearanceRounding : public ConfigObject { + Q_OBJECT + QML_ANONYMOUS + + CFG_PROPERTY(qreal, extraSmall, 4) + CFG_PROPERTY(qreal, full, 1000) + CFG_PROPERTY(qreal, large, 24) + CFG_PROPERTY(qreal, medium, 16) + CFG_PROPERTY(qreal, normal, 18) + CFG_PROPERTY(qreal, scale, 1) + CFG_PROPERTY(qreal, small, 12) + CFG_PROPERTY(qreal, smallest, 8) + + public: + explicit AppearanceRounding(QObject* parent = nullptr) + : ConfigObject(parent) {} +}; + +class AppearancePadding : public ConfigObject { + Q_OBJECT + QML_ANONYMOUS + + CFG_PROPERTY(qreal, extraLarge, 28) + CFG_PROPERTY(qreal, extraLargeIncreased, 32) + CFG_PROPERTY(qreal, extraSmall, 4) + CFG_PROPERTY(qreal, large, 16) + CFG_PROPERTY(qreal, largeIncreased, 20) + CFG_PROPERTY(qreal, larger, 12) + CFG_PROPERTY(qreal, normal, 8) + CFG_PROPERTY(qreal, scale, 1) + CFG_PROPERTY(qreal, small, 5) + CFG_PROPERTY(qreal, smaller, 7) + CFG_PROPERTY(qreal, smallest, 2) + + public: + explicit AppearancePadding(QObject* parent = nullptr) + : ConfigObject(parent) {} +}; + +class AppearanceSpacing : public ConfigObject { + Q_OBJECT + QML_ANONYMOUS + + CFG_PROPERTY(qreal, extraSmall, 4) + CFG_PROPERTY(qreal, large, 20) + CFG_PROPERTY(qreal, larger, 16) + CFG_PROPERTY(qreal, normal, 12) + CFG_PROPERTY(qreal, scale, 1) + CFG_PROPERTY(qreal, small, 8) + CFG_PROPERTY(qreal, smaller, 10) + + public: + explicit AppearanceSpacing(QObject* parent = nullptr) + : ConfigObject(parent) {} +}; + +class FontSizeTokens : public ConfigObject { + Q_OBJECT + QML_ANONYMOUS + + CFG_PROPERTY(qreal, extraLarge, 28) + CFG_PROPERTY(qreal, large, 18) + CFG_PROPERTY(qreal, larger, 16) + CFG_PROPERTY(qreal, medium, 14) + CFG_PROPERTY(qreal, normal, 13) + CFG_PROPERTY(qreal, scale, 1) + CFG_PROPERTY(qreal, small, 11) + CFG_PROPERTY(qreal, smaller, 12) + + public: + explicit FontSizeTokens(QObject* parent = nullptr) : ConfigObject(parent) {} +}; + +class FontTokens : public ConfigObject { + Q_OBJECT + QML_ANONYMOUS + + CONFIG_SUBOBJECT(FontSizeTokens, size) + + public: + explicit FontTokens(QObject* parent = nullptr) + : ConfigObject(parent), m_size(new FontSizeTokens(this)) {} +}; + +class AnimCurves : public ConfigObject { + Q_OBJECT + QML_ANONYMOUS + + CFG_PROPERTY( + QVariantList, + emphasized, + QVariantList{ + 0.05, + 0, + 2.0 / 15.0, + 0.06, + 1.0 / 6.0, + 0.4, + 5.0 / 24.0, + 0.82, + 0.25, + 1, + 1, + 1}) + + CFG_PROPERTY( + QVariantList, emphasizedAccel, QVariantList{0.3, 0, 0.8, 0.15, 1, 1}) + + CFG_PROPERTY( + QVariantList, emphasizedDecel, QVariantList{0.05, 0.7, 0.1, 1, 1, 1}) + + CFG_PROPERTY( + QVariantList, + expressiveDefaultEffects, + QVariantList{0.34, 0.8, 0.34, 1, 1, 1}) + + CFG_PROPERTY( + QVariantList, + expressiveDefaultSpatial, + QVariantList{0.38, 1.21, 0.22, 1, 1, 1}) + + CFG_PROPERTY( + QVariantList, expressiveEffects, QVariantList{0.34, 0.8, 0.34, 1, 1, 1}) + + CFG_PROPERTY( + QVariantList, + expressiveFastEffects, + QVariantList{0.31, 0.94, 0.34, 1, 1, 1}) + + CFG_PROPERTY( + QVariantList, + expressiveFastSpatial, + QVariantList{0.42, 1.67, 0.21, 0.9, 1, 1}) + + CFG_PROPERTY( + QVariantList, + expressiveSlowEffects, + QVariantList{0.34, 0.88, 0.34, 1, 1, 1}) + + CFG_PROPERTY( + QVariantList, + expressiveSlowSpatial, + QVariantList{0.39, 1.29, 0.35, 0.98, 1, 1}) + + CFG_PROPERTY(QVariantList, standard, QVariantList{0.2, 0, 0, 1, 1, 1}) + + CFG_PROPERTY(QVariantList, standardAccel, QVariantList{0.3, 0, 1, 1, 1, 1}) + + CFG_PROPERTY(QVariantList, standardDecel, QVariantList{0, 0, 0, 1, 1, 1}) + + public: + explicit AnimCurves(QObject* parent = nullptr) : ConfigObject(parent) {} +}; + +class AnimDurations : public ConfigObject { + Q_OBJECT + QML_ANONYMOUS + + CFG_PROPERTY(int, expressiveDefaultSpatial, 500) + CFG_PROPERTY(int, expressiveEffects, 200) + CFG_PROPERTY(int, expressiveFastEffects, 150) + CFG_PROPERTY(int, expressiveFastSpatial, 350) + CFG_PROPERTY(int, expressiveSlowEffects, 300) + CFG_PROPERTY(int, extraLarge, 1000) + CFG_PROPERTY(int, large, 600) + CFG_PROPERTY(int, normal, 400) + CFG_PROPERTY(qreal, scale, 1) + CFG_PROPERTY(int, small, 200) + + public: + explicit AnimDurations(QObject* parent = nullptr) : ConfigObject(parent) {} +}; + +class AnimTokens : public ConfigObject { + Q_OBJECT + QML_ANONYMOUS + + CONFIG_SUBOBJECT(AnimCurves, curves) + CONFIG_SUBOBJECT(AnimDurations, durations) + + public: + explicit AnimTokens(QObject* parent = nullptr) + : ConfigObject(parent) + , m_curves(new AnimCurves(this)) + , m_durations(new AnimDurations(this)) {} +}; + +class Tokens : public ConfigObject { + Q_OBJECT + QML_ELEMENT + QML_SINGLETON + + CONFIG_SUBOBJECT(AppearanceRounding, rounding) + CONFIG_SUBOBJECT(AppearancePadding, padding) + CONFIG_SUBOBJECT(AppearanceSpacing, spacing) + CONFIG_SUBOBJECT(FontTokens, font) + CONFIG_SUBOBJECT(AnimTokens, anim) + + public: + explicit Tokens(QObject* parent = nullptr) + : ConfigObject(parent) + , m_rounding(new AppearanceRounding(this)) + , m_padding(new AppearancePadding(this)) + , m_spacing(new AppearanceSpacing(this)) + , m_font(new FontTokens(this)) + , m_anim(new AnimTokens(this)) {} + + static Tokens* create(QQmlEngine*, QJSEngine*) { return new Tokens(); } +}; + +} // namespace ZShell::config diff --git a/Plugins/ZShell/Config/utilities.hpp b/Plugins/ZShell/Config/utilities.hpp new file mode 100644 index 0000000..ae97ed7 --- /dev/null +++ b/Plugins/ZShell/Config/utilities.hpp @@ -0,0 +1,70 @@ +#pragma once +#include "configobject.hpp" +#include +#include +#include + +namespace ZShell::config { + +class UtilitiesSizes : public ConfigObject { + Q_OBJECT + QML_ANONYMOUS + + CFG_PROPERTY(int, toastWidth, 430) + CFG_PROPERTY(int, width, 430) + + public: + explicit UtilitiesSizes(QObject* parent = nullptr) : ConfigObject(parent) {} +}; + +class Toasts : public ConfigObject { + Q_OBJECT + QML_ANONYMOUS + + CFG_PROPERTY(bool, audioInputChanged, true) + CFG_PROPERTY(bool, audioOutputChanged, true) + CFG_PROPERTY(bool, capsLockChanged, true) + CFG_PROPERTY(bool, chargingChanged, true) + CFG_PROPERTY(bool, configLoaded, true) + CFG_PROPERTY(bool, dndChanged, true) + CFG_PROPERTY(bool, gameModeChanged, true) + CFG_PROPERTY(bool, kbLayoutChanged, true) + CFG_PROPERTY(bool, kbLimit, true) + CFG_PROPERTY(bool, nowPlaying, false) + CFG_PROPERTY(bool, numLockChanged, true) + CFG_PROPERTY(bool, vpnChanged, true) + + public: + explicit Toasts(QObject* parent = nullptr) : ConfigObject(parent) {} +}; + +class Vpn : public ConfigObject { + Q_OBJECT + QML_ANONYMOUS + + CFG_PROPERTY(bool, enabled, false) + CFG_PROPERTY(QStringList, provider, (QStringList{QStringLiteral("netbird")})) + + public: + explicit Vpn(QObject* parent = nullptr) : ConfigObject(parent) {} +}; + +class Utilities : public ConfigObject { + Q_OBJECT + QML_ANONYMOUS + + CFG_PROPERTY(bool, enabled, true) + CFG_PROPERTY(int, maxToasts, 4) + CONFIG_SUBOBJECT(UtilitiesSizes, sizes) + CONFIG_SUBOBJECT(Toasts, toasts) + CONFIG_SUBOBJECT(Vpn, vpn) + + public: + explicit Utilities(QObject* parent = nullptr) + : ConfigObject(parent) + , m_sizes(new UtilitiesSizes(this)) + , m_toasts(new Toasts(this)) + , m_vpn(new Vpn(this)) {} +}; + +} // namespace ZShell::config diff --git a/Plugins/ZShell/Internal/stroke.hpp b/Plugins/ZShell/Internal/stroke.hpp index aba955b..200ae4f 100644 --- a/Plugins/ZShell/Internal/stroke.hpp +++ b/Plugins/ZShell/Internal/stroke.hpp @@ -14,6 +14,7 @@ struct Stroke { qreal width; int groupId = -1; bool isSinglePoint = false; + bool isPolyline = false; }; }; // namespace ZShell::internal diff --git a/Plugins/ZShell/Internal/strokecanvasitem.cpp b/Plugins/ZShell/Internal/strokecanvasitem.cpp index 4f8d615..dcb7e47 100644 --- a/Plugins/ZShell/Internal/strokecanvasitem.cpp +++ b/Plugins/ZShell/Internal/strokecanvasitem.cpp @@ -25,7 +25,8 @@ static bool shouldAddPoint( return QPointF::dotProduct(delta, delta) >= minDistance * minDistance; } -static QCanvasPath buildStrokePath(const QVector& points, qreal width) { +static QCanvasPath buildStrokePath( + const QVector& points, qreal width, bool polyline) { QCanvasPath path; if (points.size() == 1) { @@ -33,6 +34,13 @@ static QCanvasPath buildStrokePath(const QVector& points, qreal width) return path; } + if (polyline) { + path.moveTo(points[0]); + for (int i = 1; i < points.size(); i++) + path.lineTo(points[i]); + return path; + } + auto catmullToBezier = [](const QPointF& p0, const QPointF& p1, const QPointF& p2, @@ -61,6 +69,16 @@ static QCanvasPath buildStrokePath(const QVector& points, qreal width) return path; } +void StrokeCanvasItem::undoLastGroup() { + if (m_strokes.isEmpty()) return; + const int lastGroup = m_strokes.last().groupId; + for (int i = m_strokes.size() - 1; + i >= 0 && m_strokes[i].groupId == lastGroup; + --i) + m_strokes.remove(i); + update(); +} + void StrokeCanvasItem::setPenColor(const QColor& color) { if (m_penColor == color) return; @@ -121,13 +139,14 @@ void StrokeCanvasItem::setPenWidth(qreal width) { emit penWidthChanged(); } -void StrokeCanvasItem::beginStroke(qreal x, qreal y) { +void StrokeCanvasItem::beginStroke(qreal x, qreal y, bool polyline) { m_isDrawing = true; m_currentStroke.points.clear(); m_currentStroke.points.append({x, y}); m_currentStroke.color = m_penColor; m_currentStroke.width = m_penWidth; + m_currentStroke.isPolyline = polyline; update(); } @@ -135,6 +154,12 @@ void StrokeCanvasItem::beginStroke(qreal x, qreal y) { void StrokeCanvasItem::appendPoint(qreal x, qreal y) { const QPointF incoming{x, y}; + if (m_currentStroke.isPolyline) { + m_currentStroke.points.append(incoming); + update(); + return; + } + if (!shouldAddPoint(m_currentStroke.points, incoming, 2.0)) return; QPointF smoothed; @@ -166,8 +191,10 @@ void StrokeCanvasItem::endStroke() { if (m_currentStroke.points.isEmpty()) return; m_currentStroke.isSinglePoint = (m_currentStroke.points.size() == 1); - m_currentStroke.path = - buildStrokePath(m_currentStroke.points, m_currentStroke.width); + m_currentStroke.path = buildStrokePath( + m_currentStroke.points, + m_currentStroke.width, + m_currentStroke.isPolyline); m_currentStroke.groupId = m_nextGroupId++; m_currentStroke.points.clear(); m_strokes.append(m_currentStroke); diff --git a/Plugins/ZShell/Internal/strokecanvasitem.hpp b/Plugins/ZShell/Internal/strokecanvasitem.hpp index 67a75fd..7f1e9a0 100644 --- a/Plugins/ZShell/Internal/strokecanvasitem.hpp +++ b/Plugins/ZShell/Internal/strokecanvasitem.hpp @@ -39,6 +39,7 @@ class StrokeCanvasItem : public QCanvasPainterItem { Q_INVOKABLE void showHover(qreal x, qreal y); Q_INVOKABLE void hideHover(); + Q_INVOKABLE void undoLastGroup(); [[nodiscard]] QColor penColor() const { return m_penColor; } [[nodiscard]] qreal penWidth() const { return m_penWidth; } @@ -48,7 +49,7 @@ class StrokeCanvasItem : public QCanvasPainterItem { Q_INVOKABLE void clear(); - Q_INVOKABLE void beginStroke(qreal x, qreal y); + Q_INVOKABLE void beginStroke(qreal x, qreal y, bool polyline = false); Q_INVOKABLE void appendPoint(qreal x, qreal y); Q_INVOKABLE void endStroke(); diff --git a/Plugins/ZShell/Internal/strokecanvasrenderer.cpp b/Plugins/ZShell/Internal/strokecanvasrenderer.cpp index 704fcd4..3a77d76 100644 --- a/Plugins/ZShell/Internal/strokecanvasrenderer.cpp +++ b/Plugins/ZShell/Internal/strokecanvasrenderer.cpp @@ -8,7 +8,8 @@ static void drawStroke( QCanvasPainter* painter, const QVector& points, const QColor& color, - qreal width) { + qreal width, + bool polyline) { if (points.isEmpty()) return; painter->setStrokeStyle(color); @@ -17,6 +18,15 @@ static void drawStroke( painter->setLineCap(QCanvasPainter::LineCap::Round); painter->setLineJoin(QCanvasPainter::LineJoin::Round); + if (polyline) { + painter->beginPath(); + painter->moveTo(points[0]); + for (int i = 1; i < points.size(); i++) + painter->lineTo(points[i]); + painter->stroke(); + return; + } + if (points.size() == 1) { painter->beginPath(); painter->circle(points.front(), width * 0.5); @@ -180,7 +190,8 @@ void StrokeCanvasRenderer::paint(QCanvasPainter* painter) { painter, m_currentStroke.points, m_currentStroke.color, - m_currentStroke.width); + m_currentStroke.width, + m_currentStroke.isPolyline); if (m_hoverVisible) drawHoverCursor( diff --git a/Config/DynamicColors.qml b/Services/Colors.qml similarity index 97% rename from Config/DynamicColors.qml rename to Services/Colors.qml index 040760d..f11b78b 100644 --- a/Config/DynamicColors.qml +++ b/Services/Colors.qml @@ -6,6 +6,7 @@ import Quickshell.Io import Quickshell.Hyprland import QtQuick import ZShell +import ZShell.Config import qs.Helpers import qs.Paths @@ -280,9 +281,9 @@ Singleton { readonly property color m3tertiary_paletteKeyColor: root.layer(root.palette.m3tertiary_paletteKeyColor) } component Transparency: QtObject { - readonly property real base: Math.max(0, Math.min(1, Appearance.transparency.base - (root.light ? 0.1 : 0))) - readonly property bool enabled: Appearance.transparency.enabled - readonly property real layers: Appearance.transparency.layers + readonly property real base: Math.max(0, Math.min(1, Config.appearance.transparency.base - (root.light ? 0.1 : 0))) + readonly property bool enabled: Config.appearance.transparency.enabled + readonly property real layers: Config.appearance.transparency.layers onBaseChanged: debounceTimer.restart() onEnabledChanged: debounceTimer.restart() diff --git a/ci/Dockerfile b/ci/Dockerfile index dd94cce..e080260 100644 --- a/ci/Dockerfile +++ b/ci/Dockerfile @@ -30,14 +30,24 @@ RUN pacman -S --noconfirm \ glib2 # AUR: libcava (provides development headers for cava) -RUN pacman -S --needed --noconfirm sudo && \ +RUN pacman -Syu --noconfirm && \ + pacman -S --needed --noconfirm \ + sudo \ + meson \ + autoconf-archive \ + python-tqdm && \ useradd -m builder && \ - echo "builder ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers && \ - su builder -c " \ - git clone https://aur.archlinux.org/libcava.git /tmp/libcava && \ - cd /tmp/libcava && \ - makepkg -si --noconfirm \ - " && \ + echo "builder ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers + +RUN for i in 1 2 3 4 5; do \ + rm -rf /tmp/libcava && \ + git clone --depth 1 https://aur.archlinux.org/libcava.git /tmp/libcava && \ + break || sleep 5; \ + done && \ + test -d /tmp/libcava/.git && \ + chown -R builder /tmp/libcava + +RUN su builder -c "cd /tmp/libcava && makepkg -si --noconfirm" && \ rm -rf /tmp/libcava && \ userdel -r builder && \ sed -i '/^builder/d' /etc/sudoers diff --git a/pyproject.toml b/pyproject.toml index 2c53644..9d0589d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -13,6 +13,9 @@ dependencies = [ "materialyoucolor" ] +[project.optional-dependencies] +dev = ["pytest"] + [project.scripts] zshell-cli = "zshell:main"