200 lines
6.7 KiB
QML
200 lines
6.7 KiB
QML
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
|
|
}
|
|
}
|
|
}
|