diff options
| author | Danilo M. <danix@danix.xyz> | 2026-10-17 12:16:33 +0200 |
|---|---|---|
| committer | Danilo M. <danix@danix.xyz> | 2026-10-17 12:16:33 +0200 |
| commit | e3bd8e9f637dc6bed732170153cb09a281b842e1 (patch) | |
| tree | 76b05cc2737557b1da34a5b33188dcb067a2cbe4 /desktop/island/ObsPill.qml | |
| parent | 2148f660256b93d3ff6efde70be11d19b0f823ae (diff) | |
| download | quickshell-e3bd8e9f637dc6bed732170153cb09a281b842e1.tar.gz quickshell-e3bd8e9f637dc6bed732170153cb09a281b842e1.zip | |
island: OBS pill and its controls panel
Diffstat (limited to 'desktop/island/ObsPill.qml')
| -rw-r--r-- | desktop/island/ObsPill.qml | 125 |
1 files changed, 125 insertions, 0 deletions
diff --git a/desktop/island/ObsPill.qml b/desktop/island/ObsPill.qml new file mode 100644 index 0000000..73b35b0 --- /dev/null +++ b/desktop/island/ObsPill.qml @@ -0,0 +1,125 @@ +// Copyright (C) 2026 Danilo M. <danix@danix.xyz> +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License version 2 as +// published by the Free Software Foundation. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +import QtQuick +import ".." +import "Logic.js" as Logic + +// At rest a record dot, with the elapsed time while recording. A click +// morphs the capsule into the controls panel, as the status pill does for +// sound: record, pause, webcam, and the scene list. +Capsule { + id: pill + + property string panel: "" + signal openPanel() + + expanded: panel === "obs" + restWidth: rest.implicitWidth + 24 + panelWidth: 260 + panelHeight: controls.implicitHeight + 28 + + Row { + id: rest + anchors.centerIn: parent + spacing: 6 + opacity: pill.expanded ? 0 : 1 + visible: opacity > 0 + Behavior on opacity { NumberAnimation { duration: 120 } } + + Text { + anchors.verticalCenter: parent.verticalCenter + text: "\uf111" + color: Obs.recording ? Theme.red : Theme.subtext + opacity: Obs.paused ? 0.5 : 1 + font { family: Theme.iconFamily; pixelSize: 14 } + } + Text { + anchors.verticalCenter: parent.verticalCenter + visible: Obs.recording + text: Logic.obsElapsed(Obs.duration) + color: Theme.text + font { family: Theme.fontFamily; pixelSize: Theme.fontSize - 2 } + } + } + + MouseArea { + anchors.fill: parent + enabled: !pill.expanded + cursorShape: Qt.PointingHandCursor + onClicked: pill.openPanel() + } + + Column { + id: controls + x: 14 + y: 14 + width: pill.panelWidth - 28 + spacing: 10 + opacity: pill.expanded ? 1 : 0 + visible: opacity > 0 + Behavior on opacity { NumberAnimation { duration: 160 } } + + Text { + text: Obs.recording ? (Obs.paused ? "Paused " : "Recording ") + Logic.obsElapsed(Obs.duration) + : "Not recording" + color: Obs.recording ? Theme.red : Theme.subtext + font { family: Theme.fontFamily; pixelSize: Theme.fontSize - 2 } + } + + Row { + spacing: 8 + Button { + text: Obs.recording ? "Stop" : "Record" + danger: Obs.recording + onClicked: Obs.toggleRecord() + } + Button { + visible: Obs.recording + text: Obs.paused ? "Resume" : "Pause" + onClicked: Obs.togglePause() + } + Button { + visible: Obs.camId >= 0 + text: Obs.camOn ? "Hide webcam" : "Show webcam" + onClicked: Obs.toggleCam() + } + } + + // ponytail: a plain Column, no scrolling; about ten scenes fit the + // island's 480px window. A ListView if a scene collection outgrows it. + Repeater { + model: Obs.scenes + delegate: Rectangle { + required property string modelData + readonly property bool current: modelData === Obs.scene + width: controls.width + height: 30 + radius: 7 + color: current ? Qt.alpha(Theme.accent, 0.25) + : area.containsMouse ? Qt.alpha(Theme.surface, 0.8) : "transparent" + Text { + anchors { left: parent.left; leftMargin: 10; verticalCenter: parent.verticalCenter } + text: modelData + color: current ? Theme.text : Theme.subtext + font { family: Theme.fontFamily; pixelSize: Theme.fontSize - 2 } + } + MouseArea { + id: area + anchors.fill: parent + hoverEnabled: true + cursorShape: Qt.PointingHandCursor + onClicked: Obs.setScene(modelData) + } + } + } + } +} |
