Browse Source

Merge pull request #2220 from yann300/designDebugPanel

Mix - Scenario Panel: UI changes
cl-refactor
Arkadiy Paronyan 9 years ago
parent
commit
4440938605
  1. 2
      libethereum/BlockChain.cpp
  2. 277
      mix/qml/Block.qml
  3. 316
      mix/qml/BlockChain.qml
  4. 10
      mix/qml/MainContent.qml
  5. 77
      mix/qml/ScenarioButton.qml
  6. 16
      mix/qml/ScenarioExecution.qml
  7. 401
      mix/qml/ScenarioLoader.qml
  8. 5
      mix/qml/WebPreview.qml

2
libethereum/BlockChain.cpp

@ -391,7 +391,7 @@ ImportRoute BlockChain::import(bytes const& _block, OverlayDB const& _db, Import
try
#endif
{
block = verifyBlock(_block, m_onBad);
block = verifyBlock(_block, m_onBad, _ir);
}
#if ETH_CATCH
catch (Exception& ex)

277
mix/qml/Block.qml

@ -16,23 +16,24 @@ ColumnLayout
property int number
property int blockWidth: Layout.preferredWidth - statusWidth - horizontalMargin
property int horizontalMargin: 10
property int trHeight: 30
property int trHeight: 35
spacing: 0
property int openedTr: 0
property int blockIndex
property variant scenario
property string labelColor: "#414141"
function calculateHeight()
{
if (transactions)
{
if (index >= 0)
return 30 + 30 * transactions.count + openedTr
return trHeight + trHeight * transactions.count + openedTr
else
return 30
return trHeight
}
else
return 30
return trHeight
}
onOpenedTrChanged:
@ -41,31 +42,67 @@ ColumnLayout
height = calculateHeight()
}
DebuggerPaneStyle {
id: dbgStyle
}
Rectangle
{
id: top
Layout.preferredWidth: blockWidth
height: 10
anchors.bottom: rowHeader.top
color: "#DEDCDC"
radius: 15
anchors.left: parent.left
anchors.leftMargin: statusWidth
anchors.bottomMargin: -5
}
RowLayout
{
Layout.preferredHeight: trHeight
Layout.preferredWidth: blockWidth
id: rowHeader
spacing: 0
Rectangle
{
color: "#DEDCDC"
Layout.preferredWidth: blockWidth
Layout.preferredHeight: trHeight
radius: 4
color: "#DEDCDC"
anchors.left: parent.left
anchors.leftMargin: statusWidth + 5
anchors.leftMargin: statusWidth
Label {
anchors.verticalCenter: parent.verticalCenter
anchors.left: parent.left
anchors.leftMargin: horizontalMargin
font.pointSize: dbgStyle.absoluteSize(1)
color: "#adadad"
text:
{
if (status === "mined")
if (number === -2)
return qsTr("STARTING PARAMETERS")
else if (status === "mined")
return qsTr("BLOCK") + " " + number
else
return qsTr("BLOCK") + " pending"
return qsTr("PENDING TRANSACTIONS")
}
}
Label
{
text: qsTr("EDIT")
color: "#1397da"
anchors.verticalCenter: parent.verticalCenter
anchors.right: parent.right
anchors.rightMargin: 14
MouseArea
{
anchors.fill: parent
onClicked:
{
// load edit block panel
}
}
}
}
@ -75,11 +112,11 @@ ColumnLayout
{
id: transactionRepeater
model: transactions
RowLayout
{
id: rowTransaction
Layout.preferredHeight: trHeight
spacing: 0
function displayContent()
{
logsText.text = ""
@ -99,7 +136,7 @@ ColumnLayout
var p = log.param.get(i)
logsText.text += p.name + " = " + p.value + " - indexed:" + p.indexed + "\n"
}
else{
else {
logsText.text += "From : " + log.address + "\n"
}
}
@ -112,18 +149,19 @@ ColumnLayout
{
id: trSaveStatus
Layout.preferredWidth: statusWidth
Layout.preferredHeight: trHeight
Layout.preferredHeight: parent.height
color: "transparent"
anchors.top: parent.top
property bool saveStatus
Image {
anchors.top: parent.top
anchors.left: parent.left
anchors.leftMargin: -9
anchors.topMargin: -9
id: saveStatusImage
source: "qrc:/qml/img/recyclediscard@2x.png"
width: statusWidth
width: statusWidth + 20
fillMode: Image.PreserveAspectFit
anchors.verticalCenter: parent.verticalCenter
anchors.horizontalCenter: parent.horizontalCenter
}
Component.onCompleted:
@ -160,45 +198,76 @@ ColumnLayout
color: "#DEDCDC"
id: rowContentTr
anchors.top: parent.top
MouseArea
{
anchors.fill: parent
onDoubleClicked:
{
transactionDialog.stateAccounts = scenario.accounts
transactionDialog.execute = false
transactionDialog.open(index, blockIndex, transactions.get(index))
}
}
ColumnLayout
{
anchors.top: parent.top
spacing: 10
width: parent.width
spacing: 20
RowLayout
{
anchors.top: parent.top
anchors.verticalCenter: parent.verticalCenter
spacing: cellSpacing
Text
Layout.fillWidth: true
Rectangle
{
id: hash
Layout.preferredWidth: fromWidth
anchors.left: parent.left
anchors.leftMargin: horizontalMargin
Layout.preferredWidth: fromWidth
elide: Text.ElideRight
maximumLineCount: 1
text: {
if (index >= 0)
return transactions.get(index).sender
else
return ""
Text
{
id: hash
width: parent.width - 30
elide: Text.ElideRight
anchors.verticalCenter: parent.verticalCenter
maximumLineCount: 1
color: labelColor
font.pointSize: dbgStyle.absoluteSize(1)
font.bold: true
text: {
if (index >= 0)
return transactions.get(index).sender
else
return ""
}
}
}
Text
Rectangle
{
id: func
text: {
if (index >= 0)
parent.userFrienldyToken(transactions.get(index).label)
else
return ""
}
elide: Text.ElideRight
maximumLineCount: 1
Layout.preferredWidth: toWidth
Text
{
id: func
text: {
if (index >= 0)
parent.parent.userFrienldyToken(transactions.get(index).label)
else
return ""
}
elide: Text.ElideRight
anchors.verticalCenter: parent.verticalCenter
color: labelColor
font.pointSize: dbgStyle.absoluteSize(1)
font.bold: true
maximumLineCount: 1
width: parent.width
}
}
function userFrienldyToken(value)
{
if (value && value.indexOf("<") === 0)
@ -212,17 +281,25 @@ ColumnLayout
return value
}
Text
Rectangle
{
id: returnValue
elide: Text.ElideRight
maximumLineCount: 1
Layout.preferredWidth: valueWidth
text: {
if (index >= 0 && transactions.get(index).returned)
return transactions.get(index).returned
else
return ""
Text
{
id: returnValue
elide: Text.ElideRight
anchors.verticalCenter: parent.verticalCenter
maximumLineCount: 1
color: labelColor
font.bold: true
font.pointSize: dbgStyle.absoluteSize(1)
width: parent.width -30
text: {
if (index >= 0 && transactions.get(index).returned)
return transactions.get(index).returned
else
return ""
}
}
}
@ -236,7 +313,11 @@ ColumnLayout
{
id: logs
anchors.left: parent.left
anchors.verticalCenter: parent.verticalCenter
anchors.leftMargin: 10
color: labelColor
font.bold: true
font.pointSize: dbgStyle.absoluteSize(1)
text: {
if (index >= 0 && transactions.get(index).logs && transactions.get(index).logs.count)
return transactions.get(index).logs.count
@ -251,60 +332,6 @@ ColumnLayout
}
}
}
Rectangle
{
Layout.preferredWidth: debugActionWidth
Layout.preferredHeight: trHeight - 10
color: "transparent"
Image {
source: "qrc:/qml/img/edit.png"
width: 18
fillMode: Image.PreserveAspectFit
anchors.verticalCenter: parent.verticalCenter
anchors.horizontalCenter: parent.horizontalCenter
}
MouseArea
{
anchors.fill: parent
onClicked:
{
transactionDialog.stateAccounts = scenario.accounts
transactionDialog.execute = false
transactionDialog.open(index, blockIndex, transactions.get(index))
}
}
}
Rectangle
{
Layout.preferredWidth: debugActionWidth
Layout.preferredHeight: trHeight - 10
color: "transparent"
Image {
id: debugImg
source: "qrc:/qml/img/rightarrow@2x.png"
width: statusWidth
fillMode: Image.PreserveAspectFit
anchors.verticalCenter: parent.verticalCenter
anchors.horizontalCenter: parent.horizontalCenter
visible: transactions.get(index).recordIndex !== undefined
}
MouseArea
{
anchors.fill: parent
onClicked:
{
if (transactions.get(index).recordIndex !== undefined)
{
debugTrRequested = [ blockIndex, index ]
clientModel.debugRecord(transactions.get(index).recordIndex);
}
}
}
}
}
RowLayout
@ -340,7 +367,53 @@ ColumnLayout
}
}
}
Rectangle
{
width: debugActionWidth
height: trHeight
anchors.left: rowContentTr.right
anchors.topMargin: -6
anchors.top: rowContentTr.top
anchors.leftMargin: -50
color: "transparent"
Image {
id: debugImg
source: "qrc:/qml/img/rightarrow@2x.png"
width: debugActionWidth
fillMode: Image.PreserveAspectFit
anchors.verticalCenter: parent.verticalCenter
anchors.horizontalCenter: parent.horizontalCenter
visible: transactions.get(index).recordIndex !== undefined
}
MouseArea
{
anchors.fill: parent
onClicked:
{
if (transactions.get(index).recordIndex !== undefined)
{
debugTrRequested = [ blockIndex, index ]
clientModel.debugRecord(transactions.get(index).recordIndex);
}
}
}
}
}
}
Rectangle
{
id: right
Layout.preferredWidth: blockWidth
height: 10
anchors.top: parent.bottom
anchors.topMargin: 5
color: "#DEDCDC"
radius: 15
anchors.left: parent.left
anchors.leftMargin: statusWidth
}
}

316
mix/qml/BlockChain.qml

@ -18,15 +18,27 @@ ColumnLayout {
property int previousWidth
property variant debugTrRequested: []
signal chainChanged
signal chainReloaded
Connections
{
target: codeModel
onContractRenamed: {
rebuild.startBlinking()
}
onNewContractCompiled: {
rebuild.startBlinking()
}
}
onChainChanged: {
reBuildNeeded.start()
rebuild.startBlinking()
}
onWidthChanged:
{
if (width <= 630 || previousWidth <= 630)
var minWidth = scenarioMinWidth - 20 // margin
if (width <= minWidth || previousWidth <= minWidth)
{
fromWidth = 100
toWidth = 100
@ -47,7 +59,7 @@ ColumnLayout {
if (!scenario)
return;
if (model)
chainChanged()
rebuild.startBlinking()
model = scenario
blockModel.clear()
for (var b in model.blocks)
@ -56,11 +68,11 @@ ColumnLayout {
}
property int statusWidth: 30
property int fromWidth: 100
property int fromWidth: 150
property int toWidth: 100
property int valueWidth: 200
property int logsWidth: 50
property int debugActionWidth: 50
property int logsWidth: 40
property int debugActionWidth: 40
property int horizontalMargin: 10
property int cellSpacing: 10
@ -68,23 +80,30 @@ ColumnLayout {
{
id: header
spacing: 0
Layout.preferredHeight: 25
Image {
id: debugImage
source: "qrc:/qml/img/recycleicon@2x.png"
Layout.preferredHeight: 30
Rectangle
{
Layout.preferredWidth: statusWidth
Layout.preferredHeight: 25
fillMode: Image.PreserveAspectFit
Layout.preferredHeight: parent.height
color: "transparent"
Image {
id: debugImage
anchors.verticalCenter: parent.verticalCenter
anchors.horizontalCenter: parent.horizontalCenter
source: "qrc:/qml/img/recycleicon@2x.png"
width: statusWidth + 20
fillMode: Image.PreserveAspectFit
}
}
Rectangle
{
Layout.preferredWidth: fromWidth + cellSpacing
Layout.preferredWidth: fromWidth
Label
{
anchors.verticalCenter: parent.verticalCenter
text: "From"
anchors.left: parent.left
anchors.leftMargin: horizontalMargin + 5
anchors.leftMargin: horizontalMargin
}
}
Label
@ -120,12 +139,25 @@ ColumnLayout {
{
id: blockChainScrollView
anchors.fill: parent
anchors.topMargin: 10
anchors.topMargin: 8
ColumnLayout
{
id: blockChainLayout
width: parent.width
spacing: 10
spacing: 20
Block
{
scenario: blockChainPanel.model
Layout.preferredWidth: blockChainScrollView.width
Layout.preferredHeight: 60
blockIndex: -1
transactions: []
status: ""
number: -2
trHeight: 60
}
Repeater // List of blocks
{
id: blockChainRepeater
@ -218,158 +250,171 @@ ColumnLayout {
Layout.preferredWidth: parent.width
RowLayout
{
width: 4 * 100
anchors.horizontalCenter: parent.horizontalCenter
anchors.top: parent.top
anchors.topMargin: 10
spacing: 0
ScenarioButton {
id: rebuild
text: qsTr("Rebuild")
onClicked:
{
if (ensureNotFuturetime.running)
return;
reBuildNeeded.stop()
var retBlocks = [];
var bAdded = 0;
for (var j = 0; j < model.blocks.length; j++)
spacing: 20
Rectangle {
Layout.preferredWidth: 100
Layout.preferredHeight: 30
ScenarioButton {
id: rebuild
text: qsTr("Rebuild")
width: 100
height: 30
roundLeft: true
roundRight: true
onClicked:
{
var b = model.blocks[j];
var block = {
hash: b.hash,
number: b.number,
transactions: [],
status: b.status
}
for (var k = 0; k < model.blocks[j].transactions.length; k++)
if (ensureNotFuturetime.running)
return;
stopBlinking()
var retBlocks = [];
var bAdded = 0;
for (var j = 0; j < model.blocks.length; j++)
{
if (blockModel.get(j).transactions.get(k).saveStatus)
var b = model.blocks[j];
var block = {
hash: b.hash,
number: b.number,
transactions: [],
status: b.status
}
for (var k = 0; k < model.blocks[j].transactions.length; k++)
{
var tr = model.blocks[j].transactions[k]
tr.saveStatus = true
block.transactions.push(tr);
if (blockModel.get(j).transactions.get(k).saveStatus)
{
var tr = model.blocks[j].transactions[k]
tr.saveStatus = true
block.transactions.push(tr);
}
}
if (block.transactions.length > 0)
{
bAdded++
block.number = bAdded
block.status = "mined"
retBlocks.push(block)
}
}
if (block.transactions.length > 0)
if (retBlocks.length === 0)
retBlocks.push(projectModel.stateListModel.createEmptyBlock())
else
{
bAdded++
block.number = bAdded
block.status = "mined"
retBlocks.push(block)
var last = retBlocks[retBlocks.length - 1]
last.number = -1
last.status = "pending"
}
model.blocks = retBlocks
blockModel.clear()
for (var j = 0; j < model.blocks.length; j++)
blockModel.append(model.blocks[j])
ensureNotFuturetime.start()
clientModel.setupScenario(model);
}
if (retBlocks.length === 0)
retBlocks.push(projectModel.stateListModel.createEmptyBlock())
else
{
var last = retBlocks[retBlocks.length - 1]
last.number = -1
last.status = "pending"
}
buttonShortcut: ""
sourceImg: "qrc:/qml/img/recycleicon@2x.png"
}
}
model.blocks = retBlocks
blockModel.clear()
for (var j = 0; j < model.blocks.length; j++)
blockModel.append(model.blocks[j])
ensureNotFuturetime.start()
clientModel.setupScenario(model);
Rectangle
{
Layout.preferredWidth: 200
Layout.preferredHeight: 30
color: "transparent"
ScenarioButton {
id: addTransaction
text: qsTr("Add Tx")
onClicked:
{
var lastBlock = model.blocks[model.blocks.length - 1];
if (lastBlock.status === "mined")
{
var newblock = projectModel.stateListModel.createEmptyBlock()
blockModel.appendBlock(newblock)
model.blocks.push(newblock);
}
var item = TransactionHelper.defaultTransaction()
transactionDialog.stateAccounts = model.accounts
transactionDialog.execute = true
transactionDialog.open(model.blocks[model.blocks.length - 1].transactions.length, model.blocks.length - 1, item)
}
width: 100
height: 30
buttonShortcut: ""
sourceImg: "qrc:/qml/img/sendtransactionicon@2x.png"
roundLeft: true
roundRight: false
}
Layout.preferredWidth: 100
Layout.preferredHeight: 30
buttonShortcut: ""
sourceImg: "qrc:/qml/img/recycleicon@2x.png"
Timer
{
id: reBuildNeeded
repeat: true
id: ensureNotFuturetime
interval: 1000
repeat: false
running: false
onTriggered: {
if (!parent.fillColor || parent.fillColor === "white")
parent.fillColor = "orange"
else
parent.fillColor = "white"
}
onRunningChanged: {
if (!running)
parent.fillColor = "white"
}
}
}
ScenarioButton {
id: addTransaction
text: qsTr("Add Transaction")
onClicked:
Rectangle
{
var lastBlock = model.blocks[model.blocks.length - 1];
if (lastBlock.status === "mined")
{
var newblock = projectModel.stateListModel.createEmptyBlock()
blockModel.appendBlock(newblock)
model.blocks.push(newblock);
}
var item = TransactionHelper.defaultTransaction()
transactionDialog.stateAccounts = model.accounts
transactionDialog.execute = true
transactionDialog.open(model.blocks[model.blocks.length - 1].transactions.length, model.blocks.length - 1, item)
width: 1
height: parent.height
anchors.right: addBlockBtn.left
color: "#ededed"
}
Layout.preferredWidth: 100
Layout.preferredHeight: 30
buttonShortcut: ""
sourceImg: "qrc:/qml/img/sendtransactionicon@2x.png"
}
Timer
{
id: ensureNotFuturetime
interval: 1000
repeat: false
running: false
}
ScenarioButton {
id: addBlockBtn
text: qsTr("Add Block")
onClicked:
{
if (ensureNotFuturetime.running)
return
if (clientModel.mining || clientModel.running)
return
if (model.blocks.length > 0)
ScenarioButton {
id: addBlockBtn
text: qsTr("Add Block..")
anchors.left: addTransaction.right
roundLeft: false
roundRight: true
onClicked:
{
var lastBlock = model.blocks[model.blocks.length - 1]
if (lastBlock.status === "pending")
if (ensureNotFuturetime.running)
return
if (clientModel.mining || clientModel.running)
return
if (model.blocks.length > 0)
{
ensureNotFuturetime.start()
clientModel.mine()
var lastBlock = model.blocks[model.blocks.length - 1]
if (lastBlock.status === "pending")
{
ensureNotFuturetime.start()
clientModel.mine()
}
else
addNewBlock()
}
else
addNewBlock()
}
else
addNewBlock()
}
function addNewBlock()
{
var block = projectModel.stateListModel.createEmptyBlock()
model.blocks.push(block)
blockModel.appendBlock(block)
}
width: 100
height: 30
function addNewBlock()
{
var block = projectModel.stateListModel.createEmptyBlock()
model.blocks.push(block)
blockModel.appendBlock(block)
buttonShortcut: ""
sourceImg: "qrc:/qml/img/addblock@2x.png"
}
Layout.preferredWidth: 100
Layout.preferredHeight: 30
buttonShortcut: ""
sourceImg: "qrc:/qml/img/addblock@2x.png"
}
Connections
{
target: clientModel
@ -412,7 +457,6 @@ ColumnLayout {
return;
}
}
// tr is not in the list.
var itemTr = TransactionHelper.defaultTransaction()
itemTr.saveStatus = false
@ -438,7 +482,7 @@ ColumnLayout {
ScenarioButton {
id: newAccount
text: qsTr("New Account")
text: qsTr("New Account..")
onClicked: {
model.accounts.push(projectModel.stateListModel.newAccount("1000000", QEther.Ether))
}
@ -446,6 +490,8 @@ ColumnLayout {
Layout.preferredHeight: 30
buttonShortcut: ""
sourceImg: "qrc:/qml/img/newaccounticon@2x.png"
roundLeft: true
roundRight: true
}
}
}

10
mix/qml/MainContent.qml

@ -31,6 +31,7 @@ Rectangle {
property alias codeEditor: codeEditor
property bool webViewHorizontal: codeWebSplitter.orientation === Qt.Vertical //vertical splitter positions elements vertically, splits screen horizontally
property bool firstCompile: true
property int scenarioMinWidth: 590
Connections {
target: codeModel
@ -110,6 +111,7 @@ Rectangle {
property alias webHeight: webPreview.height
property alias showProjectView: projectList.visible
property bool runOnProjectLoad: true
property int scenarioMinWidth: scenarioMinWidth
}
ColumnLayout
@ -205,7 +207,7 @@ Rectangle {
visible: false;
Layout.fillHeight: true
Keys.onEscapePressed: visible = false
Layout.minimumWidth: 650
Layout.minimumWidth: scenarioMinWidth
anchors.right: parent.right
}
@ -215,7 +217,7 @@ Rectangle {
visible: false
Layout.fillHeight: true
Keys.onEscapePressed: visible = false
Layout.minimumWidth: 650
Layout.minimumWidth: scenarioMinWidth
anchors.right: parent.right
}
@ -224,10 +226,9 @@ Rectangle {
onDebugDataReady: {
scenarioExe.visible = false
debugPanel.visible = true
debugPanel.width = scenarioExe.width
if (scenarioExe.bc.debugTrRequested)
{
debugPanel.setTr(scenarioExe.bc.model.blocks[scenarioExe.bc.debugTrRequested[0]].transactions[scenarioExe.bc.debugTrRequested[1]])
}
}
}
@ -236,6 +237,7 @@ Rectangle {
onPanelClosed: {
debugPanel.visible = false
scenarioExe.visible = true
scenarioExe.width = debugPanel.width
}
}
}

77
mix/qml/ScenarioButton.qml

@ -2,6 +2,7 @@ import QtQuick 2.2
import QtQuick.Controls 1.1
import QtQuick.Layouts 1.0
import QtQuick.Controls.Styles 1.1
import QtGraphicalEffects 1.0
Rectangle {
id: buttonActionContainer
@ -9,15 +10,68 @@ Rectangle {
property string buttonShortcut
property string sourceImg
property string fillColor
property alias roundLeft: left.visible
property alias roundRight: right.visible
signal clicked
function startBlinking()
{
if (!blinkTimer.running)
blinkTimer.start()
}
function stopBlinking()
{
blinkTimer.stop()
}
Rectangle
{
id: left
width: 10
height: parent.height
anchors.left: parent.left
anchors.leftMargin: -8
radius: 15
}
Rectangle {
id: contentRectangle
anchors.fill: parent
border.color: "#cccccc"
border.width: 1
radius: 4
color: parent.fillColor ? parent.fillColor : "white"
color: "white"
property variant colorGradient: ["#FFFFFF", "#FFFEFC", "#FFFDF9", "#FFFCF7", "#FFFBF4", "#FFFAF2", "#FFF9EF", "#FFF8EC", "#FFF7EA", "#FFF6E7", "#FFF5E5", "#FFF5E2", "#FFF4E0", "#FFF3DD", "#FFF2DA", "#FFF1D8", "#FFF0D5", "#FFEFD3", "#FFEED0", "#FFEDCE", "#FFECCB", "#FFEBC8", "#FFEBC6", "#FFEAC3", "#FFE9C1", "#FFE8BE", "#FFE7BC", "#FFE6B9", "#FFE5B6", "#FFE4B4", "#FFE3B1", "#FFE2AF", "#FFE1AC", "#FFE1AA", "#FFE0A7", "#FFDFA4", "#FFDEA2", "#FFDD9F", "#FFDC9D", "#FFDB9A", "#FFDA97", "#FFD995", "#FFD892", "#FFD790", "#FFD78D", "#FFD68B", "#FFD588", "#FFD485", "#FFD383", "#FFD280", "#FFD17E", "#FFD07B", "#FFCF79", "#FFCE76", "#FFCD73", "#FFCD71", "#FFCC6E", "#FFCB6C", "#FFCA69", "#FFC967", "#FFC864", "#FFC761", "#FFC65F", "#FFC55C", "#FFC45A", "#FFC357", "#FFC355", "#FFC252", "#FFC14F", "#FFC04D", "#FFBF4A", "#FFBE48", "#FFBD45", "#FFBC42", "#FFBB40", "#FFBA3D", "#FFB93B", "#FFB938", "#FFB836", "#FFB733", "#FFB630", "#FFB52E", "#FFB42B", "#FFB329", "#FFB226", "#FFB124", "#FFB021", "#FFAF1E", "#FFAF1C", "#FFAE19", "#FFAD17", "#FFAC14", "#FFAB12", "#FFAA0F", "#FFA90C", "#FFA80A", "#FFA707", "#FFA605", "#FFA502", "#FFA500"]
Timer
{
id: blinkTimer
repeat: true
interval: 40
running: false
property int index: 0
property int direction: 1
onTriggered: {
index = index + direction
var color = parent.colorGradient[index]
left.color = color
right.color = color
parent.color = parent.colorGradient[index]
if (index >= parent.colorGradient.length - 1)
direction = -1
else if (index <= 0)
direction = 1
}
onRunningChanged: {
if (!running)
{
left.color = "white"
right.color = "white"
parent.color = "white"
index = 0
direction = 1
}
}
}
Image {
id: debugImage
anchors {
@ -25,12 +79,11 @@ Rectangle {
right: parent.right
top: parent.top
bottom: parent.bottom
bottomMargin: debugImg.pressed ? 0 : 2;
bottomMargin: debugImg.pressed ? -2 : 0;
topMargin: debugImg.pressed ? 2 : 0;
}
source: sourceImg
fillMode: Image.PreserveAspectFit
height: 30
}
Button {
@ -53,12 +106,22 @@ Rectangle {
}
}
Rectangle
{
id: right
width: 10
height: parent.height
anchors.left: contentRectangle.right
anchors.leftMargin: -8
radius: 15
}
Rectangle
{
anchors.top: contentRectangle.bottom
anchors.topMargin: 15
width: parent.width
Text
Label
{
text: buttonActionContainer.text
anchors.centerIn: parent

16
mix/qml/ScenarioExecution.qml

@ -28,14 +28,23 @@ Rectangle {
spacing: 10
ScenarioLoader
{
height: 70
height: 100
width: parent.width
id: loader
}
Connections
{
target: blockChain
onChainChanged:
{
loader.needSaveOrReload()
}
}
Rectangle
{
width: parent.width
width: parent.parent.width
height: 1
color: "#cccccc"
}
@ -43,7 +52,8 @@ Rectangle {
Connections
{
target: loader
onLoaded: {
onLoaded:
{
blockChain.load(scenario)
}
}

401
mix/qml/ScenarioLoader.qml

@ -10,166 +10,329 @@ import "js/Debugger.js" as Debugger
import "js/ErrorLocationFormater.js" as ErrorLocationFormater
import "."
RowLayout
ColumnLayout
{
id: blockChainSelector
signal restored(variant scenario)
signal saved(variant scenario)
signal duplicated(variant scenario)
signal loaded(variant scenario)
signal renamed(variant scenario)
spacing: 0
function init()
{
scenarioList.load()
}
id: blockChainSelector
Dialog {
id: newStateWin
modality: Qt.ApplicationModal
title: qsTr("New Project");
width: 320
height: 120
function needSaveOrReload()
{
editStatus.visible = true
}
visible: false
Rectangle
{
Layout.fillWidth: true
Layout.preferredHeight: 30
color: "transparent"
Rectangle
{
anchors.verticalCenter: parent.verticalCenter
anchors.horizontalCenter: parent.horizontalCenter
color: "transparent"
Label
{
anchors.verticalCenter: parent.verticalCenter
anchors.horizontalCenter: parent.horizontalCenter
id: scenarioName
font.bold: true
}
contentItem: Rectangle {
anchors.fill: parent
anchors.margins: 10
RowLayout {
TextInput
{
id: scenarioNameEdit
visible: false
anchors.verticalCenter: parent.verticalCenter
Text {
text: qsTr("Name:")
anchors.horizontalCenter: parent.horizontalCenter
Keys.onEnterPressed:
{
save()
}
Rectangle
function edit()
{
Layout.preferredWidth: 250
Layout.preferredHeight: parent.height
border.width: 1
border.color: "#cccccc"
TextInput
{
anchors.fill: parent
id: stateName
}
editIconRect.anchors.left = scenarioNameEdit.right
editStatus.parent.anchors.left = scenarioNameEdit.right
scenarioNameEdit.forceActiveFocus()
}
function save()
{
editIconRect.anchors.left = scenarioName.right
editStatus.parent.anchors.left = scenarioName.right
scenarioName.text = scenarioNameEdit.text
scenarioName.visible = true
scenarioNameEdit.visible = false
projectModel.stateListModel.getState(scenarioList.currentIndex).title = scenarioName.text
projectModel.saveProjectFile()
saved(state)
scenarioList.model.get(scenarioList.currentIndex).title = scenarioName.text
scenarioList.currentIndex = scenarioList.currentIndex
renamed(projectModel.stateListModel.getState(scenarioList.currentIndex))
}
}
RowLayout
Connections
{
anchors.bottom: parent.bottom
anchors.right: parent.right;
function acceptAndClose()
target: blockChainSelector
onLoaded:
{
var item = projectModel.stateListModel.createDefaultState();
item.title = stateName.text
projectModel.stateListModel.appendState(item)
projectModel.stateListModel.save()
close()
scenarioList.currentIndex = projectModel.stateListModel.count - 1
scenarioName.text = scenario.title
scenarioNameEdit.text = scenario.title
}
}
function close()
{
newStateWin.close()
stateName.text = ""
Rectangle
{
anchors.left: scenarioName.right
anchors.top: scenarioName.top
anchors.leftMargin: 2
Layout.preferredWidth: 20
Text {
id: editStatus
text: "*"
visible: false
}
}
Button {
id: okButton;
enabled: stateName.text !== ""
text: qsTr("OK");
onClicked: {
parent.acceptAndClose();
Rectangle
{
id: editIconRect
anchors.left: scenarioName.right
anchors.leftMargin: 15
Image {
source: "qrc:/qml/img/edit.png"
width: 10
fillMode: Image.PreserveAspectFit
anchors.verticalCenter: parent.verticalCenter
anchors.horizontalCenter: parent.horizontalCenter
MouseArea
{
anchors.fill: parent
onClicked:
{
scenarioName.visible = !scenarioName.visible
scenarioNameEdit.visible = !scenarioNameEdit.visible
if (!scenarioNameEdit.visible)
scenarioNameEdit.save()
else
scenarioNameEdit.edit()
}
}
}
Button {
text: qsTr("Cancel");
onClicked: parent.close();
}
}
}
}
ComboBox
RowLayout
{
id: scenarioList
model: projectModel.stateListModel
textRole: "title"
onCurrentIndexChanged:
{
restoreScenario.restore()
}
Layout.preferredWidth: 560
anchors.horizontalCenter: parent.horizontalCenter
Layout.preferredHeight: 50
spacing: 0
function load()
Row
{
var state = projectModel.stateListModel.getState(currentIndex)
loaded(state)
}
}
Layout.preferredWidth: 100 * 5
Layout.preferredHeight: 50
spacing: 15
Row
{
Layout.preferredWidth: 100 * 4
Layout.preferredHeight: 30
spacing: 0
ScenarioButton {
id: restoreScenario
width: 100
height: 30
buttonShortcut: ""
sourceImg: "qrc:/qml/img/restoreicon@2x.png"
onClicked: {
restore()
}
text: qsTr("Restore")
function restore()
Rectangle
{
var state = projectModel.stateListModel.reloadStateFromFromProject(scenarioList.currentIndex)
restored(state)
loaded(state)
}
}
color: "transparent"
width: 251
height: 30
Rectangle
{
width: 10
height: parent.height
anchors.right: scenarioList.left
anchors.rightMargin: -8
radius: 15
}
ScenarioButton {
id: saveScenario
text: qsTr("Save")
onClicked: {
projectModel.saveProjectFile()
saved(state)
}
width: 100
height: 30
buttonShortcut: ""
sourceImg: "qrc:/qml/img/saveicon@2x.png"
}
ComboBox
{
id: scenarioList
model: projectModel.stateListModel
textRole: "title"
height: parent.height
width: 150
onCurrentIndexChanged:
{
restoreScenario.restore()
}
ScenarioButton
{
id: duplicateScenario
text: qsTr("Duplicate")
onClicked: {
projectModel.stateListModel.duplicateState(scenarioList.currentIndex)
duplicated(state)
function load()
{
var state = projectModel.stateListModel.getState(currentIndex)
loaded(state)
}
style: ComboBoxStyle {
background: Rectangle {
color: "white"
anchors.fill: parent
}
label: Rectangle {
anchors.fill: parent
color: "white"
Label {
id: comboLabel
maximumLineCount: 1
elide: Text.ElideRight
width: parent.width
anchors.verticalCenter: parent.verticalCenter
anchors.horizontalCenter: parent.horizontalCenter
text: {
if (projectModel.stateListModel.getState(scenarioList.currentIndex))
return projectModel.stateListModel.getState(scenarioList.currentIndex).title
else
return ""
}
Connections {
target: blockChainSelector
onLoaded: {
comboLabel.text = projectModel.stateListModel.getState(scenarioList.currentIndex).title
}
onRenamed: {
comboLabel.text = scenario.title
}
}
}
}
}
}
Rectangle
{
width: 1
height: parent.height
anchors.right: addScenario.left
color: "#ededed"
}
ScenarioButton {
id: addScenario
anchors.left: scenarioList.right
width: 100
height: parent.height
buttonShortcut: ""
sourceImg: "qrc:/qml/img/restoreicon@2x.png"
onClicked: {
var item = projectModel.stateListModel.createDefaultState();
item.title = qsTr("New Scenario")
projectModel.stateListModel.appendState(item)
projectModel.stateListModel.save()
scenarioList.currentIndex = projectModel.stateListModel.count - 1
scenarioNameEdit.edit()
}
text: qsTr("New..")
roundRight: true
roundLeft: false
}
}
width: 100
height: 30
buttonShortcut: ""
sourceImg: "qrc:/qml/img/duplicateicon@2x.png"
}
ScenarioButton {
id: addScenario
width: 100
height: 30
buttonShortcut: ""
sourceImg: "qrc:/qml/img/plus.png"
onClicked: {
newStateWin.open()
Rectangle
{
width: 100 * 3
height: 30
color: "transparent"
Rectangle
{
width: 10
height: parent.height
anchors.right: restoreScenario.left
anchors.rightMargin: -4
radius: 15
}
ScenarioButton {
id: restoreScenario
width: 100
height: parent.height
buttonShortcut: ""
sourceImg: "qrc:/qml/img/restoreicon@2x.png"
onClicked: {
restore()
}
text: qsTr("Restore")
function restore()
{
var state = projectModel.stateListModel.reloadStateFromFromProject(scenarioList.currentIndex)
if (state)
{
editStatus.visible = false
restored(state)
loaded(state)
}
}
roundRight: false
roundLeft: true
}
Rectangle
{
width: 1
height: parent.height
anchors.right: saveScenario.left
color: "#ededed"
}
ScenarioButton {
id: saveScenario
anchors.left: restoreScenario.right
text: qsTr("Save")
onClicked: {
projectModel.saveProjectFile()
saved(state)
}
width: 100
height: parent.height
buttonShortcut: ""
sourceImg: "qrc:/qml/img/saveicon@2x.png"
roundRight: false
roundLeft: false
}
Rectangle
{
width: 1
height: parent.height
anchors.right: duplicateScenario.left
color: "#ededed"
}
ScenarioButton
{
id: duplicateScenario
anchors.left: saveScenario.right
text: qsTr("Duplicate")
onClicked: {
projectModel.stateListModel.duplicateState(scenarioList.currentIndex)
duplicated(state)
}
width: 100
height: parent.height
buttonShortcut: ""
sourceImg: "qrc:/qml/img/duplicateicon@2x.png"
roundRight: true
roundLeft: false
}
}
text: qsTr("New")
}
}
}

5
mix/qml/WebPreview.qml

@ -89,11 +89,6 @@ Item {
}
}
Connections {
target: clientModel
onRunComplete: reload();
}
Connections {
target: codeModel
onContractInterfaceChanged: reload();

Loading…
Cancel
Save