Commit 10255edd authored by Marek Dvoroznak's avatar Marek Dvoroznak Committed by Michael Natterer

app: npd-tool: add option to apply or cancel the deformation

parent c4e12fdd
......@@ -105,9 +105,9 @@ gimp_canvas_buffer_preview_init (GimpCanvasBufferPreview *transform_preview)
static void
gimp_canvas_buffer_preview_set_property (GObject *object,
guint property_id,
const GValue *value,
GParamSpec *pspec)
guint property_id,
const GValue *value,
GParamSpec *pspec)
{
GimpCanvasBufferPreviewPrivate *private = GET_PRIVATE (object);
......@@ -125,9 +125,9 @@ gimp_canvas_buffer_preview_set_property (GObject *object,
static void
gimp_canvas_buffer_preview_get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec)
guint property_id,
GValue *value,
GParamSpec *pspec)
{
GimpCanvasBufferPreviewPrivate *private = GET_PRIVATE (object);
......@@ -147,14 +147,19 @@ static void
gimp_canvas_buffer_preview_draw (GimpCanvasItem *item,
cairo_t *cr)
{
GimpDisplayShell *shell = gimp_canvas_item_get_shell (item);
GeglBuffer *buffer = GET_PRIVATE (item)->buffer;
GimpDisplayShell *shell;
GeglBuffer *buffer;
cairo_surface_t *area;
guchar *data;
cairo_rectangle_int_t rectangle;
gint viewport_offset_x, viewport_offset_y;
gint viewport_width, viewport_height;
g_return_if_fail (GIMP_IS_CANVAS_ITEM (item));
shell = gimp_canvas_item_get_shell (item);
buffer = GET_PRIVATE (item)->buffer;
g_return_if_fail (GEGL_IS_BUFFER (buffer) && buffer != NULL);
gimp_display_shell_scroll_get_scaled_viewport (shell,
&viewport_offset_x,
&viewport_offset_y,
......@@ -174,7 +179,7 @@ gimp_canvas_buffer_preview_draw (GimpCanvasItem *item,
rectangle.width,
rectangle.height),
shell->scale_x,
gegl_buffer_get_format (buffer), /* has to be cairo-ARGB32 */
babl_format ("cairo-ARGB32"),
data,
cairo_image_surface_get_stride (area),
GEGL_ABYSS_NONE);
......@@ -193,14 +198,19 @@ static void
gimp_canvas_buffer_preview_compute_bounds (GimpCanvasItem *item,
cairo_rectangle_int_t *bounds)
{
GimpDisplayShell *shell = gimp_canvas_item_get_shell (item);
GeglBuffer *buffer = GET_PRIVATE (item)->buffer;
GimpDisplayShell *shell;
GeglBuffer *buffer;
gint x_from, x_to;
gint y_from, y_to;
gint viewport_offset_x, viewport_offset_y;
gint viewport_width, viewport_height;
gint width, height;
g_return_if_fail (GIMP_IS_CANVAS_ITEM (item));
shell = gimp_canvas_item_get_shell (item);
buffer = GET_PRIVATE (item)->buffer;
g_return_if_fail (GEGL_IS_BUFFER (buffer) && buffer != NULL);
width = gegl_buffer_get_width (buffer);
height = gegl_buffer_get_height (buffer);
......
......@@ -28,6 +28,8 @@
#include "tools-types.h"
#include "gegl/gimp-gegl-utils.h"
#include "display/gimpdisplay.h"
#include "core/gimp.h"
......@@ -59,6 +61,7 @@
#define GIMP_NPD_DEBUG
#define GIMP_NPD_MAXIMUM_DEFORMATION_DELAY 100000 /* 100000 microseconds == 10 FPS */
#define GIMP_NPD_DRAW_INTERVAL 50 /* 50 milliseconds == 20 FPS */
#define GIMP_NPD_STRING "N-Point Deformation"
void gimp_n_point_deformation_tool_start (GimpNPointDeformationTool *npd_tool,
GimpDisplay *display);
......@@ -108,9 +111,9 @@ static void gimp_n_point_deformation_tool_motion (GimpTool
GimpDisplay *display);
static void gimp_n_point_deformation_tool_clear_selected_points_list
(GimpNPointDeformationTool *npd_tool);
gboolean gimp_n_point_deformation_tool_add_cp_to_selection (GimpNPointDeformationTool *npd_tool,
static gboolean gimp_n_point_deformation_tool_add_cp_to_selection (GimpNPointDeformationTool *npd_tool,
NPDControlPoint *cp);
gboolean gimp_n_point_deformation_tool_is_cp_in_area (NPDControlPoint *cp,
static gboolean gimp_n_point_deformation_tool_is_cp_in_area (NPDControlPoint *cp,
gfloat x0,
gfloat y0,
gfloat x1,
......@@ -127,6 +130,7 @@ gboolean gimp_n_point_deformation_tool_canvas_update_thread_func
static void gimp_n_point_deformation_tool_perform_deformation (GimpNPointDeformationTool *npd_tool);
static void gimp_n_point_deformation_tool_halt_threads (GimpNPointDeformationTool *npd_tool);
GimpCanvasItem *gimp_n_point_deformation_tool_add_preview (GimpNPointDeformationTool *npd_tool);
static void gimp_n_point_deformation_tool_apply_deformation (GimpNPointDeformationTool *npd_tool);
#ifdef GIMP_NPD_DEBUG
#define gimp_npd_debug(x) g_printf x
......@@ -148,7 +152,7 @@ gimp_n_point_deformation_tool_register (GimpToolRegisterCallback callback,
gimp_n_point_deformation_options_gui,
0,
"gimp-n-point-deformation-tool",
_("N-Point Deformation"),
_(GIMP_NPD_STRING),
_("N-Point Deformation Tool: Rubber-like deformation of an image using points"),
N_("_N-Point Deformation"), "<shift>N",
NULL, GIMP_HELP_TOOL_N_POINT_DEFORMATION,
......@@ -185,7 +189,6 @@ gimp_n_point_deformation_tool_init (GimpNPointDeformationTool *npd_tool)
gimp_tool_control_set_preserve (tool->control, FALSE);
gimp_tool_control_set_wants_click (tool->control, TRUE);
gimp_tool_control_set_wants_all_key_events (tool->control, TRUE);
gimp_tool_control_set_scroll_lock (tool->control, TRUE);
gimp_tool_control_set_handle_empty_image (tool->control, FALSE);
gimp_tool_control_set_dirty_mask (tool->control,
GIMP_DIRTY_IMAGE |
......@@ -194,7 +197,8 @@ gimp_n_point_deformation_tool_init (GimpNPointDeformationTool *npd_tool)
GIMP_DIRTY_SELECTION |
GIMP_DIRTY_ACTIVE_DRAWABLE);
npd_tool->active = FALSE;
npd_tool->active = FALSE;
npd_tool->deformation_active = FALSE;
}
static void
......@@ -243,12 +247,13 @@ gimp_n_point_deformation_tool_start (GimpNPointDeformationTool *npd_tool,
npd_tool->active = TRUE;
image = gimp_display_get_image (display);
drawable = gimp_image_get_active_drawable (image);
source_buffer = gimp_drawable_get_buffer (drawable);
/* create GEGL graph */
image = gimp_display_get_image (display);
drawable = gimp_image_get_active_drawable (image);
source_buffer = gegl_buffer_dup (gimp_drawable_get_buffer (drawable));
preview_buffer = gegl_buffer_new (gegl_buffer_get_extent (source_buffer),
babl_format ("cairo-ARGB32"));
preview_buffer = gegl_buffer_new (gegl_buffer_get_extent (source_buffer),
babl_format ("cairo-ARGB32"));
graph = gegl_node_new ();
......@@ -279,8 +284,10 @@ gimp_n_point_deformation_tool_start (GimpNPointDeformationTool *npd_tool,
npd_tool->drawable = drawable;
npd_tool->graph = graph;
npd_tool->model = model;
npd_tool->node = node;
npd_tool->source = source;
npd_tool->npd_node = node;
npd_tool->sink = sink;
npd_tool->source_buffer = source_buffer;
npd_tool->preview_buffer = preview_buffer;
npd_tool->selected_cp = NULL;
npd_tool->hovering_cp = NULL;
......@@ -321,6 +328,8 @@ gimp_n_point_deformation_tool_halt (GimpNPointDeformationTool *npd_tool)
gimp_n_point_deformation_tool_halt_threads (npd_tool);
npd_tool->active = FALSE;
if (gimp_draw_tool_is_active (draw_tool))
gimp_draw_tool_stop (draw_tool);
......@@ -328,6 +337,11 @@ gimp_n_point_deformation_tool_halt (GimpNPointDeformationTool *npd_tool)
gimp_tool_control_halt (tool->control);
gimp_n_point_deformation_tool_clear_selected_points_list (npd_tool);
g_object_unref (npd_tool->graph);
g_object_unref (npd_tool->source_buffer);
g_object_unref (npd_tool->preview_buffer);
npd_tool->preview_buffer = NULL;
if (npd_tool->model != NULL)
npd_destroy_model (npd_tool->model);
......@@ -365,7 +379,7 @@ gimp_n_point_deformation_tool_options_notify (GimpTool *tool,
gimp_draw_tool_pause (draw_tool);
gimp_npd_debug (("npd options notify\n"));
gimp_n_point_deformation_tool_set_options (npd_tool->node, npd_options);
gimp_n_point_deformation_tool_set_options (npd_tool->npd_node, npd_options);
gimp_draw_tool_resume (draw_tool);
}
......@@ -408,9 +422,10 @@ gimp_n_point_deformation_tool_key_press (GimpTool *tool,
case GDK_KEY_ISO_Enter:
gimp_n_point_deformation_tool_halt_threads (npd_tool);
npd_options->mesh_visible = FALSE;
gimp_n_point_deformation_tool_set_options (npd_tool->node,
npd_options);
gimp_tool_control_push_preserve (tool->control, TRUE);
gimp_n_point_deformation_tool_apply_deformation (npd_tool);
gimp_tool_control_pop_preserve (tool->control);
gimp_tool_control (tool, GIMP_TOOL_ACTION_HALT, display);
break;
......@@ -672,6 +687,7 @@ gimp_n_point_deformation_tool_button_release (GimpTool *tool,
else
if (release_type == GIMP_BUTTON_RELEASE_CANCEL)
{
gimp_npd_debug (("gimp_button_release_cancel\n"));
}
npd_tool->rubber_band = FALSE;
......@@ -840,7 +856,7 @@ gimp_n_point_deformation_tool_canvas_update_thread_func (GimpNPointDeformationTo
gtk_widget_get_window (gimp_display_get_shell (npd_tool->display)->canvas),
FALSE);
gimp_npd_debug (("canvas update thread stop\n"));
return TRUE;
}
......@@ -851,7 +867,9 @@ gimp_n_point_deformation_tool_deform_thread_func (gpointer data)
GimpNPointDeformationOptions *npd_options = GIMP_N_POINT_DEFORMATION_TOOL_GET_OPTIONS (npd_tool);
guint64 start, duration;
while (npd_tool->active) {
npd_tool->deformation_active = TRUE;
while (npd_tool->deformation_active) {
start = g_get_monotonic_time ();
/* perform the deformation only if the tool hasn't been paused */
......@@ -876,7 +894,7 @@ static void
gimp_n_point_deformation_tool_perform_deformation (GimpNPointDeformationTool *npd_tool)
{
gimp_npd_debug (("gegl_node_invalidated\n"));
gegl_node_invalidated (npd_tool->node, NULL, FALSE);
gegl_node_invalidated (npd_tool->npd_node, NULL, FALSE);
gimp_npd_debug (("gegl_node_process\n"));
gegl_node_process (npd_tool->sink);
......@@ -885,8 +903,10 @@ gimp_n_point_deformation_tool_perform_deformation (GimpNPointDeformationTool *np
static void
gimp_n_point_deformation_tool_halt_threads (GimpNPointDeformationTool *npd_tool)
{
if (!npd_tool->deformation_active) return;
gimp_npd_debug (("waiting for deform thread to finish\n"));
npd_tool->active = FALSE;
npd_tool->deformation_active = FALSE;
/* wait for deformation thread to finish its work */
g_thread_join (npd_tool->deform_thread);
......@@ -902,6 +922,8 @@ gimp_n_point_deformation_tool_add_preview (GimpNPointDeformationTool *npd_tool)
GimpCanvasItem *item;
GimpDrawTool *draw_tool = GIMP_DRAW_TOOL (npd_tool);
if (!npd_tool->preview_buffer) return;
item = gimp_canvas_buffer_preview_new (gimp_display_get_shell (draw_tool->display),
npd_tool->preview_buffer);
......@@ -909,4 +931,34 @@ gimp_n_point_deformation_tool_add_preview (GimpNPointDeformationTool *npd_tool)
g_object_unref (item);
return item;
}
static void
gimp_n_point_deformation_tool_apply_deformation (GimpNPointDeformationTool *npd_tool)
{
GimpNPointDeformationOptions *npd_options = GIMP_N_POINT_DEFORMATION_TOOL_GET_OPTIONS (npd_tool);
GeglBuffer *buffer = gimp_drawable_get_buffer(npd_tool->drawable);
GimpImage *image = gimp_display_get_image (npd_tool->display);
gint width, height;
width = gegl_buffer_get_width (buffer);
height = gegl_buffer_get_height (buffer);
npd_options->mesh_visible = FALSE;
gimp_n_point_deformation_tool_set_options (npd_tool->npd_node,
npd_options);
gimp_drawable_push_undo (npd_tool->drawable, _(GIMP_NPD_STRING), NULL,
0, 0, width, height);
gimp_gegl_apply_operation (NULL, NULL, _(GIMP_NPD_STRING),
npd_tool->npd_node,
gimp_drawable_get_buffer (npd_tool->drawable),
NULL);
gimp_drawable_update (npd_tool->drawable,
0, 0, width, height);
gimp_projection_flush (gimp_image_get_projection (image));
}
\ No newline at end of file
......@@ -47,10 +47,12 @@ struct _GimpNPointDeformationTool
GThread *deform_thread;
GeglNode *graph;
GeglNode *node;
GeglNode *source;
GeglNode *npd_node;
GeglNode *sink;
GeglBuffer *preview_buffer;
GeglBuffer *source_buffer;
GimpDrawable *drawable;
......@@ -74,7 +76,8 @@ struct _GimpNPointDeformationTool
GList *previous_cps_positions; /* list of NPDPoints holding previous
* positions of control points */
volatile gboolean active;
gboolean active;
volatile gboolean deformation_active;
gboolean rubber_band;
};
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment