select-commands.c 11 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 21 22 23 24 25
/* 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"

#include <gtk/gtk.h>

#include "libgimpmath/gimpmath.h"
#include "libgimpwidgets/gimpwidgets.h"

26
#include "gui-types.h"
Michael Natterer's avatar
Michael Natterer committed
27

28 29
#include "core/gimp.h"
#include "core/gimpcontext.h"
Michael Natterer's avatar
Michael Natterer committed
30 31
#include "core/gimpimage.h"
#include "core/gimpimage-mask.h"
32
#include "core/gimpimage-qmask.h"
Michael Natterer's avatar
Michael Natterer committed
33

34
#include "display/gimpdisplay.h"
35
#include "display/gimpdisplayshell.h"
Michael Natterer's avatar
Michael Natterer committed
36 37 38 39

#include "libgimp/gimpintl.h"


Michael Natterer's avatar
Michael Natterer committed
40
#define return_if_no_display(gdisp,data) \
41 42 43 44 45 46
  if (GIMP_IS_DISPLAY (data)) \
    gdisp = data; \
  else if (GIMP_IS_GIMP (data)) \
    gdisp = gimp_context_get_display (gimp_get_user_context (GIMP (data))); \
  else \
    gdisp = NULL; \
Michael Natterer's avatar
Michael Natterer committed
47 48 49 50
  if (! gdisp) \
    return

#define return_if_no_image(gimage,data) \
51 52 53 54 55 56
  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))); \
  else \
    gimage = NULL; \
Michael Natterer's avatar
Michael Natterer committed
57 58
  if (! gimage) \
    return
Michael Natterer's avatar
Michael Natterer committed
59 60 61 62


/*  local functions  */

63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78
static void   gimp_image_mask_feather_callback (GtkWidget   *widget,
                                                gdouble      size,
                                                GimpUnit     unit,
                                                gpointer     data);
static void   gimp_image_mask_border_callback  (GtkWidget   *widget,
                                                gdouble      size,
                                                GimpUnit     unit,
                                                gpointer     data);
static void   gimp_image_mask_grow_callback    (GtkWidget   *widget,
                                                gdouble      size,
                                                GimpUnit     unit,
                                                gpointer     data);
static void   gimp_image_mask_shrink_callback  (GtkWidget   *widget,
                                                gdouble      size,
                                                GimpUnit     unit,
                                                gpointer     data);
Michael Natterer's avatar
Michael Natterer committed
79 80 81 82 83 84 85 86 87 88 89 90 91 92 93


/*  local variables  */

static gdouble   selection_feather_radius    = 5.0;
static gint      selection_border_radius     = 5;
static gint      selection_grow_pixels       = 1;
static gint      selection_shrink_pixels     = 1;
static gboolean  selection_shrink_edge_lock  = FALSE;


void
select_invert_cmd_callback (GtkWidget *widget,
			    gpointer   data)
{
Michael Natterer's avatar
Michael Natterer committed
94 95
  GimpImage *gimage;
  return_if_no_image (gimage, data);
Michael Natterer's avatar
Michael Natterer committed
96

97
  gimp_image_mask_invert (gimage);
98
  gimp_image_flush (gimage);
Michael Natterer's avatar
Michael Natterer committed
99 100 101 102 103 104
}

void
select_all_cmd_callback (GtkWidget *widget,
			 gpointer   data)
{
Michael Natterer's avatar
Michael Natterer committed
105 106
  GimpImage *gimage;
  return_if_no_image (gimage, data);
Michael Natterer's avatar
Michael Natterer committed
107

108
  gimp_image_mask_all (gimage);
109
  gimp_image_flush (gimage);
Michael Natterer's avatar
Michael Natterer committed
110 111 112 113 114 115
}

void
select_none_cmd_callback (GtkWidget *widget,
			  gpointer   data)
{
Michael Natterer's avatar
Michael Natterer committed
116 117
  GimpImage *gimage;
  return_if_no_image (gimage, data);
Michael Natterer's avatar
Michael Natterer committed
118

119
  gimp_image_mask_clear (gimage, NULL);
120
  gimp_image_flush (gimage);
Michael Natterer's avatar
Michael Natterer committed
121 122 123 124 125 126
}

void
select_float_cmd_callback (GtkWidget *widget,
			   gpointer   data)
{
Michael Natterer's avatar
Michael Natterer committed
127 128
  GimpImage *gimage;
  return_if_no_image (gimage, data);
Michael Natterer's avatar
Michael Natterer committed
129

130
  gimp_image_mask_float (gimage, gimp_image_active_drawable (gimage), 0, 0);
131
  gimp_image_flush (gimage);
Michael Natterer's avatar
Michael Natterer committed
132 133 134 135 136 137
}

void
select_feather_cmd_callback (GtkWidget *widget,
			     gpointer   data)
{
138
  GimpDisplay *gdisp;
Michael Natterer's avatar
Michael Natterer committed
139 140
  GtkWidget   *qbox;
  return_if_no_display (gdisp, data);
Michael Natterer's avatar
Michael Natterer committed
141 142 143 144 145 146 147 148 149

  qbox = gimp_query_size_box (_("Feather Selection"),
			      gimp_standard_help_func,
			      "dialogs/feather_selection.html",
			      _("Feather Selection by:"),
			      selection_feather_radius, 0, 32767, 3,
			      gdisp->gimage->unit,
			      MIN (gdisp->gimage->xresolution,
				   gdisp->gimage->yresolution),
150
			      GIMP_DISPLAY_SHELL (gdisp->shell)->dot_for_dot,
151
			      G_OBJECT (gdisp->gimage), "disconnect",
152
			      gimp_image_mask_feather_callback, gdisp->gimage);
Michael Natterer's avatar
Michael Natterer committed
153 154 155 156 157 158 159
  gtk_widget_show (qbox);
}

void
select_sharpen_cmd_callback (GtkWidget *widget,
			     gpointer   data)
{
Michael Natterer's avatar
Michael Natterer committed
160 161
  GimpImage *gimage;
  return_if_no_image (gimage, data);
Michael Natterer's avatar
Michael Natterer committed
162

163
  gimp_image_mask_sharpen (gimage);
164
  gimp_image_flush (gimage);
Michael Natterer's avatar
Michael Natterer committed
165 166 167 168 169 170
}

void
select_shrink_cmd_callback (GtkWidget *widget,
			    gpointer   data)
{
Michael Natterer's avatar
Michael Natterer committed
171
  GimpDisplay *gdisp;
172
  GtkWidget   *shrink_dialog;
173
  GtkWidget   *edge_lock;
Michael Natterer's avatar
Michael Natterer committed
174
  return_if_no_display (gdisp, data);
Michael Natterer's avatar
Michael Natterer committed
175 176 177 178 179 180 181 182 183 184

  shrink_dialog =
    gimp_query_size_box (_("Shrink Selection"),
			 gimp_standard_help_func,
			 "dialogs/shrink_selection.html",
			 _("Shrink Selection by:"),
			 selection_shrink_pixels, 1, 32767, 0,
			 gdisp->gimage->unit,
			 MIN (gdisp->gimage->xresolution,
			      gdisp->gimage->yresolution),
185
			 GIMP_DISPLAY_SHELL (gdisp->shell)->dot_for_dot,
186
			 G_OBJECT (gdisp->gimage), "disconnect",
187
			 gimp_image_mask_shrink_callback, gdisp->gimage);
Michael Natterer's avatar
Michael Natterer committed
188 189

  edge_lock = gtk_check_button_new_with_label (_("Shrink from image border"));
190

191 192
  gtk_box_pack_start (GTK_BOX (GIMP_QUERY_BOX_VBOX (shrink_dialog)), edge_lock,
                      FALSE, FALSE, 0);
193 194

  g_object_set_data (G_OBJECT (shrink_dialog), "edge_lock_toggle", edge_lock);
Michael Natterer's avatar
Michael Natterer committed
195 196 197 198 199 200 201 202 203 204 205
  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (edge_lock),
				! selection_shrink_edge_lock);
  gtk_widget_show (edge_lock);

  gtk_widget_show (shrink_dialog);
}

void
select_grow_cmd_callback (GtkWidget *widget,
			  gpointer   data)
{
206
  GimpDisplay *gdisp;
Michael Natterer's avatar
Michael Natterer committed
207 208
  GtkWidget   *qbox;
  return_if_no_display (gdisp, data);
Michael Natterer's avatar
Michael Natterer committed
209 210 211 212 213 214 215 216 217

  qbox = gimp_query_size_box (_("Grow Selection"),
			      gimp_standard_help_func,
			      "dialogs/grow_selection.html",
			      _("Grow Selection by:"),
			      selection_grow_pixels, 1, 32767, 0,
			      gdisp->gimage->unit,
			      MIN (gdisp->gimage->xresolution,
				   gdisp->gimage->yresolution),
218
			      GIMP_DISPLAY_SHELL (gdisp->shell)->dot_for_dot,
219
			      G_OBJECT (gdisp->gimage), "disconnect",
220
			      gimp_image_mask_grow_callback, gdisp->gimage);
Michael Natterer's avatar
Michael Natterer committed
221 222 223 224 225 226 227
  gtk_widget_show (qbox);
}

void
select_border_cmd_callback (GtkWidget *widget,
			    gpointer   data)
{
228
  GimpDisplay *gdisp;
Michael Natterer's avatar
Michael Natterer committed
229 230
  GtkWidget   *qbox;
  return_if_no_display (gdisp, data);
Michael Natterer's avatar
Michael Natterer committed
231 232 233 234 235 236 237 238 239

  qbox = gimp_query_size_box (_("Border Selection"),
			      gimp_standard_help_func,
			      "dialogs/border_selection.html",
			      _("Border Selection by:"),
			      selection_border_radius, 1, 32767, 0,
			      gdisp->gimage->unit,
			      MIN (gdisp->gimage->xresolution,
				   gdisp->gimage->yresolution),
240
			      GIMP_DISPLAY_SHELL (gdisp->shell)->dot_for_dot,
241
			      G_OBJECT (gdisp->gimage), "disconnect",
242
			      gimp_image_mask_border_callback, gdisp->gimage);
Michael Natterer's avatar
Michael Natterer committed
243 244 245 246 247 248 249
  gtk_widget_show (qbox);
}

void
select_save_cmd_callback (GtkWidget *widget,
			  gpointer   data)
{
Michael Natterer's avatar
Michael Natterer committed
250 251
  GimpImage *gimage;
  return_if_no_image (gimage, data);
Michael Natterer's avatar
Michael Natterer committed
252

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

257 258 259 260 261 262 263 264 265 266 267
void
select_toggle_quickmask_cmd_callback (GtkWidget *widget,
                                      gpointer   data)
{
  GimpImage *gimage;
  return_if_no_image (gimage, data);

  gimp_image_set_qmask_state (gimage, !gimp_image_get_qmask_state (gimage));
  gimp_image_flush (gimage);
}

Michael Natterer's avatar
Michael Natterer committed
268 269 270 271

/*  private functions  */

static void
272 273 274 275
gimp_image_mask_feather_callback (GtkWidget *widget,
                                  gdouble    size,
                                  GimpUnit   unit,
                                  gpointer   data)
Michael Natterer's avatar
Michael Natterer committed
276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299
{
  GimpImage *gimage;
  gdouble    radius_x;
  gdouble    radius_y;

  gimage = GIMP_IMAGE (data);

  selection_feather_radius = size;

  radius_x = radius_y = selection_feather_radius;

  if (unit != GIMP_UNIT_PIXEL)
    {
      gdouble factor;

      factor = (MAX (gimage->xresolution, gimage->yresolution) /
		MIN (gimage->xresolution, gimage->yresolution));

      if (gimage->xresolution == MIN (gimage->xresolution, gimage->yresolution))
	radius_y *= factor;
      else
	radius_x *= factor;
    }

300
  gimp_image_mask_feather (gimage, radius_x, radius_y);
301
  gimp_image_flush (gimage);
Michael Natterer's avatar
Michael Natterer committed
302 303 304
}

static void
305 306 307 308
gimp_image_mask_border_callback (GtkWidget *widget,
                                 gdouble    size,
                                 GimpUnit   unit,
                                 gpointer   data)
Michael Natterer's avatar
Michael Natterer committed
309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332
{
  GimpImage *gimage;
  gdouble    radius_x;
  gdouble    radius_y;

  gimage = GIMP_IMAGE (data);

  selection_border_radius = ROUND (size);

  radius_x = radius_y = selection_border_radius;

  if (unit != GIMP_UNIT_PIXEL)
    {
      gdouble factor;

      factor = (MAX (gimage->xresolution, gimage->yresolution) /
		MIN (gimage->xresolution, gimage->yresolution));

      if (gimage->xresolution == MIN (gimage->xresolution, gimage->yresolution))
	radius_y *= factor;
      else
	radius_x *= factor;
    }

333
  gimp_image_mask_border (gimage, radius_x, radius_y);
334
  gimp_image_flush (gimage);
Michael Natterer's avatar
Michael Natterer committed
335 336 337
}

static void
338 339 340 341
gimp_image_mask_grow_callback (GtkWidget *widget,
                               gdouble    size,
                               GimpUnit   unit,
                               gpointer   data)
Michael Natterer's avatar
Michael Natterer committed
342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365
{
  GimpImage *gimage;
  gdouble    radius_x;
  gdouble    radius_y;

  gimage = GIMP_IMAGE (data);

  selection_grow_pixels = ROUND (size);

  radius_x = radius_y = selection_grow_pixels;

  if (unit != GIMP_UNIT_PIXEL)
    {
      gdouble factor;

      factor = (MAX (gimage->xresolution, gimage->yresolution) /
		MIN (gimage->xresolution, gimage->yresolution));

      if (gimage->xresolution == MIN (gimage->xresolution, gimage->yresolution))
	radius_y *= factor;
      else
	radius_x *= factor;
    }

366
  gimp_image_mask_grow (gimage, radius_x, radius_y);
367
  gimp_image_flush (gimage);
Michael Natterer's avatar
Michael Natterer committed
368 369 370
}

static void
371 372 373 374
gimp_image_mask_shrink_callback (GtkWidget *widget,
                                 gdouble    size,
                                 GimpUnit   unit,
                                 gpointer   data)
Michael Natterer's avatar
Michael Natterer committed
375 376 377 378 379 380 381 382 383 384 385 386
{
  GimpImage *gimage;
  gint       radius_x;
  gint       radius_y;

  gimage = GIMP_IMAGE (data);

  selection_shrink_pixels = ROUND (size);

  radius_x = radius_y = selection_shrink_pixels;

  selection_shrink_edge_lock =
387 388
    ! GTK_TOGGLE_BUTTON (g_object_get_data (G_OBJECT (widget),
					    "edge_lock_toggle"))->active;
Michael Natterer's avatar
Michael Natterer committed
389 390 391 392 393 394 395 396 397 398 399 400 401 402

  if (unit != GIMP_UNIT_PIXEL)
    {
      gdouble factor;

      factor = (MAX (gimage->xresolution, gimage->yresolution) /
		MIN (gimage->xresolution, gimage->yresolution));

      if (gimage->xresolution == MIN (gimage->xresolution, gimage->yresolution))
	radius_y *= factor;
      else
	radius_x *= factor;
    }

403 404
  gimp_image_mask_shrink (gimage, radius_x, radius_y,
                          selection_shrink_edge_lock);
405
  gimp_image_flush (gimage);
Michael Natterer's avatar
Michael Natterer committed
406
}