File indexing completed on 2024-05-12 04:21:20

0001 
0002 /*
0003    Copyright (c) 2003-2007 Clarence Dang <dang@kde.org>
0004    All rights reserved.
0005 
0006    Redistribution and use in source and binary forms, with or without
0007    modification, are permitted provided that the following conditions
0008    are met:
0009 
0010    1. Redistributions of source code must retain the above copyright
0011       notice, this list of conditions and the following disclaimer.
0012    2. Redistributions in binary form must reproduce the above copyright
0013       notice, this list of conditions and the following disclaimer in the
0014       documentation and/or other materials provided with the distribution.
0015 
0016    THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
0017    IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
0018    OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
0019    IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
0020    INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
0021    NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
0022    DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
0023    THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
0024    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
0025    THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
0026 */
0027 
0028 
0029 #define DEBUG_KP_SELECTION 0
0030 
0031 
0032 #include "layers/selections/kpAbstractSelection.h"
0033 
0034 #include <QPolygon>
0035 #include <QRect>
0036 
0037 #include "kpLogCategories.h"
0038 
0039 struct kpAbstractSelectionPrivate
0040 {
0041     QRect rect;
0042 };
0043 
0044 
0045 // protected
0046 kpAbstractSelection::kpAbstractSelection ()
0047     : QObject (),
0048       d (new kpAbstractSelectionPrivate ())
0049 {
0050     d->rect = QRect ();
0051 }
0052 
0053 // protected
0054 kpAbstractSelection::kpAbstractSelection (const QRect &rect)
0055     : QObject (),
0056       d (new kpAbstractSelectionPrivate ())
0057 {
0058     d->rect = rect;
0059 }
0060 
0061 // protected
0062 kpAbstractSelection &kpAbstractSelection::operator= (const kpAbstractSelection &rhs)
0063 {
0064     if (this == &rhs) {
0065         return *this;
0066     }
0067 
0068     d->rect = rhs.d->rect;
0069 
0070     return *this;
0071 }
0072 
0073 // protected
0074 kpAbstractSelection::~kpAbstractSelection ()
0075 {
0076     delete d;
0077 }
0078 
0079 
0080 // public virtual
0081 bool kpAbstractSelection::readFromStream (QDataStream &stream)
0082 {
0083     stream >> d->rect;
0084 
0085     return true;
0086 }
0087 
0088 // public virtual
0089 void kpAbstractSelection::writeToStream (QDataStream &stream) const
0090 {
0091     stream << d->rect;
0092 }
0093 
0094 // friend
0095 QDataStream &operator<< (QDataStream &stream, const kpAbstractSelection &selection)
0096 {
0097 #if DEBUG_KP_SELECTION && 1
0098     qCDebug(kpLogLayers) << "kpAbstractSelection::operator<<(sel: rect=" <<
0099                  selection.boundingRect ();
0100 #endif
0101     stream << selection.serialID ();
0102     selection.writeToStream (stream);
0103     return stream;
0104 }
0105 
0106 
0107 // public virtual
0108 kpCommandSize::SizeType kpAbstractSelection::size () const
0109 {
0110     return 0/*constant size*/;
0111 }
0112 
0113 
0114 // public
0115 QSize kpAbstractSelection::minimumSize () const
0116 {
0117     return  {minimumWidth (), minimumHeight ()};
0118 }
0119 
0120 
0121 // public
0122 int kpAbstractSelection::x () const
0123 {
0124     return d->rect.x ();
0125 }
0126 
0127 // public
0128 int kpAbstractSelection::y () const
0129 {
0130     return d->rect.y ();
0131 }
0132 
0133 // public
0134 QPoint kpAbstractSelection::topLeft () const
0135 {
0136     return d->rect.topLeft ();
0137 }
0138 
0139 
0140 // public
0141 int kpAbstractSelection::width () const
0142 {
0143     return boundingRect ().width ();
0144 }
0145 
0146 // public
0147 int kpAbstractSelection::height () const
0148 {
0149     return boundingRect ().height ();
0150 }
0151 
0152 // public
0153 QRect kpAbstractSelection::boundingRect () const
0154 {
0155     return d->rect;
0156 }
0157 
0158 // public static
0159 QPolygon kpAbstractSelection::CalculatePointsForRectangle (const QRect &rect)
0160 {
0161     QPolygon points;
0162 
0163     // OPT: not space optimal - current code adds duplicate corner points.
0164 
0165     // top
0166     for (int x = 0; x < rect.width (); x++) {
0167         points.append (QPoint (rect.x () + x, rect.top ()));
0168     }
0169 
0170     // right
0171     for (int y = 0; y < rect.height (); y++) {
0172         points.append (QPoint (rect.right (), rect.y () + y));
0173     }
0174 
0175     // bottom
0176     for (int x = rect.width () - 1; x >= 0; x--) {
0177         points.append (QPoint (rect.x () + x, rect.bottom ()));
0178     }
0179 
0180     // left
0181     for (int y = rect.height () - 1; y >= 0; y--) {
0182         points.append (QPoint (rect.left (), rect.y () + y));
0183     }
0184 
0185     return points;
0186 }
0187 
0188 
0189 // public
0190 bool kpAbstractSelection::contains (int x, int y) const
0191 {
0192     return contains (QPoint (x, y));
0193 }
0194 
0195 
0196 // public virtual
0197 void kpAbstractSelection::moveBy (int dx, int dy)
0198 {
0199 #if DEBUG_KP_SELECTION && 1
0200     qCDebug(kpLogLayers) << "kpAbstractSelection::moveBy(" << dx << "," << dy << ")";
0201 #endif
0202 
0203     if (dx == 0 && dy == 0) {
0204         return;
0205     }
0206 
0207     QRect oldRect = boundingRect ();
0208 
0209 #if DEBUG_KP_SELECTION && 1
0210     qCDebug(kpLogLayers) << "\toldRect=" << oldRect;
0211 #endif
0212 
0213     d->rect.translate (dx, dy);
0214 #if DEBUG_KP_SELECTION && 1
0215     qCDebug(kpLogLayers) << "\tnewRect=" << d->rect;
0216 #endif
0217 
0218     Q_EMIT changed (oldRect);
0219     Q_EMIT changed (boundingRect ());
0220 }
0221 
0222 // public
0223 void kpAbstractSelection::moveTo (int dx, int dy)
0224 {
0225     moveTo (QPoint (dx, dy));
0226 }
0227 
0228 // public
0229 void kpAbstractSelection::moveTo (const QPoint &topLeftPoint)
0230 {
0231 #if DEBUG_KP_SELECTION && 1
0232     qCDebug(kpLogLayers) << "kpAbstractSelection::moveTo(" << topLeftPoint << ")";
0233 #endif
0234     QRect oldBoundingRect = boundingRect ();
0235 #if DEBUG_KP_SELECTION && 1
0236     qCDebug(kpLogLayers) << "\toldBoundingRect=" << oldBoundingRect;
0237 #endif
0238     if (topLeftPoint == oldBoundingRect.topLeft ()) {
0239         return;
0240     }
0241 
0242     QPoint delta (topLeftPoint - oldBoundingRect.topLeft ());
0243     moveBy (delta.x (), delta.y ());
0244 }
0245 
0246 //---------------------------------------------------------------------
0247 
0248 // protected
0249 void kpAbstractSelection::paintRectangularBorder (QImage *destPixmap,
0250         const QRect &docRect,
0251         bool selectionFinished) const
0252 {
0253     (void) selectionFinished;
0254 
0255 #if DEBUG_KP_SELECTION && 1
0256     qCDebug(kpLogLayers) << "kpAbstractSelection::paintRectangularBorder() boundingRect="
0257               << boundingRect ();
0258 #endif
0259 
0260 #if DEBUG_KP_SELECTION && 1
0261     qCDebug(kpLogLayers) << "\tselection border = rectangle";
0262     qCDebug(kpLogLayers) << "\t\tx=" << boundingRect ().x () - docRect.x ()
0263               << " y=" << boundingRect ().y () - docRect.y ()
0264               << " w=" << boundingRect ().width ()
0265               << " h=" << boundingRect ().height ();
0266 #endif
0267     kpPixmapFX::drawStippleRect(destPixmap,
0268         boundingRect ().x () - docRect.x (),
0269         boundingRect ().y () - docRect.y (),
0270         boundingRect ().width (),
0271         boundingRect ().height (),
0272         kpColor::Blue,
0273         kpColor::Yellow);
0274 }
0275 
0276 //---------------------------------------------------------------------
0277 
0278 // protected
0279 void kpAbstractSelection::paintPolygonalBorder (const QPolygon &points,
0280         QImage *destPixmap,
0281         const QRect &docRect,
0282         bool selectionFinished) const
0283 {
0284 #if DEBUG_KP_SELECTION && 1
0285     qCDebug(kpLogLayers) << "kpAbstractSelection::paintPolygonalBorder() boundingRect="
0286               << boundingRect ();
0287 #endif
0288 
0289     QPolygon pointsTranslated = points;
0290     pointsTranslated.translate (-docRect.x (), -docRect.y ());
0291 
0292     if ( !selectionFinished )
0293     {
0294       kpPixmapFX::drawPolyline(destPixmap,
0295         pointsTranslated, kpColor::Blue, 1/*pen width*/, kpColor::Yellow);
0296     }
0297     else
0298     {
0299       kpPixmapFX::drawPolygon(destPixmap,
0300           pointsTranslated,
0301           kpColor::Blue, 1/*pen width*/,
0302           kpColor::Invalid/*no background*/,
0303           true/*is final*/,
0304           kpColor::Yellow);
0305 
0306       kpPixmapFX::drawStippleRect(destPixmap,
0307           boundingRect ().x () - docRect.x (),
0308           boundingRect ().y () - docRect.y (),
0309           boundingRect ().width (),
0310           boundingRect ().height (),
0311           kpColor::LightGray,
0312           kpColor::DarkGray);
0313     }
0314 }
0315 
0316 #include "moc_kpAbstractSelection.cpp"