]> git.sur5r.net Git - glabels/blob - src/object-editor-size-page.c
Imported Upstream version 2.2.8
[glabels] / 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, wh_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         wh_max = MAX( w_max, h_max );
254
255         if ( (w_base > wh_max) || (h_base > wh_max) ) {
256
257                 aspect_ratio = h_base / w_base;
258
259                 if ( aspect_ratio < 1.0 ) {
260                         w_base = wh_max;
261                         h_base = wh_max * aspect_ratio;
262
263                 } else {
264                         w_base = wh_max / aspect_ratio;
265                         h_base = wh_max;
266                 }
267         }
268
269         w_base *= editor->priv->units_per_point;
270         h_base *= editor->priv->units_per_point;
271
272         gtk_spin_button_set_value (GTK_SPIN_BUTTON (editor->priv->size_w_spin),
273                                    w_base);
274         gtk_spin_button_set_value (GTK_SPIN_BUTTON (editor->priv->size_h_spin),
275                                    h_base);
276
277         /* Emit our "changed" signal */
278         g_signal_emit (G_OBJECT (editor), gl_object_editor_signals[CHANGED], 0);
279         g_signal_emit (G_OBJECT (editor), gl_object_editor_signals[SIZE_CHANGED], 0);
280
281         editor->priv->stop_signals = FALSE;
282
283         gl_debug (DEBUG_EDITOR, "END");
284 }
285
286 /*****************************************************************************/
287 /* Set size.                                                                 */
288 /*****************************************************************************/
289 void
290 gl_object_editor_set_size (glObjectEditor      *editor,
291                              gdouble                w,
292                              gdouble                h)
293 {
294         gl_debug (DEBUG_EDITOR, "START");
295
296         editor->priv->stop_signals = TRUE;
297
298         /* save a copy in internal units */
299         editor->priv->w = w;
300         editor->priv->h = h;
301
302         /* convert internal units to displayed units */
303         gl_debug (DEBUG_EDITOR, "internal w,h = %g, %g", w, h);
304         w *= editor->priv->units_per_point;
305         h *= editor->priv->units_per_point;
306         gl_debug (DEBUG_EDITOR, "display w,h = %g, %g", w, h);
307
308         /* Set widget values */
309         gtk_spin_button_set_value (GTK_SPIN_BUTTON (editor->priv->size_w_spin), w);
310         gtk_spin_button_set_value (GTK_SPIN_BUTTON (editor->priv->size_h_spin), h);
311
312         /* Update aspect ratio */
313         editor->priv->size_aspect_ratio = h / w;
314
315         editor->priv->stop_signals = FALSE;
316
317         gl_debug (DEBUG_EDITOR, "END");
318 }
319
320 /*****************************************************************************/
321 /* Set maximum size.                                                         */
322 /*****************************************************************************/
323 void
324 gl_object_editor_set_max_size (glObjectEditor      *editor,
325                                gdouble              w_max,
326                                gdouble              h_max)
327 {
328         gdouble tmp;
329         gdouble wh_max;
330
331         gl_debug (DEBUG_EDITOR, "START");
332
333         if (editor->priv->size_page_vbox)
334         {
335
336                 editor->priv->stop_signals = TRUE;
337
338                 /* save a copy in internal units */
339                 editor->priv->w_max = w_max;
340                 editor->priv->h_max = h_max;
341
342                 /* convert internal units to displayed units */
343                 gl_debug (DEBUG_EDITOR, "internal w_max,h_max = %g, %g", w_max, h_max);
344                 w_max *= editor->priv->units_per_point;
345                 h_max *= editor->priv->units_per_point;
346                 wh_max = MAX( w_max, h_max );
347                 gl_debug (DEBUG_EDITOR, "display w_max,h_max = %g, %g", w_max, h_max);
348
349                 /* Set widget values */
350                 tmp = gtk_spin_button_get_value (GTK_SPIN_BUTTON (editor->priv->size_w_spin));
351                 gtk_spin_button_set_range (GTK_SPIN_BUTTON (editor->priv->size_w_spin),
352                                            0.0, 2.0*wh_max);
353                 gtk_spin_button_set_value (GTK_SPIN_BUTTON (editor->priv->size_w_spin), tmp);
354                 tmp = gtk_spin_button_get_value (GTK_SPIN_BUTTON (editor->priv->size_h_spin));
355                 gtk_spin_button_set_range (GTK_SPIN_BUTTON (editor->priv->size_h_spin),
356                                            0.0, 2.0*wh_max);
357                 gtk_spin_button_set_value (GTK_SPIN_BUTTON (editor->priv->size_h_spin), tmp);
358
359                 editor->priv->stop_signals = FALSE;
360
361         }
362
363         gl_debug (DEBUG_EDITOR, "END");
364 }
365
366 /*****************************************************************************/
367 /* Set base or natural size of image.                                        */
368 /*****************************************************************************/
369 void
370 gl_object_editor_set_base_size    (glObjectEditor      *editor,
371                                    gdouble              w_base,
372                                    gdouble              h_base)
373 {
374         gl_debug (DEBUG_EDITOR, "Setting w_base = %g", w_base);
375         gl_debug (DEBUG_EDITOR, "Setting h_base = %g", h_base);
376
377         editor->priv->w_base = w_base;
378         editor->priv->h_base = h_base;
379 }
380
381 /*****************************************************************************/
382 /* Query size.                                                               */
383 /*****************************************************************************/
384 void
385 gl_object_editor_get_size (glObjectEditor      *editor,
386                            gdouble             *w,
387                            gdouble             *h)
388 {
389         gl_debug (DEBUG_EDITOR, "START");
390
391
392         /* Get values from widgets */
393         *w = gtk_spin_button_get_value (GTK_SPIN_BUTTON (editor->priv->size_w_spin));
394         *h = gtk_spin_button_get_value (GTK_SPIN_BUTTON (editor->priv->size_h_spin));
395
396         /* convert everything back to our internal units (points) */
397         *w /= editor->priv->units_per_point;
398         *h /= editor->priv->units_per_point;
399
400         /* save a copy in internal units */
401         editor->priv->w = *w;
402         editor->priv->h = *h;
403
404         gl_debug (DEBUG_EDITOR, "END");
405 }
406
407 /*****************************************************************************/
408 /* PRIVATE. Prefs changed callback.  Update units related items.            */
409 /*****************************************************************************/
410 void
411 size_prefs_changed_cb (glObjectEditor *editor)
412 {
413         const gchar  *units_string;
414         gdouble       climb_rate;
415         gint          digits;
416
417         gl_debug (DEBUG_EDITOR, "START");
418
419         /* Get new configuration information */
420         units_string = gl_prefs_get_units_string ();
421         editor->priv->units_per_point = gl_prefs_get_units_per_point ();
422         climb_rate = gl_prefs_get_units_step_size ();
423         digits = gl_prefs_get_units_precision ();
424
425         /* Update characteristics of w_spin/h_spin */
426         editor->priv->stop_signals = TRUE;
427         gtk_spin_button_set_digits (GTK_SPIN_BUTTON(editor->priv->size_w_spin),
428                                     digits);
429         gtk_spin_button_set_digits (GTK_SPIN_BUTTON(editor->priv->size_h_spin),
430                                     digits);
431         gtk_spin_button_set_increments (GTK_SPIN_BUTTON(editor->priv->size_w_spin),
432                                         climb_rate, 10.0*climb_rate);
433         gtk_spin_button_set_increments (GTK_SPIN_BUTTON(editor->priv->size_h_spin),
434                                         climb_rate, 10.0*climb_rate);
435         editor->priv->stop_signals = FALSE;
436
437         /* Update units_labels */
438         gtk_label_set_text (GTK_LABEL(editor->priv->size_w_units_label),
439                             units_string);
440         gtk_label_set_text (GTK_LABEL(editor->priv->size_h_units_label),
441                             units_string);
442
443         /* Update values of w_spin/h_spin */
444         gl_object_editor_set_size (editor,
445                                    editor->priv->w,
446                                    editor->priv->h);
447         gl_object_editor_set_max_size (editor,
448                                        editor->priv->w_max,
449                                        editor->priv->h_max);
450
451         gl_debug (DEBUG_EDITOR, "END");
452 }
453