2 * object-editor-size-page.c
3 * Copyright (C) 2003-2009 Jim Evins <evins@snaught.com>.
5 * This file is part of gLabels.
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.
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.
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/>.
23 #include "object-editor.h"
25 #include <glib/gi18n.h>
30 #include "wdgt-chain-button.h"
31 #include "builder-util.h"
33 #include "object-editor-private.h"
38 /*===========================================*/
40 /*===========================================*/
43 /*===========================================*/
44 /* Private data types */
45 /*===========================================*/
48 /*===========================================*/
50 /*===========================================*/
53 /*===========================================*/
54 /* Local function prototypes */
55 /*===========================================*/
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);
63 /*--------------------------------------------------------------------------*/
64 /* PRIVATE. Prepare size page. */
65 /*--------------------------------------------------------------------------*/
67 gl_object_editor_prepare_size_page (glObjectEditor *editor,
68 glObjectEditorOption option)
70 const gchar *units_string;
74 gl_debug (DEBUG_EDITOR, "START");
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,
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),
90 gtk_box_pack_start (GTK_BOX (editor->priv->size_aspect_vbox),
91 editor->priv->size_aspect_checkbutton,
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 ();
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);
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);
117 /* Connect signals */
118 g_signal_connect_swapped (G_OBJECT (editor->priv->size_aspect_checkbutton),
120 G_CALLBACK (aspect_toggle_cb),
122 g_signal_connect_swapped (G_OBJECT (editor->priv->size_w_spin),
124 G_CALLBACK (w_spin_cb),
126 g_signal_connect_swapped (G_OBJECT (editor->priv->size_h_spin),
128 G_CALLBACK (h_spin_cb),
131 if (option == GL_OBJECT_EDITOR_SIZE_IMAGE_PAGE) {
132 g_signal_connect_swapped (G_OBJECT (editor->priv->size_reset_image_button),
134 G_CALLBACK (size_reset_cb),
138 gl_debug (DEBUG_EDITOR, "END");
142 /*--------------------------------------------------------------------------*/
143 /* PRIVATE. Maintain aspect ratio checkbox callback. */
144 /*--------------------------------------------------------------------------*/
146 aspect_toggle_cb (glObjectEditor *editor)
148 glWdgtChainButton *toggle;
151 if (editor->priv->stop_signals) return;
153 gl_debug (DEBUG_EDITOR, "START");
155 toggle = GL_WDGT_CHAIN_BUTTON (editor->priv->size_aspect_checkbutton);
157 if (gl_wdgt_chain_button_get_active (toggle)) {
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));
162 editor->priv->size_aspect_ratio = h / w;
166 gl_debug (DEBUG_EDITOR, "END");
170 /*--------------------------------------------------------------------------*/
171 /* PRIVATE. W spin button changed callback. */
172 /*--------------------------------------------------------------------------*/
174 w_spin_cb (glObjectEditor *editor)
177 glWdgtChainButton *toggle;
179 if (editor->priv->stop_signals) return;
181 gl_debug (DEBUG_EDITOR, "START");
183 toggle = GL_WDGT_CHAIN_BUTTON (editor->priv->size_aspect_checkbutton);
185 if (gl_wdgt_chain_button_get_active (toggle)) {
187 w = gtk_spin_button_get_value (GTK_SPIN_BUTTON (editor->priv->size_w_spin));
189 h = w * editor->priv->size_aspect_ratio;
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;
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);
201 gl_debug (DEBUG_EDITOR, "END");
205 /*--------------------------------------------------------------------------*/
206 /* PRIVATE. H spin button changed callback. */
207 /*--------------------------------------------------------------------------*/
209 h_spin_cb (glObjectEditor *editor)
212 glWdgtChainButton *toggle;
214 if (editor->priv->stop_signals) return;
216 gl_debug (DEBUG_EDITOR, "START");
218 toggle = GL_WDGT_CHAIN_BUTTON (editor->priv->size_aspect_checkbutton);
220 if (gl_wdgt_chain_button_get_active (toggle)) {
222 h = gtk_spin_button_get_value (GTK_SPIN_BUTTON (editor->priv->size_h_spin));
224 w = h / editor->priv->size_aspect_ratio;
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;
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);
236 gl_debug (DEBUG_EDITOR, "END");
240 /*--------------------------------------------------------------------------*/
241 /* PRIVATE. Reset image size callback. */
242 /*--------------------------------------------------------------------------*/
244 size_reset_cb (glObjectEditor *editor)
246 gdouble w_base, h_base;
247 gdouble w_max, h_max, wh_max;
248 gdouble aspect_ratio;
250 if (editor->priv->stop_signals) return;
252 gl_debug (DEBUG_EDITOR, "START");
254 editor->priv->stop_signals = TRUE;
256 w_base = editor->priv->w_base;
257 h_base = editor->priv->h_base;
259 w_max = editor->priv->w_max;
260 h_max = editor->priv->h_max;
261 wh_max = MAX( w_max, h_max );
263 if ( (w_base > wh_max) || (h_base > wh_max) ) {
265 aspect_ratio = h_base / w_base;
267 if ( aspect_ratio < 1.0 ) {
269 h_base = wh_max * aspect_ratio;
272 w_base = wh_max / aspect_ratio;
277 w_base *= editor->priv->units_per_point;
278 h_base *= editor->priv->units_per_point;
280 gtk_spin_button_set_value (GTK_SPIN_BUTTON (editor->priv->size_w_spin),
282 gtk_spin_button_set_value (GTK_SPIN_BUTTON (editor->priv->size_h_spin),
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);
289 editor->priv->stop_signals = FALSE;
291 gl_debug (DEBUG_EDITOR, "END");
295 /*****************************************************************************/
297 /*****************************************************************************/
299 gl_object_editor_set_size (glObjectEditor *editor,
303 gl_debug (DEBUG_EDITOR, "START");
305 editor->priv->stop_signals = TRUE;
307 /* save a copy in internal units */
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);
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);
321 /* Update aspect ratio */
322 editor->priv->size_aspect_ratio = h / w;
324 editor->priv->stop_signals = FALSE;
326 gl_debug (DEBUG_EDITOR, "END");
330 /*****************************************************************************/
331 /* Set maximum size. */
332 /*****************************************************************************/
334 gl_object_editor_set_max_size (glObjectEditor *editor,
341 gl_debug (DEBUG_EDITOR, "START");
343 if (editor->priv->size_page_vbox)
346 editor->priv->stop_signals = TRUE;
348 /* save a copy in internal units */
349 editor->priv->w_max = w_max;
350 editor->priv->h_max = h_max;
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);
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),
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),
367 gtk_spin_button_set_value (GTK_SPIN_BUTTON (editor->priv->size_h_spin), tmp);
369 editor->priv->stop_signals = FALSE;
373 gl_debug (DEBUG_EDITOR, "END");
377 /*****************************************************************************/
378 /* Set base or natural size of image. */
379 /*****************************************************************************/
381 gl_object_editor_set_base_size (glObjectEditor *editor,
385 gl_debug (DEBUG_EDITOR, "Setting w_base = %g", w_base);
386 gl_debug (DEBUG_EDITOR, "Setting h_base = %g", h_base);
388 editor->priv->w_base = w_base;
389 editor->priv->h_base = h_base;
393 /*****************************************************************************/
395 /*****************************************************************************/
397 gl_object_editor_get_size (glObjectEditor *editor,
401 gl_debug (DEBUG_EDITOR, "START");
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));
408 /* convert everything back to our internal units (points) */
409 *w /= editor->priv->units_per_point;
410 *h /= editor->priv->units_per_point;
412 /* save a copy in internal units */
413 editor->priv->w = *w;
414 editor->priv->h = *h;
416 gl_debug (DEBUG_EDITOR, "END");
420 /*****************************************************************************/
421 /* PRIVATE. Prefs changed callback. Update units related items. */
422 /*****************************************************************************/
424 size_prefs_changed_cb (glObjectEditor *editor)
426 const gchar *units_string;
430 gl_debug (DEBUG_EDITOR, "START");
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 ();
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),
442 gtk_spin_button_set_digits (GTK_SPIN_BUTTON(editor->priv->size_h_spin),
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;
450 /* Update units_labels */
451 gtk_label_set_text (GTK_LABEL(editor->priv->size_w_units_label),
453 gtk_label_set_text (GTK_LABEL(editor->priv->size_h_units_label),
456 /* Update values of w_spin/h_spin */
457 gl_object_editor_set_size (editor,
460 gl_object_editor_set_max_size (editor,
462 editor->priv->h_max);
464 gl_debug (DEBUG_EDITOR, "END");
470 * Local Variables: -- emacs
472 * c-basic-offset: 8 -- emacs
473 * tab-width: 8 -- emacs
474 * indent-tabs-mode: nil -- emacs