From 1f9630ed76d397f9a4feffccd862e691f651b67f Mon Sep 17 00:00:00 2001 From: zach Date: Sun, 7 Jun 2026 12:55:32 +0200 Subject: [PATCH] port new components to greeter --- Components/CollapsibleSection.qml | 10 +- Components/CustomButton.qml | 6 +- Components/CustomRadioButton.qml | 8 +- Components/CustomSpinBox.qml | 14 +- Components/IconButton.qml | 8 +- Drawers/Windows.qml | 2 - Greeter/Center.qml | 14 +- Greeter/Components/Anim.qml | 61 ++++- Greeter/Components/CollapsibleSection.qml | 10 +- Greeter/Components/CustomButton.qml | 6 +- Greeter/Components/CustomRadioButton.qml | 8 +- Greeter/Components/CustomSlider.qml | 181 +++++++++++-- Greeter/Components/CustomSpinBox.qml | 25 +- Greeter/Components/CustomSplitButton.qml | 105 +++----- Greeter/Components/CustomSplitButtonRow.qml | 30 ++- Greeter/Components/CustomSwitch.qml | 34 +-- Greeter/Components/CustomText.qml | 1 + Greeter/Components/Elevation.qml | 3 +- Greeter/Components/HoverIconButton.qml | 33 +++ Greeter/Components/IconButton.qml | 11 +- Greeter/Components/MarqueeText.qml | 2 + Greeter/Components/Menu.qml | 198 ++++++++++----- Greeter/Components/PathViewMenu.qml | 2 + Greeter/Components/StateLayer.qml | 239 +++++++++++++----- Greeter/Config/Appearance.qml | 3 +- Greeter/Config/AppearanceConf.qml | 31 ++- Greeter/Config/BackgroundConfig.qml | 7 + Greeter/Config/BarConfig.qml | 21 +- Greeter/Config/Colors.qml | 8 + Greeter/Config/Config.qml | 62 ++++- Greeter/Config/DynamicColors.qml | 76 +----- Greeter/Config/General.qml | 20 +- Greeter/Config/Launcher.qml | 1 + Greeter/Config/LockConf.qml | 2 + Greeter/Config/Screenshot.qml | 13 + Greeter/Config/Services.qml | 1 + Greeter/SessionDock.qml | 2 +- Greeter/UserDock.qml | 2 +- Modules/Dashboard/Dash/Calendar.qml | 20 +- Modules/Dashboard/Dash/Media.qml | 8 +- Modules/Launcher/Items/ActionItem.qml | 6 +- Modules/Launcher/Items/AppItem.qml | 6 +- Modules/Launcher/Items/CalcItem.qml | 12 +- Modules/Launcher/Items/VariantItem.qml | 6 +- Modules/Launcher/Items/WallpaperItem.qml | 6 +- Modules/Lock/Center.qml | 14 +- Modules/Lock/Media.qml | 6 +- Modules/Lock/NotifGroup.qml | 6 +- Modules/NotifBell.qml | 2 - Modules/Notifications/Notification.qml | 16 +- .../Notifications/Sidebar/NotifActionList.qml | 2 +- Modules/Notifications/Sidebar/NotifGroup.qml | 6 +- Modules/Settings/Controls/SpinnerButton.qml | 6 +- Modules/Settings/Controls/WallpaperGrid.qml | 8 +- Modules/SysTray/Popouts/TrayMenuPopout.qml | 16 +- Modules/SysTray/Popouts/UPowerPopout.qml | 8 +- 56 files changed, 919 insertions(+), 495 deletions(-) create mode 100644 Greeter/Components/HoverIconButton.qml create mode 100644 Greeter/Config/Screenshot.qml diff --git a/Components/CollapsibleSection.qml b/Components/CollapsibleSection.qml index 6d6fc3e..46e4753 100644 --- a/Components/CollapsibleSection.qml +++ b/Components/CollapsibleSection.qml @@ -59,15 +59,15 @@ ColumnLayout { } StateLayer { - function onClicked(): void { - root.toggleRequested(); - root.expanded = !root.expanded; - } - anchors.fill: parent color: DynamicColors.palette.m3onSurface radius: Appearance.rounding.normal showHoverBackground: false + + onClicked: { + root.toggleRequested(); + root.expanded = !root.expanded; + } } } diff --git a/Components/CustomButton.qml b/Components/CustomButton.qml index 4b572bd..b98710f 100644 --- a/Components/CustomButton.qml +++ b/Components/CustomButton.qml @@ -23,10 +23,10 @@ Button { } StateLayer { - function onClicked(): void { + radius: control.radius + + onClicked: { control.clicked(); } - - radius: control.radius } } diff --git a/Components/CustomRadioButton.qml b/Components/CustomRadioButton.qml index 481268b..67204d1 100644 --- a/Components/CustomRadioButton.qml +++ b/Components/CustomRadioButton.qml @@ -33,13 +33,13 @@ RadioButton { } StateLayer { - function onClicked(): void { - root.click(); - } - anchors.margins: -7 color: root.checked ? DynamicColors.palette.m3onSurface : DynamicColors.palette.m3primary z: -1 + + onClicked: { + root.click(); + } } CustomRect { diff --git a/Components/CustomSpinBox.qml b/Components/CustomSpinBox.qml index 72479c8..7526242 100644 --- a/Components/CustomSpinBox.qml +++ b/Components/CustomSpinBox.qml @@ -94,7 +94,9 @@ RowLayout { StateLayer { id: upState - function onClicked(): void { + 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; @@ -103,9 +105,6 @@ RowLayout { root.displayText = newValue.toString(); root.valueModified(newValue); } - - color: DynamicColors.palette.m3onPrimary - onPressAndHold: timer.start() onReleased: timer.stop() } @@ -128,7 +127,9 @@ RowLayout { StateLayer { id: downState - function onClicked(): void { + 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; @@ -137,9 +138,6 @@ RowLayout { root.displayText = newValue.toString(); root.valueModified(newValue); } - - color: DynamicColors.palette.m3onPrimary - onPressAndHold: timer.start() onReleased: timer.stop() } diff --git a/Components/IconButton.qml b/Components/IconButton.qml index e121651..22314f7 100644 --- a/Components/IconButton.qml +++ b/Components/IconButton.qml @@ -54,14 +54,14 @@ CustomRect { StateLayer { id: stateLayer - function onClicked(): void { + color: root.internalChecked ? root.activeOnColour : root.inactiveOnColour + disabled: root.disabled + + onClicked: { if (root.toggle) root.internalChecked = !root.internalChecked; root.clicked(); } - - color: root.internalChecked ? root.activeOnColour : root.inactiveOnColour - disabled: root.disabled } MaterialIcon { diff --git a/Drawers/Windows.qml b/Drawers/Windows.qml index b59b95e..4151f01 100644 --- a/Drawers/Windows.qml +++ b/Drawers/Windows.qml @@ -297,7 +297,6 @@ CustomWindow { active: visibilities.isDrawing anchors.fill: parent - z: 2 sourceComponent: Drawing { id: drawing @@ -334,7 +333,6 @@ CustomWindow { popouts: panels.popouts screen: root.screen visibilities: visibilities - z: 1 Panels { id: panels diff --git a/Greeter/Center.qml b/Greeter/Center.qml index 3c9711a..713aa5f 100644 --- a/Greeter/Center.qml +++ b/Greeter/Center.qml @@ -118,12 +118,12 @@ ColumnLayout { } StateLayer { - function onClicked(): void { - parent.forceActiveFocus(); - } - cursorShape: Qt.IBeamCursor hoverEnabled: false + + onClicked: { + parent.forceActiveFocus(); + } } RowLayout { @@ -179,11 +179,11 @@ ColumnLayout { radius: Appearance.rounding.full StateLayer { - function onClicked(): void { + color: root.greeter.buffer && !root.greeter.launching ? DynamicColors.palette.m3onPrimary : DynamicColors.palette.m3onSurface + + onClicked: { root.greeter.submit(); } - - color: root.greeter.buffer && !root.greeter.launching ? DynamicColors.palette.m3onPrimary : DynamicColors.palette.m3onSurface } MaterialIcon { diff --git a/Greeter/Components/Anim.qml b/Greeter/Components/Anim.qml index 242354f..0b02612 100644 --- a/Greeter/Components/Anim.qml +++ b/Greeter/Components/Anim.qml @@ -2,7 +2,62 @@ import QtQuick import qs.Config NumberAnimation { - duration: MaterialEasing.standardTime - easing.bezierCurve: MaterialEasing.standard - easing.type: Easing.BezierSpline + enum Type { + StandardSmall = 0, + Standard, + StandardLarge, + StandardExtraLarge, + EmphasizedSmall, + Emphasized, + EmphasizedLarge, + EmphasizedExtraLarge, + FastSpatial, + DefaultSpatial, + SlowSpatial, + FastEffects, + DefaultEffects, + SlowEffects + } + + property int type: Anim.DefaultSpatial + + duration: { + if (type < Anim.StandardSmall || type > Anim.SlowEffects) + return Appearance.anim.durations.normal; + + if (type === Anim.FastSpatial) + return Appearance.anim.durations.expressiveFastSpatial; + if (type === Anim.DefaultSpatial) + return Appearance.anim.durations.expressiveDefaultSpatial; + if (type === Anim.SlowSpatial) + return Appearance.anim.durations.large; + if (type === Anim.FastEffects) + return Appearance.anim.durations.expressiveFastEffects; + if (type === Anim.DefaultEffects) + return Appearance.anim.durations.expressiveEffects; + if (type === Anim.SlowEffects) + return Appearance.anim.durations.expressiveSlowEffects; + + const types = ["small", "normal", "large", "extraLarge"]; + const idx = type % 4; // 0-7 are the 4 standard types + return Appearance.anim.durations[types[idx]]; + } + easing.bezierCurve: { + if (type === Anim.FastSpatial) + return Appearance.anim.curves.expressiveFastSpatial; + if (type === Anim.DefaultSpatial) + return Appearance.anim.curves.expressiveDefaultSpatial; + if (type === Anim.SlowSpatial) + return Appearance.anim.curves.expressiveSlowSpatial; + if (type === Anim.FastEffects) + return Appearance.anim.curves.expressiveFastEffects; + if (type === Anim.DefaultEffects) + return Appearance.anim.curves.expressiveDefaultEffects; + if (type === Anim.SlowEffects) + return Appearance.anim.curves.expressiveSlowEffects; + + if (type >= Anim.EmphasizedSmall && type <= Anim.EmphasizedExtraLarge) + return Appearance.anim.curves.emphasized; + return Appearance.anim.curves.standard; + } } diff --git a/Greeter/Components/CollapsibleSection.qml b/Greeter/Components/CollapsibleSection.qml index 6d6fc3e..46e4753 100644 --- a/Greeter/Components/CollapsibleSection.qml +++ b/Greeter/Components/CollapsibleSection.qml @@ -59,15 +59,15 @@ ColumnLayout { } StateLayer { - function onClicked(): void { - root.toggleRequested(); - root.expanded = !root.expanded; - } - anchors.fill: parent color: DynamicColors.palette.m3onSurface radius: Appearance.rounding.normal showHoverBackground: false + + onClicked: { + root.toggleRequested(); + root.expanded = !root.expanded; + } } } diff --git a/Greeter/Components/CustomButton.qml b/Greeter/Components/CustomButton.qml index 4b572bd..b98710f 100644 --- a/Greeter/Components/CustomButton.qml +++ b/Greeter/Components/CustomButton.qml @@ -23,10 +23,10 @@ Button { } StateLayer { - function onClicked(): void { + radius: control.radius + + onClicked: { control.clicked(); } - - radius: control.radius } } diff --git a/Greeter/Components/CustomRadioButton.qml b/Greeter/Components/CustomRadioButton.qml index 481268b..67204d1 100644 --- a/Greeter/Components/CustomRadioButton.qml +++ b/Greeter/Components/CustomRadioButton.qml @@ -33,13 +33,13 @@ RadioButton { } StateLayer { - function onClicked(): void { - root.click(); - } - anchors.margins: -7 color: root.checked ? DynamicColors.palette.m3onSurface : DynamicColors.palette.m3primary z: -1 + + onClicked: { + root.click(); + } } CustomRect { diff --git a/Greeter/Components/CustomSlider.qml b/Greeter/Components/CustomSlider.qml index 32c8f69..3041698 100644 --- a/Greeter/Components/CustomSlider.qml +++ b/Greeter/Components/CustomSlider.qml @@ -1,45 +1,174 @@ +pragma ComponentBehavior: Bound + import QtQuick import QtQuick.Templates +import ZShell.Components +import ZShell +import qs.Components import qs.Config Slider { id: root - background: Item { + 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 { - anchors.bottom: parent.bottom - anchors.left: parent.left - anchors.top: parent.top - bottomRightRadius: root.implicitHeight / 6 - color: DynamicColors.palette.m3primary - implicitWidth: root.handle.x - root.implicitHeight / 2 - radius: Appearance.rounding.full - topRightRadius: root.implicitHeight / 6 + 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.bottom: parent.bottom anchors.right: parent.right - anchors.top: parent.top - bottomLeftRadius: root.implicitHeight / 6 - color: DynamicColors.tPalette.m3surfaceContainer - implicitWidth: parent.width - root.handle.x - root.handle.implicitWidth - root.implicitHeight / 2 + 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 - topLeftRadius: root.implicitHeight / 6 + } + + 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 + } + } } } - 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 + Behavior on filledWidth { + id: widthBehavior - MouseArea { - acceptedButtons: Qt.NoButton - anchors.fill: parent - cursorShape: Qt.PointingHandCursor + Anim { + } + } + + Component.onCompleted: filledWidth = Qt.binding(() => (width - handle.implicitWidth - handle.anchors.leftMargin) * pos) + + Binding { + id: posBinding + + property: "pos" + target: root + value: ZUtils.clamp(mouse.pressStartPos + mouse.dragMovement, 0, 1) + when: mouse.pressed + } + + MouseArea { + id: mouse + + property real dragMovement + property real pressStartPos + property real pressStartX + + anchors.left: parent.left + anchors.right: parent.right + anchors.verticalCenter: parent.verticalCenter + implicitHeight: handle.implicitHeight + preventStealing: true + + onPositionChanged: e => { + dragMovement = (e.x - pressStartX) / width; + root.interaction(posBinding.value); + } + onPressed: e => { + widthBehavior.enabled = false; + pressStartX = e.x; + pressStartPos = root.visualPosition; + } + onReleased: e => { + root.interaction(posBinding.value); + widthBehavior.enabled = true; + dragMovement = 0; } } } diff --git a/Greeter/Components/CustomSpinBox.qml b/Greeter/Components/CustomSpinBox.qml index 5a4245b..7526242 100644 --- a/Greeter/Components/CustomSpinBox.qml +++ b/Greeter/Components/CustomSpinBox.qml @@ -28,6 +28,7 @@ RowLayout { 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 @@ -36,7 +37,7 @@ RowLayout { text: root.isEditing ? text : root.displayText background: CustomRect { - color: DynamicColors.tPalette.m3surfaceContainerHigh + color: root.enabled ? DynamicColors.tPalette.m3surfaceContainerHigh : DynamicColors.tPalette.m3surfaceContainerLow implicitWidth: 100 radius: Appearance.rounding.full } @@ -85,7 +86,7 @@ RowLayout { CustomRect { id: upButton - color: DynamicColors.palette.m3primary + 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 @@ -93,7 +94,9 @@ RowLayout { StateLayer { id: upState - function onClicked(): void { + 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; @@ -102,9 +105,6 @@ RowLayout { root.displayText = newValue.toString(); root.valueModified(newValue); } - - color: DynamicColors.palette.m3onPrimary - onPressAndHold: timer.start() onReleased: timer.stop() } @@ -113,13 +113,13 @@ RowLayout { id: upIcon anchors.centerIn: parent - color: DynamicColors.palette.m3onPrimary + color: root.enabled ? DynamicColors.palette.m3onPrimary : Qt.alpha(DynamicColors.palette.m3onSurface, 0.5) text: "keyboard_arrow_up" } } CustomRect { - color: DynamicColors.palette.m3primary + 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 @@ -127,7 +127,9 @@ RowLayout { StateLayer { id: downState - function onClicked(): void { + 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; @@ -136,9 +138,6 @@ RowLayout { root.displayText = newValue.toString(); root.valueModified(newValue); } - - color: DynamicColors.palette.m3onPrimary - onPressAndHold: timer.start() onReleased: timer.stop() } @@ -147,7 +146,7 @@ RowLayout { id: downIcon anchors.centerIn: parent - color: DynamicColors.palette.m3onPrimary + color: root.enabled ? DynamicColors.palette.m3onPrimary : Qt.alpha(DynamicColors.palette.m3onSurface, 0.5) text: "keyboard_arrow_down" } } diff --git a/Greeter/Components/CustomSplitButton.qml b/Greeter/Components/CustomSplitButton.qml index 6f9ad95..76364cc 100644 --- a/Greeter/Components/CustomSplitButton.qml +++ b/Greeter/Components/CustomSplitButton.qml @@ -1,7 +1,6 @@ import QtQuick import QtQuick.Layouts import qs.Config -import qs.Helpers Row { id: root @@ -12,66 +11,46 @@ Row { } property alias active: menu.active - property color color: type == CustomSplitButton.Filled ? DynamicColors.palette.m3primary : DynamicColors.palette.m3secondaryContainer + property color colour: type == CustomSplitButton.Filled ? DynamicColors.palette.m3primary : DynamicColors.palette.m3secondaryContainer property bool disabled - property color disabledColor: Qt.alpha(DynamicColors.palette.m3onSurface, 0.1) - property color disabledTextColor: Qt.alpha(DynamicColors.palette.m3onSurface, 0.38) + 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.normal - property alias iconLabel: iconLabel - property alias label: label - property alias menu: menu + 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 alias stateLayer: stateLayer - property color textColor: type == CustomSplitButton.Filled ? DynamicColors.palette.m3onPrimary : DynamicColors.palette.m3onSecondaryContainer + 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.smaller + property real verticalPadding: Appearance.padding.small - function closeDropdown(): void { - SettingsDropdowns.close(menu); - } - - function openDropdown(): void { - if (root.disabled) - return; - SettingsDropdowns.open(menu, root); - } - - function toggleDropdown(): void { - if (root.disabled) - return; - SettingsDropdowns.toggle(menu, root); - } - - spacing: Math.floor(Appearance.spacing.small / 2) - - onExpandedChanged: { - if (!expanded) - SettingsDropdowns.forget(menu); - } + spacing: Math.floor(Appearance.spacing.extraSmall) CustomRect { bottomRightRadius: Appearance.rounding.small / 2 - color: root.disabled ? root.disabledColor : root.color + color: root.disabled ? root.disabledColour : root.colour implicitHeight: expandBtn.implicitHeight - implicitWidth: textRow.implicitWidth + root.horizontalPadding * 2 + 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 - function onClicked(): void { - root.active?.clicked(); - } - - color: root.textColor + bottomRightRadius: parent.bottomRightRadius + color: root.textColour disabled: root.disabled - rect.bottomRightRadius: parent.bottomRightRadius - rect.topRightRadius: parent.topRightRadius + topRightRadius: parent.topRightRadius + + onClicked: root.active?.clicked() } RowLayout { @@ -86,7 +65,7 @@ Row { Layout.alignment: Qt.AlignVCenter animate: true - color: root.disabled ? root.disabledTextColor : root.textColor + color: root.disabled ? root.disabledTextColour : root.textColour fill: 1 text: root.active?.activeIcon ?? root.fallbackIcon } @@ -98,12 +77,12 @@ Row { Layout.preferredWidth: implicitWidth animate: true clip: true - color: root.disabled ? root.disabledTextColor : root.textColor + color: root.disabled ? root.disabledTextColour : root.textColour text: root.active?.activeText ?? root.fallbackText Behavior on Layout.preferredWidth { Anim { - easing.bezierCurve: Appearance.anim.curves.emphasized + type: Anim.Emphasized } } } @@ -116,7 +95,7 @@ Row { property real rad: root.expanded ? implicitHeight / 2 * Math.min(1, Appearance.rounding.scale) : Appearance.rounding.small / 2 bottomLeftRadius: rad - color: root.disabled ? root.disabledColor : root.color + color: root.disabled ? root.disabledColour : root.colour implicitHeight: expandIcon.implicitHeight + root.verticalPadding * 2 implicitWidth: implicitHeight radius: implicitHeight / 2 * Math.min(1, Appearance.rounding.scale) @@ -130,14 +109,12 @@ Row { StateLayer { id: expandStateLayer - function onClicked(): void { - root.toggleDropdown(); - } - - color: root.textColor + color: root.textColour disabled: root.disabled rect.bottomLeftRadius: parent.bottomLeftRadius rect.topLeftRadius: parent.topLeftRadius + + onClicked: root.expanded = !root.expanded } MaterialIcon { @@ -145,7 +122,7 @@ Row { anchors.centerIn: parent anchors.horizontalCenterOffset: root.expanded ? 0 : -Math.floor(root.verticalPadding / 4) - color: root.disabled ? root.disabledTextColor : root.textColor + color: root.disabled ? root.disabledTextColour : root.textColour rotation: root.expanded ? 180 : 0 text: "expand_more" @@ -158,24 +135,14 @@ Row { } } } + } - Menu { - id: menu + Menu { + id: menu - anchors.bottomMargin: Appearance.spacing.small - anchors.right: parent.right - anchors.top: parent.bottom - anchors.topMargin: Appearance.spacing.small - - states: State { - when: root.menuOnTop - - AnchorChanges { - anchors.bottom: expandBtn.top - anchors.top: undefined - target: menu - } - } - } + attachSideY: root.menuOnTop ? Menu.Top : Menu.Bottom + attachTo: expandBtn + marginY: Appearance.spacing.small * (root.menuOnTop ? -1 : 1) + thisSideY: root.menuOnTop ? Menu.Bottom : Menu.Top } } diff --git a/Greeter/Components/CustomSplitButtonRow.qml b/Greeter/Components/CustomSplitButtonRow.qml index 491a8ed..2e59738 100644 --- a/Greeter/Components/CustomSplitButtonRow.qml +++ b/Greeter/Components/CustomSplitButtonRow.qml @@ -8,19 +8,32 @@ Item { id: root property alias active: splitButton.active - property bool enabled: true + 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) - Layout.fillWidth: true - Layout.preferredHeight: row.implicitHeight + Appearance.padding.smaller * 2 + anchors.left: parent.left + anchors.right: parent.right clip: false - z: root.expanded ? expandedZ : -1 + 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 @@ -36,7 +49,6 @@ Item { color: root.enabled ? DynamicColors.palette.m3onSurface : DynamicColors.palette.m3onSurfaceVariant font.pointSize: Appearance.font.size.larger text: root.label - z: root.expanded ? root.expandedZ : -1 } CustomSplitButton { @@ -44,14 +56,16 @@ Item { enabled: root.enabled type: CustomSplitButton.Filled - z: root.expanded ? root.expandedZ : -1 + z: 2 menu.onItemSelected: item => { root.selected(item); - splitButton.closeDropdown(); + // splitButton.closeDropdown(); } stateLayer.onClicked: { - splitButton.toggleDropdown(); + // splitButton.toggleDropdown(); + splitButton.expanded = !splitButton.expanded; + console.log(root.z); } } } diff --git a/Greeter/Components/CustomSwitch.qml b/Greeter/Components/CustomSwitch.qml index aa6e069..e715f15 100644 --- a/Greeter/Components/CustomSwitch.qml +++ b/Greeter/Components/CustomSwitch.qml @@ -1,6 +1,6 @@ import QtQuick -import QtQuick.Templates import QtQuick.Shapes +import QtQuick.Templates import qs.Config Switch { @@ -12,38 +12,41 @@ Switch { implicitWidth: implicitIndicatorWidth indicator: CustomRect { - color: root.checked ? DynamicColors.palette.m3primary : DynamicColors.layer(DynamicColors.palette.m3surfaceContainerHighest, root.cLayer) - implicitHeight: 13 + 7 * 2 + 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.3 : implicitHeight + readonly property real nonAnimWidth: root.pressed ? implicitHeight * 1.2 : implicitHeight anchors.verticalCenter: parent.verticalCenter - color: root.checked ? DynamicColors.palette.m3onPrimary : DynamicColors.layer(DynamicColors.palette.m3outline, root.cLayer + 1) - implicitHeight: parent.implicitHeight - 10 + 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 - 10 / 2 : 10 / 2 + 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 ? DynamicColors.palette.m3primary : DynamicColors.palette.m3onSurface + 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 } } } @@ -63,14 +66,14 @@ Switch { } property point end2: { if (root.pressed) - return Qt.point(width, height / 2); + 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.1, height / 2); + 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); @@ -88,7 +91,7 @@ Switch { anchors.centerIn: parent asynchronous: true - height: parent.implicitHeight - Appearance.padding.small * 2 + height: parent.implicitHeight - Appearance.padding.larger preferredRendererType: Shape.CurveRenderer width: height @@ -110,11 +113,11 @@ Switch { } ShapePath { - capStyle: Appearance.rounding.scale === 0 ? ShapePath.SquareCap : ShapePath.RoundCap + capStyle: ShapePath.RoundCap fillColor: "transparent" startX: icon.start1.x startY: icon.start1.y - strokeColor: root.checked ? DynamicColors.palette.m3primary : DynamicColors.palette.m3surfaceContainerHighest + strokeColor: root.checked && root.enabled ? DynamicColors.palette.m3primary : DynamicColors.palette.m3surfaceContainerHighest strokeWidth: Appearance.font.size.larger * 0.15 Behavior on strokeColor { @@ -148,8 +151,7 @@ Switch { } component PropAnim: PropertyAnimation { - duration: MaterialEasing.expressiveEffectsTime - easing.bezierCurve: MaterialEasing.expressiveEffects - easing.type: Easing.BezierSpline + duration: Appearance.anim.durations.expressiveFastSpatial + easing.bezierCurve: Appearance.anim.curves.expressiveFastSpatial } } diff --git a/Greeter/Components/CustomText.qml b/Greeter/Components/CustomText.qml index cff8b2d..f4c1600 100644 --- a/Greeter/Components/CustomText.qml +++ b/Greeter/Components/CustomText.qml @@ -15,6 +15,7 @@ Text { color: DynamicColors.palette.m3onSurface font.family: Appearance.font.family.sans font.pointSize: Appearance.font.size.normal + linkColor: DynamicColors.palette.m3onPrimaryFixedVariant renderType: Text.NativeRendering textFormat: Text.PlainText diff --git a/Greeter/Components/Elevation.qml b/Greeter/Components/Elevation.qml index 26b8fe6..bdef51e 100644 --- a/Greeter/Components/Elevation.qml +++ b/Greeter/Components/Elevation.qml @@ -1,6 +1,6 @@ -import qs.Config import QtQuick import QtQuick.Effects +import qs.Config RectangularShadow { property real dp: [0, 1, 3, 6, 8, 12][level] @@ -13,6 +13,7 @@ RectangularShadow { Behavior on dp { Anim { + type: Anim.SlowEffects } } } diff --git a/Greeter/Components/HoverIconButton.qml b/Greeter/Components/HoverIconButton.qml new file mode 100644 index 0000000..cd17ad0 --- /dev/null +++ b/Greeter/Components/HoverIconButton.qml @@ -0,0 +1,33 @@ +import QtQuick +import QtQuick.Controls +import qs.Config + +IconButton { + id: root + + required property bool shouldBeVisible + + opacity: 0 + scale: 0 + visible: root.scale > 0 + + Behavior on opacity { + Anim { + duration: Appearance.anim.durations.small + } + } + Behavior on scale { + Anim { + } + } + + onShouldBeVisibleChanged: { + if (root.shouldBeVisible) { + root.opacity = 1; + root.scale = 1; + } else { + root.opacity = 0; + root.scale = 0; + } + } +} diff --git a/Greeter/Components/IconButton.qml b/Greeter/Components/IconButton.qml index e55289a..22314f7 100644 --- a/Greeter/Components/IconButton.qml +++ b/Greeter/Components/IconButton.qml @@ -41,12 +41,11 @@ CustomRect { color: type === IconButton.Text ? "transparent" : disabled ? disabledColour : internalChecked ? activeColour : inactiveColour implicitHeight: label.implicitHeight + padding * 2 implicitWidth: implicitHeight - radius: internalChecked ? 6 : implicitHeight / 2 * Math.min(1, 1) + radius: internalChecked ? 6 : (implicitHeight / 2 * Math.min(1, 1)) * Appearance.rounding.scale Behavior on radius { Anim { id: radiusAnim - } } @@ -55,14 +54,14 @@ CustomRect { StateLayer { id: stateLayer - function onClicked(): void { + color: root.internalChecked ? root.activeOnColour : root.inactiveOnColour + disabled: root.disabled + + onClicked: { if (root.toggle) root.internalChecked = !root.internalChecked; root.clicked(); } - - color: root.internalChecked ? root.activeOnColour : root.inactiveOnColour - disabled: root.disabled } MaterialIcon { diff --git a/Greeter/Components/MarqueeText.qml b/Greeter/Components/MarqueeText.qml index 925b409..427d381 100644 --- a/Greeter/Components/MarqueeText.qml +++ b/Greeter/Components/MarqueeText.qml @@ -102,6 +102,7 @@ Item { animate: root.animate animateProp: "opacity" color: root.color + font.pointSize: elideText.font.pointSize text: elideText.text } @@ -111,6 +112,7 @@ Item { animate: root.animate animateProp: "opacity" color: root.color + font.pointSize: elideText.font.pointSize text: t1.text x: t1.width + root.gap } diff --git a/Greeter/Components/Menu.qml b/Greeter/Components/Menu.qml index 8222359..a633a9c 100644 --- a/Greeter/Components/Menu.qml +++ b/Greeter/Components/Menu.qml @@ -2,109 +2,169 @@ pragma ComponentBehavior: Bound import QtQuick import QtQuick.Layouts +import Quickshell import qs.Config +import qs.Drawers -Elevation { +MouseArea { id: root + enum Side { + Top, + Bottom, + Left, + Right + } + property MenuItem active: items[0] ?? null + property int attachSideX: Menu.Right + property int attachSideY: Menu.Bottom + required property Item attachTo property bool expanded property list items + property real marginX + property real marginY + property int thisSideX: Menu.Right + property int thisSideY: Menu.Top signal itemSelected(item: MenuItem) - implicitHeight: root.expanded ? column.implicitHeight + Appearance.padding.small * 2 : 0 - implicitWidth: Math.max(200, column.implicitWidth) - level: 2 - opacity: root.expanded ? 1 : 0 - radius: Appearance.rounding.normal - - Behavior on implicitHeight { - Anim { - duration: Appearance.anim.durations.expressiveDefaultSpatial - easing.bezierCurve: Appearance.anim.curves.expressiveDefaultSpatial - } + anchors.fill: parent + enabled: expanded + layer.enabled: opacity < 1 + opacity: expanded ? 1 : 0 + parent: { + const win = QsWindow.window; + const contentWin = win as Windows; + return contentWin ? contentWin.interactionWrapper : (win as QsWindow).contentItem; } + Behavior on opacity { Anim { - duration: Appearance.anim.durations.expressiveDefaultSpatial + type: Anim.DefaultEffects } } - CustomClippingRect { - anchors.fill: parent - color: DynamicColors.palette.m3surfaceContainer - radius: parent.radius + onClicked: expanded = false - ColumnLayout { - id: column + TransformWatcher { + id: watcher - anchors.left: parent.left - anchors.right: parent.right - anchors.verticalCenter: parent.verticalCenter - spacing: 5 + a: root.parent + b: root.attachTo + } - Repeater { - model: root.items + Elevation { + id: menu - CustomRect { - id: item + implicitHeight: column.implicitHeight + column.anchors.margins * 2 + implicitWidth: Math.max(200, column.implicitWidth + column.anchors.margins * 2) + level: 2 + radius: Appearance.rounding.medium + x: { + watcher.transform; + const item = root.attachTo; + let off = root.attachSideX === Menu.Left ? 0 : item.width; + if (root.thisSideX === Menu.Right) + off -= width; + return item.mapToItem(root.parent, off, 0).x + root.marginX; + } + y: { + watcher.transform; + const item = root.attachTo; + let off = root.attachSideY === Menu.Top ? 0 : item.height; + if (root.thisSideY === Menu.Bottom) + off -= height; + return item.mapToItem(root.parent, 0, off).y + root.marginY; + } - readonly property bool active: modelData === root.active - required property int index - required property MenuItem modelData + transform: Scale { + origin.y: root.thisSideY === Menu.Bottom ? menu.height : 0 + yScale: root.expanded ? 1 : 0.1 - Layout.fillWidth: true - implicitHeight: menuOptionRow.implicitHeight + Appearance.padding.normal * 2 - implicitWidth: menuOptionRow.implicitWidth + Appearance.padding.normal * 2 + Behavior on yScale { + Anim { + } + } + } + + CustomRect { + anchors.fill: parent + color: DynamicColors.palette.m3surfaceContainerLow + radius: parent.radius + + ColumnLayout { + id: column + + anchors.fill: parent + anchors.margins: Appearance.padding.extraSmall + spacing: Appearance.spacing.extraSmall + + Repeater { + id: repeater + + model: root.items CustomRect { - anchors.fill: parent - anchors.leftMargin: Appearance.padding.small - anchors.rightMargin: Appearance.padding.small - color: Qt.alpha(DynamicColors.palette.m3secondaryContainer, active ? 1 : 0) - radius: Appearance.rounding.normal - Appearance.padding.small + id: item + + readonly property bool active: modelData === root.active + required property int index + required property MenuItem modelData + + Layout.fillWidth: true + color: Qt.alpha(DynamicColors.palette.m3tertiaryContainer, active ? 1 : 0) + implicitHeight: menuOptionRow.implicitHeight + Appearance.padding.larger * 2 + implicitWidth: menuOptionRow.implicitWidth + Appearance.padding.larger * 2 + radius: Appearance.rounding.small + + Behavior on radius { + Anim { + } + } StateLayer { - function onClicked(): void { + color: item.active ? DynamicColors.palette.m3onTertiaryContainer : DynamicColors.palette.m3onSurface + disabled: !root.expanded + + onClicked: { root.itemSelected(item.modelData); root.active = item.modelData; + item.modelData.clicked(); root.expanded = false; } - - color: item.active ? DynamicColors.palette.m3onSecondaryContainer : DynamicColors.palette.m3onSurface - disabled: !root.expanded - } - } - - RowLayout { - id: menuOptionRow - - anchors.fill: parent - anchors.margins: Appearance.padding.normal - spacing: Appearance.spacing.small - - MaterialIcon { - Layout.alignment: Qt.AlignVCenter - color: item.active ? DynamicColors.palette.m3onSecondaryContainer : DynamicColors.palette.m3onSurfaceVariant - text: item.modelData.icon } - CustomText { - Layout.alignment: Qt.AlignVCenter - Layout.fillWidth: true - color: item.active ? DynamicColors.palette.m3onSecondaryContainer : DynamicColors.palette.m3onSurface - text: item.modelData.text - } + RowLayout { + id: menuOptionRow - Loader { - Layout.alignment: Qt.AlignVCenter - active: item.modelData.trailingIcon.length > 0 - visible: active + anchors.fill: parent + anchors.margins: Appearance.padding.larger + spacing: Appearance.spacing.small - sourceComponent: MaterialIcon { - color: item.active ? DynamicColors.palette.m3onSecondaryContainer : DynamicColors.palette.m3onSurface - text: item.modelData.trailingIcon + MaterialIcon { + Layout.alignment: Qt.AlignVCenter + color: item.active ? DynamicColors.palette.m3onTertiaryContainer : DynamicColors.palette.m3onSurfaceVariant + text: item.modelData.icon + } + + CustomText { + Layout.alignment: Qt.AlignVCenter + Layout.fillWidth: true + color: item.active ? DynamicColors.palette.m3onTertiaryContainer : DynamicColors.palette.m3onSurface + text: item.modelData.text + } + + Loader { + Layout.alignment: Qt.AlignVCenter + active: item.modelData.trailingIcon.length > 0 + asynchronous: true + visible: active + + sourceComponent: MaterialIcon { + color: item.active ? DynamicColors.palette.m3onTertiaryContainer : DynamicColors.palette.m3onSurfaceVariant + text: item.modelData.trailingIcon + } } } } diff --git a/Greeter/Components/PathViewMenu.qml b/Greeter/Components/PathViewMenu.qml index 898dd4b..111b236 100644 --- a/Greeter/Components/PathViewMenu.qml +++ b/Greeter/Components/PathViewMenu.qml @@ -29,6 +29,7 @@ Elevation { level: root.expanded ? 2 : 0 radius: itemHeight / 2 visible: implicitHeight > 0 + z: root.expanded ? 100 : 0 Behavior on implicitHeight { Anim { @@ -68,6 +69,7 @@ Elevation { anchors.fill: parent color: DynamicColors.palette.m3surfaceContainer radius: parent.radius + z: root.z // Main visible spinner: normal/outside text color PathView { diff --git a/Greeter/Components/StateLayer.qml b/Greeter/Components/StateLayer.qml index 53dc9e3..aa41297 100644 --- a/Greeter/Components/StateLayer.qml +++ b/Greeter/Components/StateLayer.qml @@ -1,15 +1,53 @@ -import qs.Config import QtQuick +import QtQuick.Shapes +import ZShell +import ZShell.Components +import qs.Helpers +import qs.Config MouseArea { id: root - property color color: DynamicColors.palette.m3onSurface + property alias bottomLeftRadius: base.bottomLeftRadius + property alias bottomRightRadius: base.bottomRightRadius + property real circleRadius + property alias color: base.color property bool disabled - property real radius: parent?.radius ?? 0 - property alias rect: hoverLayer + readonly property real endRadius: { + const d1 = distSq(0, 0); + const d2 = distSq(width, 0); + const d3 = distSq(0, height); + const d4 = distSq(width, height); + return (Math.sqrt(Math.max(d1, d2, d3, d4)) + (shapeMorph ? 24 : 0)) * 1.3; + } + property real endRadiusAtPress + property bool manualPressOverride + property real pressX: width / 2 + property real pressY: height / 2 + property alias radius: base.radius + readonly property alias rect: base + property bool shapeMorph + property bool showHoverBackground: true + property real stateOpacity: containsMouse ? 0.08 : 0 + property alias topLeftRadius: base.topLeftRadius + property alias topRightRadius: base.topRightRadius - function onClicked(): void { + function clamp(r: real): real { + return Math.max(0, Math.min(r, width / 2, height / 2)); + } + + function distSq(x: real, y: real): real { + return (pressX - x) ** 2 + (pressY - y) ** 2; + } + + function press(x: real, y: real): void { + pressX = x; + pressY = y; + fadeAnim.complete(); + circleRadius = 0; + circle.opacity = 0.1; + rippleAnim.restart(); + endRadiusAtPress = endRadius; } anchors.fill: parent @@ -17,79 +55,146 @@ MouseArea { enabled: !disabled hoverEnabled: true - onClicked: event => !disabled && onClicked(event) - onPressed: event => { - if (disabled) - return; - - rippleAnim.x = event.x; - rippleAnim.y = event.y; - - const dist = (ox, oy) => ox * ox + oy * oy; - rippleAnim.radius = Math.sqrt(Math.max(dist(event.x, event.y), dist(event.x, height - event.y), dist(width - event.x, event.y), dist(width - event.x, height - event.y))); - - rippleAnim.restart(); + Behavior on stateOpacity { + Anim { + type: Anim.DefaultEffects + } } - SequentialAnimation { + onCircleRadiusChanged: { + if (!(pressed || manualPressOverride) && circleRadius > endRadiusAtPress * 0.99 && !fadeAnim.running) + fadeAnim.start(); + } + onClicked: event => !disabled && onClicked(event) + onManualPressOverrideChanged: { + if (!(pressed || manualPressOverride) && circleRadius > endRadiusAtPress * 0.99 && !fadeAnim.running) + fadeAnim.start(); + } + onPressed: e => press(e.x, e.y) + onPressedChanged: { + if (!(pressed || manualPressOverride) && !rippleAnim.running && circle.opacity > 0) + fadeAnim.start(); + } + + Anim { id: rippleAnim - property real radius - property real x - property real y - - PropertyAction { - property: "x" - target: ripple - value: rippleAnim.x - } - - PropertyAction { - property: "y" - target: ripple - value: rippleAnim.y - } - - PropertyAction { - property: "opacity" - target: ripple - value: 0.08 - } - - Anim { - easing.bezierCurve: MaterialEasing.standardDecel - from: 0 - properties: "implicitWidth,implicitHeight" - target: ripple - to: rippleAnim.radius * 2 - } - - Anim { - property: "opacity" - target: ripple - to: 0 - } + alwaysRunToEnd: true + duration: Appearance.anim.durations.expressiveSlowEffects * 2 + easing.bezierCurve: Appearance.anim.curves.standard + property: "circleRadius" + target: root + to: root.endRadius } - CustomClippingRect { - id: hoverLayer + Anim { + id: fadeAnim + + property: "opacity" + target: circle + to: 0 + type: Anim.SlowEffects + } + + CustomRect { + id: base anchors.fill: parent - border.pixelAligned: false - color: Qt.alpha(root.color, root.disabled ? 0 : root.pressed ? 0.1 : root.containsMouse ? 0.08 : 0) - radius: root.radius + bottomLeftRadius: root.parent?.bottomLeftRadius ?? radius ?? 0 + bottomRightRadius: root.parent?.bottomRightRadius ?? radius ?? 0 + color: DynamicColors.palette.m3onSurface + opacity: root.stateOpacity + // Pick up radius from parent if it has one (parent can be anything with radius props) + // qmllint disable missing-property + radius: root.parent?.radius ?? 0 + topLeftRadius: root.parent?.topLeftRadius ?? radius ?? 0 + topRightRadius: root.parent?.topRightRadius ?? radius ?? 0 + // qmllint enable missing-property + } - CustomRect { - id: ripple + Shape { + id: circle - border.pixelAligned: false - color: root.color - opacity: 0 - radius: Appearance.rounding.full + anchors.fill: parent + opacity: 0 + preferredRendererType: Shape.CurveRenderer - transform: Translate { - x: -ripple.width / 2 - y: -ripple.height / 2 + ShapePath { + fillColor: base.color + startX: root.clamp(base.topLeftRadius) + startY: 0 + strokeColor: "transparent" + strokeWidth: 0 + + fillGradient: RadialGradient { + centerRadius: root.circleRadius + centerX: root.pressX + centerY: root.pressY + focalX: centerX + focalY: centerY + + GradientStop { + color: Qt.alpha(base.color, 1) + position: 0 + } + + GradientStop { + color: Qt.alpha(base.color, 1) + position: ZUtils.clamp(1 - 0.2 * root.endRadius / root.circleRadius, 0.01, 0.99) + } + + GradientStop { + color: Qt.alpha(base.color, ZUtils.clamp((root.circleRadius / root.endRadius - 0.9) / 0.1, 0, 1)) + position: 1 + } + } + + PathLine { + x: root.width - root.clamp(base.topRightRadius) + y: 0 + } + + PathArc { + radiusX: root.clamp(base.topRightRadius) + radiusY: root.clamp(base.topRightRadius) + relativeX: root.clamp(base.topRightRadius) + relativeY: root.clamp(base.topRightRadius) + } + + PathLine { + x: root.width + y: root.height - root.clamp(base.bottomRightRadius) + } + + PathArc { + radiusX: root.clamp(base.bottomRightRadius) + radiusY: root.clamp(base.bottomRightRadius) + relativeX: -root.clamp(base.bottomRightRadius) + relativeY: root.clamp(base.bottomRightRadius) + } + + PathLine { + x: root.clamp(base.bottomLeftRadius) + y: root.height + } + + PathArc { + radiusX: root.clamp(base.bottomLeftRadius) + radiusY: root.clamp(base.bottomLeftRadius) + relativeX: -root.clamp(base.bottomLeftRadius) + relativeY: -root.clamp(base.bottomLeftRadius) + } + + PathLine { + x: 0 + y: root.clamp(base.topLeftRadius) + } + + PathArc { + radiusX: root.clamp(base.topLeftRadius) + radiusY: root.clamp(base.topLeftRadius) + x: root.clamp(base.topLeftRadius) + y: 0 } } } diff --git a/Greeter/Config/Appearance.qml b/Greeter/Config/Appearance.qml index d2bf19e..7be277e 100644 --- a/Greeter/Config/Appearance.qml +++ b/Greeter/Config/Appearance.qml @@ -4,10 +4,9 @@ import Quickshell Singleton { readonly property AppearanceConf.Anim anim: Config.appearance.anim + readonly property AppearanceConf.Deform deform: Config.appearance.deform readonly property AppearanceConf.FontStuff font: Config.appearance.font readonly property AppearanceConf.Padding padding: Config.appearance.padding - // Literally just here to shorten accessing stuff :woe: - // Also kinda so I can keep accessing it with `Appearance.xxx` instead of `Conf.appearance.xxx` readonly property AppearanceConf.Rounding rounding: Config.appearance.rounding readonly property AppearanceConf.Spacing spacing: Config.appearance.spacing readonly property AppearanceConf.Transparency transparency: Config.appearance.transparency diff --git a/Greeter/Config/AppearanceConf.qml b/Greeter/Config/AppearanceConf.qml index 60c648c..859e0a3 100644 --- a/Greeter/Config/AppearanceConf.qml +++ b/Greeter/Config/AppearanceConf.qml @@ -3,6 +3,8 @@ import Quickshell.Io JsonObject { property Anim anim: Anim { } + property Deform deform: Deform { + } property FontStuff font: FontStuff { } property Padding padding: Padding { @@ -26,9 +28,13 @@ JsonObject { property list emphasized: [0.05, 0, 2 / 15, 0.06, 1 / 6, 0.4, 5 / 24, 0.82, 0.25, 1, 1, 1] property list emphasizedAccel: [0.3, 0, 0.8, 0.15, 1, 1] property list emphasizedDecel: [0.05, 0.7, 0.1, 1, 1, 1] + property list expressiveDefaultEffects: [0.34, 0.8, 0.34, 1, 1, 1] property list expressiveDefaultSpatial: [0.38, 1.21, 0.22, 1, 1, 1] property list expressiveEffects: [0.34, 0.8, 0.34, 1, 1, 1] + property list expressiveFastEffects: [0.31, 0.94, 0.34, 1, 1, 1] property list expressiveFastSpatial: [0.42, 1.67, 0.21, 0.9, 1, 1] + property list expressiveSlowEffects: [0.34, 0.88, 0.34, 1, 1, 1] + property list expressiveSlowSpatial: [0.39, 1.29, 0.35, 0.98, 1, 1] property list standard: [0.2, 0, 0, 1, 1, 1] property list standardAccel: [0.3, 0, 1, 1, 1, 1] property list standardDecel: [0, 0, 0, 1, 1, 1] @@ -36,13 +42,18 @@ JsonObject { component AnimDurations: JsonObject { property int expressiveDefaultSpatial: 500 * scale property int expressiveEffects: 200 * scale + property int expressiveFastEffects: 150 * scale property int expressiveFastSpatial: 350 * scale + property int expressiveSlowEffects: 300 * scale property int extraLarge: 1000 * scale property int large: 600 * scale property int normal: 400 * scale property real scale: 1 property int small: 200 * scale } + component Deform: JsonObject { + property real scale: 1 + } component FontFamily: JsonObject { property string clock: "Rubik" property string material: "Material Symbols Rounded" @@ -52,7 +63,8 @@ JsonObject { component FontSize: JsonObject { property int extraLarge: 28 * scale property int large: 18 * scale - property int larger: 15 * 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 @@ -65,28 +77,33 @@ JsonObject { } } component Padding: JsonObject { - property int large: 15 * scale + property int extraLargeIncreased: 32 * scale + property int extraSmall: 4 * scale + property int large: 16 * scale property int larger: 12 * scale - property int normal: 10 * scale + property int normal: 8 * scale property real scale: 1 property int small: 5 * scale property int smaller: 7 * scale property int smallest: 2 * scale } component Rounding: JsonObject { + property int extraSmall: 4 * scale property int full: 1000 * scale - property int large: 25 * scale - property int normal: 17 * scale + property int large: 24 * scale + property int medium: 16 * scale + property int normal: 18 * scale property real scale: 1 property int small: 12 * scale property int smallest: 8 * scale } component Spacing: JsonObject { + property int extraSmall: 4 * scale property int large: 20 * scale - property int larger: 15 * scale + property int larger: 16 * scale property int normal: 12 * scale property real scale: 1 - property int small: 7 * scale + property int small: 8 * scale property int smaller: 10 * scale } component Transparency: JsonObject { diff --git a/Greeter/Config/BackgroundConfig.qml b/Greeter/Config/BackgroundConfig.qml index bcae021..10e7691 100644 --- a/Greeter/Config/BackgroundConfig.qml +++ b/Greeter/Config/BackgroundConfig.qml @@ -4,4 +4,11 @@ import qs.Config JsonObject { property bool enabled: true property int wallFadeDuration: MaterialEasing.standardTime + property real alignX: 0.5 + property real alignY: 0.5 + property real zoom: 1.0 + property real sourceClipX: 0 + property real sourceClipY: 0 + property real sourceClipW: 0 + property real sourceClipH: 0 } diff --git a/Greeter/Config/BarConfig.qml b/Greeter/Config/BarConfig.qml index 7b39915..0f489ef 100644 --- a/Greeter/Config/BarConfig.qml +++ b/Greeter/Config/BarConfig.qml @@ -8,10 +8,6 @@ JsonObject { id: "workspaces", enabled: true }, - { - id: "audio", - enabled: true - }, { id: "media", enabled: true @@ -24,10 +20,6 @@ JsonObject { id: "updates", enabled: true }, - { - id: "dash", - enabled: true - }, { id: "spacer", enabled: true @@ -41,12 +33,12 @@ JsonObject { enabled: true }, { - id: "tray", + id: "hyprsunset", enabled: true }, { - id: "upower", - enabled: false + id: "tray", + enabled: true }, { id: "network", @@ -62,9 +54,13 @@ JsonObject { }, ] property int height: 34 + property bool hideWhenNotif: false property Popouts popouts: Popouts { } property int rounding: 8 + property int smoothing: 32 + property Tray tray: Tray { + } component Popouts: JsonObject { property bool activeWindow: true @@ -75,4 +71,7 @@ JsonObject { property bool tray: true property bool upower: true } + component Tray: JsonObject { + property int trayIconSize: 24 + } } diff --git a/Greeter/Config/Colors.qml b/Greeter/Config/Colors.qml index 287ea02..3b99070 100644 --- a/Greeter/Config/Colors.qml +++ b/Greeter/Config/Colors.qml @@ -1,5 +1,13 @@ import Quickshell.Io JsonObject { + property Presets presets: Presets { + } property string schemeType: "vibrant" + + component Presets: JsonObject { + property string accent: "" + property string name: "" + property string variant: "" + } } diff --git a/Greeter/Config/Config.qml b/Greeter/Config/Config.qml index fad254a..decd07c 100644 --- a/Greeter/Config/Config.qml +++ b/Greeter/Config/Config.qml @@ -4,8 +4,6 @@ import Quickshell import Quickshell.Io import ZShell import QtQuick -import qs.Helpers -import qs.Paths Singleton { id: root @@ -23,6 +21,7 @@ Singleton { 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 @@ -48,6 +47,9 @@ Singleton { padding: { scale: appearance.padding.scale }, + deform: { + scale: appearance.deform.scale + }, font: { family: { sans: appearance.font.family.sans, @@ -77,16 +79,28 @@ Singleton { function serializeBackground(): var { return { wallFadeDuration: background.wallFadeDuration, - enabled: background.enabled + enabled: background.enabled, + alignX: background.alignX, + sourceClipX: background.sourceClipX, + sourceClipY: background.sourceClipY, + sourceClipW: background.sourceClipW, + sourceClipH: background.sourceClipH, + alignY: background.alignY, + zoom: background.zoom }; } function serializeBar(): var { return { autoHide: barConfig.autoHide, + hideWhenNotif: barConfig.hideWhenNotif, rounding: barConfig.rounding, border: barConfig.border, + smoothing: barConfig.smoothing, height: barConfig.height, + tray: { + trayIconSize: barConfig.tray.trayIconSize + }, popouts: { tray: barConfig.popouts.tray, audio: barConfig.popouts.audio, @@ -102,7 +116,12 @@ Singleton { function serializeColors(): var { return { - schemeType: colors.schemeType + schemeType: colors.schemeType, + presets: { + name: colors.presets.name, + variant: colors.presets.variant, + accent: colors.presets.accent + } }; } @@ -121,7 +140,8 @@ Singleton { background: serializeBackground(), launcher: serializeLauncher(), colors: serializeColors(), - dock: serializeDock() + dock: serializeDock(), + screenshot: serializeScreenshot() }; } @@ -172,11 +192,16 @@ Singleton { return { logo: general.logo, wallpaperPath: general.wallpaperPath, - username: general.username, desktopIcons: general.desktopIcons, + dateFormat: general.dateFormat, color: { mode: general.color.mode, smart: general.color.smart, + scheduleDark: general.color.scheduleDark, + scheduleHyprsunset: general.color.scheduleHyprsunset, + scheduleHyprsunsetStart: general.color.scheduleHyprsunsetStart, + hyprsunsetTemp: general.color.hyprsunsetTemp, + scheduleHyprsunsetEnd: general.color.scheduleHyprsunsetEnd, schemeGeneration: general.color.schemeGeneration, scheduleDarkStart: general.color.scheduleDarkStart, scheduleDarkEnd: general.color.scheduleDarkEnd, @@ -190,6 +215,10 @@ Singleton { }, idle: { timeouts: general.idle.timeouts + }, + battery: { + popupThresholds: general.battery.popupThresholds, + critPerc: general.battery.critPerc } }; } @@ -198,6 +227,7 @@ Singleton { return { maxAppsShown: launcher.maxAppsShown, maxWallpapers: launcher.maxWallpapers, + uwsm: launcher.uwsm, actionPrefix: launcher.actionPrefix, specialPrefix: launcher.specialPrefix, useFuzzy: { @@ -221,6 +251,8 @@ Singleton { return { recolorLogo: lock.recolorLogo, enableFprint: lock.enableFprint, + showNotifContent: lock.showNotifContent, + showNotifIcon: lock.showNotifIcon, maxFprintTries: lock.maxFprintTries, blurAmount: lock.blurAmount, sizes: { @@ -262,9 +294,24 @@ Singleton { }; } + function serializeScreenshot(): var { + return { + enable_pp: screenshot.enable_pp, + mode: screenshot.mode, + radius: screenshot.radius, + shadow: screenshot.shadow, + rounding: screenshot.rounding, + shadow_blur: screenshot.shadow_blur, + shadow_color: screenshot.shadow_color, + shadow_offset_x: screenshot.shadow_offset_x, + shadow_offset_y: screenshot.shadow_offset_y + }; + } + function serializeServices(): var { return { weatherLocation: services.weatherLocation, + updates: services.updates, useFahrenheit: services.useFahrenheit, ddcutilService: services.ddcutilService, useTwelveHourClock: services.useTwelveHourClock, @@ -317,7 +364,6 @@ Singleton { ElapsedTimer { id: timer - } Timer { @@ -415,6 +461,8 @@ Singleton { } property Overview overview: Overview { } + property Screenshot screenshot: Screenshot { + } property Services services: Services { } property SidebarConfig sidebar: SidebarConfig { diff --git a/Greeter/Config/DynamicColors.qml b/Greeter/Config/DynamicColors.qml index fc7cd10..2b2be28 100644 --- a/Greeter/Config/DynamicColors.qml +++ b/Greeter/Config/DynamicColors.qml @@ -29,9 +29,10 @@ Singleton { readonly property alias wallLuminance: analyser.luminance function alterColor(c: color, a: real, layer: int): color { - const luminance = getLuminance(c); + const initLuminance = getLuminance(c); + const luminance = Math.max(initLuminance, 0.001); - const offset = (!light || layer == 1 ? 1 : -layer / 2) * (light ? 0.2 : 0.3) * (1 - transparency.base) * (1 + wallLuminance * (light ? (layer == 1 ? 3 : 1) : 2.5)); + const offset = (!light || layer == 1 ? 1 : -layer / 2) * (light ? 0.2 : 0.3) * (0.2 + 0.3 * (1 - transparency.base)) * (1 + wallLuminance * (light ? (layer == 1 ? 3 : 1) : 2.5)); const scale = (luminance + offset) / luminance; const r = Math.max(0, Math.min(1, c.r * scale)); const g = Math.max(0, Math.min(1, c.g * scale)); @@ -84,6 +85,10 @@ Singleton { Config.save(); } + function swapRG(c: color): color { + return Qt.rgba(c.g, c.r, c.b, c.a); + } + FileView { path: "/etc/zshell-greeter/scheme.json" watchChanges: true @@ -95,69 +100,9 @@ Singleton { ImageAnalyser { id: analyser - source: WallpaperPath.currentWallpaperPath + source: WallpaperPath.lockscreenBg } - component M3MaccchiatoPalette: QtObject { - property color m3background: "#131317" - property color m3error: "#ffb4ab" - property color m3errorContainer: "#93000a" - property color m3inverseOnSurface: "#303034" - property color m3inversePrimary: "#525b92" - property color m3inverseSurface: "#e4e1e7" - property color m3neutral_paletteKeyColor: "#77767b" - property color m3neutral_variant_paletteKeyColor: "#767680" - property color m3onBackground: "#e4e1e7" - property color m3onError: "#690005" - property color m3onErrorContainer: "#ffdad6" - property color m3onPrimary: "#232c60" - property color m3onPrimaryContainer: "#ffffff" - property color m3onPrimaryFixed: "#0b154b" - property color m3onPrimaryFixedVariant: "#3a4378" - property color m3onSecondary: "#2c2f44" - property color m3onSecondaryContainer: "#b1b3ce" - property color m3onSecondaryFixed: "#171a2e" - property color m3onSecondaryFixedVariant: "#42455c" - property color m3onSuccess: "#213528" - property color m3onSuccessContainer: "#D1E9D6" - property color m3onSurface: "#e4e1e7" - property color m3onSurfaceVariant: "#c6c5d1" - property color m3onTertiary: "#4c1f48" - property color m3onTertiaryContainer: "#000000" - property color m3onTertiaryFixed: "#340831" - property color m3onTertiaryFixedVariant: "#66365f" - property color m3outline: "#90909a" - property color m3outlineVariant: "#46464f" - property color m3primary: "#bac3ff" - property color m3primaryContainer: "#6a73ac" - property color m3primaryFixed: "#dee0ff" - property color m3primaryFixedDim: "#bac3ff" - property color m3primary_paletteKeyColor: "#6a73ac" - property color m3scrim: "#000000" - property color m3secondary: "#c3c5e0" - property color m3secondaryContainer: "#42455c" - property color m3secondaryFixed: "#dfe1fd" - property color m3secondaryFixedDim: "#c3c5e0" - property color m3secondary_paletteKeyColor: "#72758e" - property color m3shadow: "#000000" - property color m3success: "#B5CCBA" - property color m3successContainer: "#374B3E" - property color m3surface: "#131317" - property color m3surfaceBright: "#39393d" - property color m3surfaceContainer: "#1f1f23" - property color m3surfaceContainerHigh: "#2a2a2e" - property color m3surfaceContainerHighest: "#353438" - property color m3surfaceContainerLow: "#1b1b1f" - property color m3surfaceContainerLowest: "#0e0e12" - property color m3surfaceDim: "#131317" - property color m3surfaceTint: "#bac3ff" - property color m3surfaceVariant: "#46464f" - property color m3tertiary: "#f1b3e5" - property color m3tertiaryContainer: "#b77ead" - property color m3tertiaryFixed: "#ffd7f4" - property color m3tertiaryFixedDim: "#f1b3e5" - property color m3tertiary_paletteKeyColor: "#9b6592" - } component M3Palette: QtObject { property color m3background: "#191114" property color m3error: "#ffb4ab" @@ -279,8 +224,11 @@ Singleton { readonly property color m3tertiary_paletteKeyColor: root.layer(root.palette.m3tertiary_paletteKeyColor) } component Transparency: QtObject { - readonly property real base: Appearance.transparency.base - (root.light ? 0.1 : 0) + readonly property real base: Math.max(0, Math.min(1, Appearance.transparency.base - (root.light ? 0.1 : 0))) readonly property bool enabled: Appearance.transparency.enabled readonly property real layers: Appearance.transparency.layers + + onBaseChanged: debounceTimer.restart() + onEnabledChanged: debounceTimer.restart() } } diff --git a/Greeter/Config/General.qml b/Greeter/Config/General.qml index 453c2f3..45d3513 100644 --- a/Greeter/Config/General.qml +++ b/Greeter/Config/General.qml @@ -4,13 +4,15 @@ import Quickshell JsonObject { property Apps apps: Apps { } + property Battery battery: Battery { + } property Color color: Color { } + property string dateFormat: "ddd d MMM - hh:mm:ss" property bool desktopIcons: false property Idle idle: Idle { } property string logo: "" - property string username: "" property string wallpaperPath: Quickshell.env("HOME") + "/Pictures/Wallpapers" component Apps: JsonObject { @@ -19,11 +21,27 @@ JsonObject { property list playback: ["mpv"] property list terminal: ["kitty"] } + component Battery: JsonObject { + property int critPerc: 5 + property list popupThresholds: [ + { + perc: 20, + name: qsTr("Low battery"), + message: qsTr("Battery is low"), + icon: "battery_android_frame_2" + }, + ] + } component Color: JsonObject { + property int hyprsunsetTemp: 5000 property string mode: "dark" property bool neovimColors: false + property bool scheduleDark: false property int scheduleDarkEnd: 0 property int scheduleDarkStart: 0 + property bool scheduleHyprsunset: false + property int scheduleHyprsunsetEnd: 0 + property int scheduleHyprsunsetStart: 0 property bool schemeGeneration: true property bool smart: false } diff --git a/Greeter/Config/Launcher.qml b/Greeter/Config/Launcher.qml index a195868..5ab58cc 100644 --- a/Greeter/Config/Launcher.qml +++ b/Greeter/Config/Launcher.qml @@ -91,6 +91,7 @@ JsonObject { property string specialPrefix: "@" property UseFuzzy useFuzzy: UseFuzzy { } + property bool uwsm: true component Sizes: JsonObject { property int itemHeight: 50 diff --git a/Greeter/Config/LockConf.qml b/Greeter/Config/LockConf.qml index e377459..87a4f4e 100644 --- a/Greeter/Config/LockConf.qml +++ b/Greeter/Config/LockConf.qml @@ -5,6 +5,8 @@ JsonObject { property bool enableFprint: true property int maxFprintTries: 3 property bool recolorLogo: false + property bool showNotifContent: false + property bool showNotifIcon: true property Sizes sizes: Sizes { } diff --git a/Greeter/Config/Screenshot.qml b/Greeter/Config/Screenshot.qml new file mode 100644 index 0000000..cd6dd49 --- /dev/null +++ b/Greeter/Config/Screenshot.qml @@ -0,0 +1,13 @@ +import Quickshell.Io + +JsonObject { + property bool enable_pp: true + property string mode: "manual" + property real radius: 12.0 + property bool rounding: false + property bool shadow: true + property real shadow_blur: 22.0 + property list shadow_color: [0, 0, 0, 160] + property real shadow_offset_x: 5.0 + property real shadow_offset_y: 5.0 +} diff --git a/Greeter/Config/Services.qml b/Greeter/Config/Services.qml index e091fa2..4711120 100644 --- a/Greeter/Config/Services.qml +++ b/Greeter/Config/Services.qml @@ -14,6 +14,7 @@ JsonObject { "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 diff --git a/Greeter/SessionDock.qml b/Greeter/SessionDock.qml index 54eaff4..b4914ec 100644 --- a/Greeter/SessionDock.qml +++ b/Greeter/SessionDock.qml @@ -83,7 +83,7 @@ ColumnLayout { radius: Appearance.rounding.normal - Appearance.padding.smaller StateLayer { - function onClicked(): void { + onClicked: { root.greeter.sessionIndex = index; } } diff --git a/Greeter/UserDock.qml b/Greeter/UserDock.qml index c9f067a..dd4d4c7 100644 --- a/Greeter/UserDock.qml +++ b/Greeter/UserDock.qml @@ -84,7 +84,7 @@ ColumnLayout { radius: Appearance.rounding.normal - Appearance.padding.smaller StateLayer { - function onClicked(): void { + onClicked: { root.greeter.selectUser(modelData.username); } } diff --git a/Modules/Dashboard/Dash/Calendar.qml b/Modules/Dashboard/Dash/Calendar.qml index dcb9c3c..3175645 100644 --- a/Modules/Dashboard/Dash/Calendar.qml +++ b/Modules/Dashboard/Dash/Calendar.qml @@ -49,11 +49,11 @@ CustomMouseArea { StateLayer { id: prevMonthStateLayer - function onClicked(): void { + radius: Appearance.rounding.full + + onClicked: { root.state.currentDate = new Date(root.currYear, root.currMonth - 1, 1); } - - radius: Appearance.rounding.full } MaterialIcon { @@ -73,10 +73,6 @@ CustomMouseArea { implicitWidth: monthYearDisplay.implicitWidth + Appearance.padding.small * 2 StateLayer { - function onClicked(): void { - root.state.currentDate = new Date(); - } - anchors.fill: monthYearDisplay anchors.leftMargin: -Appearance.padding.normal anchors.margins: -Appearance.padding.small @@ -86,6 +82,10 @@ CustomMouseArea { return root.currMonth === now.getMonth() && root.currYear === now.getFullYear(); } radius: Appearance.rounding.full + + onClicked: { + root.state.currentDate = new Date(); + } } CustomText { @@ -107,11 +107,11 @@ CustomMouseArea { StateLayer { id: nextMonthStateLayer - function onClicked(): void { + radius: Appearance.rounding.full + + onClicked: { root.state.currentDate = new Date(root.currYear, root.currMonth + 1, 1); } - - radius: Appearance.rounding.full } MaterialIcon { diff --git a/Modules/Dashboard/Dash/Media.qml b/Modules/Dashboard/Dash/Media.qml index 4b47b81..8512134 100644 --- a/Modules/Dashboard/Dash/Media.qml +++ b/Modules/Dashboard/Dash/Media.qml @@ -295,12 +295,12 @@ Item { StateLayer { id: controlState - function onClicked(): void { - control.onClicked(); - } - color: control.canUse ? DynamicColors.palette[`m3on${control.set_color}`] : DynamicColors.palette[`m3on${control.set_color}Container`] disabled: !control.canUse + + onClicked: { + control.onClicked(); + } // radius: Appearance.rounding.full } diff --git a/Modules/Launcher/Items/ActionItem.qml b/Modules/Launcher/Items/ActionItem.qml index 068265d..f2da657 100644 --- a/Modules/Launcher/Items/ActionItem.qml +++ b/Modules/Launcher/Items/ActionItem.qml @@ -15,11 +15,11 @@ Item { implicitHeight: Config.launcher.sizes.itemHeight StateLayer { - function onClicked(): void { + radius: Appearance.rounding.smallest + + onClicked: { root.modelData?.onClicked(root.list); } - - radius: Appearance.rounding.smallest } Item { diff --git a/Modules/Launcher/Items/AppItem.qml b/Modules/Launcher/Items/AppItem.qml index b9be7b5..b553649 100644 --- a/Modules/Launcher/Items/AppItem.qml +++ b/Modules/Launcher/Items/AppItem.qml @@ -18,12 +18,12 @@ Item { implicitHeight: Config.launcher.sizes.itemHeight StateLayer { - function onClicked(): void { + radius: Appearance.rounding.smallest + + onClicked: { Apps.launch(root.modelData); root.visibilities.launcher = false; } - - radius: Appearance.rounding.smallest } Item { diff --git a/Modules/Launcher/Items/CalcItem.qml b/Modules/Launcher/Items/CalcItem.qml index 32008f2..1b1f077 100644 --- a/Modules/Launcher/Items/CalcItem.qml +++ b/Modules/Launcher/Items/CalcItem.qml @@ -23,11 +23,11 @@ Item { implicitHeight: Config.launcher.sizes.itemHeight StateLayer { - function onClicked(): void { + radius: Appearance.rounding.smallest + + onClicked: { root.onClicked(); } - - radius: Appearance.rounding.smallest } RowLayout { @@ -76,12 +76,12 @@ Item { StateLayer { id: stateLayer - function onClicked(): void { + color: DynamicColors.palette.m3onTertiary + + onClicked: { Quickshell.execDetached(["app2unit", "--", ...Config.general.apps.terminal, "fish", "-C", `exec qalc -i '${root.math}'`]); root.list.visibilities.launcher = false; } - - color: DynamicColors.palette.m3onTertiary } CustomText { diff --git a/Modules/Launcher/Items/VariantItem.qml b/Modules/Launcher/Items/VariantItem.qml index 42f47a0..0351199 100644 --- a/Modules/Launcher/Items/VariantItem.qml +++ b/Modules/Launcher/Items/VariantItem.qml @@ -14,11 +14,11 @@ Item { implicitHeight: Config.launcher.sizes.itemHeight StateLayer { - function onClicked(): void { + radius: Appearance.rounding.smallest + + onClicked: { root.modelData?.onClicked(root.list); } - - radius: Appearance.rounding.smallest } Item { diff --git a/Modules/Launcher/Items/WallpaperItem.qml b/Modules/Launcher/Items/WallpaperItem.qml index 65d9418..024633c 100644 --- a/Modules/Launcher/Items/WallpaperItem.qml +++ b/Modules/Launcher/Items/WallpaperItem.qml @@ -33,12 +33,12 @@ Item { } StateLayer { - function onClicked(): void { + radius: Appearance.rounding.normal + + onClicked: { Wallpapers.setWallpaper(root.modelData.path); root.visibilities.launcher = false; } - - radius: Appearance.rounding.normal } Elevation { diff --git a/Modules/Lock/Center.qml b/Modules/Lock/Center.qml index a336503..4507bae 100644 --- a/Modules/Lock/Center.qml +++ b/Modules/Lock/Center.qml @@ -108,12 +108,12 @@ ColumnLayout { } StateLayer { - function onClicked(): void { - parent.forceActiveFocus(); - } - cursorShape: Qt.IBeamCursor hoverEnabled: false + + onClicked: { + parent.forceActiveFocus(); + } } RowLayout { @@ -167,11 +167,11 @@ ColumnLayout { radius: Appearance.rounding.full StateLayer { - function onClicked(): void { + color: root.lock.pam.buffer ? DynamicColors.palette.m3onPrimary : DynamicColors.palette.m3onSurface + + onClicked: { root.lock.pam.passwd.start(); } - - color: root.lock.pam.buffer ? DynamicColors.palette.m3onPrimary : DynamicColors.palette.m3onSurface } MaterialIcon { diff --git a/Modules/Lock/Media.qml b/Modules/Lock/Media.qml index f47ecf7..4349bf8 100644 --- a/Modules/Lock/Media.qml +++ b/Modules/Lock/Media.qml @@ -178,11 +178,11 @@ Item { StateLayer { id: controlState - function onClicked(): void { + color: control.active ? DynamicColors.palette[`m3on${control.set_color}`] : DynamicColors.palette[`m3on${control.set_color}Container`] + + onClicked: { control.onClicked(); } - - color: control.active ? DynamicColors.palette[`m3on${control.set_color}`] : DynamicColors.palette[`m3on${control.set_color}Container`] } MaterialIcon { diff --git a/Modules/Lock/NotifGroup.qml b/Modules/Lock/NotifGroup.qml index 4c0302c..e79628b 100644 --- a/Modules/Lock/NotifGroup.qml +++ b/Modules/Lock/NotifGroup.qml @@ -161,11 +161,11 @@ CustomRect { } StateLayer { - function onClicked(): void { + color: root.urgency === "critical" ? DynamicColors.palette.m3onError : DynamicColors.palette.m3onSurface + + onClicked: { root.expanded = !root.expanded; } - - color: root.urgency === "critical" ? DynamicColors.palette.m3onError : DynamicColors.palette.m3onSurface } RowLayout { diff --git a/Modules/NotifBell.qml b/Modules/NotifBell.qml index e59f4f0..eb86926 100644 --- a/Modules/NotifBell.qml +++ b/Modules/NotifBell.qml @@ -32,8 +32,6 @@ CustomRect { } StateLayer { - cursorShape: Qt.PointingHandCursor - onClicked: { root.visibilities.sidebar = !root.visibilities.sidebar; } diff --git a/Modules/Notifications/Notification.qml b/Modules/Notifications/Notification.qml index f50561a..178b086 100644 --- a/Modules/Notifications/Notification.qml +++ b/Modules/Notifications/Notification.qml @@ -307,12 +307,12 @@ CustomRect { implicitWidth: expandIcon.height StateLayer { - function onClicked() { - root.expanded = !root.expanded; - } - color: root.modelData.urgency === NotificationUrgency.Critical ? DynamicColors.palette.m3onSecondaryContainer : DynamicColors.palette.m3onSurface radius: Appearance.rounding.full + + onClicked: { + root.expanded = !root.expanded; + } } MaterialIcon { @@ -434,12 +434,12 @@ CustomRect { radius: Appearance.rounding.full StateLayer { - function onClicked(): void { - action.modelData.invoke(); - } - color: root.modelData.urgency === NotificationUrgency.Critical ? DynamicColors.palette.m3onSecondary : DynamicColors.palette.m3onSurface radius: Appearance.rounding.full + + onClicked: { + action.modelData.invoke(); + } } CustomText { diff --git a/Modules/Notifications/Sidebar/NotifActionList.qml b/Modules/Notifications/Sidebar/NotifActionList.qml index 02ba10e..4d58aea 100644 --- a/Modules/Notifications/Sidebar/NotifActionList.qml +++ b/Modules/Notifications/Sidebar/NotifActionList.qml @@ -78,7 +78,7 @@ Item { StateLayer { id: actionStateLayer - function onClicked(): void { + onClicked: { if (action.modelData.isClose) { root.notif.close(); } else if (action.modelData.isCopy) { diff --git a/Modules/Notifications/Sidebar/NotifGroup.qml b/Modules/Notifications/Sidebar/NotifGroup.qml index 753944d..c816a62 100644 --- a/Modules/Notifications/Sidebar/NotifGroup.qml +++ b/Modules/Notifications/Sidebar/NotifGroup.qml @@ -171,11 +171,11 @@ CustomRect { radius: Appearance.rounding.full StateLayer { - function onClicked(): void { + color: root.urgency === NotificationUrgency.Critical ? DynamicColors.palette.m3onError : DynamicColors.palette.m3onSurface + + onClicked: { root.toggleExpand(!root.expanded); } - - color: root.urgency === NotificationUrgency.Critical ? DynamicColors.palette.m3onError : DynamicColors.palette.m3onSurface } RowLayout { diff --git a/Modules/Settings/Controls/SpinnerButton.qml b/Modules/Settings/Controls/SpinnerButton.qml index af95494..7aedaa1 100644 --- a/Modules/Settings/Controls/SpinnerButton.qml +++ b/Modules/Settings/Controls/SpinnerButton.qml @@ -44,11 +44,11 @@ CustomRect { } StateLayer { - function onClicked(): void { + visible: root.enabled + + onClicked: { SettingsDropdowns.toggle(menu, root); } - - visible: root.enabled } PathViewMenu { diff --git a/Modules/Settings/Controls/WallpaperGrid.qml b/Modules/Settings/Controls/WallpaperGrid.qml index c66ef00..9c91fad 100644 --- a/Modules/Settings/Controls/WallpaperGrid.qml +++ b/Modules/Settings/Controls/WallpaperGrid.qml @@ -131,16 +131,16 @@ GridView { } StateLayer { - function onClicked(): void { - Wallpapers.setWallpaper(modelData.path); - } - anchors.bottomMargin: itemMargin anchors.fill: parent anchors.leftMargin: itemMargin anchors.rightMargin: itemMargin anchors.topMargin: itemMargin radius: itemRadius + + onClicked: { + Wallpapers.setWallpaper(modelData.path); + } } } Behavior on opacity { diff --git a/Modules/SysTray/Popouts/TrayMenuPopout.qml b/Modules/SysTray/Popouts/TrayMenuPopout.qml index 908b2f6..7c48320 100644 --- a/Modules/SysTray/Popouts/TrayMenuPopout.qml +++ b/Modules/SysTray/Popouts/TrayMenuPopout.qml @@ -103,7 +103,10 @@ StackView { implicitHeight: 30 StateLayer { - function onClicked(): void { + disabled: !item.modelData.enabled + radius: item.radius + + onClicked: { const entry = item.modelData; if (entry.hasChildren) { root.rootWidth = root.biggestWidth; @@ -117,9 +120,6 @@ StackView { root.popouts.hasCurrent = false; } } - - disabled: !item.modelData.enabled - radius: item.radius } Loader { @@ -217,13 +217,13 @@ StackView { radius: Appearance.rounding.full StateLayer { - function onClicked(): void { + color: DynamicColors.palette.m3onSecondaryContainer + radius: parent.radius + + onClicked: { root.pop(); root.biggestWidth = root.rootWidth; } - - color: DynamicColors.palette.m3onSecondaryContainer - radius: parent.radius } } diff --git a/Modules/SysTray/Popouts/UPowerPopout.qml b/Modules/SysTray/Popouts/UPowerPopout.qml index 775e47f..116778a 100644 --- a/Modules/SysTray/Popouts/UPowerPopout.qml +++ b/Modules/SysTray/Popouts/UPowerPopout.qml @@ -153,12 +153,12 @@ Item { implicitWidth: icon.implicitHeight + 5 * 2 StateLayer { - function onClicked(): void { - PowerProfiles.profile = parent.profile; - } - color: profiles.current === parent.icon ? DynamicColors.palette.m3onPrimary : DynamicColors.palette.m3onSurface radius: Appearance.rounding.full + + onClicked: { + PowerProfiles.profile = parent.profile; + } } MaterialIcon {