// The floating control panel at the bottom of the capture overlay. // // Layout is a deliberate copy of GNOME 42's screenshot UI: the area segmented // control on top, and below it the shutter dead-center with "Show Pointer" on // the left and the screenshot/screencast switch on the right. import QtQuick import qs.config import qs.services Rectangle { id: root signal captureRequested // Set by the overlay so the shutter can gray out when Window mode has // nothing pickable (no Hyprland, or an empty workspace). property bool captureEnabled: true implicitWidth: 760 implicitHeight: col.implicitHeight + 2 * 20 radius: 28 border.width: 0 color: Theme.alpha(Theme.bgPopover, Theme.popoverAlpha) Column { id: col anchors { left: parent.left right: parent.right top: parent.top margins: 20 } spacing: 18 // ── Area mode ─────────────────────────────────────────────────────── Rectangle { anchors.horizontalCenter: parent.horizontalCenter implicitWidth: modes.implicitWidth + 8 implicitHeight: modes.implicitHeight + 8 radius: Theme.pillRadius border.width: 0 color: Theme.alpha(Theme.fg, 0.07) Row { id: modes anchors.centerIn: parent spacing: 2 ModeButton { glyph: "󰍹" label: "Screen" active: Capture.mode === "screen" onClicked: Capture.mode = "screen" } ModeButton { glyph: "󰖯" label: "Window" active: Capture.mode === "window" onClicked: Capture.mode = "window" } ModeButton { glyph: "󰩭" label: "Selection" active: Capture.mode === "selection" onClicked: Capture.mode = "selection" } } } // ── Pointer toggle · shutter · capture type ───────────────────────── Item { width: col.width height: 68 // "Show Pointer". wf-recorder has no cursor switch in this build, // so it is disabled while the screencast type is selected instead // of silently lying about what it does. Rectangle { id: pointerToggle anchors { left: parent.left verticalCenter: parent.verticalCenter } implicitWidth: pointerRow.implicitWidth + 26 implicitHeight: 40 radius: Theme.pillRadius border.width: 0 opacity: Capture.recordMode || Capture.intelligenceMode ? 0.4 : 1.0 color: pointerMouse.containsMouse && !Capture.recordMode && !Capture.intelligenceMode ? Theme.alpha(Theme.fg, Theme.hoverAlpha) : Theme.alpha(Theme.fg, 0.07) Behavior on color { ColorAnimation { duration: Theme.durFast } } Row { id: pointerRow anchors.centerIn: parent spacing: 8 Text { anchors.verticalCenter: parent.verticalCenter text: Capture.showPointer ? "󰄬" : "󰄱" color: Capture.showPointer ? Theme.accent : Theme.fgDim font.family: Theme.fontMono font.pixelSize: Theme.fontSizeLarge } Text { anchors.verticalCenter: parent.verticalCenter text: "Show Pointer" color: Theme.fg font.family: Theme.fontFamily font.pixelSize: Theme.fontSize } } MouseArea { id: pointerMouse anchors.fill: parent hoverEnabled: true enabled: !Capture.recordMode && !Capture.intelligenceMode cursorShape: Qt.PointingHandCursor onClicked: Capture.showPointer = !Capture.showPointer } } // ── Shutter ───────────────────────────────────────────────────── Rectangle { id: shutter anchors.centerIn: parent implicitWidth: 64 implicitHeight: 64 radius: width / 2 border.width: 0 opacity: root.captureEnabled ? 1.0 : 0.45 color: shutterMouse.containsMouse && root.captureEnabled ? Theme.alpha(Theme.fg, 0.3) : Theme.alpha(Theme.fg, 0.18) Behavior on color { ColorAnimation { duration: Theme.durFast } } Rectangle { anchors.centerIn: parent width: shutterMouse.pressed ? 40 : 46 height: width radius: width / 2 border.width: 0 color: Capture.recordMode ? Theme.danger : (Capture.intelligenceMode ? Theme.accent : Theme.fg) Behavior on width { NumberAnimation { duration: Theme.durFast } } Behavior on color { ColorAnimation { duration: Theme.durFast } } Text { anchors.centerIn: parent visible: Capture.intelligenceMode text: "󰗊" color: Theme.bgDark font.family: Theme.fontMono font.pixelSize: 21 } } MouseArea { id: shutterMouse anchors.fill: parent hoverEnabled: true enabled: root.captureEnabled cursorShape: Qt.PointingHandCursor onClicked: root.captureRequested() } } // ── Screenshot / screencast ───────────────────────────────────── Rectangle { anchors { right: parent.right verticalCenter: parent.verticalCenter } implicitWidth: types.implicitWidth + 8 implicitHeight: types.implicitHeight + 8 radius: Theme.pillRadius border.width: 0 color: Theme.alpha(Theme.fg, 0.07) Row { id: types anchors.centerIn: parent spacing: 2 ModeButton { glyph: "󰄀" label: "Shot" active: !Capture.recordMode && !Capture.intelligenceMode onClicked: Capture.selectScreenshot() } ModeButton { glyph: "󰕧" label: "Record" active: Capture.recordMode onClicked: Capture.selectRecording() } ModeButton { glyph: "󰗊" label: "Read" active: Capture.intelligenceMode onClicked: Capture.selectIntelligence() } } } } } }