summaryrefslogtreecommitdiff
path: root/tagitem.cpp
blob: 01b26fb70ae23a91fee0e94ac8a596e9bac92910 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
#include "tagitem.h"
#include "tagscene.h"

#include <QPainter>
#include <QGuiApplication>
#include <QGraphicsScene>
#include <QGraphicsSceneMouseEvent>

TagItem::TagItem(const Tag &tag)
    : valid(true)
    , m_margins(2, 2, 2, 2)
{
    setFlags(QGraphicsItem::ItemIsSelectable
             | QGraphicsItem::ItemIsMovable
             | QGraphicsItem::ItemIsFocusable
             | QGraphicsItem::ItemIgnoresTransformations
             | QGraphicsItem::ItemSendsGeometryChanges);
    QFont font(QGuiApplication::font());
    font.setPointSize(12);
    setFont(font);
    tagUpdated(tag);
}

void TagItem::tagUpdated(const Tag &tag)
{
    m_tag = tag;
    qDebug() << "TagItem updated" << tag.name << tag.anchor;
    setText(tag.name);
    setPos(tag.anchor);
}

QRectF TagItem::boundingRect() const
{
    QRectF parentRect(QGraphicsSimpleTextItem::boundingRect());
    parentRect.translate(-(parentRect.bottomRight() - parentRect.topLeft()) * 0.5);
    return parentRect.marginsAdded(m_margins);
}

/* For some reason this is not exposed through the public API so we have to copy-paste it here m( */
static void paintSelectionHighlightBorder(QPainter *painter, const QStyleOptionGraphicsItem *option, TagItem *item)
{
        const QRectF mbrect = painter->transform().mapRect(item->boundingRect());
        if (qMin(mbrect.width(), mbrect.height()) < qreal(1.0))
            return;

        const qreal pad = item->pen().widthF() / 2;
        const qreal penWidth = 0; // cosmetic pen
        const QColor fgcolor = option->palette.windowText().color();
        const QColor bgcolor( // ensure good contrast against fgcolor
            fgcolor.red()   > 127 ? 0 : 255,
            fgcolor.green() > 127 ? 0 : 255,
            fgcolor.blue()  > 127 ? 0 : 255);
        painter->setPen(QPen(bgcolor, penWidth, Qt::SolidLine));
        painter->setBrush(Qt::NoBrush);
        painter->drawRect(item->boundingRect().adjusted(pad, pad, -pad, -pad));
        painter->setPen(QPen(option->palette.windowText(), 0, Qt::DashLine));
        painter->setBrush(Qt::NoBrush);
        painter->drawRect(item->boundingRect().adjusted(pad, pad, -pad, -pad));
}

void TagItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
    bool selectionHighlight = option->state & (QStyle::State_Selected | QStyle::State_HasFocus);
    if (selectionHighlight)
        painter->setBrush(QColor("#80aaaaff"));
    else
        painter->setBrush(QColor("#80ffffff"));
    painter->drawRect(boundingRect());

    QRectF parentRect(QGraphicsSimpleTextItem::boundingRect());
    QPointF pos = (parentRect.bottomRight() - parentRect.topLeft()) * 0.5;
    painter->translate(-pos);

    QStyleOptionGraphicsItem newOption(*option);
    newOption.state = ~(QStyle::State_Selected |QStyle::State_HasFocus);
    QGraphicsSimpleTextItem::paint(painter, &newOption, widget);

    painter->translate(pos);
    if (selectionHighlight)
        paintSelectionHighlightBorder(painter, option, this);
}

QPainterPath TagItem::shape() const
{
    QPainterPath path;
    return QGraphicsItem::shape();
}

QVariant TagItem::itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant &value)
{
    //qDebug() << "itemChange" << m_tag.name << this->boundingRect() << change;
    if (change == ItemSceneChange) {
        assert(qvariant_cast<TagScene *>(value)); /* TagItems must only be used in TagScene. */
    } else if (change == ItemPositionChange) {

        /* https://gist.github.com/csukuangfj/c2a06416062bec9ed99eddd705c21275#file-qgraphicsscenetest-cpp-L90
         *
         */
        /* FIXME */
    }
    return QGraphicsItem::itemChange(change, value);
}

void TagItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
{
    if (event->buttons() & Qt::LeftButton) {
        QPoint delta = event->screenPos() - event->buttonDownScreenPos(Qt::LeftButton);
        int pixelThreshold = 10;
        if (QPoint::dotProduct(delta, delta) > pixelThreshold*pixelThreshold)
            dragAboveThreshold = true;

        if (!dragAboveThreshold) {
            // patch up event to prevent small movements
            event->setPos(event->buttonDownPos(Qt::LeftButton));
            event->setScenePos(event->buttonDownScenePos(Qt::LeftButton));
            event->setScreenPos(event->buttonDownScreenPos(Qt::LeftButton));
        }
    }
    QGraphicsItem::mouseMoveEvent(event);
}

void TagItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
{
    Q_UNUSED(event);
    dragAboveThreshold = false;
    QGraphicsItem::mouseReleaseEvent(event);
}