10 Commits
Author SHA1 Message Date
ArnoldCordewiner 6e9b94217e v1.6.0: arrow at 90%, euro+arrow bottom-aligned with the price, bitcoin icon at 110% 2026-09-05 22:05:08 +02:00
ArnoldCordewiner e4e848540c v1.5.2: optically center trend arrow with euro sign (baseline-glyph compensation, measured in real renders) 2026-09-05 21:42:34 +02:00
ArnoldCordewiner b11fe06276 v1.5.1: double-size trend arrow, equal spacing around the euro sign on flip and nixie displays 2026-09-05 21:24:03 +02:00
ArnoldCordewiner 33dd983463 v1.5.0: bigger spaced euro sign, trend arrows on flip/nixie, two-phase flip cascade (reset to 0 over 2s then new values), fix nixie flicker endurance 2026-09-05 21:13:33 +02:00
ArnoldCordewiner b040eb8c47 v1.4.0: digit-only flaps with white euro text, nixie white euro + configurable flicker, mode-conditional config fields; fix stale derived-property reads in change handler 2026-09-05 20:51:05 +02:00
ArnoldCordewiner bb9bed4184 v1.3.0: live-bind display mode to config (dialog changes apply without restart); add configurable split-flap cascade seconds 2026-09-05 20:29:14 +02:00
ArnoldCordewiner 9774d8d191 docs: fix release link 2026-09-05 20:23:52 +02:00
ArnoldCordewiner 361a319d94 v1.2.0: add split-flap board and nixie tube display modes with display style config 2026-09-05 20:22:59 +02:00
ArnoldCordewiner 944b7587bc docs: correct repository layout (config dialog lives in contents/config/) 2026-09-05 20:14:49 +02:00
ArnoldCordewiner b0fbe8a14f v1.1.1: move config dialog to contents/config/config.qml (correct Plasma 5 location; ui/ placement made the General page invisible) 2026-09-05 20:13:46 +02:00
17 changed files with 624 additions and 40 deletions
+34 -13
View File
@@ -3,14 +3,28 @@
KDE Plasma 5 widget that shows the bitcoin price in EUR, fetched from the
[CoinGecko API](https://api.coingecko.com/api/v3/simple/price?ids=bitcoin&vs_currencies=eur).
## Display
## Display styles
| Situation | Display |
Three display styles, configurable in the settings dialog:
| Style | Description |
|---|---|
| Price up compared to the previous reading | green |
| Price down compared to the previous reading | red |
| Price unchanged (or first reading) | grey |
| API failure (network error, 4xx/5xx, rate limit 429) | `--` |
| *Plain text* | Trend-colored text (green/red/grey) |
| *Split-flap board* | Airport board: white digit flaps, white € sign and a trend arrow in the default font. On a price change all flaps first reset to 0 (swept over ~2 s), then take their new values — the whole cycle spreads over the configured cascade time |
| *Nixie tubes* | Retro amber glowing digits in glass tubes with configurable random flicker, white € sign and a trend arrow in the default font |
In the split-flap and nixie styles a trend arrow sits right of the € sign:
green ▲ when the price went up, red ▼ when it went down. When the price is
unchanged the last arrow stays; on the very first reading (and on API errors)
no arrow is shown. Display style changes apply immediately, without
restarting the shell.
| Situation | Plain text color | Arrow in flip/nixie modes |
|---|---|---|
| Price up | green | green ▲ |
| Price down | red | red ▼ |
| Price unchanged | grey | last arrow stays |
| First reading / API failure | grey / `--` | no arrow |
Format: `68,969 €` (thousands separators follow the system locale, rounded to
whole euros) preceded by the bundled Bitcoin icon in the compact and full
@@ -21,19 +35,25 @@ representations.
- **Refresh interval (minutes)** — default 5, minimum **5**, maximum 1440.
The 5-minute floor exists because the CoinGecko API allows one request per
5 minutes. A hint text in the config dialog explains this.
- **Split-flap cascade (seconds)** — default 3, range 115. Spreads the flip
animation of a price change evenly over this many seconds (applies to the
split-flap display style). Only shown when that style is selected.
- **Nixie flicker (0 = off)** — default 40, range 0100. Random cathode-dropout
flicker of the nixie tubes; 0 disables it, higher values flicker more often
and deeper. Only shown when the nixie style is selected.
Configurable via right-click on the widget → *Configure Bitcoin Price…**General*.
## Installation
### Graphical
Double-click `bitcoin-price-1.1.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
to the [v1.1.0 release](../../releases/tag/v1.1.0).
to the [v1.3.0 release](../../releases/tag/v1.2.0).
### Terminal
```bash
kpackagetool5 --type Plasma/Applet --upgrade bitcoin-price-1.1.0.plasmoid
kpackagetool5 --type Plasma/Applet --upgrade bitcoin-price-1.3.0.plasmoid
# Then restart the shell if needed:
plasmashell --replace &
```
@@ -74,12 +94,13 @@ or `fetch failed, HTTP status: <code>`.
```
metadata.desktop
contents/
├── config/main.xml # config schema (refreshMinutes, min 5, max 1440)
├── images/bitcoin.svg # bundled Bitcoin icon
├── config/
├── main.xml # config schema (refreshMinutes, min 5, max 1440)
│ └── config.qml # config dialog registry (ConfigModel/ConfigCategory)
├── images/bitcoin.svg # bundled Bitcoin icon
└── ui/
├── main.qml # widget + fetch/compare logic
── config.qml # config dialog (categories)
└── configGeneral.qml # interval setting
── configGeneral.qml # interval setting page
```
Repackage yourself:
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+21
View File
@@ -5,6 +5,27 @@
http://www.kde.org/standards/kcfg/1.0/kcfg.xsd">
<kcfgfile name=""/>
<group name="General">
<entry name="displayMode" type="Enum">
<label>Display style for the price</label>
<choices>
<choice name="PlainText"/>
<choice name="SplitFlap"/>
<choice name="Nixie"/>
</choices>
<default>0</default>
</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="nixieFlicker" type="Int">
<label>Nixie tube flicker intensity (0 = off, 100 = frequent and deep)</label>
<default>40</default>
<min>0</min>
<max>100</max>
</entry>
<entry name="refreshMinutes" type="Int">
<label>Refresh interval in minutes (minimum 5 because of the CoinGecko rate limit)</label>
<default>5</default>
+225
View File
@@ -0,0 +1,225 @@
/*
* Split-flap display mode — airport departure board style.
* Only digits are shown as flaps; the euro sign is rendered as plain
* text (default font, white) next to the board, followed by a trend
* arrow (green up / red down; unchanged keeps the last arrow).
* On a price change the board first resets every flap to "0" (swept
* over ~2 s), then takes the new values (swept over the remainder of
* the cascade setting).
* Pure QtQuick so it can be tested outside the plasmoid shell.
*/
import QtQuick 2.15
Row {
id: root
// wired by the parent loader
property string display: "--"
// 1 = up, -1 = down, 0 = unchanged -> keep showing the last arrow
property int trendDir: 0
property int lastDir: 0
onTrendDirChanged: {
if (trendDir !== 0) {
lastDir = trendDir;
}
}
// total seconds over which the reset-to-zero + new value cycle spreads
property int flapSeconds: 3
spacing: height * 0.06
function digitsOf(s) {
var out = "";
for (var i = 0; i < s.length; i++) {
var ch = s.charAt(i);
if ((ch >= "0" && ch <= "9") || ch === "-") {
out += ch;
}
}
return out;
}
// UI-only derived values (euro/arrow visibility); logic must not rely
// on these — QML gives no ordering guarantee between a change handler
// and the re-evaluation of dependent bindings.
readonly property string digitsOnly: digitsOf(display)
readonly property string boardText: digitsOnly.length > 0 ? digitsOnly : "--"
property var chars: []
property bool ready: false
readonly property real cellFont: height * 0.72
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: {
chars = boardText.split("");
ready = true;
}
onDisplayChanged: {
if (!ready) {
return;
}
// compute from display directly: derived bindings may still be
// stale at this point (QML makes no ordering guarantee)
var digits = digitsOf(display);
var nc = (digits.length > 0 ? digits : "--").split("");
var n = Math.max(chars.length, nc.length);
// Phase 1: every flap resets to "0", swept over ~2 s.
// Phase 2: every flap takes its new value, swept over the
// remainder of the total cascade time.
var total = Math.max(1, flapSeconds) * 1000;
var resetSpan = Math.min(2000, Math.floor(total * 2 / 3));
var valueStart = resetSpan;
var resetStep = n > 1 ? Math.floor(Math.max(0, resetSpan - flapDuration) / (n - 1)) : 0;
var valueStep = n > 1 ? Math.floor(Math.max(0, total - valueStart - flapDuration) / (n - 1)) : 0;
for (var i = 0; i < n; i++) {
var cell = rep.itemAt(i);
var to = i < nc.length ? nc[i] : "";
if (cell) {
cell.schedule(to, i * resetStep, valueStart + i * valueStep);
}
}
chars = nc;
}
Repeater {
id: rep
model: root.chars.length
delegate: Rectangle {
id: cell
width: root.cellWidth
height: root.height
radius: 2
color: "#0b0b0d"
border.color: "#26262b"
border.width: 1
// plain properties (not bindings) so the animations control
// when the character actually changes
property string ch: ""
property string targetCh: ""
property string animCh: ""
Component.onCompleted: {
ch = root.chars[index] !== undefined ? root.chars[index] : "";
}
// schedule the two-phase cycle: reset to "0", then target
function schedule(t, resetDelay, valueDelay) {
targetCh = t;
resetTimer.interval = Math.max(0, resetDelay);
resetTimer.restart();
valueTimer.interval = Math.max(0, valueDelay);
valueTimer.restart();
}
function startFlip(newCh) {
if (newCh === ch) {
return;
}
animCh = newCh;
flipAnim.restart();
}
Timer {
id: resetTimer
interval: 0
onTriggered: cell.startFlip("0")
}
Timer {
id: valueTimer
interval: 0
onTriggered: cell.startFlip(cell.targetCh)
}
transform: Scale {
id: scaleTransform
origin.y: cell.height / 2
yScale: 1
}
SequentialAnimation {
id: flipAnim
NumberAnimation {
target: scaleTransform
property: "yScale"
to: 0.06
duration: 130
easing.type: Easing.InQuad
}
ScriptAction {
script: cell.ch = cell.animCh
}
NumberAnimation {
target: scaleTransform
property: "yScale"
to: 1
duration: 130
easing.type: Easing.OutQuad
}
}
Text {
anchors.centerIn: parent
text: cell.ch
color: "#f2f2f2"
font.family: "DejaVu Sans Mono"
font.pixelSize: root.cellFont
}
// the flap split line across the middle
Rectangle {
anchors.horizontalCenter: parent.horizontalCenter
y: parent.height / 2 - 1
width: parent.width
height: 2
color: "#000000"
opacity: 0.55
}
}
}
// breathing room between the board and the currency sign
Item {
width: root.height * 0.22
height: 1
}
// euro sign in the plain-text font, white; bottom-aligned with the
// price digits (bottomMargin tuned so the glyph bottom matches)
Text {
anchors.bottom: parent.bottom
anchors.bottomMargin: root.height * 0.02
text: "\u20AC"
visible: root.digitsOnly.length > 0
color: "#ffffff"
font.family: Qt.application.font.family
font.pixelSize: root.height * 0.85
}
// same breathing room between the euro sign and the arrow
Item {
width: root.height * 0.22
height: 1
}
// trend arrow: green up / red down; unchanged keeps the last arrow.
// Bottom-aligned with the euro sign and the digits.
Text {
anchors.bottom: parent.bottom
anchors.bottomMargin: root.height * 0.16
text: root.lastDir > 0 ? "\u25B2" : "\u25BC"
visible: root.digitsOnly.length > 0 && root.lastDir !== 0
color: root.lastDir > 0 ? "#2ecc71" : "#e74c3c"
font.family: Qt.application.font.family
font.pixelSize: root.height * 0.9
}
}
+196
View File
@@ -0,0 +1,196 @@
/*
* Nixie tube display mode — retro amber glowing digits in glass tubes.
* Glow is faked with layered text copies, so no QtGraphicalEffects
* dependency. Tubes flicker randomly (nixie cathode style); the
* flicker intensity is configurable (0 = off, 100 = nervous).
* The euro sign is plain text (default font, white), followed by a
* trend arrow (green up / red down; unchanged keeps the last arrow).
* Pure QtQuick: testable outside the plasmoid shell.
*/
import QtQuick 2.15
Row {
id: root
// wired by the parent loader
property string display: "--"
// 1 = up, -1 = down, 0 = unchanged -> keep showing the last arrow
property int trendDir: 0
property int lastDir: 0
onTrendDirChanged: {
if (trendDir !== 0) {
lastDir = trendDir;
}
}
// 0 = no flicker, 100 = frequent and deep flicker
property int flickerIntensity: 40
spacing: height * 0.05
function digitsOf(s) {
var out = "";
for (var i = 0; i < s.length; i++) {
var ch = s.charAt(i);
if (ch >= "0" && ch <= "9") {
out += ch;
}
}
return out;
}
readonly property string digits: digitsOf(display)
readonly property real tubeWidth: height * 0.52
readonly property real glowFont: height * 0.80
readonly property bool flickerOn: flickerIntensity > 0 && digits.length > 0
Repeater {
model: root.digits.length
delegate: Rectangle {
id: tube
width: root.tubeWidth
height: root.height
radius: width * 0.30
gradient: Gradient {
GradientStop { position: 0.0; color: "#3a2410" }
GradientStop { position: 0.5; color: "#241505" }
GradientStop { position: 1.0; color: "#160c03" }
}
border.color: "#4a2e12"
border.width: 1
// glass reflection strip
Rectangle {
anchors.top: parent.top
anchors.topMargin: parent.height * 0.06
anchors.horizontalCenter: parent.horizontalCenter
width: parent.width * 0.5
height: parent.height * 0.16
radius: height / 2
color: "#ffffff"
opacity: 0.06
}
// digit + glow layers, flickered as one group
Item {
id: glowGroup
anchors.fill: parent
Text {
id: glowText
anchors.centerIn: parent
text: root.digits[index]
color: "#ffb648"
font.family: "DejaVu Serif"
font.pixelSize: root.glowFont
// layered glow: two scaled copies behind the crisp digit
Text {
anchors.centerIn: parent
text: parent.text
color: "#ff8c00"
opacity: 0.30
font: parent.font
scale: 1.24
}
Text {
anchors.centerIn: parent
text: parent.text
color: "#ff9d1e"
opacity: 0.50
font: parent.font
scale: 1.10
}
}
}
// nixie flicker: random dropout of the cathode glow.
// repeat: true keeps the cycle alive; each trigger reschedules
// the next interval (intensity 40 -> ~4 s between flicks,
// 100 -> ~1.5 s).
Timer {
id: flickTimer
repeat: true
running: root.flickerOn
interval: 1500
onTriggered: {
flick.restart();
scheduleNext();
}
function scheduleNext() {
var base = 6000 - root.flickerIntensity * 45;
interval = Math.max(700, base * (0.6 + Math.random() * 0.8));
}
Component.onCompleted: scheduleNext()
}
SequentialAnimation {
id: flick
ScriptAction {
script: {
var range = root.flickerIntensity / 100 * 0.75;
glowGroup.opacity = 1 - (0.15 + Math.random() * range);
}
}
PauseAnimation { duration: 40 + Math.random() * 140 }
NumberAnimation {
target: glowGroup
property: "opacity"
to: 1.0
duration: 90 + Math.random() * 160
easing.type: Easing.OutQuad
}
}
}
}
// breathing room between the tubes and the currency sign
Item {
width: root.height * 0.22
height: 1
}
// euro sign in the plain-text font, white; bottom-aligned with the
// price digits (bottomMargin tuned so the glyph bottom matches)
Text {
anchors.bottom: parent.bottom
anchors.bottomMargin: root.height * -0.015
text: "\u20AC"
visible: root.digits.length > 0
color: "#ffffff"
font.family: Qt.application.font.family
font.pixelSize: root.height * 0.85
}
// same breathing room between the euro sign and the arrow
Item {
width: root.height * 0.22
height: 1
}
// trend arrow: green up / red down; unchanged keeps the last arrow.
// Bottom-aligned with the euro sign and the digits.
Text {
anchors.bottom: parent.bottom
anchors.bottomMargin: root.height * 0.10
text: root.lastDir > 0 ? "\u25B2" : "\u25BC"
visible: root.digits.length > 0 && root.lastDir !== 0
color: root.lastDir > 0 ? "#2ecc71" : "#e74c3c"
font.family: Qt.application.font.family
font.pixelSize: root.height * 0.81
}
// error / empty state
Text {
anchors.verticalCenter: parent.verticalCenter
text: "--"
color: "#7a4e1c"
font.family: "DejaVu Serif"
font.pixelSize: root.glowFont * 0.8
visible: root.digits.length === 0
}
}
+27
View File
@@ -0,0 +1,27 @@
/*
* Plain text display mode — colored price text.
* Pure QtQuick on purpose: no Plasma imports, so it can be loaded
* and tested outside the plasmoid shell.
*/
import QtQuick 2.15
Text {
id: root
// wired by the parent loader: the formatted price string
property string display: "--"
// trend color (green/red/grey) from the widget root
property color trendColor: "#9e9e9e"
text: root.display
color: root.trendColor
textFormat: Text.PlainText
elide: Text.ElideRight
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
font.family: Qt.application.font.family
font.pixelSize: root.height > 0
? Math.round(root.height * 0.82)
: Qt.application.font.pixelSize
}
+30
View File
@@ -2,6 +2,7 @@
* Config page for nl.a14r.bitcoinprice.
* Follows the canonical Plasma 5 config dialog pattern:
* Kirigami.FormLayout + cfg_ prefixed property aliases.
* Mode-specific settings are only visible for the matching style.
*/
import QtQuick 2.15
@@ -12,12 +13,41 @@ Kirigami.FormLayout {
id: generalPage
// The cfg_ prefix is what Plasma uses to read/write plasmoid.configuration
property alias cfg_displayMode: modeCombo.currentIndex
property alias cfg_refreshMinutes: intervalSpin.value
property alias cfg_flapSeconds: flapSpin.value
property alias cfg_nixieFlicker: flickSpin.value
Item {
Kirigami.FormData.isSection: true
}
QQC2.ComboBox {
id: modeCombo
Kirigami.FormData.label: i18n("Display style:")
model: [i18n("Plain text"), i18n("Split-flap board"), i18n("Nixie tubes")]
}
QQC2.SpinBox {
id: flapSpin
visible: modeCombo.currentIndex === 1
Kirigami.FormData.label: i18n("Split-flap cascade (seconds):")
from: 1
to: 15
stepSize: 1
editable: true
}
QQC2.SpinBox {
id: flickSpin
visible: modeCombo.currentIndex === 2
Kirigami.FormData.label: i18n("Nixie flicker (0 = off):")
from: 0
to: 100
stepSize: 10
editable: true
}
QQC2.SpinBox {
id: intervalSpin
Kirigami.FormData.label: i18n("Refresh interval (minutes):")
+90 -26
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,33 @@ Item {
id: root
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)
// Nixie tube flicker intensity (0 = off, 100 = frequent and deep)
readonly property int nixieFlicker: Math.max(0, Math.min(100, plasmoid.configuration.nixieFlicker))
// 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"
// 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"
// -1 = down, 0 = unchanged / no previous reading yet, 1 = up
@@ -61,8 +92,16 @@ Item {
}
Component.onCompleted: {
console.log("[bitcoinprice] started, refresh interval:",
refreshMinutes, "minutes");
try {
// live binding: config changes from the dialog apply immediately
displayMode = Qt.binding(function () {
return modeFromConfig(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 +114,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 {
@@ -86,26 +127,34 @@ Item {
Image {
id: btcIcon
source: "../images/bitcoin.svg"
sourceSize.width: PlasmaCore.Units.iconSizes.smallMedium
sourceSize.height: PlasmaCore.Units.iconSizes.smallMedium
sourceSize.width: Math.round(PlasmaCore.Units.iconSizes.smallMedium * 1.1)
sourceSize.height: Math.round(PlasmaCore.Units.iconSizes.smallMedium * 1.1)
anchors.verticalCenter: parent.verticalCenter
fillMode: Image.PreserveAspectFit
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; });
if (item.trendColor !== undefined) {
item.trendColor = Qt.binding(function () { return root.priceColor; });
}
if (item.trendDir !== undefined) {
item.trendDir = Qt.binding(function () { return root.trend; });
}
if (item.flapSeconds !== undefined) {
item.flapSeconds = Qt.binding(function () { return root.flapSeconds; });
}
if (item.flickerIntensity !== undefined) {
item.flickerIntensity = Qt.binding(function () { return root.nixieFlicker; });
}
}
}
}
}
@@ -115,8 +164,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
@@ -125,18 +174,33 @@ Item {
Image {
anchors.horizontalCenter: parent.horizontalCenter
source: "../images/bitcoin.svg"
sourceSize.width: PlasmaCore.Units.iconSizes.large
sourceSize.height: PlasmaCore.Units.iconSizes.large
sourceSize.width: Math.round(PlasmaCore.Units.iconSizes.large * 1.1)
sourceSize.height: Math.round(PlasmaCore.Units.iconSizes.large * 1.1)
fillMode: Image.PreserveAspectFit
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; });
if (item.trendColor !== undefined) {
item.trendColor = Qt.binding(function () { return root.priceColor; });
}
if (item.trendDir !== undefined) {
item.trendDir = Qt.binding(function () { return root.trend; });
}
if (item.flapSeconds !== undefined) {
item.flapSeconds = Qt.binding(function () { return root.flapSeconds; });
}
if (item.flickerIntensity !== undefined) {
item.flickerIntensity = Qt.binding(function () { return root.nixieFlicker; });
}
}
}
Text {
+1 -1
View File
@@ -10,7 +10,7 @@ X-KDE-ServiceTypes=Plasma/Applet
X-KDE-PluginInfo-Author=Arnold Cordewiner
X-KDE-PluginInfo-Email=hermes@a14r.be
X-KDE-PluginInfo-Name=nl.a14r.bitcoinprice
X-KDE-PluginInfo-Version=1.1.0
X-KDE-PluginInfo-Version=1.6.0
X-KDE-PluginInfo-Website=https://gitea.a14r.be/hermes/plasma-bitcoin-price
X-KDE-PluginInfo-Category=Utilities
X-KDE-PluginInfo-License=MIT