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 try
#endif #endif
{ {
block = verifyBlock(_block, m_onBad); block = verifyBlock(_block, m_onBad, _ir);
} }
#if ETH_CATCH #if ETH_CATCH
catch (Exception& ex) catch (Exception& ex)

277
mix/qml/Block.qml

@ -16,23 +16,24 @@ ColumnLayout
property int number property int number
property int blockWidth: Layout.preferredWidth - statusWidth - horizontalMargin property int blockWidth: Layout.preferredWidth - statusWidth - horizontalMargin
property int horizontalMargin: 10 property int horizontalMargin: 10
property int trHeight: 30 property int trHeight: 35
spacing: 0 spacing: 0
property int openedTr: 0 property int openedTr: 0
property int blockIndex property int blockIndex
property variant scenario property variant scenario
property string labelColor: "#414141"
function calculateHeight() function calculateHeight()
{ {
if (transactions) if (transactions)
{ {
if (index >= 0) if (index >= 0)
return 30 + 30 * transactions.count + openedTr return trHeight + trHeight * transactions.count + openedTr
else else
return 30 return trHeight
} }
else else
return 30 return trHeight
} }
onOpenedTrChanged: onOpenedTrChanged:
@ -41,31 +42,67 @@ ColumnLayout
height = calculateHeight() 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 RowLayout
{ {
Layout.preferredHeight: trHeight Layout.preferredHeight: trHeight
Layout.preferredWidth: blockWidth Layout.preferredWidth: blockWidth
id: rowHeader id: rowHeader
spacing: 0
Rectangle Rectangle
{ {
color: "#DEDCDC"
Layout.preferredWidth: blockWidth Layout.preferredWidth: blockWidth
Layout.preferredHeight: trHeight Layout.preferredHeight: trHeight
radius: 4 color: "#DEDCDC"
anchors.left: parent.left anchors.left: parent.left
anchors.leftMargin: statusWidth + 5 anchors.leftMargin: statusWidth
Label { Label {
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
anchors.left: parent.left anchors.left: parent.left
anchors.leftMargin: horizontalMargin anchors.leftMargin: horizontalMargin
font.pointSize: dbgStyle.absoluteSize(1)
color: "#adadad"
text: text:
{ {
if (status === "mined") if (number === -2)
return qsTr("STARTING PARAMETERS")
else if (status === "mined")
return qsTr("BLOCK") + " " + number return qsTr("BLOCK") + " " + number
else 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 id: transactionRepeater
model: transactions model: transactions
RowLayout RowLayout
{ {
id: rowTransaction id: rowTransaction
Layout.preferredHeight: trHeight Layout.preferredHeight: trHeight
spacing: 0
function displayContent() function displayContent()
{ {
logsText.text = "" logsText.text = ""
@ -99,7 +136,7 @@ ColumnLayout
var p = log.param.get(i) var p = log.param.get(i)
logsText.text += p.name + " = " + p.value + " - indexed:" + p.indexed + "\n" logsText.text += p.name + " = " + p.value + " - indexed:" + p.indexed + "\n"
} }
else{ else {
logsText.text += "From : " + log.address + "\n" logsText.text += "From : " + log.address + "\n"
} }
} }
@ -112,18 +149,19 @@ ColumnLayout
{ {
id: trSaveStatus id: trSaveStatus
Layout.preferredWidth: statusWidth Layout.preferredWidth: statusWidth
Layout.preferredHeight: trHeight Layout.preferredHeight: parent.height
color: "transparent" color: "transparent"
anchors.top: parent.top anchors.top: parent.top
property bool saveStatus property bool saveStatus
Image { Image {
anchors.top: parent.top
anchors.left: parent.left
anchors.leftMargin: -9
anchors.topMargin: -9
id: saveStatusImage id: saveStatusImage
source: "qrc:/qml/img/recyclediscard@2x.png" source: "qrc:/qml/img/recyclediscard@2x.png"
width: statusWidth width: statusWidth + 20
fillMode: Image.PreserveAspectFit fillMode: Image.PreserveAspectFit
anchors.verticalCenter: parent.verticalCenter
anchors.horizontalCenter: parent.horizontalCenter
} }
Component.onCompleted: Component.onCompleted:
@ -160,45 +198,76 @@ ColumnLayout
color: "#DEDCDC" color: "#DEDCDC"
id: rowContentTr id: rowContentTr
anchors.top: parent.top anchors.top: parent.top
MouseArea
{
anchors.fill: parent
onDoubleClicked:
{
transactionDialog.stateAccounts = scenario.accounts
transactionDialog.execute = false
transactionDialog.open(index, blockIndex, transactions.get(index))
}
}
ColumnLayout ColumnLayout
{ {
anchors.top: parent.top anchors.top: parent.top
spacing: 10 width: parent.width
spacing: 20
RowLayout RowLayout
{ {
anchors.top: parent.top anchors.top: parent.top
anchors.verticalCenter: parent.verticalCenter Layout.fillWidth: true
spacing: cellSpacing Rectangle
Text
{ {
id: hash Layout.preferredWidth: fromWidth
anchors.left: parent.left anchors.left: parent.left
anchors.leftMargin: horizontalMargin anchors.leftMargin: horizontalMargin
Layout.preferredWidth: fromWidth Text
elide: Text.ElideRight {
maximumLineCount: 1 id: hash
text: { width: parent.width - 30
if (index >= 0) elide: Text.ElideRight
return transactions.get(index).sender anchors.verticalCenter: parent.verticalCenter
else maximumLineCount: 1
return "" 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 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) function userFrienldyToken(value)
{ {
if (value && value.indexOf("<") === 0) if (value && value.indexOf("<") === 0)
@ -212,17 +281,25 @@ ColumnLayout
return value return value
} }
Text Rectangle
{ {
id: returnValue
elide: Text.ElideRight
maximumLineCount: 1
Layout.preferredWidth: valueWidth Layout.preferredWidth: valueWidth
text: { Text
if (index >= 0 && transactions.get(index).returned) {
return transactions.get(index).returned id: returnValue
else elide: Text.ElideRight
return "" 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 id: logs
anchors.left: parent.left anchors.left: parent.left
anchors.verticalCenter: parent.verticalCenter
anchors.leftMargin: 10 anchors.leftMargin: 10
color: labelColor
font.bold: true
font.pointSize: dbgStyle.absoluteSize(1)
text: { text: {
if (index >= 0 && transactions.get(index).logs && transactions.get(index).logs.count) if (index >= 0 && transactions.get(index).logs && transactions.get(index).logs.count)
return 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 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 int previousWidth
property variant debugTrRequested: [] property variant debugTrRequested: []
signal chainChanged signal chainChanged
signal chainReloaded
Connections
{
target: codeModel
onContractRenamed: {
rebuild.startBlinking()
}
onNewContractCompiled: {
rebuild.startBlinking()
}
}
onChainChanged: { onChainChanged: {
reBuildNeeded.start() rebuild.startBlinking()
} }
onWidthChanged: onWidthChanged:
{ {
var minWidth = scenarioMinWidth - 20 // margin
if (width <= 630 || previousWidth <= 630) if (width <= minWidth || previousWidth <= minWidth)
{ {
fromWidth = 100 fromWidth = 100
toWidth = 100 toWidth = 100
@ -47,7 +59,7 @@ ColumnLayout {
if (!scenario) if (!scenario)
return; return;
if (model) if (model)
chainChanged() rebuild.startBlinking()
model = scenario model = scenario
blockModel.clear() blockModel.clear()
for (var b in model.blocks) for (var b in model.blocks)
@ -56,11 +68,11 @@ ColumnLayout {
} }
property int statusWidth: 30 property int statusWidth: 30
property int fromWidth: 100 property int fromWidth: 150
property int toWidth: 100 property int toWidth: 100
property int valueWidth: 200 property int valueWidth: 200
property int logsWidth: 50 property int logsWidth: 40
property int debugActionWidth: 50 property int debugActionWidth: 40
property int horizontalMargin: 10 property int horizontalMargin: 10
property int cellSpacing: 10 property int cellSpacing: 10
@ -68,23 +80,30 @@ ColumnLayout {
{ {
id: header id: header
spacing: 0 spacing: 0
Layout.preferredHeight: 25 Layout.preferredHeight: 30
Image { Rectangle
id: debugImage {
source: "qrc:/qml/img/recycleicon@2x.png"
Layout.preferredWidth: statusWidth Layout.preferredWidth: statusWidth
Layout.preferredHeight: 25 Layout.preferredHeight: parent.height
fillMode: Image.PreserveAspectFit 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 Rectangle
{ {
Layout.preferredWidth: fromWidth + cellSpacing Layout.preferredWidth: fromWidth
Label Label
{ {
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
text: "From" text: "From"
anchors.left: parent.left anchors.left: parent.left
anchors.leftMargin: horizontalMargin + 5 anchors.leftMargin: horizontalMargin
} }
} }
Label Label
@ -120,12 +139,25 @@ ColumnLayout {
{ {
id: blockChainScrollView id: blockChainScrollView
anchors.fill: parent anchors.fill: parent
anchors.topMargin: 10 anchors.topMargin: 8
ColumnLayout ColumnLayout
{ {
id: blockChainLayout id: blockChainLayout
width: parent.width 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 Repeater // List of blocks
{ {
id: blockChainRepeater id: blockChainRepeater
@ -218,158 +250,171 @@ ColumnLayout {
Layout.preferredWidth: parent.width Layout.preferredWidth: parent.width
RowLayout RowLayout
{ {
width: 4 * 100 anchors.horizontalCenter: parent.horizontalCenter
anchors.top: parent.top anchors.top: parent.top
anchors.topMargin: 10 anchors.topMargin: 10
spacing: 0 spacing: 20
ScenarioButton {
id: rebuild Rectangle {
text: qsTr("Rebuild") Layout.preferredWidth: 100
onClicked: Layout.preferredHeight: 30
{
if (ensureNotFuturetime.running) ScenarioButton {
return; id: rebuild
reBuildNeeded.stop() text: qsTr("Rebuild")
var retBlocks = []; width: 100
var bAdded = 0; height: 30
for (var j = 0; j < model.blocks.length; j++) roundLeft: true
roundRight: true
onClicked:
{ {
var b = model.blocks[j]; if (ensureNotFuturetime.running)
var block = { return;
hash: b.hash, stopBlinking()
number: b.number, var retBlocks = [];
transactions: [], var bAdded = 0;
status: b.status for (var j = 0; j < model.blocks.length; j++)
}
for (var k = 0; k < model.blocks[j].transactions.length; k++)
{ {
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] if (blockModel.get(j).transactions.get(k).saveStatus)
tr.saveStatus = true {
block.transactions.push(tr); 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++ var last = retBlocks[retBlocks.length - 1]
block.number = bAdded last.number = -1
block.status = "mined" last.status = "pending"
retBlocks.push(block)
} }
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) buttonShortcut: ""
retBlocks.push(projectModel.stateListModel.createEmptyBlock()) sourceImg: "qrc:/qml/img/recycleicon@2x.png"
else }
{ }
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() Rectangle
clientModel.setupScenario(model); {
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 Timer
{ {
id: reBuildNeeded id: ensureNotFuturetime
repeat: true
interval: 1000 interval: 1000
repeat: false
running: false running: false
onTriggered: {
if (!parent.fillColor || parent.fillColor === "white")
parent.fillColor = "orange"
else
parent.fillColor = "white"
}
onRunningChanged: {
if (!running)
parent.fillColor = "white"
}
} }
}
ScenarioButton { Rectangle
id: addTransaction
text: qsTr("Add Transaction")
onClicked:
{ {
var lastBlock = model.blocks[model.blocks.length - 1]; width: 1
if (lastBlock.status === "mined") height: parent.height
{ anchors.right: addBlockBtn.left
var newblock = projectModel.stateListModel.createEmptyBlock() color: "#ededed"
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)
} }
Layout.preferredWidth: 100
Layout.preferredHeight: 30
buttonShortcut: ""
sourceImg: "qrc:/qml/img/sendtransactionicon@2x.png"
}
Timer ScenarioButton {
{ id: addBlockBtn
id: ensureNotFuturetime text: qsTr("Add Block..")
interval: 1000 anchors.left: addTransaction.right
repeat: false roundLeft: false
running: false roundRight: true
} onClicked:
ScenarioButton {
id: addBlockBtn
text: qsTr("Add Block")
onClicked:
{
if (ensureNotFuturetime.running)
return
if (clientModel.mining || clientModel.running)
return
if (model.blocks.length > 0)
{ {
var lastBlock = model.blocks[model.blocks.length - 1] if (ensureNotFuturetime.running)
if (lastBlock.status === "pending") return
if (clientModel.mining || clientModel.running)
return
if (model.blocks.length > 0)
{ {
ensureNotFuturetime.start() var lastBlock = model.blocks[model.blocks.length - 1]
clientModel.mine() if (lastBlock.status === "pending")
{
ensureNotFuturetime.start()
clientModel.mine()
}
else
addNewBlock()
} }
else else
addNewBlock() addNewBlock()
} }
else
addNewBlock()
} function addNewBlock()
{
var block = projectModel.stateListModel.createEmptyBlock()
model.blocks.push(block)
blockModel.appendBlock(block)
}
width: 100
height: 30
function addNewBlock() buttonShortcut: ""
{ sourceImg: "qrc:/qml/img/addblock@2x.png"
var block = projectModel.stateListModel.createEmptyBlock()
model.blocks.push(block)
blockModel.appendBlock(block)
} }
Layout.preferredWidth: 100
Layout.preferredHeight: 30
buttonShortcut: ""
sourceImg: "qrc:/qml/img/addblock@2x.png"
} }
Connections Connections
{ {
target: clientModel target: clientModel
@ -412,7 +457,6 @@ ColumnLayout {
return; return;
} }
} }
// tr is not in the list. // tr is not in the list.
var itemTr = TransactionHelper.defaultTransaction() var itemTr = TransactionHelper.defaultTransaction()
itemTr.saveStatus = false itemTr.saveStatus = false
@ -438,7 +482,7 @@ ColumnLayout {
ScenarioButton { 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))
} }
@ -446,6 +490,8 @@ ColumnLayout {
Layout.preferredHeight: 30 Layout.preferredHeight: 30
buttonShortcut: "" buttonShortcut: ""
sourceImg: "qrc:/qml/img/newaccounticon@2x.png" 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 alias codeEditor: codeEditor
property bool webViewHorizontal: codeWebSplitter.orientation === Qt.Vertical //vertical splitter positions elements vertically, splits screen horizontally property bool webViewHorizontal: codeWebSplitter.orientation === Qt.Vertical //vertical splitter positions elements vertically, splits screen horizontally
property bool firstCompile: true property bool firstCompile: true
property int scenarioMinWidth: 590
Connections { Connections {
target: codeModel target: codeModel
@ -110,6 +111,7 @@ Rectangle {
property alias webHeight: webPreview.height property alias webHeight: webPreview.height
property alias showProjectView: projectList.visible property alias showProjectView: projectList.visible
property bool runOnProjectLoad: true property bool runOnProjectLoad: true
property int scenarioMinWidth: scenarioMinWidth
} }
ColumnLayout ColumnLayout
@ -205,7 +207,7 @@ Rectangle {
visible: false; visible: false;
Layout.fillHeight: true Layout.fillHeight: true
Keys.onEscapePressed: visible = false Keys.onEscapePressed: visible = false
Layout.minimumWidth: 650 Layout.minimumWidth: scenarioMinWidth
anchors.right: parent.right anchors.right: parent.right
} }
@ -215,7 +217,7 @@ Rectangle {
visible: false visible: false
Layout.fillHeight: true Layout.fillHeight: true
Keys.onEscapePressed: visible = false Keys.onEscapePressed: visible = false
Layout.minimumWidth: 650 Layout.minimumWidth: scenarioMinWidth
anchors.right: parent.right anchors.right: parent.right
} }
@ -224,10 +226,9 @@ Rectangle {
onDebugDataReady: { onDebugDataReady: {
scenarioExe.visible = false scenarioExe.visible = false
debugPanel.visible = true debugPanel.visible = true
debugPanel.width = scenarioExe.width
if (scenarioExe.bc.debugTrRequested) if (scenarioExe.bc.debugTrRequested)
{
debugPanel.setTr(scenarioExe.bc.model.blocks[scenarioExe.bc.debugTrRequested[0]].transactions[scenarioExe.bc.debugTrRequested[1]]) debugPanel.setTr(scenarioExe.bc.model.blocks[scenarioExe.bc.debugTrRequested[0]].transactions[scenarioExe.bc.debugTrRequested[1]])
}
} }
} }
@ -236,6 +237,7 @@ Rectangle {
onPanelClosed: { onPanelClosed: {
debugPanel.visible = false debugPanel.visible = false
scenarioExe.visible = true 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.Controls 1.1
import QtQuick.Layouts 1.0 import QtQuick.Layouts 1.0
import QtQuick.Controls.Styles 1.1 import QtQuick.Controls.Styles 1.1
import QtGraphicalEffects 1.0
Rectangle { Rectangle {
id: buttonActionContainer id: buttonActionContainer
@ -9,15 +10,68 @@ Rectangle {
property string buttonShortcut property string buttonShortcut
property string sourceImg property string sourceImg
property string fillColor property string fillColor
property alias roundLeft: left.visible
property alias roundRight: right.visible
signal clicked 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 { Rectangle {
id: contentRectangle id: contentRectangle
anchors.fill: parent anchors.fill: parent
border.color: "#cccccc" color: "white"
border.width: 1 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"]
radius: 4
color: parent.fillColor ? parent.fillColor : "white" 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 { Image {
id: debugImage id: debugImage
anchors { anchors {
@ -25,12 +79,11 @@ Rectangle {
right: parent.right right: parent.right
top: parent.top top: parent.top
bottom: parent.bottom bottom: parent.bottom
bottomMargin: debugImg.pressed ? 0 : 2; bottomMargin: debugImg.pressed ? -2 : 0;
topMargin: debugImg.pressed ? 2 : 0; topMargin: debugImg.pressed ? 2 : 0;
} }
source: sourceImg source: sourceImg
fillMode: Image.PreserveAspectFit fillMode: Image.PreserveAspectFit
height: 30
} }
Button { Button {
@ -53,12 +106,22 @@ Rectangle {
} }
} }
Rectangle
{
id: right
width: 10
height: parent.height
anchors.left: contentRectangle.right
anchors.leftMargin: -8
radius: 15
}
Rectangle Rectangle
{ {
anchors.top: contentRectangle.bottom anchors.top: contentRectangle.bottom
anchors.topMargin: 15 anchors.topMargin: 15
width: parent.width width: parent.width
Text Label
{ {
text: buttonActionContainer.text text: buttonActionContainer.text
anchors.centerIn: parent anchors.centerIn: parent

16
mix/qml/ScenarioExecution.qml

@ -28,14 +28,23 @@ Rectangle {
spacing: 10 spacing: 10
ScenarioLoader ScenarioLoader
{ {
height: 70 height: 100
width: parent.width width: parent.width
id: loader id: loader
} }
Connections
{
target: blockChain
onChainChanged:
{
loader.needSaveOrReload()
}
}
Rectangle Rectangle
{ {
width: parent.width width: parent.parent.width
height: 1 height: 1
color: "#cccccc" color: "#cccccc"
} }
@ -43,7 +52,8 @@ Rectangle {
Connections Connections
{ {
target: loader target: loader
onLoaded: { onLoaded:
{
blockChain.load(scenario) 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 "js/ErrorLocationFormater.js" as ErrorLocationFormater
import "." import "."
RowLayout ColumnLayout
{ {
id: blockChainSelector
signal restored(variant scenario) signal restored(variant scenario)
signal saved(variant scenario) signal saved(variant scenario)
signal duplicated(variant scenario) signal duplicated(variant scenario)
signal loaded(variant scenario) signal loaded(variant scenario)
signal renamed(variant scenario)
spacing: 0 spacing: 0
function init() function init()
{ {
scenarioList.load() scenarioList.load()
} }
id: blockChainSelector function needSaveOrReload()
{
Dialog { editStatus.visible = true
id: newStateWin }
modality: Qt.ApplicationModal
title: qsTr("New Project");
width: 320
height: 120
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 { TextInput
anchors.fill: parent {
anchors.margins: 10 id: scenarioNameEdit
RowLayout { visible: false
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
Text { anchors.horizontalCenter: parent.horizontalCenter
text: qsTr("Name:") Keys.onEnterPressed:
{
save()
} }
Rectangle function edit()
{ {
Layout.preferredWidth: 250 editIconRect.anchors.left = scenarioNameEdit.right
Layout.preferredHeight: parent.height editStatus.parent.anchors.left = scenarioNameEdit.right
border.width: 1 scenarioNameEdit.forceActiveFocus()
border.color: "#cccccc" }
TextInput
{ function save()
anchors.fill: parent {
id: stateName 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 target: blockChainSelector
anchors.right: parent.right; onLoaded:
function acceptAndClose()
{ {
var item = projectModel.stateListModel.createDefaultState(); scenarioName.text = scenario.title
item.title = stateName.text scenarioNameEdit.text = scenario.title
projectModel.stateListModel.appendState(item)
projectModel.stateListModel.save()
close()
scenarioList.currentIndex = projectModel.stateListModel.count - 1
} }
}
function close() Rectangle
{ {
newStateWin.close() anchors.left: scenarioName.right
stateName.text = "" anchors.top: scenarioName.top
anchors.leftMargin: 2
Layout.preferredWidth: 20
Text {
id: editStatus
text: "*"
visible: false
} }
}
Button { Rectangle
id: okButton; {
enabled: stateName.text !== "" id: editIconRect
text: qsTr("OK"); anchors.left: scenarioName.right
onClicked: { anchors.leftMargin: 15
parent.acceptAndClose(); 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 Layout.preferredWidth: 560
model: projectModel.stateListModel anchors.horizontalCenter: parent.horizontalCenter
textRole: "title" Layout.preferredHeight: 50
onCurrentIndexChanged: spacing: 0
{
restoreScenario.restore()
}
function load() Row
{ {
var state = projectModel.stateListModel.getState(currentIndex) Layout.preferredWidth: 100 * 5
loaded(state) Layout.preferredHeight: 50
} spacing: 15
}
Row Rectangle
{
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()
{ {
var state = projectModel.stateListModel.reloadStateFromFromProject(scenarioList.currentIndex) color: "transparent"
restored(state) width: 251
loaded(state) height: 30
} Rectangle
} {
width: 10
height: parent.height
anchors.right: scenarioList.left
anchors.rightMargin: -8
radius: 15
}
ScenarioButton { ComboBox
id: saveScenario {
text: qsTr("Save") id: scenarioList
onClicked: { model: projectModel.stateListModel
projectModel.saveProjectFile() textRole: "title"
saved(state) height: parent.height
} width: 150
width: 100 onCurrentIndexChanged:
height: 30 {
buttonShortcut: "" restoreScenario.restore()
sourceImg: "qrc:/qml/img/saveicon@2x.png" }
}
ScenarioButton function load()
{ {
id: duplicateScenario var state = projectModel.stateListModel.getState(currentIndex)
text: qsTr("Duplicate") loaded(state)
onClicked: { }
projectModel.stateListModel.duplicateState(scenarioList.currentIndex)
duplicated(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 Rectangle
width: 100 {
height: 30 width: 100 * 3
buttonShortcut: "" height: 30
sourceImg: "qrc:/qml/img/plus.png" color: "transparent"
onClicked: {
newStateWin.open() 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 { Connections {
target: codeModel target: codeModel
onContractInterfaceChanged: reload(); onContractInterfaceChanged: reload();

Loading…
Cancel
Save