Files
2026-05-24 23:21:33 +02:00

181 lines
4.6 KiB
C++

#include "lineedittag.h"
#include <QKeyEvent>
#include <QPainter>
#include <QDebug>
#include <QPainterPath>
LineEditTag::LineEditTag(QWidget *parent)
: QLineEdit (parent)
{
setMinimumHeight(24);
}
LineEditTag::~LineEditTag()
{
}
QStringList LineEditTag::getTags() const
{
return tags;
}
QString LineEditTag::getTagsStr() const
{
return tags.join(' ');
}
void LineEditTag::setTags(const QString& tags)
{
if (!tags.isEmpty())
{
this->tags = tags.split(' ');
clear();
update();
}
}
void LineEditTag::setTags(const QStringList& tags)
{
if (!tags.isEmpty())
{
this->tags = tags;
clear();
update();
}
}
void LineEditTag::addTag()
{
if (!text().isEmpty())
{
tags.append(text());
clear();
update();
}
}
void LineEditTag::leaveEvent(QEvent *evt)
{
QLineEdit::leaveEvent(evt);
cursorPos = clickedPos = QPoint();
}
void LineEditTag::keyPressEvent(QKeyEvent *evt)
{
if (evt->key() == Qt::Key_Return || evt->key() == Qt::Key_Enter || evt->key() == Qt::Key_Space)
{
evt->accept();
addTag();
}
else
{
QLineEdit::keyPressEvent(evt);
}
}
void LineEditTag::mousePressEvent(QMouseEvent *evt)
{
clickedPos = evt->pos();
QLineEdit::mousePressEvent(evt);
}
void LineEditTag::mouseMoveEvent(QMouseEvent *evt)
{
QLineEdit::mouseMoveEvent(evt);
cursorPos = evt->pos();
}
void LineEditTag::paintEvent(QPaintEvent *evt)
{
QLineEdit::paintEvent(evt);
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing);
QFontMetrics fm = fontMetrics();
QRectF r = rect();
double space = double(r.height()-fm.height())/2;
int padding = 4;
int cross_size = int(r.height()-space*2);
r.setX(padding);
r.setY(double(r.height()-fm.height())/4);
QPen pen = painter.pen();
QBrush brush = painter.brush();
// Stackoverflow tag like
QColor tag_bg(225, 236, 244);
QColor tag_txt(44, 87, 119);
int x_offset = padding;
int idx = 0;
for (const QString& tag : tags)
{
QRect tag_rect = fm.boundingRect(tag);
r.setWidth(tag_rect.width()+(padding*2)+(padding+cross_size));
r.setHeight(tag_rect.height()+space);
QRectF cross_rect = QRectF(r.x()+r.width()-cross_size-padding, space, cross_size, cross_size);
if (cross_rect.contains(clickedPos))
{
clickedPos = QPoint();
tags.removeAt(idx);
}
else
{
QPainterPath tag_path;
tag_path.addRoundedRect(r, 2, 2);
// Draw tag background and text
painter.fillPath(tag_path, QBrush(tag_bg));
painter.setPen(tag_txt);
painter.drawText(QRectF(r.x()+padding, 0, tag_rect.width(), height()), Qt::AlignVCenter, tag);
// Draw the cross to remove tag
bool isHovered = r.contains(cursorPos);
if (isHovered)
{
// Manage the hovered
QPainterPath cross_path;
cross_path.addRoundedRect(cross_rect, 2, 2);
painter.fillPath(cross_path, QBrush(tag_txt));
// Manage the remove tag mouse cursor
if (cross_rect.contains(cursorPos))
{
setCursor(Qt::PointingHandCursor);
}
else
{
setCursor(Qt::ArrowCursor);
}
}
pen.setWidth(2);
pen.setColor( (isHovered ? tag_bg : tag_txt) );
painter.setPen(pen);
QPointF topL = cross_rect.topLeft(), topR = cross_rect.topRight(), botL = cross_rect.bottomLeft(), botR = cross_rect.bottomRight();
topL.setX(topL.x()+3);
topL.setY(topL.y()+3);
topR.setX(topR.x()-3);
topR.setY(topR.y()+3);
botL.setX(botL.x()+3);
botL.setY(botL.y()-3);
botR.setX(botR.x()-3);
botR.setY(botR.y()-3);
painter.drawLine(topL, botR);
painter.drawLine(topR, botL);
x_offset += r.width()+(padding);
r.setX(x_offset);
idx++;
}
}
if (textMargins().left() != (x_offset))
{
if (tags.isEmpty())
{
setTextMargins(0, 0, 0, 0);
}
else
{
setTextMargins(x_offset-padding, 0, 0, 0);
}
}
}