xybrid/xybrid/gadgets/ioport.cpp

147 lines
3.9 KiB
C++

#include "ioport.h"
using Xybrid::Gadgets::IOPort;
using namespace Xybrid::Data;
#include <QPainter>
#include <QGraphicsScene>
#include <QStyleOptionGraphicsItem>
#include <QCborMap>
#include <QMetaType>
#include <QMetaEnum>
#include "config/pluginregistry.h"
using namespace Xybrid::Config;
#include "data/graph.h"
#include "ui/patchboard/nodeobject.h"
using namespace Xybrid::UI;
#include "util/strings.h"
namespace {
bool _ = PluginRegistry::enqueueRegistration([] {
auto i = std::make_shared<PluginInfo>();
i->id = "ioport";
i->displayName = "I/O Port";
i->hidden = true;
i->createInstance = []{ return std::make_shared<IOPort>(); };
PluginRegistry::registerPlugin(i);
//inf = i;
});
Port::Type opposite(Port::Type t) {
if (t == Port::Input) return Port::Output;
return Port::Input;
}
}
IOPort::IOPort() {
}
void IOPort::remove() {
auto g = parent.lock();
if (!g) return;
if (!portSet) return;
g->removePort(type, dataType, index);
removePort(opposite(type), dataType, index);
}
void IOPort::add() {
auto g = parent.lock();
if (!g) return;
if (!portSet) return;
auto gp = g->addPort(type, dataType, index);
auto p = addPort(opposite(type), dataType, index);
if (gp && p) {
p->name = name;
gp->name = name;
p->passthroughTo = gp;
gp->passthroughTo = p;
}
}
void IOPort::setPort(Port::Type type, Port::DataType dataType, uint8_t index) {
remove();
this->type = type;
this->dataType = dataType;
this->index = index;
portSet = true;
add();
}
void IOPort::onRename() {
auto g = parent.lock();
if (!g) return;
if (!portSet) return;
auto gp = g->port(type, dataType, index);
auto p = port(opposite(type), dataType, index);
if (gp && p) {
p->name = name;
gp->name = name;
}
}
void IOPort::saveData(QCborMap& m) {
QCborMap pm;
pm.insert(QString("type"), Util::enumName(type));
pm.insert(QString("dataType"), Util::enumName(dataType));
pm.insert(QString("index"), index);
m.insert(QString("port"), pm);
}
void IOPort::loadData(QCborMap& m) {
auto pm = m.value("port").toMap();
if (pm.empty()) return;
auto pmt = QMetaType::metaObjectForType(QMetaType::type("Xybrid::Data::Port"));
auto tm = pmt->enumerator(pmt->indexOfEnumerator("Type"));
auto dtm = pmt->enumerator(pmt->indexOfEnumerator("DataType"));
std::string st = pm.value("type").toString().toStdString();
std::string sdt = pm.value("dataType").toString().toStdString();
setPort(
static_cast<Port::Type>(tm.keyToValue(st.c_str())),
static_cast<Port::DataType>(dtm.keyToValue(sdt.c_str())),
static_cast<uint8_t>(pm.value("index").toInteger())
);
}
void IOPort::onUnparent(std::shared_ptr<Graph>) { remove(); }
void IOPort::onParent(std::shared_ptr<Graph>) { add(); }
void IOPort::onGadgetCreated() {
if (!obj) return;
obj->customChrome = true;
qreal ps = (PortObject::portSize + PortObject::portSpacing) * 2;
obj->setGadgetSize(QPointF(ps, ps));
// do this after setting size
auto r = obj->boundingRect();
obj->inputPortContainer->setPos(r.center());
obj->outputPortContainer->setPos(r.center());
}
void IOPort::drawCustomChrome(QPainter* painter, const QStyleOptionGraphicsItem* opt) {
QColor outline = QColor(31, 31, 31);
if (opt->state & QStyle::State_Selected) outline = QColor(127, 127, 255);
auto r = obj->boundingRect();
auto rf = r - QMarginsF(1, 1, 1, 1);
painter->setPen(Qt::NoPen);
int ro = 180*16 * (1-type);
painter->setBrush(QColor(63, 63, 63));
painter->drawPie(rf, (90+45)*16 + ro, -90*3*16);
painter->setBrush(QColor(95, 95, 95));
painter->drawPie(rf, (90+45)*16 + 180*16 + ro, 90*16);
painter->setBrush(Qt::NoBrush);
painter->setPen(QPen(outline, 2));
painter->drawPie(r, (90+45)*16 + ro, -90*3*16);
}