[GUI] Lay out more transaction infrastructure
A little more backend development, and create some GUI framework for a confirmation dialog
This commit is contained in:
parent
972c9a6407
commit
f25a1ea360
8 changed files with 100 additions and 25 deletions
|
|
@ -43,6 +43,7 @@ OperationBase* Transaction::operationAt(int index) const {
|
||||||
|
|
||||||
void Transaction::appendOperation(OperationBase* op)
|
void Transaction::appendOperation(OperationBase* op)
|
||||||
{
|
{
|
||||||
|
op->setParent(this);
|
||||||
m_transaction.operations.push_back(op->genericOperation());
|
m_transaction.operations.push_back(op->genericOperation());
|
||||||
Q_EMIT operationsChanged();
|
Q_EMIT operationsChanged();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,14 +18,9 @@ public:
|
||||||
QQmlListProperty<OperationBase> operations();
|
QQmlListProperty<OperationBase> operations();
|
||||||
|
|
||||||
OperationBase* operationAt(int index) const;
|
OperationBase* operationAt(int index) const;
|
||||||
void appendOperation(OperationBase* op);
|
|
||||||
int operationCount() const {
|
int operationCount() const {
|
||||||
return m_transaction.operations.size();
|
return m_transaction.operations.size();
|
||||||
}
|
}
|
||||||
void clearOperations() {
|
|
||||||
m_transaction.operations.clear();
|
|
||||||
Q_EMIT operationsChanged();
|
|
||||||
}
|
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void setStatus(Status status)
|
void setStatus(Status status)
|
||||||
|
|
@ -37,6 +32,16 @@ public slots:
|
||||||
emit statusChanged(status);
|
emit statusChanged(status);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Append the operation to the transaction
|
||||||
|
* @param op The operation to append. This Transaction will take ownership of the operation.
|
||||||
|
*/
|
||||||
|
void appendOperation(OperationBase* op);
|
||||||
|
void clearOperations() {
|
||||||
|
m_transaction.operations.clear();
|
||||||
|
Q_EMIT operationsChanged();
|
||||||
|
}
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void statusChanged(Status status);
|
void statusChanged(Status status);
|
||||||
void operationsChanged();
|
void operationsChanged();
|
||||||
|
|
|
||||||
|
|
@ -56,6 +56,8 @@ FC_REFLECT( wallet_file,
|
||||||
class Wallet : public QObject
|
class Wallet : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
Q_PROPERTY(bool isOpen READ isOpen NOTIFY isOpenChanged)
|
||||||
|
Q_PROPERTY(bool isLocked READ isLocked NOTIFY isLockedChanged)
|
||||||
public:
|
public:
|
||||||
Wallet( QObject* parent = nullptr );
|
Wallet( QObject* parent = nullptr );
|
||||||
~Wallet();
|
~Wallet();
|
||||||
|
|
@ -148,5 +150,3 @@ class Wallet : public QObject
|
||||||
map<QString,QString> _label_to_key;
|
map<QString,QString> _label_to_key;
|
||||||
QString _brain_key;
|
QString _brain_key;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,8 @@ Rectangle {
|
||||||
|
|
||||||
var form = formType.createObject(formContainer, params)
|
var form = formType.createObject(formContainer, params)
|
||||||
formContainer.data = [form]
|
formContainer.data = [form]
|
||||||
form.finished.connect(function(){state = "HIDDEN"})
|
form.canceled.connect(function(){state = "HIDDEN"; internal.callbackArgs = []})
|
||||||
|
form.completed.connect(function(){state = "HIDDEN"; internal.callbackArgs = arguments})
|
||||||
if (closedCallback instanceof Function)
|
if (closedCallback instanceof Function)
|
||||||
internal.callback = closedCallback
|
internal.callback = closedCallback
|
||||||
state = "SHOWN"
|
state = "SHOWN"
|
||||||
|
|
@ -89,6 +90,7 @@ Rectangle {
|
||||||
if (internal.callback instanceof Function)
|
if (internal.callback instanceof Function)
|
||||||
internal.callback()
|
internal.callback()
|
||||||
internal.callback = undefined
|
internal.callback = undefined
|
||||||
|
internal.callbackArgs = []
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
@ -145,5 +147,6 @@ Rectangle {
|
||||||
QtObject {
|
QtObject {
|
||||||
id: internal
|
id: internal
|
||||||
property var callback
|
property var callback
|
||||||
|
property var callbackArgs
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
51
programs/light_client/qml/FormFlipper.qml
Normal file
51
programs/light_client/qml/FormFlipper.qml
Normal file
|
|
@ -0,0 +1,51 @@
|
||||||
|
import QtQuick 2.5
|
||||||
|
|
||||||
|
import Graphene.Client 0.1
|
||||||
|
|
||||||
|
Flipable {
|
||||||
|
id: flipable
|
||||||
|
anchors.fill: parent
|
||||||
|
|
||||||
|
property Component frontComponent
|
||||||
|
property Component backComponent
|
||||||
|
property GrapheneApplication app
|
||||||
|
signal canceled
|
||||||
|
signal completed
|
||||||
|
|
||||||
|
property bool flipped: false
|
||||||
|
|
||||||
|
Component.onCompleted: {
|
||||||
|
back = backComponent.createObject(flipable, {app: app, enabled: Qt.binding(function(){return flipped})})
|
||||||
|
front = frontComponent.createObject(flipable, {app: app, enabled: Qt.binding(function(){return !flipped})})
|
||||||
|
front.canceled.connect(function() { canceled.apply(this, arguments) })
|
||||||
|
front.completed.connect(function() {
|
||||||
|
if (back.hasOwnProperty("arguments"))
|
||||||
|
back.arguments = arguments
|
||||||
|
flipped = true
|
||||||
|
})
|
||||||
|
back.canceled.connect(function() {
|
||||||
|
if (front.hasOwnProperty("arguments"))
|
||||||
|
front.arguments = arguments
|
||||||
|
flipped = false
|
||||||
|
})
|
||||||
|
back.completed.connect(function() { completed.apply(this, arguments) })
|
||||||
|
}
|
||||||
|
|
||||||
|
transform: Rotation {
|
||||||
|
id: rotation
|
||||||
|
origin.x: flipable.width/2
|
||||||
|
origin.y: flipable.height/2
|
||||||
|
axis.x: 0; axis.y: 1; axis.z: 0 // set axis.y to 1 to rotate around y-axis
|
||||||
|
angle: 0 // the default angle
|
||||||
|
}
|
||||||
|
|
||||||
|
states: State {
|
||||||
|
name: "back"
|
||||||
|
PropertyChanges { target: rotation; angle: 180 }
|
||||||
|
when: flipable.flipped
|
||||||
|
}
|
||||||
|
|
||||||
|
transitions: Transition {
|
||||||
|
NumberAnimation { target: rotation; property: "angle"; duration: 500 }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -15,14 +15,21 @@ Rectangle {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
|
||||||
property GrapheneApplication app
|
property GrapheneApplication app
|
||||||
signal finished
|
signal canceled
|
||||||
|
signal completed(TransferOperation op)
|
||||||
|
|
||||||
/// The Account object for the sender
|
/// The Account object for the sender
|
||||||
property alias senderAccount: senderPicker.account
|
property alias senderAccount: senderPicker.account
|
||||||
/// The Account object for the receiver
|
/// The Account object for the receiver
|
||||||
property alias receiverAccount: recipientPicker.account
|
property alias receiverAccount: recipientPicker.account
|
||||||
/// The operation created in this form
|
|
||||||
property var operation
|
function operation() {
|
||||||
|
if (!transferButton.enabled) return app.operationBuilder.transfer(0,0,0,0, memoField.text, 0)
|
||||||
|
|
||||||
|
return app.operationBuilder.transfer(senderPicker.account.id, recipientPicker.account.id,
|
||||||
|
amountField.value * amountField.precisionAdjustment,
|
||||||
|
amountField.maxBalance.type.id, memoField.text, 0)
|
||||||
|
}
|
||||||
|
|
||||||
Component.onCompleted: console.log("Made a transfer form")
|
Component.onCompleted: console.log("Made a transfer form")
|
||||||
Component.onDestruction: console.log("Destroyed a transfer form")
|
Component.onDestruction: console.log("Destroyed a transfer form")
|
||||||
|
|
@ -77,6 +84,12 @@ Rectangle {
|
||||||
|
|
||||||
property Balance maxBalance: assetField.enabled && senderPicker.showBalance >= 0?
|
property Balance maxBalance: assetField.enabled && senderPicker.showBalance >= 0?
|
||||||
senderPicker.balances[senderPicker.showBalance] : null
|
senderPicker.balances[senderPicker.showBalance] : null
|
||||||
|
property int precisionAdjustment: maxBalance? Math.pow(10, maxBalance.type.precision) : 1
|
||||||
|
|
||||||
|
// Workaround to preserve value in case form gets disabled then re-enabled
|
||||||
|
onEnabledChanged: if (!enabled) __valueBackup = value
|
||||||
|
onMaximumValueChanged: if (enabled && maximumValue > __valueBackup) value = __valueBackup
|
||||||
|
property real __valueBackup
|
||||||
}
|
}
|
||||||
ComboBox {
|
ComboBox {
|
||||||
id: assetField
|
id: assetField
|
||||||
|
|
@ -89,25 +102,21 @@ Rectangle {
|
||||||
Text {
|
Text {
|
||||||
font.pixelSize: assetField.height / 2.5
|
font.pixelSize: assetField.height / 2.5
|
||||||
text: {
|
text: {
|
||||||
var balance = amountField.maxBalance
|
if (!senderPicker.account)
|
||||||
if (!balance || !balance.type) return ""
|
return ""
|
||||||
var precisionAdjustment = Math.pow(10, balance.type.precision)
|
return qsTr("Fee:<br/>") + operation().fee / amountField.precisionAdjustment + " CORE"
|
||||||
|
|
||||||
var op = app.operationBuilder.transfer(0, 0, amountField.value * precisionAdjustment,
|
|
||||||
balance.type.id, memoField.text, 0)
|
|
||||||
|
|
||||||
return qsTr("Fee:<br/>") + op.fee / precisionAdjustment + " CORE"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Item { Layout.fillWidth: true }
|
Item { Layout.fillWidth: true }
|
||||||
Button {
|
Button {
|
||||||
text: qsTr("Cancel")
|
text: qsTr("Cancel")
|
||||||
onClicked: finished()
|
onClicked: canceled()
|
||||||
}
|
}
|
||||||
Button {
|
Button {
|
||||||
|
id: transferButton
|
||||||
text: qsTr("Transfer")
|
text: qsTr("Transfer")
|
||||||
enabled: senderPicker.account && recipientPicker.account && senderPicker.account !== recipientPicker.account && amountField.value
|
enabled: senderPicker.account && recipientPicker.account && senderPicker.account !== recipientPicker.account && amountField.value
|
||||||
onClicked: console.log(amountField.value)
|
onClicked: completed(operation)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -60,10 +60,15 @@ ApplicationWindow {
|
||||||
|
|
||||||
Button {
|
Button {
|
||||||
text: "Transfer"
|
text: "Transfer"
|
||||||
onClicked: formBox.showForm(Qt.createComponent("TransferForm.qml"), {},
|
onClicked: {
|
||||||
function() {
|
var front = Qt.createComponent("TransferForm.qml")
|
||||||
console.log("Closed form")
|
// TODO: make back into a preview and confirm dialog
|
||||||
})
|
var back = Qt.createComponent("TransferForm.qml")
|
||||||
|
formBox.showForm(Qt.createComponent("FormFlipper.qml"), {frontComponent: front, backComponent: back},
|
||||||
|
function() {
|
||||||
|
console.log("Closed form")
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
TextField {
|
TextField {
|
||||||
id: nameField
|
id: nameField
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
<file>main.qml</file>
|
<file>main.qml</file>
|
||||||
<file>TransferForm.qml</file>
|
<file>TransferForm.qml</file>
|
||||||
<file>FormBox.qml</file>
|
<file>FormBox.qml</file>
|
||||||
|
<file>FormFlipper.qml</file>
|
||||||
<file>Scaling.qml</file>
|
<file>Scaling.qml</file>
|
||||||
<file>Identicon.qml</file>
|
<file>Identicon.qml</file>
|
||||||
<file>AccountPicker.qml</file>
|
<file>AccountPicker.qml</file>
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue