mirror of
https://github.com/qelectrotech/qelectrotech-source-mirror.git
synced 2026-08-01 17:14:13 +02:00
Feature: Add terminal name label display in element editor
This commit is contained in:
@@ -17,6 +17,8 @@
|
||||
*/
|
||||
#include "partterminal.h"
|
||||
|
||||
#include "../elementscene.h"
|
||||
#include "../../QPropertyUndoCommand/qpropertyundocommand.h"
|
||||
#include "../../qetgraphicsitem/terminal.h"
|
||||
|
||||
/**
|
||||
@@ -100,6 +102,60 @@ void PartTerminal::paint(
|
||||
|
||||
if (m_hovered)
|
||||
drawShadowShape(painter);
|
||||
|
||||
if (d->m_show_name && !d->m_name.isEmpty()) {
|
||||
painter->save();
|
||||
painter->setFont(d->m_label_font);
|
||||
painter->setPen(d->m_label_color);
|
||||
painter->setRenderHint(QPainter::Antialiasing, true);
|
||||
painter->setRenderHint(QPainter::TextAntialiasing, true);
|
||||
|
||||
QPointF label_pos = d->m_label_pos;
|
||||
QRectF text_rect;
|
||||
QFontMetrics fm(d->m_label_font);
|
||||
QSizeF text_size = fm.size(Qt::TextSingleLine, d->m_name);
|
||||
|
||||
auto compute_rect = [&]() {
|
||||
qreal dx = 0, dy = 0;
|
||||
if (d->m_label_halignment & Qt::AlignLeft) dx = 0;
|
||||
else if (d->m_label_halignment & Qt::AlignHCenter) dx = -text_size.width() / 2.0;
|
||||
else if (d->m_label_halignment & Qt::AlignRight) dx = -text_size.width();
|
||||
if (d->m_label_valignment & Qt::AlignTop) dy = 0;
|
||||
else if (d->m_label_valignment & Qt::AlignVCenter) dy = -text_size.height() / 2.0;
|
||||
else if (d->m_label_valignment & Qt::AlignBottom) dy = -text_size.height();
|
||||
return QRectF(label_pos + QPointF(dx, dy), text_size);
|
||||
};
|
||||
|
||||
if (d->m_label_rotation != 0.0) {
|
||||
painter->translate(label_pos);
|
||||
painter->rotate(d->m_label_rotation);
|
||||
text_rect = QRectF(-text_size.width()/2.0, -text_size.height()/2.0,
|
||||
text_size.width(), text_size.height());
|
||||
if (d->m_label_frame) {
|
||||
painter->drawRect(text_rect.adjusted(-1, -1, 1, 1));
|
||||
}
|
||||
painter->drawText(text_rect, static_cast<int>(d->m_label_halignment | d->m_label_valignment), d->m_name);
|
||||
} else {
|
||||
text_rect = compute_rect();
|
||||
if (d->m_label_frame) {
|
||||
painter->drawRect(text_rect.adjusted(-1, -1, 1, 1));
|
||||
}
|
||||
painter->drawText(text_rect, static_cast<int>(Qt::AlignLeft | Qt::AlignTop), d->m_name);
|
||||
}
|
||||
|
||||
if (isSelected() || m_hovered) {
|
||||
QPen outline_pen(Qt::darkBlue, 0, Qt::DashLine);
|
||||
painter->setPen(outline_pen);
|
||||
painter->setBrush(Qt::NoBrush);
|
||||
if (d->m_label_rotation != 0.0) {
|
||||
painter->drawRect(text_rect.adjusted(-1, -1, 1, 1));
|
||||
} else {
|
||||
painter->drawRect(text_rect.adjusted(-1, -1, 1, 1));
|
||||
}
|
||||
}
|
||||
|
||||
painter->restore();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -114,7 +170,27 @@ QPainterPath PartTerminal::shape() const
|
||||
QPainterPathStroker pps;
|
||||
pps.setWidth(1);
|
||||
|
||||
return (pps.createStroke(shape));
|
||||
QPainterPath path = pps.createStroke(shape);
|
||||
|
||||
if (d->m_show_name && !d->m_name.isEmpty()) {
|
||||
path.addRect(labelRect());
|
||||
}
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief PartTerminal::shadowShape
|
||||
@return the hover outline shape (terminal line only, no label rect)
|
||||
*/
|
||||
QPainterPath PartTerminal::shadowShape() const
|
||||
{
|
||||
QPainterPath shape;
|
||||
shape.lineTo(d -> m_second_point);
|
||||
|
||||
QPainterPathStroker pps;
|
||||
pps.setWidth(1);
|
||||
return pps.createStroke(shape);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -128,9 +204,40 @@ QRectF PartTerminal::boundingRect() const
|
||||
|
||||
qreal adjust = (SHADOWS_HEIGHT + 1) / 2;
|
||||
br.adjust(-adjust, -adjust, adjust, adjust);
|
||||
|
||||
if (d->m_show_name && !d->m_name.isEmpty()) {
|
||||
br = br.united(labelRect());
|
||||
}
|
||||
|
||||
return(br);
|
||||
}
|
||||
|
||||
/**
|
||||
@brief PartTerminal::labelRect
|
||||
@return the rectangle of the label text (in item coordinates),
|
||||
or an empty rect if the label is not shown
|
||||
*/
|
||||
QRectF PartTerminal::labelRect() const
|
||||
{
|
||||
if (!d->m_show_name || d->m_name.isEmpty())
|
||||
return QRectF();
|
||||
|
||||
QFontMetrics fm(d->m_label_font);
|
||||
QSizeF text_size = fm.size(Qt::TextSingleLine, d->m_name);
|
||||
QPointF label_pos = d->m_label_pos;
|
||||
|
||||
qreal dx = 0, dy = 0;
|
||||
if (d->m_label_halignment & Qt::AlignLeft) dx = 0;
|
||||
else if (d->m_label_halignment & Qt::AlignHCenter) dx = -text_size.width() / 2.0;
|
||||
else if (d->m_label_halignment & Qt::AlignRight) dx = -text_size.width();
|
||||
|
||||
if (d->m_label_valignment & Qt::AlignTop) dy = 0;
|
||||
else if (d->m_label_valignment & Qt::AlignVCenter) dy = -text_size.height() / 2.0;
|
||||
else if (d->m_label_valignment & Qt::AlignBottom) dy = -text_size.height();
|
||||
|
||||
return QRectF(label_pos + QPointF(dx, dy), text_size).adjusted(-3, -3, 3, 3);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Definit l'orientation de la borne
|
||||
@@ -282,6 +389,77 @@ void PartTerminal::setNewUuid()
|
||||
d -> m_uuid = QUuid::createUuid();
|
||||
}
|
||||
|
||||
void PartTerminal::setShowName(bool show)
|
||||
{
|
||||
if (d->m_show_name == show) return;
|
||||
prepareGeometryChange();
|
||||
d->m_show_name = show;
|
||||
update();
|
||||
emit showNameChanged();
|
||||
}
|
||||
|
||||
void PartTerminal::setLabelPos(QPointF pos)
|
||||
{
|
||||
if (d->m_label_pos == pos) return;
|
||||
prepareGeometryChange();
|
||||
d->m_label_pos = pos;
|
||||
update();
|
||||
emit labelPosChanged();
|
||||
}
|
||||
|
||||
void PartTerminal::setLabelFont(QFont font)
|
||||
{
|
||||
if (d->m_label_font == font) return;
|
||||
prepareGeometryChange();
|
||||
d->m_label_font = font;
|
||||
update();
|
||||
emit labelFontChanged();
|
||||
}
|
||||
|
||||
void PartTerminal::setLabelRotation(qreal rotation)
|
||||
{
|
||||
if (qFuzzyCompare(d->m_label_rotation, rotation)) return;
|
||||
prepareGeometryChange();
|
||||
d->m_label_rotation = rotation;
|
||||
update();
|
||||
emit labelRotationChanged();
|
||||
}
|
||||
|
||||
void PartTerminal::setLabelHAlignment(Qt::Alignment align)
|
||||
{
|
||||
if (d->m_label_halignment == align) return;
|
||||
prepareGeometryChange();
|
||||
d->m_label_halignment = align;
|
||||
update();
|
||||
emit labelHAlignmentChanged();
|
||||
}
|
||||
|
||||
void PartTerminal::setLabelVAlignment(Qt::Alignment align)
|
||||
{
|
||||
if (d->m_label_valignment == align) return;
|
||||
prepareGeometryChange();
|
||||
d->m_label_valignment = align;
|
||||
update();
|
||||
emit labelVAlignmentChanged();
|
||||
}
|
||||
|
||||
void PartTerminal::setLabelFrame(bool frame)
|
||||
{
|
||||
if (d->m_label_frame == frame) return;
|
||||
prepareGeometryChange();
|
||||
d->m_label_frame = frame;
|
||||
update();
|
||||
emit labelFrameChanged();
|
||||
}
|
||||
|
||||
void PartTerminal::setLabelColor(QColor color)
|
||||
{
|
||||
if (d->m_label_color == color) return;
|
||||
d->m_label_color = color;
|
||||
update();
|
||||
emit labelColorChanged();
|
||||
}
|
||||
|
||||
/**
|
||||
Updates the position of the second point according to the position
|
||||
and orientation of the terminal.
|
||||
@@ -338,3 +516,53 @@ void PartTerminal::handleUserTransformation(const QRectF &initial_selection_rect
|
||||
initial_selection_rect, new_selection_rect, QList<QPointF>() << saved_position_).first();
|
||||
setPos(mapped_point);
|
||||
}
|
||||
|
||||
void PartTerminal::mousePressEvent(QGraphicsSceneMouseEvent *event)
|
||||
{
|
||||
if (event->button() == Qt::LeftButton && d->m_show_name && !d->m_name.isEmpty()) {
|
||||
QPointF local_click = event->pos();
|
||||
// Only start label drag when click is on label AND NOT on terminal line
|
||||
if (!shadowShape().contains(local_click) && labelRect().contains(local_click)) {
|
||||
m_dragging_label = true;
|
||||
m_original_label_pos = d->m_label_pos;
|
||||
}
|
||||
}
|
||||
CustomElementGraphicPart::mousePressEvent(event);
|
||||
}
|
||||
|
||||
void PartTerminal::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
|
||||
{
|
||||
if (m_dragging_label) {
|
||||
QPointF delta = event->pos() - event->buttonDownPos(Qt::LeftButton);
|
||||
QPointF new_pos = m_original_label_pos + delta;
|
||||
if (!(event->modifiers() & Qt::ControlModifier)) {
|
||||
ElementScene *scene = elementScene();
|
||||
if (scene) {
|
||||
QPointF scene_pos = mapToScene(new_pos);
|
||||
new_pos = mapFromScene(scene->snapToGrid(scene_pos));
|
||||
}
|
||||
}
|
||||
setLabelPos(new_pos);
|
||||
update();
|
||||
event->accept();
|
||||
return;
|
||||
}
|
||||
CustomElementGraphicPart::mouseMoveEvent(event);
|
||||
}
|
||||
|
||||
void PartTerminal::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
|
||||
{
|
||||
if (m_dragging_label) {
|
||||
m_dragging_label = false;
|
||||
if (m_original_label_pos != d->m_label_pos) {
|
||||
auto undo = new QPropertyUndoCommand(this, "label_pos",
|
||||
QVariant(m_original_label_pos), QVariant(d->m_label_pos));
|
||||
undo->setText(tr("Déplacer le label d'une borne"));
|
||||
undo->enableAnimation();
|
||||
elementScene()->undoStack().push(undo);
|
||||
}
|
||||
event->accept();
|
||||
return;
|
||||
}
|
||||
CustomElementGraphicPart::mouseReleaseEvent(event);
|
||||
}
|
||||
|
||||
@@ -34,6 +34,14 @@ class PartTerminal : public CustomElementGraphicPart
|
||||
Q_PROPERTY(Qet::Orientation orientation READ orientation WRITE setOrientation)
|
||||
Q_PROPERTY(QString terminal_name READ terminalName WRITE setTerminalName)
|
||||
Q_PROPERTY(TerminalData::Type terminal_type READ terminalType WRITE setTerminalType)
|
||||
Q_PROPERTY(bool show_name READ showName WRITE setShowName)
|
||||
Q_PROPERTY(QPointF label_pos READ labelPos WRITE setLabelPos)
|
||||
Q_PROPERTY(QFont label_font READ labelFont WRITE setLabelFont)
|
||||
Q_PROPERTY(qreal label_rotation READ labelRotation WRITE setLabelRotation)
|
||||
Q_PROPERTY(Qt::Alignment label_halignment READ labelHAlignment WRITE setLabelHAlignment)
|
||||
Q_PROPERTY(Qt::Alignment label_valignment READ labelVAlignment WRITE setLabelVAlignment)
|
||||
Q_PROPERTY(bool label_frame READ labelFrame WRITE setLabelFrame)
|
||||
Q_PROPERTY(QColor label_color READ labelColor WRITE setLabelColor)
|
||||
|
||||
public:
|
||||
// constructors, destructor
|
||||
@@ -46,6 +54,14 @@ class PartTerminal : public CustomElementGraphicPart
|
||||
void orientationChanged();
|
||||
void nameChanged();
|
||||
void terminalTypeChanged();
|
||||
void showNameChanged();
|
||||
void labelPosChanged();
|
||||
void labelFontChanged();
|
||||
void labelRotationChanged();
|
||||
void labelHAlignmentChanged();
|
||||
void labelVAlignmentChanged();
|
||||
void labelFrameChanged();
|
||||
void labelColorChanged();
|
||||
|
||||
// methods
|
||||
public:
|
||||
@@ -64,7 +80,7 @@ class PartTerminal : public CustomElementGraphicPart
|
||||
QWidget *) override;
|
||||
|
||||
QPainterPath shape() const override;
|
||||
QPainterPath shadowShape() const override {return shape();}
|
||||
QPainterPath shadowShape() const override;
|
||||
QRectF boundingRect() const override;
|
||||
bool isUseless() const override;
|
||||
QRectF sceneGeometricRect() const override;
|
||||
@@ -90,13 +106,46 @@ class PartTerminal : public CustomElementGraphicPart
|
||||
TerminalData::Type terminalType() const {return d->m_type;}
|
||||
void setTerminalType(TerminalData::Type type);
|
||||
|
||||
bool showName() const { return d->m_show_name; }
|
||||
void setShowName(bool show);
|
||||
|
||||
QPointF labelPos() const { return d->m_label_pos; }
|
||||
void setLabelPos(QPointF pos);
|
||||
|
||||
QFont labelFont() const { return d->m_label_font; }
|
||||
void setLabelFont(QFont font);
|
||||
|
||||
qreal labelRotation() const { return d->m_label_rotation; }
|
||||
void setLabelRotation(qreal rotation);
|
||||
|
||||
Qt::Alignment labelHAlignment() const { return d->m_label_halignment; }
|
||||
void setLabelHAlignment(Qt::Alignment align);
|
||||
|
||||
Qt::Alignment labelVAlignment() const { return d->m_label_valignment; }
|
||||
void setLabelVAlignment(Qt::Alignment align);
|
||||
|
||||
bool labelFrame() const { return d->m_label_frame; }
|
||||
void setLabelFrame(bool frame);
|
||||
|
||||
QColor labelColor() const { return d->m_label_color; }
|
||||
void setLabelColor(QColor color);
|
||||
|
||||
void setNewUuid();
|
||||
|
||||
QRectF labelRect() const;
|
||||
|
||||
protected:
|
||||
void mousePressEvent(QGraphicsSceneMouseEvent *event) override;
|
||||
void mouseMoveEvent(QGraphicsSceneMouseEvent *event) override;
|
||||
void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) override;
|
||||
|
||||
private:
|
||||
void updateSecondPoint();
|
||||
TerminalData* d; // pointer to the terminal data
|
||||
|
||||
private:
|
||||
QPointF saved_position_;
|
||||
bool m_dragging_label = false;
|
||||
QPointF m_original_label_pos;
|
||||
};
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user