Skip to content

Commit c059cf3

Browse files
committed
qml: Add sorting bar to Peers page
1 parent 37c4d37 commit c059cf3

File tree

6 files changed

+234
-24
lines changed

6 files changed

+234
-24
lines changed

src/Makefile.qt.include

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -358,6 +358,7 @@ QML_RES_QML = \
358358
qml/controls/Setting.qml \
359359
qml/controls/TextButton.qml \
360360
qml/controls/Theme.qml \
361+
qml/controls/ToggleButton.qml \
361362
qml/controls/ValueInput.qml \
362363
qml/pages/initerrormessage.qml \
363364
qml/pages/main.qml \

src/qml/bitcoin_qml.qrc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
<file>controls/Setting.qml</file>
2929
<file>controls/TextButton.qml</file>
3030
<file>controls/Theme.qml</file>
31+
<file>controls/ToggleButton.qml</file>
3132
<file>controls/ValueInput.qml</file>
3233
<file>pages/initerrormessage.qml</file>
3334
<file>pages/main.qml</file>

src/qml/controls/ToggleButton.qml

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
// Copyright (c) 2023 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+
8+
Button {
9+
property color defaultColor: Theme.color.neutral2
10+
property color hoverColor: Theme.color.neutral2
11+
property color activeColor: Theme.color.neutral5
12+
property color textColor: Theme.color.neutral7
13+
property color textHoverColor: Theme.color.orangeLight1
14+
property color textActiveColor: Theme.color.neutral9
15+
id: root
16+
checkable: true
17+
hoverEnabled: true
18+
font.family: "Inter"
19+
font.styleName: "Regular"
20+
font.pixelSize: 13
21+
leftPadding: 12
22+
rightPadding: 12
23+
topPadding: 5
24+
bottomPadding: 5
25+
26+
contentItem: Text {
27+
id: buttonText
28+
text: parent.text
29+
font: parent.font
30+
color: Theme.color.white
31+
horizontalAlignment: Text.AlignHCenter
32+
verticalAlignment: Text.AlignVCenter
33+
34+
Behavior on color {
35+
ColorAnimation { duration: 150 }
36+
}
37+
}
38+
background: Rectangle {
39+
id: bg
40+
color: root.defaultColor
41+
radius: 5
42+
43+
Behavior on color {
44+
ColorAnimation { duration: 150 }
45+
}
46+
}
47+
48+
state:"DEFAULT"
49+
50+
states: [
51+
State {
52+
name: "DEFAULT"
53+
PropertyChanges { target: bg; color: root.defaultColor }
54+
},
55+
State {
56+
name: "CHECKED"
57+
when: root.checked
58+
PropertyChanges { target: bg; color: root.activeColor }
59+
PropertyChanges { target: buttonText; color: root.textActiveColor }
60+
},
61+
State {
62+
name: "HOVER"
63+
when: root.hovered
64+
PropertyChanges { target: bg; color: root.hoverColor }
65+
PropertyChanges { target: buttonText; color: root.textHoverColor }
66+
}
67+
]
68+
}

src/qml/pages/node/Peers.qml

Lines changed: 127 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ Page {
2020
anchors.top: parent.top
2121
anchors.horizontalCenter: parent.horizontalCenter
2222
id: description
23-
height: 75
2423
width: Math.min(parent.width - 40, 450)
2524
wrapMode: Text.WordWrap
2625
text: qsTr("Peers are nodes you are connected to. You want to ensure that you are connected to x, y and z, but not a, b, and c. Learn more.")
@@ -31,36 +30,89 @@ Page {
3130
horizontalAlignment: Text.AlignHCenter
3231
}
3332

33+
RowLayout {
34+
id: sortSelection
35+
anchors.top: description.bottom
36+
anchors.topMargin: 20
37+
anchors.horizontalCenter: parent.horizontalCenter
38+
spacing: 10
39+
ToggleButton {
40+
text: qsTr("ID")
41+
autoExclusive: true
42+
checked: true
43+
onClicked: {
44+
peerListModelProxy.sortBy = "nodeId"
45+
}
46+
}
47+
ToggleButton {
48+
text: qsTr("Direction")
49+
autoExclusive: true
50+
onClicked: {
51+
peerListModelProxy.sortBy = "direction"
52+
}
53+
}
54+
ToggleButton {
55+
text: qsTr("User Agent")
56+
autoExclusive: true
57+
onClicked: {
58+
peerListModelProxy.sortBy = "subversion"
59+
}
60+
}
61+
ToggleButton {
62+
text: qsTr("Type")
63+
autoExclusive: true
64+
onClicked: {
65+
peerListModelProxy.sortBy = "connectionType"
66+
}
67+
}
68+
ToggleButton {
69+
text: qsTr("Ip")
70+
autoExclusive: true
71+
onClicked: {
72+
peerListModelProxy.sortBy = "address"
73+
}
74+
}
75+
ToggleButton {
76+
text: qsTr("Network")
77+
autoExclusive: true
78+
onClicked: {
79+
peerListModelProxy.sortBy = "network"
80+
}
81+
}
82+
}
83+
3484
ListView {
3585
id: listView
3686
clip: true
3787
width: Math.min(parent.width - 40, 450)
38-
anchors.top: description.bottom
88+
anchors.top: sortSelection.bottom
89+
anchors.topMargin: 30
3990
anchors.bottom: parent.bottom
4091
anchors.horizontalCenter: parent.horizontalCenter
4192
model: peerListModelProxy
4293
spacing: 15
4394

4495
footer: Loader {
45-
anchors.centerIn: parent
4696
height: 75
4797
active: nodeModel.numOutboundPeers < nodeModel.maxNumOutboundPeers
98+
width: listView.width
4899
visible: active
49-
sourceComponent: RowLayout {
50-
spacing: 20
51-
PeersIndicator {
52-
Layout.alignment: Qt.AlignHCenter
53-
numOutboundPeers: nodeModel.numOutboundPeers
54-
maxNumOutboundPeers: nodeModel.maxNumOutboundPeers
55-
}
56-
Text {
57-
Layout.alignment: Qt.AlignHCenter
58-
text: qsTr("Looking for %1 more peer(s)").arg(
59-
nodeModel.maxNumOutboundPeers - nodeModel.numOutboundPeers)
60-
font.family: "Inter"
61-
font.styleName: "Regular"
62-
font.pixelSize: 15
63-
color: Theme.color.neutral7
100+
sourceComponent: Item {
101+
RowLayout {
102+
anchors.centerIn: parent
103+
spacing: 20
104+
PeersIndicator {
105+
numOutboundPeers: nodeModel.numOutboundPeers
106+
maxNumOutboundPeers: nodeModel.maxNumOutboundPeers
107+
}
108+
Text {
109+
text: qsTr("Looking for %1 more peer(s)").arg(
110+
nodeModel.maxNumOutboundPeers - nodeModel.numOutboundPeers)
111+
font.family: "Inter"
112+
font.styleName: "Regular"
113+
font.pixelSize: 15
114+
color: Theme.color.neutral7
115+
}
64116
}
65117
}
66118
}
@@ -70,15 +122,69 @@ Page {
70122
required property string address;
71123
required property string subversion;
72124
required property string direction;
73-
implicitHeight: 65
125+
required property string connectionType;
126+
required property string network;
127+
implicitHeight: 60
74128
implicitWidth: listView.width
75129

130+
Connections {
131+
target: peerListModelProxy
132+
function onSortByChanged(roleName) {
133+
setTextByRole(roleName)
134+
}
135+
function onDataChanged(startIndex, endIndex) {
136+
setTextByRole(peerListModelProxy.sortBy)
137+
}
138+
}
139+
140+
Component.onCompleted: {
141+
setTextByRole(peerListModelProxy.sortBy)
142+
}
143+
144+
function setTextByRole(roleName) {
145+
if (roleName == "nodeId") {
146+
primary.text = "#" + nodeId
147+
secondary.text = direction
148+
tertiary.text = address
149+
quaternary.text = subversion
150+
} else if (roleName == "direction") {
151+
primary.text = direction
152+
secondary.text = "#" + nodeId
153+
tertiary.text = address
154+
quaternary.text = subversion
155+
} else if (roleName == "subversion") {
156+
primary.text = subversion
157+
secondary.text = "#" + nodeId
158+
tertiary.text = address
159+
quaternary.text = direction
160+
} else if (roleName == "address") {
161+
primary.text = address
162+
secondary.text = direction
163+
tertiary.text = "#" + nodeId
164+
quaternary.text = subversion
165+
} else if (roleName == "connectionType") {
166+
primary.text = connectionType
167+
secondary.text = direction
168+
tertiary.text = address
169+
quaternary.text = subversion
170+
} else if (roleName == "network") {
171+
primary.text = network
172+
secondary.text = direction
173+
tertiary.text = address
174+
quaternary.text = subversion
175+
} else {
176+
primary.text = "#" + nodeId
177+
secondary.text = direction
178+
tertiary.text = address
179+
quaternary.text = subversion
180+
}
181+
}
182+
76183
ColumnLayout {
77184
anchors.left: parent.left
78185
Label {
79186
Layout.alignment: Qt.AlignLeft
80187
id: primary
81-
text: "#" + nodeId
82188
font.family: "Inter"
83189
font.styleName: "Regular"
84190
font.pixelSize: 18
@@ -87,7 +193,6 @@ Page {
87193
Label {
88194
Layout.alignment: Qt.AlignLeft
89195
id: tertiary
90-
text: address
91196
font.family: "Inter"
92197
font.styleName: "Regular"
93198
font.pixelSize: 15
@@ -98,8 +203,7 @@ Page {
98203
anchors.right: parent.right
99204
Label {
100205
Layout.alignment: Qt.AlignRight
101-
id:secondary
102-
text: direction
206+
id: secondary
103207
font.family: "Inter"
104208
font.styleName: "Regular"
105209
font.pixelSize: 18
@@ -108,7 +212,6 @@ Page {
108212
Label {
109213
Layout.alignment: Qt.AlignRight
110214
id: quaternary
111-
text: subversion
112215
font.family: "Inter"
113216
font.styleName: "Regular"
114217
font.pixelSize: 15

src/qml/peerlistsortproxy.cpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,17 @@ QHash<int, QByteArray> PeerListSortProxy::roleNames() const
2626
return roles;
2727
}
2828

29+
int PeerListSortProxy::RoleNameToIndex(const QString & name) const
30+
{
31+
auto role_names = roleNames();
32+
auto keys = role_names.keys(name.toUtf8());
33+
if (!keys.empty()) {
34+
return keys.first();
35+
} else {
36+
return PeerTableModel::NetNodeId;
37+
}
38+
}
39+
2940
QVariant PeerListSortProxy::data(const QModelIndex& index, int role) const
3041
{
3142
if (role == PeerTableModel::StatsRole) {
@@ -35,3 +46,17 @@ QVariant PeerListSortProxy::data(const QModelIndex& index, int role) const
3546
QModelIndex converted_index = PeerTableSortProxy::index(index.row(), role);
3647
return PeerTableSortProxy::data(converted_index, Qt::DisplayRole);
3748
}
49+
50+
QString PeerListSortProxy::sortBy() const
51+
{
52+
return m_sort_by;
53+
}
54+
55+
void PeerListSortProxy::setSortBy(const QString & roleName)
56+
{
57+
if (m_sort_by != roleName) {
58+
m_sort_by = roleName;
59+
sort(RoleNameToIndex(roleName));
60+
Q_EMIT sortByChanged(roleName);
61+
}
62+
}

src/qml/peerlistsortproxy.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,25 @@
1414
class PeerListSortProxy : public PeerTableSortProxy
1515
{
1616
Q_OBJECT
17+
Q_PROPERTY(QString sortBy READ sortBy WRITE setSortBy NOTIFY sortByChanged)
1718

1819
public:
1920
explicit PeerListSortProxy(QObject* parent);
2021
~PeerListSortProxy() = default;
2122

2223
QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override;
2324
QHash<int, QByteArray> roleNames() const override;
25+
QString sortBy() const;
26+
27+
public Q_SLOTS:
28+
void setSortBy(const QString & roleName);
29+
30+
Q_SIGNALS:
31+
void sortByChanged(const QString & roleName);
32+
33+
private:
34+
int RoleNameToIndex(const QString & name) const;
35+
QString m_sort_by;
2436
};
2537

2638
#endif // BITCOIN_QML_PEERLISTSORTPROXY_H

0 commit comments

Comments
 (0)