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