Skip to content

Commit

Permalink
qml: Introduce the WalletBadge component
Browse files Browse the repository at this point in the history
The WalletBadge is an Item that shows a wallet's name, type and
balance. The WalletBadge balance shows all of the decimal places
for a whole bitcoin and highlights the satoshis available. The
component can be configured to not show the Icon or the Balance.
  • Loading branch information
johnny9 committed Aug 8, 2024
1 parent a73577b commit 43d6901
Show file tree
Hide file tree
Showing 4 changed files with 171 additions and 22 deletions.
3 changes: 2 additions & 1 deletion src/Makefile.qt.include
Original file line number Diff line number Diff line change
Expand Up @@ -423,7 +423,8 @@ QML_RES_QML = \
qml/pages/wallet/CreateIntro.qml \
qml/pages/wallet/CreateName.qml \
qml/pages/wallet/CreatePassword.qml \
qml/pages/wallet/DesktopWallets.qml
qml/pages/wallet/DesktopWallets.qml \
qml/pages/wallet/WalletBadge.qml

if TARGET_ANDROID
BITCOIN_QT_H += qml/androidnotifier.h
Expand Down
1 change: 1 addition & 0 deletions src/qml/bitcoin_qml.qrc
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@
<file>pages/wallet/CreateName.qml</file>
<file>pages/wallet/CreatePassword.qml</file>
<file>pages/wallet/DesktopWallets.qml</file>
<file>pages/wallet/WalletBadge.qml</file>
</qresource>
<qresource prefix="/icons">
<file alias="add-wallet-dark">res/icons/add-wallet-dark.png</file>
Expand Down
25 changes: 4 additions & 21 deletions src/qml/pages/wallet/DesktopWallets.qml
Original file line number Diff line number Diff line change
Expand Up @@ -21,27 +21,10 @@ Page {

header: NavigationBar2 {
id: navBar
leftItem: RowLayout {
spacing: 5
Icon {
source: "image://images/singlesig-wallet"
color: Theme.color.neutral8
Layout.preferredWidth: 30
Layout.preferredHeight: 30
Layout.leftMargin: 10
}
Column {
spacing: 2
CoreText {
text: "Singlesig Wallet"
color: Theme.color.neutral7
bold: true
}
CoreText {
text: "<font color=\""+Theme.color.white+"\">₿</font> 0.00 <font color=\""+Theme.color.white+"\">167 599</font>"
color: Theme.color.neutral7
}
}
leftItem: WalletBadge {
implicitWidth: 154
implicitHeight: 46
text: qsTr("Singlesig Wallet")
}
centerItem: RowLayout {
NavigationTab {
Expand Down
164 changes: 164 additions & 0 deletions src/qml/pages/wallet/WalletBadge.qml
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
// Copyright (c) 2024 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

import QtQuick 2.15
import QtQuick.Controls 2.15
import QtQuick.Layouts 1.15

import org.bitcoincore.qt 1.0

import "../../controls"

Button {
id: root

function formatSatoshis(satoshis) {
var highlightColor = Theme.color.neutral9
var zeroColor = Theme.color.neutral7

if (root.checked || root.hovered) {
highlightColor = zeroColor = Theme.color.orange
}

// Convert satoshis to bitcoins
var bitcoins = satoshis / 100000000;

// Format bitcoins to a fixed 8 decimal places string
var bitcoinStr = bitcoins.toFixed(8);

// Split the bitcoin string into integer and fractional parts
var parts = bitcoinStr.split('.');

// Add spaces for every 3 digits in the integer part
parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ' ');

// Highlight the first significant digit and all following digits in the integer part
var significantFound = false;
parts[0] = parts[0].replace(/(\d)/g, function(match) {
if (!significantFound && match !== '0') {
significantFound = true;
}
if (significantFound) {
return '<font color="' + highlightColor + '">' + match + '</font>';
}
return match;
});

// Add spaces for every 3 digits in the decimal part
parts[1] = parts[1].replace(/\B(?=(\d{3})+(?!\d))/g, ' ');
if (significantFound) {
parts[1] = '<font color="' + highlightColor + '">' + parts[1] + '</font>';
} else {
// Highlight the first significant digit and all following digits in the fractional part
significantFound = false;
parts[1] = parts[1].replace(/(\d)/g, function(match) {
if (!significantFound && match !== '0') {
significantFound = true;
}
if (significantFound) {
return '<font color="' + highlightColor + '">' + match + '</font>';
}
return match;
});
}

// Concatenate the parts back together
var formattedBitcoins = parts.join('.');

// Format the text with the Bitcoin symbo
var formattedText = `<font color="${highlightColor}">₿</font> ${formattedBitcoins}`;

// Highlight zero in a different color if satoshis are zero
if (satoshis === 0) {
formattedText = `<font color="${zeroColor}">₿ 0.00</font>`;
}

return formattedText;
}

property color bgActiveColor: Theme.color.neutral2
property color textColor: Theme.color.neutral7
property color textHoverColor: Theme.color.orange
property color textActiveColor: Theme.color.orange
property color iconColor: "transparent"
property string iconSource: ""
property bool showBalance: true
property bool showIcon: true

checkable: true
hoverEnabled: AppMode.isDesktop
implicitHeight: 60
implicitWidth: 220
bottomPadding: 0
topPadding: 0
clip: true

contentItem: RowLayout {
anchors.fill: parent
anchors.leftMargin: 5
anchors.rightMargin: 5
clip: true
spacing: 5
Icon {
id: icon
visible: root.showIcon
source: "image://images/singlesig-wallet"
color: Theme.color.neutral8
Layout.preferredWidth: 30
Layout.preferredHeight: 30
}
ColumnLayout {
spacing: 2
CoreText {
horizontalAlignment: Text.AlignLeft
Layout.fillWidth: true
wrap: false
id: buttonText
font.pixelSize: 13
text: root.text
color: root.textColor
bold: true
visible: root.text !== ""
}
CoreText {
id: balanceText
visible: root.showBalance
text: formatSatoshis(12300)
color: Theme.color.neutral7
}
}
}

background: Rectangle {
id: bg
height: root.height
width: root.width
radius: 5
color: Theme.color.neutral3
visible: root.hovered || root.checked

FocusBorder {
visible: root.visualFocus
}

Behavior on color {
ColorAnimation { duration: 150 }
}
}

states: [
State {
name: "CHECKED"; when: root.checked
PropertyChanges { target: buttonText; color: root.textActiveColor }
PropertyChanges { target: icon; color: root.textActiveColor }
PropertyChanges { target: balanceText; color: root.textActiveColor }
},
State {
name: "HOVER"; when: root.hovered
PropertyChanges { target: buttonText; color: root.textHoverColor }
PropertyChanges { target: icon; color: root.textHoverColor }
PropertyChanges { target: balanceText; color: root.textHoverColor }
}
]
}

0 comments on commit 43d6901

Please sign in to comment.