238 lines
5.7 KiB
QML
238 lines
5.7 KiB
QML
import QtQuick
|
|
import QtQuick.Controls
|
|
import QtQuick.Layouts
|
|
|
|
import Quickshell
|
|
import Quickshell.Bluetooth
|
|
import Quickshell.Io
|
|
|
|
PanelWindow {
|
|
id: root
|
|
|
|
screen: Quickshell.screens.filter(s => s.name.includes("HDMI"))[0] || Quickshell.screens[0]
|
|
|
|
visible: controller !== null && controller.connected
|
|
aboveWindows: false
|
|
|
|
anchors {
|
|
right: true
|
|
top: true
|
|
}
|
|
|
|
margins {
|
|
top: 16
|
|
right: 8
|
|
}
|
|
|
|
implicitWidth: expanded ? 300 : 22
|
|
implicitHeight: 120
|
|
color: "transparent"
|
|
|
|
property bool expanded: false
|
|
|
|
Controller {
|
|
id: controller
|
|
connected: false
|
|
}
|
|
|
|
Process {
|
|
id: connectionProcess
|
|
|
|
command: ["sh", "-c", "dualsensectl monitor add 'echo connected' remove 'echo disconnected'"]
|
|
running: true
|
|
|
|
stdout: SplitParser {
|
|
onRead: line => {
|
|
if (line === "connected") {
|
|
controller.connected = true
|
|
batteryProcess.running = true
|
|
} else {
|
|
controller.connected = false
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
Timer {
|
|
interval: 30000
|
|
running: true
|
|
repeat: true
|
|
onTriggered: {
|
|
if (controller.connected) {
|
|
batteryProcess.running = true
|
|
}
|
|
}
|
|
}
|
|
|
|
Process {
|
|
id: batteryProcess
|
|
|
|
command: ["sh", "-c", "dualsensectl battery"]
|
|
running: true
|
|
stdout: StdioCollector {
|
|
onStreamFinished: () => {
|
|
const s = text.split(" ");
|
|
controller.percentage = s[0];
|
|
controller.chargingState = s[1];
|
|
if (s[1].indexOf("charging") === 0) {
|
|
controller.chargingState = "Charging"
|
|
}
|
|
if (s[1].indexOf("discharging") === 0) {
|
|
controller.chargingState = "Discharging"
|
|
}
|
|
if (s[1].indexOf("full") === 0) {
|
|
controller.chargingState = "Full"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
Rectangle {
|
|
id: surface
|
|
|
|
anchors {
|
|
right: parent.right
|
|
top: parent.top
|
|
bottom: parent.bottom
|
|
}
|
|
|
|
width: root.expanded ? parent.width : 22
|
|
radius: 10
|
|
color: '#1e1e2e'
|
|
border.color: "#555c637a"
|
|
border.width: 1
|
|
clip: true
|
|
|
|
MouseArea {
|
|
anchors.fill: parent
|
|
hoverEnabled: true
|
|
|
|
onClicked: (evt) => {
|
|
root.expanded = !root.expanded
|
|
}
|
|
}
|
|
|
|
HoverHandler {
|
|
id: hoverHandler
|
|
|
|
onHoveredChanged: {
|
|
if (!hovered)
|
|
root.expanded = false
|
|
}
|
|
}
|
|
|
|
Rectangle {
|
|
id: edgeHandle
|
|
|
|
width: 5
|
|
height: 70
|
|
radius: 3
|
|
|
|
anchors {
|
|
right: parent.right
|
|
verticalCenter: parent.verticalCenter
|
|
rightMargin: 8
|
|
}
|
|
|
|
color: '#828282'
|
|
|
|
Rectangle {
|
|
id: powerLevel
|
|
|
|
anchors {
|
|
bottom: parent.bottom
|
|
}
|
|
|
|
width: parent.width
|
|
height: controller.percentage * 0.01 * parent.height
|
|
radius: 3
|
|
|
|
color: controller.chargingState === "Charging"
|
|
? "#f5c542"
|
|
: controller.chargingState === "Full" ? '#68b864' : "#8ab4f8"
|
|
}
|
|
}
|
|
|
|
RowLayout {
|
|
|
|
visible: root.expanded
|
|
|
|
anchors {
|
|
left: parent.left
|
|
right: edgeHandle.left
|
|
verticalCenter: parent.verticalCenter
|
|
leftMargin: 16
|
|
rightMargin: 8
|
|
}
|
|
|
|
spacing: 10
|
|
|
|
Image {
|
|
id: image
|
|
source: "icons/dualsense.png"
|
|
Layout.preferredWidth: 100
|
|
Layout.preferredHeight: parent.height
|
|
fillMode: Image.PreserveAspectFit
|
|
}
|
|
|
|
ColumnLayout {
|
|
Label {
|
|
Layout.fillWidth: true
|
|
|
|
text: "Dualsense"
|
|
|
|
color: "white"
|
|
font.bold: true
|
|
font.pixelSize: 16
|
|
elide: Text.ElideRight
|
|
}
|
|
|
|
Label {
|
|
Layout.fillWidth: true
|
|
|
|
text: `Battery: ${Math.round(controller.percentage)} %`
|
|
|
|
color: "#d8dee9"
|
|
font.pixelSize: 14
|
|
}
|
|
|
|
Label {
|
|
Layout.fillWidth: true
|
|
|
|
text: `Status: ${controller.chargingState}`
|
|
|
|
color: root.chargingState === "charging"
|
|
? "#f5c542"
|
|
: "#d8dee9"
|
|
|
|
font.pixelSize: 14
|
|
}
|
|
}
|
|
|
|
Button {
|
|
contentItem: Image {
|
|
source: "icons/power.svg"
|
|
height: 48
|
|
fillMode: Image.PreserveAspectFit
|
|
horizontalAlignment: Text.AlignHCenter
|
|
verticalAlignment: Text.AlignVCenter
|
|
}
|
|
|
|
background: Rectangle {
|
|
color: 'transparent'
|
|
height: 48
|
|
border.width: 0
|
|
}
|
|
|
|
onClicked: {
|
|
disconnectProcess.running = true
|
|
}
|
|
}
|
|
|
|
Process {
|
|
id: disconnectProcess
|
|
command: ["sh", "-c", "dualsensectl power-off"]
|
|
}
|
|
}
|
|
}
|
|
} |