Wed Nov 29 14:28:30 2006 John Ellis <johne@verizon.net>
authorJohn Ellis <johne@verizon.net>
Wed, 29 Nov 2006 19:38:25 +0000 (19:38 +0000)
committerJohn Ellis <johne@verizon.net>
Wed, 29 Nov 2006 19:38:25 +0000 (19:38 +0000)
        * 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
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

index 55c4394..1375f82 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -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
index 530dbe6..3a4f9b3 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * 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;
@@ -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;
 }
 
index 8b2c2cf..4569dae 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * 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
index 810bc1b..8e3c6d3 100644 (file)
@@ -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;
                }
index 6f1574f..3cbc0cd 100644 (file)
@@ -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);
index cb52fd7..bbd3d3f 100644 (file)
@@ -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)
index 906ac62..4235393 100644 (file)
@@ -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 */
index e53b298..9edbb55 100644 (file)
@@ -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)
index 818cf7a..9a3075b 100644 (file)
@@ -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 */