1
+ // Copyright (c) 2024 The Bitcoin Core developers
2
+ // Distributed under the MIT software license, see the accompanying
3
+ // file COPYING or http://www.opensource.org/licenses/mit-license.php.
4
+
5
+ import QtQuick 2.15
6
+ import QtQuick.Controls 2.15
7
+ import QtQuick.Layouts 1.15
8
+
9
+ import org.bitcoincore.qt 1.0
10
+
11
+ import "../../controls"
12
+
13
+ Button {
14
+ id: root
15
+
16
+ function formatSatoshis (satoshis ) {
17
+ var highlightColor = Theme .color .neutral9
18
+ var zeroColor = Theme .color .neutral7
19
+
20
+ if (root .checked || root .hovered ) {
21
+ highlightColor = zeroColor = Theme .color .orange
22
+ }
23
+
24
+ // Convert satoshis to bitcoins
25
+ var bitcoins = satoshis / 100000000 ;
26
+
27
+ // Format bitcoins to a fixed 8 decimal places string
28
+ var bitcoinStr = bitcoins .toFixed (8 );
29
+
30
+ // Split the bitcoin string into integer and fractional parts
31
+ var parts = bitcoinStr .split (' .' );
32
+
33
+ // Add spaces for every 3 digits in the integer part
34
+ parts[0 ] = parts[0 ].replace (/ \B (?=(\d {3} )+ (?!\d ))/ g , ' ' );
35
+
36
+ // Highlight the first significant digit and all following digits in the integer part
37
+ var significantFound = false ;
38
+ parts[0 ] = parts[0 ].replace (/ (\d )/ g , function (match ) {
39
+ if (! significantFound && match !== ' 0' ) {
40
+ significantFound = true ;
41
+ }
42
+ if (significantFound) {
43
+ return ' <font color="' + highlightColor + ' ">' + match + ' </font>' ;
44
+ }
45
+ return match;
46
+ });
47
+
48
+ // Add spaces for every 3 digits in the decimal part
49
+ parts[1 ] = parts[1 ].replace (/ \B (?=(\d {3} )+ (?!\d ))/ g , ' ' );
50
+ if (significantFound) {
51
+ parts[1 ] = ' <font color="' + highlightColor + ' ">' + parts[1 ] + ' </font>' ;
52
+ } else {
53
+ // Highlight the first significant digit and all following digits in the fractional part
54
+ significantFound = false ;
55
+ parts[1 ] = parts[1 ].replace (/ (\d )/ g , function (match ) {
56
+ if (! significantFound && match !== ' 0' ) {
57
+ significantFound = true ;
58
+ }
59
+ if (significantFound) {
60
+ return ' <font color="' + highlightColor + ' ">' + match + ' </font>' ;
61
+ }
62
+ return match;
63
+ });
64
+ }
65
+
66
+ // Concatenate the parts back together
67
+ var formattedBitcoins = parts .join (' .' );
68
+
69
+ // Format the text with the Bitcoin symbo
70
+ var formattedText = ` <font color="${ highlightColor} ">₿</font> ${ formattedBitcoins} ` ;
71
+
72
+ // Highlight zero in a different color if satoshis are zero
73
+ if (satoshis === 0 ) {
74
+ formattedText = ` <font color="${ zeroColor} ">₿ 0.00</font>` ;
75
+ }
76
+
77
+ return formattedText;
78
+ }
79
+
80
+ property color bgActiveColor: Theme .color .neutral2
81
+ property color textColor: Theme .color .neutral7
82
+ property color textHoverColor: Theme .color .orange
83
+ property color textActiveColor: Theme .color .orange
84
+ property color iconColor: " transparent"
85
+ property string iconSource: " "
86
+ property bool showBalance: true
87
+ property bool showIcon: true
88
+
89
+ checkable: true
90
+ hoverEnabled: AppMode .isDesktop
91
+ implicitHeight: 60
92
+ implicitWidth: 220
93
+ bottomPadding: 0
94
+ topPadding: 0
95
+ clip: true
96
+
97
+ contentItem: RowLayout {
98
+ anchors .fill : parent
99
+ anchors .leftMargin : 5
100
+ anchors .rightMargin : 5
101
+ clip: true
102
+ spacing: 5
103
+ Icon {
104
+ id: icon
105
+ visible: root .showIcon
106
+ source: " image://images/singlesig-wallet"
107
+ color: Theme .color .neutral8
108
+ Layout .preferredWidth : 30
109
+ Layout .preferredHeight : 30
110
+ }
111
+ ColumnLayout {
112
+ spacing: 2
113
+ CoreText {
114
+ horizontalAlignment: Text .AlignLeft
115
+ Layout .fillWidth : true
116
+ wrap: false
117
+ id: buttonText
118
+ font .pixelSize : 13
119
+ text: root .text
120
+ color: root .textColor
121
+ bold: true
122
+ visible: root .text !== " "
123
+ }
124
+ CoreText {
125
+ id: balanceText
126
+ visible: root .showBalance
127
+ text: formatSatoshis (12300 )
128
+ color: Theme .color .neutral7
129
+ }
130
+ }
131
+ }
132
+
133
+ background: Rectangle {
134
+ id: bg
135
+ height: root .height
136
+ width: root .width
137
+ radius: 5
138
+ color: Theme .color .neutral3
139
+ visible: root .hovered || root .checked
140
+
141
+ FocusBorder {
142
+ visible: root .visualFocus
143
+ }
144
+
145
+ Behavior on color {
146
+ ColorAnimation { duration: 150 }
147
+ }
148
+ }
149
+
150
+ states: [
151
+ State {
152
+ name: " CHECKED" ; when: root .checked
153
+ PropertyChanges { target: buttonText; color: root .textActiveColor }
154
+ PropertyChanges { target: icon; color: root .textActiveColor }
155
+ PropertyChanges { target: balanceText; color: root .textActiveColor }
156
+ },
157
+ State {
158
+ name: " HOVER" ; when: root .hovered
159
+ PropertyChanges { target: buttonText; color: root .textHoverColor }
160
+ PropertyChanges { target: icon; color: root .textHoverColor }
161
+ PropertyChanges { target: balanceText; color: root .textHoverColor }
162
+ }
163
+ ]
164
+ }
0 commit comments