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_