gimpcolormapeditor.c 25.7 KB
Newer Older
1
/* GIMP - The GNU Image Manipulation Program
Sven Neumann's avatar
Sven Neumann committed
2 3
 * Copyright (C) 1995 Spencer Kimball and Peter Mattis
 *
4
 * This program is free software: you can redistribute it and/or modify
Sven Neumann's avatar
Sven Neumann committed
5
 * it under the terms of the GNU General Public License as published by
6
 * the Free Software Foundation; either version 3 of the License, or
Sven Neumann's avatar
Sven Neumann committed
7 8 9 10 11 12 13 14
 * (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
15
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
Sven Neumann's avatar
Sven Neumann committed
16 17 18 19
 */

#include "config.h"

20
#include <gegl.h>
Sven Neumann's avatar
Sven Neumann committed
21 22
#include <gtk/gtk.h>

23
#include "libgimpcolor/gimpcolor.h"
24
#include "libgimpmath/gimpmath.h"
25
#include "libgimpwidgets/gimpwidgets.h"
26

27
#include "widgets-types.h"
Sven Neumann's avatar
Sven Neumann committed
28

29
#include "core/gimp.h"
30
#include "core/gimpcontext.h"
31 32
#include "core/gimpcontainer.h"
#include "core/gimpimage.h"
33
#include "core/gimpimage-colormap.h"
34
#include "core/gimpmarshal.h"
35
#include "core/gimppalette.h"
36

37
#include "gimpcolordialog.h"
38
#include "gimpcolormapeditor.h"
39
#include "gimpdialogfactory.h"
40
#include "gimpdnd.h"
41
#include "gimpdocked.h"
42
#include "gimpmenufactory.h"
43
#include "gimppaletteview.h"
44
#include "gimpuimanager.h"
45
#include "gimpviewrendererpalette.h"
46
#include "gimpwidgets-utils.h"
47

48
#include "gimp-intl.h"
Michael Natterer's avatar
Michael Natterer committed
49 50


51 52
#define BORDER      6
#define RGB_EPSILON 1e-6
Michael Natterer's avatar
Michael Natterer committed
53

54 55
#define HAVE_COLORMAP(image) \
        (image != NULL && \
56
         gimp_image_get_base_type (image) == GIMP_INDEXED && \
57
         gimp_image_get_colormap (image) != NULL)
58 59


60 61
static void gimp_colormap_editor_docked_iface_init (GimpDockedInterface *face);

62
static void   gimp_colormap_editor_constructed     (GObject            *object);
63
static void   gimp_colormap_editor_dispose         (GObject            *object);
64
static void   gimp_colormap_editor_finalize        (GObject            *object);
65

66 67
static void   gimp_colormap_editor_unmap           (GtkWidget          *widget);

68
static void   gimp_colormap_editor_set_image       (GimpImageEditor    *editor,
69
                                                    GimpImage          *image);
70

71 72 73
static void   gimp_colormap_editor_set_context     (GimpDocked        *docked,
                                                    GimpContext       *context);

74 75 76
static PangoLayout *
              gimp_colormap_editor_create_layout   (GtkWidget          *widget);

77 78
static void   gimp_colormap_editor_update_entries  (GimpColormapEditor *editor);

79 80
static gboolean gimp_colormap_preview_draw         (GtkWidget          *widget,
                                                    cairo_t            *cr,
81
                                                    GimpColormapEditor *editor);
82 83 84 85 86 87 88 89 90 91

static void   gimp_colormap_editor_entry_clicked   (GimpPaletteView    *view,
                                                    GimpPaletteEntry   *entry,
                                                    GdkModifierType    state,
                                                    GimpColormapEditor *editor);
static void   gimp_colormap_editor_entry_selected  (GimpPaletteView    *view,
                                                    GimpPaletteEntry   *entry,
                                                    GimpColormapEditor *editor);
static void   gimp_colormap_editor_entry_activated (GimpPaletteView    *view,
                                                    GimpPaletteEntry   *entry,
92
                                                    GimpColormapEditor *editor);
93 94 95 96 97
static void   gimp_colormap_editor_entry_context   (GimpPaletteView    *view,
                                                    GimpPaletteEntry   *entry,
                                                    GimpColormapEditor *editor);
static void   gimp_colormap_editor_color_dropped   (GimpPaletteView    *view,
                                                    GimpPaletteEntry   *entry,
98
                                                    const GimpRGB      *color,
99
                                                    GimpColormapEditor *editor);
100 101 102

static void   gimp_colormap_adjustment_changed     (GtkAdjustment      *adjustment,
                                                    GimpColormapEditor *editor);
103
static void   gimp_colormap_hex_entry_changed      (GimpColorHexEntry  *entry,
104 105
                                                    GimpColormapEditor *editor);

106
static void   gimp_colormap_image_mode_changed     (GimpImage          *image,
107
                                                    GimpColormapEditor *editor);
108
static void   gimp_colormap_image_colormap_changed (GimpImage          *image,
109 110 111
                                                    gint                ncol,
                                                    GimpColormapEditor *editor);

112 113 114 115 116 117
static void   gimp_colormap_editor_edit_color_update
                                                    (GimpColorDialog    *dialog,
                                                     const GimpRGB      *color,
                                                     GimpColorDialogState state,
                                                     GimpColormapEditor *editor);

118

119 120 121 122
G_DEFINE_TYPE_WITH_CODE (GimpColormapEditor, gimp_colormap_editor,
                         GIMP_TYPE_IMAGE_EDITOR,
                         G_IMPLEMENT_INTERFACE (GIMP_TYPE_DOCKED,
                                                gimp_colormap_editor_docked_iface_init))
Michael Natterer's avatar
Michael Natterer committed
123

124
#define parent_class gimp_colormap_editor_parent_class
Michael Natterer's avatar
Michael Natterer committed
125

126 127
static GimpDockedInterface *parent_docked_iface = NULL;

Michael Natterer's avatar
Michael Natterer committed
128 129

static void
130
gimp_colormap_editor_class_init (GimpColormapEditorClass* klass)
Michael Natterer's avatar
Michael Natterer committed
131
{
132 133 134
  GObjectClass         *object_class       = G_OBJECT_CLASS (klass);
  GtkWidgetClass       *widget_class       = GTK_WIDGET_CLASS (klass);
  GimpImageEditorClass *image_editor_class = GIMP_IMAGE_EDITOR_CLASS (klass);
135

136
  object_class->constructed     = gimp_colormap_editor_constructed;
137
  object_class->dispose         = gimp_colormap_editor_dispose;
138
  object_class->finalize        = gimp_colormap_editor_finalize;
139

140
  widget_class->unmap           = gimp_colormap_editor_unmap;
141

142
  image_editor_class->set_image = gimp_colormap_editor_set_image;
Michael Natterer's avatar
Michael Natterer committed
143 144
}

145 146 147 148 149 150 151 152 153 154 155
static void
gimp_colormap_editor_docked_iface_init (GimpDockedInterface *iface)
{
  parent_docked_iface = g_type_interface_peek_parent (iface);

  if (! parent_docked_iface)
    parent_docked_iface = g_type_default_interface_peek (GIMP_TYPE_DOCKED);

  iface->set_context = gimp_colormap_editor_set_context;
}

Michael Natterer's avatar
Michael Natterer committed
156
static void
Michael Natterer's avatar
Michael Natterer committed
157
gimp_colormap_editor_init (GimpColormapEditor *editor)
Michael Natterer's avatar
Michael Natterer committed
158
{
159
  GtkWidget *frame;
160
  GtkWidget *grid;
161 162 163 164 165 166

  frame = gtk_frame_new (NULL);
  gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
  gtk_box_pack_start (GTK_BOX (editor), frame, TRUE, TRUE, 0);
  gtk_widget_show (frame);

167 168 169 170 171 172 173 174
  editor->view = gimp_view_new_full_by_types (NULL,
                                              GIMP_TYPE_PALETTE_VIEW,
                                              GIMP_TYPE_PALETTE,
                                              1, 1, 0,
                                              FALSE, TRUE, FALSE);
  gimp_view_set_expand (GIMP_VIEW (editor->view), TRUE);
  gtk_container_add (GTK_CONTAINER (frame), editor->view);
  gtk_widget_show (editor->view);
175

176 177
  g_signal_connect (editor->view, "draw",
                    G_CALLBACK (gimp_colormap_preview_draw),
178
                    editor);
179

180 181 182 183 184 185 186 187 188 189 190 191 192 193
  g_signal_connect (editor->view, "entry-clicked",
                    G_CALLBACK (gimp_colormap_editor_entry_clicked),
                    editor);
  g_signal_connect (editor->view, "entry-selected",
                    G_CALLBACK (gimp_colormap_editor_entry_selected),
                    editor);
  g_signal_connect (editor->view, "entry-activated",
                    G_CALLBACK (gimp_colormap_editor_entry_activated),
                    editor);
  g_signal_connect (editor->view, "entry-context",
                    G_CALLBACK (gimp_colormap_editor_entry_context),
                    editor);
  g_signal_connect (editor->view, "color-dropped",
                    G_CALLBACK (gimp_colormap_editor_color_dropped),
194 195 196
                    editor);

  /*  Some helpful hints  */
197 198 199 200 201
  grid = gtk_grid_new ();
  gtk_grid_set_column_spacing (GTK_GRID (grid), 4);
  gtk_grid_set_row_spacing (GTK_GRID (grid), 2);
  gtk_box_pack_end (GTK_BOX (editor), grid, FALSE, FALSE, 0);
  gtk_widget_show (grid);
202

203
  editor->index_adjustment = gtk_adjustment_new (0, 0, 0, 1, 10, 0);
204 205
  editor->index_spinbutton = gtk_spin_button_new (editor->index_adjustment,
                                                  1.0, 0);
206
  gtk_widget_set_halign (editor->index_spinbutton, GTK_ALIGN_START);
207 208
  gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (editor->index_spinbutton),
                               TRUE);
209 210 211
  gimp_grid_attach_aligned (GTK_GRID (grid), 0, 0,
                            _("Color index:"), 0.0, 0.5,
                            editor->index_spinbutton, 1);
212

213
  g_signal_connect (editor->index_adjustment, "value-changed",
214 215 216
                    G_CALLBACK (gimp_colormap_adjustment_changed),
                    editor);

217
  editor->color_entry = gimp_color_hex_entry_new ();
218 219 220 221
  gtk_widget_set_halign (editor->color_entry, GTK_ALIGN_START);
  gimp_grid_attach_aligned (GTK_GRID (grid), 0, 1,
                            _("HTML notation:"), 0.0, 0.5,
                            editor->color_entry, 1);
222

223
  g_signal_connect (editor->color_entry, "color-changed",
224
                    G_CALLBACK (gimp_colormap_hex_entry_changed),
225
                    editor);
226 227
}

228 229
static void
gimp_colormap_editor_constructed (GObject *object)
230
{
231
  GimpColormapEditor *editor = GIMP_COLORMAP_EDITOR (object);
232 233
  GdkModifierType     extend_mask;
  GdkModifierType     modify_mask;
234

235
  G_OBJECT_CLASS (parent_class)->constructed (object);
Michael Natterer's avatar
Michael Natterer committed
236

237 238 239 240 241
  extend_mask = gtk_widget_get_modifier_mask (GTK_WIDGET (object),
                                              GDK_MODIFIER_INTENT_EXTEND_SELECTION);
  modify_mask = gtk_widget_get_modifier_mask (GTK_WIDGET (object),
                                              GDK_MODIFIER_INTENT_MODIFY_SELECTION);

242 243 244
  gimp_editor_add_action_button (GIMP_EDITOR (editor), "colormap",
                                 "colormap-edit-color",
                                 NULL);
Michael Natterer's avatar
Michael Natterer committed
245

246 247 248
  gimp_editor_add_action_button (GIMP_EDITOR (editor), "colormap",
                                 "colormap-add-color-from-fg",
                                 "colormap-add-color-from-bg",
249
                                 gimp_get_toggle_behavior_mask (),
250
                                 NULL);
251 252 253 254 255 256 257 258 259 260

  gimp_editor_add_action_button (GIMP_EDITOR (editor), "colormap",
                                 "colormap-selection-replace",
                                 "colormap-selection-add",
                                 extend_mask,
                                 "colormap-selection-subtract",
                                 modify_mask,
                                 "colormap-selection-intersect",
                                 extend_mask | modify_mask,
                                 NULL);
Michael Natterer's avatar
Michael Natterer committed
261 262
}

263
static void
264
gimp_colormap_editor_dispose (GObject *object)
265 266 267
{
  GimpColormapEditor *editor = GIMP_COLORMAP_EDITOR (object);

268
  g_clear_pointer (&editor->color_dialog, gtk_widget_destroy);
269

270
  G_OBJECT_CLASS (parent_class)->dispose (object);
271 272
}

273
static void
274
gimp_colormap_editor_finalize (GObject *object)
275
{
276
  GimpColormapEditor *editor = GIMP_COLORMAP_EDITOR (object);
277

278
  g_clear_object (&editor->layout);
279

280
  G_OBJECT_CLASS (parent_class)->finalize (object);
281 282 283 284 285
}

static void
gimp_colormap_editor_unmap (GtkWidget *widget)
{
286
  GimpColormapEditor *editor = GIMP_COLORMAP_EDITOR (widget);
287

288
  if (editor->color_dialog)
289
    gtk_widget_hide (editor->color_dialog);
290 291 292 293

  GTK_WIDGET_CLASS (parent_class)->unmap (widget);
}

294 295
static void
gimp_colormap_editor_set_image (GimpImageEditor *image_editor,
296
                                GimpImage       *image)
297
{
298
  GimpColormapEditor *editor = GIMP_COLORMAP_EDITOR (image_editor);
299

300
  if (image_editor->image)
301
    {
302
      g_signal_handlers_disconnect_by_func (image_editor->image,
303 304
                                            gimp_colormap_image_mode_changed,
                                            editor);
305
      g_signal_handlers_disconnect_by_func (image_editor->image,
306 307
                                            gimp_colormap_image_colormap_changed,
                                            editor);
308

309
      if (editor->color_dialog)
310
        gtk_widget_hide (editor->color_dialog);
311

312
      if (! HAVE_COLORMAP (image))
313
        {
314
          gtk_adjustment_set_upper (editor->index_adjustment, 0);
315

316
          if (gtk_widget_get_mapped (GTK_WIDGET (editor)))
317
            gimp_view_set_viewable (GIMP_VIEW (editor->view), NULL);
318
        }
319 320
    }

321
  GIMP_IMAGE_EDITOR_CLASS (parent_class)->set_image (image_editor, image);
322

323
  editor->col_index = 0;
324

325
  if (image)
326
    {
327
      g_signal_connect (image, "mode-changed",
328 329
                        G_CALLBACK (gimp_colormap_image_mode_changed),
                        editor);
330
      g_signal_connect (image, "colormap-changed",
331 332
                        G_CALLBACK (gimp_colormap_image_colormap_changed),
                        editor);
333

334
      if (HAVE_COLORMAP (image))
335
        {
336 337
          gimp_view_set_viewable (GIMP_VIEW (editor->view),
                                  GIMP_VIEWABLE (gimp_image_get_colormap_palette (image)));
338

339 340
          gtk_adjustment_set_upper (editor->index_adjustment,
                                    gimp_image_get_colormap_size (image) - 1);
341
        }
342 343 344 345 346
    }

  gimp_colormap_editor_update_entries (editor);
}

347 348 349 350 351 352 353 354 355 356 357 358
static void
gimp_colormap_editor_set_context (GimpDocked  *docked,
                                  GimpContext *context)
{
  GimpColormapEditor *editor = GIMP_COLORMAP_EDITOR (docked);

  parent_docked_iface->set_context (docked, context);

  gimp_view_renderer_set_context (GIMP_VIEW (editor->view)->renderer,
                                  context);
}

359 360 361

/*  public functions  */

362
GtkWidget *
363
gimp_colormap_editor_new (GimpMenuFactory *menu_factory)
Michael Natterer's avatar
Michael Natterer committed
364
{
365
  g_return_val_if_fail (GIMP_IS_MENU_FACTORY (menu_factory), NULL);
Michael Natterer's avatar
Michael Natterer committed
366

367 368
  return g_object_new (GIMP_TYPE_COLORMAP_EDITOR,
                       "menu-factory",    menu_factory,
369 370
                       "menu-identifier", "<Colormap>",
                       "ui-path",         "/colormap-popup",
371
                       NULL);
Michael Natterer's avatar
Michael Natterer committed
372 373
}

374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438
void
gimp_colormap_editor_edit_color (GimpColormapEditor *editor)
{
  GimpImage    *image;
  const guchar *colormap;
  GimpRGB       color;
  gchar        *desc;
  gint         index;

  g_return_if_fail (GIMP_IS_COLORMAP_EDITOR (editor));

  image = GIMP_IMAGE_EDITOR (editor)->image;

  if (! HAVE_COLORMAP (image))
    return;

  index = editor->col_index;

  colormap = gimp_image_get_colormap (image);

  gimp_rgba_set_uchar (&color,
                       colormap[index * 3],
                       colormap[index * 3 + 1],
                       colormap[index * 3 + 2],
                       255);

  desc = g_strdup_printf (_("Edit colormap entry #%d"), index);

  if (! editor->color_dialog)
    {
      editor->color_dialog =
        gimp_color_dialog_new (GIMP_VIEWABLE (image),
                               GIMP_IMAGE_EDITOR (editor)->context,
                               _("Edit Colormap Entry"),
                               GIMP_ICON_COLORMAP,
                               desc,
                               GTK_WIDGET (editor),
                               gimp_dialog_factory_get_singleton (),
                               "gimp-colormap-editor-color-dialog",
                               (const GimpRGB *) &color,
                               FALSE, FALSE);

      g_signal_connect (editor->color_dialog, "destroy",
                        G_CALLBACK (gtk_widget_destroyed),
                        &editor->color_dialog);

      g_signal_connect (editor->color_dialog, "update",
                        G_CALLBACK (gimp_colormap_editor_edit_color_update),
                        editor);
    }
  else
    {
      gimp_viewable_dialog_set_viewable (GIMP_VIEWABLE_DIALOG (editor->color_dialog),
                                         GIMP_VIEWABLE (image),
                                         GIMP_IMAGE_EDITOR (editor)->context);
      g_object_set (editor->color_dialog, "description", desc, NULL);
      gimp_color_dialog_set_color (GIMP_COLOR_DIALOG (editor->color_dialog),
                                   &color);
    }

  g_free (desc);

  gtk_window_present (GTK_WINDOW (editor->color_dialog));
}

439 440 441
gint
gimp_colormap_editor_get_index (GimpColormapEditor *editor,
                                const GimpRGB      *search)
Michael Natterer's avatar
Michael Natterer committed
442
{
443 444 445
  GimpImage *image;
  gint       index;

446
  g_return_val_if_fail (GIMP_IS_COLORMAP_EDITOR (editor), 0);
447 448 449 450 451 452 453 454 455 456 457 458 459 460

  image = GIMP_IMAGE_EDITOR (editor)->image;

  if (! HAVE_COLORMAP (image))
    return -1;

  index = editor->col_index;

  if (search)
    {
      GimpRGB temp;

      gimp_image_get_colormap_entry (image, index, &temp);

461
      if (gimp_rgb_distance (&temp, search) > RGB_EPSILON)
462 463 464 465 466 467 468 469
        {
          gint n_colors = gimp_image_get_colormap_size (image);
          gint i;

          for (i = 0; i < n_colors; i++)
            {
              gimp_image_get_colormap_entry (image, i, &temp);

470
              if (gimp_rgb_distance (&temp, search) < RGB_EPSILON)
471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487
                {
                  index = i;
                  break;
                }
            }
        }
    }

  return index;
}

gboolean
gimp_colormap_editor_set_index (GimpColormapEditor *editor,
                                gint                index,
                                GimpRGB            *color)
{
  GimpImage *image;
488
  gint       size;
489 490 491 492 493 494 495 496

  g_return_val_if_fail (GIMP_IS_COLORMAP_EDITOR (editor), FALSE);

  image = GIMP_IMAGE_EDITOR (editor)->image;

  if (! HAVE_COLORMAP (image))
    return FALSE;

497 498 499 500 501 502
  size = gimp_image_get_colormap_size (image);

  if (size < 1)
    return FALSE;

  index = CLAMP (index, 0, size - 1);
503 504 505

  if (index != editor->col_index)
    {
506
      GimpPalette *palette = gimp_image_get_colormap_palette (image);
507

508
      editor->col_index = index;
509

510 511
      gimp_palette_view_select_entry (GIMP_PALETTE_VIEW (editor->view),
                                      gimp_palette_get_entry (palette, index));
512 513 514

      gimp_colormap_editor_update_entries (editor);
    }
Michael Natterer's avatar
Michael Natterer committed
515

516 517 518 519 520
  if (color)
    gimp_image_get_colormap_entry (GIMP_IMAGE_EDITOR (editor)->image,
                                   index, color);

  return TRUE;
Michael Natterer's avatar
Michael Natterer committed
521 522
}

523
gint
524
gimp_colormap_editor_max_index (GimpColormapEditor *editor)
525
{
526 527 528 529 530
  GimpImage *image;

  g_return_val_if_fail (GIMP_IS_COLORMAP_EDITOR (editor), -1);

  image = GIMP_IMAGE_EDITOR (editor)->image;
531

532 533 534 535
  if (! HAVE_COLORMAP (image))
    return -1;

  return MAX (0, gimp_image_get_colormap_size (image) - 1);
Michael Natterer's avatar
Michael Natterer committed
536 537
}

538 539 540

/*  private functions  */

541 542 543 544 545 546 547 548
static PangoLayout *
gimp_colormap_editor_create_layout (GtkWidget *widget)
{
  PangoLayout    *layout;
  PangoAttrList  *attrs;
  PangoAttribute *attr;

  layout = gtk_widget_create_pango_layout (widget,
549 550
                                           _("Only indexed images have "
                                             "a colormap."));
551

552 553 554 555 556 557 558 559 560 561 562 563 564 565 566
  pango_layout_set_alignment (layout, PANGO_ALIGN_CENTER);

  attrs = pango_attr_list_new ();

  attr = pango_attr_style_new (PANGO_STYLE_ITALIC);
  attr->start_index = 0;
  attr->end_index   = -1;
  pango_attr_list_insert (attrs, attr);

  pango_layout_set_attributes (layout, attrs);
  pango_attr_list_unref (attrs);

  return layout;
}

567
static gboolean
568 569 570
gimp_colormap_preview_draw (GtkWidget          *widget,
                            cairo_t            *cr,
                            GimpColormapEditor *editor)
571 572
{
  GimpImageEditor *image_editor = GIMP_IMAGE_EDITOR (editor);
573
  GtkStyleContext *style        = gtk_widget_get_style_context (widget);
574
  GtkAllocation    allocation;
575
  GdkRGBA          color;
576
  gint             width, height;
577
  gint             y;
578 579

  if (image_editor->image == NULL ||
580
      gimp_image_get_base_type (image_editor->image) == GIMP_INDEXED)
581 582
    return FALSE;

583 584 585
  gtk_style_context_get_color (style, gtk_widget_get_state_flags (widget),
                               &color);
  gdk_cairo_set_source_rgba (cr, &color);
586

587
  gtk_widget_get_allocation (widget, &allocation);
588 589 590 591

  if (! editor->layout)
    editor->layout = gimp_colormap_editor_create_layout (editor->view);

592 593
  pango_layout_set_width (editor->layout,
                          PANGO_SCALE * (allocation.width - 2 * BORDER));
594

595 596
  pango_layout_get_pixel_size (editor->layout, &width, &height);

597
  y = (allocation.height - height) / 2;
598

599 600 601 602
  cairo_move_to (cr, BORDER, MAX (y, 0));
  pango_cairo_show_layout (cr, editor->layout);

  return TRUE;
603 604
}

Michael Natterer's avatar
Michael Natterer committed
605
static void
606
gimp_colormap_editor_update_entries (GimpColormapEditor *editor)
Michael Natterer's avatar
Michael Natterer committed
607
{
608
  GimpImage *image = GIMP_IMAGE_EDITOR (editor)->image;
609

610 611
  if (! HAVE_COLORMAP (image) ||
      ! gimp_image_get_colormap_size (image))
Michael Natterer's avatar
Michael Natterer committed
612
    {
613 614
      gtk_widget_set_sensitive (editor->index_spinbutton, FALSE);
      gtk_widget_set_sensitive (editor->color_entry, FALSE);
615

616 617
      gtk_adjustment_set_value (editor->index_adjustment, 0);
      gtk_entry_set_text (GTK_ENTRY (editor->color_entry), "");
Michael Natterer's avatar
Michael Natterer committed
618 619 620
    }
  else
    {
621 622 623
      const guchar *colormap = gimp_image_get_colormap (image);
      const guchar *col;
      gchar        *string;
Michael Natterer's avatar
Michael Natterer committed
624

625
      gtk_adjustment_set_value (editor->index_adjustment, editor->col_index);
Michael Natterer's avatar
Michael Natterer committed
626

627
      col = colormap + editor->col_index * 3;
628

629
      string = g_strdup_printf ("%02x%02x%02x", col[0], col[1], col[2]);
630
      gtk_entry_set_text (GTK_ENTRY (editor->color_entry), string);
Michael Natterer's avatar
Michael Natterer committed
631
      g_free (string);
632

633 634
      gtk_widget_set_sensitive (editor->index_spinbutton, TRUE);
      gtk_widget_set_sensitive (editor->color_entry, TRUE);
Michael Natterer's avatar
Michael Natterer committed
635 636 637
    }
}

638 639 640 641
static void
gimp_colormap_editor_entry_clicked (GimpPaletteView    *view,
                                    GimpPaletteEntry   *entry,
                                    GdkModifierType     state,
642
                                    GimpColormapEditor *editor)
Michael Natterer's avatar
Michael Natterer committed
643
{
644 645
  GimpImageEditor *image_editor = GIMP_IMAGE_EDITOR (editor);

646
  gimp_colormap_editor_set_index (editor, entry->position, NULL);
647

648
  if (state & gimp_get_toggle_behavior_mask ())
649 650 651
    gimp_context_set_background (image_editor->context, &entry->color);
  else
    gimp_context_set_foreground (image_editor->context, &entry->color);
652
}
Michael Natterer's avatar
Michael Natterer committed
653

654 655 656 657 658 659
static void
gimp_colormap_editor_entry_selected (GimpPaletteView    *view,
                                     GimpPaletteEntry   *entry,
                                     GimpColormapEditor *editor)
{
  gint index = entry ? entry->position : 0;
Michael Natterer's avatar
Michael Natterer committed
660

661
  gimp_colormap_editor_set_index (editor, index, NULL);
662
}
663

Michael Natterer's avatar
Michael Natterer committed
664
static void
665 666 667
gimp_colormap_editor_entry_activated (GimpPaletteView    *view,
                                      GimpPaletteEntry   *entry,
                                      GimpColormapEditor *editor)
Michael Natterer's avatar
Michael Natterer committed
668
{
669
  gimp_colormap_editor_set_index (editor, entry->position, NULL);
670

671
  gimp_ui_manager_activate_action (gimp_editor_get_ui_manager (GIMP_EDITOR (editor)),
672 673
                                   "colormap",
                                   "colormap-edit-color");
Michael Natterer's avatar
Michael Natterer committed
674 675 676
}

static void
677 678 679
gimp_colormap_editor_entry_context (GimpPaletteView    *view,
                                    GimpPaletteEntry   *entry,
                                    GimpColormapEditor *editor)
Michael Natterer's avatar
Michael Natterer committed
680
{
681
  gimp_colormap_editor_set_index (editor, entry->position, NULL);
682

683 684
  gimp_editor_popup_menu (GIMP_EDITOR (editor), NULL, NULL);
}
Michael Natterer's avatar
Michael Natterer committed
685

686 687 688 689 690 691
static void
gimp_colormap_editor_color_dropped (GimpPaletteView    *view,
                                    GimpPaletteEntry   *entry,
                                    const GimpRGB      *color,
                                    GimpColormapEditor *editor)
{
Michael Natterer's avatar
Michael Natterer committed
692 693
}

694 695 696
static void
gimp_colormap_adjustment_changed (GtkAdjustment      *adjustment,
                                  GimpColormapEditor *editor)
Michael Natterer's avatar
Michael Natterer committed
697
{
698
  GimpImage *image = GIMP_IMAGE_EDITOR (editor)->image;
699

700
  if (HAVE_COLORMAP (image))
701
    {
702 703 704
      gint index = ROUND (gtk_adjustment_get_value (adjustment));

      gimp_colormap_editor_set_index (editor, index, NULL);
Michael Natterer's avatar
Michael Natterer committed
705

706 707
      gimp_colormap_editor_update_entries (editor);
    }
708
}
Michael Natterer's avatar
Michael Natterer committed
709

710
static void
711 712
gimp_colormap_hex_entry_changed (GimpColorHexEntry  *entry,
                                 GimpColormapEditor *editor)
713
{
714
  GimpImage *image = GIMP_IMAGE_EDITOR (editor)->image;
715

716
  if (image)
717
    {
718
      GimpRGB color;
719

720
      gimp_color_hex_entry_get_color (entry, &color);
Michael Natterer's avatar
Michael Natterer committed
721

722 723
      gimp_image_set_colormap_entry (image, editor->col_index, &color, TRUE);
      gimp_image_flush (image);
724
    }
725
}
Michael Natterer's avatar
Michael Natterer committed
726

727
static void
728
gimp_colormap_image_mode_changed (GimpImage          *image,
729 730
                                  GimpColormapEditor *editor)
{
731 732 733
  if (editor->color_dialog)
    gtk_widget_hide (editor->color_dialog);

734
  gimp_colormap_image_colormap_changed (image, -1, editor);
735
}
Michael Natterer's avatar
Michael Natterer committed
736

737
static void
738
gimp_colormap_image_colormap_changed (GimpImage          *image,
739 740 741
                                      gint                ncol,
                                      GimpColormapEditor *editor)
{
742
  if (HAVE_COLORMAP (image))
743
    {
744 745
      gimp_view_set_viewable (GIMP_VIEW (editor->view),
                              GIMP_VIEWABLE (gimp_image_get_colormap_palette (image)));
Michael Natterer's avatar
Michael Natterer committed
746

747 748
      gtk_adjustment_set_upper (editor->index_adjustment,
                                gimp_image_get_colormap_size (image) - 1);
749 750 751
    }
  else
    {
752
      gimp_view_set_viewable (GIMP_VIEW (editor->view), NULL);
Michael Natterer's avatar
Michael Natterer committed
753 754
    }

755 756
  if (ncol == editor->col_index || ncol == -1)
    gimp_colormap_editor_update_entries (editor);
Michael Natterer's avatar
Michael Natterer committed
757
}
758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781

static void
gimp_colormap_editor_edit_color_update (GimpColorDialog      *dialog,
                                        const GimpRGB        *color,
                                        GimpColorDialogState  state,
                                        GimpColormapEditor   *editor)
{
  GimpImage *image = GIMP_IMAGE_EDITOR (editor)->image;

  switch (state)
    {
    case GIMP_COLOR_DIALOG_UPDATE:
      break;

    case GIMP_COLOR_DIALOG_OK:
      gimp_image_set_colormap_entry (image, editor->col_index, color, TRUE);
      gimp_image_flush (image);
      /* Fall through */

    case GIMP_COLOR_DIALOG_CANCEL:
      gtk_widget_hide (editor->color_dialog);
      break;
    }
}