[GUI] Add name field and identicon to transfer form
This commit is contained in:
parent
6fd566e6f7
commit
3ad1c1715d
11 changed files with 157 additions and 22 deletions
|
|
@ -11,14 +11,25 @@
|
|||
#include <fc/thread/thread.hpp>
|
||||
#include <graphene/app/api.hpp>
|
||||
|
||||
#include <QCryptographicHash>
|
||||
#include <QObject>
|
||||
#include <QQmlListProperty>
|
||||
#include <QtQml>
|
||||
|
||||
using boost::multi_index_container;
|
||||
using namespace boost::multi_index;
|
||||
|
||||
Q_DECLARE_METATYPE(std::function<void()>)
|
||||
|
||||
class Crypto {
|
||||
Q_GADGET
|
||||
|
||||
public:
|
||||
Q_INVOKABLE QString sha256(QByteArray data) {
|
||||
return QCryptographicHash::hash(data, QCryptographicHash::Sha256).toHex();
|
||||
}
|
||||
};
|
||||
QML_DECLARE_TYPE(Crypto)
|
||||
|
||||
class Asset : public QObject {
|
||||
Q_OBJECT
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@
|
|||
|
||||
#include "ClientDataModel.hpp"
|
||||
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
fc::thread::current().set_name( "main" );
|
||||
|
|
@ -22,6 +21,9 @@ int main(int argc, char *argv[])
|
|||
qmlRegisterType<GrapheneApplication>("Graphene.Client", 0, 1, "GrapheneApplication");
|
||||
|
||||
QQmlApplicationEngine engine;
|
||||
QVariant crypto;
|
||||
crypto.setValue(Crypto());
|
||||
engine.rootContext()->setContextProperty("Crypto", crypto);
|
||||
#ifdef NDEBUG
|
||||
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
|
||||
#else
|
||||
|
|
|
|||
1
programs/light_client/qml/.gitignore
vendored
Normal file
1
programs/light_client/qml/.gitignore
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
*.depends
|
||||
|
|
@ -5,6 +5,7 @@ import QtQuick.Dialogs 1.2
|
|||
Rectangle {
|
||||
id: greySheet
|
||||
state: "HIDDEN"
|
||||
color: Qt.rgba(0, 0, 0, showOpacity)
|
||||
|
||||
property real showOpacity: .5
|
||||
property int animationTime: 300
|
||||
|
|
@ -18,8 +19,11 @@ Rectangle {
|
|||
/// Emitted when closed, following fade-out animation
|
||||
signal closed
|
||||
|
||||
function showForm(formType, closedCallback) {
|
||||
formLoader.sourceComponent = formType
|
||||
function showForm(formType, params, closedCallback) {
|
||||
if (formType.status === Component.Error)
|
||||
console.log(formType.errorString())
|
||||
|
||||
formContainer.data = [formType.createObject(formContainer, params)]
|
||||
if (closedCallback instanceof Function)
|
||||
internal.callback = closedCallback
|
||||
state = "SHOWN"
|
||||
|
|
@ -35,12 +39,12 @@ Rectangle {
|
|||
acceptedButtons: Qt.AllButtons
|
||||
}
|
||||
MouseArea {
|
||||
anchors.fill: formLoader
|
||||
anchors.fill: formContainer
|
||||
acceptedButtons: Qt.AllButtons
|
||||
onClicked: mouse.accepted = true
|
||||
}
|
||||
Loader {
|
||||
id: formLoader
|
||||
Item {
|
||||
id: formContainer
|
||||
anchors.centerIn: parent
|
||||
width: parent.width / 2
|
||||
height: parent.height / 2
|
||||
|
|
@ -51,7 +55,7 @@ Rectangle {
|
|||
name: "HIDDEN"
|
||||
PropertyChanges {
|
||||
target: greySheet
|
||||
color: Qt.rgba(0, 0, 0, 0)
|
||||
opacity: 0
|
||||
enabled: false
|
||||
}
|
||||
StateChangeScript {
|
||||
|
|
@ -63,10 +67,12 @@ Rectangle {
|
|||
StateChangeScript {
|
||||
name: "postHidden"
|
||||
script: {
|
||||
console.log("Post")
|
||||
greySheet.closed()
|
||||
formLoader.sourceComponent = undefined
|
||||
formContainer.data = []
|
||||
if (internal.callback instanceof Function)
|
||||
internal.callback()
|
||||
internal.callback = undefined
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
@ -74,7 +80,7 @@ Rectangle {
|
|||
name: "SHOWN"
|
||||
PropertyChanges {
|
||||
target: greySheet
|
||||
color: Qt.rgba(0, 0, 0, showOpacity)
|
||||
opacity: 1
|
||||
enabled: true
|
||||
}
|
||||
StateChangeScript {
|
||||
|
|
@ -95,22 +101,28 @@ Rectangle {
|
|||
Transition {
|
||||
from: "HIDDEN"
|
||||
to: "SHOWN"
|
||||
ScriptAction { scriptName: "preShown" }
|
||||
ColorAnimation {
|
||||
target: greySheet
|
||||
duration: animationTime
|
||||
SequentialAnimation {
|
||||
ScriptAction { scriptName: "preShown" }
|
||||
PropertyAnimation {
|
||||
target: greySheet
|
||||
property: "opacity"
|
||||
duration: animationTime
|
||||
}
|
||||
ScriptAction { scriptName: "postShown" }
|
||||
}
|
||||
ScriptAction { scriptName: "postShown" }
|
||||
},
|
||||
Transition {
|
||||
from: "SHOWN"
|
||||
to: "HIDDEN"
|
||||
ScriptAction { scriptName: "preHidden" }
|
||||
ColorAnimation {
|
||||
target: greySheet
|
||||
duration: animationTime
|
||||
SequentialAnimation {
|
||||
ScriptAction { scriptName: "preHidden" }
|
||||
PropertyAnimation {
|
||||
target: greySheet
|
||||
property: "opacity"
|
||||
duration: animationTime
|
||||
}
|
||||
ScriptAction { scriptName: "postHidden" }
|
||||
}
|
||||
ScriptAction { scriptName: "postHidden" }
|
||||
}
|
||||
]
|
||||
|
||||
|
|
|
|||
12
programs/light_client/qml/Scaling.qml
Normal file
12
programs/light_client/qml/Scaling.qml
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
pragma Singleton
|
||||
import QtQuick 2.5
|
||||
import QtQuick.Window 2.2
|
||||
|
||||
Item {
|
||||
function mm(millimeters) {
|
||||
return Screen.pixelDensity * millimeters
|
||||
}
|
||||
function cm(centimeters) {
|
||||
return mm(centimeters * 10)
|
||||
}
|
||||
}
|
||||
|
|
@ -1,8 +1,60 @@
|
|||
import QtQuick 2.5
|
||||
import QtQuick.Controls 1.4
|
||||
import QtQuick.Dialogs 1.2
|
||||
import QtQuick.Layouts 1.2
|
||||
|
||||
import "."
|
||||
import "jdenticon/jdenticon-1.0.1.min.js" as Jdenticon
|
||||
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
|
||||
Component.onCompleted: console.log("Made a transfer form")
|
||||
Component.onDestruction: console.log("Destroyed a transfer form")
|
||||
|
||||
Column {
|
||||
anchors.centerIn: parent
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
TextField {
|
||||
id: nameField
|
||||
Layout.fillWidth: true
|
||||
onTextChanged: identicon.requestPaint()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
18
programs/light_client/qml/jdenticon/jdenticon-1.0.1.min.js
vendored
Executable file
18
programs/light_client/qml/jdenticon/jdenticon-1.0.1.min.js
vendored
Executable file
|
|
@ -0,0 +1,18 @@
|
|||
// Jdenticon 1.0.1 | jdenticon.com | zlib licensed | (c) 2014-2015 Daniel Mester Pirttijärvi
|
||||
/*Alteration to official Jdenticon code: make jdenticon() a variable in this context instead of a property of window*/
|
||||
var jdenticon=function(){function h(){}function n(b,a,c,d){this.h=b;this.i=a;this.k=c;this.f=d}function u(b,a){this.e=b;this.g=a||n.q;b.beginPath()}function r(b,a,c){var d=(b="string"===typeof b?document.querySelector(b):b).getContext("2d");c=Math.min(b.width)*(1-2*(c===t?.08:c));d.save();d.clearRect(0,0,b.width,b.height);d.translate(0|(b.width-c)/2,0|(b.height-c)/2);v(d,a||b.getAttribute("data-jdenticon-hash"),c);d.restore()}function v(b,a,c){function d(b,c,d,e,g){e=e?parseInt(a.charAt(e),16):
|
||||
0;c=c[parseInt(a.charAt(d),16)%c.length];var f;for(d=0;d<g.length;d++)f=new n(g[d][0]*p,g[d][1]*p,p,e++%4),f=new u(b,f),c(f,p,d),f.fill()}function e(a){if(0<=a.indexOf(k))for(var b=0;b<a.length;b++)if(0<=l.indexOf(a[b]))return!0}function g(a){b.fillStyle=m[l[a]].toString()}if(30>c)throw Error("Jdenticon cannot render identicons smaller than 30 pixels.");if(!/^[0-9a-f]{10,}$/i.test(a))throw Error("Invalid hash passed to Jdenticon.");c|=0;for(var p=2*(0|c/8),f=parseInt(a.substr(-7),16)/268435455,m=
|
||||
[h.o(76,76,76),h.m(f,.6),h.o(230,230,230),h.m(f,.8),h.n(f,.4)],l=[],k,f=0;3>f;f++){k=parseInt(a.charAt(8+f),16)%m.length;if(e([0,4])||e([2,3]))k=1;l.push(k)}b.clearRect(0,0,c,c);g(0);d(b,w,2,3,[[1,0],[2,0],[2,3],[1,3],[0,1],[3,1],[3,2],[0,2]]);g(1);d(b,w,4,5,[[0,0],[3,0],[3,3],[0,3]]);g(2);d(b,y,1,null,[[1,1],[2,1],[2,2],[1,2]])}function q(){for(var b,a=document.getElementsByTagName("canvas"),c=0;c<a.length;c++)(b=a[c].getAttribute("data-jdenticon-hash"))&&r(a[c],b)}var t,x=window.jQuery;h.o=function(b,
|
||||
a,c){var d=new h;d.p="rgba("+(b&255)+","+(a&255)+","+(c&255)+","+(void 0===t?1:void 0)+")";return d};h.n=function(b,a){var c=new h;c.p="hsla("+(360*b|0)+",50%,"+(100*a|0)+"%,"+(void 0===t?1:void 0)+")";return c};h.m=function(b,a){return h.n(b,1-[.95,1,1,1,.7,.8,.8][6*b+.5|0]*(1-a))};h.prototype={toString:function(){return this.p}};n.q=new n(0,0,0,0);n.prototype={j:function(b,a,c,d){var e=this.h+this.k,g=this.i+this.k;return 1===this.f?[e-a-(d||0),this.i+b]:2===this.f?[e-b-(c||0),g-a-(d||0)]:3===this.f?
|
||||
[this.h+a,g-b-(c||0)]:[this.h+b,this.i+a]}};u.prototype={c:function(b,a){var c=a?-2:2,d=a?b.length-2:0,e=this.e;e.moveTo.apply(e,this.g.j(b[d],b[d+1]));for(d+=c;d<b.length&&0<=d;d+=c)e.lineTo.apply(e,this.g.j(b[d],b[d+1]));e.closePath()},d:function(b,a,c,d,e){var g=this.e;a=this.g.j(b,a,c,d);b=a[0];a=a[1];var h=c/2*.5522848,f=d/2*.5522848,m=b+c,l=a+d;c=b+c/2;var k=a+d/2;e&&(l=a,a+=d,f=-f);g.moveTo(b,k);g.bezierCurveTo(b,k-f,c-h,a,c,a);g.bezierCurveTo(c+h,a,m,k-f,m,k);g.bezierCurveTo(m,k+f,c+h,l,c,
|
||||
l);g.bezierCurveTo(c-h,l,b,k+f,b,k);g.closePath()},a:function(b,a,c,d,e){this.c([b,a,b+c,a,b+c,a+d,b,a+d],e)},b:function(b,a,c,d,e,g){b=[b+c,a,b+c,a+d,b,a+d,b,a];b.splice((e||0)%4,2);this.c(b,g)},l:function(b,a,c,d,e){this.c([b+c/2,a,b+c,a+d/2,b+c/2,a+d,b,a+d/2],e)},fill:function(){this.e.fill()}};var y=[function(b,a){var c=.42*a;b.c([0,0,a,0,a,a-2*c,a-c,a,0,a])},function(b,a){var c=0|.4*a;b.b(a-c,a-2*c,c,2*c,1)},function(b,a){var c=0|a/3;b.a(c,c,a-c,a-c)},function(b,a){var c=0|.1*a,d=0|.25*a;b.a(d,
|
||||
d,a-c-d,a-c-d)},function(b,a){var c=0|.15*a,d=0|.5*a;b.d(a-d-c,a-d-c,d,d)},function(b,a){var c=.1*a,d=4*c;b.a(0,0,a,a);b.c([d,d,a-c,d,d+(a-d-c)/2,a-c],!0)},function(b,a){b.b(0,0,a,a,0)},function(b,a){b.b(a/2,a/2,a/2,a/2,0)},function(b,a){b.a(0,0,a,a/2);b.a(0,a/2,a/2,a/2);b.b(a/2,a/2,a/2,a/2,1)},function(b,a){var c=0|.14*a,d=0|.35*a;b.a(0,0,a,a);b.a(d,d,a-d-c,a-d-c,!0)},function(b,a){var c=.12*a,d=3*c;b.a(0,0,a,a);b.d(d,d,a-c-d,a-c-d,!0)},function(b,a){b.b(a/2,a/2,a/2,a/2,3)},function(b,a){var c=.25*
|
||||
a;b.a(0,0,a,a);b.l(c,c,a-c,a-c,!0)},function(b,a,c){var d=.4*a;a*=1.2;c||b.d(d,d,a,a)}],w=[function(b,a){b.b(0,0,a,a,0)},function(b,a){b.b(0,a/2,a,a/2,0)},function(b,a){b.l(0,0,a,a)},function(b,a){var c=a/6;b.d(c,c,a-2*c,a-2*c)}];q.drawIcon=v;q.update=r;x&&(x.fn.jdenticon=function(b,a){this.each(function(c,d){r(d,b,a)});return this});/*Alteration to official Jdenticon code: Removed call to schedule a render immediately on load*/return q}();
|
||||
|
||||
// The following functions were added, and are not part of the official Jdenticon code
|
||||
|
||||
/// @param canvas The canvas to draw on
|
||||
/// @param data The data to generate an identicon for (this will be hashed to generate the identicon)
|
||||
function draw(canvas, data) {
|
||||
jdenticon.drawIcon(canvas.context, Crypto.sha256(data), Math.min(canvas.width, canvas.height))
|
||||
}
|
||||
21
programs/light_client/qml/jdenticon/license.txt
Executable file
21
programs/light_client/qml/jdenticon/license.txt
Executable file
|
|
@ -0,0 +1,21 @@
|
|||
|
||||
Jdenticon
|
||||
Copyright (c) 2014 Daniel Mester Pirttijärvi
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
import QtQuick 2.5
|
||||
import QtQuick.Controls 1.4
|
||||
import QtQuick.Dialogs 1.2
|
||||
import QtQuick.Window 2.2
|
||||
|
||||
import Qt.labs.settings 1.0
|
||||
|
||||
|
|
@ -47,9 +48,10 @@ ApplicationWindow {
|
|||
anchors.centerIn: parent
|
||||
Button {
|
||||
text: "Transfer"
|
||||
onClicked: formBox.showForm(Qt.createComponent("TransferForm.qml"), function() {
|
||||
console.log("Closed form")
|
||||
})
|
||||
onClicked: formBox.showForm(Qt.createComponent("TransferForm.qml"), {},
|
||||
function() {
|
||||
console.log("Closed form")
|
||||
})
|
||||
}
|
||||
TextField {
|
||||
id: nameField
|
||||
|
|
@ -73,6 +75,7 @@ ApplicationWindow {
|
|||
})
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
FormBox {
|
||||
|
|
|
|||
|
|
@ -3,6 +3,8 @@
|
|||
<file>main.qml</file>
|
||||
<file>TransferForm.qml</file>
|
||||
<file>FormBox.qml</file>
|
||||
<file>jdenticon/jdenticon-1.0.1.min.js</file>
|
||||
<file>Scaling.qml</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
||||
|
|
|
|||
1
programs/light_client/qml/qmldir
Normal file
1
programs/light_client/qml/qmldir
Normal file
|
|
@ -0,0 +1 @@
|
|||
singleton Scaling Scaling.qml
|
||||
Loading…
Reference in a new issue