From 4b99a0bf3380d4fb74a966c382b5c3dd73e91ccc Mon Sep 17 00:00:00 2001 From: Borna Rajkovic Date: Fri, 8 Apr 2022 00:21:23 +0200 Subject: [PATCH] Added initial view --- SchemeEditor.pro | 6 ++ comdel/display/component_display.cpp | 42 ++++++++ comdel/display/component_display.h | 28 ++++++ comdel/display/library_display.cpp | 52 ++++++++++ comdel/display/library_display.h | 28 ++++++ comdel/display/schema_display.cpp | 40 ++++++++ comdel/display/schema_display.h | 28 ++++++ comdel/domain/comdelgenerator.cpp | 6 +- comdel/domain/wireinstance.cpp | 4 +- comdel/domain/wireinstance.h | 3 +- main.cpp | 32 ------ mainwindow.cpp | 139 ++++++++++++++++++++++++++- mainwindow.h | 23 +++++ mainwindow.ui | 22 ++++- 14 files changed, 415 insertions(+), 38 deletions(-) create mode 100644 comdel/display/component_display.cpp create mode 100644 comdel/display/component_display.h create mode 100644 comdel/display/library_display.cpp create mode 100644 comdel/display/library_display.h create mode 100644 comdel/display/schema_display.cpp create mode 100644 comdel/display/schema_display.h diff --git a/SchemeEditor.pro b/SchemeEditor.pro index c5a309c..33e478e 100644 --- a/SchemeEditor.pro +++ b/SchemeEditor.pro @@ -9,6 +9,9 @@ CONFIG += c++17 #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 SOURCES += \ + comdel/display/component_display.cpp \ + comdel/display/library_display.cpp \ + comdel/display/schema_display.cpp \ comdel/domain/addressspace.cpp \ comdel/domain/attribute.cpp \ comdel/domain/bus.cpp \ @@ -39,6 +42,9 @@ SOURCES += \ mainwindow.cpp HEADERS += \ + comdel/display/component_display.h \ + comdel/display/library_display.h \ + comdel/display/schema_display.h \ comdel/domain/addressspace.h \ comdel/domain/attribute.h \ comdel/domain/bus.h \ diff --git a/comdel/display/component_display.cpp b/comdel/display/component_display.cpp new file mode 100644 index 0000000..fa8c495 --- /dev/null +++ b/comdel/display/component_display.cpp @@ -0,0 +1,42 @@ +#include "component_display.h" + +namespace display { + +Component *Component::ofWire(domain::WireInstance *wire) { + auto component = new Component(); + component->wireInstance = wire; + component->redraw(); + return component; +}; +Component *Component::ofComponent(domain::ComponentInstance *instance) { + auto component = new Component(); + component->componentInstance = instance; + component->redraw(); + return component; +}; +Component *Component::ofBus(domain::BusInstance *instance) { + auto component = new Component(); + component->busInstance = instance; + component->redraw(); + return component; +}; + +void Component::redraw() { + if(componentInstance) { + componentInstance->component.getDisplay().render(this); + for(auto &pin: componentInstance->component.getPins()) { + pin.getDisplay().render(this); + } + this->addToGroup(new QGraphicsSimpleTextItem(QString::fromStdString(componentInstance->name))); + } + if(busInstance && busInstance->bus.getDisplay()) { + busInstance->bus.getDisplay()->render(this); + this->addToGroup(new QGraphicsSimpleTextItem(QString::fromStdString(busInstance->name))); + } + if(wireInstance) { + wireInstance->display.render(this); + this->addToGroup(new QGraphicsSimpleTextItem(QString::fromStdString(wireInstance->name))); + } +} + +} // namespace display diff --git a/comdel/display/component_display.h b/comdel/display/component_display.h new file mode 100644 index 0000000..b299185 --- /dev/null +++ b/comdel/display/component_display.h @@ -0,0 +1,28 @@ +#ifndef DISPLAY_COMPONENT_H +#define DISPLAY_COMPONENT_H + +#include +#include + +#include + +namespace display { + +class Component: public QGraphicsItemGroup +{ +public: + static Component *ofComponent(domain::ComponentInstance *instance); + static Component *ofBus(domain::BusInstance *instance); + static Component *ofWire(domain::WireInstance *wire); + + void redraw(); + +private: + domain::ComponentInstance *componentInstance = nullptr; + domain::BusInstance *busInstance = nullptr; + domain::WireInstance *wireInstance = nullptr; +}; + +} // namespace display + +#endif // DISPLAY_COMPONENT_H diff --git a/comdel/display/library_display.cpp b/comdel/display/library_display.cpp new file mode 100644 index 0000000..e16f12c --- /dev/null +++ b/comdel/display/library_display.cpp @@ -0,0 +1,52 @@ +#include "library_display.h" + +#include +#include +#include + +namespace display { + +Library::Library() +{ + auto layout = new QVBoxLayout(); + this->setLayout(layout); + + componentList = new QListWidget(); + busList = new QListWidget(); + + layout->setMargin(4); + layout->addWidget(new QLabel("Components:")); + layout->addWidget(componentList, 1); + layout->addSpacing(8); + layout->addWidget(new QLabel("Buses:")); + layout->addWidget(busList, 1); + + setLibrary(library); +} + +void Library::setLibrary(std::optional library) { + + componentList->clear(); + busList->clear(); + + if(!library) { + return; + } + + for(auto& component: library->getComponents()) { + auto item = new QListWidgetItem{QString::fromStdString(component.getName())}; + item->setToolTip(QString::fromStdString(component.getTooltip())); + componentList->addItem(item); + } + + for(auto& bus: library->getBuses()) { + if(bus.getType() == domain::Bus::REGULAR) { + auto item = new QListWidgetItem{QString::fromStdString(bus.getName())}; + item->setToolTip(QString::fromStdString(bus.getTooltip())); + busList->addItem(item); + } + } + +} + +} // namespace display diff --git a/comdel/display/library_display.h b/comdel/display/library_display.h new file mode 100644 index 0000000..51125fe --- /dev/null +++ b/comdel/display/library_display.h @@ -0,0 +1,28 @@ +#ifndef DISPLAY_LIBRARY_H +#define DISPLAY_LIBRARY_H + +#include +#include + +#include + +namespace display { + +class Library: public QWidget +{ +public: + Library(); + + void setLibrary(std::optional library); + +private: + std::optional library; + + QListWidget *componentList; + QListWidget *busList; + +}; + +} // namespace display + +#endif // DISPLAY_LIBRARY_H diff --git a/comdel/display/schema_display.cpp b/comdel/display/schema_display.cpp new file mode 100644 index 0000000..80666d3 --- /dev/null +++ b/comdel/display/schema_display.cpp @@ -0,0 +1,40 @@ +#include "component_display.h" +#include "schema_display.h" + +namespace display { + +Schema::Schema() +{ + this->setScene(&scene); +} + + +void Schema::setSchema(std::optional& schema) +{ + scene.clear(); + this->schema = schema; + if(schema.has_value()) { + for(auto &instance: schema->instances) { + Component *group = nullptr; + auto component = dynamic_cast(instance); + if(component) { + group = Component::ofComponent(component); + } + auto bus = dynamic_cast(instance); + if(bus) { + group = Component::ofBus(bus); + } + if(group != nullptr) { + group->setPos(instance->position.first, instance->position.second); + scene.addItem(group); + } + } + for(auto &wire: schema->wires) { + auto group = Component::ofWire(wire); + group->setPos(wire->position.first, wire->position.second); + scene.addItem(group); + } + } +} + +} // namespace display diff --git a/comdel/display/schema_display.h b/comdel/display/schema_display.h new file mode 100644 index 0000000..81d680e --- /dev/null +++ b/comdel/display/schema_display.h @@ -0,0 +1,28 @@ +#ifndef DISPLAY_SCHEMA_H +#define DISPLAY_SCHEMA_H + + +#include +#include + +#include + +namespace display { + +class Schema: public QGraphicsView +{ +public: + Schema(); + + void setSchema(std::optional& schema); + +private: + QGraphicsScene scene; + + std::optional schema; + +}; + +} // namespace display + +#endif // DISPLAY_SCHEMA_H diff --git a/comdel/domain/comdelgenerator.cpp b/comdel/domain/comdelgenerator.cpp index 73c1f2c..5d27811 100644 --- a/comdel/domain/comdelgenerator.cpp +++ b/comdel/domain/comdelgenerator.cpp @@ -727,7 +727,11 @@ std::optional ComdelGenerator::loadWireInstance(WireInstanceNode if(!display) { return nullopt; } - return std::optional(new WireInstance(node.name.value, *display)); + std::pair position = std::make_pair(0, 0); + if(node.position) { + position = std::make_pair(node.position->first.value, node.position->second.value); + } + return std::optional(new WireInstance(node.name.value, *display, position)); } diff --git a/comdel/domain/wireinstance.cpp b/comdel/domain/wireinstance.cpp index cea2ff3..88cb7b0 100644 --- a/comdel/domain/wireinstance.cpp +++ b/comdel/domain/wireinstance.cpp @@ -2,8 +2,8 @@ namespace domain { -WireInstance::WireInstance(std::string name, Display display) - : name(name), display(display) +WireInstance::WireInstance(std::string name, Display display, std::pair position) + : name(name), display(display), position(position) {} diff --git a/comdel/domain/wireinstance.h b/comdel/domain/wireinstance.h index 5ea7402..6bd9dbd 100644 --- a/comdel/domain/wireinstance.h +++ b/comdel/domain/wireinstance.h @@ -14,8 +14,9 @@ class WireInstance public: std::string name; Display display; + std::pair position; - WireInstance(std::string name, Display display); + WireInstance(std::string name, Display display, std::pair position); }; } // namespace domain diff --git a/main.cpp b/main.cpp index 1650bfd..547577a 100644 --- a/main.cpp +++ b/main.cpp @@ -11,40 +11,8 @@ int main(int argc, char *argv[]) { - /* QApplication a(argc, argv); MainWindow w; w.show(); return a.exec(); -*/ - - ParseContext parseContext; - auto schema = loadSchemaFromFile(&parseContext, "/home/bbr/Documents/personal/projects/modeler/schema.csl", std::cout); - - if(schema) { - std::vector signatures; - - signatures.push_back(domain::FunctionSignature("divisible", std::vector{domain::Value::INT, domain::Value::INT})); - signatures.push_back(domain::FunctionSignature("less_then", std::vector{domain::Value::INT, domain::Value::INT})); - signatures.push_back(domain::FunctionSignature("greater_then", std::vector{domain::Value::INT, domain::Value::INT})); - signatures.push_back(domain::FunctionSignature("contains_address", std::vector{domain::Value::ADDRESS_SPACE, domain::Value::INT})); - signatures.push_back(domain::FunctionSignature("contains", std::vector{domain::Value::ADDRESS_SPACE, domain::Value::INT, domain::Value::INT})); - signatures.push_back(domain::FunctionSignature("unique", std::vector{domain::Value::ADDRESS_SPACE, domain::Value::INT, domain::Value::INT})); - - domain::ComdelGenerator generator(signatures); - auto library = generator.loadLibrary(*schema->library); - - for (auto& error : generator.getErrors()) { - parseContext.formatError(error, std::cout, "ERROR: "); - } - - if(library) { - auto instance = generator.loadSchema(*schema, *library); - - for (auto& error : generator.getErrors()) { - parseContext.formatError(error, std::cout, "ERROR: "); - } - } - } - } diff --git a/mainwindow.cpp b/mainwindow.cpp index 41a26bd..c556403 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -1,15 +1,152 @@ #include "mainwindow.h" #include "ui_mainwindow.h" +#include +#include + +#include +#include +#include + +#include + MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow) { ui->setupUi(this); + + setupUi(); + + // define allowed methods + signatures.push_back(domain::FunctionSignature("divisible", std::vector{domain::Value::INT, domain::Value::INT})); + signatures.push_back(domain::FunctionSignature("less_then", std::vector{domain::Value::INT, domain::Value::INT})); + signatures.push_back(domain::FunctionSignature("greater_then", std::vector{domain::Value::INT, domain::Value::INT})); + signatures.push_back(domain::FunctionSignature("contains_address", std::vector{domain::Value::ADDRESS_SPACE, domain::Value::INT})); + signatures.push_back(domain::FunctionSignature("contains", std::vector{domain::Value::ADDRESS_SPACE, domain::Value::INT, domain::Value::INT})); + signatures.push_back(domain::FunctionSignature("unique", std::vector{domain::Value::ADDRESS_SPACE, domain::Value::INT, domain::Value::INT})); + +} + +void MainWindow::setupUi() +{ + auto layout = new QHBoxLayout(); + ui->centralwidget->setLayout(layout); + + // setup toolbar + ui->toolBar->addAction("Load library", this, &MainWindow::onLoadLibrary); + ui->toolBar->addAction("Load schema", this, &MainWindow::onLoadSchema); + ui->toolBar->addAction("Load test", this, &MainWindow::onTestModal); + + // setup central content + libraryDisplay = new display::Library(); + schemaDisplay = new display::Schema(); + + layout->setMargin(0); + layout->addWidget(libraryDisplay); + layout->addWidget(schemaDisplay, 1); + + +} + +void MainWindow::onTestModal() { + QString filename = "/home/bbr/Documents/personal/projects/modeler/schema.csl"; + + if(!filename.isEmpty()) { + clear(); + + ParseContext parseContext; + auto schemaNode = loadSchemaFromFile(&parseContext, filename.toStdString().c_str(), std::cout); + + if(schemaNode) { + domain::ComdelGenerator generator(signatures); + library = generator.loadLibrary(*schemaNode->library); + + for (auto& error : generator.getErrors()) { + parseContext.formatError(error, std::cout, "ERROR: "); + } + + if(library) { + schema = generator.loadSchema(*schemaNode, *library); + + for (auto& error : generator.getErrors()) { + parseContext.formatError(error, std::cout, "ERROR: "); + } + } + + libraryDisplay->setLibrary(library); + schemaDisplay->setSchema(schema); + } + } + +} + +void MainWindow::onLoadLibrary() { + auto filename = QFileDialog::getOpenFileName(this, + tr("Open library"), "/home", tr("Comdel library (*.csl)")); + + if(!filename.isEmpty()) { + clear(); + + ParseContext parseContext; + auto libraryNode = loadLibraryFromFile(&parseContext, filename.toStdString().c_str(), std::cout); + if(libraryNode) { + domain::ComdelGenerator generator(signatures); + library = generator.loadLibrary(*libraryNode); + + for (auto& error : generator.getErrors()) { + parseContext.formatError(error, std::cout, "ERROR: "); + } + + libraryDisplay->setLibrary(library); + + } else { + std::cout<<"Bad request"<library); + + for (auto& error : generator.getErrors()) { + parseContext.formatError(error, std::cout, "ERROR: "); + } + + if(library) { + schema = generator.loadSchema(*schemaNode, *library); + + for (auto& error : generator.getErrors()) { + parseContext.formatError(error, std::cout, "ERROR: "); + } + } + + libraryDisplay->setLibrary(library); + schemaDisplay->setSchema(schema); + } + } + +} + +void MainWindow::clear() { + schema = std::nullopt; + library = std::nullopt; + + libraryDisplay->setLibrary(library); + schemaDisplay->setSchema(schema); } MainWindow::~MainWindow() { delete ui; } - diff --git a/mainwindow.h b/mainwindow.h index 4643e32..95d740a 100644 --- a/mainwindow.h +++ b/mainwindow.h @@ -1,8 +1,15 @@ #ifndef MAINWINDOW_H #define MAINWINDOW_H +#include #include +#include +#include + +#include +#include + QT_BEGIN_NAMESPACE namespace Ui { class MainWindow; } QT_END_NAMESPACE @@ -15,6 +22,22 @@ public: MainWindow(QWidget *parent = nullptr); ~MainWindow(); + display::Library *libraryDisplay; + display::Schema *schemaDisplay; + + std::optional library = std::nullopt; + std::optional schema = std::nullopt; + + std::vector signatures; + + void setupUi(); + void clear(); + +private slots: + void onLoadLibrary(); + void onLoadSchema(); + void onTestModal(); + private: Ui::MainWindow *ui; }; diff --git a/mainwindow.ui b/mainwindow.ui index b232854..8a2a626 100644 --- a/mainwindow.ui +++ b/mainwindow.ui @@ -14,8 +14,28 @@ MainWindow - + + + + 0 + 0 + 800 + 23 + + + + + + toolBar + + + TopToolBarArea + + + false + +