From a7498c080b3c43d4e65d8f3deb191de326d6cdfb Mon Sep 17 00:00:00 2001 From: arkpar Date: Fri, 6 Feb 2015 15:14:13 +0100 Subject: [PATCH] ui: state list refactored --- mix/AppContext.cpp | 2 +- mix/AssemblyDebuggerControl.cpp | 45 ------------------- mix/AssemblyDebuggerControl.h | 48 -------------------- mix/ClientModel.h | 1 + mix/CodeEditorExtensionManager.cpp | 8 +--- mix/MixClient.cpp | 1 - mix/StateListView.cpp | 48 -------------------- mix/StateListView.h | 45 ------------------- mix/qml/DebugInfoList.qml | 13 +++++- mix/qml/Debugger.qml | 54 +++++++++++------------ mix/qml/MainContent.qml | 48 +++----------------- mix/qml/StateList.qml | 58 ++++++++++++++----------- mix/qml/StateListModel.qml | 10 +++-- mix/qml/TransactionLog.qml | 70 +++++++++++++++++++++++++++--- mix/qml/main.qml | 25 ++++++++++- 15 files changed, 173 insertions(+), 303 deletions(-) delete mode 100644 mix/AssemblyDebuggerControl.cpp delete mode 100644 mix/AssemblyDebuggerControl.h delete mode 100644 mix/StateListView.cpp delete mode 100644 mix/StateListView.h diff --git a/mix/AppContext.cpp b/mix/AppContext.cpp index 1aa43a119..a806a39f4 100644 --- a/mix/AppContext.cpp +++ b/mix/AppContext.cpp @@ -84,7 +84,7 @@ void AppContext::load() qmlRegisterType("CodeEditorExtensionManager", 1, 0, "CodeEditorExtensionManager"); qmlRegisterType("HttpServer", 1, 0, "HttpServer"); m_applicationEngine->load(QUrl("qrc:/qml/main.qml")); - QWindow *window = qobject_cast(m_applicationEngine->rootObjects().at(0)); + QWindow *window = qobject_cast(m_applicationEngine->rootObjects().at(0)); window->setIcon(QIcon(":/res/mix_256x256x32.png")); appLoaded(); } diff --git a/mix/AssemblyDebuggerControl.cpp b/mix/AssemblyDebuggerControl.cpp deleted file mode 100644 index 7bf177981..000000000 --- a/mix/AssemblyDebuggerControl.cpp +++ /dev/null @@ -1,45 +0,0 @@ -/* - This file is part of cpp-ethereum. - cpp-ethereum is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - cpp-ethereum is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with cpp-ethereum. If not, see . -*/ -/** @file AssemblyDebuggerControl.cpp - * @author Yann yann@ethdev.com - * @date 2014 - * display opcode debugging. - */ - -#include -#include -#include -#include "ClientModel.h" -#include "AssemblyDebuggerControl.h" - -using namespace dev::mix; - -AssemblyDebuggerControl::AssemblyDebuggerControl(AppContext* _context): - Extension(_context, ExtensionDisplayBehavior::RightView) -{ -} - -QString AssemblyDebuggerControl::contentUrl() const -{ - return QStringLiteral("qrc:/qml/Debugger.qml"); -} - -QString AssemblyDebuggerControl::title() const -{ - return QApplication::tr("Debugger"); -} - -void AssemblyDebuggerControl::start() const -{ -} diff --git a/mix/AssemblyDebuggerControl.h b/mix/AssemblyDebuggerControl.h deleted file mode 100644 index 701cbc5fd..000000000 --- a/mix/AssemblyDebuggerControl.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - This file is part of cpp-ethereum. - cpp-ethereum is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - cpp-ethereum is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with cpp-ethereum. If not, see . -*/ -/** @file AssemblyDebuggerControl.h - * @author Yann yann@ethdev.com - * @date 2014 - * Extension which display debugging steps in assembly code. - */ - -#pragma once - -#include -#include "Extension.h" - -namespace dev -{ -namespace mix -{ - -class AppContext; - -/** - * @brief Extension which display transaction creation or transaction call debugging. - */ -class AssemblyDebuggerControl: public Extension -{ - Q_OBJECT - -public: - AssemblyDebuggerControl(AppContext* _context); - ~AssemblyDebuggerControl() {} - void start() const override; - QString title() const override; - QString contentUrl() const override; -}; - -} -} diff --git a/mix/ClientModel.h b/mix/ClientModel.h index be264e108..bb912f983 100644 --- a/mix/ClientModel.h +++ b/mix/ClientModel.h @@ -26,6 +26,7 @@ #include #include #include +#include #include "MachineStates.h" namespace dev diff --git a/mix/CodeEditorExtensionManager.cpp b/mix/CodeEditorExtensionManager.cpp index c7528486a..97b808eb2 100644 --- a/mix/CodeEditorExtensionManager.cpp +++ b/mix/CodeEditorExtensionManager.cpp @@ -26,8 +26,6 @@ #include #include #include "StatusPane.h" -#include "AssemblyDebuggerControl.h" -#include "StateListView.h" #include "AppContext.h" #include "MixApplication.h" #include "CodeModel.h" @@ -56,13 +54,9 @@ void CodeEditorExtensionManager::loadEditor(QQuickItem* _editor) void CodeEditorExtensionManager::initExtensions() { std::shared_ptr output = std::make_shared(m_appContext); - std::shared_ptr debug = std::make_shared(m_appContext); - std::shared_ptr stateList = std::make_shared(m_appContext); QObject::connect(m_appContext->codeModel(), &CodeModel::compilationComplete, this, &CodeEditorExtensionManager::applyCodeHighlight); initExtension(output); - initExtension(debug); - initExtension(stateList); } void CodeEditorExtensionManager::initExtension(std::shared_ptr _ext) @@ -94,10 +88,10 @@ void CodeEditorExtensionManager::applyCodeHighlight() void CodeEditorExtensionManager::setRightView(QQuickItem* _rightView) { m_rightView = _rightView; - initExtensions(); //TODO: move this to a proper place } void CodeEditorExtensionManager::setHeaderView(QQuickItem* _headerView) { m_headerView = _headerView; + initExtensions(); //TODO: move this to a proper place } diff --git a/mix/MixClient.cpp b/mix/MixClient.cpp index 512847a78..f182211c9 100644 --- a/mix/MixClient.cpp +++ b/mix/MixClient.cpp @@ -205,7 +205,6 @@ void MixClient::mine() m_state.completeMine(); bc().import(m_state.blockData(), m_stateDB); m_state.sync(bc()); - //m_state.cleanup(true); m_startState = m_state; m_executions.emplace_back(std::move(m_pendingExecutions)); h256Set changed { dev::eth::PendingChangedFilter, dev::eth::ChainChangedFilter }; diff --git a/mix/StateListView.cpp b/mix/StateListView.cpp deleted file mode 100644 index 835c332aa..000000000 --- a/mix/StateListView.cpp +++ /dev/null @@ -1,48 +0,0 @@ -/* - This file is part of cpp-ethereum. - - cpp-ethereum is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - cpp-ethereum is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with cpp-ethereum. If not, see . -*/ -/** @file StateListView.cpp - * @author Arkadiy Paronyan arkadiy@ethdev.com - * @date 2014 - * Ethereum IDE client. - */ - -#include -#include -#include -#include -#include -#include "StateListView.h" - -using namespace dev::mix; - -StateListView::StateListView(AppContext* _context): Extension(_context, ExtensionDisplayBehavior::RightView) -{ -} - -QString StateListView::contentUrl() const -{ - return QStringLiteral("qrc:/qml/StateList.qml"); -} - -QString StateListView::title() const -{ - return QApplication::tr("States"); -} - -void StateListView::start() const -{ -} diff --git a/mix/StateListView.h b/mix/StateListView.h deleted file mode 100644 index 18d1ae879..000000000 --- a/mix/StateListView.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - This file is part of cpp-ethereum. - cpp-ethereum is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - cpp-ethereum is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with cpp-ethereum. If not, see . -*/ -/** @file StateListView.h - * @author Arkadiy Paronyan arkadiy@ethdev.com - * @date 2014 - * Ethereum IDE client. - */ - -#pragma once - -#include -#include -#include "Extension.h" - -namespace dev -{ -namespace mix -{ - -/// State list control -class StateListView: public Extension -{ - Q_OBJECT - -public: - StateListView(AppContext* _context); - void start() const override; - QString title() const override; - QString contentUrl() const override; -}; - -} - -} diff --git a/mix/qml/DebugInfoList.qml b/mix/qml/DebugInfoList.qml index 1e16038e7..80c2d5509 100644 --- a/mix/qml/DebugInfoList.qml +++ b/mix/qml/DebugInfoList.qml @@ -9,7 +9,7 @@ ColumnLayout { property variant listModel; property bool collapsible; property bool enableSelection; - property real storedHeight; + property real storedHeight: 0; property Component itemDelegate signal rowActivated(int index) spacing: 0 @@ -104,6 +104,17 @@ ColumnLayout { selectionMode: enableSelection ? SelectionMode.SingleSelection : SelectionMode.NoSelection headerDelegate: null itemDelegate: root.itemDelegate + onHeightChanged: { + if (height <= 0 && collapsible) { + if (storedHeight <= 0) + storedHeight = 200; + storageContainer.state = "collapsed"; + } + else if (height > 0 && storageContainer.state == "collapsed") { + //TODO: fix increasing size + //storageContainer.state = ""; + } + } TableViewColumn { role: "modelData" width: parent.width diff --git a/mix/qml/Debugger.qml b/mix/qml/Debugger.qml index d7023f4b2..e9c718f70 100644 --- a/mix/qml/Debugger.qml +++ b/mix/qml/Debugger.qml @@ -9,8 +9,10 @@ import "js/ErrorLocationFormater.js" as ErrorLocationFormater Rectangle { id: debugPanel + + property alias transactionLog : transactionLog + objectName: "debugPanel" - anchors.fill: parent; color: "#ededed" clip: true @@ -22,7 +24,7 @@ Rectangle { function update(data, giveFocus) { - if (statusPane.result.successful) + if (statusPane && statusPane.result.successful) { Debugger.init(data); debugScrollArea.visible = true; @@ -62,6 +64,7 @@ Rectangle { property alias storageHeightSettings: storageRect.height property alias memoryDumpHeightSettings: memoryRect.height property alias callDataHeightSettings: callDataRect.height + property alias transactionLogVisible: transactionLog.visible } Rectangle @@ -113,45 +116,41 @@ Rectangle { } } - ScrollView { + SplitView { id: debugScrollArea anchors.fill: parent + orientation: Qt.Vertical + handleDelegate: Rectangle { + height: machineStates.sideMargin + color: "transparent" + } - SplitView + TransactionLog { + id: transactionLog + Layout.fillWidth: true + Layout.minimumHeight: 60 + height: 250 + } + ScrollView { property int sideMargin: 10 id: machineStates - anchors.top: parent.top - anchors.topMargin: 15 - anchors.left: parent.left; - anchors.leftMargin: machineStates.sideMargin - width: debugScrollArea.width - machineStates.sideMargin * 2 - 20; - orientation: Qt.Vertical - handleDelegate: Rectangle { - height: machineStates.sideMargin - color: "transparent" - } - + Layout.fillWidth: true + Layout.fillHeight: true function updateHeight() { - machineStates.height = transactionLog.childrenRect.height + buttonRow.childrenRect.height + assemblyCodeRow.childrenRect.height + + statesLayout.height = buttonRow.childrenRect.height + assemblyCodeRow.childrenRect.height + callStackRect.childrenRect.height + storageRect.childrenRect.height + memoryRect.childrenRect.height + callDataRect.childrenRect.height + 120; } Component.onCompleted: updateHeight(); - - TransactionLog { - id: transactionLog - Layout.fillWidth: true - Layout.minimumHeight: 60 - height: 250 - } - ColumnLayout { - - Layout.fillWidth: true - Layout.fillHeight: true id: statesLayout + anchors.top: parent.top + anchors.topMargin: 15 + anchors.left: parent.left; + anchors.leftMargin: machineStates.sideMargin + width: debugScrollArea.width - machineStates.sideMargin * 2 - 20; spacing: machineStates.sideMargin Rectangle { @@ -550,7 +549,6 @@ Rectangle { } } } - } Rectangle diff --git a/mix/qml/MainContent.qml b/mix/qml/MainContent.qml index e6c636514..80e1d920d 100644 --- a/mix/qml/MainContent.qml +++ b/mix/qml/MainContent.qml @@ -9,7 +9,6 @@ import "js/QEtherHelper.js" as QEtherHelper import "js/TransactionHelper.js" as TransactionHelper Rectangle { - objectName: "mainContent" signal keyPressed(variant event) focus: true @@ -21,11 +20,12 @@ Rectangle { anchors.fill: parent id: root - property alias rightViewVisible : rightView.visible - property alias webViewVisible : webPreview.visible - property alias projectViewVisible : projectList.visible - property alias runOnProjectLoad : mainSettings.runOnProjectLoad - property bool webViewHorizontal : codeWebSplitter.orientation === Qt.Vertical //vertical splitter positions elements vertically, splits screen horizontally + property alias rightViewVisible: rightView.visible + property alias webViewVisible: webPreview.visible + property alias projectViewVisible: projectList.visible + property alias runOnProjectLoad: mainSettings.runOnProjectLoad + property alias rightPane: rightView + property bool webViewHorizontal: codeWebSplitter.orientation === Qt.Vertical //vertical splitter positions elements vertically, splits screen horizontally property bool firstCompile: true Connections { @@ -76,7 +76,6 @@ Rectangle { CodeEditorExtensionManager { headerView: headerPaneTabs; - rightView: rightPaneTabs; } Settings { @@ -178,46 +177,13 @@ Rectangle { } } - Rectangle { + Debugger { visible: false; id: rightView; Layout.fillHeight: true Keys.onEscapePressed: visible = false - height: parent.height; - width: 515 Layout.minimumWidth: 515 anchors.right: parent.right - Rectangle { - anchors.fill: parent; - id: rightPaneView - TabView { - id: rightPaneTabs - tabsVisible: true - antialiasing: true - anchors.fill: parent - style: TabViewStyle { - frameOverlap: 1 - tabBar: - Rectangle { - color: "#ededed" - id: background - } - tab: Rectangle { - color: "#ededed" - implicitWidth: 80 - implicitHeight: 20 - radius: 2 - Text { - anchors.centerIn: parent - text: styleData.title - color: styleData.selected ? "#7da4cd" : "#202020" - } - } - frame: Rectangle { - } - } - } - } } } } diff --git a/mix/qml/StateList.qml b/mix/qml/StateList.qml index 3674e0dbc..059b35bc2 100644 --- a/mix/qml/StateList.qml +++ b/mix/qml/StateList.qml @@ -3,60 +3,66 @@ import QtQuick.Controls.Styles 1.1 import QtQuick.Controls 1.1 import QtQuick.Dialogs 1.1 import QtQuick.Layouts 1.1 +import QtQuick.Window 2.0 -Rectangle { - color: "#ededed" +Window { id: stateListContainer - focus: true - anchors.topMargin: 10 - anchors.left: parent.left - height: parent.height - width: parent.width + modality: Qt.WindowModal - ListView { - id: list - anchors.top: parent.top - height: parent.height - width: parent.width - model: projectModel.stateListModel - delegate: renderDelegate - } + width: 640 + height: 480 - Button { - anchors.bottom: parent.bottom - action: addStateAction + visible: false + ColumnLayout + { + anchors.fill: parent + TableView { + id: list + Layout.fillHeight: true + Layout.fillWidth: true + model: projectModel.stateListModel + itemDelegate: renderDelegate + headerDelegate: null + TableViewColumn { + role: "title" + title: qsTr("State") + width: list.width + } + } + + Button { + anchors.bottom: parent.bottom + action: addStateAction + } } Component { id: renderDelegate Item { - id: wrapperItem - height: 20 - width: parent.width RowLayout { anchors.fill: parent Text { Layout.fillWidth: true Layout.fillHeight: true - text: title + text: styleData.value font.pointSize: 12 verticalAlignment: Text.AlignBottom } ToolButton { text: qsTr("Edit"); Layout.fillHeight: true - onClicked: list.model.editState(index); + onClicked: list.model.editState(styleData.row); } ToolButton { - visible: list.model.count - 1 != index + visible: list.model.defaultStateIndex !== styleData.row text: qsTr("Delete"); Layout.fillHeight: true - onClicked: list.model.deleteState(index); + onClicked: list.model.deleteState(styleData.row); } ToolButton { text: qsTr("Run"); Layout.fillHeight: true - onClicked: list.model.runState(index); + onClicked: list.model.runState(styleData.row); } } } diff --git a/mix/qml/StateListModel.qml b/mix/qml/StateListModel.qml index a1b24fe0f..e87a96f76 100644 --- a/mix/qml/StateListModel.qml +++ b/mix/qml/StateListModel.qml @@ -8,7 +8,6 @@ import "js/QEtherHelper.js" as QEtherHelper Item { - property int defaultStateIndex: 0 property alias model: stateListModel property var stateList: [] @@ -111,7 +110,7 @@ Item { for(var i = 0; i < stateListModel.count; i++) { projectData.states.push(toPlainStateItem(stateList[i])); } - projectData.defaultStateIndex = defaultStateIndex; + projectData.defaultStateIndex = stateListModel.defaultStateIndex; } onNewProject: { var state = toPlainStateItem(stateListModel.createDefaultState()); @@ -127,12 +126,12 @@ Item { var item = stateDialog.getItem(); if (stateDialog.stateIndex < stateListModel.count) { if (stateDialog.isDefault) - defaultStateIndex = stateIndex; + stateListModel.defaultStateIndex = stateIndex; stateList[stateDialog.stateIndex] = item; stateListModel.set(stateDialog.stateIndex, item); } else { if (stateDialog.isDefault) - defaultStateIndex = 0; + stateListModel.defaultStateIndex = 0; stateList.push(item); stateListModel.append(item); } @@ -149,8 +148,10 @@ Item { ListModel { id: stateListModel + property int defaultStateIndex: 0 signal defaultStateChanged; signal stateListModelReady; + signal stateRun(int index) function defaultTransactionItem() { return { @@ -205,6 +206,7 @@ Item { function runState(index) { var item = stateList[index]; clientModel.setupState(item); + stateRun(index); } function deleteState(index) { diff --git a/mix/qml/TransactionLog.qml b/mix/qml/TransactionLog.qml index c8e87f025..970c4c21d 100644 --- a/mix/qml/TransactionLog.qml +++ b/mix/qml/TransactionLog.qml @@ -5,13 +5,69 @@ import QtQuick.Dialogs 1.1 import QtQuick.Layouts 1.1 Item { + Action { + id: addStateAction + text: "Add State" + shortcut: "Ctrl+Alt+T" + enabled: codeModel.hasContract && !clientModel.running; + onTriggered: projectModel.stateListModel.addState(); + } + Action { + id: editStateAction + text: "Edit State" + shortcut: "Ctrl+Alt+T" + enabled: codeModel.hasContract && !clientModel.running && statesCombo.currentIndex >= 0 && projectModel.stateListModel.count > 0; + onTriggered: projectModel.stateListModel.editState(statesCombo.currentIndex); + } + ColumnLayout { anchors.fill: parent - CheckBox { - id: recording - text: qsTr("Record transactions"); - checked: true - Layout.fillWidth: true + RowLayout { + + ComboBox { + id: statesCombo + model: projectModel.stateListModel + width: 150 + editable: false + textRole: "title" + onActivated: { + model.runState(index); + } + Connections { + target: projectModel.stateListModel + onStateRun: { + if (statesCombo.currentIndex !== index) + statesCombo.currentIndex = index; + } + } + } + Button + { + anchors.rightMargin: 9 + anchors.verticalCenter: parent.verticalCenter + action: editStateAction + } + Button + { + anchors.rightMargin: 9 + anchors.verticalCenter: parent.verticalCenter + action: addStateAction + } + Button + { + anchors.rightMargin: 9 + anchors.verticalCenter: parent.verticalCenter + action: mineAction + } + + CheckBox { + id: recording + text: qsTr("Record transactions"); + checked: true + Layout.fillWidth: true + + + } } TableView { Layout.fillWidth: true @@ -31,7 +87,7 @@ Item { TableViewColumn { role: "contract" title: qsTr("Contract") - width: 120 + width: 100 } TableViewColumn { role: "function" @@ -41,7 +97,7 @@ Item { TableViewColumn { role: "value" title: qsTr("Value") - width: 120 + width: 60 } TableViewColumn { role: "address" diff --git a/mix/qml/main.qml b/mix/qml/main.qml index 41b7c50a4..3f0c2ba7e 100644 --- a/mix/qml/main.qml +++ b/mix/qml/main.qml @@ -15,7 +15,7 @@ ApplicationWindow { height: 800 minimumWidth: 400 minimumHeight: 300 - title: qsTr("mix") + title: qsTr("Mix") menuBar: MenuBar { Menu { @@ -39,6 +39,8 @@ ApplicationWindow { MenuItem { action: debugRunAction } MenuItem { action: mineAction } MenuSeparator {} + MenuItem { action: editStatesAction } + MenuSeparator {} MenuItem { action: toggleRunOnLoadAction } } Menu { @@ -48,6 +50,7 @@ ApplicationWindow { MenuSeparator {} MenuItem { action: toggleProjectNavigatorAction } MenuItem { action: showHideRightPanelAction } + MenuItem { action: toggleTransactionLogAction } MenuItem { action: toggleWebPreviewAction } MenuItem { action: toggleWebPreviewOrientationAction } } @@ -91,6 +94,17 @@ ApplicationWindow { enabled: codeModel.hasContract && !clientModel.running &&!clientModel.mining } + StateList { + id: stateList + } + + Action { + id: editStatesAction + text: qsTr("Edit States") + shortcut: "Ctrl+Alt+E" + onTriggered: stateList.show(); + } + Connections { target: projectModel.stateListModel @@ -120,6 +134,15 @@ ApplicationWindow { onTriggered: mainContent.toggleWebPreview(); } + Action { + id: toggleTransactionLogAction + text: qsTr("Show States and Transactions") + shortcut: "Alt+1" + checkable: true + checked: mainContent.rightPane.transactionLog.visible + onTriggered: mainContent.rightPane.transactionLog.visible = !mainContent.rightPane.transactionLog.visible + } + Action { id: toggleProjectNavigatorAction text: qsTr("Show Project Navigator")