Updated bus rendering

This commit is contained in:
Borna Rajković 2022-05-26 19:21:53 +02:00
parent 5cf8235608
commit aac972c6ca
11 changed files with 142 additions and 64 deletions

View File

@ -6,7 +6,6 @@
#include <QMenu> #include <QMenu>
#include <QLine> #include <QLine>
#include <QGraphicsSceneContextMenuEvent> #include <QGraphicsSceneContextMenuEvent>
#include <iostream>
namespace display { namespace display {
@ -96,6 +95,18 @@ void Component::contextMenuEvent(QGraphicsSceneContextMenuEvent *event) {
return QGraphicsItem::itemChange(change, value); return QGraphicsItem::itemChange(change, value);
} }
BusGroup::BusGroup(const std::shared_ptr<domain::BusInstance> &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) { QVariant ComponentGroup::itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant &value) {
if (change == ItemPositionChange && scene()) { if (change == ItemPositionChange && scene()) {

View File

@ -55,10 +55,10 @@ class Bus: public QGraphicsItemGroup
std::shared_ptr<domain::BusInstance> busInstance; std::shared_ptr<domain::BusInstance> busInstance;
public: public:
Bus(const std::shared_ptr<domain::BusInstance>& instance): busInstance(instance) { Bus(const std::shared_ptr<domain::BusInstance>& 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; void contextMenuEvent(QGraphicsSceneContextMenuEvent *event) override;
}; };
class ComponentGroup: public QGraphicsItemGroup class ComponentGroup: public QGraphicsItemGroup
@ -97,18 +97,12 @@ class BusGroup: public QGraphicsItemGroup
{ {
private: private:
std::shared_ptr<domain::BusInstance> busInstance; std::shared_ptr<domain::BusInstance> busInstance;
display::Bus* bus;
public: public:
explicit BusGroup(const std::shared_ptr<domain::BusInstance>& instance): busInstance(instance) { explicit BusGroup(const std::shared_ptr<domain::BusInstance>& instance);
setFlag(ItemIsMovable, true);
setFlag(ItemSendsGeometryChanges, true);
setHandlesChildEvents(false); display::Bus* getBus() { return bus; }
addToGroup(new display::Bus(instance));
setPos(instance->position.first, instance->position.second);
}
protected: protected:
virtual QVariant itemChange(GraphicsItemChange change, const QVariant &value); virtual QVariant itemChange(GraphicsItemChange change, const QVariant &value);

View File

@ -38,7 +38,7 @@ void Schema::setSchema(domain::Schema* _schema, domain::Library* _library)
scene.addItem(group); scene.addItem(group);
} }
for(auto &instance: schema->busInstances) { for(auto &instance: schema->busInstances) {
if(instance->bus.getDisplay().has_value()) { if(instance->bus.getDisplayBus().has_value()) {
auto group = new display::BusGroup(instance); auto group = new display::BusGroup(instance);
buses.insert(std::make_pair(instance->name, group)); buses.insert(std::make_pair(instance->name, group));
scene.addItem(group); scene.addItem(group);
@ -110,7 +110,7 @@ void Schema::updateConnections() {
auto currentPos = this->mapToScene(event->pos()); auto currentPos = this->mapToScene(event->pos());
auto instance = std::make_shared<domain::BusInstance>(bus.getName(), std::make_pair(currentPos.x(), currentPos.y()), bus, 50); auto instance = std::make_shared<domain::BusInstance>(bus.getName(), std::make_pair(currentPos.x(), currentPos.y()), bus);
schema->busInstances.push_back(instance); schema->busInstances.push_back(instance);
auto group = new display::BusGroup(instance); auto group = new display::BusGroup(instance);

View File

@ -26,8 +26,8 @@ Wire::WireType Wire::getType() {
return type; return type;
} }
Bus::Bus(std::string name, std::string tooltip, BusType type, std::pair<int, int> count, std::vector<Wire> wires, std::optional<Display> display) Bus::Bus(std::string name, std::string tooltip, BusType type, std::pair<int, int> count, std::vector<Wire> wires, std::optional<ui::Bus> displayBus)
: name(name), tooltip(tooltip), type(type), count(count), wires(wires), display(display) : name(name), tooltip(tooltip), type(type), count(count), wires(wires), displayBus(displayBus)
{} {}
std::string Bus::getName() { std::string Bus::getName() {
@ -42,12 +42,11 @@ Bus::BusType Bus::getType() {
std::pair<int, int> Bus::getCount() { std::pair<int, int> Bus::getCount() {
return count; return count;
} }
std::optional<Display> Bus::getDisplay() {
return display;
}
std::vector<Wire> Bus::getWires() { std::vector<Wire> Bus::getWires() {
return wires; return wires;
} }
std::optional<ui::Bus> Bus::getDisplayBus() {
return displayBus;
}
} // namespace domain } // namespace domain

View File

@ -55,18 +55,18 @@ private:
BusType type; BusType type;
std::pair<int, int> count; std::pair<int, int> count;
std::optional<Display> display; std::optional<ui::Bus> displayBus;
std::vector<Wire> wires; std::vector<Wire> wires;
public: public:
Bus(std::string name, std::string tooltip, BusType type, std::pair<int, int> count, std::vector<Wire> wires, std::optional<Display> display = std::nullopt); Bus(std::string name, std::string tooltip, BusType type, std::pair<int, int> count, std::vector<Wire> wires, std::optional<ui::Bus> display = std::nullopt);
std::string getName(); std::string getName();
std::string getTooltip(); std::string getTooltip();
BusType getType(); BusType getType();
std::pair<int, int> getCount(); std::pair<int, int> getCount();
std::vector<Wire> getWires(); std::vector<Wire> getWires();
std::optional<Display> getDisplay(); std::optional<ui::Bus> getDisplayBus();
}; };
} // namespace domain } // namespace domain

View File

@ -125,8 +125,8 @@ void generateBus(BusInstance *bus, ostream &buffer) {
buffer << "\n"; buffer << "\n";
buffer << "\t\t// " << bus->name << " bus\n\n"; buffer << "\t\t// " << bus->name << " bus\n\n";
if(bus->bus.getDisplay().has_value()) { if(bus->bus.getDisplayBus().has_value()) {
bus->bus.getDisplay()->comdel(buffer, bus->position.first, bus->position.second, bus->size); bus->bus.getDisplayBus()->comdel(buffer, bus->position.first, bus->position.second, bus->size);
} }
} }

View File

@ -20,7 +20,7 @@ public:
group->addToGroup(new QGraphicsRectItem(x,y,w,h)); 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\trectangle {\n";
buffer << "\t\t\tx: " << (this->x + x) << "; y: " << (this->y + y) << ";\n"; buffer << "\t\t\tx: " << (this->x + x) << "; y: " << (this->y + y) << ";\n";
buffer << "\t\t\tw: " << w << "; h: " << h << ";\n"; buffer << "\t\t\tw: " << w << "; h: " << h << ";\n";
@ -39,7 +39,7 @@ public:
group->addToGroup(new QGraphicsLineItem(x1, y1, x2, y2)); 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\tline {\n";
buffer << "\t\t\tx1: " << (x1 + x) << "; y1: " << (y1 + y) << ";\n"; buffer << "\t\t\tx1: " << (x1 + x) << "; y1: " << (y1 + y) << ";\n";
buffer << "\t\t\tx2: " << (x2 + x) << "; y2: " << (y2 + 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 LEFT, RIGHT, TOP, BOTTOM
}; };
enum BusOrientation {
VERTICAL, HORIZONTAL
};
enum PinType { enum PinType {
IN, OUT, IN_OUT 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 { class Pin {
public: public:
Orientation orientation; PinOrientation orientation;
PinType pinType; PinType pinType;
int x, y, w, h; 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) { void renderIn(QGraphicsItemGroup *group) {
QPolygon polygon; QPolygon polygon;
switch (orientation) { 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); 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; 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); 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; 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); 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; 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); 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; break;
} }
@ -87,16 +128,16 @@ public:
QPolygon polygon; QPolygon polygon;
switch (orientation) { 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); 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; 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); 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; 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); 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; 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); 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; break;
} }
@ -123,12 +164,12 @@ public:
int getConnectionX() { int getConnectionX() {
switch (orientation) { switch (orientation) {
case ui::Orientation::TOP: case ui::PinOrientation::TOP:
case ui::Orientation::BOTTOM: case ui::PinOrientation::BOTTOM:
return x+w/2; return x+w/2;
case ui::Orientation::LEFT: case ui::PinOrientation::LEFT:
return x; return x;
case ui::Orientation::RIGHT: case ui::PinOrientation::RIGHT:
return x+w; return x+w;
} }
return 0; return 0;
@ -136,12 +177,12 @@ public:
int getConnectionY() { int getConnectionY() {
switch (orientation) { switch (orientation) {
case ui::Orientation::LEFT: case ui::PinOrientation::LEFT:
case ui::Orientation::RIGHT: case ui::PinOrientation::RIGHT:
return y+h/2; return y+h/2;
case ui::Orientation::TOP: case ui::PinOrientation::TOP:
return y; return y;
case ui::Orientation::BOTTOM: case ui::PinOrientation::BOTTOM:
return y+h; return y+h;
} }
return 0; return 0;
@ -151,21 +192,25 @@ public:
class Item { class Item {
public: 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(rect) rect->render(group);
if(line) line->render(group); if(line) line->render(group);
if(pin) pin->render(group); if(pin) pin->render(group);
if(bus) bus->render(group, size);
} }
std::optional<Rect> rect = std::nullopt; std::optional<Rect> rect = std::nullopt;
std::optional<Line> line = std::nullopt; std::optional<Line> line = std::nullopt;
std::optional<Pin> pin = std::nullopt; std::optional<Pin> pin = std::nullopt;
std::optional<Bus> bus = std::nullopt;
void comdel(std::ostream &buffer, int x, int y, int size) { void comdel(std::ostream &buffer, int x, int y, int size = 0) {
if(rect) rect->comdel(buffer, x, y, size); if(rect) rect->comdel(buffer, x, y);
if(line) line->comdel(buffer, x, y, size); 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) { for(auto &item: items) {
item.comdel(buffer, x, y, size); item.comdel(buffer, x, y, size);
} }

View File

@ -4,7 +4,11 @@ namespace domain {
BusInstance::BusInstance(std::string name, std::pair<int, int> position, Bus bus, int size) BusInstance::BusInstance(std::string name, std::pair<int, int> position, Bus bus, int size)
: name(name), position(position), bus(bus), size(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) {} BusInstance::BusInstance(std::string name, Bus bus): name(name), bus(bus), position(0,0), size(0) {}

View File

@ -23,7 +23,7 @@ public:
BusInstance(std::string name, Bus bus); BusInstance(std::string name, Bus bus);
BusInstance(std::string name, std::pair<int, int> position, Bus bus, int size); BusInstance(std::string name, std::pair<int, int> position, Bus bus, int size = -1);
virtual ~BusInstance() = default; virtual ~BusInstance() = default;
}; };

View File

@ -210,12 +210,17 @@ std::optional<Bus> SchemaCreator::loadBus(BusNode node)
return nullopt; return nullopt;
} }
optional<Display> display; optional<ui::Bus> displayBus;
if(type == Bus::REGULAR) { if(type == Bus::REGULAR) {
display = loadDisplay(*node.display); auto display = loadDisplay(*node.display);
if(!display) { if(!display) {
return nullopt; 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) { if(node.wires.size() == 0) {
@ -235,7 +240,7 @@ std::optional<Bus> SchemaCreator::loadBus(BusNode node)
return nullopt; return nullopt;
} }
return Bus(name, tooltip, type, count, wires, display); return Bus(name, tooltip, type, count, wires, displayBus);
} }
@ -603,17 +608,17 @@ std::optional<Display> SchemaCreator::loadDisplay(DisplayNode node)
std::string _orientation = item.asString(&errors, "orientation", "bottom"); std::string _orientation = item.asString(&errors, "orientation", "bottom");
std::string _pinType = item.asString(&errors, "type", "out"); std::string _pinType = item.asString(&errors, "type", "out");
ui::Orientation orientation; ui::PinOrientation orientation;
if(_orientation == "left") { if(_orientation == "left") {
orientation = ui::Orientation::LEFT; orientation = ui::PinOrientation::LEFT;
} else if(_orientation == "right") { } else if(_orientation == "right") {
orientation = ui::Orientation::RIGHT; orientation = ui::PinOrientation::RIGHT;
} else if(_orientation == "top") { } else if(_orientation == "top") {
orientation = ui::Orientation::TOP; orientation = ui::PinOrientation::TOP;
} else if(_orientation == "bottom") { } else if(_orientation == "bottom") {
orientation = ui::Orientation::BOTTOM; orientation = ui::PinOrientation::BOTTOM;
} else { } else {
errors.emplace_back(item.span, "unknown orientation type '" + _orientation + "'"); errors.emplace_back(item.span, "unknown pin orientation type '" + _orientation + "'");
} }
ui::PinType pinType; ui::PinType pinType;
@ -628,6 +633,24 @@ std::optional<Display> SchemaCreator::loadDisplay(DisplayNode node)
} }
displayItem.pin = ui::Pin(x, y, w, h, orientation, pinType); 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 { } else {
errors.emplace_back(item.type.span, "unsupported display type"); errors.emplace_back(item.type.span, "unsupported display type");
} }

View File

@ -310,9 +310,11 @@
orientation: horizontal; orientation: horizontal;
lineColor: black; lineColor: black;
}*/ }*/
rect { bus {
x:0; y:0; x:0; y:0;
h: 20; w: 100; h: 20; w: 100;
orientation: "horizontal";
resizable: true;
} }
} }
@wires { @wires {