import QtQuick import qs.Common import qs.Widgets Item { id: widget property var service: null property var panel: null readonly property bool recording: service ? service.recording : false readonly property bool replayArmed: service ? service.replayArmed : false readonly property bool busy: service ? service.busy : false function monitorName() { const screen = panel ? panel.targetScreen : null; return (screen && screen.name) ? screen.name : "focused"; } function elapsedText() { const total = service ? service.elapsedSeconds : 0; const mins = Math.floor(total / 60); const secs = total % 60; return (mins < 10 ? "0" : "") + mins + ":" + (secs < 10 ? "0" : "") + secs; } component CaptureButton: Rectangle { id: button property string icon: "" property string label: "" property bool active: false property bool enabled: true signal triggered height: 46 radius: Theme.cornerRadius color: active ? Theme.primarySelected : (buttonArea.containsMouse && enabled ? Theme.surfaceHover : Theme.withAlpha(Theme.surfaceLight, Theme.popupTransparency)) border.color: active ? Theme.primary : Theme.outlineLight border.width: active ? 1 : Theme.layerOutlineWidth opacity: enabled ? 1 : 0.45 Row { anchors.centerIn: parent spacing: Theme.spacingS DankIcon { anchors.verticalCenter: parent.verticalCenter name: button.icon size: Theme.iconSize - 6 color: button.active ? Theme.primary : Theme.surfaceText } StyledText { anchors.verticalCenter: parent.verticalCenter text: button.label font.pixelSize: Theme.fontSizeSmall font.weight: button.active ? Font.Medium : Font.Normal color: button.active ? Theme.primary : Theme.surfaceText } } MouseArea { id: buttonArea anchors.fill: parent hoverEnabled: true enabled: button.enabled cursorShape: enabled ? Qt.PointingHandCursor : Qt.ArrowCursor onClicked: button.triggered() } } Column { anchors.fill: parent spacing: Theme.spacingS Rectangle { width: parent.width height: 40 radius: Theme.cornerRadius color: widget.busy ? Theme.withAlpha(Theme.error, 0.15) : Theme.withAlpha(Theme.surfaceLight, Theme.popupTransparency) border.color: widget.busy ? Theme.error : Theme.outlineLight border.width: Theme.layerOutlineWidth Rectangle { id: statusDot anchors.left: parent.left anchors.leftMargin: Theme.spacingM anchors.verticalCenter: parent.verticalCenter width: 10 height: 10 radius: 5 color: widget.recording ? Theme.error : (widget.replayArmed ? Theme.warning : Theme.surfaceVariantText) SequentialAnimation on opacity { running: widget.busy loops: Animation.Infinite NumberAnimation { to: 0.25 duration: 700 } NumberAnimation { to: 1 duration: 700 } } } StyledText { anchors.left: statusDot.right anchors.leftMargin: Theme.spacingS anchors.right: elapsed.left anchors.verticalCenter: parent.verticalCenter text: { if (widget.recording) return "Recording " + widget.monitorName(); if (widget.replayArmed) return "Replay buffer armed"; return "Idle ยท " + widget.monitorName(); } font.pixelSize: Theme.fontSizeSmall color: Theme.surfaceText elide: Text.ElideRight } StyledText { id: elapsed anchors.right: parent.right anchors.rightMargin: Theme.spacingM anchors.verticalCenter: parent.verticalCenter text: widget.elapsedText() font.pixelSize: Theme.fontSizeSmall font.weight: Font.Medium color: widget.busy ? Theme.error : Theme.surfaceVariantText visible: widget.busy } } Grid { width: parent.width columns: 2 rowSpacing: Theme.spacingS columnSpacing: Theme.spacingS readonly property real cellWidth: (width - columnSpacing) / 2 CaptureButton { width: parent.cellWidth icon: widget.recording ? "stop_circle" : "videocam" label: widget.recording ? "Stop & save" : "Record" active: widget.recording enabled: !widget.replayArmed onTriggered: widget.service.toggleRecording(widget.monitorName()) } CaptureButton { width: parent.cellWidth icon: widget.replayArmed ? "stop_circle" : "history" label: widget.replayArmed ? "Disarm replay" : "Arm replay" active: widget.replayArmed enabled: !widget.recording onTriggered: widget.service.toggleReplay(widget.monitorName()) } CaptureButton { width: parent.cellWidth icon: "save" label: "Save last " + (widget.service ? widget.service.replaySeconds : 30) + "s" enabled: widget.replayArmed onTriggered: widget.service.saveReplay() } CaptureButton { width: parent.cellWidth icon: "screenshot_region" label: "Screenshot" onTriggered: { if (widget.panel) widget.panel.requestClose(); widget.service.screenshot("region"); } } } StyledText { width: parent.width text: (widget.service && widget.service.lastFile !== "") ? "Last: " + widget.service.lastFile.split("/").pop() : "Saves to " + (widget.service ? widget.service.saveDirectory : "") font.pixelSize: Theme.fontSizeSmall color: Theme.surfaceVariantText elide: Text.ElideMiddle } } }