2005-09-05 Inaki Larranaga <dooteo@euskalgnu.org>
[dia.git] / lib / object.h
blobd364c09f1eaf882d6030b02b47804f1497e89c7f
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 #include "geometry.h"
29 #include "connectionpoint.h"
30 #include "handle.h"
31 #include "objchange.h"
32 #include "diamenu.h"
33 #include "dia_xml.h"
34 #include "properties.h"
35 #include "diagramdata.h"
36 #include "parent.h"
37 #include "text.h"
39 G_BEGIN_DECLS
41 /** This enumeration gives a bitset of modifier keys currently held down.
43 typedef enum {
44 MODIFIER_NONE,
45 MODIFIER_LEFT_SHIFT,
46 MODIFIER_RIGHT_SHIFT,
47 MODIFIER_SHIFT,
48 MODIFIER_LEFT_ALT = 4,
49 MODIFIER_RIGHT_ALT = 8,
50 MODIFIER_ALT = 12,
51 MODIFIER_LEFT_CONTROL = 16,
52 MODIFIER_RIGHT_CONTROL = 32,
53 MODIFIER_CONTROL = 48
54 } ModifierKeys;
56 /************************************
57 ** Some general function prototypes
59 ** These are the prototypes for the
60 ** functions that must be defined for
61 ** every object we can insert in a
62 ** diagram.
64 ************************************/
67 Function called to create an object.
68 This function is responsible for allocation memory for the object.
69 - startpoint : initial position for the object
70 - user_data : Can be used to pass extra params to the creation
71 of the object. Can be used to have two icons of
72 the same object that are instansiated a bit different.
73 - handle1 : (return) Handle connected to startpoint
74 - handle2 : (return) Handle dragged on creation
75 both handle1 and handle2 can be NULL
77 typedef DiaObject* (*CreateFunc) (Point *startpoint,
78 void *user_data,
79 Handle **handle1,
80 Handle **handle2);
83 This function load the object's data from file fd. No header has to be
84 skipped. The data should be read using the functions in lib/files.h
86 The memory for the object has to be allocated (see CreateFunc)
88 The version number is the version number of the DiaObjectType that was saved.
89 This must be used to maintain backwards compatible if you change some
90 in the save format. All objects must be capable of reading all earlier
91 version.
93 typedef DiaObject* (*LoadFunc) (ObjectNode obj_node, int version,
94 const char *filename);
97 This function save the object's data to file fd. No header is required.
98 The data should be written using the functions in lib/files.h
100 typedef void (*SaveFunc) (DiaObject* obj, ObjectNode obj_node,
101 const char *filename);
105 Function called before an object is deleted.
106 This function must call the parent class's DestroyFunc, and then free
107 the memory associated with the object, but not the object itself
109 Must also unconnect itself from all other objects.
110 (This is by calling object_destroy, or letting the super-class call it)
112 typedef void (*DestroyFunc) (DiaObject* obj);
116 Function responsible for drawing the object.
117 Every drawing must be done through the use of the Renderer, so that we
118 can render the picture on screen, in an eps file, ...
120 typedef void (*DrawFunc) (DiaObject* obj, DiaRenderer* ddisp);
124 This function must return the distance between the DiaObject and the Point.
125 Several functions are provided in geometry.h to facilitate this calculus
127 typedef real (*DistanceFunc) (DiaObject* obj, Point* point);
131 Function called once the object has been selected.
132 Basically, this function should update the object (position of the
133 handles,...)
134 - clicked_point is the point on the screen where the user has clicked
135 - interactive_renderer is a renderer that has some extra functions
136 most notably the possibility to get EXACT
137 measures of strings. Used to place cursors
138 and other interactive stuff.
139 (Don't draw to the renderer)
140 This function need not redraw the object.
142 typedef void (*SelectFunc) (DiaObject* obj,
143 Point* clicked_point,
144 DiaRenderer* interactive_renderer);
147 Returns a copy of DiaObject.
148 This must be an depth-copy (pointers must be duplicated and so on)
149 as the initial object can be deleted any time
151 typedef DiaObject* (*CopyFunc) (DiaObject* obj);
154 Function called to move the entire object.
155 The new position is given by pos.
156 It's exact definition depends on the object. It's the point on the
157 object that 'snaps' to the grid if that is enabled. (generally it
158 is the upper left corner)
159 Returns an ObjectChange* with additional undo information, or
160 (in most cases) NULL. Undo for moving the object itself is handled
161 elsewhere.
163 typedef ObjectChange* (*MoveFunc) (DiaObject* obj, Point * pos);
167 * Function called to move one of the handles associated with the
168 * object.
169 * @param obj The object whose handle is being moved.
170 * @param handle The handle being moved.
171 * @param pos The position it has been moved to (corrected for
172 * vertical/horizontal only movement).
173 * @param cp If non-NULL, the connectionpoint found at this position.
174 * If @a cp is NULL, there may or may not be a connectionpoint.
175 * @param The reason the handle was moved.
176 * - HANDLE_MOVE_USER means the user is dragging the point.
177 * - HANDLE_MOVE_USER_FINAL means the user let go of the point.
178 * - HANDLE_MOVE_CONNECTED means it was moved because something
179 * it was connected to moved.
180 * @param modifiers gives a bitset of modifier keys currently held down
181 * - MODIFIER_SHIFT is either shift key
182 * - MODIFIER_ALT is either alt key
183 * - MODIFIER_CONTROL is either control key
184 * Each has MODIFIER_LEFT_* and MODIFIER_RIGHT_* variants
185 * @return An @a ObjectChange* with additional undo information, or
186 * (in most cases) NULL. Undo for moving the handle itself is handled
187 * elsewhere.
189 typedef ObjectChange* (*MoveHandleFunc) (DiaObject* obj,
190 Handle* handle,
191 Point* pos,
192 ConnectionPoint* cp,
193 HandleMoveReason reason,
194 ModifierKeys modifiers);
197 Function called when the user has double clicked on an DiaObject.
198 This function should return a dialog to edit the properties
199 of the object.
200 When this function is called and the dialog already is created,
201 make sure to update the values in the widgets so that it
202 accurately describes the current state of the object.
203 Remember to destroy this dialog when the object is destroyed!
205 Note that if you want to use the same dialog multiple times,
206 you should ref it first. Just run the following on the widget
207 when you create it:
208 gtk_object_ref(GTK_OBJECT(widget));
209 gtk_object_sink(GTK_OBJECT(widget)); / * optional, but recommended * /
210 If you don't do this, the widget will be destroyed when the
211 properties dialog is closed.
213 If is_default is true, this dialog is for object defaults, and
214 the toolbox options should not be shown.
216 typedef GtkWidget *(*GetPropertiesFunc) (DiaObject* obj, gboolean is_default);
219 Thiss function is called when the user clicks on
220 the "Apply" button. The widget parameter is the one created by
221 the get_properties function.
223 Must returns a Change that can be used for undo/redo.
224 The returned change is already applied.
226 typedef ObjectChange *(*ApplyPropertiesFunc) (DiaObject* obj, GtkWidget *widget);
229 This function is called to return a list of property
230 descriptions the object supports. The list should be
231 NULL terminated.
233 typedef const PropDescription *(* DescribePropsFunc) (DiaObject *obj);
236 This function is called to return the current values
237 (and type information) for a number of properties of
238 the object.
240 typedef void (* GetPropsFunc) (DiaObject *obj, GPtrArray *props);
243 This function is called to set the value of a number
244 of properties of the object.
246 typedef void (* SetPropsFunc) (DiaObject *obj, GPtrArray *props);
250 Function called when the user has double clicked on an Tool.
251 This function should return a dialog to edit the defaults
252 of the tool.
253 When this function is called and the dialog already is created,
254 make sure to update the values in the widgets so that it
255 accurately describes the current state of the tool.
257 typedef GtkWidget *(*GetDefaultsFunc) ();
261 typedef void *(*ApplyDefaultsFunc) ();
264 Return an object-specific menu with toggles etc. properly set.
266 typedef DiaMenu *(*ObjectMenuFunc) (DiaObject* obj, Point *position);
269 * Function for updates on a text part of an object. This function, if
270 * not null, will be called every time the text is changed or editing
271 * starts or stops.
272 * @param obj The self object
273 * @param text The text entry being edited
274 * @param state The state of the editing, either TEXT_EDIT_START,
275 * TEXT_EDIT_INSERT, TEXT_EDIT_DELETE, or TEXT_EDIT_END.
276 * @param textchange For TEXT_EDIT_INSERT, the text about to be inserted.
277 * For TEXT_EDIT_DELETE, the text about to be deleted.
278 * @returns For TEXT_EDIT_INSERT and TEXT_EDIT_DELETE, TRUE this change
279 * will be allowed, FALSE otherwise. For TEXT_EDIT_START and TEXT_EDIT_END,
280 * the return value is ignored.
282 typedef gboolean (*TextEditFunc) (DiaObject *obj, Text *text, TextEditState state, gchar *textchange);
284 /*************************************
285 ** The functions provided in object.c
286 *************************************/
288 void object_init(DiaObject *obj, int num_handles, int num_connections);
289 void object_destroy(DiaObject *obj); /* Unconnects handles, so don't
290 free handles before calling. */
291 void object_copy(DiaObject *from, DiaObject *to);
293 void object_save(DiaObject *obj, ObjectNode obj_node);
294 void object_load(DiaObject *obj, ObjectNode obj_node);
296 GList *object_copy_list(GList *list);
297 ObjectChange* object_list_move_delta_r(GList *objects, Point *delta, gboolean affected);
298 ObjectChange* object_list_move_delta(GList *objects, Point *delta);
299 /** Rotate an object around a point. If center is NULL, the position of
300 * the object is used. */
301 ObjectChange* object_list_rotate(GList *objects, Point *center, real angle);
302 /** Scale an object around a point. If center is NULL, the position of
303 * the object is used. */
304 ObjectChange* object_list_scale(GList *objects, Point *center, real factor);
305 void destroy_object_list(GList *list);
306 void object_add_handle(DiaObject *obj, Handle *handle);
307 void object_add_handle_at(DiaObject *obj, Handle *handle, int pos);
308 void object_remove_handle(DiaObject *obj, Handle *handle);
309 void object_add_connectionpoint(DiaObject *obj, ConnectionPoint *conpoint);
310 void object_remove_connectionpoint(DiaObject *obj,
311 ConnectionPoint *conpoint);
312 void object_add_connectionpoint_at(DiaObject *obj,
313 ConnectionPoint *conpoint,
314 int pos);
315 void object_connect(DiaObject *obj, Handle *handle,
316 ConnectionPoint *conpoint);
317 void object_unconnect(DiaObject *connected_obj, Handle *handle);
318 void object_remove_connections_to(ConnectionPoint *conpoint);
319 void object_unconnect_all(DiaObject *connected_obj);
320 void object_registry_init(void);
321 void object_register_type(DiaObjectType *type);
322 void object_registry_foreach(GHFunc func, gpointer user_data);
323 DiaObjectType *object_get_type(char *name);
324 gchar *object_get_displayname (DiaObject* obj);
326 int object_return_false(DiaObject *obj); /* Just returns FALSE */
327 void *object_return_null(DiaObject *obj); /* Just returns NULL */
328 void object_return_void(DiaObject *obj); /* Just an empty function */
330 /* These functions can be used as a default implementation for an object which
331 can be completely described, loaded and saved through standard properties.
333 DiaObject *object_load_using_properties(const DiaObjectType *type,
334 ObjectNode obj_node, int version,
335 const char *filename);
336 void object_save_using_properties(DiaObject *obj, ObjectNode obj_node,
337 int version, const char *filename);
338 DiaObject *object_copy_using_properties(DiaObject *obj);
340 /*****************************************
341 ** The structures used to define an object
342 *****************************************/
344 /** This structure defines an affine transformation that has been applied
345 * to this object. Affine transformations done on a group are performed
346 * on all objects in the group.
349 typedef struct _Affine {
350 real rotation;
351 real scale;
352 real translation;
353 } Affine;
357 This structure gives access to the functions used to manipulate an object
358 See information above on the use of the functions
361 struct _ObjectOps {
362 DestroyFunc destroy;
363 DrawFunc draw;
364 DistanceFunc distance_from;
365 SelectFunc selectf;
366 CopyFunc copy;
367 MoveFunc move;
368 MoveHandleFunc move_handle;
369 GetPropertiesFunc get_properties;
370 ApplyPropertiesFunc apply_properties;
371 ObjectMenuFunc get_object_menu;
373 DescribePropsFunc describe_props;
374 GetPropsFunc get_props;
375 SetPropsFunc set_props;
377 TextEditFunc edit_text;
380 Unused places (for extension).
381 These should be NULL for now. In the future they might be used.
382 Then an older object will be binary compatible, because all new code
383 checks if new ops are supported (!= NULL)
385 void (*(unused[5]))(DiaObject *obj,...);
389 The base class in the DiaObject hierarcy.
390 All information in this structure read-only
391 from the application point of view except
392 when connection objects. (Then handles and
393 connections are changed).
395 position is not necessarly the corner of the object, but rather
396 some 'good' spot on it which will be natural to snap to.
399 struct _DiaObject {
400 DiaObjectType *type;
401 Point position;
402 Rectangle bounding_box;
403 Affine affine;
405 int num_handles;
406 Handle **handles;
408 int num_connections;
409 ConnectionPoint **connections;
411 ObjectOps *ops;
413 Layer *parent_layer; /* Back-pointer to the owning layer.
414 This may only be set by functions internal to
415 the layer, and accessed via
416 dia_object_get_parent_layer() */
417 DiaObject *parent;
418 GList *children;
419 gboolean can_parent;
421 Color *highlight_color; /* The color that this object is currently
422 highlighted with, or NULL if it is not
423 highlighted. */
426 struct _ObjectTypeOps {
427 CreateFunc create;
428 LoadFunc load;
429 SaveFunc save;
430 GetDefaultsFunc get_defaults;
431 ApplyDefaultsFunc apply_defaults;
433 Unused places (for extension).
434 These should be NULL for now. In the future they might be used.
435 Then an older object will be binary compatible, because all new code
436 checks if new ops are supported (!= NULL)
438 void (*(unused[10]))(DiaObject *obj,...);
442 Structure so that the ObjectFactory can create objects
443 of unknown type. (Read in from a shared lib.)
445 struct _DiaObjectType {
447 char *name;
448 int version;
450 char **pixmap; /* Also put a pixmap in the sheet_object.
451 This one is used if not in sheet but in toolbar.
452 Stored in xpm format */
454 ObjectTypeOps *ops;
456 char *pixmap_file; /* fallback if pixmap is NULL */
457 void *default_user_data; /* use this if no user data is specified in
458 the .sheet file */
461 /* base property stuff ... */
462 #define OBJECT_COMMON_PROPERTIES \
463 { "obj_pos", PROP_TYPE_POINT, 0, \
464 "Object position", "Where the object is located"}, \
465 { "obj_bb", PROP_TYPE_RECT, 0, \
466 "Object bounding box", "The bounding box of the object"}
468 #define OBJECT_COMMON_PROPERTIES_OFFSETS \
469 { "obj_pos", PROP_TYPE_POINT, offsetof(DiaObject, position) }, \
470 { "obj_bb", PROP_TYPE_RECT, offsetof(DiaObject, bounding_box) }
473 gboolean dia_object_defaults_load (const gchar *filename,
474 gboolean create_lazy);
475 void dia_object_default_make (const DiaObject *obj_from);
476 DiaObject *dia_object_default_get (const DiaObjectType *type);
477 DiaObject *dia_object_default_create (const DiaObjectType *type,
478 Point *startpoint,
479 void *user_data,
480 Handle **handle1,
481 Handle **handle2);
482 gboolean dia_object_defaults_save (const gchar *filename);
483 Layer *dia_object_get_parent_layer(DiaObject *obj);
484 gboolean dia_object_is_selected (const DiaObject *obj);
486 G_END_DECLS
488 #endif /* OBJECT_H */