diff --git a/src/Makefile.qt.include b/src/Makefile.qt.include index 96416c04c3..976de83273 100644 --- a/src/Makefile.qt.include +++ b/src/Makefile.qt.include @@ -409,7 +409,8 @@ QML_RES_QML = \ qml/pages/settings/SettingsProxy.qml \ qml/pages/settings/SettingsStorage.qml \ qml/pages/settings/SettingsTheme.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 diff --git a/src/qml/bitcoin_qml.qrc b/src/qml/bitcoin_qml.qrc index 3f89b0dbf7..210c01cfab 100644 --- a/src/qml/bitcoin_qml.qrc +++ b/src/qml/bitcoin_qml.qrc @@ -66,6 +66,7 @@ pages/settings/SettingsStorage.qml pages/settings/SettingsTheme.qml pages/wallet/DesktopWallets.qml + pages/wallet/WalletBadge.qml res/icons/arrow-down.png diff --git a/src/qml/pages/wallet/DesktopWallets.qml b/src/qml/pages/wallet/DesktopWallets.qml index 87b90e0166..50281453ce 100644 --- a/src/qml/pages/wallet/DesktopWallets.qml +++ b/src/qml/pages/wallet/DesktopWallets.qml @@ -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: " 0.00 167 599" - color: Theme.color.neutral7 - } - } + leftItem: WalletBadge { + implicitWidth: 164 + implicitHeight: 60 + text: qsTr("Singlesig Wallet") } centerItem: RowLayout { NavigationTab { diff --git a/src/qml/pages/wallet/WalletBadge.qml b/src/qml/pages/wallet/WalletBadge.qml new file mode 100644 index 0000000000..14f9392fb8 --- /dev/null +++ b/src/qml/pages/wallet/WalletBadge.qml @@ -0,0 +1,151 @@ +// 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) { + // 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 '' + match + ''; + } + 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] = '' + parts[1] + ''; + } 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 '' + match + ''; + } + return match; + }); + } + + // Concatenate the parts back together + var formattedBitcoins = parts.join('.'); + + // Format the text with the Bitcoin symbol + var formattedText = ` ${formattedBitcoins}`; + + // Highlight zero in a different color if satoshis are zero + if (satoshis === 0) { + formattedText = `₿ 0.00`; + } + + return formattedText; + } + + property color bgActiveColor: Theme.color.neutral2 + property color textColor: Theme.color.neutral7 + property color textHoverColor: Theme.color.neutral9 + 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 + + contentItem: RowLayout { + anchors.fill: parent + anchors.leftMargin: 10 + spacing: 5 + Icon { + id: icon + visible: root.showIcon + source: "image://images/singlesig-wallet" + color: Theme.color.neutral8 + Layout.preferredWidth: 30 + Layout.preferredHeight: 30 + } + Column { + Layout.fillWidth: true + spacing: 2 + CoreText { + 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 } + }, + State { + name: "HOVER"; when: root.hovered + PropertyChanges { target: buttonText; color: root.textHoverColor } + PropertyChanges { target: icon; color: root.textHoverColor } + PropertyChanges { target: balanceText; color: root.textHoverColor } + } + ] +} \ No newline at end of file