From c781c47ae87c6d9c8a224d28f3ab535f720c9c6b Mon Sep 17 00:00:00 2001 From: 2 * r + 2 * t <61896496+soramanew@users.noreply.github.com> Date: Mon, 8 Jun 2026 17:05:34 +1000 Subject: [PATCH] fix: improve utils screen recorder --- modules/utilities/cards/Record.qml | 118 ++++++++++++++++------------- 1 file changed, 65 insertions(+), 53 deletions(-) diff --git a/modules/utilities/cards/Record.qml b/modules/utilities/cards/Record.qml index c0d7e0c6..2c2cae24 100644 --- a/modules/utilities/cards/Record.qml +++ b/modules/utilities/cards/Record.qml @@ -2,6 +2,7 @@ pragma ComponentBehavior: Bound import QtQuick import QtQuick.Layouts +import Caelestia.Components import Caelestia.Config import qs.components import qs.components.controls @@ -35,7 +36,7 @@ StyledRect { StyledRect { implicitWidth: implicitHeight implicitHeight: { - const h = icon.implicitHeight + Tokens.padding.large; + const h = icon.implicitHeight + Tokens.padding.small * 2; return h - (h % 2); } @@ -46,8 +47,7 @@ StyledRect { id: icon anchors.centerIn: parent - anchors.horizontalCenterOffset: -0.5 - anchors.verticalCenterOffset: 1.5 + anchors.verticalCenterOffset: 1 text: "screen_record" color: Recorder.running ? Colours.palette.m3onSecondary : Colours.palette.m3onSecondaryContainer fontStyle: Tokens.font.icon.large @@ -67,15 +67,17 @@ StyledRect { StyledText { Layout.fillWidth: true - text: Recorder.paused ? qsTr("Recording paused") : Recorder.running ? qsTr("Recording running") : qsTr("Recording off") + text: Recorder.paused ? qsTr("Paused") : Recorder.running ? qsTr("Running...") : qsTr("Ready") color: Colours.palette.m3onSurfaceVariant font: Tokens.font.body.small elide: Text.ElideRight + animate: true } } SplitButton { disabled: Recorder.running + active: menuItems.find(m => root.props.recordingMode === m.icon + m.text) ?? menuItems[0] menu.onItemSelected: item => root.props.recordingMode = item.icon + item.text @@ -117,6 +119,7 @@ StyledRect { Layout.fillWidth: true Layout.preferredHeight: implicitHeight sourceComponent: running ? recordingControls : recordingList + clip: Layout.preferredHeight < implicitHeight Behavior on Layout.preferredHeight { id: locHeightAnim @@ -128,21 +131,11 @@ StyledRect { Behavior on running { SequentialAnimation { - ParallelAnimation { - Anim { - target: listOrControls - property: "scale" - to: 0.7 - duration: Tokens.anim.durations.small - easing: Tokens.anim.standardAccel - } - Anim { - target: listOrControls - property: "opacity" - to: 0 - duration: Tokens.anim.durations.small - easing: Tokens.anim.standardAccel - } + Anim { + target: listOrControls + property: "opacity" + to: 0 + type: Anim.DefaultEffects } PropertyAction { target: locHeightAnim @@ -150,25 +143,22 @@ StyledRect { value: true } PropertyAction {} - PropertyAction { - target: locHeightAnim - property: "enabled" - value: false - } ParallelAnimation { - Anim { - target: listOrControls - property: "scale" - to: 1 - duration: Tokens.anim.durations.small - easing: Tokens.anim.standardDecel + SequentialAnimation { + PauseAnimation { + duration: 100 + } + PropertyAction { + target: locHeightAnim + property: "enabled" + value: false + } } Anim { target: listOrControls property: "opacity" to: 1 - duration: Tokens.anim.durations.small - easing: Tokens.anim.standardDecel + type: Anim.SlowEffects } } } @@ -205,7 +195,7 @@ StyledRect { animate: true text: Recorder.paused ? "PAUSED" : "REC" color: Recorder.paused ? Colours.palette.m3onTertiary : Colours.palette.m3onError - font: Tokens.font.mono.medium + font: Tokens.font.mono.small } Behavior on implicitWidth { @@ -233,6 +223,7 @@ StyledRect { } StyledText { + Layout.fillWidth: true text: { const elapsed = Recorder.elapsed; @@ -249,31 +240,52 @@ StyledRect { return qsTr("Recording for %1").arg(time); } font: Tokens.font.body.medium + elide: Text.ElideMiddle } - Item { - Layout.fillWidth: true - } + ButtonRow { + spacing: Tokens.spacing.extraSmall - IconButton { - label.animate: true - icon: Recorder.paused ? "play_arrow" : "pause" - isToggle: true - checked: Recorder.paused - type: IconButton.Tonal - font: Tokens.font.icon.large - onClicked: { - Recorder.togglePause(); - internalChecked = Recorder.paused; + IconButton { + shapeMorph: true + isRound: true + label.animate: true + icon: Recorder.paused ? "play_arrow" : "pause" + isToggle: true + checked: Recorder.paused + type: IconButton.Tonal + font: Tokens.font.icon.medium + onClicked: { + Recorder.togglePause(); + internalChecked = Recorder.paused; + } + + implicitWidth: { + // Ensure even size so icon is centered properly + const h = label.implicitHeight + Tokens.padding.large * 2; + if (h % 2 !== 0) + return h + 1; + return h; + } } - } - IconButton { - icon: "stop" - inactiveColour: Colours.palette.m3error - inactiveOnColour: Colours.palette.m3onError - font: Tokens.font.icon.large - onClicked: Recorder.stop() + IconButton { + shapeMorph: true + isRound: true + icon: "stop" + inactiveColour: Colours.palette.m3error + inactiveOnColour: Colours.palette.m3onError + font: Tokens.font.icon.medium + onClicked: Recorder.stop() + + implicitWidth: { + // Ensure even size so icon is centered properly + const h = label.implicitHeight + Tokens.padding.large * 2; + if (h % 2 !== 0) + return h + 1; + return h; + } + } } } }