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