layers-commands.c 29.6 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/gimpimage-undo-push.h"
40
#include "core/gimpitemundo.h"
41
#include "core/gimplayer.h"
Michael Natterer's avatar
Michael Natterer committed
42
#include "core/gimplayer-floating-sel.h"
43 44
#include "core/gimplayermask.h"
#include "core/gimplist.h"
45
#include "core/gimptoolinfo.h"
46
#include "core/gimpundostack.h"
47
#include "core/gimpprogress.h"
48

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

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

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

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

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

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

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


74
static const GimpLayerModeEffects layer_modes[] =
75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99
{
  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
};


100 101
/*  local function prototypes  */

102 103
static void   layers_new_layer_response    (GtkWidget             *widget,
                                            gint                   response_id,
104
                                            LayerOptionsDialog    *dialog);
105 106
static void   layers_edit_layer_response   (GtkWidget             *widget,
                                            gint                   response_id,
107
                                            LayerOptionsDialog    *dialog);
108 109
static void   layers_add_mask_response     (GtkWidget             *widget,
                                            gint                   response_id,
110
                                            LayerAddMaskDialog    *dialog);
111

112 113 114 115 116 117
static void   layers_scale_layer_callback  (GtkWidget             *dialog,
                                            GimpViewable          *viewable,
                                            gint                   width,
                                            gint                   height,
                                            GimpUnit               unit,
                                            GimpInterpolationType  interpolation,
118 119 120
                                            gdouble                xresolution,
                                            gdouble                yresolution,
                                            GimpUnit               resolution_unit,
121
                                            gpointer               data);
122 123 124 125 126 127
static void   layers_resize_layer_callback (GtkWidget             *dialog,
                                            GimpViewable          *viewable,
                                            gint                   width,
                                            gint                   height,
                                            gint                   offset_x,
                                            gint                   offset_y,
128
                                            GimpImageResizeLayers  unused,
129
                                            gpointer               data);
130

131
static gint   layers_mode_index            (GimpLayerModeEffects   layer_mode);
Michael Natterer's avatar
Michael Natterer committed
132 133


134 135
/*  private variables  */

136 137 138 139
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;
140 141


142 143
/*  public functions  */

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

155 156
  if (! gimp_drawable_is_text_layer (GIMP_DRAWABLE (layer)))
    {
157
      layers_edit_attributes_cmd_callback (action, data);
158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179
      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);
180 181 182 183 184 185
}

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

193 194 195 196
  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)),
197
                                     layer_fill_type,
198 199 200 201 202 203 204
                                     _("Layer Attributes"),
                                     "gimp-layer-edit",
                                     GIMP_STOCK_EDIT,
                                     _("Edit Layer Attributes"),
                                     GIMP_HELP_LAYER_EDIT);

  g_signal_connect (dialog->dialog, "response",
205
                    G_CALLBACK (layers_edit_layer_response),
206
                    dialog);
207

208
  gtk_widget_show (dialog->dialog);
209 210 211 212 213 214
}

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

222 223 224 225 226 227 228 229 230 231
  /*  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;
    }

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

  g_signal_connect (dialog->dialog, "response",
243
                    G_CALLBACK (layers_new_layer_response),
244
                    dialog);
245

246
  gtk_widget_show (dialog->dialog);
247 248 249
}

void
250 251
layers_new_last_vals_cmd_callback (GtkAction *action,
                                   gpointer   data)
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
{
  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),
297 298
                              layer_name ? layer_name : _("New Layer"),
                              opacity, mode);
299 300 301

  gimp_drawable_fill_by_type (GIMP_DRAWABLE (new_layer),
                              action_data_get_context (data),
302
                              layer_fill_type);
303 304 305 306 307 308 309
  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);
310 311
}

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

322
  layer = gimp_image_get_active_layer (gimage);
323

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

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

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

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

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

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

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

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

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

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

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

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

398
  gimp_image_flush (gimage);
Michael Natterer's avatar
Michael Natterer committed
399 400 401
}

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

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

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

424
  gimp_image_merge_down (gimage, layer, action_data_get_context (data),
425
                         GIMP_EXPAND_AS_NECESSARY);
426
  gimp_image_flush (gimage);
427 428
}

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

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

442
  gimp_image_flush (gimage);
443 444
}

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

453 454
  if (GIMP_IS_TEXT_LAYER (layer))
    gimp_text_layer_discard (GIMP_TEXT_LAYER (layer));
455 456
}

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

469 470
  gdisp = GIMP_IS_DISPLAY (data) ? data : NULL;

471 472 473 474 475 476 477 478 479 480 481
  dialog = resize_dialog_new (GIMP_VIEWABLE (layer),
                              _("Set Layer Boundary Size"), "gimp-layer-resize",
                              widget,
                              gimp_standard_help_func, GIMP_HELP_LAYER_RESIZE,
                              (gdisp ?
                               GIMP_DISPLAY_SHELL (gdisp->shell)->unit :
                               GIMP_UNIT_PIXEL),
                              layers_resize_layer_callback,
                              action_data_get_context (data));

  gtk_widget_show (dialog);
Michael Natterer's avatar
Michael Natterer committed
482 483 484
}

void
485
layers_resize_to_image_cmd_callback (GtkAction *action,
486
				     gpointer   data)
Michael Natterer's avatar
Michael Natterer committed
487 488
{
  GimpImage *gimage;
489 490
  GimpLayer *layer;
  return_if_no_layer (gimage, layer, data);
491

492
  gimp_layer_resize_to_image (layer, action_data_get_context (data));
493
  gimp_image_flush (gimage);
494
}
Michael Natterer's avatar
Michael Natterer committed
495

496
void
497
layers_scale_cmd_callback (GtkAction *action,
498 499
			   gpointer   data)
{
500 501 502 503 504 505
  GimpImage   *gimage;
  GimpLayer   *layer;
  GtkWidget   *widget;
  GimpDisplay *gdisp;
  GtkWidget   *dialog;
  GimpUnit     unit;
506
  return_if_no_layer (gimage, layer, data);
507
  return_if_no_widget (widget, data);
508

509 510 511 512 513 514 515 516 517 518 519 520 521
  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
522 523 524
}

void
525
layers_crop_cmd_callback (GtkAction *action,
526
                          gpointer   data)
Michael Natterer's avatar
Michael Natterer committed
527 528
{
  GimpImage *gimage;
529
  GimpLayer *layer;
530 531
  gint       x1, y1, x2, y2;
  gint       off_x, off_y;
532
  return_if_no_layer (gimage, layer, data);
533

534 535
  if (! gimp_channel_bounds (gimp_image_get_mask (gimage),
                             &x1, &y1, &x2, &y2))
536 537 538 539 540
    {
      g_message (_("Cannot crop because the current selection is empty."));
      return;
    }

541
  gimp_item_offsets (GIMP_ITEM (layer), &off_x, &off_y);
542 543 544 545

  off_x -= x1;
  off_y -= y1;

546
  gimp_image_undo_group_start (gimage, GIMP_UNDO_GROUP_ITEM_RESIZE,
547
                               _("Crop Layer"));
548

549
  gimp_item_resize (GIMP_ITEM (layer), action_data_get_context (data),
550
                    x2 - x1, y2 - y1, off_x, off_y);
551

552
  gimp_image_undo_group_end (gimage);
553

554
  gimp_image_flush (gimage);
Michael Natterer's avatar
Michael Natterer committed
555 556 557
}

void
558
layers_mask_add_cmd_callback (GtkAction *action,
559
                              gpointer   data)
Michael Natterer's avatar
Michael Natterer committed
560
{
561 562 563 564
  LayerAddMaskDialog *dialog;
  GimpImage          *gimage;
  GimpLayer          *layer;
  GtkWidget          *widget;
565
  return_if_no_layer (gimage, layer, data);
566
  return_if_no_widget (widget, data);
Michael Natterer's avatar
Michael Natterer committed
567

568
  dialog = layer_add_mask_dialog_new (layer, widget,
569
                                      layer_add_mask_type, layer_mask_invert);
570

571
  g_signal_connect (dialog->dialog, "response",
572
                    G_CALLBACK (layers_add_mask_response),
573
                    dialog);
574

575
  gtk_widget_show (dialog->dialog);
Michael Natterer's avatar
Michael Natterer committed
576 577 578
}

void
579
layers_mask_apply_cmd_callback (GtkAction *action,
580
                                gint       value,
581
                                gpointer   data)
Michael Natterer's avatar
Michael Natterer committed
582
{
583 584 585
  GimpImage         *gimage;
  GimpLayer         *layer;
  GimpMaskApplyMode  mode;
586
  return_if_no_layer (gimage, layer, data);
Michael Natterer's avatar
Michael Natterer committed
587

588
  mode = (GimpMaskApplyMode) value;
Michael Natterer's avatar
Michael Natterer committed
589

590
  if (gimp_layer_get_mask (layer))
Michael Natterer's avatar
Michael Natterer committed
591
    {
592
      gimp_layer_apply_mask (layer, mode, TRUE);
593
      gimp_image_flush (gimage);
Michael Natterer's avatar
Michael Natterer committed
594 595 596
    }
}

597 598 599 600
void
layers_mask_edit_cmd_callback (GtkAction *action,
                               gpointer   data)
{
Sven Neumann's avatar
Sven Neumann committed
601 602 603
  GimpImage     *gimage;
  GimpLayer     *layer;
  GimpLayerMask *mask;
604 605 606
  return_if_no_layer (gimage, layer, data);

  mask = gimp_layer_get_mask (layer);
607

608 609 610 611 612 613
  if (mask)
    {
      gboolean active;

      active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));

614
      gimp_layer_mask_set_edit (mask, active);
615 616 617 618 619 620 621 622
      gimp_image_flush (gimage);
    }
}

void
layers_mask_show_cmd_callback (GtkAction *action,
                               gpointer   data)
{
Sven Neumann's avatar
Sven Neumann committed
623 624 625
  GimpImage     *gimage;
  GimpLayer     *layer;
  GimpLayerMask *mask;
626 627 628 629 630 631 632 633 634 635
  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));

636
      gimp_layer_mask_set_show (mask, active, TRUE);
637 638 639 640 641 642 643 644
      gimp_image_flush (gimage);
    }
}

void
layers_mask_disable_cmd_callback (GtkAction *action,
                                  gpointer   data)
{
Sven Neumann's avatar
Sven Neumann committed
645 646 647
  GimpImage     *gimage;
  GimpLayer     *layer;
  GimpLayerMask *mask;
648 649 650 651 652 653 654 655 656 657
  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));

658 659
      gimp_layer_mask_set_apply (mask, ! active, TRUE);
      gimp_image_flush (gimage);
660 661 662
    }
}

663
void
664 665 666
layers_mask_to_selection_cmd_callback (GtkAction *action,
                                       gint       value,
                                       gpointer   data)
667 668 669
{
  GimpChannelOps  op;
  GimpImage      *gimage;
670
  GimpLayer      *layer;
671
  GimpLayerMask  *mask;
672
  return_if_no_layer (gimage, layer, data);
Michael Natterer's avatar
Michael Natterer committed
673

674
  op = (GimpChannelOps) value;
675

676
  mask = gimp_layer_get_mask (layer);
677 678

  if (mask)
679
    {
680 681 682 683
      gint off_x, off_y;

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

684 685 686 687 688
      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);
689
      gimp_image_flush (gimage);
690
    }
Michael Natterer's avatar
Michael Natterer committed
691 692
}

693
void
694
layers_alpha_add_cmd_callback (GtkAction *action,
695
                               gpointer   data)
Michael Natterer's avatar
Michael Natterer committed
696 697
{
  GimpImage *gimage;
698 699
  GimpLayer *layer;
  return_if_no_layer (gimage, layer, data);
Michael Natterer's avatar
Michael Natterer committed
700

701
  if (! gimp_drawable_has_alpha (GIMP_DRAWABLE (layer)))
702
    {
703
      gimp_layer_add_alpha (layer);
704
      gimp_image_flush (gimage);
705
    }
Michael Natterer's avatar
Michael Natterer committed
706 707
}

Michael Natterer's avatar
Michael Natterer committed
708 709 710 711 712 713 714 715 716 717 718 719 720 721 722
void
layers_alpha_remove_cmd_callback (GtkAction *action,
                                  gpointer   data)
{
  GimpImage *gimage;
  GimpLayer *layer;
  return_if_no_layer (gimage, layer, data);

  if (gimp_drawable_has_alpha (GIMP_DRAWABLE (layer)))
    {
      gimp_layer_flatten (layer, action_data_get_context (data));
      gimp_image_flush (gimage);
    }
}

723
void
724 725 726
layers_alpha_to_selection_cmd_callback (GtkAction *action,
                                        gint       value,
                                        gpointer   data)
727
{
728 729
  GimpChannelOps  op;
  GimpImage      *gimage;
730 731
  GimpLayer      *layer;
  return_if_no_layer (gimage, layer, data);
732

733
  op = (GimpChannelOps) value;
734

735
  gimp_channel_select_alpha (gimp_image_get_mask (gimage),
736
                             GIMP_DRAWABLE (layer),
737 738
                             op, FALSE, 0.0, 0.0);
  gimp_image_flush (gimage);
739 740
}

741 742 743 744 745 746 747 748
void
layers_opacity_cmd_callback (GtkAction *action,
                             gint       value,
                             gpointer   data)
{
  GimpImage      *gimage;
  GimpLayer      *layer;
  gdouble         opacity;
749
  GimpUndo       *undo;
750 751 752
  gboolean        push_undo = TRUE;
  return_if_no_layer (gimage, layer, data);

753 754 755 756 757
  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;
758 759

  opacity = action_select_value ((GimpActionSelectType) value,
760
                                 gimp_layer_get_opacity (layer),
761 762 763 764 765 766
                                 0.0, 1.0,
                                 0.01, 0.1, FALSE);
  gimp_layer_set_opacity (layer, opacity, push_undo);
  gimp_image_flush (gimage);
}

767
void
768 769 770
layers_mode_cmd_callback (GtkAction *action,
                          gint       value,
                          gpointer   data)
771 772 773
{
  GimpImage            *gimage;
  GimpLayer            *layer;
774
  GimpLayerModeEffects  layer_mode;
775 776 777 778 779 780
  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,
781
                                       GIMP_UNDO_LAYER_MODE);
782 783 784 785

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

786
  layer_mode = gimp_layer_get_mode (layer);
787 788

  index = action_select_value ((GimpActionSelectType) value,
789 790
                               layers_mode_index (layer_mode),
                               0, G_N_ELEMENTS (layer_modes) - 1,
791
                               1.0, 1.0, FALSE);
792
  gimp_layer_set_mode (layer, layer_modes[index], push_undo);
793 794 795 796
  gimp_image_flush (gimage);
}

void
797 798
layers_lock_alpha_cmd_callback (GtkAction *action,
                                gpointer   data)
799 800 801
{
  GimpImage *gimage;
  GimpLayer *layer;
802
  gboolean   lock_alpha;
803 804
  return_if_no_layer (gimage, layer, data);

805
  lock_alpha = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
806

807
  if (lock_alpha != gimp_layer_get_lock_alpha (layer))
808 809 810 811 812
    {
      GimpUndo *undo;
      gboolean  push_undo = TRUE;

      undo = gimp_image_undo_can_compress (gimage, GIMP_TYPE_ITEM_UNDO,
813
                                           GIMP_UNDO_LAYER_LOCK_ALPHA);
814 815 816 817

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

818
      gimp_layer_set_lock_alpha (layer, lock_alpha, push_undo);
819 820 821 822
      gimp_image_flush (gimage);
    }
}

Michael Natterer's avatar
Michael Natterer committed
823

824
/*  private functions  */
Michael Natterer's avatar
Michael Natterer committed
825 826

static void
827 828
layers_new_layer_response (GtkWidget          *widget,
                           gint                response_id,
829
                           LayerOptionsDialog *dialog)
Michael Natterer's avatar
Michael Natterer committed
830
{
831
  if (response_id == GTK_RESPONSE_OK)
Michael Natterer's avatar
Michael Natterer committed
832
    {
833
      GimpLayer *layer;
834

835 836 837
      if (layer_name)
        g_free (layer_name);
      layer_name =
838 839
        g_strdup (gtk_entry_get_text (GTK_ENTRY (dialog->name_entry)));

840
      layer_fill_type = dialog->fill_type;
841

842 843
      dialog->xsize =
        RINT (gimp_size_entry_get_refval (GIMP_SIZE_ENTRY (dialog->size_se),
844
                                          0));
845 846
      dialog->ysize =
        RINT (gimp_size_entry_get_refval (GIMP_SIZE_ENTRY (dialog->size_se),
847 848
                                          1));

849 850 851 852
      layer = gimp_layer_new (dialog->gimage,
                              dialog->xsize,
                              dialog->ysize,
                              gimp_image_base_type_with_alpha (dialog->gimage),
853 854 855 856
                              layer_name,
                              GIMP_OPACITY_OPAQUE, GIMP_NORMAL_MODE);

      if (layer)
Michael Natterer's avatar
Michael Natterer committed
857
        {
858
          gimp_drawable_fill_by_type (GIMP_DRAWABLE (layer),
859
                                      dialog->context,
860
                                      layer_fill_type);
861
          gimp_image_add_layer (dialog->gimage, layer, -1);
862

863
          gimp_image_flush (dialog->gimage);
864
        }
865
      else
866
        {
867 868
          g_message ("new_layer_query_response: "
                     "could not allocate new layer");
869
        }
Michael Natterer's avatar
Michael Natterer committed
870 871
    }

872
  gtk_widget_destroy (dialog->dialog);
Michael Natterer's avatar
Michael Natterer committed
873 874
}