Mercurial > geeqie.yaz
diff src/image-overlay.c @ 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 | 17acca639a86 |
children | ac0f7f942c4d |
line wrap: on
line diff
--- 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; +} +