]> git.sur5r.net Git - glabels/blob - src/object-editor-size-page.c
Imported Upstream version 3.0.0
[glabels] / 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 #include "units-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 {
70         lglUnits      units;
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_builder_util_get_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         gtk_widget_set_tooltip_text (editor->priv->size_aspect_checkbutton, _("Lock aspect ratio."));
90         gl_wdgt_chain_button_set_active (GL_WDGT_CHAIN_BUTTON(editor->priv->size_aspect_checkbutton),
91                                          TRUE);
92         gtk_box_pack_start (GTK_BOX (editor->priv->size_aspect_vbox),
93                             editor->priv->size_aspect_checkbutton,
94                             TRUE, TRUE, 0);
95
96
97         /* Get configuration information */
98         units = gl_prefs_model_get_units (gl_prefs);
99         units_string = lgl_units_get_name (units);
100         editor->priv->units_per_point = lgl_units_get_units_per_point (units);
101         climb_rate = gl_units_util_get_step_size (units);
102         digits = gl_units_util_get_precision (units);
103
104         /* Modify widgets based on configuration */
105         gtk_spin_button_set_digits (GTK_SPIN_BUTTON(editor->priv->size_w_spin), digits);
106         gtk_spin_button_set_increments (GTK_SPIN_BUTTON(editor->priv->size_w_spin),
107                                         climb_rate, 10.0*climb_rate);
108         gtk_label_set_text (GTK_LABEL(editor->priv->size_w_units_label), units_string);
109         gtk_spin_button_set_digits (GTK_SPIN_BUTTON(editor->priv->size_h_spin), digits);
110         gtk_spin_button_set_increments (GTK_SPIN_BUTTON(editor->priv->size_h_spin),
111                                         climb_rate, 10.0*climb_rate);
112         gtk_label_set_text (GTK_LABEL(editor->priv->size_h_units_label), units_string);
113
114
115         /* Connect signals */
116         g_signal_connect_swapped (G_OBJECT (editor->priv->size_aspect_checkbutton),
117                                   "toggled",
118                                   G_CALLBACK (aspect_toggle_cb),
119                                   G_OBJECT (editor));
120         g_signal_connect_swapped (G_OBJECT (editor->priv->size_w_spin),
121                                   "value-changed",
122                                   G_CALLBACK (w_spin_cb),
123                                   G_OBJECT (editor));
124         g_signal_connect_swapped (G_OBJECT (editor->priv->size_h_spin),
125                                   "value-changed",
126                                   G_CALLBACK (h_spin_cb),
127                                   G_OBJECT (editor));
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         gl_debug (DEBUG_EDITOR, "END");
134 }
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         gl_debug (DEBUG_EDITOR, "START");
147
148         toggle = GL_WDGT_CHAIN_BUTTON (editor->priv->size_aspect_checkbutton);
149
150         if (gl_wdgt_chain_button_get_active (toggle)) {
151                                                                                 
152                 w = gtk_spin_button_get_value (GTK_SPIN_BUTTON(editor->priv->size_w_spin));
153                 h = gtk_spin_button_get_value (GTK_SPIN_BUTTON(editor->priv->size_h_spin));
154                                                                                 
155                 editor->priv->size_aspect_ratio = h / w;
156                                                                                 
157         }
158
159         gl_debug (DEBUG_EDITOR, "END");
160 }
161
162
163 /*--------------------------------------------------------------------------*/
164 /* PRIVATE.  W spin button changed callback.                                */
165 /*--------------------------------------------------------------------------*/
166 static void
167 w_spin_cb (glObjectEditor *editor)
168 {
169         gdouble            w, h;
170         glWdgtChainButton *toggle;
171
172         gl_debug (DEBUG_EDITOR, "START");
173
174         toggle = GL_WDGT_CHAIN_BUTTON (editor->priv->size_aspect_checkbutton);
175
176         if (gl_wdgt_chain_button_get_active (toggle)) {
177
178                 w = gtk_spin_button_get_value (GTK_SPIN_BUTTON (editor->priv->size_w_spin));
179                                                                                 
180                 h = w * editor->priv->size_aspect_ratio;
181                                                                                 
182                 /* Update our sibling control, blocking recursion. */
183                 g_signal_handlers_block_by_func (G_OBJECT (editor->priv->size_h_spin), h_spin_cb, editor);
184                 gtk_spin_button_set_value (GTK_SPIN_BUTTON (editor->priv->size_h_spin), h);
185                 g_signal_handlers_unblock_by_func (G_OBJECT (editor->priv->size_h_spin), h_spin_cb, editor);
186         }
187                                                                                 
188         gl_object_editor_size_changed_cb (editor);
189                                                                                 
190         gl_debug (DEBUG_EDITOR, "END");
191 }
192
193
194 /*--------------------------------------------------------------------------*/
195 /* PRIVATE.  H spin button changed callback.                                */
196 /*--------------------------------------------------------------------------*/
197 static void
198 h_spin_cb (glObjectEditor *editor)
199 {
200         gdouble            w, h;
201         glWdgtChainButton *toggle;
202
203         gl_debug (DEBUG_EDITOR, "START");
204
205         toggle = GL_WDGT_CHAIN_BUTTON (editor->priv->size_aspect_checkbutton);
206                                                                                 
207         if (gl_wdgt_chain_button_get_active (toggle)) {
208
209                 h = gtk_spin_button_get_value (GTK_SPIN_BUTTON (editor->priv->size_h_spin));
210                                                                                 
211                 w = h / editor->priv->size_aspect_ratio;
212                                                                                 
213                 /* Update our sibling control, blocking recursion. */
214                 g_signal_handlers_block_by_func (G_OBJECT (editor->priv->size_w_spin), w_spin_cb, editor);
215                 gtk_spin_button_set_value (GTK_SPIN_BUTTON (editor->priv->size_w_spin), w);
216                 g_signal_handlers_unblock_by_func (G_OBJECT (editor->priv->size_w_spin), w_spin_cb, editor);
217         }
218                                                                                 
219         gl_object_editor_size_changed_cb (editor);
220                                                                                 
221         gl_debug (DEBUG_EDITOR, "END");
222 }
223
224
225 /*--------------------------------------------------------------------------*/
226 /* PRIVATE.  Reset image size callback.                                     */
227 /*--------------------------------------------------------------------------*/
228 static void
229 size_reset_cb (glObjectEditor *editor)
230 {
231         gdouble w_base, h_base;
232         gdouble w_max, h_max, wh_max;
233         gdouble aspect_ratio;
234
235         gl_debug (DEBUG_EDITOR, "START");
236
237
238         g_signal_handlers_block_by_func (G_OBJECT (editor->priv->size_w_spin), w_spin_cb, editor);
239         g_signal_handlers_block_by_func (G_OBJECT (editor->priv->size_h_spin), h_spin_cb, editor);
240
241
242         w_base = editor->priv->w_base;
243         h_base = editor->priv->h_base;
244
245         w_max = editor->priv->w_max;
246         h_max = editor->priv->h_max;
247         wh_max = MAX( w_max, h_max );
248
249         if ( (w_base > wh_max) || (h_base > wh_max) ) {
250
251                 aspect_ratio = h_base / w_base;
252
253                 if ( aspect_ratio < 1.0 ) {
254                         w_base = wh_max;
255                         h_base = wh_max * aspect_ratio;
256
257                 } else {
258                         w_base = wh_max / aspect_ratio;
259                         h_base = wh_max;
260                 }
261         }
262
263         w_base *= editor->priv->units_per_point;
264         h_base *= editor->priv->units_per_point;
265
266         gtk_spin_button_set_value (GTK_SPIN_BUTTON (editor->priv->size_w_spin),
267                                    w_base);
268         gtk_spin_button_set_value (GTK_SPIN_BUTTON (editor->priv->size_h_spin),
269                                    h_base);
270
271
272         g_signal_handlers_unblock_by_func (G_OBJECT (editor->priv->size_w_spin), w_spin_cb, editor);
273         g_signal_handlers_unblock_by_func (G_OBJECT (editor->priv->size_h_spin), h_spin_cb, editor);
274
275
276         gl_object_editor_size_changed_cb (editor);
277
278         gl_debug (DEBUG_EDITOR, "END");
279 }
280
281
282 /*****************************************************************************/
283 /* Set size.                                                                 */
284 /*****************************************************************************/
285 void
286 gl_object_editor_set_size (glObjectEditor      *editor,
287                            gdouble              w,
288                            gdouble              h)
289 {
290         gl_debug (DEBUG_EDITOR, "START");
291
292
293         g_signal_handlers_block_by_func (G_OBJECT (editor->priv->size_w_spin), w_spin_cb, editor);
294         g_signal_handlers_block_by_func (G_OBJECT (editor->priv->size_h_spin), h_spin_cb, editor);
295
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
315         g_signal_handlers_unblock_by_func (G_OBJECT (editor->priv->size_w_spin), w_spin_cb, editor);
316         g_signal_handlers_unblock_by_func (G_OBJECT (editor->priv->size_h_spin), h_spin_cb, editor);
317
318
319         gl_debug (DEBUG_EDITOR, "END");
320 }
321
322
323 /*****************************************************************************/
324 /* Set maximum size.                                                         */
325 /*****************************************************************************/
326 void
327 gl_object_editor_set_max_size (glObjectEditor      *editor,
328                                gdouble              w_max,
329                                gdouble              h_max)
330 {
331         gdouble tmp;
332         gdouble wh_max;
333
334         gl_debug (DEBUG_EDITOR, "START");
335
336
337         g_signal_handlers_block_by_func (G_OBJECT (editor->priv->size_w_spin), w_spin_cb, editor);
338         g_signal_handlers_block_by_func (G_OBJECT (editor->priv->size_h_spin), h_spin_cb, editor);
339
340
341         /* save a copy in internal units */
342         editor->priv->w_max = w_max;
343         editor->priv->h_max = h_max;
344
345         /* convert internal units to displayed units */
346         gl_debug (DEBUG_EDITOR, "internal w_max,h_max = %g, %g", w_max, h_max);
347         w_max *= editor->priv->units_per_point;
348         h_max *= editor->priv->units_per_point;
349         wh_max = MAX( w_max, h_max );
350         gl_debug (DEBUG_EDITOR, "display w_max,h_max = %g, %g", w_max, h_max);
351
352         /* Set widget values */
353         tmp = gtk_spin_button_get_value (GTK_SPIN_BUTTON (editor->priv->size_w_spin));
354         gtk_spin_button_set_range (GTK_SPIN_BUTTON (editor->priv->size_w_spin),
355                                    0.0, 2.0*wh_max);
356         gtk_spin_button_set_value (GTK_SPIN_BUTTON (editor->priv->size_w_spin), tmp);
357         tmp = gtk_spin_button_get_value (GTK_SPIN_BUTTON (editor->priv->size_h_spin));
358         gtk_spin_button_set_range (GTK_SPIN_BUTTON (editor->priv->size_h_spin),
359                                    0.0, 2.0*wh_max);
360         gtk_spin_button_set_value (GTK_SPIN_BUTTON (editor->priv->size_h_spin), tmp);
361
362
363         g_signal_handlers_unblock_by_func (G_OBJECT (editor->priv->size_w_spin), w_spin_cb, editor);
364         g_signal_handlers_unblock_by_func (G_OBJECT (editor->priv->size_h_spin), h_spin_cb, editor);
365
366
367         gl_debug (DEBUG_EDITOR, "END");
368 }
369
370
371 /*****************************************************************************/
372 /* Set base or natural size of image.                                        */
373 /*****************************************************************************/
374 void
375 gl_object_editor_set_base_size    (glObjectEditor      *editor,
376                                    gdouble              w_base,
377                                    gdouble              h_base)
378 {
379         gl_debug (DEBUG_EDITOR, "Setting w_base = %g", w_base);
380         gl_debug (DEBUG_EDITOR, "Setting h_base = %g", h_base);
381
382         editor->priv->w_base = w_base;
383         editor->priv->h_base = h_base;
384 }
385
386
387 /*****************************************************************************/
388 /* Query size.                                                               */
389 /*****************************************************************************/
390 void
391 gl_object_editor_get_size (glObjectEditor      *editor,
392                            gdouble             *w,
393                            gdouble             *h)
394 {
395         gl_debug (DEBUG_EDITOR, "START");
396
397
398         /* Get values from widgets */
399         *w = gtk_spin_button_get_value (GTK_SPIN_BUTTON (editor->priv->size_w_spin));
400         *h = gtk_spin_button_get_value (GTK_SPIN_BUTTON (editor->priv->size_h_spin));
401
402         /* convert everything back to our internal units (points) */
403         *w /= editor->priv->units_per_point;
404         *h /= editor->priv->units_per_point;
405
406         /* save a copy in internal units */
407         editor->priv->w = *w;
408         editor->priv->h = *h;
409
410         gl_debug (DEBUG_EDITOR, "END");
411 }
412
413
414 /*****************************************************************************/
415 /* PRIVATE. Prefs changed callback.  Update units related items.            */
416 /*****************************************************************************/
417 void
418 size_prefs_changed_cb (glObjectEditor *editor)
419 {
420         lglUnits      units;
421         const gchar  *units_string;
422         gdouble       climb_rate;
423         gint          digits;
424
425         gl_debug (DEBUG_EDITOR, "START");
426
427
428         g_signal_handlers_block_by_func (G_OBJECT (editor->priv->size_w_spin), w_spin_cb, editor);
429         g_signal_handlers_block_by_func (G_OBJECT (editor->priv->size_h_spin), h_spin_cb, editor);
430
431
432         /* Get new configuration information */
433         units = gl_prefs_model_get_units (gl_prefs);
434         units_string = lgl_units_get_name (units);
435         editor->priv->units_per_point = lgl_units_get_units_per_point (units);
436         climb_rate = gl_units_util_get_step_size (units);
437         digits = gl_units_util_get_precision (units);
438
439         /* Update characteristics of w_spin/h_spin */
440         gtk_spin_button_set_digits (GTK_SPIN_BUTTON(editor->priv->size_w_spin), digits);
441         gtk_spin_button_set_digits (GTK_SPIN_BUTTON(editor->priv->size_h_spin), digits);
442         gtk_spin_button_set_increments (GTK_SPIN_BUTTON(editor->priv->size_w_spin),
443                                         climb_rate, 10.0*climb_rate);
444         gtk_spin_button_set_increments (GTK_SPIN_BUTTON(editor->priv->size_h_spin),
445                                         climb_rate, 10.0*climb_rate);
446
447         /* Update units_labels */
448         gtk_label_set_text (GTK_LABEL(editor->priv->size_w_units_label),
449                             units_string);
450         gtk_label_set_text (GTK_LABEL(editor->priv->size_h_units_label),
451                             units_string);
452
453         /* Update values of w_spin/h_spin */
454         gl_object_editor_set_size (editor, editor->priv->w, editor->priv->h);
455         gl_object_editor_set_max_size (editor, editor->priv->w_max, editor->priv->h_max);
456
457
458         g_signal_handlers_unblock_by_func (G_OBJECT (editor->priv->size_w_spin), w_spin_cb, editor);
459         g_signal_handlers_unblock_by_func (G_OBJECT (editor->priv->size_h_spin), h_spin_cb, editor);
460
461
462         gl_debug (DEBUG_EDITOR, "END");
463 }
464
465
466
467 /*
468  * Local Variables:       -- emacs
469  * mode: C                -- emacs
470  * c-basic-offset: 8      -- emacs
471  * tab-width: 8           -- emacs
472  * indent-tabs-mode: nil  -- emacs
473  * End:                   -- emacs
474  */