diff options
| author | Danilo M. <danix@danix.xyz> | 2026-10-17 13:14:02 +0200 |
|---|---|---|
| committer | Danilo M. <danix@danix.xyz> | 2026-10-17 13:14:02 +0200 |
| commit | 141439750a2974a39f8dc6edf8af2c8100a36005 (patch) | |
| tree | a0510159a8c02c038de0390abddef8c5d9843330 | |
| parent | e4a1ef1ca2444831f114e631972f6e5a035047ac (diff) | |
| download | quickshell-141439750a2974a39f8dc6edf8af2c8100a36005.tar.gz quickshell-141439750a2974a39f8dc6edf8af2c8100a36005.zip | |
island: icon buttons, audio and corner controls, scene grid
| -rw-r--r-- | desktop/Button.qml | 28 | ||||
| -rw-r--r-- | desktop/island/ObsPill.qml | 88 | ||||
| -rw-r--r-- | desktop/island/README.md | 12 |
3 files changed, 92 insertions, 36 deletions
diff --git a/desktop/Button.qml b/desktop/Button.qml index 6a977fa..e1afb7a 100644 --- a/desktop/Button.qml +++ b/desktop/Button.qml @@ -15,14 +15,15 @@ Rectangle { id: btn property alias text: label.text property alias font: label.font + property string icon: "" property bool danger: false property bool enabled: true // The mouse event, for a caller that reads modifiers; a handler that // takes no argument ignores it. signal clicked(var mouse) - implicitWidth: label.implicitWidth + 22 - implicitHeight: label.implicitHeight + 12 + implicitWidth: content.implicitWidth + 22 + implicitHeight: content.implicitHeight + 12 radius: 7 opacity: enabled ? 1 : 0.4 color: area.pressed && enabled @@ -33,12 +34,25 @@ Rectangle { border.width: 1 border.color: Qt.alpha(danger ? Theme.red : Theme.text, 0.2) - Text { - id: label + Row { + id: content anchors.centerIn: parent - font { family: Theme.fontFamily; pixelSize: Theme.fontSize - 2 } - color: (area.pressed && btn.enabled) ? Theme.base - : danger ? Theme.red : Theme.text + spacing: 6 + + Text { + id: iconText + visible: btn.icon !== "" + text: btn.icon + color: label.color + font { family: Theme.iconFamily; pixelSize: label.font.pixelSize } + } + + Text { + id: label + font { family: Theme.fontFamily; pixelSize: Theme.fontSize - 2 } + color: (area.pressed && btn.enabled) ? Theme.base + : btn.danger ? Theme.red : Theme.text + } } MouseArea { diff --git a/desktop/island/ObsPill.qml b/desktop/island/ObsPill.qml index 73b35b0..6ae9b4e 100644 --- a/desktop/island/ObsPill.qml +++ b/desktop/island/ObsPill.qml @@ -78,46 +78,84 @@ Capsule { Row { spacing: 8 Button { + icon: Obs.recording ? "\udb81\ude66" : "\udb83\udec2" text: Obs.recording ? "Stop" : "Record" danger: Obs.recording onClicked: Obs.toggleRecord() } Button { visible: Obs.recording + icon: Obs.paused ? "\udb81\udc0a" : "\udb80\udfe4" text: Obs.paused ? "Resume" : "Pause" onClicked: Obs.togglePause() } + } + + Row { + spacing: 8 + visible: Obs.camId >= 0 || Obs.desktopAudio !== "" Button { visible: Obs.camId >= 0 - text: Obs.camOn ? "Hide webcam" : "Show webcam" + icon: Obs.camOn ? "\udb81\udd67" : "\udb81\udd68" + text: "Webcam" onClicked: Obs.toggleCam() } + Button { + visible: Obs.desktopAudio !== "" + icon: Obs.desktopMuted ? "\udb81\udd81" : "\udb81\udd7e" + text: "Audio" + onClicked: Obs.toggleAudio() + } } - // 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) + // The webcam's four corners on the recorded canvas. + Row { + spacing: 8 + visible: Obs.camId >= 0 + Button { icon: "\udb80\udc5b"; onClicked: Obs.moveCam("tl") } + Button { icon: "\udb80\udc5c"; onClicked: Obs.moveCam("tr") } + Button { icon: "\udb80\udc42"; onClicked: Obs.moveCam("bl") } + Button { icon: "\udb80\udc43"; onClicked: Obs.moveCam("br") } + } + + // ponytail: four columns, two rows visible; the wheel scrolls beyond + // eight scenes. Selection is click-only, so scrolling never switches. + Flickable { + width: controls.width + height: Math.min(80, grid.childrenRect.height) + contentHeight: grid.childrenRect.height + clip: true + flickableDirection: Flickable.VerticalFlick + + Grid { + id: grid + columns: 4 + spacing: 8 + + Repeater { + model: Obs.scenes + delegate: Rectangle { + required property string modelData + readonly property bool current: modelData === Obs.scene + width: 36 + height: 36 + radius: 8 + color: current ? Qt.alpha(Theme.accent, 0.25) + : area.containsMouse ? Qt.alpha(Theme.surface, 0.8) : "transparent" + Text { + anchors.centerIn: parent + text: SceneIcons.iconFor(modelData) + color: current ? Theme.text : Theme.subtext + font { family: Theme.iconFamily; pixelSize: 18 } + } + MouseArea { + id: area + anchors.fill: parent + hoverEnabled: true + cursorShape: Qt.PointingHandCursor + onClicked: Obs.setScene(modelData) + } + } } } } diff --git a/desktop/island/README.md b/desktop/island/README.md index 54a40a6..71455f3 100644 --- a/desktop/island/README.md +++ b/desktop/island/README.md @@ -81,10 +81,14 @@ copy of it exists; `obs-auth.sh` computes the SHA256 handshake QML cannot. At rest it shows a record dot, with the elapsed time while recording. A click opens its panel in the capsule: Record or Stop, Pause or Resume -(while recording), Show or Hide webcam (the first `v4l2_input` item in the -current scene; absent without one), and the scene list, current one -highlighted, click to switch. While recording the sliver pulses red, and -holds dim while paused. +(while recording), Webcam (the first `v4l2_input` item in the current +scene; absent without one), Audio (mute the global "Desktop Audio" input), +four corner buttons that move the webcam on the canvas, and a scene grid, +four columns of icon tiles, current one highlighted, click to switch. The +scene glyphs come from `~/.config/quickshell/obs-scene-icons.json`, watched +and edited from the settings window's "OBS scenes" page; an unmapped scene +shows `?`. While recording the sliver pulses red, and holds dim while +paused. QML's `WebSocket` does not expose the close code, so a wrong password reads the same as OBS quitting; it is logged once as "closed before |
