Files
arthur-os/shell/plugins/osd/Osd.qml
T

134 lines
4.3 KiB
QML

import QtQuick
import Quickshell
import Quickshell.Io
import Quickshell.Wayland
import qs.Commons
import "OsdModel.js" as OsdModel
Item {
id: root
property bool opened: false
property string icon: ""
property string message: ""
property string iconKey: ""
property int value: 0
property int maxValue: 100
property bool hasProgress: true
property int duration: 1200
readonly property int cardWidth: Style.space(269)
readonly property int mediaCardWidth: Math.round(cardWidth * 1.5)
readonly property int messageWidth: Style.space(190)
readonly property int mediaMessageWidth: messageWidth + mediaCardWidth - cardWidth
readonly property bool mediaOsd: iconKey.indexOf("media") === 0 || iconKey.indexOf("player") === 0
function iconFor(name, percent) {
return OsdModel.iconFor(name, percent)
}
function show(iconName, rawMessage, rawValue, rawMax, rawProgressText, rawDuration) {
var next = OsdModel.stateForShow(iconName, rawMessage, rawValue, rawMax, rawProgressText, rawDuration)
iconKey = next.iconKey
maxValue = next.maxValue
hasProgress = next.hasProgress
value = next.value
message = next.message
icon = next.icon
duration = next.duration
opened = true
if (duration > 0) hideTimer.restart()
else hideTimer.stop()
}
function open(payloadJson) {
try {
var p = JSON.parse(payloadJson || "{}")
show(p.icon || "", p.message || "", p.value === undefined ? "" : String(p.value), p.max === undefined ? "100" : String(p.max), p.progressText || "", p.duration === undefined ? "1200" : String(p.duration))
} catch (e) {}
}
function close() { opened = false }
Timer {
id: hideTimer
interval: root.duration
onTriggered: root.opened = false
}
IpcHandler {
target: "osd"
function show(payloadJson: string): string {
root.open(payloadJson)
return "ok"
}
function close(): string { root.close(); return "ok" }
function state(): string { return root.opened ? "open" : "closed" }
function ping(): string { return "ok" }
}
PanelWindow {
id: panel
visible: root.opened
anchors { top: true; bottom: true; left: true; right: true }
color: "transparent"
WlrLayershell.namespace: "omarchy-osd"
WlrLayershell.layer: WlrLayer.Overlay
WlrLayershell.keyboardFocus: WlrKeyboardFocus.None
exclusionMode: ExclusionMode.Ignore
Rectangle {
id: card
width: root.mediaOsd ? root.mediaCardWidth : root.cardWidth
height: Math.max(Style.space(68), Style.font.displayLarge + Style.spacing.panelGap)
anchors.horizontalCenter: parent.horizontalCenter
anchors.bottom: parent.bottom
anchors.bottomMargin: Style.space(67)
color: Util.alpha(Color.background, 0.97)
border.color: Color.popups.border
border.width: Math.max(1, Style.space(2))
radius: Style.cornerRadius
opacity: root.opened ? 1 : 0
Row {
anchors.fill: parent
anchors.leftMargin: Style.space(16)
anchors.rightMargin: Style.space(16)
spacing: Style.space(16)
Text {
width: Style.space(28)
anchors.verticalCenter: parent.verticalCenter
horizontalAlignment: Text.AlignHCenter
text: root.icon
font.family: Style.font.family
font.pixelSize: Style.font.displayLarge
color: Color.popups.text
}
Rectangle {
visible: root.hasProgress
width: visible ? Style.space(142) : 0
height: Math.max(Style.space(6), Style.spacing.sm)
anchors.verticalCenter: parent.verticalCenter
color: Util.alpha(Color.popups.text, 0.45)
Rectangle {
height: parent.height
width: parent.width * (root.hasProgress ? root.value / root.maxValue : 0)
color: Color.accent
}
}
Text {
width: root.hasProgress ? Style.space(41) : (root.mediaOsd ? root.mediaMessageWidth : root.messageWidth)
anchors.verticalCenter: parent.verticalCenter
text: root.message
font.family: Style.font.family
font.bold: true
font.pixelSize: Style.font.title
color: Color.popups.text
elide: Text.ElideRight
maximumLineCount: 1
clip: true
}
}
}
}
}