File indexing completed on 2024-05-12 15:56:47
0001 /* This file is part of the KDE project 0002 * SPDX-FileCopyrightText: 2006-2010 Thomas Zander <zander@kde.org> 0003 * 0004 * SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 0007 #ifndef KOSHAPECONTAINER_H 0008 #define KOSHAPECONTAINER_H 0009 0010 #include "KoShape.h" 0011 0012 #include <QList> 0013 0014 #include "kritaflake_export.h" 0015 0016 class QPainter; 0017 class KoShapeContainerModel; 0018 class KoShapeContainerPrivate; 0019 0020 /** 0021 * This is the base class that all Flake group-shapes are based on. 0022 * Extending from this class allows you to have child-shapes. 0023 * Like the KoShape class, this shape is a visible class with 0024 * a position and a size. It can paint itself as well if you implement 0025 * the paintComponent() method. 0026 * 0027 * <p>The most important feature of this class is that you can make 0028 * other KoShape classes to be children of this container. 0029 * 0030 * <p>The effect of grouping those shapes is that their position 0031 * is relative to the position of the container. Move the container and 0032 * all children move with it. 0033 * 0034 * <p>Each child can optionally be said to be 'clipped' by the container. 0035 * This feature will give the effect that if the child has a size and 0036 * position outside the container, parts outside the container will not be shown. 0037 * This is especially useful 0038 * for showing cutouts of content, like images, without changing the actual content. 0039 * 0040 * <p>For so called clipped children any modification made to the container is 0041 * propagated to the child. This includes rotation as well as scaling 0042 * and shearing. 0043 * 0044 * <p>Maintaining the list of children can be done using the supplied methods 0045 * addChild() and removeChild(). However, they only forward their requests to the 0046 * data model KoShapeContainerModel and if you provide a custom implementation 0047 * of that model any means can be used to maintain a list of children, as long as 0048 * you will take care to register them with the appropriate shape manager. 0049 * 0050 * <p>An example usage where a custom model might be useful is when you have a 0051 * container for text areas which are split into columns. If you resize the container 0052 * and the width of the individual columns gets too small, the model can choose to 0053 * remove a child or add one when the width allows another column. 0054 */ 0055 class KRITAFLAKE_EXPORT KoShapeContainer : public KoShape 0056 { 0057 public: 0058 0059 /** 0060 * Constructor with custom model to be used for maintaining the list of children. 0061 * For all the normal cases you don't need a custom model. Only when you want to respond 0062 * to moves of the container to do something special, or disable one of the features the 0063 * container normally has (like clipping). Use the default constructor in those cases. 0064 * @param model the custom model to be used for maintaining the list of children. 0065 */ 0066 explicit KoShapeContainer(KoShapeContainerModel *model = 0); 0067 0068 /** 0069 * Destructor for the shape container. 0070 * All children will be orphaned by calling a KoShape::setParent(0) 0071 */ 0072 ~KoShapeContainer() override; 0073 0074 /** 0075 * Add a child to this container. 0076 * 0077 * This container will NOT take over ownership of the shape. The caller or those creating 0078 * the shape is responsible to delete it if not needed any longer. 0079 * 0080 * @param shape the child to be managed in the container. 0081 */ 0082 void addShape(KoShape *shape); 0083 0084 /** 0085 * Remove a child to be completely separated from the container. 0086 * 0087 * The shape will only be removed from this container but not be deleted. 0088 * 0089 * @param shape the child to be removed. 0090 */ 0091 void removeShape(KoShape *shape); 0092 0093 /** 0094 * Return the current number of children registered. 0095 * @return the current number of children registered. 0096 */ 0097 int shapeCount() const; 0098 0099 /** 0100 * Set the argument child to have its 'clipping' property set. 0101 * 0102 * A shape that is clipped by the container will have its visible portion 0103 * limited to the area where it intersects with the container. 0104 * If a shape is positioned or sized such that it would be painted outside 0105 * of the KoShape::outline() of its parent container, setting this property 0106 * to true will clip the shape painting to the container outline. 0107 * 0108 * @param child the child for which the property will be changed. 0109 * @param clipping the property 0110 */ 0111 void setClipped(const KoShape *child, bool clipping); 0112 0113 /** 0114 * Returns if the argument child has its 'clipping' property set. 0115 * 0116 * A shape that is clipped by the container will have its visible portion 0117 * limited to the area where it intersects with the container. 0118 * If a shape is positioned or sized such that it would be painted outside 0119 * of the KoShape::outline() of its parent container, setting this property 0120 * to true will clip the shape painting to the container outline. 0121 * 0122 * @return if the argument child has its 'clipping' property set. 0123 * @param child the child for which the property will be returned. 0124 */ 0125 bool isClipped(const KoShape *child) const; 0126 0127 /** 0128 * Set the shape to inherit the container transform. 0129 * 0130 * A shape that inherits the transform of the parent container will have its 0131 * share / rotation / skew etc be calculated as being the product of both its 0132 * own local transformation and also that of its parent container. 0133 * If you set this to true and rotate the container, the shape will get that 0134 * rotation as well automatically. 0135 * 0136 * @param shape the shape for which the property will be changed. 0137 * @param inherit the new value 0138 */ 0139 void setInheritsTransform(const KoShape *shape, bool inherit); 0140 0141 /** 0142 * Returns if the shape inherits the container transform. 0143 * 0144 * A shape that inherits the transform of the parent container will have its 0145 * share / rotation / skew etc be calculated as being the product of both its 0146 * own local transformation and also that of its parent container. 0147 * If you set this to true and rotate the container, the shape will get that 0148 * rotation as well automatically. 0149 * 0150 * @return if the argument shape has its 'inherits transform' property set. 0151 * @param shape the shape for which the property will be returned. 0152 */ 0153 bool inheritsTransform(const KoShape *shape) const; 0154 0155 0156 /// reimplemented 0157 void paint(QPainter &painter) const override; 0158 0159 /** 0160 * @brief Paint the component 0161 * Implement this method to allow the shape to paint itself, just like the KoShape::paint() 0162 * method does. 0163 * 0164 * @param painter used for painting the shape 0165 * @see applyConversion() 0166 */ 0167 virtual void paintComponent(QPainter &painter) const = 0; 0168 0169 using KoShape::update; 0170 /// reimplemented 0171 void update() const override; 0172 0173 /** 0174 * Return the list of all child shapes. 0175 * @return the list of all child shapes 0176 */ 0177 QList<KoShape*> shapes() const; 0178 0179 /** 0180 * return the model for this container 0181 */ 0182 KoShapeContainerModel *model() const; 0183 0184 protected: 0185 0186 /** 0187 * set the model for this container 0188 */ 0189 void setModel(KoShapeContainerModel *model); 0190 /** 0191 * set the model, and take control of all its children 0192 */ 0193 void setModelInit(KoShapeContainerModel *model); 0194 0195 public: 0196 0197 /** 0198 * A special interface for KoShape to use during setParent call. Don't use 0199 * these method directly for managing shapes hierarchy! Use shape->setParent() 0200 * instead. 0201 */ 0202 struct ShapeInterface { 0203 ShapeInterface(KoShapeContainer *_q); 0204 0205 /** 0206 * Add a child to this container. 0207 * 0208 * This container will NOT take over ownership of the shape. The caller or those creating 0209 * the shape is responsible to delete it if not needed any longer. 0210 * 0211 * @param shape the child to be managed in the container. 0212 */ 0213 void addShape(KoShape *shape); 0214 0215 /** 0216 * Remove a child to be completely separated from the container. 0217 * 0218 * The shape will only be removed from this container but not be deleted. 0219 * 0220 * @param shape the child to be removed. 0221 */ 0222 void removeShape(KoShape *shape); 0223 0224 protected: 0225 KoShapeContainer *q; 0226 }; 0227 0228 ShapeInterface* shapeInterface(); 0229 0230 protected: 0231 KoShapeContainer(const KoShapeContainer &rhs); 0232 0233 /** 0234 * This hook is for inheriting classes that need to do something on adding/removing 0235 * of children. 0236 * This method will be called just after the child has been added/removed. 0237 * The default implementation is empty. 0238 */ 0239 virtual void shapeCountChanged() { } 0240 0241 void shapeChanged(ChangeType type, KoShape *shape = 0) override; 0242 0243 private: 0244 class Private; 0245 QScopedPointer<Private> d; 0246 }; 0247 0248 #endif