Compare commits
3 Commits
e2e0506041
...
1100a9f0b9
Author | SHA1 | Date |
---|---|---|
Borna Rajković | 1100a9f0b9 | |
Borna Rajković | f11551fef6 | |
Borna Rajković | 281926cb8b |
|
@ -5,7 +5,6 @@
|
||||||
|
|
||||||
#include <QMenu>
|
#include <QMenu>
|
||||||
#include <QGraphicsSceneContextMenuEvent>
|
#include <QGraphicsSceneContextMenuEvent>
|
||||||
#include <QGraphicsScene>
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
namespace display {
|
namespace display {
|
||||||
|
@ -46,4 +45,66 @@ void Bus::contextMenuEvent(QGraphicsSceneContextMenuEvent *event) {
|
||||||
menu.exec(event->screenPos());
|
menu.exec(event->screenPos());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QVariant BusGroup::itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant &value) {
|
||||||
|
if (change == ItemPositionChange && scene()) {
|
||||||
|
// value is the new position.
|
||||||
|
QPointF newPos = value.toPointF();
|
||||||
|
busInstance->position.first = newPos.x();
|
||||||
|
busInstance->position.second = newPos.y();
|
||||||
|
|
||||||
|
auto view = dynamic_cast<Schema*>(scene()->views()[0]);
|
||||||
|
view->updateConnections();
|
||||||
|
}
|
||||||
|
return QGraphicsItem::itemChange(change, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
QVariant ComponentGroup::itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant &value) {
|
||||||
|
if (change == ItemPositionChange && scene()) {
|
||||||
|
// value is the new position.
|
||||||
|
QPointF newPos = value.toPointF();
|
||||||
|
componentInstance->position.first = newPos.x();
|
||||||
|
componentInstance->position.second = newPos.y();
|
||||||
|
|
||||||
|
auto view = dynamic_cast<Schema*>(scene()->views()[0]);
|
||||||
|
view->updateConnections();
|
||||||
|
}
|
||||||
|
return QGraphicsItem::itemChange(change, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BusConnection::contextMenuEvent(QGraphicsSceneContextMenuEvent *event) {
|
||||||
|
QMenu menu;
|
||||||
|
menu.addAction("Ukloni poveznicu", [this](){});
|
||||||
|
menu.addSeparator();
|
||||||
|
for(int i=0; i<this->connection->attributes.size(); i++) {
|
||||||
|
auto* attr = &this->connection->attributes[i];
|
||||||
|
bool enabled = attr->attribute.getPopup().has_value();
|
||||||
|
|
||||||
|
auto action = menu.addAction(QString::fromStdString("Izmjeni " + attr->name),
|
||||||
|
[attr]() {
|
||||||
|
auto dialog = new AttributeDialog(attr);
|
||||||
|
dialog->exec();
|
||||||
|
});
|
||||||
|
action->setEnabled(enabled);
|
||||||
|
}
|
||||||
|
menu.exec(event->screenPos());
|
||||||
|
}
|
||||||
|
|
||||||
|
void DirectConnection::contextMenuEvent(QGraphicsSceneContextMenuEvent *event) {
|
||||||
|
QMenu menu;
|
||||||
|
menu.addAction("Ukloni poveznicu", [this](){});
|
||||||
|
menu.addSeparator();
|
||||||
|
for(int i=0; i<this->connection->attributes.size(); i++) {
|
||||||
|
auto* attr = &this->connection->attributes[i];
|
||||||
|
bool enabled = attr->attribute.getPopup().has_value();
|
||||||
|
|
||||||
|
auto action = menu.addAction(QString::fromStdString("Izmjeni " + attr->name),
|
||||||
|
[attr]() {
|
||||||
|
auto dialog = new AttributeDialog(attr);
|
||||||
|
dialog->exec();
|
||||||
|
});
|
||||||
|
action->setEnabled(enabled);
|
||||||
|
}
|
||||||
|
menu.exec(event->screenPos());
|
||||||
|
}
|
||||||
} // namespace display
|
} // namespace display
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#include <comdel/domain/wireinstance.h>
|
#include <comdel/domain/wireinstance.h>
|
||||||
|
|
||||||
#include <QGraphicsItemGroup>
|
#include <QGraphicsItemGroup>
|
||||||
|
#include "comdel/domain/connectioninstance.h"
|
||||||
|
|
||||||
namespace display {
|
namespace display {
|
||||||
|
|
||||||
|
@ -14,7 +15,7 @@ private:
|
||||||
domain::Pin pin;
|
domain::Pin pin;
|
||||||
public:
|
public:
|
||||||
Pin(domain::Pin pin): pin(pin) {
|
Pin(domain::Pin pin): pin(pin) {
|
||||||
pin.getDisplay().render(this);
|
pin.getDisplayPin().render(this);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -24,9 +25,12 @@ private:
|
||||||
std::shared_ptr<domain::ComponentInstance> instance;
|
std::shared_ptr<domain::ComponentInstance> instance;
|
||||||
public:
|
public:
|
||||||
Component(const std::shared_ptr<domain::ComponentInstance>& instance): instance(instance) {
|
Component(const std::shared_ptr<domain::ComponentInstance>& instance): instance(instance) {
|
||||||
|
setFlag(ItemSendsGeometryChanges, true);
|
||||||
|
|
||||||
instance->component.getDisplay().render(this);
|
instance->component.getDisplay().render(this);
|
||||||
}
|
}
|
||||||
void contextMenuEvent(QGraphicsSceneContextMenuEvent *event) override;
|
void contextMenuEvent(QGraphicsSceneContextMenuEvent *event) override;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class Bus: public QGraphicsItemGroup
|
class Bus: public QGraphicsItemGroup
|
||||||
|
@ -37,6 +41,7 @@ public:
|
||||||
instance->bus.getDisplay()->render(this);
|
instance->bus.getDisplay()->render(this);
|
||||||
}
|
}
|
||||||
void contextMenuEvent(QGraphicsSceneContextMenuEvent *event) override;
|
void contextMenuEvent(QGraphicsSceneContextMenuEvent *event) override;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class ComponentGroup: public QGraphicsItemGroup
|
class ComponentGroup: public QGraphicsItemGroup
|
||||||
|
@ -47,6 +52,8 @@ private:
|
||||||
public:
|
public:
|
||||||
explicit ComponentGroup(const std::shared_ptr<domain::ComponentInstance>& instance): componentInstance(instance) {
|
explicit ComponentGroup(const std::shared_ptr<domain::ComponentInstance>& instance): componentInstance(instance) {
|
||||||
setFlag(ItemIsMovable, true);
|
setFlag(ItemIsMovable, true);
|
||||||
|
setFlag(ItemSendsGeometryChanges, true);
|
||||||
|
|
||||||
setHandlesChildEvents(false);
|
setHandlesChildEvents(false);
|
||||||
|
|
||||||
addToGroup(new display::Component(instance));
|
addToGroup(new display::Component(instance));
|
||||||
|
@ -57,6 +64,10 @@ public:
|
||||||
|
|
||||||
setPos(instance->position.first, instance->position.second);
|
setPos(instance->position.first, instance->position.second);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual QVariant itemChange(GraphicsItemChange change, const QVariant &value);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class BusGroup: public QGraphicsItemGroup
|
class BusGroup: public QGraphicsItemGroup
|
||||||
|
@ -67,14 +78,70 @@ private:
|
||||||
public:
|
public:
|
||||||
explicit BusGroup(const std::shared_ptr<domain::BusInstance>& instance): busInstance(instance) {
|
explicit BusGroup(const std::shared_ptr<domain::BusInstance>& instance): busInstance(instance) {
|
||||||
setFlag(ItemIsMovable, true);
|
setFlag(ItemIsMovable, true);
|
||||||
|
setFlag(ItemSendsGeometryChanges, true);
|
||||||
|
|
||||||
setHandlesChildEvents(false);
|
setHandlesChildEvents(false);
|
||||||
|
|
||||||
addToGroup(new display::Bus(instance));
|
addToGroup(new display::Bus(instance));
|
||||||
|
|
||||||
setPos(instance->position.first, instance->position.second);
|
setPos(instance->position.first, instance->position.second);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual QVariant itemChange(GraphicsItemChange change, const QVariant &value);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class BusConnection: public QGraphicsLineItem
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
domain::BusConnectionInstance* connection;
|
||||||
|
ComponentGroup* component;
|
||||||
|
BusGroup* bus;
|
||||||
|
|
||||||
|
public:
|
||||||
|
BusConnection(domain::BusConnectionInstance* connection, ComponentGroup *component, BusGroup *bus): connection(connection), component(component), bus(bus) {
|
||||||
|
updateConnection();
|
||||||
|
|
||||||
|
setHandlesChildEvents(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void updateConnection() {
|
||||||
|
auto busPosition = bus->boundingRect();
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
void contextMenuEvent(QGraphicsSceneContextMenuEvent *event) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class DirectConnection: public QGraphicsLineItem
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
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) {
|
||||||
|
updateConnection();
|
||||||
|
setHandlesChildEvents(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void updateConnection() {
|
||||||
|
auto pin1 = connection->instance->component.getPin(connection->connection.getComponent().pin).getDisplayPin();
|
||||||
|
auto pin2 = connection->secondInstance->component.getPin(connection->connection.getSecondComponent()->pin).getDisplayPin();
|
||||||
|
|
||||||
|
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());
|
||||||
|
}
|
||||||
|
|
||||||
|
void contextMenuEvent(QGraphicsSceneContextMenuEvent *event) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
} // namespace display
|
} // namespace display
|
||||||
|
|
||||||
#endif // DISPLAY_COMPONENT_H
|
#endif // DISPLAY_COMPONENT_H
|
||||||
|
|
|
@ -11,18 +11,42 @@ Schema::Schema()
|
||||||
|
|
||||||
void Schema::setSchema(domain::Schema* _schema)
|
void Schema::setSchema(domain::Schema* _schema)
|
||||||
{
|
{
|
||||||
|
std::map<std::string, display::ComponentGroup*> components;
|
||||||
|
std::map<std::string, display::BusGroup*> buses;
|
||||||
|
|
||||||
scene.clear();
|
scene.clear();
|
||||||
|
connections.clear();
|
||||||
this->schema = _schema;
|
this->schema = _schema;
|
||||||
if(schema != nullptr) {
|
if(schema != nullptr) {
|
||||||
for(auto &instance: schema->componentInstances) {
|
for(auto &instance: schema->componentInstances) {
|
||||||
scene.addItem(new display::ComponentGroup(instance));
|
auto group = new display::ComponentGroup(instance);
|
||||||
|
components.insert(std::make_pair(instance->name, group));
|
||||||
|
scene.addItem(group);
|
||||||
}
|
}
|
||||||
for(auto &instance: schema->busInstances) {
|
for(auto &instance: schema->busInstances) {
|
||||||
if(instance->bus.getDisplay().has_value()) {
|
if(instance->bus.getDisplay().has_value()) {
|
||||||
scene.addItem(new display::BusGroup(instance));
|
auto group = new display::BusGroup(instance);
|
||||||
|
buses.insert(std::make_pair(instance->name, group));
|
||||||
|
scene.addItem(group);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for(auto &connection: schema->connections) {
|
||||||
|
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);
|
||||||
|
scene.addItem(con);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Schema::updateConnections() {
|
||||||
|
if(schema != nullptr) {
|
||||||
|
for(auto conn: connections) {
|
||||||
|
conn->updateConnection();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace display
|
} // namespace display
|
||||||
|
|
|
@ -9,13 +9,19 @@
|
||||||
|
|
||||||
namespace display {
|
namespace display {
|
||||||
|
|
||||||
|
class BusConnection;
|
||||||
|
|
||||||
class Schema: public QGraphicsView
|
class Schema: public QGraphicsView
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Schema();
|
Schema();
|
||||||
|
|
||||||
|
std::vector<BusConnection*> connections;
|
||||||
|
|
||||||
void setSchema(domain::Schema* schema);
|
void setSchema(domain::Schema* schema);
|
||||||
|
|
||||||
|
void updateConnections();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QGraphicsScene scene;
|
QGraphicsScene scene;
|
||||||
|
|
||||||
|
|
|
@ -61,10 +61,90 @@ public:
|
||||||
PinType pinType;
|
PinType pinType;
|
||||||
int x, y, w, h;
|
int x, y, w, h;
|
||||||
|
|
||||||
Pin(int x, int y, int w, int h): x(x), y(y), w(w), h(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) {}
|
||||||
|
|
||||||
|
void renderIn(QGraphicsItemGroup *group) {
|
||||||
|
QPolygon polygon;
|
||||||
|
|
||||||
|
switch (orientation) {
|
||||||
|
case Orientation::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:
|
||||||
|
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:
|
||||||
|
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:
|
||||||
|
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 Orientation::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:
|
||||||
|
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:
|
||||||
|
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:
|
||||||
|
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) {
|
void render(QGraphicsItemGroup *group) {
|
||||||
group->addToGroup(new QGraphicsRectItem(x,y,w,h));
|
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::Orientation::TOP:
|
||||||
|
case ui::Orientation::BOTTOM:
|
||||||
|
return x+w/2;
|
||||||
|
case ui::Orientation::LEFT:
|
||||||
|
return x;
|
||||||
|
case ui::Orientation::RIGHT:
|
||||||
|
return x+w;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int getConnectionY() {
|
||||||
|
switch (orientation) {
|
||||||
|
case ui::Orientation::LEFT:
|
||||||
|
case ui::Orientation::RIGHT:
|
||||||
|
return y+h/2;
|
||||||
|
case ui::Orientation::TOP:
|
||||||
|
return y;
|
||||||
|
case ui::Orientation::BOTTOM:
|
||||||
|
return y+h;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -109,6 +189,8 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<ui::Item>& getItems() {return items;}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<ui::Item> items;
|
std::vector<ui::Item> items;
|
||||||
};
|
};
|
||||||
|
|
|
@ -14,8 +14,8 @@ std::string PinConnection::getMessage() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Pin::Pin(std::string name, PinType type, std::string tooltip, PinConnection connection, Display display, std::optional<std::vector<Value>> wires)
|
Pin::Pin(std::string name, PinType type, std::string tooltip, PinConnection connection, domain::ui::Pin pin, std::optional<std::vector<Value>> wires)
|
||||||
: name(name), type(type), tooltip(tooltip), connection(connection), display(display), wires(wires)
|
: name(name), type(type), tooltip(tooltip), connection(connection), displayPin(pin), wires(wires)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
std::string &Pin::getName() {
|
std::string &Pin::getName() {
|
||||||
|
@ -27,8 +27,8 @@ Pin::PinType Pin::getType() {
|
||||||
std::string Pin::getTooltip() {
|
std::string Pin::getTooltip() {
|
||||||
return tooltip;
|
return tooltip;
|
||||||
}
|
}
|
||||||
Display &Pin::getDisplay() {
|
ui::Pin &Pin::getDisplayPin() {
|
||||||
return display;
|
return displayPin;
|
||||||
}
|
}
|
||||||
PinConnection &Pin::getConnection() {
|
PinConnection &Pin::getConnection() {
|
||||||
return connection;
|
return connection;
|
||||||
|
|
|
@ -43,17 +43,17 @@ private:
|
||||||
PinType type;
|
PinType type;
|
||||||
std::string tooltip;
|
std::string tooltip;
|
||||||
PinConnection connection;
|
PinConnection connection;
|
||||||
Display display;
|
domain::ui::Pin displayPin;
|
||||||
|
|
||||||
std::optional<std::vector<Value>> wires;
|
std::optional<std::vector<Value>> wires;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Pin(std::string name, PinType type, std::string tooltip, PinConnection connection, Display display, std::optional<std::vector<Value>> wires);
|
Pin(std::string name, PinType type, std::string tooltip, PinConnection connection, domain::ui::Pin pin, std::optional<std::vector<Value>> wires);
|
||||||
|
|
||||||
std::string &getName();
|
std::string &getName();
|
||||||
PinType getType();
|
PinType getType();
|
||||||
std::string getTooltip();
|
std::string getTooltip();
|
||||||
Display &getDisplay();
|
ui::Pin &getDisplayPin();
|
||||||
PinConnection &getConnection();
|
PinConnection &getConnection();
|
||||||
std::optional<std::vector<Value>> &getWires();
|
std::optional<std::vector<Value>> &getWires();
|
||||||
};
|
};
|
||||||
|
|
|
@ -542,6 +542,12 @@ optional<Pin> SchemaCreator::loadPin(PinNode node)
|
||||||
if(!display) {
|
if(!display) {
|
||||||
return nullopt;
|
return nullopt;
|
||||||
}
|
}
|
||||||
|
if(display->getItems().size() != 1 || !display->getItems()[0].pin.has_value()) {
|
||||||
|
errors.emplace_back(node.span, "@display must contain only exactly one pin definition");
|
||||||
|
return nullopt;
|
||||||
|
}
|
||||||
|
ui::Pin displayPin = *display->getItems()[0].pin;
|
||||||
|
|
||||||
|
|
||||||
if(!node.connection) {
|
if(!node.connection) {
|
||||||
errors.emplace_back(node.span, "missing @connection");
|
errors.emplace_back(node.span, "missing @connection");
|
||||||
|
@ -565,16 +571,7 @@ optional<Pin> SchemaCreator::loadPin(PinNode node)
|
||||||
wiresOpt = wires;
|
wiresOpt = wires;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Pin(name, type, tooltip, connection, *display, wiresOpt);
|
return Pin(name, type, tooltip, connection, displayPin, wiresOpt);
|
||||||
}
|
|
||||||
|
|
||||||
int getIntProperty(DisplayItemNode &node, std::string property) {
|
|
||||||
for(auto& prop: node.values) {
|
|
||||||
if(prop.key.value == property) {
|
|
||||||
return prop.value.asInt();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
throw std::exception();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<Display> SchemaCreator::loadDisplay(DisplayNode node)
|
std::optional<Display> SchemaCreator::loadDisplay(DisplayNode node)
|
||||||
|
@ -584,26 +581,53 @@ std::optional<Display> SchemaCreator::loadDisplay(DisplayNode node)
|
||||||
ui::Item displayItem;
|
ui::Item displayItem;
|
||||||
std::string type = item.type.value;
|
std::string type = item.type.value;
|
||||||
if(type == "rect") {
|
if(type == "rect") {
|
||||||
int x, y, w, h;
|
long long int x, y, w, h;
|
||||||
x = getIntProperty(item, "x");
|
x = item.asInt(&errors, "x");
|
||||||
y = getIntProperty(item, "y");
|
y = item.asInt(&errors, "y");
|
||||||
w = getIntProperty(item, "w");
|
w = item.asInt(&errors, "w");
|
||||||
h = getIntProperty(item, "h");
|
h = item.asInt(&errors, "h");
|
||||||
displayItem.rect = ui::Rect(x, y, w, h);
|
displayItem.rect = ui::Rect(x, y, w, h);
|
||||||
} else if(type == "line") {
|
} else if(type == "line") {
|
||||||
int x1, y1, x2, y2;
|
long long int x1, y1, x2, y2;
|
||||||
x1 = getIntProperty(item, "x1");
|
x1 = item.asInt(&errors, "x1");
|
||||||
y1 = getIntProperty(item, "y1");
|
y1 = item.asInt(&errors, "y1");
|
||||||
x2 = getIntProperty(item, "x2");
|
x2 = item.asInt(&errors, "x2");
|
||||||
y2 = getIntProperty(item, "y2");
|
y2 = item.asInt(&errors, "y2");
|
||||||
displayItem.line = ui::Line(x1, y1, x2, y2);
|
displayItem.line = ui::Line(x1, y1, x2, y2);
|
||||||
} else if(type == "pin") {
|
} else if(type == "pin") {
|
||||||
int x, y, w, h;
|
long long int x, y, w, h;
|
||||||
x = getIntProperty(item, "x");
|
x = item.asInt(&errors, "x");
|
||||||
y = getIntProperty(item, "y");
|
y = item.asInt(&errors, "y");
|
||||||
w = getIntProperty(item, "w");
|
w = item.asInt(&errors, "w");
|
||||||
h = getIntProperty(item, "h");
|
h = item.asInt(&errors, "h");
|
||||||
displayItem.pin = ui::Pin(x, y, w, h);
|
std::string _orientation = item.asString(&errors, "orientation", "bottom");
|
||||||
|
std::string _pinType = item.asString(&errors, "type", "out");
|
||||||
|
|
||||||
|
ui::Orientation orientation;
|
||||||
|
if(_orientation == "left") {
|
||||||
|
orientation = ui::Orientation::LEFT;
|
||||||
|
} else if(_orientation == "right") {
|
||||||
|
orientation = ui::Orientation::RIGHT;
|
||||||
|
} else if(_orientation == "top") {
|
||||||
|
orientation = ui::Orientation::TOP;
|
||||||
|
} else if(_orientation == "bottom") {
|
||||||
|
orientation = ui::Orientation::BOTTOM;
|
||||||
|
} else {
|
||||||
|
errors.emplace_back(item.span, "unknown orientation type '" + _orientation + "'");
|
||||||
|
}
|
||||||
|
|
||||||
|
ui::PinType pinType;
|
||||||
|
if(_pinType == "in") {
|
||||||
|
pinType = ui::PinType::IN;
|
||||||
|
} else if(_pinType == "out") {
|
||||||
|
pinType = ui::PinType::OUT;
|
||||||
|
} else if(_pinType == "in_out") {
|
||||||
|
pinType = ui::PinType::IN_OUT;
|
||||||
|
} else {
|
||||||
|
errors.emplace_back(item.span, "unknown pin type '" + _pinType + "'");
|
||||||
|
}
|
||||||
|
|
||||||
|
displayItem.pin = ui::Pin(x, y, w, h, orientation, pinType);
|
||||||
} else {
|
} else {
|
||||||
errors.emplace_back(item.type.span, "unsupported display type");
|
errors.emplace_back(item.type.span, "unsupported display type");
|
||||||
}
|
}
|
||||||
|
@ -946,7 +970,7 @@ vector<Enumeration> SchemaCreator::createWireEnumeration(vector<Value> wireValue
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<Attribute> SchemaCreator::createMemoryAttribute() {
|
std::optional<Attribute> SchemaCreator::createMemoryAttribute() {
|
||||||
return Attribute("_memory", Value::fromMemoryReference(nullopt), createMemoryPopup());
|
return Attribute("_memory", Value::fromMemoryReference(std::nullopt), createMemoryPopup());
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<Popup> SchemaCreator::createMemoryPopup() {
|
std::optional<Popup> SchemaCreator::createMemoryPopup() {
|
||||||
|
|
|
@ -162,10 +162,10 @@ std::string Value::stringify() {
|
||||||
case ATTRIBUTE_REFERENCE:
|
case ATTRIBUTE_REFERENCE:
|
||||||
return reference;
|
return reference;
|
||||||
case MEMORY_REFERENCE:
|
case MEMORY_REFERENCE:
|
||||||
if(memoryReference->empty()) {
|
if(memoryReference.has_value()) {
|
||||||
return "null";
|
|
||||||
} else {
|
|
||||||
return memoryReference.value();
|
return memoryReference.value();
|
||||||
|
} else {
|
||||||
|
return "null";
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
throw std::exception();
|
throw std::exception();
|
||||||
|
|
|
@ -29,22 +29,20 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
long long intValue;
|
long long intValue = 0;
|
||||||
std::string stringValue;
|
std::string stringValue;
|
||||||
bool boolValue;
|
bool boolValue = false;
|
||||||
std::optional<AddressSpace> addressSpace;
|
std::optional<AddressSpace> addressSpace = std::nullopt;
|
||||||
std::string reference;
|
std::string reference;
|
||||||
domain::ComponentInstance *memory;
|
domain::ComponentInstance *memory = nullptr;
|
||||||
|
|
||||||
std::optional<std::string> memoryReference;
|
std::optional<std::string> memoryReference = std::nullopt;
|
||||||
|
|
||||||
ValueType type;
|
ValueType type = UNDEFINED;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Value() {
|
Value() {}
|
||||||
this->type = UNDEFINED;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool equals(Value value) {
|
bool equals(Value value) {
|
||||||
if(value.getType() == type) {
|
if(value.getType() == type) {
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#define AST_NODE_H
|
#define AST_NODE_H
|
||||||
|
|
||||||
#include "token.h"
|
#include "token.h"
|
||||||
|
#include "sourceerror.h"
|
||||||
#include <optional>
|
#include <optional>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
@ -173,6 +174,52 @@ struct DisplayItemNode: public AstNode
|
||||||
{
|
{
|
||||||
IdentifierNode type;
|
IdentifierNode type;
|
||||||
std::vector<PropertyNode> values;
|
std::vector<PropertyNode> values;
|
||||||
|
|
||||||
|
long long int asInt(std::vector<SourceError>* errors, const std::string& property, long long int _default = 0) {
|
||||||
|
for(auto& prop: values) {
|
||||||
|
if(prop.key.value == property) {
|
||||||
|
if(prop.value.is(ValueNode::INT)) {
|
||||||
|
return prop.value.asInt();
|
||||||
|
} else {
|
||||||
|
if(errors != nullptr) {
|
||||||
|
errors->emplace_back(prop.value.span, "expected number");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return _default;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string asIdentifier(std::vector<SourceError>* errors, const std::string& property, std::string _default = "") {
|
||||||
|
for(auto& prop: values) {
|
||||||
|
if(prop.key.value == property) {
|
||||||
|
if(prop.value.is(ValueNode::IDENTIFIER)) {
|
||||||
|
return prop.value.asIdentifier();
|
||||||
|
} else {
|
||||||
|
if(errors != nullptr) {
|
||||||
|
errors->emplace_back(prop.value.span, "expected identifier");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return _default;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::string asString(std::vector<SourceError>* errors, const std::string& property, std::string _default = "") {
|
||||||
|
for(auto& prop: values) {
|
||||||
|
if(prop.key.value == property) {
|
||||||
|
if(prop.value.is(ValueNode::STRING)) {
|
||||||
|
return prop.value.asString();
|
||||||
|
} else {
|
||||||
|
if(errors != nullptr) {
|
||||||
|
errors->emplace_back(prop.value.span, "expected string");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return _default;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct DisplayNode: public AstNode
|
struct DisplayNode: public AstNode
|
||||||
|
|
|
@ -193,6 +193,8 @@ void MainWindow::onValidateSchema(bool /*toggled*/) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log->clear();
|
||||||
|
|
||||||
this->validationErrors.clear();
|
this->validationErrors.clear();
|
||||||
|
|
||||||
domain::ComdelValidator validator{validators};
|
domain::ComdelValidator validator{validators};
|
||||||
|
|
Loading…
Reference in New Issue