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: Root abstract class for all dimension entities
25 * The #AdgDim class is the base stub of all the dimension entities.
31 * All fields are private and should not be used directly.
32 * Use its public methods instead.
36 #include "adg-internal.h"
38 #include "adg-dim-private.h"
39 #include "adg-dim-style.h"
40 #include "adg-dress-builtins.h"
41 #include "adg-toy-text.h"
42 #include "adg-type-builtins.h"
44 #define PARENT_OBJECT_CLASS ((GObjectClass *) adg_dim_parent_class)
45 #define PARENT_ENTITY_CLASS ((AdgEntityClass *) adg_dim_parent_class)
63 static void dispose (GObject
*object
);
64 static void finalize (GObject
*object
);
65 static void get_property (GObject
*object
,
69 static void set_property (GObject
*object
,
73 static void global_changed (AdgEntity
*entity
);
74 static void local_changed (AdgEntity
*entity
);
75 static void invalidate (AdgEntity
*entity
);
76 static void arrange (AdgEntity
*entity
);
77 static gchar
* default_value (AdgDim
*dim
);
78 static gdouble
quote_angle (gdouble angle
);
79 static gboolean
set_dim_dress (AdgDim
*dim
,
81 static gboolean
set_value (AdgDim
*dim
,
83 static gboolean
set_min (AdgDim
*dim
,
85 static gboolean
set_max (AdgDim
*dim
,
89 G_DEFINE_ABSTRACT_TYPE(AdgDim
, adg_dim
, ADG_TYPE_ENTITY
);
93 adg_dim_class_init(AdgDimClass
*klass
)
95 GObjectClass
*gobject_class
;
96 AdgEntityClass
*entity_class
;
99 gobject_class
= (GObjectClass
*) klass
;
100 entity_class
= (AdgEntityClass
*) klass
;
102 g_type_class_add_private(klass
, sizeof(AdgDimPrivate
));
104 gobject_class
->dispose
= dispose
;
105 gobject_class
->finalize
= finalize
;
106 gobject_class
->get_property
= get_property
;
107 gobject_class
->set_property
= set_property
;
109 entity_class
->global_changed
= global_changed
;
110 entity_class
->local_changed
= local_changed
;
111 entity_class
->invalidate
= invalidate
;
112 entity_class
->arrange
= arrange
;
114 klass
->quote_angle
= quote_angle
;
115 klass
->default_value
= default_value
;
117 param
= adg_param_spec_dress("dim-dress",
118 P_("Dimension Dress"),
119 P_("The dress to use for rendering this dimension"),
122 g_object_class_install_property(gobject_class
, PROP_DIM_DRESS
, param
);
124 param
= g_param_spec_boxed("ref1",
126 P_("First reference point of the dimension"),
129 g_object_class_install_property(gobject_class
, PROP_REF1
, param
);
131 param
= g_param_spec_boxed("ref2",
133 P_("Second reference point of the dimension"),
136 g_object_class_install_property(gobject_class
, PROP_REF2
, param
);
138 param
= g_param_spec_boxed("pos",
140 P_("The reference position in local space of the quote: it will be combined with \"level\" to get the real quote position"),
143 g_object_class_install_property(gobject_class
, PROP_POS
, param
);
145 param
= g_param_spec_double("level",
147 P_("The dimension level, that is the factor to multiply the baseline spacing (defined in the dimension style) to get the offset from pos where the quote should be rendered"),
148 -G_MAXDOUBLE
, G_MAXDOUBLE
, 1.0,
150 g_object_class_install_property(gobject_class
, PROP_LEVEL
, param
);
152 param
= g_param_spec_enum("outside",
154 P_("Whether the arrows must be inside the extension lines (ADG_THREE_STATE_OFF), must be extended outside the extension lines (ADG_THREE_STATE_ON) or should be automatically handled depending on the available space"),
155 ADG_TYPE_THREE_STATE
, ADG_THREE_STATE_UNKNOWN
,
157 g_object_class_install_property(gobject_class
, PROP_OUTSIDE
, param
);
159 param
= g_param_spec_enum("detached",
160 P_("Detached Quote"),
161 P_("Where the quote must be positioned: in the middle of the base line (ADG_THREE_STATE_OFF), near the pos point (ADG_THREE_STATE_ON) or should be automatically deducted depending on the available space"),
162 ADG_TYPE_THREE_STATE
, ADG_THREE_STATE_UNKNOWN
,
164 g_object_class_install_property(gobject_class
, PROP_DETACHED
, param
);
166 param
= g_param_spec_string("value",
168 P_("The theoretically exact value for this quote: set to NULL to automatically get the default value"),
171 g_object_class_install_property(gobject_class
, PROP_VALUE
, param
);
173 param
= g_param_spec_string("value-min",
174 P_("Minimum Value or Low Tolerance"),
175 P_("The minimum value allowed or the lowest tolerance from value (depending of the dimension style): set to NULL to suppress"),
178 g_object_class_install_property(gobject_class
, PROP_MIN
, param
);
180 param
= g_param_spec_string("value-max",
181 P_("Maximum Value or High Tolerance"),
182 P_("The maximum value allowed or the highest tolerance from value (depending of the dimension style): set to NULL to suppress"),
185 g_object_class_install_property(gobject_class
, PROP_MAX
, param
);
189 adg_dim_init(AdgDim
*dim
)
191 AdgDimPrivate
*data
= G_TYPE_INSTANCE_GET_PRIVATE(dim
, ADG_TYPE_DIM
,
194 data
->dim_dress
= ADG_DRESS_DIMENSION
;
199 data
->outside
= ADG_THREE_STATE_UNKNOWN
;
200 data
->detached
= ADG_THREE_STATE_UNKNOWN
;
209 dispose(GObject
*object
)
211 AdgDimPrivate
*data
= ((AdgDim
*) object
)->data
;
213 if (data
->quote
.entity
!= NULL
) {
214 g_object_unref(data
->quote
.entity
);
215 data
->quote
.entity
= NULL
;
217 if (data
->ref1
!= NULL
) {
218 adg_point_destroy(data
->ref1
);
221 if (data
->ref2
!= NULL
) {
222 adg_point_destroy(data
->ref2
);
225 if (data
->pos
!= NULL
) {
226 adg_point_destroy(data
->pos
);
230 if (PARENT_OBJECT_CLASS
->dispose
)
231 PARENT_OBJECT_CLASS
->dispose(object
);
235 finalize(GObject
*object
)
237 AdgDimPrivate
*data
= ((AdgDim
*) object
)->data
;
243 if (PARENT_OBJECT_CLASS
->finalize
)
244 PARENT_OBJECT_CLASS
->finalize(object
);
248 get_property(GObject
*object
, guint prop_id
, GValue
*value
, GParamSpec
*pspec
)
250 AdgDimPrivate
*data
= ((AdgDim
*) object
)->data
;
254 g_value_set_int(value
, data
->dim_dress
);
257 g_value_set_boxed(value
, data
->ref1
);
260 g_value_set_boxed(value
, data
->ref2
);
263 g_value_set_boxed(value
, data
->pos
);
266 g_value_set_double(value
, data
->level
);
269 g_value_set_enum(value
, data
->outside
);
272 g_value_set_enum(value
, data
->detached
);
275 g_value_set_string(value
, data
->value
);
278 g_value_set_string(value
, data
->min
);
281 g_value_set_string(value
, data
->max
);
284 G_OBJECT_WARN_INVALID_PROPERTY_ID(object
, prop_id
, pspec
);
290 set_property(GObject
*object
, guint prop_id
,
291 const GValue
*value
, GParamSpec
*pspec
)
296 dim
= (AdgDim
*) object
;
301 set_dim_dress(dim
, g_value_get_int(value
));
304 if (data
->ref1
!= NULL
)
305 adg_point_destroy(data
->ref1
);
306 data
->ref1
= g_value_dup_boxed(value
);
309 if (data
->ref2
!= NULL
)
310 adg_point_destroy(data
->ref2
);
311 data
->ref2
= g_value_dup_boxed(value
);
314 if (data
->pos
!= NULL
)
315 adg_point_destroy(data
->pos
);
316 data
->pos
= g_value_dup_boxed(value
);
319 data
->level
= g_value_get_double(value
);
322 data
->outside
= g_value_get_enum(value
);
325 data
->detached
= g_value_get_enum(value
);
328 set_value(dim
, g_value_get_string(value
));
331 set_min(dim
, g_value_get_string(value
));
334 set_max(dim
, g_value_get_string(value
));
337 G_OBJECT_WARN_INVALID_PROPERTY_ID(object
, prop_id
, pspec
);
344 * adg_dim_set_dim_dress:
346 * @dress: the new #AdgDress to use
348 * Sets a new dimension dress to @dim. The new dress must be
349 * related to the original dress for this property: you cannot
350 * set a dress used for line styles to a dress managing fonts.
352 * The check is done by calling adg_dress_are_related() with
353 * @dress and the previous dress as arguments. Check out its
354 * documentation for details on what is a related dress.
357 adg_dim_set_dim_dress(AdgDim
*dim
, AdgDress dress
)
359 g_return_if_fail(ADG_IS_DIM(dim
));
361 if (set_dim_dress(dim
, dress
))
362 g_object_notify((GObject
*) dim
, "dim-dress");
366 * adg_dim_get_dim_dress:
369 * Gets the dimension dress to be used in rendering @dim.
371 * Returns: the current dimension dress
374 adg_dim_get_dim_dress(AdgDim
*dim
)
378 g_return_val_if_fail(ADG_IS_DIM(dim
), ADG_DRESS_UNDEFINED
);
382 return data
->dim_dress
;
388 * @ref1: the ref1 coordinates
389 * @ref2: the ref2 coordinates
391 * Sets the #AdgDim:ref1 and #AdgDim:ref2 reference points
392 * using @ref1 and @ref2 pairs. @ref1 or @ref2 could be
393 * %NULL (but not both), in which case only the non-null
394 * reference point is changed.
397 adg_dim_set_ref(AdgDim
*dim
, const AdgPair
*ref1
, const AdgPair
*ref2
)
402 g_return_if_fail(ADG_IS_DIM(dim
));
403 g_return_if_fail(ref1
!= NULL
|| ref2
!= NULL
);
406 object
= (GObject
*) dim
;
408 g_object_freeze_notify(object
);
411 if (data
->ref1
== NULL
)
412 data
->ref1
= adg_point_new();
414 adg_point_set_pair(data
->ref1
, ref1
);
416 g_object_notify(object
, "ref1");
420 if (data
->ref2
== NULL
)
421 data
->ref2
= adg_point_new();
423 adg_point_set_pair(data
->ref2
, ref2
);
425 g_object_notify(object
, "ref2");
428 g_object_thaw_notify(object
);
432 * adg_dim_set_ref_explicit:
434 * @ref1_x: x coordinate of ref1
435 * @ref1_y: y coordinate of ref1
436 * @ref2_x: x coordinate of ref2
437 * @ref2_y: y coordinate of ref2
439 * Works in the same way as adg_dim_set_ref() but using
440 * explicit coordinates instead of #AdgPair args. The
441 * notable difference is that, by using gdouble values,
442 * you can't set only a single reference point.
445 adg_dim_set_ref_explicit(AdgDim
*dim
,
446 gdouble ref1_x
, gdouble ref1_y
,
447 gdouble ref2_x
, gdouble ref2_y
)
456 adg_dim_set_ref(dim
, &ref1
, &ref2
);
460 * adg_dim_set_ref_from_model:
462 * @model: the source #AdgModel
463 * @ref1: name of the pair in @model to use as ref1
464 * @ref2: name of the pair in @model to use as ref2
466 * Sets #AdgDim:ref1 and #AdgDim:ref2 properties by linking
467 * them to the @ref1 and @ref2 named pairs in @model. @ref1
468 * or @ref2 could be %NULL (but not both), in which case
469 * only the non-null reference point is changed.
471 * Using this function twice you can also link the reference
472 * points to named pairs taken from different models:
475 * adg_dim_set_ref_from_model(dim, model1, ref1, NULL);
476 * adg_dim_set_ref_from_model(dim, model2, NULL, ref2);
480 adg_dim_set_ref_from_model(AdgDim
*dim
, AdgModel
*model
,
481 const gchar
*ref1
, const gchar
*ref2
)
486 g_return_if_fail(ADG_IS_DIM(dim
));
487 g_return_if_fail(ADG_IS_MODEL(model
));
488 g_return_if_fail(ref1
!= NULL
|| ref2
!= NULL
);
490 object
= (GObject
*) dim
;
493 g_object_freeze_notify(object
);
496 if (data
->ref1
== NULL
)
497 data
->ref1
= adg_point_new();
499 adg_point_set_pair_from_model(data
->ref1
, model
, ref1
);
501 g_object_notify(object
, "ref1");
505 if (data
->ref2
== NULL
)
506 data
->ref2
= adg_point_new();
508 adg_point_set_pair_from_model(data
->ref2
, model
, ref2
);
510 g_object_notify(object
, "ref2");
513 g_object_thaw_notify(object
);
520 * Gets the ref1 coordinates. The returned pair is internally owned
521 * and must not be freed or modified.
523 * Returns: the ref1 coordinates
526 adg_dim_get_ref1(AdgDim
*dim
)
530 g_return_val_if_fail(ADG_IS_DIM(dim
), NULL
);
534 return adg_point_get_pair(data
->ref1
);
541 * Gets the ref2 coordinates. The returned pair is internally owned
542 * and must not be freed or modified.
544 * Returns: the ref2 coordinates
547 adg_dim_get_ref2(AdgDim
*dim
)
551 g_return_val_if_fail(ADG_IS_DIM(dim
), NULL
);
555 return adg_point_get_pair(data
->ref2
);
561 * @pos: the pos coordinates
563 * Sets a new #AdgDim:pos position.
566 adg_dim_set_pos(AdgDim
*dim
, const AdgPair
*pos
)
570 g_return_if_fail(ADG_IS_DIM(dim
));
571 g_return_if_fail(pos
!= NULL
);
575 if (data
->pos
== NULL
)
576 data
->pos
= adg_point_new();
578 adg_point_set_pair(data
->pos
, pos
);
580 g_object_notify((GObject
*) dim
, "pos");
584 * adg_dim_set_pos_explicit:
586 * @pos_x: x coordinate of pos
587 * @pos_y: y coordinate of pos
589 * Shortcut to set #AdgDim:pos using explicit coordinates.
592 adg_dim_set_pos_explicit(AdgDim
*dim
, gdouble x
, gdouble y
)
599 adg_dim_set_pos(dim
, &pos
);
603 * adg_dim_set_pos_from_model:
605 * @model: the source #AdgModel
606 * @ref1: name of the pair in @model to use as pos
608 * Sets #AdgDim:pos by linking it to the @pos named pair
612 adg_dim_set_pos_from_model(AdgDim
*dim
, AdgModel
*model
, const gchar
*pos
)
616 g_return_if_fail(ADG_IS_DIM(dim
));
617 g_return_if_fail(ADG_IS_MODEL(model
));
618 g_return_if_fail(pos
!= NULL
);
622 if (data
->pos
== NULL
)
623 data
->pos
= adg_point_new();
625 adg_point_set_pair_from_model(data
->pos
, model
, pos
);
627 g_object_notify((GObject
*) dim
, "pos");
634 * Gets the position coordinates. The returned pair is internally owned
635 * and must not be freed or modified.
637 * Returns: the pos coordinates
640 adg_dim_get_pos(AdgDim
*dim
)
644 g_return_val_if_fail(ADG_IS_DIM(dim
), NULL
);
648 return adg_point_get_pair(data
->pos
);
654 * @level: the new level
656 * Sets a new level for this dimension. The level is used to
657 * stack the quotes using a spacing value from dim_style
658 * (specified in global space).
661 adg_dim_set_level(AdgDim
*dim
, gdouble level
)
665 g_return_if_fail(ADG_IS_DIM(dim
));
670 g_object_notify((GObject
*) dim
, "level");
677 * Gets the level of this dimension.
679 * Returns: the level value
682 adg_dim_get_level(AdgDim
*dim
)
686 g_return_val_if_fail(ADG_IS_DIM(dim
), 0);
694 * adg_dim_set_outside:
696 * @outside: the new outside state
698 * Sets a new state for the #AdgDim:outside flag: check the property
699 * documentation for further details.
702 adg_dim_set_outside(AdgDim
*dim
, AdgThreeState outside
)
706 g_return_if_fail(ADG_IS_DIM(dim
));
709 data
->outside
= outside
;
711 g_object_notify((GObject
*) dim
, "outside");
715 * adg_dim_get_outside:
718 * Gets the state of the #AdgDim:outside property: check the property
719 * documentation for further details.
721 * Returns: the current flag state
724 adg_dim_get_outside(AdgDim
*dim
)
728 g_return_val_if_fail(ADG_IS_DIM(dim
), ADG_THREE_STATE_UNKNOWN
);
732 return data
->outside
;
736 * adg_dim_set_detached:
738 * @detached: the new detached state
740 * Sets a new state for the #AdgDim:detached flag: check the property
741 * documentation for further details.
743 * This is used only by dimensions where detaching has meaning.
744 * In some cases, such as with #AdgRDim dimensions, this property is
748 adg_dim_set_detached(AdgDim
*dim
, AdgThreeState detached
)
752 g_return_if_fail(ADG_IS_DIM(dim
));
755 data
->detached
= detached
;
757 g_object_notify((GObject
*) dim
, "detached");
761 * adg_dim_get_detached:
764 * Gets the state of the #AdgDim:detached property: check the property
765 * documentation for further details.
767 * Returns: the current flag state
770 adg_dim_get_detached(AdgDim
*dim
)
774 g_return_val_if_fail(ADG_IS_DIM(dim
), ADG_THREE_STATE_UNKNOWN
);
778 return data
->detached
;
784 * @value: the value text
786 * Explicitely sets the text to use as value. If @value is %NULL or
787 * was never set, an automatic text is calculated using the format
788 * specified in the current #AdgDimStyle and getting its value by
789 * calling the default_value() virtual method.
792 adg_dim_set_value(AdgDim
*dim
, const gchar
*value
)
794 g_return_if_fail(ADG_IS_DIM(dim
));
796 if (set_value(dim
, value
))
797 g_object_notify((GObject
*) dim
, "value");
804 * Gets the value text. The string is internally owned and
805 * must not be freed or modified.
807 * Returns: the value text
810 adg_dim_get_value(AdgDim
*dim
)
814 g_return_val_if_fail(ADG_IS_DIM(dim
), NULL
);
822 * adg_dim_set_limits:
824 * @min: the new minumum value
825 * @max: the new maximum value
827 * Shortcut to set both the limits at once.
830 adg_dim_set_limits(AdgDim
*dim
, const gchar
*min
, const gchar
*max
)
832 g_return_if_fail(ADG_IS_DIM(dim
));
834 g_object_freeze_notify((GObject
*) dim
);
835 adg_dim_set_min(dim
, min
);
836 adg_dim_set_max(dim
, max
);
837 g_object_thaw_notify((GObject
*) dim
);
843 * @min: the new minimum limit
845 * Sets the minimum value. Use %NULL as @min to disable it.
848 adg_dim_set_min(AdgDim
*dim
, const gchar
*min
)
850 g_return_if_fail(ADG_IS_DIM(dim
));
852 if (set_min(dim
, min
))
853 g_object_notify((GObject
*) dim
, "value-min");
860 * Gets the minimum value text or %NULL on minimum value disabled.
861 * The string is internally owned and must not be freed or modified.
863 * Returns: the mimimum value text
866 adg_dim_get_min(AdgDim
*dim
)
870 g_return_val_if_fail(ADG_IS_DIM(dim
), NULL
);
880 * @max: the new maximum value
882 * Sets the maximum value. Use %NULL as @max to disable it.
885 adg_dim_set_max(AdgDim
*dim
, const gchar
*max
)
887 g_return_if_fail(ADG_IS_DIM(dim
));
889 if (set_max(dim
, max
))
890 g_object_notify((GObject
*) dim
, "value-max");
897 * Gets the maximum value text or %NULL on maximum value disabled.
898 * The string is internally owned and must not be freed or modified.
900 * Returns: the maximum value text
903 adg_dim_get_max(AdgDim
*dim
)
907 g_return_val_if_fail(ADG_IS_DIM(dim
), NULL
);
919 * This function is only useful in new dimension implementations.
922 * Gets the quote entity, if any. This function is valid only after
923 * the #AdgDim implementation of the arrange() virtual method has
926 * Returns: the quote entity
929 adg_dim_get_quote(AdgDim
*dim
)
933 g_return_val_if_fail(ADG_IS_DIM(dim
), NULL
);
937 return data
->quote
.entity
;
941 * adg_dim_quote_angle:
943 * @angle: an angle (in radians)
946 * This function is only useful in new dimension implementations.
949 * Converts @angle accordling to the style of @dim. Any quote angle
950 * should be validated by this method because every dimensioning
951 * style has its own convention regardling the text rotation.
953 * Returns: the angle to use (always in radians)
956 adg_dim_quote_angle(AdgDim
*dim
, gdouble angle
)
960 g_return_val_if_fail(ADG_IS_DIM(dim
), angle
);
962 klass
= ADG_DIM_GET_CLASS(dim
);
964 if (klass
->quote_angle
== NULL
)
967 return klass
->quote_angle(angle
);
972 global_changed(AdgEntity
*entity
)
974 AdgDimPrivate
*data
= ((AdgDim
*) entity
)->data
;
976 if (PARENT_ENTITY_CLASS
->global_changed
)
977 PARENT_ENTITY_CLASS
->global_changed(entity
);
979 if (data
->quote
.entity
!= NULL
)
980 adg_entity_global_changed((AdgEntity
*) data
->quote
.entity
);
984 local_changed(AdgEntity
*entity
)
986 AdgDimPrivate
*data
= ((AdgDim
*) entity
)->data
;
988 if (PARENT_ENTITY_CLASS
->local_changed
)
989 PARENT_ENTITY_CLASS
->local_changed(entity
);
991 if (data
->quote
.entity
!= NULL
)
992 adg_entity_local_changed((AdgEntity
*) data
->quote
.entity
);
996 invalidate(AdgEntity
*entity
)
998 AdgDimPrivate
*data
= ((AdgDim
*) entity
)->data
;
1000 if (PARENT_ENTITY_CLASS
->invalidate
)
1001 PARENT_ENTITY_CLASS
->invalidate(entity
);
1003 if (data
->quote
.entity
!= NULL
)
1004 adg_entity_invalidate((AdgEntity
*) data
->quote
.entity
);
1006 adg_point_invalidate(data
->ref1
);
1007 adg_point_invalidate(data
->ref2
);
1008 adg_point_invalidate(data
->pos
);
1012 arrange(AdgEntity
*entity
)
1015 AdgDimPrivate
*data
;
1016 AdgEntity
*quote_entity
;
1017 AdgContainer
*quote_container
;
1018 AdgEntity
*value_entity
;
1019 AdgEntity
*min_entity
;
1020 AdgEntity
*max_entity
;
1021 const AdgPair
*shift
;
1024 dim
= (AdgDim
*) entity
;
1027 /* Resolve the dim style */
1028 if (data
->dim_style
== NULL
)
1029 data
->dim_style
= (AdgDimStyle
*)
1030 adg_entity_style(entity
, data
->dim_dress
);
1032 if (data
->quote
.entity
== NULL
)
1033 data
->quote
.entity
= g_object_new(ADG_TYPE_ALIGNMENT
,
1034 "local-method", ADG_MIX_NONE
,
1035 "parent", dim
, NULL
);
1037 quote_entity
= (AdgEntity
*) data
->quote
.entity
;
1038 quote_container
= (AdgContainer
*) data
->quote
.entity
;
1040 if (data
->quote
.value
== NULL
) {
1041 AdgDress dress
= adg_dim_style_get_value_dress(data
->dim_style
);
1043 data
->quote
.value
= g_object_new(ADG_TYPE_TOY_TEXT
,
1044 "local-method", ADG_MIX_PARENT
,
1045 "font-dress", dress
, NULL
);
1047 adg_container_add(quote_container
, (AdgEntity
*) data
->quote
.value
);
1050 adg_toy_text_set_label(data
->quote
.value
, data
->value
);
1052 AdgDimClass
*klass
= ADG_DIM_GET_CLASS(dim
);
1054 if (klass
->default_value
) {
1055 /* Automatically generate the value text */
1056 gchar
*text
= klass
->default_value(dim
);
1057 adg_toy_text_set_label(data
->quote
.value
, text
);
1063 if (data
->quote
.min
== NULL
&& data
->min
!= NULL
) {
1064 AdgDress dress
= adg_dim_style_get_min_dress(data
->dim_style
);
1066 data
->quote
.min
= g_object_new(ADG_TYPE_TOY_TEXT
,
1067 "local-method", ADG_MIX_PARENT
,
1068 "font-dress", dress
, NULL
);
1070 adg_container_add(quote_container
, (AdgEntity
*) data
->quote
.min
);
1071 adg_toy_text_set_label(data
->quote
.min
, data
->min
);
1074 if (data
->quote
.max
== NULL
&& data
->max
!= NULL
) {
1075 AdgDress dress
= adg_dim_style_get_max_dress(data
->dim_style
);
1077 data
->quote
.max
= g_object_new(ADG_TYPE_TOY_TEXT
,
1078 "local-method", ADG_MIX_PARENT
,
1079 "font-dress", dress
, NULL
);
1081 adg_container_add(quote_container
, (AdgEntity
*) data
->quote
.max
);
1082 adg_toy_text_set_label(data
->quote
.max
, data
->max
);
1085 value_entity
= (AdgEntity
*) data
->quote
.value
;
1086 min_entity
= (AdgEntity
*) data
->quote
.min
;
1087 max_entity
= (AdgEntity
*) data
->quote
.max
;
1088 shift
= adg_dim_style_get_quote_shift(data
->dim_style
);
1090 adg_entity_set_global_map(quote_entity
, adg_matrix_identity());
1091 adg_entity_global_changed(quote_entity
);
1093 cairo_matrix_init_translate(&map
, shift
->x
, shift
->y
);
1094 adg_entity_set_global_map(value_entity
, &map
);
1095 adg_entity_arrange(value_entity
);
1097 /* Limit values (min and max) */
1098 if (min_entity
!= NULL
|| max_entity
!= NULL
) {
1099 const CpmlExtents
*extents
= adg_entity_get_extents(value_entity
);
1100 //CpmlExtents min_extents = { 0 };
1101 //CpmlExtents max_extents = { 0 };
1102 const AdgPair
*limits_shift
= adg_dim_style_get_limits_shift(data
->dim_style
);
1105 if (min_entity
!= NULL
)
1106 cpml_extents_copy(&min_extents
, adg_entity_get_extents(min_entity
));
1108 if (max_entity
!= NULL
)
1109 cpml_extents_copy(&max_extents
, adg_entity_get_extents(max_entity
));
1111 if (min_entity
!= NULL
&& max_entity
!= NULL
)
1112 spacing
= adg_dim_style_get_limits_spacing(data
->dim_style
);
1114 cairo_matrix_init_translate(&map
,
1116 shift
->x
+ limit_shift
->x
,
1117 (spacing
+ min_extents
.size
.y
+
1118 max_extents
.size
.y
- extents
->size
.y
) / 2 +
1119 shift
->y
+ limit_shift
->y
);
1121 cairo_matrix_init_translate(&map
, extents
->size
.x
+ limits_shift
->x
,
1122 -extents
->size
.y
/ 2 + limits_shift
->y
);
1124 if (min_entity
!= NULL
) {
1125 adg_entity_set_global_map(min_entity
, &map
);
1126 adg_entity_arrange(min_entity
);
1127 extents
= adg_entity_get_extents(min_entity
);
1128 map
.y0
-= extents
->size
.y
+
1129 adg_dim_style_get_limits_spacing(data
->dim_style
);
1132 if (max_entity
!= NULL
) {
1133 adg_entity_set_global_map(max_entity
, &map
);
1134 adg_entity_arrange(max_entity
);
1138 adg_entity_arrange(quote_entity
);
1142 default_value(AdgDim
*dim
)
1144 g_warning("AdgDim::default_value not implemented for `%s'",
1145 g_type_name(G_TYPE_FROM_INSTANCE(dim
)));
1146 return g_strdup("undef");
1150 quote_angle(gdouble angle
)
1152 angle
= cpml_angle(angle
);
1154 if (angle
> G_PI_4
* 4 / 3 || angle
<= -G_PI_4
* 3)
1155 angle
= cpml_angle(angle
+ G_PI
);
1161 set_dim_dress(AdgDim
*dim
, AdgDress dress
)
1163 AdgDimPrivate
*data
= dim
->data
;
1165 if (adg_dress_set(&data
->dim_dress
, dress
)) {
1166 data
->dim_style
= NULL
;
1174 set_value(AdgDim
*dim
, const gchar
*value
)
1176 AdgDimPrivate
*data
;
1180 if (adg_strcmp(value
, data
->value
) == 0)
1183 g_free(data
->value
);
1184 data
->value
= g_strdup(value
);
1186 if (data
->quote
.value
!= NULL
) {
1187 g_object_unref(data
->quote
.value
);
1188 data
->quote
.value
= NULL
;
1195 set_min(AdgDim
*dim
, const gchar
*min
)
1197 AdgDimPrivate
*data
= dim
->data
;
1199 if (adg_strcmp(min
, data
->min
) == 0)
1203 data
->min
= g_strdup(min
);
1205 if (data
->quote
.min
!= NULL
) {
1206 g_object_unref(data
->quote
.min
);
1207 data
->quote
.min
= NULL
;
1214 set_max(AdgDim
*dim
, const gchar
*max
)
1216 AdgDimPrivate
*data
= dim
->data
;
1218 if (adg_strcmp(max
, data
->max
) == 0)
1222 data
->max
= g_strdup(max
);
1224 if (data
->quote
.max
!= NULL
) {
1225 g_object_unref(data
->quote
.max
);
1226 data
->quote
.max
= NULL
;