[gimp/wip/animation: 84/197] plug-ins: don't rebuild whole xsheet when changing animation duration.
- From: Jehan Pagès <jehanp src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp/wip/animation: 84/197] plug-ins: don't rebuild whole xsheet when changing animation duration.
- Date: Sat, 7 Oct 2017 03:05:28 +0000 (UTC)
commit 52b764db6940b038c4454045198d1f259019d10d
Author: Jehan <jehan girinstud io>
Date: Sat Nov 12 03:10:25 2016 +0100
plug-ins: don't rebuild whole xsheet when changing animation duration.
plug-ins/animation-play/widgets/animation-xsheet.c | 231 ++++++++++++++++++--
1 files changed, 211 insertions(+), 20 deletions(-)
---
diff --git a/plug-ins/animation-play/widgets/animation-xsheet.c
b/plug-ins/animation-play/widgets/animation-xsheet.c
index 5ee9d5c..e834dc2 100755
--- a/plug-ins/animation-play/widgets/animation-xsheet.c
+++ b/plug-ins/animation-play/widgets/animation-xsheet.c
@@ -59,7 +59,8 @@ struct _AnimationXSheetPrivate
GList *comment_fields;
- guint layout_reset_src;
+ guint layout_update_src;
+ gint duration;
};
static void animation_xsheet_constructed (GObject *object);
@@ -74,25 +75,26 @@ static void animation_xsheet_get_property (GObject *object,
static void animation_xsheet_finalize (GObject *object);
/* Construction methods */
-static gboolean animation_xsheet_reset_layout (AnimationXSheet *xsheet);
+static void animation_xsheet_reset_layout (AnimationXSheet *xsheet);
+static gboolean animation_xsheet_update_layout (AnimationXSheet *xsheet);
/* Callbacks on animation. */
-static void on_animation_loaded (Animation *animation,
- AnimationXSheet *xsheet);
-static void on_animation_duration_changed (Animation *animation,
- gint duration,
- 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);
+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,
@@ -282,7 +284,7 @@ animation_xsheet_finalize (GObject *object)
G_OBJECT_CLASS (parent_class)->finalize (object);
}
-static gboolean
+static void
animation_xsheet_reset_layout (AnimationXSheet *xsheet)
{
GtkWidget *frame;
@@ -317,6 +319,7 @@ animation_xsheet_reset_layout (AnimationXSheet *xsheet)
n_tracks = animation_cel_animation_get_levels (xsheet->priv->animation);
n_frames = animation_get_duration (ANIMATION (xsheet->priv->animation));
+ xsheet->priv->duration = n_frames;
/* The cels structure is a matrix of every cel widget. */
for (j = 0; j < n_tracks; j++)
@@ -460,10 +463,198 @@ 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);
+}
+
+static gboolean
+animation_xsheet_update_layout (AnimationXSheet *xsheet)
+{
+ GList *iter;
+ GList *item;
+ gint prev_duration;
+ gint duration;
+ gint n_tracks;
+ gint i;
+
+ prev_duration = xsheet->priv->duration;
+ duration = animation_get_duration (ANIMATION (xsheet->priv->animation));
+ xsheet->priv->duration = duration;
+
+ n_tracks = animation_cel_animation_get_levels (xsheet->priv->animation);
+
+ /* Only consider duration change in this first version, i.e. removing
+ * or adding frames at the end of the animation.
+ * Further updates could allow removing a given frame, adding a frame
+ * in the middle of the animation, and adding, removing or moving
+ * tracks.
+ */
+ if (prev_duration < duration)
+ {
+ GtkWidget *frame;
+ gint j = 0;
+
+ for (iter = xsheet->priv->cels; iter; iter = iter->next, j++)
+ {
+ /* Show the hidden cels. */
+ item = g_list_nth (iter->data, prev_duration);
+ for (i = prev_duration; item && i < duration; item = item->next, i++)
+ {
+ gtk_widget_show (gtk_widget_get_parent (item->data));
+ }
+ /* Create new cels. */
+ for (; i < duration; i++)
+ {
+ GtkWidget *cel;
+
+ frame = gtk_frame_new (NULL);
+ gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
+ gtk_table_attach (GTK_TABLE (xsheet->priv->track_layout),
+ frame, j + 1, j + 2, i + 1, i + 2,
+ GTK_FILL, GTK_FILL, 0, 0);
+
+ cel = gtk_toggle_button_new ();
+ iter->data = g_list_append (iter->data, cel);
+ g_object_set_data (G_OBJECT (cel), "track-num",
+ GINT_TO_POINTER (j));
+ g_object_set_data (G_OBJECT (cel), "frame-position",
+ GINT_TO_POINTER (i));
+ animation_xsheet_rename_cel (xsheet, cel, FALSE);
+ g_signal_connect (cel, "button-release-event",
+ G_CALLBACK (animation_xsheet_cel_clicked),
+ xsheet);
+ gtk_button_set_relief (GTK_BUTTON (cel), GTK_RELIEF_NONE);
+ gtk_button_set_focus_on_click (GTK_BUTTON (cel), FALSE);
+ gtk_container_add (GTK_CONTAINER (frame), cel);
+ gtk_widget_show (cel);
+ gtk_widget_show (frame);
+ }
+ }
+
+ /* Show hidden position buttons. */
+ item = g_list_nth (xsheet->priv->position_buttons,
+ prev_duration);
+ for (i = prev_duration ; item && i < duration; item = item->next, i++)
+ {
+ gtk_widget_show (gtk_widget_get_parent (item->data));
+ }
+
+ /* Create new position buttons. */
+ for (; i < duration; i++)
+ {
+ GtkWidget *label;
+ gchar *num_str;
+
+ frame = gtk_frame_new (NULL);
+ gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_ETCHED_OUT);
+ gtk_table_attach (GTK_TABLE (xsheet->priv->track_layout),
+ frame, 0, 1, i + 1, i + 2,
+ GTK_FILL, GTK_FILL, 0, 0);
+
+ num_str = g_strdup_printf ("%d", i + 1);
+ label = gtk_toggle_button_new ();
+ xsheet->priv->position_buttons = g_list_append (xsheet->priv->position_buttons,
+ label);
+ gtk_button_set_label (GTK_BUTTON (label), num_str);
+ g_free (num_str);
+ g_object_set_data (G_OBJECT (label), "frame-position",
+ GINT_TO_POINTER (i));
+ gtk_button_set_relief (GTK_BUTTON (label), GTK_RELIEF_NONE);
+ gtk_button_set_focus_on_click (GTK_BUTTON (label), FALSE);
+ g_signal_connect (label, "button-press-event",
+ G_CALLBACK (animation_xsheet_frame_clicked),
+ xsheet);
+ gtk_container_add (GTK_CONTAINER (frame), label);
+
+ gtk_widget_show (label);
+ gtk_widget_show (frame);
+ }
+
+ /* Show hidden comment fields. */
+ item = g_list_nth (xsheet->priv->comment_fields,
+ prev_duration);
+ for (i = prev_duration; item && i < duration; item = item->next, i++)
+ {
+ gtk_widget_show (gtk_widget_get_parent (item->data));
+ }
+
+ /* Create new comment fields. */
+ for (; i < duration; i++)
+ {
+ GtkWidget *comment_field;
+ const gchar *comment;
+ GtkTextBuffer *text_buffer;
+
+ frame = gtk_frame_new (NULL);
+ gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
+ gtk_table_attach (GTK_TABLE (xsheet->priv->track_layout),
+ frame, n_tracks + 1, n_tracks + 6, i + 1, i + 2,
+ GTK_FILL, GTK_FILL, 0, 0);
+ comment_field = gtk_text_view_new ();
+ xsheet->priv->comment_fields = g_list_append (xsheet->priv->comment_fields,
+ comment_field);
+ text_buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (comment_field));
+ comment = animation_cel_animation_get_comment (xsheet->priv->animation,
+ i);
+ if (comment != NULL)
+ gtk_text_buffer_insert_at_cursor (text_buffer, comment, -1);
+
+ g_object_set_data (G_OBJECT (comment_field), "frame-position",
+ GINT_TO_POINTER (i));
+ g_object_set_data (G_OBJECT (text_buffer), "frame-position",
+ GINT_TO_POINTER (i));
+ g_signal_connect (comment_field, "key-press-event",
+ G_CALLBACK (animation_xsheet_comment_keypress),
+ xsheet);
+ g_signal_connect (text_buffer, "changed",
+ (GCallback) animation_xsheet_comment_changed,
+ xsheet);
+ gtk_container_add (GTK_CONTAINER (frame), comment_field);
+ gtk_widget_show (comment_field);
+ gtk_widget_show (frame);
+ }
+ }
+ else if (duration < prev_duration)
+ {
+ /* Removing frames at the end. */
+ for (iter = xsheet->priv->cels; iter; iter = iter->next)
+ {
+ GList *track_cels;
+
+ /* Remove the "cels" buttons. */
+ track_cels = iter->data;
+ item = g_list_nth (track_cels, duration);
+
+ for (i = duration; i < prev_duration; i++)
+ {
+ /* Make sure this is not a selected frame. */
+ g_queue_remove (xsheet->priv->selected_frames,
+ GINT_TO_POINTER (i));
+ }
+ /* Hide the parent frame but keep it around. */
+ for (; item; item = item->next)
+ {
+ gtk_widget_hide (gtk_widget_get_parent (item->data));
+ }
+ }
+ /* Remove the position button. */
+ item = g_list_nth (xsheet->priv->position_buttons,
+ duration);
+ for (; item; item = item->next)
+ {
+ gtk_widget_hide (gtk_widget_get_parent (item->data));
+ }
+
+ /* Remove the comments field. */
+ item = g_list_nth (xsheet->priv->comment_fields,
+ duration);
+ for (; item; item = item->next)
+ {
+ gtk_widget_hide (gtk_widget_get_parent (item->data));
+ }
+ }
/* 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;
+ xsheet->priv->layout_update_src = 0;
return FALSE;
}
@@ -513,7 +704,7 @@ on_animation_duration_changed (Animation *animation,
gint duration,
AnimationXSheet *xsheet)
{
- if (! xsheet->priv->layout_reset_src)
+ if (! xsheet->priv->layout_update_src)
{
gint src;
@@ -522,9 +713,9 @@ on_animation_duration_changed (Animation *animation,
* 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,
+ src = g_idle_add ((GSourceFunc) animation_xsheet_update_layout,
xsheet);
- xsheet->priv->layout_reset_src = src;
+ xsheet->priv->layout_update_src = src;
}
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]