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 // Local includes
0016 
0017 #include "dimgchilditem.h"
0018 #include "graphicsdimgitem.h"
0019 #include "imagezoomsettings.h"
0020 
0021 namespace Digikam
0022 {
0023 
0024 /**
0025  * This is a simple example. Just create
0026  * new SimpleRectChildItem(item);
0027  * where item is a GrahpicsDImgItem,
0028  * and at the center of the image,
0029  * a rectangle of 1% the size of the image will be drawn.
0030  *
0031  * class SimpleRectChildItem : public DImgChildItem
0032  * {
0033  * public:
0034  *
0035  *     SimpleRectChildItem(QGraphicsItem* const parent)
0036  *         : DImgChildItem(parent)
0037  *     {
0038  *         setRelativePos(0.5, 0.5);
0039  *         setRelativeSize(0.01, 0.01);
0040  *     }
0041  *
0042  *     void paint(QPainter* painter, const QStyleOptionGraphicsItem*, QWidget*)
0043  *     {
0044  *         painter->setPen(Qt::red);
0045  *         painter->drawRect(boundingRect());
0046  *     }
0047  * };
0048  */
0049 
0050 class Q_DECL_HIDDEN DImgChildItem::Private
0051 {
0052 public:
0053 
0054     explicit Private(DImgChildItem* const q)
0055         : q(q)
0056     {
0057     }
0058 
0059     void connectParent(bool active = true);
0060 
0061 public:
0062 
0063     QPointF              relativePos;
0064     QSizeF               relativeSize;
0065 
0066     DImgChildItem* const q;
0067 };
0068 
0069 void DImgChildItem::Private::connectParent(bool active)
0070 {
0071     GraphicsDImgItem* const parent = q->parentDImgItem();
0072 
0073     if (parent)
0074     {
0075         if (active)
0076         {
0077             q->connect(parent, SIGNAL(imageSizeChanged(QSizeF)),
0078                        q, SLOT(imageSizeChanged(QSizeF)));
0079         }
0080         else
0081         {
0082             q->disconnect(parent, SIGNAL(imageSizeChanged(QSizeF)),
0083                           q, SLOT(imageSizeChanged(QSizeF)));
0084         }
0085     }
0086 }
0087 
0088 // ------------------------------------------------------------------------
0089 
0090 DImgChildItem::DImgChildItem(QGraphicsItem* const parent)
0091     : QGraphicsObject(parent),
0092       d              (new Private(this))
0093 {
0094     d->connectParent();
0095 }
0096 
0097 DImgChildItem::~DImgChildItem()
0098 {
0099     delete d;
0100 }
0101 
0102 void DImgChildItem::setRelativePos(const QPointF& relativePos)
0103 {
0104     if (d->relativePos == relativePos)
0105     {
0106         return;
0107     }
0108 
0109     d->relativePos = relativePos;
0110     updatePos();
0111 
0112     Q_EMIT positionOnImageChanged();
0113     Q_EMIT geometryOnImageChanged();
0114 }
0115 
0116 void DImgChildItem::setRelativeSize(const QSizeF& relativeSize)
0117 {
0118     if (d->relativeSize == relativeSize)
0119     {
0120         return;
0121     }
0122 
0123     d->relativeSize = relativeSize;
0124     updateSize();
0125 
0126     Q_EMIT sizeOnImageChanged();
0127     Q_EMIT geometryOnImageChanged();
0128 }
0129 
0130 void DImgChildItem::setRelativeRect(const QRectF& rect)
0131 {
0132     setRelativePos(rect.topLeft());
0133     setRelativeSize(rect.size());
0134 }
0135 
0136 QRectF DImgChildItem::relativeRect() const
0137 {
0138     return QRectF(d->relativePos, d->relativeSize);
0139 }
0140 
0141 QPointF DImgChildItem::relativePos() const
0142 {
0143     return d->relativePos;
0144 }
0145 
0146 QSizeF DImgChildItem::relativeSize() const
0147 {
0148     return d->relativeSize;
0149 }
0150 
0151 void DImgChildItem::setOriginalPos(const QPointF& posInOriginal)
0152 {
0153     if (!parentItem())
0154     {
0155         return;
0156     }
0157 
0158     QSizeF originalSize = parentDImgItem()->zoomSettings()->originalImageSize();
0159     setRelativePos(QPointF(posInOriginal.x() / originalSize.width(),
0160                            posInOriginal.y() / originalSize.height()));
0161 }
0162 
0163 void DImgChildItem::setOriginalSize(const QSizeF& sizeInOriginal)
0164 {
0165     if (!parentItem())
0166     {
0167         return;
0168     }
0169 
0170     QSizeF originalSize = parentDImgItem()->zoomSettings()->originalImageSize();
0171     setRelativeSize(QSizeF(sizeInOriginal.width()  / originalSize.width(),
0172                            sizeInOriginal.height() / originalSize.height()));
0173 }
0174 
0175 void DImgChildItem::setOriginalRect(const QRectF& rect)
0176 {
0177     setOriginalPos(rect.topLeft());
0178     setOriginalSize(rect.size());
0179 }
0180 
0181 QRect DImgChildItem::originalRect() const
0182 {
0183     return QRect(originalPos(), originalSize());
0184 }
0185 
0186 QSize DImgChildItem::originalSize() const
0187 {
0188     QSizeF originalSize = parentDImgItem()->zoomSettings()->originalImageSize();
0189 
0190     return QSizeF(d->relativeSize.width()  * originalSize.width(),
0191                   d->relativeSize.height() * originalSize.height()).toSize();
0192 }
0193 
0194 QPoint DImgChildItem::originalPos() const
0195 {
0196     QSizeF originalSize = parentDImgItem()->zoomSettings()->originalImageSize();
0197 
0198     return QPointF(d->relativePos.x() * originalSize.width(),
0199                    d->relativePos.y() * originalSize.height()).toPoint();
0200 }
0201 
0202 void DImgChildItem::setPos(const QPointF& pos)
0203 {
0204     if (!parentItem())
0205     {
0206         return;
0207     }
0208 
0209     const QSizeF imageSize = parentItem()->boundingRect().size();
0210 
0211     setRelativePos(QPointF(pos.x() / imageSize.width(),
0212                            pos.y() / imageSize.height()));
0213 }
0214 
0215 void DImgChildItem::setSize(const QSizeF& size)
0216 {
0217     if (!parentItem())
0218     {
0219         return;
0220     }
0221 
0222     const QSizeF imageSize = parentItem()->boundingRect().size();
0223 
0224     setRelativeSize(QSizeF(size.width()  / imageSize.width(),
0225                            size.height() / imageSize.height()));
0226 }
0227 
0228 void DImgChildItem::setRect(const QRectF& rect)
0229 {
0230     setPos(rect.topLeft());
0231     setSize(rect.size());
0232 }
0233 
0234 void DImgChildItem::setRectInSceneCoordinates(const QRectF& rect)
0235 {
0236     if (!parentItem())
0237     {
0238         return;
0239     }
0240 
0241     QRectF itemRect(parentItem()->mapFromScene(rect.topLeft()),
0242                     parentItem()->mapFromScene(rect.bottomRight()));
0243     setRect(itemRect);
0244 }
0245 
0246 QRectF DImgChildItem::rect() const
0247 {
0248     return QRectF(pos(), size());
0249 }
0250 
0251 QSizeF DImgChildItem::size() const
0252 {
0253     if (!parentItem())
0254     {
0255         return QSizeF();
0256     }
0257 
0258     const QSizeF imageSize = parentItem()->boundingRect().size();
0259 
0260     return QSizeF(d->relativeSize.width()  * imageSize.width(),
0261                   d->relativeSize.height() * imageSize.height());
0262 }
0263 
0264 GraphicsDImgItem* DImgChildItem::parentDImgItem() const
0265 {
0266     return dynamic_cast<GraphicsDImgItem*>(parentItem());
0267 }
0268 
0269 void DImgChildItem::updatePos()
0270 {
0271     if (!parentItem())
0272     {
0273         return;
0274     }
0275 
0276     QSizeF imageSize = parentItem()->boundingRect().size();
0277     QGraphicsObject::setPos(imageSize.width() * d->relativePos.x(), imageSize.height() * d->relativePos.y());
0278 
0279     Q_EMIT positionChanged();
0280     Q_EMIT geometryChanged();
0281 }
0282 
0283 void DImgChildItem::updateSize()
0284 {
0285     prepareGeometryChange();
0286 
0287     Q_EMIT sizeChanged();
0288     Q_EMIT geometryChanged();
0289 }
0290 
0291 void DImgChildItem::imageSizeChanged(const QSizeF&)
0292 {
0293     updateSize();
0294     updatePos();
0295 }
0296 
0297 QVariant DImgChildItem::itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant& value)
0298 {
0299     if      (change == QGraphicsItem::ItemParentChange)
0300     {
0301         d->connectParent(false);    // disconnect old parent
0302     }
0303     else if (change == QGraphicsItem::ItemParentHasChanged)
0304     {
0305         d->connectParent(true);     // connect new parent
0306     }
0307 
0308     return QGraphicsObject::itemChange(change, value);
0309 }
0310 
0311 QRectF DImgChildItem::boundingRect() const
0312 {
0313     if (!parentItem())
0314     {
0315         return QRectF();
0316     }
0317 
0318     return QRectF(QPointF(0, 0), size());
0319 }
0320 
0321 } // namespace Digikam
0322 
0323 #include "moc_dimgchilditem.cpp"