mirror of
https://github.com/qelectrotech/qelectrotech-source-mirror.git
synced 2026-10-07 20:34:14 +02:00
Resize free texts by dragging a corner
A selected free text gets the corner handles of the previous commit: dragging one sets the width the text wraps to, keeping the opposite corner in place; double-clicking a handle goes back to the automatic width. One undo step per drag, on the folio's undo stack. The handles are hidden while the text is typed in. DiagramTextItem shows the handles for a subclass that asks for them (textResizeHandlesWanted()); only free texts do for now. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -22,6 +22,8 @@
|
||||
#include "../qetapp.h"
|
||||
#include "../richtext/richtexteditor_p.h"
|
||||
#include "../textanchor.h"
|
||||
#include "../utils/qetutils.h"
|
||||
#include "../QetGraphicsItemModeler/textresizehandles.h"
|
||||
|
||||
/**
|
||||
@brief DiagramTextItem::DiagramTextItem
|
||||
@@ -335,6 +337,7 @@ void DiagramTextItem::focusInEvent(QFocusEvent *event)
|
||||
|
||||
m_previous_html_text = toHtml();
|
||||
m_previous_text = toPlainText();
|
||||
refreshTextResizeHandles();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -357,6 +360,87 @@ void DiagramTextItem::focusOutEvent(QFocusEvent *event)
|
||||
|
||||
setFlag(QGraphicsItem::ItemIsMovable, true);
|
||||
setFlag(QGraphicsTextItem::ItemIsFocusable, false);
|
||||
refreshTextResizeHandles();
|
||||
}
|
||||
|
||||
/**
|
||||
@brief DiagramTextItem::itemChange
|
||||
Show or hide the resize handles with the selection.
|
||||
@param change
|
||||
@param value
|
||||
@return
|
||||
*/
|
||||
QVariant DiagramTextItem::itemChange(GraphicsItemChange change, const QVariant &value)
|
||||
{
|
||||
if (change == QGraphicsItem::ItemSelectedHasChanged)
|
||||
refreshTextResizeHandles();
|
||||
else if (change == QGraphicsItem::ItemSceneHasChanged && !scene())
|
||||
removeTextResizeHandles();
|
||||
|
||||
return QGraphicsTextItem::itemChange(change, value);
|
||||
}
|
||||
|
||||
/**
|
||||
@brief DiagramTextItem::textResizeHandlesWanted
|
||||
@return true when the corner handles to change the width of this text
|
||||
should be shown. A text without a "textWidth" property never has them.
|
||||
*/
|
||||
bool DiagramTextItem::textResizeHandlesWanted() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief DiagramTextItem::isEditing
|
||||
@return true while the text itself is being typed in
|
||||
*/
|
||||
bool DiagramTextItem::isEditing() const
|
||||
{
|
||||
return textInteractionFlags() & Qt::TextEditable;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief DiagramTextItem::refreshTextResizeHandles
|
||||
Create or remove the corner handles to change the width of this text,
|
||||
according to textResizeHandlesWanted().
|
||||
Called from itemChange() and when the edition starts or ends, not from
|
||||
paint(): moving items from paint() left fragments behind
|
||||
(qelectrotech#1002).
|
||||
*/
|
||||
void DiagramTextItem::refreshTextResizeHandles()
|
||||
{
|
||||
const bool wanted = scene() && textResizeHandlesWanted();
|
||||
if (wanted && !m_resize_handles)
|
||||
{
|
||||
m_resize_handles = new TextResizeHandles(this, QETUtils::graphicsHandlerSize(this));
|
||||
connect(m_resize_handles, &TextResizeHandles::resizeFinished,
|
||||
this, &DiagramTextItem::pushResizeCommand);
|
||||
}
|
||||
else if (!wanted && m_resize_handles) {
|
||||
removeTextResizeHandles();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@brief DiagramTextItem::removeTextResizeHandles
|
||||
*/
|
||||
void DiagramTextItem::removeTextResizeHandles()
|
||||
{
|
||||
delete m_resize_handles;
|
||||
m_resize_handles = nullptr;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief DiagramTextItem::pushResizeCommand
|
||||
Make the width change done with the resize handles undoable. The change
|
||||
is already applied, live during the drag.
|
||||
*/
|
||||
void DiagramTextItem::pushResizeCommand(qreal old_width, qreal new_width,
|
||||
QPointF old_pos, QPointF new_pos)
|
||||
{
|
||||
if (Diagram *diagram_ = diagram())
|
||||
diagram_->undoStack().push(new TextResizeCommand(this, old_width, new_width,
|
||||
old_pos, new_pos));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
class Diagram;
|
||||
class QDomElement;
|
||||
class QDomDocument;
|
||||
class TextResizeHandles;
|
||||
|
||||
/**
|
||||
This class represents a selectable, movable and editable text field on a
|
||||
@@ -90,12 +91,16 @@ class DiagramTextItem : public QGraphicsTextItem
|
||||
void setPlainText(const QString &text);
|
||||
bool isHtml() const;
|
||||
|
||||
void refreshTextResizeHandles();
|
||||
TextResizeHandles *textResizeHandles() const {return m_resize_handles;}
|
||||
|
||||
protected:
|
||||
void paint(QPainter *,
|
||||
const QStyleOptionGraphicsItem *,
|
||||
QWidget *) override;
|
||||
void focusInEvent(QFocusEvent *) override;
|
||||
void focusOutEvent(QFocusEvent *) override;
|
||||
QVariant itemChange(GraphicsItemChange change, const QVariant &value) override;
|
||||
|
||||
void mouseDoubleClickEvent (QGraphicsSceneMouseEvent *event) override;
|
||||
void mousePressEvent (QGraphicsSceneMouseEvent *event) override;
|
||||
@@ -110,7 +115,10 @@ class DiagramTextItem : public QGraphicsTextItem
|
||||
void prepareAlignment();
|
||||
void finishAlignment();
|
||||
|
||||
virtual bool textResizeHandlesWanted() const;
|
||||
virtual bool hasUserTextWidth() const {return false;}
|
||||
bool isEditing() const;
|
||||
void removeTextResizeHandles();
|
||||
|
||||
|
||||
protected:
|
||||
@@ -128,7 +136,11 @@ class DiagramTextItem : public QGraphicsTextItem
|
||||
QPointF m_mouse_to_origin_movement;
|
||||
|
||||
private:
|
||||
void pushResizeCommand(qreal old_width, qreal new_width,
|
||||
QPointF old_pos, QPointF new_pos);
|
||||
|
||||
QRectF m_alignment_rect;
|
||||
TextResizeHandles *m_resize_handles = nullptr;
|
||||
Qt::Alignment m_alignment = (Qt::AlignTop | Qt::AlignLeft);
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -148,6 +148,16 @@ void IndependentTextItem::setTextWidth(qreal width)
|
||||
emit textWidthChanged(width);
|
||||
}
|
||||
|
||||
/**
|
||||
@brief IndependentTextItem::textResizeHandlesWanted
|
||||
@return true when this text is selected and not being typed in: the
|
||||
corner handles then change its width.
|
||||
*/
|
||||
bool IndependentTextItem::textResizeHandlesWanted() const
|
||||
{
|
||||
return isSelected() && !isEditing();
|
||||
}
|
||||
|
||||
void IndependentTextItem::focusOutEvent(QFocusEvent *event)
|
||||
{
|
||||
DiagramTextItem::focusOutEvent(event);
|
||||
|
||||
@@ -63,6 +63,7 @@ class IndependentTextItem : public DiagramTextItem
|
||||
|
||||
protected:
|
||||
void focusOutEvent(QFocusEvent *event) override;
|
||||
bool textResizeHandlesWanted() const override;
|
||||
bool hasUserTextWidth() const override {return m_text_width > 0;}
|
||||
|
||||
private:
|
||||
|
||||
Reference in New Issue
Block a user