Ejemplo n.º 1
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);
  GimpRegionSelectOptions *options    = GIMP_REGION_SELECT_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.º 2
0
static void
gimp_foreground_select_tool_cursor_update (GimpTool         *tool,
                                           const GimpCoords *coords,
                                           GdkModifierType   state,
                                           GimpDisplay      *display)
{
  GimpForegroundSelectTool *fg_select = GIMP_FOREGROUND_SELECT_TOOL (tool);

  if (fg_select->mask)
    {
      GimpForegroundSelectOptions *options;

      options = GIMP_FOREGROUND_SELECT_TOOL_GET_OPTIONS (tool);

      gimp_tool_control_set_toggled (tool->control, options->background);

      switch (GIMP_SELECTION_TOOL (tool)->function)
        {
        case SELECTION_MOVE_MASK:
        case SELECTION_MOVE:
        case SELECTION_MOVE_COPY:
        case SELECTION_ANCHOR:
          return;
        default:
          break;
        }
    }

  GIMP_TOOL_CLASS (parent_class)->cursor_update (tool, coords, state, display);
}
Ejemplo n.º 3
0
static void
gimp_foreground_select_tool_oper_update (GimpTool         *tool,
                                         const GimpCoords *coords,
                                         GdkModifierType   state,
                                         gboolean          proximity,
                                         GimpDisplay      *display)
{
  GimpForegroundSelectTool *fg_select = GIMP_FOREGROUND_SELECT_TOOL (tool);
  const gchar              *status    = NULL;

  GIMP_TOOL_CLASS (parent_class)->oper_update (tool, coords, state, proximity,
                                               display);

  if (fg_select->mask && display == tool->display)
    {
      GimpDrawTool *draw_tool = GIMP_DRAW_TOOL (tool);

      gimp_draw_tool_pause (draw_tool);

      fg_select->last_coords = *coords;

      gimp_draw_tool_resume (draw_tool);

      if (fg_select->strokes)
        status = _("Add more strokes or press Enter to accept the selection");
      else
        status = _("Mark foreground by painting on the object to extract");
    }
  else
    {
      if (GIMP_SELECTION_TOOL (tool)->function == SELECTION_SELECT)
        status = _("Roughly outline the object to extract");
    }

  if (proximity && status)
    gimp_tool_replace_status (tool, display, "%s", status);
}
Ejemplo n.º 4
0
static void
gimp_foreground_select_tool_cursor_update (GimpTool         *tool,
                                           const GimpCoords *coords,
                                           GdkModifierType   state,
                                           GimpDisplay      *display)
{
  GimpForegroundSelectTool *fg_select = GIMP_FOREGROUND_SELECT_TOOL (tool);

  if (fg_select->state == MATTING_STATE_PAINT_TRIMAP)
    {
      switch (GIMP_SELECTION_TOOL (tool)->function)
        {
        case SELECTION_MOVE_MASK:
        case SELECTION_MOVE:
        case SELECTION_MOVE_COPY:
        case SELECTION_ANCHOR:
          return;
        default:
          break;
        }
    }

  GIMP_TOOL_CLASS (parent_class)->cursor_update (tool, coords, state, display);
}
Ejemplo n.º 5
0
static void
gimp_rectangle_select_tool_button_press (GimpTool            *tool,
                                         const GimpCoords    *coords,
                                         guint32              time,
                                         GdkModifierType      state,
                                         GimpButtonPressType  press_type,
                                         GimpDisplay         *display)
{
  GimpRectangleTool              *rectangle;
  GimpRectangleSelectTool        *rect_sel_tool;
  GimpDisplayShell               *shell;
  GimpRectangleSelectToolPrivate *priv;
  GimpRectangleFunction           function;

  rectangle     = GIMP_RECTANGLE_TOOL (tool);
  rect_sel_tool = GIMP_RECTANGLE_SELECT_TOOL (tool);
  shell         = gimp_display_get_shell (display);
  priv          = GIMP_RECTANGLE_SELECT_TOOL_GET_PRIVATE (rect_sel_tool);

  if (tool->display && display != tool->display)
    {
      gimp_rectangle_tool_cancel (GIMP_RECTANGLE_TOOL (tool));
    }

  if (gimp_selection_tool_start_edit (GIMP_SELECTION_TOOL (tool),
                                      display, coords))
    {
      /* In some cases we want to finish the rectangle select tool
       * and hand over responsability to the selection tool
       */
      gimp_rectangle_tool_execute (rectangle);
      gimp_rectangle_tool_control (tool, GIMP_TOOL_ACTION_HALT, display);
      gimp_rectangle_select_tool_update_option_defaults (rect_sel_tool,
                                                         TRUE);
      return;
    }

  gimp_tool_control_activate (tool->control);

  priv->saved_show_selection = gimp_display_shell_get_show_selection (shell);

  /* if the shift or ctrl keys are down, we don't want to adjust, we
   * want to create a new rectangle, regardless of pointer loc */
  if (state & (gimp_get_extend_selection_mask () |
               gimp_get_modify_selection_mask ()))
    {
      gimp_rectangle_tool_set_function (rectangle,
                                        GIMP_RECTANGLE_TOOL_CREATING);
    }

  gimp_rectangle_tool_button_press (tool, coords, time, state, display);

  priv->press_x = coords->x;
  priv->press_y = coords->y;

  /* if we have an existing rectangle in the current display, then
   * we have already "executed", and need to undo at this point,
   * unless the user has done something in the meantime
   */
  function = gimp_rectangle_tool_get_function (rectangle);

  if (function == GIMP_RECTANGLE_TOOL_CREATING)
    {
      priv->use_saved_op = FALSE;
    }
  else
    {
      GimpImage      *image      = gimp_display_get_image (tool->display);
      GimpUndoStack  *undo_stack = gimp_image_get_undo_stack (image);
      GimpUndoStack  *redo_stack = gimp_image_get_redo_stack (image);
      GimpUndo       *undo;
      GimpChannelOps  operation;

      undo = gimp_undo_stack_peek (undo_stack);

      if (undo && priv->undo == undo)
        {
          /* prevent this change from halting the tool */
          gimp_tool_control_push_preserve (tool->control, TRUE);

          gimp_image_undo (image);

          gimp_tool_control_pop_preserve (tool->control);

          /* we will need to redo if the user cancels or executes */
          priv->redo = gimp_undo_stack_peek (redo_stack);
        }

      /* if the operation is "Replace", turn off the marching ants,
         because they are confusing */
      operation = gimp_rectangle_select_tool_get_operation (rect_sel_tool);

      if (operation == GIMP_CHANNEL_OP_REPLACE)
        gimp_display_shell_set_show_selection (shell, FALSE);
    }

  priv->undo = NULL;
}
Ejemplo n.º 6
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.º 7
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.º 8
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.º 9
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);
}
Ejemplo n.º 10
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.º 11
0
static void
gimp_foreground_select_tool_oper_update (GimpTool         *tool,
                                         const GimpCoords *coords,
                                         GdkModifierType   state,
                                         gboolean          proximity,
                                         GimpDisplay      *display)
{
  GimpForegroundSelectTool    *fg_select    = GIMP_FOREGROUND_SELECT_TOOL (tool);
  GimpForegroundSelectOptions *options      = GIMP_FOREGROUND_SELECT_TOOL_GET_OPTIONS (fg_select);
  const gchar                 *status_stage = NULL;
  const gchar                 *status_mode  = NULL;

  GimpDisplayShell   *shell   = gimp_display_get_shell (display);
  GimpImage          *image   = gimp_display_get_image (display);

  GIMP_TOOL_CLASS (parent_class)->oper_update (tool, coords, state, proximity,
                                               display);

  if (fg_select->state == MATTING_STATE_FREE_SELECT)
    {
      if (GIMP_SELECTION_TOOL (tool)->function == SELECTION_SELECT)
        status_stage = _("Roughly outline the object to extract");
    }
  else
    {
      GimpDrawTool *draw_tool = GIMP_DRAW_TOOL (tool);

      gimp_draw_tool_pause (draw_tool);

      fg_select->last_coords = *coords;

      gimp_draw_tool_resume (draw_tool);

      if (options->draw_mode == GIMP_MATTING_DRAW_MODE_FOREGROUND)
        status_mode = _("Selecting foreground, ");
      else if (options->draw_mode == GIMP_MATTING_DRAW_MODE_BACKGROUND)
        status_mode = _("Selecting background, ");
      else
        status_mode = _("Selecting unknown, ");

      if (fg_select->state == MATTING_STATE_PAINT_TRIMAP)
        status_stage = _("press Enter to preview.");
      else
        status_stage = _("press Escape to exit preview or Enter to apply.");
    }

  if (proximity && status_stage)
    {
      if (status_mode)
        gimp_tool_replace_status (tool, display, "%s%s", status_mode, status_stage);
      else
        gimp_tool_replace_status (tool, display, "%s", status_stage);
    }

  gimp_foreground_select_tool_update_gui (fg_select);

  gimp_tool_gui_set_shell (fg_select->gui, shell);
  gimp_tool_gui_set_viewable (fg_select->gui, GIMP_VIEWABLE (image));

  gimp_tool_gui_show (fg_select->gui);
}