1 /* gEDA - GPL Electronic Design Automation
2 * libgeda - gEDA's library
3 * Copyright (C) 1998-2010 Ales Hvezda
4 * Copyright (C) 1998-2010 gEDA Contributors (see ChangeLog for details)
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 * \brief functions for the basic object type
24 * This file contains the code used to handle OBJECTs (st_object).
25 * The object is the basic type of all elements stored in schematic
28 * The object be extended to become concrete objects like a line,
29 * a pin, text, a circle or a picture. These extentions are substructures
30 * in the object struct.
31 * The subobjects are picture (st_picture), path (st_path), arcs (st_arc),
32 * a line (st_line), box (st_box), circle (st_circle), text (st_text) and
33 * a complex type (st_complex).
35 * Pins, nets and busses are just a kind of a line.
37 * The complex object can carry many primary objects. If the complex
38 * object is a symbol, then the complex symbol contains all the pins,
39 * the text and the graphics.
41 * \image html o_object_relations.png
42 * \image latex o_object_relations.pdf "object relations" width=14cm
49 /* instrumentation code */
55 #include "libgeda_priv.h"
57 #ifdef HAVE_LIBDMALLOC
61 /*! Default setting for object selection function. */
62 void (*select_func
)() = NULL
;
65 /*! \brief Check if point is inside a region
66 * \par Function Description
67 * This function takes a rectangular region and a point. It will check
68 * if the point is located in the region or not.
70 * \param [in] xmin Smaller x coordinate of the region.
71 * \param [in] ymin Smaller y coordinate of the region.
72 * \param [in] xmax Larger x coordinate of the region.
73 * \param [in] ymax Larger y coordinate of the region.
74 * \param [in] x x coordinate of the point to check.
75 * \param [in] y y coordinate of the point to check.
76 * \return 1 if the point is inside the region, 0 otherwise.
78 int inside_region(int xmin
, int ymin
, int xmax
, int ymax
, int x
, int y
)
80 return ((x
>= xmin
&& x
<= xmax
&& y
>= ymin
&& y
<= ymax
) ? 1 : 0);
83 /*! \brief Recalculate position of the given object.
84 * \par Function Description
85 * This function will take an object and recalculate its
86 * position on the screen.
88 * \param [in] toplevel The TOPLEVEL object.
89 * \param [in,out] o_current OBJECT to recalculate.
92 void o_recalc_single_object(TOPLEVEL
*toplevel
, OBJECT
*o_current
)
94 if (o_current
!= NULL
) {
95 switch(o_current
->type
) {
98 o_line_recalc(toplevel
, o_current
);
102 o_net_recalc(toplevel
, o_current
);
106 o_bus_recalc(toplevel
, o_current
);
110 o_box_recalc(toplevel
, o_current
);
114 o_path_recalc(toplevel
, o_current
);
118 o_picture_recalc(toplevel
, o_current
);
122 o_circle_recalc(toplevel
, o_current
);
126 case(OBJ_PLACEHOLDER
):
127 o_complex_recalc(toplevel
, o_current
);
131 o_pin_recalc(toplevel
, o_current
);
135 o_arc_recalc(toplevel
, o_current
);
139 o_text_recalc(toplevel
, o_current
);
146 /*! \brief Recalculate position of a list (GList) of objects.
147 * \par Function Description
148 * This function will take a list (GList) of objects and recalculate their
149 * positions on the screen.
151 * \param [in] toplevel The TOPLEVEL object.
152 * \param [in,out] object_glist OBJECT list to recalculate.
156 o_recalc_object_glist(TOPLEVEL
*toplevel
, GList
*object_glist
)
158 GList
*list
= object_glist
;
161 while (list
!= NULL
) {
162 o_current
= (OBJECT
*) list
->data
;
163 o_recalc_single_object(toplevel
, o_current
);
164 list
= g_list_next(list
);
169 /*! \brief Set an #OBJECT's line options.
170 * \par Function Description
171 * This function allows a line's end, type, width, length and space to be set.
172 * See #OBJECT_END and #OBJECT_TYPE for information on valid
173 * object end and type values.
175 * \param [in] toplevel The TOPLEVEL object.
176 * \param [in,out] o_current OBJECT to set line options on.
177 * \param [in] end An OBJECT_END.
178 * \param [in] type An OBJECT_TYPE.
179 * \param [in] width Line width.
180 * \param [in] length Line length.
181 * \param [in] space Spacing between dashes/dots. Cannot be negative.
183 * \todo Make space an unsigned int and check for a max value instead.
184 * If a max value is not required, then it would simplify the code.
186 void o_set_line_options(TOPLEVEL
*toplevel
, OBJECT
*o_current
,
187 OBJECT_END end
, OBJECT_TYPE type
,
188 int width
, int length
, int space
)
190 if(o_current
== NULL
) {
194 /* do some error checking / correcting */
199 s_log_message (_("Invalid space specified, setting to 100\n"));
207 s_log_message (_("Invalid length specified, setting to 100\n"));
211 s_log_message (_("Invalid space specified, setting to 100\n"));
219 o_emit_pre_change_notify (toplevel
, o_current
);
221 o_current
->line_width
= width
;
222 o_current
->line_end
= end
;
223 o_current
->line_type
= type
;
225 o_current
->line_length
= length
;
226 o_current
->line_space
= space
;
228 /* Recalculate the object's bounding box */
229 o_recalc_single_object( toplevel
, o_current
);
230 o_emit_change_notify (toplevel
, o_current
);
234 /*! \brief get #OBJECT's line properties.
235 * \par Function Description
236 * This function get's the #OBJECT's line options.
237 * See #OBJECT_END and #OBJECT_TYPE for information on valid
238 * object end and type values.
240 * \param [in] object OBJECT to read the properties
241 * \param [out] end An OBJECT_END.
242 * \param [out] type An OBJECT_TYPE.
243 * \param [out] width Line width.
244 * \param [out] length Line length.
245 * \param [out] space Spacing between dashes/dots.
246 * \return TRUE on succes, FALSE otherwise
249 gboolean
o_get_line_options(OBJECT
*object
,
250 OBJECT_END
*end
, OBJECT_TYPE
*type
,
251 int *width
, int *length
, int *space
)
253 if (object
->type
!= OBJ_LINE
254 && object
->type
!= OBJ_ARC
255 && object
->type
!= OBJ_BOX
256 && object
->type
!= OBJ_CIRCLE
257 && object
->type
!= OBJ_PATH
)
260 *end
= object
->line_end
;
261 *type
= object
->line_type
;
262 *width
= object
->line_width
;
263 *length
= object
->line_length
;
264 *space
= object
->line_space
;
269 /*! \brief Set #OBJECT's fill options.
270 * \par Function Description
271 * This function allows an #OBJECT's fill options to be configured.
272 * See #OBJECT_FILLING for information on valid fill types.
274 * \param [in] toplevel The TOPLEVEL object.
275 * \param [in,out] o_current OBJECT to be updated.
276 * \param [in] type OBJECT_FILLING type.
277 * \param [in] width fill width.
278 * \param [in] pitch1 cross hatch line distance
279 * \param [in] angle1 cross hatch angle
280 * \param [in] pitch2 cross hatch line distance
281 * \param [in] angle2 cross hatch angle
284 void o_set_fill_options(TOPLEVEL
*toplevel
, OBJECT
*o_current
,
285 OBJECT_FILLING type
, int width
,
286 int pitch1
, int angle1
,
287 int pitch2
, int angle2
)
289 if(o_current
== NULL
) {
293 o_emit_pre_change_notify (toplevel
, o_current
);
295 o_current
->fill_type
= type
;
296 o_current
->fill_width
= width
;
298 o_current
->fill_pitch1
= pitch1
;
299 o_current
->fill_angle1
= angle1
;
301 o_current
->fill_pitch2
= pitch2
;
302 o_current
->fill_angle2
= angle2
;
304 o_emit_change_notify (toplevel
, o_current
);
307 /*! \brief get #OBJECT's fill properties.
308 * \par Function Description
309 * This function get's the #OBJECT's fill options.
310 * See #OBJECT_FILLING for information on valid fill types.
312 * \param [in] object OBJECT to read the properties
313 * \param [out] type OBJECT_FILLING type
314 * \param [out] width fill width.
315 * \param [out] pitch1 cross hatch line distance
316 * \param [out] angle1 cross hatch angle
317 * \param [out] pitch2 cross hatch line distance
318 * \param [out] angle2 cross hatch angle
319 * \return TRUE on succes, FALSE otherwise
322 gboolean
o_get_fill_options(OBJECT
*object
,
323 OBJECT_FILLING
*type
, int *width
,
324 int *pitch1
, int *angle1
,
325 int *pitch2
, int *angle2
)
327 if (object
->type
!= OBJ_BOX
328 && object
->type
!= OBJ_CIRCLE
329 && object
->type
!= OBJ_PATH
)
332 *type
= object
->fill_type
;
333 *width
= object
->fill_width
;
334 *pitch1
= object
->fill_pitch1
;
335 *angle1
= object
->fill_angle1
;
336 *pitch2
= object
->fill_pitch2
;
337 *angle2
= object
->fill_angle2
;
342 /*! \brief get the base position of an object
343 * \par Function Description
344 * This function gets the position of an object in world coordinates.
346 * \param [in] toplevel The toplevel environment.
347 * \param [out] x pointer to the x-position
348 * \param [out] y pointer to the y-position
349 * \param [in] object The object to get the position.
350 * \return TRUE if successfully determined the position, FALSE otherwise
352 gboolean
o_get_position (TOPLEVEL
*toplevel
, gint
*x
, gint
*y
, OBJECT
*object
)
354 gboolean (*func
) (TOPLEVEL
*, int*, int*, OBJECT
*) = NULL
;
356 switch (object
->type
) {
357 case OBJ_LINE
: func
= o_line_get_position
; break;
358 case OBJ_NET
: func
= o_net_get_position
; break;
359 case OBJ_BUS
: func
= o_bus_get_position
; break;
360 case OBJ_BOX
: func
= o_box_get_position
; break;
361 case OBJ_PICTURE
: func
= o_picture_get_position
; break;
362 case OBJ_CIRCLE
: func
= o_circle_get_position
; break;
363 case OBJ_PLACEHOLDER
:
364 case OBJ_COMPLEX
: func
= o_complex_get_position
; break;
365 case OBJ_TEXT
: func
= o_text_get_position
; break;
366 case OBJ_PATH
: func
= o_path_get_position
; break;
367 case OBJ_PIN
: func
= o_pin_get_position
; break;
368 case OBJ_ARC
: func
= o_arc_get_position
; break;
370 g_critical ("o_get_position: object %p has bad type '%c'\n",
371 object
, object
->type
);
375 return (*func
) (toplevel
, x
, y
, object
);
381 /*! \brief Translates an object in world coordinates
382 * \par Function Description
383 * This function translates the object <B>object</B> by
384 * <B>dx</B> and <B>dy</B>.
386 * \param [in] toplevel The toplevel environment.
387 * \param [in] dx Amount to horizontally translate object
388 * \param [in] dy Amount to vertically translate object
389 * \param [in] object The object to translate.
391 void o_translate_world (TOPLEVEL
*toplevel
, gint dx
, gint dy
, OBJECT
*object
)
393 void (*func
) (TOPLEVEL
*, int, int, OBJECT
*) = NULL
;
395 switch (object
->type
) {
396 case OBJ_LINE
: func
= o_line_translate_world
; break;
397 case OBJ_NET
: func
= o_net_translate_world
; break;
398 case OBJ_BUS
: func
= o_bus_translate_world
; break;
399 case OBJ_BOX
: func
= o_box_translate_world
; break;
400 case OBJ_PICTURE
: func
= o_picture_translate_world
; break;
401 case OBJ_CIRCLE
: func
= o_circle_translate_world
; break;
402 case OBJ_PLACEHOLDER
:
403 case OBJ_COMPLEX
: func
= o_complex_translate_world
; break;
404 case OBJ_TEXT
: func
= o_text_translate_world
; break;
405 case OBJ_PATH
: func
= o_path_translate_world
; break;
406 case OBJ_PIN
: func
= o_pin_translate_world
; break;
407 case OBJ_ARC
: func
= o_arc_translate_world
; break;
409 g_critical ("o_translate_world: object %p has bad type '%c'\n",
410 object
, object
->type
);
414 (*func
) (toplevel
, dx
, dy
, object
);
419 /*! \brief Rotates an object in world coordinates
420 * \par Function Description
421 * This function rotates the object <B>object</B> about the coordinates
422 * <B>world_centerx</B> and <B>world_centery</B>, by <B>angle</B>degrees.
424 * \param [in] toplevel The toplevel environment.
425 * \param [in] world_centerx X coordinate of rotation center (world coords)
426 * \param [in] world_centery Y coordinate of rotation center (world coords)
427 * \param [in] angle Angle of rotation (degrees)
428 * \param [in] object The object to rotate.
430 void o_rotate_world (TOPLEVEL
*toplevel
, int world_centerx
, int world_centery
, int angle
, OBJECT
*object
)
432 void (*func
) (TOPLEVEL
*, int, int, int, OBJECT
*) = NULL
;
434 switch (object
->type
) {
435 case OBJ_LINE
: func
= o_line_rotate_world
; break;
436 case OBJ_NET
: func
= o_net_rotate_world
; break;
437 case OBJ_BUS
: func
= o_bus_rotate_world
; break;
438 case OBJ_BOX
: func
= o_box_rotate_world
; break;
439 case OBJ_PICTURE
: func
= o_picture_rotate_world
; break;
440 case OBJ_CIRCLE
: func
= o_circle_rotate_world
; break;
441 case OBJ_PLACEHOLDER
:
442 case OBJ_COMPLEX
: func
= o_complex_rotate_world
; break;
443 case OBJ_TEXT
: func
= o_text_rotate_world
; break;
444 case OBJ_PATH
: func
= o_path_rotate_world
; break;
445 case OBJ_PIN
: func
= o_pin_rotate_world
; break;
446 case OBJ_ARC
: func
= o_arc_rotate_world
; break;
448 g_critical ("o_rotate_world: object %p has bad type '%c'\n",
449 object
, object
->type
);
453 (*func
) (toplevel
, world_centerx
, world_centery
, angle
, object
);
458 /*! \brief Mirrors an object in world coordinates
459 * \par Function Description
460 * This function mirrors an object about the point
461 * (<B>world_centerx</B>,<B>world_centery</B>) in world units.
463 * \param [in] toplevel The TOPLEVEL object.
464 * \param [in] world_centerx Origin x coordinate in WORLD units.
465 * \param [in] world_centery Origin y coordinate in WORLD units.
466 * \param [in,out] object The OBJECT to mirror.
468 void o_mirror_world (TOPLEVEL
*toplevel
, int world_centerx
, int world_centery
, OBJECT
*object
)
470 void (*func
) (TOPLEVEL
*, int, int, OBJECT
*) = NULL
;
472 switch (object
->type
) {
473 case OBJ_LINE
: func
= o_line_mirror_world
; break;
474 case OBJ_NET
: func
= o_net_mirror_world
; break;
475 case OBJ_BUS
: func
= o_bus_mirror_world
; break;
476 case OBJ_BOX
: func
= o_box_mirror_world
; break;
477 case OBJ_PICTURE
: func
= o_picture_mirror_world
; break;
478 case OBJ_CIRCLE
: func
= o_circle_mirror_world
; break;
479 case OBJ_PLACEHOLDER
:
480 case OBJ_COMPLEX
: func
= o_complex_mirror_world
; break;
481 case OBJ_TEXT
: func
= o_text_mirror_world
; break;
482 case OBJ_PATH
: func
= o_path_mirror_world
; break;
483 case OBJ_PIN
: func
= o_pin_mirror_world
; break;
484 case OBJ_ARC
: func
= o_arc_mirror_world
; break;
486 g_critical ("o_mirror_world: object %p has bad type '%c'\n",
487 object
, object
->type
);
491 (*func
) (toplevel
, world_centerx
, world_centery
, object
);
496 /*! \brief Calculates the distance between the given point and the closest
497 * point on the given object.
499 * \param [in] object The given object.
500 * \param [in] x The x coordinate of the given point.
501 * \param [in] y The y coordinate of the given point.
502 * \return The shortest distance from the object to the point. If the
503 * distance cannot be calculated, this function returns a really large
504 * number (G_MAXDOUBLE). If an error occurs, this function returns
507 double o_shortest_distance (OBJECT
*object
, int x
, int y
)
509 return o_shortest_distance_full (object
, x
, y
, FALSE
);
512 /*! \brief Calculates the distance between the given point and the closest
513 * point on the given object. Allows forcing objects to solid.
515 * \param [in] object The given object.
516 * \param [in] x The x coordinate of the given point.
517 * \param [in] y The y coordinate of the given point.
518 * \param [in] force_solid If true, force treating the object as solid.
519 * \return The shortest distance from the object to the point. If the
520 * distance cannot be calculated, this function returns a really large
521 * number (G_MAXDOUBLE). If an error occurs, this function returns
524 double o_shortest_distance_full (OBJECT
*object
, int x
, int y
, int force_solid
)
526 double shortest_distance
= G_MAXDOUBLE
;
527 double (*func
) (OBJECT
*, int, int, int) = NULL
;
529 g_return_val_if_fail (object
!= NULL
, G_MAXDOUBLE
);
531 switch(object
->type
) {
535 case OBJ_LINE
: func
= o_line_shortest_distance
; break;
536 case OBJ_BOX
: func
= o_box_shortest_distance
; break;
537 case OBJ_PICTURE
: func
= o_picture_shortest_distance
; break;
538 case OBJ_CIRCLE
: func
= o_circle_shortest_distance
; break;
539 case OBJ_PLACEHOLDER
:
540 case OBJ_COMPLEX
: func
= o_complex_shortest_distance
; break;
541 case OBJ_TEXT
: func
= o_text_shortest_distance
; break;
542 case OBJ_PATH
: func
= o_path_shortest_distance
; break;
543 case OBJ_ARC
: func
= o_arc_shortest_distance
; break;
545 g_critical ("o_shortest_distance: object %p has bad type '%c'\n",
546 object
, object
->type
);
550 shortest_distance
= (*func
) (object
, x
, y
, force_solid
);
553 return shortest_distance
;
556 /*! \brief Mark an OBJECT's cached bounds as invalid
557 * \par Function Description
558 * Recursively marks the cached bounds of the given OBJECT and its
559 * parents as having been invalidated and in need of an update. They
560 * will be recalculated next time the OBJECT's bounds are requested
561 * (e.g. via world_get_single_object_bounds() ).
562 * \param [in] toplevel
565 * \todo Turn this into a macro?
567 void o_bounds_invalidate(TOPLEVEL
*toplevel
, OBJECT
*obj
)
570 obj
->w_bounds_valid
= FALSE
;
571 } while ((obj
= obj
->parent
) != NULL
);
575 /*! \brief Change the color of an object
577 * \par Function Description
578 * This function changes the color of an object.
580 * \param [in] toplevel The TOPLEVEL structure.
581 * \param [in] object The OBJECT to change color.
582 * \param [in] color The new color.
584 void o_set_color (TOPLEVEL
*toplevel
, OBJECT
*object
, int color
)
586 g_return_if_fail (object
!= NULL
);
588 object
->color
= color
;
590 if (object
->type
== OBJ_COMPLEX
||
591 object
->type
== OBJ_PLACEHOLDER
)
592 o_glist_set_color (toplevel
, object
->complex->prim_objs
, color
);
596 /*! \brief Get an object's parent PAGE.
598 * \par Function Description
599 * Returns the PAGE structure which owns \a object. If \a object is
600 * not currently associated with a PAGE, returns NULL. If \a object is
601 * part of a compound object, recurses upward.
603 * \param [in] toplevel The TOPLEVEL structure.
604 * \param [in] object The OBJECT for which to retrieve the parent PAGE.
605 * \return The PAGE which owns \a object or NULL.
607 * \sa s_page_append_object() s_page_append() s_page_remove()
610 o_get_page (TOPLEVEL
*toplevel
, OBJECT
*object
)
612 if (object
->parent
!= NULL
) {
613 return o_get_page (toplevel
, object
->parent
);
618 /*! \brief Get an object's parent PAGE, or fall back to global current page.
620 * \par Function Description
621 * If set, returns the PAGE structure which owns \a object. If \a
622 * object does not have a parent page set, returns the global current
623 * page from \a toplevel. If the object parent page is inconsistent
624 * with the global current page, a critical-level error message is
627 * \warning This function is primarily intended to assist in the
628 * migration of code from using the TOPLEVEL current page to using the
629 * o_get_page(). It should not be used in new code.
631 * \deprecated Use o_get_page() in new code.
633 * \param [in] toplevel The TOPLEVEL structure.
634 * \param [in] object The OBJECT for which to retrieve the parent PAGE.
635 * \return The PAGE which owns \a object, the global current PAGE, or NULL.
638 o_get_page_compat (TOPLEVEL
*toplevel
, OBJECT
*object
) {
639 PAGE
*page
= o_get_page (toplevel
, object
);
640 if (page
!= toplevel
->page_current
) {
641 g_critical ("o_get_page_compat: OBJECT.page = %p, TOPLEVEL.page_current = %p",
642 page
, toplevel
->page_current
);
643 return toplevel
->page_current
;
649 /* Structure for each entry in a TOPLEVEL's list of registered change
650 * notification handlers */
651 struct change_notify_entry
{
652 ChangeNotifyFunc pre_change_func
;
653 ChangeNotifyFunc change_func
;
657 /*! \brief Add change notification handlers to a TOPLEVEL.
658 * \par Function Description
659 * Adds a set of change notification handlers to a #TOPLEVEL instance.
660 * \a pre_change_func will be called just before an object is
661 * modified, and \a change_func will be called just after an object is
662 * modified, with the affected object and the given \a user_data.
664 * \param toplevel #TOPLEVEL structure to add handlers to.
665 * \param pre_change_func Function to be called just before changes.
666 * \param change_func Function to be called just after changes.
667 * \param user_data User data to be passed to callback functions.
670 o_add_change_notify (TOPLEVEL
*toplevel
,
671 ChangeNotifyFunc pre_change_func
,
672 ChangeNotifyFunc change_func
,
675 struct change_notify_entry
*entry
= g_new0 (struct change_notify_entry
, 1);
676 entry
->pre_change_func
= pre_change_func
;
677 entry
->change_func
= change_func
;
678 entry
->user_data
= user_data
;
679 toplevel
->change_notify_funcs
=
680 g_list_prepend (toplevel
->change_notify_funcs
, entry
);
683 /*! \brief Remove change notification handlers from a TOPLEVEL.
684 * \par Function Description
685 * Removes a set of change notification handlers and their associated
686 * \a user_data from \a toplevel. If no registered set of handlers
687 * matches the given \a pre_change_func, \a change_func and \a
688 * user_data, does nothing.
690 * \see o_add_change_notify()
692 * \param toplevel #TOPLEVEL structure to remove handlers from.
693 * \param pre_change_func Function called just before changes.
694 * \param change_func Function called just after changes.
695 * \param user_data User data passed to callback functions.
698 o_remove_change_notify (TOPLEVEL
*toplevel
,
699 ChangeNotifyFunc pre_change_func
,
700 ChangeNotifyFunc change_func
,
704 for (iter
= toplevel
->change_notify_funcs
;
705 iter
!= NULL
; iter
= g_list_next (iter
)) {
707 struct change_notify_entry
*entry
=
708 (struct change_notify_entry
*) iter
->data
;
711 && (entry
->pre_change_func
== pre_change_func
)
712 && (entry
->change_func
== change_func
)
713 && (entry
->user_data
== user_data
)) {
718 toplevel
->change_notify_funcs
=
719 g_list_remove_all (toplevel
->change_notify_funcs
, NULL
);
722 /*! \brief Emit an object pre-change notification.
723 * \par Function Description
724 * Calls each pre-change callback function registered with #TOPLEVEL
725 * to notify listeners that \a object is about to be modified. All
726 * libgeda functions that modify #OBJECT structures should call this
727 * just before making a change to an #OBJECT.
729 * \param toplevel #TOPLEVEL structure to emit notifications from.
730 * \param object #OBJECT structure to emit notifications for.
733 o_emit_pre_change_notify (TOPLEVEL
*toplevel
, OBJECT
*object
)
736 for (iter
= toplevel
->change_notify_funcs
;
737 iter
!= NULL
; iter
= g_list_next (iter
)) {
739 struct change_notify_entry
*entry
=
740 (struct change_notify_entry
*) iter
->data
;
742 if ((entry
!= NULL
) && (entry
->pre_change_func
!= NULL
)) {
743 entry
->pre_change_func (entry
->user_data
, object
);
748 /*! \brief Emit an object change notification.
749 * \par Function Description
750 * Calls each change callback function registered with #TOPLEVEL to
751 * notify listeners that \a object has just been modified. All
752 * libgeda functions that modify #OBJECT structures should call this
753 * just after making a change to an #OBJECT.
755 * \param toplevel #TOPLEVEL structure to emit notifications from.
756 * \param object #OBJECT structure to emit notifications for.
759 o_emit_change_notify (TOPLEVEL
*toplevel
, OBJECT
*object
)
762 for (iter
= toplevel
->change_notify_funcs
;
763 iter
!= NULL
; iter
= g_list_next (iter
)) {
765 struct change_notify_entry
*entry
=
766 (struct change_notify_entry
*) iter
->data
;
768 if ((entry
!= NULL
) && (entry
->change_func
!= NULL
)) {
769 entry
->change_func (entry
->user_data
, object
);
774 /*! \brief Query visibility of the object.
775 * \par Function Description
776 * Attribute getter for the visible field within the object.
778 * \param toplevel The TOPLEVEL structure
779 * \param object The OBJECT structure to be queried
780 * \return TRUE when VISIBLE, FALSE otherwise
783 o_is_visible (TOPLEVEL
*toplevel
, OBJECT
*object
)
785 g_return_val_if_fail (object
!= NULL
, FALSE
);
786 return object
->visibility
== VISIBLE
;
789 /*! \brief Set visibility of the object.
790 * \par Function Description
791 * Set value of visibility field within the object.
792 * If resulting visibility value is changed,
793 * invalidate the bounds of the object and parent objects.
795 * \param toplevel The #TOPLEVEL structure
796 * \param object The #OBJECT structure to be modified
799 o_set_visibility (TOPLEVEL
*toplevel
, OBJECT
*object
, int visibility
)
801 g_return_if_fail (object
!= NULL
);
802 if (object
->visibility
!= visibility
) {
803 object
->visibility
= visibility
;
804 o_bounds_invalidate (toplevel
, object
);