[gimp/wip/animation: 335/373] plug-ins: onion skins can now be configured.



commit 92841a7ce558e65aea41354c864ab65830660a76
Author: Jehan <jehan girinstud io>
Date:   Fri Jun 23 17:09:36 2017 +0200

    plug-ins: onion skins can now be configured.
    
    Only up to 5 onion skins are allowed right now (that's already a lot to
    not have a messy output). Frame position with identical contents are
    overlooked (if we shoot on 2s or 3s, obviously displaying an onion skin
    of identical content is meaningless).
    This data is not yet saved in the parasite, but this will come.

 .../animation-play/core/animation-celanimation.c   |  151 ++++++++++++++------
 .../animation-play/core/animation-celanimation.h   |    4 +
 plug-ins/animation-play/widgets/animation-dialog.c |   50 ++++++-
 3 files changed, 155 insertions(+), 50 deletions(-)
---
diff --git a/plug-ins/animation-play/core/animation-celanimation.c 
b/plug-ins/animation-play/core/animation-celanimation.c
index 0d04cea..b2c9d1a 100644
--- a/plug-ins/animation-play/core/animation-celanimation.c
+++ b/plug-ins/animation-play/core/animation-celanimation.c
@@ -43,6 +43,7 @@ struct _AnimationCelAnimationPrivate
 {
   /* The number of frames. */
   gint             duration;
+  gint             onion_skins;
 
   /* Panel comments. */
   GList           *comments;
@@ -135,8 +136,12 @@ static void      on_camera_offsets_changed                 (AnimationCamera
                                                             AnimationCelAnimation  *animation);
 /* Utils */
 
-static void         animation_cel_animation_cleanup        (AnimationCelAnimation  *animation);
-static void         animation_cel_animation_clean_track    (Track                   *track);
+static void      animation_cel_animation_cleanup           (AnimationCelAnimation  *animation);
+static void      animation_cel_animation_clean_track       (Track                   *track);
+static gchar *   animation_cel_animation_get_hash          (AnimationCelAnimation  *animation,
+                                                            gint                    position,
+                                                            gboolean                layers_only);
+
 
 G_DEFINE_TYPE (AnimationCelAnimation, animation_cel_animation, ANIMATION_TYPE_ANIMATION)
 
@@ -284,6 +289,19 @@ animation_cel_animation_get_comment (AnimationCelAnimation *animation,
 }
 
 void
+animation_cel_animation_set_onion_skins (AnimationCelAnimation *animation,
+                                         gint                   skins)
+{
+  animation->priv->onion_skins = skins;
+}
+
+gint
+animation_cel_animation_get_onion_skins (AnimationCelAnimation *animation)
+{
+  return animation->priv->onion_skins;
+}
+
+void
 animation_cel_animation_set_duration (AnimationCelAnimation *animation,
                                       gint                   duration)
 {
@@ -603,48 +621,8 @@ static gchar *
 animation_cel_animation_get_frame_hash (Animation *animation,
                                         gint       position)
 {
-  AnimationCelAnimation *cel_animation;
-  gchar                 *hash = g_strdup ("");
-  GList                 *iter;
-  gint                   main_offset_x;
-  gint                   main_offset_y;
-
-  cel_animation = ANIMATION_CEL_ANIMATION (animation);
-  animation_camera_get (cel_animation->priv->camera,
-                        position, &main_offset_x, &main_offset_y);
-
-  /* Create the new buffer layer composition. */
-  for (iter = cel_animation->priv->tracks; iter; iter = iter->next)
-    {
-      Track *track = iter->data;
-      GList *layers;
-      GList *layer;
-
-      layers = g_list_nth_data (track->frames, position);
-
-      for (layer = layers; layer; layer = layer->next)
-        {
-          gint tattoo;
-
-          tattoo = GPOINTER_TO_INT (layer->data);
-          if (tattoo)
-            {
-              gchar *tmp = hash;
-              hash = g_strdup_printf ("%s[%d,%d]%d;",
-                                      hash,
-                                      main_offset_x, main_offset_y,
-                                      tattoo);
-              g_free (tmp);
-            }
-        }
-    }
-  if (strlen (hash) == 0)
-    {
-      g_free (hash);
-      hash = NULL;
-    }
-  return hash;
-
+  return animation_cel_animation_get_hash (ANIMATION_CEL_ANIMATION (animation),
+                                           position, FALSE);
 }
 
 static GeglBuffer *
@@ -952,9 +930,11 @@ animation_cel_animation_update_paint_view (Animation *animation,
   AnimationCelAnimation *cel_animation;
   gint                  *layers;
   GList                 *iter;
+  gchar                 *prev_hash;
   gint                   num_layers;
   gint32                 image_id;
   gint                   last_layer;
+  gint                   skin = 0;
   gint                   i;
 
   cel_animation = ANIMATION_CEL_ANIMATION (animation);
@@ -988,8 +968,29 @@ animation_cel_animation_update_paint_view (Animation *animation,
         }
     }
 
-  if (position > 0)
+  prev_hash = animation_cel_animation_get_hash (cel_animation, position, TRUE);
+  for (i = position - 1; skin < cel_animation->priv->onion_skins && i >= 0; i--)
     {
+      gchar  *hash;
+      gint32  color;
+
+      hash = animation_cel_animation_get_hash (cel_animation, i, TRUE);
+      if (g_strcmp0 (hash, prev_hash) == 0)
+        {
+          g_free (hash);
+          continue;
+        }
+      g_free (prev_hash);
+      prev_hash = hash;
+
+      switch (skin)
+        {
+        case 0: color = GIMP_COLOR_TAG_BROWN; break;
+        case 1: color = GIMP_COLOR_TAG_ORANGE; break;
+        case 2: color = GIMP_COLOR_TAG_YELLOW; break;
+        case 3: color = GIMP_COLOR_TAG_VIOLET; break;
+        default: color = GIMP_COLOR_TAG_GRAY; break;
+        }
       /* Show layers from previous position (onion skinning). */
       for (iter = cel_animation->priv->tracks; iter; iter = iter->next)
         {
@@ -997,7 +998,7 @@ animation_cel_animation_update_paint_view (Animation *animation,
           GList *frame_layers;
           GList *iter2;
 
-          frame_layers = g_list_nth_data (track->frames, position - 1);
+          frame_layers = g_list_nth_data (track->frames, i);
 
           for (iter2 = frame_layers; iter2; iter2 = iter2->next)
             {
@@ -1007,10 +1008,12 @@ animation_cel_animation_update_paint_view (Animation *animation,
               tattoo = GPOINTER_TO_INT (iter2->data);
               layer = gimp_image_get_layer_by_tattoo (image_id, tattoo);
               if (! gimp_item_get_visible (layer))
-                show_layer (layer, GIMP_COLOR_TAG_ORANGE, 0.5);
+                show_layer (layer, color, 0.5 - 0.1 * skin);
             }
         }
+      skin++;
     }
+  g_free (prev_hash);
   gimp_image_set_active_layer (image_id, last_layer);
 }
 
@@ -1348,3 +1351,57 @@ animation_cel_animation_clean_track (Track *track)
   g_list_free_full (track->frames, (GDestroyNotify) g_list_free);
   g_free (track);
 }
+
+static gchar *
+animation_cel_animation_get_hash (AnimationCelAnimation *animation,
+                                  gint                   position,
+                                  gboolean               layers_only)
+{
+  gchar *hash = g_strdup ("");
+  GList *iter;
+  gint   main_offset_x;
+  gint   main_offset_y;
+
+  animation_camera_get (animation->priv->camera,
+                        position, &main_offset_x, &main_offset_y);
+
+  /* Create the new buffer layer composition. */
+  for (iter = animation->priv->tracks; iter; iter = iter->next)
+    {
+      Track *track = iter->data;
+      GList *layers;
+      GList *layer;
+
+      layers = g_list_nth_data (track->frames, position);
+
+      for (layer = layers; layer; layer = layer->next)
+        {
+          gint tattoo;
+
+          tattoo = GPOINTER_TO_INT (layer->data);
+          if (tattoo)
+            {
+              gchar *tmp = hash;
+              if (layers_only)
+                {
+                  hash = g_strdup_printf ("%s%d;",
+                                          hash, tattoo);
+                }
+              else
+                {
+                  hash = g_strdup_printf ("%s[%d,%d]%d;",
+                                          hash,
+                                          main_offset_x, main_offset_y,
+                                          tattoo);
+                }
+              g_free (tmp);
+            }
+        }
+    }
+  if (strlen (hash) == 0)
+    {
+      g_free (hash);
+      hash = NULL;
+    }
+  return hash;
+}
diff --git a/plug-ins/animation-play/core/animation-celanimation.h 
b/plug-ins/animation-play/core/animation-celanimation.h
index 1aa0d00..fc7da1b 100644
--- a/plug-ins/animation-play/core/animation-celanimation.h
+++ b/plug-ins/animation-play/core/animation-celanimation.h
@@ -66,6 +66,10 @@ const gchar * animation_cel_animation_get_comment     (AnimationCelAnimation *an
 void          animation_cel_animation_set_duration    (AnimationCelAnimation *animation,
                                                        gint                   duration);
 
+void          animation_cel_animation_set_onion_skins (AnimationCelAnimation *animation,
+                                                       gint                   skins);
+gint          animation_cel_animation_get_onion_skins (AnimationCelAnimation *animation);
+
 GObject     * animation_cel_animation_get_main_camera (AnimationCelAnimation *animation);
 
 gint          animation_cel_animation_get_levels      (AnimationCelAnimation *animation);
diff --git a/plug-ins/animation-play/widgets/animation-dialog.c 
b/plug-ins/animation-play/widgets/animation-dialog.c
index 1534caa..9bb754b 100755
--- a/plug-ins/animation-play/widgets/animation-dialog.c
+++ b/plug-ins/animation-play/widgets/animation-dialog.c
@@ -104,6 +104,7 @@ struct _AnimationDialogPrivate
   GtkWidget         *settings;
   GtkWidget         *animation_type_combo;
   GtkWidget         *fpscombo;
+  GtkWidget         *onion_spin;
   GtkWidget         *duration_spin;
   GtkWidget         *proxycombo;
 
@@ -166,6 +167,8 @@ static void        help_callback             (GtkAction        *action,
 static void        animation_type_changed    (GtkWidget        *combo,
                                               AnimationDialog  *dialog);
 
+static void        on_onion_spin_changed     (GtkAdjustment    *adjustment,
+                                              AnimationDialog  *dialog);
 static void        on_duration_spin_changed  (GtkAdjustment    *adjustment,
                                               AnimationDialog  *dialog);
 
@@ -574,13 +577,39 @@ animation_dialog_constructed (GObject *object)
                     3, 5, 2, 3, GTK_SHRINK, GTK_SHRINK, 1, 1);
   gtk_widget_show (priv->fpscombo);
 
+  /* Settings: onion skinning */
+  widget = gtk_label_new (_("Onion skins:"));
+  g_signal_connect (dialog, "notify::animation",
+                    G_CALLBACK (hide_on_animatic),
+                    widget);
+  gtk_table_attach (GTK_TABLE (priv->settings), widget,
+                    0, 3, 3, 4, GTK_SHRINK, GTK_SHRINK, 1, 1);
+  gtk_widget_show (widget);
+
+  adjust = GTK_ADJUSTMENT (gtk_adjustment_new (0.0, 0.0, 5.0, 1.0, 2.0, 0.0));
+  priv->onion_spin = gtk_spin_button_new (adjust, 0.0, 0.0);
+  g_signal_connect (dialog, "notify::animation",
+                    G_CALLBACK (hide_on_animatic),
+                    priv->onion_spin);
+  gtk_entry_set_width_chars (GTK_ENTRY (priv->onion_spin), 1);
+  gimp_help_set_help_data (priv->onion_spin, _("Number of skins to show on painting area"), NULL);
+  gtk_table_attach (GTK_TABLE (priv->settings), priv->onion_spin,
+                    3, 4, 3, 4, GTK_SHRINK, GTK_SHRINK, 1, 1);
+
+  g_signal_connect (adjust,
+                    "value-changed",
+                    G_CALLBACK (on_onion_spin_changed),
+                    dialog);
+
+  gtk_widget_show (priv->onion_spin);
+
   /* Settings: duration */
   widget = gtk_label_new (_("Duration:"));
   g_signal_connect (dialog, "notify::animation",
                     G_CALLBACK (hide_on_animatic),
                     widget);
   gtk_table_attach (GTK_TABLE (priv->settings), widget,
-                    0, 3, 3, 4, GTK_SHRINK, GTK_SHRINK, 1, 1);
+                    0, 3, 4, 5, GTK_SHRINK, GTK_SHRINK, 1, 1);
   gtk_widget_show (widget);
 
   adjust = GTK_ADJUSTMENT (gtk_adjustment_new (240.0, 1.0, G_MAXDOUBLE, 1.0, 10.0, 0.0));
@@ -591,7 +620,7 @@ animation_dialog_constructed (GObject *object)
   gtk_entry_set_width_chars (GTK_ENTRY (priv->duration_spin), 5);
   gimp_help_set_help_data (priv->duration_spin, _("Duration in frames"), NULL);
   gtk_table_attach (GTK_TABLE (priv->settings), priv->duration_spin,
-                    3, 4, 3, 4, GTK_SHRINK, GTK_SHRINK, 1, 1);
+                    3, 4, 4, 5, GTK_SHRINK, GTK_SHRINK, 1, 1);
 
   g_signal_connect (adjust,
                     "value-changed",
@@ -605,7 +634,7 @@ animation_dialog_constructed (GObject *object)
                     G_CALLBACK (hide_on_animatic),
                     widget);
   gtk_table_attach (GTK_TABLE (priv->settings), widget,
-                    4, 5, 3, 4, GTK_SHRINK, GTK_SHRINK, 1, 1);
+                    4, 5, 4, 5, GTK_SHRINK, GTK_SHRINK, 1, 1);
   gtk_widget_show (widget);
 
   gtk_widget_show (priv->settings);
@@ -1563,6 +1592,21 @@ on_duration_spin_changed (GtkAdjustment   *adjustment,
   animation_cel_animation_set_duration (animation, (gint) value);
 }
 
+static void
+on_onion_spin_changed (GtkAdjustment   *adjustment,
+                       AnimationDialog *dialog)
+{
+  AnimationDialogPrivate *priv = GET_PRIVATE (dialog);
+  AnimationCelAnimation  *animation;
+  gdouble                 value = gtk_adjustment_get_value (adjustment);
+
+  g_return_if_fail (priv->animation &&
+                    ANIMATION_IS_CEL_ANIMATION (priv->animation));
+
+  animation = ANIMATION_CEL_ANIMATION (priv->animation);
+  animation_cel_animation_set_onion_skins (animation, (gint) value);
+}
+
 
 /*
  * Callback emitted when the user hits the Enter key of the fps combo.


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