1 /* ADG - Automatic Drawing Generation
2 * Copyright (C) 2007,2008,2009,2010 Nicola Fontana <ntd at entidi.it>
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser 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.
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 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
23 * @short_description: The drawing container
25 * The canvas is the toplevel entity of an ADG drawing. It can be
26 * bound to a GTK+ widget, such as #AdgGtkArea, or manually rendered
27 * to a custom surface.
33 * All fields are private and should not be used directly.
34 * Use its public methods instead.
38 #include "adg-internal.h"
39 #include "adg-canvas.h"
40 #include "adg-canvas-private.h"
41 #include "adg-dress-builtins.h"
42 #include "adg-color-style.h"
44 #define _ADG_OLD_OBJECT_CLASS ((GObjectClass *) adg_canvas_parent_class)
45 #define _ADG_OLD_ENTITY_CLASS ((AdgEntityClass *) adg_canvas_parent_class)
48 G_DEFINE_TYPE(AdgCanvas
, adg_canvas
, ADG_TYPE_CONTAINER
);
53 PROP_BACKGROUND_DRESS
,
68 static void _adg_dispose (GObject
*object
);
69 static void _adg_get_property (GObject
*object
,
73 static void _adg_set_property (GObject
*object
,
77 static void _adg_global_changed (AdgEntity
*entity
);
78 static void _adg_local_changed (AdgEntity
*entity
);
79 static void _adg_invalidate (AdgEntity
*entity
);
80 static void _adg_arrange (AdgEntity
*entity
);
81 static void _adg_render (AdgEntity
*entity
,
86 adg_canvas_class_init(AdgCanvasClass
*klass
)
88 GObjectClass
*gobject_class
;
89 AdgEntityClass
*entity_class
;
92 gobject_class
= (GObjectClass
*) klass
;
93 entity_class
= (AdgEntityClass
*) klass
;
95 g_type_class_add_private(klass
, sizeof(AdgCanvasPrivate
));
97 gobject_class
->dispose
= _adg_dispose
;
98 gobject_class
->get_property
= _adg_get_property
;
99 gobject_class
->set_property
= _adg_set_property
;
101 entity_class
->global_changed
= _adg_global_changed
;
102 entity_class
->local_changed
= _adg_local_changed
;
103 entity_class
->invalidate
= _adg_invalidate
;
104 entity_class
->arrange
= _adg_arrange
;
105 entity_class
->render
= _adg_render
;
107 param
= g_param_spec_boxed("size",
109 P_("The size set on this canvas: use 0 to have an automatic dimension based on the canvas extents"),
112 g_object_class_install_property(gobject_class
, PROP_SIZE
, param
);
114 param
= adg_param_spec_dress("background-dress",
115 P_("Background Dress"),
116 P_("The color dress to use for the canvas background"),
117 ADG_DRESS_COLOR_BACKGROUND
,
119 g_object_class_install_property(gobject_class
, PROP_BACKGROUND_DRESS
, param
);
121 param
= adg_param_spec_dress("frame-dress",
123 P_("Line dress to use while drawing the frame around the canvas"),
124 ADG_DRESS_LINE_FRAME
,
126 g_object_class_install_property(gobject_class
, PROP_FRAME_DRESS
, param
);
128 param
= g_param_spec_object("title-block",
130 P_("The title block to assign to this canvas"),
131 ADG_TYPE_TITLE_BLOCK
,
133 g_object_class_install_property(gobject_class
, PROP_TITLE_BLOCK
, param
);
135 param
= g_param_spec_double("top-margin",
137 P_("The margin (in identity space) to leave above the frame"),
138 G_MINDOUBLE
, G_MAXDOUBLE
, 15,
140 g_object_class_install_property(gobject_class
, PROP_TOP_MARGIN
, param
);
142 param
= g_param_spec_double("right-margin",
144 P_("The margin (in identity space) to leave empty at the right of the frame"),
145 G_MINDOUBLE
, G_MAXDOUBLE
, 15,
147 g_object_class_install_property(gobject_class
, PROP_RIGHT_MARGIN
, param
);
149 param
= g_param_spec_double("bottom-margin",
151 P_("The margin (in identity space) to leave empty below the frame"),
152 G_MINDOUBLE
, G_MAXDOUBLE
, 15,
154 g_object_class_install_property(gobject_class
, PROP_BOTTOM_MARGIN
, param
);
156 param
= g_param_spec_double("left-margin",
158 P_("The margin (in identity space) to leave empty at the left of the frame"),
159 G_MINDOUBLE
, G_MAXDOUBLE
, 15,
161 g_object_class_install_property(gobject_class
, PROP_LEFT_MARGIN
, param
);
163 param
= g_param_spec_boolean("has-frame",
164 P_("Has Frame Flag"),
165 P_("If enabled, a frame using the frame dress will be drawn around the canvas extents, taking into account the margins"),
168 g_object_class_install_property(gobject_class
, PROP_HAS_FRAME
, param
);
170 param
= g_param_spec_double("top-padding",
172 P_("The padding (in identity space) to leave empty above between the drawing and the frame"),
173 G_MINDOUBLE
, G_MAXDOUBLE
, 15,
175 g_object_class_install_property(gobject_class
, PROP_TOP_PADDING
, param
);
177 param
= g_param_spec_double("right-padding",
179 P_("The padding (in identity space) to leave empty at the right between the drawing and the frame"),
180 G_MINDOUBLE
, G_MAXDOUBLE
, 15,
182 g_object_class_install_property(gobject_class
, PROP_RIGHT_PADDING
, param
);
184 param
= g_param_spec_double("bottom-padding",
185 P_("Bottom Padding"),
186 P_("The padding (in identity space) to leave empty below between the drawing and the frame"),
187 G_MINDOUBLE
, G_MAXDOUBLE
, 15,
189 g_object_class_install_property(gobject_class
, PROP_BOTTOM_PADDING
, param
);
191 param
= g_param_spec_double("left-padding",
193 P_("The padding (in identity space) to leave empty at the left between the drawing and the frame"),
194 G_MINDOUBLE
, G_MAXDOUBLE
, 15,
196 g_object_class_install_property(gobject_class
, PROP_LEFT_PADDING
, param
);
200 adg_canvas_init(AdgCanvas
*canvas
)
202 AdgCanvasPrivate
*data
= G_TYPE_INSTANCE_GET_PRIVATE(canvas
,
208 data
->background_dress
= ADG_DRESS_COLOR_BACKGROUND
;
209 data
->frame_dress
= ADG_DRESS_LINE_FRAME
;
210 data
->title_block
= NULL
;
211 data
->top_margin
= 15;
212 data
->right_margin
= 15;
213 data
->bottom_margin
= 15;
214 data
->left_margin
= 15;
215 data
->has_frame
= TRUE
;
216 data
->top_padding
= 15;
217 data
->right_padding
= 15;
218 data
->bottom_padding
= 15;
219 data
->left_padding
= 15;
225 _adg_dispose(GObject
*object
)
227 AdgCanvasPrivate
*data
= ((AdgCanvas
*) object
)->data
;
229 if (data
->title_block
) {
230 g_object_unref(data
->title_block
);
231 data
->title_block
= NULL
;
234 if (_ADG_OLD_OBJECT_CLASS
->dispose
)
235 _ADG_OLD_OBJECT_CLASS
->dispose(object
);
240 _adg_get_property(GObject
*object
, guint prop_id
,
241 GValue
*value
, GParamSpec
*pspec
)
243 AdgCanvasPrivate
*data
= ((AdgCanvas
*) object
)->data
;
247 g_value_set_boxed(value
, &data
->size
);
249 case PROP_BACKGROUND_DRESS
:
250 g_value_set_int(value
, data
->background_dress
);
252 case PROP_FRAME_DRESS
:
253 g_value_set_int(value
, data
->frame_dress
);
255 case PROP_TITLE_BLOCK
:
256 g_value_set_object(value
, data
->title_block
);
258 case PROP_TOP_MARGIN
:
259 g_value_set_double(value
, data
->top_margin
);
261 case PROP_RIGHT_MARGIN
:
262 g_value_set_double(value
, data
->right_margin
);
264 case PROP_BOTTOM_MARGIN
:
265 g_value_set_double(value
, data
->bottom_margin
);
267 case PROP_LEFT_MARGIN
:
268 g_value_set_double(value
, data
->left_margin
);
271 g_value_set_boolean(value
, data
->has_frame
);
273 case PROP_TOP_PADDING
:
274 g_value_set_double(value
, data
->top_padding
);
276 case PROP_RIGHT_PADDING
:
277 g_value_set_double(value
, data
->right_padding
);
279 case PROP_BOTTOM_PADDING
:
280 g_value_set_double(value
, data
->bottom_padding
);
282 case PROP_LEFT_PADDING
:
283 g_value_set_double(value
, data
->left_padding
);
286 G_OBJECT_WARN_INVALID_PROPERTY_ID(object
, prop_id
, pspec
);
292 _adg_set_property(GObject
*object
, guint prop_id
,
293 const GValue
*value
, GParamSpec
*pspec
)
296 AdgCanvasPrivate
*data
;
297 AdgTitleBlock
*title_block
;
299 canvas
= (AdgCanvas
*) object
;
304 adg_pair_copy(&data
->size
, g_value_get_boxed(value
));
306 case PROP_BACKGROUND_DRESS
:
307 data
->background_dress
= g_value_get_int(value
);
309 case PROP_FRAME_DRESS
:
310 data
->frame_dress
= g_value_get_int(value
);
312 case PROP_TITLE_BLOCK
:
313 title_block
= g_value_get_object(value
);
315 g_object_ref(title_block
);
316 adg_entity_set_parent((AdgEntity
*) title_block
,
317 (AdgEntity
*) canvas
);
319 if (data
->title_block
)
320 g_object_unref(data
->title_block
);
321 data
->title_block
= title_block
;
323 case PROP_TOP_MARGIN
:
324 data
->top_margin
= g_value_get_double(value
);
326 case PROP_RIGHT_MARGIN
:
327 data
->right_margin
= g_value_get_double(value
);
329 case PROP_BOTTOM_MARGIN
:
330 data
->bottom_margin
= g_value_get_double(value
);
332 case PROP_LEFT_MARGIN
:
333 data
->left_margin
= g_value_get_double(value
);
336 data
->has_frame
= g_value_get_boolean(value
);
338 case PROP_TOP_PADDING
:
339 data
->top_padding
= g_value_get_double(value
);
341 case PROP_RIGHT_PADDING
:
342 data
->right_padding
= g_value_get_double(value
);
344 case PROP_BOTTOM_PADDING
:
345 data
->bottom_padding
= g_value_get_double(value
);
347 case PROP_LEFT_PADDING
:
348 data
->left_padding
= g_value_get_double(value
);
351 G_OBJECT_WARN_INVALID_PROPERTY_ID(object
, prop_id
, pspec
);
360 * Creates a new empty canvas object.
362 * Returns: the canvas
367 return g_object_new(ADG_TYPE_CANVAS
, NULL
);
371 * adg_canvas_set_size:
372 * @canvas: an #AdgCanvas
373 * @size: the new size for the canvas
375 * Sets a specific size on @canvas. The x and/or y
376 * components of the returned #AdgPair could be %0, in which
377 * case the size returned by adg_entity_get_extents() on
378 * @canvas will be used instead.
381 adg_canvas_set_size(AdgCanvas
*canvas
, const AdgPair
*size
)
383 g_return_if_fail(ADG_IS_CANVAS(canvas
));
384 g_return_if_fail(size
!= NULL
);
386 g_object_set((GObject
*) canvas
, "size", size
, NULL
);
390 * adg_canvas_set_size_explicit:
391 * @canvas: an #AdgCanvas
392 * @x: the new width of the canvas or %0 to reset
393 * @y: the new height of the canvas or %0 to reset
395 * A convenient function to set the size of @canvas using
396 * explicit coordinates. Check adg_canvas_set_size() for
400 adg_canvas_set_size_explicit(AdgCanvas
*canvas
, gdouble x
, gdouble y
)
407 adg_canvas_set_size(canvas
, &size
);
411 * adg_canvas_get_size:
412 * @canvas: an #AdgCanvas
414 * Gets the specific size set on @canvas. The x and/or y
415 * components of the returned #AdgPair could be %0, in which
416 * case the size returned by adg_entity_get_extents() on
417 * @canvas will be used instead.
419 * Returns: the explicit size set on this canvas or %NULL on errors
422 adg_canvas_get_size(AdgCanvas
*canvas
)
424 AdgCanvasPrivate
*data
;
426 g_return_val_if_fail(ADG_IS_CANVAS(canvas
), NULL
);
433 * adg_canvas_set_background_dress:
434 * @canvas: an #AdgCanvas
435 * @dress: the new #AdgDress to use
437 * Sets a new background dress for rendering @canvas: the new
438 * dress must be a color dress.
441 adg_canvas_set_background_dress(AdgCanvas
*canvas
, AdgDress dress
)
443 g_return_if_fail(ADG_IS_CANVAS(canvas
));
444 g_object_set((GObject
*) canvas
, "background-dress", dress
, NULL
);
448 * adg_canvas_get_background_dress:
449 * @canvas: an #AdgCanvas
451 * Gets the background dress to be used in rendering @canvas.
453 * Returns: the current background dress
456 adg_canvas_get_background_dress(AdgCanvas
*canvas
)
458 AdgCanvasPrivate
*data
;
460 g_return_val_if_fail(ADG_IS_CANVAS(canvas
), ADG_DRESS_UNDEFINED
);
464 return data
->background_dress
;
468 * adg_canvas_set_frame_dress:
469 * @canvas: an #AdgCanvas
470 * @dress: the new #AdgDress to use
472 * Sets the #AdgCanvas:frame-dress property of @canvas to @dress:
473 * the new dress must be a line dress.
476 adg_canvas_set_frame_dress(AdgCanvas
*canvas
, AdgDress dress
)
478 g_return_if_fail(ADG_IS_CANVAS(canvas
));
479 g_object_set((GObject
*) canvas
, "frame-dress", dress
, NULL
);
483 * adg_canvas_get_frame_dress:
484 * @canvas: an #AdgCanvas
486 * Gets the frame dress to be used in rendering the border of @canvas.
488 * Returns: the current frame dress
491 adg_canvas_get_frame_dress(AdgCanvas
*canvas
)
493 AdgCanvasPrivate
*data
;
495 g_return_val_if_fail(ADG_IS_CANVAS(canvas
), ADG_DRESS_UNDEFINED
);
498 return data
->frame_dress
;
502 * adg_canvas_set_title_block:
503 * @canvas: an #AdgCanvas
504 * @title_block: a title block
506 * Sets the #AdgCanvas:title-block property of @canvas to @title_block.
508 * Although a title block entity could be added to @canvas in the usual
509 * way, that is using the adg_container_add() method, assigning a title
510 * block with adg_canvas_set_title_block() is somewhat different:
512 * - @title_block will be automatically attached to the bottom right
513 * corner of to the @canvas frame (this could be accomplished in the
514 * usual way too, by resetting the right and bottom paddings);
515 * - the @title_block boundary box is not taken into account while
516 * computing the extents of @canvas.
519 adg_canvas_set_title_block(AdgCanvas
*canvas
, AdgTitleBlock
*title_block
)
521 g_return_if_fail(ADG_IS_CANVAS(canvas
));
522 g_return_if_fail(title_block
== NULL
|| ADG_IS_TITLE_BLOCK(title_block
));
523 g_object_set((GObject
*) canvas
, "title-block", title_block
, NULL
);
527 * adg_canvas_get_title_block:
528 * @canvas: an #AdgCanvas
530 * Gets the #AdgTitleBlock object of @canvas: check
531 * adg_canvas_set_title_block() for details.
533 * Returns: the title block object or %NULL
536 adg_canvas_get_title_block(AdgCanvas
*canvas
)
538 AdgCanvasPrivate
*data
;
540 g_return_val_if_fail(ADG_IS_CANVAS(canvas
), NULL
);
543 return data
->title_block
;
547 * adg_canvas_set_top_margin:
548 * @canvas: an #AdgCanvas
549 * @value: the new margin, in identity space
551 * Changes the top margin of @canvas by setting #AdgCanvas:top-margin
552 * to @value. Negative values are allowed.
555 adg_canvas_set_top_margin(AdgCanvas
*canvas
, gdouble value
)
557 g_return_if_fail(ADG_IS_CANVAS(canvas
));
558 g_object_set((GObject
*) canvas
, "top-margin", value
, NULL
);
562 * adg_canvas_get_top_margin:
563 * @canvas: an #AdgCanvas
565 * Gets the top margin (in identity space) of @canvas.
567 * Returns: the requested margin or %0 on error
570 adg_canvas_get_top_margin(AdgCanvas
*canvas
)
572 AdgCanvasPrivate
*data
;
574 g_return_val_if_fail(ADG_IS_CANVAS(canvas
), 0.);
577 return data
->top_margin
;
581 * adg_canvas_set_right_margin:
582 * @canvas: an #AdgCanvas
583 * @value: the new margin, in identity space
585 * Changes the right margin of @canvas by setting #AdgCanvas:right-margin
586 * to @value. Negative values are allowed.
589 adg_canvas_set_right_margin(AdgCanvas
*canvas
, gdouble value
)
591 g_return_if_fail(ADG_IS_CANVAS(canvas
));
592 g_object_set((GObject
*) canvas
, "right-margin", value
, NULL
);
596 * adg_canvas_get_right_margin:
597 * @canvas: an #AdgCanvas
599 * Gets the right margin (in identity space) of @canvas.
601 * Returns: the requested margin or %0 on error
604 adg_canvas_get_right_margin(AdgCanvas
*canvas
)
606 AdgCanvasPrivate
*data
;
608 g_return_val_if_fail(ADG_IS_CANVAS(canvas
), 0.);
611 return data
->right_margin
;
616 * adg_canvas_set_bottom_margin:
617 * @canvas: an #AdgCanvas
618 * @value: the new margin, in identity space
620 * Changes the bottom margin of @canvas by setting #AdgCanvas:bottom-margin
621 * to @value. Negative values are allowed.
624 adg_canvas_set_bottom_margin(AdgCanvas
*canvas
, gdouble value
)
626 g_return_if_fail(ADG_IS_CANVAS(canvas
));
627 g_object_set((GObject
*) canvas
, "bottom-margin", value
, NULL
);
631 * adg_canvas_get_bottom_margin:
632 * @canvas: an #AdgCanvas
634 * Gets the bottom margin (in identity space) of @canvas.
636 * Returns: the requested margin or %0 on error
639 adg_canvas_get_bottom_margin(AdgCanvas
*canvas
)
641 AdgCanvasPrivate
*data
;
643 g_return_val_if_fail(ADG_IS_CANVAS(canvas
), 0.);
646 return data
->bottom_margin
;
650 * adg_canvas_set_left_margin:
651 * @canvas: an #AdgCanvas
652 * @value: the new margin, in identity space
654 * Changes the left margin of @canvas by setting #AdgCanvas:left-margin
655 * to @value. Negative values are allowed.
658 adg_canvas_set_left_margin(AdgCanvas
*canvas
, gdouble value
)
660 g_return_if_fail(ADG_IS_CANVAS(canvas
));
661 g_object_set((GObject
*) canvas
, "left-margin", value
, NULL
);
665 * adg_canvas_get_left_margin:
666 * @canvas: an #AdgCanvas
668 * Gets the left margin (in identity space) of @canvas.
670 * Returns: the requested margin or %0 on error
673 adg_canvas_get_left_margin(AdgCanvas
*canvas
)
675 AdgCanvasPrivate
*data
;
677 g_return_val_if_fail(ADG_IS_CANVAS(canvas
), 0.);
680 return data
->left_margin
;
684 * adg_canvas_set_margins:
685 * @canvas: an #AdgCanvas
686 * @top: top margin, in identity space
687 * @right: right margin, in identity space
688 * @bottom: bottom margin, in identity space
689 * @left: left margin, in identity space
691 * Convenient function to set all the margins at once.
694 adg_canvas_set_margins(AdgCanvas
*canvas
, gdouble top
, gdouble right
,
695 gdouble bottom
, gdouble left
)
697 g_return_if_fail(ADG_IS_CANVAS(canvas
));
698 g_object_set((GObject
*) canvas
,
700 "right-margin", right
,
701 "bottom-margin", bottom
,
707 * adg_canvas_switch_frame:
708 * @canvas: an #AdgCanvas
709 * @new_state: the new flag status
711 * Sets a new status on the #AdgCanvas:has-frame property: %TRUE
712 * means a border around the canvas extents (less the margins)
713 * should be rendered.
716 adg_canvas_switch_frame(AdgCanvas
*canvas
, gboolean new_state
)
718 g_return_if_fail(ADG_IS_CANVAS(canvas
));
719 g_object_set((GObject
*) canvas
, "has-frame", new_state
, NULL
);
723 * adg_canvas_has_frame:
724 * @canvas: an #AdgCanvas
726 * Gets the current status of the #AdgCanvas:has-frame property,
727 * that is whether a border around the canvas extents (less the
728 * margins) should be rendered (%TRUE) or not (%FALSE).
730 * Returns: the current status of the frame flag
733 adg_canvas_has_frame(AdgCanvas
*canvas
)
735 AdgCanvasPrivate
*data
;
737 g_return_val_if_fail(ADG_IS_CANVAS(canvas
), FALSE
);
740 return data
->has_frame
;
744 * adg_canvas_set_top_padding:
745 * @canvas: an #AdgCanvas
746 * @value: the new padding, in identity space
748 * Changes the top padding of @canvas by setting #AdgCanvas:top-padding
749 * to @value. Negative values are allowed.
752 adg_canvas_set_top_padding(AdgCanvas
*canvas
, gdouble value
)
754 g_return_if_fail(ADG_IS_CANVAS(canvas
));
755 g_object_set((GObject
*) canvas
, "top-padding", value
, NULL
);
759 * adg_canvas_get_top_padding:
760 * @canvas: an #AdgCanvas
762 * Gets the top padding (in identity space) of @canvas.
764 * Returns: the requested padding or %0 on error
767 adg_canvas_get_top_padding(AdgCanvas
*canvas
)
769 AdgCanvasPrivate
*data
;
771 g_return_val_if_fail(ADG_IS_CANVAS(canvas
), 0.);
774 return data
->top_padding
;
778 * adg_canvas_set_right_padding:
779 * @canvas: an #AdgCanvas
780 * @value: the new padding, in identity space
782 * Changes the right padding of @canvas by setting #AdgCanvas:right-padding
783 * to @value. Negative values are allowed.
786 adg_canvas_set_right_padding(AdgCanvas
*canvas
, gdouble value
)
788 g_return_if_fail(ADG_IS_CANVAS(canvas
));
789 g_object_set((GObject
*) canvas
, "right-padding", value
, NULL
);
793 * adg_canvas_get_right_padding:
794 * @canvas: an #AdgCanvas
796 * Gets the right padding (in identity space) of @canvas.
798 * Returns: the requested padding or %0 on error
801 adg_canvas_get_right_padding(AdgCanvas
*canvas
)
803 AdgCanvasPrivate
*data
;
805 g_return_val_if_fail(ADG_IS_CANVAS(canvas
), 0.);
808 return data
->right_padding
;
813 * adg_canvas_set_bottom_padding:
814 * @canvas: an #AdgCanvas
815 * @value: the new padding, in identity space
817 * Changes the bottom padding of @canvas by setting #AdgCanvas:bottom-padding
818 * to @value. Negative values are allowed.
821 adg_canvas_set_bottom_padding(AdgCanvas
*canvas
, gdouble value
)
823 g_return_if_fail(ADG_IS_CANVAS(canvas
));
824 g_object_set((GObject
*) canvas
, "bottom-padding", value
, NULL
);
828 * adg_canvas_get_bottom_padding:
829 * @canvas: an #AdgCanvas
831 * Gets the bottom padding (in identity space) of @canvas.
833 * Returns: the requested padding or %0 on error
836 adg_canvas_get_bottom_padding(AdgCanvas
*canvas
)
838 AdgCanvasPrivate
*data
;
840 g_return_val_if_fail(ADG_IS_CANVAS(canvas
), 0.);
843 return data
->bottom_padding
;
847 * adg_canvas_set_left_padding:
848 * @canvas: an #AdgCanvas
849 * @value: the new padding, in identity space
851 * Changes the left padding of @canvas by setting #AdgCanvas:left-padding
852 * to @value. Negative values are allowed.
855 adg_canvas_set_left_padding(AdgCanvas
*canvas
, gdouble value
)
857 g_return_if_fail(ADG_IS_CANVAS(canvas
));
858 g_object_set((GObject
*) canvas
, "left-padding", value
, NULL
);
862 * adg_canvas_get_left_padding:
863 * @canvas: an #AdgCanvas
865 * Gets the left padding (in identity space) of @canvas.
867 * Returns: the requested padding or %0 on error
870 adg_canvas_get_left_padding(AdgCanvas
*canvas
)
872 AdgCanvasPrivate
*data
;
874 g_return_val_if_fail(ADG_IS_CANVAS(canvas
), 0.);
877 return data
->left_padding
;
881 * adg_canvas_set_paddings:
882 * @canvas: an #AdgCanvas
883 * @top: top padding, in identity space
884 * @right: right padding, in identity space
885 * @bottom: bottom padding, in identity space
886 * @left: left padding, in identity space
888 * Convenient function to set all the paddings at once.
891 adg_canvas_set_paddings(AdgCanvas
*canvas
, gdouble top
, gdouble right
,
892 gdouble bottom
, gdouble left
)
894 g_return_if_fail(ADG_IS_CANVAS(canvas
));
895 g_object_set((GObject
*) canvas
,
897 "right-padding", right
,
898 "bottom-padding", bottom
,
899 "left-padding", left
,
905 _adg_global_changed(AdgEntity
*entity
)
907 AdgCanvasPrivate
*data
= ((AdgCanvas
*) entity
)->data
;
909 if (_ADG_OLD_ENTITY_CLASS
->global_changed
)
910 _ADG_OLD_ENTITY_CLASS
->global_changed(entity
);
912 if (data
->title_block
)
913 adg_entity_global_changed((AdgEntity
*) data
->title_block
);
917 _adg_local_changed(AdgEntity
*entity
)
919 AdgCanvasPrivate
*data
= ((AdgCanvas
*) entity
)->data
;
921 if (_ADG_OLD_ENTITY_CLASS
->local_changed
)
922 _ADG_OLD_ENTITY_CLASS
->local_changed(entity
);
924 if (data
->title_block
)
925 adg_entity_local_changed((AdgEntity
*) data
->title_block
);
929 _adg_invalidate(AdgEntity
*entity
)
931 AdgCanvasPrivate
*data
= ((AdgCanvas
*) entity
)->data
;
933 if (_ADG_OLD_ENTITY_CLASS
->invalidate
)
934 _ADG_OLD_ENTITY_CLASS
->invalidate(entity
);
936 if (data
->title_block
)
937 adg_entity_invalidate((AdgEntity
*) data
->title_block
);
941 _adg_arrange(AdgEntity
*entity
)
943 AdgCanvasPrivate
*data
= ((AdgCanvas
*) entity
)->data
;
946 if (_ADG_OLD_ENTITY_CLASS
->arrange
)
947 _ADG_OLD_ENTITY_CLASS
->arrange(entity
);
949 cpml_extents_copy(&extents
, adg_entity_get_extents(entity
));
951 /* The extents should be defined, otherwise there is no drawing */
952 g_return_if_fail(extents
.is_defined
);
954 extents
.org
.x
-= data
->left_margin
+ data
->left_padding
;
955 extents
.org
.y
-= data
->top_margin
+ data
->top_padding
;
956 extents
.size
.x
+= data
->left_margin
+ data
->left_padding
;
957 extents
.size
.x
+= data
->right_margin
+ data
->right_padding
;
958 extents
.size
.y
+= data
->top_margin
+ data
->top_padding
;
959 extents
.size
.y
+= data
->bottom_margin
+ data
->bottom_padding
;
960 adg_entity_set_extents(entity
, &extents
);
962 if (data
->title_block
) {
963 AdgEntity
*title_block_entity
;
964 const CpmlExtents
*title_block_extents
;
967 title_block_entity
= (AdgEntity
*) data
->title_block
;
968 adg_entity_arrange(title_block_entity
);
969 title_block_extents
= adg_entity_get_extents(title_block_entity
);
971 shift
.x
= extents
.org
.x
+ extents
.size
.x
- title_block_extents
->org
.x
972 - title_block_extents
->size
.x
- data
->right_margin
;
973 shift
.y
= extents
.org
.y
+ extents
.size
.y
- title_block_extents
->org
.y
974 - title_block_extents
->size
.y
- data
->bottom_margin
;
976 /* The following block could be optimized by skipping tiny shift,
977 * usually left by mathematical roundings */
978 if (shift
.x
!= 0 || shift
.y
!= 0) {
979 AdgMatrix unglobal
, map
;
980 adg_matrix_copy(&unglobal
, adg_entity_get_global_matrix(entity
));
981 cairo_matrix_invert(&unglobal
);
983 cairo_matrix_transform_distance(&unglobal
, &shift
.x
, &shift
.y
);
984 cairo_matrix_init_translate(&map
, shift
.x
, shift
.y
);
985 adg_entity_transform_global_map(title_block_entity
, &map
,
986 ADG_TRANSFORM_AFTER
);
988 adg_entity_global_changed(title_block_entity
);
989 adg_entity_arrange(title_block_entity
);
995 _adg_render(AdgEntity
*entity
, cairo_t
*cr
)
997 AdgCanvasPrivate
*data
;
998 const CpmlExtents
*extents
;
1000 data
= ((AdgCanvas
*) entity
)->data
;
1001 extents
= adg_entity_get_extents(entity
);
1005 /* Background fill */
1006 cairo_identity_matrix(cr
);
1007 cairo_rectangle(cr
, extents
->org
.x
, extents
->org
.y
,
1008 extents
->size
.x
, extents
->size
.y
);
1009 adg_entity_apply_dress(entity
, data
->background_dress
, cr
);
1013 if (data
->has_frame
) {
1015 cpml_extents_copy(&frame
, extents
);
1017 frame
.org
.x
+= data
->left_margin
;
1018 frame
.org
.y
+= data
->top_margin
;
1019 frame
.size
.x
-= data
->left_margin
+ data
->right_margin
;
1020 frame
.size
.y
-= data
->top_margin
+ data
->bottom_margin
;
1022 cairo_rectangle(cr
, frame
.org
.x
, frame
.org
.y
,
1023 frame
.size
.x
, frame
.size
.y
);
1024 cairo_set_matrix(cr
, adg_entity_get_global_matrix(entity
));
1025 adg_entity_apply_dress(entity
, data
->frame_dress
, cr
);
1031 if (data
->title_block
)
1032 adg_entity_render((AdgEntity
*) data
->title_block
, cr
);
1034 if (_ADG_OLD_ENTITY_CLASS
->render
)
1035 _ADG_OLD_ENTITY_CLASS
->render(entity
, cr
);