Added initial view

This commit is contained in:
Borna Rajkovic 2022-04-08 00:21:23 +02:00
parent 3cdd126927
commit 4b99a0bf33
14 changed files with 415 additions and 38 deletions

View File

@ -9,6 +9,9 @@ CONFIG += c++17
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
SOURCES += \ SOURCES += \
comdel/display/component_display.cpp \
comdel/display/library_display.cpp \
comdel/display/schema_display.cpp \
comdel/domain/addressspace.cpp \ comdel/domain/addressspace.cpp \
comdel/domain/attribute.cpp \ comdel/domain/attribute.cpp \
comdel/domain/bus.cpp \ comdel/domain/bus.cpp \
@ -39,6 +42,9 @@ SOURCES += \
mainwindow.cpp mainwindow.cpp
HEADERS += \ HEADERS += \
comdel/display/component_display.h \
comdel/display/library_display.h \
comdel/display/schema_display.h \
comdel/domain/addressspace.h \ comdel/domain/addressspace.h \
comdel/domain/attribute.h \ comdel/domain/attribute.h \
comdel/domain/bus.h \ comdel/domain/bus.h \

View File

@ -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

View File

@ -0,0 +1,28 @@
#ifndef DISPLAY_COMPONENT_H
#define DISPLAY_COMPONENT_H
#include <comdel/domain/instance.h>
#include <comdel/domain/wireinstance.h>
#include <QGraphicsItemGroup>
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

View File

@ -0,0 +1,52 @@
#include "library_display.h"
#include <QLabel>
#include <QListWidget>
#include <QVBoxLayout>
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<domain::Library> 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

View File

@ -0,0 +1,28 @@
#ifndef DISPLAY_LIBRARY_H
#define DISPLAY_LIBRARY_H
#include <QListWidget>
#include <QWidget>
#include <comdel/domain/library.h>
namespace display {
class Library: public QWidget
{
public:
Library();
void setLibrary(std::optional<domain::Library> library);
private:
std::optional<domain::Library> library;
QListWidget *componentList;
QListWidget *busList;
};
} // namespace display
#endif // DISPLAY_LIBRARY_H

View File

@ -0,0 +1,40 @@
#include "component_display.h"
#include "schema_display.h"
namespace display {
Schema::Schema()
{
this->setScene(&scene);
}
void Schema::setSchema(std::optional<domain::Schema>& schema)
{
scene.clear();
this->schema = schema;
if(schema.has_value()) {
for(auto &instance: schema->instances) {
Component *group = nullptr;
auto component = dynamic_cast<domain::ComponentInstance*>(instance);
if(component) {
group = Component::ofComponent(component);
}
auto bus = dynamic_cast<domain::BusInstance*>(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

View File

@ -0,0 +1,28 @@
#ifndef DISPLAY_SCHEMA_H
#define DISPLAY_SCHEMA_H
#include <QGraphicsView>
#include <QWidget>
#include <comdel/domain/schema.h>
namespace display {
class Schema: public QGraphicsView
{
public:
Schema();
void setSchema(std::optional<domain::Schema>& schema);
private:
QGraphicsScene scene;
std::optional<domain::Schema> schema;
};
} // namespace display
#endif // DISPLAY_SCHEMA_H

View File

@ -727,7 +727,11 @@ std::optional<WireInstance*> ComdelGenerator::loadWireInstance(WireInstanceNode
if(!display) { if(!display) {
return nullopt; return nullopt;
} }
return std::optional<WireInstance*>(new WireInstance(node.name.value, *display)); std::pair<int, int> position = std::make_pair(0, 0);
if(node.position) {
position = std::make_pair(node.position->first.value, node.position->second.value);
}
return std::optional<WireInstance*>(new WireInstance(node.name.value, *display, position));
} }

View File

@ -2,8 +2,8 @@
namespace domain { namespace domain {
WireInstance::WireInstance(std::string name, Display display) WireInstance::WireInstance(std::string name, Display display, std::pair<int, int> position)
: name(name), display(display) : name(name), display(display), position(position)
{} {}

View File

@ -14,8 +14,9 @@ class WireInstance
public: public:
std::string name; std::string name;
Display display; Display display;
std::pair<int, int> position;
WireInstance(std::string name, Display display); WireInstance(std::string name, Display display, std::pair<int, int> position);
}; };
} // namespace domain } // namespace domain

View File

@ -11,40 +11,8 @@
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
/*
QApplication a(argc, argv); QApplication a(argc, argv);
MainWindow w; MainWindow w;
w.show(); w.show();
return a.exec(); return a.exec();
*/
ParseContext parseContext;
auto schema = loadSchemaFromFile(&parseContext, "/home/bbr/Documents/personal/projects/modeler/schema.csl", std::cout);
if(schema) {
std::vector<domain::FunctionSignature> signatures;
signatures.push_back(domain::FunctionSignature("divisible", std::vector<domain::Value::ValueType>{domain::Value::INT, domain::Value::INT}));
signatures.push_back(domain::FunctionSignature("less_then", std::vector<domain::Value::ValueType>{domain::Value::INT, domain::Value::INT}));
signatures.push_back(domain::FunctionSignature("greater_then", std::vector<domain::Value::ValueType>{domain::Value::INT, domain::Value::INT}));
signatures.push_back(domain::FunctionSignature("contains_address", std::vector<domain::Value::ValueType>{domain::Value::ADDRESS_SPACE, domain::Value::INT}));
signatures.push_back(domain::FunctionSignature("contains", std::vector<domain::Value::ValueType>{domain::Value::ADDRESS_SPACE, domain::Value::INT, domain::Value::INT}));
signatures.push_back(domain::FunctionSignature("unique", std::vector<domain::Value::ValueType>{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: ");
}
}
}
} }

View File

@ -1,15 +1,152 @@
#include "mainwindow.h" #include "mainwindow.h"
#include "ui_mainwindow.h" #include "ui_mainwindow.h"
#include <QFileDialog>
#include <QHBoxLayout>
#include <comdel/parser/parsecontext.h>
#include <comdel/parser/parserutil.h>
#include <comdel/domain/comdelgenerator.h>
#include <iostream>
MainWindow::MainWindow(QWidget *parent) MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent) : QMainWindow(parent)
, ui(new Ui::MainWindow) , ui(new Ui::MainWindow)
{ {
ui->setupUi(this); ui->setupUi(this);
setupUi();
// define allowed methods
signatures.push_back(domain::FunctionSignature("divisible", std::vector<domain::Value::ValueType>{domain::Value::INT, domain::Value::INT}));
signatures.push_back(domain::FunctionSignature("less_then", std::vector<domain::Value::ValueType>{domain::Value::INT, domain::Value::INT}));
signatures.push_back(domain::FunctionSignature("greater_then", std::vector<domain::Value::ValueType>{domain::Value::INT, domain::Value::INT}));
signatures.push_back(domain::FunctionSignature("contains_address", std::vector<domain::Value::ValueType>{domain::Value::ADDRESS_SPACE, domain::Value::INT}));
signatures.push_back(domain::FunctionSignature("contains", std::vector<domain::Value::ValueType>{domain::Value::ADDRESS_SPACE, domain::Value::INT, domain::Value::INT}));
signatures.push_back(domain::FunctionSignature("unique", std::vector<domain::Value::ValueType>{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"<<std::endl;
}
}
}
void MainWindow::onLoadSchema() {
auto filename = QFileDialog::getOpenFileName(this,
tr("Open schema"), "/home", tr("Comdel 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::clear() {
schema = std::nullopt;
library = std::nullopt;
libraryDisplay->setLibrary(library);
schemaDisplay->setSchema(schema);
} }
MainWindow::~MainWindow() MainWindow::~MainWindow()
{ {
delete ui; delete ui;
} }

View File

@ -1,8 +1,15 @@
#ifndef MAINWINDOW_H #ifndef MAINWINDOW_H
#define MAINWINDOW_H #define MAINWINDOW_H
#include <QListWidget>
#include <QMainWindow> #include <QMainWindow>
#include <comdel/display/library_display.h>
#include <comdel/display/schema_display.h>
#include <comdel/domain/library.h>
#include <comdel/domain/schema.h>
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; } namespace Ui { class MainWindow; }
QT_END_NAMESPACE QT_END_NAMESPACE
@ -15,6 +22,22 @@ public:
MainWindow(QWidget *parent = nullptr); MainWindow(QWidget *parent = nullptr);
~MainWindow(); ~MainWindow();
display::Library *libraryDisplay;
display::Schema *schemaDisplay;
std::optional<domain::Library> library = std::nullopt;
std::optional<domain::Schema> schema = std::nullopt;
std::vector<domain::FunctionSignature> signatures;
void setupUi();
void clear();
private slots:
void onLoadLibrary();
void onLoadSchema();
void onTestModal();
private: private:
Ui::MainWindow *ui; Ui::MainWindow *ui;
}; };

View File

@ -14,8 +14,28 @@
<string>MainWindow</string> <string>MainWindow</string>
</property> </property>
<widget class="QWidget" name="centralwidget"/> <widget class="QWidget" name="centralwidget"/>
<widget class="QMenuBar" name="menubar"/> <widget class="QMenuBar" name="menubar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>800</width>
<height>23</height>
</rect>
</property>
</widget>
<widget class="QStatusBar" name="statusbar"/> <widget class="QStatusBar" name="statusbar"/>
<widget class="QToolBar" name="toolBar">
<property name="windowTitle">
<string>toolBar</string>
</property>
<attribute name="toolBarArea">
<enum>TopToolBarArea</enum>
</attribute>
<attribute name="toolBarBreak">
<bool>false</bool>
</attribute>
</widget>
</widget> </widget>
<resources/> <resources/>
<connections/> <connections/>