/* * Copyright (C) 2007 Ross Burton * * Author: Ross Burton * * 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 Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifdef HAVE_CONFIG_H # include #endif /* HAVE_CONFIG_H */ #include #include #include #include #include "katachi-image-cache.h" #include "katachi-image-store.h" #include "katachi-fullscreen.h" struct _KatachiFullscreenPrivate { KatachiImageStore *store; GtkTreePath *path; GtkWidget *image_view; }; G_DEFINE_TYPE (KatachiFullscreen, katachi_fullscreen, GTK_TYPE_WINDOW); enum { PROP_0, PROP_STORE, }; static void got_pixbuf (GFile *file, GdkPixbuf *pixbuf, gpointer user_data) { KatachiFullscreen *fullscreen = user_data; gtk_image_view_set_pixbuf (GTK_IMAGE_VIEW (fullscreen->priv->image_view), pixbuf, TRUE); /* The image view takes it's own reference, so unref our copy */ g_object_unref (pixbuf); } static void update_pixbuf (KatachiFullscreen *fullscreen) { GtkTreeIter iter; GFile *file = NULL; /* If we have no path, unset the image view */ if (fullscreen->priv->path == NULL) { gtk_image_view_set_pixbuf (GTK_IMAGE_VIEW (fullscreen->priv->image_view), NULL, FALSE); return; } if (!gtk_tree_model_get_iter (GTK_TREE_MODEL (fullscreen->priv->store), &iter, fullscreen->priv->path)) { /* * This generally happens if the path points to past the end of the store. * Create a new path starting at the beginning so we effectively wrap * around. */ gtk_tree_path_free (fullscreen->priv->path); fullscreen->priv->path = gtk_tree_path_new_first (); update_pixbuf (fullscreen); return; } gtk_image_view_set_pixbuf (GTK_IMAGE_VIEW (fullscreen->priv->image_view), NULL, FALSE); gtk_tree_model_get (GTK_TREE_MODEL (fullscreen->priv->store), &iter, COL_FILE, &file, -1); if (file) { katachi_image_cache_get_pixbuf (fullscreen->priv->image_view, file, TRUE, got_pixbuf, fullscreen); } } static gboolean on_key_press (GtkWidget *window, GdkEventKey *event, KatachiFullscreen *fullscreen) { switch (event->keyval) { /* Leave fullscreen mode */ case GDK_Q: case GDK_q: case GDK_Escape: case GDK_Return: case GDK_KP_Enter: case GDK_F11: { /* Send a Delete event to the window, so the calling code can either let it destroy, or hide it. */ GdkEvent *event; event = gdk_event_new (GDK_DELETE); event->type = GDK_DELETE; event->any.window = g_object_ref (window->window); event->any.send_event = TRUE; gtk_main_do_event (event); gdk_event_free (event); } return TRUE; break; /* Display the next image */ case GDK_space: case GDK_Down: case GDK_Right: case GDK_Next: gtk_tree_path_next (fullscreen->priv->path); update_pixbuf (fullscreen); break; /* Display the previous image */ case GDK_Up: case GDK_Left: case GDK_Prior: gtk_tree_path_prev (fullscreen->priv->path); update_pixbuf (fullscreen); break; default: return FALSE; break; } } static void katachi_fullscreen_finalize (GObject *object) { gtk_tree_path_free (KATACHI_FULLSCREEN (object)->priv->path); G_OBJECT_CLASS (katachi_fullscreen_parent_class)->finalize (object); } static void katachi_fullscreen_dispose (GObject *object) { katachi_fullscreen_set_store (KATACHI_FULLSCREEN (object), NULL); G_OBJECT_CLASS (katachi_fullscreen_parent_class)->dispose (object); } static void katachi_fullscreen_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec) { KatachiFullscreen *fullscreen = KATACHI_FULLSCREEN (object); switch (property_id) { case PROP_STORE: g_value_set_object (value, fullscreen->priv->store); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); } } static void katachi_fullscreen_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) { KatachiFullscreen *fullscreen = KATACHI_FULLSCREEN (object); switch (property_id) { case PROP_STORE: katachi_fullscreen_set_store (fullscreen, g_value_get_object (value)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); } } static void katachi_fullscreen_class_init (KatachiFullscreenClass *klass) { GObjectClass *object_class; g_type_class_add_private (klass, sizeof (KatachiFullscreenPrivate)); object_class = G_OBJECT_CLASS (klass); object_class->get_property = katachi_fullscreen_get_property; object_class->set_property = katachi_fullscreen_set_property; object_class->dispose = katachi_fullscreen_dispose; object_class->finalize = katachi_fullscreen_finalize; g_object_class_install_property (object_class, PROP_STORE, g_param_spec_object ("store", "store", NULL, KATACHI_TYPE_IMAGE_STORE, G_PARAM_READWRITE)); } static void katachi_fullscreen_init (KatachiFullscreen *this) { GtkWidget *scroller; GdkScreen *screen; this->priv = G_TYPE_INSTANCE_GET_PRIVATE (this, KATACHI_TYPE_FULLSCREEN, KatachiFullscreenPrivate); screen = gtk_widget_get_screen (GTK_WIDGET (this)); gtk_window_set_default_size (GTK_WINDOW (this), gdk_screen_get_width (screen), gdk_screen_get_height (screen)); gtk_window_fullscreen (GTK_WINDOW (this)); g_signal_connect (this, "key-press-event", G_CALLBACK (on_key_press), this); this->priv->image_view = gtk_image_view_new (); gtk_image_view_set_black_bg (GTK_IMAGE_VIEW (this->priv->image_view), TRUE); scroller = gtk_image_scroll_win_new (GTK_IMAGE_VIEW (this->priv->image_view)); gtk_widget_show_all (scroller); gtk_container_add (GTK_CONTAINER (this), scroller); } /* * Public methods */ GtkWidget * katachi_fullscreen_new (void) { return g_object_new (KATACHI_TYPE_FULLSCREEN, NULL); } void katachi_fullscreen_set_store (KatachiFullscreen *fullscreen, KatachiImageStore *store) { g_return_if_fail (KATACHI_IS_FULLSCREEN (fullscreen)); if (fullscreen->priv->store) { g_object_unref (fullscreen->priv->store); fullscreen->priv->store = NULL; } if (store) { fullscreen->priv->store = g_object_ref (store); } } void katachi_fullscreen_set_path (KatachiFullscreen *fullscreen, GtkTreePath *path) { GdkPixbuf *pixbuf = NULL; g_return_if_fail (KATACHI_IS_FULLSCREEN (fullscreen)); if (fullscreen->priv->path) { gtk_tree_path_free (fullscreen->priv->path); fullscreen->priv->path = NULL; } if (path) { fullscreen->priv->path = gtk_tree_path_copy (path); update_pixbuf (fullscreen); } } /** * katachi_fullscreen_get_path: * * Returns a copy of the currently selected GtkTreePath. Free it when you have * finished with it. */ GtkTreePath * katachi_fullscreen_get_path (KatachiFullscreen *fullscreen) { g_return_val_if_fail (KATACHI_IS_FULLSCREEN (fullscreen), NULL); if (fullscreen->priv->path) { return gtk_tree_path_copy (fullscreen->priv->path); } else { return NULL; } }