v1.3.0: live-bind display mode to config (dialog changes apply without restart); add configurable split-flap cascade seconds
This commit is contained in:
@@ -15,6 +15,7 @@ Three display styles, configurable in the settings dialog:
|
|||||||
|
|
||||||
In the split-flap and nixie styles the digits keep their display color and the
|
In the split-flap and nixie styles the digits keep their display color and the
|
||||||
trend (up/down/unchanged) is shown on a small LED next to the display.
|
trend (up/down/unchanged) is shown on a small LED next to the display.
|
||||||
|
Display style changes apply immediately, without restarting the shell.
|
||||||
|
|
||||||
| Situation | Plain text color | Trend LED |
|
| Situation | Plain text color | Trend LED |
|
||||||
|---|---|---|
|
|---|---|---|
|
||||||
@@ -32,19 +33,22 @@ representations.
|
|||||||
- **Refresh interval (minutes)** — default 5, minimum **5**, maximum 1440.
|
- **Refresh interval (minutes)** — default 5, minimum **5**, maximum 1440.
|
||||||
The 5-minute floor exists because the CoinGecko API allows one request per
|
The 5-minute floor exists because the CoinGecko API allows one request per
|
||||||
5 minutes. A hint text in the config dialog explains this.
|
5 minutes. A hint text in the config dialog explains this.
|
||||||
|
- **Split-flap cascade (seconds)** — default 3, range 1–15. Spreads the flip
|
||||||
|
animation of a price change evenly over this many seconds (applies to the
|
||||||
|
split-flap display style).
|
||||||
|
|
||||||
Configurable via right-click on the widget → *Configure Bitcoin Price…* → *General*.
|
Configurable via right-click on the widget → *Configure Bitcoin Price…* → *General*.
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
### Graphical
|
### Graphical
|
||||||
Double-click `bitcoin-price-1.2.0.plasmoid` in Dolphin (Plasma installs it to
|
Double-click `bitcoin-price-1.3.0.plasmoid` in Dolphin (Plasma installs it to
|
||||||
`~/.local/share/plasma/plasmoids/` automatically). The latest build is attached
|
`~/.local/share/plasma/plasmoids/` automatically). The latest build is attached
|
||||||
to the [v1.2.0 release](../../releases/tag/v1.2.0).
|
to the [v1.3.0 release](../../releases/tag/v1.2.0).
|
||||||
|
|
||||||
### Terminal
|
### Terminal
|
||||||
```bash
|
```bash
|
||||||
kpackagetool5 --type Plasma/Applet --upgrade bitcoin-price-1.2.0.plasmoid
|
kpackagetool5 --type Plasma/Applet --upgrade bitcoin-price-1.3.0.plasmoid
|
||||||
# Then restart the shell if needed:
|
# Then restart the shell if needed:
|
||||||
plasmashell --replace &
|
plasmashell --replace &
|
||||||
```
|
```
|
||||||
|
|||||||
Binary file not shown.
@@ -14,6 +14,12 @@
|
|||||||
</choices>
|
</choices>
|
||||||
<default>0</default>
|
<default>0</default>
|
||||||
</entry>
|
</entry>
|
||||||
|
<entry name="flapSeconds" type="Int">
|
||||||
|
<label>Seconds over which the split-flap cascade spreads a price change</label>
|
||||||
|
<default>3</default>
|
||||||
|
<min>1</min>
|
||||||
|
<max>15</max>
|
||||||
|
</entry>
|
||||||
<entry name="refreshMinutes" type="Int">
|
<entry name="refreshMinutes" type="Int">
|
||||||
<label>Refresh interval in minutes (minimum 5 because of the CoinGecko rate limit)</label>
|
<label>Refresh interval in minutes (minimum 5 because of the CoinGecko rate limit)</label>
|
||||||
<default>5</default>
|
<default>5</default>
|
||||||
|
|||||||
@@ -13,6 +13,8 @@ Row {
|
|||||||
// wired by the parent loader
|
// wired by the parent loader
|
||||||
property string display: "--"
|
property string display: "--"
|
||||||
property color trendColor: "#9e9e9e"
|
property color trendColor: "#9e9e9e"
|
||||||
|
// seconds over which the cascade to a new price is spread
|
||||||
|
property int flapSeconds: 3
|
||||||
|
|
||||||
spacing: height * 0.06
|
spacing: height * 0.06
|
||||||
|
|
||||||
@@ -20,6 +22,8 @@ Row {
|
|||||||
property bool ready: false
|
property bool ready: false
|
||||||
readonly property real cellFont: height * 0.72
|
readonly property real cellFont: height * 0.72
|
||||||
readonly property real cellWidth: cellFont * 0.80
|
readonly property real cellWidth: cellFont * 0.80
|
||||||
|
// one flap open+close takes 260 ms; keep delays above that
|
||||||
|
readonly property int flapDuration: 260
|
||||||
|
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
chars = display.split("");
|
chars = display.split("");
|
||||||
@@ -32,14 +36,21 @@ Row {
|
|||||||
}
|
}
|
||||||
var nc = display.split("");
|
var nc = display.split("");
|
||||||
var n = Math.max(chars.length, nc.length);
|
var n = Math.max(chars.length, nc.length);
|
||||||
|
// spread the changed cells evenly across flapSeconds
|
||||||
|
var changed = [];
|
||||||
for (var i = 0; i < n; i++) {
|
for (var i = 0; i < n; i++) {
|
||||||
var from = i < chars.length ? chars[i] : "";
|
var from = i < chars.length ? chars[i] : "";
|
||||||
var to = i < nc.length ? nc[i] : "";
|
var to = i < nc.length ? nc[i] : "";
|
||||||
if (from !== to) {
|
if (from !== to) {
|
||||||
var cell = rep.itemAt(i);
|
changed.push([i, to]);
|
||||||
if (cell) {
|
}
|
||||||
cell.flipTo(to, i * 45);
|
}
|
||||||
}
|
var span = Math.max(1, flapSeconds) * 1000 - flapDuration;
|
||||||
|
var step = changed.length > 1 ? Math.max(0, Math.floor(span / (changed.length - 1))) : 0;
|
||||||
|
for (var j = 0; j < changed.length; j++) {
|
||||||
|
var cell = rep.itemAt(changed[j][0]);
|
||||||
|
if (cell) {
|
||||||
|
cell.flipTo(changed[j][1], j * step);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
chars = nc;
|
chars = nc;
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ Kirigami.FormLayout {
|
|||||||
// The cfg_ prefix is what Plasma uses to read/write plasmoid.configuration
|
// The cfg_ prefix is what Plasma uses to read/write plasmoid.configuration
|
||||||
property alias cfg_displayMode: modeCombo.currentIndex
|
property alias cfg_displayMode: modeCombo.currentIndex
|
||||||
property alias cfg_refreshMinutes: intervalSpin.value
|
property alias cfg_refreshMinutes: intervalSpin.value
|
||||||
|
property alias cfg_flapSeconds: flapSpin.value
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
Kirigami.FormData.isSection: true
|
Kirigami.FormData.isSection: true
|
||||||
@@ -25,6 +26,15 @@ Kirigami.FormLayout {
|
|||||||
model: [i18n("Plain text"), i18n("Split-flap board"), i18n("Nixie tubes")]
|
model: [i18n("Plain text"), i18n("Split-flap board"), i18n("Nixie tubes")]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QQC2.SpinBox {
|
||||||
|
id: flapSpin
|
||||||
|
Kirigami.FormData.label: i18n("Split-flap cascade (seconds):")
|
||||||
|
from: 1
|
||||||
|
to: 15
|
||||||
|
stepSize: 1
|
||||||
|
editable: true
|
||||||
|
}
|
||||||
|
|
||||||
QQC2.SpinBox {
|
QQC2.SpinBox {
|
||||||
id: intervalSpin
|
id: intervalSpin
|
||||||
Kirigami.FormData.label: i18n("Refresh interval (minutes):")
|
Kirigami.FormData.label: i18n("Refresh interval (minutes):")
|
||||||
|
|||||||
+28
-1
@@ -25,11 +25,29 @@ Item {
|
|||||||
|
|
||||||
readonly property int refreshMinutes: Math.max(5, plasmoid.configuration.refreshMinutes)
|
readonly property int refreshMinutes: Math.max(5, plasmoid.configuration.refreshMinutes)
|
||||||
|
|
||||||
|
// Seconds over which the split-flap display cascades to a new price
|
||||||
|
readonly property int flapSeconds: Math.max(1, plasmoid.configuration.flapSeconds)
|
||||||
|
|
||||||
// 0 = plain text, 1 = split-flap board, 2 = nixie tubes
|
// 0 = plain text, 1 = split-flap board, 2 = nixie tubes
|
||||||
property int displayMode: 0
|
property int displayMode: 0
|
||||||
readonly property string modeSource: displayMode === 1 ? "DisplayFlip.qml"
|
readonly property string modeSource: displayMode === 1 ? "DisplayFlip.qml"
|
||||||
: displayMode === 2 ? "DisplayNixie.qml"
|
: displayMode === 2 ? "DisplayNixie.qml"
|
||||||
: "DisplayText.qml"
|
: "DisplayText.qml"
|
||||||
|
|
||||||
|
// Enum config values arrive either as an int index or as the choice
|
||||||
|
// name, depending on the Plasma version — accept both.
|
||||||
|
function modeFromConfig(v) {
|
||||||
|
if (typeof v === "number") {
|
||||||
|
return Math.max(0, Math.min(2, Math.round(v)));
|
||||||
|
}
|
||||||
|
if (v === "SplitFlap") {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (v === "Nixie") {
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
readonly property string apiUrl: "https://api.coingecko.com/api/v3/simple/price?ids=bitcoin&vs_currencies=eur"
|
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
|
// -1 = down, 0 = unchanged / no previous reading yet, 1 = up
|
||||||
@@ -72,7 +90,10 @@ Item {
|
|||||||
|
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
try {
|
try {
|
||||||
displayMode = Math.max(0, Math.min(2, plasmoid.configuration.displayMode));
|
// live binding: config changes from the dialog apply immediately
|
||||||
|
displayMode = Qt.binding(function () {
|
||||||
|
return modeFromConfig(plasmoid.configuration.displayMode);
|
||||||
|
});
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
// outside a real plasmoid shell (tests): keep the default
|
// outside a real plasmoid shell (tests): keep the default
|
||||||
}
|
}
|
||||||
@@ -119,6 +140,9 @@ Item {
|
|||||||
onLoaded: {
|
onLoaded: {
|
||||||
item.display = Qt.binding(function () { return root.displayText; });
|
item.display = Qt.binding(function () { return root.displayText; });
|
||||||
item.trendColor = Qt.binding(function () { return root.priceColor; });
|
item.trendColor = Qt.binding(function () { return root.priceColor; });
|
||||||
|
if (item.flapSeconds !== undefined) {
|
||||||
|
item.flapSeconds = Qt.binding(function () { return root.flapSeconds; });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -154,6 +178,9 @@ Item {
|
|||||||
onLoaded: {
|
onLoaded: {
|
||||||
item.display = Qt.binding(function () { return root.displayText; });
|
item.display = Qt.binding(function () { return root.displayText; });
|
||||||
item.trendColor = Qt.binding(function () { return root.priceColor; });
|
item.trendColor = Qt.binding(function () { return root.priceColor; });
|
||||||
|
if (item.flapSeconds !== undefined) {
|
||||||
|
item.flapSeconds = Qt.binding(function () { return root.flapSeconds; });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -10,7 +10,7 @@ X-KDE-ServiceTypes=Plasma/Applet
|
|||||||
X-KDE-PluginInfo-Author=Arnold Cordewiner
|
X-KDE-PluginInfo-Author=Arnold Cordewiner
|
||||||
X-KDE-PluginInfo-Email=hermes@a14r.be
|
X-KDE-PluginInfo-Email=hermes@a14r.be
|
||||||
X-KDE-PluginInfo-Name=nl.a14r.bitcoinprice
|
X-KDE-PluginInfo-Name=nl.a14r.bitcoinprice
|
||||||
X-KDE-PluginInfo-Version=1.2.0
|
X-KDE-PluginInfo-Version=1.3.0
|
||||||
X-KDE-PluginInfo-Website=https://gitea.a14r.be/hermes/plasma-bitcoin-price
|
X-KDE-PluginInfo-Website=https://gitea.a14r.be/hermes/plasma-bitcoin-price
|
||||||
X-KDE-PluginInfo-Category=Utilities
|
X-KDE-PluginInfo-Category=Utilities
|
||||||
X-KDE-PluginInfo-License=MIT
|
X-KDE-PluginInfo-License=MIT
|
||||||
|
|||||||
Reference in New Issue
Block a user