1 /* This file is part of the KDE project 2 * Copyright (C) 2006-2010 Thomas Zander <zander@kde.org> 3 * 4 * This library is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU Library General Public 6 * License as published by the Free Software Foundation; either 7 * version 2 of the License, or (at your option) any later version. 8 * 9 * This library is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 * Library General Public License for more details. 13 * 14 * You should have received a copy of the GNU Library General Public License 15 * along with this library; see the file COPYING.LIB. If not, write to 16 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 * Boston, MA 02110-1301, USA. 18 */ 19 20 #ifndef KOSHAPECONTAINER_H 21 #define KOSHAPECONTAINER_H 22 23 #include "KoShape.h" 24 25 #include <QList> 26 27 #include "kritaflake_export.h" 28 29 class QPainter; 30 class KoShapeContainerModel; 31 class KoShapeContainerPrivate; 32 33 /** 34 * This is the base class that all Flake group-shapes are based on. 35 * Extending from this class allows you to have child-shapes. 36 * Like the KoShape class, this shape is a visible class with 37 * a position and a size. It can paint itself as well if you implement 38 * the paintComponent() method. 39 * 40 * <p>The most important feature of this class is that you can make 41 * other KoShape classes to be children of this container. 42 * 43 * <p>The effect of grouping those shapes is that their position 44 * is relative to the position of the container. Move the container and 45 * all children move with it. 46 * 47 * <p>Each child can optionally be said to be 'clipped' by the container. 48 * This feature will give the effect that if the child has a size and 49 * position outside the container, parts outside the container will not be shown. 50 * This is especially useful 51 * for showing cutouts of content, like images, without changing the actual content. 52 * 53 * <p>For so called clipped children any modification made to the container is 54 * propagated to the child. This includes rotation as well as scaling 55 * and shearing. 56 * 57 * <p>Maintaining the list of children can be done using the supplied methods 58 * addChild() and removeChild(). However, they only forward their requests to the 59 * data model KoShapeContainerModel and if you provide a custom implementation 60 * of that model any means can be used to maintain a list of children, as long as 61 * you will take care to register them with the appropriate shape manager. 62 * 63 * <p>An example usage where a custom model might be useful is when you have a 64 * container for text areas which are split into columns. If you resize the container 65 * and the width of the individual columns gets too small, the model can choose to 66 * remove a child or add one when the width allows another column. 67 */ 68 class KRITAFLAKE_EXPORT KoShapeContainer : public KoShape 69 { 70 public: 71 72 /** 73 * Constructor with custom model to be used for maintaining the list of children. 74 * For all the normal cases you don't need a custom model. Only when you want to respond 75 * to moves of the container to do something special, or disable one of the features the 76 * container normally has (like clipping). Use the default constructor in those cases. 77 * @param model the custom model to be used for maintaining the list of children. 78 */ 79 explicit KoShapeContainer(KoShapeContainerModel *model = 0); 80 81 /** 82 * Destructor for the shape container. 83 * All children will be orphaned by calling a KoShape::setParent(0) 84 */ 85 ~KoShapeContainer() override; 86 87 /** 88 * Add a child to this container. 89 * 90 * This container will NOT take over ownership of the shape. The caller or those creating 91 * the shape is responsible to delete it if not needed any longer. 92 * 93 * @param shape the child to be managed in the container. 94 */ 95 void addShape(KoShape *shape); 96 97 /** 98 * Remove a child to be completely separated from the container. 99 * 100 * The shape will only be removed from this container but not be deleted. 101 * 102 * @param shape the child to be removed. 103 */ 104 void removeShape(KoShape *shape); 105 106 /** 107 * Return the current number of children registered. 108 * @return the current number of children registered. 109 */ 110 int shapeCount() const; 111 112 /** 113 * Set the argument child to have its 'clipping' property set. 114 * 115 * A shape that is clipped by the container will have its visible portion 116 * limited to the area where it intersects with the container. 117 * If a shape is positioned or sized such that it would be painted outside 118 * of the KoShape::outline() of its parent container, setting this property 119 * to true will clip the shape painting to the container outline. 120 * 121 * @param child the child for which the property will be changed. 122 * @param clipping the property 123 */ 124 void setClipped(const KoShape *child, bool clipping); 125 126 /** 127 * Returns if the argument child has its 'clipping' property set. 128 * 129 * A shape that is clipped by the container will have its visible portion 130 * limited to the area where it intersects with the container. 131 * If a shape is positioned or sized such that it would be painted outside 132 * of the KoShape::outline() of its parent container, setting this property 133 * to true will clip the shape painting to the container outline. 134 * 135 * @return if the argument child has its 'clipping' property set. 136 * @param child the child for which the property will be returned. 137 */ 138 bool isClipped(const KoShape *child) const; 139 140 /** 141 * Set the shape to inherit the container transform. 142 * 143 * A shape that inherits the transform of the parent container will have its 144 * share / rotation / skew etc be calculated as being the product of both its 145 * own local transformation and also that of its parent container. 146 * If you set this to true and rotate the container, the shape will get that 147 * rotation as well automatically. 148 * 149 * @param shape the shape for which the property will be changed. 150 * @param inherit the new value 151 */ 152 void setInheritsTransform(const KoShape *shape, bool inherit); 153 154 /** 155 * Returns if the shape inherits the container transform. 156 * 157 * A shape that inherits the transform of the parent container will have its 158 * share / rotation / skew etc be calculated as being the product of both its 159 * own local transformation and also that of its parent container. 160 * If you set this to true and rotate the container, the shape will get that 161 * rotation as well automatically. 162 * 163 * @return if the argument shape has its 'inherits transform' property set. 164 * @param shape the shape for which the property will be returned. 165 */ 166 bool inheritsTransform(const KoShape *shape) const; 167 168 169 /// reimplemented 170 void paint(QPainter &painter, KoShapePaintingContext &paintcontext) const override; 171 172 /** 173 * @brief Paint the component 174 * Implement this method to allow the shape to paint itself, just like the KoShape::paint() 175 * method does. 176 * 177 * @param painter used for painting the shape 178 * @param paintcontext the painting context 179 * @see applyConversion() 180 */ 181 virtual void paintComponent(QPainter &painter, KoShapePaintingContext &paintcontext) const = 0; 182 183 using KoShape::update; 184 /// reimplemented 185 void update() const override; 186 187 /** 188 * Return the list of all child shapes. 189 * @return the list of all child shapes 190 */ 191 QList<KoShape*> shapes() const; 192 193 /** 194 * return the model for this container 195 */ 196 KoShapeContainerModel *model() const; 197 198 protected: 199 200 /** 201 * set the model for this container 202 */ 203 void setModel(KoShapeContainerModel *model); 204 /** 205 * set the model, and take control of all its children 206 */ 207 void setModelInit(KoShapeContainerModel *model); 208 209 public: 210 211 /** 212 * A special interface for KoShape to use during setParent call. Don't use 213 * these method directly for managing shapes hierarchy! Use shape->setParent() 214 * instead. 215 */ 216 struct ShapeInterface { 217 ShapeInterface(KoShapeContainer *_q); 218 219 /** 220 * Add a child to this container. 221 * 222 * This container will NOT take over ownership of the shape. The caller or those creating 223 * the shape is responsible to delete it if not needed any longer. 224 * 225 * @param shape the child to be managed in the container. 226 */ 227 void addShape(KoShape *shape); 228 229 /** 230 * Remove a child to be completely separated from the container. 231 * 232 * The shape will only be removed from this container but not be deleted. 233 * 234 * @param shape the child to be removed. 235 */ 236 void removeShape(KoShape *shape); 237 238 protected: 239 KoShapeContainer *q; 240 }; 241 242 ShapeInterface* shapeInterface(); 243 244 protected: 245 KoShapeContainer(const KoShapeContainer &rhs); 246 247 /** 248 * This hook is for inheriting classes that need to do something on adding/removing 249 * of children. 250 * This method will be called just after the child has been added/removed. 251 * The default implementation is empty. 252 */ shapeCountChanged()253 virtual void shapeCountChanged() { } 254 255 void shapeChanged(ChangeType type, KoShape *shape = 0) override; 256 257 private: 258 class Private; 259 QScopedPointer<Private> d; 260 }; 261 262 #endif 263