[gimp] app: implement a few more functions for the ToolPath context menu.



commit c10778fa034554d2820477dd2b3e0e2067d2680f
Author: Simon Budig <simon budig de>
Date:   Mon May 25 22:12:02 2020 +0200

    app: implement a few more functions for the ToolPath context menu.

 app/actions/vector-toolpath-actions.c  |  32 ++++++-
 app/actions/vector-toolpath-commands.c |  40 +++++++++
 app/actions/vector-toolpath-commands.h |  13 +++
 app/display/gimptoolpath.c             | 159 +++++++++++++++++++++++++++++++--
 app/display/gimptoolpath.h             |   8 ++
 app/display/gimptoolwidget.c           |   4 +-
 app/display/gimptoolwidget.h           |   2 -
 app/tools/gimpvectortool.c             |   2 +-
 menus/vector-toolpath-menu.xml         |   6 +-
 9 files changed, 250 insertions(+), 16 deletions(-)
---
diff --git a/app/actions/vector-toolpath-actions.c b/app/actions/vector-toolpath-actions.c
index 7c59b43a3e..213db37498 100644
--- a/app/actions/vector-toolpath-actions.c
+++ b/app/actions/vector-toolpath-actions.c
@@ -41,10 +41,27 @@
 
 static const GimpActionEntry vector_toolpath_actions[] =
 {
-  { "vector-tool-popup", NULL,
+  { "vector-toolpath-popup", NULL,
     NC_("vector-toolpath-action", "Vector Toolpath Menu"), NULL, NULL, NULL,
     NULL },
 
+  { "vector-toolpath-delete-anchor", GIMP_ICON_PATH,
+    NC_("vector-toolpath-action", "_Delete Anchor"), NULL, NULL,
+    vector_toolpath_delete_anchor_cmd_callback,
+    NULL },
+  { "vector-toolpath-shift-start", GIMP_ICON_PATH,
+    NC_("vector-toolpath-action", "Shift S_tart"), NULL, NULL,
+    vector_toolpath_shift_start_cmd_callback,
+    NULL },
+
+  { "vector-toolpath-insert-anchor", GIMP_ICON_PATH,
+    NC_("vector-toolpath-action", "_Insert Anchor"), NULL, NULL,
+    vector_toolpath_insert_anchor_cmd_callback,
+    NULL },
+  { "vector-toolpath-delete-segment", GIMP_ICON_PATH,
+    NC_("vector-toolpath-action", "Delete _Segment"), NULL, NULL,
+    vector_toolpath_delete_segment_cmd_callback,
+    NULL },
   { "vector-toolpath-reverse-stroke", GIMP_ICON_PATH,
     NC_("vector-toolpath-action", "_Reverse Stroke"), NULL, NULL,
     vector_toolpath_reverse_stroke_cmd_callback,
@@ -64,7 +81,7 @@ vector_toolpath_actions_setup (GimpActionGroup *group)
 }
 
 /* The following code is written on the assumption that this is for a
- * context menu, activated by right-clicking in a text layer.
+ * context menu, activated by right-clicking on a toolpath vectors widget.
  * Therefore, the tool must have a display.  If for any reason the
  * code is adapted to a different situation, some existence testing
  * will need to be added.
@@ -74,6 +91,9 @@ vector_toolpath_actions_update (GimpActionGroup *group,
                                 gpointer         data)
 {
   GimpToolPath *toolpath = GIMP_TOOL_PATH (data);
+  gboolean on_handle, on_curve;
+
+  gimp_tool_path_get_popup_state (toolpath, &on_handle, &on_curve);
 
 #define SET_VISIBLE(action,condition) \
         gimp_action_group_set_action_visible (group, action, (condition) != 0)
@@ -82,5 +102,11 @@ vector_toolpath_actions_update (GimpActionGroup *group,
 #define SET_ACTIVE(action,condition) \
         gimp_action_group_set_action_active (group, action, (condition) != 0)
 
-  SET_SENSITIVE ("vector-toolpath-reverse-stroke", TRUE);
+  SET_VISIBLE ("vector-toolpath-shift-start",    on_handle);
+  SET_VISIBLE ("vector-toolpath-delete-anchor",  on_handle);
+
+  SET_VISIBLE ("vector-toolpath-insert-anchor",  !on_handle && on_curve);
+  SET_VISIBLE ("vector-toolpath-delete-segment", !on_handle && on_curve);
+  SET_VISIBLE ("vector-toolpath-reverse-stroke", on_curve);
+
 }
diff --git a/app/actions/vector-toolpath-commands.c b/app/actions/vector-toolpath-commands.c
index 220e35ab38..8ea1c412c2 100644
--- a/app/actions/vector-toolpath-commands.c
+++ b/app/actions/vector-toolpath-commands.c
@@ -44,6 +44,46 @@
 
 /*  public functions  */
 
+void
+vector_toolpath_delete_anchor_cmd_callback (GimpAction *action,
+                                            GVariant   *value,
+                                            gpointer    data)
+{
+  GimpToolPath *tool_path = GIMP_TOOL_PATH (data);
+
+  gimp_tool_path_delete_anchor (tool_path);
+}
+
+void
+vector_toolpath_shift_start_cmd_callback (GimpAction *action,
+                                          GVariant   *value,
+                                          gpointer    data)
+{
+  GimpToolPath *tool_path = GIMP_TOOL_PATH (data);
+
+  gimp_tool_path_shift_start (tool_path);
+}
+
+void
+vector_toolpath_insert_anchor_cmd_callback (GimpAction *action,
+                                            GVariant   *value,
+                                            gpointer    data)
+{
+  GimpToolPath *tool_path = GIMP_TOOL_PATH (data);
+
+  gimp_tool_path_insert_anchor (tool_path);
+}
+
+void
+vector_toolpath_delete_segment_cmd_callback (GimpAction *action,
+                                             GVariant   *value,
+                                             gpointer    data)
+{
+  GimpToolPath *tool_path = GIMP_TOOL_PATH (data);
+
+  gimp_tool_path_delete_segment (tool_path);
+}
+
 void
 vector_toolpath_reverse_stroke_cmd_callback (GimpAction *action,
                                              GVariant   *value,
diff --git a/app/actions/vector-toolpath-commands.h b/app/actions/vector-toolpath-commands.h
index 9a14b34170..552fa78011 100644
--- a/app/actions/vector-toolpath-commands.h
+++ b/app/actions/vector-toolpath-commands.h
@@ -19,6 +19,19 @@
 #define __VECTOR_TOOLPATH_COMMANDS_H__
 
 
+void   vector_toolpath_delete_anchor_cmd_callback  (GimpAction *action,
+                                                    GVariant   *value,
+                                                    gpointer    data);
+void   vector_toolpath_shift_start_cmd_callback    (GimpAction *action,
+                                                    GVariant   *value,
+                                                    gpointer    data);
+
+void   vector_toolpath_insert_anchor_cmd_callback  (GimpAction *action,
+                                                    GVariant   *value,
+                                                    gpointer    data);
+void   vector_toolpath_delete_segment_cmd_callback (GimpAction *action,
+                                                    GVariant   *value,
+                                                    gpointer    data);
 void   vector_toolpath_reverse_stroke_cmd_callback (GimpAction *action,
                                                     GVariant   *value,
                                                     gpointer    data);
diff --git a/app/display/gimptoolpath.c b/app/display/gimptoolpath.c
index a28f82f6d9..2a1681d92e 100644
--- a/app/display/gimptoolpath.c
+++ b/app/display/gimptoolpath.c
@@ -129,6 +129,10 @@ struct _GimpToolPathPrivate
   GList                *items;
 
   GimpUIManager        *ui_manager;
+  gboolean              popup_on_handle;
+  GimpAnchor           *popup_handle;
+  GimpStroke           *popup_stroke;
+  gdouble               popup_position;
 };
 
 
@@ -179,7 +183,6 @@ static gboolean gimp_tool_path_get_cursor      (GimpToolWidget        *widget,
 static GimpUIManager * gimp_tool_path_get_popup (GimpToolWidget       *widget,
                                                 const GimpCoords      *coords,
                                                 GdkModifierType        state,
-                                                GimpDisplay           *display,
                                                 const gchar          **ui_path);
 
 static GimpVectorFunction
@@ -1289,11 +1292,12 @@ static GimpUIManager *
 gimp_tool_path_get_popup (GimpToolWidget    *widget,
                           const GimpCoords  *coords,
                           GdkModifierType    state,
-                          GimpDisplay       *display,
                           const gchar      **ui_path)
 {
   GimpToolPath        *path    = GIMP_TOOL_PATH (widget);
   GimpToolPathPrivate *private = path->private;
+  gboolean on_handle = FALSE;
+  gboolean on_curve  = FALSE;
 
   if (!private->ui_manager)
     {
@@ -1310,9 +1314,48 @@ gimp_tool_path_get_popup (GimpToolWidget    *widget,
                                        widget);
     }
 
-  gimp_ui_manager_update (private->ui_manager, widget);
-  *ui_path = "/vector-toolpath-popup";
-  return private->ui_manager;
+  private->popup_on_handle = FALSE;
+  private->popup_handle = NULL;
+  private->popup_stroke = NULL;
+  private->popup_position = 0.0;
+
+  if (private->vectors)
+    {
+      on_handle = gimp_canvas_item_on_vectors_handle (private->path,
+                                                      private->vectors,
+                                                      coords,
+                                                      GIMP_CANVAS_HANDLE_SIZE_CIRCLE,
+                                                      GIMP_CANVAS_HANDLE_SIZE_CIRCLE,
+                                                      GIMP_ANCHOR_ANCHOR,
+                                                      private->sel_count > 2,
+                                                      &private->popup_handle,
+                                                      &private->popup_stroke);
+
+      if (! on_handle)
+        on_curve = gimp_canvas_item_on_vectors_curve (private->path,
+                                                      private->vectors,
+                                                      coords,
+                                                      GIMP_CANVAS_HANDLE_SIZE_CIRCLE,
+                                                      GIMP_CANVAS_HANDLE_SIZE_CIRCLE,
+                                                      NULL,
+                                                      &private->popup_position,
+                                                      &private->popup_handle,
+                                                      NULL,
+                                                      &private->popup_stroke);
+    }
+
+  if (on_handle)
+    private->popup_on_handle = TRUE;
+
+  if (on_handle || on_curve)
+    {
+      gimp_ui_manager_update (private->ui_manager, widget);
+
+      *ui_path = "/vector-toolpath-popup";
+      return private->ui_manager;
+    }
+
+  return NULL;
 }
 
 
@@ -1977,8 +2020,112 @@ gimp_tool_path_set_vectors (GimpToolPath *path,
   g_object_notify (G_OBJECT (path), "vectors");
 }
 
+void
+gimp_tool_path_get_popup_state (GimpToolPath *path,
+                                gboolean     *on_handle,
+                                gboolean     *on_curve)
+{
+  GimpToolPathPrivate *private = path->private;
+
+  if (on_handle)
+    *on_handle = private->popup_on_handle;
+
+  if (on_curve)
+    *on_curve = private->popup_stroke != NULL;
+
+}
+
+void
+gimp_tool_path_delete_anchor (GimpToolPath *path)
+{
+  GimpToolPathPrivate *private = path->private;
+  g_return_if_fail (private->popup_stroke != NULL);
+  g_return_if_fail (private->popup_handle != NULL);
+
+  gimp_vectors_freeze (private->vectors);
+  gimp_tool_path_begin_change (path, _("Delete Anchors"));
+  if (private->popup_handle->type == GIMP_ANCHOR_ANCHOR)
+    {
+      gimp_stroke_anchor_delete (private->popup_stroke, private->popup_handle);
+      if (gimp_stroke_is_empty (private->popup_stroke))
+        gimp_vectors_stroke_remove (private->vectors,
+                                    private->popup_stroke);
+    }
+  else
+    {
+      gimp_stroke_anchor_convert (private->popup_stroke,
+                                  private->popup_handle,
+                                  GIMP_ANCHOR_FEATURE_EDGE);
+    }
+
+  gimp_tool_path_end_change (path, TRUE);
+  gimp_vectors_thaw (private->vectors);
+}
+
+void
+gimp_tool_path_shift_start (GimpToolPath *path)
+{
+  GimpToolPathPrivate *private = path->private;
+  g_return_if_fail (private->popup_stroke != NULL);
+  g_return_if_fail (private->popup_handle != NULL);
+
+  gimp_vectors_freeze (private->vectors);
+  gimp_tool_path_begin_change (path, _("Shift start"));
+  gimp_stroke_shift_start (private->popup_stroke, private->popup_handle);
+  gimp_tool_path_end_change (path, TRUE);
+  gimp_vectors_thaw (private->vectors);
+}
+
+void
+gimp_tool_path_insert_anchor (GimpToolPath *path)
+{
+  GimpToolPathPrivate *private = path->private;
+  g_return_if_fail (private->popup_stroke != NULL);
+  g_return_if_fail (private->popup_handle != NULL);
+
+  gimp_vectors_freeze (private->vectors);
+  gimp_tool_path_begin_change (path, _("Insert Anchor"));
+  private->cur_anchor = gimp_stroke_anchor_insert (private->popup_stroke,
+                                                   private->popup_handle,
+                                                   private->popup_position);
+  gimp_tool_path_end_change (path, TRUE);
+  gimp_vectors_thaw (private->vectors);
+}
+
+void
+gimp_tool_path_delete_segment (GimpToolPath *path)
+{
+  GimpToolPathPrivate *private = path->private;
+  GimpStroke *new_stroke;
+
+  g_return_if_fail (private->popup_stroke != NULL);
+  g_return_if_fail (private->popup_handle != NULL);
+
+  gimp_vectors_freeze (private->vectors);
+
+  gimp_tool_path_begin_change (path, _("Delete Segment"));
+
+  new_stroke = gimp_stroke_open (private->popup_stroke,
+                                 private->popup_handle);
+  if (new_stroke)
+    {
+      gimp_vectors_stroke_add (private->vectors, new_stroke);
+      g_object_unref (new_stroke);
+    }
+  gimp_tool_path_end_change (path, TRUE);
+  gimp_vectors_thaw (private->vectors);
+}
+
 void
 gimp_tool_path_reverse_stroke (GimpToolPath *path)
 {
-  g_printerr ("REVERSE_STROKE\n");
+  GimpToolPathPrivate *private = path->private;
+
+  g_return_if_fail (private->popup_stroke != NULL);
+
+  gimp_vectors_freeze (private->vectors);
+  gimp_tool_path_begin_change (path, _("Insert Anchor"));
+  gimp_stroke_reverse (private->popup_stroke);
+  gimp_tool_path_end_change (path, TRUE);
+  gimp_vectors_thaw (private->vectors);
 }
diff --git a/app/display/gimptoolpath.h b/app/display/gimptoolpath.h
index b51f00d67a..268f116086 100644
--- a/app/display/gimptoolpath.h
+++ b/app/display/gimptoolpath.h
@@ -64,6 +64,14 @@ GimpToolWidget * gimp_tool_path_new         (GimpDisplayShell *shell);
 void             gimp_tool_path_set_vectors (GimpToolPath     *path,
                                              GimpVectors      *vectors);
 
+void             gimp_tool_path_get_popup_state (GimpToolPath *path,
+                                                 gboolean     *on_handle,
+                                                 gboolean     *on_curve);
+
+void             gimp_tool_path_delete_anchor  (GimpToolPath *path);
+void             gimp_tool_path_shift_start    (GimpToolPath *path);
+void             gimp_tool_path_insert_anchor  (GimpToolPath *path);
+void             gimp_tool_path_delete_segment (GimpToolPath *path);
 void             gimp_tool_path_reverse_stroke (GimpToolPath *path);
 
 #endif /* __GIMP_TOOL_PATH_H__ */
diff --git a/app/display/gimptoolwidget.c b/app/display/gimptoolwidget.c
index 952240a9a8..3f2c590304 100644
--- a/app/display/gimptoolwidget.c
+++ b/app/display/gimptoolwidget.c
@@ -1089,7 +1089,6 @@ GimpUIManager *
 gimp_tool_widget_get_popup (GimpToolWidget        *widget,
                             const GimpCoords      *coords,
                             GdkModifierType        state,
-                            GimpDisplay           *display,
                             const gchar          **ui_path)
 {
   g_return_val_if_fail (GIMP_IS_TOOL_WIDGET (widget), FALSE);
@@ -1099,8 +1098,7 @@ gimp_tool_widget_get_popup (GimpToolWidget        *widget,
       GIMP_TOOL_WIDGET_GET_CLASS (widget)->get_popup)
     {
       return GIMP_TOOL_WIDGET_GET_CLASS (widget)->get_popup (widget, coords,
-                                                             state, display,
-                                                             ui_path);
+                                                             state, ui_path);
     }
 
   return NULL;
diff --git a/app/display/gimptoolwidget.h b/app/display/gimptoolwidget.h
index 241488095c..ceb1a2a1cc 100644
--- a/app/display/gimptoolwidget.h
+++ b/app/display/gimptoolwidget.h
@@ -124,7 +124,6 @@ struct _GimpToolWidgetClass
            (* get_popup)       (GimpToolWidget        *widget,
                                 const GimpCoords      *coords,
                                 GdkModifierType        state,
-                                GimpDisplay           *display,
                                 const gchar          **ui_path);
 };
 
@@ -321,7 +320,6 @@ GimpUIManager *
            gimp_tool_widget_get_popup       (GimpToolWidget        *widget,
                                              const GimpCoords      *coords,
                                              GdkModifierType        state,
-                                             GimpDisplay           *display,
                                              const gchar          **ui_path);
 
 #endif /* __GIMP_TOOL_WIDGET_H__ */
diff --git a/app/tools/gimpvectortool.c b/app/tools/gimpvectortool.c
index 60ddde8b8c..4662f4c07c 100644
--- a/app/tools/gimpvectortool.c
+++ b/app/tools/gimpvectortool.c
@@ -403,7 +403,7 @@ gimp_vector_tool_get_popup (GimpTool         *tool,
     }
 
   return gimp_tool_widget_get_popup (GIMP_TOOL_WIDGET (vector_tool->widget),
-                                     coords, state, display, ui_path);
+                                     coords, state, ui_path);
 }
 
 static void
diff --git a/menus/vector-toolpath-menu.xml b/menus/vector-toolpath-menu.xml
index 1a7605bc7e..e82eaca520 100644
--- a/menus/vector-toolpath-menu.xml
+++ b/menus/vector-toolpath-menu.xml
@@ -3,7 +3,11 @@
 
 <ui>
   <popup action="vector-toolpath-popup">
-    <menuitem action="vector-toolpath-reverse-stroke" />
+    <menuitem action="vector-toolpath-delete-anchor" />
+    <menuitem action="vector-toolpath-shift-start" />
     <separator />
+    <menuitem action="vector-toolpath-insert-anchor" />
+    <menuitem action="vector-toolpath-delete-segment" />
+    <menuitem action="vector-toolpath-reverse-stroke" />
   </popup>
 </ui>


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