246 lines
6.7 KiB
C++
246 lines
6.7 KiB
C++
#ifndef DOMAIN_DISPLAY_H
|
|
#define DOMAIN_DISPLAY_H
|
|
|
|
#include <QGraphicsItem>
|
|
#include <optional>
|
|
|
|
#include <ostream>
|
|
|
|
namespace domain {
|
|
|
|
namespace ui {
|
|
|
|
class Rect {
|
|
public:
|
|
int x, y, w, h;
|
|
|
|
Rect(int x, int y, int w, int h): x(x), y(y), w(w), h(h) {}
|
|
|
|
void render(QGraphicsItemGroup *group) {
|
|
group->addToGroup(new QGraphicsRectItem(x,y,w,h));
|
|
}
|
|
|
|
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";
|
|
buffer << "\t\t}\n\n";
|
|
}
|
|
|
|
};
|
|
|
|
class Line {
|
|
public:
|
|
int x1, y1, x2, y2;
|
|
|
|
Line(int x1, int y1, int x2, int y2): x1(x1), y1(y1), x2(x2), y2(y2) {}
|
|
|
|
void render(QGraphicsItemGroup *group) {
|
|
group->addToGroup(new QGraphicsLineItem(x1, y1, x2, y2));
|
|
}
|
|
|
|
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";
|
|
buffer << "\t\t}\n\n";
|
|
}
|
|
};
|
|
|
|
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:
|
|
PinOrientation orientation;
|
|
PinType pinType;
|
|
int x, y, w, h;
|
|
|
|
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 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 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 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 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;
|
|
}
|
|
group->addToGroup(new QGraphicsPolygonItem(polygon));
|
|
}
|
|
|
|
void renderOut(QGraphicsItemGroup *group) {
|
|
QPolygon polygon;
|
|
|
|
switch (orientation) {
|
|
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 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 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 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;
|
|
}
|
|
group->addToGroup(new QGraphicsPolygonItem(polygon));
|
|
}
|
|
|
|
void renderInOut(QGraphicsItemGroup *group) {
|
|
group->addToGroup(new QGraphicsRectItem(x, y ,w, h));
|
|
}
|
|
|
|
void render(QGraphicsItemGroup *group) {
|
|
switch (pinType) {
|
|
case PinType::IN:
|
|
renderIn(group);
|
|
break;
|
|
case PinType::OUT:
|
|
renderOut(group);
|
|
break;
|
|
case PinType::IN_OUT:
|
|
renderInOut(group);
|
|
break;
|
|
}
|
|
}
|
|
|
|
int getConnectionX() {
|
|
switch (orientation) {
|
|
case ui::PinOrientation::TOP:
|
|
case ui::PinOrientation::BOTTOM:
|
|
return x+w/2;
|
|
case ui::PinOrientation::LEFT:
|
|
return x;
|
|
case ui::PinOrientation::RIGHT:
|
|
return x+w;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int getConnectionY() {
|
|
switch (orientation) {
|
|
case ui::PinOrientation::LEFT:
|
|
case ui::PinOrientation::RIGHT:
|
|
return y+h/2;
|
|
case ui::PinOrientation::TOP:
|
|
return y;
|
|
case ui::PinOrientation::BOTTOM:
|
|
return y+h;
|
|
}
|
|
return 0;
|
|
}
|
|
};
|
|
|
|
|
|
class Item {
|
|
public:
|
|
Item(): rect(std::nullopt), line(std::nullopt), pin(std::nullopt), bus(std::nullopt) {}
|
|
|
|
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> rect = std::nullopt;
|
|
std::optional<Line> line = 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 = 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);
|
|
}
|
|
};
|
|
|
|
}
|
|
|
|
class Display
|
|
{
|
|
public:
|
|
|
|
Display(std::vector<ui::Item> items);
|
|
|
|
void render(QGraphicsItemGroup *group) {
|
|
for(auto &item: items) {
|
|
item.render(group);
|
|
}
|
|
}
|
|
|
|
void comdel(std::ostream &buffer, int x, int y, int size = 0) {
|
|
for(auto &item: items) {
|
|
item.comdel(buffer, x, y, size);
|
|
}
|
|
}
|
|
|
|
std::vector<ui::Item>& getItems() {return items;}
|
|
|
|
private:
|
|
std::vector<ui::Item> items;
|
|
};
|
|
|
|
} // namespace domain
|
|
|
|
#endif // DOMAIN_DISPLAY_H
|