changeset 117:0c2e1f0a001b

Wed Nov 29 14:28:30 2006 John Ellis <johne@verizon.net> * image-overlay.[ch]: Rewrite most of the information overlay code to be more flexible and easily extended. * image.[ch], typedefs.h: Remove image_new_func, and replace it with image_state_func callback which is much more informative. * img-view.c, layout.c, layout_image.c: Updates for new image overlay function names.
author gqview
date Wed, 29 Nov 2006 19:38:25 +0000
parents 1bd40943dc2a
children ac0f7f942c4d
files ChangeLog src/image-overlay.c src/image-overlay.h src/image.c src/image.h src/img-view.c src/layout.c src/layout_image.c src/typedefs.h
diffstat 9 files changed, 231 insertions(+), 112 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Tue Nov 28 18:20:56 2006 +0000
+++ b/ChangeLog	Wed Nov 29 19:38:25 2006 +0000
@@ -1,3 +1,12 @@
+Wed Nov 29 14:28:30 2006  John Ellis  <johne@verizon.net>
+
+	* image-overlay.[ch]: Rewrite most of the information overlay code to
+	be more flexible and easily extended.
+	* image.[ch], typedefs.h: Remove image_new_func, and replace it with
+	image_state_func callback which is much more informative.
+	* img-view.c, layout.c, layout_image.c: Updates for new image overlay
+	function names.
+
 Tue Nov 28 13:17:18 2006  John Ellis  <johne@verizon.net>
 
 	* image.c: When resuming a previous color adjustment, set the display
--- a/src/image-overlay.c	Tue Nov 28 18:20:56 2006 +0000
+++ b/src/image-overlay.c	Wed Nov 29 19:38:25 2006 +0000
@@ -1,6 +1,6 @@
 /*
  * GQview
- * (C) 2004 John Ellis
+ * (C) 2006 John Ellis
  *
  * Author: John Ellis
  *
@@ -27,21 +27,31 @@
  *----------------------------------------------------------------------------
  */
 
-typedef struct _OverlayUpdate OverlayUpdate;
-struct _OverlayUpdate {
+typedef struct _OverlayStateData OverlayStateData;
+struct _OverlayStateData {
 	ImageWindow *imd;
-	gint id;
+	ImageState changed_states;
+
+	gint show_info;
+	gint show_status;
+
+	gint ovl_info;
+	gint ovl_color;
+	gint ovl_rotate;
+	gint ovl_end;
+
 	gint idle_id;
+	gint timer_id;
 	gulong destroy_id;
 };
 
-#define IMAGE_OVERLAY_UPDATE_KEY "image-overlay-update"
+#define OSD_DATA "overlay-data"
 
-#define IMAGE_OVERLAY_X 10
-#define IMAGE_OVERLAY_Y -10
+#define OSD_INFO_X 10
+#define OSD_INFO_Y -10
 
 
-static GdkPixbuf *image_overlay_info_render(ImageWindow *imd)
+static GdkPixbuf *image_osd_info_render(ImageWindow *imd)
 {
 	GdkPixbuf *pixbuf;
 	gint width, height;
@@ -172,77 +182,175 @@
 	return pixbuf;
 }
 
-static void image_overlay_update_destroy_cb(GtkWidget *widget, gpointer data)
+static void image_osd_ovl_reset(OverlayStateData *osd, gint *id)
 {
-	OverlayUpdate *ou = data;
-
-	g_source_remove(ou->idle_id);
-	g_free(ou);
+	if (*id)
+		{
+		image_overlay_remove(osd->imd, *id);
+		*id = 0;
+		}
 }
 
-static gint image_overlay_update_cb(gpointer data)
+static gint image_osd_update_cb(gpointer data)
 {
-	OverlayUpdate *ou = data;
-	GdkPixbuf *pixbuf;
+	OverlayStateData *osd = data;
+
+	if (osd->show_info)
+		{
+		if (osd->changed_states & IMAGE_STATE_IMAGE)
+			{
+			GdkPixbuf *pixbuf;
 
-	pixbuf = image_overlay_info_render(ou->imd);
-	image_overlay_set(ou->imd, ou->id, pixbuf, IMAGE_OVERLAY_X, IMAGE_OVERLAY_Y);
-	g_object_unref(pixbuf);
+			pixbuf = image_osd_info_render(osd->imd);
+			if (osd->ovl_info == 0)
+				{
+				osd->ovl_info = image_overlay_add(osd->imd, pixbuf,
+								  OSD_INFO_X, OSD_INFO_Y, TRUE, FALSE);
+				}
+			else
+				{
+				image_overlay_set(osd->imd, osd->ovl_info, pixbuf, OSD_INFO_X, OSD_INFO_Y);
+				}
+			g_object_unref(pixbuf);
+			}
+		}
+	else
+		{
+		image_osd_ovl_reset(osd, & osd->ovl_info);
+		}
 
-	g_object_set_data(G_OBJECT(ou->imd->pr), IMAGE_OVERLAY_UPDATE_KEY, NULL);
-	g_signal_handler_disconnect(ou->imd->pr, ou->destroy_id);
-	g_free(ou);
+	if (osd->show_status)
+		{
+		}
+	else
+		{
+		image_osd_ovl_reset(osd, & osd->ovl_color);
+		image_osd_ovl_reset(osd, & osd->ovl_rotate);
+		image_osd_ovl_reset(osd, & osd->ovl_end);
+		}
 
+	osd->idle_id = -1;
 	return FALSE;
 }
 
-static void image_overlay_update_schedule(ImageWindow *imd, gint id)
+static void image_osd_update_schedule(OverlayStateData *osd, gint force)
 {
-	OverlayUpdate *ou;
+	if (force) osd->changed_states |= IMAGE_STATE_IMAGE;
 
-	ou = g_object_get_data(G_OBJECT(imd->pr), IMAGE_OVERLAY_UPDATE_KEY);
-	if (ou) return;
+	if (osd->idle_id == -1)
+		{
+		osd->idle_id = g_idle_add_full(G_PRIORITY_HIGH, image_osd_update_cb, osd, NULL);
+		}
+}
 
-	ou = g_new0(OverlayUpdate, 1);
-	ou->imd = imd;
-	ou->id = id;
-	ou->idle_id = g_idle_add_full(G_PRIORITY_HIGH, image_overlay_update_cb, ou, NULL);
-	ou->destroy_id = g_signal_connect(G_OBJECT(imd->pr), "destroy",
-					  G_CALLBACK(image_overlay_update_destroy_cb), ou);
-	g_object_set_data(G_OBJECT(imd->pr), IMAGE_OVERLAY_UPDATE_KEY, ou);
+void image_osd_update(ImageWindow *imd)
+{
+	OverlayStateData *osd;
+
+	if (!imd) return;
+
+	osd = g_object_get_data(G_OBJECT(imd->pr), "IMAGE_OVERLAY_DATA");
+	if (!osd) return;
+
+	image_osd_update_schedule(osd, TRUE);
 }
 
-void image_overlay_update(ImageWindow *imd, gint id)
+static void image_osd_state_cb(ImageWindow *imd, ImageState state, gpointer data)
+{
+	OverlayStateData *osd = data;
+
+	osd->changed_states |= state;
+	image_osd_update_schedule(osd, FALSE);
+}
+
+static void image_osd_free(OverlayStateData *osd)
 {
-	if (id < 0) return;
-	image_overlay_update_schedule(imd, id);
+	if (!osd) return;
+
+	if (osd->idle_id != -1) g_source_remove(osd->idle_id);
+
+	if (osd->imd)
+		{
+		g_object_set_data(G_OBJECT(osd->imd->pr), "IMAGE_OVERLAY_DATA", NULL);
+		g_signal_handler_disconnect(osd->imd->pr, osd->destroy_id);
+
+		image_set_state_func(osd->imd, NULL, NULL);
+		image_overlay_remove(osd->imd, osd->ovl_info);
+		}
+
+	g_free(osd);
+}
+
+static void image_osd_remove(ImageWindow *imd)
+{
+	OverlayStateData *osd;
+
+	osd = g_object_get_data(G_OBJECT(imd->pr), "IMAGE_OVERLAY_DATA");
+	image_osd_free(osd);
 }
 
-static void image_overlay_upate_cb(ImageWindow *imd, gpointer data)
+static void image_osd_destroy_cb(GtkWidget *widget, gpointer data)
 {
-	gint id;
+	OverlayStateData *osd = data;
 
-	id = GPOINTER_TO_INT(data);
-	image_overlay_update_schedule(imd, id);
+	osd->imd = NULL;
+	image_osd_free(osd);
 }
 
-gint image_overlay_info_enable(ImageWindow *imd)
+static void image_osd_enable(ImageWindow *imd, gint info, gint status)
 {
-	gint id;
-	GdkPixbuf *pixbuf;
+	OverlayStateData *osd;
+
+	osd = g_object_get_data(G_OBJECT(imd->pr), "IMAGE_OVERLAY_DATA");
+	if (!osd)
+		{
+		osd = g_new0(OverlayStateData, 1);
+		osd->imd = imd;
+		osd->idle_id = -1;
+		osd->timer_id = -1;
 
-	pixbuf = image_overlay_info_render(imd);
-	id = image_overlay_add(imd, pixbuf, IMAGE_OVERLAY_X, IMAGE_OVERLAY_Y, TRUE, FALSE);
-	g_object_unref(pixbuf);
+		osd->destroy_id = g_signal_connect(G_OBJECT(imd->pr), "destroy",
+						   G_CALLBACK(image_osd_destroy_cb), osd);
+		g_object_set_data(G_OBJECT(imd->pr), "IMAGE_OVERLAY_DATA", osd);
+
+		image_set_state_func(osd->imd, image_osd_state_cb, osd);
+		}
 
-	image_set_new_func(imd, image_overlay_upate_cb, GINT_TO_POINTER(id));
+	if (osd->show_info != info ||
+	    osd->show_status != status)
+		{
+		osd->show_info = info;
+		osd->show_status = status;
 
-	return id;
+		image_osd_update_schedule(osd, TRUE);
+		}
 }
 
-void image_overlay_info_disable(ImageWindow *imd, gint id)
+void image_osd_set(ImageWindow *imd, gint info, gint status)
 {
-	image_set_new_func(imd, NULL, NULL);
-	image_overlay_remove(imd, id);
+	if (!imd) return;
+
+	if (!info && !status)
+		{
+		image_osd_remove(imd);
+		return;
+		}
+
+	image_osd_enable(imd, info, status);
 }
 
+gint image_osd_get(ImageWindow *imd, gint *info, gint *status)
+{
+	OverlayStateData *osd;
+
+	if (!imd) return FALSE;
+
+	osd = g_object_get_data(G_OBJECT(imd->pr), "IMAGE_OVERLAY_DATA");
+	if (!osd) return FALSE;
+
+	if (info) *info = osd->show_info;
+	if (status) *status = osd->show_status;
+
+	return TRUE;
+}
+
--- a/src/image-overlay.h	Tue Nov 28 18:20:56 2006 +0000
+++ b/src/image-overlay.h	Wed Nov 29 19:38:25 2006 +0000
@@ -1,6 +1,6 @@
 /*
  * GQview
- * (C) 2004 John Ellis
+ * (C) 2006 John Ellis
  *
  * Author: John Ellis
  *
@@ -13,10 +13,10 @@
 #define IMAGE_OVERLAY_H
 
 
-gint image_overlay_info_enable(ImageWindow *imd);
-void image_overlay_info_disable(ImageWindow *imd, gint id);
+void image_osd_set(ImageWindow *imd, gint info, gint status);
+gint image_osd_get(ImageWindow *imd, gint *info, gint *status);
 
-void image_overlay_update(ImageWindow *imd, gint id);
+void image_osd_update(ImageWindow *imd);
 
 
 #endif
--- a/src/image.c	Tue Nov 28 18:20:56 2006 +0000
+++ b/src/image.c	Wed Nov 29 19:38:25 2006 +0000
@@ -111,9 +111,23 @@
 	image_complete_util(imd, FALSE);
 }
 
-static void image_new_util(ImageWindow *imd)
+static void image_state_set(ImageWindow *imd, ImageState state)
 {
-	if (imd->func_new) imd->func_new(imd, imd->data_new);
+	if (state == IMAGE_STATE_NONE)
+		{
+		imd->state = state;
+		}
+	else
+		{
+		imd->state |= state;
+		}
+	if (imd->func_state) imd->func_state(imd, state, imd->data_state);
+}
+
+static void image_state_unset(ImageWindow *imd, ImageState state)
+{
+	imd->state &= ~state;
+	if (imd->func_state) imd->func_state(imd, state, imd->data_state);
 }
 
 /*
@@ -272,7 +286,7 @@
 		}
 
 	imd->cm = NULL;
-	imd->state |= IMAGE_STATE_COLOR_ADJ;
+	image_state_set(imd, IMAGE_STATE_COLOR_ADJ);
 
 	image_post_process_alter(imd, FALSE);
 
@@ -446,7 +460,7 @@
 					break;
 				}
 
-			if (rotate) imd->state |= IMAGE_STATE_COLOR_ADJ;
+			if (rotate) image_state_set(imd, IMAGE_STATE_COLOR_ADJ);
 			}
 		}
 
@@ -455,7 +469,7 @@
 		if (!image_post_process_color(imd, 0, exif))
 			{
 			/* fixme: note error to user */
-			imd->state |= IMAGE_STATE_COLOR_ADJ;
+			image_state_set(imd, IMAGE_STATE_COLOR_ADJ);
 			}
 		}
 
@@ -643,6 +657,7 @@
 	if (debug) printf ("image done\n");
 
 	g_object_set(G_OBJECT(imd->pr), "loading", FALSE, NULL);
+	image_state_unset(imd, IMAGE_STATE_LOADING);
 
 	if (imd->delay_flip &&
 	    image_get_pixbuf(imd) != image_loader_get_pixbuf(imd->il))
@@ -714,6 +729,7 @@
 		imd->il->func_done = image_load_done_cb;
 
 		g_object_set(G_OBJECT(imd->pr), "loading", TRUE, NULL);
+		image_state_set(imd, IMAGE_STATE_LOADING);
 
 		if (!imd->delay_flip)
 			{
@@ -791,6 +807,8 @@
 		return FALSE;
 		}
 
+	image_state_set(imd, IMAGE_STATE_LOADING);
+
 #ifdef IMAGE_THROTTLE_LARGER_IMAGES
 	image_load_buffer_throttle(imd->il);
 #endif
@@ -816,7 +834,7 @@
 
 	imd->delay_alter_type = ALTER_NONE;
 
-	imd->state = IMAGE_STATE_NONE;
+	image_state_set(imd, IMAGE_STATE_NONE);
 }
 
 /*
@@ -931,7 +949,7 @@
 		}
 
 	image_update_title(imd);
-	image_new_util(imd);
+	image_state_set(imd, IMAGE_STATE_IMAGE);
 }
 
 /*
@@ -1059,19 +1077,19 @@
 }
 
 void image_set_complete_func(ImageWindow *imd,
-			     void (*func)(ImageWindow *, gint preload, gpointer),
+			     void (*func)(ImageWindow *imd, gint preload, gpointer data),
 			     gpointer data)
 {
 	imd->func_complete = func;
 	imd->data_complete = data;
 }
 
-void image_set_new_func(ImageWindow *imd,
-			void (*func)(ImageWindow *, gpointer),
+void image_set_state_func(ImageWindow *imd,
+			void (*func)(ImageWindow *imd, ImageState state, gpointer data),
 			gpointer data)
 {
-	imd->func_new = func;
-	imd->data_new = data;
+	imd->func_state = func;
+	imd->data_state = data;
 }
 
 
@@ -1119,7 +1137,7 @@
 	imd->image_name = filename_from_path(imd->image_path);
 
 	image_update_title(imd);
-	image_new_util(imd);
+	image_state_set(imd, IMAGE_STATE_IMAGE);
 }
 
 /* load a new image */
@@ -1140,7 +1158,7 @@
 void image_change_pixbuf(ImageWindow *imd, GdkPixbuf *pixbuf, gdouble zoom)
 {
 	pixbuf_renderer_set_pixbuf((PixbufRenderer *)imd->pr, pixbuf, zoom);
-	image_new_util(imd);
+	image_state_set(imd, IMAGE_STATE_IMAGE);
 }
 
 void image_change_from_collection(ImageWindow *imd, CollectionData *cd, CollectInfo *info, gdouble zoom)
@@ -1290,11 +1308,11 @@
 		{
 		/* still loading, wait till done */
 		imd->delay_alter_type = type;
-		imd->state |= IMAGE_STATE_ROTATE_USER;
+		image_state_set(imd, IMAGE_STATE_ROTATE_USER);
 
 		if (imd->cm && (imd->state & IMAGE_STATE_ROTATE_AUTO))
 			{
-			imd->state &= ~IMAGE_STATE_ROTATE_AUTO;
+			image_state_unset(imd, IMAGE_STATE_ROTATE_AUTO);
 			}
 		return;
 		}
--- a/src/image.h	Tue Nov 28 18:20:56 2006 +0000
+++ b/src/image.h	Wed Nov 29 19:38:25 2006 +0000
@@ -32,11 +32,11 @@
 				  void (*func)(ImageWindow *imd, gint x, gint y, gint width, gint height, gpointer data),
 				  gpointer data);
 void image_set_complete_func(ImageWindow *imd,
-			     void (*func)(ImageWindow *, gint preload, gpointer),
+			     void (*func)(ImageWindow *imd, gint preload, gpointer data),
 			     gpointer data);
-void image_set_new_func(ImageWindow *imd,
-			void (*func)(ImageWindow *, gpointer),
-			gpointer data);
+void image_set_state_func(ImageWindow *imd,
+			  void (*func)(ImageWindow *imd, ImageState state, gpointer data),
+			  gpointer data);
 
 /* path, name */
 const gchar *image_get_path(ImageWindow *imd);
--- a/src/img-view.c	Tue Nov 28 18:20:56 2006 +0000
+++ b/src/img-view.c	Wed Nov 29 19:38:25 2006 +0000
@@ -45,8 +45,6 @@
 
 	GList *list;
 	GList *list_pointer;
-
-	gint overlay_id;
 };
 
 
@@ -689,13 +687,18 @@
 
 static void view_fullscreen_toggle(ViewWindow *vw, gint force_off)
 {
+	gint info, status;
+
 	if (force_off && !vw->fs) return;
 
 	if (vw->fs)
 		{
-		fullscreen_stop(vw->fs);
+		if (image_osd_get(vw->fs->imd, &info, &status))
+			{
+			image_osd_set(vw->imd, info, status);
+			}
 
-		if (vw->overlay_id != -1) vw->overlay_id = image_overlay_info_enable(vw->imd);
+		fullscreen_stop(vw->fs);
 		}
 	else
 		{
@@ -707,10 +710,10 @@
 
 		if (vw->ss) vw->ss->imd = vw->fs->imd;
 
-		if (vw->overlay_id != -1)
+		if (image_osd_get(vw->imd, &info, &status))
 			{
-			image_overlay_info_disable(vw->imd, vw->overlay_id);
-			vw->overlay_id = image_overlay_info_enable(vw->fs->imd);
+			image_osd_set(vw->imd, FALSE, FALSE);
+			image_osd_set(vw->fs->imd, info, status);
 			}
 		}
 }
@@ -721,14 +724,13 @@
 
 	imd = view_window_active_image(vw);
 
-	if (vw->overlay_id == -1)
+	if (!image_osd_get(imd, NULL, NULL))
 		{
-		vw->overlay_id = image_overlay_info_enable(imd);
+		image_osd_set(imd, TRUE, TRUE);
 		}
 	else
 		{
-		image_overlay_info_disable(imd, vw->overlay_id);
-		vw->overlay_id = -1;
+		image_osd_set(imd, FALSE, FALSE);
 		}
 }
 
@@ -822,8 +824,6 @@
 	vw->list = NULL;
 	vw->list_pointer = NULL;
 
-	vw->overlay_id = -1;
-
 	vw->window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
 
 	geometry.min_width = 8;
@@ -1627,7 +1627,7 @@
 			}
 		}
 
-	if (vw->overlay_id != -1) image_overlay_update(imd, vw->overlay_id);
+	image_osd_update(imd);
 }
 
 static void view_real_moved(ViewWindow *vw, const gchar *source, const gchar *dest)
--- a/src/layout.c	Tue Nov 28 18:20:56 2006 +0000
+++ b/src/layout.c	Wed Nov 29 19:38:25 2006 +0000
@@ -1832,7 +1832,6 @@
 	lw->bar_exif_size = -1;
 	lw->bar_exif_advanced = FALSE;
 
-	lw->full_screen_overlay_id = -1;
 	lw->full_screen_overlay_on = FALSE;
 
 	/* default layout */
--- a/src/layout_image.c	Tue Nov 28 18:20:56 2006 +0000
+++ b/src/layout_image.c	Wed Nov 29 19:38:25 2006 +0000
@@ -49,27 +49,14 @@
 
 	if (!lw->full_screen) return;
 
-	if (enable)
-		{
-		if (lw->full_screen_overlay_id == -1)
-			{
-			lw->full_screen_overlay_id = image_overlay_info_enable(lw->image);
-			}
-		}
-	else
-		{
-		if (lw->full_screen_overlay_id != -1)
-			{
-			image_overlay_info_disable(lw->image, lw->full_screen_overlay_id);
-			lw->full_screen_overlay_id = -1;
-			}
-		}
+	image_osd_set(lw->image, enable, enable);
 }
 
 void layout_image_overlay_update(LayoutWindow *lw)
 {
 	if (!lw || !lw->full_screen) return;
-	if (lw->full_screen_overlay_id != -1) image_overlay_update(lw->image, lw->full_screen_overlay_id);
+
+	image_osd_update(lw->image);
 }
 
 /*
@@ -344,7 +331,6 @@
 		}
 
 	lw->full_screen = NULL;
-	lw->full_screen_overlay_id = -1;
 }
 
 void layout_image_full_screen_start(LayoutWindow *lw)
--- a/src/typedefs.h	Tue Nov 28 18:20:56 2006 +0000
+++ b/src/typedefs.h	Wed Nov 29 19:38:25 2006 +0000
@@ -255,15 +255,15 @@
 	gint completed;
 	ImageState state;	/* mask of IMAGE_STATE_* flags about current image */
 
-	void (*func_update)(ImageWindow *, gpointer);
-	void (*func_complete)(ImageWindow *, gint preload, gpointer);
-	void (*func_new)(ImageWindow *, gpointer);
+	void (*func_update)(ImageWindow *imd, gpointer data);
+	void (*func_complete)(ImageWindow *imd, gint preload, gpointer data);
+	void (*func_state)(ImageWindow *imd, ImageState state, gpointer data);
 	ImageTileRequestFunc func_tile_request;
 	ImageTileDisposeFunc func_tile_dispose;
 
 	gpointer data_update;
 	gpointer data_complete;
-	gpointer data_new;
+	gpointer data_state;
 	gpointer data_tile;
 
 	/* button, scroll functions */
@@ -398,7 +398,6 @@
 	/* full screen */
 
 	FullScreenData *full_screen;
-	gint full_screen_overlay_id;
 	gint full_screen_overlay_on;
 
 	/* dividers */