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>
26 #include <gtk/gtklabel.h>
27 #include <gtk/gtkspinbutton.h>
31 #include "wdgt-chain-button.h"
34 #include "object-editor-private.h"
39 /*===========================================*/
41 /*===========================================*/
44 /*===========================================*/
45 /* Private data types */
46 /*===========================================*/
49 /*===========================================*/
51 /*===========================================*/
54 /*===========================================*/
55 /* Local function prototypes */
56 /*===========================================*/
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);
64 /*--------------------------------------------------------------------------*/
65 /* PRIVATE. Prepare size page. */
66 /*--------------------------------------------------------------------------*/
68 gl_object_editor_prepare_size_page (glObjectEditor *editor,
69 glObjectEditorOption option)
71 const gchar *units_string;
75 gl_debug (DEBUG_EDITOR, "START");
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,
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),
91 gtk_box_pack_start (GTK_BOX (editor->priv->size_aspect_vbox),
92 editor->priv->size_aspect_checkbutton,
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 ();
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);
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);
118 /* Connect signals */
119 g_signal_connect_swapped (G_OBJECT (editor->priv->size_aspect_checkbutton),
121 G_CALLBACK (aspect_toggle_cb),
123 g_signal_connect_swapped (G_OBJECT (editor->priv->size_w_spin),
125 G_CALLBACK (w_spin_cb),
127 g_signal_connect_swapped (G_OBJECT (editor->priv->size_h_spin),
129 G_CALLBACK (h_spin_cb),
132 if (option == GL_OBJECT_EDITOR_SIZE_IMAGE_PAGE) {
133 g_signal_connect_swapped (G_OBJECT (editor->priv->size_reset_image_button),
135 G_CALLBACK (size_reset_cb),
139 gl_debug (DEBUG_EDITOR, "END");
143 /*--------------------------------------------------------------------------*/
144 /* PRIVATE. Maintain aspect ratio checkbox callback. */
145 /*--------------------------------------------------------------------------*/
147 aspect_toggle_cb (glObjectEditor *editor)
149 glWdgtChainButton *toggle;
152 if (editor->priv->stop_signals) return;
154 gl_debug (DEBUG_EDITOR, "START");
156 toggle = GL_WDGT_CHAIN_BUTTON (editor->priv->size_aspect_checkbutton);
158 if (gl_wdgt_chain_button_get_active (toggle)) {
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));
163 editor->priv->size_aspect_ratio = h / w;
167 gl_debug (DEBUG_EDITOR, "END");
171 /*--------------------------------------------------------------------------*/
172 /* PRIVATE. W spin button changed callback. */
173 /*--------------------------------------------------------------------------*/
175 w_spin_cb (glObjectEditor *editor)
178 glWdgtChainButton *toggle;
180 if (editor->priv->stop_signals) return;
182 gl_debug (DEBUG_EDITOR, "START");
184 toggle = GL_WDGT_CHAIN_BUTTON (editor->priv->size_aspect_checkbutton);
186 if (gl_wdgt_chain_button_get_active (toggle)) {
188 w = gtk_spin_button_get_value (GTK_SPIN_BUTTON (editor->priv->size_w_spin));
190 h = w * editor->priv->size_aspect_ratio;
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;
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);
202 gl_debug (DEBUG_EDITOR, "END");
206 /*--------------------------------------------------------------------------*/
207 /* PRIVATE. H spin button changed callback. */
208 /*--------------------------------------------------------------------------*/
210 h_spin_cb (glObjectEditor *editor)
213 glWdgtChainButton *toggle;
215 if (editor->priv->stop_signals) return;
217 gl_debug (DEBUG_EDITOR, "START");
219 toggle = GL_WDGT_CHAIN_BUTTON (editor->priv->size_aspect_checkbutton);
221 if (gl_wdgt_chain_button_get_active (toggle)) {
223 h = gtk_spin_button_get_value (GTK_SPIN_BUTTON (editor->priv->size_h_spin));
225 w = h / editor->priv->size_aspect_ratio;
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;
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);
237 gl_debug (DEBUG_EDITOR, "END");
241 /*--------------------------------------------------------------------------*/
242 /* PRIVATE. Reset image size callback. */
243 /*--------------------------------------------------------------------------*/
245 size_reset_cb (glObjectEditor *editor)
247 gdouble w_base, h_base;
248 gdouble w_max, h_max, wh_max;
249 gdouble aspect_ratio;
251 if (editor->priv->stop_signals) return;
253 gl_debug (DEBUG_EDITOR, "START");
255 editor->priv->stop_signals = TRUE;
257 w_base = editor->priv->w_base;
258 h_base = editor->priv->h_base;
260 w_max = editor->priv->w_max;
261 h_max = editor->priv->h_max;
262 wh_max = MAX( w_max, h_max );
264 if ( (w_base > wh_max) || (h_base > wh_max) ) {
266 aspect_ratio = h_base / w_base;
268 if ( aspect_ratio < 1.0 ) {
270 h_base = wh_max * aspect_ratio;
273 w_base = wh_max / aspect_ratio;
278 w_base *= editor->priv->units_per_point;
279 h_base *= editor->priv->units_per_point;
281 gtk_spin_button_set_value (GTK_SPIN_BUTTON (editor->priv->size_w_spin),
283 gtk_spin_button_set_value (GTK_SPIN_BUTTON (editor->priv->size_h_spin),
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);
290 editor->priv->stop_signals = FALSE;
292 gl_debug (DEBUG_EDITOR, "END");
296 /*****************************************************************************/
298 /*****************************************************************************/
300 gl_object_editor_set_size (glObjectEditor *editor,
304 gl_debug (DEBUG_EDITOR, "START");
306 editor->priv->stop_signals = TRUE;
308 /* save a copy in internal units */
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);
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);
322 /* Update aspect ratio */
323 editor->priv->size_aspect_ratio = h / w;
325 editor->priv->stop_signals = FALSE;
327 gl_debug (DEBUG_EDITOR, "END");
331 /*****************************************************************************/
332 /* Set maximum size. */
333 /*****************************************************************************/
335 gl_object_editor_set_max_size (glObjectEditor *editor,
342 gl_debug (DEBUG_EDITOR, "START");
344 if (editor->priv->size_page_vbox)
347 editor->priv->stop_signals = TRUE;
349 /* save a copy in internal units */
350 editor->priv->w_max = w_max;
351 editor->priv->h_max = h_max;
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);
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),
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),
368 gtk_spin_button_set_value (GTK_SPIN_BUTTON (editor->priv->size_h_spin), tmp);
370 editor->priv->stop_signals = FALSE;
374 gl_debug (DEBUG_EDITOR, "END");
378 /*****************************************************************************/
379 /* Set base or natural size of image. */
380 /*****************************************************************************/
382 gl_object_editor_set_base_size (glObjectEditor *editor,
386 gl_debug (DEBUG_EDITOR, "Setting w_base = %g", w_base);
387 gl_debug (DEBUG_EDITOR, "Setting h_base = %g", h_base);
389 editor->priv->w_base = w_base;
390 editor->priv->h_base = h_base;
394 /*****************************************************************************/
396 /*****************************************************************************/
398 gl_object_editor_get_size (glObjectEditor *editor,
402 gl_debug (DEBUG_EDITOR, "START");
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));
409 /* convert everything back to our internal units (points) */
410 *w /= editor->priv->units_per_point;
411 *h /= editor->priv->units_per_point;
413 /* save a copy in internal units */
414 editor->priv->w = *w;
415 editor->priv->h = *h;
417 gl_debug (DEBUG_EDITOR, "END");
421 /*****************************************************************************/
422 /* PRIVATE. Prefs changed callback. Update units related items. */
423 /*****************************************************************************/
425 size_prefs_changed_cb (glObjectEditor *editor)
427 const gchar *units_string;
431 gl_debug (DEBUG_EDITOR, "START");
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 ();
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),
443 gtk_spin_button_set_digits (GTK_SPIN_BUTTON(editor->priv->size_h_spin),
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;
451 /* Update units_labels */
452 gtk_label_set_text (GTK_LABEL(editor->priv->size_w_units_label),
454 gtk_label_set_text (GTK_LABEL(editor->priv->size_h_units_label),
457 /* Update values of w_spin/h_spin */
458 gl_object_editor_set_size (editor,
461 gl_object_editor_set_max_size (editor,
463 editor->priv->h_max);
465 gl_debug (DEBUG_EDITOR, "END");
471 * Local Variables: -- emacs
473 * c-basic-offset: 8 -- emacs
474 * tab-width: 8 -- emacs
475 * indent-tabs-mode: nil -- emacs