[gimp/wip/animation: 373/373] plug-ins: better GUI feedback when previewing zoom/offset keyframes.



commit 926ca7b3725cac13b8f310f1666fbe66cbd4a063
Author: Jehan <jehan girinstud io>
Date:   Sat Sep 30 03:23:08 2017 +0200

    plug-ins: better GUI feedback when previewing zoom/offset keyframes.
    
    For efficiency, when editing a frame offset or zoom at a given position,
    I do not apply the keyframe immediately (which may update neighbour
    frames by interpolation) since there may likely be many recomputations.
    I still want the GUI to act as though this is just like any keyframe,
    with the camera icon, reset buttons, etc.

 plug-ins/animation-play/core/animation-camera.c    |   36 ++++++---
 .../animation-play/core/animation-celanimation.c   |    6 ++
 .../widgets/animation-keyframe-view.c              |   91 ++++++++++++++------
 3 files changed, 96 insertions(+), 37 deletions(-)
---
diff --git a/plug-ins/animation-play/core/animation-camera.c b/plug-ins/animation-play/core/animation-camera.c
index d3151d2..6142dee 100644
--- a/plug-ins/animation-play/core/animation-camera.c
+++ b/plug-ins/animation-play/core/animation-camera.c
@@ -57,8 +57,8 @@ struct _AnimationCameraPrivate
   GList     *zoom;
 
   /* Preview */
-  Offset    *preview_offset;
   gint       preview_position;
+  Offset    *preview_offset;
   gdouble    preview_scale;
 
   gboolean   block_signals;
@@ -322,6 +322,10 @@ animation_camera_delete_offset_keyframe (AnimationCamera *camera,
       g_signal_emit (camera, signals[KEYFRAME_DELETED], 0, position);
       animation_camera_emit_camera_changed (camera, position);
     }
+  if (camera->priv->preview_position == position)
+    {
+      animation_camera_reset_preview (camera);
+    }
 }
 
 void
@@ -342,6 +346,10 @@ animation_camera_delete_zoom_keyframe (AnimationCamera *camera,
       g_signal_emit (camera, signals[KEYFRAME_DELETED], 0, position);
       animation_camera_emit_camera_changed (camera, position);
     }
+  if (camera->priv->preview_position == position)
+    {
+      animation_camera_reset_preview (camera);
+    }
 }
 
 void
@@ -362,6 +370,7 @@ animation_camera_preview_keyframe (AnimationCamera *camera,
   camera->priv->preview_scale     = scale;
   camera->priv->preview_position  = position;
 
+  g_signal_emit (camera, signals[KEYFRAME_SET], 0, position);
   g_signal_emit (camera, signals[CAMERA_CHANGED], 0,
                  position, 1);
 }
@@ -369,7 +378,7 @@ animation_camera_preview_keyframe (AnimationCamera *camera,
 void
 animation_camera_apply_preview (AnimationCamera *camera)
 {
-  if (camera->priv->preview_offset)
+  if (camera->priv->preview_position != -1)
     {
       gint    preview_offset_x;
       gint    preview_offset_y;
@@ -386,7 +395,8 @@ animation_camera_apply_preview (AnimationCamera *camera)
                                  &real_offset_x, &real_offset_y,
                                  &real_scale);
 
-      g_free (camera->priv->preview_offset);
+      if (camera->priv->preview_offset)
+        g_free (camera->priv->preview_offset);
       camera->priv->preview_offset    = NULL;
       position = camera->priv->preview_position;
       camera->priv->preview_position  = -1;
@@ -415,9 +425,9 @@ void
 animation_camera_reset_preview (AnimationCamera *camera)
 {
   gboolean changed = FALSE;
-  gint     position_changed;
+  gint     position_changed = -1;
 
-  if (camera->priv->preview_offset)
+  if (camera->priv->preview_position != -1)
     {
       gint    preview_offset_x;
       gint    preview_offset_y;
@@ -437,15 +447,19 @@ animation_camera_reset_preview (AnimationCamera *camera)
                  preview_scale != real_scale);
       position_changed = camera->priv->preview_position;
 
-      g_free (camera->priv->preview_offset);
-      camera->priv->preview_offset    = NULL;
+      if (camera->priv->preview_offset)
+        g_free (camera->priv->preview_offset);
+      camera->priv->preview_offset = NULL;
     }
 
-  camera->priv->preview_position  = -1;
-
+  camera->priv->preview_position = -1;
   if (changed)
-    g_signal_emit (camera, signals[CAMERA_CHANGED], 0,
-                   position_changed, 1);
+    {
+      g_signal_emit (camera, signals[KEYFRAME_DELETED], 0,
+                     position_changed);
+      g_signal_emit (camera, signals[CAMERA_CHANGED], 0,
+                     position_changed, 1);
+    }
 }
 
 void
diff --git a/plug-ins/animation-play/core/animation-celanimation.c 
b/plug-ins/animation-play/core/animation-celanimation.c
index 940bb55..c9e4b03 100644
--- a/plug-ins/animation-play/core/animation-celanimation.c
+++ b/plug-ins/animation-play/core/animation-celanimation.c
@@ -770,7 +770,13 @@ animation_cel_animation_serialize (Animation   *animation,
 
   priv = ANIMATION_CEL_ANIMATION (animation)->priv;
 
+  g_signal_handlers_block_by_func (priv->camera,
+                                   G_CALLBACK (on_camera_changed),
+                                   animation);
   animation_camera_reset_preview (priv->camera);
+  g_signal_handlers_unblock_by_func (priv->camera,
+                                     G_CALLBACK (on_camera_changed),
+                                     animation);
   animation_get_size (animation, &width, &height);
   xml = g_strdup_printf ("<animation type=\"cels\" framerate=\"%f\" "
                           " duration=\"%d\" onion-skins=\"%d\""
diff --git a/plug-ins/animation-play/widgets/animation-keyframe-view.c 
b/plug-ins/animation-play/widgets/animation-keyframe-view.c
index f2e5308..141a1d4 100644
--- a/plug-ins/animation-play/widgets/animation-keyframe-view.c
+++ b/plug-ins/animation-play/widgets/animation-keyframe-view.c
@@ -36,9 +36,11 @@ struct _AnimationKeyFrameViewPrivate
   AnimationCamera *camera;
   gint             position;
 
+  gboolean         local_offset_keyframe;
   GtkWidget       *offset_entry;
   GtkWidget       *delete_offset_button;
 
+  gboolean         local_scale_keyframe;
   GtkWidget       *scale_entry;
   GtkWidget       *delete_scale_button;
 
@@ -56,11 +58,13 @@ static void     animation_keyframe_view_dispose      (GObject               *obj
 
 static gboolean animation_keyframe_update_source     (gpointer               user_data);
 
+static void     on_entry_changed                     (GimpSizeEntry         *entry,
+                                                      AnimationKeyFrameView *view);
 static void     on_scale_entry_changed               (GtkSpinButton         *button,
                                                       AnimationKeyFrameView *view);
 static void     on_offset_entry_changed              (GimpSizeEntry         *entry,
                                                       AnimationKeyFrameView *view);
-static void     on_offsets_changed                   (AnimationCamera       *camera,
+static void     on_camera_changed                    (AnimationCamera       *camera,
                                                       gint                   position,
                                                       gint                   duration,
                                                       AnimationKeyFrameView *view);
@@ -146,13 +150,15 @@ animation_keyframe_view_show (AnimationKeyFrameView *view,
           view->priv->update_position != -1)
         {
           /* We jumped to another position. Apply the ongoing preview. */
-          animation_camera_set_offsets (view->priv->camera,
-                                        view->priv->update_position,
-                                        view->priv->update_x_offset,
-                                        view->priv->update_y_offset);
-          animation_camera_zoom (view->priv->camera,
-                                 view->priv->update_position,
-                                 view->priv->update_scale);
+          if (view->priv->local_offset_keyframe)
+            animation_camera_set_offsets (view->priv->camera,
+                                          view->priv->update_position,
+                                          view->priv->update_x_offset,
+                                          view->priv->update_y_offset);
+          if (view->priv->local_scale_keyframe)
+            animation_camera_zoom (view->priv->camera,
+                                   view->priv->update_position,
+                                   view->priv->update_scale);
         }
       view->priv->camera   = camera;
       view->priv->position = position;
@@ -183,7 +189,7 @@ animation_keyframe_view_show (AnimationKeyFrameView *view,
                                             G_CALLBACK (on_offset_entry_changed),
                                             view);
       g_signal_handlers_disconnect_by_func (view->priv->camera,
-                                            G_CALLBACK (on_offsets_changed),
+                                            G_CALLBACK (on_camera_changed),
                                             view);
       animation_camera_reset_preview (camera);
       animation_camera_get (camera, position, &x_offset, &y_offset, &scale);
@@ -200,7 +206,7 @@ animation_keyframe_view_show (AnimationKeyFrameView *view,
                         G_CALLBACK (on_offset_entry_changed),
                         view);
       g_signal_connect (camera, "camera-changed",
-                        G_CALLBACK (on_offsets_changed),
+                        G_CALLBACK (on_camera_changed),
                         view);
       gtk_widget_show (GTK_WIDGET (view));
 
@@ -224,7 +230,7 @@ static void animation_keyframe_view_dispose (GObject *object)
   if (view->priv->camera)
     {
       g_signal_handlers_disconnect_by_func (view->priv->camera,
-                                            G_CALLBACK (on_offsets_changed),
+                                            G_CALLBACK (on_camera_changed),
                                             view);
       view->priv->camera = NULL;
     }
@@ -307,15 +313,8 @@ animation_keyframe_update_source (gpointer user_data)
 }
 
 static void
-on_scale_entry_changed (GtkSpinButton         *button G_GNUC_UNUSED,
-                        AnimationKeyFrameView *view)
-{
-  on_offset_entry_changed (NULL, view);
-}
-
-static void
-on_offset_entry_changed (GimpSizeEntry         *entry G_GNUC_UNUSED,
-                         AnimationKeyFrameView *view)
+on_entry_changed (GimpSizeEntry         *entry G_GNUC_UNUSED,
+                  AnimationKeyFrameView *view)
 {
   gdouble x_offset;
   gdouble y_offset;
@@ -340,10 +339,28 @@ on_offset_entry_changed (GimpSizeEntry         *entry G_GNUC_UNUSED,
 }
 
 static void
-on_offsets_changed (AnimationCamera       *camera,
-                    gint                   position,
-                    gint                   duration,
-                    AnimationKeyFrameView *view)
+on_scale_entry_changed (GtkSpinButton         *button G_GNUC_UNUSED,
+                        AnimationKeyFrameView *view)
+{
+  view->priv->local_scale_keyframe = TRUE;
+  gtk_widget_show (view->priv->delete_scale_button);
+  on_entry_changed (NULL, view);
+}
+
+static void
+on_offset_entry_changed (GimpSizeEntry         *entry G_GNUC_UNUSED,
+                         AnimationKeyFrameView *view)
+{
+  view->priv->local_offset_keyframe = TRUE;
+  gtk_widget_show (view->priv->delete_offset_button);
+  on_entry_changed (NULL, view);
+}
+
+static void
+on_camera_changed (AnimationCamera       *camera,
+                   gint                   position,
+                   gint                   duration,
+                   AnimationKeyFrameView *view)
 {
   if (view->priv->position >= position &&
       view->priv->position < position + duration)
@@ -355,6 +372,9 @@ on_offsets_changed (AnimationCamera       *camera,
       g_signal_handlers_block_by_func (view->priv->offset_entry,
                                        G_CALLBACK (on_offset_entry_changed),
                                        view);
+      g_signal_handlers_block_by_func (view->priv->offset_entry,
+                                       G_CALLBACK (on_scale_entry_changed),
+                                       view);
       animation_camera_get (camera, view->priv->position,
                             &x_offset, &y_offset, &scale);
       gimp_size_entry_set_value (GIMP_SIZE_ENTRY (view->priv->offset_entry),
@@ -366,12 +386,17 @@ on_offsets_changed (AnimationCamera       *camera,
       g_signal_handlers_unblock_by_func (view->priv->offset_entry,
                                          G_CALLBACK (on_offset_entry_changed),
                                          view);
+      g_signal_handlers_unblock_by_func (view->priv->offset_entry,
+                                         G_CALLBACK (on_scale_entry_changed),
+                                         view);
 
-      if (animation_camera_has_offset_keyframe (camera, view->priv->position))
+      if (animation_camera_has_offset_keyframe (camera, view->priv->position) ||
+          view->priv->local_offset_keyframe)
         gtk_widget_show (view->priv->delete_offset_button);
       else
         gtk_widget_hide (view->priv->delete_offset_button);
-      if (animation_camera_has_zoom_keyframe (camera, view->priv->position))
+      if (animation_camera_has_zoom_keyframe (camera, view->priv->position) ||
+          view->priv->local_scale_keyframe)
         gtk_widget_show (view->priv->delete_scale_button);
       else
         gtk_widget_hide (view->priv->delete_scale_button);
@@ -382,16 +407,30 @@ static void
 on_delete_offset_clicked (GtkButton             *button,
                           AnimationKeyFrameView *view)
 {
+  g_signal_handlers_block_by_func (view->priv->scale_entry,
+                                   G_CALLBACK (on_offset_entry_changed),
+                                   view);
+  view->priv->local_offset_keyframe = FALSE;
   animation_camera_delete_offset_keyframe (view->priv->camera,
                                            view->priv->position);
   gtk_widget_hide (view->priv->delete_offset_button);
+  g_signal_handlers_unblock_by_func (view->priv->scale_entry,
+                                     G_CALLBACK (on_offset_entry_changed),
+                                     view);
 }
 
 static void
 on_delete_scale_clicked (GtkButton             *button,
                          AnimationKeyFrameView *view)
 {
+  g_signal_handlers_block_by_func (view->priv->scale_entry,
+                                   G_CALLBACK (on_scale_entry_changed),
+                                   view);
+  view->priv->local_scale_keyframe = FALSE;
   animation_camera_delete_zoom_keyframe (view->priv->camera,
                                          view->priv->position);
   gtk_widget_hide (view->priv->delete_scale_button);
+  g_signal_handlers_unblock_by_func (view->priv->scale_entry,
+                                     G_CALLBACK (on_scale_entry_changed),
+                                     view);
 }


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