layers-commands.c 39.5 KB
Newer Older
1
/* GIMP - The GNU Image Manipulation Program
Michael Natterer's avatar
Michael Natterer committed
2 3
 * Copyright (C) 1995 Spencer Kimball and Peter Mattis
 *
4
 * This program is free software: you can redistribute it and/or modify
Michael Natterer's avatar
Michael Natterer 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
Michael Natterer's avatar
Michael Natterer 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 <http://www.gnu.org/licenses/>.
Michael Natterer's avatar
Michael Natterer committed
16 17 18 19
 */

#include "config.h"

20
#include <string.h>
Michael Natterer's avatar
Michael Natterer committed
21

22
#include <gegl.h>
Michael Natterer's avatar
Michael Natterer committed
23 24 25
#include <gtk/gtk.h>

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

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

32
#include "config/gimpdialogconfig.h"
33

Michael Natterer's avatar
Michael Natterer committed
34
#include "core/gimp.h"
35
#include "core/gimpchannel.h"
36
#include "core/gimpcontainer.h"
37
#include "core/gimpcontext.h"
38
#include "core/gimpdrawable-fill.h"
39
#include "core/gimpgrouplayer.h"
40
#include "core/gimpimage.h"
41
#include "core/gimpimage-merge.h"
42
#include "core/gimpimage-undo.h"
43
#include "core/gimpimage-undo-push.h"
44
#include "core/gimpitemundo.h"
45
#include "core/gimplayer-floating-selection.h"
46
#include "core/gimplayer-new.h"
47
#include "core/gimppickable.h"
48
#include "core/gimppickable-auto-shrink.h"
49
#include "core/gimptoolinfo.h"
50
#include "core/gimpundostack.h"
51
#include "core/gimpprogress.h"
52

53
#include "text/gimptext.h"
54
#include "text/gimptext-vectors.h"
55 56
#include "text/gimptextlayer.h"

57 58
#include "vectors/gimpvectors-warp.h"

59
#include "widgets/gimpaction.h"
60
#include "widgets/gimpdock.h"
61
#include "widgets/gimphelp-ids.h"
62
#include "widgets/gimpprogressdialog.h"
Michael Natterer's avatar
Michael Natterer committed
63

64
#include "display/gimpdisplay.h"
65
#include "display/gimpdisplayshell.h"
66
#include "display/gimpimagewindow.h"
67

68 69 70
#include "tools/gimptexttool.h"
#include "tools/tool_manager.h"

71
#include "dialogs/dialogs.h"
72
#include "dialogs/layer-add-mask-dialog.h"
73
#include "dialogs/layer-options-dialog.h"
74
#include "dialogs/resize-dialog.h"
75
#include "dialogs/scale-dialog.h"
Michael Natterer's avatar
Michael Natterer committed
76

77
#include "actions.h"
Michael Natterer's avatar
Michael Natterer committed
78 79
#include "layers-commands.h"

80
#include "gimp-intl.h"
Michael Natterer's avatar
Michael Natterer committed
81 82


83
static const GimpLayerModeEffects layer_modes[] =
84 85 86 87 88 89
{
  GIMP_NORMAL_MODE,
  GIMP_DISSOLVE_MODE,
  GIMP_MULTIPLY_MODE,
  GIMP_DIVIDE_MODE,
  GIMP_SCREEN_MODE,
90
  GIMP_NEW_OVERLAY_MODE,
91 92 93 94 95 96 97 98 99 100 101 102 103 104
  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,
105 106 107 108 109
  GIMP_VALUE_MODE,
  GIMP_LCH_HUE_MODE,
  GIMP_LCH_CHROMA_MODE,
  GIMP_LCH_COLOR_MODE,
  GIMP_LCH_LIGHTNESS_MODE
110 111 112
};


113 114
/*  local function prototypes  */

115 116
static void   layers_new_layer_response    (GtkWidget             *widget,
                                            gint                   response_id,
117
                                            LayerOptionsDialog    *dialog);
118 119
static void   layers_edit_layer_response   (GtkWidget             *widget,
                                            gint                   response_id,
120
                                            LayerOptionsDialog    *dialog);
121 122 123 124 125 126
static void   layers_add_mask_callback     (GtkWidget             *dialog,
                                            GimpLayer             *layer,
                                            GimpAddMaskType        add_mask_type,
                                            GimpChannel           *channel,
                                            gboolean               invert,
                                            gpointer               user_data);
127 128 129 130 131 132
static void   layers_scale_layer_callback  (GtkWidget             *dialog,
                                            GimpViewable          *viewable,
                                            gint                   width,
                                            gint                   height,
                                            GimpUnit               unit,
                                            GimpInterpolationType  interpolation,
133 134 135
                                            gdouble                xresolution,
                                            gdouble                yresolution,
                                            GimpUnit               resolution_unit,
136
                                            gpointer               user_data);
137 138
static void   layers_resize_layer_callback (GtkWidget             *dialog,
                                            GimpViewable          *viewable,
139
                                            GimpContext           *context,
140 141
                                            gint                   width,
                                            gint                   height,
142
                                            GimpUnit               unit,
143 144
                                            gint                   offset_x,
                                            gint                   offset_y,
145
                                            GimpItemSet            unused,
146
                                            gboolean               unused2,
147
                                            gpointer               data);
148

149
static gint   layers_mode_index            (GimpLayerModeEffects   layer_mode);
Michael Natterer's avatar
Michael Natterer committed
150 151


152 153
/*  private variables  */

154 155 156
static GimpUnit               layer_resize_unit   = GIMP_UNIT_PIXEL;
static GimpUnit               layer_scale_unit    = GIMP_UNIT_PIXEL;
static GimpInterpolationType  layer_scale_interp  = -1;
157 158


159 160
/*  public functions  */

161 162 163 164
void
layers_text_tool_cmd_callback (GtkAction *action,
                               gpointer   data)
{
165
  GimpImage *image;
166 167
  GimpLayer *layer;
  GtkWidget *widget;
168
  GimpTool  *active_tool;
169
  return_if_no_layer (image, layer, data);
170 171
  return_if_no_widget (widget, data);

172
  if (! gimp_item_is_text_layer (GIMP_ITEM (layer)))
173
    {
174
      layers_edit_attributes_cmd_callback (action, data);
175 176 177
      return;
    }

178
  active_tool = tool_manager_get_active (image->gimp);
179 180 181

  if (! GIMP_IS_TEXT_TOOL (active_tool))
    {
182 183
      GimpToolInfo *tool_info = gimp_get_tool_info (image->gimp,
                                                    "gimp-text-tool");
184 185 186 187

      if (GIMP_IS_TOOL_INFO (tool_info))
        {
          gimp_context_set_tool (action_data_get_context (data), tool_info);
188
          active_tool = tool_manager_get_active (image->gimp);
189 190 191 192 193
        }
    }

  if (GIMP_IS_TEXT_TOOL (active_tool))
    gimp_text_tool_set_layer (GIMP_TEXT_TOOL (active_tool), layer);
194 195 196 197
}

void
layers_edit_attributes_cmd_callback (GtkAction *action,
198
                                     gpointer   data)
199
{
200
  LayerOptionsDialog *dialog;
201
  GimpImage          *image;
202 203
  GimpLayer          *layer;
  GtkWidget          *widget;
204
  GimpDialogConfig   *config;
205
  return_if_no_layer (image, layer, data);
206 207
  return_if_no_widget (widget, data);

208 209
  config = GIMP_DIALOG_CONFIG (image->gimp->config);

210
  dialog = layer_options_dialog_new (gimp_item_get_image (GIMP_ITEM (layer)),
211
                                     layer,
212
                                     action_data_get_context (data),
213
                                     widget,
214 215
                                     _("Layer Attributes"),
                                     "gimp-layer-edit",
216
                                     "gtk-edit",
217
                                     _("Edit Layer Attributes"),
218 219 220
                                     GIMP_HELP_LAYER_EDIT,
                                     gimp_object_get_name (layer),
                                     config->layer_new_fill_type);
221 222

  g_signal_connect (dialog->dialog, "response",
223
                    G_CALLBACK (layers_edit_layer_response),
224
                    dialog);
225

226
  gtk_widget_show (dialog->dialog);
227 228 229 230
}

void
layers_new_cmd_callback (GtkAction *action,
231
                         gpointer   data)
232
{
233
  LayerOptionsDialog *dialog;
234
  GimpImage          *image;
235 236
  GtkWidget          *widget;
  GimpLayer          *floating_sel;
237
  GimpDialogConfig   *config;
238
  return_if_no_image (image, data);
239 240
  return_if_no_widget (widget, data);

241 242
  config = GIMP_DIALOG_CONFIG (image->gimp->config);

243 244 245
  /*  If there is a floating selection, the new command transforms
   *  the current fs into a new layer
   */
246
  if ((floating_sel = gimp_image_get_floating_selection (image)))
247
    {
248 249 250 251
      GError *error = NULL;

      if (! floating_sel_to_layer (floating_sel, &error))
        {
252
          gimp_message_literal (image->gimp,
253 254
                                G_OBJECT (widget), GIMP_MESSAGE_WARNING,
                                error->message);
255 256 257 258
          g_clear_error (&error);
          return;
        }

259
      gimp_image_flush (image);
260 261 262
      return;
    }

263 264 265
  dialog = layer_options_dialog_new (image, NULL,
                                     action_data_get_context (data),
                                     widget,
266 267 268 269
                                     _("New Layer"),
                                     "gimp-layer-new",
                                     GIMP_STOCK_LAYER,
                                     _("Create a New Layer"),
270 271 272
                                     GIMP_HELP_LAYER_NEW,
                                     config->layer_new_name,
                                     config->layer_new_fill_type);
273 274

  g_signal_connect (dialog->dialog, "response",
275
                    G_CALLBACK (layers_new_layer_response),
276
                    dialog);
277

278
  gtk_widget_show (dialog->dialog);
279 280 281
}

void
282 283
layers_new_last_vals_cmd_callback (GtkAction *action,
                                   gpointer   data)
284
{
285
  GimpImage            *image;
286
  GtkWidget            *widget;
287 288 289 290 291 292
  GimpLayer            *floating_sel;
  GimpLayer            *new_layer;
  gint                  width, height;
  gint                  off_x, off_y;
  gdouble               opacity;
  GimpLayerModeEffects  mode;
293
  GimpDialogConfig     *config;
294
  return_if_no_image (image, data);
295
  return_if_no_widget (widget, data);
296

297 298
  config = GIMP_DIALOG_CONFIG (image->gimp->config);

299 300 301
  /*  If there is a floating selection, the new command transforms
   *  the current fs into a new layer
   */
302
  if ((floating_sel = gimp_image_get_floating_selection (image)))
303
    {
304
      layers_new_cmd_callback (action, data);
305 306 307 308 309 310 311
      return;
    }

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

312
      gimp_item_get_offset (GIMP_ITEM (template), &off_x, &off_y);
313 314
      width   = gimp_item_get_width  (GIMP_ITEM (template));
      height  = gimp_item_get_height (GIMP_ITEM (template));
315 316
      opacity = gimp_layer_get_opacity (template);
      mode    = gimp_layer_get_mode (template);
317 318 319
    }
  else
    {
320 321
      width   = gimp_image_get_width (image);
      height  = gimp_image_get_height (image);
322 323 324 325 326 327
      off_x   = 0;
      off_y   = 0;
      opacity = 1.0;
      mode    = GIMP_NORMAL_MODE;
    }

328
  gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_EDIT_PASTE,
329 330
                               _("New Layer"));

331
  new_layer = gimp_layer_new (image, width, height,
332
                              gimp_image_get_layer_format (image, TRUE),
333
                              config->layer_new_name,
334
                              opacity, mode);
335

336 337
  gimp_drawable_fill (GIMP_DRAWABLE (new_layer),
                      action_data_get_context (data),
338
                      config->layer_new_fill_type);
339 340
  gimp_item_translate (GIMP_ITEM (new_layer), off_x, off_y, FALSE);

341 342
  gimp_image_add_layer (image, new_layer,
                        GIMP_IMAGE_ACTIVE_PARENT, -1, TRUE);
343

344
  gimp_image_undo_group_end (image);
345

346
  gimp_image_flush (image);
347 348
}

349 350 351 352
void
layers_new_from_visible_cmd_callback (GtkAction *action,
                                      gpointer   data)
{
353 354 355 356
  GimpImage        *image;
  GimpLayer        *layer;
  GimpPickable     *pickable;
  GimpColorProfile *profile;
357 358
  return_if_no_image (image, data);

359
  pickable = GIMP_PICKABLE (image);
360

361 362
  gimp_pickable_flush (pickable);

363 364
  profile = gimp_color_managed_get_color_profile (GIMP_COLOR_MANAGED (image));

365 366 367 368 369 370
  layer = gimp_layer_new_from_gegl_buffer (gimp_pickable_get_buffer (pickable),
                                           image,
                                           gimp_image_get_layer_format (image,
                                                                        TRUE),
                                           _("Visible"),
                                           GIMP_OPACITY_OPAQUE,
371
                                           GIMP_NORMAL_MODE,
372
                                           profile);
373 374 375

  gimp_image_add_layer (image, layer,
                        GIMP_IMAGE_ACTIVE_PARENT, -1, TRUE);
376 377 378 379

  gimp_image_flush (image);
}

380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395
void
layers_new_group_cmd_callback (GtkAction *action,
                               gpointer   data)
{
  GimpImage *image;
  GimpLayer *layer;
  return_if_no_image (image, data);

  layer = gimp_group_layer_new (image);

  gimp_image_add_layer (image, layer,
                        GIMP_IMAGE_ACTIVE_PARENT, -1, TRUE);

  gimp_image_flush (image);
}

Michael Natterer's avatar
Michael Natterer committed
396
void
397 398 399
layers_select_cmd_callback (GtkAction *action,
                            gint       value,
                            gpointer   data)
Michael Natterer's avatar
Michael Natterer committed
400
{
401 402 403 404
  GimpImage     *image;
  GimpLayer     *layer;
  GimpContainer *container;
  GimpLayer     *new_layer;
405
  return_if_no_image (image, data);
Michael Natterer's avatar
Michael Natterer committed
406

407
  layer = gimp_image_get_active_layer (image);
408

409 410 411 412 413
  if (layer)
    container = gimp_item_get_container (GIMP_ITEM (layer));
  else
    container = gimp_image_get_layers (image);

414
  new_layer = (GimpLayer *) action_select_object ((GimpActionSelectType) value,
415
                                                  container,
416
                                                  (GimpObject *) layer);
417

418
  if (new_layer && new_layer != layer)
419
    {
420 421
      gimp_image_set_active_layer (image, new_layer);
      gimp_image_flush (image);
422 423 424
    }
}

Michael Natterer's avatar
Michael Natterer committed
425
void
426
layers_raise_cmd_callback (GtkAction *action,
427
                           gpointer   data)
Michael Natterer's avatar
Michael Natterer committed
428
{
429
  GimpImage *image;
430
  GimpLayer *layer;
431
  return_if_no_layer (image, layer, data);
Michael Natterer's avatar
Michael Natterer committed
432

433
  gimp_image_raise_item (image, GIMP_ITEM (layer), NULL);
434
  gimp_image_flush (image);
Michael Natterer's avatar
Michael Natterer committed
435 436 437
}

void
438
layers_raise_to_top_cmd_callback (GtkAction *action,
439
                                  gpointer   data)
Michael Natterer's avatar
Michael Natterer committed
440
{
441
  GimpImage *image;
442
  GimpLayer *layer;
443
  return_if_no_layer (image, layer, data);
Michael Natterer's avatar
Michael Natterer committed
444

445
  gimp_image_raise_item_to_top (image, GIMP_ITEM (layer));
446
  gimp_image_flush (image);
Michael Natterer's avatar
Michael Natterer committed
447 448 449
}

void
450
layers_lower_cmd_callback (GtkAction *action,
451
                           gpointer   data)
Michael Natterer's avatar
Michael Natterer committed
452
{
453
  GimpImage *image;
454
  GimpLayer *layer;
455
  return_if_no_layer (image, layer, data);
Michael Natterer's avatar
Michael Natterer committed
456

457
  gimp_image_lower_item (image, GIMP_ITEM (layer), NULL);
458
  gimp_image_flush (image);
Michael Natterer's avatar
Michael Natterer committed
459 460 461
}

void
462
layers_lower_to_bottom_cmd_callback (GtkAction *action,
463
                                     gpointer   data)
Michael Natterer's avatar
Michael Natterer committed
464
{
465
  GimpImage *image;
466
  GimpLayer *layer;
467
  return_if_no_layer (image, layer, data);
Michael Natterer's avatar
Michael Natterer committed
468

469
  gimp_image_lower_item_to_bottom (image, GIMP_ITEM (layer));
470
  gimp_image_flush (image);
Michael Natterer's avatar
Michael Natterer committed
471 472 473
}

void
474
layers_duplicate_cmd_callback (GtkAction *action,
475
                               gpointer   data)
Michael Natterer's avatar
Michael Natterer committed
476
{
477
  GimpImage *image;
478
  GimpLayer *layer;
Michael Natterer's avatar
Michael Natterer committed
479
  GimpLayer *new_layer;
480
  return_if_no_layer (image, layer, data);
Michael Natterer's avatar
Michael Natterer committed
481

482 483
  new_layer = GIMP_LAYER (gimp_item_duplicate (GIMP_ITEM (layer),
                                               G_TYPE_FROM_INSTANCE (layer)));
484

485 486 487 488
  /*  use the actual parent here, not GIMP_IMAGE_ACTIVE_PARENT because
   *  the latter would add a duplicated group inside itself instead of
   *  above it
   */
489 490 491
  gimp_image_add_layer (image, new_layer,
                        gimp_layer_get_parent (layer), -1,
                        TRUE);
Michael Natterer's avatar
Michael Natterer committed
492

493
  gimp_image_flush (image);
Michael Natterer's avatar
Michael Natterer committed
494 495 496
}

void
497
layers_anchor_cmd_callback (GtkAction *action,
498
                            gpointer   data)
Michael Natterer's avatar
Michael Natterer committed
499
{
500
  GimpImage *image;
501
  GimpLayer *layer;
502
  return_if_no_layer (image, layer, data);
Michael Natterer's avatar
Michael Natterer committed
503

504
  if (gimp_layer_is_floating_sel (layer))
505
    {
506
      floating_sel_anchor (layer);
507
      gimp_image_flush (image);
508
    }
509
}
Michael Natterer's avatar
Michael Natterer committed
510

511
void
512
layers_merge_down_cmd_callback (GtkAction *action,
513
                                gpointer   data)
514
{
515
  GimpImage *image;
516
  GimpLayer *layer;
517
  return_if_no_layer (image, layer, data);
518

519
  gimp_image_merge_down (image, layer, action_data_get_context (data),
520
                         GIMP_EXPAND_AS_NECESSARY, NULL);
521
  gimp_image_flush (image);
522 523
}

524 525 526 527 528 529 530 531 532 533 534 535
void
layers_merge_group_cmd_callback (GtkAction *action,
                                 gpointer   data)
{
  GimpImage *image;
  GimpLayer *layer;
  return_if_no_layer (image, layer, data);

  gimp_image_merge_group_layer (image, GIMP_GROUP_LAYER (layer));
  gimp_image_flush (image);
}

536
void
537
layers_delete_cmd_callback (GtkAction *action,
538
                            gpointer   data)
539
{
540
  GimpImage *image;
541
  GimpLayer *layer;
542
  return_if_no_layer (image, layer, data);
Michael Natterer's avatar
Michael Natterer committed
543

544
  gimp_image_remove_layer (image, layer, TRUE, NULL);
545
  gimp_image_flush (image);
546 547
}

548
void
549
layers_text_discard_cmd_callback (GtkAction *action,
550 551
                                  gpointer   data)
{
552
  GimpImage *image;
553
  GimpLayer *layer;
554
  return_if_no_layer (image, layer, data);
555

556 557
  if (GIMP_IS_TEXT_LAYER (layer))
    gimp_text_layer_discard (GIMP_TEXT_LAYER (layer));
558 559
}

560 561 562 563 564 565 566 567 568 569 570 571 572 573 574
void
layers_text_to_vectors_cmd_callback (GtkAction *action,
                                     gpointer   data)
{
  GimpImage *image;
  GimpLayer *layer;
  return_if_no_layer (image, layer, data);

  if (GIMP_IS_TEXT_LAYER (layer))
    {
      GimpVectors *vectors;
      gint         x, y;

      vectors = gimp_text_vectors_new (image, GIMP_TEXT_LAYER (layer)->text);

575
      gimp_item_get_offset (GIMP_ITEM (layer), &x, &y);
576 577
      gimp_item_translate (GIMP_ITEM (vectors), x, y, FALSE);

578 579
      gimp_image_add_vectors (image, vectors,
                              GIMP_IMAGE_ACTIVE_PARENT, -1, TRUE);
580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601

      gimp_image_flush (image);
    }
}

void
layers_text_along_vectors_cmd_callback (GtkAction *action,
                                        gpointer   data)
{
  GimpImage   *image;
  GimpLayer   *layer;
  GimpVectors *vectors;
  return_if_no_layer (image, layer, data);
  return_if_no_vectors (image, vectors, data);

  if (GIMP_IS_TEXT_LAYER (layer))
    {
      GimpVectors *new_vectors;

      new_vectors = gimp_text_vectors_new (image, GIMP_TEXT_LAYER (layer)->text);

      gimp_vectors_warp_vectors (vectors, new_vectors,
602
                                 0.5 * gimp_item_get_height (GIMP_ITEM (layer)));
603 604 605

      gimp_item_set_visible (GIMP_ITEM (new_vectors), TRUE, FALSE);

606 607
      gimp_image_add_vectors (image, new_vectors,
                              GIMP_IMAGE_ACTIVE_PARENT, -1, TRUE);
608 609 610 611 612

      gimp_image_flush (image);
    }
}

613
void
614
layers_resize_cmd_callback (GtkAction *action,
615
                            gpointer   data)
616
{
617 618 619 620
  GimpImage *image;
  GimpLayer *layer;
  GtkWidget *widget;
  GtkWidget *dialog;
621
  return_if_no_layer (image, layer, data);
622
  return_if_no_widget (widget, data);
Michael Natterer's avatar
Michael Natterer committed
623

624
#define RESIZE_DIALOG_KEY "gimp-resize-dialog"
625

626
  dialog = dialogs_get_dialog (G_OBJECT (layer), RESIZE_DIALOG_KEY);
627

628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646
  if (! dialog)
    {
      GimpDisplay *display = NULL;

      if (GIMP_IS_IMAGE_WINDOW (data))
        display = action_data_get_display (data);

      if (layer_resize_unit != GIMP_UNIT_PERCENT && display)
        layer_resize_unit = gimp_display_get_shell (display)->unit;

      dialog = resize_dialog_new (GIMP_VIEWABLE (layer),
                                  action_data_get_context (data),
                                  _("Set Layer Boundary Size"),
                                  "gimp-layer-resize",
                                  widget,
                                  gimp_standard_help_func,
                                  GIMP_HELP_LAYER_RESIZE,
                                  layer_resize_unit,
                                  layers_resize_layer_callback,
647
                                  NULL);
648 649 650

      dialogs_attach_dialog (G_OBJECT (layer), RESIZE_DIALOG_KEY, dialog);
    }
651

652
  gtk_window_present (GTK_WINDOW (dialog));
Michael Natterer's avatar
Michael Natterer committed
653 654 655
}

void
656
layers_resize_to_image_cmd_callback (GtkAction *action,
657
                                     gpointer   data)
Michael Natterer's avatar
Michael Natterer committed
658
{
659
  GimpImage *image;
660
  GimpLayer *layer;
661
  return_if_no_layer (image, layer, data);
662

663
  gimp_layer_resize_to_image (layer, action_data_get_context (data));
664
  gimp_image_flush (image);
665
}
Michael Natterer's avatar
Michael Natterer committed
666

667
void
668
layers_scale_cmd_callback (GtkAction *action,
669
                           gpointer   data)
670
{
671 672 673 674
  GimpImage *image;
  GimpLayer *layer;
  GtkWidget *widget;
  GtkWidget *dialog;
675
  return_if_no_layer (image, layer, data);
676
  return_if_no_widget (widget, data);
677

678
#define SCALE_DIALOG_KEY "gimp-scale-dialog"
679

680
  dialog = dialogs_get_dialog (G_OBJECT (layer), SCALE_DIALOG_KEY);
681

682 683 684
  if (! dialog)
    {
      GimpDisplay *display = NULL;
685

686 687 688 689 690 691 692 693
      if (GIMP_IS_IMAGE_WINDOW (data))
        display = action_data_get_display (data);

      if (layer_scale_unit != GIMP_UNIT_PERCENT && display)
        layer_scale_unit = gimp_display_get_shell (display)->unit;

      if (layer_scale_interp == -1)
        layer_scale_interp = image->gimp->config->interpolation_type;
694

695 696 697 698 699 700 701 702 703 704 705 706 707 708
      dialog = scale_dialog_new (GIMP_VIEWABLE (layer),
                                 action_data_get_context (data),
                                 _("Scale Layer"), "gimp-layer-scale",
                                 widget,
                                 gimp_standard_help_func, GIMP_HELP_LAYER_SCALE,
                                 layer_scale_unit,
                                 layer_scale_interp,
                                 layers_scale_layer_callback,
                                 display);

      dialogs_attach_dialog (G_OBJECT (layer), SCALE_DIALOG_KEY, dialog);
    }

  gtk_window_present (GTK_WINDOW (dialog));
Michael Natterer's avatar
Michael Natterer committed
709 710 711
}

void
712 713
layers_crop_to_selection_cmd_callback (GtkAction *action,
                                       gpointer   data)
Michael Natterer's avatar
Michael Natterer committed
714
{
715
  GimpImage *image;
716
  GimpLayer *layer;
717
  GtkWidget *widget;
718 719
  gint       x, y;
  gint       width, height;
720
  gint       off_x, off_y;
721
  return_if_no_layer (image, layer, data);
722
  return_if_no_widget (widget, data);
723

724 725
  if (! gimp_item_bounds (GIMP_ITEM (gimp_image_get_mask (image)),
                          &x, &y, &width, &height))
726
    {
727
      gimp_message_literal (image->gimp,
728 729
                            G_OBJECT (widget), GIMP_MESSAGE_WARNING,
                            _("Cannot crop because the current selection is empty."));
730 731 732
      return;
    }

733
  gimp_item_get_offset (GIMP_ITEM (layer), &off_x, &off_y);
734 735
  off_x -= x;
  off_y -= y;
736

737
  gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_ITEM_RESIZE,
738
                               _("Crop Layer to Selection"));
739

740
  gimp_item_resize (GIMP_ITEM (layer), action_data_get_context (data),
741
                    width, height, off_x, off_y);
742

743
  gimp_image_undo_group_end (image);
744

745
  gimp_image_flush (image);
Michael Natterer's avatar
Michael Natterer committed
746 747
}

748 749 750 751 752 753 754 755 756 757 758
void
layers_crop_to_content_cmd_callback (GtkAction *action,
                                     gpointer   data)
{
  GimpImage *image;
  GimpLayer *layer;
  GtkWidget *widget;
  gint       x1, y1, x2, y2;
  return_if_no_layer (image, layer, data);
  return_if_no_widget (widget, data);

759 760 761 762 763
  switch (gimp_pickable_auto_shrink (GIMP_PICKABLE (layer),
                                     0, 0,
                                     gimp_item_get_width  (GIMP_ITEM (layer)),
                                     gimp_item_get_height (GIMP_ITEM (layer)),
                                     &x1, &y1, &x2, &y2))
764
    {
765 766 767
    case GIMP_AUTO_SHRINK_SHRINK:
      gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_ITEM_RESIZE,
                                   _("Crop Layer to Content"));
768

769 770
      gimp_item_resize (GIMP_ITEM (layer), action_data_get_context (data),
                        x2 - x1, y2 - y1, -x1, -y1);
771

772 773 774
      gimp_image_undo_group_end (image);
      gimp_image_flush (image);
      break;
775

776 777 778 779 780
    case GIMP_AUTO_SHRINK_EMPTY:
      gimp_message_literal (image->gimp,
                            G_OBJECT (widget), GIMP_MESSAGE_INFO,
                            _("Cannot crop because the active layer has no content."));
      break;
781

782 783 784 785 786 787
    case GIMP_AUTO_SHRINK_UNSHRINKABLE:
      gimp_message_literal (image->gimp,
                            G_OBJECT (widget), GIMP_MESSAGE_INFO,
                            _("Cannot crop because the active layer is already cropped to its content."));
      break;
    }
788 789
}

Michael Natterer's avatar
Michael Natterer committed
790
void
791
layers_mask_add_cmd_callback (GtkAction *action,
792
                              gpointer   data)
Michael Natterer's avatar
Michael Natterer committed
793
{
794 795 796 797
  GimpImage *image;
  GimpLayer *layer;
  GtkWidget *widget;
  GtkWidget *dialog;
798
  return_if_no_layer (image, layer, data);
799
  return_if_no_widget (widget, data);
Michael Natterer's avatar
Michael Natterer committed
800

801 802 803
  if (gimp_layer_get_mask (layer))
    return;

804
#define ADD_MASK_DIALOG_KEY "gimp-add-mask-dialog"
805

806
  dialog = dialogs_get_dialog (G_OBJECT (layer), ADD_MASK_DIALOG_KEY);
807

808 809 810
  if (! dialog)
    {
      GimpDialogConfig *config = GIMP_DIALOG_CONFIG (image->gimp->config);
811

812 813 814 815 816 817 818 819 820 821 822
      dialog = layer_add_mask_dialog_new (layer, action_data_get_context (data),
                                          widget,
                                          config->layer_add_mask_type,
                                          config->layer_add_mask_invert,
                                          layers_add_mask_callback,
                                          NULL);

      dialogs_attach_dialog (G_OBJECT (layer), ADD_MASK_DIALOG_KEY, dialog);
    }

  gtk_window_present (GTK_WINDOW (dialog));
Michael Natterer's avatar
Michael Natterer committed
823 824
}

825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872
void
layers_mask_add_last_vals_cmd_callback (GtkAction *action,
                                        gpointer   data)
{
  GimpImage        *image;
  GimpLayer        *layer;
  GtkWidget        *widget;
  GimpDialogConfig *config;
  GimpChannel      *channel = NULL;
  GimpLayerMask    *mask;
  return_if_no_layer (image, layer, data);
  return_if_no_widget (widget, data);

  if (gimp_layer_get_mask (layer))
    return;

  config = GIMP_DIALOG_CONFIG (image->gimp->config);

  if (config->layer_add_mask_type == GIMP_ADD_MASK_CHANNEL)
    {
      channel = gimp_image_get_active_channel (image);

      if (! channel)
        {
          GimpContainer *channels = gimp_image_get_channels (image);

          channel = GIMP_CHANNEL (gimp_container_get_first_child (channels));
        }

      if (! channel)
        {
          layers_mask_add_cmd_callback (action, data);
          return;
        }
    }

  mask = gimp_layer_create_mask (layer,
                                 config->layer_add_mask_type,
                                 channel);

  if (config->layer_add_mask_invert)
    gimp_channel_invert (GIMP_CHANNEL (mask), FALSE);

  gimp_layer_add_mask (layer, mask, TRUE, NULL);

  gimp_image_flush (image);
}

Michael Natterer's avatar
Michael Natterer committed
873
void
874
layers_mask_apply_cmd_callback (GtkAction *action,
875
                                gint       value,
876
                                gpointer   data)
Michael Natterer's avatar
Michael Natterer committed
877
{
878 879
  GimpImage *image;
  GimpLayer *layer;
880
  return_if_no_layer (image, layer, data);
Michael Natterer's avatar
Michael Natterer committed
881

882
  if (gimp_layer_get_mask (layer))
Michael Natterer's avatar
Michael Natterer committed
883
    {
884 885
      GimpMaskApplyMode mode = (GimpMaskApplyMode) value;

886
      gimp_layer_apply_mask (layer, mode, TRUE);
887
      gimp_image_flush (image);
Michael Natterer's avatar
Michael Natterer committed
888 889 890
    }
}

891 892 893 894
void
layers_mask_edit_cmd_callback (GtkAction *action,
                               gpointer   data)
{
895 896
  GimpImage *image;
  GimpLayer *layer;
897
  return_if_no_layer (image, layer, data);
898

899
  if (gimp_layer_get_mask (layer))
900 901 902 903 904
    {
      gboolean active;

      active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));

905
      gimp_layer_set_edit_mask (layer, active);
906
      gimp_image_flush (image);
907 908 909 910 911 912 913
    }
}

void
layers_mask_show_cmd_callback (GtkAction *action,
                               gpointer   data)
{
914 915
  GimpImage *image;
  GimpLayer *layer;
916
  return_if_no_layer (image, layer, data);
917

918
  if (gimp_layer_get_mask (layer))
919 920 921 922 923
    {
      gboolean active;

      active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));

924
      gimp_layer_set_show_mask (layer, active, TRUE);
925
      gimp_image_flush (image);
926 927 928 929 930 931 932
    }
}

void
layers_mask_disable_cmd_callback (GtkAction *action,
                                  gpointer   data)
{
933 934
  GimpImage *image;
  GimpLayer *layer;
935
  return_if_no_layer (image, layer, data);
936

937
  if (gimp_layer_get_mask (layer))
938 939 940 941 942
    {
      gboolean active;

      active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));

943
      gimp_layer_set_apply_mask (layer, ! active, TRUE);
944
      gimp_image_flush (image);
945 946 947
    }
}

948
void
949 950 951
layers_mask_to_selection_cmd_callback (GtkAction *action,
                                       gint       value,
                                       gpointer   data)
952
{
953 954 955
  GimpImage     *image;
  GimpLayer     *layer;
  GimpLayerMask *mask;
956
  return_if_no_layer (image, layer, data);
Michael Natterer's avatar
Michael Natterer committed
957

958
  mask = gimp_layer_get_mask (layer);
959 960

  if (mask)
961
    {
962 963 964
      gimp_item_to_selection (GIMP_ITEM (mask),
                              (GimpChannelOps) value,
                              TRUE, FALSE, 0.0, 0.0);
965
      gimp_image_flush (image);