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} }