xybrid/xybrid/ui/gadgets/layoutgadget.cpp

89 lines
2.9 KiB
C++

#include "layoutgadget.h"
using Xybrid::UI::LayoutGadget;
#include "ui/patchboard/nodeobject.h"
#include "ui/patchboard/nodeuiscene.h"
namespace Xybrid::UI {
class LayoutSpacerGadget : public Gadget {
public:
LayoutSpacerGadget(QGraphicsItem* parent = nullptr) : Gadget(parent) { }
~LayoutSpacerGadget() override = default;
QRectF boundingRect() const override;
};
}
using Xybrid::UI::LayoutSpacerGadget;
QRectF LayoutSpacerGadget::boundingRect() const {
auto l = static_cast<LayoutGadget*>(parentItem());
auto w = l->spacing;
return QRectF(QPointF(), QSizeF(w, w));
}
QPointF LayoutGadget::orient(const QPointF& o) const {
if (!vertical) return o;
return QPointF(o.y(), o.x());
}
QSizeF LayoutGadget::orient(const QSizeF& o) const {
if (!vertical) return o;
return o.transposed();
}
QRectF LayoutGadget::orient(const QRectF& o) const {
if (!vertical) return o;
return o.transposed();
}
LayoutGadget::LayoutGadget(QGraphicsItem* parent, bool vertical) : Gadget(parent), vertical(vertical) {
setFlag(GraphicsItemFlag::ItemClipsChildrenToShape, false);
setFlag(GraphicsItemFlag::ItemClipsToShape, false);
if (vertical) { // different defaults for vertical layouts
margin = 0;
spacing = 3;
}
}
LayoutGadget::LayoutGadget(NodeObject* parent, bool vertical) : LayoutGadget(parent->contents, vertical) {
QObject::connect(parent, &NodeObject::finalized, this, [this, parent] {
updateGeometry();
parent->setGadgetSize();
});
}
LayoutGadget::LayoutGadget(NodeUIScene* parent, bool vertical) : LayoutGadget(static_cast<QGraphicsItem*>(nullptr), vertical) {
QObject::connect(parent, &NodeUIScene::finalized, this, [this] {
updateGeometry();
});
parent->addItem(this);
}
LayoutGadget* LayoutGadget::addSpacer() { new LayoutSpacerGadget(this); return this; }
void LayoutGadget::updateGeometry() {
qreal cur = margin;
auto ms = orient(minSize);
qreal h = ms.height();
for (auto c : childItems()) { // clazy:exclude=range-loop-detach
auto g = static_cast<Gadget*>(c);
g->updateGeometry();
auto r = orient(g->layoutBoundingRect());
h = std::max(h, r.height());
}
for (auto c : childItems()) { // clazy:exclude=range-loop-detach
auto g = static_cast<Gadget*>(c);
auto r = orient(g->layoutBoundingRect());
g->centerOn(orient(QPointF(cur + r.width()/2, r.height()/2 + (h - r.height())*bias)));
cur += r.width() + spacing;
}
cur += margin - spacing;
size = orient(QSizeF(std::max(cur, ms.width()), h));
}
QRectF LayoutGadget::boundingRect() const { return { QPointF(), size }; }
void LayoutGadget::paint(QPainter* painter, const QStyleOptionGraphicsItem* opt, QWidget*) {
if (drawPanel) NodeObject::drawPanel(painter, opt, boundingRect().adjusted(-panelMargin, -panelMargin, panelMargin, panelMargin));
}