[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:
Nathan Hourt 2015-07-24 15:55:58 -04:00
parent 972c9a6407
commit f25a1ea360
8 changed files with 100 additions and 25 deletions

View file

@ -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();
} }

View file

@ -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();

View file

@ -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;
}; };

View file

@ -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
} }
} }

View 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 }
}
}

View file

@ -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)
} }
} }
} }

View file

@ -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

View file

@ -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>