v1.2.0: add split-flap board and nixie tube display modes with display style config

This commit is contained in:
ArnoldCordewiner
2026-09-05 20:22:59 +02:00
parent 944b7587bc
commit 361a319d94
9 changed files with 385 additions and 31 deletions
+40 -22
View File
@@ -7,6 +7,10 @@
* - Grey : unchanged (or first reading)
* - "--" : API failure (network error, 4xx/5xx, 429 rate limit)
*
* Display modes: 0 = plain text (trend-colored), 1 = split-flap board,
* 2 = nixie tubes. In the flip and nixie modes the trend shows on a
* small LED, the digits themselves stay white / amber.
*
* Refresh interval: configurable, minimum 5 minutes
* (CoinGecko limit: 1 call per 5 minutes).
*/
@@ -20,6 +24,12 @@ Item {
id: root
readonly property int refreshMinutes: Math.max(5, plasmoid.configuration.refreshMinutes)
// 0 = plain text, 1 = split-flap board, 2 = nixie tubes
property int displayMode: 0
readonly property string modeSource: displayMode === 1 ? "DisplayFlip.qml"
: displayMode === 2 ? "DisplayNixie.qml"
: "DisplayText.qml"
readonly property string apiUrl: "https://api.coingecko.com/api/v3/simple/price?ids=bitcoin&vs_currencies=eur"
// -1 = down, 0 = unchanged / no previous reading yet, 1 = up
@@ -61,8 +71,13 @@ Item {
}
Component.onCompleted: {
console.log("[bitcoinprice] started, refresh interval:",
refreshMinutes, "minutes");
try {
displayMode = Math.max(0, Math.min(2, plasmoid.configuration.displayMode));
} catch (e) {
// outside a real plasmoid shell (tests): keep the default
}
console.log("[bitcoinprice] started, refresh interval:", refreshMinutes,
"minutes, display mode:", displayMode);
}
Plasmoid.backgroundHints: PlasmaCore.Types.StandardBackground
@@ -75,7 +90,9 @@ Item {
Item {
id: compact
Layout.minimumWidth: row.implicitWidth + PlasmaCore.Units.smallSpacing * 2
Layout.minimumWidth: btcIcon.width + row.spacing
+ (displayLoader.item ? displayLoader.item.implicitWidth : 0)
+ PlasmaCore.Units.smallSpacing * 2
Layout.minimumHeight: PlasmaCore.Units.iconSizes.smallMedium
Row {
@@ -93,19 +110,16 @@ Item {
visible: root.state === "ok"
}
Text {
id: priceLabel
Loader {
id: displayLoader
anchors.verticalCenter: parent.verticalCenter
text: root.displayText
color: root.priceColor
textFormat: Text.PlainText
elide: Text.ElideRight
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
font.family: PlasmaCore.Theme.defaultFont.family
font.pixelSize: compact.height > PlasmaCore.Units.iconSizes.small
? Math.round(compact.height * 0.6)
: PlasmaCore.Theme.defaultFont.pixelSize
height: compact.height * 0.62
width: item ? item.implicitWidth : 0
source: root.modeSource
onLoaded: {
item.display = Qt.binding(function () { return root.displayText; });
item.trendColor = Qt.binding(function () { return root.priceColor; });
}
}
}
}
@@ -115,8 +129,8 @@ Item {
Item {
id: fullRep
implicitWidth: PlasmaCore.Units.gridUnit * 14
implicitHeight: PlasmaCore.Units.gridUnit * 9
implicitWidth: PlasmaCore.Units.gridUnit * 16
implicitHeight: PlasmaCore.Units.gridUnit * 10
Column {
anchors.centerIn: parent
@@ -131,12 +145,16 @@ Item {
visible: root.state === "ok"
}
Text {
Loader {
id: fullDisplayLoader
anchors.horizontalCenter: parent.horizontalCenter
text: root.displayText
color: root.priceColor
font.family: PlasmaCore.Theme.defaultFont.family
font.pixelSize: PlasmaCore.Units.gridUnit * 2
height: PlasmaCore.Units.gridUnit * 2.4
width: item ? item.implicitWidth : 0
source: root.modeSource
onLoaded: {
item.display = Qt.binding(function () { return root.displayText; });
item.trendColor = Qt.binding(function () { return root.priceColor; });
}
}
Text {