gimpcolordialog.c 13.8 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
/* The GIMP -- an image manipulation program
 * Copyright (C) 1995 Spencer Kimball and Peter Mattis
 *
 * color_notebook module (C) 1998 Austin Donnelly <austin@greenend.org.uk>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 */
20

Tomas Ogren's avatar
Tomas Ogren committed
21
#include "config.h"
22

23 24
#include <gtk/gtk.h>

25
#include "libgimpcolor/gimpcolor.h"
26
#include "libgimpwidgets/gimpwidgets.h"
27

28
#include "gui-types.h"
29

30 31
#include "core/gimpviewable.h"

32
#include "widgets/gimpdialogfactory.h"
33 34
#include "widgets/gimpviewabledialog.h"

35
#include "color-history.h"
36
#include "color-notebook.h"
37

38
#include "gimp-intl.h"
39

40

41 42
#define RESPONSE_RESET   1
#define COLOR_AREA_SIZE 20
43 44


45 46
struct _ColorNotebook
{
47 48
  GtkWidget             *shell;
  GtkWidget             *selection;
49

50
  GtkWidget             *history[COLOR_HISTORY_SIZE];
51

52 53
  ColorNotebookCallback  callback;
  gpointer               client_data;
54

55
  gboolean               wants_updates;
56 57 58
};


59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74
static void   color_notebook_help_func     (const gchar           *help_id,
                                            gpointer               help_data);

static void   color_notebook_response      (GtkWidget             *widget,
                                            gint                   response_id,
                                            ColorNotebook         *cnp);

static void   color_notebook_color_changed (GimpColorSelection    *selection,
                                            ColorNotebook         *cnp);

static void   color_history_color_clicked  (GtkWidget             *widget,
                                            ColorNotebook         *cnp);
static void   color_history_color_changed  (GtkWidget             *widget,
                                            gpointer               data);
static void   color_history_add_clicked    (GtkWidget             *widget,
                                            ColorNotebook         *cnp);
75

76

77
static GList *color_notebooks = NULL;
78

79

80 81
/*  public functions  */

82
ColorNotebook *
83 84 85 86
color_notebook_new (GimpViewable          *viewable,
                    const gchar           *title,
                    const gchar           *stock_id,
                    const gchar           *desc,
87
                    GtkWidget             *parent,
88 89
                    GimpDialogFactory     *dialog_factory,
                    const gchar           *dialog_identifier,
90 91 92 93 94
                    const GimpRGB         *color,
                    ColorNotebookCallback  callback,
                    gpointer               client_data,
                    gboolean               wants_updates,
                    gboolean               show_alpha)
95
{
96 97 98 99
  ColorNotebook *cnp;
  GtkWidget     *table;
  GtkWidget     *button;
  GtkWidget     *arrow;
100
  const gchar   *role;
101
  gint           i;
102

103
  g_return_val_if_fail (viewable == NULL || GIMP_IS_VIEWABLE (viewable), NULL);
104
  g_return_val_if_fail (GTK_IS_WIDGET (parent), NULL);
105 106 107 108
  g_return_val_if_fail (dialog_factory == NULL ||
                        GIMP_IS_DIALOG_FACTORY (dialog_factory), NULL);
  g_return_val_if_fail (dialog_factory == NULL || dialog_identifier != NULL,
                        NULL);
109 110
  g_return_val_if_fail (color != NULL, NULL);

111 112
  cnp = g_new0 (ColorNotebook, 1);

113 114
  cnp->callback      = callback;
  cnp->client_data   = client_data;
115 116
  cnp->wants_updates = wants_updates;

117 118
  role = dialog_identifier ? dialog_identifier : "gimp-color-selector";

119 120
  if (desc)
    {
121
      cnp->shell = gimp_viewable_dialog_new (viewable, title, role,
122
                                             stock_id, desc,
123
                                             parent,
124
                                             color_notebook_help_func, NULL,
125 126 127 128 129 130
                                             NULL);

      gtk_window_set_resizable (GTK_WINDOW (cnp->shell), FALSE);
    }
  else
    {
131
      cnp->shell = gimp_dialog_new (title, role,
132
                                    parent, 0,
133 134
                                    color_notebook_help_func, NULL,
                                    NULL);
135 136
   }

137 138
  g_object_set_data (G_OBJECT (cnp->shell), "color-notebook", cnp);

139
  gtk_dialog_add_buttons (GTK_DIALOG (cnp->shell),
140
                          GIMP_STOCK_RESET, RESPONSE_RESET,
141 142 143
                          GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
                          GTK_STOCK_OK,     GTK_RESPONSE_OK,
                          NULL);
144
  gtk_dialog_set_default_response (GTK_DIALOG (cnp->shell), GTK_RESPONSE_OK);
145

146 147 148
  g_signal_connect (cnp->shell, "response",
                    G_CALLBACK (color_notebook_response),
                    cnp);
149

150 151
  g_object_add_weak_pointer (G_OBJECT (cnp->shell), (gpointer *) &cnp->shell);

152 153 154
  if (dialog_factory)
    gimp_dialog_factory_add_foreign (dialog_factory, dialog_identifier,
                                     cnp->shell);
155

156
  cnp->selection = gimp_color_selection_new ();
157
  gtk_container_set_border_width (GTK_CONTAINER (cnp->selection), 12);
158 159 160 161 162 163 164 165 166
  gimp_color_selection_set_show_alpha (GIMP_COLOR_SELECTION (cnp->selection),
                                       show_alpha);
  gimp_color_selection_set_color (GIMP_COLOR_SELECTION (cnp->selection), color);
  gimp_color_selection_set_old_color (GIMP_COLOR_SELECTION (cnp->selection),
                                      color);
  gtk_container_add (GTK_CONTAINER (GTK_DIALOG (cnp->shell)->vbox),
                     cnp->selection);
  gtk_widget_show (cnp->selection);

167
  g_signal_connect (cnp->selection, "color_changed",
168
                    G_CALLBACK (color_notebook_color_changed),
169
                    cnp);
170

171
  /* The color history */
172
  table = gtk_table_new (2, 1 + COLOR_HISTORY_SIZE / 2, TRUE);
173 174 175 176 177
  gtk_table_set_row_spacings (GTK_TABLE (table), 2);
  gtk_table_set_col_spacings (GTK_TABLE (table), 2);
  gtk_table_set_col_spacing (GTK_TABLE (table), 0, 4);
  gtk_box_pack_end (GTK_BOX (GIMP_COLOR_SELECTION (cnp->selection)->right_vbox),
                    table, FALSE, FALSE, 0);
178
  gtk_widget_show (table);
179 180

  button = gtk_button_new ();
181
  gtk_widget_set_size_request (button, COLOR_AREA_SIZE, COLOR_AREA_SIZE);
182
  gtk_table_attach_defaults (GTK_TABLE (table), button, 0, 1, 0, 1);
183 184 185 186 187
  gimp_help_set_help_data (button,
			   _("Add the current color to the color history"),
			   NULL);
  gtk_widget_show (button);

188
  g_signal_connect (button, "clicked",
Michael Natterer's avatar
Michael Natterer committed
189 190
		    G_CALLBACK (color_history_add_clicked),
		    cnp);
191 192 193 194 195 196 197

  arrow = gtk_arrow_new (GTK_ARROW_RIGHT, GTK_SHADOW_OUT);
  gtk_container_add (GTK_CONTAINER (button), arrow);
  gtk_widget_show (arrow);

  for (i = 0; i < COLOR_HISTORY_SIZE; i++)
    {
198
      GimpRGB history_color;
199
      gint    row, column;
200 201 202

      color_history_get (i, &history_color);

203
      button = gtk_button_new ();
204
      gtk_widget_set_size_request (button, COLOR_AREA_SIZE, COLOR_AREA_SIZE);
205 206 207 208

      column = i % (COLOR_HISTORY_SIZE / 2);
      row    = i / (COLOR_HISTORY_SIZE / 2);

209
      gtk_table_attach_defaults (GTK_TABLE (table), button,
210
                                 column + 1, column + 2, row, row + 1);
211

212
      cnp->history[i] = gimp_color_area_new (&history_color,
213 214 215 216 217 218
					     GIMP_COLOR_AREA_SMALL_CHECKS,
					     GDK_BUTTON2_MASK);
      gtk_container_add (GTK_CONTAINER (button), cnp->history[i]);
      gtk_widget_show (cnp->history[i]);
      gtk_widget_show (button);

219
      g_signal_connect (button, "clicked",
Michael Natterer's avatar
Michael Natterer committed
220 221
			G_CALLBACK (color_history_color_clicked),
			cnp);
222

223
      g_signal_connect (cnp->history[i], "color_changed",
Michael Natterer's avatar
Michael Natterer committed
224
			G_CALLBACK (color_history_color_changed),
225
			GINT_TO_POINTER (i));
226 227
    }

228 229
  gtk_widget_show (cnp->shell);

230 231
  color_notebooks = g_list_prepend (color_notebooks, cnp);

232 233 234
  return cnp;
}

235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322
void
color_notebook_free (ColorNotebook *cnp)
{
  g_return_if_fail (cnp != NULL);

  color_notebooks = g_list_remove (color_notebooks, cnp);

  /*  may be already destroyed by dialog factory  */
  if (cnp->shell)
    {
      g_object_remove_weak_pointer (G_OBJECT (cnp->shell),
                                    (gpointer *) &cnp->shell);
      gtk_widget_destroy (cnp->shell);
    }

  g_free (cnp);
}

void
color_notebook_set_viewable (ColorNotebook *cnb,
                             GimpViewable  *viewable)
{
  g_return_if_fail (cnb != NULL);

  if (GIMP_IS_VIEWABLE_DIALOG (cnb->shell))
    gimp_viewable_dialog_set_viewable (GIMP_VIEWABLE_DIALOG (cnb->shell),
                                       viewable);
}

void
color_notebook_set_title (ColorNotebook *cnb,
                          const gchar   *title)
{
  g_return_if_fail (cnb != NULL);
  g_return_if_fail (title != NULL);

  gtk_window_set_title (GTK_WINDOW (cnb->shell), title);
}

void
color_notebook_set_color (ColorNotebook *cnp,
			  const GimpRGB *color)
{
  g_return_if_fail (cnp != NULL);
  g_return_if_fail (color != NULL);

  g_signal_handlers_block_by_func (cnp->selection,
                                   color_notebook_color_changed,
                                   cnp);

  gimp_color_selection_set_color (GIMP_COLOR_SELECTION (cnp->selection), color);
  gimp_color_selection_set_old_color (GIMP_COLOR_SELECTION (cnp->selection),
                                      color);

  g_signal_handlers_unblock_by_func (cnp->selection,
                                     color_notebook_color_changed,
                                     cnp);
}

void
color_notebook_get_color (ColorNotebook *cnp,
			  GimpRGB       *color)
{
  g_return_if_fail (cnp != NULL);
  g_return_if_fail (color != NULL);

  gimp_color_selection_get_color (GIMP_COLOR_SELECTION (cnp->selection), color);
}

void
color_notebook_show (ColorNotebook *cnp)
{
  g_return_if_fail (cnp != NULL);

  gtk_window_present (GTK_WINDOW (cnp->shell));
}

void
color_notebook_hide (ColorNotebook *cnp)
{
  g_return_if_fail (cnp != NULL);

  gtk_widget_hide (cnp->shell);
}


/*  private functions  */

323
static void
324 325
color_notebook_help_func (const gchar *help_id,
                          gpointer     help_data)
326
{
327 328
  ColorNotebook     *cnp;
  GimpColorNotebook *notebook;
329

330
  cnp = g_object_get_data (G_OBJECT (help_data), "color-notebook");
331

332 333
  notebook =
    GIMP_COLOR_NOTEBOOK (GIMP_COLOR_SELECTION (cnp->selection)->notebook);
334

335
  help_id = GIMP_COLOR_SELECTOR_GET_CLASS (notebook->cur_page)->help_id;
336 337

  gimp_standard_help_func (help_id, NULL);
338 339 340
}

static void
341 342 343
color_notebook_response (GtkWidget     *widget,
                         gint           response_id,
                         ColorNotebook *cnp)
344
{
345 346 347
  GimpRGB color;

  switch (response_id)
348
    {
349 350 351 352 353
    case RESPONSE_RESET:
      gimp_color_selection_reset (GIMP_COLOR_SELECTION (cnp->selection));
      break;

    case GTK_RESPONSE_OK:
354
      color_history_add_clicked (NULL, cnp);
355

356 357 358
      gimp_color_selection_get_color (GIMP_COLOR_SELECTION (cnp->selection),
                                      &color);

359
      if (cnp->callback)
360
        cnp->callback (cnp, &color,
361 362
                       COLOR_NOTEBOOK_OK,
                       cnp->client_data);
363
      break;
364

365 366 367
    default:
      gimp_color_selection_get_old_color (GIMP_COLOR_SELECTION (cnp->selection),
                                          &color);
368

369 370 371
      if (cnp->callback)
        cnp->callback (cnp, &color,
                       COLOR_NOTEBOOK_CANCEL,
372
                       cnp->client_data);
373
      break;
374 375 376
    }
}

377
static void
378 379
color_notebook_color_changed (GimpColorSelection *selection,
                              ColorNotebook      *cnp)
380
{
381
  GimpRGB color;
382

383
  gimp_color_selection_get_color (selection, &color);
384

385 386 387 388 389
  if (cnp->wants_updates && cnp->callback)
    cnp->callback (cnp,
                   &color,
                   COLOR_NOTEBOOK_UPDATE,
                   cnp->client_data);
390 391 392
}


393
/*  color history callbacks  */
394 395

static void
396 397
color_history_color_clicked (GtkWidget     *widget,
			     ColorNotebook *cnp)
398 399
{
  GimpColorArea *color_area;
400
  GimpRGB        color;
401 402 403

  color_area = GIMP_COLOR_AREA (GTK_BIN (widget)->child);

404 405 406
  gimp_color_area_get_color (color_area, &color);
  gimp_color_selection_set_color (GIMP_COLOR_SELECTION (cnp->selection),
                                  &color);
407 408 409 410 411 412
}

static void
color_history_color_changed (GtkWidget *widget,
			     gpointer   data)
{
413 414 415
  GimpRGB  changed_color;
  gint     color_index;
  GList   *list;
416 417 418

  gimp_color_area_get_color (GIMP_COLOR_AREA (widget), &changed_color);

419 420
  color_index = GPOINTER_TO_INT (data);

421
  color_history_set (color_index, &changed_color);
422

423 424
  for (list = color_notebooks; list; list = g_list_next (list))
    {
425
      ColorNotebook *notebook = list->data;
426

427 428 429 430 431
      if (notebook->history[color_index] != widget)
        {
          g_signal_handlers_block_by_func (notebook->history[color_index],
                                           color_history_color_changed,
                                           data);
432

433 434
          gimp_color_area_set_color
            (GIMP_COLOR_AREA (notebook->history[color_index]), &changed_color);
435

436 437 438 439
          g_signal_handlers_unblock_by_func (notebook->history[color_index],
                                             color_history_color_changed,
                                             data);
        }
440 441 442 443
    }
}

static void
444 445
color_history_add_clicked (GtkWidget     *widget,
			   ColorNotebook *cnp)
446
{
447 448 449
  GimpRGB color;
  gint    shift_begin;
  gint    i;
450

451 452 453 454
  gimp_color_selection_get_color (GIMP_COLOR_SELECTION (cnp->selection),
                                  &color);

  shift_begin = color_history_add (&color);
455

456
  for (i = shift_begin; i >= 0; i--)
457
    {
458
      color_history_get (i, &color);
459

460
      gimp_color_area_set_color (GIMP_COLOR_AREA (cnp->history[i]), &color);
461 462
    }
}