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