/* dtkComposerSceneEdge.cpp --- * * Author: Julien Wintz * Copyright (C) 2008-2011 - Julien Wintz, Inria. * Created: Fri Feb 3 14:00:23 2012 (+0100) * Version: $Id: b93835089aa5df441e625080f7486a89de5b739c $ * Last-Updated: Wed Apr 10 17:00:57 2013 (+0200) * By: Thibaud Kloczko * Update #: 191 */ /* Commentary: * */ /* Change log: * */ #include "dtkComposerSceneEdge.h" #include "dtkComposerScene.h" #include "dtkComposerSceneNode.h" #include "dtkComposerSceneNodeComposite.h" #include "dtkComposerScenePort.h" class dtkComposerSceneEdgePrivate { public: dtkComposerSceneNode *parent; dtkComposerScene *scene; public: dtkComposerScenePort *source; dtkComposerScenePort *destination; public: QPainterPath path; public: bool valid; bool flagged; bool connected_to_selection; }; dtkComposerSceneEdge::dtkComposerSceneEdge(void) : QGraphicsItem(), d(new dtkComposerSceneEdgePrivate) { d->source = NULL; d->destination = NULL; d->scene = NULL; d->parent = NULL; d->valid = false; d->flagged = false; d->connected_to_selection = false; this->setFlags(QGraphicsItem::ItemIsSelectable); this->setZValue(0); } dtkComposerSceneEdge::~dtkComposerSceneEdge(void) { delete d; d = NULL; } QRectF dtkComposerSceneEdge::boundingRect(void) const { return d->path.boundingRect(); } void dtkComposerSceneEdge::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) { Q_UNUSED(option); Q_UNUSED(widget); painter->save(); painter->setPen(QPen(Qt::black, 1)); // if (!d->scene) if (dtkComposerScene *scene = dynamic_cast ( this->scene())) d->scene = scene; if (d->scene && d->scene->maskedEdges()) this->setOpacity(0.05); if (d->connected_to_selection) { painter->setBrush(Qt::yellow); this->setOpacity(1); } else if (!d->flagged) painter->setBrush(Qt::gray); else if (d->valid) painter->setBrush(Qt::green); else painter->setBrush(Qt::red); if (this->isSelected()) painter->setBrush(Qt::magenta); painter->drawPath(d->path); painter->restore(); } QPainterPath dtkComposerSceneEdge::shape(void) const { QPainterPathStroker stroker; stroker.setWidth(10); return stroker.createStroke(d->path); } dtkComposerScenePort *dtkComposerSceneEdge::source(void) { return d->source; } dtkComposerScenePort *dtkComposerSceneEdge::destination(void) { return d->destination; } void dtkComposerSceneEdge::setSource(dtkComposerScenePort *port) { d->source = port; this->adjust(); } void dtkComposerSceneEdge::setDestination(dtkComposerScenePort *port) { d->destination = port; this->adjust(); } void dtkComposerSceneEdge::adjust(void) { if (!d->source || !d->destination) return; if (!this->isVisible()) return; QRectF rect; rect = d->source->boundingRect(); QPointF start = d->source->mapToScene(rect.center()); rect = d->destination->boundingRect(); QPointF end = d->destination->mapToScene(rect.center()); this->adjust(start, end); } void dtkComposerSceneEdge::adjust(const QPointF& start, const QPointF& end) { this->prepareGeometryChange(); QPointF midPoint = (start + end) / 2; qreal halfMid = (midPoint.x() - start.x()) / 2; QPainterPath path; path.moveTo(start); path.cubicTo(QPointF(end.x() - halfMid, start.y()), QPointF(start.x() + halfMid, end.y()), end); QPainterPathStroker stroker; stroker.setWidth(3); stroker.setCapStyle(Qt::RoundCap); d->path = stroker.createStroke(path); this->update(); } bool dtkComposerSceneEdge::link(bool anyway) { Q_UNUSED(anyway); if (!d->source || !d->destination) return false; if (d->source == d->destination) return false; if (d->source->node() == d->destination->node()) return false; if (d->source->type() == dtkComposerScenePort::Output) d->source->node()->addOutputEdge(this); if (d->destination->type() == dtkComposerScenePort::Input) d->destination->node()->addInputEdge(this); return true; } bool dtkComposerSceneEdge::unlink(void) { if (!d->source || !d->destination) return false; if (d->source->type() == dtkComposerScenePort::Output) d->source->node()->removeOutputEdge(this); if (d->destination->type() == dtkComposerScenePort::Input) d->destination->node()->removeInputEdge(this); return true; } bool dtkComposerSceneEdge::valid(void) { return (d->valid == true); } bool dtkComposerSceneEdge::invalid(void) { return (d->valid == false); } void dtkComposerSceneEdge::validate(void) { d->valid = true; d->flagged = true; } void dtkComposerSceneEdge::invalidate(void) { d->valid = false; d->flagged = true; } void dtkComposerSceneEdge::setConnected(bool value) { d->connected_to_selection = value; this->update(); } dtkComposerSceneNode *dtkComposerSceneEdge::parent(void) { return d->parent; } void dtkComposerSceneEdge::setParent(dtkComposerSceneNode *parent) { d->parent = parent; }