diff --git a/comdel/display/component_display.cpp b/comdel/display/component_display.cpp index ba55739..f865f89 100644 --- a/comdel/display/component_display.cpp +++ b/comdel/display/component_display.cpp @@ -6,7 +6,6 @@ #include #include #include -#include namespace display { @@ -96,6 +95,18 @@ void Component::contextMenuEvent(QGraphicsSceneContextMenuEvent *event) { return QGraphicsItem::itemChange(change, value); } + BusGroup::BusGroup(const std::shared_ptr &instance): busInstance(instance) { + setFlag(ItemIsMovable, true); + setFlag(ItemSendsGeometryChanges, true); + + setHandlesChildEvents(false); + + bus = new display::Bus(instance); + addToGroup(bus); + + setPos(instance->position.first, instance->position.second); + } + QVariant ComponentGroup::itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant &value) { if (change == ItemPositionChange && scene()) { diff --git a/comdel/display/component_display.h b/comdel/display/component_display.h index f82d7c8..c7ac893 100644 --- a/comdel/display/component_display.h +++ b/comdel/display/component_display.h @@ -55,10 +55,10 @@ class Bus: public QGraphicsItemGroup std::shared_ptr busInstance; public: Bus(const std::shared_ptr& instance): busInstance(instance) { - instance->bus.getDisplay()->render(this); + instance->bus.getDisplayBus()->render(this, instance->size); } + domain::BusInstance *getBusInstance() { return busInstance.get(); } void contextMenuEvent(QGraphicsSceneContextMenuEvent *event) override; - }; class ComponentGroup: public QGraphicsItemGroup @@ -97,18 +97,12 @@ class BusGroup: public QGraphicsItemGroup { private: std::shared_ptr busInstance; + display::Bus* bus; public: - explicit BusGroup(const std::shared_ptr& instance): busInstance(instance) { - setFlag(ItemIsMovable, true); - setFlag(ItemSendsGeometryChanges, true); + explicit BusGroup(const std::shared_ptr& instance); - setHandlesChildEvents(false); - - addToGroup(new display::Bus(instance)); - - setPos(instance->position.first, instance->position.second); - } + display::Bus* getBus() { return bus; } protected: virtual QVariant itemChange(GraphicsItemChange change, const QVariant &value); diff --git a/comdel/display/schema_display.cpp b/comdel/display/schema_display.cpp index 01f0b88..00b0ef1 100644 --- a/comdel/display/schema_display.cpp +++ b/comdel/display/schema_display.cpp @@ -38,7 +38,7 @@ void Schema::setSchema(domain::Schema* _schema, domain::Library* _library) scene.addItem(group); } for(auto &instance: schema->busInstances) { - if(instance->bus.getDisplay().has_value()) { + if(instance->bus.getDisplayBus().has_value()) { auto group = new display::BusGroup(instance); buses.insert(std::make_pair(instance->name, group)); scene.addItem(group); @@ -110,7 +110,7 @@ void Schema::updateConnections() { auto currentPos = this->mapToScene(event->pos()); - auto instance = std::make_shared(bus.getName(), std::make_pair(currentPos.x(), currentPos.y()), bus, 50); + auto instance = std::make_shared(bus.getName(), std::make_pair(currentPos.x(), currentPos.y()), bus); schema->busInstances.push_back(instance); auto group = new display::BusGroup(instance); diff --git a/comdel/domain/bus.cpp b/comdel/domain/bus.cpp index 4492014..683ad05 100644 --- a/comdel/domain/bus.cpp +++ b/comdel/domain/bus.cpp @@ -26,8 +26,8 @@ Wire::WireType Wire::getType() { return type; } -Bus::Bus(std::string name, std::string tooltip, BusType type, std::pair count, std::vector wires, std::optional display) - : name(name), tooltip(tooltip), type(type), count(count), wires(wires), display(display) +Bus::Bus(std::string name, std::string tooltip, BusType type, std::pair count, std::vector wires, std::optional displayBus) + : name(name), tooltip(tooltip), type(type), count(count), wires(wires), displayBus(displayBus) {} std::string Bus::getName() { @@ -42,12 +42,11 @@ Bus::BusType Bus::getType() { std::pair Bus::getCount() { return count; } -std::optional Bus::getDisplay() { - return display; -} std::vector Bus::getWires() { return wires; } - +std::optional Bus::getDisplayBus() { + return displayBus; +} } // namespace domain diff --git a/comdel/domain/bus.h b/comdel/domain/bus.h index dbaab10..13d4386 100644 --- a/comdel/domain/bus.h +++ b/comdel/domain/bus.h @@ -55,18 +55,18 @@ private: BusType type; std::pair count; - std::optional display; + std::optional displayBus; std::vector wires; public: - Bus(std::string name, std::string tooltip, BusType type, std::pair count, std::vector wires, std::optional display = std::nullopt); + Bus(std::string name, std::string tooltip, BusType type, std::pair count, std::vector wires, std::optional display = std::nullopt); std::string getName(); std::string getTooltip(); BusType getType(); std::pair getCount(); std::vector getWires(); - std::optional getDisplay(); + std::optional getDisplayBus(); }; } // namespace domain diff --git a/comdel/domain/comdel_generator.cpp b/comdel/domain/comdel_generator.cpp index 03836dc..b9393b7 100644 --- a/comdel/domain/comdel_generator.cpp +++ b/comdel/domain/comdel_generator.cpp @@ -125,8 +125,8 @@ void generateBus(BusInstance *bus, ostream &buffer) { buffer << "\n"; buffer << "\t\t// " << bus->name << " bus\n\n"; - if(bus->bus.getDisplay().has_value()) { - bus->bus.getDisplay()->comdel(buffer, bus->position.first, bus->position.second, bus->size); + if(bus->bus.getDisplayBus().has_value()) { + bus->bus.getDisplayBus()->comdel(buffer, bus->position.first, bus->position.second, bus->size); } } diff --git a/comdel/domain/display.h b/comdel/domain/display.h index cc46f8f..ed87bee 100644 --- a/comdel/domain/display.h +++ b/comdel/domain/display.h @@ -20,7 +20,7 @@ public: group->addToGroup(new QGraphicsRectItem(x,y,w,h)); } - void comdel(std::ostream &buffer, int x, int y, int size) { + void comdel(std::ostream &buffer, int x, int y) { buffer << "\t\trectangle {\n"; buffer << "\t\t\tx: " << (this->x + x) << "; y: " << (this->y + y) << ";\n"; buffer << "\t\t\tw: " << w << "; h: " << h << ";\n"; @@ -39,7 +39,7 @@ public: group->addToGroup(new QGraphicsLineItem(x1, y1, x2, y2)); } - void comdel(std::ostream &buffer, int x, int y, int size) { + void comdel(std::ostream &buffer, int x, int y) { buffer << "\t\tline {\n"; buffer << "\t\t\tx1: " << (x1 + x) << "; y1: " << (y1 + y) << ";\n"; buffer << "\t\t\tx2: " << (x2 + x) << "; y2: " << (y2 + y) << ";\n"; @@ -47,36 +47,77 @@ public: } }; -enum Orientation { +enum PinOrientation { LEFT, RIGHT, TOP, BOTTOM }; +enum BusOrientation { + VERTICAL, HORIZONTAL +}; enum PinType { IN, OUT, IN_OUT }; + +class Bus { +public: + int x, y, w, h; + BusOrientation orientation; + + Bus(int x, int y, int w, int h, BusOrientation orientation): x(x), y(y), w(w), h(h), orientation(orientation) {} + + void render(QGraphicsItemGroup *group, int size) { + if(orientation == HORIZONTAL) { + group->addToGroup(new QGraphicsRectItem(x,y,size, h)); + } else { + group->addToGroup(new QGraphicsRectItem(x,y,w,size)); + } + } + + int getDefaultSize() { + if(orientation == HORIZONTAL) { + return w; + } else { + return h; + } + } + + void comdel(std::ostream &buffer, int x, int y, int size) { + buffer << "\t\trectangle {\n"; + buffer << "\t\t\tx: " << (this->x + x) << "; y: " << (this->y + y) << ";\n"; + if(orientation == HORIZONTAL) { + buffer << "\t\t\tw: " << size << "; h: " << h << ";\n"; + } else { + buffer << "\t\t\tw: " << w << "; h: " << size << ";\n"; + } + buffer << "\t\t}\n\n"; + } + +}; + + class Pin { public: - Orientation orientation; + PinOrientation orientation; PinType pinType; int x, y, w, h; - Pin(int x, int y, int w, int h, Orientation orientation, PinType pinType): x(x), y(y), w(w), h(h), orientation(orientation), pinType(pinType) {} + Pin(int x, int y, int w, int h, PinOrientation orientation, PinType pinType): x(x), y(y), w(w), h(h), orientation(orientation), pinType(pinType) {} void renderIn(QGraphicsItemGroup *group) { QPolygon polygon; switch (orientation) { - case Orientation::TOP: + case PinOrientation::TOP: polygon << QPoint(x, y) << QPoint(x, y+h) << QPoint(x+w, y+h) << QPoint(x+w, y) << QPoint(x+w/2, y+h/2); break; - case Orientation::BOTTOM: + case PinOrientation::BOTTOM: polygon << QPoint(x, y) << QPoint(x, y+h) << QPoint(x+w/2, y+h/2) << QPoint(x+w, y+h) << QPoint(x+w, y); break; - case Orientation::LEFT: + case PinOrientation::LEFT: polygon << QPoint(x, y) << QPoint(x+w/2, y+h/2) << QPoint(x, y+h) << QPoint(x+w, y+h) << QPoint(x+w, y); break; - case Orientation::RIGHT: + case PinOrientation::RIGHT: polygon << QPoint(x, y) << QPoint(x, y+h) << QPoint(x+w, y+h) << QPoint(x+w/2, y+h/2) << QPoint(x+w, y); break; } @@ -87,16 +128,16 @@ public: QPolygon polygon; switch (orientation) { - case Orientation::TOP: + case PinOrientation::TOP: polygon << QPoint(x, y+h/2) << QPoint(x, y+h) << QPoint(x+w, y+h) << QPoint(x+w, y+h/2) << QPoint(x+w/2, y); break; - case Orientation::BOTTOM: + case PinOrientation::BOTTOM: polygon << QPoint(x, y) << QPoint(x, y+h/2) << QPoint(x+w/2, y+h) << QPoint(x+w, y+h/2) << QPoint(x+w, y); break; - case Orientation::LEFT: + case PinOrientation::LEFT: polygon << QPoint(x+w, y) << QPoint(x+w/2, y) << QPoint(x, y+h/2) << QPoint(x+w/2, y+h) << QPoint(x+w, y+w); break; - case Orientation::RIGHT: + case PinOrientation::RIGHT: polygon << QPoint(x, y) << QPoint(x, y+h) << QPoint(x+w/2, y+h) << QPoint(x+w, y+h/2) << QPoint(x+w/2, y); break; } @@ -123,12 +164,12 @@ public: int getConnectionX() { switch (orientation) { - case ui::Orientation::TOP: - case ui::Orientation::BOTTOM: + case ui::PinOrientation::TOP: + case ui::PinOrientation::BOTTOM: return x+w/2; - case ui::Orientation::LEFT: + case ui::PinOrientation::LEFT: return x; - case ui::Orientation::RIGHT: + case ui::PinOrientation::RIGHT: return x+w; } return 0; @@ -136,12 +177,12 @@ public: int getConnectionY() { switch (orientation) { - case ui::Orientation::LEFT: - case ui::Orientation::RIGHT: + case ui::PinOrientation::LEFT: + case ui::PinOrientation::RIGHT: return y+h/2; - case ui::Orientation::TOP: + case ui::PinOrientation::TOP: return y; - case ui::Orientation::BOTTOM: + case ui::PinOrientation::BOTTOM: return y+h; } return 0; @@ -151,21 +192,25 @@ public: class Item { public: - Item(): rect(std::nullopt), line(std::nullopt), pin(std::nullopt) {} + Item(): rect(std::nullopt), line(std::nullopt), pin(std::nullopt), bus(std::nullopt) {} - void render(QGraphicsItemGroup *group) { + void render(QGraphicsItemGroup *group, int size = 0) { if(rect) rect->render(group); if(line) line->render(group); if(pin) pin->render(group); + if(bus) bus->render(group, size); } std::optional rect = std::nullopt; std::optional line = std::nullopt; std::optional pin = std::nullopt; + std::optional bus = std::nullopt; - void comdel(std::ostream &buffer, int x, int y, int size) { - if(rect) rect->comdel(buffer, x, y, size); - if(line) line->comdel(buffer, x, y, size); + void comdel(std::ostream &buffer, int x, int y, int size = 0) { + if(rect) rect->comdel(buffer, x, y); + if(line) line->comdel(buffer, x, y); + // pins aren't exported + if(bus) bus->comdel(buffer, x, y, size); } }; @@ -183,7 +228,7 @@ public: } } - void comdel(std::ostream &buffer, int x, int y, int size) { + void comdel(std::ostream &buffer, int x, int y, int size = 0) { for(auto &item: items) { item.comdel(buffer, x, y, size); } diff --git a/comdel/domain/instance.cpp b/comdel/domain/instance.cpp index 7deb689..77143da 100644 --- a/comdel/domain/instance.cpp +++ b/comdel/domain/instance.cpp @@ -4,7 +4,11 @@ namespace domain { BusInstance::BusInstance(std::string name, std::pair position, Bus bus, int size) : name(name), position(position), bus(bus), size(size) -{} +{ + if(size < 0 && bus.getDisplayBus().has_value()) { + this->size = bus.getDisplayBus()->getDefaultSize(); + } +} BusInstance::BusInstance(std::string name, Bus bus): name(name), bus(bus), position(0,0), size(0) {} diff --git a/comdel/domain/instance.h b/comdel/domain/instance.h index 38c158d..99428a0 100644 --- a/comdel/domain/instance.h +++ b/comdel/domain/instance.h @@ -23,7 +23,7 @@ public: BusInstance(std::string name, Bus bus); - BusInstance(std::string name, std::pair position, Bus bus, int size); + BusInstance(std::string name, std::pair position, Bus bus, int size = -1); virtual ~BusInstance() = default; }; diff --git a/comdel/domain/schemacreator.cpp b/comdel/domain/schemacreator.cpp index 1d5d68c..089138f 100644 --- a/comdel/domain/schemacreator.cpp +++ b/comdel/domain/schemacreator.cpp @@ -210,12 +210,17 @@ std::optional SchemaCreator::loadBus(BusNode node) return nullopt; } - optional display; + optional displayBus; if(type == Bus::REGULAR) { - display = loadDisplay(*node.display); + auto display = loadDisplay(*node.display); if(!display) { return nullopt; } + if(display->getItems().size() != 1 || !display->getItems()[0].bus.has_value()) { + errors.emplace_back(node.span, "@display must contain only exactly one bus definition"); + return nullopt; + } + displayBus = *display->getItems()[0].bus; } if(node.wires.size() == 0) { @@ -235,7 +240,7 @@ std::optional SchemaCreator::loadBus(BusNode node) return nullopt; } - return Bus(name, tooltip, type, count, wires, display); + return Bus(name, tooltip, type, count, wires, displayBus); } @@ -603,17 +608,17 @@ std::optional SchemaCreator::loadDisplay(DisplayNode node) std::string _orientation = item.asString(&errors, "orientation", "bottom"); std::string _pinType = item.asString(&errors, "type", "out"); - ui::Orientation orientation; + ui::PinOrientation orientation; if(_orientation == "left") { - orientation = ui::Orientation::LEFT; + orientation = ui::PinOrientation::LEFT; } else if(_orientation == "right") { - orientation = ui::Orientation::RIGHT; + orientation = ui::PinOrientation::RIGHT; } else if(_orientation == "top") { - orientation = ui::Orientation::TOP; + orientation = ui::PinOrientation::TOP; } else if(_orientation == "bottom") { - orientation = ui::Orientation::BOTTOM; + orientation = ui::PinOrientation::BOTTOM; } else { - errors.emplace_back(item.span, "unknown orientation type '" + _orientation + "'"); + errors.emplace_back(item.span, "unknown pin orientation type '" + _orientation + "'"); } ui::PinType pinType; @@ -628,6 +633,24 @@ std::optional SchemaCreator::loadDisplay(DisplayNode node) } displayItem.pin = ui::Pin(x, y, w, h, orientation, pinType); + } else if(type == "bus") { + long long int x, y, w, h; + x = item.asInt(&errors, "x"); + y = item.asInt(&errors, "y"); + w = item.asInt(&errors, "w"); + h = item.asInt(&errors, "h"); + std::string _orientation = item.asString(&errors, "orientation", "bottom"); + + ui::BusOrientation orientation; + if(_orientation == "horizontal") { + orientation = ui::BusOrientation::HORIZONTAL; + } else if(_orientation == "vertical") { + orientation = ui::BusOrientation::VERTICAL; + } else { + errors.emplace_back(item.span, "unknown bus orientation type '" + _orientation + "'"); + } + + displayItem.bus = ui::Bus(x, y, w, h, orientation); } else { errors.emplace_back(item.type.span, "unsupported display type"); } diff --git a/examples/simplified FRISC model/frisc_library.csl b/examples/simplified FRISC model/frisc_library.csl index 1c4560b..40580aa 100644 --- a/examples/simplified FRISC model/frisc_library.csl +++ b/examples/simplified FRISC model/frisc_library.csl @@ -310,9 +310,11 @@ orientation: horizontal; lineColor: black; }*/ - rect { + bus { x:0; y:0; h: 20; w: 100; + orientation: "horizontal"; + resizable: true; } } @wires {