159 lines
5.9 KiB
QML
159 lines
5.9 KiB
QML
import QtQuick
|
|
import QtQuick.Shapes
|
|
import Quickshell.Services.UPower
|
|
|
|
Column {
|
|
anchors {
|
|
top: parent.top
|
|
horizontalCenter: parent.horizontalCenter
|
|
}
|
|
width: Math.max(childrenRect.width, 300)
|
|
height: childrenRect.height
|
|
anchors.topMargin: 6
|
|
Rectangle {
|
|
radius: 12
|
|
height: 40
|
|
anchors.left: parent.left
|
|
anchors.right: parent.right
|
|
anchors.margins: 6
|
|
color: "#111"
|
|
Rectangle {
|
|
color: "white"
|
|
width: (parent.width - anchors.margins * 2)/3
|
|
anchors.top: parent.top
|
|
anchors.bottom: parent.bottom
|
|
anchors.margins: 4
|
|
x: PowerProfiles.profile * width + anchors.margins
|
|
Behavior on x {NumberAnimation {duration: 300; easing.type: Easing.OutQuint}}
|
|
radius: 8
|
|
}
|
|
Row {
|
|
id: profilesRow
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
anchors.left: parent.left
|
|
anchors.right: parent.right
|
|
anchors.margins: 4
|
|
component Profile: Rectangle {
|
|
id: profile
|
|
color: "transparent"
|
|
required property var powerProfile
|
|
width: parent.width/3
|
|
height: 40
|
|
Text {
|
|
parent: profile
|
|
anchors.centerIn: parent
|
|
text: PowerProfile.toString(powerProfile)
|
|
color: PowerProfiles.profile === powerProfile ? "black" : "white"
|
|
Behavior on color { ColorAnimation {duration: 50}}
|
|
}
|
|
TapHandler {onTapped: PowerProfiles.profile = powerProfile}
|
|
}
|
|
Profile {powerProfile: PowerProfile.PowerSaver}
|
|
Profile {powerProfile: PowerProfile.Balanced}
|
|
Profile {powerProfile: PowerProfile.Performance}
|
|
}
|
|
}
|
|
Repeater {
|
|
model: UPower.devices.values.filter(dev => dev.model)
|
|
delegate: Row {
|
|
spacing: 6
|
|
Shape {
|
|
id: meter
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
width: 120
|
|
height: 120
|
|
preferredRendererType: Shape.CurveRenderer
|
|
ShapePath {
|
|
fillColor: "transparent"
|
|
strokeColor: "#444"
|
|
strokeWidth: 6
|
|
capStyle: ShapePath.RoundCap
|
|
PathAngleArc {
|
|
centerX: meter.width/2
|
|
centerY: meter.height/2
|
|
moveToStart: true
|
|
radiusX: meter.width/2 - 12
|
|
radiusY: meter.height/2 - 12
|
|
startAngle: 90
|
|
sweepAngle: 270
|
|
}
|
|
}
|
|
ShapePath {
|
|
fillColor: "transparent"
|
|
strokeColor: "white"
|
|
strokeWidth: 6
|
|
capStyle: ShapePath.RoundCap
|
|
PathAngleArc {
|
|
centerX: meter.width/2
|
|
centerY: meter.height/2
|
|
moveToStart: true
|
|
radiusX: meter.width/2 - 12
|
|
radiusY: meter.height/2 - 12
|
|
startAngle: 90
|
|
sweepAngle: modelData.percentage * 270
|
|
}
|
|
}
|
|
Text {
|
|
anchors.centerIn: parent
|
|
font.pixelSize: 20
|
|
color: "white"
|
|
text: Math.round(modelData.percentage * 100) + "%"
|
|
}
|
|
}
|
|
Column {
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
spacing: 6
|
|
Text {
|
|
x: 4
|
|
text: UPowerDeviceType.toString(modelData.type)
|
|
font.pixelSize: 20
|
|
color: "white"
|
|
}
|
|
Row {
|
|
spacing: 6
|
|
component InfoCard: Rectangle {
|
|
id: card
|
|
required property var data
|
|
required property var label
|
|
color: "#111"
|
|
height: 60
|
|
width: 100
|
|
radius: 12
|
|
Column {
|
|
parent: card
|
|
anchors.centerIn: parent
|
|
Text {
|
|
anchors.horizontalCenter: parent.horizontalCenter
|
|
color: "white"
|
|
font.pixelSize: 16
|
|
text: card.data
|
|
}
|
|
Text {
|
|
anchors.horizontalCenter: parent.horizontalCenter
|
|
color: "#aaa"
|
|
text: card.label
|
|
font.pixelSize: 12
|
|
}
|
|
}
|
|
}
|
|
InfoCard {
|
|
data: modelData.changeRate + "W"
|
|
label: UPowerDeviceState.toString(modelData.state)
|
|
}
|
|
InfoCard {
|
|
property int time: (modelData.timeToEmpty ? modelData.timeToEmpty : modelData.timeToFull)
|
|
data: `${Math.floor(time / 60 / 60)}H ${Math.floor((time / 60) % 60)}M`
|
|
label: modelData.timeToEmpty ? "to empty" : "to full"
|
|
}
|
|
InfoCard {
|
|
data: Math.round(modelData.healthPercentage) + "%"
|
|
label: "healthy"
|
|
}
|
|
Item {width: 6; height: 1}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
Item {width: 1; height: 6}
|
|
}
|