[gthumb/ext: 2/3] [slideshow] various slideshow improvements
- From: Paolo Bacchilega <paobac src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [gthumb/ext: 2/3] [slideshow] various slideshow improvements
- Date: Tue, 1 Sep 2009 19:42:52 +0000 (UTC)
commit 7dd53c57eff21b3514d87bf1237941d845f143f6
Author: Paolo Bacchilega <paobac src gnome org>
Date: Tue Sep 1 21:35:44 2009 +0200
[slideshow] various slideshow improvements
added a tab in the preferences dialog to configure the slideshow;
make the transition system extensible.
configure.ac | 2 +
extensions/comments/main.c | 39 ++--
extensions/file_viewer/gth-file-viewer-page.c | 2 +-
extensions/file_viewer/main.c | 2 +-
extensions/image_viewer/main.c | 2 +-
extensions/image_viewer/preferences.h | 14 +-
extensions/photo_importer/dlg-photo-importer.c | 6 +-
extensions/slideshow/Makefile.am | 8 +-
extensions/slideshow/actions.c | 25 ++-
extensions/slideshow/data/Makefile.am | 18 ++
.../slideshow/data/gthumb-slideshow.schemas.in | 57 ++++
extensions/slideshow/data/ui/Makefile.am | 5 +
.../slideshow/data/ui/slideshow-preferences.ui | 105 +++++++
extensions/slideshow/gth-slideshow.c | 287 +++++++++++---------
extensions/slideshow/gth-slideshow.h | 23 ++-
extensions/slideshow/gth-transition.c | 213 +++++++++++++++
extensions/slideshow/gth-transition.h | 68 +++++
extensions/slideshow/main.c | 124 +++++++++
extensions/slideshow/preferences.c | 189 +++++++++++++
extensions/slideshow/preferences.h | 39 +++
extensions/slideshow/slideshow.extension.in.in | 1 -
gthumb/dlg-personalize-filters.c | 4 +-
gthumb/gth-browser.c | 15 +-
gthumb/gth-filter-file.c | 2 +-
gthumb/gth-hook.c | 4 +-
gthumb/gth-main-default-tests.c | 108 ++++----
gthumb/gth-main.c | 233 ++++++++--------
gthumb/gth-main.h | 18 +-
gthumb/gth-test-chain.c | 2 +-
gthumb/gth-test-selector.c | 8 +-
30 files changed, 1272 insertions(+), 351 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index d63faa9..820e734 100644
--- a/configure.ac
+++ b/configure.ac
@@ -286,6 +286,8 @@ extensions/search/Makefile
extensions/search/data/Makefile
extensions/search/data/ui/Makefile
extensions/slideshow/Makefile
+extensions/slideshow/data/Makefile
+extensions/slideshow/data/ui/Makefile
gthumb/Makefile
gthumb/cursors/Makefile
gthumb/icons/Makefile
diff --git a/extensions/comments/main.c b/extensions/comments/main.c
index 3ee1885..85a20d7 100644
--- a/extensions/comments/main.c
+++ b/extensions/comments/main.c
@@ -81,24 +81,27 @@ gthumb_extension_activate (void)
gth_main_register_metadata_info_v (comments_metadata_info);
gth_main_register_metadata_provider (GTH_TYPE_METADATA_PROVIDER_COMMENT);
gth_main_register_type ("edit-metadata-dialog-page", GTH_TYPE_EDIT_COMMENT_PAGE);
- gth_main_register_test ("comment::note",
- GTH_TYPE_TEST_SIMPLE,
- "attributes", "comment::note",
- "display-name", _("Comment"),
- "data-type", GTH_TEST_DATA_TYPE_STRING,
- "get-data-func", get_comment_for_test,
- NULL);
- gth_main_register_test ("comment::place",
- GTH_TYPE_TEST_SIMPLE,
- "attributes", "comment::place",
- "display-name", _("Place"),
- "data-type", GTH_TEST_DATA_TYPE_STRING,
- "get-data-func", get_place_for_test,
- NULL);
- gth_main_register_test ("comment::category",
- GTH_TYPE_TEST_CATEGORY,
- "display-name", _("Tag"),
- NULL);
+ gth_main_register_object (GTH_TYPE_TEST,
+ "comment::note",
+ GTH_TYPE_TEST_SIMPLE,
+ "attributes", "comment::note",
+ "display-name", _("Comment"),
+ "data-type", GTH_TEST_DATA_TYPE_STRING,
+ "get-data-func", get_comment_for_test,
+ NULL);
+ gth_main_register_object (GTH_TYPE_TEST,
+ "comment::place",
+ GTH_TYPE_TEST_SIMPLE,
+ "attributes", "comment::place",
+ "display-name", _("Place"),
+ "data-type", GTH_TEST_DATA_TYPE_STRING,
+ "get-data-func", get_place_for_test,
+ NULL);
+ gth_main_register_object (GTH_TYPE_TEST,
+ "comment::category",
+ GTH_TYPE_TEST_CATEGORY,
+ "display-name", _("Tag"),
+ NULL);
gth_hook_add_callback ("add-sidecars", 10, G_CALLBACK (comments__add_sidecars_cb), NULL);
}
diff --git a/extensions/file_viewer/gth-file-viewer-page.c b/extensions/file_viewer/gth-file-viewer-page.c
index 51a54f9..98df0f1 100644
--- a/extensions/file_viewer/gth-file-viewer-page.c
+++ b/extensions/file_viewer/gth-file-viewer-page.c
@@ -249,7 +249,7 @@ gth_file_viewer_page_finalize (GObject *obj)
self = GTH_FILE_VIEWER_PAGE (obj);
- g_object_unref (self->priv->thumb_loader);
+ _g_object_unref (self->priv->thumb_loader);
G_OBJECT_CLASS (gth_file_viewer_page_parent_class)->finalize (obj);
}
diff --git a/extensions/file_viewer/main.c b/extensions/file_viewer/main.c
index a83d43d..be2e406 100644
--- a/extensions/file_viewer/main.c
+++ b/extensions/file_viewer/main.c
@@ -30,7 +30,7 @@
G_MODULE_EXPORT void
gthumb_extension_activate (void)
{
- gth_main_register_object ("viewer-page", GTH_TYPE_FILE_VIEWER_PAGE);
+ gth_main_register_object (GTH_TYPE_VIEWER_PAGE, NULL, GTH_TYPE_FILE_VIEWER_PAGE, NULL);
}
diff --git a/extensions/image_viewer/main.c b/extensions/image_viewer/main.c
index f3e3d75..5bd8a24 100644
--- a/extensions/image_viewer/main.c
+++ b/extensions/image_viewer/main.c
@@ -48,7 +48,7 @@ gthumb_extension_activate (void)
gth_main_register_metadata_category (image_metadata_category);
gth_main_register_metadata_info_v (image_metadata_info);
gth_main_register_metadata_provider (GTH_TYPE_METADATA_PROVIDER_IMAGE);
- gth_main_register_object ("viewer-page", GTH_TYPE_IMAGE_VIEWER_PAGE);
+ gth_main_register_object (GTH_TYPE_VIEWER_PAGE, NULL, GTH_TYPE_IMAGE_VIEWER_PAGE, NULL);
gth_hook_add_callback ("dlg-preferences-construct", 10, G_CALLBACK (image_viewer__dlg_preferences_construct_cb), NULL);
}
diff --git a/extensions/image_viewer/preferences.h b/extensions/image_viewer/preferences.h
index f8fd8d3..50c976f 100644
--- a/extensions/image_viewer/preferences.h
+++ b/extensions/image_viewer/preferences.h
@@ -25,13 +25,13 @@
#include <gthumb.h>
-#define PREF_ZOOM_QUALITY "/apps/gthumb/viewer/zoom_quality"
-#define PREF_ZOOM_CHANGE "/apps/gthumb/viewer/zoom_change"
-#define PREF_TRANSP_TYPE "/apps/gthumb/viewer/transparency_type"
-#define PREF_RESET_SCROLLBARS "/apps/gthumb/viewer/reset_scrollbars"
-#define PREF_CHECK_TYPE "/apps/gthumb/viewer/check_type"
-#define PREF_CHECK_SIZE "/apps/gthumb/viewer/check_size"
-#define PREF_BLACK_BACKGROUND "/apps/gthumb/viewer/black_background"
+#define PREF_VIEWER_ZOOM_QUALITY "/apps/gthumb/viewer/zoom_quality"
+#define PREF_VIEWER_ZOOM_CHANGE "/apps/gthumb/viewer/zoom_change"
+#define PREF_VIEWER_TRANSP_TYPE "/apps/gthumb/viewer/transparency_type"
+#define PREF_VIEWER_RESET_SCROLLBARS "/apps/gthumb/viewer/reset_scrollbars"
+#define PREF_VIEWER_CHECK_TYPE "/apps/gthumb/viewer/check_type"
+#define PREF_VIEWER_CHECK_SIZE "/apps/gthumb/viewer/check_size"
+#define PREF_VIEWER_BLACK_BACKGROUND "/apps/gthumb/viewer/black_background"
void image_viewer__dlg_preferences_construct_cb (GtkWidget *dialog,
GthBrowser *browser,
diff --git a/extensions/photo_importer/dlg-photo-importer.c b/extensions/photo_importer/dlg-photo-importer.c
index 4e55b1a..bc5382b 100644
--- a/extensions/photo_importer/dlg-photo-importer.c
+++ b/extensions/photo_importer/dlg-photo-importer.c
@@ -432,7 +432,7 @@ filter_combobox_changed_cb (GtkComboBox *widget,
idx = gtk_combo_box_get_active (widget);
test_id = g_list_nth (data->general_tests, idx)->data;
- test = gth_main_get_test (test_id);
+ test = gth_main_get_registered_object (GTH_TYPE_TEST, test_id);
gth_file_list_set_filter (GTH_FILE_LIST (data->file_list), test);
g_object_unref (test);
@@ -654,7 +654,7 @@ dlg_photo_importer (GthBrowser *browser,
/**/
- tests = gth_main_get_all_tests ();
+ tests = gth_main_get_registered_objects_id (GTH_TYPE_TEST);
general_filter = "file::type::is_media"; /* default value */
active_filter = 0;
@@ -667,7 +667,7 @@ dlg_photo_importer (GthBrowser *browser,
continue;
i_general += 1;
- test = gth_main_get_test (registered_test_id);
+ test = gth_main_get_registered_object (GTH_TYPE_TEST, registered_test_id);
if (strcmp (registered_test_id, general_filter) == 0) {
active_filter = i_general;
gth_file_list_set_filter (GTH_FILE_LIST (data->file_list), test);
diff --git a/extensions/slideshow/Makefile.am b/extensions/slideshow/Makefile.am
index 8f70c94..09e09b0 100644
--- a/extensions/slideshow/Makefile.am
+++ b/extensions/slideshow/Makefile.am
@@ -1,5 +1,7 @@
if ENABLE_CLUTTER
+SUBDIRS = data
+
extensiondir = $(libdir)/gthumb-2.0/extensions
extension_LTLIBRARIES = libslideshow.la
@@ -10,7 +12,11 @@ libslideshow_la_SOURCES = \
callbacks.h \
gth-slideshow.c \
gth-slideshow.h \
- main.c
+ gth-transition.c \
+ gth-transition.h \
+ main.c \
+ preferences.c \
+ preferences.h
libslideshow_la_CFLAGS = $(GTHUMB_CFLAGS) $(CLUTTER_CFLAGS) $(DISABLE_DEPRECATED) $(WARNINGS) -I$(top_srcdir) -I$(top_builddir)/gthumb
libslideshow_la_LDFLAGS = $(EXTENSION_LIBTOOL_FLAGS)
diff --git a/extensions/slideshow/actions.c b/extensions/slideshow/actions.c
index 316e63d..5e9a4fa 100644
--- a/extensions/slideshow/actions.c
+++ b/extensions/slideshow/actions.c
@@ -25,6 +25,8 @@
#include <glib/gi18n.h>
#include <gthumb.h>
#include "gth-slideshow.h"
+#include "gth-transition.h"
+#include "preferences.h"
void
@@ -34,6 +36,8 @@ gth_browser_activate_action_view_slideshow (GtkAction *action,
GList *items;
GList *file_list;
GtkWidget *slideshow;
+ 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))
@@ -42,11 +46,30 @@ gth_browser_activate_action_view_slideshow (GtkAction *action,
file_list = gth_file_list_get_files (GTH_FILE_LIST (gth_browser_get_file_list (browser)), items);
slideshow = gth_slideshow_new (browser, file_list);
+ gth_slideshow_set_delay (GTH_SLIDESHOW (slideshow), eel_gconf_get_float (PREF_SLIDESHOW_CHANGE_DELAY, 5) * 1000);
+ gth_slideshow_set_automatic (GTH_SLIDESHOW (slideshow), eel_gconf_get_boolean (PREF_SLIDESHOW_AUTOMATIC, TRUE));
+ gth_slideshow_set_loop (GTH_SLIDESHOW (slideshow), eel_gconf_get_boolean (PREF_SLIDESHOW_WRAP_AROUND, FALSE));
+
+ transition_id = eel_gconf_get_string (PREF_SLIDESHOW_TRANSITION, DEFAULT_TRANSITION);
+ if (strcmp (transition_id, "random") == 0) {
+ transitions = gth_main_get_registered_objects (GTH_TYPE_TRANSITION);
+ }
+ else {
+ GthTransition *transition = gth_main_get_registered_object (GTH_TYPE_TRANSITION, transition_id);
+
+ if (transition != NULL)
+ transitions = g_list_append (NULL, transition);
+ else
+ transitions = NULL;
+ }
+ gth_slideshow_set_transitions (GTH_SLIDESHOW (slideshow), transitions);
+
gtk_window_fullscreen (GTK_WINDOW (slideshow));
/*gtk_window_set_default_size (GTK_WINDOW (slideshow), 700, 700);*/
gtk_window_present (GTK_WINDOW (slideshow));
- gth_slideshow_play (GTH_SLIDESHOW (slideshow));
+ _g_object_list_unref (transitions);
+ g_free (transition_id);
_g_object_list_unref (file_list);
_gtk_tree_path_list_free (items);
}
diff --git a/extensions/slideshow/data/Makefile.am b/extensions/slideshow/data/Makefile.am
new file mode 100644
index 0000000..c641128
--- /dev/null
+++ b/extensions/slideshow/data/Makefile.am
@@ -0,0 +1,18 @@
+SUBDIRS = ui
+
+schemadir = @GCONF_SCHEMA_FILE_DIR@
+schema_in_files = gthumb-slideshow.schemas.in
+schema_DATA = $(schema_in_files:.schemas.in=.schemas)
+
+ INTLTOOL_SCHEMAS_RULE@
+
+if GCONF_SCHEMAS_INSTALL
+install-data-local:
+ GCONF_CONFIG_SOURCE=$(GCONF_SCHEMA_CONFIG_SOURCE) $(GCONFTOOL) --makefile-install-rule $(top_builddir)/extensions/image_viewer/data/$(schema_DATA)
+endif
+
+EXTRA_DIST = $(schema_in_files)
+
+CLEANFILES = $(schema_DATA)
+
+-include $(top_srcdir)/git.mk
diff --git a/extensions/slideshow/data/gthumb-slideshow.schemas.in b/extensions/slideshow/data/gthumb-slideshow.schemas.in
new file mode 100644
index 0000000..0c6bfa2
--- /dev/null
+++ b/extensions/slideshow/data/gthumb-slideshow.schemas.in
@@ -0,0 +1,57 @@
+<gconfschemafile>
+ <schemalist>
+
+ <schema>
+ <key>/schemas/apps/gthumb/slideshow/change_delay</key>
+ <applyto>/apps/gthumb/slideshow/change_delay</applyto>
+ <owner>gthumb</owner>
+ <type>float</type>
+ <default>4.0</default>
+ <locale name="C">
+ <short></short>
+ <long>
+ </long>
+ </locale>
+ </schema>
+
+ <schema>
+ <key>/schemas/apps/gthumb/slideshow/wrap_around</key>
+ <applyto>/apps/gthumb/slideshow/wrap_around</applyto>
+ <owner>gthumb</owner>
+ <type>bool</type>
+ <default>false</default>
+ <locale name="C">
+ <short></short>
+ <long>
+ </long>
+ </locale>
+ </schema>
+
+ <schema>
+ <key>/schemas/apps/gthumb/slideshow/automatic</key>
+ <applyto>/apps/gthumb/slideshow/automatic</applyto>
+ <owner>gthumb</owner>
+ <type>bool</type>
+ <default>true</default>
+ <locale name="C">
+ <short></short>
+ <long>
+ </long>
+ </locale>
+ </schema>
+
+ <schema>
+ <key>/schemas/apps/gthumb/slideshow/transition</key>
+ <applyto>/apps/gthumb/slideshow/transition</applyto>
+ <owner>gthumb</owner>
+ <type>string</type>
+ <default>fade-in</default>
+ <locale name="C">
+ <short></short>
+ <long>
+ </long>
+ </locale>
+ </schema>
+
+ </schemalist>
+</gconfschemafile>
diff --git a/extensions/slideshow/data/ui/Makefile.am b/extensions/slideshow/data/ui/Makefile.am
new file mode 100644
index 0000000..4263369
--- /dev/null
+++ b/extensions/slideshow/data/ui/Makefile.am
@@ -0,0 +1,5 @@
+uidir = $(datadir)/gthumb-2.0/ui
+ui_DATA = slideshow-preferences.ui
+EXTRA_DIST = $(ui_DATA)
+
+-include $(top_srcdir)/git.mk
diff --git a/extensions/slideshow/data/ui/slideshow-preferences.ui b/extensions/slideshow/data/ui/slideshow-preferences.ui
new file mode 100644
index 0000000..ebae268
--- /dev/null
+++ b/extensions/slideshow/data/ui/slideshow-preferences.ui
@@ -0,0 +1,105 @@
+<?xml version="1.0"?>
+<interface>
+ <requires lib="gtk+" version="2.16"/>
+ <!-- interface-naming-policy project-wide -->
+ <object class="GtkAdjustment" id="delay_adjustment">
+ <property name="value">5</property>
+ <property name="lower">0.10000000000000001</property>
+ <property name="upper">100</property>
+ <property name="step_increment">0.10000000000000001</property>
+ </object>
+ <object class="GtkVBox" id="preferences_page">
+ <property name="visible">True</property>
+ <property name="border_width">12</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkHBox" id="transition_box">
+ <property name="visible">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkLabel" id="transition_label">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">_Transition effect:</property>
+ <property name="use_underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkHBox" id="hbox1">
+ <property name="visible">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkCheckButton" id="automatic_checkbutton">
+ <property name="label" translatable="yes" comments="This is the first part of the phrase "change automatically, every x seconds", where x is an input control that let the user choose a value.">_Change automatically, every</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="change_delay_spinbutton">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="invisible_char">●</property>
+ <property name="adjustment">delay_adjustment</property>
+ <property name="digits">1</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label2">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">seconds</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="wrap_around_checkbutton">
+ <property name="label" translatable="yes">_Restart when finished</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </object>
+</interface>
diff --git a/extensions/slideshow/gth-slideshow.c b/extensions/slideshow/gth-slideshow.c
index f269f55..374a2ae 100644
--- a/extensions/slideshow/gth-slideshow.c
+++ b/extensions/slideshow/gth-slideshow.c
@@ -25,53 +25,109 @@
#include <clutter/clutter.h>
#include <clutter-gtk/clutter-gtk.h>
#include "gth-slideshow.h"
+#include "gth-transition.h"
-#define ANIMATION_DURATION 200
-#define OPACITY_AT_MSECS(t)((int) (255 * ((double) (t) / ANIMATION_DURATION)))
#define HIDE_CURSOR_DELAY 1000
#define DEFAULT_DELAY 2000
-#define ANGLE_AT_MSECS(t)((180.0 * ((double) (t) / ANIMATION_DURATION)))
-#define POSITION_AT_MSECS(x, t)(((float)(x) * ((double) (t) / ANIMATION_DURATION)))
+
struct _GthSlideshowPrivate {
GthBrowser *browser;
GList *file_list; /* GthFileData */
+ gboolean automatic;
+ gboolean loop;
GList *current;
GthImageLoader *image_loader;
- ClutterActor *stage;
+ GList *transitions; /* GthTransition */
+ int n_transitions;
+ GthTransition *transition;
+ ClutterTimeline *timeline;
ClutterActor *texture1;
ClutterActor *texture2;
- ClutterActor *current_texture;
- ClutterActor *next_texture;
- ClutterTimeline *timeline;
- gboolean first_frame;
guint next_event;
guint delay;
guint hide_cursor_event;
+ GRand *rand;
+ gboolean first_show;
+ gboolean one_loaded;
};
static gpointer parent_class = NULL;
+static GthTransition *
+_gth_slideshow_get_transition (GthSlideshow *self)
+{
+ if (self->priv->transitions == NULL)
+ return NULL;
+ else if (self->priv->transitions->next == NULL)
+ return self->priv->transitions->data;
+ else
+ return g_list_nth_data (self->priv->transitions,
+ g_rand_int_range (self->priv->rand, 0, self->priv->n_transitions));
+}
+
+
static void
_gth_slideshow_load_current_image (GthSlideshow *self)
{
+ if (self->priv->next_event != 0) {
+ g_source_remove (self->priv->next_event);
+ self->priv->next_event = 0;
+ }
+
if (self->priv->current == NULL) {
- gtk_widget_destroy (GTK_WIDGET (self));
- return;
+ if (! self->priv->one_loaded || ! self->priv->loop) {
+ gtk_widget_destroy (GTK_WIDGET (self));
+ return;
+ }
+
+ if (clutter_timeline_get_direction (self->priv->timeline) == CLUTTER_TIMELINE_FORWARD)
+ self->priv->current = g_list_first (self->priv->file_list);
+ else
+ self->priv->current = g_list_last (self->priv->file_list);
}
+ self->priv->transition = _gth_slideshow_get_transition (self);
gth_image_loader_set_file_data (GTH_IMAGE_LOADER (self->priv->image_loader), (GthFileData *) self->priv->current->data);
gth_image_loader_load (GTH_IMAGE_LOADER (self->priv->image_loader));
}
static void
+_gth_slideshow_swap_current_and_next (GthSlideshow *self)
+{
+ ClutterGeometry tmp_geometry;
+
+ self->current_texture = self->next_texture;
+ if (self->current_texture == self->priv->texture1)
+ self->next_texture = self->priv->texture2;
+ else
+ self->next_texture = self->priv->texture1;
+
+ tmp_geometry = self->current_geometry;
+ self->current_geometry = self->next_geometry;
+ self->next_geometry = tmp_geometry;
+}
+
+
+static void
+_gth_slideshow_animation_completed (GthSlideshow *self)
+{
+ if (clutter_timeline_get_direction (self->priv->timeline) == CLUTTER_TIMELINE_FORWARD)
+ _gth_slideshow_swap_current_and_next (self);
+}
+
+
+static void
_gth_slideshow_load_next_image (GthSlideshow *self)
{
- if (clutter_timeline_is_playing (self->priv->timeline))
- return;
+ 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->next;
clutter_timeline_set_direction (self->priv->timeline, CLUTTER_TIMELINE_FORWARD);
_gth_slideshow_load_current_image (self);
@@ -81,8 +137,11 @@ _gth_slideshow_load_next_image (GthSlideshow *self)
static void
_gth_slideshow_load_prev_image (GthSlideshow *self)
{
- if (clutter_timeline_is_playing (self->priv->timeline))
- return;
+ 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);
@@ -94,8 +153,10 @@ next_image_cb (gpointer user_data)
{
GthSlideshow *self = user_data;
- g_source_remove (self->priv->next_event);
- self->priv->next_event = 0;
+ 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;
@@ -106,15 +167,13 @@ static void
animation_completed_cb (ClutterTimeline *timeline,
GthSlideshow *self)
{
- if (clutter_timeline_get_direction (self->priv->timeline) == CLUTTER_TIMELINE_FORWARD) {
- self->priv->current_texture = self->priv->next_texture;
- if (self->priv->current_texture == self->priv->texture1)
- self->priv->next_texture = self->priv->texture2;
- else
- self->priv->next_texture = self->priv->texture1;
- }
+ _gth_slideshow_animation_completed (self);
- /*self->priv->next_event = g_timeout_add (self->priv->delay, next_image_cb, 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);
+ }
}
@@ -123,72 +182,10 @@ animation_frame_cb (ClutterTimeline *timeline,
int msecs,
GthSlideshow *self)
{
- float image_w, image_h;
-
-#ifndef SLIDE
- clutter_actor_get_size (self->priv->stage, &image_w, &image_h);
-
- clutter_actor_set_x (self->priv->next_texture, POSITION_AT_MSECS(image_w, ANIMATION_DURATION - msecs));
- if (self->priv->current_texture != NULL)
- clutter_actor_set_x (self->priv->current_texture, POSITION_AT_MSECS(- image_w, msecs));
-
- if (self->priv->first_frame) {
- if (self->priv->current_texture != NULL)
- clutter_actor_show (self->priv->current_texture);
- clutter_actor_show (self->priv->next_texture);
- self->priv->first_frame = FALSE;
- }
-#endif
-
-#ifdef FADE
- if (self->priv->current_texture != NULL)
- clutter_actor_set_opacity (self->priv->current_texture, OPACITY_AT_MSECS(ANIMATION_DURATION - msecs));
- clutter_actor_set_opacity (self->priv->next_texture, OPACITY_AT_MSECS(msecs));
-
- if (self->priv->first_frame) {
- if (self->priv->current_texture != NULL) {
- clutter_actor_show (self->priv->current_texture);
- clutter_actor_raise (self->priv->next_texture, self->priv->current_texture);
- }
- clutter_actor_show (self->priv->next_texture);
- self->priv->first_frame = FALSE;
- }
-#endif
-
-#ifdef ROTATE
- if ((float) msecs >= (float) ANIMATION_DURATION / 2.0) {
- clutter_actor_show (self->priv->next_texture);
- if (self->priv->current_texture != NULL)
- clutter_actor_hide (self->priv->current_texture);
- }
- else {
- clutter_actor_hide (self->priv->next_texture);
- if (self->priv->current_texture != NULL)
- clutter_actor_show (self->priv->current_texture);
- }
-
- clutter_actor_get_size (self->priv->stage, &image_w, &image_h);
- clutter_actor_set_rotation (self->priv->next_texture,
- CLUTTER_Y_AXIS,
- ANGLE_AT_MSECS (ANIMATION_DURATION - msecs),
- image_w / 2.0,
- 0.0,
- 0.0);
- if (self->priv->current_texture != NULL)
- clutter_actor_set_rotation (self->priv->current_texture,
- CLUTTER_Y_AXIS,
- ANGLE_AT_MSECS (- msecs),
- image_w / 2.0,
- 0.0,
- 0.0);
-
- if (self->priv->first_frame) {
- if (self->priv->current_texture != NULL)
- clutter_actor_raise (self->priv->next_texture, self->priv->current_texture);
- clutter_actor_show (self->priv->next_texture);
- self->priv->first_frame = FALSE;
- }
-#endif
+ if (self->priv->transition != NULL)
+ gth_transition_frame (self->priv->transition, self, msecs);
+ if (self->first_frame)
+ self->first_frame = FALSE;
}
@@ -196,7 +193,7 @@ static void
animation_started_cb (ClutterTimeline *timeline,
GthSlideshow *self)
{
- self->priv->first_frame = TRUE;
+ self->first_frame = TRUE;
}
@@ -213,35 +210,38 @@ image_loader_ready_cb (GthImageLoader *image_loader,
if (error != NULL) {
g_clear_error (&error);
_gth_slideshow_load_next_image (self);
+ return;
}
- clutter_actor_hide (self->priv->next_texture);
+ self->priv->one_loaded = TRUE;
+
+ clutter_actor_hide (self->next_texture);
image = gth_image_loader_get_pixbuf (GTH_IMAGE_LOADER (image_loader));
- gtk_clutter_texture_set_from_pixbuf (CLUTTER_TEXTURE (self->priv->next_texture), image, NULL);
+ gtk_clutter_texture_set_from_pixbuf (CLUTTER_TEXTURE (self->next_texture), image, NULL);
image_w = gdk_pixbuf_get_width (image);
image_h = gdk_pixbuf_get_height (image);
- clutter_actor_get_size (self->priv->stage, &stage_w, &stage_h);
+ clutter_actor_get_size (self->stage, &stage_w, &stage_h);
scale_keeping_ratio (&image_w, &image_h, (int) stage_w, (int) stage_h, TRUE);
- clutter_actor_set_size (self->priv->next_texture, (float) image_w, (float) image_h);
+ clutter_actor_set_size (self->next_texture, (float) image_w, (float) image_h);
image_x = (stage_w - image_w) / 2;
image_y = (stage_h - image_h) / 2;
- clutter_actor_set_position (self->priv->next_texture, image_x, image_y);
+ clutter_actor_set_position (self->next_texture, image_x, image_y);
- if (clutter_timeline_get_direction (self->priv->timeline) == CLUTTER_TIMELINE_BACKWARD) {
- ClutterActor *tmp;
+ self->next_geometry.x = image_x;
+ self->next_geometry.y = image_y;
+ self->next_geometry.width = image_w;
+ self->next_geometry.height = image_h;
- tmp = self->priv->next_texture;
- self->priv->next_texture = self->priv->current_texture;
- self->priv->current_texture = tmp;
- }
+ if (clutter_timeline_get_direction (self->priv->timeline) == CLUTTER_TIMELINE_BACKWARD)
+ _gth_slideshow_swap_current_and_next (self);
clutter_timeline_rewind (self->priv->timeline);
clutter_timeline_start (self->priv->timeline);
- if (self->priv->current_texture == NULL)
- clutter_timeline_advance (self->priv->timeline, ANIMATION_DURATION);
+ if (self->current_texture == NULL)
+ clutter_timeline_advance (self->priv->timeline, GTH_TRANSITION_DURATION);
}
@@ -252,6 +252,12 @@ gth_slideshow_init (GthSlideshow *self)
self->priv->file_list = NULL;
self->priv->next_event = 0;
self->priv->delay = DEFAULT_DELAY;
+ self->priv->automatic = FALSE;
+ self->priv->loop = FALSE;
+ self->priv->transitions = NULL;
+ self->priv->n_transitions = 0;
+ self->priv->rand = g_rand_new ();
+ self->priv->first_show = TRUE;
self->priv->image_loader = gth_image_loader_new (FALSE);
g_signal_connect (self->priv->image_loader, "ready", G_CALLBACK (image_loader_ready_cb), self);
@@ -272,6 +278,8 @@ gth_slideshow_finalize (GObject *object)
_g_object_unref (self->priv->browser);
_g_object_unref (self->priv->image_loader);
_g_object_unref (self->priv->timeline);
+ _g_object_list_unref (self->priv->transitions);
+ g_rand_free (self->priv->rand);
G_OBJECT_CLASS (parent_class)->finalize (object);
}
@@ -326,7 +334,7 @@ hide_cursor_cb (gpointer data)
g_source_remove (self->priv->hide_cursor_event);
self->priv->hide_cursor_event = 0;
- clutter_stage_hide_cursor (CLUTTER_STAGE (self->priv->stage));
+ clutter_stage_hide_cursor (CLUTTER_STAGE (self->stage));
return FALSE;
}
@@ -338,7 +346,7 @@ stage_input_cb (ClutterStage *stage,
GthSlideshow *self)
{
if (event->type == CLUTTER_MOTION) {
- clutter_stage_show_cursor (CLUTTER_STAGE (self->priv->stage));
+ clutter_stage_show_cursor (CLUTTER_STAGE (self->stage));
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);
@@ -362,6 +370,18 @@ stage_input_cb (ClutterStage *stage,
static void
+gth_slideshow_show_cb (GtkWidget *widget,
+ GthSlideshow *self)
+{
+ if (! self->priv->first_show)
+ return;
+
+ _gth_slideshow_load_current_image (self);
+ self->priv->first_show = FALSE;
+}
+
+
+static void
_gth_slideshow_construct (GthSlideshow *self,
GthBrowser *browser,
GList *file_list)
@@ -372,32 +392,35 @@ _gth_slideshow_construct (GthSlideshow *self,
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->priv->stage = gtk_clutter_embed_get_stage (GTK_CLUTTER_EMBED (embed));
- clutter_stage_hide_cursor (CLUTTER_STAGE (self->priv->stage));
- clutter_stage_set_color (CLUTTER_STAGE (self->priv->stage), &stage_color);
- g_signal_connect (self->priv->stage, "motion-event", G_CALLBACK (stage_input_cb), self);
- g_signal_connect (self->priv->stage, "key-release-event", G_CALLBACK (stage_input_cb), self);
+ self->stage = gtk_clutter_embed_get_stage (GTK_CLUTTER_EMBED (embed));
+ clutter_stage_hide_cursor (CLUTTER_STAGE (self->stage));
+ clutter_stage_set_color (CLUTTER_STAGE (self->stage), &stage_color);
+ g_signal_connect (self->stage, "motion-event", G_CALLBACK (stage_input_cb), self);
+ g_signal_connect (self->stage, "key-release-event", G_CALLBACK (stage_input_cb), self);
gtk_widget_show (embed);
gtk_container_add (GTK_CONTAINER (self), embed);
self->priv->texture1 = clutter_texture_new ();
clutter_actor_hide (self->priv->texture1);
- clutter_container_add_actor (CLUTTER_CONTAINER (self->priv->stage), self->priv->texture1);
+ clutter_container_add_actor (CLUTTER_CONTAINER (self->stage), self->priv->texture1);
self->priv->texture2 = clutter_texture_new ();
clutter_actor_hide (self->priv->texture2);
- clutter_container_add_actor (CLUTTER_CONTAINER (self->priv->stage), self->priv->texture2);
+ clutter_container_add_actor (CLUTTER_CONTAINER (self->stage), self->priv->texture2);
- self->priv->current_texture = NULL;
- self->priv->next_texture = self->priv->texture1;
+ self->current_texture = NULL;
+ self->next_texture = self->priv->texture1;
- self->priv->timeline = clutter_timeline_new (ANIMATION_DURATION);
+ self->priv->timeline = clutter_timeline_new (GTH_TRANSITION_DURATION);
g_signal_connect (self->priv->timeline, "completed", G_CALLBACK (animation_completed_cb), 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);
}
@@ -414,19 +437,35 @@ gth_slideshow_new (GthBrowser *browser,
}
-static gboolean
-start_playing (gpointer user_data)
+void
+gth_slideshow_set_delay (GthSlideshow *self,
+ guint msecs)
{
- GthSlideshow *self = user_data;
+ self->priv->delay = msecs;
+}
- _gth_slideshow_load_current_image (self);
- return FALSE;
+void
+gth_slideshow_set_automatic (GthSlideshow *self,
+ gboolean automatic)
+{
+ self->priv->automatic = automatic;
+}
+
+
+void
+gth_slideshow_set_loop (GthSlideshow *self,
+ gboolean loop)
+{
+ self->priv->loop = loop;
}
void
-gth_slideshow_play (GthSlideshow *self)
+gth_slideshow_set_transitions (GthSlideshow *self,
+ GList *transitions)
{
- g_idle_add (start_playing, self);
+ _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);
}
diff --git a/extensions/slideshow/gth-slideshow.h b/extensions/slideshow/gth-slideshow.h
index 7d05209..b18c7d1 100644
--- a/extensions/slideshow/gth-slideshow.h
+++ b/extensions/slideshow/gth-slideshow.h
@@ -24,6 +24,8 @@
#define GTH_SLIDESHOW_H
#include <gthumb.h>
+#include <clutter/clutter.h>
+#include <clutter-gtk/clutter-gtk.h>
G_BEGIN_DECLS
@@ -41,6 +43,12 @@ typedef struct _GthSlideshowPrivate GthSlideshowPrivate;
struct _GthSlideshow
{
GtkWindow __parent;
+ ClutterActor *stage;
+ ClutterActor *current_texture;
+ ClutterActor *next_texture;
+ ClutterGeometry current_geometry;
+ ClutterGeometry next_geometry;
+ gboolean first_frame;
GthSlideshowPrivate *priv;
};
@@ -49,10 +57,17 @@ struct _GthSlideshowClass
GtkWindowClass __parent_class;
};
-GType gth_slideshow_get_type (void);
-GtkWidget * gth_slideshow_new (GthBrowser *browser,
- GList *file_list /* GthFileData */);
-void gth_slideshow_play (GthSlideshow *self);
+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_loop (GthSlideshow *self,
+ gboolean loop);
+void gth_slideshow_set_transitions (GthSlideshow *self,
+ GList *transitions);
G_END_DECLS
diff --git a/extensions/slideshow/gth-transition.c b/extensions/slideshow/gth-transition.c
new file mode 100644
index 0000000..ff1d55e
--- /dev/null
+++ b/extensions/slideshow/gth-transition.c
@@ -0,0 +1,213 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+/*
+ * GThumb
+ *
+ * Copyright (C) 2009 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
+ */
+
+#include <config.h>
+#include "gth-transition.h"
+
+
+/* Properties */
+enum {
+ PROP_0,
+ PROP_ID,
+ PROP_DISPLAY_NAME,
+ PROP_FRAME_FUNC
+};
+
+
+struct _GthTransitionPrivate {
+ char *id;
+ char *display_name;
+ FrameFunc frame_func;
+};
+
+
+static gpointer parent_class = NULL;
+
+
+static void
+gth_transition_init (GthTransition *self)
+{
+ self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, GTH_TYPE_TRANSITION, GthTransitionPrivate);
+ self->priv->id = g_strdup ("");
+ self->priv->display_name = g_strdup ("");
+ self->priv->frame_func = NULL;
+}
+
+
+static void
+gth_transition_finalize (GObject *object)
+{
+ GthTransition *self = GTH_TRANSITION (object);
+
+ g_free (self->priv->id);
+ g_free (self->priv->display_name);
+
+ G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+
+static void
+gth_transition_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ GthTransition *self = GTH_TRANSITION (object);
+
+ switch (property_id) {
+ case PROP_ID:
+ g_free (self->priv->id);
+ self->priv->id = g_value_dup_string (value);
+ if (self->priv->id == NULL)
+ self->priv->id = g_strdup ("");
+ break;
+
+ case PROP_DISPLAY_NAME:
+ g_free (self->priv->display_name);
+ self->priv->display_name = g_value_dup_string (value);
+ if (self->priv->display_name == NULL)
+ self->priv->display_name = g_strdup ("");
+ break;
+
+ case PROP_FRAME_FUNC:
+ self->priv->frame_func = g_value_get_pointer (value);
+ break;
+
+ default:
+ break;
+ }
+}
+
+
+static void
+gth_transition_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ GthTransition *self = GTH_TRANSITION (object);
+
+ switch (property_id) {
+ case PROP_ID:
+ g_value_set_string (value, self->priv->id);
+ break;
+
+ case PROP_DISPLAY_NAME:
+ g_value_set_string (value, self->priv->display_name);
+ break;
+
+ case PROP_FRAME_FUNC:
+ g_value_set_pointer (value, self->priv->frame_func);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+static void
+gth_transition_class_init (GthTransitionClass *klass)
+{
+ GObjectClass *object_class;
+
+ parent_class = g_type_class_peek_parent (klass);
+ g_type_class_add_private (klass, sizeof (GthTransitionPrivate));
+
+ object_class = G_OBJECT_CLASS (klass);
+ object_class->get_property = gth_transition_get_property;
+ object_class->set_property = gth_transition_set_property;
+ object_class->finalize = gth_transition_finalize;
+
+ g_object_class_install_property (object_class,
+ PROP_ID,
+ g_param_spec_string ("id",
+ "ID",
+ "The object id",
+ NULL,
+ G_PARAM_READWRITE));
+ g_object_class_install_property (object_class,
+ PROP_DISPLAY_NAME,
+ g_param_spec_string ("display-name",
+ "Display name",
+ "The user visible name",
+ NULL,
+ G_PARAM_READWRITE));
+ g_object_class_install_property (object_class,
+ PROP_FRAME_FUNC,
+ g_param_spec_pointer ("frame-func",
+ "Frame Function",
+ "The fuction used to set the current frame",
+ G_PARAM_READWRITE));
+}
+
+
+GType
+gth_transition_get_type (void)
+{
+ static GType type = 0;
+
+ if (! type) {
+ GTypeInfo type_info = {
+ sizeof (GthTransitionClass),
+ NULL,
+ NULL,
+ (GClassInitFunc) gth_transition_class_init,
+ NULL,
+ NULL,
+ sizeof (GthTransition),
+ 0,
+ (GInstanceInitFunc) gth_transition_init
+ };
+
+ type = g_type_register_static (G_TYPE_OBJECT,
+ "GthTransition",
+ &type_info,
+ 0);
+ }
+
+ return type;
+}
+
+
+const char *
+gth_transition_get_id (GthTransition *self)
+{
+ return self->priv->id;
+}
+
+
+const char *
+gth_transition_get_display_name (GthTransition *self)
+{
+ return self->priv->display_name;
+}
+
+
+void
+gth_transition_frame (GthTransition *self,
+ GthSlideshow *slideshow,
+ int msecs)
+{
+ if (self->priv->frame_func != NULL)
+ self->priv->frame_func (slideshow, msecs);
+}
diff --git a/extensions/slideshow/gth-transition.h b/extensions/slideshow/gth-transition.h
new file mode 100644
index 0000000..c760e48
--- /dev/null
+++ b/extensions/slideshow/gth-transition.h
@@ -0,0 +1,68 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+/*
+ * GThumb
+ *
+ * Copyright (C) 2009 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef GTH_TRANSITION_H
+#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
+
+#define GTH_TRANSITION_DURATION 200
+
+#define GTH_TYPE_TRANSITION (gth_transition_get_type ())
+#define GTH_TRANSITION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTH_TYPE_TRANSITION, GthTransition))
+#define GTH_TRANSITION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTH_TRANSITION_TYPE, GthTransitionClass))
+#define GTH_IS_TRANSITION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTH_TYPE_TRANSITION))
+#define GTH_IS_TRANSITION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTH_TYPE_TRANSITION))
+#define GTH_TRANSITION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GTH_TYPE_TRANSITION, GthTransitionClass))
+
+typedef struct _GthTransition GthTransition;
+typedef struct _GthTransitionClass GthTransitionClass;
+typedef struct _GthTransitionPrivate GthTransitionPrivate;
+
+typedef void (*FrameFunc) (GthSlideshow *slideshow, int msecs);
+
+struct _GthTransition
+{
+ GtkWindow __parent;
+ GthTransitionPrivate *priv;
+};
+
+struct _GthTransitionClass
+{
+ GtkWindowClass __parent_class;
+};
+
+GType gth_transition_get_type (void);
+const char * gth_transition_get_id (GthTransition *self);
+const char * gth_transition_get_display_name (GthTransition *self);
+void gth_transition_frame (GthTransition *self,
+ GthSlideshow *slideshow,
+ int msecs);
+
+G_END_DECLS
+
+#endif /* GTH_TRANSITION_H */
diff --git a/extensions/slideshow/main.c b/extensions/slideshow/main.c
index b6e4e74..df81799 100644
--- a/extensions/slideshow/main.c
+++ b/extensions/slideshow/main.c
@@ -25,13 +25,137 @@
#include <gtk/gtk.h>
#include <gthumb.h>
#include "callbacks.h"
+#include "gth-transition.h"
+#include "preferences.h"
+
+
+#define OPACITY_AT_MSECS(t)((int) (255 * ((double) (t) / GTH_TRANSITION_DURATION)))
+#define ANGLE_AT_MSECS(t)((180.0 * ((double) (t) / GTH_TRANSITION_DURATION)))
+#define POSITION_AT_MSECS(x, t)(((float)(x) * ((double) (t) / GTH_TRANSITION_DURATION)))
+
+
+static void
+no_transition (GthSlideshow *self,
+ int msecs)
+{
+ if (self->first_frame) {
+ if (self->current_texture != NULL)
+ clutter_actor_hide (self->current_texture);
+ clutter_actor_show (self->next_texture);
+ }
+}
+
+
+static void
+slide_in_transition (GthSlideshow *self,
+ int msecs)
+{
+ float stage_w, stage_h;
+
+ clutter_actor_get_size (self->stage, &stage_w, &stage_h);
+
+ clutter_actor_set_x (self->next_texture, POSITION_AT_MSECS (stage_w, GTH_TRANSITION_DURATION - msecs) + self->next_geometry.x);
+ if (self->current_texture != NULL)
+ clutter_actor_set_x (self->current_texture, POSITION_AT_MSECS (- stage_w, msecs) + self->current_geometry.x);
+
+ if (self->first_frame) {
+ if (self->current_texture != NULL)
+ clutter_actor_show (self->current_texture);
+ clutter_actor_show (self->next_texture);
+ }
+}
+
+
+static void
+fade_in_transition (GthSlideshow *self,
+ int msecs)
+{
+ if (self->current_texture != NULL)
+ clutter_actor_set_opacity (self->current_texture, OPACITY_AT_MSECS (GTH_TRANSITION_DURATION - msecs));
+ clutter_actor_set_opacity (self->next_texture, OPACITY_AT_MSECS(msecs));
+
+ if (self->first_frame) {
+ if (self->current_texture != NULL) {
+ clutter_actor_show (self->current_texture);
+ clutter_actor_raise (self->next_texture, self->current_texture);
+ }
+ clutter_actor_show (self->next_texture);
+ }
+}
+
+
+static void
+flip_transition (GthSlideshow *self,
+ int msecs)
+{
+ float stage_w, stage_h;
+
+ if ((float) msecs >= (float) GTH_TRANSITION_DURATION / 2.0) {
+ clutter_actor_show (self->next_texture);
+ if (self->current_texture != NULL)
+ clutter_actor_hide (self->current_texture);
+ }
+ else {
+ clutter_actor_hide (self->next_texture);
+ if (self->current_texture != NULL)
+ clutter_actor_show (self->current_texture);
+ }
+
+ clutter_actor_get_size (self->stage, &stage_w, &stage_h);
+ clutter_actor_set_rotation (self->next_texture,
+ CLUTTER_Y_AXIS,
+ ANGLE_AT_MSECS (GTH_TRANSITION_DURATION - msecs),
+ stage_w / 2.0,
+ 0.0,
+ 0.0);
+ if (self->current_texture != NULL)
+ clutter_actor_set_rotation (self->current_texture,
+ CLUTTER_Y_AXIS,
+ ANGLE_AT_MSECS (- msecs),
+ stage_w / 2.0,
+ 0.0,
+ 0.0);
+
+ if (self->first_frame) {
+ if (self->current_texture != NULL)
+ clutter_actor_raise (self->next_texture, self->current_texture);
+ clutter_actor_show (self->next_texture);
+ self->first_frame = FALSE;
+ }
+}
G_MODULE_EXPORT void
gthumb_extension_activate (void)
{
+ gth_main_register_object (GTH_TYPE_TRANSITION,
+ "none",
+ GTH_TYPE_TRANSITION,
+ "display-name", _("None"),
+ "frame-func", no_transition,
+ NULL);
+ gth_main_register_object (GTH_TYPE_TRANSITION,
+ "slide-in",
+ GTH_TYPE_TRANSITION,
+ "display-name", _("Slide In"),
+ "frame-func", slide_in_transition,
+ NULL);
+ gth_main_register_object (GTH_TYPE_TRANSITION,
+ "fade-in",
+ GTH_TYPE_TRANSITION,
+ "display-name", _("Fade In"),
+ "frame-func", fade_in_transition,
+ NULL);
+ gth_main_register_object (GTH_TYPE_TRANSITION,
+ "flip",
+ GTH_TYPE_TRANSITION,
+ "display-name", _("Flip Page"),
+ "frame-func", flip_transition,
+ NULL);
+
gth_hook_add_callback ("gth-browser-construct", 10, G_CALLBACK (ss__gth_browser_construct_cb), NULL);
gth_hook_add_callback ("gth-browser-update-sensitivity", 10, G_CALLBACK (ss__gth_browser_update_sensitivity_cb), NULL);
+ gth_hook_add_callback ("dlg-preferences-construct", 20, G_CALLBACK (ss__dlg_preferences_construct_cb), NULL);
}
diff --git a/extensions/slideshow/preferences.c b/extensions/slideshow/preferences.c
new file mode 100644
index 0000000..f9fbc32
--- /dev/null
+++ b/extensions/slideshow/preferences.c
@@ -0,0 +1,189 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+/*
+ * GThumb
+ *
+ * Copyright (C) 2009 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
+ */
+
+#include <config.h>
+#include <glib/gi18n.h>
+#include "gth-transition.h"
+#include "preferences.h"
+
+
+#define GET_WIDGET(name) _gtk_builder_get_widget (data->builder, (name))
+#define BROWSER_DATA_KEY "slideshow-preference-data"
+
+
+enum {
+ TRANSITION_COLUMN_ID,
+ TRANSITION_COLUMN_DISPLAY_NAME
+};
+
+
+typedef struct {
+ GtkBuilder *builder;
+ GtkWidget *transition_combobox;
+} BrowserData;
+
+
+static void
+browser_data_free (BrowserData *data)
+{
+ g_object_unref (data->builder);
+ g_free (data);
+}
+
+
+static void
+transition_combobox_changed_cb (GtkComboBox *combo_box,
+ BrowserData *data)
+{
+ GtkTreeIter iter;
+ GtkTreeModel *tree_model;
+ char *transition_id;
+
+ if (! gtk_combo_box_get_active_iter (GTK_COMBO_BOX (data->transition_combobox), &iter))
+ return;
+
+ tree_model = gtk_combo_box_get_model (GTK_COMBO_BOX (data->transition_combobox));
+ gtk_tree_model_get (tree_model, &iter, TRANSITION_COLUMN_ID, &transition_id, -1);
+ eel_gconf_set_string (PREF_SLIDESHOW_TRANSITION, transition_id);
+
+ g_free (transition_id);
+}
+
+
+static void
+automatic_checkbutton_toggled_cb (GtkToggleButton *button,
+ BrowserData *data)
+{
+ eel_gconf_set_boolean (PREF_SLIDESHOW_AUTOMATIC, gtk_toggle_button_get_active (button));
+}
+
+
+static void
+wrap_around_checkbutton_toggled_cb (GtkToggleButton *button,
+ BrowserData *data)
+{
+ eel_gconf_set_boolean (PREF_SLIDESHOW_WRAP_AROUND, gtk_toggle_button_get_active (button));
+}
+
+
+static void
+change_delay_spinbutton_value_changed_cb (GtkSpinButton *spinbutton,
+ BrowserData *data)
+{
+ eel_gconf_set_float (PREF_SLIDESHOW_CHANGE_DELAY, gtk_spin_button_get_value (spinbutton));
+}
+
+
+void
+ss__dlg_preferences_construct_cb (GtkWidget *dialog,
+ GthBrowser *browser,
+ GtkBuilder *dialog_builder)
+{
+ BrowserData *data;
+ GtkWidget *notebook;
+ GtkWidget *page;
+ GtkListStore *model;
+ GtkCellRenderer *renderer;
+ char *current_transition;
+ GList *transitions;
+ GList *scan;
+ GtkTreeIter iter;
+ int i, i_active;
+ GtkWidget *label;
+
+ data = g_new0 (BrowserData, 1);
+ data->builder = _gtk_builder_new_from_file ("slideshow-preferences.ui", "slideshow");
+
+ notebook = _gtk_builder_get_widget (dialog_builder, "notebook");
+
+ page = _gtk_builder_get_widget (data->builder, "preferences_page");
+ gtk_widget_show (page);
+
+ model = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_STRING);
+ data->transition_combobox = gtk_combo_box_new_with_model (GTK_TREE_MODEL (model));
+ g_object_unref (model);
+
+ renderer = gtk_cell_renderer_text_new ();
+ gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (data->transition_combobox),
+ renderer,
+ TRUE);
+ gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (data->transition_combobox),
+ renderer,
+ "text", TRANSITION_COLUMN_DISPLAY_NAME,
+ NULL);
+
+ current_transition = eel_gconf_get_string (PREF_SLIDESHOW_TRANSITION, DEFAULT_TRANSITION);
+ transitions = gth_main_get_registered_objects (GTH_TYPE_TRANSITION);
+ for (i = 0, i_active = 0, scan = transitions; scan; scan = scan->next, i++) {
+ GthTransition *transition = scan->data;
+
+ if (strcmp (gth_transition_get_id (transition), current_transition) == 0)
+ i_active = i;
+
+ gtk_list_store_append (model, &iter);
+ gtk_list_store_set (model, &iter,
+ TRANSITION_COLUMN_ID, gth_transition_get_id (transition),
+ TRANSITION_COLUMN_DISPLAY_NAME, gth_transition_get_display_name (transition),
+ -1);
+ }
+
+ if (strcmp ("random", current_transition) == 0)
+ i_active = i;
+ gtk_list_store_append (model, &iter);
+ gtk_list_store_set (model, &iter,
+ TRANSITION_COLUMN_ID, "random",
+ TRANSITION_COLUMN_DISPLAY_NAME, _("Random"),
+ -1);
+
+ gtk_combo_box_set_active (GTK_COMBO_BOX (data->transition_combobox), i_active);
+ gtk_widget_show (data->transition_combobox);
+ gtk_container_add (GTK_CONTAINER (GET_WIDGET ("transition_box")), data->transition_combobox);
+ g_free (current_transition);
+
+ gtk_spin_button_set_value (GTK_SPIN_BUTTON (GET_WIDGET ("change_delay_spinbutton")), eel_gconf_get_float (PREF_SLIDESHOW_CHANGE_DELAY, 5));
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (GET_WIDGET ("automatic_checkbutton")), eel_gconf_get_boolean (PREF_SLIDESHOW_AUTOMATIC, TRUE));
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (GET_WIDGET ("wrap_around_checkbutton")), eel_gconf_get_boolean (PREF_SLIDESHOW_WRAP_AROUND, FALSE));
+
+ g_signal_connect (G_OBJECT (data->transition_combobox),
+ "changed",
+ G_CALLBACK (transition_combobox_changed_cb),
+ data);
+ g_signal_connect (G_OBJECT (GET_WIDGET ("automatic_checkbutton")),
+ "toggled",
+ G_CALLBACK (automatic_checkbutton_toggled_cb),
+ data);
+ g_signal_connect (G_OBJECT (GET_WIDGET ("wrap_around_checkbutton")),
+ "toggled",
+ G_CALLBACK (wrap_around_checkbutton_toggled_cb),
+ data);
+ g_signal_connect (G_OBJECT (GET_WIDGET ("change_delay_spinbutton")),
+ "value-changed",
+ G_CALLBACK (change_delay_spinbutton_value_changed_cb),
+ data);
+
+ label = gtk_label_new (_("Slideshow"));
+ gtk_widget_show (label);
+
+ gtk_notebook_append_page (GTK_NOTEBOOK (notebook), page, label);
+
+ g_object_set_data_full (G_OBJECT (dialog), BROWSER_DATA_KEY, data, (GDestroyNotify) browser_data_free);
+}
diff --git a/extensions/slideshow/preferences.h b/extensions/slideshow/preferences.h
new file mode 100644
index 0000000..354efa0
--- /dev/null
+++ b/extensions/slideshow/preferences.h
@@ -0,0 +1,39 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+/*
+ * GThumb
+ *
+ * Copyright (C) 2009 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef PREFERENCES_H
+#define PREFERENCES_H
+
+#include <gthumb.h>
+
+#define PREF_SLIDESHOW_CHANGE_DELAY "/apps/gthumb/slideshow/change_delay"
+#define PREF_SLIDESHOW_WRAP_AROUND "/apps/gthumb/slideshow/wrap_around"
+#define PREF_SLIDESHOW_AUTOMATIC "/apps/gthumb/slideshow/automatic"
+#define PREF_SLIDESHOW_TRANSITION "/apps/gthumb/slideshow/transition"
+
+#define DEFAULT_TRANSITION "fade-in"
+
+void ss__dlg_preferences_construct_cb (GtkWidget *dialog,
+ GthBrowser *browser,
+ GtkBuilder *builder);
+
+#endif /* CALLBACKS_H */
diff --git a/extensions/slideshow/slideshow.extension.in.in b/extensions/slideshow/slideshow.extension.in.in
index 6b4226c..0feac0b 100644
--- a/extensions/slideshow/slideshow.extension.in.in
+++ b/extensions/slideshow/slideshow.extension.in.in
@@ -8,4 +8,3 @@ Version=1.0
[Loader]
Type=module
File=%LIBRARY%
-Requires=catalogs
diff --git a/gthumb/dlg-personalize-filters.c b/gthumb/dlg-personalize-filters.c
index e83443b..df0ee30 100644
--- a/gthumb/dlg-personalize-filters.c
+++ b/gthumb/dlg-personalize-filters.c
@@ -519,7 +519,7 @@ dlg_personalize_filters (GthBrowser *browser)
/* Set widgets data. */
- tests = gth_main_get_all_tests ();
+ tests = gth_main_get_registered_objects_id (GTH_TYPE_TEST);
general_filter = eel_gconf_get_string (PREF_GENERAL_FILTER, DEFAULT_GENERAL_FILTER);
active_filter = 0;
@@ -536,7 +536,7 @@ dlg_personalize_filters (GthBrowser *browser)
if (strcmp (registered_test_id, general_filter) == 0)
active_filter = i_general;
- test = gth_main_get_test (registered_test_id);
+ test = gth_main_get_registered_object (GTH_TYPE_TEST, registered_test_id);
data->general_tests = g_list_prepend (data->general_tests, g_strdup (gth_test_get_id (test)));
gtk_combo_box_append_text (GTK_COMBO_BOX (data->general_filter_combobox), gth_test_get_display_name (test));
g_object_unref (test);
diff --git a/gthumb/gth-browser.c b/gthumb/gth-browser.c
index 32918cd..d15ce77 100644
--- a/gthumb/gth-browser.c
+++ b/gthumb/gth-browser.c
@@ -108,6 +108,7 @@ struct _GthBrowserPrivateData {
GtkWidget *list_extra_widget;
GtkWidget *file_properties;
+ GList *viewer_pages;
GtkWidget *viewer_pane;
GtkWidget *viewer_sidebar;
GtkWidget *viewer_container;
@@ -1997,6 +1998,7 @@ gth_browser_finalize (GObject *object)
_g_object_unref (browser->priv->current_file);
_g_object_unref (browser->priv->viewer_page);
_g_object_unref (browser->priv->image_preloader);
+ _g_object_list_unref (browser->priv->viewer_pages);
_g_object_list_unref (browser->priv->history);
gth_icon_cache_free (browser->priv->menu_icon_cache);
g_hash_table_unref (browser->priv->named_dialogs);
@@ -4154,9 +4156,8 @@ _gth_browser_load_file (GthBrowser *browser,
GthFileData *file_data,
gboolean view)
{
- GPtrArray *viewer_pages;
- int i;
- GList *files;
+ GList *scan;
+ GList *files;
if (file_data == NULL) {
_gth_browser_deactivate_viewer_page (browser);
@@ -4181,11 +4182,11 @@ _gth_browser_load_file (GthBrowser *browser,
_gth_browser_make_file_visible (browser, browser->priv->current_file);
- viewer_pages = gth_main_get_object_set ("viewer-page");
- for (i = viewer_pages->len - 1; i >= 0; i--) {
- GthViewerPage *registered_viewer_page;
+ if (browser->priv->viewer_pages == NULL)
+ browser->priv->viewer_pages = gth_main_get_registered_objects (GTH_TYPE_VIEWER_PAGE);
+ for (scan = browser->priv->viewer_pages; scan; scan = scan->next) {
+ GthViewerPage *registered_viewer_page = scan->data;
- registered_viewer_page = g_ptr_array_index (viewer_pages, i);
if (gth_viewer_page_can_view (registered_viewer_page, browser->priv->current_file)) {
if ((browser->priv->viewer_page != NULL) && (G_OBJECT_TYPE (registered_viewer_page) != G_OBJECT_TYPE (browser->priv->viewer_page))) {
gth_viewer_page_deactivate (browser->priv->viewer_page);
diff --git a/gthumb/gth-filter-file.c b/gthumb/gth-filter-file.c
index e761c2d..50b20f5 100644
--- a/gthumb/gth-filter-file.c
+++ b/gthumb/gth-filter-file.c
@@ -88,7 +88,7 @@ gth_filter_file_load_from_data (GthFilterFile *filters,
dom_domizable_load_from_element (DOM_DOMIZABLE (test), child);
}
else if (strcmp (child->tag_name, "test") == 0) {
- test = gth_main_get_test (dom_element_get_attribute (child, "id"));
+ test = gth_main_get_registered_object (GTH_TYPE_TEST, dom_element_get_attribute (child, "id"));
if (test != NULL)
dom_domizable_load_from_element (DOM_DOMIZABLE (test), child);
}
diff --git a/gthumb/gth-hook.c b/gthumb/gth-hook.c
index ad1b193..5c58758 100644
--- a/gthumb/gth-hook.c
+++ b/gthumb/gth-hook.c
@@ -117,9 +117,9 @@ hook_compare_func (GHook *new_hook,
GthHookCallback *new_function = GTH_HOOK_CALLBACK (new_hook);
GthHookCallback *sibling_function = GTH_HOOK_CALLBACK (sibling);
- if (new_function->sort_order > sibling_function->sort_order)
+ if (new_function->sort_order < sibling_function->sort_order)
return -1;
- else if (new_function->sort_order < sibling_function->sort_order)
+ else if (new_function->sort_order > sibling_function->sort_order)
return 1;
else
return 0;
diff --git a/gthumb/gth-main-default-tests.c b/gthumb/gth-main-default-tests.c
index 8b8ecd8..30bbcf1 100644
--- a/gthumb/gth-main-default-tests.c
+++ b/gthumb/gth-main-default-tests.c
@@ -135,54 +135,62 @@ get_filesize_for_test (GthTest *test,
void
gth_main_register_default_tests (void)
{
- gth_main_register_test ("file::type::is_file",
- GTH_TYPE_TEST_SIMPLE,
- "display-name", _("All Files"),
- "data-type", GTH_TEST_DATA_TYPE_NONE,
- "get-data-func", is_file_test,
- NULL);
- gth_main_register_test ("file::type::is_image",
- GTH_TYPE_TEST_SIMPLE,
- "display-name", _("Images"),
- "data-type", GTH_TEST_DATA_TYPE_NONE,
- "get-data-func", is_image_test,
- NULL);
- gth_main_register_test ("file::type::is_video",
- GTH_TYPE_TEST_SIMPLE,
- "display-name", _("Video"),
- "data-type", GTH_TEST_DATA_TYPE_NONE,
- "get-data-func", is_video_test,
- NULL);
- gth_main_register_test ("file::type::is_audio",
- GTH_TYPE_TEST_SIMPLE,
- "display-name", _("Audio"),
- "data-type", GTH_TEST_DATA_TYPE_NONE,
- "get-data-func", is_audio_test,
- NULL);
- gth_main_register_test ("file::type::is_media",
- GTH_TYPE_TEST_SIMPLE,
- "display-name", _("Media"),
- "data-type", GTH_TEST_DATA_TYPE_NONE,
- "get-data-func", is_media_test,
- NULL);
- gth_main_register_test ("file::type::is_text",
- GTH_TYPE_TEST_SIMPLE,
- "display-name", _("Text Files"),
- "data-type", GTH_TEST_DATA_TYPE_NONE,
- "get-data-func", is_text_test,
- NULL);
- gth_main_register_test ("file::name",
- GTH_TYPE_TEST_SIMPLE,
- "attributes", "gth::file::display-name",
- "display-name", _("Filename"),
- "data-type", GTH_TEST_DATA_TYPE_STRING,
- "get-data-func", get_filename_for_test,
- NULL);
- gth_main_register_test ("file::size",
- GTH_TYPE_TEST_SIMPLE,
- "attributes", "gth::file::size",
- "display-name", _("Size"),
- "data-type", GTH_TEST_DATA_TYPE_SIZE,
- "get-data-func", get_filesize_for_test,
- NULL);
+ gth_main_register_object (GTH_TYPE_TEST,
+ "file::type::is_file",
+ GTH_TYPE_TEST_SIMPLE,
+ "display-name", _("All Files"),
+ "data-type", GTH_TEST_DATA_TYPE_NONE,
+ "get-data-func", is_file_test,
+ NULL);
+ gth_main_register_object (GTH_TYPE_TEST,
+ "file::type::is_image",
+ GTH_TYPE_TEST_SIMPLE,
+ "display-name", _("Images"),
+ "data-type", GTH_TEST_DATA_TYPE_NONE,
+ "get-data-func", is_image_test,
+ NULL);
+ gth_main_register_object (GTH_TYPE_TEST,
+ "file::type::is_video",
+ GTH_TYPE_TEST_SIMPLE,
+ "display-name", _("Video"),
+ "data-type", GTH_TEST_DATA_TYPE_NONE,
+ "get-data-func", is_video_test,
+ NULL);
+ gth_main_register_object (GTH_TYPE_TEST,
+ "file::type::is_audio",
+ GTH_TYPE_TEST_SIMPLE,
+ "display-name", _("Audio"),
+ "data-type", GTH_TEST_DATA_TYPE_NONE,
+ "get-data-func", is_audio_test,
+ NULL);
+ gth_main_register_object (GTH_TYPE_TEST,
+ "file::type::is_media",
+ GTH_TYPE_TEST_SIMPLE,
+ "display-name", _("Media"),
+ "data-type", GTH_TEST_DATA_TYPE_NONE,
+ "get-data-func", is_media_test,
+ NULL);
+ gth_main_register_object (GTH_TYPE_TEST,
+ "file::type::is_text",
+ GTH_TYPE_TEST_SIMPLE,
+ "display-name", _("Text Files"),
+ "data-type", GTH_TEST_DATA_TYPE_NONE,
+ "get-data-func", is_text_test,
+ NULL);
+ gth_main_register_object (GTH_TYPE_TEST,
+ "file::name",
+ GTH_TYPE_TEST_SIMPLE,
+ "attributes", "gth::file::display-name",
+ "display-name", _("Filename"),
+ "data-type", GTH_TEST_DATA_TYPE_STRING,
+ "get-data-func", get_filename_for_test,
+ NULL);
+ gth_main_register_object (GTH_TYPE_TEST,
+ "file::size",
+ GTH_TYPE_TEST_SIMPLE,
+ "attributes", "gth::file::size",
+ "display-name", _("Size"),
+ "data-type", GTH_TEST_DATA_TYPE_SIZE,
+ "get-data-func", get_filesize_for_test,
+ NULL);
}
diff --git a/gthumb/gth-main.c b/gthumb/gth-main.c
index b177e17..7218389 100644
--- a/gthumb/gth-main.c
+++ b/gthumb/gth-main.c
@@ -77,7 +77,8 @@ gth_type_spec_create_object (GthTypeSpec *spec,
GObject *object;
object = g_object_newv (spec->object_type, spec->n_params, spec->params);
- g_object_set (object, "id", object_id, NULL);
+ if (g_object_class_find_property (G_OBJECT_GET_CLASS (object), "id"))
+ g_object_set (object, "id", object_id, NULL);
return object;
}
@@ -94,11 +95,11 @@ struct _GthMainPrivate
GPtrArray *metadata_info;
gboolean metadata_info_sorted;
GHashTable *sort_types;
- GHashTable *tests;
GHashTable *loaders;
GList *viewer_pages;
GHashTable *types;
- GHashTable *objects;
+ GHashTable *classes;
+ GHashTable *objects_order;
GBookmarkFile *bookmarks;
GthFilterFile *filters;
GthTagsFile *tags;
@@ -126,12 +127,14 @@ gth_main_finalize (GObject *object)
if (gth_main->priv->sort_types != NULL)
g_hash_table_unref (gth_main->priv->sort_types);
- if (gth_main->priv->tests != NULL)
- g_hash_table_unref (gth_main->priv->tests);
if (gth_main->priv->loaders != NULL)
g_hash_table_unref (gth_main->priv->loaders);
if (gth_main->priv->types != NULL)
g_hash_table_unref (gth_main->priv->types);
+ if (gth_main->priv->classes != NULL)
+ g_hash_table_unref (gth_main->priv->classes);
+ if (gth_main->priv->objects_order != NULL)
+ g_hash_table_unref (gth_main->priv->objects_order);
if (gth_main->priv->bookmarks != NULL)
g_bookmark_file_free (gth_main->priv->bookmarks);
@@ -168,10 +171,6 @@ gth_main_init (GthMain *main)
g_str_equal,
NULL,
NULL);
- main->priv->tests = g_hash_table_new_full (g_str_hash,
- (GEqualFunc) g_content_type_equals,
- NULL,
- (GDestroyNotify) gth_type_spec_free);
main->priv->loaders = g_hash_table_new (g_str_hash, g_str_equal);
main->priv->metadata_category = g_ptr_array_new ();
main->priv->metadata_info = g_ptr_array_new ();
@@ -664,90 +663,6 @@ _gth_main_create_type_spec (GType object_type,
void
-gth_main_register_test (const char *object_id,
- GType object_type,
- const char *first_property_name,
- ...)
-{
- va_list var_args;
- GthTypeSpec *spec;
-
- va_start (var_args, first_property_name);
- spec = _gth_main_create_type_spec (object_type, first_property_name, var_args);
- va_end (var_args);
-
- g_hash_table_insert (Main->priv->tests, (gpointer) object_id, spec);
-}
-
-
-GthTest *
-gth_main_get_test (const char *object_id)
-{
- GthTypeSpec *spec = NULL;
-
- if (object_id == NULL)
- return NULL;
-
- spec = g_hash_table_lookup (Main->priv->tests, object_id);
- if (spec == NULL)
- return NULL;
-
- return (GthTest *) gth_type_spec_create_object (spec, object_id);
-}
-
-
-static void
-collect_objects (gpointer key,
- gpointer value,
- gpointer user_data)
-{
- GList **objects = user_data;
- GthTypeSpec *spec = value;
-
- *objects = g_list_prepend (*objects, gth_type_spec_create_object (spec, key));
-}
-
-
-G_GNUC_UNUSED
-static GList *
-_gth_main_get_all_objects (GHashTable *table)
-{
- GList *objects = NULL;
-
- g_hash_table_foreach (table, collect_objects, &objects);
- return g_list_reverse (objects);
-}
-
-
-static void
-collect_names (gpointer key,
- gpointer value,
- gpointer user_data)
-{
- GList **objects = user_data;
-
- *objects = g_list_prepend (*objects, g_strdup (key));
-}
-
-
-static GList *
-_gth_main_get_all_object_names (GHashTable *table)
-{
- GList *objects = NULL;
-
- g_hash_table_foreach (table, collect_names, &objects);
- return g_list_reverse (objects);
-}
-
-
-GList *
-gth_main_get_all_tests (void)
-{
- return _gth_main_get_all_object_names (Main->priv->tests);
-}
-
-
-void
gth_main_register_file_loader (FileLoader loader,
const char *first_mime_type,
...)
@@ -782,7 +697,7 @@ gth_main_get_general_filter (void)
GthTest *filter;
filter_name = eel_gconf_get_string (PREF_GENERAL_FILTER, DEFAULT_GENERAL_FILTER);
- filter = gth_main_get_test (filter_name);
+ filter = gth_main_get_registered_object (GTH_TYPE_TEST, filter_name);
g_free (filter_name);
return filter;
@@ -908,39 +823,131 @@ gth_main_get_type_set (const char *set_name)
static void
-_g_destroy_object_array (GPtrArray *array)
+g_ptr_array_destroy (gpointer array)
{
- g_ptr_array_foreach (array, (GFunc) g_object_unref, NULL);
- g_ptr_array_free (array, TRUE);
+ g_ptr_array_free ((GPtrArray *) array, TRUE);
}
void
-gth_main_register_object (const char *set_name,
- GType object_type)
-{
- GPtrArray *set;
+gth_main_register_object (GType superclass_type,
+ const char *object_id,
+ GType object_type,
+ const char *first_property_name,
+ ...)
+{
+ const char *superclass_name;
+ GHashTable *object_hash;
+ GPtrArray *object_order;
+ va_list var_args;
+ GthTypeSpec *spec;
+ char *id;
- if (Main->priv->objects == NULL)
- Main->priv->objects = g_hash_table_new_full (g_str_hash,
+ if (object_id == NULL)
+ object_id = g_type_name (object_type);
+
+ if (Main->priv->classes == NULL) {
+ Main->priv->classes = g_hash_table_new_full (g_str_hash,
g_str_equal,
(GDestroyNotify) g_free,
- (GDestroyNotify) _g_destroy_object_array);
+ (GDestroyNotify) g_hash_table_destroy);
+ Main->priv->objects_order = g_hash_table_new_full (g_str_hash,
+ g_str_equal,
+ (GDestroyNotify) g_free,
+ g_ptr_array_destroy);
+ }
- set = g_hash_table_lookup (Main->priv->objects, set_name);
- if (set == NULL) {
- set = g_ptr_array_new ();
- g_hash_table_insert (Main->priv->objects, g_strdup (set_name), set);
+ superclass_name = g_type_name (superclass_type);
+ object_hash = g_hash_table_lookup (Main->priv->classes, superclass_name);
+ object_order = g_hash_table_lookup (Main->priv->objects_order, superclass_name);
+
+ if (object_hash == NULL) {
+ object_hash = g_hash_table_new_full (g_str_hash,
+ g_str_equal,
+ (GDestroyNotify) g_free,
+ (GDestroyNotify) gth_type_spec_free);
+ g_hash_table_insert (Main->priv->classes, g_strdup (superclass_name), object_hash);
+
+ object_order = g_ptr_array_new ();
+ g_hash_table_insert (Main->priv->objects_order, g_strdup (superclass_name), object_order);
}
- g_ptr_array_add (set, g_object_new (object_type, NULL));
+ va_start (var_args, first_property_name);
+ spec = _gth_main_create_type_spec (object_type, first_property_name, var_args);
+ va_end (var_args);
+
+ id = g_strdup (object_id);
+ g_hash_table_insert (object_hash, id, spec);
+ g_ptr_array_add (object_order, id);
}
-GPtrArray *
-gth_main_get_object_set (const char *set_name)
+GList *
+gth_main_get_registered_objects (GType superclass_type)
+{
+ GList *objects = NULL;
+ GHashTable *object_hash;
+ GPtrArray *object_order;
+ int i;
+
+ object_hash = g_hash_table_lookup (Main->priv->classes, g_type_name (superclass_type));
+ if (object_hash == NULL)
+ return NULL;
+ object_order = g_hash_table_lookup (Main->priv->objects_order, g_type_name (superclass_type));
+
+ for (i = object_order->len - 1; i >= 0; i--) {
+ char *object_id;
+ GthTypeSpec *spec;
+
+ object_id = g_ptr_array_index (object_order, i);
+ spec = g_hash_table_lookup (object_hash, object_id);
+ objects = g_list_prepend (objects, gth_type_spec_create_object (spec, object_id));
+ }
+
+ return objects;
+}
+
+
+GList *
+gth_main_get_registered_objects_id (GType superclass_type)
+{
+ GList *objects = NULL;
+ GHashTable *object_hash;
+ GPtrArray *object_order;
+ int i;
+
+ object_hash = g_hash_table_lookup (Main->priv->classes, g_type_name (superclass_type));
+ if (object_hash == NULL)
+ return NULL;
+ object_order = g_hash_table_lookup (Main->priv->objects_order, g_type_name (superclass_type));
+
+ for (i = object_order->len - 1; i >= 0; i--) {
+ char *object_id;
+
+ object_id = g_ptr_array_index (object_order, i);
+ objects = g_list_prepend (objects, g_strdup (object_id));
+ }
+
+ return objects;
+}
+
+
+gpointer
+gth_main_get_registered_object (GType superclass_type,
+ const char *object_id)
{
- return g_hash_table_lookup (Main->priv->objects, set_name);
+ GHashTable *object_hash;
+ GthTypeSpec *spec;
+
+ object_hash = g_hash_table_lookup (Main->priv->classes, g_type_name (superclass_type));
+ if (object_hash == NULL)
+ return NULL;
+
+ spec = g_hash_table_lookup (object_hash, object_id);
+ if (spec == NULL)
+ return NULL;
+
+ return (gpointer) gth_type_spec_create_object (spec, object_id);
}
@@ -1008,7 +1015,7 @@ gth_main_get_all_filters (void)
filter_file = gth_main_get_default_filter_file ();
filters = gth_filter_file_get_tests (filter_file);
- registered_tests = gth_main_get_all_tests ();
+ registered_tests = gth_main_get_registered_objects_id (GTH_TYPE_TEST);
for (scan = registered_tests; scan; scan = scan->next) {
const char *registered_test_id = scan->data;
gboolean test_present = FALSE;
@@ -1024,7 +1031,7 @@ gth_main_get_all_filters (void)
if (! test_present) {
GthTest *registered_test;
- registered_test = gth_main_get_test (registered_test_id);
+ registered_test = gth_main_get_registered_object (GTH_TYPE_TEST, registered_test_id);
filters = g_list_append (filters, registered_test);
gth_filter_file_add (filter_file, registered_test);
changed = TRUE;
diff --git a/gthumb/gth-main.h b/gthumb/gth-main.h
index bf39fe4..79f21cb 100644
--- a/gthumb/gth-main.h
+++ b/gthumb/gth-main.h
@@ -86,21 +86,21 @@ GPtrArray * gth_main_get_all_metadata_info (void);
void gth_main_register_sort_type (GthFileDataSort *sort_type);
GthFileDataSort * gth_main_get_sort_type (const char *name);
GList * gth_main_get_all_sort_types (void);
-void gth_main_register_test (const char *id,
- GType type,
- const char *first_property,
- ...);
-GthTest * gth_main_get_test (const char *id);
-GList * gth_main_get_all_tests (void);
void gth_main_register_file_loader (FileLoader loader,
const char *first_mime_type,
...);
FileLoader gth_main_get_file_loader (const char *mime_type);
GthTest * gth_main_get_general_filter (void);
GthTest * gth_main_add_general_filter (GthTest *filter);
-void gth_main_register_object (const char *set_name,
- GType object_type);
-GPtrArray * gth_main_get_object_set (const char *set_name);
+void gth_main_register_object (GType superclass_type,
+ const char *object_id,
+ GType object_type,
+ const char *first_property,
+ ...);
+GList * gth_main_get_registered_objects (GType superclass_type);
+GList * gth_main_get_registered_objects_id (GType superclass_type);
+gpointer gth_main_get_registered_object (GType superclass_type,
+ const char *object_id);
void gth_main_register_type (const char *set_name,
GType object_type);
GArray * gth_main_get_type_set (const char *set_name);
diff --git a/gthumb/gth-test-chain.c b/gthumb/gth-test-chain.c
index cb4b5da..98e898a 100644
--- a/gthumb/gth-test-chain.c
+++ b/gthumb/gth-test-chain.c
@@ -159,7 +159,7 @@ gth_test_chain_real_load_from_element (DomDomizable *base,
if (g_strcmp0 (node->tag_name, "test") == 0) {
GthTest *test;
- test = gth_main_get_test (dom_element_get_attribute (node, "id"));
+ test = gth_main_get_registered_object (GTH_TYPE_TEST, dom_element_get_attribute (node, "id"));
if (test == NULL)
continue;
diff --git a/gthumb/gth-test-selector.c b/gthumb/gth-test-selector.c
index d79d9d0..b9c201c 100644
--- a/gthumb/gth-test-selector.c
+++ b/gthumb/gth-test-selector.c
@@ -156,7 +156,7 @@ test_combo_box_changed_cb (GtkComboBox *scope_combo_box,
if (test_name != NULL) {
GthTest *test;
- test = gth_main_get_test (test_name);
+ test = gth_main_get_registered_object (GTH_TYPE_TEST, test_name);
gth_test_selector_set_test (self, test);
g_object_unref (test);
}
@@ -197,10 +197,10 @@ get_all_tests (void)
GList *scan;
GList *tests = NULL;
- test_ids = gth_main_get_all_tests ();
+ test_ids = gth_main_get_registered_objects_id (GTH_TYPE_TEST);
for (scan = test_ids; scan; scan = scan->next) {
char *test_name = scan->data;
- tests = g_list_prepend (tests, gth_main_get_test (test_name));
+ tests = g_list_prepend (tests, gth_main_get_registered_object (GTH_TYPE_TEST, test_name));
}
tests = g_list_sort (tests, compare_test_by_display_name);
@@ -375,7 +375,7 @@ gth_test_selector_set_test (GthTestSelector *self,
GthTest *local_test = NULL;
if (test == NULL)
- test = local_test = gth_main_get_test ("file::name");
+ test = local_test = gth_main_get_registered_object (GTH_TYPE_TEST, "file::name");
/* update the active test */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]