Ejemplo n.º 1
0
/**
 * gimp_seamless_clone_tool_stop:
 * @sc: The seamless clone tool whose resources should be freed
 * @display_change_only: Mark that the only reason for this call was a
 *                       switch of the working display.
 *
 * This function frees any resources associated with the seamless clone
 * tool, including caches, gegl graphs, and anything the tool created.
 * Afterwards, it initializes all the relevant pointers to some initial
 * value (usually NULL) like the init function does.
 *
 * Note that for seamless cloning, no change needs to be done when
 * switching to a different display, except for clearing the image map.
 * So for that, we provide a boolean parameter to specify that the only
 * change was one of the display
 */
static void
gimp_seamless_clone_tool_stop (GimpSeamlessCloneTool *sc,
                               gboolean               display_change_only)
{
  /* See if we actually have any reason to stop */
  if (sc->tool_state == SC_STATE_INIT)
    return;

  if (! display_change_only)
    {
      sc->tool_state = SC_STATE_INIT;

      g_clear_object (&sc->paste);
      g_clear_object (&sc->render_node);
      sc->sc_node = NULL;
    }

  /* This should always happen, even when we just switch a display */
  if (sc->filter)
    {
      gimp_drawable_filter_abort (sc->filter);
      g_clear_object (&sc->filter);

      if (GIMP_TOOL (sc)->display)
        gimp_image_flush (gimp_display_get_image (GIMP_TOOL (sc)->display));
    }

  gimp_draw_tool_stop (GIMP_DRAW_TOOL (sc));
}
Ejemplo n.º 2
0
static void
gimp_warp_tool_halt (GimpWarpTool *wt)
{
  GimpTool        *tool    = GIMP_TOOL (wt);
  GimpWarpOptions *options = GIMP_WARP_TOOL_GET_OPTIONS (wt);

  if (wt->coords_buffer)
    {
      g_object_unref (wt->coords_buffer);
      wt->coords_buffer = NULL;
    }

  if (wt->graph)
    {
      g_object_unref (wt->graph);
      wt->graph       = NULL;
      wt->render_node = NULL;
    }

  if (wt->filter)
    {
      gimp_drawable_filter_abort (wt->filter);
      g_object_unref (wt->filter);
      wt->filter = NULL;

      gimp_image_flush (gimp_display_get_image (tool->display));
    }

  if (wt->redo_stack)
    {
      g_list_free_full (wt->redo_stack, (GDestroyNotify) g_object_unref);
      wt->redo_stack = NULL;
    }

  tool->display  = NULL;
  tool->drawable = NULL;

  if (gimp_draw_tool_is_active (GIMP_DRAW_TOOL (wt)))
    gimp_draw_tool_stop (GIMP_DRAW_TOOL (wt));

  if (options->animate_button)
    {
      gtk_widget_set_sensitive (options->animate_button, FALSE);

      g_signal_handlers_disconnect_by_func (options->animate_button,
                                            gimp_warp_tool_animate,
                                            wt);
    }
}
Ejemplo n.º 3
0
static void
gimp_blend_tool_halt (GimpBlendTool *blend_tool)
{
  GimpTool *tool = GIMP_TOOL (blend_tool);

  if (blend_tool->graph)
    {
      g_object_unref (blend_tool->graph);
      blend_tool->graph = NULL;

      blend_tool->render_node    = NULL;
#if 0
      blend_tool->subtract_node  = NULL;
      blend_tool->divide_node    = NULL;
#endif
      blend_tool->dist_node      = NULL;
    }

  if (blend_tool->dist_buffer)
    {
      g_object_unref (blend_tool->dist_buffer);
      blend_tool->dist_buffer = NULL;
    }

  if (blend_tool->filter)
    {
      gimp_drawable_filter_abort (blend_tool->filter);
      g_object_unref (blend_tool->filter);
      blend_tool->filter = NULL;

      gimp_image_flush (gimp_display_get_image (tool->display));
    }

  tool->display  = NULL;
  tool->drawable = NULL;

  if (gimp_draw_tool_is_active (GIMP_DRAW_TOOL (blend_tool)))
    gimp_draw_tool_stop (GIMP_DRAW_TOOL (blend_tool));
}
Ejemplo n.º 4
0
static void
gimp_warp_tool_animate (GimpWarpTool *wt)
{
  GimpTool        *tool    = GIMP_TOOL (wt);
  GimpWarpOptions *options = GIMP_WARP_TOOL_GET_OPTIONS (wt);
  GimpImage       *orig_image;
  GimpImage       *image;
  GimpLayer       *layer;
  GimpLayer       *first_layer;
  GeglNode        *scale_node;
  GimpProgress    *progress;
  GtkWidget       *widget;
  gint             i;

  if (! gimp_warp_tool_get_undo_desc (tool, tool->display))
    {
      gimp_tool_message_literal (tool, tool->display,
                                 _("Please add some warp strokes first."));
      return;
    }

  /*  get rid of the image map so we can use wt->graph  */
  if (wt->filter)
    {
      gimp_drawable_filter_abort (wt->filter);
      g_object_unref (wt->filter);
      wt->filter = NULL;
    }

  gimp_progress_start (GIMP_PROGRESS (tool), FALSE,
                       _("Rendering Frame %d"), 1);

  orig_image = gimp_item_get_image (GIMP_ITEM (tool->drawable));

  image = gimp_create_image (orig_image->gimp,
                             gimp_item_get_width  (GIMP_ITEM (tool->drawable)),
                             gimp_item_get_height (GIMP_ITEM (tool->drawable)),
                             gimp_drawable_get_base_type (tool->drawable),
                             gimp_drawable_get_precision (tool->drawable),
                             TRUE);

  /*  the first frame is always the unwarped image  */
  layer = GIMP_LAYER (gimp_item_convert (GIMP_ITEM (tool->drawable), image,
                                         GIMP_TYPE_LAYER));
  gimp_object_take_name (GIMP_OBJECT (layer),
                         g_strdup_printf (_("Frame %d"), 1));

  gimp_item_set_offset (GIMP_ITEM (layer), 0, 0);
  gimp_item_set_visible (GIMP_ITEM (layer), TRUE, FALSE);
  gimp_layer_set_mode (layer, GIMP_NORMAL_MODE, FALSE);
  gimp_layer_set_opacity (layer, GIMP_OPACITY_OPAQUE, FALSE);
  gimp_image_add_layer (image, layer, NULL, 0, FALSE);

  first_layer = layer;

  scale_node = gegl_node_new_child (NULL,
                                    "operation",    "gimp:scalar-multiply",
                                    "n-components", 2,
                                    NULL);
  gimp_warp_tool_add_op (wt, scale_node);

  progress = gimp_sub_progress_new (GIMP_PROGRESS (tool));

  for (i = 1; i < options->n_animation_frames; i++)
    {
      gimp_progress_set_text (GIMP_PROGRESS (tool),
                              _("Rendering Frame %d"), i + 1);

      gimp_sub_progress_set_step (GIMP_SUB_PROGRESS (progress),
                                  i, options->n_animation_frames);

      layer = GIMP_LAYER (gimp_item_duplicate (GIMP_ITEM (first_layer),
                                               GIMP_TYPE_LAYER));
      gimp_object_take_name (GIMP_OBJECT (layer),
                             g_strdup_printf (_("Frame %d"), i + 1));

      gegl_node_set (scale_node,
                     "factor", (gdouble) i /
                               (gdouble) (options->n_animation_frames - 1),
                     NULL);

      gimp_gegl_apply_operation (gimp_drawable_get_buffer (GIMP_DRAWABLE (first_layer)),
                                 progress,
                                 _("Frame"),
                                 wt->graph,
                                 gimp_drawable_get_buffer (GIMP_DRAWABLE (layer)),
                                 NULL);

      gimp_image_add_layer (image, layer, NULL, 0, FALSE);
    }

  g_object_unref (progress);

  gimp_warp_tool_remove_op (wt, scale_node);

  gimp_progress_end (GIMP_PROGRESS (tool));

  /*  recreate the image map  */
  gimp_warp_tool_create_filter (wt, tool->drawable);
  gimp_drawable_filter_apply (wt->filter, NULL);

  widget = GTK_WIDGET (gimp_display_get_shell (tool->display));
  gimp_create_display (orig_image->gimp, image, GIMP_UNIT_PIXEL, 1.0,
                       G_OBJECT (gtk_widget_get_screen (widget)),
                       gimp_widget_get_monitor (widget));
  g_object_unref (image);
}