]> Pileus Git - ~andy/gtk/blob - gtk/gtkgamma.c
Removed some GTK_WIDGET_DRAWABLE() tests - we need to update the value
[~andy/gtk] / gtk / gtkgamma.c
1 /* GTK - The GIMP Toolkit
2  * Copyright (C) 1997 David Mosberger
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17  * Boston, MA 02111-1307, USA.
18  */
19 #include <string.h>
20 #include <stdlib.h>
21 #include <stdio.h>
22
23 #include "gtkgamma.h"
24 #include "gtkcurve.h"
25 #include "gtkdialog.h"
26 #include "gtkdrawingarea.h"
27 #include "gtkentry.h"
28 #include "gtkhbox.h"
29 #include "gtklabel.h"
30 #include "gtkmain.h"
31 #include "gtkpixmap.h"
32 #include "gtkradiobutton.h"
33 #include "gtksignal.h"
34 #include "gtktable.h"
35 #include "gtkvbox.h"
36 #include "gtkwindow.h"
37 #include "gtkintl.h"
38
39 static GtkVBoxClass *parent_class = NULL;
40
41
42 /* forward declarations: */
43 static void gtk_gamma_curve_class_init (GtkGammaCurveClass *class);
44 static void gtk_gamma_curve_init (GtkGammaCurve *curve);
45 static void gtk_gamma_curve_destroy (GtkObject *object);
46
47 static void curve_type_changed_callback (GtkWidget *w, gpointer data);
48 static void button_realize_callback     (GtkWidget *w);
49 static void button_toggled_callback     (GtkWidget *w, gpointer data);
50 static void button_clicked_callback     (GtkWidget *w, gpointer data);
51
52 enum
53   {
54     LINEAR = 0,
55     SPLINE,
56     FREE,
57     GAMMA,
58     RESET,
59     NUM_XPMS
60   };
61
62 static const char *xpm[][27] =
63   {
64     /* spline: */
65     {
66       /* width height ncolors chars_per_pixel */
67       "16 16 4 1",
68       /* colors */
69       ". c None",
70       "B c #000000",
71       "+ c #BC2D2D",
72       "r c #FF0000",
73       /* pixels */
74       "..............BB",
75       ".........rrrrrrB",
76       ".......rr.......",
77       ".....B+.........",
78       "....BBB.........",
79       "....+B..........",
80       "....r...........",
81       "...r............",
82       "...r............",
83       "..r.............",
84       "..r.............",
85       ".r..............",
86       ".r..............",
87       ".r..............",
88       "B+..............",
89       "BB.............."
90     },
91     /* linear: */
92     {
93       /* width height ncolors chars_per_pixel */
94       "16 16 5 1",
95       /* colors */
96       ". c None", /* transparent */
97       "B c #000000",
98       "' c #7F7F7F",
99       "+ c #824141",
100       "r c #FF0000",
101       /* pixels */
102       "..............BB",
103       "..............+B",
104       "..............r.",
105       ".............r..",
106       ".............r..",
107       "....'B'.....r...",
108       "....BBB.....r...",
109       "....+B+....r....",
110       "....r.r....r....",
111       "...r...r..r.....",
112       "...r...r..r.....",
113       "..r.....rB+.....",
114       "..r.....BBB.....",
115       ".r......'B'.....",
116       "B+..............",
117       "BB.............."
118     },
119     /* free: */
120     {
121       /* width height ncolors chars_per_pixel */
122       "16 16 2 1",
123       /* colors */
124       ". c None",
125       "r c #FF0000",
126       /* pixels */
127       "................",
128       "................",
129       "......r.........",
130       "......r.........",
131       ".......r........",
132       ".......r........",
133       ".......r........",
134       "........r.......",
135       "........r.......",
136       "........r.......",
137       ".....r...r.rrrrr",
138       "....r....r......",
139       "...r.....r......",
140       "..r.......r.....",
141       ".r........r.....",
142       "r..............."
143     },
144     /* gamma: */
145     {
146       /* width height ncolors chars_per_pixel */
147       "16 16 10 1",
148       /* colors */
149       ". c None",
150       "B c #000000",
151       "& c #171717",
152       "# c #2F2F2F",
153       "X c #464646",
154       "= c #5E5E5E",
155       "/ c #757575",
156       "+ c #8C8C8C",
157       "- c #A4A4A4",
158       "` c #BBBBBB",
159       /* pixels */
160       "................",
161       "................",
162       "................",
163       "....B=..+B+.....",
164       "....X&`./&-.....",
165       "...../+.XX......",
166       "......B.B+......",
167       "......X.X.......",
168       "......X&+.......",
169       "......-B........",
170       "....../=........",
171       "......#B........",
172       "......BB........",
173       "......B#........",
174       "................",
175       "................"
176     },
177     /* reset: */
178     {
179       /* width height ncolors chars_per_pixel */
180       "16 16 4 1",
181       /* colors */
182       ". c None",
183       "B c #000000",
184       "+ c #824141",
185       "r c #FF0000",
186       /* pixels */
187       "..............BB",
188       "..............+B",
189       ".............r..",
190       "............r...",
191       "...........r....",
192       "..........r.....",
193       ".........r......",
194       "........r.......",
195       ".......r........",
196       "......r.........",
197       ".....r..........",
198       "....r...........",
199       "...r............",
200       "..r.............",
201       "B+..............",
202       "BB.............."
203     }
204   };
205
206 guint
207 gtk_gamma_curve_get_type (void)
208 {
209   static guint gamma_curve_type = 0;
210
211   if (!gamma_curve_type)
212     {
213       static const GtkTypeInfo gamma_curve_info =
214       {
215         "GtkGammaCurve",
216         sizeof (GtkGammaCurve),
217         sizeof (GtkGammaCurveClass),
218         (GtkClassInitFunc) gtk_gamma_curve_class_init,
219         (GtkObjectInitFunc) gtk_gamma_curve_init,
220         /* reserved_1 */ NULL,
221         /* reserved_2 */ NULL,
222         (GtkClassInitFunc) NULL,
223       };
224
225       gamma_curve_type =
226         gtk_type_unique (gtk_vbox_get_type (), &gamma_curve_info);
227     }
228   return gamma_curve_type;
229 }
230
231 static void
232 gtk_gamma_curve_class_init (GtkGammaCurveClass *class)
233 {
234   GtkObjectClass *object_class;
235
236   parent_class = gtk_type_class (gtk_vbox_get_type ());
237
238   object_class = (GtkObjectClass *) class;
239   object_class->destroy = gtk_gamma_curve_destroy;
240 }
241
242 static void
243 gtk_gamma_curve_init (GtkGammaCurve *curve)
244 {
245   GtkWidget *vbox;
246   int i;
247
248   curve->gamma = 1.0;
249
250   curve->table = gtk_table_new (1, 2, FALSE);
251   gtk_table_set_col_spacings (GTK_TABLE (curve->table), 3);
252   gtk_container_add (GTK_CONTAINER (curve), curve->table);
253
254   curve->curve = gtk_curve_new ();
255   gtk_signal_connect (GTK_OBJECT (curve->curve), "curve_type_changed",
256                       (GtkSignalFunc) curve_type_changed_callback, curve);
257   gtk_table_attach_defaults (GTK_TABLE (curve->table), curve->curve, 0, 1, 0, 1);
258
259   vbox = gtk_vbox_new (/* homogeneous */ FALSE, /* spacing */ 3);
260   gtk_table_attach (GTK_TABLE (curve->table), vbox, 1, 2, 0, 1, 0, 0, 0, 0);
261
262   /* toggle buttons: */
263   for (i = 0; i < 3; ++i)
264     {
265       curve->button[i] = gtk_toggle_button_new ();
266       gtk_object_set_data (GTK_OBJECT (curve->button[i]), "_GtkGammaCurveIndex",
267                            GINT_TO_POINTER (i));
268       gtk_container_add (GTK_CONTAINER (vbox), curve->button[i]);
269       gtk_signal_connect (GTK_OBJECT (curve->button[i]), "realize",
270                           (GtkSignalFunc) button_realize_callback, 0);
271       gtk_signal_connect (GTK_OBJECT (curve->button[i]), "toggled",
272                           (GtkSignalFunc) button_toggled_callback, curve);
273       gtk_widget_show (curve->button[i]);
274     }
275
276   /* push buttons: */
277   for (i = 3; i < 5; ++i)
278     {
279       curve->button[i] = gtk_button_new ();
280       gtk_object_set_data (GTK_OBJECT (curve->button[i]), "_GtkGammaCurveIndex",
281                            GINT_TO_POINTER (i));
282       gtk_container_add (GTK_CONTAINER (vbox), curve->button[i]);
283       gtk_signal_connect (GTK_OBJECT (curve->button[i]), "realize",
284                           (GtkSignalFunc) button_realize_callback, 0);
285       gtk_signal_connect (GTK_OBJECT (curve->button[i]), "clicked",
286                           (GtkSignalFunc) button_clicked_callback, curve);
287       gtk_widget_show (curve->button[i]);
288     }
289
290   gtk_widget_show (vbox);
291   gtk_widget_show (curve->table);
292   gtk_widget_show (curve->curve);
293 }
294
295 static void
296 button_realize_callback (GtkWidget *w)
297 {
298   GtkWidget *pixmap;
299   GdkBitmap *mask;
300   GdkPixmap *pm;
301   int i;
302
303   i = GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (w), "_GtkGammaCurveIndex"));
304   pm = gdk_pixmap_create_from_xpm_d (w->window, &mask,
305                                      &w->style->bg[GTK_STATE_NORMAL], xpm[i]);
306
307   pixmap = gtk_pixmap_new (pm, mask);
308   gtk_container_add (GTK_CONTAINER (w), pixmap);
309   gtk_widget_show (pixmap);
310
311   gdk_pixmap_unref (pm);
312   gdk_bitmap_unref (mask);   /* a bitmap is really just a special pixmap */
313 }
314
315 static void
316 button_toggled_callback (GtkWidget *w, gpointer data)
317 {
318   GtkGammaCurve *c = data;
319   GtkCurveType type;
320   int active, i;
321
322   if (!GTK_TOGGLE_BUTTON (w)->active)
323     return;
324
325   active = GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (w), "_GtkGammaCurveIndex"));
326
327   for (i = 0; i < 3; ++i)
328     if ((i != active) && GTK_TOGGLE_BUTTON (c->button[i])->active)
329       break;
330
331   if (i < 3)
332     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (c->button[i]), FALSE);
333
334   switch (active)
335     {
336     case 0:  type = GTK_CURVE_TYPE_SPLINE; break;
337     case 1:  type = GTK_CURVE_TYPE_LINEAR; break;
338     default: type = GTK_CURVE_TYPE_FREE; break;
339     }
340   gtk_curve_set_curve_type (GTK_CURVE (c->curve), type);
341 }
342
343 static void
344 gamma_cancel_callback (GtkWidget *w, gpointer data)
345 {
346   GtkGammaCurve *c = data;
347
348   gtk_widget_destroy (c->gamma_dialog);
349   c->gamma_dialog = 0;
350 }
351
352 static void
353 gamma_ok_callback (GtkWidget *w, gpointer data)
354 {
355   GtkGammaCurve *c = data;
356   gchar *start, *end;
357   gfloat v;
358
359   start = gtk_entry_get_text (GTK_ENTRY (c->gamma_text));
360   if (start)
361     {
362       v = strtod (start, &end);
363       if (end > start && v > 0.0)
364         c->gamma = v;
365     }
366   gtk_curve_set_gamma (GTK_CURVE (c->curve), c->gamma);
367   gamma_cancel_callback (w, data);
368 }
369
370 static void
371 button_clicked_callback (GtkWidget *w, gpointer data)
372 {
373   GtkGammaCurve *c = data;
374   int active;
375
376   active = GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (w), "_GtkGammaCurveIndex"));
377   if (active == 3)
378     {
379       /* set gamma */
380       if (c->gamma_dialog)
381         return;
382       else
383         {
384           GtkWidget *vbox, *hbox, *label, *button;
385           gchar buf[64];
386           
387           c->gamma_dialog = gtk_dialog_new ();
388           gtk_window_set_title (GTK_WINDOW (c->gamma_dialog), _("Gamma"));
389           vbox = GTK_DIALOG (c->gamma_dialog)->vbox;
390           
391           hbox = gtk_hbox_new (/* homogeneous */ FALSE, 0);
392           gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 2);
393           gtk_widget_show (hbox);
394           
395           label = gtk_label_new (_("Gamma value"));
396           gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 2);
397           gtk_widget_show (label);
398           
399           sprintf (buf, "%g", c->gamma);
400           c->gamma_text = gtk_entry_new ();
401           gtk_entry_set_text (GTK_ENTRY (c->gamma_text), buf);
402           gtk_box_pack_start (GTK_BOX (hbox), c->gamma_text, TRUE, TRUE, 2);
403           gtk_widget_show (c->gamma_text);
404           
405           /* fill in action area: */
406           hbox = GTK_DIALOG (c->gamma_dialog)->action_area;
407           
408           button = gtk_button_new_with_label (_("OK"));
409           GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
410           gtk_signal_connect (GTK_OBJECT (button), "clicked",
411                               (GtkSignalFunc) gamma_ok_callback, c);
412           gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
413           gtk_widget_grab_default (button);
414           gtk_widget_show (button);
415           
416           button = gtk_button_new_with_label (_("Cancel"));
417           gtk_signal_connect (GTK_OBJECT (button), "clicked",
418                               (GtkSignalFunc) gamma_cancel_callback, c);
419           gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
420           gtk_widget_show (button);
421           
422           gtk_widget_show (c->gamma_dialog);
423         }
424     }
425   else
426     {
427       /* reset */
428       gtk_curve_reset (GTK_CURVE (c->curve));
429     }
430 }
431
432 static void
433 curve_type_changed_callback (GtkWidget *w, gpointer data)
434 {
435   GtkGammaCurve *c = data;
436   GtkCurveType new_type;
437   int active;
438
439   new_type = GTK_CURVE (w)->curve_type;
440   switch (new_type)
441     {
442     case GTK_CURVE_TYPE_SPLINE: active = 0; break;
443     case GTK_CURVE_TYPE_LINEAR: active = 1; break;
444     default:                    active = 2; break;
445     }
446   if (!GTK_TOGGLE_BUTTON (c->button[active])->active)
447     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (c->button[active]), TRUE);
448 }
449
450 GtkWidget*
451 gtk_gamma_curve_new (void)
452 {
453   return gtk_type_new (gtk_gamma_curve_get_type ());
454 }
455
456 static void
457 gtk_gamma_curve_destroy (GtkObject *object)
458 {
459   GtkGammaCurve *c;
460
461   g_return_if_fail (object != NULL);
462   g_return_if_fail (GTK_IS_GAMMA_CURVE (object));
463
464   c = GTK_GAMMA_CURVE (object);
465
466   if (c->gamma_dialog)
467     gtk_widget_destroy (c->gamma_dialog);
468
469   if (GTK_OBJECT_CLASS (parent_class)->destroy)
470     (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
471 }
472