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"
32 #include "units-util.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)
71 const gchar *units_string;
75 gl_debug (DEBUG_EDITOR, "START");
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,
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),
92 gtk_box_pack_start (GTK_BOX (editor->priv->size_aspect_vbox),
93 editor->priv->size_aspect_checkbutton,
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);
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);
115 /* Connect signals */
116 g_signal_connect_swapped (G_OBJECT (editor->priv->size_aspect_checkbutton),
118 G_CALLBACK (aspect_toggle_cb),
120 g_signal_connect_swapped (G_OBJECT (editor->priv->size_w_spin),
122 G_CALLBACK (w_spin_cb),
124 g_signal_connect_swapped (G_OBJECT (editor->priv->size_h_spin),
126 G_CALLBACK (h_spin_cb),
128 g_signal_connect_swapped (G_OBJECT (editor->priv->size_reset_image_button),
130 G_CALLBACK (size_reset_cb),
133 gl_debug (DEBUG_EDITOR, "END");
137 /*--------------------------------------------------------------------------*/
138 /* PRIVATE. Maintain aspect ratio checkbox callback. */
139 /*--------------------------------------------------------------------------*/
141 aspect_toggle_cb (glObjectEditor *editor)
143 glWdgtChainButton *toggle;
146 gl_debug (DEBUG_EDITOR, "START");
148 toggle = GL_WDGT_CHAIN_BUTTON (editor->priv->size_aspect_checkbutton);
150 if (gl_wdgt_chain_button_get_active (toggle)) {
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));
155 editor->priv->size_aspect_ratio = h / w;
159 gl_debug (DEBUG_EDITOR, "END");
163 /*--------------------------------------------------------------------------*/
164 /* PRIVATE. W spin button changed callback. */
165 /*--------------------------------------------------------------------------*/
167 w_spin_cb (glObjectEditor *editor)
170 glWdgtChainButton *toggle;
172 gl_debug (DEBUG_EDITOR, "START");
174 toggle = GL_WDGT_CHAIN_BUTTON (editor->priv->size_aspect_checkbutton);
176 if (gl_wdgt_chain_button_get_active (toggle)) {
178 w = gtk_spin_button_get_value (GTK_SPIN_BUTTON (editor->priv->size_w_spin));
180 h = w * editor->priv->size_aspect_ratio;
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);
188 gl_object_editor_size_changed_cb (editor);
190 gl_debug (DEBUG_EDITOR, "END");
194 /*--------------------------------------------------------------------------*/
195 /* PRIVATE. H spin button changed callback. */
196 /*--------------------------------------------------------------------------*/
198 h_spin_cb (glObjectEditor *editor)
201 glWdgtChainButton *toggle;
203 gl_debug (DEBUG_EDITOR, "START");
205 toggle = GL_WDGT_CHAIN_BUTTON (editor->priv->size_aspect_checkbutton);
207 if (gl_wdgt_chain_button_get_active (toggle)) {
209 h = gtk_spin_button_get_value (GTK_SPIN_BUTTON (editor->priv->size_h_spin));
211 w = h / editor->priv->size_aspect_ratio;
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);
219 gl_object_editor_size_changed_cb (editor);
221 gl_debug (DEBUG_EDITOR, "END");
225 /*--------------------------------------------------------------------------*/
226 /* PRIVATE. Reset image size callback. */
227 /*--------------------------------------------------------------------------*/
229 size_reset_cb (glObjectEditor *editor)
231 gdouble w_base, h_base;
232 gdouble w_max, h_max, wh_max;
233 gdouble aspect_ratio;
235 gl_debug (DEBUG_EDITOR, "START");
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);
242 w_base = editor->priv->w_base;
243 h_base = editor->priv->h_base;
245 w_max = editor->priv->w_max;
246 h_max = editor->priv->h_max;
247 wh_max = MAX( w_max, h_max );
249 if ( (w_base > wh_max) || (h_base > wh_max) ) {
251 aspect_ratio = h_base / w_base;
253 if ( aspect_ratio < 1.0 ) {
255 h_base = wh_max * aspect_ratio;
258 w_base = wh_max / aspect_ratio;
263 w_base *= editor->priv->units_per_point;
264 h_base *= editor->priv->units_per_point;
266 gtk_spin_button_set_value (GTK_SPIN_BUTTON (editor->priv->size_w_spin),
268 gtk_spin_button_set_value (GTK_SPIN_BUTTON (editor->priv->size_h_spin),
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);
276 gl_object_editor_size_changed_cb (editor);
278 gl_debug (DEBUG_EDITOR, "END");
282 /*****************************************************************************/
284 /*****************************************************************************/
286 gl_object_editor_set_size (glObjectEditor *editor,
290 gl_debug (DEBUG_EDITOR, "START");
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);
297 /* save a copy in internal units */
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);
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);
311 /* Update aspect ratio */
312 editor->priv->size_aspect_ratio = h / w;
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);
319 gl_debug (DEBUG_EDITOR, "END");
323 /*****************************************************************************/
324 /* Set maximum size. */
325 /*****************************************************************************/
327 gl_object_editor_set_max_size (glObjectEditor *editor,
334 gl_debug (DEBUG_EDITOR, "START");
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);
341 /* save a copy in internal units */
342 editor->priv->w_max = w_max;
343 editor->priv->h_max = h_max;
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);
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),
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),
360 gtk_spin_button_set_value (GTK_SPIN_BUTTON (editor->priv->size_h_spin), tmp);
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);
367 gl_debug (DEBUG_EDITOR, "END");
371 /*****************************************************************************/
372 /* Set base or natural size of image. */
373 /*****************************************************************************/
375 gl_object_editor_set_base_size (glObjectEditor *editor,
379 gl_debug (DEBUG_EDITOR, "Setting w_base = %g", w_base);
380 gl_debug (DEBUG_EDITOR, "Setting h_base = %g", h_base);
382 editor->priv->w_base = w_base;
383 editor->priv->h_base = h_base;
387 /*****************************************************************************/
389 /*****************************************************************************/
391 gl_object_editor_get_size (glObjectEditor *editor,
395 gl_debug (DEBUG_EDITOR, "START");
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));
402 /* convert everything back to our internal units (points) */
403 *w /= editor->priv->units_per_point;
404 *h /= editor->priv->units_per_point;
406 /* save a copy in internal units */
407 editor->priv->w = *w;
408 editor->priv->h = *h;
410 gl_debug (DEBUG_EDITOR, "END");
414 /*****************************************************************************/
415 /* PRIVATE. Prefs changed callback. Update units related items. */
416 /*****************************************************************************/
418 size_prefs_changed_cb (glObjectEditor *editor)
421 const gchar *units_string;
425 gl_debug (DEBUG_EDITOR, "START");
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);
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);
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);
447 /* Update units_labels */
448 gtk_label_set_text (GTK_LABEL(editor->priv->size_w_units_label),
450 gtk_label_set_text (GTK_LABEL(editor->priv->size_h_units_label),
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);
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);
462 gl_debug (DEBUG_EDITOR, "END");
468 * Local Variables: -- emacs
470 * c-basic-offset: 8 -- emacs
471 * tab-width: 8 -- emacs
472 * indent-tabs-mode: nil -- emacs