From eed9e4f8a03552499a06bb098a4adb83f42054ce Mon Sep 17 00:00:00 2001 From: 2 * r + 2 * t <61896496+soramanew@users.noreply.github.com> Date: Thu, 23 Apr 2026 20:05:44 +1000 Subject: [PATCH] feat: improve dash media controls --- components/controls/IconButton.qml | 8 +++- modules/dashboard/dash/Media.qml | 69 ++++++++++++++++-------------- 2 files changed, 43 insertions(+), 34 deletions(-) diff --git a/components/controls/IconButton.qml b/components/controls/IconButton.qml index 8d0b0f94..46d07b9b 100644 --- a/components/controls/IconButton.qml +++ b/components/controls/IconButton.qml @@ -19,6 +19,10 @@ StyledRect { property alias font: label.fontStyle property int type: IconButton.Filled property bool disabled + property bool isRound + + readonly property alias pressed: stateLayer.pressed + readonly property alias hovered: stateLayer.containsMouse property alias stateLayer: stateLayer property alias label: label @@ -44,7 +48,7 @@ StyledRect { onCheckedChanged: internalChecked = checked - radius: internalChecked ? Tokens.rounding.medium : implicitHeight / 2 * Math.min(1, Tokens.rounding.scale) + radius: stateLayer.pressed ? Tokens.rounding.small : internalChecked ? Tokens.rounding.medium : isRound ? implicitHeight / 2 * Math.min(1, Tokens.rounding.scale) : Tokens.rounding.large color: type === IconButton.Text ? "transparent" : disabled ? disabledColour : internalChecked ? activeColour : inactiveColour implicitWidth: implicitHeight @@ -79,6 +83,8 @@ StyledRect { Behavior on radius { Anim { id: radiusAnim + + type: Anim.DefaultEffects } } } diff --git a/modules/dashboard/dash/Media.qml b/modules/dashboard/dash/Media.qml index 7d806325..2bdbac70 100644 --- a/modules/dashboard/dash/Media.qml +++ b/modules/dashboard/dash/Media.qml @@ -1,13 +1,12 @@ pragma ComponentBehavior: Bound import QtQuick -import QtQuick.Shapes import QtQuick.Effects import M3Shapes import Caelestia.Config import Caelestia.Services -import Caelestia.Components import qs.components +import qs.components.controls import qs.components.effects import qs.services import qs.utils @@ -223,30 +222,51 @@ Item { elide: Text.ElideRight } - Row { + Item { id: controls anchors.top: artist.bottom - anchors.horizontalCenter: parent.horizontalCenter + anchors.left: parent.left + anchors.right: parent.right anchors.topMargin: Tokens.spacing.medium + anchors.margins: Tokens.padding.large - spacing: Tokens.spacing.small + implicitHeight: Math.max(previousBtn.implicitHeight, playPauseBtn.implicitHeight, nextBtn.implicitHeight) PlayerControl { + id: previousBtn + + anchors.left: parent.left + width: Math.round(implicitWidth * shapeMorphExpansion - playPauseBtn.implicitWidth * (playPauseBtn.shapeMorphExpansion - 1)) + + type: IconButton.Tonal icon: "skip_previous" - canUse: Players.active?.canGoPrevious ?? false + disabled: !Players.active?.canGoPrevious onClicked: Players.active?.previous() } PlayerControl { + id: playPauseBtn + + anchors.left: previousBtn.right + anchors.right: nextBtn.left + anchors.margins: Tokens.spacing.small + icon: Players.active?.isPlaying ? "pause" : "play_arrow" - canUse: Players.active?.canTogglePlaying ?? false + checked: Players.active?.isPlaying + disabled: !Players.active?.canTogglePlaying onClicked: Players.active?.togglePlaying() } PlayerControl { + id: nextBtn + + anchors.right: parent.right + width: Math.round(implicitWidth * shapeMorphExpansion - playPauseBtn.implicitWidth * (playPauseBtn.shapeMorphExpansion - 1)) + + type: IconButton.Tonal icon: "skip_next" - canUse: Players.active?.canGoNext ?? false + disabled: !Players.active?.canGoNext onClicked: Players.active?.next() } } @@ -269,33 +289,16 @@ Item { fillMode: AnimatedImage.PreserveAspectFit } - component PlayerControl: StyledRect { - id: control + component PlayerControl: IconButton { + property real shapeMorphExpansion: pressed ? 1.16 : 1 - required property string icon - required property bool canUse + font: Tokens.font.icon.medium + isRound: true - signal clicked - - implicitWidth: Math.max(icon.implicitHeight, icon.implicitHeight) + Tokens.padding.extraSmall - implicitHeight: implicitWidth - - StateLayer { - disabled: !control.canUse - radius: Tokens.rounding.full - onClicked: control.clicked() - } - - MaterialIcon { - id: icon - - anchors.centerIn: parent - anchors.verticalCenterOffset: font.pointSize * 0.05 - - animate: true - text: control.icon - color: control.canUse ? Colours.palette.m3onSurface : Colours.palette.m3outline - fontStyle: Tokens.font.icon.large + Behavior on shapeMorphExpansion { + Anim { + type: Anim.FastSpatial + } } } }