doc: update copyright line for 2021
[adg.git] / src / adg / adg-param-dress.c
blobffe305a998b93cc50aa20e8674d3b372d0a409cd
1 /* ADG - Automatic Drawing Generation
2 * Copyright (C) 2007-2021 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.
21 /**
22 * SECTION:adg-param-dress
23 * @Section_Id:AdgParamDress
24 * @title: AdgParamDress
25 * @short_description: Metadata for dress specification
27 * The %ADG_TYPE_PARAM_DRESS type is a parameter specification
28 * compatible with %G_TYPE_PARAM_ENUM that provides additional
29 * validation: it rejects values that are incompatibles (that
30 * is, that are not related) with the current one. Check the
31 * adg_dress_are_related() documentation for details on what
32 * <emphasis>related</emphasis> means.
34 * Internally, the value setting is performed by calling the
35 * adg_dress_set() API.
37 * Since: 1.0
38 **/
41 #include "adg-internal.h"
42 #include "adg-dress.h"
44 #include "adg-param-dress.h"
46 #define ADG_PARAM_SPEC_DRESS(pspec) (G_TYPE_CHECK_INSTANCE_CAST((pspec), ADG_TYPE_PARAM_DRESS, AdgParamSpecDress))
49 typedef struct _AdgParamSpecDress AdgParamSpecDress;
51 struct _AdgParamSpecDress {
52 GParamSpecEnum parent;
53 AdgDress source_dress;
57 static void _adg_param_dress_init (GParamSpec *pspec);
58 static void _adg_param_dress_set_default (GParamSpec *pspec,
59 GValue *value);
60 static gboolean _adg_param_dress_validate (GParamSpec *pspec,
61 GValue *value);
62 static gint _adg_param_dress_cmp (GParamSpec *pspec,
63 const GValue *value1,
64 const GValue *value2);
67 GType
68 adg_param_dress_get_type(void)
70 static GType type = 0;
72 if (G_UNLIKELY(type == 0)) {
73 /* const */ GParamSpecTypeInfo pspec_info = {
74 sizeof(AdgParamSpecDress), /* instance_size */
75 0, /* n_preallocs */
76 _adg_param_dress_init,
77 G_TYPE_INVALID, /* value_type */
78 NULL, /* finalize */
79 _adg_param_dress_set_default,
80 _adg_param_dress_validate,
81 _adg_param_dress_cmp,
83 pspec_info.value_type = ADG_TYPE_DRESS;
84 type = g_param_type_register_static(g_intern_static_string("AdgParamDress"),
85 &pspec_info);
88 return type;
92 /**
93 * adg_param_spec_dress:
94 * @name: canonical name
95 * @nick: nickname of the param
96 * @blurb: brief desciption
97 * @dress: the #AdgDress dress
98 * @flags: a combination of #GParamFlags
100 * Creates a param spec to hold a dress value. This is similar to
101 * g_param_spec_enum() but rejects a new dress value if it is not
102 * related with the old one. The setting is performed via
103 * adg_dress_set(), so check its documentation for details.
105 * Returns: (transfer full): the newly allocated #GParamSpec.
107 * Since: 1.0
109 GParamSpec *
110 adg_param_spec_dress(const gchar *name, const gchar *nick, const gchar *blurb,
111 AdgDress dress, GParamFlags flags)
113 AdgParamSpecDress *dspec;
115 dspec = g_param_spec_internal(ADG_TYPE_PARAM_DRESS,
116 name, nick, blurb, flags);
117 dspec->source_dress = dress;
119 return (GParamSpec *) dspec;
123 static void
124 _adg_param_dress_init(GParamSpec *pspec)
126 AdgParamSpecDress *dspec = ADG_PARAM_SPEC_DRESS(pspec);
127 dspec->source_dress = ADG_DRESS_UNDEFINED;
130 static void
131 _adg_param_dress_set_default(GParamSpec *pspec,
132 GValue *value)
134 value->data[0].v_long = ADG_PARAM_SPEC_DRESS(pspec)->source_dress;
137 static gboolean
138 _adg_param_dress_validate(GParamSpec *pspec, GValue *value)
140 AdgParamSpecDress *dspec;
141 AdgDress *dress;
142 AdgDress wanted_dress;
144 dspec = ADG_PARAM_SPEC_DRESS(pspec);
145 dress = (AdgDress *) &value->data[0].v_long;
146 wanted_dress = *dress;
148 /* Fallback to the source dress, returned in case of errors */
149 *dress = dspec->source_dress;
151 /* This method will fail (that is, it leaves *dress untouched)
152 * if the current *dress value (source_dress) and wanted_dress
153 * are not related */
154 adg_dress_set(dress, wanted_dress);
156 return *dress != wanted_dress;
159 static gint
160 _adg_param_dress_cmp(GParamSpec *pspec,
161 const GValue *value1,
162 const GValue *value2)
164 glong v1 = value1->data[0].v_long;
165 glong v2 = value2->data[0].v_long;
167 return v1 < v2 ? -1 : (v1 > v2);