Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduce Wallet Select Dropdown #401

Merged
merged 2 commits into from
Aug 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion src/Makefile.qt.include
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ QT_MOC_CPP = \
qml/models/moc_nodemodel.cpp \
qml/models/moc_options_model.cpp \
qml/models/moc_peerlistsortproxy.cpp \
qml/models/moc_walletlistmodel.cpp \
qml/moc_appmode.cpp \
qml/moc_walletcontroller.cpp \
qt/moc_addressbookpage.cpp \
Expand Down Expand Up @@ -122,6 +123,7 @@ BITCOIN_QT_H = \
qml/models/nodemodel.h \
qml/models/options_model.h \
qml/models/peerlistsortproxy.h \
qml/models/walletlistmodel.h \
qml/appmode.h \
qml/bitcoin.h \
qml/guiconstants.h \
Expand Down Expand Up @@ -311,6 +313,7 @@ BITCOIN_QML_BASE_CPP = \
qml/models/nodemodel.cpp \
qml/models/options_model.cpp \
qml/models/peerlistsortproxy.cpp \
qml/models/walletlistmodel.cpp \
qml/imageprovider.cpp \
qml/util.cpp \
qml/walletcontroller.cpp
Expand Down Expand Up @@ -339,6 +342,7 @@ QML_RES_ICONS = \
qml/res/icons/info.png \
qml/res/icons/network-dark.png \
qml/res/icons/network-light.png \
qml/res/icons/plus.png \
qml/res/icons/shutdown.png \
qml/res/icons/singlesig-wallet.png \
qml/res/icons/storage-dark.png \
Expand Down Expand Up @@ -423,7 +427,9 @@ 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 \
qml/pages/wallet/WalletSelect.qml

if TARGET_ANDROID
BITCOIN_QT_H += qml/androidnotifier.h
Expand Down
4 changes: 4 additions & 0 deletions src/qml/bitcoin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include <qml/models/nodemodel.h>
#include <qml/models/options_model.h>
#include <qml/models/peerlistsortproxy.h>
#include <qml/models/walletlistmodel.h>
#include <qml/imageprovider.h>
#include <qml/util.h>
#include <qml/walletcontroller.h>
Expand Down Expand Up @@ -295,12 +296,15 @@ int QmlGuiMain(int argc, char* argv[])
assert(!network_style.isNull());
engine.addImageProvider(QStringLiteral("images"), new ImageProvider{network_style.data()});

WalletListModel wallet_list_model{*node, nullptr};

engine.rootContext()->setContextProperty("networkTrafficTower", &network_traffic_tower);
engine.rootContext()->setContextProperty("nodeModel", &node_model);
engine.rootContext()->setContextProperty("chainModel", &chain_model);
engine.rootContext()->setContextProperty("peerTableModel", &peer_model);
engine.rootContext()->setContextProperty("peerListModelProxy", &peer_model_sort_proxy);
engine.rootContext()->setContextProperty("walletController", &wallet_controller);
engine.rootContext()->setContextProperty("walletListModel", &wallet_list_model);

OptionsQmlModel options_model(*node, !need_onboarding.toBool());
engine.rootContext()->setContextProperty("optionsModel", &options_model);
Expand Down
3 changes: 3 additions & 0 deletions src/qml/bitcoin_qml.qrc
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,8 @@
<file>pages/wallet/CreateName.qml</file>
<file>pages/wallet/CreatePassword.qml</file>
<file>pages/wallet/DesktopWallets.qml</file>
<file>pages/wallet/WalletBadge.qml</file>
<file>pages/wallet/WalletSelect.qml</file>
</qresource>
<qresource prefix="/icons">
<file alias="add-wallet-dark">res/icons/add-wallet-dark.png</file>
Expand All @@ -95,6 +97,7 @@
<file alias="info">res/icons/info.png</file>
<file alias="network-dark">res/icons/network-dark.png</file>
<file alias="network-light">res/icons/network-light.png</file>
<file alias="plus">res/icons/plus.png</file>
<file alias="shutdown">res/icons/shutdown.png</file>
<file alias="singlesig-wallet">res/icons/singlesig-wallet.png</file>
<file alias="storage-dark">res/icons/storage-dark.png</file>
Expand Down
2 changes: 2 additions & 0 deletions src/qml/controls/Icon.qml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import QtQuick.Controls 2.15

Button {
id: root
width: icon.width
height: icon.height
required property color color
required property url source
property int size: 32
Expand Down
4 changes: 4 additions & 0 deletions src/qml/imageprovider.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -162,5 +162,9 @@ QPixmap ImageProvider::requestPixmap(const QString& id, QSize* size, const QSize
return QIcon(":/icons/hidden").pixmap(requested_size);
}

if (id == "plus") {
*size = requested_size;
return QIcon(":/icons/plus").pixmap(requested_size);
}
return {};
}
81 changes: 81 additions & 0 deletions src/qml/models/walletlistmodel.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
// 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.

#include <qml/models/walletlistmodel.h>
johnny9 marked this conversation as resolved.
Show resolved Hide resolved

#include <interfaces/node.h>

#include <QSet>

WalletListModel::WalletListModel(interfaces::Node& node, QObject *parent)
: QAbstractListModel(parent)
, m_node(node)
{
setSelectedWallet("Singlesig Wallet");
}

void WalletListModel::listWalletDir()
{
QSet<QString> existing_names;
for (int i = 0; i < rowCount(); ++i) {
QModelIndex index = this->index(i, 0);
QString name = data(index, NameRole).toString();
existing_names.insert(name);
}

for (const std::string &name : m_node.walletLoader().listWalletDir()) {
QString qname = QString::fromStdString(name);
if (!existing_names.contains(qname)) {
addItem({ qname });
}
}
}

void WalletListModel::setSelectedWallet(QString wallet_name)
{
if (m_selected_wallet != wallet_name) {
m_selected_wallet = wallet_name;
Q_EMIT selectedWalletChanged();
}
}

QString WalletListModel::selectedWallet() const
{
return m_selected_wallet;
}

int WalletListModel::rowCount(const QModelIndex &parent) const
{
Q_UNUSED(parent);
return m_items.size();
}

QVariant WalletListModel::data(const QModelIndex &index, int role) const
{
if (!index.isValid() || index.row() < 0 || index.row() >= m_items.size())
return QVariant();

const auto &item = m_items[index.row()];
switch (role) {
case Qt::DisplayRole:
case NameRole:
return item.name;
default:
return QVariant();
}
}

QHash<int, QByteArray> WalletListModel::roleNames() const
{
QHash<int, QByteArray> roles;
roles[NameRole] = "name";
return roles;
}

void WalletListModel::addItem(const Item &item)
{
beginInsertRows(QModelIndex(), rowCount(), rowCount());
m_items.append(item);
endInsertRows();
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does it need a blank line at the end?

55 changes: 55 additions & 0 deletions src/qml/models/walletlistmodel.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
// 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.

#ifndef BITCOIN_QML_MODELS_WALLETLISTMODEL_H
#define BITCOIN_QML_MODELS_WALLETLISTMODEL_H

#include <interfaces/wallet.h>
#include <QAbstractListModel>
#include <QList>

namespace interfaces {
class Node;
}

class WalletListModel : public QAbstractListModel
{
Q_OBJECT
Q_PROPERTY(QString selectedWallet READ selectedWallet WRITE setSelectedWallet NOTIFY selectedWalletChanged)

public:
WalletListModel(interfaces::Node& node, QObject *parent = nullptr);
~WalletListModel() = default;

enum Roles {
NameRole = Qt::UserRole + 1
};

int rowCount(const QModelIndex &parent = QModelIndex()) const override;
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
QHash<int, QByteArray> roleNames() const override;

void setSelectedWallet(QString wallet_name);
QString selectedWallet() const;

public Q_SLOTS:
void listWalletDir();

Q_SIGNALS:
void selectedWalletChanged();

private:
struct Item {
QString name;
};

void addItem(const Item &item);

QList<Item> m_items;
interfaces::Node& m_node;
QString m_selected_wallet;

};

#endif // BITCOIN_QML_MODELS_WALLETLISTMODEL_H
johnny9 marked this conversation as resolved.
Show resolved Hide resolved
37 changes: 18 additions & 19 deletions src/qml/pages/wallet/DesktopWallets.qml
Original file line number Diff line number Diff line change
Expand Up @@ -21,27 +21,26 @@ 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: walletListModel.selectedWallet

MouseArea {
anchors.fill: parent
onClicked: {
walletListModel.listWalletDir()
walletSelect.opened ? walletSelect.close() : walletSelect.open()
}
}

WalletSelect {
id: walletSelect
model: walletListModel
closePolicy: Popup.CloseOnPressOutside
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

close when press outside.
I guess it should also close when clicking on it again, additionally when clicking outside?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I want to add this as an issue. It turns out its more difficult than I thought to fix this.

x: 0
y: parent.height
}
}
centerItem: RowLayout {
NavigationTab {
Expand Down
Loading
Loading