[AdgWidget] First implementation
[adg.git] / adg / adg-rotable.c
blob850e715bbcb81ef9d4eb408cea72ef036f920042
1 /* ADG - Automatic Drawing Generation
2 * Copyright (C) 2007,2008,2009 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:rotable
23 * @title: AdgRotable
24 * @short_description: Interface for rotable entities
26 * The #AdgRotableIface interface gives a common way to manage entities
27 * that needs a custom rotation on the origin point.
28 **/
30 /**
31 * AdgRotableIface:
32 * @base_iface: the base interface
33 * @get_angle: returns the current angle
34 * @set_angle: sets a new angle
36 * The virtual methods @get_angle and @set_angle must be defined
37 * by all the types which implement this interface.
38 **/
40 #include "adg-rotable.h"
41 #include "adg-intl.h"
44 enum {
45 ANGLE_CHANGED,
46 LAST_SIGNAL
49 static void iface_base (AdgRotableIface*iface);
50 static void iface_init (AdgRotableIface*iface);
51 static gdouble get_angle (AdgRotable *rotable);
52 static void set_angle (AdgRotable *rotable,
53 gdouble angle);
55 static guint signals[LAST_SIGNAL] = { 0 };
58 GType
59 adg_rotable_get_type(void)
61 static GType rotable_type = 0;
63 if (G_UNLIKELY(rotable_type == 0)) {
64 static const GTypeInfo rotable_info = {
65 sizeof(AdgRotableIface),
66 (GBaseInitFunc) iface_base,
67 NULL,
68 (GClassInitFunc) iface_init,
69 NULL,
72 rotable_type = g_type_register_static(G_TYPE_INTERFACE,
73 "AdgRotable",
74 &rotable_info, 0);
77 return rotable_type;
80 static void
81 iface_base(AdgRotableIface *iface)
83 static gboolean initialized = FALSE;
84 GParamSpec *param;
85 GType param_types[1];
87 if (initialized) {
88 return;
90 initialized = TRUE;
92 param = g_param_spec_object("angle",
93 P_("Rotation Angle"),
94 P_("The angle (in radians) the entity should rotate around the origin point"),
95 G_TYPE_DOUBLE,
96 G_PARAM_READWRITE);
97 g_object_interface_install_property(iface, param);
99 /**
100 * AdgRotable::angle-changed:
101 * @rotable: an entity implementing #AdgRotable
102 * @old_angle: the previous rotation angle
104 * Emitted whenever the angle has changed.
106 param_types[0] = G_TYPE_DOUBLE;
107 signals[ANGLE_CHANGED] = g_signal_newv("angle-changed", ADG_TYPE_ROTABLE,
108 G_SIGNAL_RUN_FIRST,
109 NULL, NULL, NULL,
110 g_cclosure_marshal_VOID__DOUBLE,
111 G_TYPE_NONE, 1, param_types);
114 static void
115 iface_init (AdgRotableIface *iface)
117 iface->get_angle = get_angle;
118 iface->set_angle = set_angle;
122 static gdouble
123 get_angle(AdgRotable *rotable)
125 g_warning("AdgRotable::get_angle not implemented for `%s'",
126 g_type_name(G_TYPE_FROM_INSTANCE(rotable)));
127 return 0.;
130 static void
131 set_angle(AdgRotable *rotable, gdouble angle)
133 g_warning("AdgRotable::set_angle not implemented for `%s'",
134 g_type_name(G_TYPE_FROM_INSTANCE(rotable)));
138 * adg_rotable_get_angle:
139 * @rotable: an entity implementing AdgRotable
141 * Gets the rotation angle of @rotable.
143 * Return value: The rotation angle (in radians)
145 gdouble
146 adg_rotable_get_angle(AdgRotable *rotable)
148 g_return_val_if_fail(ADG_IS_ROTABLE(rotable), 0.);
150 return ADG_ROTABLE_GET_IFACE(rotable)->get_angle(rotable);
154 * adg_rotable_set_angle:
155 * @rotable: an entity implementing AdgRotable
156 * @angle: the new angle
158 * Sets the rotation angle of @rotable to @angle.
159 * An "angle-changed" signal is emitted.
161 void
162 adg_rotable_set_angle(AdgRotable *rotable, gdouble angle)
164 AdgRotableIface *iface;
165 gdouble old_angle;
167 g_return_if_fail(ADG_IS_ROTABLE(rotable));
169 iface = ADG_ROTABLE_GET_IFACE(rotable);
171 old_angle = iface->get_angle(rotable);
172 iface->set_angle(rotable, angle);
174 g_signal_emit(rotable, signals[ANGLE_CHANGED], 0, &old_angle);