File indexing completed on 2024-05-19 04:26:33

0001 /*
0002  *  SPDX-FileCopyrightText: 2004 Boudewijn Rempt <boud@valdyas.org>
0003  *
0004  *  SPDX-License-Identifier: GPL-2.0-or-later
0005  */
0006 #ifndef KIS_SELECTION_H_
0007 #define KIS_SELECTION_H_
0008 
0009 #include <QRect>
0010 
0011 #include "kis_types.h"
0012 #include "kritaimage_export.h"
0013 
0014 #include "KisSelectionTags.h"
0015 
0016 #include "kis_pixel_selection.h"
0017 
0018 
0019 class KisSelectionComponent;
0020 class QPainterPath;
0021 
0022 /**
0023  * KisSelection is a composite object. It may contain an instance
0024  * of KisPixelSelection and a KisShapeSelection object. Both these
0025  * selections are merged into a projection of the KisSelection.
0026  *
0027  * Every pixel in the paint device can indicate a degree of selectedness, varying
0028  * between MIN_SELECTED and MAX_SELECTED.
0029  *
0030  * The projection() paint device itself is only a projection: you can
0031  * read from it, but not write to it. You need to keep track of
0032  * the need for updating the projection yourself: there is no
0033  * automatic updating after changing the contents of one or more
0034  * of the selection components.
0035  */
0036 class KRITAIMAGE_EXPORT KisSelection : public KisShared
0037 {
0038 private:
0039     struct ChangeShapeSelectionCommand;
0040 
0041 public:
0042 
0043     /**
0044      * Create a new KisSelection.
0045      */
0046     KisSelection();
0047 
0048     /**
0049      * Create a new KisSelection.
0050      *
0051      * @param defaultBounds defines the bounds of the selection when
0052      * Select All is initiated.
0053      * @param resolutionProxy defines resolution with which vector
0054      * selections are rendered
0055      */
0056     KisSelection(KisDefaultBoundsBaseSP defaultBounds, KisImageResolutionProxySP resolutionProxy);
0057 
0058     /**
0059      * Copy the selection. The selection components are copied, too.
0060      */
0061     KisSelection(const KisSelection& rhs);
0062     KisSelection& operator=(const KisSelection &rhs);
0063 
0064     /**
0065      * Delete the selection. The shape selection component is deleted, the
0066      * pixel selection component is contained in a shared pointer, so that
0067      * may still be valid.
0068      */
0069     virtual ~KisSelection();
0070 
0071     /**
0072      * Create a new selection using the content of copySource as the mask.
0073      */
0074     KisSelection(const KisPaintDeviceSP copySource, KritaUtils::DeviceCopyMode copyMode, KisDefaultBoundsBaseSP defaultBounds, KisImageResolutionProxySP resolutionProxy);
0075 
0076     /**
0077      * The paint device of the pixel selection should report
0078      * about it's setDirty events to its parent. The creator
0079      * should set the parent manually if it wants to get the
0080      * signals
0081      */
0082     void setParentNode(KisNodeWSP node);
0083 
0084     bool hasNonEmptyPixelSelection() const;
0085     bool hasNonEmptyShapeSelection() const;
0086     bool hasShapeSelection() const;
0087 
0088     bool outlineCacheValid() const;
0089     QPainterPath outlineCache() const;
0090     void recalculateOutlineCache();
0091 
0092 
0093     /**
0094      * Tells whether the cached thumbnail of the selection is still valid
0095      */
0096     bool thumbnailImageValid() const;
0097 
0098     /**
0099      * Recalculates the thumbnail of the selection
0100      */
0101     void recalculateThumbnailImage(const QColor &maskColor);
0102 
0103     /**
0104      * Returns the thumbnail of the selection.
0105      */
0106     QImage thumbnailImage() const;
0107 
0108     /**
0109      * Returns the transformation which should be applied to the thumbnail before
0110      * being painted over the image
0111      */
0112     QTransform thumbnailImageTransform() const;
0113 
0114 
0115     /**
0116      * return the pixel selection component of this selection. Pixel
0117      * selection component is always present in the selection. In case
0118      * the user wants a vector selection, pixel selection will store
0119      * the pixelated version of it.
0120      *
0121      * NOTE: use pixelSelection() for changing the selection only. For
0122      * reading the selection and passing the data to bitBlt function use
0123      * projection(). Although projection() and pixelSelection() currently
0124      * point ot the same paint device, this behavior may change in the
0125      * future.
0126      */
0127     KisPixelSelectionSP pixelSelection() const;
0128 
0129     /**
0130      * return the vector selection component of this selection or zero
0131      * if hasShapeSelection() returns false.
0132      */
0133     KisSelectionComponent* shapeSelection() const;
0134 
0135     /**
0136      * @brief converts shape selection into the vector state
0137      *
0138      * The selection must not have any shape selection active. It should
0139      * be checked by calling hasShapeSelection() in advance.
0140      *
0141      * @param shapeSelection new shape selection object that should be
0142      *                       attached to the selection
0143      * @return undo command that executes and undos the conversion
0144      */
0145     KUndo2Command* convertToVectorSelection(KisSelectionComponent* shapeSelection);
0146 
0147     /**
0148      * @see convertToVectorSelection()
0149      */
0150     void convertToVectorSelectionNoUndo(KisSelectionComponent* shapeSelection);
0151 
0152     /**
0153      * Returns the projection of the selection. It may be the same
0154      * as pixel selection. You must read selection data from this
0155      * paint device only
0156      */
0157     KisPixelSelectionSP projection() const;
0158 
0159     /**
0160      * Updates the projection of the selection. You should call this
0161      * method after the every change of the selection components.
0162      * There is no automatic updates framework present
0163      */
0164     void updateProjection(const QRect& rect);
0165     void updateProjection();
0166 
0167     void setVisible(bool visible);
0168     bool isVisible();
0169 
0170     /**
0171      * Convenience functions. Just call the corresponding methods
0172      * of the underlying projection
0173      */
0174     bool isTotallyUnselected(const QRect & r) const;
0175 
0176     QRect selectedRect() const;
0177 
0178     /**
0179      * @brief Slow, but exact way of determining the rectangle
0180      * that encloses the selection.
0181      *
0182      * Default pixel of the selection device may vary and you would get wrong bounds.
0183      * selectedExactRect() handles all these cases.
0184      *
0185      */
0186     QRect selectedExactRect() const;
0187 
0188     void setX(qint32 x);
0189     void setY(qint32 y);
0190 
0191     qint32 x() const;
0192     qint32 y() const;
0193 
0194     void setDefaultBounds(KisDefaultBoundsBaseSP bounds);
0195     void setResolutionProxy(KisImageResolutionProxySP proxy);
0196     KisImageResolutionProxySP resolutionProxy() const;
0197 
0198     void clear();
0199 
0200     /**
0201      * @brief flatten creates a new pixel selection component from the shape selection
0202      * and throws away the shape selection. This has no effect if there is no
0203      * shape selection.
0204      */
0205     KUndo2Command* flatten();
0206 
0207     void notifySelectionChanged();
0208 
0209     /**
0210      * Request rerendering of the shape selection component in a
0211      * compressed way. Usually, you don't need to call it manually,
0212      * because all the work is done by KisShapeSelectionModel.
0213      */
0214     void requestCompressedProjectionUpdate(const QRect &rc);
0215 
0216     /// XXX: This method was marked KDE_DEPRECATED but without information on what to
0217     /// replace it with. Undeprecate, therefore.
0218     quint8 selected(qint32 x, qint32 y) const;
0219 
0220     KisNodeWSP parentNode() const;
0221 
0222 private:
0223     friend class KisSelectionTest;
0224     friend class KisMaskTest;
0225     friend class KisAdjustmentLayerTest;
0226     friend class KisUpdateSelectionJob;
0227     friend class KisSelectionUpdateCompressor;
0228     friend class KisDeselectActiveSelectionCommand;
0229 
0230     void copyFrom(const KisSelection &rhs);
0231 
0232 private:
0233 
0234     struct Private;
0235     Private * const m_d;
0236 };
0237 
0238 #endif // KIS_SELECTION_H_