]> git.sur5r.net Git - glabels/blob - src/object-editor-size-page.c
Cleanup of shadows for boxes and ellipses.
[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         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 = gl_prefs_model_get_units (gl_prefs);
98         units_string = lgl_units_get_name (units);
99         editor->priv->units_per_point = lgl_units_get_units_per_point (units);
100         climb_rate = gl_units_util_get_step_size (units);
101         digits = gl_units_util_get_precision (units);
102
103         /* Modify widgets based on configuration */
104         gtk_spin_button_set_digits (GTK_SPIN_BUTTON(editor->priv->size_w_spin), digits);
105         gtk_spin_button_set_increments (GTK_SPIN_BUTTON(editor->priv->size_w_spin),
106                                         climb_rate, 10.0*climb_rate);
107         gtk_label_set_text (GTK_LABEL(editor->priv->size_w_units_label), units_string);
108         gtk_spin_button_set_digits (GTK_SPIN_BUTTON(editor->priv->size_h_spin), digits);
109         gtk_spin_button_set_increments (GTK_SPIN_BUTTON(editor->priv->size_h_spin),
110                                         climb_rate, 10.0*climb_rate);
111         gtk_label_set_text (GTK_LABEL(editor->priv->size_h_units_label), units_string);
112
113
114         /* Connect signals */
115         g_signal_connect_swapped (G_OBJECT (editor->priv->size_aspect_checkbutton),
116                                   "toggled",
117                                   G_CALLBACK (aspect_toggle_cb),
118                                   G_OBJECT (editor));
119         g_signal_connect_swapped (G_OBJECT (editor->priv->size_w_spin),
120                                   "changed",
121                                   G_CALLBACK (w_spin_cb),
122                                   G_OBJECT (editor));
123         g_signal_connect_swapped (G_OBJECT (editor->priv->size_h_spin),
124                                   "changed",
125                                   G_CALLBACK (h_spin_cb),
126                                   G_OBJECT (editor));
127         g_signal_connect_swapped (G_OBJECT (editor->priv->size_reset_image_button),
128                                   "clicked",
129                                   G_CALLBACK (size_reset_cb),
130                                   G_OBJECT (editor));
131
132         gl_debug (DEBUG_EDITOR, "END");
133 }
134
135
136 /*--------------------------------------------------------------------------*/
137 /* PRIVATE.  Maintain aspect ratio checkbox callback.                       */
138 /*--------------------------------------------------------------------------*/
139 static void
140 aspect_toggle_cb (glObjectEditor *editor)
141 {
142         glWdgtChainButton *toggle;
143         gdouble            w, h;
144
145         if (editor->priv->stop_signals) return;
146
147         gl_debug (DEBUG_EDITOR, "START");
148
149         toggle = GL_WDGT_CHAIN_BUTTON (editor->priv->size_aspect_checkbutton);
150
151         if (gl_wdgt_chain_button_get_active (toggle)) {
152                                                                                 
153                 w = gtk_spin_button_get_value (GTK_SPIN_BUTTON(editor->priv->size_w_spin));
154                 h = gtk_spin_button_get_value (GTK_SPIN_BUTTON(editor->priv->size_h_spin));
155                                                                                 
156                 editor->priv->size_aspect_ratio = h / w;
157                                                                                 
158         }
159
160         gl_debug (DEBUG_EDITOR, "END");
161 }
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         gl_object_editor_size_changed_cb (editor);
192                                                                                 
193         gl_debug (DEBUG_EDITOR, "END");
194 }
195
196
197 /*--------------------------------------------------------------------------*/
198 /* PRIVATE.  H spin button changed callback.                                */
199 /*--------------------------------------------------------------------------*/
200 static void
201 h_spin_cb (glObjectEditor *editor)
202 {
203         gdouble            w, h;
204         glWdgtChainButton *toggle;
205
206         if (editor->priv->stop_signals) return;
207
208         gl_debug (DEBUG_EDITOR, "START");
209
210         toggle = GL_WDGT_CHAIN_BUTTON (editor->priv->size_aspect_checkbutton);
211                                                                                 
212         if (gl_wdgt_chain_button_get_active (toggle)) {
213
214                 h = gtk_spin_button_get_value (GTK_SPIN_BUTTON (editor->priv->size_h_spin));
215                                                                                 
216                 w = h / editor->priv->size_aspect_ratio;
217                                                                                 
218                 /* Update our sibling control, blocking recursion. */
219                 editor->priv->stop_signals = TRUE;
220                 gtk_spin_button_set_value (GTK_SPIN_BUTTON (editor->priv->size_w_spin), w);
221                 editor->priv->stop_signals = FALSE;
222         }
223                                                                                 
224         gl_object_editor_size_changed_cb (editor);
225                                                                                 
226         gl_debug (DEBUG_EDITOR, "END");
227 }
228
229
230 /*--------------------------------------------------------------------------*/
231 /* PRIVATE.  Reset image size callback.                                     */
232 /*--------------------------------------------------------------------------*/
233 static void
234 size_reset_cb (glObjectEditor *editor)
235 {
236         gdouble w_base, h_base;
237         gdouble w_max, h_max, wh_max;
238         gdouble aspect_ratio;
239
240         if (editor->priv->stop_signals) return;
241
242         gl_debug (DEBUG_EDITOR, "START");
243
244         editor->priv->stop_signals = TRUE;
245
246         w_base = editor->priv->w_base;
247         h_base = editor->priv->h_base;
248
249         w_max = editor->priv->w_max;
250         h_max = editor->priv->h_max;
251         wh_max = MAX( w_max, h_max );
252
253         if ( (w_base > wh_max) || (h_base > wh_max) ) {
254
255                 aspect_ratio = h_base / w_base;
256
257                 if ( aspect_ratio < 1.0 ) {
258                         w_base = wh_max;
259                         h_base = wh_max * aspect_ratio;
260
261                 } else {
262                         w_base = wh_max / aspect_ratio;
263                         h_base = wh_max;
264                 }
265         }
266
267         w_base *= editor->priv->units_per_point;
268         h_base *= editor->priv->units_per_point;
269
270         gtk_spin_button_set_value (GTK_SPIN_BUTTON (editor->priv->size_w_spin),
271                                    w_base);
272         gtk_spin_button_set_value (GTK_SPIN_BUTTON (editor->priv->size_h_spin),
273                                    h_base);
274
275         editor->priv->stop_signals = FALSE;
276
277         gl_object_editor_size_changed_cb (editor);
278
279         gl_debug (DEBUG_EDITOR, "END");
280 }
281
282
283 /*****************************************************************************/
284 /* Set size.                                                                 */
285 /*****************************************************************************/
286 void
287 gl_object_editor_set_size (glObjectEditor      *editor,
288                              gdouble                w,
289                              gdouble                h)
290 {
291         gl_debug (DEBUG_EDITOR, "START");
292
293         editor->priv->stop_signals = TRUE;
294
295         /* save a copy in internal units */
296         editor->priv->w = w;
297         editor->priv->h = h;
298
299         /* convert internal units to displayed units */
300         gl_debug (DEBUG_EDITOR, "internal w,h = %g, %g", w, h);
301         w *= editor->priv->units_per_point;
302         h *= editor->priv->units_per_point;
303         gl_debug (DEBUG_EDITOR, "display w,h = %g, %g", w, h);
304
305         /* Set widget values */
306         gtk_spin_button_set_value (GTK_SPIN_BUTTON (editor->priv->size_w_spin), w);
307         gtk_spin_button_set_value (GTK_SPIN_BUTTON (editor->priv->size_h_spin), h);
308
309         /* Update aspect ratio */
310         editor->priv->size_aspect_ratio = h / w;
311
312         editor->priv->stop_signals = FALSE;
313
314         gl_debug (DEBUG_EDITOR, "END");
315 }
316
317
318 /*****************************************************************************/
319 /* Set maximum size.                                                         */
320 /*****************************************************************************/
321 void
322 gl_object_editor_set_max_size (glObjectEditor      *editor,
323                                gdouble              w_max,
324                                gdouble              h_max)
325 {
326         gdouble tmp;
327         gdouble wh_max;
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                 wh_max = MAX( w_max, h_max );
345                 gl_debug (DEBUG_EDITOR, "display w_max,h_max = %g, %g", w_max, h_max);
346
347                 /* Set widget values */
348                 tmp = gtk_spin_button_get_value (GTK_SPIN_BUTTON (editor->priv->size_w_spin));
349                 gtk_spin_button_set_range (GTK_SPIN_BUTTON (editor->priv->size_w_spin),
350                                            0.0, 2.0*wh_max);
351                 gtk_spin_button_set_value (GTK_SPIN_BUTTON (editor->priv->size_w_spin), tmp);
352                 tmp = gtk_spin_button_get_value (GTK_SPIN_BUTTON (editor->priv->size_h_spin));
353                 gtk_spin_button_set_range (GTK_SPIN_BUTTON (editor->priv->size_h_spin),
354                                            0.0, 2.0*wh_max);
355                 gtk_spin_button_set_value (GTK_SPIN_BUTTON (editor->priv->size_h_spin), tmp);
356
357                 editor->priv->stop_signals = FALSE;
358
359         }
360
361         gl_debug (DEBUG_EDITOR, "END");
362 }
363
364
365 /*****************************************************************************/
366 /* Set base or natural size of image.                                        */
367 /*****************************************************************************/
368 void
369 gl_object_editor_set_base_size    (glObjectEditor      *editor,
370                                    gdouble              w_base,
371                                    gdouble              h_base)
372 {
373         gl_debug (DEBUG_EDITOR, "Setting w_base = %g", w_base);
374         gl_debug (DEBUG_EDITOR, "Setting h_base = %g", h_base);
375
376         editor->priv->w_base = w_base;
377         editor->priv->h_base = h_base;
378 }
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 /*****************************************************************************/
409 /* PRIVATE. Prefs changed callback.  Update units related items.            */
410 /*****************************************************************************/
411 void
412 size_prefs_changed_cb (glObjectEditor *editor)
413 {
414         lglUnits      units;
415         const gchar  *units_string;
416         gdouble       climb_rate;
417         gint          digits;
418
419         gl_debug (DEBUG_EDITOR, "START");
420
421         /* Get new configuration information */
422         units = gl_prefs_model_get_units (gl_prefs);
423         units_string = lgl_units_get_name (units);
424         editor->priv->units_per_point = lgl_units_get_units_per_point (units);
425         climb_rate = gl_units_util_get_step_size (units);
426         digits = gl_units_util_get_precision (units);
427
428         /* Update characteristics of w_spin/h_spin */
429         editor->priv->stop_signals = TRUE;
430         gtk_spin_button_set_digits (GTK_SPIN_BUTTON(editor->priv->size_w_spin),
431                                     digits);
432         gtk_spin_button_set_digits (GTK_SPIN_BUTTON(editor->priv->size_h_spin),
433                                     digits);
434         gtk_spin_button_set_increments (GTK_SPIN_BUTTON(editor->priv->size_w_spin),
435                                         climb_rate, 10.0*climb_rate);
436         gtk_spin_button_set_increments (GTK_SPIN_BUTTON(editor->priv->size_h_spin),
437                                         climb_rate, 10.0*climb_rate);
438         editor->priv->stop_signals = FALSE;
439
440         /* Update units_labels */
441         gtk_label_set_text (GTK_LABEL(editor->priv->size_w_units_label),
442                             units_string);
443         gtk_label_set_text (GTK_LABEL(editor->priv->size_h_units_label),
444                             units_string);
445
446         /* Update values of w_spin/h_spin */
447         gl_object_editor_set_size (editor,
448                                    editor->priv->w,
449                                    editor->priv->h);
450         gl_object_editor_set_max_size (editor,
451                                        editor->priv->w_max,
452                                        editor->priv->h_max);
453
454         gl_debug (DEBUG_EDITOR, "END");
455 }
456
457
458
459 /*
460  * Local Variables:       -- emacs
461  * mode: C                -- emacs
462  * c-basic-offset: 8      -- emacs
463  * tab-width: 8           -- emacs
464  * indent-tabs-mode: nil  -- emacs
465  * End:                   -- emacs
466  */