Added connection generation

This commit is contained in:
Borna Rajković committed 2022-05-25 07:39:45 +02:00
1 parent cbff8ff5f2
commit 5cf8235608
16 files changed
+440 -35

No files matched your search

+12 -3
View File
@@ -4,9 +4,9 @@
#include "mainwindow.h"
#include <QMenu>
#include <QLine>
#include <QGraphicsSceneContextMenuEvent>
#include <iostream>
#include <QDebug>
namespace display {
@@ -47,14 +47,20 @@ void Component::contextMenuEvent(QGraphicsSceneContextMenuEvent *event) {
auto view = dynamic_cast<Schema*>(this->scene()->views()[0]);
view->state = Schema::CREATING_CONNECTION;
view->context.pin = this;
view->context.startingPoint = view->mapToScene(event->pos().toPoint());
view->context.startingPoint = dynamic_cast<ComponentGroup*>(this->parentItem())->pos() + QPointF(pin.getDisplayPin().getConnectionX(), pin.getDisplayPin().getConnectionY());
view->context.line = new QGraphicsLineItem(QLineF(view->context.startingPoint, event->scenePos()));
this->scene()->addItem(view->context.line);
view->showConnectable(this);
}
}
void Pin::mouseMoveEvent(QGraphicsSceneMouseEvent *event) {
auto view = dynamic_cast<Schema*>(this->scene()->views()[0]);
if(view->state == Schema::CREATING_CONNECTION) {
auto line = view->context.line->line();
line.setP2(event->scenePos());
view->context.line->setLine(line);
}
}
@@ -62,6 +68,9 @@ void Component::contextMenuEvent(QGraphicsSceneContextMenuEvent *event) {
if(event->button() == Qt::MouseButton::LeftButton) {
auto view = dynamic_cast<Schema*>(this->scene()->views()[0]);
view->state = Schema::DEFAULT;
this->scene()->removeItem(view->context.line);
delete view->context.line;
view->removeConnectable(event->scenePos());
}
}
+30 -4
View File
@@ -15,8 +15,10 @@ class Pin: public QGraphicsItemGroup
{
private:
domain::Pin pin;
std::shared_ptr<domain::ComponentInstance> componentInstance;
public:
Pin(domain::Pin pin): pin(pin) {
Pin(domain::Pin pin, std::shared_ptr<domain::ComponentInstance> componentInstance): pin(pin), componentInstance(componentInstance) {
pin.getDisplayPin().render(this);
}
@@ -25,6 +27,13 @@ public:
void mouseMoveEvent(QGraphicsSceneMouseEvent *event) override;
void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) override;
domain::Pin& getPin() {
return pin;
}
domain::ComponentInstance* getComponentInstance() {
return componentInstance.get();
}
};
class Component: public QGraphicsItemGroup
@@ -56,8 +65,13 @@ class ComponentGroup: public QGraphicsItemGroup
{
private:
std::shared_ptr<domain::ComponentInstance> componentInstance;
std::vector<display::Pin*> pins;
public:
std::shared_ptr<domain::ComponentInstance> getComponentInstance() { return componentInstance; }
std::vector<display::Pin*>& getPins() { return pins; }
explicit ComponentGroup(const std::shared_ptr<domain::ComponentInstance>& instance): componentInstance(instance) {
setFlag(ItemIsMovable, true);
setFlag(ItemSendsGeometryChanges, true);
@@ -67,7 +81,8 @@ public:
addToGroup(new display::Component(instance));
for(auto &pin: instance->component.getPins()) {
addToGroup(new display::Pin(pin));
pins.push_back(new display::Pin(pin, componentInstance));
addToGroup(pins.back());
}
setPos(instance->position.first, instance->position.second);
@@ -118,6 +133,12 @@ public:
auto pin = connection->instance->component.getPin(connection->connection.getComponent().pin).getDisplayPin();
setLine(connection->instance->position.first + pin.getConnectionX(), connection->instance->position.second + pin.getConnectionY(), connection->bus->position.first + busPosition.width()/2, connection->bus->position.second + busPosition.height()/2);
connection->start.first = connection->instance->position.first + pin.getConnectionX();
connection->start.second = connection->instance->position.second + pin.getConnectionY();
connection->end.first = connection->bus->position.first + busPosition.width()/2;
connection->end.second = connection->bus->position.second + busPosition.height()/2;
}
void contextMenuEvent(QGraphicsSceneContextMenuEvent *event) override;
@@ -130,10 +151,9 @@ public:
domain::DirectConnectionInstance* connection;
ComponentGroup* first;
ComponentGroup* second;
BusGroup* bus;
public:
DirectConnection(domain::DirectConnectionInstance* connection, ComponentGroup *first, ComponentGroup *second, BusGroup *bus): connection(connection), first(first), second(second), bus(bus) {
DirectConnection(domain::DirectConnectionInstance* connection, ComponentGroup *first, ComponentGroup *second): connection(connection), first(first), second(second) {
updateConnection();
setHandlesChildEvents(false);
}
@@ -144,6 +164,12 @@ public:
setLine(connection->instance->position.first + pin1.getConnectionX(), connection->instance->position.second + pin1.getConnectionY(),
connection->secondInstance->position.first + pin2.getConnectionX(), connection->secondInstance->position.second + pin2.getConnectionY());
connection->start.first = connection->instance->position.first + pin1.getConnectionX();
connection->start.second = connection->instance->position.second + pin1.getConnectionY();
connection->end.first = connection->secondInstance->position.first + pin2.getConnectionX();
connection->end.second = connection->secondInstance->position.second + pin2.getConnectionY();
}
void contextMenuEvent(QGraphicsSceneContextMenuEvent *event) override;
+166 -9
View File
@@ -3,14 +3,15 @@
#include <QDrag>
#include <QDragEnterEvent>
#include <QDropEvent>
#include <QMimeData>
#include <iostream>
namespace display {
Schema::Schema()
{
this->selectedBrush.setColor(QColor::fromRgb(20,20,125));
this->selectedPen.setColor(QColor::fromRgb(20, 20, 125));
this->setScene(&scene);
this->setAcceptDrops(true);
}
@@ -18,16 +19,21 @@ Schema::Schema()
void Schema::setSchema(domain::Schema* _schema, domain::Library* _library)
{
std::map<std::string, display::ComponentGroup*> components;
std::map<std::string, display::BusGroup*> buses;
components.clear();
buses.clear();
scene.clear();
connections.clear();
busConnections.clear();
this->schema = _schema;
this->library = _library;
if(schema != nullptr) {
for(auto &instance: schema->componentInstances) {
auto group = new display::ComponentGroup(instance);
for(auto pin: group->getPins()) {
display::Pin* p = pin;
domain::ConnectionComponent connection{instance->name, p->getPin().getName()};
pins.insert(std::make_pair(connection, p));
}
components.insert(std::make_pair(instance->name, group));
scene.addItem(group);
}
@@ -42,7 +48,13 @@ void Schema::setSchema(domain::Schema* _schema, domain::Library* _library)
auto busInstance = dynamic_cast<domain::BusConnectionInstance*>(connection.get());
if(busInstance != nullptr) {
auto con = new display::BusConnection(busInstance, components[busInstance->instance->name], buses[busInstance->bus->name]);
connections.push_back(con);
busConnections.push_back(con);
scene.addItem(con);
}
auto directInstance = dynamic_cast<domain::DirectConnectionInstance*>(connection.get());
if(directInstance != nullptr) {
auto con = new display::DirectConnection(directInstance, components[directInstance->instance->name], components[directInstance->secondInstance->name]);
directConnections.push_back(con);
scene.addItem(con);
}
}
@@ -51,7 +63,10 @@ void Schema::setSchema(domain::Schema* _schema, domain::Library* _library)
void Schema::updateConnections() {
if(schema != nullptr) {
for(auto conn: connections) {
for(auto conn: busConnections) {
conn->updateConnection();
}
for(auto conn: directConnections) {
conn->updateConnection();
}
}
@@ -61,8 +76,6 @@ void Schema::updateConnections() {
if(event->mimeData()->hasFormat("comdel/component") ||
event->mimeData()->hasFormat("comdel/bus")) {
event->acceptProposedAction();
} else {
std::cout<<"false"<< std::endl;
}
}
@@ -82,6 +95,13 @@ void Schema::updateConnections() {
auto group = new display::ComponentGroup(instance);
scene.addItem(group);
for(auto pin: group->getPins()) {
display::Pin* p = pin;
domain::ConnectionComponent connection{instance->name, p->getPin().getName()};
pins.insert(std::make_pair(connection, p));
}
components[instance->name] = group;
event->acceptProposedAction();
}
@@ -95,6 +115,7 @@ void Schema::updateConnections() {
auto group = new display::BusGroup(instance);
scene.addItem(group);
buses[instance->name] = group;
event->acceptProposedAction();
}
@@ -104,4 +125,140 @@ void Schema::updateConnections() {
event->acceptProposedAction();
}
void Schema::removeConnectable(QPointF endPoint) {
auto instance = context.pin->getComponentInstance();
auto& pin = context.pin->getPin();
auto busInstances = getAvailableConnectionBusses(instance, pin);
for(auto &bus: busInstances) {
auto rect = buses[bus->name]->boundingRect();
rect = QRectF(buses[bus->name]->x(), buses[bus->name]->y(), rect.width(), rect.height());
if(rect.contains(endPoint)) {
auto con = library->getConnection({instance->component.getName(), pin.getName()}, bus->bus.getName());
if(con.has_value()) {
std::vector<domain::InstanceAttribute> attributes;
for(auto attr: con->getAttributes()) {
attributes.emplace_back(attr.getName(), attr.getDefault(), attr);
}
auto conInstance = std::make_shared<domain::BusConnectionInstance>(instance, attributes, bus, *con);
schema->connections.push_back(conInstance);
if (conInstance != nullptr) {
auto c = new display::BusConnection(conInstance.get(), components[conInstance->instance->name],
buses[conInstance->bus->name]);
busConnections.push_back(c);
scene.addItem(c);
}
break;
}
}
}
auto pinInstances = getAvailableConnectionPins(instance, pin);
for(auto &pinInstance: pinInstances) {
auto rect = pins[pinInstance]->boundingRect();
rect.setX(pins[pinInstance]->scenePos().x());
rect.setY(pins[pinInstance]->scenePos().y());
if(rect.contains(endPoint)) {
auto name = components[pinInstance.component]->getComponentInstance()->component.getName();
auto con = library->getConnection({instance->component.getName(), pin.getName()}, {name, pinInstance.pin});
if(con.has_value()) {
auto bus = library->getBus(con->getBus());
auto busInstance = std::make_shared<domain::BusInstance>(bus.getName(), bus);
schema->busInstances.push_back(busInstance);
std::vector<domain::InstanceAttribute> attributes;
for(auto attr: con->getAttributes()) {
attributes.emplace_back(attr.getName(), attr.getDefault(), attr);
}
auto conInstance = std::make_shared<domain::DirectConnectionInstance>(instance, components[pinInstance.component]->getComponentInstance().get(), attributes, busInstance.get(), *con);
schema->connections.push_back(conInstance);
if (conInstance != nullptr) {
auto c = new display::DirectConnection(conInstance.get(), components[conInstance->instance->name], components[conInstance->secondInstance->name]);
directConnections.push_back(c);
scene.addItem(c);
}
break;
}
}
}
updateConnections();
for(auto& item: this->context.selectable) {
this->scene.removeItem(item);
delete item;
}
this->context.selectable.clear();
}
void Schema::showConnectable(Pin *domainPin) {
auto& pin = domainPin->getPin();
auto busInstances = getAvailableConnectionBusses(domainPin->getComponentInstance(), domainPin->getPin());
for(auto bus: busInstances) {
auto& group = buses[bus->name];
auto rect = new QGraphicsRectItem(group->boundingRect());
rect->setPen(selectedPen);
rect->setPos(group->scenePos());
auto _rect = rect->rect();
_rect.setWidth(_rect.width() + 1);
_rect.setHeight(_rect.height() + 1);
rect->setRect(_rect);
context.selectable.push_back(rect);
scene.addItem(rect);
}
std::vector<domain::ConnectionComponent> pinInstances = getAvailableConnectionPins(domainPin->getComponentInstance(), domainPin->getPin());
for(auto& pinInstance: pinInstances) {
auto& instance = pins[pinInstance];
auto rect = new QGraphicsRectItem(instance->boundingRect());
rect->setPen(selectedPen);
rect->setPos(instance->scenePos());
auto _rect = rect->rect();
_rect.setWidth(_rect.width() + 1);
_rect.setHeight(_rect.height() + 1);
rect->setRect(_rect);
context.selectable.push_back(rect);
scene.addItem(rect);
}
}
std::vector<domain::BusInstance*> Schema::getAvailableConnectionBusses(domain::ComponentInstance *instance, domain::Pin &pin) {
std::vector<domain::BusInstance*> instances;
for(const auto& bus: schema->busInstances) {
if(library->hasConnection(domain::ConnectionComponent{instance->component.getName(), pin.getName()}, bus->bus.getName())) {
instances.push_back(bus.get());
}
}
return instances;
}
std::vector<domain::ConnectionComponent> Schema::getAvailableConnectionPins(domain::ComponentInstance *instance, domain::Pin &pin) {
std::vector<domain::ConnectionComponent> instances;
domain::ConnectionComponent source{instance->component.getName(), pin.getName()};
for(const auto& entry: pins) {
std::string name = components[entry.first.component]->getComponentInstance()->component.getName();
if(library->hasConnection(source, domain::ConnectionComponent{name, entry.first.pin})) {
instances.push_back(entry.first);
}
}
return instances;
}
} // namespace display
+22 -2
View File
@@ -4,9 +4,11 @@
#include <QGraphicsView>
#include <QWidget>
#include <QGraphicsLineItem>
#include <comdel/domain/schema.h>
#include <comdel/domain/library.h>
#include "component_display.h"
namespace display {
@@ -18,27 +20,41 @@ class Schema: public QGraphicsView
public:
QBrush selectedBrush;
QPen selectedPen;
enum State {
DEFAULT,
CREATING_CONNECTION
};
struct Context {
display::Pin *pin;
display::Pin *pin = nullptr;
QPointF startingPoint;
QGraphicsLineItem *line = nullptr;
std::vector<QGraphicsRectItem*> selectable;
};
std::map<std::string, display::ComponentGroup*> components;
std::map<std::string, display::BusGroup*> buses;
std::map<domain::ConnectionComponent, display::Pin*> pins;
State state = DEFAULT;
Context context;
Schema();
std::vector<BusConnection*> connections;
std::vector<BusConnection*> busConnections;
std::vector<DirectConnection*> directConnections;
void setSchema(domain::Schema* schema, domain::Library* library);
void updateConnections();
void removeConnectable(QPointF f);
void showConnectable(Pin *pin);
protected:
void dragEnterEvent(QDragEnterEvent *event) override;
@@ -50,6 +66,10 @@ private:
domain::Schema* schema;
domain::Library* library;
std::vector<domain::BusInstance*> getAvailableConnectionBusses(domain::ComponentInstance *instance, domain::Pin &pin);
std::vector<domain::ConnectionComponent> getAvailableConnectionPins(domain::ComponentInstance *instance, domain::Pin &pin);
};
} // namespace display