Skip to content
Snippets Groups Projects
QGVEdge.cpp 4.47 KiB
Newer Older
nicolas.bergont's avatar
nicolas.bergont committed
/***************************************************************
QGVCore
Copyright (c) 2014, Bergont Nicolas, All rights reserved.

This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 3.0 of the License, or (at your option) any later version.

This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public
License along with this library.
***************************************************************/
Nicolas's avatar
Nicolas committed
#include <QGVEdge.h>
Nicolas's avatar
Nicolas committed
#include <QGVScene.h>
#include <QGVGraphPrivate.h>
#include <QGVEdgePrivate.h>
Nicolas's avatar
Nicolas committed
#include <QDebug>
#include <QPainter>

Martin Zenzes's avatar
Martin Zenzes committed
QGVEdge::QGVEdge(QGVEdgePrivate *edge, QGVScene *scene) :  _scene(scene), _edge(edge)
Nicolas's avatar
Nicolas committed
{
nicolas.bergont's avatar
nicolas.bergont committed
    setFlag(QGraphicsItem::ItemIsSelectable, true);
Nicolas's avatar
Nicolas committed
}

QGVEdge::~QGVEdge()
{
    _scene->removeItem(this);
Nicolas's avatar
Nicolas committed
}

QString QGVEdge::label() const
{
nicolas.bergont's avatar
nicolas.bergont committed
    return getAttribute("xlabel");
Nicolas's avatar
Nicolas committed
}

QRectF QGVEdge::boundingRect() const
{
nicolas.bergont's avatar
nicolas.bergont committed
    return _path.boundingRect() | _head_arrow.boundingRect() | _tail_arrow.boundingRect() | _label_rect;
Nicolas's avatar
Nicolas committed
}

QPainterPath QGVEdge::shape() const
{
    QPainterPathStroker ps;
    ps.setCapStyle(_pen.capStyle());
    ps.setWidth(_pen.widthF() + 10);
    ps.setJoinStyle(_pen.joinStyle());
    ps.setMiterLimit(_pen.miterLimit());
    return ps.createStroke(_path);
}

void QGVEdge::setLabel(const QString &label)
{
    setAttribute("xlabel", label);
}

void QGVEdge::paint(QPainter * painter, const QStyleOptionGraphicsItem *, QWidget *)
Nicolas's avatar
Nicolas committed
{
    painter->save();

    if(isSelected())
nicolas.bergont's avatar
nicolas.bergont committed
    {
        QPen tpen(_pen);
        tpen.setColor(_pen.color().darker(120));
        tpen.setStyle(Qt::DotLine);
        painter->setPen(tpen);
    }
Nicolas's avatar
Nicolas committed
    else
        painter->setPen(_pen);


    painter->drawPath(_path);

nicolas.bergont's avatar
nicolas.bergont committed
    /*
    QRectF pp = _path.controlPointRect();
    if(pp.width() < pp.height())
    {
        painter->save();
        painter->translate(_label_rect.topLeft());
        painter->rotate(90);
        painter->drawText(QRectF(QPointF(0, -_label_rect.width()), _label_rect.size()), Qt::AlignCenter, _label);
        painter->restore();
    }
    else
    */
    painter->drawText(_label_rect, Qt::AlignCenter, _label);
Nicolas's avatar
Nicolas committed

    // painter->setBrush(QBrush(_pen.color(), Qt::SolidPattern));
nicolas.bergont's avatar
nicolas.bergont committed
    painter->drawPolygon(_head_arrow);
    painter->drawPolygon(_tail_arrow);
Nicolas's avatar
Nicolas committed
    painter->restore();
}

void QGVEdge::setAttribute(const QString &name, const QString &value)
{
Martin Zenzes's avatar
Martin Zenzes committed
    char empty[] = "";
		agsafeset(_edge->edge(), name.toLocal8Bit().data(), value.toLocal8Bit().data(), empty);
Nicolas's avatar
Nicolas committed
}

nicolas.bergont's avatar
nicolas.bergont committed
QString QGVEdge::getAttribute(const QString &name) const
{
		char* value = agget(_edge->edge(), name.toLocal8Bit().data());
nicolas.bergont's avatar
nicolas.bergont committed
    if(value)
        return value;
    return QString();
}

Nicolas's avatar
Nicolas committed
void QGVEdge::updateLayout()
{
    prepareGeometryChange();

		qreal gheight = QGVCore::graphHeight(_scene->_graph->graph());
Nicolas's avatar
Nicolas committed

		const splines* spl = ED_spl(_edge->edge());
nicolas.bergont's avatar
nicolas.bergont committed
    _path = QGVCore::toPath(spl, gheight);
Nicolas's avatar
Nicolas committed


nicolas.bergont's avatar
nicolas.bergont committed
    //Edge arrows
Nicolas's avatar
Nicolas committed
    if((spl->list != 0) && (spl->list->size%3 == 1))
    {
        if(spl->list->sflag)
        {
nicolas.bergont's avatar
nicolas.bergont committed
            _tail_arrow = toArrow(QLineF(QGVCore::toPoint(spl->list->list[0], gheight), QGVCore::toPoint(spl->list->sp, gheight)));
Nicolas's avatar
Nicolas committed
        }

        if(spl->list->eflag)
nicolas.bergont's avatar
nicolas.bergont committed
        {
            _head_arrow = toArrow(QLineF(QGVCore::toPoint(spl->list->list[spl->list->size-1], gheight), QGVCore::toPoint(spl->list->ep, gheight)));
        }
    }
Nicolas's avatar
Nicolas committed

    _pen.setWidth(QGVCore::toPenWidth(getAttribute("penwidth")));
nicolas.bergont's avatar
nicolas.bergont committed
    _pen.setColor(QGVCore::toColor(getAttribute("color")));
    _pen.setStyle(QGVCore::toPenStyle(getAttribute("style")));
Nicolas's avatar
Nicolas committed

nicolas.bergont's avatar
nicolas.bergont committed
    //Edge label
		textlabel_t *xlabel = ED_xlabel(_edge->edge());
nicolas.bergont's avatar
nicolas.bergont committed
    if(xlabel)
    {
        _label = xlabel->text;
        _label_rect.setSize(QSize(xlabel->dimen.x, xlabel->dimen.y));
				_label_rect.moveCenter(QGVCore::toPoint(xlabel->pos, QGVCore::graphHeight(_scene->_graph->graph())));
nicolas.bergont's avatar
nicolas.bergont committed
    }
Nicolas's avatar
Nicolas committed

nicolas.bergont's avatar
nicolas.bergont committed
    setToolTip(getAttribute("tooltip"));
}
Nicolas's avatar
Nicolas committed

nicolas.bergont's avatar
nicolas.bergont committed
QPolygonF QGVEdge::toArrow(const QLineF &line) const
{
    QLineF n = line.normalVector();
    QPointF o(n.dx() / 3.0, n.dy() / 3.0);
Nicolas's avatar
Nicolas committed

nicolas.bergont's avatar
nicolas.bergont committed
    //Only support normal arrow type
    QPolygonF polygon;
    polygon.append(line.p1() + o);
    polygon.append(line.p2());
    polygon.append(line.p1() - o);
Nicolas's avatar
Nicolas committed

nicolas.bergont's avatar
nicolas.bergont committed
    return polygon;
Nicolas's avatar
Nicolas committed
}