]> git.sur5r.net Git - glabels/blob - glabels2/src/object-editor-shadow-page.c
2007-03-23 Jim Evins <evins@snaught.com>
[glabels] / glabels2 / src / object-editor-shadow-page.c
1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
2
3 /*
4  *  (GLABELS) Label and Business Card Creation program for GNOME
5  *
6  *  object-editor.c:  object properties editor module
7  *
8  *  Copyright (C) 2006  Jim Evins <evins@snaught.com>.
9  *
10  *  This program is free software; you can redistribute it and/or modify
11  *  it under the terms of the GNU General Public License as published by
12  *  the Free Software Foundation; either version 2 of the License, or
13  *  (at your option) any later version.
14  *
15  *  This program is distributed in the hope that it will be useful,
16  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  *  GNU General Public License for more details.
19  *
20  *  You should have received a copy of the GNU General Public License
21  *  along with this program; if not, write to the Free Software
22  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
23  */
24 #include <config.h>
25
26 #include "object-editor.h"
27
28 #include <glib/gi18n.h>
29 #include <gtk/gtktogglebutton.h>
30 #include <gtk/gtklabel.h>
31 #include <gtk/gtkspinbutton.h>
32 #include <gtk/gtkcombobox.h>
33 #include <math.h>
34
35 #include "prefs.h"
36 #include "mygal/widget-color-combo.h"
37 #include "color.h"
38 #include "util.h"
39
40 #include "object-editor-private.h"
41
42 #include "debug.h"
43
44 /*===========================================*/
45 /* Private macros                            */
46 /*===========================================*/
47
48 /*===========================================*/
49 /* Private data types                        */
50 /*===========================================*/
51
52 /*===========================================*/
53 /* Private globals                           */
54 /*===========================================*/
55
56 /*===========================================*/
57 /* Local function prototypes                 */
58 /*===========================================*/
59
60 static void shadow_enable_check_toggled_cb (glObjectEditor        *editor);
61 static void shadow_color_radio_toggled_cb  (glObjectEditor        *editor);
62
63
64 /*--------------------------------------------------------------------------*/
65 /* PRIVATE.  Prepare shadow page.                                         */
66 /*--------------------------------------------------------------------------*/
67 void
68 gl_object_editor_prepare_shadow_page (glObjectEditor *editor)
69 {
70         const gchar  *units_string;
71         gdouble       climb_rate;
72         gint          digits;
73
74         gl_debug (DEBUG_EDITOR, "START");
75
76         /* Extract widgets from XML tree. */
77         editor->priv->shadow_page_vbox
78                 = glade_xml_get_widget (editor->priv->gui, "shadow_page_vbox");
79         editor->priv->shadow_enable_check
80                 = glade_xml_get_widget (editor->priv->gui, "shadow_enable_check");
81         editor->priv->shadow_controls_table
82                 = glade_xml_get_widget (editor->priv->gui, "shadow_controls_table");
83         editor->priv->shadow_x_spin
84                 = glade_xml_get_widget (editor->priv->gui, "shadow_x_spin");
85         editor->priv->shadow_y_spin
86                 = glade_xml_get_widget (editor->priv->gui, "shadow_y_spin");
87         editor->priv->shadow_x_units_label
88                 = glade_xml_get_widget (editor->priv->gui, "shadow_x_units_label");
89         editor->priv->shadow_y_units_label
90                 = glade_xml_get_widget (editor->priv->gui, "shadow_y_units_label");
91         editor->priv->shadow_color_radio
92                 = glade_xml_get_widget (editor->priv->gui, "shadow_color_radio");       
93         editor->priv->shadow_key_radio
94                 = glade_xml_get_widget (editor->priv->gui, "shadow_key_radio"); 
95         editor->priv->shadow_color_combo
96                 = glade_xml_get_widget (editor->priv->gui, "shadow_color_combo");
97         editor->priv->shadow_key_combo
98                 = glade_xml_get_widget (editor->priv->gui, "shadow_key_combo"); 
99         editor->priv->shadow_opacity_spin
100                 = glade_xml_get_widget (editor->priv->gui, "shadow_opacity_spin");
101
102         gl_util_combo_box_add_text_model ( GTK_COMBO_BOX(editor->priv->shadow_key_combo));
103
104         /* Get configuration information */
105         units_string = gl_prefs_get_units_string ();
106         editor->priv->units_per_point = gl_prefs_get_units_per_point ();
107         climb_rate = gl_prefs_get_units_step_size ();
108         digits = gl_prefs_get_units_precision ();
109
110         /* Modify widgets based on configuration */
111         gtk_spin_button_set_digits (GTK_SPIN_BUTTON(editor->priv->shadow_x_spin), digits);
112         gtk_spin_button_set_increments (GTK_SPIN_BUTTON(editor->priv->shadow_x_spin),
113                                         climb_rate, 10.0*climb_rate);
114         gtk_label_set_text (GTK_LABEL(editor->priv->shadow_x_units_label), units_string);
115         gtk_spin_button_set_digits (GTK_SPIN_BUTTON(editor->priv->shadow_y_spin), digits);
116         gtk_spin_button_set_increments (GTK_SPIN_BUTTON(editor->priv->shadow_y_spin),
117                                         climb_rate, 10.0*climb_rate);
118         gtk_label_set_text (GTK_LABEL(editor->priv->shadow_y_units_label), units_string);
119
120         /* Un-hide */
121         gtk_widget_show_all (editor->priv->shadow_page_vbox);
122
123         /* Connect signals */
124         g_signal_connect_swapped (G_OBJECT (editor->priv->shadow_enable_check),
125                                   "toggled",
126                                   G_CALLBACK (shadow_enable_check_toggled_cb),
127                                   G_OBJECT (editor));                             
128         g_signal_connect_swapped (G_OBJECT (editor->priv->shadow_x_spin),
129                                   "changed",
130                                   G_CALLBACK (gl_object_editor_changed_cb),
131                                   G_OBJECT (editor));
132         g_signal_connect_swapped (G_OBJECT (editor->priv->shadow_y_spin),
133                                   "changed",
134                                   G_CALLBACK (gl_object_editor_changed_cb),
135                                   G_OBJECT (editor));
136         g_signal_connect_swapped (G_OBJECT (editor->priv->shadow_color_combo),
137                                   "color_changed",
138                                   G_CALLBACK (gl_object_editor_changed_cb),
139                                   G_OBJECT (editor));
140         g_signal_connect_swapped (G_OBJECT (editor->priv->shadow_key_combo),
141                                   "changed",
142                                   G_CALLBACK (gl_object_editor_changed_cb),
143                                   G_OBJECT (editor));
144         g_signal_connect_swapped (G_OBJECT (editor->priv->shadow_color_radio),
145                                   "toggled",
146                                   G_CALLBACK (shadow_color_radio_toggled_cb),
147                                   G_OBJECT (editor));                             
148         g_signal_connect_swapped (G_OBJECT (editor->priv->shadow_key_radio),
149                                   "toggled",
150                                   G_CALLBACK (shadow_color_radio_toggled_cb),
151                                   G_OBJECT (editor));                             
152         g_signal_connect_swapped (G_OBJECT (editor->priv->shadow_opacity_spin),
153                                   "changed",
154                                   G_CALLBACK (gl_object_editor_changed_cb),
155                                   G_OBJECT (editor));
156
157         gl_debug (DEBUG_EDITOR, "END");
158 }
159
160 /*****************************************************************************/
161 /* Set shadow parameters.                                                    */
162 /*****************************************************************************/
163 void
164 gl_object_editor_set_shadow_state (glObjectEditor      *editor,
165                                    gboolean             state)
166 {
167         gl_debug (DEBUG_EDITOR, "START");
168
169         g_signal_handlers_block_by_func (G_OBJECT(editor->priv->shadow_enable_check),
170                                          shadow_enable_check_toggled_cb,
171                                          editor);
172
173         gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (editor->priv->shadow_enable_check),
174                                       state);
175         gtk_widget_set_sensitive (editor->priv->shadow_controls_table, state);
176
177         g_signal_handlers_unblock_by_func (G_OBJECT(editor->priv->shadow_enable_check),
178                                            shadow_enable_check_toggled_cb,
179                                            editor);
180
181         gl_debug (DEBUG_EDITOR, "END");
182 }
183
184 void
185 gl_object_editor_set_shadow_offset (glObjectEditor      *editor,
186                                     gdouble              x,
187                                     gdouble              y)
188 {
189         gl_debug (DEBUG_EDITOR, "START");
190
191         g_signal_handlers_block_by_func (G_OBJECT(editor->priv->shadow_x_spin),
192                                          gl_object_editor_changed_cb,
193                                          editor);
194         g_signal_handlers_block_by_func (G_OBJECT(editor->priv->shadow_y_spin),
195                                          gl_object_editor_changed_cb,
196                                          editor);
197
198         /* save a copy in internal units */
199         editor->priv->shadow_x = x;
200         editor->priv->shadow_y = y;
201
202         /* convert internal units to displayed units */
203         gl_debug (DEBUG_EDITOR, "internal x,y = %g, %g", x, y);
204         x *= editor->priv->units_per_point;
205         y *= editor->priv->units_per_point;
206         gl_debug (DEBUG_EDITOR, "display x,y = %g, %g", x, y);
207
208         /* Set widget values */
209         gtk_spin_button_set_value (GTK_SPIN_BUTTON (editor->priv->shadow_x_spin), x);
210         gtk_spin_button_set_value (GTK_SPIN_BUTTON (editor->priv->shadow_y_spin), y);
211
212         g_signal_handlers_unblock_by_func (G_OBJECT(editor->priv->shadow_x_spin),
213                                            gl_object_editor_changed_cb,
214                                            editor);
215         g_signal_handlers_unblock_by_func (G_OBJECT(editor->priv->shadow_y_spin),
216                                            gl_object_editor_changed_cb,
217                                            editor);
218
219         gl_debug (DEBUG_EDITOR, "END");
220 }
221
222 void
223 gl_object_editor_set_shadow_color (glObjectEditor      *editor,
224                                    gboolean             merge_flag,
225                                    glColorNode         *color_node)
226 {
227         GdkColor *gdk_color;
228
229         gl_debug (DEBUG_EDITOR, "START");
230
231         g_signal_handlers_block_by_func (G_OBJECT(editor->priv->shadow_color_combo),
232                                          G_CALLBACK (gl_object_editor_changed_cb),
233                                          editor);
234         g_signal_handlers_block_by_func (G_OBJECT(editor->priv->shadow_key_combo),
235                                          G_CALLBACK (gl_object_editor_changed_cb),
236                                          editor);
237
238         gtk_widget_set_sensitive (editor->priv->shadow_key_radio, merge_flag);
239
240         if ( color_node->color == GL_COLOR_NONE ) {
241
242                 color_combo_set_color_to_default (COLOR_COMBO(editor->priv->shadow_color_combo));
243
244         } else {
245
246                 gdk_color = gl_color_to_gdk_color (color_node->color);
247                 color_combo_set_color (COLOR_COMBO(editor->priv->shadow_color_combo),
248                                            gdk_color);
249                 g_free (gdk_color);
250
251         }
252         
253         if (!color_node->field_flag) {
254                 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON
255                                                   (editor->priv->shadow_color_radio), TRUE); 
256                 gtk_widget_set_sensitive (editor->priv->shadow_color_combo, TRUE);
257                 gtk_widget_set_sensitive (editor->priv->shadow_key_combo, FALSE);
258                 
259         } else {
260                 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON
261                                                   (editor->priv->shadow_key_radio), TRUE); 
262                 gtk_widget_set_sensitive (editor->priv->shadow_color_combo, FALSE);
263                 gtk_widget_set_sensitive (editor->priv->shadow_key_combo, TRUE);
264                 
265                 gl_util_combo_box_set_active_text (GTK_COMBO_BOX (editor->priv->shadow_key_combo),
266                                                    color_node->key);
267         }
268         
269         g_signal_handlers_unblock_by_func (G_OBJECT(editor->priv->shadow_color_combo),
270                                            G_CALLBACK (gl_object_editor_changed_cb),
271                                            editor);
272         g_signal_handlers_unblock_by_func (G_OBJECT(editor->priv->shadow_key_combo),
273                                            G_CALLBACK (gl_object_editor_changed_cb),
274                                            editor);
275
276         gl_debug (DEBUG_EDITOR, "END");
277 }
278
279 void
280 gl_object_editor_set_shadow_opacity (glObjectEditor      *editor,
281                                      gdouble              alpha)
282 {
283         gl_debug (DEBUG_EDITOR, "START");
284
285         g_signal_handlers_block_by_func (G_OBJECT(editor->priv->shadow_opacity_spin),
286                                          gl_object_editor_changed_cb,
287                                          editor);
288
289         gtk_spin_button_set_value (GTK_SPIN_BUTTON (editor->priv->shadow_opacity_spin),
290                                    alpha * 100.0);
291
292         g_signal_handlers_unblock_by_func (G_OBJECT(editor->priv->shadow_opacity_spin),
293                                            gl_object_editor_changed_cb,
294                                            editor);
295
296         gl_debug (DEBUG_EDITOR, "END");
297 }
298
299
300 /*****************************************************************************/
301 /* Set maximum shadow offset.                                                */
302 /*****************************************************************************/
303 void
304 gl_object_editor_set_max_shadow_offset (glObjectEditor      *editor,
305                                         gdouble              x_max,
306                                         gdouble              y_max)
307 {
308         gdouble tmp;
309
310         gl_debug (DEBUG_EDITOR, "START");
311
312         g_signal_handlers_block_by_func (G_OBJECT(editor->priv->shadow_x_spin),
313                                          gl_object_editor_changed_cb,
314                                          editor);
315         g_signal_handlers_block_by_func (G_OBJECT(editor->priv->shadow_y_spin),
316                                          gl_object_editor_changed_cb,
317                                          editor);
318
319         /* save a copy in internal units */
320         editor->priv->shadow_x_max = x_max;
321         editor->priv->shadow_y_max = y_max;
322
323         /* convert internal units to displayed units */
324         gl_debug (DEBUG_EDITOR, "internal x_max,y_max = %g, %g", x_max, y_max);
325         x_max *= editor->priv->units_per_point;
326         y_max *= editor->priv->units_per_point;
327         gl_debug (DEBUG_EDITOR, "display x_max,y_max = %g, %g", x_max, y_max);
328
329         /* Set widget values */
330         tmp = gtk_spin_button_get_value (GTK_SPIN_BUTTON (editor->priv->shadow_x_spin));
331         gtk_spin_button_set_range (GTK_SPIN_BUTTON (editor->priv->shadow_x_spin),
332                                    -x_max, x_max);
333         gtk_spin_button_set_value (GTK_SPIN_BUTTON (editor->priv->shadow_x_spin), tmp);
334         tmp = gtk_spin_button_get_value (GTK_SPIN_BUTTON (editor->priv->shadow_y_spin));
335         gtk_spin_button_set_range (GTK_SPIN_BUTTON (editor->priv->shadow_y_spin),
336                                    -y_max, y_max);
337         gtk_spin_button_set_value (GTK_SPIN_BUTTON (editor->priv->shadow_y_spin), tmp);
338
339         g_signal_handlers_unblock_by_func (G_OBJECT(editor->priv->shadow_x_spin),
340                                            gl_object_editor_changed_cb,
341                                            editor);
342         g_signal_handlers_unblock_by_func (G_OBJECT(editor->priv->shadow_y_spin),
343                                            gl_object_editor_changed_cb,
344                                            editor);
345
346         gl_debug (DEBUG_EDITOR, "END");
347 }
348
349 /*****************************************************************************/
350 /* Query shadow parameters.                                                  */
351 /*****************************************************************************/
352 gboolean
353 gl_object_editor_get_shadow_state (glObjectEditor      *editor)
354 {
355         gboolean state;
356
357         gl_debug (DEBUG_EDITOR, "START");
358
359         state = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (editor->priv->shadow_enable_check));
360
361         gl_debug (DEBUG_EDITOR, "END");
362
363         return state;
364 }
365
366 void
367 gl_object_editor_get_shadow_offset (glObjectEditor      *editor,
368                                     gdouble             *x,
369                                     gdouble             *y)
370 {
371         gl_debug (DEBUG_EDITOR, "START");
372
373         /* Get values from widgets */
374         *x = gtk_spin_button_get_value (GTK_SPIN_BUTTON (editor->priv->shadow_x_spin));
375         *y = gtk_spin_button_get_value (GTK_SPIN_BUTTON (editor->priv->shadow_y_spin));
376
377         /* convert everything back to our internal units (points) */
378         *x /= editor->priv->units_per_point;
379         *y /= editor->priv->units_per_point;
380
381         /* save a copy in internal units */
382         editor->priv->shadow_x = *x;
383         editor->priv->shadow_y = *y;
384
385         gl_debug (DEBUG_EDITOR, "END");
386 }
387
388 glColorNode*
389 gl_object_editor_get_shadow_color (glObjectEditor      *editor)
390 {
391         GdkColor    *gdk_color;
392         gboolean     is_default;
393         glColorNode *color_node;
394  
395         gl_debug (DEBUG_EDITOR, "START");
396
397         color_node = gl_color_node_new_default ();
398         
399         if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (editor->priv->shadow_key_radio))) {
400                 color_node->field_flag = TRUE;
401                 color_node->key = 
402                         gtk_combo_box_get_active_text (GTK_COMBO_BOX (editor->priv->shadow_key_combo));
403     } else {
404                 color_node->field_flag = FALSE;
405                 color_node->key = NULL;
406                 gdk_color = color_combo_get_color (COLOR_COMBO(editor->priv->shadow_color_combo),
407                                            &is_default);
408
409                 if (!is_default) {
410                 color_node->color = gl_color_from_gdk_color (gdk_color);
411         }
412         }
413
414         gl_debug (DEBUG_EDITOR, "END");
415
416         return color_node;
417 }
418
419 gdouble
420 gl_object_editor_get_shadow_opacity (glObjectEditor      *editor)
421 {
422         gdouble alpha;
423
424         gl_debug (DEBUG_EDITOR, "START");
425
426         alpha = gtk_spin_button_get_value (GTK_SPIN_BUTTON (editor->priv->shadow_opacity_spin));
427
428         gl_debug (DEBUG_EDITOR, "END");
429
430         return alpha / 100.0;
431 }
432
433
434 /*****************************************************************************/
435 /* PRIVATE. Prefs changed callback.  Update units related items.            */
436 /*****************************************************************************/
437 void
438 shadow_prefs_changed_cb (glObjectEditor *editor)
439 {
440         const gchar  *units_string;
441         gdouble       climb_rate;
442         gint          digits;
443
444         gl_debug (DEBUG_EDITOR, "START");
445
446         /* Get new configuration information */
447         units_string = gl_prefs_get_units_string ();
448         editor->priv->units_per_point = gl_prefs_get_units_per_point ();
449         climb_rate = gl_prefs_get_units_step_size ();
450         digits = gl_prefs_get_units_precision ();
451
452         /* Update characteristics of x_spin/y_spin */
453         g_signal_handlers_block_by_func (G_OBJECT(editor->priv->shadow_x_spin),
454                                          gl_object_editor_changed_cb,
455                                          editor);
456         g_signal_handlers_block_by_func (G_OBJECT(editor->priv->shadow_y_spin),
457                                          gl_object_editor_changed_cb,
458                                          editor);
459         gtk_spin_button_set_digits (GTK_SPIN_BUTTON(editor->priv->shadow_x_spin),
460                                     digits);
461         gtk_spin_button_set_digits (GTK_SPIN_BUTTON(editor->priv->shadow_y_spin),
462                                     digits);
463         gtk_spin_button_set_increments (GTK_SPIN_BUTTON(editor->priv->shadow_x_spin),
464                                         climb_rate, 10.0*climb_rate);
465         gtk_spin_button_set_increments (GTK_SPIN_BUTTON(editor->priv->shadow_y_spin),
466                                         climb_rate, 10.0*climb_rate);
467         g_signal_handlers_unblock_by_func (G_OBJECT(editor->priv->shadow_x_spin),
468                                            gl_object_editor_changed_cb,
469                                            editor);
470         g_signal_handlers_unblock_by_func (G_OBJECT(editor->priv->shadow_y_spin),
471                                            gl_object_editor_changed_cb,
472                                            editor);
473
474         /* Update units_labels */
475         gtk_label_set_text (GTK_LABEL(editor->priv->shadow_x_units_label),
476                             units_string);
477         gtk_label_set_text (GTK_LABEL(editor->priv->shadow_y_units_label),
478                             units_string);
479
480         /* Update values of x_spin/y_spin */
481         gl_object_editor_set_shadow_offset (editor,
482                                             editor->priv->shadow_x,
483                                             editor->priv->shadow_y);
484         gl_object_editor_set_max_shadow_offset (editor,
485                                                 editor->priv->shadow_x_max,
486                                                 editor->priv->shadow_y_max);
487
488         gl_debug (DEBUG_EDITOR, "END");
489 }
490
491 /*--------------------------------------------------------------------------*/
492 /* PRIVATE.  shadow enable check callback.                                  */
493 /*--------------------------------------------------------------------------*/
494 static void
495 shadow_enable_check_toggled_cb (glObjectEditor *editor)
496 {
497         gboolean state;
498
499         gl_debug (DEBUG_EDITOR, "START");
500
501         state = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (editor->priv->shadow_enable_check));
502
503         gtk_widget_set_sensitive (editor->priv->shadow_controls_table, state);
504
505         /* Emit our "changed" signal */
506         g_signal_emit (G_OBJECT (editor), gl_object_editor_signals[CHANGED], 0);
507
508         gl_debug (DEBUG_EDITOR, "END");
509 }
510
511
512 /*--------------------------------------------------------------------------*/
513 /* PRIVATE.  shadow color radio callback.                                   */
514 /*--------------------------------------------------------------------------*/
515 static void
516 shadow_color_radio_toggled_cb (glObjectEditor *editor)
517 {
518     gl_debug (DEBUG_EDITOR, "START");
519         
520         if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (editor->priv->shadow_color_radio))) {
521                 gtk_widget_set_sensitive (editor->priv->shadow_color_combo, TRUE);
522                 gtk_widget_set_sensitive (editor->priv->shadow_key_combo, FALSE);
523     } else {
524                 gtk_widget_set_sensitive (editor->priv->shadow_color_combo, FALSE);
525                 gtk_widget_set_sensitive (editor->priv->shadow_key_combo, TRUE);
526                 
527         }
528  
529         /* Emit our "changed" signal */
530         g_signal_emit (G_OBJECT (editor), gl_object_editor_signals[CHANGED], 0);
531  
532         gl_debug (DEBUG_EDITOR, "END");
533 }