Merge branch 'main' into feat/wallpaper-picker-rework
C++ / fmt (pull_request) Successful in 8s
JS/TS / fmt (pull_request) Successful in 13s
JS/TS / lint (pull_request) Successful in 15s
Python / fmt (pull_request) Successful in 25s
Python / lint (pull_request) Successful in 28s
Python / test (pull_request) Successful in 55s
Python / typecheck (pull_request) Failing after 58s
Rust / fmt (pull_request) Successful in 44s
C++ / build (pull_request) Successful in 3m35s
Rust / build (pull_request) Successful in 1m53s
Python / buildcheck (pull_request) Successful in 2m36s
Rust / clippy (pull_request) Successful in 1m28s
C++ / clang-tidy (pull_request) Successful in 5m15s

This commit is contained in:
2026-08-14 19:18:15 +02:00
359 changed files with 5235 additions and 8203 deletions
+1 -1
View File
@@ -155,7 +155,7 @@ if("plugin" IN_LIST ENABLE_MODULES)
endif() endif()
if("shell" IN_LIST ENABLE_MODULES) 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}") install(DIRECTORY ${dir} DESTINATION "${INSTALL_QSCONFDIR}")
endforeach() endforeach()
+12 -12
View File
@@ -1,5 +1,5 @@
import QtQuick import QtQuick
import qs.Config import ZShell.Config
AnchorAnimation { AnchorAnimation {
enum Type { enum Type {
@@ -20,32 +20,32 @@ AnchorAnimation {
duration: { duration: {
if (type < AnchorAnim.StandardSmall || type > AnchorAnim.SlowSpatial) if (type < AnchorAnim.StandardSmall || type > AnchorAnim.SlowSpatial)
return Appearance.anim.durations.expressiveDefaultSpatial; return Tokens.anim.durations.expressiveDefaultSpatial;
if (type == AnchorAnim.FastSpatial) if (type == AnchorAnim.FastSpatial)
return Appearance.anim.durations.expressiveFastSpatial; return Tokens.anim.durations.expressiveFastSpatial;
if (type == AnchorAnim.DefaultSpatial) if (type == AnchorAnim.DefaultSpatial)
return Appearance.anim.durations.expressiveDefaultSpatial; return Tokens.anim.durations.expressiveDefaultSpatial;
if (type == AnchorAnim.SlowSpatial) if (type == AnchorAnim.SlowSpatial)
return Appearance.anim.durations.large; return Tokens.anim.durations.large;
const types = ["small", "normal", "large", "extraLarge"]; const types = ["small", "normal", "large", "extraLarge"];
const idx = type % 4; const idx = type % 4;
return Appearance.anim.durations[types[idx]]; return Tokens.anim.durations[types[idx]];
} }
easing.bezierCurve: { easing.bezierCurve: {
if (type == AnchorAnim.FastSpatial) if (type == AnchorAnim.FastSpatial)
return Appearance.anim.curves.expressiveFastSpatial; return Tokens.anim.curves.expressiveFastSpatial;
if (type == AnchorAnim.DefaultSpatial) if (type == AnchorAnim.DefaultSpatial)
return Appearance.anim.curves.expressiveDefaultSpatial; return Tokens.anim.curves.expressiveDefaultSpatial;
if (type == AnchorAnim.SlowSpatial) if (type == AnchorAnim.SlowSpatial)
return Appearance.anim.curves.expressiveSlowSpatial; return Tokens.anim.curves.expressiveSlowSpatial;
if (type >= AnchorAnim.StandardSmall && type <= AnchorAnim.StandardExtraLarge) if (type >= AnchorAnim.StandardSmall && type <= AnchorAnim.StandardExtraLarge)
return Appearance.anim.curves.standard; return Tokens.anim.curves.standard;
if (type >= AnchorAnim.EmphasizedSmall && type <= AnchorAnim.EmphasizedExtraLarge) 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;
} }
} }
+17 -17
View File
@@ -1,5 +1,5 @@
import QtQuick import QtQuick
import qs.Config import ZShell.Config
NumberAnimation { NumberAnimation {
enum Type { enum Type {
@@ -23,41 +23,41 @@ NumberAnimation {
duration: { duration: {
if (type < Anim.StandardSmall || type > Anim.SlowEffects) if (type < Anim.StandardSmall || type > Anim.SlowEffects)
return Appearance.anim.durations.normal; return Tokens.anim.durations.normal;
if (type === Anim.FastSpatial) if (type === Anim.FastSpatial)
return Appearance.anim.durations.expressiveFastSpatial; return Tokens.anim.durations.expressiveFastSpatial;
if (type === Anim.DefaultSpatial) if (type === Anim.DefaultSpatial)
return Appearance.anim.durations.expressiveDefaultSpatial; return Tokens.anim.durations.expressiveDefaultSpatial;
if (type === Anim.SlowSpatial) if (type === Anim.SlowSpatial)
return Appearance.anim.durations.large; return Tokens.anim.durations.large;
if (type === Anim.FastEffects) if (type === Anim.FastEffects)
return Appearance.anim.durations.expressiveFastEffects; return Tokens.anim.durations.expressiveFastEffects;
if (type === Anim.DefaultEffects) if (type === Anim.DefaultEffects)
return Appearance.anim.durations.expressiveEffects; return Tokens.anim.durations.expressiveEffects;
if (type === Anim.SlowEffects) if (type === Anim.SlowEffects)
return Appearance.anim.durations.expressiveSlowEffects; return Tokens.anim.durations.expressiveSlowEffects;
const types = ["small", "normal", "large", "extraLarge"]; const types = ["small", "normal", "large", "extraLarge"];
const idx = type % 4; const idx = type % 4;
return Appearance.anim.durations[types[idx]]; return Tokens.anim.durations[types[idx]];
} }
easing.bezierCurve: { easing.bezierCurve: {
if (type === Anim.FastSpatial) if (type === Anim.FastSpatial)
return Appearance.anim.curves.expressiveFastSpatial; return Tokens.anim.curves.expressiveFastSpatial;
if (type === Anim.DefaultSpatial) if (type === Anim.DefaultSpatial)
return Appearance.anim.curves.expressiveDefaultSpatial; return Tokens.anim.curves.expressiveDefaultSpatial;
if (type === Anim.SlowSpatial) if (type === Anim.SlowSpatial)
return Appearance.anim.curves.expressiveSlowSpatial; return Tokens.anim.curves.expressiveSlowSpatial;
if (type === Anim.FastEffects) if (type === Anim.FastEffects)
return Appearance.anim.curves.expressiveFastEffects; return Tokens.anim.curves.expressiveFastEffects;
if (type === Anim.DefaultEffects) if (type === Anim.DefaultEffects)
return Appearance.anim.curves.expressiveDefaultEffects; return Tokens.anim.curves.expressiveDefaultEffects;
if (type === Anim.SlowEffects) if (type === Anim.SlowEffects)
return Appearance.anim.curves.expressiveSlowEffects; return Tokens.anim.curves.expressiveSlowEffects;
if (type >= Anim.EmphasizedSmall && type <= Anim.EmphasizedExtraLarge) if (type >= Anim.EmphasizedSmall && type <= Anim.EmphasizedExtraLarge)
return Appearance.anim.curves.emphasized; return Tokens.anim.curves.emphasized;
return Appearance.anim.curves.standard; return Tokens.anim.curves.standard;
} }
} }
+15 -14
View File
@@ -1,11 +1,12 @@
import QtQuick import QtQuick
import QtQuick.Templates import QtQuick.Templates
import qs.Config import ZShell.Config
import qs.Services
Slider { Slider {
id: root id: root
property color color: DynamicColors.palette.m3secondary property color color: Colors.palette.m3secondary
required property string icon required property string icon
property bool initialized: false property bool initialized: false
readonly property bool isHorizontal: orientation === Qt.Horizontal readonly property bool isHorizontal: orientation === Qt.Horizontal
@@ -19,9 +20,9 @@ Slider {
background: CustomRect { background: CustomRect {
id: groove id: groove
color: DynamicColors.layer(DynamicColors.palette.m3surfaceContainer, 2) color: Colors.layer(Colors.palette.m3surfaceContainer, 2)
height: root.availableHeight height: root.availableHeight
radius: Appearance.rounding.full radius: Tokens.rounding.full
width: root.availableWidth width: root.availableWidth
x: root.leftPadding x: root.leftPadding
y: root.topPadding y: root.topPadding
@@ -62,8 +63,8 @@ Slider {
id: rect id: rect
anchors.fill: parent anchors.fill: parent
color: DynamicColors.palette.m3inverseSurface color: Colors.palette.m3inverseSurface
radius: Appearance.rounding.full radius: Tokens.rounding.full
MouseArea { MouseArea {
id: handleInteraction id: handleInteraction
@@ -82,12 +83,12 @@ Slider {
function update(): void { function update(): void {
animate = !moving; animate = !moving;
binding.when = moving; binding.when = moving;
font.pointSize = moving ? Appearance.font.size.small : Appearance.font.size.larger; font.pointSize = moving ? Tokens.font.size.small : Tokens.font.size.larger;
font.family = moving ? Appearance.font.family.sans : Appearance.font.family.material; font.family = moving ? Config.appearance.font.family.sans : Config.appearance.font.family.material;
} }
anchors.centerIn: parent anchors.centerIn: parent
color: DynamicColors.palette.m3inverseOnSurface color: Colors.palette.m3inverseOnSurface
text: root.icon text: root.icon
onMovingChanged: anim.restart() onMovingChanged: anim.restart()
@@ -105,8 +106,8 @@ Slider {
id: anim id: anim
Anim { Anim {
duration: Appearance.anim.durations.normal / 2 duration: Tokens.anim.durations.normal / 2
easing.bezierCurve: Appearance.anim.curves.standardAccel easing.bezierCurve: Tokens.anim.curves.standardAccel
property: "scale" property: "scale"
target: icon target: icon
to: 0 to: 0
@@ -117,8 +118,8 @@ Slider {
} }
Anim { Anim {
duration: Appearance.anim.durations.normal / 2 duration: Tokens.anim.durations.normal / 2
easing.bezierCurve: Appearance.anim.curves.standardDecel easing.bezierCurve: Tokens.anim.curves.standardDecel
property: "scale" property: "scale"
target: icon target: icon
to: 1 to: 1
@@ -129,7 +130,7 @@ Slider {
} }
Behavior on value { Behavior on value {
Anim { Anim {
duration: Appearance.anim.durations.large duration: Tokens.anim.durations.large
} }
} }
+10 -9
View File
@@ -1,5 +1,6 @@
import QtQuick import QtQuick
import qs.Config import ZShell.Config
import qs.Services
CustomRect { CustomRect {
id: root id: root
@@ -13,14 +14,14 @@ CustomRect {
property color activeColor property color activeColor
property color activeOnColor property color activeOnColor
property bool checked property bool checked
property real checkedRadius: Appearance.rounding.medium property real checkedRadius: Tokens.rounding.medium
property real defaultRadius: Appearance.rounding.large property real defaultRadius: Tokens.rounding.large
property color disabledColor: Qt.alpha(DynamicColors.palette.m3onSurface, 0.1) property color disabledColor: Qt.alpha(Colors.palette.m3onSurface, 0.1)
property color disabledOnColor: Qt.alpha(DynamicColors.palette.m3onSurface, 0.38) property color disabledOnColor: Qt.alpha(Colors.palette.m3onSurface, 0.38)
property bool fillWidth property bool fillWidth
property font font: ({ property font font: ({
family: Appearance.font.family.sans, family: Config.appearance.font.family.sans,
pointSize: Appearance.font.size.larger, pointSize: Tokens.font.size.larger,
bold: false bold: false
}) })
property real horizontalPadding: padding property real horizontalPadding: padding
@@ -35,7 +36,7 @@ CustomRect {
readonly property color onColor: !enabled ? disabledOnColor : internalChecked ? activeOnColor : inactiveOnColor readonly property color onColor: !enabled ? disabledOnColor : internalChecked ? activeOnColor : inactiveOnColor
property real padding property real padding
readonly property alias pressed: stateLayer.pressed readonly property alias pressed: stateLayer.pressed
property real pressedRadius: Appearance.rounding.smallest property real pressedRadius: Tokens.rounding.smallest
readonly property alias radiusAnim: radiusAnim readonly property alias radiusAnim: radiusAnim
property bool radiusMorph: true property bool radiusMorph: true
property alias shapeMorph: stateLayer.shapeMorph property alias shapeMorph: stateLayer.shapeMorph
@@ -53,7 +54,7 @@ CustomRect {
if (internalChecked) if (internalChecked)
return checkedRadius; return checkedRadius;
if (isRound) if (isRound)
return (height || implicitHeight) / 2 * Math.min(1, Appearance.rounding.scale); return (height || implicitHeight) / 2 * Math.min(1, Tokens.rounding.scale);
return defaultRadius; return defaultRadius;
} }
+59 -4
View File
@@ -1,8 +1,63 @@
import QtQuick import QtQuick
import qs.Config import ZShell.Config
ColorAnimation { ColorAnimation {
duration: MaterialEasing.standardTime enum Type {
easing.bezierCurve: MaterialEasing.standard StandardSmall = 0,
easing.type: Easing.BezierSpline 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;
}
} }
+9 -8
View File
@@ -1,7 +1,8 @@
import qs.Config import ZShell.Config
import ZShell.Internal import ZShell.Internal
import QtQuick import QtQuick
import QtQuick.Templates import QtQuick.Templates
import qs.Services
BusyIndicator { BusyIndicator {
id: root id: root
@@ -17,12 +18,12 @@ BusyIndicator {
} }
property int animState property int animState
property color bgColor: DynamicColors.palette.m3secondaryContainer property color bgColor: Colors.palette.m3secondaryContainer
property color fgColor: DynamicColors.palette.m3primary property color fgColor: Colors.palette.m3primary
property real implicitSize: Appearance.font.size.normal * 3 property real implicitSize: Tokens.font.size.normal * 3
property real internalStrokeWidth: strokeWidth property real internalStrokeWidth: strokeWidth
readonly property alias progress: manager.progress 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 property alias type: manager.indeterminateAnimationType
implicitHeight: implicitSize implicitHeight: implicitSize
@@ -50,7 +51,7 @@ BusyIndicator {
} }
transitions: Transition { transitions: Transition {
Anim { Anim {
duration: manager.completeEndDuration * Appearance.anim.durations.scale duration: manager.completeEndDuration * Tokens.anim.durations.scale
properties: "opacity,internalStrokeWidth" properties: "opacity,internalStrokeWidth"
} }
} }
@@ -76,7 +77,7 @@ BusyIndicator {
} }
NumberAnimation { NumberAnimation {
duration: manager.duration * Appearance.anim.durations.scale duration: manager.duration * Tokens.anim.durations.scale
from: 0 from: 0
loops: Animation.Infinite loops: Animation.Infinite
property: "progress" property: "progress"
@@ -86,7 +87,7 @@ BusyIndicator {
} }
NumberAnimation { NumberAnimation {
duration: manager.completeEndDuration * Appearance.anim.durations.scale duration: manager.completeEndDuration * Tokens.anim.durations.scale
from: 0 from: 0
property: "completeEndProgress" property: "completeEndProgress"
running: root.animState === CircularIndicator.Completing running: root.animState === CircularIndicator.Completing
+7 -6
View File
@@ -3,24 +3,25 @@ pragma ComponentBehavior: Bound
import QtQuick import QtQuick
import QtQuick.Shapes import QtQuick.Shapes
import ZShell.Components import ZShell.Components
import qs.Config import ZShell.Config
import qs.Services
Item { Item {
id: root id: root
readonly property real arcRadius: (size - padding - strokeWidth * (1 + waveAmplitude * 2)) / 2 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)) 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 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) readonly property real gapAngle: ((spacing + strokeWidth) / (arcRadius || 1)) * (180 / Math.PI)
property alias hasEndIndicator: dot.active property alias hasEndIndicator: dot.active
property real implicitSize property real implicitSize
property int padding: 0 property int padding: 0
readonly property real size: Math.min(width, height) 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 startAngle: -90
property int strokeWidth: Appearance.padding.small property int strokeWidth: Tokens.padding.small
property int sweepAngle: 360 property int sweepAngle: 360
readonly property real thickness: strokeWidth * (1 + waveAmplitude) * 2 readonly property real thickness: strokeWidth * (1 + waveAmplitude) * 2
property real value property real value
@@ -110,7 +111,7 @@ Item {
implicitHeight: Math.min(1, remainingArc.sweepAngle) * Math.min(4, root.strokeWidth) implicitHeight: Math.min(1, remainingArc.sweepAngle) * Math.min(4, root.strokeWidth)
implicitWidth: 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) opacity: Math.min(1, remainingArc.sweepAngle)
radius: Appearance.rounding.full radius: Tokens.rounding.full
} }
} }
} }
+7 -6
View File
@@ -1,7 +1,8 @@
pragma ComponentBehavior: Bound pragma ComponentBehavior: Bound
import QtQuick import QtQuick
import qs.Config import ZShell.Config
import qs.Services
Item { Item {
id: root id: root
@@ -18,9 +19,9 @@ Item {
property real lastChromaticHue: 0 property real lastChromaticHue: 0
readonly property real radius: (Math.min(width, height) - handleSize) / 2 readonly property real radius: (Math.min(width, height) - handleSize) / 2
readonly property int segmentCount: 240 readonly property int segmentCount: 240
readonly property color thumbColor: DynamicColors.palette.m3inverseSurface readonly property color thumbColor: Colors.palette.m3inverseSurface
readonly property color thumbContentColor: DynamicColors.palette.m3inverseOnSurface readonly property color thumbContentColor: Colors.palette.m3inverseOnSurface
readonly property color trackColor: DynamicColors.layer(DynamicColors.palette.m3surfaceContainer, 2) readonly property color trackColor: Colors.layer(Colors.palette.m3surfaceContainer, 2)
function hueToAngle(hue) { function hueToAngle(hue) {
return arcStartAngle + arcSweep * hue; return arcStartAngle + arcSweep * hue;
@@ -153,8 +154,8 @@ Item {
anchors.centerIn: parent anchors.centerIn: parent
color: root.drawing?.drawingState.penColor color: root.drawing?.drawingState.penColor
implicitHeight: implicitWidth implicitHeight: implicitWidth
implicitWidth: canvas.height - root.handleSize - Appearance.padding.extraLarge * 2 implicitWidth: canvas.height - root.handleSize - Tokens.padding.extraLarge * 2
radius: Appearance.rounding.full radius: Tokens.rounding.full
Behavior on color { Behavior on color {
enabled: false enabled: false
+6 -5
View File
@@ -1,6 +1,7 @@
import QtQuick import QtQuick
import QtQuick.Controls import QtQuick.Controls
import qs.Config import ZShell.Config
import qs.Services
CheckBox { CheckBox {
id: control id: control
@@ -18,14 +19,14 @@ CheckBox {
indicator: CustomRect { indicator: CustomRect {
// x: control.leftPadding // x: control.leftPadding
// y: parent.implicitHeight / 2 - implicitHeight / 2 // y: parent.implicitHeight / 2 - implicitHeight / 2
border.color: control.checked ? DynamicColors.palette.m3primary : "transparent" border.color: control.checked ? Colors.palette.m3primary : "transparent"
color: DynamicColors.palette.m3surfaceVariant color: Colors.palette.m3surfaceVariant
implicitHeight: control.checkHeight implicitHeight: control.checkHeight
implicitWidth: control.checkWidth implicitWidth: control.checkWidth
radius: Appearance.rounding.smallest / 2 radius: Tokens.rounding.smallest / 2
CustomRect { CustomRect {
color: DynamicColors.palette.m3primary color: Colors.palette.m3primary
implicitHeight: control.checkHeight - (y * 2) implicitHeight: control.checkHeight - (y * 2)
implicitWidth: control.checkWidth - (x * 2) implicitWidth: control.checkWidth - (x * 2)
radius: 3 radius: 3
+8 -7
View File
@@ -5,7 +5,8 @@ import QtQuick.Templates
import ZShell import ZShell
import ZShell.Components import ZShell.Components
import ZShell.Internal import ZShell.Internal
import qs.Config import ZShell.Config
import qs.Services
ProgressBar { ProgressBar {
id: root id: root
@@ -16,8 +17,8 @@ ProgressBar {
Stopped Stopped
} }
property color bgColor: DynamicColors.palette.m3secondaryContainer property color bgColor: Colors.palette.m3secondaryContainer
property color fgColor: DynamicColors.palette.m3primary property color fgColor: Colors.palette.m3primary
property int indeterminateAnimState: CustomProgressBar.Stopped property int indeterminateAnimState: CustomProgressBar.Stopped
property real waveAmplitude: 0.5 property real waveAmplitude: 0.5
property int waveDuration: 1000 property int waveDuration: 1000
@@ -64,7 +65,7 @@ ProgressBar {
LinearIndicatorManager { LinearIndicatorManager {
id: manager id: manager
gap: Appearance.spacing.extraSmall gap: Tokens.spacing.extraSmall
Anim on completeEndProgress { Anim on completeEndProgress {
duration: manager.completeEndDuration duration: manager.completeEndDuration
@@ -94,7 +95,7 @@ ProgressBar {
id: remaining id: remaining
anchors.right: parent.right anchors.right: parent.right
implicitWidth: parent.width - wave.implicitWidth - Appearance.spacing.extraSmall implicitWidth: parent.width - wave.implicitWidth - Tokens.spacing.extraSmall
} }
Line { Line {
@@ -106,7 +107,7 @@ ProgressBar {
color: root.fgColor color: root.fgColor
implicitHeight: implicitSize implicitHeight: implicitSize
implicitWidth: implicitSize implicitWidth: implicitSize
radius: Appearance.rounding.full radius: Tokens.rounding.full
Behavior on implicitSize { Behavior on implicitSize {
Anim { Anim {
@@ -200,7 +201,7 @@ ProgressBar {
color: root.bgColor color: root.bgColor
implicitHeight: parent.height implicitHeight: parent.height
implicitWidth: bounds.y - bounds.x implicitWidth: bounds.y - bounds.x
radius: Appearance.rounding.full radius: Tokens.rounding.full
x: bounds.x x: bounds.x
} }
component Wave: WavyLine { component Wave: WavyLine {
+8 -7
View File
@@ -1,11 +1,12 @@
import QtQuick import QtQuick
import QtQuick.Templates import QtQuick.Templates
import qs.Config import ZShell.Config
import qs.Services
RadioButton { RadioButton {
id: root id: root
font.pointSize: Appearance.font.size.normal font.pointSize: Tokens.font.size.normal
implicitHeight: Math.max(implicitIndicatorHeight, implicitContentHeight) implicitHeight: Math.max(implicitIndicatorHeight, implicitContentHeight)
implicitWidth: implicitIndicatorWidth + implicitContentWidth + contentItem.anchors.leftMargin implicitWidth: implicitIndicatorWidth + implicitContentWidth + contentItem.anchors.leftMargin
@@ -20,12 +21,12 @@ RadioButton {
id: outerCircle id: outerCircle
anchors.verticalCenter: parent.verticalCenter 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 border.width: 2
color: "transparent" color: "transparent"
implicitHeight: 16 implicitHeight: 16
implicitWidth: 16 implicitWidth: 16
radius: Appearance.rounding.full radius: Tokens.rounding.full
Behavior on border.color { Behavior on border.color {
CAnim { CAnim {
@@ -34,7 +35,7 @@ RadioButton {
StateLayer { StateLayer {
anchors.margins: -7 anchors.margins: -7
color: root.checked ? DynamicColors.palette.m3onSurface : DynamicColors.palette.m3primary color: root.checked ? Colors.palette.m3onSurface : Colors.palette.m3primary
z: -1 z: -1
onClicked: { onClicked: {
@@ -44,10 +45,10 @@ RadioButton {
CustomRect { CustomRect {
anchors.centerIn: parent 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 implicitHeight: 8
implicitWidth: 8 implicitWidth: 8
radius: Appearance.rounding.full radius: Tokens.rounding.full
} }
} }
} }
+7 -6
View File
@@ -1,7 +1,8 @@
import QtQuick import QtQuick
import QtQuick.Templates import QtQuick.Templates
import qs.Helpers import qs.Helpers
import qs.Config import ZShell.Config
import qs.Services
ScrollBar { ScrollBar {
id: root id: root
@@ -17,7 +18,7 @@ ScrollBar {
readonly property real travelScale: root.rawTravel > 0 ? root.effectiveTravel / root.rawTravel : 0 readonly property real travelScale: root.rawTravel > 0 ? root.effectiveTravel / root.rawTravel : 0
enabled: !Visibilities.getForActive().isDrawing enabled: !Visibilities.getForActive().isDrawing
implicitWidth: Appearance.padding.extraSmall * 2 implicitWidth: Tokens.padding.extraSmall * 2
contentItem: Item { contentItem: Item {
} }
@@ -51,15 +52,15 @@ ScrollBar {
anchors.right: parent.right anchors.right: parent.right
anchors.top: parent.top anchors.top: parent.top
implicitWidth: handle.implicitWidth implicitWidth: handle.implicitWidth
radius: Appearance.rounding.full radius: Tokens.rounding.full
CustomRect { CustomRect {
id: handle id: handle
anchors.right: parent.right anchors.right: parent.right
color: DynamicColors.palette.m3secondary color: Colors.palette.m3secondary
implicitHeight: root.height * root.effectiveSize 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: { opacity: {
if (!root.enabled) if (!root.enabled)
return 0; return 0;
@@ -73,7 +74,7 @@ ScrollBar {
return 0.6; return 0.6;
return 0; 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 y: root.reversed ? root.height * (1 + root.nonAnimY) * root.travelScale : root.height * root.nonAnimY * root.travelScale
Behavior on implicitWidth { Behavior on implicitWidth {
+17 -16
View File
@@ -5,20 +5,21 @@ import QtQuick.Templates
import ZShell.Components import ZShell.Components
import ZShell import ZShell
import qs.Components import qs.Components
import qs.Config import ZShell.Config
import qs.Services
Slider { Slider {
id: root id: root
property bool animateWave property bool animateWave
property color bgColor: enabled ? DynamicColors.palette.m3secondaryContainer : Qt.alpha(DynamicColors.palette.m3onSurface, 0.1) property color bgColor: enabled ? Colors.palette.m3secondaryContainer : Qt.alpha(Colors.palette.m3onSurface, 0.1)
property color fgColor: enabled ? DynamicColors.palette.m3primary : Qt.alpha(DynamicColors.palette.m3onSurface, 0.38) property color fgColor: enabled ? Colors.palette.m3primary : Qt.alpha(Colors.palette.m3onSurface, 0.38)
property real filledWidth property real filledWidth
property alias inset: inset 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 string insetIcon: ""
property real pos: visualPosition property real pos: visualPosition
property int radius: Appearance.rounding.small property int radius: Tokens.rounding.small
property int waveDuration: 1000 property int waveDuration: 1000
property real waveFrequency: 6 property real waveFrequency: 6
property bool wavy property bool wavy
@@ -35,15 +36,15 @@ Slider {
id: remaining id: remaining
anchors.left: handle.right anchors.left: handle.right
anchors.leftMargin: Appearance.spacing.extraSmall anchors.leftMargin: Tokens.spacing.extraSmall
anchors.right: parent.right anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
bottomLeftRadius: Appearance.rounding.extraSmall / 2 bottomLeftRadius: Tokens.rounding.extraSmall / 2
color: root.bgColor color: root.bgColor
implicitHeight: parent.height * (parent.height <= 12 ? opacity : Math.min(opacity * 2, 1)) implicitHeight: parent.height * (parent.height <= 12 ? opacity : Math.min(opacity * 2, 1))
opacity: Math.min(width, 12) / 12 opacity: Math.min(width, 12) / 12
radius: root.radius radius: root.radius
topLeftRadius: Appearance.rounding.extraSmall / 2 topLeftRadius: Tokens.rounding.extraSmall / 2
} }
CustomRect { CustomRect {
@@ -54,14 +55,14 @@ Slider {
implicitHeight: 4 * remaining.opacity implicitHeight: 4 * remaining.opacity
implicitWidth: implicitHeight implicitWidth: implicitHeight
opacity: remaining.opacity opacity: remaining.opacity
radius: Appearance.rounding.full radius: Tokens.rounding.full
} }
CustomRect { CustomRect {
id: handle id: handle
anchors.left: filled.right anchors.left: filled.right
anchors.leftMargin: Appearance.spacing.extraSmall anchors.leftMargin: Tokens.spacing.extraSmall
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
color: root.fgColor color: root.fgColor
implicitHeight: { implicitHeight: {
@@ -70,7 +71,7 @@ Slider {
return parent.height * (mouse.pressed ? lerp(3.5, 1.5) : lerp(3, 1.2)); return parent.height * (mouse.pressed ? lerp(3.5, 1.5) : lerp(3, 1.2));
} }
implicitWidth: 4 implicitWidth: 4
radius: Appearance.rounding.full radius: Tokens.rounding.full
Behavior on implicitHeight { Behavior on implicitHeight {
Anim { Anim {
@@ -91,17 +92,17 @@ Slider {
MaterialIcon { MaterialIcon {
id: inset 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 property real dockT: attached ? 1 : 0
anchors.bottom: parent.bottom anchors.bottom: parent.bottom
anchors.top: parent.top anchors.top: parent.top
color: root.insetColor color: root.insetColor
font.pixelSize: Appearance.font.size.smaller * 2 font.pixelSize: Tokens.font.size.smaller * 2
text: root.insetIcon text: root.insetIcon
verticalAlignment: Text.AlignVCenter verticalAlignment: Text.AlignVCenter
visible: !root.wavy && root.insetIcon !== "" 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 { Behavior on dockT {
Anim { Anim {
@@ -113,12 +114,12 @@ Slider {
id: lineComp id: lineComp
CustomRect { CustomRect {
bottomRightRadius: Appearance.rounding.extraSmall / 2 bottomRightRadius: Tokens.rounding.extraSmall / 2
color: root.fgColor color: root.fgColor
implicitHeight: root.height implicitHeight: root.height
implicitWidth: root.filledWidth implicitWidth: root.filledWidth
radius: root.radius radius: root.radius
topRightRadius: Appearance.rounding.extraSmall / 2 topRightRadius: Tokens.rounding.extraSmall / 2
} }
} }
+19 -18
View File
@@ -1,6 +1,7 @@
import QtQuick import QtQuick
import QtQuick.Templates import QtQuick.Templates
import qs.Config import ZShell.Config
import qs.Services
DoubleSpinBox { DoubleSpinBox {
id: root id: root
@@ -29,36 +30,36 @@ DoubleSpinBox {
editable: true editable: true
implicitHeight: Math.max(up.indicator.implicitHeight, down.indicator.implicitHeight, contentItem.implicitHeight) + topPadding + bottomPadding implicitHeight: Math.max(up.indicator.implicitHeight, down.indicator.implicitHeight, contentItem.implicitHeight) + topPadding + bottomPadding
implicitWidth: contentItem.implicitWidth + leftPadding + rightPadding implicitWidth: contentItem.implicitWidth + leftPadding + rightPadding
leftPadding: up.indicator.implicitWidth + Appearance.spacing.extraSmall / 2 leftPadding: up.indicator.implicitWidth + Tokens.spacing.extraSmall / 2
rightPadding: down.indicator.implicitWidth + Appearance.spacing.extraSmall / 2 rightPadding: down.indicator.implicitWidth + Tokens.spacing.extraSmall / 2
spacing: Appearance.spacing.small spacing: Tokens.spacing.small
contentItem: TextFieldBase { contentItem: TextFieldBase {
horizontalAlignment: TextField.AlignHCenter horizontalAlignment: TextField.AlignHCenter
implicitWidth: 65 implicitWidth: 65
inputMethodHints: Qt.ImhFormattedNumbersOnly inputMethodHints: Qt.ImhFormattedNumbersOnly
leftPadding: Appearance.padding.larger leftPadding: Tokens.padding.larger
readOnly: !root.editable readOnly: !root.editable
rightPadding: Appearance.padding.larger rightPadding: Tokens.padding.larger
text: root.textFromValue(root.value, root.locale) text: root.textFromValue(root.value, root.locale)
validator: root.validator validator: root.validator
background: CustomRect { background: CustomRect {
color: DynamicColors.layer(DynamicColors.palette.m3surfaceContainerHighest, root.cLayer) color: Colors.layer(Colors.palette.m3surfaceContainerHighest, root.cLayer)
radius: Appearance.rounding.extraSmall radius: Tokens.rounding.extraSmall
} }
} }
down.indicator: IconButton { down.indicator: IconButton {
id: downButton id: downButton
bottomRightRadius: pressed ? Appearance.rounding.small : Appearance.rounding.extraSmall bottomRightRadius: pressed ? Tokens.rounding.small : Tokens.rounding.extraSmall
color: enabled ? DynamicColors.layer(DynamicColors.palette.m3surfaceContainerHighest, root.cLayer) : disabledColor color: enabled ? Colors.layer(Colors.palette.m3surfaceContainerHighest, root.cLayer) : disabledColor
disabledColor: Qt.alpha(DynamicColors.palette.m3surfaceContainerHighest, 0.4) disabledColor: Qt.alpha(Colors.palette.m3surfaceContainerHighest, 0.4)
icon: "remove" icon: "remove"
isRound: true isRound: true
label.anchors.horizontalCenterOffset: pressed ? 0 : 2 label.anchors.horizontalCenterOffset: pressed ? 0 : 2
padding: Appearance.padding.extraSmall padding: Tokens.padding.extraSmall
topRightRadius: pressed ? Appearance.rounding.small : Appearance.rounding.extraSmall topRightRadius: pressed ? Tokens.rounding.small : Tokens.rounding.extraSmall
type: IconButton.Text type: IconButton.Text
Behavior on bottomRightRadius { Behavior on bottomRightRadius {
@@ -81,14 +82,14 @@ DoubleSpinBox {
id: upButton id: upButton
anchors.right: parent.right anchors.right: parent.right
bottomLeftRadius: pressed ? Appearance.rounding.small : Appearance.rounding.extraSmall bottomLeftRadius: pressed ? Tokens.rounding.small : Tokens.rounding.extraSmall
color: enabled ? DynamicColors.layer(DynamicColors.palette.m3surfaceContainerHighest, root.cLayer) : disabledColor color: enabled ? Colors.layer(Colors.palette.m3surfaceContainerHighest, root.cLayer) : disabledColor
disabledColor: Qt.alpha(DynamicColors.palette.m3surfaceContainerHighest, 0.4) disabledColor: Qt.alpha(Colors.palette.m3surfaceContainerHighest, 0.4)
icon: "add" icon: "add"
isRound: true isRound: true
label.anchors.horizontalCenterOffset: pressed ? 0 : -2 label.anchors.horizontalCenterOffset: pressed ? 0 : -2
padding: Appearance.padding.extraSmall padding: Tokens.padding.extraSmall
topLeftRadius: pressed ? Appearance.rounding.small : Appearance.rounding.extraSmall topLeftRadius: pressed ? Tokens.rounding.small : Tokens.rounding.extraSmall
type: IconButton.Text type: IconButton.Text
Behavior on bottomLeftRadius { Behavior on bottomLeftRadius {
+16 -15
View File
@@ -1,6 +1,7 @@
import QtQuick import QtQuick
import QtQuick.Layouts import QtQuick.Layouts
import qs.Config import ZShell.Config
import qs.Services
Row { Row {
id: root id: root
@@ -11,14 +12,14 @@ Row {
} }
property alias active: menu.active property alias active: menu.active
property color color: type == CustomSplitButton.Filled ? DynamicColors.palette.m3primary : DynamicColors.palette.m3secondaryContainer property color color: type == CustomSplitButton.Filled ? Colors.palette.m3primary : Colors.palette.m3secondaryContainer
property color disabledColor: Qt.alpha(DynamicColors.palette.m3onSurface, 0.1) property color disabledColor: Qt.alpha(Colors.palette.m3onSurface, 0.1)
property color disabledTextColor: Qt.alpha(DynamicColors.palette.m3onSurface, 0.38) property color disabledTextColor: Qt.alpha(Colors.palette.m3onSurface, 0.38)
readonly property alias expandBtn: expandBtn readonly property alias expandBtn: expandBtn
property alias expanded: menu.expanded property alias expanded: menu.expanded
property string fallbackIcon property string fallbackIcon
property string fallbackText property string fallbackText
property real horizontalPadding: Appearance.padding.larger property real horizontalPadding: Tokens.padding.larger
readonly property alias iconLabel: iconLabel readonly property alias iconLabel: iconLabel
readonly property alias label: label readonly property alias label: label
readonly property alias menu: menu readonly property alias menu: menu
@@ -26,20 +27,20 @@ Row {
property bool menuOnTop property bool menuOnTop
property real minLeftWidth property real minLeftWidth
readonly property alias stateLayer: stateLayer 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 readonly property alias textRow: textRow
property int type: CustomSplitButton.Filled 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 { CustomRect {
bottomRightRadius: Appearance.rounding.small / 2 bottomRightRadius: Tokens.rounding.small / 2
color: !root.enabled ? root.disabledColor : root.color color: !root.enabled ? root.disabledColor : root.color
implicitHeight: expandBtn.implicitHeight implicitHeight: expandBtn.implicitHeight
implicitWidth: Math.max(root.minLeftWidth, textRow.implicitWidth + root.horizontalPadding * 2) implicitWidth: Math.max(root.minLeftWidth, textRow.implicitWidth + root.horizontalPadding * 2)
radius: implicitHeight / 2 * Math.min(1, Appearance.rounding.scale) radius: implicitHeight / 2 * Math.min(1, Tokens.rounding.scale)
topRightRadius: Appearance.rounding.small / 2 topRightRadius: Tokens.rounding.small / 2
StateLayer { StateLayer {
id: stateLayer id: stateLayer
@@ -57,7 +58,7 @@ Row {
anchors.centerIn: parent anchors.centerIn: parent
anchors.horizontalCenterOffset: Math.floor(root.verticalPadding / 4) anchors.horizontalCenterOffset: Math.floor(root.verticalPadding / 4)
spacing: Appearance.spacing.small spacing: Tokens.spacing.small
MaterialIcon { MaterialIcon {
id: iconLabel id: iconLabel
@@ -91,13 +92,13 @@ Row {
CustomRect { CustomRect {
id: expandBtn 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 bottomLeftRadius: rad
color: !root.enabled ? root.disabledColor : root.color color: !root.enabled ? root.disabledColor : root.color
implicitHeight: expandIcon.implicitHeight + root.verticalPadding * 2 implicitHeight: expandIcon.implicitHeight + root.verticalPadding * 2
implicitWidth: implicitHeight implicitWidth: implicitHeight
radius: implicitHeight / 2 * Math.min(1, Appearance.rounding.scale) radius: implicitHeight / 2 * Math.min(1, Tokens.rounding.scale)
topLeftRadius: rad topLeftRadius: rad
Behavior on rad { Behavior on rad {
@@ -141,7 +142,7 @@ Row {
attachSideY: root.menuOnTop ? Menu.Top : Menu.Bottom attachSideY: root.menuOnTop ? Menu.Top : Menu.Bottom
attachTo: expandBtn 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 thisSideY: root.menuOnTop ? Menu.Bottom : Menu.Top
} }
} }
+7 -6
View File
@@ -2,7 +2,8 @@ pragma ComponentBehavior: Bound
import QtQuick import QtQuick
import QtQuick.Layouts import QtQuick.Layouts
import qs.Config import ZShell.Config
import qs.Services
Item { Item {
id: root id: root
@@ -21,7 +22,7 @@ Item {
anchors.left: parent.left anchors.left: parent.left
anchors.right: parent.right anchors.right: parent.right
clip: false clip: false
implicitHeight: row.implicitHeight + Appearance.padding.smaller * 2 implicitHeight: row.implicitHeight + Tokens.padding.smaller * 2
opacity: shouldBeActive ? 1 : 0 opacity: shouldBeActive ? 1 : 0
scale: shouldBeActive ? 1 : 0.8 scale: shouldBeActive ? 1 : 0.8
z: splitButton.menu.implicitHeight > 0 ? expandedZ : 1 z: splitButton.menu.implicitHeight > 0 ? expandedZ : 1
@@ -39,15 +40,15 @@ Item {
id: row id: row
anchors.left: parent.left anchors.left: parent.left
anchors.margins: Appearance.padding.small anchors.margins: Tokens.padding.small
anchors.right: parent.right anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
spacing: Appearance.spacing.normal spacing: Tokens.spacing.normal
CustomText { CustomText {
Layout.fillWidth: true Layout.fillWidth: true
color: root.enabled ? DynamicColors.palette.m3onSurface : DynamicColors.palette.m3onSurfaceVariant color: root.enabled ? Colors.palette.m3onSurface : Colors.palette.m3onSurfaceVariant
font.pointSize: Appearance.font.size.larger font.pointSize: Tokens.font.size.larger
text: root.label text: root.label
} }
+15 -14
View File
@@ -1,7 +1,8 @@
import QtQuick import QtQuick
import QtQuick.Shapes import QtQuick.Shapes
import QtQuick.Templates import QtQuick.Templates
import qs.Config import ZShell.Config
import qs.Services
Switch { Switch {
id: root id: root
@@ -12,20 +13,20 @@ Switch {
implicitWidth: implicitIndicatorWidth implicitWidth: implicitIndicatorWidth
indicator: CustomRect { indicator: CustomRect {
color: root.checked && root.enabled ? DynamicColors.palette.m3primary : DynamicColors.layer(DynamicColors.palette.m3surfaceContainerHighest, root.cLayer) color: root.checked && root.enabled ? Colors.palette.m3primary : Colors.layer(Colors.palette.m3surfaceContainerHighest, root.cLayer)
implicitHeight: Appearance.font.size.medium + Appearance.padding.normal * 2 implicitHeight: Tokens.font.size.medium + Tokens.padding.normal * 2
implicitWidth: implicitHeight * 1.7 implicitWidth: implicitHeight * 1.7
radius: Appearance.rounding.full radius: Tokens.rounding.full
CustomRect { CustomRect {
readonly property real nonAnimWidth: root.pressed ? implicitHeight * 1.2 : implicitHeight readonly property real nonAnimWidth: root.pressed ? implicitHeight * 1.2 : implicitHeight
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
color: root.checked && root.enabled ? DynamicColors.palette.m3onPrimary : DynamicColors.layer(DynamicColors.palette.m3outline, root.cLayer + 1) color: root.checked && root.enabled ? Colors.palette.m3onPrimary : Colors.layer(Colors.palette.m3outline, root.cLayer + 1)
implicitHeight: parent.implicitHeight - Appearance.padding.extraSmall implicitHeight: parent.implicitHeight - Tokens.padding.extraSmall
implicitWidth: nonAnimWidth implicitWidth: nonAnimWidth
radius: Appearance.rounding.full radius: Tokens.rounding.full
x: root.checked ? parent.implicitWidth - nonAnimWidth - Appearance.padding.extraSmall / 2 : Appearance.padding.extraSmall / 2 x: root.checked ? parent.implicitWidth - nonAnimWidth - Tokens.padding.extraSmall / 2 : Tokens.padding.extraSmall / 2
Behavior on implicitWidth { Behavior on implicitWidth {
Anim { Anim {
@@ -40,7 +41,7 @@ Switch {
CustomRect { CustomRect {
anchors.fill: parent 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 opacity: root.pressed ? 0.1 : root.hovered ? 0.08 : 0
radius: parent.radius radius: parent.radius
@@ -91,7 +92,7 @@ Switch {
anchors.centerIn: parent anchors.centerIn: parent
asynchronous: true asynchronous: true
height: parent.implicitHeight - Appearance.padding.larger height: parent.implicitHeight - Tokens.padding.larger
preferredRendererType: Shape.CurveRenderer preferredRendererType: Shape.CurveRenderer
width: height width: height
@@ -117,8 +118,8 @@ Switch {
fillColor: "transparent" fillColor: "transparent"
startX: icon.start1.x startX: icon.start1.x
startY: icon.start1.y startY: icon.start1.y
strokeColor: root.checked && root.enabled ? DynamicColors.palette.m3primary : DynamicColors.palette.m3surfaceContainerHighest strokeColor: root.checked && root.enabled ? Colors.palette.m3primary : Colors.palette.m3surfaceContainerHighest
strokeWidth: Appearance.font.size.larger * 0.15 strokeWidth: Tokens.font.size.larger * 0.15
Behavior on strokeColor { Behavior on strokeColor {
CAnim { CAnim {
@@ -151,7 +152,7 @@ Switch {
} }
component PropAnim: PropertyAnimation { component PropAnim: PropertyAnimation {
duration: Appearance.anim.durations.expressiveFastSpatial duration: Tokens.anim.durations.expressiveFastSpatial
easing.bezierCurve: Appearance.anim.curves.expressiveFastSpatial easing.bezierCurve: Tokens.anim.curves.expressiveFastSpatial
} }
} }
+6 -5
View File
@@ -1,7 +1,8 @@
pragma ComponentBehavior: Bound pragma ComponentBehavior: Bound
import QtQuick import QtQuick
import qs.Config import ZShell.Config
import qs.Services
Text { Text {
id: root id: root
@@ -12,10 +13,10 @@ Text {
property string animateProp: "scale" property string animateProp: "scale"
property real animateTo: 1 property real animateTo: 1
color: DynamicColors.palette.m3onSurface color: Colors.palette.m3onSurface
font.family: Appearance.font.family.sans font.family: Config.appearance.font.family.sans
font.pointSize: Appearance.font.size.normal font.pointSize: Tokens.font.size.normal
linkColor: DynamicColors.palette.m3onPrimaryFixedVariant linkColor: Colors.palette.m3onPrimaryFixedVariant
renderType: Text.NativeRendering renderType: Text.NativeRendering
textFormat: Text.PlainText textFormat: Text.PlainText
+23 -22
View File
@@ -2,7 +2,8 @@ pragma ComponentBehavior: Bound
import QtQuick import QtQuick
import QtQuick.Shapes import QtQuick.Shapes
import qs.Config import ZShell.Config
import qs.Services
TextFieldBase { TextFieldBase {
id: root id: root
@@ -16,26 +17,26 @@ TextFieldBase {
readonly property string effectiveSupportingText: isError && errorText ? errorText : supportingText readonly property string effectiveSupportingText: isError && errorText ? errorText : supportingText
property bool emptyIsValid: true property bool emptyIsValid: true
property string errorText property string errorText
readonly property int filledOffset: type === CustomTextField.Filled ? Appearance.spacing.small : 0 readonly property int filledOffset: type === CustomTextField.Filled ? Tokens.spacing.small : 0
readonly property int horizontalPadding: Appearance.padding.large readonly property int horizontalPadding: Tokens.padding.large
property bool isError property bool isError
property string leadingIcon property string leadingIcon
readonly property int leadingOffset: leadingIcon ? leadingIconLoader.width + leadingIconLoader.anchors.leftMargin : 0 readonly property int leadingOffset: leadingIcon ? leadingIconLoader.width + leadingIconLoader.anchors.leftMargin : 0
property int radius: Appearance.rounding.small property int radius: Tokens.rounding.small
readonly property real smallFontScale: smallFontSize / font.pointSize readonly property real smallFontScale: smallFontSize / font.pointSize
property int smallFontSize: Appearance.font.size.small property int smallFontSize: Tokens.font.size.small
property string supportingText 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 property string trailingIcon
readonly property int trailingOffset: trailingIcon ? trailingIconLoader.width + trailingIconLoader.anchors.rightMargin : 0 readonly property int trailingOffset: trailingIcon ? trailingIconLoader.width + trailingIconLoader.anchors.rightMargin : 0
property int type: CustomTextField.Outlined property int type: CustomTextField.Outlined
readonly property bool valid: !validate || (!text && emptyIsValid) || (validate instanceof RegExp ? validate.test(text) : !!validate(text)) readonly property bool valid: !validate || (!text && emptyIsValid) || (validate instanceof RegExp ? validate.test(text) : !!validate(text))
property var validate // Regex or function property var validate // Regex or function
bottomPadding: Appearance.padding.large + supportingTextOffset - filledOffset bottomPadding: Tokens.padding.large + supportingTextOffset - filledOffset
leftPadding: horizontalPadding + leadingOffset leftPadding: horizontalPadding + leadingOffset
rightPadding: horizontalPadding + trailingOffset rightPadding: horizontalPadding + trailingOffset
topPadding: Appearance.padding.large + filledOffset topPadding: Tokens.padding.large + filledOffset
background: Loader { background: Loader {
anchors.bottomMargin: root.supportingTextOffset anchors.bottomMargin: root.supportingTextOffset
@@ -80,9 +81,9 @@ TextFieldBase {
anchors.left: parent.left anchors.left: parent.left
anchors.leftMargin: root.leftPadding anchors.leftMargin: root.leftPadding
anchors.topMargin: Appearance.padding.extraSmall anchors.topMargin: Tokens.padding.extraSmall
anchors.verticalCenter: parent.verticalCenter 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.family: root.font.family
font.pointSize: root.font.pointSize font.pointSize: root.font.pointSize
font.variableAxes: root.font.variableAxes font.variableAxes: root.font.variableAxes
@@ -128,8 +129,8 @@ TextFieldBase {
} }
AnchorAnim { AnchorAnim {
duration: Appearance.anim.durations.expressiveEffects duration: Tokens.anim.durations.expressiveEffects
easing.bezierCurve: Appearance.anim.curves.expressiveEffects easing.bezierCurve: Tokens.anim.curves.expressiveEffects
} }
} }
} }
@@ -139,11 +140,11 @@ TextFieldBase {
active: root.leadingIcon active: root.leadingIcon
anchors.left: parent.left anchors.left: parent.left
anchors.leftMargin: Appearance.padding.normal anchors.leftMargin: Tokens.padding.normal
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
sourceComponent: MaterialIcon { sourceComponent: MaterialIcon {
color: DynamicColors.palette.m3onSurfaceVariant color: Colors.palette.m3onSurfaceVariant
text: root.leadingIcon text: root.leadingIcon
} }
} }
@@ -153,11 +154,11 @@ TextFieldBase {
active: root.trailingIcon active: root.trailingIcon
anchors.right: parent.right anchors.right: parent.right
anchors.rightMargin: Appearance.padding.normal anchors.rightMargin: Tokens.padding.normal
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
sourceComponent: MaterialIcon { sourceComponent: MaterialIcon {
color: DynamicColors.palette.m3onSurfaceVariant color: Colors.palette.m3onSurfaceVariant
text: root.trailingIcon text: root.trailingIcon
} }
} }
@@ -172,8 +173,8 @@ TextFieldBase {
anchors.leftMargin: root.horizontalPadding anchors.leftMargin: root.horizontalPadding
sourceComponent: CustomText { sourceComponent: CustomText {
color: root.isError ? DynamicColors.palette.m3error : DynamicColors.palette.m3onSurfaceVariant color: root.isError ? Colors.palette.m3error : Colors.palette.m3onSurfaceVariant
font.pointSize: Appearance.font.size.small font.pointSize: Tokens.font.size.small
text: root.effectiveSupportingText text: root.effectiveSupportingText
} }
} }
@@ -195,14 +196,14 @@ TextFieldBase {
id: path id: path
readonly property real inset: strokeWidth / 2 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 property real outlineGapScale: root.activeFocus || root.text ? 1 : 0
capStyle: ShapePath.RoundCap capStyle: ShapePath.RoundCap
fillColor: "transparent" fillColor: "transparent"
startX: path.inset + root.horizontalPadding - root.clampedRadius + path.outlineGap * (1 - path.outlineGapScale) / 2 + path.outlineGap * path.outlineGapScale startX: path.inset + root.horizontalPadding - root.clampedRadius + path.outlineGap * (1 - path.outlineGapScale) / 2 + path.outlineGap * path.outlineGapScale
startY: path.inset 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 strokeWidth: root.activeFocus ? 2 : 1
Behavior on outlineGapScale { Behavior on outlineGapScale {
@@ -279,7 +280,7 @@ TextFieldBase {
id: filledComp id: filledComp
CustomRect { CustomRect {
color: root.activeFocus ? DynamicColors.tPalette.m3surfaceContainerHighest : DynamicColors.tPalette.m3surfaceContainerHigh color: root.activeFocus ? Colors.tPalette.m3surfaceContainerHighest : Colors.tPalette.m3surfaceContainerHigh
topLeftRadius: root.clampedRadius topLeftRadius: root.clampedRadius
topRightRadius: root.clampedRadius topRightRadius: root.clampedRadius
@@ -287,7 +288,7 @@ TextFieldBase {
anchors.bottom: parent.bottom anchors.bottom: parent.bottom
anchors.left: parent.left anchors.left: parent.left
anchors.right: parent.right 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 implicitHeight: root.activeFocus ? 2 : 1
Behavior on implicitHeight { Behavior on implicitHeight {
+6 -5
View File
@@ -1,15 +1,16 @@
import QtQuick import QtQuick
import QtQuick.Controls import QtQuick.Controls
import qs.Config import ZShell.Config
import qs.Services
TextInput { TextInput {
renderType: Text.NativeRendering renderType: Text.NativeRendering
selectedTextColor: DynamicColors.palette.m3onSecondaryContainer selectedTextColor: Colors.palette.m3onSecondaryContainer
selectionColor: DynamicColors.tPalette.colSecondaryContainer selectionColor: Colors.tPalette.colSecondaryContainer
font { font {
family: Appearance?.font.family.sans ?? "sans-serif" family: Config.appearance?.font.family.sans ?? "sans-serif"
hintingPreference: Font.PreferFullHinting hintingPreference: Font.PreferFullHinting
pixelSize: Appearance?.font.size.normal ?? 15 pixelSize: Config.appearance?.font.size.normal ?? 15
} }
} }
+3 -2
View File
@@ -1,13 +1,14 @@
import QtQuick import QtQuick
import QtQuick.Effects import QtQuick.Effects
import qs.Config import ZShell.Config
import qs.Services
RectangularShadow { RectangularShadow {
property real dp: [0, 1, 3, 6, 8, 12][level] property real dp: [0, 1, 3, 6, 8, 12][level]
property int level property int level
blur: (dp * 5) ** 0.7 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 offset.y: dp / 2
spread: -dp * 0.3 + (dp * 0.1) ** 2 spread: -dp * 0.3 + (dp * 0.1) ** 2
+1 -1
View File
@@ -1,6 +1,6 @@
import QtQuick import QtQuick
import Quickshell import Quickshell
import qs.Config import ZShell.Config
Image { Image {
id: root id: root
+1 -1
View File
@@ -1,5 +1,5 @@
import QtQuick import QtQuick
import qs.Config import ZShell.Config
BaseStyledSlider { BaseStyledSlider {
id: root id: root
+1 -1
View File
@@ -1,5 +1,5 @@
import QtQuick import QtQuick
import qs.Config import ZShell.Config
BaseStyledSlider { BaseStyledSlider {
id: root id: root
+9 -8
View File
@@ -1,5 +1,6 @@
import QtQuick import QtQuick
import qs.Config import ZShell.Config
import qs.Services
ButtonBase { ButtonBase {
id: root id: root
@@ -7,8 +8,8 @@ ButtonBase {
property alias icon: label.text property alias icon: label.text
readonly property alias label: label readonly property alias label: label
activeColor: type === IconButton.Filled ? DynamicColors.palette.m3primary : DynamicColors.palette.m3secondary activeColor: type === IconButton.Filled ? Colors.palette.m3primary : Colors.palette.m3secondary
activeOnColor: type === IconButton.Filled ? DynamicColors.palette.m3onPrimary : type === IconButton.Tonal ? DynamicColors.palette.m3onSecondary : DynamicColors.palette.m3primary activeOnColor: type === IconButton.Filled ? Colors.palette.m3onPrimary : type === IconButton.Tonal ? Colors.palette.m3onSecondary : Colors.palette.m3primary
implicitHeight: { implicitHeight: {
const h = label.implicitHeight + padding * 2; const h = label.implicitHeight + padding * 2;
if (h % 2 !== 0) if (h % 2 !== 0)
@@ -18,15 +19,15 @@ ButtonBase {
implicitWidth: implicitHeight implicitWidth: implicitHeight
inactiveColor: { inactiveColor: {
if (!isToggle && type === IconButton.Filled) if (!isToggle && type === IconButton.Filled)
return DynamicColors.palette.m3primary; return Colors.palette.m3primary;
return type === IconButton.Filled ? DynamicColors.tPalette.m3surfaceContainer : DynamicColors.palette.m3secondaryContainer; return type === IconButton.Filled ? Colors.tPalette.m3surfaceContainer : Colors.palette.m3secondaryContainer;
} }
inactiveOnColor: { inactiveOnColor: {
if (!isToggle && type === IconButton.Filled) if (!isToggle && type === IconButton.Filled)
return DynamicColors.palette.m3onPrimary; return Colors.palette.m3onPrimary;
return type === IconButton.Tonal ? DynamicColors.palette.m3onSecondaryContainer : DynamicColors.palette.m3onSurfaceVariant; 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 { MaterialIcon {
id: label id: label
+13 -12
View File
@@ -1,6 +1,7 @@
import QtQuick import QtQuick
import QtQuick.Layouts import QtQuick.Layouts
import qs.Config import ZShell.Config
import qs.Services
ButtonBase { ButtonBase {
id: root id: root
@@ -10,34 +11,34 @@ ButtonBase {
readonly property alias label: label readonly property alias label: label
property alias text: label.text 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: { activeOnColor: {
if (type === TextButton.Text) if (type === TextButton.Text)
return DynamicColors.palette.m3primary; return Colors.palette.m3primary;
return type === TextButton.Filled ? DynamicColors.palette.m3onPrimary : DynamicColors.palette.m3onSecondary; return type === TextButton.Filled ? Colors.palette.m3onPrimary : Colors.palette.m3onSecondary;
} }
horizontalPadding: Appearance.padding.larger horizontalPadding: Tokens.padding.larger
implicitHeight: row.implicitHeight + verticalPadding * 2 implicitHeight: row.implicitHeight + verticalPadding * 2
implicitWidth: row.implicitWidth + horizontalPadding * 2 implicitWidth: row.implicitWidth + horizontalPadding * 2
inactiveColor: { inactiveColor: {
if (!isToggle && type === TextButton.Filled) if (!isToggle && type === TextButton.Filled)
return DynamicColors.palette.m3primary; return Colors.palette.m3primary;
return type === TextButton.Filled ? DynamicColors.tPalette.m3surfaceContainer : DynamicColors.palette.m3secondaryContainer; return type === TextButton.Filled ? Colors.tPalette.m3surfaceContainer : Colors.palette.m3secondaryContainer;
} }
inactiveOnColor: { inactiveOnColor: {
if (!isToggle && type === TextButton.Filled) if (!isToggle && type === TextButton.Filled)
return DynamicColors.palette.m3onPrimary; return Colors.palette.m3onPrimary;
if (type === TextButton.Text) if (type === TextButton.Text)
return DynamicColors.palette.m3primary; return Colors.palette.m3primary;
return type === TextButton.Filled ? DynamicColors.palette.m3onSurface : DynamicColors.palette.m3onSecondaryContainer; return type === TextButton.Filled ? Colors.palette.m3onSurface : Colors.palette.m3onSecondaryContainer;
} }
verticalPadding: Appearance.padding.small verticalPadding: Tokens.padding.small
RowLayout { RowLayout {
id: row id: row
anchors.centerIn: parent anchors.centerIn: parent
spacing: Appearance.spacing.small spacing: Tokens.spacing.small
MaterialIcon { MaterialIcon {
id: iconLabel id: iconLabel
+3 -2
View File
@@ -1,7 +1,8 @@
import QtQuick import QtQuick
import Quickshell import Quickshell
import M3Shapes import M3Shapes
import qs.Config import ZShell.Config
import qs.Services
MaterialShape { MaterialShape {
id: root id: root
@@ -48,7 +49,7 @@ MaterialShape {
return [pos, vel]; return [pos, vel];
} }
color: DynamicColors.palette.m3primary color: Colors.palette.m3primary
implicitSize: 38 implicitSize: 38
toShape: shapes[0] toShape: shapes[0]
+3 -2
View File
@@ -1,12 +1,13 @@
import QtQuick import QtQuick
import qs.Config import ZShell.Config
import qs.Services
Item { Item {
id: root id: root
property alias anim: marqueeAnim property alias anim: marqueeAnim
property bool animate: false property bool animate: false
property color color: DynamicColors.palette.m3onSurface property color color: Colors.palette.m3onSurface
property int fadeStrengthAnimMs: 180 property int fadeStrengthAnimMs: 180
property real fadeStrengthIdle: 0.0 property real fadeStrengthIdle: 0.0
property real fadeStrengthMoving: 1.0 property real fadeStrengthMoving: 1.0
+4 -3
View File
@@ -1,11 +1,12 @@
import qs.Config import ZShell.Config
import qs.Services
CustomText { CustomText {
id: root id: root
readonly property list<int> allowed: [20, 24, 40, 48] readonly property list<int> allowed: [20, 24, 40, 48]
property real fill: 0 property real fill: 0
property int grade: DynamicColors.light ? 0 : -25 property int grade: Colors.light ? 0 : -25
readonly property int opsz: clampOpsz(optical) readonly property int opsz: clampOpsz(optical)
property int optical: fontInfo.pixelSize property int optical: fontInfo.pixelSize
@@ -16,7 +17,7 @@ CustomText {
} }
font.family: "Material Symbols Rounded" font.family: "Material Symbols Rounded"
font.pointSize: Appearance.font.size.larger font.pointSize: Tokens.font.size.larger
font.variableAxes: ({ font.variableAxes: ({
FILL: fill, FILL: fill,
GRAD: grade, GRAD: grade,
+16 -15
View File
@@ -3,8 +3,9 @@ pragma ComponentBehavior: Bound
import QtQuick import QtQuick
import QtQuick.Layouts import QtQuick.Layouts
import Quickshell import Quickshell
import qs.Config import ZShell.Config
import qs.Drawers import qs.Drawers
import qs.Services
MouseArea { MouseArea {
id: root id: root
@@ -77,7 +78,7 @@ MouseArea {
implicitHeight: column.implicitHeight + column.anchors.margins * 2 implicitHeight: column.implicitHeight + column.anchors.margins * 2
implicitWidth: Math.max(200, column.implicitWidth + column.anchors.margins * 2) implicitWidth: Math.max(200, column.implicitWidth + column.anchors.margins * 2)
level: 2 level: 2
radius: Appearance.rounding.medium radius: Tokens.rounding.medium
x: { x: {
watcher.transform; watcher.transform;
const item = root.attachTo; const item = root.attachTo;
@@ -107,15 +108,15 @@ MouseArea {
CustomRect { CustomRect {
anchors.fill: parent anchors.fill: parent
color: DynamicColors.palette.m3surfaceContainerLow color: Colors.palette.m3surfaceContainerLow
radius: parent.radius radius: parent.radius
ColumnLayout { ColumnLayout {
id: column id: column
anchors.fill: parent anchors.fill: parent
anchors.margins: Appearance.padding.extraSmall anchors.margins: Tokens.padding.extraSmall
spacing: Appearance.spacing.extraSmall spacing: Tokens.spacing.extraSmall
Repeater { Repeater {
id: repeater id: repeater
@@ -130,10 +131,10 @@ MouseArea {
required property MenuItem modelData required property MenuItem modelData
Layout.fillWidth: true Layout.fillWidth: true
color: Qt.alpha(DynamicColors.palette.m3tertiaryContainer, active ? 1 : 0) color: Qt.alpha(Colors.palette.m3tertiaryContainer, active ? 1 : 0)
implicitHeight: menuOptionRow.implicitHeight + Appearance.padding.larger * 2 implicitHeight: menuOptionRow.implicitHeight + Tokens.padding.larger * 2
implicitWidth: menuOptionRow.implicitWidth + Appearance.padding.larger * 2 implicitWidth: menuOptionRow.implicitWidth + Tokens.padding.larger * 2
radius: Appearance.rounding.small radius: Tokens.rounding.small
Behavior on radius { Behavior on radius {
Anim { Anim {
@@ -141,7 +142,7 @@ MouseArea {
} }
StateLayer { StateLayer {
color: item.active ? DynamicColors.palette.m3onTertiaryContainer : DynamicColors.palette.m3onSurface color: item.active ? Colors.palette.m3onTertiaryContainer : Colors.palette.m3onSurface
enabled: root.expanded enabled: root.expanded
onClicked: { onClicked: {
@@ -156,19 +157,19 @@ MouseArea {
id: menuOptionRow id: menuOptionRow
anchors.fill: parent anchors.fill: parent
anchors.margins: Appearance.padding.larger anchors.margins: Tokens.padding.larger
spacing: Appearance.spacing.small spacing: Tokens.spacing.small
MaterialIcon { MaterialIcon {
Layout.alignment: Qt.AlignVCenter 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 text: item.modelData.icon
} }
CustomText { CustomText {
Layout.alignment: Qt.AlignVCenter Layout.alignment: Qt.AlignVCenter
Layout.fillWidth: true 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 text: item.modelData.text
} }
@@ -179,7 +180,7 @@ MouseArea {
visible: active visible: active
sourceComponent: MaterialIcon { sourceComponent: MaterialIcon {
color: item.active ? DynamicColors.palette.m3onTertiaryContainer : DynamicColors.palette.m3onSurfaceVariant color: item.active ? Colors.palette.m3onTertiaryContainer : Colors.palette.m3onSurfaceVariant
text: item.modelData.trailingIcon text: item.modelData.trailingIcon
} }
} }
+13 -12
View File
@@ -1,5 +1,6 @@
import QtQuick import QtQuick
import qs.Config import ZShell.Config
import qs.Services
TextFieldBase { TextFieldBase {
id: root id: root
@@ -8,17 +9,17 @@ TextFieldBase {
readonly property alias clearIcon: clearIcon readonly property alias clearIcon: clearIcon
readonly property alias searchIcon: searchIcon readonly property alias searchIcon: searchIcon
bottomPadding: Appearance.padding.large bottomPadding: Tokens.padding.large
leftPadding: searchIcon.width + searchIcon.anchors.leftMargin + Appearance.spacing.small leftPadding: searchIcon.width + searchIcon.anchors.leftMargin + Tokens.spacing.small
rightPadding: clearIcon.width + clearIcon.anchors.rightMargin + Appearance.spacing.small rightPadding: clearIcon.width + clearIcon.anchors.rightMargin + Tokens.spacing.small
topPadding: Appearance.padding.large topPadding: Tokens.padding.large
background: CustomRect { background: CustomRect {
id: bg id: bg
anchors.fill: parent anchors.fill: parent
color: DynamicColors.tPalette.m3surfaceContainer color: Colors.tPalette.m3surfaceContainer
radius: Appearance.rounding.full radius: Tokens.rounding.full
StateLayer { StateLayer {
id: stateLayer id: stateLayer
@@ -58,10 +59,10 @@ TextFieldBase {
id: searchIcon id: searchIcon
anchors.left: parent.left anchors.left: parent.left
anchors.leftMargin: Appearance.padding.large anchors.leftMargin: Tokens.padding.large
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
color: DynamicColors.palette.m3onSurfaceVariant color: Colors.palette.m3onSurfaceVariant
font.pointSize: Appearance.font.size.large font.pointSize: Tokens.font.size.large
text: "search" text: "search"
} }
@@ -69,12 +70,12 @@ TextFieldBase {
id: clearIcon id: clearIcon
anchors.right: parent.right anchors.right: parent.right
anchors.rightMargin: Appearance.padding.larger anchors.rightMargin: Tokens.padding.larger
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
enabled: root.text enabled: root.text
icon: "clear" icon: "clear"
opacity: root.text ? 1 : 0 opacity: root.text ? 1 : 0
radius: Appearance.rounding.full radius: Tokens.rounding.full
radiusMorph: false radiusMorph: false
stateLayer.hoverEnabled: enabled stateLayer.hoverEnabled: enabled
type: IconButton.Text type: IconButton.Text
+5 -4
View File
@@ -3,7 +3,8 @@ import QtQuick.Shapes
import ZShell import ZShell
import ZShell.Components import ZShell.Components
import qs.Helpers import qs.Helpers
import qs.Config import ZShell.Config
import qs.Services
MouseArea { MouseArea {
id: root id: root
@@ -79,8 +80,8 @@ MouseArea {
id: rippleAnim id: rippleAnim
alwaysRunToEnd: true alwaysRunToEnd: true
duration: Appearance.anim.durations.expressiveSlowEffects * 2 duration: Tokens.anim.durations.expressiveSlowEffects * 2
easing.bezierCurve: Appearance.anim.curves.standard easing.bezierCurve: Tokens.anim.curves.standard
property: "circleRadius" property: "circleRadius"
target: root target: root
to: root.endRadius to: root.endRadius
@@ -101,7 +102,7 @@ MouseArea {
anchors.fill: parent anchors.fill: parent
bottomLeftRadius: root.parent?.bottomLeftRadius ?? radius ?? 0 bottomLeftRadius: root.parent?.bottomLeftRadius ?? radius ?? 0
bottomRightRadius: root.parent?.bottomRightRadius ?? radius ?? 0 bottomRightRadius: root.parent?.bottomRightRadius ?? radius ?? 0
color: DynamicColors.palette.m3onSurface color: Colors.palette.m3onSurface
opacity: root.stateOpacity opacity: root.stateOpacity
// Pick up radius from parent if it has one (parent can be anything with radius props) // Pick up radius from parent if it has one (parent can be anything with radius props)
// qmllint disable missing-property // qmllint disable missing-property
+12 -11
View File
@@ -1,5 +1,6 @@
import QtQuick import QtQuick
import qs.Config import ZShell.Config
import qs.Services
ButtonBase { ButtonBase {
id: root id: root
@@ -7,28 +8,28 @@ ButtonBase {
readonly property alias label: label readonly property alias label: label
property alias text: label.text 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: { activeOnColor: {
if (type === TextButton.Text) if (type === TextButton.Text)
return DynamicColors.palette.m3primary; return Colors.palette.m3primary;
return type === TextButton.Filled ? DynamicColors.palette.m3onPrimary : DynamicColors.palette.m3onSecondary; return type === TextButton.Filled ? Colors.palette.m3onPrimary : Colors.palette.m3onSecondary;
} }
horizontalPadding: Appearance.padding.normal horizontalPadding: Tokens.padding.normal
implicitHeight: label.implicitHeight + verticalPadding * 2 implicitHeight: label.implicitHeight + verticalPadding * 2
implicitWidth: label.implicitWidth + horizontalPadding * 2 implicitWidth: label.implicitWidth + horizontalPadding * 2
inactiveColor: { inactiveColor: {
if (!isToggle && type === TextButton.Filled) if (!isToggle && type === TextButton.Filled)
return DynamicColors.palette.m3primary; return Colors.palette.m3primary;
return type === TextButton.Filled ? DynamicColors.tPalette.m3surfaceContainer : DynamicColors.palette.m3secondaryContainer; return type === TextButton.Filled ? Colors.tPalette.m3surfaceContainer : Colors.palette.m3secondaryContainer;
} }
inactiveOnColor: { inactiveOnColor: {
if (!isToggle && type === TextButton.Filled) if (!isToggle && type === TextButton.Filled)
return DynamicColors.palette.m3onPrimary; return Colors.palette.m3onPrimary;
if (type === TextButton.Text) if (type === TextButton.Text)
return DynamicColors.palette.m3primary; return Colors.palette.m3primary;
return type === TextButton.Filled ? DynamicColors.palette.m3onSurface : DynamicColors.palette.m3onSecondaryContainer; return type === TextButton.Filled ? Colors.palette.m3onSurface : Colors.palette.m3onSecondaryContainer;
} }
verticalPadding: Appearance.padding.small verticalPadding: Tokens.padding.small
CustomText { CustomText {
id: label id: label
+9 -8
View File
@@ -1,19 +1,20 @@
import QtQuick import QtQuick
import QtQuick.Templates import QtQuick.Templates
import qs.Config import ZShell.Config
import qs.Services
TextField { TextField {
id: root id: root
color: DynamicColors.palette.m3onSurface color: Colors.palette.m3onSurface
cursorVisible: !readOnly cursorVisible: !readOnly
font.pointSize: Appearance.font.size.small font.pointSize: Tokens.font.size.small
implicitHeight: contentHeight + topPadding + bottomPadding implicitHeight: contentHeight + topPadding + bottomPadding
implicitWidth: contentWidth + leftPadding + rightPadding 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 renderType: echoMode === TextField.Password ? TextField.QtRendering : TextField.NativeRendering
selectedTextColor: color selectedTextColor: color
selectionColor: Qt.alpha(DynamicColors.palette.m3primary, 0.4) selectionColor: Qt.alpha(Colors.palette.m3primary, 0.4)
verticalAlignment: TextInput.AlignVCenter verticalAlignment: TextInput.AlignVCenter
Behavior on color { Behavior on color {
@@ -32,10 +33,10 @@ TextField {
property bool disableBlink property bool disableBlink
color: DynamicColors.palette.m3primary color: Colors.palette.m3primary
implicitHeight: root.cursorRectangle.height implicitHeight: root.cursorRectangle.height
implicitWidth: 1.5 implicitWidth: 1.5
radius: Appearance.rounding.large radius: Tokens.rounding.large
x: root.cursorRectangle.x x: root.cursorRectangle.x
y: root.cursorRectangle.y y: root.cursorRectangle.y
@@ -46,7 +47,7 @@ TextField {
} }
Behavior on x { Behavior on x {
Anim { Anim {
duration: Appearance.anim.durations.expressiveFastEffects duration: Tokens.anim.durations.expressiveFastEffects
easing.bezierCurve: [0.2, 1, 0.21, 1, 1, 1] easing.bezierCurve: [0.2, 1, 0.21, 1, 1, 1]
} }
} }
+36 -35
View File
@@ -2,7 +2,8 @@ import ZShell
import QtQuick import QtQuick
import QtQuick.Layouts import QtQuick.Layouts
import qs.Components import qs.Components
import qs.Config import ZShell.Config
import qs.Services
CustomRect { CustomRect {
id: root id: root
@@ -12,27 +13,27 @@ CustomRect {
anchors.left: parent.left anchors.left: parent.left
anchors.right: parent.right anchors.right: parent.right
border.color: { border.color: {
let colour = DynamicColors.palette.m3outlineVariant; let colour = Colors.palette.m3outlineVariant;
if (root.modelData.type === Toast.Success) if (root.modelData.type === Toast.Success)
colour = DynamicColors.palette.m3success; colour = Colors.palette.m3success;
if (root.modelData.type === Toast.Warning) if (root.modelData.type === Toast.Warning)
colour = DynamicColors.palette.m3secondaryContainer; colour = Colors.palette.m3secondaryContainer;
if (root.modelData.type === Toast.Error) if (root.modelData.type === Toast.Error)
colour = DynamicColors.palette.m3error; colour = Colors.palette.m3error;
return Qt.alpha(colour, 0.3); return Qt.alpha(colour, 0.3);
} }
border.width: 1 border.width: 1
color: { color: {
if (root.modelData.type === Toast.Success) if (root.modelData.type === Toast.Success)
return DynamicColors.palette.m3successContainer; return Colors.palette.m3successContainer;
if (root.modelData.type === Toast.Warning) if (root.modelData.type === Toast.Warning)
return DynamicColors.palette.m3secondary; return Colors.palette.m3secondary;
if (root.modelData.type === Toast.Error) if (root.modelData.type === Toast.Error)
return DynamicColors.palette.m3errorContainer; return Colors.palette.m3errorContainer;
return DynamicColors.palette.m3surface; return Colors.palette.m3surface;
} }
implicitHeight: layout.implicitHeight + Appearance.padding.smaller * 2 implicitHeight: layout.implicitHeight + Tokens.padding.smaller * 2
radius: Appearance.rounding.normal radius: Tokens.rounding.normal
Behavior on border.color { Behavior on border.color {
CAnim { CAnim {
@@ -51,24 +52,24 @@ CustomRect {
id: layout id: layout
anchors.fill: parent anchors.fill: parent
anchors.leftMargin: Appearance.padding.normal anchors.leftMargin: Tokens.padding.normal
anchors.margins: Appearance.padding.smaller anchors.margins: Tokens.padding.smaller
anchors.rightMargin: Appearance.padding.normal anchors.rightMargin: Tokens.padding.normal
spacing: Appearance.spacing.normal spacing: Tokens.spacing.normal
CustomRect { CustomRect {
color: { color: {
if (root.modelData.type === Toast.Success) if (root.modelData.type === Toast.Success)
return DynamicColors.palette.m3success; return Colors.palette.m3success;
if (root.modelData.type === Toast.Warning) if (root.modelData.type === Toast.Warning)
return DynamicColors.palette.m3secondaryContainer; return Colors.palette.m3secondaryContainer;
if (root.modelData.type === Toast.Error) if (root.modelData.type === Toast.Error)
return DynamicColors.palette.m3error; return Colors.palette.m3error;
return DynamicColors.palette.m3surfaceContainerHigh; return Colors.palette.m3surfaceContainerHigh;
} }
implicitHeight: icon.implicitHeight + Appearance.padding.smaller * 2 implicitHeight: icon.implicitHeight + Tokens.padding.smaller * 2
implicitWidth: implicitHeight implicitWidth: implicitHeight
radius: Appearance.rounding.normal radius: Tokens.rounding.normal
MaterialIcon { MaterialIcon {
id: icon id: icon
@@ -76,14 +77,14 @@ CustomRect {
anchors.centerIn: parent anchors.centerIn: parent
color: { color: {
if (root.modelData.type === Toast.Success) if (root.modelData.type === Toast.Success)
return DynamicColors.palette.m3onSuccess; return Colors.palette.m3onSuccess;
if (root.modelData.type === Toast.Warning) if (root.modelData.type === Toast.Warning)
return DynamicColors.palette.m3onSecondaryContainer; return Colors.palette.m3onSecondaryContainer;
if (root.modelData.type === Toast.Error) if (root.modelData.type === Toast.Error)
return DynamicColors.palette.m3onError; return Colors.palette.m3onError;
return DynamicColors.palette.m3onSurfaceVariant; 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 text: root.modelData.icon
} }
} }
@@ -98,15 +99,15 @@ CustomRect {
Layout.fillWidth: true Layout.fillWidth: true
color: { color: {
if (root.modelData.type === Toast.Success) if (root.modelData.type === Toast.Success)
return DynamicColors.palette.m3onSuccessContainer; return Colors.palette.m3onSuccessContainer;
if (root.modelData.type === Toast.Warning) if (root.modelData.type === Toast.Warning)
return DynamicColors.palette.m3onSecondary; return Colors.palette.m3onSecondary;
if (root.modelData.type === Toast.Error) if (root.modelData.type === Toast.Error)
return DynamicColors.palette.m3onErrorContainer; return Colors.palette.m3onErrorContainer;
return DynamicColors.palette.m3onSurface; return Colors.palette.m3onSurface;
} }
elide: Text.ElideRight elide: Text.ElideRight
font.pointSize: Appearance.font.size.normal font.pointSize: Tokens.font.size.normal
text: root.modelData.title text: root.modelData.title
} }
@@ -114,12 +115,12 @@ CustomRect {
Layout.fillWidth: true Layout.fillWidth: true
color: { color: {
if (root.modelData.type === Toast.Success) if (root.modelData.type === Toast.Success)
return DynamicColors.palette.m3onSuccessContainer; return Colors.palette.m3onSuccessContainer;
if (root.modelData.type === Toast.Warning) if (root.modelData.type === Toast.Warning)
return DynamicColors.palette.m3onSecondary; return Colors.palette.m3onSecondary;
if (root.modelData.type === Toast.Error) if (root.modelData.type === Toast.Error)
return DynamicColors.palette.m3onErrorContainer; return Colors.palette.m3onErrorContainer;
return DynamicColors.palette.m3onSurface; return Colors.palette.m3onSurface;
} }
elide: Text.ElideRight elide: Text.ElideRight
opacity: 0.8 opacity: 0.8
+7 -7
View File
@@ -4,13 +4,13 @@ import ZShell
import Quickshell import Quickshell
import QtQuick import QtQuick
import qs.Components import qs.Components
import qs.Config import ZShell.Config
Item { Item {
id: root id: root
property bool flag property bool flag
readonly property int spacing: Appearance.spacing.small readonly property int spacing: Tokens.spacing.small
implicitHeight: { implicitHeight: {
let h = -spacing; let h = -spacing;
@@ -21,7 +21,7 @@ Item {
} }
return h; return h;
} }
implicitWidth: Config.utilities.sizes.toastWidth - Appearance.padding.normal * 2 implicitWidth: Config.utilities.sizes.toastWidth - Tokens.padding.normal * 2
Repeater { Repeater {
id: repeater id: repeater
@@ -81,8 +81,8 @@ Item {
Behavior on anchors.bottomMargin { Behavior on anchors.bottomMargin {
Anim { Anim {
duration: Appearance.anim.durations.expressiveDefaultSpatial duration: Tokens.anim.durations.expressiveDefaultSpatial
easing.bezierCurve: Appearance.anim.curves.expressiveDefaultSpatial easing.bezierCurve: Tokens.anim.curves.expressiveDefaultSpatial
} }
} }
Behavior on opacity { Behavior on opacity {
@@ -104,8 +104,8 @@ Item {
Anim { Anim {
id: initAnim id: initAnim
duration: Appearance.anim.durations.expressiveDefaultSpatial duration: Tokens.anim.durations.expressiveDefaultSpatial
easing.bezierCurve: Appearance.anim.curves.expressiveDefaultSpatial easing.bezierCurve: Tokens.anim.curves.expressiveDefaultSpatial
from: 0 from: 0
properties: "opacity,scale" properties: "opacity,scale"
target: toast target: toast
+3 -2
View File
@@ -1,12 +1,13 @@
import QtQuick import QtQuick
import QtQuick.Shapes import QtQuick.Shapes
import qs.Config import ZShell.Config
import qs.Services
Shape { Shape {
id: root id: root
property real amplitude: 3 property real amplitude: 3
property color color: DynamicColors.palette.m3surfaceContainer property color color: Colors.palette.m3surfaceContainer
readonly property real waveHeight: amplitude * 2 readonly property real waveHeight: amplitude * 2
property int waves: 4 property int waves: 4
-13
View File
@@ -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"
}
}
-119
View File
@@ -1,119 +0,0 @@
pragma Singleton
import Quickshell
import QtQuick
Singleton {
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: QtObject {
property AnimCurves curves: AnimCurves {
}
property AnimDurations durations: AnimDurations {
}
property real mediaGifSpeedAdjustment: Config.appearance.anim.mediaGifSpeedAdjustment
property real sessionGifSpeed: Config.appearance.anim.sessionGifSpeed
}
component AnimCurves: QtObject {
property list<real> emphasized: [0.05, 0, 2 / 15, 0.06, 1 / 6, 0.4, 5 / 24, 0.82, 0.25, 1, 1, 1]
property list<real> emphasizedAccel: [0.3, 0, 0.8, 0.15, 1, 1]
property list<real> emphasizedDecel: [0.05, 0.7, 0.1, 1, 1, 1]
property list<real> expressiveDefaultEffects: [0.34, 0.8, 0.34, 1, 1, 1]
property list<real> expressiveDefaultSpatial: [0.38, 1.21, 0.22, 1, 1, 1]
property list<real> expressiveEffects: [0.34, 0.8, 0.34, 1, 1, 1]
property list<real> expressiveFastEffects: [0.31, 0.94, 0.34, 1, 1, 1]
property list<real> expressiveFastSpatial: [0.42, 1.67, 0.21, 0.9, 1, 1]
property list<real> expressiveSlowEffects: [0.34, 0.88, 0.34, 1, 1, 1]
property list<real> expressiveSlowSpatial: [0.39, 1.29, 0.35, 0.98, 1, 1]
property list<real> standard: [0.2, 0, 0, 1, 1, 1]
property list<real> standardAccel: [0.3, 0, 1, 1, 1, 1]
property list<real> standardDecel: [0, 0, 0, 1, 1, 1]
}
component AnimDurations: QtObject {
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: QtObject {
property real scale: Config.appearance.deform.scale
}
component FontFamily: QtObject {
property string clock: Config.appearance.font.family.clock
property string material: Config.appearance.font.family.material
property string mono: Config.appearance.font.family.mono
property string sans: Config.appearance.font.family.sans
}
component FontSize: QtObject {
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: QtObject {
property FontFamily family: FontFamily {
}
property FontSize size: FontSize {
}
}
component Padding: QtObject {
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: QtObject {
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: QtObject {
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: QtObject {
property real base: Config.appearance.transparency.base
property bool enabled: Config.appearance.transparency.enabled
property real layers: Config.appearance.transparency.layers
}
}
-35
View File
@@ -1,35 +0,0 @@
import Quickshell.Io
JsonObject {
property Anim anim: Anim {
}
property Deform deform: Deform {
}
property FontStuff font: FontStuff {
}
property Transparency transparency: Transparency {
}
component Anim: JsonObject {
property real mediaGifSpeedAdjustment: 300
property real sessionGifSpeed: 0.7
}
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 FontStuff: JsonObject {
property FontFamily family: FontFamily {
}
}
component Transparency: JsonObject {
property real base: 0.85
property bool enabled: false
property real layers: 0.4
}
}
-7
View File
@@ -1,7 +0,0 @@
import Quickshell.Io
import qs.Config
JsonObject {
property bool enabled: true
property int wallFadeDuration: MaterialEasing.standardTime
}
-104
View File
@@ -1,104 +0,0 @@
import Quickshell.Io
JsonObject {
property bool autoHide: false
property int border: 8
property list<var> 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: "statusIcons",
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 statusIcons: true
property bool tray: true
}
component Tray: JsonObject {
property bool recolorIcons: false
property bool showOnHover: false
property list<var> statusIcons: [
{
id: "audio",
enabled: true
},
{
id: "microphone",
enabled: true
},
{
id: "bluetooth",
enabled: true
},
{
id: "network",
enabled: false
},
{
id: "wifi",
enabled: false
},
{
id: "power",
enabled: true
},
]
property int trayIconSize: 24
}
}
-15
View File
@@ -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
}
}
-13
View File
@@ -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: ""
}
}
-186
View File
@@ -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 {
}
}
}
}
-37
View File
@@ -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
}
}
-10
View File
@@ -1,10 +0,0 @@
import Quickshell.Io
JsonObject {
property bool enable: false
property real height: 60
property bool hoverToReveal: true
property list<string> ignoredAppRegexes: []
property list<string> pinnedApps: ["org.kde.dolphin", "kitty",]
property bool pinnedOnStartup: false
}
-68
View File
@@ -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<string> archiver: ["ark"]
property list<string> audio: ["pavucontrol"]
property list<string> document: ["libreoffice"]
property list<string> editor: ["kate"]
property list<string> explorer: ["dolphin"]
property list<string> image: ["imv"]
property list<string> playback: ["mpv"]
property list<string> terminal: ["kitty"]
}
component Battery: JsonObject {
property int critPerc: 5
property list<var> 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<var> timeouts: [
{
name: "Lock",
timeout: 180,
idleAction: "lock"
},
{
name: "Screen",
timeout: 300,
idleAction: "dpms off",
activeAction: "dpms on"
}
]
}
}
-15
View File
@@ -1,15 +0,0 @@
import Quickshell.Io
JsonObject {
property list<var> timeouts: [
{
timeout: 180,
idleAction: "lock"
},
{
timeout: 300,
idleAction: "dpms off",
activeAction: "dpms on"
}
]
}
-114
View File
@@ -1,114 +0,0 @@
import Quickshell.Io
JsonObject {
property string actionPrefix: ">"
property list<var> 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<string> favoriteApps: []
property list<string> 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
}
}
-18
View File
@@ -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
}
}
-26
View File
@@ -1,26 +0,0 @@
pragma Singleton
import Quickshell
Singleton {
id: root
readonly property list<real> emphasized: [0.05, 0, 2 / 15, 0.06, 1 / 6, 0.4, 5 / 24, 0.82, 0.25, 1, 1, 1]
readonly property list<real> emphasizedAccel: [0.3, 0, 0.8, 0.15, 1, 1]
readonly property int emphasizedAccelTime: 200 * scale
readonly property list<real> 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<real> expressiveDefaultSpatial: [0.38, 1.21, 0.22, 1.00, 1, 1]
readonly property int expressiveDefaultSpatialTime: 500 * scale
readonly property list<real> expressiveEffects: [0.34, 0.80, 0.34, 1.00, 1, 1]
readonly property int expressiveEffectsTime: 200 * scale
readonly property list<real> 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<real> standard: [0.2, 0, 0, 1, 1, 1]
readonly property list<real> standardAccel: [0.3, 0, 1, 1, 1, 1]
readonly property int standardAccelTime: 200 * scale
readonly property list<real> standardDecel: [0, 0, 0, 1, 1, 1]
readonly property int standardDecelTime: 250 * scale
readonly property int standardTime: 300 * scale
}
-21
View File
@@ -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
}
}
-16
View File
@@ -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
}
}
-8
View File
@@ -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
}
-14
View File
@@ -1,14 +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 saveOnCopy: false
property bool shadow: true
property real shadow_blur: 22.0
property list<int> shadow_color: [0, 0, 0, 160]
property real shadow_offset_x: 5.0
property real shadow_offset_y: 5.0
}
-23
View File
@@ -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<var> 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: ""
}
-12
View File
@@ -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
}
}
-7
View File
@@ -1,7 +0,0 @@
import Quickshell.Io
JsonObject {
property real base: 0.85
property bool enabled: false
property real layers: 0.4
}
-35
View File
@@ -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<var> provider: ["netbird"]
}
}
-6
View File
@@ -1,6 +0,0 @@
import Quickshell.Io
JsonObject {
property string inactiveTextColor: "white"
property string textColor: "black"
}
+1 -1
View File
@@ -5,7 +5,7 @@ import ZShell
import Quickshell import Quickshell
import Quickshell.Services.Pipewire import Quickshell.Services.Pipewire
import QtQuick import QtQuick
import qs.Config import ZShell.Config
Singleton { Singleton {
id: root id: root
+1 -1
View File
@@ -2,7 +2,7 @@ import Quickshell
import Quickshell.Services.UPower import Quickshell.Services.UPower
import QtQuick import QtQuick
import ZShell import ZShell
import qs.Config import ZShell.Config
import qs.Components.Toast import qs.Components.Toast
import qs.Helpers import qs.Helpers
+1 -1
View File
@@ -11,7 +11,7 @@ import qs.Components
import qs.Modules import qs.Modules
import qs.Helpers import qs.Helpers
import qs.Paths import qs.Paths
import qs.Config import ZShell.Config
Singleton { Singleton {
id: root id: root
+1 -1
View File
@@ -2,7 +2,7 @@ pragma ComponentBehavior: Bound
import Quickshell import Quickshell
import QtQuick import QtQuick
import qs.Config import ZShell.Config
import qs.Components import qs.Components
Scope { Scope {
+1 -1
View File
@@ -1,7 +1,7 @@
import Quickshell import Quickshell
import QtQuick import QtQuick
import qs.Components import qs.Components
import qs.Config import ZShell.Config
import qs.Helpers import qs.Helpers
import qs.Modules as BarPopouts import qs.Modules as BarPopouts
+4 -4
View File
@@ -14,7 +14,7 @@ import qs.Modules.Settings as Settings
import qs.Modules.Drawing as Drawing import qs.Modules.Drawing as Drawing
import qs.Modules.Dock as Dock import qs.Modules.Dock as Dock
import qs.Modules.Clipboard as Clipboard import qs.Modules.Clipboard as Clipboard
import qs.Config import ZShell.Config
Item { Item {
id: root id: root
@@ -108,7 +108,7 @@ Item {
id: toasts id: toasts
anchors.bottom: sidebar.visible ? parent.bottom : utilities.top anchors.bottom: sidebar.visible ? parent.bottom : utilities.top
anchors.margins: Appearance.padding.normal anchors.margins: Tokens.padding.normal
anchors.right: sidebar.left anchors.right: sidebar.left
} }
@@ -155,8 +155,8 @@ Item {
Behavior on offsetScale { Behavior on offsetScale {
Anim { Anim {
duration: Appearance.anim.durations.expressiveDefaultSpatial duration: Tokens.anim.durations.expressiveDefaultSpatial
easing.bezierCurve: Appearance.anim.curves.expressiveDefaultSpatial easing.bezierCurve: Tokens.anim.curves.expressiveDefaultSpatial
} }
} }
+13 -12
View File
@@ -11,9 +11,10 @@ import ZShell.Blobs
import qs.Daemons import qs.Daemons
import qs.Components import qs.Components
import qs.Modules.Bar import qs.Modules.Bar
import qs.Config import ZShell.Config
import qs.Helpers import qs.Helpers
import qs.Drawers import qs.Drawers
import qs.Services
CustomWindow { CustomWindow {
id: root id: root
@@ -50,7 +51,7 @@ CustomWindow {
property var root: Quickshell.shellDir property var root: Quickshell.shellDir
readonly property real sdfBorderOffset: 2 * fsTransitionProg readonly property real sdfBorderOffset: 2 * fsTransitionProg
readonly property real shadowOpacity: 0.7 * (1 - 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.exclusionMode: ExclusionMode.Ignore
WlrLayershell.keyboardFocus: visibilities.launcher || visibilities.settings ? WlrKeyboardFocus.OnDemand : WlrKeyboardFocus.None WlrLayershell.keyboardFocus: visibilities.launcher || visibilities.settings ? WlrKeyboardFocus.OnDemand : WlrKeyboardFocus.None
@@ -178,7 +179,7 @@ CustomWindow {
layer.effect: MultiEffect { layer.effect: MultiEffect {
blurMax: 32 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 shadowEnabled: true
} }
@@ -209,7 +210,7 @@ CustomWindow {
implicitHeight: panels.dashboard.height * (1 + extraHeight) implicitHeight: panels.dashboard.height * (1 + extraHeight)
implicitWidth: panels.dashboard.width implicitWidth: panels.dashboard.width
panel: panels.dashboardWrapper panel: panels.dashboardWrapper
radius: Appearance.rounding.normal radius: Tokens.rounding.normal
x: panels.dashboardWrapper.x + panels.dashboard.x + root.borderThickness x: panels.dashboardWrapper.x + panels.dashboard.x + root.borderThickness
y: panels.dashboardWrapper.y + panels.dashboard.y + bar.implicitHeight - panels.dashboard.height * extraHeight y: panels.dashboardWrapper.y + panels.dashboard.y + bar.implicitHeight - panels.dashboard.height * extraHeight
} }
@@ -222,7 +223,7 @@ CustomWindow {
deformAmount: 0.06 deformAmount: 0.06
implicitHeight: panels.launcher.height * (1 + extraHeight) implicitHeight: panels.launcher.height * (1 + extraHeight)
panel: panels.launcher panel: panels.launcher
radius: Appearance.rounding.smallest + 5 radius: Tokens.rounding.smallest + 5
y: panels.launcher.y + bar.implicitHeight y: panels.launcher.y + bar.implicitHeight
} }
@@ -252,7 +253,7 @@ CustomWindow {
id: notifsBg id: notifsBg
panel: panels.notifications panel: panels.notifications
radius: Appearance.rounding.normal radius: Tokens.rounding.normal
} }
PanelBg { PanelBg {
@@ -273,7 +274,7 @@ CustomWindow {
implicitHeight: panels.popouts.height * (1 + extraHeight) implicitHeight: panels.popouts.height * (1 + extraHeight)
implicitWidth: panels.popouts.width implicitWidth: panels.popouts.width
panel: panels.popoutsWrapper 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 x: panels.popoutsWrapper.x + panels.popouts.x + root.borderThickness
y: panels.popoutsWrapper.y + panels.popouts.y + bar.implicitHeight - panels.popouts.height * extraHeight y: panels.popoutsWrapper.y + panels.popouts.y + bar.implicitHeight - panels.popouts.height * extraHeight
@@ -290,7 +291,7 @@ CustomWindow {
implicitHeight: panels.resources.height implicitHeight: panels.resources.height
implicitWidth: panels.resources.width implicitWidth: panels.resources.width
panel: panels.resourcesWrapper panel: panels.resourcesWrapper
radius: Appearance.rounding.large radius: Tokens.rounding.large
x: panels.resourcesWrapper.x + panels.resources.x + root.borderThickness x: panels.resourcesWrapper.x + panels.resources.x + root.borderThickness
y: panels.resourcesWrapper.y + panels.resources.y + bar.implicitHeight y: panels.resourcesWrapper.y + panels.resources.y + bar.implicitHeight
} }
@@ -300,7 +301,7 @@ CustomWindow {
deformAmount: 0.03 deformAmount: 0.03
panel: panels.settings panel: panels.settings
radius: Appearance.rounding.large + Appearance.padding.normal radius: Tokens.rounding.large + Tokens.padding.normal
} }
PanelBg { PanelBg {
@@ -308,7 +309,7 @@ CustomWindow {
deformAmount: 0.08 deformAmount: 0.08
panel: panels.dock panel: panels.dock
radius: Appearance.rounding.normal radius: Tokens.rounding.normal
} }
PanelBg { PanelBg {
@@ -316,7 +317,7 @@ CustomWindow {
deformAmount: 0.08 deformAmount: 0.08
panel: panels.drawing panel: panels.drawing
radius: Appearance.rounding.normal radius: Tokens.rounding.normal
} }
PanelBg { PanelBg {
@@ -441,7 +442,7 @@ CustomWindow {
group: blobGroup group: blobGroup
implicitHeight: panel.height implicitHeight: panel.height
implicitWidth: panel.width implicitWidth: panel.width
radius: Appearance.rounding.smallest radius: Tokens.rounding.smallest
x: panel.x + root.borderThickness x: panel.x + root.borderThickness
y: panel.y + bar.implicitHeight y: panel.y + bar.implicitHeight
} }
+45 -45
View File
@@ -2,10 +2,10 @@ pragma ComponentBehavior: Bound
import QtQuick import QtQuick
import QtQuick.Layouts import QtQuick.Layouts
import qs.Paths import ZShell.Config
import qs.Components import qs.Components
import qs.Helpers import qs.Helpers
import qs.Config import qs.Services
ColumnLayout { ColumnLayout {
id: root id: root
@@ -18,61 +18,61 @@ ColumnLayout {
Layout.fillHeight: true Layout.fillHeight: true
Layout.fillWidth: false Layout.fillWidth: false
Layout.preferredWidth: centerWidth Layout.preferredWidth: centerWidth
spacing: Appearance.spacing.large * 2 spacing: Tokens.spacing.large * 2
RowLayout { RowLayout {
Layout.alignment: Qt.AlignHCenter Layout.alignment: Qt.AlignHCenter
spacing: Appearance.spacing.small spacing: Tokens.spacing.small
CustomText { CustomText {
Layout.alignment: Qt.AlignVCenter Layout.alignment: Qt.AlignVCenter
color: DynamicColors.palette.m3secondary color: Colors.palette.m3secondary
font.bold: true font.bold: true
font.family: Appearance.font.family.clock font.family: Config.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 text: Time.hourStr
} }
CustomText { CustomText {
Layout.alignment: Qt.AlignVCenter Layout.alignment: Qt.AlignVCenter
color: DynamicColors.palette.m3primary color: Colors.palette.m3primary
font.bold: true font.bold: true
font.family: Appearance.font.family.clock font.family: Config.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: ":" text: ":"
} }
CustomText { CustomText {
Layout.alignment: Qt.AlignVCenter Layout.alignment: Qt.AlignVCenter
color: DynamicColors.palette.m3secondary color: Colors.palette.m3secondary
font.bold: true font.bold: true
font.family: Appearance.font.family.clock font.family: Config.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 text: Time.minuteStr
} }
} }
CustomText { CustomText {
Layout.alignment: Qt.AlignHCenter Layout.alignment: Qt.AlignHCenter
Layout.topMargin: -Appearance.padding.large * 2 Layout.topMargin: -Tokens.padding.large * 2
color: DynamicColors.palette.m3tertiary color: Colors.palette.m3tertiary
font.bold: true font.bold: true
font.family: Appearance.font.family.mono font.family: Config.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") text: Time.format("dddd, d MMMM yyyy")
} }
CustomClippingRect { CustomClippingRect {
Layout.alignment: Qt.AlignHCenter Layout.alignment: Qt.AlignHCenter
Layout.topMargin: Appearance.spacing.large * 2 Layout.topMargin: Tokens.spacing.large * 2
color: DynamicColors.tPalette.m3surfaceContainer color: Colors.tPalette.m3surfaceContainer
implicitHeight: root.centerWidth / 2 implicitHeight: root.centerWidth / 2
implicitWidth: root.centerWidth / 2 implicitWidth: root.centerWidth / 2
radius: Appearance.rounding.full radius: Tokens.rounding.full
MaterialIcon { MaterialIcon {
anchors.centerIn: parent anchors.centerIn: parent
color: DynamicColors.palette.m3onSurfaceVariant color: Colors.palette.m3onSurfaceVariant
font.pointSize: Math.floor(root.centerWidth / 4) font.pointSize: Math.floor(root.centerWidth / 4)
text: "person" text: "person"
} }
@@ -87,9 +87,9 @@ ColumnLayout {
CustomText { CustomText {
Layout.alignment: Qt.AlignHCenter Layout.alignment: Qt.AlignHCenter
color: DynamicColors.palette.m3onSurfaceVariant color: Colors.palette.m3onSurfaceVariant
font.family: Appearance.font.family.mono font.family: Config.appearance.font.family.mono
font.pointSize: Appearance.font.size.normal font.pointSize: Tokens.font.size.normal
font.weight: 600 font.weight: 600
text: root.greeter.username text: root.greeter.username
visible: text.length > 0 visible: text.length > 0
@@ -97,11 +97,11 @@ ColumnLayout {
CustomRect { CustomRect {
Layout.alignment: Qt.AlignHCenter Layout.alignment: Qt.AlignHCenter
color: DynamicColors.tPalette.m3surfaceContainer color: Colors.tPalette.m3surfaceContainer
focus: true focus: true
implicitHeight: input.implicitHeight + Appearance.padding.small * 2 implicitHeight: input.implicitHeight + Tokens.padding.small * 2
implicitWidth: root.centerWidth * 0.8 implicitWidth: root.centerWidth * 0.8
radius: Appearance.rounding.full radius: Tokens.rounding.full
Keys.onPressed: event => { Keys.onPressed: event => {
if (root.greeter.launching) if (root.greeter.launching)
@@ -130,11 +130,11 @@ ColumnLayout {
id: input id: input
anchors.fill: parent anchors.fill: parent
anchors.margins: Appearance.padding.small anchors.margins: Tokens.padding.small
spacing: Appearance.spacing.normal spacing: Tokens.spacing.normal
Item { Item {
implicitHeight: statusIcon.implicitHeight + Appearance.padding.small * 2 implicitHeight: statusIcon.implicitHeight + Tokens.padding.small * 2
implicitWidth: implicitHeight implicitWidth: implicitHeight
MaterialIcon { MaterialIcon {
@@ -142,7 +142,7 @@ ColumnLayout {
anchors.centerIn: parent anchors.centerIn: parent
animate: true 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 opacity: root.greeter.launching ? 0 : 1
text: { text: {
if (root.greeter.errorMessage) if (root.greeter.errorMessage)
@@ -173,13 +173,13 @@ ColumnLayout {
} }
CustomRect { CustomRect {
color: root.greeter.buffer && !root.greeter.launching ? DynamicColors.palette.m3primary : DynamicColors.layer(DynamicColors.palette.m3surfaceContainerHigh, 2) color: root.greeter.buffer && !root.greeter.launching ? Colors.palette.m3primary : Colors.layer(Colors.palette.m3surfaceContainerHigh, 2)
implicitHeight: enterIcon.implicitHeight + Appearance.padding.small * 2 implicitHeight: enterIcon.implicitHeight + Tokens.padding.small * 2
implicitWidth: implicitHeight implicitWidth: implicitHeight
radius: Appearance.rounding.full radius: Tokens.rounding.full
StateLayer { 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: { onClicked: {
root.greeter.submit(); root.greeter.submit();
@@ -190,7 +190,7 @@ ColumnLayout {
id: enterIcon id: enterIcon
anchors.centerIn: parent 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 font.weight: 500
text: root.greeter.launching ? "hourglass_top" : "arrow_forward" text: root.greeter.launching ? "hourglass_top" : "arrow_forward"
} }
@@ -200,7 +200,7 @@ ColumnLayout {
Item { Item {
Layout.fillWidth: true Layout.fillWidth: true
Layout.topMargin: -Appearance.spacing.large Layout.topMargin: -Tokens.spacing.large
implicitHeight: Math.max(message.implicitHeight, stateMessage.implicitHeight) implicitHeight: Math.max(message.implicitHeight, stateMessage.implicitHeight)
Behavior on implicitHeight { Behavior on implicitHeight {
@@ -236,8 +236,8 @@ ColumnLayout {
anchors.left: parent.left anchors.left: parent.left
anchors.right: parent.right anchors.right: parent.right
animateProp: "opacity" animateProp: "opacity"
color: DynamicColors.palette.m3onSurfaceVariant color: Colors.palette.m3onSurfaceVariant
font.family: Appearance.font.family.mono font.family: Config.appearance.font.family.mono
horizontalAlignment: Qt.AlignHCenter horizontalAlignment: Qt.AlignHCenter
lineHeight: 1.2 lineHeight: 1.2
opacity: shouldBeVisible && !message.msg ? 1 : 0 opacity: shouldBeVisible && !message.msg ? 1 : 0
@@ -291,9 +291,9 @@ ColumnLayout {
anchors.left: parent.left anchors.left: parent.left
anchors.right: parent.right anchors.right: parent.right
color: isError ? DynamicColors.palette.m3error : DynamicColors.palette.m3primary color: isError ? Colors.palette.m3error : Colors.palette.m3primary
font.family: Appearance.font.family.mono font.family: Config.appearance.font.family.mono
font.pointSize: Appearance.font.size.small font.pointSize: Tokens.font.size.small
horizontalAlignment: Qt.AlignHCenter horizontalAlignment: Qt.AlignHCenter
opacity: 0 opacity: 0
scale: 0.7 scale: 0.7
@@ -363,14 +363,14 @@ ColumnLayout {
id: exitAnim id: exitAnim
Anim { Anim {
duration: Appearance.anim.durations.large duration: Tokens.anim.durations.large
property: "scale" property: "scale"
target: message target: message
to: 0.7 to: 0.7
} }
Anim { Anim {
duration: Appearance.anim.durations.large duration: Tokens.anim.durations.large
property: "opacity" property: "opacity"
target: message target: message
to: 0 to: 0
@@ -380,7 +380,7 @@ ColumnLayout {
} }
component FlashAnim: NumberAnimation { component FlashAnim: NumberAnimation {
duration: Appearance.anim.durations.small duration: Tokens.anim.durations.small
easing.type: Easing.Linear easing.type: Easing.Linear
property: "opacity" property: "opacity"
target: message target: message
+17 -17
View File
@@ -1,5 +1,5 @@
import QtQuick import QtQuick
import qs.Config import ZShell.Config
NumberAnimation { NumberAnimation {
enum Type { enum Type {
@@ -23,41 +23,41 @@ NumberAnimation {
duration: { duration: {
if (type < Anim.StandardSmall || type > Anim.SlowEffects) if (type < Anim.StandardSmall || type > Anim.SlowEffects)
return Appearance.anim.durations.normal; return Tokens.anim.durations.normal;
if (type === Anim.FastSpatial) if (type === Anim.FastSpatial)
return Appearance.anim.durations.expressiveFastSpatial; return Tokens.anim.durations.expressiveFastSpatial;
if (type === Anim.DefaultSpatial) if (type === Anim.DefaultSpatial)
return Appearance.anim.durations.expressiveDefaultSpatial; return Tokens.anim.durations.expressiveDefaultSpatial;
if (type === Anim.SlowSpatial) if (type === Anim.SlowSpatial)
return Appearance.anim.durations.large; return Tokens.anim.durations.large;
if (type === Anim.FastEffects) if (type === Anim.FastEffects)
return Appearance.anim.durations.expressiveFastEffects; return Tokens.anim.durations.expressiveFastEffects;
if (type === Anim.DefaultEffects) if (type === Anim.DefaultEffects)
return Appearance.anim.durations.expressiveEffects; return Tokens.anim.durations.expressiveEffects;
if (type === Anim.SlowEffects) if (type === Anim.SlowEffects)
return Appearance.anim.durations.expressiveSlowEffects; return Tokens.anim.durations.expressiveSlowEffects;
const types = ["small", "normal", "large", "extraLarge"]; const types = ["small", "normal", "large", "extraLarge"];
const idx = type % 4; // 0-7 are the 4 standard types 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: { easing.bezierCurve: {
if (type === Anim.FastSpatial) if (type === Anim.FastSpatial)
return Appearance.anim.curves.expressiveFastSpatial; return Tokens.anim.curves.expressiveFastSpatial;
if (type === Anim.DefaultSpatial) if (type === Anim.DefaultSpatial)
return Appearance.anim.curves.expressiveDefaultSpatial; return Tokens.anim.curves.expressiveDefaultSpatial;
if (type === Anim.SlowSpatial) if (type === Anim.SlowSpatial)
return Appearance.anim.curves.expressiveSlowSpatial; return Tokens.anim.curves.expressiveSlowSpatial;
if (type === Anim.FastEffects) if (type === Anim.FastEffects)
return Appearance.anim.curves.expressiveFastEffects; return Tokens.anim.curves.expressiveFastEffects;
if (type === Anim.DefaultEffects) if (type === Anim.DefaultEffects)
return Appearance.anim.curves.expressiveDefaultEffects; return Tokens.anim.curves.expressiveDefaultEffects;
if (type === Anim.SlowEffects) if (type === Anim.SlowEffects)
return Appearance.anim.curves.expressiveSlowEffects; return Tokens.anim.curves.expressiveSlowEffects;
if (type >= Anim.EmphasizedSmall && type <= Anim.EmphasizedExtraLarge) if (type >= Anim.EmphasizedSmall && type <= Anim.EmphasizedExtraLarge)
return Appearance.anim.curves.emphasized; return Tokens.anim.curves.emphasized;
return Appearance.anim.curves.standard; return Tokens.anim.curves.standard;
} }
} }
@@ -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
}
}
}
-165
View File
@@ -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;
}
}
}
+59 -4
View File
@@ -1,8 +1,63 @@
import QtQuick import QtQuick
import qs.Config import ZShell.Config
ColorAnimation { ColorAnimation {
duration: MaterialEasing.standardTime enum Type {
easing.bezierCurve: MaterialEasing.standard StandardSmall = 0,
easing.type: Easing.BezierSpline 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;
}
} }
+11 -11
View File
@@ -1,7 +1,8 @@
import qs.Config import ZShell.Config
import ZShell.Internal import ZShell.Internal
import QtQuick import QtQuick
import QtQuick.Templates import QtQuick.Templates
import qs.Services
BusyIndicator { BusyIndicator {
id: root id: root
@@ -17,12 +18,12 @@ BusyIndicator {
} }
property int animState property int animState
property color bgColour: DynamicColors.palette.m3secondaryContainer property color bgColor: Colors.palette.m3secondaryContainer
property color fgColour: DynamicColors.palette.m3primary property color fgColor: Colors.palette.m3primary
property real implicitSize: Appearance.font.size.normal * 3 property real implicitSize: Tokens.font.size.normal * 3
property real internalStrokeWidth: strokeWidth property real internalStrokeWidth: strokeWidth
readonly property alias progress: manager.progress 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 property alias type: manager.indeterminateAnimationType
implicitHeight: implicitSize implicitHeight: implicitSize
@@ -31,8 +32,8 @@ BusyIndicator {
contentItem: CircularProgress { contentItem: CircularProgress {
anchors.fill: parent anchors.fill: parent
bgColour: root.bgColour bgColor: root.bgColor
fgColour: root.fgColour fgColor: root.fgColor
padding: root.padding padding: root.padding
rotation: manager.rotation rotation: manager.rotation
startAngle: manager.startFraction * 360 startAngle: manager.startFraction * 360
@@ -50,7 +51,7 @@ BusyIndicator {
} }
transitions: Transition { transitions: Transition {
Anim { Anim {
duration: manager.completeEndDuration * Appearance.anim.durations.scale duration: manager.completeEndDuration * Tokens.anim.durations.scale
properties: "opacity,internalStrokeWidth" properties: "opacity,internalStrokeWidth"
} }
} }
@@ -73,11 +74,10 @@ BusyIndicator {
CircularIndicatorManager { CircularIndicatorManager {
id: manager id: manager
} }
NumberAnimation { NumberAnimation {
duration: manager.duration * Appearance.anim.durations.scale duration: manager.duration * Tokens.anim.durations.scale
from: 0 from: 0
loops: Animation.Infinite loops: Animation.Infinite
property: "progress" property: "progress"
@@ -87,7 +87,7 @@ BusyIndicator {
} }
NumberAnimation { NumberAnimation {
duration: manager.completeEndDuration * Appearance.anim.durations.scale duration: manager.completeEndDuration * Tokens.anim.durations.scale
from: 0 from: 0
property: "completeEndProgress" property: "completeEndProgress"
running: root.animState === CircularIndicator.Completing running: root.animState === CircularIndicator.Completing
+92 -41
View File
@@ -1,66 +1,117 @@
pragma ComponentBehavior: Bound
import QtQuick import QtQuick
import QtQuick.Shapes import QtQuick.Shapes
import qs.Config import ZShell.Components
import ZShell.Config
import qs.Services
Shape { Item {
id: root id: root
readonly property real arcRadius: (size - padding - strokeWidth) / 2 readonly property real arcRadius: (size - padding - strokeWidth * (1 + waveAmplitude * 2)) / 2
property color bgColour: DynamicColors.palette.m3secondaryContainer property color bgColor: Colors.palette.m3secondaryContainer
property color fgColour: DynamicColors.palette.m3primary 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) readonly property real gapAngle: ((spacing + strokeWidth) / (arcRadius || 1)) * (180 / Math.PI)
property alias hasEndIndicator: dot.active
property real implicitSize
property int padding: 0 property int padding: 0
readonly property real size: Math.min(width, height) 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 startAngle: -90
property int strokeWidth: Appearance.padding.smaller property int strokeWidth: Tokens.padding.small
readonly property real vValue: value || 1 / 360 property int sweepAngle: 360
readonly property real thickness: strokeWidth * (1 + waveAmplitude) * 2
property real value 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 implicitHeight: implicitSize
preferredRendererType: Shape.CurveRenderer implicitWidth: implicitSize
ShapePath { Shape {
capStyle: Appearance.rounding.scale === 0 ? ShapePath.SquareCap : ShapePath.RoundCap asynchronous: true
fillColor: "transparent" opacity: Math.min(1, remainingArc.sweepAngle)
strokeColor: root.bgColour preferredRendererType: Shape.CurveRenderer
strokeWidth: root.strokeWidth
Behavior on strokeColor { ShapePath {
CAnim { capStyle: ShapePath.RoundCap
duration: Appearance.anim.durations.large fillColor: "transparent"
strokeColor: root.bgColor
strokeWidth: Math.min(1, remainingArc.sweepAngle) * root.strokeWidth
Behavior on strokeColor {
CAnim {
}
} }
}
PathAngleArc { PathAngleArc {
centerX: root.size / 2 id: remainingArc
centerY: root.size / 2
radiusX: root.arcRadius centerX: root.size / 2
radiusY: root.arcRadius centerY: root.size / 2
startAngle: root.startAngle + 360 * root.vValue + root.gapAngle radiusX: root.arcRadius
sweepAngle: Math.max(-root.gapAngle, 360 * (1 - root.vValue) - root.gapAngle * 2) 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 { WavyLine {
capStyle: Appearance.rounding.scale === 0 ? ShapePath.SquareCap : ShapePath.RoundCap id: wave
fillColor: "transparent"
strokeColor: root.fgColour
strokeWidth: root.strokeWidth
Behavior on strokeColor { amplitudeMultiplier: root.wavy ? 0.5 : 0
CAnim { anchors.fill: parent
duration: Appearance.anim.durations.large 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 { duration: 2000
centerX: root.size / 2 easing.type: Easing.Linear
centerY: root.size / 2 from: 0
radiusX: root.arcRadius loops: Animation.Infinite
radiusY: root.arcRadius paused: root.wavePaused || wave.amplitudeMultiplier === 0
startAngle: root.startAngle running: true
sweepAngle: 360 * root.vValue 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
} }
} }
} }
-135
View File
@@ -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
}
}
}
}
-208
View File
@@ -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;
}
}
}
-34
View File
@@ -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
}
}
-14
View File
@@ -1,14 +0,0 @@
import QtQuick
import QtQuick.Effects
MultiEffect {
property color sourceColor: "black"
brightness: 1 - sourceColor.hslLightness
colorization: 1
Behavior on colorizationColor {
CAnim {
}
}
}
-70
View File
@@ -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
}
}
}
@@ -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
}
]
}
}
}
}
}
-32
View File
@@ -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();
}
}
}
-37
View File
@@ -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
}
}
}
-169
View File
@@ -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
}
}
}
-10
View File
@@ -1,10 +0,0 @@
pragma ComponentBehavior: Bound
import Quickshell.Widgets
import QtQuick
IconImage {
id: root
asynchronous: true
}
-53
View File
@@ -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
}
}
}
-189
View File
@@ -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));
}
}
}
}
}
-5
View File
@@ -1,5 +0,0 @@
import Quickshell.Hyprland
GlobalShortcut {
appid: "zshell"
}
-174
View File
@@ -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;
}
}
}
-168
View File
@@ -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();
}
}
}
-148
View File
@@ -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
}
}
@@ -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;
}
}
}
}
-157
View File
@@ -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
}
}
+6 -7
View File
@@ -1,7 +1,8 @@
pragma ComponentBehavior: Bound pragma ComponentBehavior: Bound
import QtQuick import QtQuick
import qs.Config import ZShell.Config
import qs.Services
Text { Text {
id: root id: root
@@ -12,10 +13,10 @@ Text {
property string animateProp: "scale" property string animateProp: "scale"
property real animateTo: 1 property real animateTo: 1
color: DynamicColors.palette.m3onSurface color: Colors.palette.m3onSurface
font.family: Appearance.font.family.sans font.family: Config.appearance.font.family.sans
font.pointSize: Appearance.font.size.normal font.pointSize: Tokens.font.size.normal
linkColor: DynamicColors.palette.m3onPrimaryFixedVariant linkColor: Colors.palette.m3onPrimaryFixedVariant
renderType: Text.NativeRendering renderType: Text.NativeRendering
textFormat: Text.PlainText textFormat: Text.PlainText
@@ -28,7 +29,6 @@ Text {
SequentialAnimation { SequentialAnimation {
Anim { Anim {
easing.bezierCurve: MaterialEasing.standardAccel
to: root.animateFrom to: root.animateFrom
} }
@@ -36,7 +36,6 @@ Text {
} }
Anim { Anim {
easing.bezierCurve: MaterialEasing.standardDecel
to: root.animateTo to: root.animateTo
} }
} }
+9 -8
View File
@@ -2,17 +2,18 @@ pragma ComponentBehavior: Bound
import QtQuick import QtQuick
import QtQuick.Controls import QtQuick.Controls
import qs.Config import ZShell.Config
import qs.Services
TextField { TextField {
id: root id: root
background: null background: null
color: DynamicColors.palette.m3onSurface color: Colors.palette.m3onSurface
cursorVisible: !readOnly cursorVisible: !readOnly
font.family: Appearance.font.family.sans font.family: Config.appearance.font.family.sans
font.pointSize: Appearance.font.size.smaller font.pointSize: Tokens.font.size.smaller
placeholderTextColor: DynamicColors.palette.m3outline placeholderTextColor: Colors.palette.m3outline
renderType: echoMode === TextField.Password ? TextField.QtRendering : TextField.NativeRendering renderType: echoMode === TextField.Password ? TextField.QtRendering : TextField.NativeRendering
Behavior on color { Behavior on color {
@@ -24,13 +25,13 @@ TextField {
property bool disableBlink property bool disableBlink
color: DynamicColors.palette.m3primary color: Colors.palette.m3primary
implicitWidth: 2 implicitWidth: 2
radius: Appearance.rounding.normal radius: Tokens.rounding.normal
Behavior on opacity { Behavior on opacity {
Anim { Anim {
duration: Appearance.anim.durations.small duration: Tokens.anim.durations.small
} }
} }
+6 -5
View File
@@ -1,15 +1,16 @@
import QtQuick import QtQuick
import QtQuick.Controls import QtQuick.Controls
import qs.Config import ZShell.Config
import qs.Services
TextInput { TextInput {
renderType: Text.NativeRendering renderType: Text.NativeRendering
selectedTextColor: DynamicColors.palette.m3onSecondaryContainer selectedTextColor: Colors.palette.m3onSecondaryContainer
selectionColor: DynamicColors.tPalette.colSecondaryContainer selectionColor: Colors.tPalette.m3onSecondaryContainer
font { font {
family: Appearance?.font.family.sans ?? "sans-serif" family: Config.appearance?.font.family.sans ?? "sans-serif"
hintingPreference: Font.PreferFullHinting hintingPreference: Font.PreferFullHinting
pixelSize: Appearance?.font.size.normal ?? 15 pixelSize: Config.appearance?.font.size.normal ?? 15
} }
} }
-25
View File
@@ -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
}
}
@@ -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
}
}
}
+3 -2
View File
@@ -1,13 +1,14 @@
import QtQuick import QtQuick
import QtQuick.Effects import QtQuick.Effects
import qs.Config import ZShell.Config
import qs.Services
RectangularShadow { RectangularShadow {
property real dp: [0, 1, 3, 6, 8, 12][level] property real dp: [0, 1, 3, 6, 8, 12][level]
property int level property int level
blur: (dp * 5) ** 0.7 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 offset.y: dp / 2
spread: -dp * 0.3 + (dp * 0.1) ** 2 spread: -dp * 0.3 + (dp * 0.1) ** 2

Some files were not shown because too many files have changed in this diff Show More