]> git.sur5r.net Git - glabels/blob - glabels2/src/object-editor-size-page.c
58fbe5fabe2cdc1aebfbd9ddc55160caf23a105e
[glabels] / glabels2 / src / object-editor-size-page.c
1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
2
3 /*
4  *  (GLABELS) Label and Business Card Creation program for GNOME
5  *
6  *  object-editor.c:  object properties editor module
7  *
8  *  Copyright (C) 2003  Jim Evins <evins@snaught.com>.
9  *
10  *  This program is free software; you can redistribute it and/or modify
11  *  it under the terms of the GNU General Public License as published by
12  *  the Free Software Foundation; either version 2 of the License, or
13  *  (at your option) any later version.
14  *
15  *  This program is distributed in the hope that it will be useful,
16  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  *  GNU General Public License for more details.
19  *
20  *  You should have received a copy of the GNU General Public License
21  *  along with this program; if not, write to the Free Software
22  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
23  */
24 #include <config.h>
25
26 #include "object-editor.h"
27
28 #include <glib/gi18n.h>
29 #include <gtk/gtklabel.h>
30 #include <gtk/gtkspinbutton.h>
31 #include <math.h>
32
33 #include "prefs.h"
34 #include "wdgt-chain-button.h"
35
36 #include "object-editor-private.h"
37
38 #include "debug.h"
39
40 /*===========================================*/
41 /* Private macros                            */
42 /*===========================================*/
43
44 /*===========================================*/
45 /* Private data types                        */
46 /*===========================================*/
47
48 /*===========================================*/
49 /* Private globals                           */
50 /*===========================================*/
51
52 /*===========================================*/
53 /* Local function prototypes                 */
54 /*===========================================*/
55
56 static void aspect_toggle_cb                    (glObjectEditor        *editor);
57 static void size_reset_cb                       (glObjectEditor        *editor);
58 static void w_spin_cb                           (glObjectEditor        *editor);
59 static void h_spin_cb                           (glObjectEditor        *editor);
60
61
62 /*--------------------------------------------------------------------------*/
63 /* PRIVATE.  Prepare size page.                                             */
64 /*--------------------------------------------------------------------------*/
65 void
66 gl_object_editor_prepare_size_page (glObjectEditor       *editor,
67                                     glObjectEditorOption  option)
68 {
69         const gchar  *units_string;
70         gdouble       climb_rate;
71         gint          digits;
72
73         gl_debug (DEBUG_EDITOR, "START");
74
75         /* Extract widgets from XML tree. */
76         editor->priv->size_page_vbox =
77                 glade_xml_get_widget (editor->priv->gui, "size_page_vbox");
78         editor->priv->size_w_spin =
79                 glade_xml_get_widget (editor->priv->gui, "size_w_spin");
80         editor->priv->size_h_spin =
81                 glade_xml_get_widget (editor->priv->gui, "size_h_spin");
82         editor->priv->size_w_units_label =
83                 glade_xml_get_widget (editor->priv->gui, "size_w_units_label");
84         editor->priv->size_h_units_label =
85                 glade_xml_get_widget (editor->priv->gui, "size_h_units_label");
86         editor->priv->size_aspect_checkbutton =
87                 glade_xml_get_widget (editor->priv->gui, "size_aspect_checkbutton");
88         editor->priv->size_reset_image_button =
89                 glade_xml_get_widget (editor->priv->gui, "size_reset_image_button");
90
91         /* Get configuration information */
92         units_string = gl_prefs_get_units_string ();
93         editor->priv->units_per_point = gl_prefs_get_units_per_point ();
94         climb_rate = gl_prefs_get_units_step_size ();
95         digits = gl_prefs_get_units_precision ();
96
97         /* Modify widgets based on configuration */
98         gtk_spin_button_set_digits (GTK_SPIN_BUTTON(editor->priv->size_w_spin), digits);
99         gtk_spin_button_set_increments (GTK_SPIN_BUTTON(editor->priv->size_w_spin),
100                                         climb_rate, 10.0*climb_rate);
101         gtk_label_set_text (GTK_LABEL(editor->priv->size_w_units_label), units_string);
102         gtk_spin_button_set_digits (GTK_SPIN_BUTTON(editor->priv->size_h_spin), digits);
103         gtk_spin_button_set_increments (GTK_SPIN_BUTTON(editor->priv->size_h_spin),
104                                         climb_rate, 10.0*climb_rate);
105         gtk_label_set_text (GTK_LABEL(editor->priv->size_h_units_label), units_string);
106
107         /* Un-hide */
108         gtk_widget_show_all (editor->priv->size_page_vbox);
109         if (option != GL_OBJECT_EDITOR_SIZE_IMAGE_PAGE) {
110                 gtk_widget_hide (editor->priv->size_reset_image_button);
111         }
112
113         /* Connect signals */
114         g_signal_connect_swapped (G_OBJECT (editor->priv->size_aspect_checkbutton),
115                                   "toggled",
116                                   G_CALLBACK (aspect_toggle_cb),
117                                   G_OBJECT (editor));
118         g_signal_connect_swapped (G_OBJECT (editor->priv->size_w_spin),
119                                   "changed",
120                                   G_CALLBACK (w_spin_cb),
121                                   G_OBJECT (editor));
122         g_signal_connect_swapped (G_OBJECT (editor->priv->size_h_spin),
123                                   "changed",
124                                   G_CALLBACK (h_spin_cb),
125                                   G_OBJECT (editor));
126
127         if (option == GL_OBJECT_EDITOR_SIZE_IMAGE_PAGE) {
128                 g_signal_connect_swapped (G_OBJECT (editor->priv->size_reset_image_button),
129                                           "clicked",
130                                           G_CALLBACK (size_reset_cb),
131                                           G_OBJECT (editor));
132         }
133
134         gl_debug (DEBUG_EDITOR, "END");
135 }
136
137 /*--------------------------------------------------------------------------*/
138 /* PRIVATE.  Maintain aspect ratio checkbox callback.                       */
139 /*--------------------------------------------------------------------------*/
140 static void
141 aspect_toggle_cb (glObjectEditor *editor)
142 {
143         glWdgtChainButton *toggle;
144         gdouble            w, h;
145
146         if (editor->priv->stop_signals) return;
147
148         gl_debug (DEBUG_EDITOR, "START");
149
150         toggle = GL_WDGT_CHAIN_BUTTON (editor->priv->size_aspect_checkbutton);
151
152         if (gl_wdgt_chain_button_get_active (toggle)) {
153                                                                                 
154                 w = gtk_spin_button_get_value (GTK_SPIN_BUTTON(editor->priv->size_w_spin));
155                 h = gtk_spin_button_get_value (GTK_SPIN_BUTTON(editor->priv->size_h_spin));
156                                                                                 
157                 editor->priv->size_aspect_ratio = h / w;
158                                                                                 
159         }
160
161         gl_debug (DEBUG_EDITOR, "END");
162 }
163
164 /*--------------------------------------------------------------------------*/
165 /* PRIVATE.  W spin button changed callback.                                */
166 /*--------------------------------------------------------------------------*/
167 static void
168 w_spin_cb (glObjectEditor *editor)
169 {
170         gdouble            w, h;
171         glWdgtChainButton *toggle;
172
173         if (editor->priv->stop_signals) return;
174
175         gl_debug (DEBUG_EDITOR, "START");
176
177         toggle = GL_WDGT_CHAIN_BUTTON (editor->priv->size_aspect_checkbutton);
178
179         if (gl_wdgt_chain_button_get_active (toggle)) {
180
181                 w = gtk_spin_button_get_value (GTK_SPIN_BUTTON (editor->priv->size_w_spin));
182                                                                                 
183                 h = w * editor->priv->size_aspect_ratio;
184                                                                                 
185                 /* Update our sibling control, blocking recursion. */
186                 editor->priv->stop_signals = TRUE;
187                 gtk_spin_button_set_value (GTK_SPIN_BUTTON (editor->priv->size_h_spin), h);
188                 editor->priv->stop_signals = FALSE;
189         }
190                                                                                 
191         /* Emit our "changed" signal */
192         g_signal_emit (G_OBJECT (editor), gl_object_editor_signals[CHANGED], 0);
193         g_signal_emit (G_OBJECT (editor), gl_object_editor_signals[SIZE_CHANGED], 0);
194                                                                                 
195         gl_debug (DEBUG_EDITOR, "END");
196 }
197
198 /*--------------------------------------------------------------------------*/
199 /* PRIVATE.  H spin button changed callback.                                */
200 /*--------------------------------------------------------------------------*/
201 static void
202 h_spin_cb (glObjectEditor *editor)
203 {
204         gdouble            w, h;
205         glWdgtChainButton *toggle;
206
207         if (editor->priv->stop_signals) return;
208
209         gl_debug (DEBUG_EDITOR, "START");
210
211         toggle = GL_WDGT_CHAIN_BUTTON (editor->priv->size_aspect_checkbutton);
212                                                                                 
213         if (gl_wdgt_chain_button_get_active (toggle)) {
214
215                 h = gtk_spin_button_get_value (GTK_SPIN_BUTTON (editor->priv->size_h_spin));
216                                                                                 
217                 w = h / editor->priv->size_aspect_ratio;
218                                                                                 
219                 /* Update our sibling control, blocking recursion. */
220                 editor->priv->stop_signals = TRUE;
221                 gtk_spin_button_set_value (GTK_SPIN_BUTTON (editor->priv->size_w_spin), w);
222                 editor->priv->stop_signals = FALSE;
223         }
224                                                                                 
225         /* Emit our "changed" signal */
226         g_signal_emit (G_OBJECT (editor), gl_object_editor_signals[CHANGED], 0);
227         g_signal_emit (G_OBJECT (editor), gl_object_editor_signals[SIZE_CHANGED], 0);
228                                                                                 
229         gl_debug (DEBUG_EDITOR, "END");
230 }
231
232 /*--------------------------------------------------------------------------*/
233 /* PRIVATE.  Reset image size callback.                                     */
234 /*--------------------------------------------------------------------------*/
235 static void
236 size_reset_cb (glObjectEditor *editor)
237 {
238         gdouble w_base, h_base;
239         gdouble w_max, h_max;
240         gdouble aspect_ratio;
241
242         if (editor->priv->stop_signals) return;
243
244         gl_debug (DEBUG_EDITOR, "START");
245
246         editor->priv->stop_signals = TRUE;
247
248         w_base = editor->priv->w_base;
249         h_base = editor->priv->h_base;
250
251         w_max = editor->priv->w_max;
252         h_max = editor->priv->h_max;
253
254         if ( (w_base > w_max) || (h_base > h_max) ) {
255
256                 aspect_ratio = h_base / w_base;
257
258                 if ( h_max > w_max*aspect_ratio ) {
259                         w_base = w_max;
260                         h_base = w_max * aspect_ratio;
261
262                 } else {
263                         w_base = h_max / aspect_ratio;
264                         h_base = h_max;
265                 }
266         }
267
268         w_base *= editor->priv->units_per_point;
269         h_base *= editor->priv->units_per_point;
270
271         gtk_spin_button_set_value (GTK_SPIN_BUTTON (editor->priv->size_w_spin),
272                                    w_base);
273         gtk_spin_button_set_value (GTK_SPIN_BUTTON (editor->priv->size_h_spin),
274                                    h_base);
275
276         /* Emit our "changed" signal */
277         g_signal_emit (G_OBJECT (editor), gl_object_editor_signals[CHANGED], 0);
278         g_signal_emit (G_OBJECT (editor), gl_object_editor_signals[SIZE_CHANGED], 0);
279
280         editor->priv->stop_signals = FALSE;
281
282         gl_debug (DEBUG_EDITOR, "END");
283 }
284
285 /*****************************************************************************/
286 /* Set size.                                                                 */
287 /*****************************************************************************/
288 void
289 gl_object_editor_set_size (glObjectEditor      *editor,
290                              gdouble                w,
291                              gdouble                h)
292 {
293         gl_debug (DEBUG_EDITOR, "START");
294
295         editor->priv->stop_signals = TRUE;
296
297         /* save a copy in internal units */
298         editor->priv->w = w;
299         editor->priv->h = h;
300
301         /* convert internal units to displayed units */
302         gl_debug (DEBUG_EDITOR, "internal w,h = %g, %g", w, h);
303         w *= editor->priv->units_per_point;
304         h *= editor->priv->units_per_point;
305         gl_debug (DEBUG_EDITOR, "display w,h = %g, %g", w, h);
306
307         /* Set widget values */
308         gtk_spin_button_set_value (GTK_SPIN_BUTTON (editor->priv->size_w_spin), w);
309         gtk_spin_button_set_value (GTK_SPIN_BUTTON (editor->priv->size_h_spin), h);
310
311         /* Update aspect ratio */
312         editor->priv->size_aspect_ratio = h / w;
313
314         editor->priv->stop_signals = FALSE;
315
316         gl_debug (DEBUG_EDITOR, "END");
317 }
318
319 /*****************************************************************************/
320 /* Set maximum size.                                                         */
321 /*****************************************************************************/
322 void
323 gl_object_editor_set_max_size (glObjectEditor      *editor,
324                                gdouble              w_max,
325                                gdouble              h_max)
326 {
327         gdouble tmp;
328
329         gl_debug (DEBUG_EDITOR, "START");
330
331         if (editor->priv->size_page_vbox)
332         {
333
334                 editor->priv->stop_signals = TRUE;
335
336                 /* save a copy in internal units */
337                 editor->priv->w_max = w_max;
338                 editor->priv->h_max = h_max;
339
340                 /* convert internal units to displayed units */
341                 gl_debug (DEBUG_EDITOR, "internal w_max,h_max = %g, %g", w_max, h_max);
342                 w_max *= editor->priv->units_per_point;
343                 h_max *= editor->priv->units_per_point;
344                 gl_debug (DEBUG_EDITOR, "display w_max,h_max = %g, %g", w_max, h_max);
345
346                 /* Set widget values */
347                 tmp = gtk_spin_button_get_value (GTK_SPIN_BUTTON (editor->priv->size_w_spin));
348                 gtk_spin_button_set_range (GTK_SPIN_BUTTON (editor->priv->size_w_spin),
349                                            0.0, 2.0*w_max);
350                 gtk_spin_button_set_value (GTK_SPIN_BUTTON (editor->priv->size_w_spin), tmp);
351                 tmp = gtk_spin_button_get_value (GTK_SPIN_BUTTON (editor->priv->size_h_spin));
352                 gtk_spin_button_set_range (GTK_SPIN_BUTTON (editor->priv->size_h_spin),
353                                            0.0, 2.0*h_max);
354                 gtk_spin_button_set_value (GTK_SPIN_BUTTON (editor->priv->size_h_spin), tmp);
355
356                 editor->priv->stop_signals = FALSE;
357
358         }
359
360         gl_debug (DEBUG_EDITOR, "END");
361 }
362
363 /*****************************************************************************/
364 /* Set base or natural size of image.                                        */
365 /*****************************************************************************/
366 void
367 gl_object_editor_set_base_size    (glObjectEditor      *editor,
368                                    gdouble              w_base,
369                                    gdouble              h_base)
370 {
371         gl_debug (DEBUG_EDITOR, "Setting w_base = %g", w_base);
372         gl_debug (DEBUG_EDITOR, "Setting h_base = %g", h_base);
373
374         editor->priv->w_base = w_base;
375         editor->priv->h_base = h_base;
376 }
377
378 /*****************************************************************************/
379 /* Query size.                                                               */
380 /*****************************************************************************/
381 void
382 gl_object_editor_get_size (glObjectEditor      *editor,
383                            gdouble             *w,
384                            gdouble             *h)
385 {
386         gl_debug (DEBUG_EDITOR, "START");
387
388
389         /* Get values from widgets */
390         *w = gtk_spin_button_get_value (GTK_SPIN_BUTTON (editor->priv->size_w_spin));
391         *h = gtk_spin_button_get_value (GTK_SPIN_BUTTON (editor->priv->size_h_spin));
392
393         /* convert everything back to our internal units (points) */
394         *w /= editor->priv->units_per_point;
395         *h /= editor->priv->units_per_point;
396
397         /* save a copy in internal units */
398         editor->priv->w = *w;
399         editor->priv->h = *h;
400
401         gl_debug (DEBUG_EDITOR, "END");
402 }
403
404 /*****************************************************************************/
405 /* PRIVATE. Prefs changed callback.  Update units related items.            */
406 /*****************************************************************************/
407 void
408 size_prefs_changed_cb (glObjectEditor *editor)
409 {
410         const gchar  *units_string;
411         gdouble       climb_rate;
412         gint          digits;
413
414         gl_debug (DEBUG_EDITOR, "START");
415
416         /* Get new configuration information */
417         units_string = gl_prefs_get_units_string ();
418         editor->priv->units_per_point = gl_prefs_get_units_per_point ();
419         climb_rate = gl_prefs_get_units_step_size ();
420         digits = gl_prefs_get_units_precision ();
421
422         /* Update characteristics of w_spin/h_spin */
423         editor->priv->stop_signals = TRUE;
424         gtk_spin_button_set_digits (GTK_SPIN_BUTTON(editor->priv->size_w_spin),
425                                     digits);
426         gtk_spin_button_set_digits (GTK_SPIN_BUTTON(editor->priv->size_h_spin),
427                                     digits);
428         gtk_spin_button_set_increments (GTK_SPIN_BUTTON(editor->priv->size_w_spin),
429                                         climb_rate, 10.0*climb_rate);
430         gtk_spin_button_set_increments (GTK_SPIN_BUTTON(editor->priv->size_h_spin),
431                                         climb_rate, 10.0*climb_rate);
432         editor->priv->stop_signals = FALSE;
433
434         /* Update units_labels */
435         gtk_label_set_text (GTK_LABEL(editor->priv->size_w_units_label),
436                             units_string);
437         gtk_label_set_text (GTK_LABEL(editor->priv->size_h_units_label),
438                             units_string);
439
440         /* Update values of w_spin/h_spin */
441         gl_object_editor_set_size (editor,
442                                    editor->priv->w,
443                                    editor->priv->h);
444         gl_object_editor_set_max_size (editor,
445                                        editor->priv->w_max,
446                                        editor->priv->h_max);
447
448         gl_debug (DEBUG_EDITOR, "END");
449 }
450