diff --git a/programs/light_client/ClientDataModel.hpp b/programs/light_client/ClientDataModel.hpp index d3ae8d1d..d7533ba4 100644 --- a/programs/light_client/ClientDataModel.hpp +++ b/programs/light_client/ClientDataModel.hpp @@ -19,6 +19,7 @@ using boost::multi_index_container; using namespace boost::multi_index; using ObjectId = qint64; +Q_DECLARE_METATYPE(ObjectId) Q_DECLARE_METATYPE(std::function) diff --git a/programs/light_client/main.cpp b/programs/light_client/main.cpp index 2c733daa..a2c12ac4 100644 --- a/programs/light_client/main.cpp +++ b/programs/light_client/main.cpp @@ -13,6 +13,7 @@ int main(int argc, char *argv[]) app.setOrganizationName("Cryptonomex, Inc."); qRegisterMetaType>(); + qRegisterMetaType(); qmlRegisterType("Graphene.Client", 0, 1, "Asset"); qmlRegisterType("Graphene.Client", 0, 1, "Balance"); diff --git a/programs/light_client/qml/AccountPicker.qml b/programs/light_client/qml/AccountPicker.qml new file mode 100644 index 00000000..b148f64f --- /dev/null +++ b/programs/light_client/qml/AccountPicker.qml @@ -0,0 +1,54 @@ +import QtQuick 2.5 +import QtQuick.Controls 1.4 +import QtQuick.Dialogs 1.2 +import QtQuick.Layouts 1.2 + +import Graphene.Client 0.1 + +import "." + +RowLayout { + property Account account + + property alias placeholderText: accountNameField.placeholderText + + function setFocus() { + accountNameField.forceActiveFocus() + } + + Identicon { + name: accountNameField.text + width: Scaling.cm(2) + height: Scaling.cm(2) + } + Column { + Layout.fillWidth: true + TextField { + id: accountNameField + + width: parent.width + onEditingFinished: accountDetails.update(text) + } + Label { + id: accountDetails + function update(name) { + if (!name) + { + text = "" + return + } + + account = app.model.getAccount(name) + if (account == null) + text = qsTr("Error fetching account.") + else + text = Qt.binding(function() { + if (account == null) + return qsTr("Account does not exist.") + return qsTr("Account ID: %1").arg(account.id < 0? qsTr("Loading...") + : account.id) + }) + } + } + } +} diff --git a/programs/light_client/qml/FormBox.qml b/programs/light_client/qml/FormBox.qml index 1df969ef..799069cf 100644 --- a/programs/light_client/qml/FormBox.qml +++ b/programs/light_client/qml/FormBox.qml @@ -22,8 +22,14 @@ Rectangle { function showForm(formType, params, closedCallback) { if (formType.status === Component.Error) console.log(formType.errorString()) + if (!params instanceof Object) + params = {app: app} + else + params.app = app - formContainer.data = [formType.createObject(formContainer, params)] + var form = formType.createObject(formContainer, params) + formContainer.data = [form] + form.finished.connect(function(){state = "HIDDEN"}) if (closedCallback instanceof Function) internal.callback = closedCallback state = "SHOWN" diff --git a/programs/light_client/qml/Identicon.qml b/programs/light_client/qml/Identicon.qml new file mode 100644 index 00000000..fb674e55 --- /dev/null +++ b/programs/light_client/qml/Identicon.qml @@ -0,0 +1,39 @@ +import QtQuick 2.5 + +import "jdenticon/jdenticon-1.0.1.min.js" as Jdenticon + +Canvas { + id: identicon + contextType: "2d" + + property var name + onNameChanged: requestPaint() + + onPaint: { + if (name) + Jdenticon.draw(identicon, name) + else { + var context = identicon.context + context.reset() + var draw_circle = function(context, x, y, radius) { + context.beginPath() + context.arc(x, y, radius, 0, 2 * Math.PI, false) + context.fillStyle = "rgba(0, 0, 0, 0.1)" + context.fill() + } + var size = Math.min(identicon.height, identicon.width) + var centerX = size / 2 + var centerY = size / 2 + var radius = size/15 + draw_circle(context, centerX, centerY, radius) + draw_circle(context, 2*radius, 2*radius, radius) + draw_circle(context, centerX, 2*radius, radius) + draw_circle(context, size - 2*radius, 2*radius, radius) + draw_circle(context, size - 2*radius, centerY, radius) + draw_circle(context, size - 2*radius, size - 2*radius, radius) + draw_circle(context, centerX, size - 2*radius, radius) + draw_circle(context, 2*radius, size - 2*radius, radius) + draw_circle(context, 2*radius, centerY, radius) + } + } +} diff --git a/programs/light_client/qml/TransferForm.qml b/programs/light_client/qml/TransferForm.qml index deab6255..8ff7beac 100644 --- a/programs/light_client/qml/TransferForm.qml +++ b/programs/light_client/qml/TransferForm.qml @@ -3,57 +3,61 @@ import QtQuick.Controls 1.4 import QtQuick.Dialogs 1.2 import QtQuick.Layouts 1.2 +import Graphene.Client 0.1 + import "." -import "jdenticon/jdenticon-1.0.1.min.js" as Jdenticon Rectangle { anchors.fill: parent + property alias senderAccount: senderPicker.account + property alias receiverAccount: recipientPicker.account + + property GrapheneApplication app + signal finished + Component.onCompleted: console.log("Made a transfer form") Component.onDestruction: console.log("Destroyed a transfer form") - Column { + ColumnLayout { anchors.centerIn: parent + width: parent.width - Scaling.cm(2) + spacing: Scaling.cm(1) + AccountPicker { + id: senderPicker + width: parent.width + Component.onCompleted: setFocus() + placeholderText: qsTr("Sender") + } + AccountPicker { + id: recipientPicker + width: parent.width + placeholderText: qsTr("Recipient") + layoutDirection: Qt.RightToLeft + } RowLayout { - Canvas { - id: identicon - width: Scaling.cm(2) - height: Scaling.cm(2) - contextType: "2d" - - onPaint: { - if (nameField.text) - Jdenticon.draw(identicon, nameField.text) - else { - var context = identicon.context - context.reset() - var draw_circle = function(context, x, y, radius) { - context.beginPath() - context.arc(x, y, radius, 0, 2 * Math.PI, false) - context.fillStyle = "rgba(0, 0, 0, 0.1)" - context.fill() - } - var size = Math.min(identicon.height, identicon.width) - var centerX = size / 2 - var centerY = size / 2 - var radius = size/15 - draw_circle(context, centerX, centerY, radius) - draw_circle(context, 2*radius, 2*radius, radius) - draw_circle(context, centerX, 2*radius, radius) - draw_circle(context, size - 2*radius, 2*radius, radius) - draw_circle(context, size - 2*radius, centerY, radius) - draw_circle(context, size - 2*radius, size - 2*radius, radius) - draw_circle(context, centerX, size - 2*radius, radius) - draw_circle(context, 2*radius, size - 2*radius, radius) - draw_circle(context, 2*radius, centerY, radius) - } - } + width: parent.width + SpinBox { + Layout.preferredWidth: Scaling.cm(4) + Layout.minimumWidth: Scaling.cm(1.5) + enabled: senderPicker.account + minimumValue: 0 + maximumValue: Number.POSITIVE_INFINITY } - TextField { - id: nameField - Layout.fillWidth: true - onTextChanged: identicon.requestPaint() + ComboBox { + Layout.minimumWidth: Scaling.cm(3) + enabled: senderPicker.account + model: ["CORE", "USD", "GOLD"] + } + Item { Layout.fillWidth: true } + Button { + text: qsTr("Cancel") + onClicked: finished() + } + Button { + text: qsTr("Transfer") + enabled: senderPicker.account } } } diff --git a/programs/light_client/qml/main.qml b/programs/light_client/qml/main.qml index 5ddf1bd0..9e6e1f96 100644 --- a/programs/light_client/qml/main.qml +++ b/programs/light_client/qml/main.qml @@ -76,9 +76,9 @@ ApplicationWindow { else { console.log("Waiting for result...") - acct.idChanged.connect(function(loadedAcct) { + acct.idChanged.connect(function() { console.log( "ID CHANGED" ); - console.log(JSON.stringify(loadedAcct)) + console.log(JSON.stringify(acct)) }) } } diff --git a/programs/light_client/qml/qml.qrc b/programs/light_client/qml/qml.qrc index c038aad0..ed16a610 100644 --- a/programs/light_client/qml/qml.qrc +++ b/programs/light_client/qml/qml.qrc @@ -3,8 +3,10 @@ main.qml TransferForm.qml FormBox.qml - jdenticon/jdenticon-1.0.1.min.js Scaling.qml + Identicon.qml + AccountPicker.qml + jdenticon/jdenticon-1.0.1.min.js