Files
qelectrotech-source-mirror/sources/editor/graphicspart/partdynamictextfield.h
T
ispyisail bdc1d5878d Position X/Y of a symbol text is the point chosen by its alignment
The text properties showed and edited the top-left corner of a text,
whatever its alignment, and changing the alignment did not move the
text. A right-aligned label next to a symbol therefore needed a
different X for every text length to keep the same gap (#1155).

Position X/Y is now the anchor point: the point of the text chosen by
the alignment (right edge for "right", middle for "centre"...). Typing a
position puts that point there, and changing the alignment moves the
text so that the new anchor point is on the same X/Y. It is the same
point that already stays fixed when the text changes.

Applies to the element text properties on a folio and to the text
field properties in the symbol editor. The saved x/y is still the
top-left corner, so projects and symbols load and save unchanged and
look the same; only the numbers shown for texts that are not top-left
aligned change.

The geometry is in textanchor.h, shared by DiagramTextItem and
PartDynamicTextField, and tested in tst_textanchor.

Not changed: static texts of the symbol editor (PartText), whose
position is tied to the font baseline; texts inside a text group, which
have no position or alignment of their own; rotation still pivots on
the top-left corner (or the centre), not on the anchor.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 18:12:43 +13:00

151 lines
6.0 KiB
C++

/*
Copyright 2006-2026 The QElectroTech Team
This file is part of QElectroTech.
QElectroTech is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
QElectroTech 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with QElectroTech. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef PARTDYNAMICTEXTFIELD_H
#define PARTDYNAMICTEXTFIELD_H
#include "../../qetgraphicsitem/dynamicelementtextitem.h"
#include "QGraphicsTextItem"
#include "customelementpart.h"
/**
@brief The PartDynamicTextField class
This class represents an editable dynamic text field
which may be used to compose the
drawing of an electrical element within the element editor.
The field will remain editable once the element is added onto
a diagram
*/
class PartDynamicTextField : public QGraphicsTextItem, public CustomElementPart
{
Q_OBJECT
Q_PROPERTY(QString text READ text WRITE setText NOTIFY textChanged)
Q_PROPERTY(DynamicElementTextItem::TextFrom textFrom READ textFrom WRITE setTextFrom NOTIFY textFromChanged)
Q_PROPERTY(QString infoName READ infoName WRITE setInfoName NOTIFY infoNameChanged)
Q_PROPERTY(QString compositeText READ compositeText WRITE setCompositeText NOTIFY compositeTextChanged)
Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged)
Q_PROPERTY(bool frame READ frame WRITE setFrame NOTIFY frameChanged)
Q_PROPERTY(qreal textWidth READ textWidth WRITE setTextWidth NOTIFY textWidthChanged)
Q_PROPERTY(Qt::Alignment alignment READ alignment WRITE setAlignment NOTIFY alignmentChanged)
Q_PROPERTY(QPointF anchorPos READ anchorPos WRITE setAnchorPos)
Q_PROPERTY(Qt::Alignment alignmentAtAnchor READ alignment WRITE setAlignmentAtAnchor NOTIFY alignmentChanged)
Q_PROPERTY(QFont font READ font WRITE setFont NOTIFY fontChanged)
Q_PROPERTY(bool keepVisualRotation READ keepVisualRotation WRITE setKeepVisualRotation NOTIFY keepVisualRotationChanged)
Q_PROPERTY(bool rotationPointCenter READ rotationPointCenter WRITE setRotationPointCenter NOTIFY rotationPointCenterChanged)
public:
///PROPERTY
void setProperty(const char *name, const QVariant &value) override {QGraphicsTextItem::setProperty(name, value);}
QVariant property(const char *name) const override {return QGraphicsTextItem::property(name);}
signals:
void taggChanged(QString tagg);
void textChanged(QString text);
void textFromChanged(DynamicElementTextItem::TextFrom text_from);
void infoNameChanged(QString info);
void compositeTextChanged(QString text);
void colorChanged(QColor color);
void frameChanged(bool frame);
void textWidthChanged(qreal width);
void alignmentChanged(Qt::Alignment alignment);
void fontChanged(QFont font);
void keepVisualRotationChanged(bool keep);
void rotationPointCenterChanged(bool center);
public:
PartDynamicTextField(QETElementEditor *editor, QGraphicsItem *parent = nullptr);
enum {Type = UserType + 1110};
int type() const override {return Type;}
QString name() const override;
QString xmlName() const override;
static QString xmlTaggName() {return QString("dynamic_text");}
bool isUseless() const override {return false;}
QUuid uuid() const {return m_uuid;}
void setNewUuid() {m_uuid = QUuid::createUuid();}
QRectF sceneGeometricRect() const override {return sceneBoundingRect();}
void startUserTransformation(const QRectF &initial_selection_rect) override;
void handleUserTransformation(const QRectF &initial_selection_rect, const QRectF &new_selection_rect) override;
const QDomElement toXml(QDomDocument &dom_doc) const override;
void fromXml(const QDomElement &dom_elmt) override;
void fromTextFieldXml(const QDomElement &dom_element);
DynamicElementTextItem::TextFrom textFrom() const;
void setTextFrom (DynamicElementTextItem::TextFrom text_from);
QString text() const;
void setText(const QString &text);
void setInfoName(const QString &info_name);
QString infoName() const;
void setCompositeText(const QString &text);
QString compositeText() const;
void setColor(const QColor& color);
QColor color() const;
void setFrame(bool frame);
bool frame() const;
void setTextWidth(qreal width);
void setPlainText(const QString &text);
void setAlignment(Qt::Alignment alignment);
Qt::Alignment alignment() const;
QPointF anchorPos() const;
void setAnchorPos(const QPointF &anchor);
void setAlignmentAtAnchor(Qt::Alignment alignment);
void setFont(const QFont &font);
void setKeepVisualRotation(const bool &keep);
bool keepVisualRotation() const;
void setRotationPointCenter(const bool &center);
bool rotationPointCenter() const;
void setRotation(qreal angle);
void mirror(qreal axis_x = 0);
void flip(qreal axis_y = 0);
protected:
void mouseMoveEvent(QGraphicsSceneMouseEvent *event) override;
void mousePressEvent(QGraphicsSceneMouseEvent *event) override;
void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) override;
QVariant itemChange(GraphicsItemChange change, const QVariant &value) override;
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override;
private:
void elementInfoChanged();
void prepareAlignment();
void finishAlignment();
private:
QPointF m_origin_pos,
m_saved_point;
QString m_text,
m_info_name,
m_composite_text;
DynamicElementTextItem::TextFrom m_text_from = DynamicElementTextItem::UserText;
QUuid m_uuid;
bool m_frame = false,
m_first_add = true,
m_block_alignment = false,
m_keep_visual_rotation = false,
m_rotation_point_center = false;
qreal m_text_width = -1;
Qt::Alignment m_alignment = Qt::AlignTop|Qt::AlignLeft;
QRectF m_alignment_rect;
};
#endif // PARTDYNAMICTEXTFIELD_H