[gthumb] [slideshow] use a simple slideshow if clutter is not available
- From: Paolo Bacchilega <paobac src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gthumb] [slideshow] use a simple slideshow if clutter is not available
- Date: Sat, 24 Apr 2010 21:39:26 +0000 (UTC)
commit 6814927c486268f0129e42f00c930db2c29d3ce6
Author: Paolo Bacchilega <paobac src gnome org>
Date: Sat Apr 24 23:35:30 2010 +0200
[slideshow] use a simple slideshow if clutter is not available
If clutter is not available or the clutter initialization fails
use a simple slideshow with no transitions based on gth_image_viewer,
instead of disabling the slideshow feature altogether.
extensions/slideshow/Makefile.am | 4 -
extensions/slideshow/actions.c | 25 +-
extensions/slideshow/callbacks.c | 4 +
extensions/slideshow/gth-slideshow.c | 868 +++++++++++++++++++++------------
extensions/slideshow/gth-slideshow.h | 45 ++-
extensions/slideshow/gth-transition.c | 6 +-
extensions/slideshow/gth-transition.h | 6 +-
extensions/slideshow/main.c | 10 +-
extensions/slideshow/preferences.c | 4 +
9 files changed, 617 insertions(+), 355 deletions(-)
---
diff --git a/extensions/slideshow/Makefile.am b/extensions/slideshow/Makefile.am
index 26329c7..e40a44c 100644
--- a/extensions/slideshow/Makefile.am
+++ b/extensions/slideshow/Makefile.am
@@ -1,5 +1,3 @@
-if ENABLE_CLUTTER
-
SUBDIRS = data
extensiondir = $(pkglibdir)/extensions
@@ -32,8 +30,6 @@ extensioninidir = $(extensiondir)
extensionini_DATA = $(extensionini_in_files:.extension.in.in=.extension)
DISTCLEANFILES = $(extensionini_DATA)
-endif
-
extensionini_in_files = slideshow.extension.in.in
%.extension.in: %.extension.in.in $(extension_LTLIBRARIES)
diff --git a/extensions/slideshow/actions.c b/extensions/slideshow/actions.c
index 6ac470c..5af174d 100644
--- a/extensions/slideshow/actions.c
+++ b/extensions/slideshow/actions.c
@@ -33,12 +33,13 @@ void
gth_browser_activate_action_view_slideshow (GtkAction *action,
GthBrowser *browser)
{
- GList *items;
- GList *file_list;
- GtkWidget *slideshow;
- GthFileData *location;
- char *transition_id;
- GList *transitions = NULL;
+ GList *items;
+ GList *file_list;
+ GthProjector *projector;
+ GtkWidget *slideshow;
+ GthFileData *location;
+ char *transition_id;
+ GList *transitions = NULL;
items = gth_file_selection_get_selected (GTH_FILE_SELECTION (gth_browser_get_file_list_view (browser)));
if ((items == NULL) || (items->next == NULL))
@@ -46,10 +47,18 @@ gth_browser_activate_action_view_slideshow (GtkAction *action,
else
file_list = gth_file_list_get_files (GTH_FILE_LIST (gth_browser_get_file_list (browser)), items);
- slideshow = gth_slideshow_new (browser, file_list);
+ projector = NULL;
+#ifdef HAVE_CLUTTER
+ if (ClutterInitResult == CLUTTER_INIT_SUCCESS)
+ projector = &clutter_projector;
+#endif /* HAVE_CLUTTER */
+ if (projector == NULL)
+ projector = &default_projector;
+
+ slideshow = gth_slideshow_new (projector, browser, file_list);
location = gth_browser_get_location_data (browser);
- if (g_file_info_get_attribute_status (location->info, "slideshow::personalize") == G_FILE_ATTRIBUTE_STATUS_SET) {
+ if (g_file_info_get_attribute_boolean (location->info, "slideshow::personalize")) {
gth_slideshow_set_delay (GTH_SLIDESHOW (slideshow), g_file_info_get_attribute_int32 (location->info, "slideshow::delay"));
gth_slideshow_set_automatic (GTH_SLIDESHOW (slideshow), g_file_info_get_attribute_boolean (location->info, "slideshow::automatic"));
gth_slideshow_set_wrap_around (GTH_SLIDESHOW (slideshow), g_file_info_get_attribute_boolean (location->info, "slideshow::wrap-around"));
diff --git a/extensions/slideshow/callbacks.c b/extensions/slideshow/callbacks.c
index b968827..ea94b5d 100644
--- a/extensions/slideshow/callbacks.c
+++ b/extensions/slideshow/callbacks.c
@@ -382,6 +382,10 @@ ss__dlg_catalog_properties (GtkBuilder *builder,
gtk_widget_show (gth_slideshow_preferences_get_widget (GTH_SLIDESHOW_PREFERENCES (slideshow_preferences), "playlist_box"));
gtk_widget_show (slideshow_preferences);
+#ifndef HAVE_CLUTTER
+ gtk_widget_hide (gth_slideshow_preferences_get_widget (GTH_SLIDESHOW_PREFERENCES (slideshow_preferences), "transition_box"));
+#endif /* ! HAVE_CLUTTER */
+
label = gtk_label_new (_("Slideshow"));
gtk_widget_show (label);
diff --git a/extensions/slideshow/gth-slideshow.c b/extensions/slideshow/gth-slideshow.c
index 4bf22ff..76bbbee 100644
--- a/extensions/slideshow/gth-slideshow.c
+++ b/extensions/slideshow/gth-slideshow.c
@@ -22,12 +22,15 @@
#include <config.h>
#include <gtk/gtk.h>
+#include <gdk/gdkkeysyms.h>
+#ifdef HAVE_CLUTTER
#include <clutter/clutter.h>
#include <clutter-gtk/clutter-gtk.h>
+#endif /* HAVE_CLUTTER */
#if HAVE_GSTREAMER
#include <gst/gst.h>
#include <extensions/gstreamer_utils/gstreamer-utils.h>
-#endif
+#endif /* HAVE_GSTREAMER */
#include "gth-slideshow.h"
#include "gth-transition.h"
@@ -35,33 +38,44 @@
#define DEFAULT_DELAY 2000
+typedef enum {
+ GTH_SLIDESHOW_DIRECTION_FORWARD,
+ GTH_SLIDESHOW_DIRECTION_BACKWARD
+} GthSlideshowDirection;
+
+
struct _GthSlideshowPrivate {
- GthBrowser *browser;
- GList *file_list; /* GthFileData */
- gboolean automatic;
- gboolean wrap_around;
- GList *current;
- GthImagePreloader *preloader;
- GList *transitions; /* GthTransition */
- int n_transitions;
- GthTransition *transition;
- ClutterTimeline *timeline;
- ClutterActor *image1;
- ClutterActor *image2;
- guint next_event;
- guint delay;
- guint hide_cursor_event;
- GRand *rand;
- gboolean first_show;
- gboolean one_loaded;
- char **audio_files;
- gboolean audio_loop;
+ GthProjector *projector;
+ GthBrowser *browser;
+ GList *file_list; /* GthFileData */
+ gboolean automatic;
+ gboolean wrap_around;
+ GList *current;
+ GthImagePreloader *preloader;
+ GList *transitions; /* GthTransition */
+ int n_transitions;
+ GthTransition *transition;
+ GthSlideshowDirection direction;
+#if HAVE_CLUTTER
+ ClutterTimeline *timeline;
+ ClutterActor *image1;
+ ClutterActor *image2;
+#endif
+ GtkWidget *viewer;
+ guint next_event;
+ guint delay;
+ guint hide_cursor_event;
+ GRand *rand;
+ gboolean first_show;
+ gboolean one_loaded;
+ char **audio_files;
+ gboolean audio_loop;
#if HAVE_GSTREAMER
- int current_audio_file;
- GstElement *playbin;
+ int current_audio_file;
+ GstElement *playbin;
#endif
- gboolean paused;
- gboolean animating;
+ gboolean paused;
+ gboolean animating;
};
@@ -101,7 +115,7 @@ _gth_slideshow_load_current_image (GthSlideshow *self)
return;
}
- if (clutter_timeline_get_direction (self->priv->timeline) == CLUTTER_TIMELINE_FORWARD)
+ if (self->priv->direction == GTH_SLIDESHOW_DIRECTION_FORWARD)
self->priv->current = g_list_first (self->priv->file_list);
else
self->priv->current = g_list_last (self->priv->file_list);
@@ -124,6 +138,486 @@ _gth_slideshow_load_current_image (GthSlideshow *self)
static void
+_gth_slideshow_load_next_image (GthSlideshow *self)
+{
+ self->priv->projector->load_next_image (self); /* FIXME */
+ self->priv->direction = GTH_SLIDESHOW_DIRECTION_FORWARD;
+
+ if (self->priv->paused)
+ return;
+
+ self->priv->current = self->priv->current->next;
+ _gth_slideshow_load_current_image (self);
+}
+
+
+static void
+_gth_slideshow_load_prev_image (GthSlideshow *self)
+{
+ self->priv->projector->load_prev_image (self); /* FIXME */
+ self->priv->direction = GTH_SLIDESHOW_DIRECTION_BACKWARD;
+
+ if (self->priv->paused)
+ return;
+
+ self->priv->current = self->priv->current->prev;
+ _gth_slideshow_load_current_image (self);
+}
+
+
+static gboolean
+next_image_cb (gpointer user_data)
+{
+ GthSlideshow *self = user_data;
+
+ if (self->priv->next_event != 0) {
+ g_source_remove (self->priv->next_event);
+ self->priv->next_event = 0;
+ }
+ _gth_slideshow_load_next_image (self);
+
+ return FALSE;
+}
+
+
+static void
+view_next_image_automatically (GthSlideshow *self)
+{
+ if (self->priv->automatic) {
+ if (self->priv->next_event != 0)
+ g_source_remove (self->priv->next_event);
+ self->priv->next_event = g_timeout_add (self->priv->delay, next_image_cb, self);
+ }
+}
+
+
+static void
+image_preloader_requested_ready_cb (GthImagePreloader *preloader,
+ GError *error,
+ gpointer user_data)
+{
+ GthSlideshow *self = user_data;
+ GthImageLoader *image_loader;
+ GdkPixbuf *pixbuf;
+
+ if (error != NULL) {
+ g_clear_error (&error);
+ _gth_slideshow_load_next_image (self);
+ return;
+ }
+
+ image_loader = gth_image_preloader_get_loader (self->priv->preloader, (GthFileData *) self->priv->current->data);
+ if (image_loader == NULL) {
+ _gth_slideshow_load_next_image (self);
+ return;
+ }
+
+ pixbuf = gth_image_loader_get_pixbuf (image_loader);
+ if (pixbuf == NULL) {
+ _gth_slideshow_load_next_image (self);
+ return;
+ }
+
+ self->priv->one_loaded = TRUE;
+ self->priv->projector->image_ready (self, pixbuf); /* FIXME */
+}
+
+
+static void
+gth_slideshow_init (GthSlideshow *self)
+{
+ self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, GTH_TYPE_SLIDESHOW, GthSlideshowPrivate);
+ self->priv->file_list = NULL;
+ self->priv->next_event = 0;
+ self->priv->delay = DEFAULT_DELAY;
+ self->priv->automatic = FALSE;
+ self->priv->wrap_around = FALSE;
+ self->priv->transitions = NULL;
+ self->priv->n_transitions = 0;
+ self->priv->rand = g_rand_new ();
+ self->priv->first_show = TRUE;
+ self->priv->audio_files = NULL;
+ self->priv->paused = FALSE;
+ self->priv->animating = FALSE;
+ self->priv->direction = GTH_SLIDESHOW_DIRECTION_FORWARD;
+
+ self->priv->preloader = gth_image_preloader_new ();
+ g_signal_connect (self->priv->preloader,
+ "requested_ready",
+ G_CALLBACK (image_preloader_requested_ready_cb),
+ self);
+}
+
+
+static void
+gth_slideshow_finalize (GObject *object)
+{
+ GthSlideshow *self = GTH_SLIDESHOW (object);
+
+ if (self->priv->next_event != 0)
+ g_source_remove (self->priv->next_event);
+ if (self->priv->hide_cursor_event != 0)
+ g_source_remove (self->priv->hide_cursor_event);
+
+ _g_object_list_unref (self->priv->file_list);
+ _g_object_unref (self->priv->browser);
+ _g_object_unref (self->priv->preloader);
+ _g_object_list_unref (self->priv->transitions);
+ g_rand_free (self->priv->rand);
+ g_strfreev (self->priv->audio_files);
+ self->priv->projector->finalize (self); /* FIXME */
+
+#if HAVE_GSTREAMER
+ if (self->priv->playbin != NULL) {
+ gst_element_set_state (self->priv->playbin, GST_STATE_NULL);
+ gst_object_unref (GST_OBJECT (self->priv->playbin));
+ self->priv->playbin = NULL;
+ }
+#endif
+
+ G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+
+static void
+gth_slideshow_class_init (GthSlideshowClass *klass)
+{
+ GObjectClass *gobject_class;
+
+ parent_class = g_type_class_peek_parent (klass);
+ g_type_class_add_private (klass, sizeof (GthSlideshowPrivate));
+
+ gobject_class = G_OBJECT_CLASS (klass);
+ gobject_class->finalize = gth_slideshow_finalize;
+}
+
+
+GType
+gth_slideshow_get_type (void)
+{
+ static GType type = 0;
+
+ if (! type) {
+ GTypeInfo type_info = {
+ sizeof (GthSlideshowClass),
+ NULL,
+ NULL,
+ (GClassInitFunc) gth_slideshow_class_init,
+ NULL,
+ NULL,
+ sizeof (GthSlideshow),
+ 0,
+ (GInstanceInitFunc) gth_slideshow_init
+ };
+
+ type = g_type_register_static (GTK_TYPE_WINDOW,
+ "GthSlideshow",
+ &type_info,
+ 0);
+ }
+
+ return type;
+}
+
+
+static gboolean
+hide_cursor_cb (gpointer data)
+{
+ GthSlideshow *self = data;
+
+ g_source_remove (self->priv->hide_cursor_event);
+ self->priv->hide_cursor_event = 0;
+ self->priv->projector->hide_cursor (self); /* FIXME */
+
+ return FALSE;
+}
+
+
+static void
+_gth_slideshow_toggle_pause (GthSlideshow *self)
+{
+ self->priv->paused = ! self->priv->paused;
+ if (self->priv->paused) {
+ self->priv->projector->paused (self); /* FIXME */
+#if HAVE_GSTREAMER
+ if (self->priv->playbin != NULL)
+ gst_element_set_state (self->priv->playbin, GST_STATE_PAUSED);
+#endif
+ }
+ else { /* resume */
+ _gth_slideshow_load_next_image (self);
+#if HAVE_GSTREAMER
+ if (self->priv->playbin != NULL)
+ gst_element_set_state (self->priv->playbin, GST_STATE_PLAYING);
+#endif
+ }
+}
+
+
+#if HAVE_GSTREAMER
+static void
+bus_message_cb (GstBus *bus,
+ GstMessage *message,
+ gpointer user_data)
+{
+ GthSlideshow *self = user_data;
+
+ if (GST_MESSAGE_TYPE (message) == GST_MESSAGE_EOS) {
+ self->priv->current_audio_file++;
+ if ((self->priv->audio_files[self->priv->current_audio_file] == NULL)
+ && self->priv->audio_loop)
+ {
+ self->priv->current_audio_file = 0;
+ }
+ gst_element_set_state (self->priv->playbin, GST_STATE_NULL);
+ g_object_set (G_OBJECT (self->priv->playbin), "uri", self->priv->audio_files[self->priv->current_audio_file], NULL);
+ gst_element_set_state (self->priv->playbin, GST_STATE_PLAYING);
+ }
+}
+#endif
+
+
+static void
+gth_slideshow_show_cb (GtkWidget *widget,
+ GthSlideshow *self)
+{
+ if (! self->priv->first_show)
+ return;
+
+#if HAVE_GSTREAMER
+ if (gstreamer_init ()) {
+ if ((self->priv->audio_files != NULL) && (self->priv->audio_files[0] != NULL)) {
+ self->priv->current_audio_file = 0;
+ if (self->priv->playbin == NULL) {
+ GstBus *bus;
+
+ self->priv->playbin = gst_element_factory_make ("playbin", "playbin");
+ bus = gst_pipeline_get_bus (GST_PIPELINE (self->priv->playbin));
+ gst_bus_add_signal_watch (bus);
+ g_signal_connect (bus, "message", G_CALLBACK (bus_message_cb), self);
+ }
+ else
+ gst_element_set_state (self->priv->playbin, GST_STATE_NULL);
+ g_object_set (G_OBJECT (self->priv->playbin), "uri", self->priv->audio_files[self->priv->current_audio_file], NULL);
+ gst_element_set_state (self->priv->playbin, GST_STATE_PLAYING);
+ }
+ }
+#endif
+
+ _gth_slideshow_load_current_image (self);
+ self->priv->first_show = FALSE;
+}
+
+
+static void
+_gth_slideshow_construct (GthSlideshow *self,
+ GthProjector *projector,
+ GthBrowser *browser,
+ GList *file_list)
+{
+ self->priv->projector = projector;
+ self->priv->browser = _g_object_ref (browser);
+ self->priv->file_list = _g_object_list_ref (file_list);
+ self->priv->current = self->priv->file_list;
+ self->priv->one_loaded = FALSE;
+
+ self->priv->projector->construct (self); /* FIXME */
+
+ g_signal_connect (self, "show", G_CALLBACK (gth_slideshow_show_cb), self);
+}
+
+
+GtkWidget *
+gth_slideshow_new (GthProjector *projector,
+ GthBrowser *browser,
+ GList *file_list /* GthFileData */)
+{
+ GthSlideshow *window;
+
+ g_return_val_if_fail (projector != NULL, NULL);
+
+ window = (GthSlideshow *) g_object_new (GTH_TYPE_SLIDESHOW, NULL);
+ _gth_slideshow_construct (window, projector, browser, file_list);
+
+ return (GtkWidget*) window;
+}
+
+
+void
+gth_slideshow_set_delay (GthSlideshow *self,
+ guint msecs)
+{
+ self->priv->delay = msecs;
+}
+
+
+void
+gth_slideshow_set_automatic (GthSlideshow *self,
+ gboolean automatic)
+{
+ self->priv->automatic = automatic;
+}
+
+
+void
+gth_slideshow_set_wrap_around (GthSlideshow *self,
+ gboolean wrap_around)
+{
+ self->priv->wrap_around = wrap_around;
+}
+
+
+void
+gth_slideshow_set_transitions (GthSlideshow *self,
+ GList *transitions)
+{
+ _g_object_list_unref (self->priv->transitions);
+ self->priv->transitions = _g_object_list_ref (transitions);
+ self->priv->n_transitions = g_list_length (self->priv->transitions);
+}
+
+
+void
+gth_slideshow_set_playlist (GthSlideshow *self,
+ char **files)
+{
+ self->priv->audio_files = g_strdupv (files);
+ self->priv->audio_loop = TRUE;
+}
+
+
+/* -- default projector -- */
+
+
+static void
+default_projector_load_next_image (GthSlideshow *self)
+{
+ /* void */
+}
+
+
+static void
+default_projector_load_prev_image (GthSlideshow *self)
+{
+ /* void */
+}
+
+
+static void
+default_projector_image_ready (GthSlideshow *self,
+ GdkPixbuf *pixbuf)
+{
+ gth_image_viewer_set_pixbuf (GTH_IMAGE_VIEWER (self->priv->viewer), pixbuf);
+ view_next_image_automatically (self);
+}
+
+
+static void
+default_projector_finalize (GthSlideshow *self)
+{
+ /* void */
+}
+
+
+static void
+default_projector_hide_cursor (GthSlideshow *self)
+{
+ gth_image_viewer_hide_cursor (GTH_IMAGE_VIEWER (self->priv->viewer));
+}
+
+
+static void
+default_projector_paused (GthSlideshow *self)
+{
+ /* void */
+}
+
+
+static void
+viewer_event_cb (GtkWidget *widget,
+ GdkEvent *event,
+ GthSlideshow *self)
+{
+ if (event->type == GDK_MOTION_NOTIFY) {
+ gth_image_viewer_show_cursor (GTH_IMAGE_VIEWER (self->priv->viewer));
+ if (self->priv->hide_cursor_event != 0)
+ g_source_remove (self->priv->hide_cursor_event);
+ self->priv->hide_cursor_event = g_timeout_add (HIDE_CURSOR_DELAY, hide_cursor_cb, self);
+ }
+ else if (event->type == GDK_BUTTON_PRESS) {
+ switch (((GdkEventButton *) event)->button) {
+ case 1:
+ _gth_slideshow_load_next_image (self);
+ break;
+ case 3:
+ _gth_slideshow_load_prev_image (self);
+ break;
+ default:
+ break;
+ }
+ }
+ else if (event->type == GDK_KEY_RELEASE) {
+ switch (((GdkEventKey *) event)->keyval) {
+ case GDK_Escape:
+ _gth_slideshow_close (self);
+ break;
+
+ case GDK_space:
+ _gth_slideshow_toggle_pause (self);
+ break;
+
+ case GDK_Up:
+ case GDK_Right:
+ _gth_slideshow_load_next_image (self);
+ break;
+
+ case GDK_Down:
+ case GDK_Left:
+ _gth_slideshow_load_prev_image (self);
+ break;
+ }
+ }
+}
+
+
+static void
+default_projector_construct (GthSlideshow *self)
+{
+ self->priv->viewer = gth_image_viewer_new ();
+ gth_image_viewer_set_black_background (GTH_IMAGE_VIEWER (self->priv->viewer), TRUE);
+ gth_image_viewer_hide_frame (GTH_IMAGE_VIEWER (self->priv->viewer));
+ gth_image_viewer_set_fit_mode (GTH_IMAGE_VIEWER (self->priv->viewer), GTH_FIT_SIZE_IF_LARGER);
+ gth_image_viewer_set_zoom_change (GTH_IMAGE_VIEWER (self->priv->viewer), GTH_ZOOM_CHANGE_FIT_SIZE_IF_LARGER);
+ gth_image_viewer_set_transp_type (GTH_IMAGE_VIEWER (self->priv->viewer), GTH_TRANSP_TYPE_BLACK);
+ gth_image_viewer_set_zoom_quality (GTH_IMAGE_VIEWER (self->priv->viewer), GTH_ZOOM_QUALITY_LOW);
+
+ g_signal_connect (self->priv->viewer, "button-press-event", G_CALLBACK (viewer_event_cb), self);
+ g_signal_connect (self->priv->viewer, "motion-notify-event", G_CALLBACK (viewer_event_cb), self);
+ g_signal_connect (self->priv->viewer, "key-release-event", G_CALLBACK (viewer_event_cb), self);
+
+ gtk_widget_show (self->priv->viewer);
+ gtk_container_add (GTK_CONTAINER (self), self->priv->viewer);
+}
+
+
+GthProjector default_projector = {
+ default_projector_construct,
+ default_projector_paused,
+ default_projector_hide_cursor,
+ default_projector_finalize,
+ default_projector_image_ready,
+ default_projector_load_prev_image,
+ default_projector_load_next_image
+};
+
+
+#ifdef HAVE_CLUTTER
+
+
+/* -- clutter projector -- */
+
+
+static void
_gth_slideshow_swap_current_and_next (GthSlideshow *self)
{
ClutterGeometry tmp_geometry;
@@ -212,48 +706,24 @@ _gth_slideshow_animation_completed (GthSlideshow *self)
static void
-_gth_slideshow_load_next_image (GthSlideshow *self)
+clutter_projector_load_next_image (GthSlideshow *self)
{
if (clutter_timeline_is_playing (self->priv->timeline)) {
clutter_timeline_pause (self->priv->timeline);
_gth_slideshow_animation_completed (self);
}
-
- if (self->priv->paused)
- return;
-
- self->priv->current = self->priv->current->next;
clutter_timeline_set_direction (self->priv->timeline, CLUTTER_TIMELINE_FORWARD);
- _gth_slideshow_load_current_image (self);
}
static void
-_gth_slideshow_load_prev_image (GthSlideshow *self)
+clutter_projector_load_prev_image (GthSlideshow *self)
{
if (clutter_timeline_is_playing (self->priv->timeline)) {
clutter_timeline_pause (self->priv->timeline);
_gth_slideshow_animation_completed (self);
}
-
- self->priv->current = self->priv->current->prev;
clutter_timeline_set_direction (self->priv->timeline, CLUTTER_TIMELINE_BACKWARD);
- _gth_slideshow_load_current_image (self);
-}
-
-
-static gboolean
-next_image_cb (gpointer user_data)
-{
- GthSlideshow *self = user_data;
-
- if (self->priv->next_event != 0) {
- g_source_remove (self->priv->next_event);
- self->priv->next_event = 0;
- }
- _gth_slideshow_load_next_image (self);
-
- return FALSE;
}
@@ -262,12 +732,7 @@ animation_completed_cb (ClutterTimeline *timeline,
GthSlideshow *self)
{
_gth_slideshow_animation_completed (self);
-
- if (self->priv->automatic) {
- if (self->priv->next_event != 0)
- g_source_remove (self->priv->next_event);
- self->priv->next_event = g_timeout_add (self->priv->delay, next_image_cb, self);
- }
+ view_next_image_automatically (self);
}
@@ -306,43 +771,19 @@ _gth_slideshow_get_transition (GthSlideshow *self)
static void
-image_preloader_requested_ready_cb (GthImagePreloader *preloader,
- GError *error,
- gpointer user_data)
+clutter_projector_image_ready (GthSlideshow *self,
+ GdkPixbuf *pixbuf)
{
- GthSlideshow *self = user_data;
- GthImageLoader *image_loader;
- GdkPixbuf *pixbuf;
- GdkPixbuf *image;
- ClutterActor *texture;
- int pixbuf_w, pixbuf_h;
- float stage_w, stage_h;
- int pixbuf_x, pixbuf_y;
+ GdkPixbuf *image;
+ ClutterActor *texture;
+ int pixbuf_w, pixbuf_h;
+ float stage_w, stage_h;
+ int pixbuf_x, pixbuf_y;
- if (error != NULL) {
- g_clear_error (&error);
- _gth_slideshow_load_next_image (self);
- return;
- }
-
- self->priv->one_loaded = TRUE;
clutter_actor_get_size (self->stage, &stage_w, &stage_h);
-
if ((stage_w == 0) || (stage_h == 0))
return;
- image_loader = gth_image_preloader_get_loader (self->priv->preloader, (GthFileData *) self->priv->current->data);
- if (image_loader == NULL) {
- _gth_slideshow_load_next_image (self);
- return;
- }
-
- pixbuf = gth_image_loader_get_pixbuf (image_loader);
- if (pixbuf == NULL) {
- _gth_slideshow_load_next_image (self);
- return;
- }
-
image = gdk_pixbuf_new (gdk_pixbuf_get_colorspace (pixbuf),
FALSE,
gdk_pixbuf_get_bits_per_sample (pixbuf),
@@ -393,135 +834,25 @@ image_preloader_requested_ready_cb (GthImagePreloader *preloader,
static void
-gth_slideshow_init (GthSlideshow *self)
-{
- self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, GTH_TYPE_SLIDESHOW, GthSlideshowPrivate);
- self->priv->file_list = NULL;
- self->priv->next_event = 0;
- self->priv->delay = DEFAULT_DELAY;
- self->priv->automatic = FALSE;
- self->priv->wrap_around = FALSE;
- self->priv->transitions = NULL;
- self->priv->n_transitions = 0;
- self->priv->rand = g_rand_new ();
- self->priv->first_show = TRUE;
- self->priv->audio_files = NULL;
- self->priv->paused = FALSE;
- self->priv->animating = FALSE;
-
- self->priv->preloader = gth_image_preloader_new ();
- g_signal_connect (self->priv->preloader,
- "requested_ready",
- G_CALLBACK (image_preloader_requested_ready_cb),
- self);
-}
-
-
-static void
-gth_slideshow_finalize (GObject *object)
+clutter_projector_finalize (GthSlideshow *self)
{
- GthSlideshow *self = GTH_SLIDESHOW (object);
-
- if (self->priv->next_event != 0)
- g_source_remove (self->priv->next_event);
- if (self->priv->hide_cursor_event != 0)
- g_source_remove (self->priv->hide_cursor_event);
-
- _g_object_list_unref (self->priv->file_list);
- _g_object_unref (self->priv->browser);
- _g_object_unref (self->priv->preloader);
_g_object_unref (self->priv->timeline);
- _g_object_list_unref (self->priv->transitions);
- g_rand_free (self->priv->rand);
- g_strfreev (self->priv->audio_files);
-
-#if HAVE_GSTREAMER
- if (self->priv->playbin != NULL) {
- gst_element_set_state (self->priv->playbin, GST_STATE_NULL);
- gst_object_unref (GST_OBJECT (self->priv->playbin));
- self->priv->playbin = NULL;
- }
-#endif
-
- G_OBJECT_CLASS (parent_class)->finalize (object);
}
static void
-gth_slideshow_class_init (GthSlideshowClass *klass)
+clutter_projector_hide_cursor (GthSlideshow *self)
{
- GObjectClass *gobject_class;
-
- parent_class = g_type_class_peek_parent (klass);
- g_type_class_add_private (klass, sizeof (GthSlideshowPrivate));
-
- gobject_class = G_OBJECT_CLASS (klass);
- gobject_class->finalize = gth_slideshow_finalize;
-}
-
-
-GType
-gth_slideshow_get_type (void)
-{
- static GType type = 0;
-
- if (! type) {
- GTypeInfo type_info = {
- sizeof (GthSlideshowClass),
- NULL,
- NULL,
- (GClassInitFunc) gth_slideshow_class_init,
- NULL,
- NULL,
- sizeof (GthSlideshow),
- 0,
- (GInstanceInitFunc) gth_slideshow_init
- };
-
- type = g_type_register_static (GTK_TYPE_WINDOW,
- "GthSlideshow",
- &type_info,
- 0);
- }
-
- return type;
-}
-
-
-static gboolean
-hide_cursor_cb (gpointer data)
-{
- GthSlideshow *self = data;
-
- g_source_remove (self->priv->hide_cursor_event);
- self->priv->hide_cursor_event = 0;
-
clutter_stage_hide_cursor (CLUTTER_STAGE (self->stage));
-
- return FALSE;
}
static void
-_gth_slideshow_toggle_pause (GthSlideshow *self)
+clutter_projector_paused (GthSlideshow *self)
{
- self->priv->paused = ! self->priv->paused;
- if (self->priv->paused) {
- if (self->priv->animating) {
- clutter_timeline_pause (self->priv->timeline);
- _gth_slideshow_animation_completed (self);
- }
-#if HAVE_GSTREAMER
- if (self->priv->playbin != NULL)
- gst_element_set_state (self->priv->playbin, GST_STATE_PAUSED);
-#endif
- }
- else { /* resume */
- _gth_slideshow_load_next_image (self);
-#if HAVE_GSTREAMER
- if (self->priv->playbin != NULL)
- gst_element_set_state (self->priv->playbin, GST_STATE_PLAYING);
-#endif
+ if (self->priv->animating) {
+ clutter_timeline_pause (self->priv->timeline);
+ _gth_slideshow_animation_completed (self);
}
}
@@ -573,61 +904,6 @@ stage_input_cb (ClutterStage *stage,
}
-#if HAVE_GSTREAMER
-static void
-bus_message_cb (GstBus *bus,
- GstMessage *message,
- gpointer user_data)
-{
- GthSlideshow *self = user_data;
-
- if (GST_MESSAGE_TYPE (message) == GST_MESSAGE_EOS) {
- self->priv->current_audio_file++;
- if ((self->priv->audio_files[self->priv->current_audio_file] == NULL)
- && self->priv->audio_loop)
- {
- self->priv->current_audio_file = 0;
- }
- gst_element_set_state (self->priv->playbin, GST_STATE_NULL);
- g_object_set (G_OBJECT (self->priv->playbin), "uri", self->priv->audio_files[self->priv->current_audio_file], NULL);
- gst_element_set_state (self->priv->playbin, GST_STATE_PLAYING);
- }
-}
-#endif
-
-
-static void
-gth_slideshow_show_cb (GtkWidget *widget,
- GthSlideshow *self)
-{
- if (! self->priv->first_show)
- return;
-
-#if HAVE_GSTREAMER
- if (gstreamer_init ()) {
- if ((self->priv->audio_files != NULL) && (self->priv->audio_files[0] != NULL)) {
- self->priv->current_audio_file = 0;
- if (self->priv->playbin == NULL) {
- GstBus *bus;
-
- self->priv->playbin = gst_element_factory_make ("playbin", "playbin");
- bus = gst_pipeline_get_bus (GST_PIPELINE (self->priv->playbin));
- gst_bus_add_signal_watch (bus);
- g_signal_connect (bus, "message", G_CALLBACK (bus_message_cb), self);
- }
- else
- gst_element_set_state (self->priv->playbin, GST_STATE_NULL);
- g_object_set (G_OBJECT (self->priv->playbin), "uri", self->priv->audio_files[self->priv->current_audio_file], NULL);
- gst_element_set_state (self->priv->playbin, GST_STATE_PLAYING);
- }
- }
-#endif
-
- _gth_slideshow_load_current_image (self);
- self->priv->first_show = FALSE;
-}
-
-
static void
gth_slideshow_size_allocate_cb (GtkWidget *widget,
GtkAllocation *allocation,
@@ -698,18 +974,11 @@ gth_slideshow_size_allocate_cb (GtkWidget *widget,
static void
-_gth_slideshow_construct (GthSlideshow *self,
- GthBrowser *browser,
- GList *file_list)
+clutter_projector_construct (GthSlideshow *self)
{
GtkWidget *embed;
ClutterColor background_color = { 0x0, 0x0, 0x0, 0xff };
- self->priv->browser = _g_object_ref (browser);
- self->priv->file_list = _g_object_list_ref (file_list);
- self->priv->current = self->priv->file_list;
- self->priv->one_loaded = FALSE;
-
embed = gtk_clutter_embed_new ();
self->stage = gtk_clutter_embed_get_stage (GTK_CLUTTER_EMBED (embed));
clutter_stage_hide_cursor (CLUTTER_STAGE (self->stage));
@@ -737,62 +1006,19 @@ _gth_slideshow_construct (GthSlideshow *self,
g_signal_connect (self->priv->timeline, "new-frame", G_CALLBACK (animation_frame_cb), self);
g_signal_connect (self->priv->timeline, "started", G_CALLBACK (animation_started_cb), self);
- g_signal_connect (self, "show", G_CALLBACK (gth_slideshow_show_cb), self);
g_signal_connect (self, "size-allocate", G_CALLBACK (gth_slideshow_size_allocate_cb), self);
}
-GtkWidget *
-gth_slideshow_new (GthBrowser *browser,
- GList *file_list /* GthFileData */)
-{
- GthSlideshow *window;
-
- window = (GthSlideshow *) g_object_new (GTH_TYPE_SLIDESHOW, NULL);
- _gth_slideshow_construct (window, browser, file_list);
-
- return (GtkWidget*) window;
-}
-
-
-void
-gth_slideshow_set_delay (GthSlideshow *self,
- guint msecs)
-{
- self->priv->delay = msecs;
-}
-
-
-void
-gth_slideshow_set_automatic (GthSlideshow *self,
- gboolean automatic)
-{
- self->priv->automatic = automatic;
-}
-
-
-void
-gth_slideshow_set_wrap_around (GthSlideshow *self,
- gboolean wrap_around)
-{
- self->priv->wrap_around = wrap_around;
-}
-
-
-void
-gth_slideshow_set_transitions (GthSlideshow *self,
- GList *transitions)
-{
- _g_object_list_unref (self->priv->transitions);
- self->priv->transitions = _g_object_list_ref (transitions);
- self->priv->n_transitions = g_list_length (self->priv->transitions);
-}
+GthProjector clutter_projector = {
+ clutter_projector_construct,
+ clutter_projector_paused,
+ clutter_projector_hide_cursor,
+ clutter_projector_finalize,
+ clutter_projector_image_ready,
+ clutter_projector_load_prev_image,
+ clutter_projector_load_next_image
+};
-void
-gth_slideshow_set_playlist (GthSlideshow *self,
- char **files)
-{
- self->priv->audio_files = g_strdupv (files);
- self->priv->audio_loop = TRUE;
-}
+#endif /* HAVE_CLUTTER*/
diff --git a/extensions/slideshow/gth-slideshow.h b/extensions/slideshow/gth-slideshow.h
index 85f6c06..de5cba3 100644
--- a/extensions/slideshow/gth-slideshow.h
+++ b/extensions/slideshow/gth-slideshow.h
@@ -24,8 +24,10 @@
#define GTH_SLIDESHOW_H
#include <gthumb.h>
+#ifdef HAVE_CLUTTER
#include <clutter/clutter.h>
#include <clutter-gtk/clutter-gtk.h>
+#endif /* HAVE_CLUTTER */
G_BEGIN_DECLS
@@ -43,12 +45,14 @@ typedef struct _GthSlideshowPrivate GthSlideshowPrivate;
struct _GthSlideshow
{
GtkWindow __parent;
+#ifdef HAVE_CLUTTER
ClutterActor *stage;
ClutterActor *current_image;
ClutterActor *next_image;
ClutterGeometry current_geometry;
ClutterGeometry next_geometry;
gboolean first_frame;
+#endif /* HAVE_CLUTTER */
GthSlideshowPrivate *priv;
};
@@ -57,19 +61,36 @@ struct _GthSlideshowClass
GtkWindowClass __parent_class;
};
+typedef struct {
+ void (* construct) (GthSlideshow *self);
+ void (* paused) (GthSlideshow *self);
+ void (* hide_cursor) (GthSlideshow *self);
+ void (* finalize) (GthSlideshow *self);
+ void (* image_ready) (GthSlideshow *self,
+ GdkPixbuf *pixbuf);
+ void (* load_prev_image) (GthSlideshow *self);
+ void (* load_next_image) (GthSlideshow *self);
+} GthProjector;
+
+extern GthProjector default_projector;
+#ifdef HAVE_CLUTTER
+extern GthProjector clutter_projector;
+#endif /* HAVE_CLUTTER */
+
GType gth_slideshow_get_type (void);
-GtkWidget * gth_slideshow_new (GthBrowser *browser,
- GList *file_list /* GthFileData */);
-void gth_slideshow_set_delay (GthSlideshow *self,
- guint msecs);
-void gth_slideshow_set_automatic (GthSlideshow *self,
- gboolean automatic);
-void gth_slideshow_set_wrap_around (GthSlideshow *self,
- gboolean wrap_around);
-void gth_slideshow_set_transitions (GthSlideshow *self,
- GList *transitions);
-void gth_slideshow_set_playlist (GthSlideshow *self,
- char **files);
+GtkWidget * gth_slideshow_new (GthProjector *projector,
+ GthBrowser *browser,
+ GList *file_list /* GthFileData */);
+void gth_slideshow_set_delay (GthSlideshow *self,
+ guint msecs);
+void gth_slideshow_set_automatic (GthSlideshow *self,
+ gboolean automatic);
+void gth_slideshow_set_wrap_around (GthSlideshow *self,
+ gboolean wrap_around);
+void gth_slideshow_set_transitions (GthSlideshow *self,
+ GList *transitions);
+void gth_slideshow_set_playlist (GthSlideshow *self,
+ char **files);
G_END_DECLS
diff --git a/extensions/slideshow/gth-transition.c b/extensions/slideshow/gth-transition.c
index ff1d55e..724fb18 100644
--- a/extensions/slideshow/gth-transition.c
+++ b/extensions/slideshow/gth-transition.c
@@ -34,9 +34,9 @@ enum {
struct _GthTransitionPrivate {
- char *id;
- char *display_name;
- FrameFunc frame_func;
+ char *id;
+ char *display_name;
+ FrameFunc frame_func;
};
diff --git a/extensions/slideshow/gth-transition.h b/extensions/slideshow/gth-transition.h
index 6920c79..133571f 100644
--- a/extensions/slideshow/gth-transition.h
+++ b/extensions/slideshow/gth-transition.h
@@ -24,8 +24,6 @@
#define GTH_TRANSITION_H
#include <glib-object.h>
-#include <clutter/clutter.h>
-#include <clutter-gtk/clutter-gtk.h>
#include "gth-slideshow.h"
G_BEGIN_DECLS
@@ -47,13 +45,13 @@ typedef void (*FrameFunc) (GthSlideshow *slideshow, int msecs);
struct _GthTransition
{
- GtkWindow __parent;
+ GObject __parent;
GthTransitionPrivate *priv;
};
struct _GthTransitionClass
{
- GtkWindowClass __parent_class;
+ GObjectClass __parent_class;
};
GType gth_transition_get_type (void);
diff --git a/extensions/slideshow/main.c b/extensions/slideshow/main.c
index d7ef3a3..48e15a6 100644
--- a/extensions/slideshow/main.c
+++ b/extensions/slideshow/main.c
@@ -29,6 +29,8 @@
#include "preferences.h"
+#ifdef HAVE_CLUTTER
+
#define VALUE_AT_MSECS(v, t)(((double) (v) * ((double) (t) / GTH_TRANSITION_DURATION)))
@@ -264,12 +266,13 @@ cube_from_bottom_transition (GthSlideshow *self,
}
+#endif /* HAVE_CLUTTER */
+
+
G_MODULE_EXPORT void
gthumb_extension_activate (void)
{
- if (ClutterInitResult != CLUTTER_INIT_SUCCESS)
- return;
-
+#ifdef HAVE_CLUTTER
gth_main_register_object (GTH_TYPE_TRANSITION,
"none",
GTH_TYPE_TRANSITION,
@@ -324,6 +327,7 @@ gthumb_extension_activate (void)
"display-name", _("Cube from bottom"),
"frame-func", cube_from_bottom_transition,
NULL);
+#endif /* HAVE_CLUTTER */
gth_hook_add_callback ("slideshow", 10, G_CALLBACK (ss__slideshow_cb), NULL);
gth_hook_add_callback ("gth-browser-construct", 10, G_CALLBACK (ss__gth_browser_construct_cb), NULL);
diff --git a/extensions/slideshow/preferences.c b/extensions/slideshow/preferences.c
index 24db38e..b33ff7d 100644
--- a/extensions/slideshow/preferences.c
+++ b/extensions/slideshow/preferences.c
@@ -102,6 +102,10 @@ ss__dlg_preferences_construct_cb (GtkWidget *dialog,
gtk_widget_show (data->preferences_page);
g_free (current_transition);
+#ifndef HAVE_CLUTTER
+ gtk_widget_hide (gth_slideshow_preferences_get_widget (GTH_SLIDESHOW_PREFERENCES (data->preferences_page), "transition_box"));
+#endif /* ! HAVE_CLUTTER */
+
g_signal_connect (gth_slideshow_preferences_get_widget (GTH_SLIDESHOW_PREFERENCES (data->preferences_page), "transition_combobox"),
"changed",
G_CALLBACK (transition_combobox_changed_cb),
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]