Ejemplo n.º 1
0
static GimpChannel *
gimp_fuzzy_select_tool_get_mask (GimpRegionSelectTool *region_select,
                                 GimpDisplay          *display)
{
  GimpTool                *tool        = GIMP_TOOL (region_select);
  GimpSelectionOptions    *sel_options = GIMP_SELECTION_TOOL_GET_OPTIONS (tool);
  GimpRegionSelectOptions *options     = GIMP_REGION_SELECT_TOOL_GET_OPTIONS (tool);
  GimpDrawable            *drawable;
  gint                     x, y;

  drawable = gimp_image_get_active_drawable (display->image);

  x = region_select->x;
  y = region_select->y;

  if (! options->sample_merged)
    {
      gint off_x, off_y;

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

      x -= off_x;
      y -= off_y;
    }

  return gimp_image_contiguous_region_by_seed (display->image, drawable,
                                               options->sample_merged,
                                               sel_options->antialias,
                                               options->threshold,
                                               options->select_transparent,
                                               options->select_criterion,
                                               x, y);
}
Ejemplo n.º 2
0
static void
gimp_region_select_tool_button_press (GimpTool        *tool,
                                      GimpCoords      *coords,
                                      guint32          time,
                                      GdkModifierType  state,
                                      GimpDisplay     *display)
{
  GimpRegionSelectTool *region_sel = GIMP_REGION_SELECT_TOOL (tool);
  GimpSelectionOptions *options    = GIMP_SELECTION_TOOL_GET_OPTIONS (tool);

  region_sel->x               = coords->x;
  region_sel->y               = coords->y;
  region_sel->saved_threshold = options->threshold;

  gimp_tool_control_activate (tool->control);
  tool->display = display;

  if (gimp_selection_tool_start_edit (GIMP_SELECTION_TOOL (region_sel), coords))
    return;

  gimp_tool_push_status (tool, display,
                         _("Move the mouse to change threshold"));

  /*  calculate the region boundary  */
  region_sel->segs = gimp_region_select_tool_calculate (region_sel, display,
                                                        &region_sel->num_segs);

  gimp_draw_tool_start (GIMP_DRAW_TOOL (tool), display);
}
Ejemplo n.º 3
0
static GdkSegment *
gimp_region_select_tool_calculate (GimpRegionSelectTool *region_sel,
                                   GimpDisplay          *display,
                                   gint                 *num_segs)
{
  GimpTool             *tool    = GIMP_TOOL (region_sel);
  GimpSelectionOptions *options = GIMP_SELECTION_TOOL_GET_OPTIONS (tool);
  GimpDisplayShell     *shell   = GIMP_DISPLAY_SHELL (display->shell);
  GimpDrawable         *drawable;
  GdkSegment           *segs;
  BoundSeg             *bsegs;
  PixelRegion           maskPR;

  drawable = gimp_image_get_active_drawable (display->image);

  gimp_display_shell_set_override_cursor (shell, GDK_WATCH);

  if (region_sel->region_mask)
    g_object_unref (region_sel->region_mask);

  region_sel->region_mask =
    GIMP_REGION_SELECT_TOOL_GET_CLASS (region_sel)->get_mask (region_sel,
                                                              display);

  if (! region_sel->region_mask)
    {
      gimp_display_shell_unset_override_cursor (shell);

      *num_segs = 0;
      return NULL;
    }

  /*  calculate and allocate a new segment array which represents the
   *  boundary of the contiguous region
   */
  pixel_region_init (&maskPR,
                     gimp_drawable_get_tiles (GIMP_DRAWABLE (region_sel->region_mask)),
                     0, 0,
                     gimp_item_width  (GIMP_ITEM (region_sel->region_mask)),
                     gimp_item_height (GIMP_ITEM (region_sel->region_mask)),
                     FALSE);

  bsegs = boundary_find (&maskPR, BOUNDARY_WITHIN_BOUNDS,
                         0, 0,
                         gimp_item_width  (GIMP_ITEM (region_sel->region_mask)),
                         gimp_item_height (GIMP_ITEM (region_sel->region_mask)),
                         BOUNDARY_HALF_WAY,
                         num_segs);

  segs = g_new (GdkSegment, *num_segs);

  gimp_display_shell_transform_segments (shell, bsegs, segs, *num_segs,
                                         ! options->sample_merged);
  g_free (bsegs);

  gimp_display_shell_unset_override_cursor (shell);

  return segs;
}
Ejemplo n.º 4
0
static GimpChannelOps
gimp_rectangle_select_tool_get_operation (GimpRectangleSelectTool *rect_sel_tool)
{
  GimpRectangleSelectToolPrivate *priv;
  GimpSelectionOptions           *options;

  priv    = GIMP_RECTANGLE_SELECT_TOOL_GET_PRIVATE (rect_sel_tool);
  options = GIMP_SELECTION_TOOL_GET_OPTIONS (rect_sel_tool);

  if (priv->use_saved_op)
    return priv->operation;
  else
    return options->operation;
}
Ejemplo n.º 5
0
static void
gimp_rectangle_select_tool_real_select (GimpRectangleSelectTool *rect_sel_tool,
                                        GimpChannelOps           operation,
                                        gint                     x,
                                        gint                     y,
                                        gint                     w,
                                        gint                     h)
{
  GimpTool                   *tool    = GIMP_TOOL (rect_sel_tool);
  GimpSelectionOptions       *options = GIMP_SELECTION_TOOL_GET_OPTIONS (tool);
  GimpRectangleSelectOptions *rect_select_options;
  GimpChannel                *channel;

  rect_select_options = GIMP_RECTANGLE_SELECT_TOOL_GET_OPTIONS (tool);

  channel = gimp_image_get_mask (gimp_display_get_image (tool->display));

  if (rect_select_options->round_corners)
    {
      /* To prevent elliptification of the rectangle,
       * we must cap the corner radius.
       */
      gdouble max    = MIN (w / 2.0, h / 2.0);
      gdouble radius = MIN (rect_select_options->corner_radius, max);

      gimp_channel_select_round_rect (channel,
                                      x, y, w, h,
                                      radius, radius,
                                      operation,
                                      options->antialias,
                                      options->feather,
                                      options->feather_radius,
                                      options->feather_radius,
                                      TRUE);
    }
  else
    {
      gimp_channel_select_rectangle (channel,
                                     x, y, w, h,
                                     operation,
                                     options->feather,
                                     options->feather_radius,
                                     options->feather_radius,
                                     TRUE);
    }
}
Ejemplo n.º 6
0
static void
gimp_region_select_tool_cursor_update (GimpTool        *tool,
                                       GimpCoords      *coords,
                                       GdkModifierType  state,
                                       GimpDisplay     *display)
{
  GimpSelectionOptions *options  = GIMP_SELECTION_TOOL_GET_OPTIONS (tool);
  GimpCursorModifier    modifier = GIMP_CURSOR_MODIFIER_NONE;

  if (! gimp_image_coords_in_active_pickable (display->image, coords,
                                              options->sample_merged, FALSE))
    modifier = GIMP_CURSOR_MODIFIER_BAD;

  gimp_tool_control_set_cursor_modifier (tool->control, modifier);

  GIMP_TOOL_CLASS (parent_class)->cursor_update (tool, coords, state, display);
}
Ejemplo n.º 7
0
static void
gimp_region_select_tool_motion (GimpTool        *tool,
                                GimpCoords      *coords,
                                guint32          time,
                                GdkModifierType  state,
                                GimpDisplay     *display)
{
  GimpRegionSelectTool *region_sel = GIMP_REGION_SELECT_TOOL (tool);
  GimpSelectionOptions *options    = GIMP_SELECTION_TOOL_GET_OPTIONS (tool);
  GdkSegment           *new_segs;
  gint                  num_new_segs;
  gint                  diff_x, diff_y;
  gdouble               diff;

  static guint32 last_time = 0;

  /* don't let the events come in too fast, ignore below a delay of 100 ms */
  if (time - last_time < 100)
    return;

  last_time = time;

  diff_x = coords->x - region_sel->x;
  diff_y = coords->y - region_sel->y;

  diff = ((ABS (diff_x) > ABS (diff_y)) ? diff_x : diff_y) / 2.0;

  g_object_set (options,
                "threshold", CLAMP (region_sel->saved_threshold + diff, 0, 255),
                NULL);

  /*  calculate the new region boundary  */
  new_segs = gimp_region_select_tool_calculate (region_sel, display,
                                                &num_new_segs);

  gimp_draw_tool_pause (GIMP_DRAW_TOOL (tool));

  /*  make sure the XSegment array is freed before we assign the new one  */
  if (region_sel->segs)
    g_free (region_sel->segs);

  region_sel->segs     = new_segs;
  region_sel->num_segs = num_new_segs;

  gimp_draw_tool_resume (GIMP_DRAW_TOOL (tool));
}
Ejemplo n.º 8
0
static GimpChannel *
gimp_by_color_select_tool_get_mask (GimpRegionSelectTool *region_select,
                                    GimpDisplay          *display)
{
  GimpTool              *tool    = GIMP_TOOL (region_select);
  GimpSelectionOptions  *options = GIMP_SELECTION_TOOL_GET_OPTIONS (tool);
  GimpDrawable          *drawable;
  GimpPickable          *pickable;
  GimpRGB                color;
  gint                   x, y;

  drawable = gimp_image_get_active_drawable (display->image);

  x = region_select->x;
  y = region_select->y;

  if (! options->sample_merged)
    {
      gint off_x, off_y;

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

      x -= off_x;
      y -= off_y;

      pickable = GIMP_PICKABLE (drawable);
    }
  else
    {
      pickable = GIMP_PICKABLE (display->image->projection);
    }

  gimp_pickable_flush (pickable);

  if (gimp_pickable_get_color_at (pickable, x, y, &color))
    return gimp_image_contiguous_region_by_color (display->image, drawable,
                                                  options->sample_merged,
                                                  options->antialias,
                                                  options->threshold,
                                                  options->select_transparent,
                                                  options->select_criterion,
                                                  &color);
  else
    return NULL;
}
Ejemplo n.º 9
0
static void
gimp_ellipse_select_tool_select (GimpRectangleSelectTool *rect_tool,
                                 GimpChannelOps           operation,
                                 gint                     x,
                                 gint                     y,
                                 gint                     w,
                                 gint                     h)
{
  GimpTool             *tool    = GIMP_TOOL (rect_tool);
  GimpSelectionOptions *options = GIMP_SELECTION_TOOL_GET_OPTIONS (rect_tool);

  gimp_channel_select_ellipse (gimp_image_get_mask (tool->display->image),
                               x, y, w, h,
                               operation,
                               options->antialias,
                               options->feather,
                               options->feather_radius,
                               options->feather_radius,
                               TRUE);
}
Ejemplo n.º 10
0
static void
gimp_foreground_select_tool_apply (GimpForegroundSelectTool *fg_select,
                                   GimpDisplay              *display)
{
  GimpTool             *tool    = GIMP_TOOL (fg_select);
  GimpSelectionOptions *options = GIMP_SELECTION_TOOL_GET_OPTIONS (tool);
  GimpImage            *image   = gimp_display_get_image (display);

  g_return_if_fail (fg_select->mask != NULL);

  gimp_channel_select_channel (gimp_image_get_mask (image),
                               C_("command", "Foreground Select"),
                               fg_select->mask, 0, 0,
                               options->operation,
                               options->feather,
                               options->feather_radius,
                               options->feather_radius);

  gimp_tool_control (tool, GIMP_TOOL_ACTION_HALT, display);

  gimp_image_flush (image);
}
Ejemplo n.º 11
0
static GeglBuffer *
gimp_fuzzy_select_tool_get_mask (GimpRegionSelectTool *region_select,
                                 GimpDisplay          *display)
{
  GimpTool                *tool        = GIMP_TOOL (region_select);
  GimpSelectionOptions    *sel_options = GIMP_SELECTION_TOOL_GET_OPTIONS (tool);
  GimpRegionSelectOptions *options     = GIMP_REGION_SELECT_TOOL_GET_OPTIONS (tool);
  GimpImage               *image       = gimp_display_get_image (display);
  GimpDrawable            *drawable    = gimp_image_get_active_drawable (image);
  GimpPickable            *pickable;
  gint                     x, y;

  x = region_select->x;
  y = region_select->y;

  if (! options->sample_merged)
    {
      gint off_x, off_y;

      gimp_item_get_offset (GIMP_ITEM (drawable), &off_x, &off_y);

      x -= off_x;
      y -= off_y;

      pickable = GIMP_PICKABLE (drawable);
    }
  else
    {
      pickable = GIMP_PICKABLE (image);
    }

  return gimp_pickable_contiguous_region_by_seed (pickable,
                                                  sel_options->antialias,
                                                  options->threshold / 255.0,
                                                  options->select_transparent,
                                                  options->select_criterion,
                                                  options->diagonal_neighbors,
                                                  x, y);
}
Ejemplo n.º 12
0
static void
gimp_selection_tool_modifier_key (GimpTool        *tool,
                                  GdkModifierType  key,
                                  gboolean         press,
                                  GdkModifierType  state,
                                  GimpDisplay     *display)
{
  GimpSelectionTool    *selection_tool = GIMP_SELECTION_TOOL (tool);
  GimpSelectionOptions *options        = GIMP_SELECTION_TOOL_GET_OPTIONS (tool);
  GdkModifierType       extend_mask;
  GdkModifierType       modify_mask;

  extend_mask = gimp_get_extend_selection_mask ();
  modify_mask = gimp_get_modify_selection_mask ();

  if (key == extend_mask ||
      key == modify_mask ||
      key == GDK_MOD1_MASK)
    {
      GimpChannelOps button_op = options->operation;

      if (press)
        {
          if (key == (state & (extend_mask |
                               modify_mask |
                               GDK_MOD1_MASK)))
            {
              /*  first modifier pressed  */

              selection_tool->saved_operation = options->operation;
            }
        }
      else
        {
          if (! (state & (extend_mask |
                          modify_mask |
                          GDK_MOD1_MASK)))
            {
              /*  last modifier released  */

              button_op = selection_tool->saved_operation;
            }
        }

      if (state & GDK_MOD1_MASK)
        {
          /*  if alt is down, pretend that neither
           *  shift nor control are down
           */
          button_op = selection_tool->saved_operation;
        }
      else if (state & (extend_mask |
                        modify_mask))
        {
          /*  else get the operation from the modifier state, but only
           *  if there is actually a modifier pressed, so we don't
           *  override the "last modifier released" assignment above
           */
          button_op = gimp_modifiers_to_channel_op (state);
        }

      if (button_op != options->operation)
        {
          g_object_set (options, "operation", button_op, NULL);
        }
    }
}
Ejemplo n.º 13
0
static void
gimp_selection_tool_cursor_update (GimpTool         *tool,
                                   const GimpCoords *coords,
                                   GdkModifierType   state,
                                   GimpDisplay      *display)
{
  GimpSelectionTool    *selection_tool = GIMP_SELECTION_TOOL (tool);
  GimpSelectionOptions *options;
  GimpToolCursorType    tool_cursor;
  GimpCursorModifier    modifier;

  options = GIMP_SELECTION_TOOL_GET_OPTIONS (tool);

  tool_cursor = gimp_tool_control_get_tool_cursor (tool->control);
  modifier    = GIMP_CURSOR_MODIFIER_NONE;

  switch (selection_tool->function)
    {
    case SELECTION_SELECT:
      switch (options->operation)
        {
        case GIMP_CHANNEL_OP_REPLACE:
          break;
        case GIMP_CHANNEL_OP_ADD:
          modifier = GIMP_CURSOR_MODIFIER_PLUS;
          break;
        case GIMP_CHANNEL_OP_SUBTRACT:
          modifier = GIMP_CURSOR_MODIFIER_MINUS;
          break;
        case GIMP_CHANNEL_OP_INTERSECT:
          modifier = GIMP_CURSOR_MODIFIER_INTERSECT;
          break;
        }
      break;

    case SELECTION_MOVE_MASK:
      modifier = GIMP_CURSOR_MODIFIER_MOVE;
      break;

    case SELECTION_MOVE:
    case SELECTION_MOVE_COPY:
      tool_cursor = GIMP_TOOL_CURSOR_MOVE;
      break;

    case SELECTION_ANCHOR:
      modifier = GIMP_CURSOR_MODIFIER_ANCHOR;
      break;
    }

  /*  we don't set the bad modifier ourselves, so a subclass has set
   *  it, always leave it there since it's more important than what we
   *  have to say.
   */
  if (gimp_tool_control_get_cursor_modifier (tool->control) ==
      GIMP_CURSOR_MODIFIER_BAD)
    {
      modifier = GIMP_CURSOR_MODIFIER_BAD;
    }

  gimp_tool_set_cursor (tool, display,
                        gimp_tool_control_get_cursor (tool->control),
                        tool_cursor,
                        modifier);
}
Ejemplo n.º 14
0
static void
gimp_selection_tool_oper_update (GimpTool         *tool,
                                 const GimpCoords *coords,
                                 GdkModifierType   state,
                                 gboolean          proximity,
                                 GimpDisplay      *display)
{
  GimpSelectionTool    *selection_tool = GIMP_SELECTION_TOOL (tool);
  GimpSelectionOptions *options        = GIMP_SELECTION_TOOL_GET_OPTIONS (tool);
  GimpImage            *image;
  GimpChannel          *selection;
  GimpDrawable         *drawable;
  GimpLayer            *layer;
  GimpLayer            *floating_sel;
  GdkModifierType       extend_mask;
  GdkModifierType       modify_mask;
  gboolean              move_layer        = FALSE;
  gboolean              move_floating_sel = FALSE;
  gboolean              selection_empty;

  image        = gimp_display_get_image (display);
  selection    = gimp_image_get_mask (image);
  drawable     = gimp_image_get_active_drawable (image);
  layer        = gimp_image_pick_layer (image, coords->x, coords->y);
  floating_sel = gimp_image_get_floating_selection (image);

  extend_mask = gimp_get_extend_selection_mask ();
  modify_mask = gimp_get_modify_selection_mask ();

  if (drawable)
    {
      if (floating_sel)
        {
          if (layer == floating_sel)
            move_floating_sel = TRUE;
        }
      else if (gimp_item_mask_intersect (GIMP_ITEM (drawable),
                                         NULL, NULL, NULL, NULL))
        {
          move_layer = TRUE;
        }
    }

  selection_empty = gimp_channel_is_empty (selection);

  selection_tool->function = SELECTION_SELECT;

  if (selection_tool->allow_move &&
      (state & GDK_MOD1_MASK) && (state & modify_mask) && move_layer)
    {
      /* move the selection */
      selection_tool->function = SELECTION_MOVE;
    }
  else if (selection_tool->allow_move &&
           (state & GDK_MOD1_MASK) && (state & extend_mask) && move_layer)
    {
      /* move a copy of the selection */
      selection_tool->function = SELECTION_MOVE_COPY;
    }
  else if (selection_tool->allow_move &&
           (state & GDK_MOD1_MASK) && ! selection_empty)
    {
      /* move the selection mask */
      selection_tool->function = SELECTION_MOVE_MASK;
    }
  else if (selection_tool->allow_move &&
           ! (state & (extend_mask | modify_mask)) &&
           move_floating_sel)
    {
      /* move the selection */
      selection_tool->function = SELECTION_MOVE;
    }
  else if ((state & modify_mask) || (state & extend_mask))
    {
      /* select */
      selection_tool->function = SELECTION_SELECT;
    }
  else if (floating_sel)
    {
      /* anchor the selection */
      selection_tool->function = SELECTION_ANCHOR;
    }

  gimp_tool_pop_status (tool, display);

  if (proximity)
    {
      const gchar     *status      = NULL;
      gboolean         free_status = FALSE;
      GdkModifierType  modifiers   = (extend_mask | modify_mask);

      if (! selection_empty)
        modifiers |= GDK_MOD1_MASK;

      switch (selection_tool->function)
        {
        case SELECTION_SELECT:
          switch (options->operation)
            {
            case GIMP_CHANNEL_OP_REPLACE:
              if (! selection_empty)
                {
                  status = gimp_suggest_modifiers (_("Click-Drag to replace the "
                                                     "current selection"),
                                                   modifiers & ~state,
                                                   NULL, NULL, NULL);
                  free_status = TRUE;
                }
              else
                {
                  status = _("Click-Drag to create a new selection");
                }
              break;

            case GIMP_CHANNEL_OP_ADD:
              status = gimp_suggest_modifiers (_("Click-Drag to add to the "
                                                 "current selection"),
                                               modifiers
                                               & ~(state | extend_mask),
                                               NULL, NULL, NULL);
              free_status = TRUE;
              break;

            case GIMP_CHANNEL_OP_SUBTRACT:
              status = gimp_suggest_modifiers (_("Click-Drag to subtract from the "
                                                 "current selection"),
                                               modifiers
                                               & ~(state | modify_mask),
                                               NULL, NULL, NULL);
              free_status = TRUE;
              break;

            case GIMP_CHANNEL_OP_INTERSECT:
              status = gimp_suggest_modifiers (_("Click-Drag to intersect with "
                                                 "the current selection"),
                                               modifiers & ~state,
                                               NULL, NULL, NULL);
              free_status = TRUE;
              break;
            }
          break;

        case SELECTION_MOVE_MASK:
          status = gimp_suggest_modifiers (_("Click-Drag to move the "
                                             "selection mask"),
                                           modifiers & ~state,
                                           NULL, NULL, NULL);
          free_status = TRUE;
          break;

        case SELECTION_MOVE:
          status = _("Click-Drag to move the selected pixels");
          break;

        case SELECTION_MOVE_COPY:
          status = _("Click-Drag to move a copy of the selected pixels");
          break;

        case SELECTION_ANCHOR:
          status = _("Click to anchor the floating selection");
          break;

        default:
          g_return_if_reached ();
        }

      if (status)
        gimp_tool_push_status (tool, display, "%s", status);

      if (free_status)
        g_free ((gchar *) status);
    }
}
Ejemplo n.º 15
0
static void
gimp_selection_tool_modifier_key (GimpTool        *tool,
                                  GdkModifierType  key,
                                  gboolean         press,
                                  GdkModifierType  state,
                                  GimpDisplay     *display)
{
  GimpSelectionTool    *selection_tool = GIMP_SELECTION_TOOL (tool);
  GimpSelectionOptions *options;

  options = GIMP_SELECTION_TOOL_GET_OPTIONS (tool);

  if (key == GDK_SHIFT_MASK   ||
      key == GDK_CONTROL_MASK ||
      key == GDK_MOD1_MASK)
    {
      GimpChannelOps button_op = options->operation;

      if (press)
        {
          if (key == (state & (GDK_SHIFT_MASK   |
                               GDK_CONTROL_MASK |
                               GDK_MOD1_MASK)))
            {
              /*  first modifier pressed  */

              selection_tool->saved_operation = options->operation;
            }
        }
      else
        {
          if (! (state & (GDK_SHIFT_MASK   |
                          GDK_CONTROL_MASK |
                          GDK_MOD1_MASK)))
            {
              /*  last modifier released  */

              button_op = selection_tool->saved_operation;
            }
        }

      if (state & GDK_MOD1_MASK)
        {
          /*  if alt is down, pretend that neither
           *  shift nor control are down
           */
          button_op = selection_tool->saved_operation;
        }
      else if ((state & GDK_CONTROL_MASK) && (state & GDK_SHIFT_MASK))
        {
          button_op = GIMP_CHANNEL_OP_INTERSECT;
        }
      else if (state & GDK_SHIFT_MASK)
        {
          button_op = GIMP_CHANNEL_OP_ADD;
        }
      else if (state & GDK_CONTROL_MASK)
        {
          button_op = GIMP_CHANNEL_OP_SUBTRACT;
        }

      if (button_op != options->operation)
        {
          g_object_set (options, "operation", button_op, NULL);
        }
    }
}
Ejemplo n.º 16
0
static gboolean
gimp_rectangle_select_tool_rectangle_change_complete (GimpRectangleTool *rectangle)
{
  GimpTool                       *tool;
  GimpRectangleSelectTool        *rect_sel_tool;
  GimpRectangleSelectToolPrivate *priv;

  tool          = GIMP_TOOL (rectangle);
  rect_sel_tool = GIMP_RECTANGLE_SELECT_TOOL (tool);
  priv          = GIMP_RECTANGLE_SELECT_TOOL_GET_PRIVATE (rect_sel_tool);

  /* prevent change in selection from halting the tool */
  gimp_tool_control_push_preserve (tool->control, TRUE);

  if (tool->display && ! gimp_tool_control_is_active (tool->control))
    {
      GimpImage     *image      = gimp_display_get_image (tool->display);
      GimpUndoStack *undo_stack = gimp_image_get_undo_stack (image);
      GimpUndo      *undo       = gimp_undo_stack_peek (undo_stack);
      gint           x1, y1, x2, y2;

      /* if we got here via button release, we have already undone the
       * previous operation.  But if we got here by some other means,
       * we need to undo it now.
       */
      if (undo && priv->undo == undo)
        {
          gimp_image_undo (image);
          priv->undo = NULL;
        }

      g_object_get (rectangle,
                    "x1", &x1,
                    "y1", &y1,
                    "x2", &x2,
                    "y2", &y2,
                    NULL);

      if (gimp_rectangle_select_tool_select (rectangle, x1, y1, x2 - x1, y2 - y1))
        {
          /* save the undo that we got when executing, but only if
           * we actually selected something
           */
          priv->undo = gimp_undo_stack_peek (undo_stack);
          priv->redo = NULL;
        }

      if (! priv->use_saved_op)
        {
          GimpSelectionOptions *options;

          options = GIMP_SELECTION_TOOL_GET_OPTIONS (tool);

          /* remember the operation now in case we modify the rectangle */
          priv->operation    = options->operation;
          priv->use_saved_op = TRUE;
        }

      gimp_image_flush (image);
    }

  gimp_tool_control_pop_preserve (tool->control);

  gimp_rectangle_select_tool_update_option_defaults (rect_sel_tool, FALSE);

  return TRUE;
}
Ejemplo n.º 17
0
static void
gimp_region_select_tool_button_release (GimpTool              *tool,
                                        GimpCoords            *coords,
                                        guint32                time,
                                        GdkModifierType        state,
                                        GimpButtonReleaseType  release_type,
                                        GimpDisplay           *display)
{
  GimpRegionSelectTool    *region_sel  = GIMP_REGION_SELECT_TOOL (tool);
  GimpSelectionOptions    *sel_options = GIMP_SELECTION_TOOL_GET_OPTIONS (tool);
  GimpRegionSelectOptions *options     = GIMP_REGION_SELECT_TOOL_GET_OPTIONS (tool);

  gimp_tool_pop_status (tool, display);

  gimp_draw_tool_stop (GIMP_DRAW_TOOL (tool));

  gimp_tool_control_halt (tool->control);

  if (release_type != GIMP_BUTTON_RELEASE_CANCEL)
    {
      gint off_x, off_y;

      if (GIMP_SELECTION_TOOL (tool)->function == SELECTION_ANCHOR)
        {
          if (gimp_image_floating_sel (display->image))
            {
              /*  If there is a floating selection, anchor it  */
              floating_sel_anchor (gimp_image_floating_sel (display->image));
            }
          else
            {
              /*  Otherwise, clear the selection mask  */
              gimp_channel_clear (gimp_image_get_mask (display->image), NULL,
                                  TRUE);
            }

          gimp_image_flush (display->image);
        }
      else if (region_sel->region_mask)
        {
          if (options->sample_merged)
            {
              off_x = 0;
              off_y = 0;
            }
          else
            {
              GimpDrawable *drawable;

              drawable = gimp_image_get_active_drawable (display->image);

              gimp_item_offsets (GIMP_ITEM (drawable), &off_x, &off_y);
            }

          gimp_channel_select_channel (gimp_image_get_mask (display->image),
                                       GIMP_REGION_SELECT_TOOL_GET_CLASS (tool)->undo_desc,
                                       region_sel->region_mask,
                                       off_x,
                                       off_y,
                                       sel_options->operation,
                                       sel_options->feather,
                                       sel_options->feather_radius,
                                       sel_options->feather_radius);


          gimp_image_flush (display->image);
        }
    }

  if (region_sel->region_mask)
    {
      g_object_unref (region_sel->region_mask);
      region_sel->region_mask = NULL;
    }

  if (region_sel->segs)
    {
      g_free (region_sel->segs);
      region_sel->segs     = NULL;
      region_sel->num_segs = 0;
    }

  /*  Restore the original threshold  */
  g_object_set (options,
                "threshold", region_sel->saved_threshold,
                NULL);
}