[gimp/wip/animation: 128/145] plug-ins: add the concept of display size.



commit 4c09858eda297320db263cac9eacd5688fc8cbd1
Author: Jehan <jehan girinstud io>
Date:   Sun Jun 25 22:35:07 2017 +0200

    plug-ins: add the concept of display size.
    
    The size of the animation may be different from the one of the image.
    This way, we can create bigger images than the display, for instance for
    panning, zooming, or other effects.

 plug-ins/animation-play/core/animation-renderer.c  |   16 ++++
 plug-ins/animation-play/core/animation.c           |   64 +++++++++++++--
 plug-ins/animation-play/core/animation.h           |    6 ++
 plug-ins/animation-play/widgets/animation-dialog.c |   83 +++++++++++++++++---
 4 files changed, 151 insertions(+), 18 deletions(-)
---
diff --git a/plug-ins/animation-play/core/animation-renderer.c 
b/plug-ins/animation-play/core/animation-renderer.c
index 6a229f7..ec4955a 100644
--- a/plug-ins/animation-play/core/animation-renderer.c
+++ b/plug-ins/animation-play/core/animation-renderer.c
@@ -76,6 +76,10 @@ static void     on_proxy_changed                 (AnimationPlayback *animation,
                                                   gdouble            ratio,
                                                   AnimationRenderer *renderer);
 
+static void     on_size_changed                  (Animation         *animation,
+                                                  gint               width,
+                                                  gint               height,
+                                                  AnimationRenderer *renderer);
 static void     on_frames_changed                (Animation         *animation,
                                                   gint               position,
                                                   gint               length,
@@ -397,6 +401,16 @@ on_proxy_changed (AnimationPlayback *playback,
 }
 
 static void
+on_size_changed (Animation         *animation,
+                 gint               width,
+                 gint               height,
+                 AnimationRenderer *renderer)
+{
+  on_frames_changed (animation, 0, animation_get_duration (animation),
+                     renderer);
+}
+
+static void
 on_frames_changed (Animation         *animation,
                    gint               position,
                    gint               length,
@@ -508,6 +522,8 @@ animation_renderer_new (GObject *playback)
                                        renderer->priv->cache_size);
   renderer->priv->hashes     = g_new0 (gchar*,
                                        renderer->priv->cache_size);
+  g_signal_connect (animation, "size-changed",
+                    G_CALLBACK (on_size_changed), renderer);
   g_signal_connect (animation, "frames-changed",
                     G_CALLBACK (on_frames_changed), renderer);
   g_signal_connect (animation, "duration-changed",
diff --git a/plug-ins/animation-play/core/animation.c b/plug-ins/animation-play/core/animation.c
index dabdd43..ef5a555 100644
--- a/plug-ins/animation-play/core/animation.c
+++ b/plug-ins/animation-play/core/animation.c
@@ -45,6 +45,7 @@ enum
 {
   LOADING,
   LOADED,
+  SIZE_CHANGED,
   FRAMES_CHANGED,
   DURATION_CHANGED,
   FRAMERATE_CHANGED,
@@ -64,6 +65,10 @@ struct _AnimationPrivate
 {
   gint32    image_id;
 
+  /* Animation size may be different from image size. */
+  gint      width;
+  gint      height;
+
   gdouble   framerate;
 
   gboolean  loaded;
@@ -137,6 +142,26 @@ animation_class_init (AnimationClass *klass)
                   G_TYPE_NONE,
                   0);
   /**
+   * Animation::size-changed:
+   * @animation: the animation.
+   * @width: @animation width.
+   * @height: @animation height.
+   *
+   * The ::size-changed signal will be emitted when @animation display
+   * size changes.
+   */
+  animation_signals[SIZE_CHANGED] =
+    g_signal_new ("size-changed",
+                  G_TYPE_FROM_CLASS (klass),
+                  G_SIGNAL_RUN_FIRST,
+                  G_STRUCT_OFFSET (AnimationClass, size_changed),
+                  NULL, NULL,
+                  NULL,
+                  G_TYPE_NONE,
+                  2,
+                  G_TYPE_INT,
+                  G_TYPE_INT);
+  /**
    * Animation::frames-changed:
    * @animation: the animation.
    * @position: the first frame position whose contents changed.
@@ -372,20 +397,32 @@ animation_get_duration (Animation *animation)
 }
 
 void
+animation_set_size (Animation *animation,
+                    gint       width,
+                    gint       height)
+{
+  AnimationPrivate *priv = ANIMATION_GET_PRIVATE (animation);
+
+  if (width != priv->width || height != priv->height)
+    {
+      priv->width  = width;
+      priv->height = height;
+      g_signal_emit (animation, animation_signals[SIZE_CHANGED], 0,
+                     width, height);
+    }
+}
+
+void
 animation_get_size (Animation *animation,
                     gint      *width,
                     gint      *height)
 {
   AnimationPrivate *priv = ANIMATION_GET_PRIVATE (animation);
-  gint              image_width;
-  gint              image_height;
-
-  image_width  = gimp_image_width (priv->image_id);
-  image_height = gimp_image_height (priv->image_id);
 
-  /* Full preview size. */
-  *width  = image_width;
-  *height = image_height;
+  if (width)
+    *width  = priv->width;
+  if (height)
+    *height = priv->height;
 }
 
 void
@@ -452,6 +489,8 @@ animation_set_property (GObject      *object,
         {
           const gchar *xml   = g_value_get_string (value);
           GError      *error = NULL;
+          gint         width;
+          gint         height;
 
           if (! xml ||
               ! ANIMATION_GET_CLASS (animation)->deserialize (animation,
@@ -465,6 +504,15 @@ animation_set_property (GObject      *object,
               ANIMATION_GET_CLASS (animation)->reset_defaults (animation);
             }
           g_clear_error (&error);
+
+          animation_get_size (animation, &width, &height);
+          if (width <= 0 || height <= 0)
+            {
+              /* Default display size is the size of the image. */
+              animation_set_size (animation,
+                                  gimp_image_width (priv->image_id),
+                                  gimp_image_height (priv->image_id));
+            }
         }
       break;
 
diff --git a/plug-ins/animation-play/core/animation.h b/plug-ins/animation-play/core/animation.h
index e4c9aad..6127ec3 100644
--- a/plug-ins/animation-play/core/animation.h
+++ b/plug-ins/animation-play/core/animation.h
@@ -45,6 +45,9 @@ struct _AnimationClass
                                       gdouble       ratio);
   void         (*loaded)             (Animation    *animation);
 
+  void         (*size_changed)       (Animation    *animation,
+                                      gint          width,
+                                      gint          height);
   void         (*frames_changed)     (Animation    *animation,
                                       gint          position,
                                       gint          length);
@@ -90,6 +93,9 @@ void          animation_save_to_parasite   (Animation   *animation,
 
 gint          animation_get_duration       (Animation   *animation);
 
+void          animation_set_size           (Animation   *animation,
+                                            gint         width,
+                                            gint         height);
 void          animation_get_size           (Animation   *animation,
                                             gint        *width,
                                             gint        *height);
diff --git a/plug-ins/animation-play/widgets/animation-dialog.c 
b/plug-ins/animation-play/widgets/animation-dialog.c
index ae2317c..f8e9b57 100755
--- a/plug-ins/animation-play/widgets/animation-dialog.c
+++ b/plug-ins/animation-play/widgets/animation-dialog.c
@@ -103,6 +103,7 @@ struct _AnimationDialogPrivate
   /* Notebook: settings. */
   GtkWidget         *settings;
   GtkWidget         *animation_type_combo;
+  GtkWidget         *size_entry;
   GtkWidget         *fpscombo;
   GtkWidget         *onion_spin;
   GtkWidget         *duration_spin;
@@ -167,6 +168,9 @@ static void        help_callback             (GtkAction        *action,
 static void        animation_type_changed    (GtkWidget        *combo,
                                               AnimationDialog  *dialog);
 
+static void        animation_size_changed    (GimpSizeEntry    *gse,
+                                              AnimationDialog  *dialog);
+
 static void        on_onion_spin_changed     (GtkAdjustment    *adjustment,
                                               AnimationDialog  *dialog);
 static void        on_duration_spin_changed  (GtkAdjustment    *adjustment,
@@ -505,10 +509,33 @@ animation_dialog_constructed (GObject *object)
                     3, 5, 0, 1, GTK_SHRINK, GTK_SHRINK, 1, 1);
   gtk_widget_show (priv->animation_type_combo);
 
+  /* Settings: animation size. */
+  widget = gtk_label_new (_("Animation Size: "));
+  gtk_table_attach (GTK_TABLE (priv->settings), widget,
+                    0, 3, 1, 2, GTK_EXPAND, GTK_SHRINK, 1, 1);
+  gtk_widget_show (widget);
+
+  priv->size_entry = gimp_size_entry_new (2, GIMP_UNIT_PIXEL, "%a", TRUE, FALSE, FALSE, 7,
+                                          GIMP_SIZE_ENTRY_UPDATE_SIZE);
+  gimp_size_entry_show_unit_menu (GIMP_SIZE_ENTRY (priv->size_entry), FALSE);
+  gimp_size_entry_attach_label (GIMP_SIZE_ENTRY (priv->size_entry),
+                                _("Width"), 0, 1, 0.0);
+  gimp_size_entry_attach_label (GIMP_SIZE_ENTRY (priv->size_entry),
+                                _("Height"), 0, 2, 0.0);
+  gimp_size_entry_attach_label (GIMP_SIZE_ENTRY (priv->size_entry),
+                                _("px"), 1, 3, 0.5);
+  gtk_table_attach (GTK_TABLE (priv->settings), priv->size_entry,
+                    3, 5, 1, 2, GTK_EXPAND, GTK_SHRINK, 1, 1);
+  g_signal_connect (priv->size_entry,
+                    "value-changed",
+                    G_CALLBACK (animation_size_changed),
+                    dialog);
+  gtk_widget_show (priv->size_entry);
+
   /* Settings: proxy. */
   widget = gtk_label_new (_("Proxy: "));
   gtk_table_attach (GTK_TABLE (priv->settings), widget,
-                    0, 3, 1, 2, GTK_EXPAND, GTK_SHRINK, 1, 1);
+                    0, 3, 2, 3, GTK_EXPAND, GTK_SHRINK, 1, 1);
   gtk_widget_show (widget);
 
   priv->proxycombo = gtk_combo_box_text_new_with_entry ();
@@ -541,12 +568,12 @@ animation_dialog_constructed (GObject *object)
 
   gtk_widget_show (priv->proxycombo);
   gtk_table_attach (GTK_TABLE (priv->settings), priv->proxycombo,
-                    3, 5, 1, 2, GTK_SHRINK, GTK_SHRINK, 1, 1);
+                    3, 5, 2, 3, GTK_SHRINK, GTK_SHRINK, 1, 1);
 
   /* Settings: fps */
   widget = gtk_label_new (_("Framerate: "));
   gtk_table_attach (GTK_TABLE (priv->settings), widget,
-                    0, 3, 2, 3, GTK_EXPAND, GTK_SHRINK, 1, 1);
+                    0, 3, 3, 4, GTK_EXPAND, GTK_SHRINK, 1, 1);
   gtk_widget_show (widget);
 
   priv->fpscombo = gtk_combo_box_text_new_with_entry ();
@@ -574,7 +601,7 @@ animation_dialog_constructed (GObject *object)
   gimp_help_set_help_data (priv->fpscombo, _("Frame Rate"), NULL);
 
   gtk_table_attach (GTK_TABLE (priv->settings), priv->fpscombo,
-                    3, 5, 2, 3, GTK_SHRINK, GTK_SHRINK, 1, 1);
+                    3, 5, 3, 4, GTK_SHRINK, GTK_SHRINK, 1, 1);
   gtk_widget_show (priv->fpscombo);
 
   /* Settings: onion skinning */
@@ -583,7 +610,7 @@ animation_dialog_constructed (GObject *object)
                     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 (0.0, 0.0, 5.0, 1.0, 2.0, 0.0));
@@ -594,7 +621,7 @@ animation_dialog_constructed (GObject *object)
   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);
+                    3, 4, 4, 5, GTK_SHRINK, GTK_SHRINK, 1, 1);
 
   g_signal_connect (adjust,
                     "value-changed",
@@ -609,7 +636,7 @@ animation_dialog_constructed (GObject *object)
                     G_CALLBACK (hide_on_animatic),
                     widget);
   gtk_table_attach (GTK_TABLE (priv->settings), widget,
-                    0, 3, 4, 5, GTK_SHRINK, GTK_SHRINK, 1, 1);
+                    0, 3, 5, 6, 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));
@@ -620,7 +647,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, 4, 5, GTK_SHRINK, GTK_SHRINK, 1, 1);
+                    3, 4, 5, 6, GTK_SHRINK, GTK_SHRINK, 1, 1);
 
   g_signal_connect (adjust,
                     "value-changed",
@@ -634,7 +661,7 @@ animation_dialog_constructed (GObject *object)
                     G_CALLBACK (hide_on_animatic),
                     widget);
   gtk_table_attach (GTK_TABLE (priv->settings), widget,
-                    4, 5, 4, 5, GTK_SHRINK, GTK_SHRINK, 1, 1);
+                    4, 5, 5, 6, GTK_SHRINK, GTK_SHRINK, 1, 1);
   gtk_widget_show (widget);
 
   gtk_widget_show (priv->settings);
@@ -1254,6 +1281,8 @@ animation_dialog_set_animation (AnimationDialog *dialog,
   gchar                  *text;
   gdouble                 fps;
   gint                    index;
+  gint                    width;
+  gint                    height;
 
   /* Disconnect all handlers on the previous animation. */
   if (priv->animation)
@@ -1316,6 +1345,20 @@ animation_dialog_set_animation (AnimationDialog *dialog,
                 "animation", animation,
                 NULL);
 
+  /* Settings: display size. */
+  g_signal_handlers_block_by_func (priv->size_entry,
+                                   G_CALLBACK (animation_size_changed),
+                                   dialog);
+  animation_get_size (animation, &width, &height);
+  gimp_size_entry_set_value (GIMP_SIZE_ENTRY (priv->size_entry),
+                             0, (gdouble) width);
+  gimp_size_entry_set_value (GIMP_SIZE_ENTRY (priv->size_entry),
+                             1, (gdouble) height);
+
+  g_signal_handlers_unblock_by_func (priv->size_entry,
+                                     G_CALLBACK (animation_size_changed),
+                                     dialog);
+
   /* Settings: proxy image. */
   g_signal_handlers_unblock_by_func (GTK_ENTRY (gtk_bin_get_child (GTK_BIN (priv->proxycombo))),
                                    G_CALLBACK (proxycombo_activated),
@@ -1409,7 +1452,7 @@ animation_dialog_set_animation (AnimationDialog *dialog,
       /* The animation type box. */
       gtk_combo_box_set_active (GTK_COMBO_BOX (priv->animation_type_combo), 1);
 
-      /* Settings: onion-skins */
+      /* Settings: onion-skins. */
       skins = animation_cel_animation_get_onion_skins (ANIMATION_CEL_ANIMATION (animation));
       gtk_spin_button_set_value (GTK_SPIN_BUTTON (priv->onion_spin),
                                  (gdouble) skins);
@@ -1547,6 +1590,26 @@ help_callback (GtkAction           *action,
 }
 
 static void
+animation_size_changed (GimpSizeEntry   *gse,
+                        AnimationDialog *dialog)
+{
+  AnimationDialogPrivate *priv = GET_PRIVATE (dialog);
+  gint                    width;
+  gint                    height;
+
+  width  = (gint) gimp_size_entry_get_value (gse, 0);
+  height = (gint) gimp_size_entry_get_value (gse, 1);
+
+  animation_set_size (priv->animation, width, height);
+  /* Resize the drawing areas. */
+  gtk_widget_set_size_request (priv->drawing_area, width, height);
+  gtk_widget_set_size_request (priv->shape_drawing_area, width, height);
+  /* Keep identical zoom. */
+  update_scale (ANIMATION_DIALOG (dialog),
+                get_zoom (ANIMATION_DIALOG (dialog), -1));
+}
+
+static void
 animation_type_changed (GtkWidget       *combo,
                         AnimationDialog *dialog)
 {


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