[gimp/soc-2010-cage-2: 8/8] cage tool: implement options_notify to allow switching back to edit mode and update fill option



commit aa98319f1b9a8979de8a1804be69ec680c9dfed2
Author: Michael Muré <batolettre gmail com>
Date:   Sat Jan 22 00:44:35 2011 +0100

    cage tool: implement options_notify to allow switching back to edit mode
    and update fill option

 app/gegl/gimpcageconfig.c |   10 ++-
 app/tools/gimpcagetool.c  |  191 +++++++++++++++++++++++++++++++++++---------
 app/tools/gimpcagetool.h  |    5 +
 3 files changed, 163 insertions(+), 43 deletions(-)
---
diff --git a/app/gegl/gimpcageconfig.c b/app/gegl/gimpcageconfig.c
index 9fe9d51..438317c 100644
--- a/app/gegl/gimpcageconfig.c
+++ b/app/gegl/gimpcageconfig.c
@@ -71,16 +71,18 @@ print_cage (GimpCageConfig *gcc)
 
   for (i = 0; i < gcc->n_cage_vertices; i++)
     {
-      printf("cgx: %.0f    cgy: %.0f    cvdx: %.0f    cvdy: %.0f  sf: %.2f  normx: %.2f  normy: %.2f\n",
+      printf("cgx: %.0f    cgy: %.0f    cvdx: %.0f    cvdy: %.0f  sf: %.2f  normx: %.2f  normy: %.2f %s\n",
              gcc->cage_points[i].src_point.x + ((gcc->cage_mode==GIMP_CAGE_MODE_CAGE_CHANGE)?gcc->displacement_x:0),
              gcc->cage_points[i].src_point.y + ((gcc->cage_mode==GIMP_CAGE_MODE_CAGE_CHANGE)?gcc->displacement_y:0),
              gcc->cage_points[i].dest_point.x + ((gcc->cage_mode==GIMP_CAGE_MODE_DEFORM)?gcc->displacement_x:0),
              gcc->cage_points[i].dest_point.y + ((gcc->cage_mode==GIMP_CAGE_MODE_DEFORM)?gcc->displacement_y:0),
              gcc->cage_points[i].edge_scaling_factor,
              gcc->cage_points[i].edge_normal.x,
-             gcc->cage_points[i].edge_normal.y);
+             gcc->cage_points[i].edge_normal.y,
+             ((gcc->cage_points[i].selected) ? "S" : "NS"));
     }
   printf("bounding box: x: %d  y: %d  width: %d  height: %d\n", bounding_box.x, bounding_box.y, bounding_box.width, bounding_box.height);
+  printf("disp x: %f  disp y: %f\n", gcc->displacement_x, gcc->displacement_y);
   printf("done\n");
 }
 #endif
@@ -331,9 +333,9 @@ gimp_cage_config_reset_displacement (GimpCageConfig  *gcc)
  * gimp_cage_config_get_bounding_box:
  * @gcc: the cage config
  *
- * Compute the bounding box of the destination cage
+ * Compute the bounding box of the source cage
  *
- * Returns: the bounding box of the destination cage, as a GeglRectangle
+ * Returns: the bounding box of the source cage, as a GeglRectangle
  */
 GeglRectangle
 gimp_cage_config_get_bounding_box (GimpCageConfig  *gcc)
diff --git a/app/tools/gimpcagetool.c b/app/tools/gimpcagetool.c
index 379757a..bdc7ea7 100644
--- a/app/tools/gimpcagetool.c
+++ b/app/tools/gimpcagetool.c
@@ -65,6 +65,9 @@ static void       gimp_cage_tool_finalize           (GObject               *obje
 static void       gimp_cage_tool_start              (GimpCageTool          *ct,
                                                      GimpDisplay           *display);
 static void       gimp_cage_tool_halt               (GimpCageTool          *ct);
+static void       gimp_cage_tool_options_notify     (GimpTool              *tool,
+                                                     GimpToolOptions       *options,
+                                                     const GParamSpec      *pspec);
 static void       gimp_cage_tool_button_press       (GimpTool              *tool,
                                                      const GimpCoords      *coords,
                                                      guint32                time,
@@ -107,8 +110,6 @@ static gint       gimp_cage_tool_is_on_handle       (GimpCageTool          *ct,
                                                      gdouble                y,
                                                      gint                   handle_size);
 
-static void       gimp_cage_tool_switch_to_deform   (GimpCageTool          *ct,
-                                                     GimpDisplay           *display);
 static void       gimp_cage_tool_remove_last_handle (GimpCageTool          *ct);
 static void       gimp_cage_tool_compute_coef       (GimpCageTool          *ct,
                                                      GimpDisplay           *display);
@@ -118,8 +119,8 @@ static void       gimp_cage_tool_image_map_flush    (GimpImageMap          *imag
                                                      GimpTool              *tool);
 static void       gimp_cage_tool_image_map_update   (GimpCageTool          *ct);
 
-static GeglNode * gimp_cage_tool_create_render_node (GimpCageTool          *ct);
-
+static void       gimp_cage_tool_create_render_node (GimpCageTool          *ct);
+static void       gimp_cage_tool_render_node_update (GimpCageTool          *ct);
 
 G_DEFINE_TYPE (GimpCageTool, gimp_cage_tool, GIMP_TYPE_DRAW_TOOL)
 
@@ -162,6 +163,7 @@ gimp_cage_tool_class_init (GimpCageToolClass *klass)
 
   object_class->finalize     = gimp_cage_tool_finalize;
 
+  tool_class->options_notify = gimp_cage_tool_options_notify;
   tool_class->button_press   = gimp_cage_tool_button_press;
   tool_class->button_release = gimp_cage_tool_button_release;
   tool_class->key_press      = gimp_cage_tool_key_press;
@@ -193,6 +195,9 @@ gimp_cage_tool_init (GimpCageTool *self)
   self->tool_state      = CAGE_STATE_INIT;
 
   self->coef            = NULL;
+  self->render_node     = NULL;
+  self->coef_node       = NULL;
+  self->cage_node       = NULL;
   self->image_map       = NULL;
 
   gimp_tool_control_set_wants_click (tool->control, TRUE);
@@ -249,6 +254,13 @@ gimp_cage_tool_start (GimpCageTool *ct,
       ct->config = NULL;
     }
 
+  if (ct->coef)
+    {
+      gegl_buffer_destroy (ct->coef);
+      ct->dirty_coef = TRUE;
+      ct->coef = NULL;
+    }
+
   if (ct->image_map)
     {
       gimp_image_map_abort (ct->image_map);
@@ -256,6 +268,14 @@ gimp_cage_tool_start (GimpCageTool *ct,
       ct->image_map = NULL;
     }
 
+  if (ct->render_node)
+    {
+      g_object_unref (ct->render_node);
+      ct->render_node = NULL;
+      ct->coef_node   = NULL;
+      ct->cage_node   = NULL;
+    }
+
   ct->config          = g_object_new (GIMP_TYPE_CAGE_CONFIG, NULL);
   ct->hovering_handle = -1;
   ct->cage_complete   = FALSE;
@@ -272,6 +292,71 @@ gimp_cage_tool_start (GimpCageTool *ct,
   gimp_draw_tool_start (GIMP_DRAW_TOOL (ct), display);
 }
 
+static void
+gimp_cage_tool_options_notify (GimpTool         *tool,
+                               GimpToolOptions  *options,
+                               const GParamSpec *pspec)
+{
+  GimpCageTool *ct = GIMP_CAGE_TOOL (tool);
+
+  GIMP_TOOL_CLASS (parent_class)->options_notify (tool, options, pspec);
+
+  gimp_draw_tool_pause (GIMP_DRAW_TOOL (tool));
+
+  if (strcmp (pspec->name, "cage-mode") == 0)
+    {
+      GimpCageMode mode;
+
+      g_object_get (options,
+                    "cage-mode", &mode,
+                    NULL);
+
+      if (mode == GIMP_CAGE_MODE_DEFORM)
+      /* switch to deform mode */
+        {
+          ct->cage_complete = TRUE;
+          gimp_cage_config_reset_displacement (ct->config);
+          gimp_cage_config_reverse_cage_if_needed (ct->config);
+          gimp_tool_push_status (tool, tool->display, _("Press ENTER to commit the transform"));
+          ct->tool_state = DEFORM_STATE_WAIT;
+
+          if (ct->dirty_coef)
+            {
+              gimp_cage_tool_compute_coef (ct, tool->display);
+            }
+
+          if (!ct->render_node)
+            {
+              gimp_cage_tool_create_render_node (ct);
+            }
+
+          if (!ct->image_map)
+            {
+              GimpImage       *image    = gimp_display_get_image (tool->display);
+              GimpDrawable    *drawable = gimp_image_get_active_drawable (image);
+              gimp_cage_tool_create_image_map (ct, drawable);
+            }
+
+          gimp_cage_tool_image_map_update (ct);
+        }
+      else
+      /* switch to edit mode */
+        {
+          gimp_image_map_clear (ct->image_map);
+          gimp_image_flush (gimp_display_get_image (tool->display));
+          gimp_tool_pop_status (tool, tool->display);
+          ct->tool_state = CAGE_STATE_WAIT;
+        }
+    }
+  else if (strcmp  (pspec->name, "fill-plain-color") == 0)
+    {
+      gimp_cage_tool_render_node_update (ct);
+      gimp_cage_tool_image_map_update (ct);
+    }
+
+  gimp_draw_tool_resume (GIMP_DRAW_TOOL (tool));
+}
+
 static gboolean
 gimp_cage_tool_key_press (GimpTool    *tool,
                           GdkEventKey *kevent,
@@ -334,6 +419,7 @@ gimp_cage_tool_motion (GimpTool         *tool,
   switch (ct->tool_state)
     {
       case CAGE_STATE_MOVE_HANDLE:
+      case CAGE_STATE_CLOSING:
       case DEFORM_STATE_MOVE_HANDLE:
         gimp_cage_config_add_displacement (ct->config,
                                            options->cage_mode,
@@ -509,6 +595,7 @@ gimp_cage_tool_button_release (GimpTool              *tool,
                                GimpDisplay           *display)
 {
   GimpCageTool    *ct      = GIMP_CAGE_TOOL (tool);
+  GimpCageOptions *options = GIMP_CAGE_TOOL_GET_OPTIONS (ct);
 
   gimp_draw_tool_pause (GIMP_DRAW_TOOL (ct));
 
@@ -543,15 +630,20 @@ gimp_cage_tool_button_release (GimpTool              *tool,
       switch(ct->tool_state)
         {
           case CAGE_STATE_CLOSING:
-            gimp_cage_tool_switch_to_deform (ct, display);
+            ct->dirty_coef = TRUE;
+            gimp_cage_config_commit_displacement (ct->config);
+            g_object_set (options, "cage-mode", GIMP_CAGE_MODE_DEFORM, NULL);
             break;
 
           case CAGE_STATE_MOVE_HANDLE:
+            ct->dirty_coef = TRUE;
             ct->tool_state = CAGE_STATE_WAIT;
+            gimp_cage_config_commit_displacement (ct->config);
             break;
 
           case DEFORM_STATE_MOVE_HANDLE:
             ct->tool_state = DEFORM_STATE_WAIT;
+            gimp_cage_config_commit_displacement (ct->config);
             gimp_cage_tool_image_map_update (ct);
             break;
 
@@ -573,9 +665,7 @@ gimp_cage_tool_button_release (GimpTool              *tool,
                 ct->tool_state = DEFORM_STATE_WAIT;
               }
             break;
-
         }
-      gimp_cage_config_commit_displacement (ct->config);
     }
 
   gimp_draw_tool_resume (GIMP_DRAW_TOOL (tool));
@@ -629,7 +719,7 @@ gimp_cage_tool_draw (GimpDrawTool *draw_tool)
   gimp_draw_tool_push_group (draw_tool, stroke_group);
 
   /* If needed, draw ligne to the cursor. */
-  if (ct->tool_state == CAGE_STATE_WAIT || ct->tool_state == CAGE_STATE_MOVE_HANDLE)
+  if (!ct->cage_complete)
     {
       GimpVector2 last_point = gimp_cage_config_get_point_coordinate (ct->config, GIMP_CAGE_MODE_CAGE_CHANGE, n_vertices - 1);
       gimp_draw_tool_add_line (draw_tool,
@@ -767,29 +857,6 @@ gimp_cage_tool_remove_last_handle (GimpCageTool *ct)
 }
 
 static void
-gimp_cage_tool_switch_to_deform (GimpCageTool *ct,
-                                 GimpDisplay  *display)
-{
-  GimpTool        *tool     = GIMP_TOOL (ct);
-  GimpCageOptions *options  = GIMP_CAGE_TOOL_GET_OPTIONS (ct);
-  GimpImage       *image    = gimp_display_get_image (display);
-  GimpDrawable    *drawable = gimp_image_get_active_drawable (image);
-
-  ct->cage_complete = TRUE;
-
-  gimp_cage_config_reverse_cage_if_needed (ct->config);
-  gimp_cage_tool_compute_coef (ct, display);
-
-  gimp_cage_tool_create_image_map (ct, drawable);
-
-  gimp_tool_push_status (tool, display, _("Press ENTER to commit the transform"));
-
-  ct->tool_state = DEFORM_STATE_WAIT;
-
-  g_object_set (options, "cage-mode", GIMP_CAGE_MODE_DEFORM, NULL);
-}
-
-static void
 gimp_cage_tool_compute_coef (GimpCageTool *ct,
                              GimpDisplay  *display)
 {
@@ -862,10 +929,12 @@ gimp_cage_tool_compute_coef (GimpCageTool *ct,
   ct->coef = buffer;
   g_object_unref (gegl);
 
+  ct->dirty_coef = FALSE;
+
   gimp_display_shell_remove_item (shell, p);
 }
 
-static GeglNode *
+static void
 gimp_cage_tool_create_render_node (GimpCageTool *ct)
 {
   GimpCageOptions *options  = GIMP_CAGE_TOOL_GET_OPTIONS (ct);
@@ -873,6 +942,9 @@ gimp_cage_tool_create_render_node (GimpCageTool *ct)
   GeglNode        *input, *output; /* Proxy nodes*/
   GeglNode        *node; /* wraper to be returned */
 
+  g_return_if_fail (ct->render_node == NULL);
+  /* render_node is not supposed to be recreated */
+
   node = gegl_node_new ();
 
   input  = gegl_node_get_input_proxy  (node, "input");
@@ -908,25 +980,58 @@ gimp_cage_tool_create_render_node (GimpCageTool *ct)
   gegl_node_connect_to (render, "output",
                         output, "input");
 
-  return node;
+  ct->render_node = node;
+  ct->cage_node = cage;
+  ct->coef_node = coef;
+}
+
+static void
+gimp_cage_tool_render_node_update (GimpCageTool *ct)
+{
+  GimpCageOptions *options  = GIMP_CAGE_TOOL_GET_OPTIONS (ct);
+  gboolean         option_fill, node_fill;
+  GeglBuffer      *buffer;
+
+  g_object_get (options,
+                "fill-plain-color", &option_fill,
+                NULL);
+
+  gegl_node_get (ct->cage_node,
+                 "fill-plain-color", &node_fill,
+                 NULL);
+
+  if (option_fill != node_fill)
+    {
+      gegl_node_set (ct->cage_node,
+                     "fill_plain_color", option_fill,
+                     NULL);
+    }
+
+  gegl_node_get (ct->coef_node,
+                 "buffer", &buffer,
+                 NULL);
+
+  if (option_fill != node_fill)
+    {
+      gegl_node_set (ct->coef_node,
+                     "buffer",  ct->coef,
+                     NULL);
+    }
 }
 
 static void
 gimp_cage_tool_create_image_map (GimpCageTool *ct,
                                  GimpDrawable *drawable)
 {
-  GeglNode *node;
-
-  node = gimp_cage_tool_create_render_node (ct);
+  if (!ct->render_node)
+    gimp_cage_tool_create_render_node (ct);
 
   ct->image_map = gimp_image_map_new (drawable,
                                       _("Cage transform"),
-                                      node,
+                                      ct->render_node,
                                       NULL,
                                       NULL);
 
-  g_object_unref (node);
-
   g_signal_connect (ct->image_map, "flush",
                     G_CALLBACK (gimp_cage_tool_image_map_flush),
                     ct);
@@ -997,6 +1102,14 @@ gimp_cage_tool_halt (GimpCageTool *ct)
       ct->coef = NULL;
     }
 
+  if (ct->render_node)
+    {
+      g_object_unref (ct->render_node);
+      ct->render_node = NULL;
+      ct->coef_node   = NULL;
+      ct->cage_node   = NULL;
+    }
+
   if (ct->image_map)
     {
       gimp_tool_control_set_preserve (tool->control, TRUE);
diff --git a/app/tools/gimpcagetool.h b/app/tools/gimpcagetool.h
index 3ea6f60..4e0e8bf 100644
--- a/app/tools/gimpcagetool.h
+++ b/app/tools/gimpcagetool.h
@@ -60,6 +60,11 @@ struct _GimpCageTool
   gboolean        cage_complete; /* Cage closed or not */
 
   GeglBuffer     *coef; /* Gegl where the coefficient of the transformation are stored */
+  gboolean        dirty_coef; /* Indicate if the coef are still valid */
+
+  GeglNode       *render_node; /* Gegl node graph to render the transfromation */
+  GeglNode       *cage_node; /* Gegl node that compute the cage transform */
+  GeglNode       *coef_node; /* Gegl node that read in the coef buffer */
 
   gint            tool_state; /* Current state in statemachine */
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]