From 56f9db8089c7db0de835e1064cc6f130287aac51 Mon Sep 17 00:00:00 2001 From: John Ellis Date: Wed, 29 Nov 2006 19:38:25 +0000 Subject: [PATCH] Wed Nov 29 14:28:30 2006 John Ellis * 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. --- ChangeLog | 9 ++ src/image-overlay.c | 214 +++++++++++++++++++++++++++++++++----------- src/image-overlay.h | 8 +- src/image.c | 50 +++++++---- src/image.h | 8 +- src/img-view.c | 28 +++--- src/layout.c | 1 - src/layout_image.c | 20 +---- src/typedefs.h | 9 +- 9 files changed, 233 insertions(+), 114 deletions(-) diff --git a/ChangeLog b/ChangeLog index 55c43948..1375f82b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +Wed Nov 29 14:28:30 2006 John Ellis + + * 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 * image.c: When resuming a previous color adjustment, set the display diff --git a/src/image-overlay.c b/src/image-overlay.c index 530dbe69..3a4f9b3b 100644 --- a/src/image-overlay.c +++ b/src/image-overlay.c @@ -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 @@ static GdkPixbuf *image_overlay_info_render(ImageWindow *imd) 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; - 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); + if (osd->show_info) + { + if (osd->changed_states & IMAGE_STATE_IMAGE) + { + GdkPixbuf *pixbuf; - 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); + 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); + } + + 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; - - ou = g_object_get_data(G_OBJECT(imd->pr), IMAGE_OVERLAY_UPDATE_KEY); - if (ou) return; - - 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); + if (force) osd->changed_states |= IMAGE_STATE_IMAGE; + + if (osd->idle_id == -1) + { + osd->idle_id = g_idle_add_full(G_PRIORITY_HIGH, image_osd_update_cb, osd, NULL); + } } -void image_overlay_update(ImageWindow *imd, gint id) +void image_osd_update(ImageWindow *imd) { - if (id < 0) return; - image_overlay_update_schedule(imd, id); + 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); } -static void image_overlay_upate_cb(ImageWindow *imd, gpointer data) +static void image_osd_state_cb(ImageWindow *imd, ImageState state, gpointer data) { - gint id; + OverlayStateData *osd = data; - id = GPOINTER_TO_INT(data); - image_overlay_update_schedule(imd, id); + osd->changed_states |= state; + image_osd_update_schedule(osd, FALSE); } -gint image_overlay_info_enable(ImageWindow *imd) +static void image_osd_free(OverlayStateData *osd) { - gint id; - GdkPixbuf *pixbuf; + if (!osd) return; + + if (osd->idle_id != -1) g_source_remove(osd->idle_id); - pixbuf = image_overlay_info_render(imd); - id = image_overlay_add(imd, pixbuf, IMAGE_OVERLAY_X, IMAGE_OVERLAY_Y, TRUE, FALSE); - g_object_unref(pixbuf); + 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_new_func(imd, image_overlay_upate_cb, GINT_TO_POINTER(id)); + image_set_state_func(osd->imd, NULL, NULL); + image_overlay_remove(osd->imd, osd->ovl_info); + } - return id; + g_free(osd); } -void image_overlay_info_disable(ImageWindow *imd, gint id) +static void image_osd_remove(ImageWindow *imd) { - image_set_new_func(imd, NULL, NULL); - image_overlay_remove(imd, id); + OverlayStateData *osd; + + osd = g_object_get_data(G_OBJECT(imd->pr), "IMAGE_OVERLAY_DATA"); + image_osd_free(osd); +} + +static void image_osd_destroy_cb(GtkWidget *widget, gpointer data) +{ + OverlayStateData *osd = data; + + osd->imd = NULL; + image_osd_free(osd); +} + +static void image_osd_enable(ImageWindow *imd, gint info, gint status) +{ + 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; + + 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); + } + + if (osd->show_info != info || + osd->show_status != status) + { + osd->show_info = info; + osd->show_status = status; + + image_osd_update_schedule(osd, TRUE); + } +} + +void image_osd_set(ImageWindow *imd, gint info, gint status) +{ + 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; } diff --git a/src/image-overlay.h b/src/image-overlay.h index 8b2c2cfa..4569dae9 100644 --- a/src/image-overlay.h +++ b/src/image-overlay.h @@ -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 diff --git a/src/image.c b/src/image.c index 810bc1b8..8e3c6d34 100644 --- a/src/image.c +++ b/src/image.c @@ -111,9 +111,23 @@ static void image_render_complete_cb(PixbufRenderer *pr, gpointer data) 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 @@ static void image_post_process_color_cb(ColorMan *cm, ColorManReturnType type, g } 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 @@ static void image_post_process(ImageWindow *imd, gint clamp) break; } - if (rotate) imd->state |= IMAGE_STATE_COLOR_ADJ; + if (rotate) image_state_set(imd, IMAGE_STATE_COLOR_ADJ); } } @@ -455,7 +469,7 @@ static void image_post_process(ImageWindow *imd, gint clamp) 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 @@ static void image_load_done_cb(ImageLoader *il, gpointer data) 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 @@ static gint image_read_ahead_check(ImageWindow *imd) 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 @@ static gint image_load_begin(ImageWindow *imd, const gchar *path) 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 @@ static void image_reset(ImageWindow *imd) imd->delay_alter_type = ALTER_NONE; - imd->state = IMAGE_STATE_NONE; + image_state_set(imd, IMAGE_STATE_NONE); } /* @@ -931,7 +949,7 @@ static void image_change_real(ImageWindow *imd, const gchar *path, } image_update_title(imd); - image_new_util(imd); + image_state_set(imd, IMAGE_STATE_IMAGE); } /* @@ -1059,19 +1077,19 @@ void image_set_update_func(ImageWindow *imd, } 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 @@ void image_set_path(ImageWindow *imd, const gchar *newpath) 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 @@ GdkPixbuf *image_get_pixbuf(ImageWindow *imd) 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 @@ void image_alter(ImageWindow *imd, AlterType type) { /* 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; } diff --git a/src/image.h b/src/image.h index 6f1574fb..3cbc0cd3 100644 --- a/src/image.h +++ b/src/image.h @@ -32,11 +32,11 @@ void image_set_scroll_notify_func(ImageWindow *imd, 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); diff --git a/src/img-view.c b/src/img-view.c index cb52fd7f..bbd3d3fc 100644 --- a/src/img-view.c +++ b/src/img-view.c @@ -45,8 +45,6 @@ struct _ViewWindow GList *list; GList *list_pointer; - - gint overlay_id; }; @@ -689,13 +687,18 @@ static void view_fullscreen_stop_func(FullScreenData *fs, gpointer data) 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 @@ static void view_fullscreen_toggle(ViewWindow *vw, gint force_off) 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 @@ static void view_overlay_toggle(ViewWindow *vw) 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 @@ static ViewWindow *real_view_window_new(const gchar *path, GList *list, Collecti 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 @@ static void view_real_removed(ViewWindow *vw, const gchar *path, GList *ignore_l } } - 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) diff --git a/src/layout.c b/src/layout.c index 906ac62e..42353930 100644 --- a/src/layout.c +++ b/src/layout.c @@ -1832,7 +1832,6 @@ LayoutWindow *layout_new_with_geometry(const gchar *path, gint popped, gint hidd lw->bar_exif_size = -1; lw->bar_exif_advanced = FALSE; - lw->full_screen_overlay_id = -1; lw->full_screen_overlay_on = FALSE; /* default layout */ diff --git a/src/layout_image.c b/src/layout_image.c index e53b2988..9edbb550 100644 --- a/src/layout_image.c +++ b/src/layout_image.c @@ -49,27 +49,14 @@ static void layout_image_overlay_set(LayoutWindow *lw, gint enable) 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 @@ static void layout_image_full_screen_stop_func(FullScreenData *fs, gpointer data } lw->full_screen = NULL; - lw->full_screen_overlay_id = -1; } void layout_image_full_screen_start(LayoutWindow *lw) diff --git a/src/typedefs.h b/src/typedefs.h index 818cf7a9..9a3075ba 100644 --- a/src/typedefs.h +++ b/src/typedefs.h @@ -255,15 +255,15 @@ struct _ImageWindow 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 @@ struct _LayoutWindow /* full screen */ FullScreenData *full_screen; - gint full_screen_overlay_id; gint full_screen_overlay_on; /* dividers */ -- 2.20.1