[gimp/wip/animation: 82/197] plug-ins: add a spin button to set duration for cel animations.
- From: Jehan Pagès <jehanp src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp/wip/animation: 82/197] plug-ins: add a spin button to set duration for cel animations.
- Date: Sat, 7 Oct 2017 03:05:17 +0000 (UTC)
commit e04da2b7adabcdbc43a6167385fff6692fa55fdb
Author: Jehan <jehan girinstud io>
Date: Fri Nov 11 03:13:24 2016 +0100
plug-ins: add a spin button to set duration for cel animations.
Current GUI is not very pretty, but I just do something which "works"
for now. I also have some issues with the spin button: clicking an arrow
sometimes moves of 2 or 3 frames. Using a debugger, there seems to be
some race condition with GtkSpinButton code which reproduces the event.
I will have to get a closer look later.
.../animation-play/core/animation-celanimation.c | 9 ++-
plug-ins/animation-play/widgets/animation-dialog.c | 62 +++++++++++++
plug-ins/animation-play/widgets/animation-xsheet.c | 91 ++++++++++++++------
3 files changed, 133 insertions(+), 29 deletions(-)
---
diff --git a/plug-ins/animation-play/core/animation-celanimation.c
b/plug-ins/animation-play/core/animation-celanimation.c
index 49eea13..df1f80f 100644
--- a/plug-ins/animation-play/core/animation-celanimation.c
+++ b/plug-ins/animation-play/core/animation-celanimation.c
@@ -337,9 +337,12 @@ animation_cel_animation_set_duration (AnimationCelAnimation *animation,
}
}
- animation->priv->duration = duration;
- g_signal_emit_by_name (animation, "duration-changed",
- duration);
+ if (duration != animation->priv->duration)
+ {
+ animation->priv->duration = duration;
+ g_signal_emit_by_name (animation, "duration-changed",
+ duration);
+ }
}
gint
diff --git a/plug-ins/animation-play/widgets/animation-dialog.c
b/plug-ins/animation-play/widgets/animation-dialog.c
index 948b41a..3be948b 100755
--- a/plug-ins/animation-play/widgets/animation-dialog.c
+++ b/plug-ins/animation-play/widgets/animation-dialog.c
@@ -71,6 +71,8 @@ struct _AnimationDialogPrivate
GtkWidget *animation_type_combo;
GtkWidget *fpscombo;
+ GtkWidget *duration_box;
+ GtkWidget *duration_spin;
GtkWidget *zoomcombo;
GtkWidget *proxycombo;
@@ -147,6 +149,9 @@ static void help_callback (GtkAction *action,
static void animation_type_changed (GtkWidget *combo,
AnimationDialog *dialog);
+static void on_duration_spin_changed (GtkAdjustment *adjustment,
+ AnimationDialog *dialog);
+
static void fpscombo_activated (GtkEntry *combo,
AnimationDialog *dialog);
static void fpscombo_changed (GtkWidget *combo,
@@ -477,6 +482,32 @@ animation_dialog_constructed (GObject *object)
gtk_container_add (GTK_CONTAINER (widget),
priv->proxycombo);
+ /* Settings: duration */
+ priv->duration_box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
+ gtk_box_pack_end (GTK_BOX (priv->settings_bar), priv->duration_box, FALSE, FALSE, 0);
+
+ widget = gtk_label_new (_("frames"));
+ gtk_box_pack_end (GTK_BOX (priv->duration_box), widget, FALSE, FALSE, 0);
+ gtk_widget_show (widget);
+
+ adjust = GTK_ADJUSTMENT (gtk_adjustment_new (240.0, 1.0, G_MAXDOUBLE, 1.0, 10.0, 0.0));
+ priv->duration_spin = gtk_spin_button_new (adjust, 0.0, 0.0);
+ gtk_entry_set_width_chars (GTK_ENTRY (priv->duration_spin), 5);
+ gimp_help_set_help_data (priv->duration_spin, _("Duration in frames"), NULL);
+ gtk_box_pack_end (GTK_BOX (priv->duration_box), priv->duration_spin, FALSE, FALSE, 0);
+
+ widget = gtk_label_new (_("Duration:"));
+ gtk_box_pack_end (GTK_BOX (priv->duration_box), widget, FALSE, FALSE, 0);
+ gtk_widget_show (widget);
+
+ g_signal_connect (adjust,
+ "value-changed",
+ G_CALLBACK (on_duration_spin_changed),
+ dialog);
+
+ gtk_widget_show (priv->duration_spin);
+ gtk_widget_show (priv->duration_box);
+
/* Settings: fps */
priv->fpscombo = gtk_combo_box_text_new_with_entry ();
@@ -1242,6 +1273,9 @@ animation_dialog_set_animation (AnimationDialog *dialog,
/* The animation type box. */
gtk_combo_box_set_active (GTK_COMBO_BOX (priv->animation_type_combo), 0);
+
+ /* The duration box. */
+ gtk_widget_hide (priv->duration_box);
}
else
{
@@ -1256,6 +1290,9 @@ animation_dialog_set_animation (AnimationDialog *dialog,
/* The animation type box. */
gtk_combo_box_set_active (GTK_COMBO_BOX (priv->animation_type_combo), 1);
+
+ /* The duration box. */
+ gtk_widget_show (priv->duration_box);
}
/* The bottom panel. */
@@ -1439,6 +1476,21 @@ animation_type_changed (GtkWidget *combo,
animation_load (animation);
}
+static void
+on_duration_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_duration (animation, (gint) value);
+}
+
/*
* Callback emitted when the user hits the Enter key of the fps combo.
@@ -1953,6 +2005,7 @@ playback_range_changed (AnimationPlayback *playback,
AnimationDialogPrivate *priv = GET_PRIVATE (dialog);
GtkAdjustment *startframe_adjust;
GtkAdjustment *stopframe_adjust;
+ GtkAdjustment *duration_adjust;
update_progress (dialog);
@@ -1974,6 +2027,15 @@ playback_range_changed (AnimationPlayback *playback,
G_CALLBACK (endframe_changed),
dialog);
+ /* The duration adjust for cel animation. */
+ duration_adjust = gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (priv->duration_spin));
+ g_signal_handlers_block_by_func (duration_adjust,
+ G_CALLBACK (on_duration_spin_changed),
+ dialog);
+ gtk_adjustment_set_value (duration_adjust, animation_get_duration (priv->animation));
+ g_signal_handlers_unblock_by_func (duration_adjust,
+ G_CALLBACK (on_duration_spin_changed),
+ dialog);
show_playing_progress (dialog);
}
diff --git a/plug-ins/animation-play/widgets/animation-xsheet.c
b/plug-ins/animation-play/widgets/animation-xsheet.c
index c7aaa9a..5ee9d5c 100755
--- a/plug-ins/animation-play/widgets/animation-xsheet.c
+++ b/plug-ins/animation-play/widgets/animation-xsheet.c
@@ -58,36 +58,41 @@ struct _AnimationXSheetPrivate
GQueue *selected_frames;
GList *comment_fields;
+
+ guint layout_reset_src;
};
-static void animation_xsheet_constructed (GObject *object);
-static void animation_xsheet_set_property (GObject *object,
- guint property_id,
- const GValue *value,
- GParamSpec *pspec);
-static void animation_xsheet_get_property (GObject *object,
- guint property_id,
- GValue *value,
- GParamSpec *pspec);
-static void animation_xsheet_finalize (GObject *object);
+static void animation_xsheet_constructed (GObject *object);
+static void animation_xsheet_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec);
+static void animation_xsheet_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec);
+static void animation_xsheet_finalize (GObject *object);
/* Construction methods */
-static void animation_xsheet_reset_layout (AnimationXSheet *xsheet);
+static gboolean animation_xsheet_reset_layout (AnimationXSheet *xsheet);
/* Callbacks on animation. */
-static void on_animation_loaded (Animation *animation,
- AnimationXSheet *xsheet);
-/* Callbacks on callback. */
-static void on_animation_rendered (AnimationPlayback *animation,
- gint frame_number,
- GeglBuffer *buffer,
- gboolean must_draw_null,
- AnimationXSheet *xsheet);
+static void on_animation_loaded (Animation *animation,
+ AnimationXSheet *xsheet);
+static void on_animation_duration_changed (Animation *animation,
+ gint duration,
+ AnimationXSheet *xsheet);
+/* Callbacks on playback. */
+static void on_animation_rendered (AnimationPlayback *animation,
+ gint frame_number,
+ GeglBuffer *buffer,
+ gboolean must_draw_null,
+ AnimationXSheet *xsheet);
/* Callbacks on layer view. */
-static void on_layer_selection (AnimationLayerView *view,
- GList *layers,
- AnimationXSheet *xsheet);
+static void on_layer_selection (AnimationLayerView *view,
+ GList *layers,
+ AnimationXSheet *xsheet);
/* UI Signals */
static gboolean animation_xsheet_frame_clicked (GtkWidget *button,
@@ -171,8 +176,8 @@ animation_xsheet_new (AnimationCelAnimation *animation,
NULL);
ANIMATION_XSHEET (xsheet)->priv->playback = playback;
g_signal_connect (ANIMATION_XSHEET (xsheet)->priv->playback,
- "render",
- G_CALLBACK (on_animation_rendered), xsheet);
+ "render", G_CALLBACK (on_animation_rendered),
+ xsheet);
return xsheet;
}
@@ -204,6 +209,11 @@ animation_xsheet_constructed (GObject *object)
/* Reload everything when we reload the animation. */
g_signal_connect_after (xsheet->priv->animation, "loaded",
G_CALLBACK (on_animation_loaded), xsheet);
+
+ g_signal_connect_after (xsheet->priv->animation,
+ "duration-changed",
+ G_CALLBACK (on_animation_duration_changed),
+ xsheet);
}
static void
@@ -272,7 +282,7 @@ animation_xsheet_finalize (GObject *object)
G_OBJECT_CLASS (parent_class)->finalize (object);
}
-static void
+static gboolean
animation_xsheet_reset_layout (AnimationXSheet *xsheet)
{
GtkWidget *frame;
@@ -288,8 +298,12 @@ animation_xsheet_reset_layout (AnimationXSheet *xsheet)
(GtkCallback) gtk_widget_destroy,
NULL);
g_list_free_full (xsheet->priv->cels, (GDestroyNotify) g_list_free);
- g_list_free (xsheet->priv->comment_fields);
xsheet->priv->cels = NULL;
+ g_list_free (xsheet->priv->comment_fields);
+ xsheet->priv->comment_fields = NULL;
+ g_list_free (xsheet->priv->position_buttons);
+ xsheet->priv->position_buttons = NULL;
+ xsheet->priv->active_pos_button = NULL;
xsheet->priv->selected_track = -1;
g_queue_clear (xsheet->priv->selected_frames);
@@ -446,6 +460,11 @@ animation_xsheet_reset_layout (AnimationXSheet *xsheet)
gtk_table_set_row_spacings (GTK_TABLE (xsheet->priv->track_layout), 0);
gtk_table_set_col_spacings (GTK_TABLE (xsheet->priv->track_layout), 0);
+
+ /* Return a boolean in order to be used as a source function.
+ * FALSE means the source should be removed once processed. */
+ xsheet->priv->layout_reset_src = 0;
+ return FALSE;
}
static void
@@ -490,6 +509,26 @@ on_animation_loaded (Animation *animation,
}
static void
+on_animation_duration_changed (Animation *animation,
+ gint duration,
+ AnimationXSheet *xsheet)
+{
+ if (! xsheet->priv->layout_reset_src)
+ {
+ gint src;
+
+ /* Directly running animation_xsheet_reset_layout() repeats
+ * indefinitely with a loop timer. There seems to be some kind of
+ * race condition in the spin button code when the action takes
+ * too long. Run this as idle instead.
+ */
+ src = g_idle_add ((GSourceFunc) animation_xsheet_reset_layout,
+ xsheet);
+ xsheet->priv->layout_reset_src = src;
+ }
+}
+
+static void
on_animation_rendered (AnimationPlayback *playback,
gint frame_number,
GeglBuffer *buffer,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]