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