mirror of
https://github.com/noctalia-dev/noctalia-shell.git
synced 2026-05-11 17:08:27 +08:00
nbattery: using simple rectangle instead of canvas
This commit is contained in:
+33
-123
@@ -87,30 +87,6 @@ Item {
|
||||
}
|
||||
}
|
||||
|
||||
// Repaint when animated percentage changes (throttled)
|
||||
onAnimatedPercentageChanged: {
|
||||
if (!repaintTimer.running) {
|
||||
repaintTimer.start();
|
||||
}
|
||||
}
|
||||
onActiveColorChanged: batteryCanvas.requestPaint()
|
||||
onEmptyColorChanged: batteryCanvas.requestPaint()
|
||||
onVerticalChanged: batteryCanvas.requestPaint()
|
||||
|
||||
// Throttle timer to limit repaint frequency (~30 FPS)
|
||||
Timer {
|
||||
id: repaintTimer
|
||||
interval: 33
|
||||
repeat: true
|
||||
onTriggered: {
|
||||
batteryCanvas.requestPaint();
|
||||
// Stop once animation settles
|
||||
if (Math.abs(root.animatedPercentage - root.percentage) < 0.5) {
|
||||
stop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Timer to alternate between percentage text and state icon when charging/plugged
|
||||
Timer {
|
||||
id: alternateTimer
|
||||
@@ -125,8 +101,9 @@ Item {
|
||||
Layout.maximumWidth: implicitWidth
|
||||
Layout.maximumHeight: implicitHeight
|
||||
|
||||
Canvas {
|
||||
id: batteryCanvas
|
||||
// Battery body container
|
||||
Item {
|
||||
id: batteryBody
|
||||
width: root.vertical ? root.bodyHeight : root.bodyWidth + root.terminalWidth
|
||||
height: root.vertical ? root.bodyWidth + root.terminalWidth : root.bodyHeight
|
||||
anchors.left: root.vertical ? undefined : parent.left
|
||||
@@ -134,103 +111,36 @@ Item {
|
||||
anchors.horizontalCenter: root.vertical ? parent.horizontalCenter : undefined
|
||||
anchors.verticalCenter: root.vertical ? undefined : parent.verticalCenter
|
||||
|
||||
// Optimized Canvas settings for better GPU performance
|
||||
renderStrategy: Canvas.Cooperative
|
||||
renderTarget: Canvas.FramebufferObject
|
||||
|
||||
// Enable layer caching
|
||||
layer.enabled: true
|
||||
layer.smooth: true
|
||||
|
||||
Component.onCompleted: {
|
||||
requestPaint();
|
||||
// Battery body background
|
||||
Rectangle {
|
||||
id: bodyBackground
|
||||
y: root.vertical ? root.terminalWidth : 0
|
||||
width: root.vertical ? root.bodyHeight : root.bodyWidth
|
||||
height: root.vertical ? root.bodyWidth : root.bodyHeight
|
||||
radius: root.cornerRadius
|
||||
color: root.emptyColor
|
||||
}
|
||||
|
||||
onPaint: {
|
||||
const ctx = getContext("2d");
|
||||
|
||||
ctx.reset();
|
||||
|
||||
const bodyW = root.bodyWidth;
|
||||
const bodyH = root.bodyHeight;
|
||||
const termW = root.terminalWidth;
|
||||
const termH = root.terminalHeight;
|
||||
const radius = root.cornerRadius;
|
||||
const isVertical = root.vertical;
|
||||
|
||||
if (isVertical) {
|
||||
// Vertical: body is rotated (width becomes height)
|
||||
// Terminal at top, fill from bottom to top
|
||||
const vBodyW = bodyH; // swapped
|
||||
const vBodyH = bodyW; // swapped
|
||||
|
||||
// Draw battery body background
|
||||
ctx.fillStyle = root.emptyColor;
|
||||
ctx.beginPath();
|
||||
roundedRect(ctx, 0, termW, vBodyW, vBodyH, radius);
|
||||
ctx.fill();
|
||||
|
||||
// Draw terminal cap at the top (centered)
|
||||
const termX = (vBodyW - termH) / 2;
|
||||
ctx.beginPath();
|
||||
roundedRect(ctx, termX, 0, termH, termW, radius / 2);
|
||||
ctx.fill();
|
||||
|
||||
// Draw fill based on percentage (bottom to top)
|
||||
const pct = Math.max(0, Math.min(100, root.animatedPercentage));
|
||||
if (pct > 0 && root.ready) {
|
||||
const fillH = vBodyH * (pct / 100);
|
||||
const fillY = termW + vBodyH - fillH;
|
||||
|
||||
ctx.fillStyle = root.activeColor;
|
||||
ctx.beginPath();
|
||||
roundedRect(ctx, 0, fillY, vBodyW, fillH, radius);
|
||||
ctx.fill();
|
||||
}
|
||||
} else {
|
||||
// Horizontal: original drawing logic
|
||||
// Draw battery body background (semi-transparent empty portion)
|
||||
ctx.fillStyle = root.emptyColor;
|
||||
ctx.beginPath();
|
||||
roundedRect(ctx, 0, 0, bodyW, bodyH, radius);
|
||||
ctx.fill();
|
||||
|
||||
// Draw terminal cap on the right (semi-transparent)
|
||||
const termX = bodyW;
|
||||
const termY = (bodyH - termH) / 2;
|
||||
ctx.beginPath();
|
||||
roundedRect(ctx, termX, termY, termW, termH, radius / 2);
|
||||
ctx.fill();
|
||||
|
||||
// Draw fill based on percentage (left to right, no padding)
|
||||
const pct = Math.max(0, Math.min(100, root.animatedPercentage));
|
||||
if (pct > 0 && root.ready) {
|
||||
const fillW = bodyW * (pct / 100);
|
||||
|
||||
ctx.fillStyle = root.activeColor;
|
||||
ctx.beginPath();
|
||||
roundedRect(ctx, 0, 0, fillW, bodyH, radius);
|
||||
ctx.fill();
|
||||
}
|
||||
}
|
||||
// Terminal cap
|
||||
Rectangle {
|
||||
x: root.vertical ? (root.bodyHeight - root.terminalHeight) / 2 : root.bodyWidth
|
||||
y: root.vertical ? 0 : (root.bodyHeight - root.terminalHeight) / 2
|
||||
width: root.vertical ? root.terminalHeight : root.terminalWidth
|
||||
height: root.vertical ? root.terminalWidth : root.terminalHeight
|
||||
radius: root.cornerRadius / 2
|
||||
color: root.emptyColor
|
||||
}
|
||||
|
||||
// Helper function to draw rounded rectangle
|
||||
function roundedRect(ctx, x, y, w, h, r) {
|
||||
if (w < 2 * r)
|
||||
r = w / 2;
|
||||
if (h < 2 * r)
|
||||
r = h / 2;
|
||||
ctx.moveTo(x + r, y);
|
||||
ctx.lineTo(x + w - r, y);
|
||||
ctx.arcTo(x + w, y, x + w, y + r, r);
|
||||
ctx.lineTo(x + w, y + h - r);
|
||||
ctx.arcTo(x + w, y + h, x + w - r, y + h, r);
|
||||
ctx.lineTo(x + r, y + h);
|
||||
ctx.arcTo(x, y + h, x, y + h - r, r);
|
||||
ctx.lineTo(x, y + r);
|
||||
ctx.arcTo(x, y, x + r, y, r);
|
||||
ctx.closePath();
|
||||
// Fill level
|
||||
Rectangle {
|
||||
id: fillRect
|
||||
visible: root.ready && root.animatedPercentage > 0
|
||||
x: 0
|
||||
y: root.vertical ? root.terminalWidth + root.bodyWidth * (1 - root.animatedPercentage / 100) : 0
|
||||
width: root.vertical ? root.bodyHeight : root.bodyWidth * (root.animatedPercentage / 100)
|
||||
height: root.vertical ? root.bodyWidth * (root.animatedPercentage / 100) : root.bodyHeight
|
||||
radius: root.cornerRadius
|
||||
color: root.activeColor
|
||||
}
|
||||
}
|
||||
|
||||
@@ -239,8 +149,8 @@ Item {
|
||||
id: percentageText
|
||||
visible: opacity > 0
|
||||
opacity: root.showPercentageText && root.ready && !root.showStateIcon ? 1 : 0
|
||||
x: batteryCanvas.x + Style.pixelAlignCenter(batteryCanvas.width, width)
|
||||
y: batteryCanvas.y + Style.pixelAlignCenter(batteryCanvas.height, height)
|
||||
x: batteryBody.x + Style.pixelAlignCenter(batteryBody.width, width)
|
||||
y: batteryBody.y + Style.pixelAlignCenter(batteryBody.height, height)
|
||||
font.family: Settings.data.ui.fontFixed
|
||||
font.weight: Style.fontWeightBold
|
||||
text: Math.round(root.animatedPercentage)
|
||||
@@ -263,8 +173,8 @@ Item {
|
||||
id: stateIconOverlay
|
||||
visible: opacity > 0
|
||||
opacity: !root.ready || (root.hasStateIcon && root.showStateIcon) ? 1 : 0
|
||||
x: batteryCanvas.x + Style.pixelAlignCenter(batteryCanvas.width, width)
|
||||
y: batteryCanvas.y + Style.pixelAlignCenter(batteryCanvas.height, height)
|
||||
x: batteryBody.x + Style.pixelAlignCenter(batteryBody.width, width)
|
||||
y: batteryBody.y + Style.pixelAlignCenter(batteryBody.height, height)
|
||||
icon: root.stateIcon
|
||||
pointSize: Style.toOdd(root.baseSize)
|
||||
color: Qt.alpha(root.textColor, 0.75)
|
||||
|
||||
Reference in New Issue
Block a user