File indexing completed on 2025-04-27 03:58:23

0001 /* ============================================================
0002  *
0003  * This file is a part of digiKam project
0004  * https://www.digikam.org
0005  *
0006  * Date        : 2010-05-15
0007  * Description : Graphics View item for a child item on a DImg item
0008  *
0009  * SPDX-FileCopyrightText: 2010-2011 by Marcel Wiesweg <marcel dot wiesweg at gmx dot de>
0010  *
0011  * SPDX-License-Identifier: GPL-2.0-or-later
0012  *
0013  * ============================================================ */
0014 
0015 #ifndef DIGIKAM_DIMG_CHILD_ITEM_H
0016 #define DIGIKAM_DIMG_CHILD_ITEM_H
0017 
0018 // Qt includes
0019 
0020 #include <QGraphicsObject>
0021 
0022 // Local includes
0023 
0024 #include "digikam_export.h"
0025 
0026 namespace Digikam
0027 {
0028 
0029 class GraphicsDImgItem;
0030 
0031 class DIGIKAM_EXPORT DImgChildItem : public QGraphicsObject     // clazy:exclude=ctor-missing-parent-argument
0032 {
0033     Q_OBJECT
0034 
0035 public:
0036 
0037     /**
0038      * This is a base class for items that are positioned on top
0039      * of a GraphicsDImgItem, positioned in relative coordinates,
0040      * i.e. [0;1], on the image.
0041      * From the set relative size, the boundingRect() is calculated.
0042      */
0043 
0044     explicit DImgChildItem(QGraphicsItem* const parent = nullptr);
0045     ~DImgChildItem()                              override;
0046 
0047     /**
0048      * Sets the position and size of this item, relative to the DImg displayed in the parent item.
0049      * The values of relativePosition must be in the interval [0;1].
0050      */
0051     void setRelativePos(const QPointF& relativePosition);
0052     void setRelativePos(qreal x, qreal y)
0053     {
0054         setRelativePos(QPointF(x, y));
0055     }
0056 
0057     void setRelativeSize(const QSizeF& relativeSize);
0058     void setRelativeSize(qreal width, qreal height)
0059     {
0060         setRelativeSize(QSizeF(width, height));
0061     }
0062 
0063     void setRelativeRect(const QRectF& rect);
0064     void setRelativeRect(qreal x, qreal y, qreal width, qreal height)
0065     {
0066         setRelativeRect(QRectF(x, y, width, height));
0067     }
0068 
0069     /**
0070      * Returns the position and size relative to the DImg displayed in the parent item.
0071      * All four values are in the interval [0;1].
0072      */
0073     QRectF  relativeRect()                  const;
0074     QPointF relativePos()                   const;
0075     QSizeF  relativeSize()                  const;
0076 
0077     /**
0078      * Sets the position and size of this item, in coordinates of the original image.
0079      * Requires a valid parent item.
0080      */
0081 
0082     void setOriginalPos(const QPointF& posInOriginal);
0083     void setOriginalPos(qreal x, qreal y)
0084     {
0085         setOriginalPos(QPointF(x, y));
0086     }
0087 
0088     void setOriginalSize(const QSizeF& sizeInOriginal);
0089     void setOriginalSize(qreal width, qreal height)
0090     {
0091         setOriginalSize(QSizeF(width, height));
0092     }
0093 
0094     void setOriginalRect(const QRectF& rect);
0095     void setOriginalRect(qreal x, qreal y, qreal width, qreal height)
0096     {
0097         setOriginalRect(QRectF(x, y,width, height));
0098     }
0099 
0100     /**
0101      * Returns the position and size in coordinates of the original image.
0102      * Note that the return value is integer based. At high zoom rates,
0103      * different values of relativeRect() or zoomedRect() may result in the same originalRect(),
0104      * when one pixel in the original is represented by more than one pixel on screen.
0105      */
0106     QRect  originalRect()                   const;
0107     QPoint originalPos()                    const;
0108     QSize  originalSize()                   const;
0109 
0110     /**
0111      * Sets the position and size of this item, in coordinates of the parent DImg item.
0112      * This is accepting unscaled parent coordinates, just like the "normal" setPos() does.
0113      * Requires a valid parent item.
0114      */
0115     void setPos(const QPointF& zoomedPos);
0116     void setPos(qreal x, qreal y)
0117     {
0118         setPos(QPointF(x, y));
0119     }
0120 
0121     void setSize(const QSizeF& zoomedSize);
0122     void setSize(qreal width, qreal height)
0123     {
0124         setSize(QSizeF(width, height));
0125     }
0126 
0127     void setRect(const QRectF& rect);
0128     void setRect(qreal x, qreal y, qreal width, qreal height)
0129     {
0130         setPos(QPointF(x,y));
0131         setSize(QSizeF(width, height));
0132     }
0133 
0134     /**
0135      * Equivalent to mapping the scene coordinates to the parent item, and calling setRect().
0136      */
0137     void setRectInSceneCoordinates(const QRectF& rect);
0138 
0139     /**
0140      * Returns position and size of this item, in coordinates of the parent DImg with the current zoom.
0141      * This is the same result as QRectF(pos(), boundingRect()), boundingRect is virtual and may be
0142      * overridden by base classes.
0143      */
0144     QRectF rect()                           const;
0145     QSizeF size()                           const;
0146 
0147     // Override
0148     void moveBy(qreal dx, qreal dy)
0149     {
0150         setPos(pos().x() + dx, pos().y() + dy);
0151     }
0152 
0153     /**
0154      * If the parent item is a GraphicsDImgItem, return it,
0155      * if the parent item is null or of a different class, returns 0.
0156      */
0157     GraphicsDImgItem* parentDImgItem()      const;
0158 
0159     /**
0160      * Reimplemented. Returns a rectangle starting at (0,0) (pos() in parent coordinates)
0161      * and has a size determined by the relative size.
0162      */
0163     QRectF boundingRect()                   const override;
0164 
0165 protected Q_SLOTS:
0166 
0167     void imageSizeChanged(const QSizeF&);
0168 
0169 Q_SIGNALS:
0170 
0171     /**
0172      * These signals are emitted when the geometry, relative to the original image,
0173      * of this item has changed. This happens by calling any of the methods above.
0174      */
0175     void positionOnImageChanged();
0176     void sizeOnImageChanged();
0177     void geometryOnImageChanged();
0178 
0179     /**
0180      * These signals are emitted in any case when the geometry changed:
0181      * Either after changing the geometry relative to the original image,
0182      * or when the size of the parent GraphicsDImgItem changed (zooming).
0183      * positionChanged() is equivalent to listening to xChanged() and yChanged().
0184      */
0185     void positionChanged();
0186     void sizeChanged();
0187     void geometryChanged();
0188 
0189 protected:
0190 
0191     QVariant itemChange(GraphicsItemChange change,
0192                         const QVariant& value)    override;
0193 
0194 private:
0195 
0196     void updatePos();
0197     void updateSize();
0198 
0199 private:
0200 
0201     class Private;
0202     Private* const d;
0203 };
0204 
0205 } // namespace Digikam
0206 
0207 #endif // DIGIKAM_DIMG_CHILD_ITEM_H