layers-commands.c 32.1 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"

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

Michael Natterer's avatar
Michael Natterer committed
31
#include "core/gimp.h"
32
#include "core/gimpcontext.h"
33 34
#include "core/gimpimage.h"
#include "core/gimpimage-mask.h"
35
#include "core/gimpimage-mask-select.h"
36
#include "core/gimpimage-merge.h"
37
#include "core/gimpimage-undo.h"
38
#include "core/gimplayer.h"
Michael Natterer's avatar
Michael Natterer committed
39
#include "core/gimplayer-floating-sel.h"
40 41 42
#include "core/gimplayermask.h"
#include "core/gimplist.h"

43 44
#include "pdb/procedural_db.h"

45
#include "widgets/gimpenummenu.h"
46
#include "widgets/gimphelp-ids.h"
47
#include "widgets/gimpitemtreeview.h"
48
#include "widgets/gimpviewabledialog.h"
Michael Natterer's avatar
Michael Natterer committed
49

50 51
#include "display/gimpdisplay.h"

Michael Natterer's avatar
Michael Natterer committed
52
#include "layers-commands.h"
53
#include "image-commands.h"
Michael Natterer's avatar
Michael Natterer committed
54
#include "resize-dialog.h"
Michael Natterer's avatar
Michael Natterer committed
55

56
#include "gimp-intl.h"
Michael Natterer's avatar
Michael Natterer committed
57 58


59 60
/*  local function prototypes  */

61 62 63 64 65
static void   layers_add_mask_query       (GimpLayer *layer);
static void   layers_scale_layer_query    (GimpImage *gimage,
					   GimpLayer *layer);
static void   layers_resize_layer_query   (GimpImage *gimage,
					   GimpLayer *layer);
Michael Natterer's avatar
Michael Natterer committed
66 67


68
#define return_if_no_image(gimage,data) \
69 70 71 72
  if (GIMP_IS_DISPLAY (data)) \
    gimage = ((GimpDisplay *) data)->gimage; \
  else if (GIMP_IS_GIMP (data)) \
    gimage = gimp_context_get_image (gimp_get_user_context (GIMP (data))); \
73 74
  else if (GIMP_IS_ITEM_TREE_VIEW (data)) \
    gimage = ((GimpItemTreeView *) data)->gimage; \
75 76
  else \
    gimage = NULL; \
77 78 79
  if (! gimage) \
    return

80 81
#define return_if_no_layer(gimage,layer,data) \
  return_if_no_image (gimage,data); \
82 83 84 85
  layer = gimp_image_get_active_layer (gimage); \
  if (! layer) \
    return

86

87 88
/*  public functions  */

Michael Natterer's avatar
Michael Natterer committed
89
void
90 91
layers_select_previous_cmd_callback (GtkWidget *widget,
                                     gpointer   data)
Michael Natterer's avatar
Michael Natterer committed
92 93 94 95
{
  GimpImage *gimage;
  GimpLayer *new_layer;
  gint       current_layer;
96
  return_if_no_image (gimage, data);
Michael Natterer's avatar
Michael Natterer committed
97 98 99 100 101 102 103 104 105 106 107 108

  current_layer =
    gimp_image_get_layer_index (gimage, gimp_image_get_active_layer (gimage));

  if (current_layer > 0)
    {
      new_layer = (GimpLayer *)
	gimp_container_get_child_by_index (gimage->layers, current_layer - 1);

      if (new_layer)
	{
	  gimp_image_set_active_layer (gimage, new_layer);
109
	  gimp_image_flush (gimage);
Michael Natterer's avatar
Michael Natterer committed
110 111 112 113 114
	}
    }
}

void
115 116
layers_select_next_cmd_callback (GtkWidget *widget,
                                 gpointer   data)
Michael Natterer's avatar
Michael Natterer committed
117 118 119 120
{
  GimpImage *gimage;
  GimpLayer *new_layer;
  gint       current_layer;
121
  return_if_no_image (gimage, data);
Michael Natterer's avatar
Michael Natterer committed
122 123 124 125

  current_layer =
    gimp_image_get_layer_index (gimage, gimp_image_get_active_layer (gimage));

126 127
  new_layer =
    GIMP_LAYER (gimp_container_get_child_by_index (gimage->layers,
Michael Natterer's avatar
Michael Natterer committed
128 129 130 131 132
						   current_layer + 1));

  if (new_layer)
    {
      gimp_image_set_active_layer (gimage, new_layer);
133
      gimp_image_flush (gimage);
Michael Natterer's avatar
Michael Natterer committed
134 135 136
    }
}

137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178
void
layers_select_top_cmd_callback (GtkWidget *widget,
                                gpointer   data)
{
  GimpImage *gimage;
  GimpLayer *new_layer;
  return_if_no_image (gimage, data);

  new_layer = (GimpLayer *)
    gimp_container_get_child_by_index (gimage->layers, 0);

  if (new_layer)
    {
      gimp_image_set_active_layer (gimage, new_layer);
      gimp_image_flush (gimage);
    }
}

void
layers_select_bottom_cmd_callback (GtkWidget *widget,
                                   gpointer   data)
{
  GimpImage *gimage;
  GimpLayer *new_layer;
  gint       num_layers;
  return_if_no_image (gimage, data);

  num_layers = gimp_container_num_children (gimage->layers);

  if (num_layers > 0)
    {
      new_layer = (GimpLayer *)
        gimp_container_get_child_by_index (gimage->layers, num_layers - 1);

      if (new_layer)
        {
          gimp_image_set_active_layer (gimage, new_layer);
          gimp_image_flush (gimage);
        }
    }
}

Michael Natterer's avatar
Michael Natterer committed
179 180 181 182 183
void
layers_raise_cmd_callback (GtkWidget *widget,
			   gpointer   data)
{
  GimpImage *gimage;
184
  GimpLayer *active_layer;
185
  return_if_no_layer (gimage, active_layer, data);
Michael Natterer's avatar
Michael Natterer committed
186

187
  gimp_image_raise_layer (gimage, active_layer);
188
  gimp_image_flush (gimage);
Michael Natterer's avatar
Michael Natterer committed
189 190 191 192 193 194 195
}

void
layers_lower_cmd_callback (GtkWidget *widget,
			   gpointer   data)
{
  GimpImage *gimage;
196
  GimpLayer *active_layer;
197
  return_if_no_layer (gimage, active_layer, data);
Michael Natterer's avatar
Michael Natterer committed
198

199
  gimp_image_lower_layer (gimage, active_layer);
200
  gimp_image_flush (gimage);
Michael Natterer's avatar
Michael Natterer committed
201 202 203 204 205 206 207
}

void
layers_raise_to_top_cmd_callback (GtkWidget *widget,
				  gpointer   data)
{
  GimpImage *gimage;
208
  GimpLayer *active_layer;
209
  return_if_no_layer (gimage, active_layer, data);
Michael Natterer's avatar
Michael Natterer committed
210

211
  gimp_image_raise_layer_to_top (gimage, active_layer);
212
  gimp_image_flush (gimage);
Michael Natterer's avatar
Michael Natterer committed
213 214 215 216 217 218 219
}

void
layers_lower_to_bottom_cmd_callback (GtkWidget *widget,
				     gpointer   data)
{
  GimpImage *gimage;
220
  GimpLayer *active_layer;
221
  return_if_no_layer (gimage, active_layer, data);
Michael Natterer's avatar
Michael Natterer committed
222

223
  gimp_image_lower_layer_to_bottom (gimage, active_layer);
224
  gimp_image_flush (gimage);
Michael Natterer's avatar
Michael Natterer committed
225 226 227 228 229 230 231
}

void
layers_new_cmd_callback (GtkWidget *widget,
			 gpointer   data)
{
  GimpImage *gimage;
232
  return_if_no_image (gimage, data);
Michael Natterer's avatar
Michael Natterer committed
233

Michael Natterer's avatar
Michael Natterer committed
234
  layers_new_layer_query (gimage, NULL, TRUE);
Michael Natterer's avatar
Michael Natterer committed
235 236 237 238 239 240 241 242 243
}

void
layers_duplicate_cmd_callback (GtkWidget *widget,
			       gpointer   data)
{
  GimpImage *gimage;
  GimpLayer *active_layer;
  GimpLayer *new_layer;
244
  return_if_no_layer (gimage, active_layer, data);
Michael Natterer's avatar
Michael Natterer committed
245

246 247 248 249
  new_layer =
    GIMP_LAYER (gimp_item_duplicate (GIMP_ITEM (active_layer),
                                     G_TYPE_FROM_INSTANCE (active_layer),
                                     TRUE));
Michael Natterer's avatar
Michael Natterer committed
250 251
  gimp_image_add_layer (gimage, new_layer, -1);

252
  gimp_image_flush (gimage);
Michael Natterer's avatar
Michael Natterer committed
253 254 255
}

void
256
layers_anchor_cmd_callback (GtkWidget *widget,
Michael Natterer's avatar
Michael Natterer committed
257 258 259
			    gpointer   data)
{
  GimpImage *gimage;
260
  GimpLayer *active_layer;
261
  return_if_no_layer (gimage, active_layer, data);
Michael Natterer's avatar
Michael Natterer committed
262

263 264 265 266 267
  if (gimp_layer_is_floating_sel (active_layer))
    {
      floating_sel_anchor (active_layer);
      gimp_image_flush (gimage);
    }
268
}
Michael Natterer's avatar
Michael Natterer committed
269

270 271 272 273 274
void
layers_merge_down_cmd_callback (GtkWidget *widget,
				gpointer   data)
{
  GimpImage *gimage;
275
  GimpLayer *active_layer;
276
  return_if_no_layer (gimage, active_layer, data);
277

278
  gimp_image_merge_down (gimage, active_layer, GIMP_EXPAND_AS_NECESSARY);
279
  gimp_image_flush (gimage);
280 281
}

282 283 284 285 286
void
layers_delete_cmd_callback (GtkWidget *widget,
			    gpointer   data)
{
  GimpImage *gimage;
287
  GimpLayer *active_layer;
288
  return_if_no_layer (gimage, active_layer, data);
Michael Natterer's avatar
Michael Natterer committed
289

290 291
  if (gimp_layer_is_floating_sel (active_layer))
    floating_sel_remove (active_layer);
Michael Natterer's avatar
Michael Natterer committed
292
  else
293
    gimp_image_remove_layer (gimage, active_layer);
294

295
  gimp_image_flush (gimage);
296 297 298
}

void
299 300
layers_resize_cmd_callback (GtkWidget *widget,
			    gpointer   data)
301 302
{
  GimpImage *gimage;
303
  GimpLayer *active_layer;
304
  return_if_no_layer (gimage, active_layer, data);
Michael Natterer's avatar
Michael Natterer committed
305

306
  layers_resize_layer_query (gimage, active_layer);
Michael Natterer's avatar
Michael Natterer committed
307 308 309
}

void
310 311
layers_resize_to_image_cmd_callback (GtkWidget *widget,
				     gpointer   data)
Michael Natterer's avatar
Michael Natterer committed
312 313
{
  GimpImage *gimage;
314
  GimpLayer *active_layer;
315
  return_if_no_layer (gimage, active_layer, data);
316

317
  gimp_layer_resize_to_image (active_layer);
318
  gimp_image_flush (gimage);
319
}
Michael Natterer's avatar
Michael Natterer committed
320

321 322 323 324 325 326
void
layers_scale_cmd_callback (GtkWidget *widget,
			   gpointer   data)
{
  GimpImage *gimage;
  GimpLayer *active_layer;
327
  return_if_no_layer (gimage, active_layer, data);
328 329

  layers_scale_layer_query (gimage, active_layer);
Michael Natterer's avatar
Michael Natterer committed
330 331 332
}

void
333 334
layers_crop_cmd_callback (GtkWidget *widget,
                          gpointer   data)
Michael Natterer's avatar
Michael Natterer committed
335 336
{
  GimpImage *gimage;
337
  GimpLayer *active_layer;
338 339
  gint       x1, y1, x2, y2;
  gint       off_x, off_y;
340
  return_if_no_layer (gimage, active_layer, data);
341 342 343 344 345 346 347

  if (! gimp_image_mask_bounds (gimage, &x1, &y1, &x2, &y2))
    {
      g_message (_("Cannot crop because the current selection is empty."));
      return;
    }

348
  gimp_item_offsets (GIMP_ITEM (active_layer), &off_x, &off_y);
349 350 351 352

  off_x -= x1;
  off_y -= y1;

353 354
  gimp_image_undo_group_start (gimage, GIMP_UNDO_GROUP_LAYER_RESIZE,
                               _("Crop Layer"));
355 356 357 358

  if (gimp_layer_is_floating_sel (active_layer))
    floating_sel_relax (active_layer, TRUE);

359
  gimp_item_resize (GIMP_ITEM (active_layer), x2 - x1, y2 - y1, off_x, off_y);
360 361 362 363

  if (gimp_layer_is_floating_sel (active_layer))
    floating_sel_rigor (active_layer, TRUE);

364
  gimp_image_undo_group_end (gimage);
365

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

void
370 371
layers_mask_add_cmd_callback (GtkWidget *widget,
                              gpointer   data)
Michael Natterer's avatar
Michael Natterer committed
372 373
{
  GimpImage *gimage;
374
  GimpLayer *active_layer;
375
  return_if_no_layer (gimage, active_layer, data);
Michael Natterer's avatar
Michael Natterer committed
376

377
  layers_add_mask_query (active_layer);
Michael Natterer's avatar
Michael Natterer committed
378 379 380
}

void
381 382
layers_mask_apply_cmd_callback (GtkWidget *widget,
                                gpointer   data)
Michael Natterer's avatar
Michael Natterer committed
383 384
{
  GimpImage *gimage;
385
  GimpLayer *active_layer;
386
  return_if_no_layer (gimage, active_layer, data);
Michael Natterer's avatar
Michael Natterer committed
387

388
  if (gimp_layer_get_mask (active_layer))
Michael Natterer's avatar
Michael Natterer committed
389
    {
390
      gimp_layer_apply_mask (active_layer, GIMP_MASK_APPLY, TRUE);
391
      gimp_image_flush (gimage);
Michael Natterer's avatar
Michael Natterer committed
392 393 394 395
    }
}

void
396 397
layers_mask_delete_cmd_callback (GtkWidget *widget,
                                 gpointer   data)
Michael Natterer's avatar
Michael Natterer committed
398 399
{
  GimpImage *gimage;
400
  GimpLayer *active_layer;
401
  return_if_no_layer (gimage, active_layer, data);
Michael Natterer's avatar
Michael Natterer committed
402

403
  if (gimp_layer_get_mask (active_layer))
Michael Natterer's avatar
Michael Natterer committed
404
    {
405
      gimp_layer_apply_mask (active_layer, GIMP_MASK_DISCARD, TRUE);
406
      gimp_image_flush (gimage);
Michael Natterer's avatar
Michael Natterer committed
407 408 409
    }
}

410 411 412 413 414 415 416 417 418
void
layers_mask_to_selection_cmd_callback (GtkWidget *widget,
                                       gpointer   data,
                                       guint      action)
{
  GimpChannelOps  op;
  GimpImage      *gimage;
  GimpLayer      *active_layer;
  GimpLayerMask  *mask;
419
  return_if_no_layer (gimage, active_layer, data);
Michael Natterer's avatar
Michael Natterer committed
420

421 422
  op = (GimpChannelOps) action;

423 424 425
  mask = gimp_layer_get_mask (active_layer);

  if (mask)
426
    {
427 428 429 430 431 432 433 434 435
      gint off_x, off_y;

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

      gimp_image_mask_select_channel (gimage,
                                      _("Layer Mask to Selection"),
                                      GIMP_CHANNEL (mask),
                                      off_x, off_y,
                                      op, FALSE, 0.0, 0.0);
436
      gimp_image_flush (gimage);
437
    }
Michael Natterer's avatar
Michael Natterer committed
438 439
}

440 441 442
void
layers_alpha_add_cmd_callback (GtkWidget *widget,
                               gpointer   data)
Michael Natterer's avatar
Michael Natterer committed
443 444
{
  GimpImage *gimage;
445
  GimpLayer *active_layer;
446
  return_if_no_layer (gimage, active_layer, data);
Michael Natterer's avatar
Michael Natterer committed
447

448 449 450
  if (! gimp_drawable_has_alpha (GIMP_DRAWABLE (active_layer)))
    {
      gimp_layer_add_alpha (active_layer);
451
      gimp_image_flush (gimage);
452
    }
Michael Natterer's avatar
Michael Natterer committed
453 454
}

455 456 457 458
void
layers_alpha_to_selection_cmd_callback (GtkWidget *widget,
                                        gpointer   data,
                                        guint      action)
459
{
460 461 462
  GimpChannelOps  op;
  GimpImage      *gimage;
  GimpLayer      *active_layer;
463 464
  return_if_no_layer (gimage, active_layer, data);

465 466
  op = (GimpChannelOps) action;

467 468 469 470 471 472 473 474
  if (gimp_drawable_has_alpha (GIMP_DRAWABLE (active_layer)))
    {
      gimp_image_mask_select_alpha (gimage, active_layer,
                                    op, FALSE, 0.0, 0.0);
      gimp_image_flush (gimage);
    }
}

475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495
void
layers_merge_layers_cmd_callback (GtkWidget *widget,
                                  gpointer   data)
{
  GimpImage *gimage;
  return_if_no_image (gimage, data);

  image_layers_merge_query (gimage, TRUE);
}

void
layers_flatten_image_cmd_callback (GtkWidget *widget,
                                   gpointer   data)
{
  GimpImage *gimage;
  return_if_no_image (gimage, data);

  gimp_image_flatten (gimage);
  gimp_image_flush (gimage);
}

Michael Natterer's avatar
Michael Natterer committed
496 497 498 499 500
void
layers_edit_attributes_cmd_callback (GtkWidget *widget,
				     gpointer   data)
{
  GimpImage *gimage;
501
  GimpLayer *active_layer;
502
  return_if_no_layer (gimage, active_layer, data);
Michael Natterer's avatar
Michael Natterer committed
503

504
  layers_edit_layer_query (active_layer);
Michael Natterer's avatar
Michael Natterer committed
505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526
}


/********************************/
/*  The new layer query dialog  */
/********************************/

typedef struct _NewLayerOptions NewLayerOptions;

struct _NewLayerOptions
{
  GtkWidget    *query_box;
  GtkWidget    *name_entry;
  GtkWidget    *size_se;

  GimpFillType  fill_type;
  gint          xsize;
  gint          ysize;

  GimpImage    *gimage;
};

527
static GimpFillType  fill_type  = GIMP_TRANSPARENT_FILL;
Michael Natterer's avatar
Michael Natterer committed
528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543
static gchar        *layer_name = NULL;

static void
new_layer_query_ok_callback (GtkWidget *widget,
			     gpointer   data)
{
  NewLayerOptions *options;
  GimpLayer       *layer;
  GimpImage       *gimage;

  options = (NewLayerOptions *) data;

  if (layer_name)
    g_free (layer_name);
  layer_name = g_strdup (gtk_entry_get_text (GTK_ENTRY (options->name_entry)));

544
  options->xsize =
Michael Natterer's avatar
Michael Natterer committed
545 546 547 548 549 550 551 552
    RINT (gimp_size_entry_get_refval (GIMP_SIZE_ENTRY (options->size_se), 0));
  options->ysize =
    RINT (gimp_size_entry_get_refval (GIMP_SIZE_ENTRY (options->size_se), 1));

  fill_type = options->fill_type;

  if ((gimage = options->gimage))
    {
553 554 555
      layer = gimp_layer_new (gimage,
                              options->xsize,
                              options->ysize,
Michael Natterer's avatar
Michael Natterer committed
556
			      gimp_image_base_type_with_alpha (gimage),
557 558
			      layer_name,
                              GIMP_OPACITY_OPAQUE, GIMP_NORMAL_MODE);
559
      if (layer)
Michael Natterer's avatar
Michael Natterer committed
560
	{
Michael Natterer's avatar
Michael Natterer committed
561 562 563
	  gimp_drawable_fill_by_type (GIMP_DRAWABLE (layer),
				      gimp_get_user_context (gimage->gimp),
				      fill_type);
Michael Natterer's avatar
Michael Natterer committed
564
	  gimp_image_add_layer (gimage, layer, -1);
565

566
          gimp_image_flush (gimage);
567 568
	}
      else
Michael Natterer's avatar
Michael Natterer committed
569 570 571 572 573 574 575 576 577 578
	{
	  g_message ("new_layer_query_ok_callback():\n"
		     "could not allocate new layer");
	}
    }

  gtk_widget_destroy (options->query_box);
}

void
579
layers_new_layer_query (GimpImage *gimage,
Michael Natterer's avatar
Michael Natterer committed
580 581
                        GimpLayer *template,
                        gboolean   interactive)
Michael Natterer's avatar
Michael Natterer committed
582 583
{
  NewLayerOptions *options;
584
  GimpLayer       *floating_sel;
Michael Natterer's avatar
Michael Natterer committed
585 586 587 588 589 590
  GtkWidget       *vbox;
  GtkWidget       *table;
  GtkWidget       *label;
  GtkObject       *adjustment;
  GtkWidget       *spinbutton;
  GtkWidget       *frame;
591
  GtkWidget       *button;
Michael Natterer's avatar
Michael Natterer committed
592

593
  g_return_if_fail (GIMP_IS_IMAGE (gimage));
594
  g_return_if_fail (template == NULL || GIMP_IS_LAYER (template));
595 596 597 598 599 600 601

  /*  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);
602
      gimp_image_flush (gimage);
603 604 605
      return;
    }

Michael Natterer's avatar
Michael Natterer committed
606
  if (template || ! interactive)
607
    {
Michael Natterer's avatar
Michael Natterer committed
608 609 610 611 612 613 614 615
      GimpLayer            *new_layer;
      gint                  width, height;
      gint                  off_x, off_y;
      gdouble               opacity;
      GimpLayerModeEffects  mode;

      if (template)
        {
616 617 618
          gimp_item_offsets (GIMP_ITEM (template), &off_x, &off_y);
          width   = gimp_item_width  (GIMP_ITEM (template));
          height  = gimp_item_height (GIMP_ITEM (template));
Michael Natterer's avatar
Michael Natterer committed
619 620 621 622 623 624 625 626 627 628 629 630
          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;
        }
631

632 633
      gimp_image_undo_group_start (gimage, GIMP_UNDO_GROUP_EDIT_PASTE,
                                   _("New Layer"));
634

635 636 637
      new_layer = gimp_layer_new (gimage,
                                  width,
                                  height,
638 639
                                  gimp_image_base_type_with_alpha (gimage),
                                  _("Empty Layer Copy"),
Michael Natterer's avatar
Michael Natterer committed
640 641 642 643 644 645 646 647
                                  opacity,
                                  mode);

      if (template)
        {
          gimp_drawable_fill_by_type (GIMP_DRAWABLE (new_layer),
                                      gimp_get_user_context (gimage->gimp),
                                      GIMP_TRANSPARENT_FILL);
648
          gimp_item_translate (GIMP_ITEM (new_layer), off_x, off_y, FALSE);
Michael Natterer's avatar
Michael Natterer committed
649
        }
650 651 652

      gimp_image_add_layer (gimage, new_layer, -1);

653
      gimp_image_undo_group_end (gimage);
654 655 656
      return;
    }

657 658
  options = g_new0 (NewLayerOptions, 1);

Michael Natterer's avatar
Michael Natterer committed
659 660 661 662 663
  options->fill_type = fill_type;
  options->gimage    = gimage;

  /*  The dialog  */
  options->query_box =
664 665
    gimp_viewable_dialog_new (GIMP_VIEWABLE (gimage),
                              _("New Layer"), "new_layer_options",
666
                              GIMP_STOCK_LAYER,
667
                              _("Create a New Layer"),
668
                              gimp_standard_help_func,
669
                              GIMP_HELP_LAYER_NEW,
Michael Natterer's avatar
Michael Natterer committed
670

671 672
                              GTK_STOCK_CANCEL, gtk_widget_destroy,
                              NULL, 1, NULL, FALSE, TRUE,
Michael Natterer's avatar
Michael Natterer committed
673

674 675
                              GTK_STOCK_OK, new_layer_query_ok_callback,
                              options, NULL, NULL, TRUE, FALSE,
676

677
                              NULL);
Michael Natterer's avatar
Michael Natterer committed
678

679 680 681
  g_object_weak_ref (G_OBJECT (options->query_box),
		     (GWeakNotify) g_free,
		     options);
Michael Natterer's avatar
Michael Natterer committed
682 683

  /*  The main vbox  */
684
  vbox = gtk_vbox_new (FALSE, 4);
Michael Natterer's avatar
Michael Natterer committed
685 686 687 688 689 690 691 692 693 694 695 696 697
  gtk_container_set_border_width (GTK_CONTAINER (vbox), 4);
  gtk_container_add (GTK_CONTAINER (GTK_DIALOG (options->query_box)->vbox),
		     vbox);

  table = gtk_table_new (3, 2, FALSE);
  gtk_table_set_col_spacing (GTK_TABLE (table), 0, 4);
  gtk_table_set_row_spacing (GTK_TABLE (table), 0, 4);
  gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, FALSE, 0);

  /*  The name label and entry  */
  options->name_entry = gtk_entry_new ();
  gtk_entry_set_text (GTK_ENTRY (options->name_entry),
		      (layer_name ? layer_name : _("New Layer")));
698 699 700
  gimp_table_attach_aligned (GTK_TABLE (table), 0, 0,
                             _("Layer _Name:"), 1.0, 0.5,
                             options->name_entry, 1, FALSE);
Michael Natterer's avatar
Michael Natterer committed
701 702 703 704 705 706 707 708 709 710 711 712 713 714 715

  /*  The size labels  */
  label = gtk_label_new (_("Layer Width:"));
  gtk_misc_set_alignment (GTK_MISC (label), 1.0, 0.5);
  gtk_table_attach (GTK_TABLE (table), label, 0, 1, 1, 2,
		    GTK_SHRINK | GTK_FILL, GTK_SHRINK, 0, 0);
  gtk_widget_show (label);

  label = gtk_label_new (_("Height:"));
  gtk_misc_set_alignment (GTK_MISC (label), 1.0, 0.5);
  gtk_table_attach (GTK_TABLE (table), label, 0, 1, 2, 3,
		    GTK_SHRINK | GTK_FILL, GTK_SHRINK, 0, 0);
  gtk_widget_show (label);

  /*  The size sizeentry  */
716 717 718 719 720
  spinbutton = gimp_spin_button_new (&adjustment,
                                     1, 1, 1, 1, 10, 1,
                                     1, 2);
  gtk_entry_set_width_chars (GTK_ENTRY (spinbutton), 10);

Michael Natterer's avatar
Michael Natterer committed
721
  options->size_se = gimp_size_entry_new (1, gimage->unit, "%a",
722
					  TRUE, TRUE, FALSE, 10,
Michael Natterer's avatar
Michael Natterer committed
723
					  GIMP_SIZE_ENTRY_UPDATE_SIZE);
724 725 726
  gtk_table_set_col_spacing (GTK_TABLE (options->size_se), 1, 4);
  gtk_table_set_row_spacing (GTK_TABLE (options->size_se), 0, 2);

Michael Natterer's avatar
Michael Natterer committed
727 728 729 730 731
  gimp_size_entry_add_field (GIMP_SIZE_ENTRY (options->size_se),
                             GTK_SPIN_BUTTON (spinbutton), NULL);
  gtk_table_attach_defaults (GTK_TABLE (options->size_se), spinbutton,
                             1, 2, 0, 1);
  gtk_widget_show (spinbutton);
732

Michael Natterer's avatar
Michael Natterer committed
733 734 735 736
  gtk_table_attach (GTK_TABLE (table), options->size_se, 1, 2, 1, 3,
                    GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
  gtk_widget_show (options->size_se);

737
  gimp_size_entry_set_unit (GIMP_SIZE_ENTRY (options->size_se),
Michael Natterer's avatar
Michael Natterer committed
738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764
			    GIMP_UNIT_PIXEL);

  gimp_size_entry_set_resolution (GIMP_SIZE_ENTRY (options->size_se), 0,
                                  gimage->xresolution, FALSE);
  gimp_size_entry_set_resolution (GIMP_SIZE_ENTRY (options->size_se), 1,
                                  gimage->yresolution, FALSE);

  gimp_size_entry_set_refval_boundaries (GIMP_SIZE_ENTRY (options->size_se), 0,
                                         GIMP_MIN_IMAGE_SIZE,
                                         GIMP_MAX_IMAGE_SIZE);
  gimp_size_entry_set_refval_boundaries (GIMP_SIZE_ENTRY (options->size_se), 1,
                                         GIMP_MIN_IMAGE_SIZE,
                                         GIMP_MAX_IMAGE_SIZE);

  gimp_size_entry_set_size (GIMP_SIZE_ENTRY (options->size_se), 0,
			    0, gimage->width);
  gimp_size_entry_set_size (GIMP_SIZE_ENTRY (options->size_se), 1,
			    0, gimage->height);

  gimp_size_entry_set_refval (GIMP_SIZE_ENTRY (options->size_se), 0,
			      gimage->width);
  gimp_size_entry_set_refval (GIMP_SIZE_ENTRY (options->size_se), 1,
			      gimage->height);

  gtk_widget_show (table);

  /*  The radio frame  */
765 766 767 768 769 770 771 772
  frame = gimp_enum_radio_frame_new_with_range (GIMP_TYPE_FILL_TYPE,
                                                GIMP_FOREGROUND_FILL,
                                                GIMP_TRANSPARENT_FILL,
                                                gtk_label_new (_("Layer Fill Type")),
                                                2,
                                                G_CALLBACK (gimp_radio_button_update),
                                                &options->fill_type,
                                                &button);
773
  gimp_radio_group_set_active (GTK_RADIO_BUTTON (button),
774
                               GINT_TO_POINTER (options->fill_type));
Michael Natterer's avatar
Michael Natterer committed
775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804

  gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0);
  gtk_widget_show (frame);

  gtk_widget_show (vbox);
  gtk_widget_show (options->query_box);
}

/**************************************/
/*  The edit layer attributes dialog  */
/**************************************/

typedef struct _EditLayerOptions EditLayerOptions;

struct _EditLayerOptions
{
  GtkWidget *query_box;
  GtkWidget *name_entry;
  GimpLayer *layer;
  GimpImage *gimage;
};

static void
edit_layer_query_ok_callback (GtkWidget *widget,
			      gpointer   data)
{
  EditLayerOptions *options;
  GimpLayer        *layer;

  options = (EditLayerOptions *) data;
805
  layer   = options->layer;
Michael Natterer's avatar
Michael Natterer committed
806

807
  if (options->gimage)
Michael Natterer's avatar
Michael Natterer committed
808
    {
809 810 811 812 813
      const gchar *new_name;

      new_name = gtk_entry_get_text (GTK_ENTRY (options->name_entry));

      if (strcmp (new_name, gimp_object_get_name (GIMP_OBJECT (layer))))
Michael Natterer's avatar
Michael Natterer committed
814
        {
815 816
          gimp_item_rename (GIMP_ITEM (layer), new_name);
          gimp_image_flush (options->gimage);
817
        }
Michael Natterer's avatar
Michael Natterer committed
818 819
    }

820
  gtk_widget_destroy (options->query_box);
Michael Natterer's avatar
Michael Natterer committed
821 822 823 824 825 826 827
}

void
layers_edit_layer_query (GimpLayer *layer)
{
  EditLayerOptions *options;
  GtkWidget        *vbox;
828
  GtkWidget        *table;
Michael Natterer's avatar
Michael Natterer committed
829

830 831
  options = g_new0 (EditLayerOptions, 1);

Michael Natterer's avatar
Michael Natterer committed
832
  options->layer  = layer;
833
  options->gimage = gimp_item_get_image (GIMP_ITEM (layer));
Michael Natterer's avatar
Michael Natterer committed
834 835 836

  /*  The dialog  */
  options->query_box =
837 838 839 840 841 842
    gimp_viewable_dialog_new (GIMP_VIEWABLE (layer),
                              _("Layer Attributes"),
                              "edit_layer_attributes",
                              GIMP_STOCK_EDIT,
                              _("Edit Layer Attributes"),
                              gimp_standard_help_func,
843
                              GIMP_HELP_LAYER_EDIT,
Michael Natterer's avatar
Michael Natterer committed
844

845 846
                              GTK_STOCK_CANCEL, gtk_widget_destroy,
                              NULL, 1, NULL, FALSE, TRUE,
Michael Natterer's avatar
Michael Natterer committed
847

848 849
                              GTK_STOCK_OK, edit_layer_query_ok_callback,
                              options, NULL, NULL, TRUE, FALSE,
850

851
                              NULL);
Michael Natterer's avatar
Michael Natterer committed
852

853 854 855
  g_object_weak_ref (G_OBJECT (options->query_box),
		     (GWeakNotify) g_free,
		     options);
Michael Natterer's avatar
Michael Natterer committed
856 857

  /*  The main vbox  */
858
  vbox = gtk_vbox_new (FALSE, 4);
Michael Natterer's avatar
Michael Natterer committed
859 860 861 862
  gtk_container_set_border_width (GTK_CONTAINER (vbox), 4);
  gtk_container_add (GTK_CONTAINER (GTK_DIALOG (options->query_box)->vbox),
		     vbox);

863 864 865 866 867
  /*  The name label and entry  */
  table = gtk_table_new (1, 2, FALSE);
  gtk_table_set_col_spacing (GTK_TABLE (table), 0, 4);
  gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, FALSE, 0);
  gtk_widget_show (table);
Michael Natterer's avatar
Michael Natterer committed
868 869 870 871 872 873

  options->name_entry = gtk_entry_new ();
  gtk_entry_set_text (GTK_ENTRY (options->name_entry),
		      ((gimp_layer_is_floating_sel (layer) ?
			_("Floating Selection") :
			gimp_object_get_name (GIMP_OBJECT (layer)))));
874 875 876
  gimp_table_attach_aligned (GTK_TABLE (table), 0, 0,
                             _("Layer _Name"), 1.0, 0.5,
                             options->name_entry, 1, FALSE);
Michael Natterer's avatar
Michael Natterer committed
877

878
  g_signal_connect (options->name_entry, "activate",
879 880 881
		    G_CALLBACK (edit_layer_query_ok_callback),
		    options);

Michael Natterer's avatar
Michael Natterer committed
882 883 884 885 886 887 888 889 890 891 892 893
  gtk_widget_show (vbox);
  gtk_widget_show (options->query_box);
}

/*******************************/
/*  The add mask query dialog  */
/*******************************/

typedef struct _AddMaskOptions AddMaskOptions;

struct _AddMaskOptions
{
894 895 896
  GtkWidget       *query_box;
  GimpLayer       *layer;
  GimpAddMaskType  add_mask_type;
897
  gboolean         invert;
Michael Natterer's avatar
Michael Natterer committed
898 899 900 901 902 903 904 905 906 907 908 909 910
};

static void
add_mask_query_ok_callback (GtkWidget *widget,
			    gpointer   data)
{
  AddMaskOptions *options;
  GimpImage      *gimage;
  GimpLayerMask  *mask;
  GimpLayer      *layer;

  options = (AddMaskOptions *) data;

911
  if ((layer = (options->layer)) && (gimage = GIMP_ITEM (layer)->gimage))
Michael Natterer's avatar
Michael Natterer committed
912 913
    {
      mask = gimp_layer_create_mask (layer, options->add_mask_type);
914 915 916 917

      if (options->invert)
        gimp_channel_invert (GIMP_CHANNEL (mask), FALSE);

Michael Natterer's avatar
Michael Natterer committed
918
      gimp_layer_add_mask (layer, mask, TRUE);
919
      g_object_unref (mask);
920

921
      gimp_image_flush (gimage);
Michael Natterer's avatar
Michael Natterer committed
922 923 924 925 926 927 928 929 930 931
    }

  gtk_widget_destroy (options->query_box);
}

static void
layers_add_mask_query (GimpLayer *layer)
{
  AddMaskOptions *options;
  GtkWidget      *frame;
932 933
  GtkWidget      *button;
  GtkWidget      *sep;
Michael Natterer's avatar
Michael Natterer committed
934
  GimpImage      *gimage;
935

Michael Natterer's avatar
Michael Natterer committed
936 937 938
  /*  The new options structure  */
  options = g_new (AddMaskOptions, 1);
  options->layer         = layer;
939
  options->add_mask_type = GIMP_ADD_WHITE_MASK;
940
  options->invert        = FALSE;
Michael Natterer's avatar
Michael Natterer committed
941

942
  gimage = gimp_item_get_image (GIMP_ITEM (layer));
943

Michael Natterer's avatar
Michael Natterer committed
944 945
  /*  The dialog  */
  options->query_box =
946
    gimp_viewable_dialog_new (GIMP_VIEWABLE (layer),
947
                              _("Add Layer Mask"), "add_mask_options",
948
                              GTK_STOCK_ADD,
949
                              _("Add a Mask to the Layer"),
950
                              gimp_standard_help_func,
951
                              GIMP_HELP_LAYER_MASK_ADD,
Michael Natterer's avatar
Michael Natterer committed
952

953 954
                              GTK_STOCK_CANCEL, gtk_widget_destroy,
                              NULL, 1, NULL, FALSE, TRUE,
Michael Natterer's avatar
Michael Natterer committed
955

956 957
                              GTK_STOCK_OK, add_mask_query_ok_callback,
                              options, NULL, NULL, TRUE, FALSE,
958

959
                              NULL);
Michael Natterer's avatar
Michael Natterer committed
960

961
  g_object_weak_ref (G_OBJECT (options->query_box),
962 963 964 965 966 967 968 969 970
		     (GWeakNotify) g_free, options);

  frame = gimp_enum_radio_frame_new (GIMP_TYPE_ADD_MASK_TYPE,
                                     gtk_label_new (_("Initialize Layer Mask to:")),
                                     6,
                                     G_CALLBACK (gimp_radio_button_update),
                                     &options->add_mask_type,
                                     &button);
  gimp_radio_group_set_active (GTK_RADIO_BUTTON (button),
971
                               GINT_TO_POINTER (options->add_mask_type));
972

Michael Natterer's avatar
Michael Natterer committed
973 974 975 976
  gtk_container_add (GTK_CONTAINER (GTK_DIALOG (options->query_box)->vbox),
		     frame);
  gtk_widget_show (frame);

977 978 979 980 981 982 983 984 985 986 987 988 989
  sep = gtk_hseparator_new ();
  gtk_box_pack_start (GTK_BOX (GTK_BIN (frame)->child), sep, FALSE, FALSE, 0);
  gtk_widget_show (sep);

  button = gtk_check_button_new_with_mnemonic (_("In_vert Mask"));
  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), options->invert);
  g_signal_connect (button, "toggled",
                    G_CALLBACK (gimp_toggle_button_update),
                    &options->invert);

  gtk_box_pack_end (GTK_BOX (GTK_BIN (frame)->child), button, FALSE, FALSE, 0);
  gtk_widget_show (button);

Michael Natterer's avatar
Michael Natterer committed
990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017
  gtk_widget_show (options->query_box);
}


/****************************/
/*  The scale layer dialog  */
/****************************/

typedef struct _ScaleLayerOptions ScaleLayerOptions;

struct _ScaleLayerOptions
{
  GimpLayer *layer;
  Resize    *resize;
};

static void
scale_layer_query_ok_callback (GtkWidget *widget,
			       gpointer   data)
{
  ScaleLayerOptions *options;
  GimpLayer         *layer;

  options = (ScaleLayerOptions *) data;

  if (options->resize->width > 0 && options->resize->height > 0 &&
      (layer =  (options->layer)))
    {
1018 1019
      GimpImage *gimage;

Michael Natterer's avatar
Michael Natterer committed
1020 1021
      gtk_widget_set_sensitive (options->resize->resize_shell, FALSE);

1022 1023 1024
      gimage = gimp_item_get_image (GIMP_ITEM (layer));

      if (gimage)
Michael Natterer's avatar
Michael Natterer committed
1025 1026
	{
	  if (gimp_layer_is_floating_sel (layer))
1027 1028 1029 1030 1031 1032
            {
              gimp_image_undo_group_start (gimage, GIMP_UNDO_GROUP_LAYER_SCALE,
                                           _("Scale Layer"));

              floating_sel_relax (layer, TRUE);
            }
Michael Natterer's avatar
Michael Natterer committed
1033

1034 1035 1036 1037 1038
	  gimp_item_scale_by_origin (GIMP_ITEM (layer),
                                     options->resize->width,
                                     options->resize->height,
                                     options->resize->interpolation,
                                     TRUE);
Michael Natterer's avatar
Michael Natterer committed
1039 1040

	  if (gimp_layer_is_floating_sel (layer))
1041 1042
            {
              floating_sel_rigor (layer, TRUE);
Michael Natterer's avatar
Michael Natterer committed
1043

1044 1045
              gimp_image_undo_group_end (gimage);
            }
Michael Natterer's avatar
Michael Natterer committed
1046

1047
          gimp_image_flush (gimage);
Michael Natterer's avatar
Michael Natterer committed
1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060
	}

      gtk_widget_destroy (options->resize->resize_shell);
    }
  else
    {
      g_message (_("Invalid width or height.\n"
		   "Both must be positive."));
    }
}

static void
layers_scale_layer_query (GimpImage *gimage,
Michael Natterer's avatar
Michael Natterer committed
1061
                          GimpLayer *layer)
Michael Natterer's avatar
Michael Natterer committed
1062 1063 1064
{
  ScaleLayerOptions *options;

1065 1066 1067 1068
  options = g_new0 (ScaleLayerOptions, 1);

  options->layer = layer;

Michael Natterer's avatar
Michael Natterer committed
1069
  options->resize =
1070
    resize_widget_new (GIMP_VIEWABLE (layer),
Michael Natterer's avatar
Michael Natterer committed
1071
                       ScaleWidget,
1072 1073
		       gimp_item_width  (GIMP_ITEM (layer)),
		       gimp_item_height (GIMP_ITEM (layer)),
Michael Natterer's avatar
Michael Natterer committed
1074 1075 1076 1077
		       gimage->xresolution,
		       gimage->yresolution,
		       gimage->unit,
		       TRUE,
1078
		       G_CALLBACK (scale_layer_query_ok_callback),
1079
                       options);