2 * (GLABELS) Label and Business Card Creation program for GNOME
4 * wdgt_vector.c: vector properties widget module
6 * Copyright (C) 2001-2002 Jim Evins <evins@snaught.com>.
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 #include "wdgt-vector.h"
34 #define M_PI 3.14159265358979323846 /* pi */
37 #define LENGTH(x,y) sqrt( (x)*(x) + (y)*(y) )
38 #define ANGLE(x,y) ( (180.0/M_PI)*atan2( -(y), (x) ) )
39 #define COMP_X(l,a) ( (l) * cos( (M_PI/180.0)*(a) ) )
40 #define COMP_Y(l,a) ( -(l) * sin( (M_PI/180.0)*(a) ) )
42 /*===========================================*/
44 /*===========================================*/
51 typedef void (*glWdgtVectorSignal) (GObject * object, gpointer data);
53 /*===========================================*/
55 /*===========================================*/
57 static GtkContainerClass *parent_class;
59 static gint wdgt_vector_signals[LAST_SIGNAL] = { 0 };
61 /*===========================================*/
62 /* Local function prototypes */
63 /*===========================================*/
65 static void gl_wdgt_vector_class_init (glWdgtVectorClass * class);
66 static void gl_wdgt_vector_instance_init (glWdgtVector * vector);
67 static void gl_wdgt_vector_finalize (GObject * object);
68 static void gl_wdgt_vector_construct (glWdgtVector * vector, gchar * label);
69 static void changed_cb (glWdgtVector * vector);
71 /*================================================================*/
72 /* Boilerplate Object stuff. */
73 /*================================================================*/
75 gl_wdgt_vector_get_type (void)
77 static guint wdgt_vector_type = 0;
79 if (!wdgt_vector_type) {
80 GTypeInfo wdgt_vector_info = {
81 sizeof (glWdgtVectorClass),
84 (GClassInitFunc) gl_wdgt_vector_class_init,
87 sizeof (glWdgtVector),
89 (GInstanceInitFunc) gl_wdgt_vector_instance_init,
93 g_type_register_static (gtk_vbox_get_type (),
95 &wdgt_vector_info, 0);
98 return wdgt_vector_type;
102 gl_wdgt_vector_class_init (glWdgtVectorClass * class)
104 GObjectClass *object_class;
106 object_class = (GObjectClass *) class;
108 parent_class = gtk_type_class (gtk_vbox_get_type ());
110 object_class->finalize = gl_wdgt_vector_finalize;
112 wdgt_vector_signals[CHANGED] =
113 g_signal_new ("changed",
114 G_OBJECT_CLASS_TYPE(object_class),
116 G_STRUCT_OFFSET (glWdgtVectorClass, changed),
118 gl_marshal_VOID__VOID,
124 gl_wdgt_vector_instance_init (glWdgtVector * vector)
126 vector->len_spin = NULL;
127 vector->angle_spin = NULL;
131 gl_wdgt_vector_finalize (GObject * object)
133 glWdgtVector *vector;
134 glWdgtVectorClass *class;
136 g_return_if_fail (object != NULL);
137 g_return_if_fail (GL_IS_WDGT_VECTOR (object));
139 vector = GL_WDGT_VECTOR (object);
141 G_OBJECT_CLASS (parent_class)->finalize (object);
145 gl_wdgt_vector_new (gchar * label)
147 glWdgtVector *vector;
149 vector = g_object_new (gl_wdgt_vector_get_type (), NULL);
151 gl_wdgt_vector_construct (vector, label);
153 return GTK_WIDGET (vector);
156 /*============================================================*/
157 /* Construct composite widget. */
158 /*============================================================*/
160 gl_wdgt_vector_construct (glWdgtVector * vector,
163 GtkWidget *wvbox, *wframe, *wtable, *wlabel;
165 const gchar *units_string;
166 gdouble units_per_point, climb_rate;
169 units_string = gl_prefs_get_units_string ();
170 units_per_point = gl_prefs_get_units_per_point ();
171 climb_rate = gl_prefs_get_units_step_size ();
172 digits = gl_prefs_get_units_precision ();
174 wvbox = GTK_WIDGET (vector);
176 wframe = gtk_frame_new (label);
177 gtk_box_pack_start (GTK_BOX (wvbox), wframe, FALSE, FALSE, 0);
179 wtable = gtk_table_new (2, 3, TRUE);
180 gtk_container_set_border_width (GTK_CONTAINER (wtable), 10);
181 gtk_table_set_row_spacings (GTK_TABLE (wtable), 5);
182 gtk_table_set_col_spacings (GTK_TABLE (wtable), 5);
183 gtk_container_add (GTK_CONTAINER (wframe), wtable);
186 wlabel = gtk_label_new (_("Length:"));
187 gtk_misc_set_alignment (GTK_MISC (wlabel), 0, 0.5);
188 gtk_label_set_justify (GTK_LABEL (wlabel), GTK_JUSTIFY_RIGHT);
189 gtk_table_attach_defaults (GTK_TABLE (wtable), wlabel, 0, 1, 0, 1);
191 adjust = gtk_adjustment_new (climb_rate, climb_rate, 100.0, climb_rate,
193 vector->len_spin = gtk_spin_button_new (GTK_ADJUSTMENT (adjust),
195 gtk_spin_button_set_snap_to_ticks (GTK_SPIN_BUTTON (vector->len_spin),
197 gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (vector->len_spin), TRUE);
198 g_signal_connect_swapped (G_OBJECT (vector->len_spin), "changed",
199 G_CALLBACK (changed_cb),
201 gtk_table_attach_defaults (GTK_TABLE (wtable), vector->len_spin, 1, 2,
203 /* Length units label */
204 vector->len_units_label = gtk_label_new (units_string);
205 gtk_misc_set_alignment (GTK_MISC (vector->len_units_label), 0, 0.5);
206 gtk_table_attach_defaults (GTK_TABLE (wtable), vector->len_units_label,
210 wlabel = gtk_label_new (_("Angle:"));
211 gtk_misc_set_alignment (GTK_MISC (wlabel), 0, 0.5);
212 gtk_table_attach_defaults (GTK_TABLE (wtable), wlabel, 0, 1, 1, 2);
214 adjust = gtk_adjustment_new (0.0, -180.0, +180.0, 1.0, 10.0, 10.0);
216 gtk_spin_button_new (GTK_ADJUSTMENT (adjust), 1.0, 0);
217 gtk_spin_button_set_snap_to_ticks (GTK_SPIN_BUTTON (vector->angle_spin),
219 gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (vector->angle_spin),
221 g_signal_connect_swapped (G_OBJECT (vector->angle_spin), "changed",
222 G_CALLBACK (changed_cb),
224 gtk_table_attach_defaults (GTK_TABLE (wtable), vector->angle_spin, 1, 2,
226 /* Angle units label */
227 vector->angle_units_label = gtk_label_new (_("degrees"));
228 gtk_misc_set_alignment (GTK_MISC (vector->angle_units_label), 0, 0.5);
229 gtk_table_attach_defaults (GTK_TABLE (wtable),
230 vector->angle_units_label, 2, 3, 1, 2);
234 /*--------------------------------------------------------------------------*/
235 /* PRIVATE. Callback for when any control in the widget has changed. */
236 /*--------------------------------------------------------------------------*/
238 changed_cb (glWdgtVector * vector)
240 /* Emit our "changed" signal */
241 g_signal_emit (G_OBJECT (vector), wdgt_vector_signals[CHANGED], 0);
244 /*====================================================================*/
245 /* query values from controls. */
246 /*====================================================================*/
248 gl_wdgt_vector_get_params (glWdgtVector * vector,
252 gdouble length, angle;
253 gdouble units_per_point;
255 units_per_point = gl_prefs_get_units_per_point ();
258 gtk_spin_button_get_value (GTK_SPIN_BUTTON(vector->len_spin));
260 gtk_spin_button_get_value (GTK_SPIN_BUTTON(vector->angle_spin));
262 length /= units_per_point;
264 *dx = COMP_X (length, angle);
265 *dy = COMP_Y (length, angle);
268 /*====================================================================*/
269 /* set values and ranges for controls. */
270 /*====================================================================*/
272 gl_wdgt_vector_set_params (glWdgtVector * vector,
278 GtkObject *length_adjust;
279 gdouble length, angle;
280 const gchar *units_string;
281 gdouble units_per_point, climb_rate;
284 units_string = gl_prefs_get_units_string ();
285 units_per_point = gl_prefs_get_units_per_point ();
286 climb_rate = gl_prefs_get_units_step_size ();
287 digits = gl_prefs_get_units_precision ();
289 /* Put everything into our display units */
290 dx *= units_per_point;
291 dy *= units_per_point;
292 x_max *= units_per_point;
293 y_max *= units_per_point;
295 length = LENGTH (dx, dy);
296 angle = ANGLE (dx, dy);
298 length_adjust = gtk_adjustment_new (length, 0.0, LENGTH (x_max, y_max),
299 climb_rate, 10.0, 10.0);
300 gtk_spin_button_configure (GTK_SPIN_BUTTON (vector->len_spin),
301 GTK_ADJUSTMENT (length_adjust),
303 gtk_spin_button_update (GTK_SPIN_BUTTON (vector->len_spin));
305 gtk_spin_button_set_value (GTK_SPIN_BUTTON (vector->angle_spin), angle);