226 lines
8.2 KiB
QML
226 lines
8.2 KiB
QML
// 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-centre 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 grey 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()
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|