File indexing completed on 2025-01-05 03:58:06
0001 /* ============================================================ 0002 * 0003 * This file is a part of digiKam project 0004 * https://www.digikam.org 0005 * 0006 * Date : 2010-07-23 0007 * Description : face marquer widget for FacesEngine Demo 0008 * 0009 * SPDX-FileCopyrightText: 2009-2024 by Gilles Caulier <caulier dot gilles at gmail dot com> 0010 * SPDX-FileCopyrightText: 2010 by Adrien Bustany <madcat at mymadcat dot com> 0011 * SPDX-FileCopyrightText: 2010 by Aditya Bhatt <adityabhatt1991 at gmail dot com> 0012 * 0013 * SPDX-License-Identifier: GPL-2.0-or-later 0014 * 0015 * ============================================================ */ 0016 0017 #include "demomarquee.h" 0018 0019 // Qt includes 0020 0021 #include <QPointF> 0022 #include <QPen> 0023 #include <QString> 0024 #include <QGraphicsSimpleTextItem> 0025 #include <QGraphicsScene> 0026 #include <QTimer> 0027 0028 // Local includes 0029 0030 #include "digikam_debug.h" 0031 #include "demofancyrect.h" 0032 0033 namespace FaceEngineDemo 0034 { 0035 0036 class Q_DECL_HIDDEN Marquee::Private 0037 { 0038 public: 0039 0040 enum ResizeType 0041 { 0042 TopLeft = 0, 0043 TopRight, 0044 BottomLeft, 0045 BottomRight 0046 }; 0047 0048 public: 0049 0050 explicit Private() 0051 : handleSize (10), 0052 htl (nullptr), 0053 htr (nullptr), 0054 hbr (nullptr), 0055 hbl (nullptr), 0056 rect (nullptr), 0057 label (nullptr), 0058 moving (false), 0059 resizing (false), 0060 resizeType (0) 0061 { 0062 } 0063 0064 public: 0065 0066 const int handleSize; 0067 QPen rectPen; ///< The pen used to draw the frames 0068 QPen outlinePen; ///< Text outline pen 0069 0070 /// Handles 0071 FancyRect* htl; 0072 FancyRect* htr; 0073 FancyRect* hbr; 0074 FancyRect* hbl; 0075 0076 FancyRect* rect; ///< Main frame 0077 QGraphicsSimpleTextItem* label; 0078 0079 bool moving; ///< Tells if we are moving the marquee 0080 QPointF moveOffset; ///< where the mouse was when the user began to drag the marquee 0081 bool resizing; ///< Tells if we are resizing the marquee 0082 int resizeType; ///< See ResizeType values. 0083 }; 0084 0085 Marquee::Marquee(FancyRect* const rect, QGraphicsItem* const parent) 0086 : QObject (nullptr), 0087 QGraphicsItemGroup(parent), 0088 d (new Private) 0089 { 0090 d->rect = rect; 0091 d->rectPen.setColor(Qt::red); 0092 d->rectPen.setWidth(2); 0093 d->outlinePen.setColor(Qt::red); 0094 addToGroup(d->rect); 0095 d->rect->setPen(d->rectPen); 0096 setPos(d->rect->scenePos()); 0097 d->rect->setPos(0, 0); 0098 createHandles(); 0099 0100 d->label = new QGraphicsSimpleTextItem(QString::fromLatin1(""), this); 0101 d->label->setBrush(QBrush(d->rectPen.color())); 0102 d->label->setPen(d->outlinePen); 0103 d->label->setZValue(2); 0104 0105 QFont font = d->label->font(); 0106 font.setBold(true); 0107 font.setPointSize(12); 0108 d->label->setFont(font); 0109 setFlag(QGraphicsItem::ItemIsSelectable); 0110 setSelected(true); 0111 0112 QTimer::singleShot(1000, this, SIGNAL(selected(this))); 0113 } 0114 0115 Marquee::~Marquee() 0116 { 0117 delete d; 0118 } 0119 0120 QRectF Marquee::boundingRect() const 0121 { 0122 return d->rect->rect(); 0123 } 0124 0125 QRectF Marquee::toRectF() const 0126 { 0127 return QRectF(x(), y(), d->rect->rect().width(), d->rect->rect().height()); 0128 } 0129 0130 void Marquee::createHandles() 0131 { 0132 d->htl = new FancyRect(0, 0, d->handleSize, d->handleSize); 0133 d->htl->setZValue(1); 0134 d->htr = new FancyRect(0, 0, d->handleSize, d->handleSize); 0135 d->htr->setZValue(1); 0136 d->hbl = new FancyRect(0, 0, d->handleSize, d->handleSize); 0137 d->hbl->setZValue(1); 0138 d->hbr = new FancyRect(0, 0, d->handleSize, d->handleSize); 0139 d->hbr->setZValue(1); 0140 0141 d->htl->setPen(d->rectPen); 0142 d->htr->setPen(d->rectPen); 0143 d->hbl->setPen(d->rectPen); 0144 d->hbr->setPen(d->rectPen); 0145 0146 addToGroup(d->htl); 0147 addToGroup(d->htr); 0148 addToGroup(d->hbl); 0149 addToGroup(d->hbr); 0150 placeHandles(); 0151 } 0152 0153 void Marquee::placeHandles() 0154 { 0155 qreal rw = d->rect->rect().width(); 0156 qreal rh = d->rect->rect().height(); 0157 qreal ox = d->rect->rect().x(); 0158 qreal oy = d->rect->rect().y(); 0159 qreal hs = d->hbr->boundingRect().width(); 0160 0161 d->htl->setPos(ox, oy); 0162 d->htr->setPos(ox+rw-hs+2, oy); 0163 d->hbl->setPos(ox, oy+rh-hs+2); 0164 d->hbr->setPos(ox+rw-hs+2, oy+rh-hs+2); 0165 } 0166 0167 void Marquee::mousePressEvent(QGraphicsSceneMouseEvent* e) 0168 { 0169 Q_EMIT selected(this); 0170 0171 // Check for some resize handles under the mouse 0172 0173 if (d->htl->isUnderMouse()) 0174 { 0175 d->resizing = true; 0176 d->resizeType = Private::TopLeft; 0177 return; 0178 } 0179 0180 if (d->htr->isUnderMouse()) 0181 { 0182 d->resizing = true; 0183 d->resizeType = Private::TopRight; 0184 return; 0185 } 0186 0187 if (d->hbl->isUnderMouse()) 0188 { 0189 d->resizing = true; 0190 d->resizeType = Private::BottomLeft; 0191 return; 0192 } 0193 0194 if (d->hbr->isUnderMouse()) 0195 { 0196 d->resizing = true; 0197 d->resizeType = Private::BottomRight; 0198 return; 0199 } 0200 0201 // If no handle is under the mouse, then we move the frame 0202 0203 d->resizing = false; 0204 d->moving = true; 0205 d->moveOffset = e->pos(); 0206 0207 Q_EMIT changed(); 0208 } 0209 0210 void Marquee::mouseMoveEvent(QGraphicsSceneMouseEvent* e) 0211 { 0212 if (d->resizing) 0213 { 0214 QRectF r = d->rect->rect(); 0215 0216 switch (d->resizeType) 0217 { 0218 case Private::TopLeft: 0219 { 0220 r.setTopLeft(e->pos()); 0221 break; 0222 } 0223 0224 case Private::TopRight: 0225 { 0226 r.setTopRight(e->pos()); 0227 break; 0228 } 0229 0230 case Private::BottomLeft: 0231 { 0232 r.setBottomLeft(e->pos()); 0233 break; 0234 } 0235 0236 case Private::BottomRight: 0237 { 0238 r.setBottomRight(e->pos()); 0239 break; 0240 } 0241 0242 default: 0243 { 0244 break; 0245 } 0246 } 0247 0248 if ((r.width() < 2*d->handleSize) || (r.height() < 2*d->handleSize)) 0249 { 0250 return; 0251 } 0252 0253 setPos(pos() + r.topLeft()); 0254 r.moveTopLeft(QPointF(0, 0)); 0255 d->rect->setRect(r); 0256 placeHandles(); 0257 } 0258 0259 if (d->moving) 0260 { 0261 setPos(e->scenePos() - d->moveOffset); 0262 } 0263 0264 Q_EMIT changed(); 0265 } 0266 0267 void Marquee::mouseReleaseEvent(QGraphicsSceneMouseEvent* e) 0268 { 0269 Q_UNUSED(e); 0270 d->resizing = false; 0271 d->moving = false; 0272 0273 Q_EMIT changed(); 0274 } 0275 0276 } // namespace FaceEngineDemo 0277 0278 #include "moc_demomarquee.cpp"