File indexing completed on 2024-05-19 04:22:59

0001 
0002 // OPT: The selection classes should use copy-on-write.
0003 
0004 /*
0005    Copyright (c) 2003-2007 Clarence Dang <dang@kde.org>
0006    All rights reserved.
0007 
0008    Redistribution and use in source and binary forms, with or without
0009    modification, are permitted provided that the following conditions
0010    are met:
0011 
0012    1. Redistributions of source code must retain the above copyright
0013       notice, this list of conditions and the following disclaimer.
0014    2. Redistributions in binary form must reproduce the above copyright
0015       notice, this list of conditions and the following disclaimer in the
0016       documentation and/or other materials provided with the distribution.
0017 
0018    THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
0019    IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
0020    OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
0021    IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
0022    INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
0023    NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
0024    DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
0025    THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
0026    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
0027    THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
0028 */
0029 
0030 
0031 #ifndef KPABSTRACTSELECTION_H
0032 #define KPABSTRACTSELECTION_H
0033 
0034 
0035 #include <QObject>
0036 
0037 #include "commands/kpCommandSize.h"
0038 #include "pixmapfx/kpPixmapFX.h"
0039 
0040 
0041 class QImage;
0042 class QPolygon;
0043 class QPoint;
0044 class QRect;
0045 class QSize;
0046 
0047 
0048 //
0049 // Abstract base class for selections.
0050 //
0051 // Selections consist of:
0052 //
0053 // 1. Bounding rectangle (provided by this base class) relative to the
0054 //    source document
0055 // 2. Border (must be on, or inside, the bounding rectangle and does not
0056 //    have to be rectangular)
0057 // 3. Optional content (e.g. image or text).
0058 //
0059 // A selection without content is a selection border.
0060 //
0061 // Any content outside the border should not be rendered i.e. the selection
0062 // is transparent in all areas outside of the border.  Pixels on, or inside,
0063 // the border are considered to be renderable content.  Parts, or all, of
0064 // this content can be transparent.
0065 //
0066 class kpAbstractSelection : public QObject
0067 {
0068 Q_OBJECT
0069 
0070 //
0071 // Initialization
0072 //
0073 
0074 protected:
0075     // (Call these in subclass constructors)
0076     kpAbstractSelection ();
0077     kpAbstractSelection (const QRect &rect);
0078 
0079     // (Call this in subclass implementations of operator=)
0080     kpAbstractSelection &operator= (const kpAbstractSelection &rhs);
0081 
0082 public:
0083     // To implement, create an instance of your type and then call your
0084     // implementation of operator=().
0085     virtual kpAbstractSelection *clone () const = 0;
0086 
0087     ~kpAbstractSelection () override;
0088 
0089 
0090 //
0091 // Marshalling
0092 //
0093 
0094 public:
0095     // Returns a unique ID for this type of selection, use for marshalling.
0096     virtual int serialID () const = 0;
0097 
0098     // This is called after your object has been created with the default
0099     // constructor.
0100     //
0101     // Reads the object marshalled in the <stream> and returns whether it
0102     // succeeded.  This is called by kpSelectionFactory so the serialID()
0103     // has already been read and removed from the <stream>.
0104     //
0105     // You must override this.  Remember to call this base implementation
0106     // before your code.
0107     virtual bool readFromStream (QDataStream &stream);
0108 
0109     // Marshalls the object into the <stream>.  This is called by
0110     // operator<<() so the serialID() has already been written into the
0111     // <stream>.
0112     //
0113     // You must override this.  Remember to call this base implementation
0114     // before your code.
0115     virtual void writeToStream (QDataStream &stream) const;
0116 
0117     // Writes the serialID() of the <selection> to the <stream> and then
0118     // calls writeToStream() to do the remaining marshalling.
0119     //
0120     // (kpSelectionFactory::FromStream() is the ">>" replacement)
0121     friend QDataStream &operator<< (QDataStream &stream,
0122         const kpAbstractSelection &selection);
0123 
0124 
0125 //
0126 // General Queries
0127 //
0128 
0129 public:
0130     // Returns e.g. i18n ("Selection") or i18n ("Text").
0131     virtual QString name () const = 0;
0132 
0133     // Returns the memory usage of the selection (like kpCommand's),
0134     // _not_ its dimensions.
0135     //
0136     // You must override this and add the size returned by this implementation.
0137     virtual kpCommandSize::SizeType size () const;
0138 
0139 public:
0140     // e.g. return false for an elliptical selection.
0141     virtual bool isRectangular () const = 0;
0142 
0143 
0144 //
0145 // Position & Dimensions
0146 //
0147 
0148 public:
0149     // Returns the minimum allowed dimensions of your selection type.
0150     // Usually this is 1x1 pixels by pixels.
0151     virtual int minimumWidth () const = 0;
0152     virtual int minimumHeight () const = 0;
0153     QSize minimumSize () const;
0154 
0155 public:
0156     // (in document coordinates)
0157     int x () const;
0158     int y () const;
0159     QPoint topLeft () const;
0160 
0161 public:
0162     // (in document coordinates)
0163 
0164     // Returns the width of the bounding rectangle.
0165     int width () const;
0166 
0167     // Returns the height of the bounding rectangle.
0168     int height () const;
0169 
0170     // Returns the bounding rectangle.
0171     QRect boundingRect () const;
0172 
0173 public:
0174     // Use this to implement calculatePoints() for rectangular selections.
0175     static QPolygon CalculatePointsForRectangle (const QRect &rect);
0176 
0177     // Returns the border.  This may be recalculated for every call so
0178     // may be slow.
0179     virtual QPolygon calculatePoints () const = 0;
0180 
0181 
0182 //
0183 // Point Testing
0184 //
0185 
0186 public:
0187     // Returns whether the given <point> is on or inside the -- possibly,
0188     // non-rectangular -- border of the selection.
0189     //
0190     // (for non-rectangular selections, may return false even if
0191     //  kpView::onSelectionResizeHandle())
0192     virtual bool contains (const QPoint &point) const = 0;
0193     bool contains (int x, int y) const;
0194 
0195 
0196 //
0197 // Content
0198 //
0199 
0200 public:
0201     // i.e. Has an image or text - not just a border.
0202     virtual bool hasContent () const = 0;
0203 
0204     // Deletes the content, changing the selection back into a border.
0205     // If the selection has no content, it does nothing.
0206     virtual void deleteContent () = 0;
0207 
0208 
0209 //
0210 // Mutation - Movement
0211 //
0212 
0213 public:
0214     // (You only need to override this if you store your own border
0215     //  coordinates)
0216     virtual void moveBy (int dx, int dy);
0217 
0218     // (These call moveBy() so if you only reimplement moveBy(), that should
0219     //  be sufficient)
0220     void moveTo (int dx, int dy);
0221     void moveTo (const QPoint &topLeftPoint);
0222 
0223 
0224 //
0225 // Rendering
0226 //
0227 
0228 public:
0229     // Renders the selection on top of <*destPixmap>.  This does not render
0230     // the border.
0231     //
0232     // <docRect> is the document rectangle that <*destPixmap> represents.
0233     //
0234     // You need to clip to boundingRect() or if you are a non-rectangular
0235     // selection, an even smaller region,
0236     //
0237     // However, there is no need to do any explicit clipping to <docRect>,
0238     // since any drawing outside the bounds of <destPixmap> is discarded.
0239     // However, you may choose to clip for whatever reason e.g. performance.
0240     virtual void paint (QImage *destPixmap, const QRect &docRect) const = 0;
0241 
0242 
0243 protected:
0244     // Use this to implement paintBorder() for rectangular selections.
0245     void paintRectangularBorder (QImage *destPixmap, const QRect &docRect,
0246         bool selectionFinished) const;
0247 
0248     // Use this to implement paintBorder() for non-rectangular selections
0249     // (this calls calculatePoints()).
0250     //
0251     // If <selectionFinished>, this also draws a bounding rectangular box.
0252     void paintPolygonalBorder (const QPolygon &points,
0253         QImage *destPixmap, const QRect &docRect,
0254         bool selectionFinished) const;
0255 
0256 public:
0257     // Renders the selection border on top of <*destPixmap>.
0258     //
0259     // <docRect> is the same as for paint().
0260     //
0261     // If <selectionFinished> is false, the user is still dragging out the
0262     // selection border so it may be drawn differently.
0263     virtual void paintBorder (QImage *destPixmap, const QRect &docRect,
0264         bool selectionFinished) const = 0;
0265 
0266 
0267 Q_SIGNALS:
0268     // Signals that a view update is required in the document region <docRect>,
0269     // due to the selection changing.
0270     void changed (const QRect &docRect);
0271 
0272 
0273 private:
0274     struct kpAbstractSelectionPrivate * const d;
0275 };
0276 
0277 
0278 #endif  // KPABSTRACTSELECTION_H