+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
/*
* GQview
- * (C) 2004 John Ellis
+ * (C) 2006 John Ellis
*
* Author: John Ellis
*
*----------------------------------------------------------------------------
*/
-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;
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;
}
/*
* GQview
- * (C) 2004 John Ellis
+ * (C) 2006 John Ellis
*
* Author: John Ellis
*
#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
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);
}
/*
}
imd->cm = NULL;
- imd->state |= IMAGE_STATE_COLOR_ADJ;
+ image_state_set(imd, IMAGE_STATE_COLOR_ADJ);
image_post_process_alter(imd, FALSE);
break;
}
- if (rotate) imd->state |= IMAGE_STATE_COLOR_ADJ;
+ if (rotate) image_state_set(imd, IMAGE_STATE_COLOR_ADJ);
}
}
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);
}
}
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))
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)
{
return FALSE;
}
+ image_state_set(imd, IMAGE_STATE_LOADING);
+
#ifdef IMAGE_THROTTLE_LARGER_IMAGES
image_load_buffer_throttle(imd->il);
#endif
imd->delay_alter_type = ALTER_NONE;
- imd->state = IMAGE_STATE_NONE;
+ image_state_set(imd, IMAGE_STATE_NONE);
}
/*
}
image_update_title(imd);
- image_new_util(imd);
+ image_state_set(imd, IMAGE_STATE_IMAGE);
}
/*
}
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;
}
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 */
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)
{
/* 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;
}
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);
GList *list;
GList *list_pointer;
-
- gint overlay_id;
};
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
{
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);
}
}
}
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);
}
}
vw->list = NULL;
vw->list_pointer = NULL;
- vw->overlay_id = -1;
-
vw->window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
geometry.min_width = 8;
}
}
- 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)
lw->bar_exif_size = -1;
lw->bar_exif_advanced = FALSE;
- lw->full_screen_overlay_id = -1;
lw->full_screen_overlay_on = FALSE;
/* default layout */
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);
}
/*
}
lw->full_screen = NULL;
- lw->full_screen_overlay_id = -1;
}
void layout_image_full_screen_start(LayoutWindow *lw)
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 */
/* full screen */
FullScreenData *full_screen;
- gint full_screen_overlay_id;
gint full_screen_overlay_on;
/* dividers */