diff --git a/CMakeLists.txt b/CMakeLists.txt index d121c10..1237ce9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -38,5 +38,5 @@ add_executable(SchemeEditor comdel/parser/comdellexer.cpp main.cpp mainwindow.ui - comdel/domain/comdelvalidator.cpp comdel/domain/comdelvalidator.h comdel/display/attribute_dialog.cpp comdel/display/attribute_dialog.h comdel/display/name_dialog.cpp comdel/display/name_dialog.h comdel/domain/comdel_generator.cpp comdel/domain/comdel_generator.h) + comdel/domain/comdelvalidator.cpp comdel/domain/comdelvalidator.h comdel/display/attribute_dialog.cpp comdel/display/attribute_dialog.h comdel/display/name_dialog.cpp comdel/display/name_dialog.h comdel/domain/comdel_generator.cpp comdel/domain/comdel_generator.h comdel/display/library_list.cpp comdel/display/library_list.h) target_link_libraries(SchemeEditor Qt5::Core Qt5::Gui Qt5::Widgets) diff --git a/comdel/display/component_display.cpp b/comdel/display/component_display.cpp index f4b33c1..086578d 100644 --- a/comdel/display/component_display.cpp +++ b/comdel/display/component_display.cpp @@ -6,6 +6,7 @@ #include #include #include +#include namespace display { @@ -35,8 +36,36 @@ void Component::contextMenuEvent(QGraphicsSceneContextMenuEvent *event) { menu.exec(event->screenPos()); } + void Pin::contextMenuEvent(QGraphicsSceneContextMenuEvent *event) { + QMenu menu; + menu.addAction("Connect pin", [&]() {}); + menu.exec(event->screenPos()); + } -void Bus::contextMenuEvent(QGraphicsSceneContextMenuEvent *event) { + void Pin::mousePressEvent(QGraphicsSceneMouseEvent *event) { + if(event->button() == Qt::MouseButton::LeftButton) { + auto view = dynamic_cast(this->scene()->views()[0]); + view->state = Schema::CREATING_CONNECTION; + view->context.pin = this; + view->context.startingPoint = view->mapToScene(event->pos().toPoint()); + } + } + + void Pin::mouseMoveEvent(QGraphicsSceneMouseEvent *event) { + auto view = dynamic_cast(this->scene()->views()[0]); + if(view->state == Schema::CREATING_CONNECTION) { + + } + } + + void Pin::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) { + if(event->button() == Qt::MouseButton::LeftButton) { + auto view = dynamic_cast(this->scene()->views()[0]); + view->state = Schema::DEFAULT; + } + } + + void Bus::contextMenuEvent(QGraphicsSceneContextMenuEvent *event) { QMenu menu; menu.addAction("Izmjeni ime", [this](){ auto dialog = new NameDialog(this->busInstance.get()); @@ -107,4 +136,5 @@ void Bus::contextMenuEvent(QGraphicsSceneContextMenuEvent *event) { } menu.exec(event->screenPos()); } + } // namespace display diff --git a/comdel/display/component_display.h b/comdel/display/component_display.h index 09b9208..792bd23 100644 --- a/comdel/display/component_display.h +++ b/comdel/display/component_display.h @@ -5,6 +5,8 @@ #include #include +#include +#include #include "comdel/domain/connectioninstance.h" namespace display { @@ -17,6 +19,12 @@ public: Pin(domain::Pin pin): pin(pin) { pin.getDisplayPin().render(this); } + + void contextMenuEvent(QGraphicsSceneContextMenuEvent *event) override; + void mousePressEvent(QGraphicsSceneMouseEvent *event) override; + void mouseMoveEvent(QGraphicsSceneMouseEvent *event) override; + void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) override; + }; class Component: public QGraphicsItemGroup diff --git a/comdel/display/library_display.cpp b/comdel/display/library_display.cpp index e16f12c..749c4ad 100644 --- a/comdel/display/library_display.cpp +++ b/comdel/display/library_display.cpp @@ -11,8 +11,8 @@ Library::Library() auto layout = new QVBoxLayout(); this->setLayout(layout); - componentList = new QListWidget(); - busList = new QListWidget(); + componentList = new LibraryList(this); + busList = new LibraryList(this); layout->setMargin(4); layout->addWidget(new QLabel("Components:")); @@ -34,14 +34,14 @@ void Library::setLibrary(std::optional library) { } for(auto& component: library->getComponents()) { - auto item = new QListWidgetItem{QString::fromStdString(component.getName())}; + auto item = new LibraryListItem{component.getName(), "comdel/component", component.getName(), componentList}; 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())}; + auto item = new LibraryListItem{bus.getName(), "comdel/bus", bus.getName(), busList}; item->setToolTip(QString::fromStdString(bus.getTooltip())); busList->addItem(item); } diff --git a/comdel/display/library_display.h b/comdel/display/library_display.h index 51125fe..c35aa36 100644 --- a/comdel/display/library_display.h +++ b/comdel/display/library_display.h @@ -5,6 +5,7 @@ #include #include +#include "library_list.h" namespace display { @@ -18,8 +19,8 @@ public: private: std::optional library; - QListWidget *componentList; - QListWidget *busList; + LibraryList *componentList; + LibraryList *busList; }; diff --git a/comdel/display/library_list.cpp b/comdel/display/library_list.cpp new file mode 100644 index 0000000..0b769a2 --- /dev/null +++ b/comdel/display/library_list.cpp @@ -0,0 +1,31 @@ +// +// Created by bbr on 22.05.22.. +// + +#include "library_list.h" + +#include +#include +#include + +namespace display { + + LibraryList::LibraryList(QWidget *parent): QListWidget(parent) { + setDragDropMode(DragOnly); + } + + QMimeData *LibraryList::mimeData(const QList items) const { + for(auto qItem: items) { + // we only allow one item to be dragged at a time + auto item = dynamic_cast(qItem); + auto* md = new QMimeData(); + md->setData(QString::fromStdString(item->mimeType), QByteArray::fromStdString(item->value)); + return md; + } + return nullptr; + } + + LibraryListItem::LibraryListItem(std::string title, std::string mimeType, std::string value, QListWidget *parent): QListWidgetItem(parent), mimeType(mimeType), value(value) { + setText(QString::fromStdString(title)); + } +} // display \ No newline at end of file diff --git a/comdel/display/library_list.h b/comdel/display/library_list.h new file mode 100644 index 0000000..4b8ab76 --- /dev/null +++ b/comdel/display/library_list.h @@ -0,0 +1,34 @@ +// +// Created by bbr on 22.05.22.. +// + +#ifndef SCHEMEEDITOR_LIBRARY_LIST_H +#define SCHEMEEDITOR_LIBRARY_LIST_H + +#include +#include +#include + +namespace display { + + class LibraryList: public QListWidget { + Q_OBJECT + public: + LibraryList(QWidget *parent); + + protected: + QMimeData *mimeData(const QList items) const override; + }; + + class LibraryListItem: public QListWidgetItem { + + public: + std::string mimeType; + std::string value; + + LibraryListItem(std::string title, std::string mimeType, std::string value, QListWidget *parent); + }; + +} // display + +#endif //SCHEMEEDITOR_LIBRARY_LIST_H diff --git a/comdel/display/schema_display.cpp b/comdel/display/schema_display.cpp index dd546a3..7dae0e8 100644 --- a/comdel/display/schema_display.cpp +++ b/comdel/display/schema_display.cpp @@ -1,15 +1,22 @@ #include "component_display.h" #include "schema_display.h" +#include +#include +#include +#include +#include + namespace display { Schema::Schema() { this->setScene(&scene); + this->setAcceptDrops(true); } -void Schema::setSchema(domain::Schema* _schema) +void Schema::setSchema(domain::Schema* _schema, domain::Library* _library) { std::map components; std::map buses; @@ -17,6 +24,7 @@ void Schema::setSchema(domain::Schema* _schema) scene.clear(); connections.clear(); this->schema = _schema; + this->library = _library; if(schema != nullptr) { for(auto &instance: schema->componentInstances) { auto group = new display::ComponentGroup(instance); @@ -49,4 +57,51 @@ void Schema::updateConnections() { } } + void Schema::dragEnterEvent(QDragEnterEvent *event) { + if(event->mimeData()->hasFormat("comdel/component") || + event->mimeData()->hasFormat("comdel/bus")) { + event->acceptProposedAction(); + } else { + std::cout<<"false"<< std::endl; + } + } + + void Schema::dropEvent(QDropEvent *event) { + if(event->mimeData()->hasFormat("comdel/component")) { + auto component = library->getComponent(event->mimeData()->data("comdel/component").toStdString()); + + auto attributes = std::vector(); + for(auto attr: component.getAttributes()) { + attributes.emplace_back(attr.getName(), attr.getDefault(), attr); + } + + auto currentPos = this->mapToScene(event->pos()); + + auto instance = std::make_shared(component.getInstanceName(), attributes, std::make_pair(currentPos.x(), currentPos.y()), component); + schema->componentInstances.push_back(instance); + + auto group = new display::ComponentGroup(instance); + scene.addItem(group); + + event->acceptProposedAction(); + } + if(event->mimeData()->hasFormat("comdel/bus")) { + auto bus = library->getBus(event->mimeData()->data("comdel/bus").toStdString()); + + auto currentPos = this->mapToScene(event->pos()); + + auto instance = std::make_shared(bus.getName(), std::make_pair(currentPos.x(), currentPos.y()), bus, 50); + schema->busInstances.push_back(instance); + + auto group = new display::BusGroup(instance); + scene.addItem(group); + + event->acceptProposedAction(); + } + } + + void Schema::dragMoveEvent(QDragMoveEvent *event) { + event->acceptProposedAction(); + } + } // namespace display diff --git a/comdel/display/schema_display.h b/comdel/display/schema_display.h index db7ad98..131f0bd 100644 --- a/comdel/display/schema_display.h +++ b/comdel/display/schema_display.h @@ -6,6 +6,7 @@ #include #include +#include namespace display { @@ -13,19 +14,42 @@ namespace display { class Schema: public QGraphicsView { + Q_OBJECT + public: + + enum State { + DEFAULT, + CREATING_CONNECTION + }; + + struct Context { + display::Pin *pin; + QPointF startingPoint; + }; + + State state = DEFAULT; + Context context; + Schema(); std::vector connections; - void setSchema(domain::Schema* schema); + void setSchema(domain::Schema* schema, domain::Library* library); void updateConnections(); +protected: + + void dragEnterEvent(QDragEnterEvent *event) override; + void dropEvent(QDropEvent *event) override; + void dragMoveEvent(QDragMoveEvent *event) override; + private: QGraphicsScene scene; domain::Schema* schema; + domain::Library* library; }; } // namespace display diff --git a/mainwindow.cpp b/mainwindow.cpp index 33cb6f9..1094f7e 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -96,7 +96,7 @@ void MainWindow::onLoadLibrary() { // on library load we create a new schema schema = new domain::Schema(); - schemaDisplay->setSchema(schema); + schemaDisplay->setSchema(schema, &(*library)); } } else { @@ -145,7 +145,7 @@ void MainWindow::onLoadSchema() { if(generator.getErrors().empty()) { libraryDisplay->setLibrary(library); - schemaDisplay->setSchema(schema); + schemaDisplay->setSchema(schema, &(*library)); } } } @@ -251,7 +251,7 @@ void MainWindow::clear() { library = std::nullopt; libraryDisplay->setLibrary(library); - schemaDisplay->setSchema(schema); + schemaDisplay->setSchema(schema, nullptr); } MainWindow::~MainWindow()