Browse Source

ScenarioExecution.qml ux design

cl-refactor
yann300 10 years ago
parent
commit
6e6ebc6037
  1. 1
      mix/qml.qrc
  2. 137
      mix/qml/Block.qml
  3. 164
      mix/qml/BlockChain.qml
  4. 62
      mix/qml/ScenarioButton.qml
  5. 7
      mix/qml/ScenarioExecution.qml
  6. 27
      mix/qml/ScenarioLoader.qml
  7. 3
      mix/qml/StateListModel.qml
  8. BIN
      mix/qml/img/duplicateIcon.png
  9. BIN
      mix/qml/img/duplicateIcon@2x.png
  10. BIN
      mix/qml/img/newIcon.png
  11. BIN
      mix/qml/img/newIcon@2x.png
  12. BIN
      mix/qml/img/recycle-discard.png
  13. BIN
      mix/qml/img/recycle-discard@2x.png
  14. BIN
      mix/qml/img/recycle-icon.png
  15. BIN
      mix/qml/img/recycle-icon@2x.png
  16. BIN
      mix/qml/img/recycle-keep.png
  17. BIN
      mix/qml/img/recycle-keep@2x.png
  18. BIN
      mix/qml/img/restoreIcon.png
  19. BIN
      mix/qml/img/restoreIcon@2x.png
  20. BIN
      mix/qml/img/saveIcon.png
  21. BIN
      mix/qml/img/saveIcon@2x.png
  22. 12
      mix/res.qrc

1
mix/qml.qrc

@ -68,5 +68,6 @@
<file>qml/BlockChain.qml</file> <file>qml/BlockChain.qml</file>
<file>qml/ScenarioExecution.qml</file> <file>qml/ScenarioExecution.qml</file>
<file>qml/ScenarioLoader.qml</file> <file>qml/ScenarioLoader.qml</file>
<file>qml/ScenarioButton.qml</file>
</qresource> </qresource>
</RCC> </RCC>

137
mix/qml/Block.qml

@ -10,16 +10,32 @@ import "."
ColumnLayout ColumnLayout
{ {
id: root
property variant transactions property variant transactions
property string status property string status
property int number property int number
property int blockWidth: Layout.preferredWidth - statusWidth - horizontalMargin
property int horizontalMargin: 10
property int trHeight: 30
spacing: 0
RowLayout
{
Layout.preferredHeight: trHeight
Layout.preferredWidth: blockWidth
id: rowHeader
Rectangle Rectangle
{ {
width: parent.width color: "#DEDCDC"
height: 50 Layout.preferredWidth: blockWidth
Layout.preferredHeight: trHeight
radius: 4
anchors.left: parent.left anchors.left: parent.left
anchors.leftMargin: statusWidth anchors.leftMargin: statusWidth + 5
Label { Label {
anchors.verticalCenter: parent.verticalCenter
anchors.left: parent.left
anchors.leftMargin: horizontalMargin
text: text:
{ {
if (status === "mined") if (status === "mined")
@ -27,8 +43,7 @@ ColumnLayout
else else
return qsTr("BLOCK") + " pending" return qsTr("BLOCK") + " pending"
} }
}
anchors.left: parent.left
} }
} }
@ -36,57 +51,80 @@ ColumnLayout
{ {
id: transactionRepeater id: transactionRepeater
model: transactions model: transactions
Row
RowLayout
{ {
height: 50 Layout.preferredHeight: trHeight
Rectangle Rectangle
{ {
id: trSaveStatus id: trSaveStatus
Layout.preferredWidth: statusWidth
Layout.preferredHeight: trHeight
color: "transparent" color: "transparent"
CheckBox property bool saveStatus
Image {
id: saveStatusImage
source: "qrc:/qml/img/recycle-discard@2x.png"
width: statusWidth
fillMode: Image.PreserveAspectFit
anchors.verticalCenter: parent.verticalCenter
anchors.horizontalCenter: parent.horizontalCenter
}
Component.onCompleted:
{ {
id: saveStatus
checked: {
if (index >= 0) if (index >= 0)
return transactions.get(index).saveStatus saveStatus = transactions.get(index).saveStatus
else
return true
} }
onCheckedChanged:
onSaveStatusChanged:
{ {
if (saveStatus)
saveStatusImage.source = "qrc:/qml/img/recycle-keep@2x.png"
else
saveStatusImage.source = "qrc:/qml/img/recycle-discard@2x.png"
if (index >= 0) if (index >= 0)
transactions.get(index).saveStatus = checked transactions.get(index).saveStatus = saveStatus
}
MouseArea {
id: statusMouseArea
anchors.fill: parent
onClicked:
{
parent.saveStatus = !parent.saveStatus
} }
} }
} }
Rectangle Rectangle
{ {
width: parent.width Layout.preferredWidth: blockWidth
height: 50 Layout.preferredHeight: parent.height
color: "#cccccc" color: "#DEDCDC"
radius: 4 RowLayout
Row
{ {
Label anchors.verticalCenter: parent.verticalCenter
{ spacing: cellSpacing
id: status Text
width: statusWidth
}
Label
{ {
id: hash id: hash
width: fromWidth anchors.left: parent.left
anchors.leftMargin: horizontalMargin
Layout.preferredWidth: fromWidth
elide: Text.ElideRight
maximumLineCount: 1
text: { text: {
if (index >= 0) if (index >= 0)
return transactions.get(index).sender return transactions.get(index).sender
else else
return "" return ""
} }
clip: true
} }
Label
Text
{ {
id: func id: func
text: { text: {
@ -95,9 +133,9 @@ ColumnLayout
else else
return "" return ""
} }
elide: Text.ElideRight
width: toWidth maximumLineCount: 1
clip: true Layout.preferredWidth: toWidth
} }
function userFrienldyToken(value) function userFrienldyToken(value)
@ -108,43 +146,52 @@ ColumnLayout
return value return value
} }
Label Text
{ {
id: returnValue id: returnValue
width: valueWidth elide: Text.ElideRight
maximumLineCount: 1
Layout.preferredWidth: valueWidth
text: { text: {
if (index >= 0 && transactions.get(index).returned) if (index >= 0 && transactions.get(index).returned)
return transactions.get(index).returned return transactions.get(index).returned
else else
return "" return ""
} }
clip: true
} }
Label Rectangle
{ {
id: logs Layout.preferredWidth: logsWidth
Layout.preferredHeight: trHeight - 10
width: logsWidth width: logsWidth
color: "transparent"
Text
{
id: logs
anchors.left: parent.left
anchors.leftMargin: 10
text: { text: {
if (index >= 0 && transactions.get(index).logs) if (index >= 0 && transactions.get(index).logs && transactions.get(index).logs.count)
{ {
for (var k in transactions.get(index).logs) for (var k = 0; k < transactions.get(index).logs.count; k++)
{ {
console.log("_________________________") /*console.log("_________________________")
console.log(JSON.stringify(transactions.get(index).logs[k])) console.log(JSON.stringify(transactions.get(index).logs[k]))
console.log("_________________________") console.log("_________________________")*/
} }
return transactions.get(index).logs.length return transactions.get(index).logs.count
} }
else else
return 0 return ""
}
} }
} }
Button Button
{ {
id: debug id: debug
width: debugActionWidth Layout.preferredWidth: debugActionWidth
text: "debug" text: "debug"
onClicked: onClicked:
{ {

164
mix/qml/BlockChain.qml

@ -11,91 +11,126 @@ import "js/TransactionHelper.js" as TransactionHelper
import "js/QEtherHelper.js" as QEtherHelper import "js/QEtherHelper.js" as QEtherHelper
import "." import "."
Column { ColumnLayout {
id: blockChainPanel id: blockChainPanel
property variant model property variant model
spacing: 5 spacing: 0
property int previousWidth
onWidthChanged:
{
function load(scenario) if (width <= 630 || previousWidth <= 630)
{
fromWidth = 100
toWidth = 100
valueWidth = 200
}
else
{ {
var diff = (width - previousWidth) / 3;
fromWidth = fromWidth + diff < 100 ? 100 : fromWidth + diff
toWidth = toWidth + diff < 100 ? 100 : toWidth + diff
valueWidth = valueWidth + diff < 200 ? 200 : valueWidth + diff
}
previousWidth = width
}
function load(scenario)
{
if (!scenario) if (!scenario)
return; return;
model = scenario model = scenario
blockModel.clear() blockModel.clear()
for (var b in model.blocks) for (var b in model.blocks)
blockModel.append(model.blocks[b]) blockModel.append(model.blocks[b])
previousWidth = width
} }
property int statusWidth: 50 property int statusWidth: 30
property int fromWidth: 100 property int fromWidth: 100
property int toWidth: 250 property int toWidth: 100
property int valueWidth: 50 property int valueWidth: 200
property int logsWidth: 50 property int logsWidth: 50
property int debugActionWidth: 50 property int debugActionWidth: 50
property int horizontalMargin: 10
property int cellSpacing: 10
Row RowLayout
{ {
id: header id: header
width: parent.width spacing: 0
Label Layout.preferredHeight: 25
{ Image {
text: "Status" id: debugImage
width: statusWidth source: "qrc:/qml/img/recycle-icon@2x.png"
Layout.preferredWidth: statusWidth
Layout.preferredHeight: 25
fillMode: Image.PreserveAspectFit
} }
Rectangle
{
Layout.preferredWidth: fromWidth + cellSpacing
Label Label
{ {
anchors.verticalCenter: parent.verticalCenter
text: "From" text: "From"
width: fromWidth anchors.left: parent.left
anchors.leftMargin: horizontalMargin + 5
}
} }
Label Label
{ {
text: "To" text: "To"
width: toWidth Layout.preferredWidth: toWidth + cellSpacing
} }
Label Label
{ {
text: "Value" text: "Value"
width: valueWidth Layout.preferredWidth: valueWidth + cellSpacing
} }
Label Label
{ {
text: "Logs" text: "Logs"
width: logsWidth Layout.preferredWidth: logsWidth + cellSpacing
} }
Label Label
{ {
text: "Action" text: "Action"
width: debugActionWidth Layout.preferredWidth: debugActionWidth
} }
} }
Rectangle Rectangle
{ {
width: parent.width Layout.preferredHeight: 500
height: 500 Layout.preferredWidth: parent.width
//height: 500
border.color: "#cccccc" border.color: "#cccccc"
border.width: 2 border.width: 2
color: "white" color: "white"
ScrollView ScrollView
{ {
width: parent.width id: blockChainScrollView
height: parent.height anchors.fill: parent
anchors.topMargin: 10
ColumnLayout ColumnLayout
{ {
id: blockChainLayout
width: parent.width
spacing: 10
Repeater // List of blocks Repeater // List of blocks
{ {
id: blockChainRepeater id: blockChainRepeater
width: parent.width
model: blockModel model: blockModel
Block Block
{ {
height: Layout.preferredWidth: blockChainScrollView.width
Layout.preferredHeight:
{ {
if (index >= 0) if (index >= 0)
return 50 + 50 * blockModel.get(index).transactions.length return 30 + 30 * blockModel.get(index).transactions.count
else else
return 0 return 50
} }
transactions: transactions:
@ -143,8 +178,6 @@ Column {
function removeTransaction(blockIndex, trIndex) function removeTransaction(blockIndex, trIndex)
{ {
console.log(blockIndex)
console.log(trIndex)
blockModel.get(blockIndex).transactions.remove(trIndex) blockModel.get(blockIndex).transactions.remove(trIndex)
} }
@ -160,14 +193,29 @@ Column {
function getTransaction(block, tr) function getTransaction(block, tr)
{ {
return blockModel.get(block - 1).transactions.get(tr) return blockModel.get(block).transactions.get(tr)
} }
function setTransaction(blockIndex, trIndex, tr)
{
blockModel.get(blockIndex).transactions.set(trIndex, tr)
} }
function setTransactionProperty(blockIndex, trIndex, propertyName, value)
{
blockModel.get(blockIndex).transactions.set(trIndex, { propertyName: value })
}
}
Rectangle
{
Layout.preferredWidth: parent.width
RowLayout RowLayout
{ {
width: parent.width width: parent.width
Button { anchors.top: parent.top
anchors.topMargin: 10
ScenarioButton {
id: rebuild id: rebuild
text: qsTr("Rebuild") text: qsTr("Rebuild")
onClicked: onClicked:
@ -182,7 +230,7 @@ Column {
blockModel.removeTransaction(j, k) blockModel.removeTransaction(j, k)
if (model.blocks[j].transactions.length === 0) if (model.blocks[j].transactions.length === 0)
{ {
model.blocks[j].splice(j, 1); model.blocks.splice(j, 1);
blockModel.removeBlock(j); blockModel.removeBlock(j);
} }
} }
@ -190,9 +238,14 @@ Column {
} }
clientModel.setupScenario(model); clientModel.setupScenario(model);
} }
Layout.preferredWidth: 100
Layout.preferredHeight: 30
buttonShortcut: ""
sourceImg: "qrc:/qml/img/recycle-icon@2x.png"
} }
Button { ScenarioButton {
id: addTransaction id: addTransaction
text: qsTr("Add Transaction") text: qsTr("Add Transaction")
onClicked: onClicked:
@ -204,9 +257,13 @@ Column {
transactionDialog.stateAccounts = model.accounts transactionDialog.stateAccounts = model.accounts
transactionDialog.open(model.blocks[model.blocks.length - 1].transactions.length, model.blocks.length - 1, item) transactionDialog.open(model.blocks[model.blocks.length - 1].transactions.length, model.blocks.length - 1, item)
} }
Layout.preferredWidth: 100
Layout.preferredHeight: 30
buttonShortcut: ""
sourceImg: "qrc:/qml/img/recycle-icon@2x.png"
} }
Button { ScenarioButton {
id: addBlockBtn id: addBlockBtn
text: qsTr("Add Block") text: qsTr("Add Block")
onClicked: onClicked:
@ -224,6 +281,10 @@ Column {
model.blocks.push(block) model.blocks.push(block)
blockModel.appendBlock(block) blockModel.appendBlock(block)
} }
Layout.preferredWidth: 100
Layout.preferredHeight: 30
buttonShortcut: ""
sourceImg: "qrc:/qml/img/recycle-icon@2x.png"
} }
Connections Connections
@ -247,26 +308,29 @@ Column {
} }
onNewRecord: onNewRecord:
{ {
var blockIndex = _r.transactionIndex.split(":")[0] var blockIndex = parseInt(_r.transactionIndex.split(":")[0]) - 1
var trIndex = _r.transactionIndex.split(":")[1] var trIndex = parseInt(_r.transactionIndex.split(":")[1])
if (parseInt(blockIndex) <= model.blocks.length) if (blockIndex <= model.blocks.length)
{ {
var item = model.blocks[parseInt(blockIndex) - 1]; var item = model.blocks[blockIndex]
if (parseInt(trIndex) <= item.transactions.length) if (trIndex <= item.transactions.length)
{ {
var tr = item.transactions[parseInt(trIndex)]; var tr = item.transactions[trIndex]
tr.returned = _r.returned; tr.returned = _r.returned
blockModel.getTransaction(blockIndex, trIndex).returned = _r.returned; tr.recordIndex = _r.recordIndex
tr.recordIndex = _r.recordIndex; tr.logs = _r.logs
blockModel.getTransaction(blockIndex, trIndex).recordIndex = _r.recordIndex; var trModel = blockModel.getTransaction(blockIndex, trIndex)
tr.logs = _r.logs; trModel.returned = _r.returned
blockModel.getTransaction(blockIndex, trIndex).logs = _r.logs; trModel.recordIndex = _r.recordIndex
trModel.logs = _r.logs
blockModel.setTransaction(blockIndex, trIndex, trModel)
return; return;
} }
} }
// tr is not in the list. coming from JavaScript // tr is not in the list. coming from JavaScript
var itemTr = TransactionHelper.defaultTransaction() var itemTr = TransactionHelper.defaultTransaction()
itemTr.saveStatus = false
itemTr.functionId = _r.function itemTr.functionId = _r.function
itemTr.contractId = _r.contract itemTr.contractId = _r.contract
itemTr.gasAuto = true itemTr.gasAuto = true
@ -279,7 +343,6 @@ Column {
itemTr.sender = _r.sender itemTr.sender = _r.sender
itemTr.recordIndex = _r.recordIndex itemTr.recordIndex = _r.recordIndex
itemTr.logs = _r.logs itemTr.logs = _r.logs
model.blocks[model.blocks.length - 1].transactions.push(itemTr) model.blocks[model.blocks.length - 1].transactions.push(itemTr)
blockModel.appendTransaction(itemTr) blockModel.appendTransaction(itemTr)
} }
@ -288,12 +351,17 @@ Column {
} }
} }
Button { ScenarioButton {
id: newAccount id: newAccount
text: qsTr("New Account") text: qsTr("New Account")
onClicked: { onClicked: {
model.accounts.push(projectModel.stateListModel.newAccount("1000000", QEther.Ether)) model.accounts.push(projectModel.stateListModel.newAccount("1000000", QEther.Ether))
} }
Layout.preferredWidth: 100
Layout.preferredHeight: 30
buttonShortcut: ""
sourceImg: "qrc:/qml/img/recycle-icon@2x.png"
}
} }
} }

62
mix/qml/ScenarioButton.qml

@ -0,0 +1,62 @@
import QtQuick 2.2
import QtQuick.Controls 1.1
import QtQuick.Layouts 1.0
import QtQuick.Controls.Styles 1.1
Rectangle {
id: buttonActionContainer
property string text
property string buttonShortcut
property string sourceImg
signal clicked
Rectangle {
id: contentRectangle
anchors.fill: parent
border.color: "#cccccc"
border.width: 1
radius: 4
Image {
id: debugImage
anchors {
centerIn: parent
bottomMargin: debugImg.pressed ? 0 : 1;
topMargin: debugImg.pressed ? 1 : 0;
}
source: sourceImg
fillMode: Image.PreserveAspectFit
height: 30
}
Button {
anchors.fill: parent
id: debugImg
action: buttonAction
style: ButtonStyle {
background: Rectangle {
color: "transparent"
}
}
}
Action {
id: buttonAction
shortcut: buttonShortcut
onTriggered: {
buttonActionContainer.clicked();
}
}
}
Rectangle
{
anchors.top: contentRectangle.bottom
anchors.topMargin: 15
width: parent.width
Text
{
text: buttonActionContainer.text
anchors.centerIn: parent
}
}
}

7
mix/qml/ScenarioExecution.qml

@ -9,9 +9,7 @@ import "js/ErrorLocationFormater.js" as ErrorLocationFormater
import "." import "."
Rectangle { Rectangle {
color: "#ededed"
border.color: "red"
border.width: 1
Connections Connections
{ {
@ -26,9 +24,10 @@ Rectangle {
{ {
anchors.margins: 10 anchors.margins: 10
anchors.fill: parent anchors.fill: parent
spacing: 5 spacing: 10
ScenarioLoader ScenarioLoader
{ {
height: 70
width: parent.width width: parent.width
id: loader id: loader
} }

27
mix/qml/ScenarioLoader.qml

@ -37,32 +37,39 @@ RowLayout
loaded(state) loaded(state)
} }
} }
Button
{ ScenarioButton {
id: restoreScenario id: restoreScenario
text: qsTr("Restore") Layout.preferredWidth: 100
Layout.preferredHeight: 30
buttonShortcut: ""
sourceImg: "qrc:/qml/img/restoreIcon@2x.png"
onClicked: { onClicked: {
restore() restore()
} }
text: qsTr("Restore")
function restore() function restore()
{ {
var state = projectModel.stateListModel.reloadStateFromFromProject(scenarioList.currentIndex) var state = projectModel.stateListModel.reloadStateFromFromProject(scenarioList.currentIndex)
restored(state) restored(state)
loaded(state) loaded(state)
} }
} }
Button
{ ScenarioButton {
id: saveScenario id: saveScenario
text: qsTr("Save") text: qsTr("Save")
onClicked: { onClicked: {
projectModel.saveProjectFile() projectModel.saveProjectFile()
saved(state) saved(state)
} }
Layout.preferredWidth: 100
Layout.preferredHeight: 30
buttonShortcut: ""
sourceImg: "qrc:/qml/img/saveIcon@2x.png"
} }
Button
ScenarioButton
{ {
id: duplicateScenario id: duplicateScenario
text: qsTr("Duplicate") text: qsTr("Duplicate")
@ -73,5 +80,9 @@ RowLayout
projectModel.stateListModel.save() projectModel.stateListModel.save()
duplicated(state) duplicated(state)
} }
Layout.preferredWidth: 100
Layout.preferredHeight: 30
buttonShortcut: ""
sourceImg: "qrc:/qml/img/duplicateIcon@2x.png"
} }
} }

3
mix/qml/StateListModel.qml

@ -16,6 +16,8 @@ Item {
property string defaultAccount: "cb73d9408c4720e230387d956eb0f829d8a4dd2c1055f96257167e14e7169074" //support for old project property string defaultAccount: "cb73d9408c4720e230387d956eb0f829d8a4dd2c1055f96257167e14e7169074" //support for old project
function fromPlainStateItem(s) { function fromPlainStateItem(s) {
console.log("èèèèèèèèèèèè");
console.log(s);
if (!s.accounts) if (!s.accounts)
s.accounts = [stateListModel.newAccount("1000000", QEther.Ether, defaultAccount)]; //support for old project s.accounts = [stateListModel.newAccount("1000000", QEther.Ether, defaultAccount)]; //support for old project
if (!s.contracts) if (!s.contracts)
@ -137,7 +139,6 @@ Item {
} }
function toPlainTransactionItem(t) { function toPlainTransactionItem(t) {
console.log(JSON.stringify(t));
var r = { var r = {
type: t.type, type: t.type,
contractId: t.contractId, contractId: t.contractId,

BIN
mix/qml/img/duplicateIcon.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1020 B

BIN
mix/qml/img/duplicateIcon@2x.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

BIN
mix/qml/img/newIcon.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 801 B

BIN
mix/qml/img/newIcon@2x.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

BIN
mix/qml/img/recycle-discard.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 723 B

BIN
mix/qml/img/recycle-discard@2x.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

BIN
mix/qml/img/recycle-icon.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 697 B

BIN
mix/qml/img/recycle-icon@2x.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

BIN
mix/qml/img/recycle-keep.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 904 B

BIN
mix/qml/img/recycle-keep@2x.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

BIN
mix/qml/img/restoreIcon.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
mix/qml/img/restoreIcon@2x.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

BIN
mix/qml/img/saveIcon.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

BIN
mix/qml/img/saveIcon@2x.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

12
mix/res.qrc

@ -68,5 +68,17 @@
<file>qml/img/warningicon.png</file> <file>qml/img/warningicon.png</file>
<file>qml/img/warningicon@2x.png</file> <file>qml/img/warningicon@2x.png</file>
<file>qml/QAddressView.qml</file> <file>qml/QAddressView.qml</file>
<file>qml/img/recycle-discard.png</file>
<file>qml/img/recycle-discard@2x.png</file>
<file>qml/img/recycle-icon.png</file>
<file>qml/img/recycle-icon@2x.png</file>
<file>qml/img/recycle-keep.png</file>
<file>qml/img/recycle-keep@2x.png</file>
<file>qml/img/restoreIcon.png</file>
<file>qml/img/restoreIcon@2x.png</file>
<file>qml/img/saveIcon.png</file>
<file>qml/img/saveIcon@2x.png</file>
<file>qml/img/duplicateIcon.png</file>
<file>qml/img/duplicateIcon@2x.png</file>
</qresource> </qresource>
</RCC> </RCC>

Loading…
Cancel
Save