]> Pileus Git - ~andy/gtk/blob - gtk/gtkgamma.c
Go to the GUP proposed ordering of buttons with [OK] in the lower right
[~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   const gchar *start;
364   gchar *end;
365   gfloat v;
366
367   start = gtk_entry_get_text (GTK_ENTRY (c->gamma_text));
368   if (start)
369     {
370       v = strtod (start, &end);
371       if (end > start && v > 0.0)
372         c->gamma = v;
373     }
374   gtk_curve_set_gamma (GTK_CURVE (c->curve), c->gamma);
375   gamma_cancel_callback (w, data);
376 }
377
378 static void
379 button_clicked_callback (GtkWidget *w, gpointer data)
380 {
381   GtkGammaCurve *c = data;
382   int active;
383
384   active = GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (w), "_GtkGammaCurveIndex"));
385   if (active == 3)
386     {
387       /* set gamma */
388       if (c->gamma_dialog)
389         return;
390       else
391         {
392           GtkWidget *vbox, *hbox, *label, *button;
393           gchar buf[64];
394           
395           c->gamma_dialog = gtk_dialog_new ();
396           gtk_window_set_title (GTK_WINDOW (c->gamma_dialog), _("Gamma"));
397           vbox = GTK_DIALOG (c->gamma_dialog)->vbox;
398           
399           hbox = gtk_hbox_new (/* homogeneous */ FALSE, 0);
400           gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 2);
401           gtk_widget_show (hbox);
402           
403           label = gtk_label_new (_("_Gamma value"));
404           gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 2);
405           gtk_widget_show (label);
406           
407           sprintf (buf, "%g", c->gamma);
408           c->gamma_text = gtk_entry_new ();
409           gtk_label_set_mnemonic_widget (GTK_LABEL (label), c->gamma_text);
410           gtk_entry_set_text (GTK_ENTRY (c->gamma_text), buf);
411           gtk_box_pack_start (GTK_BOX (hbox), c->gamma_text, TRUE, TRUE, 2);
412           gtk_widget_show (c->gamma_text);
413           
414           /* fill in action area: */
415           hbox = GTK_DIALOG (c->gamma_dialog)->action_area;
416
417           button = gtk_button_new_with_label (_("Cancel"));
418           gtk_signal_connect (GTK_OBJECT (button), "clicked",
419                               (GtkSignalFunc) gamma_cancel_callback, c);
420           gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
421           gtk_widget_show (button);
422           
423           button = gtk_button_new_with_label (_("OK"));
424           GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
425           gtk_signal_connect (GTK_OBJECT (button), "clicked",
426                               (GtkSignalFunc) gamma_ok_callback, c);
427           gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
428           gtk_widget_grab_default (button);
429           gtk_widget_show (button);
430           
431           gtk_widget_show (c->gamma_dialog);
432         }
433     }
434   else
435     {
436       /* reset */
437       gtk_curve_reset (GTK_CURVE (c->curve));
438     }
439 }
440
441 static void
442 curve_type_changed_callback (GtkWidget *w, gpointer data)
443 {
444   GtkGammaCurve *c = data;
445   GtkCurveType new_type;
446   int active;
447
448   new_type = GTK_CURVE (w)->curve_type;
449   switch (new_type)
450     {
451     case GTK_CURVE_TYPE_SPLINE: active = 0; break;
452     case GTK_CURVE_TYPE_LINEAR: active = 1; break;
453     default:                    active = 2; break;
454     }
455   if (!GTK_TOGGLE_BUTTON (c->button[active])->active)
456     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (c->button[active]), TRUE);
457 }
458
459 GtkWidget*
460 gtk_gamma_curve_new (void)
461 {
462   return gtk_type_new (GTK_TYPE_GAMMA_CURVE);
463 }
464
465 static void
466 gtk_gamma_curve_destroy (GtkObject *object)
467 {
468   GtkGammaCurve *c;
469
470   g_return_if_fail (GTK_IS_GAMMA_CURVE (object));
471
472   c = GTK_GAMMA_CURVE (object);
473
474   if (c->gamma_dialog)
475     gtk_widget_destroy (c->gamma_dialog);
476
477   if (GTK_OBJECT_CLASS (parent_class)->destroy)
478     (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
479 }
480