[gimp] app: in GimpTransformGridTool, compress successive undo steps



commit b0e9639684f1b613c55ecef45898d3de08513ebc
Author: Ell <ell_se yahoo com>
Date:   Mon Jan 6 12:00:27 2020 +0200

    app: in GimpTransformGridTool, compress successive undo steps
    
    Add a boolean 'compress' parameter to
    gimp_transform_grid_tool_push_internal_undo().  When TRUE,
    successive undo steps added rapidly are compressed into a single
    step.
    
    In the various subclasses, compress undo steps for dialog changes,
    since we push an undo step for every intermediate change for those
    (such as while dragging a spin-scale).  In contrast, we only push
    tool-widget undo steps upon button release, hence there's no need
    to compress them.

 app/tools/gimprotatetool.c        |  4 ++--
 app/tools/gimpscaletool.c         |  2 +-
 app/tools/gimpsheartool.c         |  4 ++--
 app/tools/gimptransformgridtool.c | 31 ++++++++++++++++++++++---------
 app/tools/gimptransformgridtool.h |  3 ++-
 5 files changed, 29 insertions(+), 15 deletions(-)
---
diff --git a/app/tools/gimprotatetool.c b/app/tools/gimprotatetool.c
index 8e8c561f9b..27114e5459 100644
--- a/app/tools/gimprotatetool.c
+++ b/app/tools/gimprotatetool.c
@@ -464,7 +464,7 @@ rotate_angle_changed (GtkAdjustment         *adj,
 
       tg_tool->trans_info[ANGLE] = value;
 
-      gimp_transform_grid_tool_push_internal_undo (tg_tool);
+      gimp_transform_grid_tool_push_internal_undo (tg_tool, TRUE);
 
       gimp_transform_tool_recalc_matrix (tr_tool, tool->display);
     }
@@ -486,7 +486,7 @@ rotate_center_changed (GtkWidget             *widget,
       tg_tool->trans_info[PIVOT_X] = px;
       tg_tool->trans_info[PIVOT_Y] = py;
 
-      gimp_transform_grid_tool_push_internal_undo (tg_tool);
+      gimp_transform_grid_tool_push_internal_undo (tg_tool, TRUE);
 
       gimp_transform_tool_recalc_matrix (tr_tool, tool->display);
     }
diff --git a/app/tools/gimpscaletool.c b/app/tools/gimpscaletool.c
index dacea95046..b7fcd96bbc 100644
--- a/app/tools/gimpscaletool.c
+++ b/app/tools/gimpscaletool.c
@@ -443,7 +443,7 @@ gimp_scale_tool_size_notify (GtkWidget             *box,
               tg_tool->trans_info[Y1] = tg_tool->trans_info[Y0] + height;
             }
 
-          gimp_transform_grid_tool_push_internal_undo (tg_tool);
+          gimp_transform_grid_tool_push_internal_undo (tg_tool, TRUE);
 
           gimp_transform_tool_recalc_matrix (tr_tool, tool->display);
         }
diff --git a/app/tools/gimpsheartool.c b/app/tools/gimpsheartool.c
index d00ec42a46..c90a3d84e1 100644
--- a/app/tools/gimpsheartool.c
+++ b/app/tools/gimpsheartool.c
@@ -300,7 +300,7 @@ shear_x_mag_changed (GtkAdjustment         *adj,
       tg_tool->trans_info[SHEAR_X] = value;
       tg_tool->trans_info[SHEAR_Y] = 0.0;  /* can only shear in one axis */
 
-      gimp_transform_grid_tool_push_internal_undo (tg_tool);
+      gimp_transform_grid_tool_push_internal_undo (tg_tool, TRUE);
 
       gimp_transform_tool_recalc_matrix (tr_tool, tool->display);
     }
@@ -322,7 +322,7 @@ shear_y_mag_changed (GtkAdjustment         *adj,
       tg_tool->trans_info[SHEAR_Y] = value;
       tg_tool->trans_info[SHEAR_X] = 0.0;  /* can only shear in one axis */
 
-      gimp_transform_grid_tool_push_internal_undo (tg_tool);
+      gimp_transform_grid_tool_push_internal_undo (tg_tool, TRUE);
 
       gimp_transform_tool_recalc_matrix (tr_tool, tool->display);
     }
diff --git a/app/tools/gimptransformgridtool.c b/app/tools/gimptransformgridtool.c
index 68311259db..d7f745dc1e 100644
--- a/app/tools/gimptransformgridtool.c
+++ b/app/tools/gimptransformgridtool.c
@@ -61,12 +61,15 @@
 #define EPSILON 1e-6
 
 
-#define RESPONSE_RESET    1
-#define RESPONSE_READJUST 2
+#define RESPONSE_RESET     1
+#define RESPONSE_READJUST  2
+
+#define UNDO_COMPRESS_TIME (0.5 * G_TIME_SPAN_SECOND)
 
 
 typedef struct
 {
+  gint64                 time;
   GimpTransformDirection direction;
   TransInfo              trans_infos[2];
 } UndoInfo;
@@ -399,7 +402,7 @@ gimp_transform_grid_tool_button_release (GimpTool              *tool,
   if (release_type != GIMP_BUTTON_RELEASE_CANCEL)
     {
       /* We're done with an interaction, save it on the undo list */
-      gimp_transform_grid_tool_push_internal_undo (tg_tool);
+      gimp_transform_grid_tool_push_internal_undo (tg_tool, FALSE);
     }
   else
     {
@@ -1289,7 +1292,7 @@ gimp_transform_grid_tool_response (GimpToolGui           *gui,
         tg_options->direction_linked = direction_linked;
 
         /*  push the restored info to the undo stack  */
-        gimp_transform_grid_tool_push_internal_undo (tg_tool);
+        gimp_transform_grid_tool_push_internal_undo (tg_tool, FALSE);
       }
       break;
 
@@ -1355,7 +1358,7 @@ gimp_transform_grid_tool_response (GimpToolGui           *gui,
           if (transform_valid)
             {
               /*  push the new info to the undo stack  */
-              gimp_transform_grid_tool_push_internal_undo (tg_tool);
+              gimp_transform_grid_tool_push_internal_undo (tg_tool, FALSE);
             }
           else
             {
@@ -1598,7 +1601,8 @@ gimp_transform_grid_tool_matrix_to_info (GimpTransformGridTool *tg_tool,
 }
 
 void
-gimp_transform_grid_tool_push_internal_undo (GimpTransformGridTool *tg_tool)
+gimp_transform_grid_tool_push_internal_undo (GimpTransformGridTool *tg_tool,
+                                             gboolean               compress)
 {
   UndoInfo *undo_info;
 
@@ -1613,18 +1617,27 @@ gimp_transform_grid_tool_push_internal_undo (GimpTransformGridTool *tg_tool)
   if (! trans_infos_equal (undo_info->trans_infos, tg_tool->trans_infos))
     {
       GimpTransformOptions *tr_options = GIMP_TRANSFORM_TOOL_GET_OPTIONS (tg_tool);
+      gint64                time       = 0;
       gboolean              flush = FALSE;
 
       if (tg_tool->undo_list->next == NULL)
         flush = TRUE;
 
-      undo_info            = undo_info_new ();
+      if (compress)
+        time = g_get_monotonic_time ();
+
+      if (! compress || time - undo_info->time >= UNDO_COMPRESS_TIME)
+        {
+          undo_info = undo_info_new ();
+
+          tg_tool->undo_list = g_list_prepend (tg_tool->undo_list, undo_info);
+        }
+
+      undo_info->time      = time;
       undo_info->direction = tr_options->direction;
       memcpy (undo_info->trans_infos, tg_tool->trans_infos,
               sizeof (tg_tool->trans_infos));
 
-      tg_tool->undo_list = g_list_prepend (tg_tool->undo_list, undo_info);
-
       /* If we undid anything and started interacting, we have to
        * discard the redo history
        */
diff --git a/app/tools/gimptransformgridtool.h b/app/tools/gimptransformgridtool.h
index 0807300e83..a91cef5a75 100644
--- a/app/tools/gimptransformgridtool.h
+++ b/app/tools/gimptransformgridtool.h
@@ -106,7 +106,8 @@ gboolean   gimp_transform_grid_tool_info_to_matrix     (GimpTransformGridTool *t
 void       gimp_transform_grid_tool_matrix_to_info     (GimpTransformGridTool *tg_tool,
                                                         const GimpMatrix3     *transform);
 
-void       gimp_transform_grid_tool_push_internal_undo (GimpTransformGridTool *tg_tool);
+void       gimp_transform_grid_tool_push_internal_undo (GimpTransformGridTool *tg_tool,
+                                                        gboolean               compress);
 
 
 #endif  /*  __GIMP_TRANSFORM_GRID_TOOL_H__  */


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