Skip to content
Closed
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
5 changes: 4 additions & 1 deletion src/Makefile.qt.include
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ QT_FORMS_UI = \
qt/forms/transactiondescdialog.ui

QT_MOC_CPP = \
qml/moc_engine.cpp \
qml/moc_nodemodel.cpp \
qt/moc_addressbookpage.cpp \
qt/moc_addresstablemodel.cpp \
Expand Down Expand Up @@ -108,6 +109,7 @@ QT_QRC_LOCALE = qt/bitcoin_locale.qrc

BITCOIN_QT_H = \
qml/bitcoin.h \
qml/engine.h \
qml/imageprovider.h \
qml/nodemodel.h \
qml/util.h \
Expand Down Expand Up @@ -286,6 +288,7 @@ BITCOIN_QT_WALLET_CPP = \

BITCOIN_QML_BASE_CPP = \
qml/bitcoin.cpp \
qml/engine.cpp \
qml/imageprovider.cpp \
qml/nodemodel.cpp \
qml/util.cpp
Expand Down Expand Up @@ -444,7 +447,7 @@ ui_%.h: %.ui
$(AM_V_GEN) QT_SELECT=$(QT_SELECT) $(MOC) $(DEFAULT_INCLUDES) $(QT_INCLUDES_UNSUPPRESSED) $(MOC_DEFS) $< > $@

moc_%.cpp: %.h
$(AM_V_GEN) QT_SELECT=$(QT_SELECT) $(MOC) $(DEFAULT_INCLUDES) $(QT_INCLUDES_UNSUPPRESSED) $(MOC_DEFS) $< > $@
$(AM_V_GEN) QT_SELECT=$(QT_SELECT) $(MOC) $(DEFAULT_INCLUDES) $(QT_INCLUDES_UNSUPPRESSED) $(QT_QUICK_CFLAGS) $(MOC_DEFS) $< > $@

%.qm: %.ts
@test -f $(LRELEASE)
Expand Down
16 changes: 6 additions & 10 deletions src/qml/bitcoin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include <logging.h>
#include <node/ui_interface.h>
#include <noui.h>
#include <qml/engine.h>
#include <qml/imageprovider.h>
#include <qml/nodemodel.h>
#include <qml/util.h>
Expand All @@ -29,7 +30,6 @@

#include <QDebug>
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include <QQuickWindow>
#include <QString>
Expand Down Expand Up @@ -157,30 +157,26 @@ int QmlGuiMain(int argc, char* argv[])

handler_message_box.disconnect();

NodeModel node_model{*node};
InitExecutor init_executor{*node};
QObject::connect(&node_model, &NodeModel::requestedInitialize, &init_executor, &InitExecutor::initialize);
QObject::connect(&node_model, &NodeModel::requestedShutdown, &init_executor, &InitExecutor::shutdown);
QObject::connect(&init_executor, &InitExecutor::initializeResult, &node_model, &NodeModel::initializeResult);
QObject::connect(&init_executor, &InitExecutor::shutdownResult, qGuiApp, &QGuiApplication::quit, Qt::QueuedConnection);
// QObject::connect(&init_executor, &InitExecutor::runawayException, &node_model, &NodeModel::handleRunawayException);

qGuiApp->setQuitOnLastWindowClosed(false);
QObject::connect(qGuiApp, &QGuiApplication::lastWindowClosed, [&] {
node->startShutdown();
node_model.startNodeShutdown();
init_executor.shutdown();
});

GUIUtil::LoadFont(":/fonts/inter/regular");
GUIUtil::LoadFont(":/fonts/inter/semibold");

QQmlApplicationEngine engine;
qmlRegisterType<NodeModel>("BitcoinCore", 1, 0, "NodeModel");

Engine engine(*node);

QScopedPointer<const NetworkStyle> network_style{NetworkStyle::instantiate(Params().NetworkIDString())};
assert(!network_style.isNull());
engine.addImageProvider(QStringLiteral("images"), new ImageProvider{network_style.data()});

engine.rootContext()->setContextProperty("nodeModel", &node_model);
engine.rootContext()->setContextProperty("initExecutor", &init_executor);

engine.load(QUrl(QStringLiteral("qrc:///qml/pages/stub.qml")));
if (engine.rootObjects().isEmpty()) {
Expand Down
26 changes: 26 additions & 0 deletions src/qml/engine.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// Copyright (c) 2021 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/engine.h>

#include <interfaces/node.h>
#include <node/context.h>

#include <QQmlContext>

Engine::Engine(interfaces::Node& node)
: m_node(node)
{
}

Engine::~Engine()
{
}

interfaces::Node& Engine::node(QObject* object)
{
auto context = Assert(QQmlEngine::contextForObject(object));
auto engine = Assert(context->engine());
return Assert(qobject_cast<Engine*>(engine))->node();
}
30 changes: 30 additions & 0 deletions src/qml/engine.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// Copyright (c) 2021 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_ENGINE_H
#define BITCOIN_QML_ENGINE_H

#include <QQmlApplicationEngine>

namespace interfaces {
class Node;
}

class Engine : public QQmlApplicationEngine
{
Q_OBJECT

public:
explicit Engine(interfaces::Node& node);
~Engine();

interfaces::Node& node() const { return m_node; }

static interfaces::Node& node(QObject* object);

private:
interfaces::Node& m_node;
};

#endif // BITCOIN_QML_ENGINE_H
31 changes: 12 additions & 19 deletions src/qml/nodemodel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,15 @@
#include <qml/nodemodel.h>

#include <interfaces/node.h>
#include <qml/engine.h>
#include <qt/guiutil.h>
#include <validation.h>

#include <cassert>

NodeModel::NodeModel(interfaces::Node& node)
: m_node{node}
NodeModel::NodeModel(QObject* parent)
: QObject(parent)
{
ConnectToBlockTipSignal();
}

void NodeModel::setBlockTipHeight(int new_height)
Expand All @@ -23,27 +24,19 @@ void NodeModel::setBlockTipHeight(int new_height)
}
}

void NodeModel::startNodeInitializionThread()
void NodeModel::classBegin()
{
Q_EMIT requestedInitialize();
}

void NodeModel::startNodeShutdown()
{
Q_EMIT requestedShutdown();
}

void NodeModel::initializeResult([[maybe_unused]] bool success, interfaces::BlockAndHeaderTipInfo tip_info)
{
// TODO: Handle the `success` parameter,
setBlockTipHeight(tip_info.block_height);
}

void NodeModel::ConnectToBlockTipSignal()
void NodeModel::componentComplete()
{
auto& node = Engine::node(this);
setBlockTipHeight(node.getNumBlocks());
assert(!m_handler_notify_block_tip);
m_handler_notify_block_tip = m_node.handleNotifyBlockTip(
m_handler_notify_block_tip = node.handleNotifyBlockTip(
[this](SynchronizationState state, interfaces::BlockTip tip, double verification_progress) {
setBlockTipHeight(tip.block_height);
GUIUtil::ObjectInvoke(this, [=] {
setBlockTipHeight(tip.block_height);
});
});
}
20 changes: 7 additions & 13 deletions src/qml/nodemodel.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,47 +6,41 @@
#define BITCOIN_QML_NODEMODEL_H

#include <interfaces/handler.h>
#include <interfaces/node.h>

#include <memory>

#include <QObject>
#include <QQmlParserStatus>

namespace interfaces {
class Node;
}

/** Model for Bitcoin network client. */
class NodeModel : public QObject
class NodeModel : public QObject, public QQmlParserStatus
{
Q_OBJECT
Q_INTERFACES(QQmlParserStatus)
Q_PROPERTY(int blockTipHeight READ blockTipHeight NOTIFY blockTipHeightChanged)

public:
explicit NodeModel(interfaces::Node& node);
explicit NodeModel(QObject* parent = nullptr);

int blockTipHeight() const { return m_block_tip_height; }
void setBlockTipHeight(int new_height);

Q_INVOKABLE void startNodeInitializionThread();
void startNodeShutdown();

public Q_SLOTS:
void initializeResult(bool success, interfaces::BlockAndHeaderTipInfo tip_info);
// QQmlParserStatus
void classBegin() override;
void componentComplete() override;

Q_SIGNALS:
void blockTipHeightChanged();
void requestedInitialize();
void requestedShutdown();

private:
// Properties that are exposed to QML.
int m_block_tip_height{0};

interfaces::Node& m_node;
std::unique_ptr<interfaces::Handler> m_handler_notify_block_tip;

void ConnectToBlockTipSignal();
};

#endif // BITCOIN_QML_NODEMODEL_H
67 changes: 43 additions & 24 deletions src/qml/pages/stub.qml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

import BitcoinCore 1.0
import QtQuick 2.12
import QtQuick.Controls 2.12
import QtQuick.Layouts 1.11
Expand All @@ -16,33 +17,51 @@ ApplicationWindow {
color: "black"
visible: true

Component.onCompleted: nodeModel.startNodeInitializionThread();
Component.onCompleted: initExecutor.initialize()

ColumnLayout {
Connections {
target: initExecutor
onInitializeResult: nodeModel.initializeResult(success, tip_info)
}

BusyIndicator {
running: !initExecutor.ready
visible: running
anchors.centerIn: parent
spacing: 15
width: 400
Image {
Layout.alignment: Qt.AlignCenter
source: "image://images/app"
sourceSize.width: 64
sourceSize.height: 64
}
BlockCounter {
Layout.alignment: Qt.AlignCenter
blockHeight: nodeModel.blockTipHeight
}
ProgressIndicator {
id: indicator
Layout.fillWidth: true
progress: 0.666
background: MouseArea {
onClicked: indicator.progress = mouseX / width
}

Loader {
id: loader
active: initExecutor.ready
anchors.centerIn: parent
sourceComponent: ColumnLayout {
spacing: 15
width: 400
NodeModel {
id: nodeModel
}
Image {
Layout.alignment: Qt.AlignCenter
source: "image://images/app"
sourceSize.width: 64
sourceSize.height: 64
}
BlockCounter {
Layout.alignment: Qt.AlignCenter
blockHeight: nodeModel.blockTipHeight
}
ProgressIndicator {
id: indicator
Layout.fillWidth: true
progress: 0.666
background: MouseArea {
onClicked: indicator.progress = mouseX / width
}
}
ConnectionOptions {
Layout.preferredWidth: 400
focus: true
}
}
ConnectionOptions {
Layout.preferredWidth: 400
focus: true
}
}
}
5 changes: 5 additions & 0 deletions src/qt/initexecutor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,11 @@ InitExecutor::InitExecutor(interfaces::Node& node)
{
m_context.moveToThread(&m_thread);
m_thread.start();

connect(this, &InitExecutor::initializeResult, this, [=](bool success, interfaces::BlockAndHeaderTipInfo tip_info) {
m_ready = success;
Q_EMIT readyChanged();
});
}

InitExecutor::~InitExecutor()
Expand Down
5 changes: 5 additions & 0 deletions src/qt/initexecutor.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,19 @@ QT_END_NAMESPACE
class InitExecutor : public QObject
{
Q_OBJECT
Q_PROPERTY(bool ready READ ready NOTIFY readyChanged)
public:
explicit InitExecutor(interfaces::Node& node);
~InitExecutor();

bool ready() const { return m_ready; }

public Q_SLOTS:
void initialize();
void shutdown();

Q_SIGNALS:
void readyChanged();
void initializeResult(bool success, interfaces::BlockAndHeaderTipInfo tip_info);
void shutdownResult();
void runawayException(const QString& message);
Expand All @@ -42,6 +46,7 @@ public Q_SLOTS:
interfaces::Node& m_node;
QObject m_context;
QThread m_thread;
bool m_ready{false};
};

#endif // BITCOIN_QT_INITEXECUTOR_H