127 lines
4.6 KiB
C++
127 lines
4.6 KiB
C++
#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);
|
|
}
|