diff --git a/libethereum/BlockChain.cpp b/libethereum/BlockChain.cpp index 9b81fddcc..640fd2df4 100644 --- a/libethereum/BlockChain.cpp +++ b/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) diff --git a/mix/qml/Block.qml b/mix/qml/Block.qml index 6fb274ccd..31d3e924c 100644 --- a/mix/qml/Block.qml +++ b/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 + } } diff --git a/mix/qml/BlockChain.qml b/mix/qml/BlockChain.qml index d3fad6fda..02ff72be2 100644 --- a/mix/qml/BlockChain.qml +++ b/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 } } } diff --git a/mix/qml/MainContent.qml b/mix/qml/MainContent.qml index de19baf35..7f180a899 100644 --- a/mix/qml/MainContent.qml +++ b/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 } } } diff --git a/mix/qml/ScenarioButton.qml b/mix/qml/ScenarioButton.qml index 4dd7bc53f..d4beaefaa 100644 --- a/mix/qml/ScenarioButton.qml +++ b/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 diff --git a/mix/qml/ScenarioExecution.qml b/mix/qml/ScenarioExecution.qml index bc872bff7..3e9d8e089 100644 --- a/mix/qml/ScenarioExecution.qml +++ b/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) } } diff --git a/mix/qml/ScenarioLoader.qml b/mix/qml/ScenarioLoader.qml index 93f4f059b..bc26b103d 100644 --- a/mix/qml/ScenarioLoader.qml +++ b/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") } } - } diff --git a/mix/qml/WebPreview.qml b/mix/qml/WebPreview.qml index e4d0b61a5..5d0f208af 100644 --- a/mix/qml/WebPreview.qml +++ b/mix/qml/WebPreview.qml @@ -89,11 +89,6 @@ Item { } } - Connections { - target: clientModel - onRunComplete: reload(); - } - Connections { target: codeModel onContractInterfaceChanged: reload();