[gimp/soc-2010-cage-2] Cage tool: add rubber band selection for deform mode



commit bd5f13d2a341aec1a98172e70b309420d495f099
Author: Michael Muré <batolettre gmail com>
Date:   Mon Jan 10 14:55:38 2011 +0100

    Cage tool: add rubber band selection for deform mode

 app/gegl/gimpcageconfig.c |   63 ++++++++++++++++++++++++++++++++++++++++++++-
 app/gegl/gimpcageconfig.h |    8 +++++-
 app/tools/gimpcagetool.c  |   43 ++++++++++++++++++++++++++++++
 app/tools/gimpcagetool.h  |    3 ++
 4 files changed, 115 insertions(+), 2 deletions(-)
---
diff --git a/app/gegl/gimpcageconfig.c b/app/gegl/gimpcageconfig.c
index c61b805..723530b 100644
--- a/app/gegl/gimpcageconfig.c
+++ b/app/gegl/gimpcageconfig.c
@@ -592,6 +592,67 @@ gimp_cage_config_select_point (GimpCageConfig  *gcc,
 }
 
 /**
+ * gimp_cage_config_select_area:
+ * @gcc: the cage config
+ * @mode: the actual mode of the cage, GIMP_CAGE_MODE_CAGE_CHANGE or GIMP_CAGE_MODE_DEFORM
+ * @area: the area to select
+ *
+ * Select cage's point inside the given area and deselect others
+ */
+void
+gimp_cage_config_select_area  (GimpCageConfig  *gcc,
+                               GimpCageMode     mode,
+                               GeglRectangle    area)
+{
+  g_return_if_fail (GIMP_IS_CAGE_CONFIG (gcc));
+
+  gimp_cage_config_deselect_points (gcc);
+  gimp_cage_config_select_add_area (gcc, mode, area);
+}
+
+/**
+ * gimp_cage_config_select_add_area:
+ * @gcc: the cage config
+ * @mode: the actual mode of the cage, GIMP_CAGE_MODE_CAGE_CHANGE or GIMP_CAGE_MODE_DEFORM
+ * @area: the area to select
+ *
+ * Select cage's point inside the given area. Already selected point stay selected.
+ */
+void
+gimp_cage_config_select_add_area  (GimpCageConfig  *gcc,
+                                   GimpCageMode     mode,
+                                   GeglRectangle    area)
+{
+  gint  i;
+
+  g_return_if_fail (GIMP_IS_CAGE_CONFIG (gcc));
+
+  for (i = 0; i < gcc->n_cage_vertices; i++)
+    {
+      if (mode == GIMP_CAGE_MODE_CAGE_CHANGE)
+        {
+          if (gcc->cage_points[i].src_point.x >= area.x &&
+              gcc->cage_points[i].src_point.x <= area.x + area.width &&
+              gcc->cage_points[i].src_point.y >= area.y &&
+              gcc->cage_points[i].src_point.y <= area.y + area.height)
+            {
+              gcc->cage_points[i].selected = TRUE;
+            }
+        }
+      else
+        {
+          if (gcc->cage_points[i].dest_point.x >= area.x &&
+              gcc->cage_points[i].dest_point.x <= area.x + area.width &&
+              gcc->cage_points[i].dest_point.y >= area.y &&
+              gcc->cage_points[i].dest_point.y <= area.y + area.height)
+            {
+              gcc->cage_points[i].selected = TRUE;
+            }
+        }
+    }
+}
+
+/**
  * gimp_cage_config_toggle_point_selection:
  * @gcc: the cage config
  * @point_number: the index of the point to toggle selection
@@ -616,7 +677,7 @@ gimp_cage_config_toggle_point_selection (GimpCageConfig  *gcc,
  * Deselect all cage points.
  */
 void
-gimp_cage_deselect_points (GimpCageConfig  *gcc)
+gimp_cage_config_deselect_points (GimpCageConfig  *gcc)
 {
   gint  i;
 
diff --git a/app/gegl/gimpcageconfig.h b/app/gegl/gimpcageconfig.h
index f26f493..42812c9 100644
--- a/app/gegl/gimpcageconfig.h
+++ b/app/gegl/gimpcageconfig.h
@@ -76,8 +76,14 @@ gboolean        gimp_cage_config_point_inside           (GimpCageConfig  *gcc,
                                                          gfloat           y);
 void            gimp_cage_config_select_point           (GimpCageConfig  *gcc,
                                                          gint             point_number);
+void            gimp_cage_config_select_area            (GimpCageConfig  *gcc,
+                                                         GimpCageMode     mode,
+                                                         GeglRectangle    area);
+void            gimp_cage_config_select_add_area        (GimpCageConfig  *gcc,
+                                                         GimpCageMode     mode,
+                                                         GeglRectangle    area);
 void            gimp_cage_config_toggle_point_selection (GimpCageConfig  *gcc,
                                                          gint             point_number);
-void            gimp_cage_deselect_points               (GimpCageConfig  *gcc);
+void            gimp_cage_config_deselect_points        (GimpCageConfig  *gcc);
 
 #endif /* __GIMP_CAGE_CONFIG_H__ */
diff --git a/app/tools/gimpcagetool.c b/app/tools/gimpcagetool.c
index ba97ac4..d10be25 100644
--- a/app/tools/gimpcagetool.c
+++ b/app/tools/gimpcagetool.c
@@ -20,6 +20,7 @@
 #include "config.h"
 
 #include <string.h>
+#include <stdlib.h>
 
 #include <gegl.h>
 #include <gtk/gtk.h>
@@ -132,6 +133,7 @@ enum
   CAGE_STATE_CLOSING,
   DEFORM_STATE_WAIT,
   DEFORM_STATE_MOVE_HANDLE,
+  DEFORM_STATE_SELECTING
 };
 
 void
@@ -469,6 +471,13 @@ gimp_cage_tool_button_press (GimpTool            *tool,
         break;
 
       case DEFORM_STATE_WAIT:
+        if (handle == -1)
+        /* User clicked on the background, we start a rubber band selection */
+          {
+            ct->selection_start_x = coords->x;
+            ct->selection_start_y = coords->y;
+            ct->tool_state = DEFORM_STATE_SELECTING;
+          }
         if (handle >= 0)
         /* User clicked on a handle, so we move it */
           {
@@ -521,6 +530,10 @@ gimp_cage_tool_button_release (GimpTool              *tool,
             gimp_cage_tool_image_map_update (ct);
             ct->tool_state = DEFORM_STATE_WAIT;
             break;
+
+          case DEFORM_STATE_SELECTING:
+            ct->tool_state = DEFORM_STATE_WAIT;
+            break;
         }
       gimp_cage_config_reset_displacement (ct->config);
     }
@@ -541,6 +554,26 @@ gimp_cage_tool_button_release (GimpTool              *tool,
             ct->tool_state = DEFORM_STATE_WAIT;
             gimp_cage_tool_image_map_update (ct);
             break;
+
+          case DEFORM_STATE_SELECTING:
+              {
+                GeglRectangle area = {MIN(ct->selection_start_x, coords->x),
+                                      MIN(ct->selection_start_y, coords->y),
+                                      abs (ct->selection_start_x - coords->x),
+                                      abs (ct->selection_start_y - coords->y)};
+
+                if (state & GDK_SHIFT_MASK)
+                  {
+                    gimp_cage_config_select_add_area (ct->config, GIMP_CAGE_MODE_DEFORM, area);
+                  }
+                else
+                  {
+                    gimp_cage_config_select_area (ct->config, GIMP_CAGE_MODE_DEFORM, area);
+                  }
+                ct->tool_state = DEFORM_STATE_WAIT;
+              }
+            break;
+
         }
       gimp_cage_config_commit_displacement (ct->config);
     }
@@ -669,6 +702,16 @@ gimp_cage_tool_draw (GimpDrawTool *draw_tool)
                            GIMP_HANDLE_ANCHOR_CENTER);
         }
     }
+
+  if (ct->tool_state == DEFORM_STATE_SELECTING)
+    {
+      gimp_draw_tool_add_rectangle (draw_tool,
+                                    FALSE,
+                                    MIN(ct->selection_start_x, ct->cursor_x),
+                                    MIN(ct->selection_start_y, ct->cursor_y),
+                                    abs (ct->selection_start_x - ct->cursor_x),
+                                    abs (ct->selection_start_y - ct->cursor_y));
+    }
 }
 
 static gint
diff --git a/app/tools/gimpcagetool.h b/app/tools/gimpcagetool.h
index bc35fb0..3ea6f60 100644
--- a/app/tools/gimpcagetool.h
+++ b/app/tools/gimpcagetool.h
@@ -53,6 +53,9 @@ struct _GimpCageTool
   gdouble         movement_start_x; /* Where the movement started */
   gdouble         movement_start_y; /* Where the movement started */
 
+  gdouble         selection_start_x; /* Where the selection started */
+  gdouble         selection_start_y; /* Where the selection started */
+
   gint            hovering_handle; /* Handle which the cursor is above */
   gboolean        cage_complete; /* Cage closed or not */
 



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