Skip to content

Commit 720c814

Browse files
committed
qml: Introduce the BlockClock.qml and BlockClockComponent.qml files
- The BlockClock.qml files provides the control for BlockClock and determines how the elements would be displayed. - The BlockClockComponent.qml file uses the aforementioned control to display the value, and determines what will be displayed.
1 parent a9e210a commit 720c814

File tree

4 files changed

+245
-0
lines changed

4 files changed

+245
-0
lines changed

src/Makefile.qt.include

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -323,12 +323,14 @@ QML_QRC = qml/bitcoin_qml.qrc
323323
QML_RES_QML = \
324324
qml/components/AboutOptions.qml \
325325
qml/components/BlockCounter.qml \
326+
qml/components/BlockClockComponent.qml \
326327
qml/components/ConnectionOptions.qml \
327328
qml/components/ConnectionSettings.qml \
328329
qml/components/DeveloperOptions.qml \
329330
qml/components/StorageLocations.qml \
330331
qml/components/StorageOptions.qml \
331332
qml/components/StorageSettings.qml \
333+
qml/controls/BlockClock.qml \
332334
qml/controls/ContinueButton.qml \
333335
qml/controls/ExternalLink.qml \
334336
qml/controls/Header.qml \

src/qml/bitcoin_qml.qrc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
11
<!DOCTYPE RCC><RCC version="1.0">
22
<qresource prefix="/qml">
33
<file>components/AboutOptions.qml</file>
4+
<file>components/BlockClockComponent.qml</file>
45
<file>components/BlockCounter.qml</file>
56
<file>components/ConnectionOptions.qml</file>
67
<file>components/ConnectionSettings.qml</file>
78
<file>components/DeveloperOptions.qml</file>
89
<file>components/StorageLocations.qml</file>
910
<file>components/StorageOptions.qml</file>
1011
<file>components/StorageSettings.qml</file>
12+
<file>controls/BlockClock.qml</file>
1113
<file>controls/ContinueButton.qml</file>
1214
<file>controls/ExternalLink.qml</file>
1315
<file>controls/Header.qml</file>
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
import QtQuick 2.15
2+
import QtQuick.Controls 2.15
3+
import QtQuick.Layouts 1.15
4+
import "../controls"
5+
6+
BlockClock {
7+
id: blockClock
8+
anchors.centerIn: parent
9+
synced: nodeModel.verificationProgress > 0.999
10+
pause: nodeModel.pause
11+
// TODO: Modify following logic once nodeModel.numOutboundPeers property is incorporated.
12+
conns: true
13+
14+
states: [
15+
State {
16+
name: "intialBlockDownload"; when: !synced && !pause && conns
17+
PropertyChanges {
18+
target: blockClock
19+
20+
ringProgress: nodeModel.verificationProgress
21+
header: Math.round(ringProgress * 100) + "%"
22+
subText: Math.round(nodeModel.remainingSyncTime/60000) > 0 ? Math.round(nodeModel.remainingSyncTime/60000) + "mins" : Math.round(nodeModel.remainingSyncTime/1000) + "secs"
23+
}
24+
},
25+
26+
State {
27+
name: "blockClock"; when: synced && !pause && conns
28+
PropertyChanges {
29+
target: blockClock
30+
31+
ringProgress: blockList[0]
32+
header: Math.floor(nodeModel.blockTipHeight / 1000) + "," + nodeModel.blockTipHeight % 1000
33+
subText: "Blocktime"
34+
blockList: chainModel.timeRatioList
35+
}
36+
},
37+
38+
State {
39+
name: "Manual Pause"; when: pause
40+
PropertyChanges {
41+
target: blockClock
42+
43+
ringProgress: 0
44+
header: "Paused"
45+
headerSize: 24
46+
subText: "Tap to start"
47+
blockList: {}
48+
}
49+
},
50+
51+
State {
52+
name: "Connecting"; when: !pause && !conns
53+
PropertyChanges {
54+
target: blockClock
55+
56+
ringProgress: 0
57+
header: "Connecting"
58+
headerSize: 24
59+
subText: "Please Wait"
60+
blockList: {}
61+
}
62+
}
63+
]
64+
}

src/qml/controls/BlockClock.qml

Lines changed: 177 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,177 @@
1+
import QtQuick 2.15
2+
import QtQuick.Controls 2.15
3+
import QtQuick.Layouts 1.15
4+
import QtGraphicalEffects 1.0
5+
6+
import "../components"
7+
8+
Item {
9+
id: root
10+
11+
Layout.alignment: Qt.AlignCenter
12+
width: size
13+
height: size
14+
15+
property real ringProgress: 0
16+
property string header
17+
property string subText
18+
property bool synced
19+
property bool pause
20+
property bool conns
21+
22+
property int headerSize: 32
23+
24+
property int size: 200
25+
property real arcBegin: 0
26+
property real arcEnd: ringProgress * 360
27+
property real lineWidth: 4
28+
property string colorCircle: "#f1d54a"
29+
property string colorBackground: Theme.color.neutral2
30+
31+
property variant blockList: []
32+
property variant colorList: ["#EC5445", "#ED6E46", "#EE8847", "#EFA148", "#F0BB49", "#F1D54A"]
33+
34+
property alias beginAnimation: animationArcBegin.enabled
35+
property alias endAnimation: animationArcEnd.enabled
36+
37+
property int animationDuration: 250
38+
39+
onArcBeginChanged: canvas.requestPaint()
40+
onArcEndChanged: canvas.requestPaint()
41+
onSyncedChanged: canvas.requestPaint()
42+
onBlockListChanged: canvas.requestPaint()
43+
44+
Behavior on arcBegin {
45+
id: animationArcBegin
46+
enabled: true
47+
NumberAnimation {
48+
duration: root.animationDuration
49+
easing.type: Easing.InOutCubic
50+
}
51+
}
52+
53+
Behavior on arcEnd {
54+
id: animationArcEnd
55+
enabled: true
56+
NumberAnimation {
57+
easing.type: Easing.Bezier
58+
easing.bezierCurve: [0.5, 0.0, 0.2, 1, 1, 1]
59+
duration: root.animationDuration
60+
}
61+
}
62+
63+
Canvas {
64+
id: canvas
65+
anchors.fill: parent
66+
rotation: -90
67+
68+
onPaint: {
69+
var ctx = getContext("2d")
70+
var x = width / 2
71+
var y = height / 2
72+
73+
ctx.reset()
74+
75+
// Paint background
76+
ctx.beginPath();
77+
ctx.arc(x, y, (width / 2) - parent.lineWidth / 2, 0, Math.PI * 2, false)
78+
ctx.lineWidth = root.lineWidth
79+
ctx.strokeStyle = root.colorBackground
80+
ctx.stroke()
81+
82+
if (!synced) {
83+
var start = Math.PI * (parent.arcBegin / 180)
84+
var end = Math.PI * (parent.arcEnd / 180)
85+
// Paint foreground arc
86+
ctx.beginPath();
87+
ctx.arc(x, y, (width / 2) - parent.lineWidth / 2, start, end, false)
88+
ctx.lineWidth = root.lineWidth
89+
ctx.strokeStyle = root.colorCircle
90+
ctx.stroke()
91+
}
92+
93+
else {
94+
var del = 0.0025
95+
if (parent.blockList.length) {
96+
// Paint Block time points
97+
for (var i = 1; i < parent.blockList.length - 1; i++) {
98+
var starts = Math.PI * ((parent.blockList[i]) * 360 / 180)
99+
var ends = Math.PI * ((parent.blockList[i + 1]) * 360 / 180)
100+
var conf = blockList.length - i - 1
101+
ctx.beginPath();
102+
ctx.arc(x, y, (width / 2) - parent.lineWidth / 2, starts, ends, false)
103+
ctx.lineWidth = root.lineWidth
104+
ctx.strokeStyle = conf > 5 ? colorList[5] : colorList[conf]
105+
ctx.stroke()
106+
107+
// Paint dark segments
108+
var start = Math.PI * ((parent.blockList[i + 1] - del) * 360 / 180)
109+
ctx.beginPath();
110+
ctx.arc(x, y, (width / 2) - parent.lineWidth/2, start, ends, false)
111+
ctx.lineWidth = 4
112+
ctx.strokeStyle = root.colorBackground
113+
ctx.stroke();
114+
}
115+
116+
// Print last segment
117+
var starts = Math.PI * ((parent.blockList[parent.blockList.length - 1]) * 360 / 180)
118+
var ends = Math.PI * (ringProgress * 360 / 180)
119+
120+
ctx.beginPath();
121+
ctx.arc(x, y, (width / 2) - parent.lineWidth / 2, starts, ends, false)
122+
ctx.lineWidth = root.lineWidth
123+
ctx.strokeStyle = colorList[0];
124+
ctx.stroke()
125+
}
126+
}
127+
}
128+
}
129+
130+
ColumnLayout {
131+
anchors.centerIn: root
132+
Image {
133+
Layout.alignment: Qt.AlignCenter
134+
source: "image://images/bitcoin-circle"
135+
sourceSize.width: 40
136+
sourceSize.height: 40
137+
Layout.bottomMargin: 7
138+
ColorOverlay {
139+
anchors.fill: parent
140+
source: parent
141+
color: Theme.color.neutral9
142+
}
143+
}
144+
Header {
145+
Layout.fillWidth: true
146+
header: root.header
147+
headerSize: root.headerSize
148+
headerBold: true
149+
description: root.subText
150+
descriptionMargin: 2
151+
descriptionColor: Theme.color.neutral4
152+
descriptionBold: true
153+
Layout.bottomMargin: 14
154+
}
155+
// TODO: Replace following with PeersIndicator{} once it is incorporated.
156+
RowLayout {
157+
Layout.alignment: Qt.AlignCenter
158+
spacing: 5
159+
Repeater {
160+
model: 5
161+
Rectangle {
162+
width: 3
163+
height: width
164+
radius: width/2
165+
color: Theme.color.neutral9
166+
}
167+
}
168+
}
169+
}
170+
171+
MouseArea {
172+
anchors.fill: canvas
173+
onClicked: {
174+
nodeModel.pause = !pause
175+
}
176+
}
177+
}

0 commit comments

Comments
 (0)