layers-commands.c 28.4 KB
Newer Older
Michael Natterer's avatar
Michael Natterer committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
/* The GIMP -- an image manipulation program
 * Copyright (C) 1995 Spencer Kimball and Peter Mattis
 *
 * 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.
 */

#include "config.h"

21
#include <string.h>
Michael Natterer's avatar
Michael Natterer committed
22 23 24 25

#include <gtk/gtk.h>

#include "libgimpmath/gimpmath.h"
26
#include "libgimpbase/gimpbase.h"
Michael Natterer's avatar
Michael Natterer committed
27 28
#include "libgimpwidgets/gimpwidgets.h"

Michael Natterer's avatar
Michael Natterer committed
29
#include "actions-types.h"
Michael Natterer's avatar
Michael Natterer committed
30

31 32
#include "config/gimpcoreconfig.h"

Michael Natterer's avatar
Michael Natterer committed
33
#include "core/gimp.h"
34
#include "core/gimpchannel-select.h"
35
#include "core/gimpcontext.h"
36
#include "core/gimpimage.h"
37
#include "core/gimpimage-merge.h"
38
#include "core/gimpimage-undo.h"
39
#include "core/gimpitemundo.h"
40
#include "core/gimplayer.h"
Michael Natterer's avatar
Michael Natterer committed
41
#include "core/gimplayer-floating-sel.h"
42 43
#include "core/gimplayermask.h"
#include "core/gimplist.h"
44
#include "core/gimptoolinfo.h"
45
#include "core/gimpundostack.h"
46
#include "core/gimpprogress.h"
47

48
#include "text/gimptext.h"
49 50
#include "text/gimptextlayer.h"

51
#include "widgets/gimpaction.h"
52
#include "widgets/gimpdock.h"
53
#include "widgets/gimphelp-ids.h"
54
#include "widgets/gimpprogressdialog.h"
Michael Natterer's avatar
Michael Natterer committed
55

56
#include "display/gimpdisplay.h"
57
#include "display/gimpdisplayshell.h"
58

59 60 61
#include "tools/gimptexttool.h"
#include "tools/tool_manager.h"

62
#include "dialogs/layer-add-mask-dialog.h"
63
#include "dialogs/layer-options-dialog.h"
64
#include "dialogs/resize-dialog.h"
65
#include "dialogs/scale-dialog.h"
Michael Natterer's avatar
Michael Natterer committed
66

67
#include "actions.h"
Michael Natterer's avatar
Michael Natterer committed
68 69
#include "layers-commands.h"

70
#include "gimp-intl.h"
Michael Natterer's avatar
Michael Natterer committed
71 72


73
static const GimpLayerModeEffects layer_modes[] =
74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98
{
  GIMP_NORMAL_MODE,
  GIMP_DISSOLVE_MODE,
  GIMP_MULTIPLY_MODE,
  GIMP_DIVIDE_MODE,
  GIMP_SCREEN_MODE,
  GIMP_OVERLAY_MODE,
  GIMP_DODGE_MODE,
  GIMP_BURN_MODE,
  GIMP_HARDLIGHT_MODE,
  GIMP_SOFTLIGHT_MODE,
  GIMP_GRAIN_EXTRACT_MODE,
  GIMP_GRAIN_MERGE_MODE,
  GIMP_DIFFERENCE_MODE,
  GIMP_ADDITION_MODE,
  GIMP_SUBTRACT_MODE,
  GIMP_DARKEN_ONLY_MODE,
  GIMP_LIGHTEN_ONLY_MODE,
  GIMP_HUE_MODE,
  GIMP_SATURATION_MODE,
  GIMP_COLOR_MODE,
  GIMP_VALUE_MODE
};


99 100 101 102 103 104 105 106 107 108
typedef struct _ResizeLayerOptions ResizeLayerOptions;

struct _ResizeLayerOptions
{
  GimpLayer    *layer;
  GimpContext  *context;
  ResizeDialog *dialog;
};


109 110
/*  local function prototypes  */

111 112
static void   layers_new_layer_response    (GtkWidget             *widget,
                                            gint                   response_id,
113
                                            LayerOptionsDialog    *dialog);
114 115
static void   layers_edit_layer_response   (GtkWidget             *widget,
                                            gint                   response_id,
116
                                            LayerOptionsDialog    *dialog);
117 118
static void   layers_add_mask_response     (GtkWidget             *widget,
                                            gint                   response_id,
119
                                            LayerAddMaskDialog    *dialog);
120 121 122 123 124 125 126 127 128 129
static void   layers_scale_layer_callback  (GtkWidget             *dialog,
                                            GimpViewable          *viewable,
                                            gint                   width,
                                            gint                   height,
                                            GimpUnit               unit,
                                            GimpInterpolationType  interpolation,
                                            gpointer               data);
static void   layers_resize_layer_callback (GtkWidget             *widget,
                                            gpointer               data);
static gint   layers_mode_index            (GimpLayerModeEffects   layer_mode);
Michael Natterer's avatar
Michael Natterer committed
130 131


132 133
/*  private variables  */

134 135 136 137
static GimpFillType     layer_fill_type     = GIMP_TRANSPARENT_FILL;
static gchar           *layer_name          = NULL;
static GimpAddMaskType  layer_add_mask_type = GIMP_ADD_WHITE_MASK;
static gboolean         layer_mask_invert   = FALSE;
138 139


140 141
/*  public functions  */

142 143 144 145 146 147 148
void
layers_text_tool_cmd_callback (GtkAction *action,
                               gpointer   data)
{
  GimpImage *gimage;
  GimpLayer *layer;
  GtkWidget *widget;
149
  GimpTool  *active_tool;
150 151 152
  return_if_no_layer (gimage, layer, data);
  return_if_no_widget (widget, data);

153 154
  if (! gimp_drawable_is_text_layer (GIMP_DRAWABLE (layer)))
    {
155
      layers_edit_attributes_cmd_callback (action, data);
156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177
      return;
    }

  active_tool = tool_manager_get_active (gimage->gimp);

  if (! GIMP_IS_TEXT_TOOL (active_tool))
    {
      GimpToolInfo *tool_info;

      tool_info = (GimpToolInfo *)
        gimp_container_get_child_by_name (gimage->gimp->tool_info_list,
                                          "gimp-text-tool");

      if (GIMP_IS_TOOL_INFO (tool_info))
        {
          gimp_context_set_tool (action_data_get_context (data), tool_info);
          active_tool = tool_manager_get_active (gimage->gimp);
        }
    }

  if (GIMP_IS_TEXT_TOOL (active_tool))
    gimp_text_tool_set_layer (GIMP_TEXT_TOOL (active_tool), layer);
178 179 180 181 182 183
}

void
layers_edit_attributes_cmd_callback (GtkAction *action,
				     gpointer   data)
{
184
  LayerOptionsDialog *dialog;
185 186 187
  GimpImage          *gimage;
  GimpLayer          *layer;
  GtkWidget          *widget;
188 189 190
  return_if_no_layer (gimage, layer, data);
  return_if_no_widget (widget, data);

191 192 193 194
  dialog = layer_options_dialog_new (gimp_item_get_image (GIMP_ITEM (layer)),
                                     action_data_get_context (data),
                                     layer, widget,
                                     gimp_object_get_name (GIMP_OBJECT (layer)),
195
                                     layer_fill_type,
196 197 198 199 200 201 202
                                     _("Layer Attributes"),
                                     "gimp-layer-edit",
                                     GIMP_STOCK_EDIT,
                                     _("Edit Layer Attributes"),
                                     GIMP_HELP_LAYER_EDIT);

  g_signal_connect (dialog->dialog, "response",
203
                    G_CALLBACK (layers_edit_layer_response),
204
                    dialog);
205

206
  gtk_widget_show (dialog->dialog);
207 208 209 210 211 212
}

void
layers_new_cmd_callback (GtkAction *action,
			 gpointer   data)
{
213
  LayerOptionsDialog *dialog;
214 215 216
  GimpImage          *gimage;
  GtkWidget          *widget;
  GimpLayer          *floating_sel;
217 218 219
  return_if_no_image (gimage, data);
  return_if_no_widget (widget, data);

220 221 222 223 224 225 226 227 228 229
  /*  If there is a floating selection, the new command transforms
   *  the current fs into a new layer
   */
  if ((floating_sel = gimp_image_floating_sel (gimage)))
    {
      floating_sel_to_layer (floating_sel);
      gimp_image_flush (gimage);
      return;
    }

230 231 232
  dialog = layer_options_dialog_new (gimage, action_data_get_context (data),
                                     NULL, widget,
                                     layer_name ? layer_name : _("New Layer"),
233
                                     layer_fill_type,
234 235 236 237 238 239 240
                                     _("New Layer"),
                                     "gimp-layer-new",
                                     GIMP_STOCK_LAYER,
                                     _("Create a New Layer"),
                                     GIMP_HELP_LAYER_NEW);

  g_signal_connect (dialog->dialog, "response",
241
                    G_CALLBACK (layers_new_layer_response),
242
                    dialog);
243

244
  gtk_widget_show (dialog->dialog);
245 246 247
}

void
248 249
layers_new_last_vals_cmd_callback (GtkAction *action,
                                   gpointer   data)
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
{
  GimpImage            *gimage;
  GimpLayer            *floating_sel;
  GimpLayer            *new_layer;
  gint                  width, height;
  gint                  off_x, off_y;
  gdouble               opacity;
  GimpLayerModeEffects  mode;
  return_if_no_image (gimage, data);

  /*  If there is a floating selection, the new command transforms
   *  the current fs into a new layer
   */
  if ((floating_sel = gimp_image_floating_sel (gimage)))
    {
      floating_sel_to_layer (floating_sel);
      gimp_image_flush (gimage);
      return;
    }

  if (GIMP_IS_LAYER (GIMP_ACTION (action)->viewable))
    {
      GimpLayer *template = GIMP_LAYER (GIMP_ACTION (action)->viewable);

      gimp_item_offsets (GIMP_ITEM (template), &off_x, &off_y);
      width   = gimp_item_width  (GIMP_ITEM (template));
      height  = gimp_item_height (GIMP_ITEM (template));
      opacity = template->opacity;
      mode    = template->mode;
    }
  else
    {
      width   = gimp_image_get_width (gimage);
      height  = gimp_image_get_height (gimage);
      off_x   = 0;
      off_y   = 0;
      opacity = 1.0;
      mode    = GIMP_NORMAL_MODE;
    }

  gimp_image_undo_group_start (gimage, GIMP_UNDO_GROUP_EDIT_PASTE,
                               _("New Layer"));

  new_layer = gimp_layer_new (gimage, width, height,
                              gimp_image_base_type_with_alpha (gimage),
295 296
                              layer_name ? layer_name : _("New Layer"),
                              opacity, mode);
297 298 299

  gimp_drawable_fill_by_type (GIMP_DRAWABLE (new_layer),
                              action_data_get_context (data),
300
                              layer_fill_type);
301 302 303 304 305 306 307
  gimp_item_translate (GIMP_ITEM (new_layer), off_x, off_y, FALSE);

  gimp_image_add_layer (gimage, new_layer, -1);

  gimp_image_undo_group_end (gimage);

  gimp_image_flush (gimage);
308 309
}

Michael Natterer's avatar
Michael Natterer committed
310
void
311 312 313
layers_select_cmd_callback (GtkAction *action,
                            gint       value,
                            gpointer   data)
Michael Natterer's avatar
Michael Natterer committed
314 315
{
  GimpImage *gimage;
316
  GimpLayer *layer;
Michael Natterer's avatar
Michael Natterer committed
317
  GimpLayer *new_layer;
318
  return_if_no_image (gimage, data);
Michael Natterer's avatar
Michael Natterer committed
319

320
  layer = gimp_image_get_active_layer (gimage);
321

322 323 324
  new_layer = (GimpLayer *) action_select_object ((GimpActionSelectType) value,
                                                  gimage->layers,
                                                  (GimpObject *) layer);
325

326
  if (new_layer && new_layer != layer)
327 328 329 330 331 332
    {
      gimp_image_set_active_layer (gimage, new_layer);
      gimp_image_flush (gimage);
    }
}

Michael Natterer's avatar
Michael Natterer committed
333
void
334
layers_raise_cmd_callback (GtkAction *action,
Michael Natterer's avatar
Michael Natterer committed
335 336 337
			   gpointer   data)
{
  GimpImage *gimage;
338 339
  GimpLayer *layer;
  return_if_no_layer (gimage, layer, data);
Michael Natterer's avatar
Michael Natterer committed
340

341
  gimp_image_raise_layer (gimage, layer);
342
  gimp_image_flush (gimage);
Michael Natterer's avatar
Michael Natterer committed
343 344 345
}

void
346 347
layers_raise_to_top_cmd_callback (GtkAction *action,
				  gpointer   data)
Michael Natterer's avatar
Michael Natterer committed
348 349
{
  GimpImage *gimage;
350 351
  GimpLayer *layer;
  return_if_no_layer (gimage, layer, data);
Michael Natterer's avatar
Michael Natterer committed
352

353
  gimp_image_raise_layer_to_top (gimage, layer);
354
  gimp_image_flush (gimage);
Michael Natterer's avatar
Michael Natterer committed
355 356 357
}

void
358 359
layers_lower_cmd_callback (GtkAction *action,
			   gpointer   data)
Michael Natterer's avatar
Michael Natterer committed
360 361
{
  GimpImage *gimage;
362 363
  GimpLayer *layer;
  return_if_no_layer (gimage, layer, data);
Michael Natterer's avatar
Michael Natterer committed
364

365
  gimp_image_lower_layer (gimage, layer);
366
  gimp_image_flush (gimage);
Michael Natterer's avatar
Michael Natterer committed
367 368 369
}

void
370
layers_lower_to_bottom_cmd_callback (GtkAction *action,
Michael Natterer's avatar
Michael Natterer committed
371 372 373
				     gpointer   data)
{
  GimpImage *gimage;
374 375
  GimpLayer *layer;
  return_if_no_layer (gimage, layer, data);
Michael Natterer's avatar
Michael Natterer committed
376

377
  gimp_image_lower_layer_to_bottom (gimage, layer);
378
  gimp_image_flush (gimage);
Michael Natterer's avatar
Michael Natterer committed
379 380 381
}

void
382
layers_duplicate_cmd_callback (GtkAction *action,
Michael Natterer's avatar
Michael Natterer committed
383 384 385
			       gpointer   data)
{
  GimpImage *gimage;
386
  GimpLayer *layer;
Michael Natterer's avatar
Michael Natterer committed
387
  GimpLayer *new_layer;
388
  return_if_no_layer (gimage, layer, data);
Michael Natterer's avatar
Michael Natterer committed
389

390
  new_layer =
391 392
    GIMP_LAYER (gimp_item_duplicate (GIMP_ITEM (layer),
                                     G_TYPE_FROM_INSTANCE (layer),
393
                                     TRUE));
Michael Natterer's avatar
Michael Natterer committed
394 395
  gimp_image_add_layer (gimage, new_layer, -1);

396
  gimp_image_flush (gimage);
Michael Natterer's avatar
Michael Natterer committed
397 398 399
}

void
400
layers_anchor_cmd_callback (GtkAction *action,
Michael Natterer's avatar
Michael Natterer committed
401 402 403
			    gpointer   data)
{
  GimpImage *gimage;
404 405
  GimpLayer *layer;
  return_if_no_layer (gimage, layer, data);
Michael Natterer's avatar
Michael Natterer committed
406

407
  if (gimp_layer_is_floating_sel (layer))
408
    {
409
      floating_sel_anchor (layer);
410 411
      gimp_image_flush (gimage);
    }
412
}
Michael Natterer's avatar
Michael Natterer committed
413

414
void
415
layers_merge_down_cmd_callback (GtkAction *action,
416 417 418
				gpointer   data)
{
  GimpImage *gimage;
419 420
  GimpLayer *layer;
  return_if_no_layer (gimage, layer, data);
421

422
  gimp_image_merge_down (gimage, layer, action_data_get_context (data),
423
                         GIMP_EXPAND_AS_NECESSARY);
424
  gimp_image_flush (gimage);
425 426
}

427
void
428
layers_delete_cmd_callback (GtkAction *action,
429 430 431
			    gpointer   data)
{
  GimpImage *gimage;
432 433
  GimpLayer *layer;
  return_if_no_layer (gimage, layer, data);
Michael Natterer's avatar
Michael Natterer committed
434

435 436
  if (gimp_layer_is_floating_sel (layer))
    floating_sel_remove (layer);
Michael Natterer's avatar
Michael Natterer committed
437
  else
438
    gimp_image_remove_layer (gimage, layer);
439

440
  gimp_image_flush (gimage);
441 442
}

443
void
444
layers_text_discard_cmd_callback (GtkAction *action,
445 446 447
                                  gpointer   data)
{
  GimpImage *gimage;
448 449
  GimpLayer *layer;
  return_if_no_layer (gimage, layer, data);
450

451 452
  if (GIMP_IS_TEXT_LAYER (layer))
    gimp_text_layer_discard (GIMP_TEXT_LAYER (layer));
453 454
}

455
void
456
layers_resize_cmd_callback (GtkAction *action,
457
			    gpointer   data)
458
{
459 460 461 462 463
  ResizeLayerOptions *options;
  GimpImage          *gimage;
  GimpLayer          *layer;
  GtkWidget          *widget;
  GimpDisplay        *gdisp;
464
  return_if_no_layer (gimage, layer, data);
465
  return_if_no_widget (widget, data);
Michael Natterer's avatar
Michael Natterer committed
466

467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491
  gdisp = GIMP_IS_DISPLAY (data) ? data : NULL;

  options = g_new0 (ResizeLayerOptions, 1);

  options->context = action_data_get_context (data);
  options->layer   = layer;

  options->dialog =
    resize_dialog_new (GIMP_VIEWABLE (layer), widget,
                       RESIZE_DIALOG,
		       gimp_item_width  (GIMP_ITEM (layer)),
		       gimp_item_height (GIMP_ITEM (layer)),
		       gimage->xresolution,
		       gimage->yresolution,
		       (gdisp ?
                        GIMP_DISPLAY_SHELL (gdisp->shell)->unit :
                        GIMP_UNIT_PIXEL),
		       G_CALLBACK (layers_resize_layer_callback),
                       options);

  g_object_weak_ref (G_OBJECT (options->dialog->shell),
		     (GWeakNotify) g_free,
		     options);

  gtk_widget_show (options->dialog->shell);
Michael Natterer's avatar
Michael Natterer committed
492 493 494
}

void
495
layers_resize_to_image_cmd_callback (GtkAction *action,
496
				     gpointer   data)
Michael Natterer's avatar
Michael Natterer committed
497 498
{
  GimpImage *gimage;
499 500
  GimpLayer *layer;
  return_if_no_layer (gimage, layer, data);
501

502
  gimp_layer_resize_to_image (layer, action_data_get_context (data));
503
  gimp_image_flush (gimage);
504
}
Michael Natterer's avatar
Michael Natterer committed
505

506
void
507
layers_scale_cmd_callback (GtkAction *action,
508 509
			   gpointer   data)
{
510 511 512 513 514 515
  GimpImage   *gimage;
  GimpLayer   *layer;
  GtkWidget   *widget;
  GimpDisplay *gdisp;
  GtkWidget   *dialog;
  GimpUnit     unit;
516
  return_if_no_layer (gimage, layer, data);
517
  return_if_no_widget (widget, data);
518

519 520 521 522 523 524 525 526 527 528 529 530 531
  gdisp = action_data_get_display (data);

  unit = gdisp ? GIMP_DISPLAY_SHELL (gdisp->shell)->unit : GIMP_UNIT_PIXEL;

  dialog = scale_dialog_new (GIMP_VIEWABLE (layer),
                             _("Scale Layer"), "gimp-layer-scale",
                             widget,
                             gimp_standard_help_func, GIMP_HELP_LAYER_SCALE,
                             unit, gimage->gimp->config->interpolation_type,
                             layers_scale_layer_callback,
                             gdisp);

  gtk_widget_show (dialog);
Michael Natterer's avatar
Michael Natterer committed
532 533 534
}

void
535
layers_crop_cmd_callback (GtkAction *action,
536
                          gpointer   data)
Michael Natterer's avatar
Michael Natterer committed
537 538
{
  GimpImage *gimage;
539
  GimpLayer *layer;
540 541
  gint       x1, y1, x2, y2;
  gint       off_x, off_y;
542
  return_if_no_layer (gimage, layer, data);
543

544 545
  if (! gimp_channel_bounds (gimp_image_get_mask (gimage),
                             &x1, &y1, &x2, &y2))
546 547 548 549 550
    {
      g_message (_("Cannot crop because the current selection is empty."));
      return;
    }

551
  gimp_item_offsets (GIMP_ITEM (layer), &off_x, &off_y);
552 553 554 555

  off_x -= x1;
  off_y -= y1;

556
  gimp_image_undo_group_start (gimage, GIMP_UNDO_GROUP_ITEM_RESIZE,
557
                               _("Crop Layer"));
558

559
  gimp_item_resize (GIMP_ITEM (layer), action_data_get_context (data),
560
                    x2 - x1, y2 - y1, off_x, off_y);
561

562
  gimp_image_undo_group_end (gimage);
563

564
  gimp_image_flush (gimage);
Michael Natterer's avatar
Michael Natterer committed
565 566 567
}

void
568
layers_mask_add_cmd_callback (GtkAction *action,
569
                              gpointer   data)
Michael Natterer's avatar
Michael Natterer committed
570
{
571 572 573 574
  LayerAddMaskDialog *dialog;
  GimpImage          *gimage;
  GimpLayer          *layer;
  GtkWidget          *widget;
575
  return_if_no_layer (gimage, layer, data);
576
  return_if_no_widget (widget, data);
Michael Natterer's avatar
Michael Natterer committed
577

578
  dialog = layer_add_mask_dialog_new (layer, widget,
579
                                      layer_add_mask_type, layer_mask_invert);
580

581
  g_signal_connect (dialog->dialog, "response",
582
                    G_CALLBACK (layers_add_mask_response),
583
                    dialog);
584

585
  gtk_widget_show (dialog->dialog);
Michael Natterer's avatar
Michael Natterer committed
586 587 588
}

void
589
layers_mask_apply_cmd_callback (GtkAction *action,
590
                                gint       value,
591
                                gpointer   data)
Michael Natterer's avatar
Michael Natterer committed
592
{
593 594 595
  GimpImage         *gimage;
  GimpLayer         *layer;
  GimpMaskApplyMode  mode;
596
  return_if_no_layer (gimage, layer, data);
Michael Natterer's avatar
Michael Natterer committed
597

598
  mode = (GimpMaskApplyMode) value;
Michael Natterer's avatar
Michael Natterer committed
599

600
  if (gimp_layer_get_mask (layer))
Michael Natterer's avatar
Michael Natterer committed
601
    {
602
      gimp_layer_apply_mask (layer, mode, TRUE);
603
      gimp_image_flush (gimage);
Michael Natterer's avatar
Michael Natterer committed
604 605 606
    }
}

607 608 609 610
void
layers_mask_edit_cmd_callback (GtkAction *action,
                               gpointer   data)
{
Sven Neumann's avatar
Sven Neumann committed
611 612 613
  GimpImage     *gimage;
  GimpLayer     *layer;
  GimpLayerMask *mask;
614 615 616
  return_if_no_layer (gimage, layer, data);

  mask = gimp_layer_get_mask (layer);
617

618 619 620 621 622 623 624 625 626 627 628 629 630 631 632
  if (mask)
    {
      gboolean active;

      active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));

      gimp_layer_mask_set_edit (mask, active);
      gimp_image_flush (gimage);
    }
}

void
layers_mask_show_cmd_callback (GtkAction *action,
                               gpointer   data)
{
Sven Neumann's avatar
Sven Neumann committed
633 634 635
  GimpImage     *gimage;
  GimpLayer     *layer;
  GimpLayerMask *mask;
636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654
  return_if_no_layer (gimage, layer, data);

  mask = gimp_layer_get_mask (layer);

  if (mask)
    {
      gboolean active;

      active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));

      gimp_layer_mask_set_show (mask, active);
      gimp_image_flush (gimage);
    }
}

void
layers_mask_disable_cmd_callback (GtkAction *action,
                                  gpointer   data)
{
Sven Neumann's avatar
Sven Neumann committed
655 656 657
  GimpImage     *gimage;
  GimpLayer     *layer;
  GimpLayerMask *mask;
658 659 660 661 662 663 664 665 666 667 668 669 670 671 672
  return_if_no_layer (gimage, layer, data);

  mask = gimp_layer_get_mask (layer);

  if (mask)
    {
      gboolean active;

      active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));

      gimp_layer_mask_set_apply (mask, ! active);
      gimp_image_flush (gimage);
    }
}

673
void
674 675 676
layers_mask_to_selection_cmd_callback (GtkAction *action,
                                       gint       value,
                                       gpointer   data)
677 678 679
{
  GimpChannelOps  op;
  GimpImage      *gimage;
680
  GimpLayer      *layer;
681
  GimpLayerMask  *mask;
682
  return_if_no_layer (gimage, layer, data);
Michael Natterer's avatar
Michael Natterer committed
683

684
  op = (GimpChannelOps) value;
685

686
  mask = gimp_layer_get_mask (layer);
687 688

  if (mask)
689
    {
690 691 692 693
      gint off_x, off_y;

      gimp_item_offsets (GIMP_ITEM (mask), &off_x, &off_y);

694 695 696 697 698
      gimp_channel_select_channel (gimp_image_get_mask (gimage),
                                   _("Layer Mask to Selection"),
                                   GIMP_CHANNEL (mask),
                                   off_x, off_y,
                                   op, FALSE, 0.0, 0.0);
699
      gimp_image_flush (gimage);
700
    }
Michael Natterer's avatar
Michael Natterer committed
701 702
}

703
void
704
layers_alpha_add_cmd_callback (GtkAction *action,
705
                               gpointer   data)
Michael Natterer's avatar
Michael Natterer committed
706 707
{
  GimpImage *gimage;
708 709
  GimpLayer *layer;
  return_if_no_layer (gimage, layer, data);
Michael Natterer's avatar
Michael Natterer committed
710

711
  if (! gimp_drawable_has_alpha (GIMP_DRAWABLE (layer)))
712
    {
713
      gimp_layer_add_alpha (layer);
714
      gimp_image_flush (gimage);
715
    }
Michael Natterer's avatar
Michael Natterer committed
716 717
}

718
void
719 720 721
layers_alpha_to_selection_cmd_callback (GtkAction *action,
                                        gint       value,
                                        gpointer   data)
722
{
723 724
  GimpChannelOps  op;
  GimpImage      *gimage;
725 726
  GimpLayer      *layer;
  return_if_no_layer (gimage, layer, data);
727

728
  op = (GimpChannelOps) value;
729

730
  gimp_channel_select_alpha (gimp_image_get_mask (gimage),
731
                             GIMP_DRAWABLE (layer),
732 733
                             op, FALSE, 0.0, 0.0);
  gimp_image_flush (gimage);
734 735
}

736 737 738 739 740 741 742 743
void
layers_opacity_cmd_callback (GtkAction *action,
                             gint       value,
                             gpointer   data)
{
  GimpImage      *gimage;
  GimpLayer      *layer;
  gdouble         opacity;
744
  GimpUndo       *undo;
745 746 747
  gboolean        push_undo = TRUE;
  return_if_no_layer (gimage, layer, data);

748 749 750 751 752
  undo = gimp_image_undo_can_compress (gimage, GIMP_TYPE_ITEM_UNDO,
                                       GIMP_UNDO_LAYER_OPACITY);

  if (undo && GIMP_ITEM_UNDO (undo)->item == GIMP_ITEM (layer))
    push_undo = FALSE;
753 754

  opacity = action_select_value ((GimpActionSelectType) value,
755
                                 gimp_layer_get_opacity (layer),
756 757 758 759 760 761
                                 0.0, 1.0,
                                 0.01, 0.1, FALSE);
  gimp_layer_set_opacity (layer, opacity, push_undo);
  gimp_image_flush (gimage);
}

762
void
763 764 765
layers_mode_cmd_callback (GtkAction *action,
                          gint       value,
                          gpointer   data)
766 767 768
{
  GimpImage            *gimage;
  GimpLayer            *layer;
769
  GimpLayerModeEffects  layer_mode;
770 771 772 773 774 775
  gint                  index;
  GimpUndo             *undo;
  gboolean              push_undo = TRUE;
  return_if_no_layer (gimage, layer, data);

  undo = gimp_image_undo_can_compress (gimage, GIMP_TYPE_ITEM_UNDO,
776
                                       GIMP_UNDO_LAYER_MODE);
777 778 779 780

  if (undo && GIMP_ITEM_UNDO (undo)->item == GIMP_ITEM (layer))
    push_undo = FALSE;

781
  layer_mode = gimp_layer_get_mode (layer);
782 783

  index = action_select_value ((GimpActionSelectType) value,
784 785
                               layers_mode_index (layer_mode),
                               0, G_N_ELEMENTS (layer_modes) - 1,
786
                               1.0, 1.0, FALSE);
787
  gimp_layer_set_mode (layer, layer_modes[index], push_undo);
788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817
  gimp_image_flush (gimage);
}

void
layers_preserve_trans_cmd_callback (GtkAction *action,
                                    gpointer   data)
{
  GimpImage *gimage;
  GimpLayer *layer;
  gboolean   preserve;
  return_if_no_layer (gimage, layer, data);

  preserve = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));

  if (preserve != gimp_layer_get_preserve_trans (layer))
    {
      GimpUndo *undo;
      gboolean  push_undo = TRUE;

      undo = gimp_image_undo_can_compress (gimage, GIMP_TYPE_ITEM_UNDO,
                                           GIMP_UNDO_LAYER_PRESERVE_TRANS);

      if (undo && GIMP_ITEM_UNDO (undo)->item == GIMP_ITEM (layer))
        push_undo = FALSE;

      gimp_layer_set_preserve_trans (layer, preserve, push_undo);
      gimp_image_flush (gimage);
    }
}

Michael Natterer's avatar
Michael Natterer committed
818

819
/*  private functions  */
Michael Natterer's avatar
Michael Natterer committed
820 821

static void
822 823
layers_new_layer_response (GtkWidget          *widget,
                           gint                response_id,
824
                           LayerOptionsDialog *dialog)
Michael Natterer's avatar
Michael Natterer committed
825
{
826
  if (response_id == GTK_RESPONSE_OK)
Michael Natterer's avatar
Michael Natterer committed
827
    {
828
      GimpLayer *layer;
829

830 831 832
      if (layer_name)
        g_free (layer_name);
      layer_name =
833 834
        g_strdup (gtk_entry_get_text (GTK_ENTRY (dialog->name_entry)));

835
      layer_fill_type = dialog->fill_type;
836

837 838
      dialog->xsize =
        RINT (gimp_size_entry_get_refval (GIMP_SIZE_ENTRY (dialog->size_se),
839
                                          0));
840 841
      dialog->ysize =
        RINT (gimp_size_entry_get_refval (GIMP_SIZE_ENTRY (dialog->size_se),
842 843
                                          1));

844 845 846 847
      layer = gimp_layer_new (dialog->gimage,
                              dialog->xsize,
                              dialog->ysize,
                              gimp_image_base_type_with_alpha (dialog->gimage),
848 849 850 851
                              layer_name,
                              GIMP_OPACITY_OPAQUE, GIMP_NORMAL_MODE);

      if (layer)
Michael Natterer's avatar
Michael Natterer committed
852
        {
853
          gimp_drawable_fill_by_type (GIMP_DRAWABLE (layer),
854
                                      dialog->context,
855
                                      layer_fill_type);
856
          gimp_image_add_layer (dialog->gimage, layer, -1);
857

858
          gimp_image_flush (dialog->gimage);
859
        }
860
      else
861
        {
862 863
          g_message ("new_layer_query_response: "
                     "could not allocate new layer");
864
        }
Michael Natterer's avatar
Michael Natterer committed
865 866
    }

867
  gtk_widget_destroy (dialog->dialog);
Michael Natterer's avatar
Michael Natterer committed
868 869
}

870
static void
871 872
layers_edit_layer_response (GtkWidget          *widget,
                            gint                response_id,
873
                            LayerOptionsDialog *dialog)
874 875 876
{
  if (response_id == GTK_RESPONSE_OK)
    {
877
      GimpLayer   *layer = dialog->layer;
878
      const gchar *new_name;
879

880
      new_name = gtk_entry_get_text (GTK_ENTRY (dialog->name_entry));
Michael Natterer's avatar
Michael Natterer committed
881

882 883 884
      if (strcmp (new_name, gimp_object_get_name (GIMP_OBJECT (layer))))
        {
          gimp_item_rename (GIMP_ITEM (layer), new_name);
885
          gimp_image_flush (dialog->gimage);
886
        }
Michael Natterer's avatar
Michael Natterer committed
887

888
      if (dialog->rename_toggle &&