]> git.draconx.ca Git - liblbx.git/commitdiff
lbxgui: Add support for animating images.
authorNick Bowler <nbowler@draconx.ca>
Mon, 8 Feb 2010 02:24:32 +0000 (21:24 -0500)
committerNick Bowler <nbowler@draconx.ca>
Mon, 8 Feb 2010 17:00:55 +0000 (12:00 -0500)
src/gui/lbxgui.c
src/gui/lbxgui.glade

index f943be361ca0a2e14467b6ab81978291d0decc1f..0592a7ef9d8675a76792899eca464b019a127fdb 100644 (file)
@@ -1,6 +1,8 @@
 #include <config.h>
 #include <stdlib.h>
 #include <string.h>
+#include <math.h>
+
 #include <gtk/gtk.h>
 
 #include "lbx.h"
@@ -11,7 +13,6 @@ static GtkBuilder *builder;
 
 static GtkWidget *canvas;
 static LBX_IMG *image;
-
 /* LBX images can have up to three palettes, with each superseding the last. */
 static struct lbx_colour palette_external[256];
 static struct lbx_colour palette_internal[256];
@@ -19,6 +20,24 @@ static struct lbx_colour palette_override[256];
 
 GdkPixbuf *framebuf;
 
+void play_toggled(GtkToggleButton *button, gpointer data)
+{
+       gboolean active = gtk_toggle_button_get_active(button);
+       GtkWidget *spin;
+
+       if (active && !image) {
+               gtk_toggle_button_set_active(button, FALSE);
+               return;
+       }
+
+       spin = GTK_WIDGET(gtk_builder_get_object(builder, "framespin"));
+       gtk_widget_set_sensitive(spin, !active);
+
+       if (active) {
+               gtk_spin_button_set_value(GTK_SPIN_BUTTON(spin), 0);
+       }
+}
+
 static void get_colour(unsigned char index, unsigned char out[static 3])
 {
        struct lbx_colour *colour;
@@ -80,6 +99,63 @@ void set_frame(GtkSpinButton *spin, gpointer data)
        gdk_window_invalidate_rect(canvas->window, NULL, FALSE);
 }
 
+static void tick(void *p, double delta)
+{
+       static double elapsed = 0;
+       double seconds_per_frame = 1.0/15;
+       struct lbx_imginfo info;
+       GtkSpinButton   *spin;
+       GtkToggleButton *play;
+       unsigned frame;
+
+       if (!image)
+               return;
+
+       lbximg_getinfo(image, &info);
+       spin = GTK_SPIN_BUTTON(gtk_builder_get_object(builder, "framespin"));
+       play = GTK_TOGGLE_BUTTON(gtk_builder_get_object(builder, "playbutton"));
+
+       frame = gtk_spin_button_get_value_as_int(spin);
+       if (!gtk_toggle_button_get_active(play))
+               return;
+
+       elapsed += delta;
+       while (elapsed > seconds_per_frame) {
+               elapsed -= seconds_per_frame;
+
+               if (++frame >= info.nframes) {
+                       if (!info.looping) {
+                               gtk_toggle_button_set_active(play, FALSE);
+                               break;
+                       }
+
+                       frame = info.loopstart;
+               }
+
+               gtk_spin_button_set_value(spin, frame);
+       }
+}
+
+static gboolean timeout(gpointer data)
+{
+       static double lasttime = INFINITY;
+       static GTimer *timer;
+
+       if (isinf(lasttime)) {
+               timer = g_timer_new();
+               if (timer) {
+                       lasttime = 0;
+               }
+       } else {
+               double time = g_timer_elapsed(timer, NULL);
+
+               tick(data, time - lasttime);
+               lasttime = time;
+       }
+
+       return TRUE;
+}
+
 gboolean canvas_expose(GtkWidget *canvas, GdkEventExpose *event, gpointer data)
 {
        if (!framebuf)
@@ -310,6 +386,8 @@ int main(int argc, char **argv)
 
        interface_init();
        gtk_builder_connect_signals(builder, window);
+
+       g_timeout_add(33, timeout, NULL);
        gtk_widget_show_all(window);
        gtk_main();
 }
index fb12bceaa985450854ca15d6d6f86efe71b87786..510098bf0afec3c3956072180a47b77e12cdea41 100644 (file)
                         <property name="position">3</property>
                       </packing>
                     </child>
+                    <child>
+                      <object class="GtkToggleButton" id="playbutton">
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="receives_default">True</property>
+                        <signal name="toggled" handler="play_toggled"/>
+                        <child>
+                          <object class="GtkImage" id="image1">
+                            <property name="visible">True</property>
+                            <property name="stock">gtk-media-play</property>
+                          </object>
+                        </child>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="padding">3</property>
+                        <property name="position">4</property>
+                      </packing>
+                    </child>
                   </object>
                   <packing>
                     <property name="expand">False</property>