moved kdeaccessibility kdeaddons kdeadmin kdeartwork kdebindings kdeedu kdegames...
[kdeedu.git] / kig / objects / object_calcer.h
blob9e1447deaa1007e2a668c42f3c250ce72f3b8f05
1 // Copyright (C) 2003 Dominique Devriese <devriese@kde.org>
3 // This program is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU General Public License
5 // as published by the Free Software Foundation; either version 2
6 // of the License, or (at your option) any later version.
8 // This program is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 // GNU General Public License for more details.
13 // You should have received a copy of the GNU General Public License
14 // along with this program; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
16 // 02111-1307, USA.
18 #ifndef KIG_OBJECTS_OBJECT_CALCER_H
19 #define KIG_OBJECTS_OBJECT_CALCER_H
21 #include "common.h"
22 #include "../misc/boost_intrusive_pointer.hpp"
24 class ObjectCalcer;
26 void intrusive_ptr_add_ref( ObjectCalcer* p );
27 void intrusive_ptr_release( ObjectCalcer* p );
29 /**
30 * An ObjectCalcer is an object that represents an algorithm for
31 * calculating an ObjectImp from other ObjectImp's. It is also a node
32 * in the dependency graph of a certain document. E.g. a LineImp can
33 * be calculated from the two PointImp's it has to go through; every
34 * time either of them moves, this calculation is redone. In this
35 * case, there would be an ObjectCalcer that keeps a reference to its
36 * two parents ( the ObjectCalcer's representing the points ), and
37 * that will calculate its ObjectImp value every time it is asked to
38 * do so ( i.e. every time one of its parents moves.. ).
40 * Each ObjectHolder keeps its ObjectImp itself, and recalculates it
41 * from its parents in its calc() method ( if necessary ).
43 * Because of the complex relations that ObjectCalcer's hold to other
44 * ObjectCalcer's and to other classes, they have been made
45 * reference-counted. This means that they keep a count internally of
46 * how much times a pointer to them is held. If this count reaches 0,
47 * this means that nobody needs them anymore, and they delete
48 * themselves. E.g. an ObjectCalcer always keeps a reference to its
49 * parents, to ensure that those aren't deleted before it is deleted.
51 * At runtime, there will be an entire graph of ObjectCalcer that
52 * depend on their parents.. At the bottom, there are Calcer's that
53 * the user is aware of, and that are held by ObjectHolder's. At the
54 * top, there are Calcer's without parents that serve only to hold
55 * some data. Those are most likely ObjectConstCalcer's. There are
56 * some algorithms to work with the dependency graph in various ways
57 * in ../misc/calcpath.h
59 * ObjectCalcer's also decide how an object should be allowed to
60 * move. If the user selects a point, and tries to move it, then its
61 * ObjectCalcer will be asked whether it can move, and if so, will be
62 * asked to move. See below with the canMove(), move() and
63 * moveReferencePoint() methods..
65 class ObjectCalcer
67 protected:
68 /**
69 * ObjectCalcer's are reference counted.. They all take a reference
70 * to their parents, and some other classes like ObjectHolder take a
71 * reference to some ObjectCalcer's that they don't want to see
72 * deleted..
74 friend void intrusive_ptr_add_ref( ObjectCalcer* p );
75 friend void intrusive_ptr_release( ObjectCalcer* p );
76 int refcount;
77 void ref();
78 void deref();
80 // we keep track of our children, so algorithms can easily walk over
81 // the dependency graph..
83 std::vector<ObjectCalcer*> mchildren;
85 ObjectCalcer();
86 public:
87 // a calcer should call this to register itself as a child of this
88 // calcer. This automatically takes a reference.
89 void addChild( ObjectCalcer* c );
90 // a calcer should call this in its destructor, to inform its parent
91 // that it is no longer a child of this calcer. This will release
92 // the reference taken in addChild..
93 void delChild( ObjectCalcer* c );
95 // use this pointer type to keep a reference to an ObjectCalcer...
96 typedef myboost::intrusive_ptr<ObjectCalcer> shared_ptr;
98 /**
99 * Returns the child ObjectCalcer's of this ObjectCalcer.
101 std::vector<ObjectCalcer*> children() const;
103 virtual ~ObjectCalcer();
105 * Returns the parent ObjectCalcer's of this ObjectCalcer.
107 virtual std::vector<ObjectCalcer*> parents() const = 0;
109 * Returns the ObjectImp of this ObjectCalcer.
111 virtual const ObjectImp* imp() const = 0;
113 * Makes the ObjectCalcer recalculate its ObjectImp from its
114 * parents.
116 virtual void calc( const KigDocument& ) = 0;
119 * An ObjectCalcer expects its parents to have an ObjectImp of a
120 * certain type. This method returns the ObjectImpType that o
121 * should have. os is a list of all the parents in order, and o is
122 * part of it. This method will return the ObjectImpType that the
123 * parent should *at least* be. For example, a Translated object
124 * can translate any sort of object, so it will return
125 * ObjectImp::stype() here ( the topmost ObjectImpType, that all
126 * other ObjectImpType's inherit ).
128 virtual const ObjectImpType* impRequirement(
129 ObjectCalcer* o, const std::vector<ObjectCalcer*>& os ) const = 0;
132 * Returns whether this ObjectCalcer supports moving.
134 virtual bool canMove() const;
136 * Returns whether this ObjectCalcer can be translated at any position
137 * in the coordinate plane. Note that a ConstrainedPointType can be
138 * moved, but cannot be moved everywhere.
140 virtual bool isFreelyTranslatable() const;
142 * Moving an object most of the time signifies invoking changes in
143 * some of its parents. This method returns the set of parents that
144 * will be changed in the move() method. The object itself should
145 * not be included.
147 virtual std::vector<ObjectCalcer*> movableParents() const;
149 * In order to support simultaneously moving objects that are in
150 * different locations, we need for each object a location that it
151 * is assumed to be at, at the moment the moving starts. This
152 * method returns such a point.
154 virtual Coordinate moveReferencePoint() const;
156 * This is the method that does the real moving work. It will be
157 * invoked to tell the object to move to the new location to. After
158 * this, the calc() method will be calced, so you only need to do
159 * the real changes in this method, updating the ObjectImp should be
160 * done in the calc() method, not here.
162 virtual void move( const Coordinate& to, const KigDocument& doc );
165 * If this ObjectCalcer represents a curve, return true if the given
166 * point is by construction on this curve. If this ObjectCalcer
167 * represents a point, return true if this point is by construction
168 * on the given curve.
170 virtual bool isDefinedOnOrThrough( const ObjectCalcer* o ) const = 0;
174 * This is an ObjectCalcer that uses one of the various ObjectType's
175 * to calculate its ObjectImp. It basically forwards all of its
176 * functionality to the ObjectType that it holds a pointer to.
178 class ObjectTypeCalcer
179 : public ObjectCalcer
181 std::vector<ObjectCalcer*> mparents;
182 const ObjectType* mtype;
183 ObjectImp* mimp;
184 public:
185 typedef myboost::intrusive_ptr<ObjectTypeCalcer> shared_ptr;
187 * Construct a new ObjectTypeCalcer with a given type and parents.
189 // ObjectTypeCalcer( const ObjectType* type, const std::vector<ObjectCalcer*>& parents );
191 * the sort boolean tells whether the sortArgs method should be invoked or not;
192 * if not present
194 ObjectTypeCalcer( const ObjectType* type, const std::vector<ObjectCalcer*>& parents, bool sort=true );
195 ~ObjectTypeCalcer();
197 const ObjectImp* imp() const;
198 std::vector<ObjectCalcer*> parents() const;
199 void calc( const KigDocument& doc );
202 * Set the parents of this ObjectTypeCalcer to np. This object will
203 * release the reference it had to its old parents, and take a new
204 * one on the new parents.
206 void setParents( const std::vector<ObjectCalcer*> np );
207 void setType( const ObjectType* t );
209 const ObjectType* type() const;
211 const ObjectImpType* impRequirement(
212 ObjectCalcer* o, const std::vector<ObjectCalcer*>& os ) const;
213 bool isDefinedOnOrThrough( const ObjectCalcer* o ) const;
214 bool canMove() const;
215 bool isFreelyTranslatable() const;
216 std::vector<ObjectCalcer*> movableParents() const;
217 Coordinate moveReferencePoint() const;
218 void move( const Coordinate& to, const KigDocument& doc );
222 * This is an ObjectCalcer that keeps an ObjectImp, and never
223 * calculates a new one. It is a trivial, but very useful
224 * ObjectCalcer. It is used often in Kig, for holding data to be used
225 * by other ObjectCalcer's.
227 class ObjectConstCalcer
228 : public ObjectCalcer
230 ObjectImp* mimp;
231 public:
232 typedef myboost::intrusive_ptr<ObjectConstCalcer> shared_ptr;
235 * Construct a new ObjectConstCalcer with the given imp as the
236 * stored ObjectImp.
238 * This class takes ownership of the imp you pass it, it should have
239 * been constructed using new, and this class is responsible for
240 * deleting it.
242 ObjectConstCalcer( ObjectImp* imp );
243 ~ObjectConstCalcer();
245 const ObjectImp* imp() const;
246 void calc( const KigDocument& doc );
247 std::vector<ObjectCalcer*> parents() const;
250 * Set the ObjectImp of this ObjectConstCalcer to the given
251 * newimp. The old one will be deleted.
253 void setImp( ObjectImp* newimp );
255 * Set the ObjectImp of this ObjectConstCalcer to the given
256 * newimp. The old one will not be deleted, but returned.
258 ObjectImp* switchImp( ObjectImp* newimp );
260 const ObjectImpType* impRequirement(
261 ObjectCalcer* o, const std::vector<ObjectCalcer*>& os ) const;
262 bool isDefinedOnOrThrough( const ObjectCalcer* o ) const;
266 * This is an ObjectCalcer that has a single parent, and gets a
267 * certain property from it in its calc() method.
269 * @see ObjectImp::property
271 class ObjectPropertyCalcer
272 : public ObjectCalcer
274 ObjectImp* mimp;
275 ObjectCalcer* mparent;
276 int mpropid;
277 public:
279 * Construct a new ObjectPropertyCalcer, that will get the property
280 * from parent with number propid.
282 ObjectPropertyCalcer( ObjectCalcer* parent, int propid );
283 ~ObjectPropertyCalcer();
285 const ObjectImp* imp() const;
286 std::vector<ObjectCalcer*> parents() const;
287 void calc( const KigDocument& doc );
289 int propId() const;
290 ObjectCalcer* parent() const;
292 const ObjectImpType* impRequirement(
293 ObjectCalcer* o, const std::vector<ObjectCalcer*>& os ) const;
294 bool isDefinedOnOrThrough( const ObjectCalcer* o ) const;
297 #endif