2004-01-17 Hans Breuer <hans@breuer.org>
[dia.git] / lib / object.h
bloba487c35b87c6e9b26a6adf14b1f8847c30895279
1 /* Dia -- an diagram creation/manipulation program -*- c -*-
2 * Copyright (C) 1998 Alexander Larsson
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program 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
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 /** @file object.h -- definitions for Dia objects, in particular the 'virtual'
20 * functions and the object and type structures.
22 #ifndef OBJECT_H
23 #define OBJECT_H
25 #include "diatypes.h"
26 #include <gtk/gtk.h>
28 typedef guint16 ObjectId; /** The id of an objecttype */
30 #include "geometry.h"
31 #include "connectionpoint.h"
32 #include "handle.h"
33 #include "objchange.h"
34 #include "diamenu.h"
35 #include "dia_xml.h"
36 #include "properties.h"
37 #include "diagramdata.h"
38 #include "parent.h"
40 /** This enumeration gives a bitset of modifier keys currently held down.
42 typedef enum {
43 MODIFIER_NONE,
44 MODIFIER_LEFT_SHIFT,
45 MODIFIER_RIGHT_SHIFT,
46 MODIFIER_SHIFT,
47 MODIFIER_LEFT_ALT = 4,
48 MODIFIER_RIGHT_ALT = 8,
49 MODIFIER_ALT = 12,
50 MODIFIER_LEFT_CONTROL = 16,
51 MODIFIER_RIGHT_CONTROL = 32,
52 MODIFIER_CONTROL = 48
53 } ModifierKeys;
55 /************************************
56 ** Some general function prototypes
58 ** These are the prototypes for the
59 ** functions that must be defined for
60 ** every object we can insert in a
61 ** diagram.
63 ************************************/
66 Function called to create an object.
67 This function is responsible for allocation memory for the object.
68 - startpoint : initial position for the object
69 - user_data : Can be used to pass extra params to the creation
70 of the object. Can be used to have two icons of
71 the same object that are instansiated a bit different.
72 - handle1 : (return) Handle connected to startpoint
73 - handle2 : (return) Handle dragged on creation
74 both handle1 and handle2 can be NULL
76 typedef Object* (*CreateFunc) (Point *startpoint,
77 void *user_data,
78 Handle **handle1,
79 Handle **handle2);
82 This function load the object's data from file fd. No header has to be
83 skipped. The data should be read using the functions in lib/files.h
85 The memory for the object has to be allocated (see CreateFunc)
87 The version number is the version number of the ObjectType that was saved.
88 This must be used to maintain backwards compatible if you change some
89 in the save format. All objects must be capable of reading all earlier
90 version.
92 typedef Object* (*LoadFunc) (ObjectNode obj_node, int version,
93 const char *filename);
96 This function save the object's data to file fd. No header is required.
97 The data should be written using the functions in lib/files.h
99 typedef void (*SaveFunc) (Object* obj, ObjectNode obj_node,
100 const char *filename);
104 Function called before an object is deleted.
105 This function must call the parent class's DestroyFunc, and then free
106 the memory associated with the object, but not the object itself
108 Must also unconnect itself from all other objects.
109 (This is by calling object_destroy, or letting the super-class call it)
111 typedef void (*DestroyFunc) (Object* obj);
115 Function responsible for drawing the object.
116 Every drawing must be done through the use of the Renderer, so that we
117 can render the picture on screen, in an eps file, ...
119 typedef void (*DrawFunc) (Object* obj, DiaRenderer* ddisp);
123 This function must return the distance between the Object and the Point.
124 Several functions are provided in geometry.h to facilitate this calculus
126 typedef real (*DistanceFunc) (Object* obj, Point* point);
130 Function called once the object has been selected.
131 Basically, this function should update the object (position of the
132 handles,...)
133 - clicked_point is the point on the screen where the user has clicked
134 - interactive_renderer is a renderer that has some extra functions
135 most notably the possibility to get EXACT
136 measures of strings. Used to place cursors
137 and other interactive stuff.
138 (Don't draw to the renderer)
139 This function need not redraw the object.
141 typedef void (*SelectFunc) (Object* obj,
142 Point* clicked_point,
143 DiaRenderer* interactive_renderer);
146 Returns a copy of Object.
147 This must be an depth-copy (pointers must be duplicated and so on)
148 as the initial object can be deleted any time
150 typedef Object* (*CopyFunc) (Object* obj);
153 Function called to move the entire object.
154 The new position is given by pos.
155 It's exact definition depends on the object. It's the point on the
156 object that 'snaps' to the grid if that is enabled. (generally it
157 is the upper left corner)
158 Returns an ObjectChange* with additional undo information, or
159 (in most cases) NULL. Undo for moving the object itself is handled
160 elsewhere.
162 typedef ObjectChange* (*MoveFunc) (Object* obj, Point * pos);
166 * Function called to move one of the handles associated with the
167 * object.
168 * @param obj The object whose handle is being moved.
169 * @param handle The handle being moved.
170 * @param pos The position it has been moved to (corrected for
171 * vertical/horizontal only movement).
172 * @param cp If non-NULL, the connectionpoint found at this position.
173 * If @a cp is NULL, there may or may not be a connectionpoint.
174 * @param The reason the handle was moved.
175 * - HANDLE_MOVE_USER means the user is dragging the point.
176 * - HANDLE_MOVE_USER_FINAL means the user let go of the point.
177 * - HANDLE_MOVE_CONNECTED means it was moved because something
178 * it was connected to moved.
179 * @param modifiers gives a bitset of modifier keys currently held down
180 * - MODIFIER_SHIFT is either shift key
181 * - MODIFIER_ALT is either alt key
182 * - MODIFIER_CONTROL is either control key
183 * Each has MODIFIER_LEFT_* and MODIFIER_RIGHT_* variants
184 * @return An @a ObjectChange* with additional undo information, or
185 * (in most cases) NULL. Undo for moving the handle itself is handled
186 * elsewhere.
188 typedef ObjectChange* (*MoveHandleFunc) (Object* obj,
189 Handle* handle,
190 Point* pos,
191 ConnectionPoint* cp,
192 HandleMoveReason reason,
193 ModifierKeys modifiers);
196 Function called when the user has double clicked on an Object.
197 This function should return a dialog to edit the properties
198 of the object.
199 When this function is called and the dialog already is created,
200 make sure to update the values in the widgets so that it
201 accurately describes the current state of the object.
202 Remember to destroy this dialog when the object is destroyed!
204 Note that if you want to use the same dialog multiple times,
205 you should ref it first. Just run the following on the widget
206 when you create it:
207 gtk_object_ref(GTK_OBJECT(widget));
208 gtk_object_sink(GTK_OBJECT(widget)); / * optional, but recommended * /
209 If you don't do this, the widget will be destroyed when the
210 properties dialog is closed.
212 If is_default is true, this dialog is for object defaults, and
213 the toolbox options should not be shown.
215 typedef GtkWidget *(*GetPropertiesFunc) (Object* obj, gboolean is_default);
218 Thiss function is called when the user clicks on
219 the "Apply" button. The widget parameter is the one created by
220 the get_properties function.
222 Must returns a Change that can be used for undo/redo.
223 The returned change is already applied.
225 typedef ObjectChange *(*ApplyPropertiesFunc) (Object* obj, GtkWidget *widget);
228 This function is called to return a list of property
229 descriptions the object supports. The list should be
230 NULL terminated.
232 typedef const PropDescription *(* DescribePropsFunc) (Object *obj);
235 This function is called to return the current values
236 (and type information) for a number of properties of
237 the object.
239 typedef void (* GetPropsFunc) (Object *obj, GPtrArray *props);
242 This function is called to set the value of a number
243 of properties of the object.
245 typedef void (* SetPropsFunc) (Object *obj, GPtrArray *props);
249 Function called when the user has double clicked on an Tool.
250 This function should return a dialog to edit the defaults
251 of the tool.
252 When this function is called and the dialog already is created,
253 make sure to update the values in the widgets so that it
254 accurately describes the current state of the tool.
256 typedef GtkWidget *(*GetDefaultsFunc) ();
260 typedef void *(*ApplyDefaultsFunc) ();
263 Return an object-specific menu with toggles etc. properly set.
265 typedef DiaMenu *(*ObjectMenuFunc) (Object* obj, Point *position);
267 /*************************************
268 ** The functions provided in object.c
269 *************************************/
271 void object_init(Object *obj, int num_handles, int num_connections);
272 void object_destroy(Object *obj); /* Unconnects handles, so don't
273 free handles before calling. */
274 void object_copy(Object *from, Object *to);
276 void object_save(Object *obj, ObjectNode obj_node);
277 void object_load(Object *obj, ObjectNode obj_node);
279 GList *object_copy_list(GList *list);
280 ObjectChange* object_list_move_delta_r(GList *objects, Point *delta, gboolean affected);
281 ObjectChange* object_list_move_delta(GList *objects, Point *delta);
282 void destroy_object_list(GList *list);
283 void object_add_handle(Object *obj, Handle *handle);
284 void object_add_handle_at(Object *obj, Handle *handle, int pos);
285 void object_remove_handle(Object *obj, Handle *handle);
286 void object_add_connectionpoint(Object *obj, ConnectionPoint *conpoint);
287 void object_remove_connectionpoint(Object *obj,
288 ConnectionPoint *conpoint);
289 void object_add_connectionpoint_at(Object *obj,
290 ConnectionPoint *conpoint,
291 int pos);
292 void object_connect(Object *obj, Handle *handle,
293 ConnectionPoint *conpoint);
294 void object_unconnect(Object *connected_obj, Handle *handle);
295 void object_remove_connections_to(ConnectionPoint *conpoint);
296 void object_unconnect_all(Object *connected_obj);
297 void object_registry_init(void);
298 void object_register_type(ObjectType *type);
299 void object_registry_foreach(GHFunc func, gpointer user_data);
300 ObjectType *object_get_type(char *name);
302 int object_return_false(Object *obj); /* Just returns FALSE */
303 void *object_return_null(Object *obj); /* Just returns NULL */
304 void object_return_void(Object *obj); /* Just an empty function */
306 /* These functions can be used as a default implementation for an object which
307 can be completely described, loaded and saved through standard properties.
309 Object *object_load_using_properties(const ObjectType *type,
310 ObjectNode obj_node, int version,
311 const char *filename);
312 void object_save_using_properties(Object *obj, ObjectNode obj_node,
313 int version, const char *filename);
314 Object *object_copy_using_properties(Object *obj);
316 /*****************************************
317 ** The structures used to define an object
318 *****************************************/
322 This structure gives access to the functions used to manipulate an object
323 See information above on the use of the functions
326 struct _ObjectOps {
327 DestroyFunc destroy;
328 DrawFunc draw;
329 DistanceFunc distance_from;
330 SelectFunc selectf;
331 CopyFunc copy;
332 MoveFunc move;
333 MoveHandleFunc move_handle;
334 GetPropertiesFunc get_properties;
335 ApplyPropertiesFunc apply_properties;
336 ObjectMenuFunc get_object_menu;
338 DescribePropsFunc describe_props;
339 GetPropsFunc get_props;
340 SetPropsFunc set_props;
343 Unused places (for extension).
344 These should be NULL for now. In the future they might be used.
345 Then an older object will be binary compatible, because all new code
346 checks if new ops are supported (!= NULL)
348 void (*(unused[6]))(Object *obj,...);
352 The base class in the Object hierarcy.
353 All information in this structure read-only
354 from the application point of view except
355 when connection objects. (Then handles and
356 connections are changed).
358 position is not necessarly the corner of the object, but rather
359 some 'good' spot on it which will be natural to snap to.
362 struct _Object {
363 ObjectType *type;
364 Point position;
365 Rectangle bounding_box;
367 int num_handles;
368 Handle **handles;
370 int num_connections;
371 ConnectionPoint **connections;
373 ObjectOps *ops;
375 Layer *parent_layer; /* Back-pointer to the owning layer.
376 This may only be set by functions internal to
377 the layer, and accessed via
378 dia_object_get_parent_layer() */
379 Object *parent;
380 GList *children;
381 gboolean can_parent;
384 struct _ObjectTypeOps {
385 CreateFunc create;
386 LoadFunc load;
387 SaveFunc save;
388 GetDefaultsFunc get_defaults;
389 ApplyDefaultsFunc apply_defaults;
391 Unused places (for extension).
392 These should be NULL for now. In the future they might be used.
393 Then an older object will be binary compatible, because all new code
394 checks if new ops are supported (!= NULL)
396 void (*(unused[10]))(Object *obj,...);
400 Structure so that the ObjectFactory can create objects
401 of unknown type. (Read in from a shared lib.)
403 struct _ObjectType {
404 char *name;
405 int version;
407 char **pixmap; /* Also put a pixmap in the sheet_object.
408 This one is used if not in sheet but in toolbar.
409 Stored in xpm format */
411 ObjectTypeOps *ops;
413 char *pixmap_file; /* fallback if pixmap is NULL */
414 void *default_user_data; /* use this if no user data is specified in
415 the .sheet file */
418 /* base property stuff ... */
419 #define OBJECT_COMMON_PROPERTIES \
420 { "obj_pos", PROP_TYPE_POINT, 0, \
421 "Object position", "Where the object is located"}, \
422 { "obj_bb", PROP_TYPE_RECT, 0, \
423 "Object bounding box", "The bounding box of the object"}
425 #define OBJECT_COMMON_PROPERTIES_OFFSETS \
426 { "obj_pos", PROP_TYPE_POINT, offsetof(Object, position) }, \
427 { "obj_bb", PROP_TYPE_RECT, offsetof(Object, bounding_box) }
430 gboolean dia_object_defaults_load (const gchar *filename,
431 gboolean create_lazy);
432 void dia_object_default_make (const Object *obj_from);
433 Object *dia_object_default_get (const ObjectType *type);
434 Object *dia_object_default_create (const ObjectType *type,
435 Point *startpoint,
436 void *user_data,
437 Handle **handle1,
438 Handle **handle2);
439 gboolean dia_object_defaults_save (const gchar *filename);
440 Layer *dia_object_get_parent_layer(Object *obj);
441 gboolean dia_object_is_selected (const Object *obj);
443 #endif /* OBJECT_H */