[gimp/wip/animation: 73/197] plug-ins: select layer for each track/frame couple.



commit 95a140a3a6d246e7e8d313bb608acc1b4672fa2a
Author: Jehan <jehan girinstud io>
Date:   Wed Aug 10 05:53:38 2016 +0200

    plug-ins: select layer for each track/frame couple.
    
    For now, only a single layer can be selected on a given frame.

 .../animation-play/core/animation-celanimation.c   |   89 ++++++++++++++++++--
 .../animation-play/core/animation-celanimation.h   |    8 ++
 .../animation-play/widgets/animation-layer-view.c  |   27 +++---
 plug-ins/animation-play/widgets/animation-xsheet.c |   52 ++++++++++++
 4 files changed, 156 insertions(+), 20 deletions(-)
---
diff --git a/plug-ins/animation-play/core/animation-celanimation.c 
b/plug-ins/animation-play/core/animation-celanimation.c
index 8d1d36a..34d1057 100644
--- a/plug-ins/animation-play/core/animation-celanimation.c
+++ b/plug-ins/animation-play/core/animation-celanimation.c
@@ -185,6 +185,78 @@ animation_cel_animation_finalize (GObject *object)
 /**** Public Functions ****/
 
 void
+animation_cel_animation_set_layers (AnimationCelAnimation *animation,
+                                    gint                   level,
+                                    gint                   position,
+                                    GList                 *layers)
+{
+  Track *track;
+
+  track = g_list_nth_data (animation->priv->tracks, level);
+
+  if (track)
+    {
+      GList *frame_layer = g_list_nth (track->frames, position);
+
+      if (! frame_layer)
+        {
+          gint frames_length = g_list_length (track->frames);
+          gint i;
+
+          track->frames = g_list_reverse (track->frames);
+          for (i = frames_length; i < position + 1; i++)
+            {
+              track->frames = g_list_prepend (track->frames, 0);
+              frame_layer = track->frames;
+            }
+          track->frames = g_list_reverse (track->frames);
+        }
+      if (layers)
+        {
+          frame_layer->data = layers->data;
+        }
+      else
+        {
+          frame_layer->data = 0;
+        }
+      animation_cel_animation_cache (animation, position);
+      if (animation_get_position (ANIMATION (animation)) - 1 == position)
+        {
+          GeglBuffer *buffer;
+
+          buffer = animation_get_frame (ANIMATION (animation), position + 1);
+          g_signal_emit_by_name (animation, "render",
+                                 position, buffer, TRUE);
+          if (buffer)
+            g_object_unref (buffer);
+        }
+    }
+}
+
+GList *
+animation_cel_animation_get_layers (AnimationCelAnimation *animation,
+                                    gint                   level,
+                                    gint                   position)
+{
+  GList *layers = NULL;
+  Track *track;
+
+  track = g_list_nth_data (animation->priv->tracks, level);
+
+  if (track)
+    {
+      gpointer layer = g_list_nth_data (track->frames, position);
+
+      if (layer)
+        {
+          layers = g_list_prepend (layers, layer);
+        }
+    }
+
+  return layers;
+}
+
+void
 animation_cel_animation_set_comment (AnimationCelAnimation *animation,
                                      gint                   position,
                                      const gchar           *comment)
@@ -512,6 +584,7 @@ animation_cel_animation_serialize (Animation *animation)
                   xml = g_strconcat (xml, xml2, NULL);
                   g_free (tmp);
                   g_free (xml2);
+                  duration = 0;
                 }
             }
           pos++;
@@ -561,16 +634,16 @@ animation_cel_animation_same (Animation *animation,
 
   cel_animation = ANIMATION_CEL_ANIMATION (animation);
 
-  g_return_val_if_fail (pos1 >= 0                            &&
-                        pos1 < cel_animation->priv->duration &&
-                        pos2 >= 0                            &&
-                        pos2 < cel_animation->priv->duration,
+  g_return_val_if_fail (pos1 > 0                              &&
+                        pos1 <= cel_animation->priv->duration &&
+                        pos2 > 0                              &&
+                        pos2 <= cel_animation->priv->duration,
                         FALSE);
 
   cache1 = g_list_nth_data (cel_animation->priv->cache,
-                            pos1);
+                            pos1 - 1);
   cache2 = g_list_nth_data (cel_animation->priv->cache,
-                            pos2);
+                            pos2 - 1);
 
   return animation_cel_animation_cache_cmp (cache1, cache2);
 }
@@ -732,11 +805,13 @@ animation_cel_animation_start_element (GMarkupParseContext  *context,
               if (track_length < status->frame_position + status->frame_duration)
                 {
                   /* Make sure the list is long enough. */
+                  status->track->frames = g_list_reverse (status->track->frames);
                   for (i = track_length; i < status->frame_position + status->frame_duration; i++)
                     {
                       status->track->frames = g_list_prepend (status->track->frames,
                                                               NULL);
                     }
+                  status->track->frames = g_list_reverse (status->track->frames);
                 }
               iter = status->track->frames;
               for (i = 0; i < status->frame_position + status->frame_duration; i++)
@@ -1048,7 +1123,7 @@ animation_cel_animation_cache_cmp (Cache *cache1,
 static void
 animation_cel_animation_clean_cache (Cache *cache)
 {
-  if (--(cache->refs) == 0)
+  if (cache != NULL && --(cache->refs) == 0)
     {
       g_object_unref (cache->buffer);
       g_free (cache->composition);
diff --git a/plug-ins/animation-play/core/animation-celanimation.h 
b/plug-ins/animation-play/core/animation-celanimation.h
index f256d04..0f91100 100644
--- a/plug-ins/animation-play/core/animation-celanimation.h
+++ b/plug-ins/animation-play/core/animation-celanimation.h
@@ -49,6 +49,14 @@ struct _AnimationCelAnimationClass
 GType         animation_cel_animation_get_type (void);
 
 
+void          animation_cel_animation_set_layers      (AnimationCelAnimation *animation,
+                                                       gint                   level,
+                                                       gint                   position,
+                                                       GList                 *layers);
+GList       * animation_cel_animation_get_layers      (AnimationCelAnimation *animation,
+                                                       gint                   level,
+                                                       gint                   position);
+
 void          animation_cel_animation_set_comment     (AnimationCelAnimation *animation,
                                                        gint                   position,
                                                        const gchar           *comment);
diff --git a/plug-ins/animation-play/widgets/animation-layer-view.c 
b/plug-ins/animation-play/widgets/animation-layer-view.c
index ef58139..e6e54df 100644
--- a/plug-ins/animation-play/widgets/animation-layer-view.c
+++ b/plug-ins/animation-play/widgets/animation-layer-view.c
@@ -37,7 +37,7 @@ enum
 /* Tree model rows. */
 enum
 {
-  COLUMN_LAYER_ID,
+  COLUMN_LAYER_TATTOO,
   COLUMN_LAYER_NAME,
   COLUMN_SIZE
 };
@@ -75,7 +75,7 @@ static void          animation_layer_view_fill    (AnimationLayerView *view,
                                                    gint                parent_layer,
                                                    GtkTreeIter        *parent);
 static GtkTreePath * animation_layer_view_get_row (AnimationLayerView *view,
-                                                   gint                layer_id,
+                                                   gint                tattoo,
                                                    GtkTreeIter        *parent);
 
 /* Signal handlers */
@@ -212,9 +212,9 @@ animation_layer_view_select (AnimationLayerView *view,
   for (layer = layers; layer; layer = layer->next)
     {
       GtkTreePath *path;
-      gint         layer_id = GPOINTER_TO_INT (layer->data);
+      gint         tattoo = GPOINTER_TO_INT (layer->data);
       
-      path = animation_layer_view_get_row (view, layer_id, NULL);
+      path = animation_layer_view_get_row (view, tattoo, NULL);
       g_warn_if_fail (path != NULL);
       if (path)
         {
@@ -236,7 +236,8 @@ animation_layer_view_constructed (GObject *object)
   GtkTreeSelection *selection;
 
   selection = gtk_tree_view_get_selection (view);
-  gtk_tree_selection_set_mode (selection, GTK_SELECTION_MULTIPLE);
+  /*gtk_tree_selection_set_mode (selection, GTK_SELECTION_MULTIPLE);*/
+  gtk_tree_selection_set_mode (selection, GTK_SELECTION_SINGLE);
 
   g_signal_connect (selection, "changed",
                     G_CALLBACK (on_selection_changed),
@@ -379,7 +380,7 @@ animation_layer_view_fill (AnimationLayerView *view,
     {
       gtk_tree_store_insert (store, &iter, parent, i);
       gtk_tree_store_set (store, &iter,
-                          COLUMN_LAYER_ID, layers[i],
+                          COLUMN_LAYER_TATTOO, gimp_item_get_tattoo (layers[i]),
                           COLUMN_LAYER_NAME, gimp_item_get_name (layers[i]),
                           -1);
       if (gimp_item_is_group (layers[i]))
@@ -391,16 +392,16 @@ animation_layer_view_fill (AnimationLayerView *view,
 
 /* animation_layer_view_get_row:
  * @view: the #AnimationLayerView.
- * @layer_id: the #GimpLayer id.
+ * @tattoo: the #GimpLayer tattoo.
  * @parent: %NULL to search from the first call (used for recursivity).
  *
- * Returns: the #GtkTreePath for the row of @layer_id, NULL if not found
+ * Returns: the #GtkTreePath for the row of @tattoo, NULL if not found
  * in @view.
  * The returned path should be freed with gtk_tree_path_free()
  */
 static GtkTreePath *
 animation_layer_view_get_row (AnimationLayerView *view,
-                              gint                layer_id,
+                              gint                tattoo,
                               GtkTreeIter        *parent)
 {
   GtkTreeModel *model;
@@ -416,9 +417,9 @@ animation_layer_view_get_row (AnimationLayerView *view,
       GValue       value = { 0, };
 
       gtk_tree_model_get_value (model, &iter,
-                                COLUMN_LAYER_ID,
+                                COLUMN_LAYER_TATTOO,
                                 &value);
-      if (g_value_get_int (&value) == layer_id)
+      if (g_value_get_int (&value) == tattoo)
         path = gtk_tree_model_get_path (model, &iter);
 
       g_value_unset (&value);
@@ -431,7 +432,7 @@ animation_layer_view_get_row (AnimationLayerView *view,
         {
           GtkTreePath *found_path;
 
-          found_path = animation_layer_view_get_row (view, layer_id, &iter);
+          found_path = animation_layer_view_get_row (view, tattoo, &iter);
 
           if (found_path)
             return found_path;
@@ -465,7 +466,7 @@ on_selection_changed (GtkTreeSelection   *selection,
           GValue value = { 0, };
 
           gtk_tree_model_get_value (model, &iter,
-                                    COLUMN_LAYER_ID,
+                                    COLUMN_LAYER_TATTOO,
                                     &value);
           layers = g_list_prepend (layers,
                                    GINT_TO_POINTER (g_value_get_int (&value)));
diff --git a/plug-ins/animation-play/widgets/animation-xsheet.c 
b/plug-ins/animation-play/widgets/animation-xsheet.c
index f63c6a9..5569ad3 100755
--- a/plug-ins/animation-play/widgets/animation-xsheet.c
+++ b/plug-ins/animation-play/widgets/animation-xsheet.c
@@ -77,6 +77,11 @@ static void on_animation_loaded           (Animation       *animation,
                                            gint             preview_height,
                                            AnimationXSheet *xsheet);
 
+/* Callbacks on layer view. */
+static void on_layer_selection            (AnimationLayerView *view,
+                                           GList              *layers,
+                                           AnimationXSheet    *xsheet);
+
 /* UI Signals */
 static gboolean animation_xsheet_cel_clicked         (GtkWidget       *button,
                                                       GdkEvent        *event,
@@ -170,6 +175,10 @@ animation_xsheet_constructed (GObject *object)
 
   gtk_widget_show (xsheet->priv->track_layout);
 
+  /* Tie the layer view to the xsheet. */
+  g_signal_connect (xsheet->priv->layer_view, "layer-selection",
+                    G_CALLBACK (on_layer_selection), xsheet);
+
   /* Reload everything when we reload the animation. */
   g_signal_connect_after (xsheet->priv->animation, "loaded",
                           G_CALLBACK (on_animation_loaded), xsheet);
@@ -401,6 +410,29 @@ animation_xsheet_reset_layout (AnimationXSheet *xsheet)
 }
 
 static void
+on_layer_selection (AnimationLayerView *view,
+                    GList              *layers,
+                    AnimationXSheet    *xsheet)
+{
+  GQueue   *frames;
+  gpointer  position;
+
+  if (g_queue_is_empty (xsheet->priv->selected_frames))
+    return;
+
+  frames = g_queue_copy (xsheet->priv->selected_frames);
+  while (! g_queue_is_empty (frames))
+    {
+      position = g_queue_pop_head (frames);
+      animation_cel_animation_set_layers (xsheet->priv->animation,
+                                          xsheet->priv->selected_track,
+                                          GPOINTER_TO_INT (position),
+                                          layers);
+    }
+  g_queue_free (frames);
+}
+
+static void
 on_animation_loaded (Animation       *animation,
                      gint             first_frame,
                      gint             num_frames,
@@ -486,6 +518,26 @@ animation_xsheet_cel_clicked (GtkWidget       *button,
         }
     }
 
+  /* Finally update the layer view. */
+  if (g_queue_is_empty (xsheet->priv->selected_frames))
+    {
+      animation_layer_view_select (ANIMATION_LAYER_VIEW (xsheet->priv->layer_view),
+                                   NULL);
+    }
+  else
+    {
+      GList *layers;
+
+      /* When several frames are selected, show layers of the first selected. */
+      position = g_queue_peek_tail (xsheet->priv->selected_frames);
+
+      layers = animation_cel_animation_get_layers (xsheet->priv->animation,
+                                                   GPOINTER_TO_INT (track_num),
+                                                   GPOINTER_TO_INT (position));
+      animation_layer_view_select (ANIMATION_LAYER_VIEW (xsheet->priv->layer_view),
+                                   layers);
+    }
+
   /* All handled here. */
   return TRUE;
 }


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