1/* GTK - The GIMP Toolkit 2 * Copyright (C) 1997 David Mosberger 3 * 2004 Roger Leigh 4 * 5 * This library is free software; you can redistribute it and/or 6 * modify it under the terms of the GNU Lesser General Public 7 * License as published by the Free Software Foundation; either 8 * version 2 of the License, or (at your option) any later version. 9 * 10 * This library is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 * Lesser General Public License for more details. 14 * 15 * You should have received a copy of the GNU Lesser General Public 16 * License along with this library; if not, write to the 17 * Free Software Foundation, Inc., 59 Temple Place - Suite 330, 18 * Boston, MA 02111-1307, USA. 19 */ 20 21/* 22 * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS 23 * file for a list of people on the GTK+ Team. See the ChangeLog 24 * files for a list of changes. These files are distributed with 25 * GTK+ at ftp://ftp.gtk.org/pub/gtk/. 26 */ 27 28/* 29 * Incorporated into Gutenprint by Roger Leigh in 2004. Subsequent 30 * changes are by the Gutenprint team. 31 */ 32 33#include <config.h> 34#include <string.h> 35#include <stdlib.h> 36#include <stdio.h> 37 38#include <gtk/gtkdialog.h> 39#include <gtk/gtkdrawingarea.h> 40#include <gtk/gtkentry.h> 41#include <gtk/gtkhbox.h> 42#include <gtk/gtkimage.h> 43#include <gtk/gtklabel.h> 44#include <gtk/gtkmain.h> 45#include <gtk/gtkradiobutton.h> 46#include <gtk/gtkstock.h> 47#include <gtk/gtktable.h> 48#include <gtk/gtkvbox.h> 49#include <gtk/gtkwindow.h> 50 51#include <gutenprint/gutenprint-intl-internal.h> 52 53#include <gutenprintui2/curve.h> 54#include <gutenprintui2/gammacurve.h> 55 56static GtkVBoxClass *parent_class = NULL; 57 58 59/* forward declarations: */ 60static void stpui_gamma_curve_class_init (StpuiGammaCurveClass *class); 61static void stpui_gamma_curve_init (StpuiGammaCurve *curve); 62static void stpui_gamma_curve_destroy (GtkObject *object); 63 64static void curve_type_changed_callback (GtkWidget *w, gpointer data); 65static void button_realize_callback (GtkWidget *w); 66static void button_toggled_callback (GtkWidget *w, gpointer data); 67static void button_clicked_callback (GtkWidget *w, gpointer data); 68 69enum 70 { 71 LINEAR = 0, 72 SPLINE, 73 FREE, 74 GAMMA, 75 RESET, 76 NUM_XPMS 77 }; 78 79static const char *xpm[][27] = 80 { 81 /* spline: */ 82 { 83 /* width height ncolors chars_per_pixel */ 84 "16 16 4 1", 85 /* colors */ 86 ". c None", 87 "B c #000000", 88 "+ c #BC2D2D", 89 "r c #FF0000", 90 /* pixels */ 91 "..............BB", 92 ".........rrrrrrB", 93 ".......rr.......", 94 ".....B+.........", 95 "....BBB.........", 96 "....+B..........", 97 "....r...........", 98 "...r............", 99 "...r............", 100 "..r.............", 101 "..r.............", 102 ".r..............", 103 ".r..............", 104 ".r..............", 105 "B+..............", 106 "BB.............." 107 }, 108 /* linear: */ 109 { 110 /* width height ncolors chars_per_pixel */ 111 "16 16 5 1", 112 /* colors */ 113 ". c None", /* transparent */ 114 "B c #000000", 115 "' c #7F7F7F", 116 "+ c #824141", 117 "r c #FF0000", 118 /* pixels */ 119 "..............BB", 120 "..............+B", 121 "..............r.", 122 ".............r..", 123 ".............r..", 124 "....'B'.....r...", 125 "....BBB.....r...", 126 "....+B+....r....", 127 "....r.r....r....", 128 "...r...r..r.....", 129 "...r...r..r.....", 130 "..r.....rB+.....", 131 "..r.....BBB.....", 132 ".r......'B'.....", 133 "B+..............", 134 "BB.............." 135 }, 136 /* free: */ 137 { 138 /* width height ncolors chars_per_pixel */ 139 "16 16 2 1", 140 /* colors */ 141 ". c None", 142 "r c #FF0000", 143 /* pixels */ 144 "................", 145 "................", 146 "......r.........", 147 "......r.........", 148 ".......r........", 149 ".......r........", 150 ".......r........", 151 "........r.......", 152 "........r.......", 153 "........r.......", 154 ".....r...r.rrrrr", 155 "....r....r......", 156 "...r.....r......", 157 "..r.......r.....", 158 ".r........r.....", 159 "r..............." 160 }, 161 /* gamma: */ 162 { 163 /* width height ncolors chars_per_pixel */ 164 "16 16 10 1", 165 /* colors */ 166 ". c None", 167 "B c #000000", 168 "& c #171717", 169 "# c #2F2F2F", 170 "X c #464646", 171 "= c #5E5E5E", 172 "/ c #757575", 173 "+ c #8C8C8C", 174 "- c #A4A4A4", 175 "` c #BBBBBB", 176 /* pixels */ 177 "................", 178 "................", 179 "................", 180 "....B=..+B+.....", 181 "....X&`./&-.....", 182 "...../+.XX......", 183 "......B.B+......", 184 "......X.X.......", 185 "......X&+.......", 186 "......-B........", 187 "....../=........", 188 "......#B........", 189 "......BB........", 190 "......B#........", 191 "................", 192 "................" 193 }, 194 /* reset: */ 195 { 196 /* width height ncolors chars_per_pixel */ 197 "16 16 4 1", 198 /* colors */ 199 ". c None", 200 "B c #000000", 201 "+ c #824141", 202 "r c #FF0000", 203 /* pixels */ 204 "..............BB", 205 "..............+B", 206 ".............r..", 207 "............r...", 208 "...........r....", 209 "..........r.....", 210 ".........r......", 211 "........r.......", 212 ".......r........", 213 "......r.........", 214 ".....r..........", 215 "....r...........", 216 "...r............", 217 "..r.............", 218 "B+..............", 219 "BB.............." 220 } 221 }; 222 223GType 224stpui_gamma_curve_get_type (void) 225{ 226 static GType gamma_curve_type = 0; 227 228 if (!gamma_curve_type) 229 { 230 static const GTypeInfo gamma_curve_info = 231 { 232 sizeof (StpuiGammaCurveClass), 233 NULL, /* base_init */ 234 NULL, /* base_finalize */ 235 (GClassInitFunc) stpui_gamma_curve_class_init, 236 NULL, /* class_finalize */ 237 NULL, /* class_data */ 238 sizeof (StpuiGammaCurve), 239 0, /* n_preallocs */ 240 (GInstanceInitFunc) stpui_gamma_curve_init, 241 }; 242 243 gamma_curve_type = g_type_register_static (GTK_TYPE_VBOX, "StpuiGammaCurve", 244 &gamma_curve_info, 0); 245 } 246 return gamma_curve_type; 247} 248 249static void 250stpui_gamma_curve_class_init (StpuiGammaCurveClass *class) 251{ 252 GtkObjectClass *object_class; 253 254 parent_class = g_type_class_peek_parent (class); 255 256 object_class = (GtkObjectClass *) class; 257 object_class->destroy = stpui_gamma_curve_destroy; 258} 259 260static void 261stpui_gamma_curve_init (StpuiGammaCurve *curve) 262{ 263 GtkWidget *vbox; 264 int i; 265 266 curve->gamma = 1.0; 267 268 curve->table = gtk_table_new (1, 2, FALSE); 269 gtk_table_set_col_spacings (GTK_TABLE (curve->table), 3); 270 gtk_container_add (GTK_CONTAINER (curve), curve->table); 271 272 curve->curve = stpui_curve_new (); 273 g_signal_connect (curve->curve, "curve_type_changed", 274 G_CALLBACK (curve_type_changed_callback), curve); 275 gtk_table_attach_defaults (GTK_TABLE (curve->table), curve->curve, 0, 1, 0, 1); 276 277 vbox = gtk_vbox_new (/* homogeneous */ FALSE, /* spacing */ 3); 278 gtk_table_attach (GTK_TABLE (curve->table), vbox, 1, 2, 0, 1, 0, 0, 0, 0); 279 280 /* toggle buttons: */ 281 for (i = 0; i < 3; ++i) 282 { 283 curve->button[i] = gtk_toggle_button_new (); 284 g_object_set_data (G_OBJECT (curve->button[i]), "_StpuiGammaCurveIndex", 285 GINT_TO_POINTER (i)); 286 gtk_container_add (GTK_CONTAINER (vbox), curve->button[i]); 287 g_signal_connect (curve->button[i], "realize", 288 G_CALLBACK (button_realize_callback), NULL); 289 g_signal_connect (curve->button[i], "toggled", 290 G_CALLBACK (button_toggled_callback), curve); 291 gtk_widget_show (curve->button[i]); 292 } 293 294 /* push buttons: */ 295 for (i = 3; i < 5; ++i) 296 { 297 curve->button[i] = gtk_button_new (); 298 g_object_set_data (G_OBJECT (curve->button[i]), "_StpuiGammaCurveIndex", 299 GINT_TO_POINTER (i)); 300 gtk_container_add (GTK_CONTAINER (vbox), curve->button[i]); 301 g_signal_connect (curve->button[i], "realize", 302 G_CALLBACK (button_realize_callback), NULL); 303 g_signal_connect (curve->button[i], "clicked", 304 G_CALLBACK (button_clicked_callback), curve); 305 gtk_widget_show (curve->button[i]); 306 } 307 308 gtk_widget_show (vbox); 309 gtk_widget_show (curve->table); 310 gtk_widget_show (curve->curve); 311} 312 313static void 314button_realize_callback (GtkWidget *w) 315{ 316 GtkWidget *pixmap; 317 GdkBitmap *mask; 318 GdkPixmap *pm; 319 int i; 320 321 i = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (w), "_StpuiGammaCurveIndex")); 322 pm = gdk_pixmap_create_from_xpm_d (w->window, &mask, 323 &w->style->bg[GTK_STATE_NORMAL], (gchar **)xpm[i]); 324 325 pixmap = gtk_image_new_from_pixmap (pm, mask); 326 gtk_container_add (GTK_CONTAINER (w), pixmap); 327 gtk_widget_show (pixmap); 328 329 g_object_unref (pm); 330 g_object_unref (mask); 331} 332 333static void 334button_toggled_callback (GtkWidget *w, gpointer data) 335{ 336 StpuiGammaCurve *c = data; 337 StpuiCurveType 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), "_StpuiGammaCurveIndex")); 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 = STPUI_CURVE_TYPE_SPLINE; break; 355 case 1: type = STPUI_CURVE_TYPE_LINEAR; break; 356 default: type = STPUI_CURVE_TYPE_FREE; break; 357 } 358 stpui_curve_set_curve_type (STPUI_CURVE (c->curve), type); 359} 360 361static void 362gamma_cancel_callback (GtkWidget *w, gpointer data) 363{ 364 StpuiGammaCurve *c = data; 365 366 gtk_widget_destroy (c->gamma_dialog); 367} 368 369static void 370gamma_ok_callback (GtkWidget *w, gpointer data) 371{ 372 StpuiGammaCurve *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 stpui_curve_set_gamma (STPUI_CURVE (c->curve), c->gamma); 385 gamma_cancel_callback (w, data); 386} 387 388static void 389button_clicked_callback (GtkWidget *w, gpointer data) 390{ 391 StpuiGammaCurve *c = data; 392 int active; 393 394 active = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (w), "_StpuiGammaCurveIndex")); 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 stpui_curve_reset (STPUI_CURVE (c->curve)); 453 } 454} 455 456static void 457curve_type_changed_callback (GtkWidget *w, gpointer data) 458{ 459 StpuiGammaCurve *c = data; 460 StpuiCurveType new_type; 461 int active; 462 463 new_type = STPUI_CURVE (w)->curve_type; 464 switch (new_type) 465 { 466 case STPUI_CURVE_TYPE_SPLINE: active = 0; break; 467 case STPUI_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 474GtkWidget* 475stpui_gamma_curve_new (void) 476{ 477 return g_object_new (STPUI_TYPE_GAMMA_CURVE, NULL); 478} 479 480static void 481stpui_gamma_curve_destroy (GtkObject *object) 482{ 483 StpuiGammaCurve *c; 484 485 g_return_if_fail (STPUI_IS_GAMMA_CURVE (object)); 486 487 c = STPUI_GAMMA_CURVE (object); 488 489 if (c->gamma_dialog) 490 gtk_widget_destroy (c->gamma_dialog); 491 492 if (GTK_OBJECT_CLASS (parent_class)->destroy) 493 (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); 494} 495 496