[gimp/wip/animation: 164/197] plug-ins: save animation's camera work in the parasite.



commit e6f44694dc8ee471bfa065e3458b1358bfa45bd2
Author: Jehan <jehan girinstud io>
Date:   Mon Jun 26 00:01:51 2017 +0200

    plug-ins: save animation's camera work in the parasite.
    
    The camera still sucks. There should be drag'n drop capabilities, and
    right now there are various bugs, like when adding new frames. That's
    work-in-progress!

 plug-ins/animation-play/core/animation-camera.c    |   11 ++
 plug-ins/animation-play/core/animation-camera.h    |    3 +
 .../animation-play/core/animation-celanimation.c   |  111 +++++++++++++++++---
 plug-ins/animation-play/widgets/animation-xsheet.c |   33 ++++--
 4 files changed, 134 insertions(+), 24 deletions(-)
---
diff --git a/plug-ins/animation-play/core/animation-camera.c b/plug-ins/animation-play/core/animation-camera.c
index 8376158..f31c10a 100644
--- a/plug-ins/animation-play/core/animation-camera.c
+++ b/plug-ins/animation-play/core/animation-camera.c
@@ -179,6 +179,17 @@ animation_camera_new (Animation *animation)
   return camera;
 }
 
+gboolean
+animation_camera_has_keyframe (AnimationCamera *camera,
+                               gint             position)
+{
+  g_return_val_if_fail (position >= 0 &&
+                        position < animation_get_duration (camera->priv->animation),
+                        FALSE);
+
+  return (g_list_nth_data (camera->priv->offsets, position) != NULL);
+}
+
 void
 animation_camera_set_keyframe (AnimationCamera *camera,
                                gint             position,
diff --git a/plug-ins/animation-play/core/animation-camera.h b/plug-ins/animation-play/core/animation-camera.h
index 4f27b19..63e4e09 100644
--- a/plug-ins/animation-play/core/animation-camera.h
+++ b/plug-ins/animation-play/core/animation-camera.h
@@ -57,6 +57,9 @@ GType             animation_camera_get_type        (void) G_GNUC_CONST;
 
 AnimationCamera * animation_camera_new             (Animation       *animation);
 
+gboolean          animation_camera_has_keyframe    (AnimationCamera *camera,
+                                                    gint             position);
+
 void              animation_camera_set_keyframe    (AnimationCamera *camera,
                                                     gint             position,
                                                     gint             x,
diff --git a/plug-ins/animation-play/core/animation-celanimation.c 
b/plug-ins/animation-play/core/animation-celanimation.c
index 5b84261..b7a5d70 100644
--- a/plug-ins/animation-play/core/animation-celanimation.c
+++ b/plug-ins/animation-play/core/animation-celanimation.c
@@ -66,6 +66,8 @@ typedef enum
   SEQUENCE_STATE,
   FRAME_STATE,
   LAYER_STATE,
+  CAMERA_STATE,
+  KEYFRAME_STATE,
   COMMENTS_STATE,
   COMMENT_STATE,
   END_STATE
@@ -86,6 +88,7 @@ typedef struct
                                      ANIMATION_TYPE_CEL_ANIMATION, \
                                      AnimationCelAnimationPrivate)
 
+static void         animation_cel_animation_constructed       (GObject      *object);
 static void         animation_cel_animation_finalize          (GObject      *object);
 
 /* Virtual methods */
@@ -153,6 +156,7 @@ animation_cel_animation_class_init (AnimationCelAnimationClass *klass)
   GObjectClass   *object_class = G_OBJECT_CLASS (klass);
   AnimationClass *anim_class   = ANIMATION_CLASS (klass);
 
+  object_class->constructed  = animation_cel_animation_constructed;
   object_class->finalize     = animation_cel_animation_finalize;
 
   anim_class->get_duration   = animation_cel_animation_get_duration;
@@ -175,6 +179,17 @@ animation_cel_animation_init (AnimationCelAnimation *animation)
   animation->priv = G_TYPE_INSTANCE_GET_PRIVATE (animation,
                                                  ANIMATION_TYPE_CEL_ANIMATION,
                                                  AnimationCelAnimationPrivate);
+  animation->priv->camera = animation_camera_new (ANIMATION (animation));
+}
+
+static void
+animation_cel_animation_constructed (GObject *object)
+{
+  AnimationCelAnimation *animation = ANIMATION_CEL_ANIMATION (object);
+
+  g_signal_connect (animation->priv->camera, "offsets-changed",
+                    G_CALLBACK (on_camera_offsets_changed),
+                    animation);
 }
 
 static void
@@ -737,11 +752,6 @@ animation_cel_animation_reset_defaults (Animation *animation)
                                           layers);
         }
     }
-
-  priv->camera = animation_camera_new (animation);
-  g_signal_connect (priv->camera, "offsets-changed",
-                    G_CALLBACK (on_camera_offsets_changed),
-                    animation);
 }
 
 static gchar *
@@ -852,6 +862,33 @@ animation_cel_animation_serialize (Animation   *animation,
     }
 
   tmp = xml;
+  xml = g_strconcat (xml, "<camera>", NULL);
+  g_free (tmp);
+
+  for (i = 0; i < priv->duration; i++)
+    {
+      if (animation_camera_has_keyframe (priv->camera, i))
+        {
+          gint offset_x;
+          gint offset_y;
+
+          animation_camera_get (priv->camera,
+                                i, &offset_x, &offset_y);
+          xml2 = g_markup_printf_escaped ("<keyframe " "position=\"%d\""
+                                          " x=\"%d\" y=\"%d\"/>",
+                                          i, offset_x, offset_y);
+          tmp = xml;
+          xml = g_strconcat (xml, xml2, NULL);
+          g_free (tmp);
+          g_free (xml2);
+        }
+    }
+
+  tmp = xml;
+  xml = g_strconcat (xml, "</camera>", NULL);
+  g_free (tmp);
+
+  tmp = xml;
   xml = g_strconcat (xml, "<comments title=\"\">", NULL);
   g_free (tmp);
 
@@ -912,14 +949,6 @@ animation_cel_animation_deserialize (Animation    *animation,
       /* Reverse track order. */
       cel_animation->priv->tracks = g_list_reverse (cel_animation->priv->tracks);
 
-      /* TODO: just testing right now. I will have to add actual
-       * (de)serialization, otherwise there is no persistency of
-       * camera works.
-       */
-      cel_animation->priv->camera = animation_camera_new (animation);
-      g_signal_connect (cel_animation->priv->camera, "offsets-changed",
-                        G_CALLBACK (on_camera_offsets_changed),
-                        animation);
       g_signal_emit_by_name (animation, "frames-changed", 0,
                              cel_animation->priv->duration);
     }
@@ -1134,6 +1163,10 @@ animation_cel_animation_start_element (GMarkupParseContext  *context,
         {
           status->state = PLAYBACK_STATE;
         }
+      else if (g_strcmp0 (element_name, "camera") == 0)
+        {
+          status->state = CAMERA_STATE;
+        }
       else
         {
           g_set_error (error, 0, 0,
@@ -1244,6 +1277,48 @@ animation_cel_animation_start_element (GMarkupParseContext  *context,
                    _("Unexpected child of <layer>: \"%s\"."),
                    element_name);
       return;
+    case CAMERA_STATE:
+      if (g_strcmp0 (element_name, "keyframe") != 0)
+        {
+          g_set_error (error, 0, 0,
+                       _("Tag <keyframe> expected. "
+                         "Got \"%s\" instead."),
+                       element_name);
+          return;
+        }
+      else
+        {
+          gboolean has_x    = FALSE;
+          gboolean has_y    = FALSE;
+          gint     position = -1;
+          gint     x;
+          gint     y;
+
+          while (*names && *values)
+            {
+              if (strcmp (*names, "position") == 0 && **values)
+                {
+                  position = (gint) g_ascii_strtoll (*values, NULL, 10);
+                }
+              else if (strcmp (*names, "x") == 0 && **values)
+                {
+                  has_x = TRUE;
+                  x = (gint) g_ascii_strtoll (*values, NULL, 10);
+                }
+              else if (strcmp (*names, "y") == 0 && **values)
+                {
+                  has_y = TRUE;
+                  y = (gint) g_ascii_strtoll (*values, NULL, 10);
+                }
+
+              names++;
+              values++;
+            }
+          if (position >= 0 && has_x && has_y)
+            animation_camera_set_keyframe (priv->camera, position, x, y);
+        }
+      status->state = KEYFRAME_STATE;
+      break;
     case COMMENTS_STATE:
       if (g_strcmp0 (element_name, "comment") != 0)
         {
@@ -1277,6 +1352,12 @@ animation_cel_animation_start_element (GMarkupParseContext  *context,
                    _("Unexpected child of <comment>: <\"%s\">."),
                    element_name);
       return;
+    case KEYFRAME_STATE:
+      /* <keyframe> should have no child tag for now. */
+      g_set_error (error, 0, 0,
+                   _("Unexpected child of <keyframe>: <\"%s\">."),
+                   element_name);
+      return;
     default:
       g_set_error (error, 0, 0,
                    _("Unknown state!"));
@@ -1297,6 +1378,7 @@ animation_cel_animation_end_element (GMarkupParseContext *context,
     case SEQUENCE_STATE:
     case COMMENTS_STATE:
     case PLAYBACK_STATE:
+    case CAMERA_STATE:
       status->state = ANIMATION_STATE;
       break;
     case FRAME_STATE:
@@ -1311,6 +1393,9 @@ animation_cel_animation_end_element (GMarkupParseContext *context,
     case COMMENT_STATE:
       status->state = COMMENTS_STATE;
       break;
+    case KEYFRAME_STATE:
+      status->state = CAMERA_STATE;
+      break;
     default: /* START/END_STATE */
       /* invalid XML. I expect the parser to raise an error anyway.*/
       break;
diff --git a/plug-ins/animation-play/widgets/animation-xsheet.c 
b/plug-ins/animation-play/widgets/animation-xsheet.c
index 87820ef..76c83fe 100755
--- a/plug-ins/animation-play/widgets/animation-xsheet.c
+++ b/plug-ins/animation-play/widgets/animation-xsheet.c
@@ -703,13 +703,14 @@ animation_xsheet_add_frames (AnimationXSheet *xsheet,
                              gint             position,
                              gint             n_frames)
 {
-  GtkWidget *frame;
-  GList     *iter;
-  gdouble    framerate;
-  gint       duration;
-  gint       n_tracks;
-  gint       i;
-  gint       j;
+  AnimationCamera *camera;
+  GtkWidget       *frame;
+  GList           *iter;
+  gdouble          framerate;
+  gint             duration;
+  gint             n_tracks;
+  gint             i;
+  gint             j;
 
   duration = animation_get_duration (ANIMATION (xsheet->priv->animation));
 
@@ -717,6 +718,7 @@ animation_xsheet_add_frames (AnimationXSheet *xsheet,
 
   n_tracks = animation_cel_animation_get_levels (xsheet->priv->animation);
   framerate = animation_get_framerate (ANIMATION (xsheet->priv->animation));
+  camera = ANIMATION_CAMERA (animation_cel_animation_get_main_camera (xsheet->priv->animation));
 
   for (j = 0, iter = xsheet->priv->cels; iter; iter = iter->next, j++)
     {
@@ -805,6 +807,17 @@ animation_xsheet_add_frames (AnimationXSheet *xsheet,
       label = gtk_toggle_button_new ();
       xsheet->priv->effect_buttons = g_list_append (xsheet->priv->effect_buttons,
                                                     label);
+
+      if (animation_camera_has_keyframe (camera, i))
+        {
+          GtkWidget *image;
+
+          image = gtk_image_new_from_icon_name ("gtk-ok",
+                                                GTK_ICON_SIZE_SMALL_TOOLBAR);
+          gtk_container_add (GTK_CONTAINER (label), image);
+          gtk_widget_show (image);
+        }
+
       g_object_set_data (G_OBJECT (label), "frame-position",
                          GINT_TO_POINTER (i));
       gtk_button_set_relief (GTK_BUTTON (label), GTK_RELIEF_NONE);
@@ -812,12 +825,10 @@ animation_xsheet_add_frames (AnimationXSheet *xsheet,
       g_signal_connect (label, "button-press-event",
                         G_CALLBACK (animation_xsheet_effect_clicked),
                         xsheet);
-      g_signal_connect (animation_cel_animation_get_main_camera (xsheet->priv->animation),
-                        "keyframe-set",
+      g_signal_connect (camera, "keyframe-set",
                         G_CALLBACK (on_camera_keyframe_set),
                         xsheet);
-      g_signal_connect (animation_cel_animation_get_main_camera (xsheet->priv->animation),
-                        "keyframe-deleted",
+      g_signal_connect (camera, "keyframe-deleted",
                         G_CALLBACK (on_camera_keyframe_deleted),
                         xsheet);
       gtk_container_add (GTK_CONTAINER (frame), label);


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