diff --git a/.config/quickshell/modules/common/widgets/RippleButton.qml b/.config/quickshell/modules/common/widgets/RippleButton.qml index 98b6aad8..4d38236e 100644 --- a/.config/quickshell/modules/common/widgets/RippleButton.qml +++ b/.config/quickshell/modules/common/widgets/RippleButton.qml @@ -8,6 +8,9 @@ import QtQuick.Layouts import Quickshell.Io import Quickshell.Widgets +/** + * A button with ripple effect similar to in Material Design. + */ Button { id: root property bool toggled @@ -19,12 +22,12 @@ Button { property bool rippleEnabled: true property var altAction - property color colBackground: ColorUtils.transparentize(Appearance.colors.colLayer1Hover, 1) - property color colBackgroundHover: Appearance.colors.colLayer1Hover - property color colBackgroundToggled: Appearance.m3colors.m3primary - property color colBackgroundToggledHover: Appearance.colors.colPrimaryHover - property color colRipple: Appearance.colors.colLayer1Active - property color colRippleToggled: Appearance.colors.colPrimaryActive + property color colBackground: ColorUtils.transparentize(Appearance?.colors.colLayer1Hover, 1) || "#00000000" + property color colBackgroundHover: Appearance?.colors.colLayer1Hover ?? "#E5DFED" + property color colBackgroundToggled: Appearance?.m3colors.m3primary ?? "#65558F" + property color colBackgroundToggledHover: Appearance?.colors.colPrimaryHover ?? "#77699C" + property color colRipple: Appearance?.colors.colLayer1Active ?? "#D6CEE2" + property color colRippleToggled: Appearance?.colors.colPrimaryActive ?? "#D6CEE2" property color buttonColor: root.enabled ? (root.toggled ? (root.hovered ? colBackgroundToggledHover : @@ -48,8 +51,8 @@ Button { component RippleAnim: NumberAnimation { duration: rippleDuration - easing.type: Appearance.animation.elementMoveEnter.type - easing.bezierCurve: Appearance.animationCurves.standardDecel + easing.type: Appearance?.animation.elementMoveEnter.type + easing.bezierCurve: Appearance?.animationCurves.standardDecel } MouseArea { @@ -125,7 +128,7 @@ Button { color: root.buttonColor Behavior on color { - animation: Appearance.animation.elementMoveFast.colorAnimation.createObject(this) + animation: Appearance?.animation.elementMoveFast.colorAnimation.createObject(this) } layer.enabled: true @@ -140,11 +143,11 @@ Button { Rectangle { id: ripple - radius: Appearance.rounding.full + radius: Appearance?.rounding.full ?? 9999 opacity: 0 color: root.rippleColor Behavior on color { - animation: Appearance.animation.elementMoveFast.colorAnimation.createObject(this) + animation: Appearance?.animation.elementMoveFast.colorAnimation.createObject(this) } transform: Translate { diff --git a/.config/quickshell/modules/common/widgets/RoundCorner.qml b/.config/quickshell/modules/common/widgets/RoundCorner.qml index 59e9a0c0..c9a2827a 100644 --- a/.config/quickshell/modules/common/widgets/RoundCorner.qml +++ b/.config/quickshell/modules/common/widgets/RoundCorner.qml @@ -58,11 +58,7 @@ Item { } Behavior on size { - NumberAnimation { - duration: root.animationDuration - easing.type: Easing.OutCubic - } - + animation: Appearance?.animation.elementMoveFast.numberAnimation.createObject(this) } } diff --git a/.config/quickshell/modules/common/widgets/SecondaryTabButton.qml b/.config/quickshell/modules/common/widgets/SecondaryTabButton.qml index 6f87e719..44677deb 100644 --- a/.config/quickshell/modules/common/widgets/SecondaryTabButton.qml +++ b/.config/quickshell/modules/common/widgets/SecondaryTabButton.qml @@ -9,7 +9,7 @@ import Quickshell.Io import Quickshell.Widgets TabButton { - id: button + id: root property string buttonText property string buttonIcon property bool selected: false @@ -17,6 +17,10 @@ TabButton { height: buttonBackground.height property int tabContentWidth: buttonBackground.width - buttonBackground.radius*2 + property color colBackground: ColorUtils.transparentize(Appearance.colors.colLayer1Hover, 1) + property color colBackgroundHover: Appearance.colors.colLayer1Hover + property color colRipple: Appearance.colors.colLayer1Active + PointingHandInteraction {} component RippleAnim: NumberAnimation { @@ -42,7 +46,7 @@ TabButton { rippleAnim.restart(); } onReleased: (event) => { - button.click() // Because the MouseArea already consumed the event + root.click() // Because the MouseArea already consumed the event rippleFadeAnim.restart(); } } @@ -88,9 +92,9 @@ TabButton { background: Rectangle { id: buttonBackground - radius: Appearance.rounding.small + radius: Appearance?.rounding.small ?? 7 implicitHeight: 37 - color: (button.hovered ? Appearance.colors.colLayer1Hover : ColorUtils.transparentize(Appearance.colors.colLayer1Hover, 1)) + color: (root.hovered ? root.colBackgroundHover : root.colBackground) layer.enabled: true layer.effect: OpacityMask { maskSource: Rectangle { @@ -108,7 +112,7 @@ TabButton { id: ripple radius: Appearance.rounding.full - color: Appearance.colors.colLayer1Active + color: root.colRipple opacity: 0 transform: Translate { diff --git a/.config/quickshell/modules/common/widgets/StyledListView.qml b/.config/quickshell/modules/common/widgets/StyledListView.qml index ed6aa916..c13d8082 100644 --- a/.config/quickshell/modules/common/widgets/StyledListView.qml +++ b/.config/quickshell/modules/common/widgets/StyledListView.qml @@ -9,7 +9,10 @@ import Quickshell import Quickshell.Wayland import Quickshell.Hyprland -ListView { // Scrollable window +/** + * A ListView with animations. + */ +ListView { id: root spacing: 5 property real removeOvershoot: 20 // Account for gaps and bouncy animations @@ -23,7 +26,7 @@ ListView { // Scrollable window add: Transition { animations: [ - Appearance.animation.elementMove.numberAnimation.createObject(this, { + Appearance?.animation.elementMove.numberAnimation.createObject(this, { properties: "opacity,scale", from: 0, to: 1, @@ -33,10 +36,10 @@ ListView { // Scrollable window addDisplaced: Transition { animations: [ - Appearance.animation.elementMove.numberAnimation.createObject(this, { + Appearance?.animation.elementMove.numberAnimation.createObject(this, { property: "y", }), - Appearance.animation.elementMove.numberAnimation.createObject(this, { + Appearance?.animation.elementMove.numberAnimation.createObject(this, { properties: "opacity,scale", to: 1, }), @@ -45,10 +48,10 @@ ListView { // Scrollable window displaced: Transition { animations: [ - Appearance.animation.elementMove.numberAnimation.createObject(this, { + Appearance?.animation.elementMove.numberAnimation.createObject(this, { property: "y", }), - Appearance.animation.elementMove.numberAnimation.createObject(this, { + Appearance?.animation.elementMove.numberAnimation.createObject(this, { properties: "opacity,scale", to: 1, }), @@ -57,10 +60,10 @@ ListView { // Scrollable window move: Transition { animations: [ - Appearance.animation.elementMove.numberAnimation.createObject(this, { + Appearance?.animation.elementMove.numberAnimation.createObject(this, { property: "y", }), - Appearance.animation.elementMove.numberAnimation.createObject(this, { + Appearance?.animation.elementMove.numberAnimation.createObject(this, { properties: "opacity,scale", to: 1, }), @@ -68,10 +71,10 @@ ListView { // Scrollable window } moveDisplaced: Transition { animations: [ - Appearance.animation.elementMove.numberAnimation.createObject(this, { + Appearance?.animation.elementMove.numberAnimation.createObject(this, { property: "y", }), - Appearance.animation.elementMove.numberAnimation.createObject(this, { + Appearance?.animation.elementMove.numberAnimation.createObject(this, { properties: "opacity,scale", to: 1, }), @@ -80,11 +83,11 @@ ListView { // Scrollable window remove: Transition { animations: [ - Appearance.animation.elementMove.numberAnimation.createObject(this, { + Appearance?.animation.elementMove.numberAnimation.createObject(this, { property: "x", to: root.width + root.removeOvershoot, }), - Appearance.animation.elementMove.numberAnimation.createObject(this, { + Appearance?.animation.elementMove.numberAnimation.createObject(this, { property: "opacity", to: 0, }) @@ -94,10 +97,10 @@ ListView { // Scrollable window // This is movement when something is removed, not removing animation! removeDisplaced: Transition { animations: [ - Appearance.animation.elementMove.numberAnimation.createObject(this, { + Appearance?.animation.elementMove.numberAnimation.createObject(this, { property: "y", }), - Appearance.animation.elementMove.numberAnimation.createObject(this, { + Appearance?.animation.elementMove.numberAnimation.createObject(this, { properties: "opacity,scale", to: 1, }), diff --git a/.config/quickshell/modules/common/widgets/StyledProgressBar.qml b/.config/quickshell/modules/common/widgets/StyledProgressBar.qml index 7173af88..c5fdbf78 100644 --- a/.config/quickshell/modules/common/widgets/StyledProgressBar.qml +++ b/.config/quickshell/modules/common/widgets/StyledProgressBar.qml @@ -8,22 +8,25 @@ import Quickshell import Quickshell.Widgets import Qt5Compat.GraphicalEffects +/** + * Material 3 progress bar. See https://m3.material.io/components/progress-indicators/overview + */ ProgressBar { id: root property real valueBarWidth: 120 property real valueBarHeight: 4 property real valueBarGap: 4 - property color highlightColor: Appearance.m3colors.m3primary - property color trackColor: Appearance.m3colors.m3secondaryContainer + property color highlightColor: Appearance?.m3colors.m3primary ?? "#685496" + property color trackColor: Appearance?.m3colors.m3secondaryContainer ?? "#F1D3F9" Behavior on value { - animation: Appearance.animation.elementMoveEnter.numberAnimation.createObject(this) + animation: Appearance?.animation.elementMoveEnter.numberAnimation.createObject(this) } background: Rectangle { anchors.fill: parent color: "transparent" - radius: Appearance.rounding.full + radius: Appearance?.rounding.full ?? 9999 implicitHeight: valueBarHeight implicitWidth: valueBarWidth } @@ -35,21 +38,21 @@ ProgressBar { Rectangle { // Left progress fill width: root.visualPosition * parent.width height: parent.height - radius: Appearance.rounding.full + radius: Appearance?.rounding.full ?? 9999 color: root.highlightColor } Rectangle { // Right remaining part fill anchors.right: parent.right width: (1 - root.visualPosition) * parent.width - valueBarGap height: parent.height - radius: Appearance.rounding.full + radius: Appearance?.rounding.full ?? 9999 color: root.trackColor } Rectangle { // Stop point anchors.right: parent.right width: valueBarGap height: valueBarGap - radius: Appearance.rounding.full + radius: Appearance?.rounding.full ?? 9999 color: root.highlightColor } } diff --git a/.config/quickshell/modules/common/widgets/StyledSlider.qml b/.config/quickshell/modules/common/widgets/StyledSlider.qml index eb241854..00aba779 100644 --- a/.config/quickshell/modules/common/widgets/StyledSlider.qml +++ b/.config/quickshell/modules/common/widgets/StyledSlider.qml @@ -8,22 +8,23 @@ import Quickshell.Widgets // Material 3 slider. See https://m3.material.io/components/sliders/overview Slider { - id: slider + id: root property real scale: 0.85 property real backgroundDotSize: 4 * scale property real backgroundDotMargins: 4 * scale // property real handleMargins: 0 * scale - property real handleMargins: (slider.pressed ? 0 : 2) * scale - property real handleWidth: (slider.pressed ? 3 : 5) * scale + property real handleMargins: (root.pressed ? 0 : 2) * scale + property real handleWidth: (root.pressed ? 3 : 5) * scale property real handleHeight: 44 * scale - property real handleLimit: slider.backgroundDotMargins + property real handleLimit: root.backgroundDotMargins property real trackHeight: 30 * scale property color highlightColor: Appearance.m3colors.m3primary property color trackColor: Appearance.m3colors.m3secondaryContainer property color handleColor: Appearance.m3colors.m3onSecondaryContainer property real trackRadius: Appearance.rounding.verysmall * scale + property real unsharpenRadius: Appearance.rounding.unsharpen - property real limitedHandleRangeWidth: (slider.availableWidth - handleWidth - slider.handleLimit * 2) + property real limitedHandleRangeWidth: (root.availableWidth - handleWidth - root.handleLimit * 2) property string tooltipContent: `${Math.round(value * 100)}%` Layout.fillWidth: true from: 0 @@ -46,7 +47,7 @@ Slider { MouseArea { anchors.fill: parent onPressed: (mouse) => mouse.accepted = false - cursorShape: slider.pressed ? Qt.ClosedHandCursor : Qt.PointingHandCursor + cursorShape: root.pressed ? Qt.ClosedHandCursor : Qt.PointingHandCursor } background: Item { @@ -57,60 +58,56 @@ Slider { Rectangle { anchors.verticalCenter: parent.verticalCenter anchors.left: parent.left - width: slider.handleLimit * 2 + slider.visualPosition * slider.limitedHandleRangeWidth - (slider.handleMargins + slider.handleWidth / 2) + width: root.handleLimit * 2 + root.visualPosition * root.limitedHandleRangeWidth - (root.handleMargins + root.handleWidth / 2) height: trackHeight - color: slider.highlightColor - topLeftRadius: slider.trackRadius - bottomLeftRadius: slider.trackRadius - topRightRadius: Appearance.rounding.unsharpen - bottomRightRadius: Appearance.rounding.unsharpen + color: root.highlightColor + topLeftRadius: root.trackRadius + bottomLeftRadius: root.trackRadius + topRightRadius: root.unsharpenRadius + bottomRightRadius: root.unsharpenRadius } // Fill right Rectangle { anchors.verticalCenter: parent.verticalCenter anchors.right: parent.right - width: slider.handleLimit * 2 + (1 - slider.visualPosition) * slider.limitedHandleRangeWidth - (slider.handleMargins + slider.handleWidth / 2) + width: root.handleLimit * 2 + (1 - root.visualPosition) * root.limitedHandleRangeWidth - (root.handleMargins + root.handleWidth / 2) height: trackHeight - color: slider.trackColor - topLeftRadius: Appearance.rounding.unsharpen - bottomLeftRadius: Appearance.rounding.unsharpen - topRightRadius: slider.trackRadius - bottomRightRadius: slider.trackRadius + color: root.trackColor + topLeftRadius: root.unsharpenRadius + bottomLeftRadius: root.unsharpenRadius + topRightRadius: root.trackRadius + bottomRightRadius: root.trackRadius } // Dot at the end Rectangle { anchors.verticalCenter: parent.verticalCenter anchors.right: parent.right - anchors.rightMargin: slider.backgroundDotMargins - width: slider.backgroundDotSize - height: slider.backgroundDotSize + anchors.rightMargin: root.backgroundDotMargins + width: root.backgroundDotSize + height: root.backgroundDotSize radius: Appearance.rounding.full - color: slider.handleColor + color: root.handleColor } } handle: Rectangle { id: handle - x: slider.leftPadding + slider.handleLimit + slider.visualPosition * slider.limitedHandleRangeWidth - y: slider.topPadding + slider.availableHeight / 2 - height / 2 - implicitWidth: slider.handleWidth - implicitHeight: slider.handleHeight + x: root.leftPadding + root.handleLimit + root.visualPosition * root.limitedHandleRangeWidth + y: root.topPadding + root.availableHeight / 2 - height / 2 + implicitWidth: root.handleWidth + implicitHeight: root.handleHeight radius: Appearance.rounding.full - color: slider.handleColor + color: root.handleColor Behavior on implicitWidth { - NumberAnimation { - duration: Appearance.animation.elementMoveFast.duration - easing.type: Appearance.animation.elementMoveFast.type - easing.bezierCurve: Appearance.animation.elementMoveFast.bezierCurve - } + animation: Appearance?.animation.elementMoveFast.numberAnimation.createObject(this) } StyledToolTip { - extraVisibleCondition: slider.pressed - content: slider.tooltipContent + extraVisibleCondition: root.pressed + content: root.tooltipContent } } } \ No newline at end of file diff --git a/.config/quickshell/modules/common/widgets/StyledSwitch.qml b/.config/quickshell/modules/common/widgets/StyledSwitch.qml index be327967..5342d41c 100644 --- a/.config/quickshell/modules/common/widgets/StyledSwitch.qml +++ b/.config/quickshell/modules/common/widgets/StyledSwitch.qml @@ -4,11 +4,16 @@ import QtQuick.Layouts import QtQuick.Controls import Qt5Compat.GraphicalEffects +/** + * Material 3 switch. See https://m3.material.io/components/switch/overview + */ Switch { id: root property real scale: 1 implicitHeight: 32 * root.scale implicitWidth: 52 * root.scale + property color activeColor: Appearance?.m3colors.m3primary ?? "#685496" + property color inactiveColor: Appearance?.m3colors.m3surfaceContainerHighest ?? "#45464F" PointingHandInteraction {} @@ -16,10 +21,10 @@ Switch { background: Rectangle { width: parent.width height: parent.height - radius: Appearance.rounding.full - color: root.checked ? Appearance.m3colors.m3primary : Appearance.m3colors.m3surfaceContainerHighest + radius: Appearance?.rounding.full ?? 9999 + color: root.checked ? root.activeColor : root.inactiveColor border.width: 2 * root.scale - border.color: root.checked ? Appearance.m3colors.m3primary : Appearance.m3colors.m3outline + border.color: root.checked ? root.activeColor : Appearance.m3colors.m3outline Behavior on color { animation: Appearance.animation.elementMoveFast.colorAnimation.createObject(this) diff --git a/.config/quickshell/modules/common/widgets/StyledText.qml b/.config/quickshell/modules/common/widgets/StyledText.qml index c5969b0b..eafb395c 100644 --- a/.config/quickshell/modules/common/widgets/StyledText.qml +++ b/.config/quickshell/modules/common/widgets/StyledText.qml @@ -6,7 +6,7 @@ Text { renderType: Text.NativeRendering font.hintingPreference: Font.PreferFullHinting verticalAlignment: Text.AlignVCenter - font.family: Appearance.font.family.main - font.pixelSize: Appearance.font.pixelSize.small - color: Appearance.m3colors.m3onBackground + font.family: Appearance?.font.family.main ?? "sans-serif" + font.pixelSize: Appearance?.font.pixelSize.small ?? 15 + color: Appearance?.m3colors.m3onBackground ?? "black" } diff --git a/.config/quickshell/modules/common/widgets/StyledToolTip.qml b/.config/quickshell/modules/common/widgets/StyledToolTip.qml index 627dfb96..1b4bd033 100644 --- a/.config/quickshell/modules/common/widgets/StyledToolTip.qml +++ b/.config/quickshell/modules/common/widgets/StyledToolTip.qml @@ -19,11 +19,7 @@ ToolTip { visible: opacity > 0 Behavior on opacity { - NumberAnimation { - duration: Appearance.animation.elementMoveFast.duration - easing.type: Appearance.animation.elementMoveFast.type - easing.bezierCurve: Appearance.animation.elementMoveFast.bezierCurve - } + animation: Appearance?.animation.elementMoveFast.numberAnimation.createObject(this) } background: null @@ -37,34 +33,26 @@ ToolTip { id: backgroundRectangle anchors.bottom: contentItemBackground.bottom anchors.horizontalCenter: contentItemBackground.horizontalCenter - color: Appearance.colors.colTooltip - radius: Appearance.rounding.verysmall + color: Appearance?.colors.colTooltip ?? "#3C4043" + radius: Appearance?.rounding.verysmall ?? 7 width: internalVisibleCondition ? (tooltipTextObject.width + 2 * padding) : 0 height: internalVisibleCondition ? (tooltipTextObject.height + 2 * padding) : 0 clip: true Behavior on width { - NumberAnimation { - duration: Appearance.animation.elementMoveFast.duration - easing.type: Appearance.animation.elementMoveFast.type - easing.bezierCurve: Appearance.animation.elementMoveFast.bezierCurve - } + animation: Appearance?.animation.elementMoveFast.numberAnimation.createObject(this) } Behavior on height { - NumberAnimation { - duration: Appearance.animation.elementMoveFast.duration - easing.type: Appearance.animation.elementMoveFast.type - easing.bezierCurve: Appearance.animation.elementMoveFast.bezierCurve - } + animation: Appearance?.animation.elementMoveFast.numberAnimation.createObject(this) } StyledText { id: tooltipTextObject anchors.centerIn: parent text: content - font.pixelSize: Appearance.font.pixelSize.smaller + font.pixelSize: Appearance?.font.pixelSize.smaller ?? 14 font.hintingPreference: Font.PreferNoHinting // Prevent shaky text - color: Appearance.colors.colOnTooltip + color: Appearance?.colors.colOnTooltip ?? "#FFFFFF" wrapMode: Text.Wrap } }