mirror of
https://github.com/qelectrotech/qelectrotech-source-mirror.git
synced 2026-10-21 22:04:13 +02:00
Width handles: a text is not dragged narrower than its widest word
Narrower, a long word ran out of the text's box while the short lines were still aligned inside the too narrow width: on a right aligned or centred text a lone "1" stood in the middle under its words, and moved on every step. Found on a real plan (-XS20, "Steckdosen Windfang, 1"). The probe checks that no line runs out of the text after narrowing, and also for a text aligned bottom left. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -16,6 +16,8 @@
|
||||
along with QElectroTech. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "dynamicelementtextitem.h"
|
||||
#include <QScopedPointer>
|
||||
#include <QTextDocument>
|
||||
#include "../QetGraphicsItemModeler/textresizehandles.h"
|
||||
#include "../shownkinds.h"
|
||||
#include "../qetproject.h"
|
||||
@@ -1063,6 +1065,20 @@ void DynamicElementTextItem::handlerMousePressEvent(QetGraphicsHandlerItem *hand
|
||||
m_resize_fixed_parent = mapToParent(resizeAnchor());
|
||||
}
|
||||
|
||||
/**
|
||||
@brief DynamicElementTextItem::minimumTextWidth
|
||||
@return the narrowest width the text can be dragged to: that of its
|
||||
widest word. Narrower, a long word runs out of the text's box while
|
||||
the short lines are still aligned inside it, and a centred or right
|
||||
aligned text falls apart (a lone "1" in the middle under its words).
|
||||
*/
|
||||
qreal DynamicElementTextItem::minimumTextWidth() const
|
||||
{
|
||||
QScopedPointer<QTextDocument> narrowest(document()->clone());
|
||||
narrowest->setTextWidth(0);
|
||||
return qMax(narrowest->idealWidth(), qreal(10));
|
||||
}
|
||||
|
||||
/**
|
||||
@brief DynamicElementTextItem::resizeAnchor
|
||||
@return the point of the text, in its own coordinates, that a drag on
|
||||
@@ -1102,7 +1118,7 @@ void DynamicElementTextItem::handlerMouseMoveEvent(QetGraphicsHandlerItem *handl
|
||||
if (handle == m_left_resize_handle)
|
||||
delta = -delta;
|
||||
|
||||
qreal new_width = qMax(m_resize_baseline_width + delta, qreal(10));
|
||||
qreal new_width = qMax(m_resize_baseline_width + delta, minimumTextWidth());
|
||||
setTextWidth(new_width);
|
||||
|
||||
//Keep the point the text is aligned on in place, whatever the new
|
||||
|
||||
@@ -171,6 +171,7 @@ class DynamicElementTextItem : public DiagramTextItem
|
||||
void removeResizeHandles();
|
||||
void updateResizeHandlesPos();
|
||||
QPointF resizeAnchor() const;
|
||||
qreal minimumTextWidth() const;
|
||||
void fitAutoTextWidth();
|
||||
void handlerMousePressEvent(QetGraphicsHandlerItem *handle, QGraphicsSceneMouseEvent *event);
|
||||
void handlerMouseMoveEvent(QetGraphicsHandlerItem *handle, QGraphicsSceneMouseEvent *event);
|
||||
|
||||
@@ -14,6 +14,9 @@
|
||||
#include <QGraphicsSceneMouseEvent>
|
||||
#include <QSettings>
|
||||
#include <QTemporaryDir>
|
||||
#include <QTextBlock>
|
||||
#include <QTextDocument>
|
||||
#include <QTextLayout>
|
||||
#include <cstdio>
|
||||
#include <stdexcept>
|
||||
|
||||
@@ -82,6 +85,20 @@ static void drag(Diagram *scene, DynamicElementTextItem *text, bool left, qreal
|
||||
mouse(scene, h, QEvent::GraphicsSceneMouseRelease, end);
|
||||
}
|
||||
|
||||
/// Every line lies inside the text's width: none runs out of it.
|
||||
static bool linesInside(DynamicElementTextItem *text)
|
||||
{
|
||||
QTextDocument *doc = text->document();
|
||||
const qreal inner = doc->textWidth() - 2 * doc->documentMargin();
|
||||
for (QTextBlock b = doc->begin(); b.isValid(); b = b.next())
|
||||
for (int i = 0; i < b.layout()->lineCount(); ++i) {
|
||||
const QTextLine line = b.layout()->lineAt(i);
|
||||
if (line.x() < -0.01 || line.x() + line.naturalTextWidth() > inner + 0.01)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/// The width changed by exactly as much as the mouse moved.
|
||||
static void checkGrowth(DynamicElementTextItem *text, qreal before, qreal moved, const char *message)
|
||||
{
|
||||
@@ -124,6 +141,7 @@ static void checkText(Diagram *scene, Element *element, DynamicElementTextItem *
|
||||
const qreal height = text->boundingRect().height();
|
||||
drag(scene, text, false, 25 - width);
|
||||
check(text->boundingRect().height() > height + 5, "narrowing the text wraps it onto more lines");
|
||||
check(linesInside(text), "a text is not narrower than its widest word: no line runs out of it");
|
||||
check(near(anchor(text), fixed), "a text that wraps keeps its alignment point in place");
|
||||
scene->undoStack().undo();
|
||||
check(near(text->pos(), pos), "undo puts the wrapped text back");
|
||||
@@ -136,6 +154,7 @@ static void checkAll(Diagram *scene, Element *element, DynamicElementTextItem *t
|
||||
checkText(scene, element, text, Qt::AlignRight | Qt::AlignTop);
|
||||
checkText(scene, element, text, Qt::AlignHCenter | Qt::AlignVCenter);
|
||||
checkText(scene, element, text, Qt::AlignRight | Qt::AlignBottom);
|
||||
checkText(scene, element, text, Qt::AlignLeft | Qt::AlignBottom);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
|
||||
Reference in New Issue
Block a user