]> Pileus Git - ~andy/gtk/blob - gtk/gtkgamma.c
Practically everything changed.
[~andy/gtk] / gtk / gtkgamma.c
1 /* GTK - The GTK+ 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 "config.h"
28 #include <string.h>
29 #include <stdlib.h>
30 #include <stdio.h>
31
32 #include <gdk-pixbuf/gdk-pixdata.h>
33
34 #include "gtkgamma.h"
35 #include "gtkcurve.h"
36 #include "gtkdialog.h"
37 #include "gtkdrawingarea.h"
38 #include "gtkentry.h"
39 #include "gtkhbox.h"
40 #include "gtkimage.h"
41 #include "gtklabel.h"
42 #include "gtkmain.h"
43 #include "gtkradiobutton.h"
44 #include "gtkstock.h"
45 #include "gtktable.h"
46 #include "gtkvbox.h"
47 #include "gtkwindow.h"
48 #include "gtkintl.h"
49 #include "gtkalias.h"
50
51 /* forward declarations: */
52 static void gtk_gamma_curve_destroy (GtkObject *object);
53
54 static void curve_type_changed_callback (GtkWidget *w, gpointer data);
55 static void button_realize_callback     (GtkWidget *w);
56 static void button_toggled_callback     (GtkWidget *w, gpointer data);
57 static void button_clicked_callback     (GtkWidget *w, gpointer data);
58
59 enum
60   {
61     LINEAR = 0,
62     SPLINE,
63     FREE,
64     GAMMA,
65     RESET,
66     NUM_XPMS
67   };
68
69 /* GdkPixbuf RGBA C-Source image dump 1-byte-run-length-encoded */
70
71 #ifdef __SUNPRO_C
72 #pragma align 4 (spline_pixdata)
73 #endif
74 #ifdef __GNUC__
75 static const guint8 spline_pixdata[] __attribute__ ((__aligned__ (4))) = 
76 #else
77 static const guint8 spline_pixdata[] = 
78 #endif
79 { ""
80   /* Pixbuf magic (0x47646b50) */
81   "GdkP"
82   /* length: header (24) + pixel_data (182) */
83   "\0\0\0\316"
84   /* pixdata_type (0x2010002) */
85   "\2\1\0\2"
86   /* rowstride (64) */
87   "\0\0\0@"
88   /* width (16) */
89   "\0\0\0\20"
90   /* height (16) */
91   "\0\0\0\20"
92   /* pixel_data: */
93   "\216\0\0\0\0\202\0\0\0\377\211\0\0\0\0\206\377\0\0\377\1\0\0\0\377\207"
94   "\0\0\0\0\202\377\0\0\377\214\0\0\0\0\2\0\0\0\377\274--\377\215\0\0\0"
95   "\0\203\0\0\0\377\215\0\0\0\0\2\274--\377\0\0\0\377\216\0\0\0\0\1\377"
96   "\0\0\377\216\0\0\0\0\1\377\0\0\377\217\0\0\0\0\1\377\0\0\377\216\0\0"
97   "\0\0\1\377\0\0\377\217\0\0\0\0\1\377\0\0\377\216\0\0\0\0\1\377\0\0\377"
98   "\217\0\0\0\0\1\377\0\0\377\217\0\0\0\0\1\377\0\0\377\216\0\0\0\0\2\0"
99   "\0\0\377\274--\377\216\0\0\0\0\202\0\0\0\377\216\0\0\0\0"};
100
101
102 /* GdkPixbuf RGBA C-Source image dump 1-byte-run-length-encoded */
103
104 #ifdef __SUNPRO_C
105 #pragma align 4 (linear_pixdata)
106 #endif
107 #ifdef __GNUC__
108 static const guint8 linear_pixdata[] __attribute__ ((__aligned__ (4))) = 
109 #else
110 static const guint8 linear_pixdata[] = 
111 #endif
112 { ""
113   /* Pixbuf magic (0x47646b50) */
114   "GdkP"
115   /* length: header (24) + pixel_data (323) */
116   "\0\0\1["
117   /* pixdata_type (0x2010002) */
118   "\2\1\0\2"
119   /* rowstride (64) */
120   "\0\0\0@"
121   /* width (16) */
122   "\0\0\0\20"
123   /* height (16) */
124   "\0\0\0\20"
125   /* pixel_data: */
126   "\216\0\0\0\0\202\0\0\0\377\216\0\0\0\0\2\202AA\377\0\0\0\377\216\0\0"
127   "\0\0\1\377\0\0\377\216\0\0\0\0\1\377\0\0\377\217\0\0\0\0\1\377\0\0\377"
128   "\206\0\0\0\0\3\177\177\177\377\0\0\0\377\177\177\177\377\205\0\0\0\0"
129   "\1\377\0\0\377\207\0\0\0\0\203\0\0\0\377\205\0\0\0\0\1\377\0\0\377\207"
130   "\0\0\0\0\3\202AA\377\0\0\0\377\202AA\377\204\0\0\0\0\1\377\0\0\377\210"
131   "\0\0\0\0\3\377\0\0\377\0\0\0\0\377\0\0\377\204\0\0\0\0\1\377\0\0\377"
132   "\207\0\0\0\0\1\377\0\0\377\203\0\0\0\0\1\377\0\0\377\202\0\0\0\0\1\377"
133   "\0\0\377\210\0\0\0\0\1\377\0\0\377\203\0\0\0\0\1\377\0\0\377\202\0\0"
134   "\0\0\1\377\0\0\377\207\0\0\0\0\1\377\0\0\377\205\0\0\0\0\3\377\0\0\377"
135   "\0\0\0\377\202AA\377\207\0\0\0\0\1\377\0\0\377\205\0\0\0\0\203\0\0\0"
136   "\377\206\0\0\0\0\1\377\0\0\377\206\0\0\0\0\3\177\177\177\377\0\0\0\377"
137   "\177\177\177\377\205\0\0\0\0\2\0\0\0\377\202AA\377\216\0\0\0\0\202\0"
138   "\0\0\377\216\0\0\0\0"};
139
140
141 /* GdkPixbuf RGBA C-Source image dump 1-byte-run-length-encoded */
142
143 #ifdef __SUNPRO_C
144 #pragma align 4 (free_pixdata)
145 #endif
146 #ifdef __GNUC__
147 static const guint8 free_pixdata[] __attribute__ ((__aligned__ (4))) = 
148 #else
149 static const guint8 free_pixdata[] = 
150 #endif
151 { ""
152   /* Pixbuf magic (0x47646b50) */
153   "GdkP"
154   /* length: header (24) + pixel_data (204) */
155   "\0\0\0\344"
156   /* pixdata_type (0x2010002) */
157   "\2\1\0\2"
158   /* rowstride (64) */
159   "\0\0\0@"
160   /* width (16) */
161   "\0\0\0\20"
162   /* height (16) */
163   "\0\0\0\20"
164   /* pixel_data: */
165   "\246\0\0\0\0\1\377\0\0\377\217\0\0\0\0\1\377\0\0\377\220\0\0\0\0\1\377"
166   "\0\0\377\217\0\0\0\0\1\377\0\0\377\217\0\0\0\0\1\377\0\0\377\220\0\0"
167   "\0\0\1\377\0\0\377\217\0\0\0\0\1\377\0\0\377\217\0\0\0\0\1\377\0\0\377"
168   "\214\0\0\0\0\1\377\0\0\377\203\0\0\0\0\2\377\0\0\377\0\0\0\0\205\377"
169   "\0\0\377\204\0\0\0\0\1\377\0\0\377\204\0\0\0\0\1\377\0\0\377\211\0\0"
170   "\0\0\1\377\0\0\377\205\0\0\0\0\1\377\0\0\377\210\0\0\0\0\1\377\0\0\377"
171   "\207\0\0\0\0\1\377\0\0\377\206\0\0\0\0\1\377\0\0\377\210\0\0\0\0\1\377"
172   "\0\0\377\205\0\0\0\0\1\377\0\0\377\217\0\0\0\0"};
173
174
175 /* GdkPixbuf RGBA C-Source image dump 1-byte-run-length-encoded */
176
177 #ifdef __SUNPRO_C
178 #pragma align 4 (gamma_pixdata)
179 #endif
180 #ifdef __GNUC__
181 static const guint8 gamma_pixdata[] __attribute__ ((__aligned__ (4))) = 
182 #else
183 static const guint8 gamma_pixdata[] = 
184 #endif
185 { ""
186   /* Pixbuf magic (0x47646b50) */
187   "GdkP"
188   /* length: header (24) + pixel_data (218) */
189   "\0\0\0\362"
190   /* pixdata_type (0x2010002) */
191   "\2\1\0\2"
192   /* rowstride (64) */
193   "\0\0\0@"
194   /* width (16) */
195   "\0\0\0\20"
196   /* height (16) */
197   "\0\0\0\20"
198   /* pixel_data: */
199   "\264\0\0\0\0\2\0\0\0\377^^^\377\202\0\0\0\0\3\214\214\214\377\0\0\0\377"
200   "\214\214\214\377\211\0\0\0\0\7FFF\377\27\27\27\377\273\273\273\377\0"
201   "\0\0\0uuu\377\27\27\27\377\244\244\244\377\212\0\0\0\0\3uuu\377\214\214"
202   "\214\377\0\0\0\0\202FFF\377\214\0\0\0\0\4\0\0\0\377\0\0\0\0\0\0\0\377"
203   "\214\214\214\377\214\0\0\0\0\3FFF\377\0\0\0\0FFF\377\215\0\0\0\0\3FF"
204   "F\377\27\27\27\377\214\214\214\377\215\0\0\0\0\2\244\244\244\377\0\0"
205   "\0\377\216\0\0\0\0\2uuu\377^^^\377\216\0\0\0\0\2///\377\0\0\0\377\216"
206   "\0\0\0\0\202\0\0\0\377\216\0\0\0\0\2\0\0\0\377///\377\250\0\0\0\0"};
207
208
209 /* GdkPixbuf RGBA C-Source image dump 1-byte-run-length-encoded */
210
211 #ifdef __SUNPRO_C
212 #pragma align 4 (reset_pixdata)
213 #endif
214 #ifdef __GNUC__
215 static const guint8 reset_pixdata[] __attribute__ ((__aligned__ (4))) = 
216 #else
217 static const guint8 reset_pixdata[] = 
218 #endif
219 { ""
220   /* Pixbuf magic (0x47646b50) */
221   "GdkP"
222   /* length: header (24) + pixel_data (173) */
223   "\0\0\0\305"
224   /* pixdata_type (0x2010002) */
225   "\2\1\0\2"
226   /* rowstride (64) */
227   "\0\0\0@"
228   /* width (16) */
229   "\0\0\0\20"
230   /* height (16) */
231   "\0\0\0\20"
232   /* pixel_data: */
233   "\216\0\0\0\0\202\0\0\0\377\216\0\0\0\0\2\202AA\377\0\0\0\377\215\0\0"
234   "\0\0\1\377\0\0\377\216\0\0\0\0\1\377\0\0\377\216\0\0\0\0\1\377\0\0\377"
235   "\216\0\0\0\0\1\377\0\0\377\216\0\0\0\0\1\377\0\0\377\216\0\0\0\0\1\377"
236   "\0\0\377\216\0\0\0\0\1\377\0\0\377\216\0\0\0\0\1\377\0\0\377\216\0\0"
237   "\0\0\1\377\0\0\377\216\0\0\0\0\1\377\0\0\377\216\0\0\0\0\1\377\0\0\377"
238   "\216\0\0\0\0\1\377\0\0\377\215\0\0\0\0\2\0\0\0\377\202AA\377\216\0\0"
239   "\0\0\202\0\0\0\377\216\0\0\0\0"};
240
241 G_DEFINE_TYPE (GtkGammaCurve, gtk_gamma_curve, GTK_TYPE_VBOX)
242
243 static void
244 gtk_gamma_curve_class_init (GtkGammaCurveClass *class)
245 {
246   GtkObjectClass *object_class;
247
248   object_class = (GtkObjectClass *) class;
249   object_class->destroy = gtk_gamma_curve_destroy;
250 }
251
252 static void
253 gtk_gamma_curve_init (GtkGammaCurve *curve)
254 {
255   GtkWidget *vbox;
256   int i;
257
258   curve->gamma = 1.0;
259
260   curve->table = gtk_table_new (1, 2, FALSE);
261   gtk_table_set_col_spacings (GTK_TABLE (curve->table), 3);
262   gtk_container_add (GTK_CONTAINER (curve), curve->table);
263
264   curve->curve = gtk_curve_new ();
265   g_signal_connect (curve->curve, "curve_type_changed",
266                     G_CALLBACK (curve_type_changed_callback), curve);
267   gtk_table_attach_defaults (GTK_TABLE (curve->table), curve->curve, 0, 1, 0, 1);
268
269   vbox = gtk_vbox_new (/* homogeneous */ FALSE, /* spacing */ 3);
270   gtk_table_attach (GTK_TABLE (curve->table), vbox, 1, 2, 0, 1, 0, 0, 0, 0);
271
272   /* toggle buttons: */
273   for (i = 0; i < 3; ++i)
274     {
275       curve->button[i] = gtk_toggle_button_new ();
276       g_object_set_data (G_OBJECT (curve->button[i]), I_("_GtkGammaCurveIndex"),
277                          GINT_TO_POINTER (i));
278       gtk_container_add (GTK_CONTAINER (vbox), curve->button[i]);
279       g_signal_connect (curve->button[i], "realize",
280                         G_CALLBACK (button_realize_callback), NULL);
281       g_signal_connect (curve->button[i], "toggled",
282                         G_CALLBACK (button_toggled_callback), curve);
283       gtk_widget_show (curve->button[i]);
284     }
285
286   /* push buttons: */
287   for (i = 3; i < 5; ++i)
288     {
289       curve->button[i] = gtk_button_new ();
290       g_object_set_data (G_OBJECT (curve->button[i]), I_("_GtkGammaCurveIndex"),
291                          GINT_TO_POINTER (i));
292       gtk_container_add (GTK_CONTAINER (vbox), curve->button[i]);
293       g_signal_connect (curve->button[i], "realize",
294                         G_CALLBACK (button_realize_callback), NULL);
295       g_signal_connect (curve->button[i], "clicked",
296                         G_CALLBACK (button_clicked_callback), curve);
297       gtk_widget_show (curve->button[i]);
298     }
299
300   gtk_widget_show (vbox);
301   gtk_widget_show (curve->table);
302   gtk_widget_show (curve->curve);
303 }
304
305 static void
306 button_realize_callback (GtkWidget *w)
307 {
308   GtkWidget *image;
309   struct {
310     const guint8 *stream;
311     gint length;
312   } streams[5] = {
313     { linear_pixdata, sizeof (linear_pixdata) },
314     { spline_pixdata, sizeof (spline_pixdata) },
315     { free_pixdata, sizeof (free_pixdata) },
316     { gamma_pixdata, sizeof (gamma_pixdata) },
317     { reset_pixdata, sizeof (reset_pixdata) }
318   };
319   GdkPixdata pixdata;
320   GdkPixbuf *pixbuf;
321   int i;
322
323   i = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (w), "_GtkGammaCurveIndex"));
324   gdk_pixdata_deserialize (&pixdata, streams[i].length, streams[i].stream, NULL);
325   pixbuf = gdk_pixbuf_from_pixdata (&pixdata, TRUE, NULL);
326   image = gtk_image_new_from_pixbuf (pixbuf);
327   gtk_container_add (GTK_CONTAINER (w), image);
328   gtk_widget_show (image);
329
330   g_object_unref (pixbuf);
331 }
332
333 static void
334 button_toggled_callback (GtkWidget *w, gpointer data)
335 {
336   GtkGammaCurve *c = data;
337   GtkCurveType type;
338   int active, i;
339
340   if (!GTK_TOGGLE_BUTTON (w)->active)
341     return;
342
343   active = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (w), "_GtkGammaCurveIndex"));
344
345   for (i = 0; i < 3; ++i)
346     if ((i != active) && GTK_TOGGLE_BUTTON (c->button[i])->active)
347       break;
348
349   if (i < 3)
350     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (c->button[i]), FALSE);
351
352   switch (active)
353     {
354     case 0:  type = GTK_CURVE_TYPE_SPLINE; break;
355     case 1:  type = GTK_CURVE_TYPE_LINEAR; break;
356     default: type = GTK_CURVE_TYPE_FREE; break;
357     }
358   gtk_curve_set_curve_type (GTK_CURVE (c->curve), type);
359 }
360
361 static void
362 gamma_cancel_callback (GtkWidget *w, gpointer data)
363 {
364   GtkGammaCurve *c = data;
365
366   gtk_widget_destroy (c->gamma_dialog);
367 }
368
369 static void
370 gamma_ok_callback (GtkWidget *w, gpointer data)
371 {
372   GtkGammaCurve *c = data;
373   const gchar *start;
374   gchar *end;
375   gfloat v;
376
377   start = gtk_entry_get_text (GTK_ENTRY (c->gamma_text));
378   if (start)
379     {
380       v = g_strtod (start, &end);
381       if (end > start && v > 0.0)
382         c->gamma = v;
383     }
384   gtk_curve_set_gamma (GTK_CURVE (c->curve), c->gamma);
385   gamma_cancel_callback (w, data);
386 }
387
388 static void
389 button_clicked_callback (GtkWidget *w, gpointer data)
390 {
391   GtkGammaCurve *c = data;
392   int active;
393
394   active = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (w), "_GtkGammaCurveIndex"));
395   if (active == 3)
396     {
397       /* set gamma */
398       if (c->gamma_dialog)
399         return;
400       else
401         {
402           GtkWidget *vbox, *hbox, *label, *button;
403           gchar buf[64];
404           
405           c->gamma_dialog = gtk_dialog_new ();
406           gtk_window_set_screen (GTK_WINDOW (c->gamma_dialog),
407                                  gtk_widget_get_screen (w));
408           gtk_window_set_title (GTK_WINDOW (c->gamma_dialog), _("Gamma"));
409           g_object_add_weak_pointer (G_OBJECT (c->gamma_dialog),
410                                      (gpointer *)&c->gamma_dialog);
411           
412           vbox = GTK_DIALOG (c->gamma_dialog)->vbox;
413           
414           hbox = gtk_hbox_new (/* homogeneous */ FALSE, 0);
415           gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 2);
416           gtk_widget_show (hbox);
417           
418           label = gtk_label_new_with_mnemonic (_("_Gamma value"));
419           gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 2);
420           gtk_widget_show (label);
421           
422           sprintf (buf, "%g", c->gamma);
423           c->gamma_text = gtk_entry_new ();
424           gtk_label_set_mnemonic_widget (GTK_LABEL (label), c->gamma_text);
425           gtk_entry_set_text (GTK_ENTRY (c->gamma_text), buf);
426           gtk_box_pack_start (GTK_BOX (hbox), c->gamma_text, TRUE, TRUE, 2);
427           gtk_widget_show (c->gamma_text);
428           
429           /* fill in action area: */
430           hbox = GTK_DIALOG (c->gamma_dialog)->action_area;
431
432           button = gtk_button_new_from_stock (GTK_STOCK_CANCEL);
433           g_signal_connect (button, "clicked",
434                             G_CALLBACK (gamma_cancel_callback), c);
435           gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
436           gtk_widget_show (button);
437           
438           button = gtk_button_new_from_stock (GTK_STOCK_OK);
439           GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
440           g_signal_connect (button, "clicked",
441                             G_CALLBACK (gamma_ok_callback), c);
442           gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
443           gtk_widget_grab_default (button);
444           gtk_widget_show (button);
445           
446           gtk_widget_show (c->gamma_dialog);
447         }
448     }
449   else
450     {
451       /* reset */
452       gtk_curve_reset (GTK_CURVE (c->curve));
453     }
454 }
455
456 static void
457 curve_type_changed_callback (GtkWidget *w, gpointer data)
458 {
459   GtkGammaCurve *c = data;
460   GtkCurveType new_type;
461   int active;
462
463   new_type = GTK_CURVE (w)->curve_type;
464   switch (new_type)
465     {
466     case GTK_CURVE_TYPE_SPLINE: active = 0; break;
467     case GTK_CURVE_TYPE_LINEAR: active = 1; break;
468     default:                    active = 2; break;
469     }
470   if (!GTK_TOGGLE_BUTTON (c->button[active])->active)
471     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (c->button[active]), TRUE);
472 }
473
474 GtkWidget*
475 gtk_gamma_curve_new (void)
476 {
477   return g_object_new (GTK_TYPE_GAMMA_CURVE, NULL);
478 }
479
480 static void
481 gtk_gamma_curve_destroy (GtkObject *object)
482 {
483   GtkGammaCurve *c = GTK_GAMMA_CURVE (object);
484
485   if (c->gamma_dialog)
486     gtk_widget_destroy (c->gamma_dialog);
487
488   if (GTK_OBJECT_CLASS (gtk_gamma_curve_parent_class)->destroy)
489     (* GTK_OBJECT_CLASS (gtk_gamma_curve_parent_class)->destroy) (object);
490 }
491
492 #define __GTK_GAMMA_CURVE_C__
493 #include "gtkaliasdef.c"