QElectroTech 0.200.1-dev
Loading...
Searching...
No Matches
diagramimageitem.h
Go to the documentation of this file.
1/*
2 Copyright 2006-2026 The QElectroTech Team
3 This file is part of QElectroTech.
4
5 QElectroTech is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 2 of the License, or
8 (at your option) any later version.
9
10 QElectroTech is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with QElectroTech. If not, see <http://www.gnu.org/licenses/>.
17*/
18#ifndef DIAGRAM_IMAGE_ITEM_H
19#define DIAGRAM_IMAGE_ITEM_H
20
21#include "qetgraphicsitem.h"
22#include "shapetransform.h"
24
25#include <QColor>
26#include <QList>
27#include <QStyleOptionGraphicsItem>
28#include <QVector>
29
30class QDomElement;
31class QDomDocument;
32class QGraphicsSceneContextMenuEvent;
34
41 Q_OBJECT
42 Q_PROPERTY(QPixmap pixmap READ pixmap WRITE setPixmap NOTIFY pixmapChanged)
43 Q_PROPERTY(qreal scaleFactorX READ scaleFactorX WRITE setScaleFactorX NOTIFY transformChanged)
44 Q_PROPERTY(qreal scaleFactorY READ scaleFactorY WRITE setScaleFactorY NOTIFY transformChanged)
46 Q_PROPERTY(qreal skewX READ skewX WRITE setSkewX NOTIFY transformChanged)
47 Q_PROPERTY(qreal skewY READ skewY WRITE setSkewY NOTIFY transformChanged)
48 Q_PROPERTY(QPointF pivot READ pivot WRITE setPivot NOTIFY transformChanged)
49 // A second, deliberately non-compensating property on the SAME
50 // underlying value -- setPivot() (above) intentionally adjusts
51 // pos() to keep the image visually in place, which is exactly
52 // wrong for crop()'s own undo chain: crop() already computes the
53 // correct final pos() itself (accounting for the crop, not just
54 // the pivot move) and pushes it as its own separate "pos" command,
55 // so a chained "pivot" step going through the compensating setter
56 // would silently overwrite that already-correct pos() a second
57 // time. rawPivot exists solely for that one caller.
58 Q_PROPERTY(QPointF rawPivot READ pivot WRITE setPivotRaw NOTIFY transformChanged)
59
60 // constructors, destructor
61 public:
63 DiagramImageItem(const QPixmap &pixmap, QetGraphicsItem * = nullptr);
64 ~DiagramImageItem() override;
65
66 // attributes
67 public:
68 enum { Type = UserType + 1007 };
69
70 // A deliberately smaller, image-specific set than QetShapeItem's own
71 // HandleMode/HandleRole: images have no path/polygon/arc concepts at
72 // all, so reusing those enums directly would pull in a great deal of
73 // irrelevant baggage for no benefit. RotateSkew's math (rotate,
74 // skew, and their shared scaleAndShearOffset()/scaleOnlyOffset()
75 // helpers) mirrors QetShapeItem's own identical formulas -- adapted
76 // to this class's own, simpler 4-corner/4-edge/1-pivot handle set,
77 // not shared code, since the two classes' broader handle roles
78 // differ too much (no path/polygon/arc concepts here) for sharing
79 // the dispatcher itself to be worth an indirect abstraction.
80 enum class HandleMode { Size, RotateSkew };
82
83 // methods
84 public:
90 int type() const override { return Type; }
91
92 virtual bool fromXml(const QDomElement &);
93 virtual QDomElement toXml(QDomDocument &) const;
94 void editProperty() override;
95 void setPixmap(const QPixmap &pixmap);
96 QPixmap pixmap() const { return pixmap_; }
97 QRectF boundingRect() const override;
98 QString name() const override;
99
107 void paintForExport(QPainter *painter)
108 {
109 QStyleOptionGraphicsItem option;
110 paint(painter, &option, nullptr);
111 }
112
113 qreal scaleFactorX() const { return m_transform.scaleX; }
114 qreal scaleFactorY() const { return m_transform.scaleY; }
115 void setScaleFactorX(qreal factor);
116 void setScaleFactorY(qreal factor);
117 qreal rotationAngle() const { return m_transform.rotation; }
118 void setRotationAngle(qreal angle);
119 qreal skewX() const { return m_transform.skewX; }
120 void setSkewX(qreal skew);
121 qreal skewY() const { return m_transform.skewY; }
122 void setSkewY(qreal skew);
123 QPointF pivot() const { return m_transform.pivot; }
124 void setPivot(const QPointF &pivot);
125 void setPivotRaw(const QPointF &pivot);
126
127 signals:
130
131 protected:
132 void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *) override;
133 void contextMenuEvent(QGraphicsSceneContextMenuEvent *event) override;
134 void mousePressEvent(QGraphicsSceneMouseEvent *event) override;
135 void hoverEnterEvent(QGraphicsSceneHoverEvent *event) override;
136 void hoverLeaveEvent(QGraphicsSceneHoverEvent *event) override;
137 bool sceneEventFilter(QGraphicsItem *watched, QEvent *event) override;
138 QVariant itemChange(GraphicsItemChange change, const QVariant &value) override;
139
140 private:
141 void replaceImage();
142 void mirror(bool horizontal);
143 void setTransparentColor();
144 void crop();
145 void restoreAspectRatio();
146 void saveImageAs();
147 void saveOriginalImageAs();
148 void saveImagePixmapAs(const QPixmap &pixmap, const QString &dialogTitle, bool hasTransparency);
149 static bool writeRasterAsSvg(const QPixmap &pixmap, const QString &path);
150 static QPixmap computeDisplayPixmap(const QPixmap &base, const QRect &cropRect, const QList<ImageTransparentColorDialog::PickedColor> &colors);
151
152 void toggleHandleMode();
154 static QString handleModeLabel(HandleMode mode);
155 void updateModeHint();
157 QString currentModeStatusHint() const;
158 void rebuildHandles();
159 void repositionHandles();
160 void clearHandles();
162 void handlerMousePressEvent(int index, Qt::KeyboardModifiers mods);
163 void handlerMouseMoveEvent(int index, QGraphicsSceneMouseEvent *event);
164 void handlerMouseReleaseEvent(int index);
165 void dragResize(int index, const QPointF &localPos, Qt::KeyboardModifiers mods);
166 void dragRotateHandle(int cornerIndex, const QPointF &scenePos, Qt::KeyboardModifiers mods);
167 void dragSkewHandle(int edgeIndex, const QPointF &scenePos, Qt::KeyboardModifiers mods);
168 void dragPivot(const QPointF &localPos);
169 QPointF scaleOnlyOffset(const QPointF &localPoint) const;
170 QPointF scaleAndShearOffset(const QPointF &localPoint) const;
171 QPointF handlePosition(int index) const;
172 static QPointF cornerPosition(int cornerIndex, qreal w, qreal h);
173 static QPointF edgeMidpointPosition(int edgeIndex, qreal w, qreal h);
174 static QColor colorForHandleRole(HandleRole role);
175 static QString hintForHandleRole(HandleRole role);
176 void showStatusHint(const QString &text) const;
177 void clearStatusHint() const;
178
179 protected:
180 QPixmap pixmap_;
181 // The true, pristine original -- never itself cropped or colour-
182 // keyed. pixmap_ (the displayed result) is always re-derived from
183 // this plus m_crop_rect and m_transparent_colors (each colour
184 // carrying its own tolerance), via computeDisplayPixmap(). Without
185 // keeping this separate, re-opening either the crop or
186 // transparency dialog after using the other would show an
187 // already-modified image as if it were the source -- areas already
188 // cropped away or coloured out would be gone for good, with no way
189 // to recover or adjust them, only start over. Updated by whatever
190 // genuinely replaces or reorients the image's actual content
191 // (construction, replaceImage(), and mirror(), which also mirrors
192 // m_crop_rect to keep referring to the same region of the
193 // now-flipped base) -- never by crop() or setTransparentColor()
194 // themselves, which only ever change which subset of this base is
195 // shown.
197 QRect m_crop_rect; // relative to m_base_pixmap; equals m_base_pixmap.rect() when nothing has been cropped
198 QList<ImageTransparentColorDialog::PickedColor> m_transparent_colors;
199
200 // Independent scaleX/scaleY here is the actual point of this whole
201 // member: QGraphicsItem::scale() is a single, uniform float, which
202 // is exactly why an image could never break its own aspect ratio
203 // before this. skewX/skewY exist in the struct but are never
204 // written by anything below -- deliberately deferred, not an
205 // oversight (see the .cpp for why).
207 bool m_pivotIsCustom = false;
209 QVector<QetGraphicsHandlerItem *> m_handler_vector;
210 QVector<HandleRole> m_handleRoles;
212 QPointF m_original_pos; // scene position at the start of a resize/rotate/pivot drag, for Escape-to-cancel
214 bool m_deferHandleReposition = false; // see setPivot()'s comment
215 bool m_resizeCenterAnchored = false; // decided once, at press time -- see handlerMousePressEvent()'s comment for why, mirroring the identical fix already made for shape creation
216};
217#endif
static QString handleModeLabel(HandleMode mode)
DiagramImageItem::handleModeLabel.
Definition diagramimageitem.cpp:439
bool m_resizeCenterAnchored
Definition diagramimageitem.h:215
void handlerMouseReleaseEvent(int index)
DiagramImageItem::handlerMouseReleaseEvent Two responsibilities, in order: first, Resize's own pivot ...
Definition diagramimageitem.cpp:796
QPointF pivot() const
Definition diagramimageitem.h:123
ShapeTransform m_transform
Definition diagramimageitem.h:206
QVector< QetGraphicsHandlerItem * > m_handler_vector
Definition diagramimageitem.h:209
void hoverEnterEvent(QGraphicsSceneHoverEvent *event) override
DiagramImageItem::hoverEnterEvent.
Definition diagramimageitem.cpp:504
qreal scaleFactorY() const
Definition diagramimageitem.h:114
void dragSkewHandle(int edgeIndex, const QPointF &scenePos, Qt::KeyboardModifiers mods)
DiagramImageItem::dragSkewHandle Verified numerically before writing this (all 4 edges,...
Definition diagramimageitem.cpp:991
virtual bool fromXml(const QDomElement &)
DiagramImageItem::fromXml Load this image from xml element e.
Definition diagramimageitem.cpp:1321
void setScaleFactorY(qreal factor)
Definition diagramimageitem.cpp:171
DiagramImageItem(QetGraphicsItem *=nullptr)
DiagramImageItem::DiagramImageItem Constructor without pixmap.
Definition diagramimageitem.cpp:49
void showStatusHint(const QString &text) const
DiagramImageItem::showStatusHint.
Definition diagramimageitem.cpp:684
QRect m_crop_rect
Definition diagramimageitem.h:197
static QString hintForHandleRole(HandleRole role)
Definition diagramimageitem.cpp:560
void setPixmap(const QPixmap &pixmap)
DiagramImageItem::setPixmap Set the new pixmap to be draw.
Definition diagramimageitem.cpp:131
ShapeTransform m_original_transform
Definition diagramimageitem.h:213
void setSkewY(qreal skew)
Definition diagramimageitem.cpp:198
bool m_pivotIsCustom
Definition diagramimageitem.h:207
void setRotationAngle(qreal angle)
Definition diagramimageitem.cpp:180
void hoverLeaveEvent(QGraphicsSceneHoverEvent *event) override
DiagramImageItem::hoverLeaveEvent.
Definition diagramimageitem.cpp:513
void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *) override
DiagramImageItem::paint Draw the pixmap.
Definition diagramimageitem.cpp:95
@ Type
Definition diagramimageitem.h:68
QVector< HandleRole > m_handleRoles
Definition diagramimageitem.h:210
void setPivot(const QPointF &pivot)
DiagramImageItem::setPivot Unlike scale/rotation, moving the pivot alone WOULD visibly shift the imag...
Definition diagramimageitem.cpp:216
void repositionHandles()
DiagramImageItem::repositionHandles Moves the existing handle items to match current geometry,...
Definition diagramimageitem.cpp:616
QPointF scaleAndShearOffset(const QPointF &localPoint) const
Definition diagramimageitem.cpp:366
void contextMenuEvent(QGraphicsSceneContextMenuEvent *event) override
DiagramImageItem::contextMenuEvent.
Definition diagramimageitem.cpp:1557
void clearHandles()
DiagramImageItem::clearHandles.
Definition diagramimageitem.cpp:522
void resetPivotToBoundingRectCenter()
DiagramImageItem::resetPivotToBoundingRectCenter Used after a resize drag ends (see handlerMouseRelea...
Definition diagramimageitem.cpp:278
static QPointF edgeMidpointPosition(int edgeIndex, qreal w, qreal h)
DiagramImageItem::edgeMidpointPosition Matches QetShapeItem::edgeMidpoint()'s own slot convention exa...
Definition diagramimageitem.cpp:339
void replaceImage()
DiagramImageItem::replaceImage Context-menu action: swaps the underlying pixmap for one loaded from a...
Definition diagramimageitem.cpp:1637
static bool writeRasterAsSvg(const QPixmap &pixmap, const QString &path)
DiagramImageItem::writeRasterAsSvg Wraps pixmap as a base64-embedded PNG inside a minimal,...
Definition diagramimageitem.cpp:1212
void handlerMouseMoveEvent(int index, QGraphicsSceneMouseEvent *event)
DiagramImageItem::handlerMouseMoveEvent.
Definition diagramimageitem.cpp:753
qreal rotationAngle
Definition diagramimageitem.h:45
QPixmap m_base_pixmap
Definition diagramimageitem.h:196
void setPivotRaw(const QPointF &pivot)
DiagramImageItem::setPivotRaw Sets m_transform.pivot directly, with NO position compensation at all –...
Definition diagramimageitem.cpp:261
QString name() const override
DiagramImageItem::name.
Definition diagramimageitem.cpp:1310
void paintForExport(QPainter *painter)
Definition diagramimageitem.h:107
void clearStatusHint() const
DiagramImageItem::clearStatusHint.
Definition diagramimageitem.cpp:695
void mousePressEvent(QGraphicsSceneMouseEvent *event) override
DiagramImageItem::mousePressEvent Clicking an already-selected image cycles its handle mode,...
Definition diagramimageitem.cpp:401
void dragResize(int index, const QPointF &localPos, Qt::KeyboardModifiers mods)
DiagramImageItem::dragResize Verified numerically (all 8 handles, a rotated and non-uniformly scaled ...
Definition diagramimageitem.cpp:891
void editProperty() override
DiagramImageItem::editProperty Open the appropriate dialog to edit this image.
Definition diagramimageitem.cpp:119
static QColor colorForHandleRole(HandleRole role)
DiagramImageItem::rebuildHandles A deliberately small switch compared to QetShapeItem's own version: ...
Definition diagramimageitem.cpp:548
QPixmap pixmap
Definition diagramimageitem.h:42
qreal skewY() const
Definition diagramimageitem.h:121
qreal rotationAngle() const
Definition diagramimageitem.h:117
static QPixmap computeDisplayPixmap(const QPixmap &base, const QRect &cropRect, const QList< ImageTransparentColorDialog::PickedColor > &colors)
DiagramImageItem::computeDisplayPixmap Re-derives what pixmap_ should be from first principles: crop ...
Definition diagramimageitem.cpp:1281
HandleMode m_handleMode
Definition diagramimageitem.h:208
static QPointF cornerPosition(int cornerIndex, qreal w, qreal h)
DiagramImageItem::cornerPosition Matches QetShapeItem::cornerPoint()'s own slot convention exactly (0...
Definition diagramimageitem.cpp:323
void rebuildHandles()
Definition diagramimageitem.cpp:572
void setSkewX(qreal skew)
Definition diagramimageitem.cpp:189
QPointF m_original_pos
Definition diagramimageitem.h:212
void mirror(bool horizontal)
DiagramImageItem::mirror Context-menu action: flips the pixmap itself, not a transform – unlike QetSh...
Definition diagramimageitem.cpp:1690
void handlerMousePressEvent(int index, Qt::KeyboardModifiers mods)
DiagramImageItem::handlerMousePressEvent For a Resize handle, temporarily repositions the pivot for t...
Definition diagramimageitem.cpp:725
QPointF pivot
Definition diagramimageitem.h:48
QPointF handlePosition(int index) const
DiagramImageItem::handlePosition Local-space position of handle at vector index index,...
Definition diagramimageitem.cpp:381
QPointF rawPivot
Definition diagramimageitem.h:58
qreal scaleFactorX() const
Definition diagramimageitem.h:113
void updateModeHint()
DiagramImageItem::updateModeHint Keeps the tooltip in sync with what the next click would do – called...
Definition diagramimageitem.cpp:454
QString currentModeStatusHint() const
DiagramImageItem::currentModeStatusHint One-line reference for whatever handles are visible right now...
Definition diagramimageitem.cpp:492
bool sceneEventFilter(QGraphicsItem *watched, QEvent *event) override
DiagramImageItem::sceneEventFilter Dispatches handle interaction events – structurally identical to Q...
Definition diagramimageitem.cpp:639
int type() const override
Definition diagramimageitem.h:90
qreal skewY
Definition diagramimageitem.h:47
HandleMode nextHandleMode() const
DiagramImageItem::nextHandleMode.
Definition diagramimageitem.cpp:431
void toggleHandleMode()
DiagramImageItem::toggleHandleMode.
Definition diagramimageitem.cpp:418
qreal scaleFactorY
Definition diagramimageitem.h:44
void crop()
DiagramImageItem::crop Context-menu action: opens ImageCropDialog against pixmap_ (the current,...
Definition diagramimageitem.cpp:1834
int m_vector_index
Definition diagramimageitem.h:211
QList< ImageTransparentColorDialog::PickedColor > m_transparent_colors
Definition diagramimageitem.h:198
void refreshInteractionHints()
DiagramImageItem::refreshInteractionHints Keeps the tooltip text current, and – if already being hove...
Definition diagramimageitem.cpp:473
HandleRole
Definition diagramimageitem.h:81
@ SkewEdge
Definition diagramimageitem.h:81
@ Pivot
Definition diagramimageitem.h:81
@ Rotate
Definition diagramimageitem.h:81
@ Resize
Definition diagramimageitem.h:81
void saveImageAs()
DiagramImageItem::saveImageAs Saves the currently displayed pixmap (crop and colour-keyed transparenc...
Definition diagramimageitem.cpp:1071
QPixmap pixmap() const
Definition diagramimageitem.h:96
void saveImagePixmapAs(const QPixmap &pixmap, const QString &dialogTitle, bool hasTransparency)
DiagramImageItem::saveImagePixmapAs Shared by saveImageAs() and saveOriginalImageAs(): prompts for a ...
Definition diagramimageitem.cpp:1102
qreal skewX() const
Definition diagramimageitem.h:119
qreal skewX
Definition diagramimageitem.h:46
virtual QDomElement toXml(QDomDocument &) const
Definition diagramimageitem.cpp:1444
void setScaleFactorX(qreal factor)
DiagramImageItem::setScaleFactorX / setScaleFactorY / setRotationAngle Matching QetShapeItem's own se...
Definition diagramimageitem.cpp:162
bool m_deferHandleReposition
Definition diagramimageitem.h:214
QPointF scaleOnlyOffset(const QPointF &localPoint) const
DiagramImageItem::scaleOnlyOffset / scaleAndShearOffset Verbatim ports of QetShapeItem's own identica...
Definition diagramimageitem.cpp:360
HandleMode
Definition diagramimageitem.h:80
@ RotateSkew
Definition diagramimageitem.h:80
@ Size
Definition diagramimageitem.h:80
void saveOriginalImageAs()
DiagramImageItem::saveOriginalImageAs Saves m_base_pixmap – the true, pristine original,...
Definition diagramimageitem.cpp:1085
void restoreAspectRatio()
DiagramImageItem::restoreAspectRatio Context-menu action, the direct answer to "restoration of aspect...
Definition diagramimageitem.cpp:1051
QRectF boundingRect() const override
DiagramImageItem::boundingRect the outer bounds of the item as a rectangle, if no pixmap are set,...
Definition diagramimageitem.cpp:1296
qreal scaleFactorX
Definition diagramimageitem.h:43
void dragRotateHandle(int cornerIndex, const QPointF &scenePos, Qt::KeyboardModifiers mods)
DiagramImageItem::dragRotateHandle Verified numerically before writing this (all 4 corners,...
Definition diagramimageitem.cpp:962
void setTransparentColor()
DiagramImageItem::setTransparentColor Context-menu action: opens ImageTransparentColorDialog against ...
Definition diagramimageitem.cpp:1758
void dragPivot(const QPointF &localPos)
DiagramImageItem::dragPivot Marks the pivot as user-customized, the same way QetShapeItem's own pivot...
Definition diagramimageitem.cpp:1030
QPixmap pixmap_
Definition diagramimageitem.h:180
void transformChanged()
QVariant itemChange(GraphicsItemChange change, const QVariant &value) override
DiagramImageItem::itemChange.
Definition diagramimageitem.cpp:1238
The QetGraphicsHandlerItem class This graphics item represents a point, destined to be used as an han...
Definition qetgraphicshandleritem.h:37
QetGraphicsItem(QGraphicsItem *parent=nullptr)
Definition qetgraphicsitem.cpp:44
The ShapeTransform struct Rotation, skew and scale applied to a shape's local geometry around an arbi...
Definition shapetransform.h:50