/*
* Geeqie
* (C) 2006 John Ellis
+ * Copyright (C) 2008 The Geeqie Team
*
* Author: John Ellis
*
* This software comes with no warranty of any kind, use at your own risk!
*/
-#include "gqview.h"
+#include "main.h"
#include "image-overlay.h"
#include "collect.h"
#include "layout.h"
#include "pixbuf-renderer.h"
#include "pixbuf_util.h"
+#include "histogram.h"
/*
#define IMAGE_OSD_DEFAULT_DURATION 30
+#define HISTOGRAM_HEIGHT 140
+
+void set_default_image_overlay_template_string(ConfOptions *options)
+{
+ if (options->image_overlay.common.template_string) g_free(options->image_overlay.common.template_string);
+ options->image_overlay.common.template_string = g_strdup(DEFAULT_OVERLAY_INFO);
+}
+
+/*
+ *----------------------------------------------------------------------------
+ * image histogram
+ *----------------------------------------------------------------------------
+ */
+
+
+#define HIST_PREPARE(imd, lw) \
+ LayoutWindow *lw = NULL; \
+ if (imd) \
+ lw = layout_find_by_image(imd);
+
+void image_osd_histogram_onoff_toggle(ImageWindow *imd, gint x)
+{
+ HIST_PREPARE(imd, lw)
+ if (lw)
+ {
+ lw->histogram_enabled = !!(x);
+ if (lw->histogram_enabled && !lw->histogram)
+ lw->histogram = histogram_new();
+ }
+}
+
+gint image_osd_histogram_onoff_status(ImageWindow *imd)
+{
+ HIST_PREPARE(imd, lw)
+ return lw ? lw->histogram_enabled : FALSE;
+}
+
+void image_osd_histogram_chan_toggle(ImageWindow *imd)
+{
+ HIST_PREPARE(imd, lw)
+ if (lw && lw->histogram)
+ histogram_set_channel(lw->histogram, (histogram_get_channel(lw->histogram) +1)%HCHAN_COUNT);
+}
+
+void image_osd_histogram_log_toggle(ImageWindow *imd)
+{
+ HIST_PREPARE(imd,lw)
+ if (lw && lw->histogram)
+ histogram_set_mode(lw->histogram, !histogram_get_mode(lw->histogram));
+}
+
+
static void image_osd_timer_schedule(OverlayStateData *osd);
gint pos, prev;
gint last;
gchar *name, *data;
- GString *new = g_string_new(str);
+ GString *new;
gchar *ret;
ExifData *exif;
- exif = exif_read_fd(imd->image_fd, FALSE);
+ if (!str || !*str) return g_strdup("");
+
+ new = g_string_new(str);
+
+ exif = exif_read_fd(imd->image_fd);
prev = 0;
last = FALSE;
while (TRUE)
{
+ gint was_digit = 0;
+ gint limit = 0;
+ gchar *trunc = NULL;
+ gchar *p;
+
start = strchr(new->str, delim);
if (!start)
break;
if (!end)
break;
- name = g_strndup(start+1, end-start-1);
+ for (p = end; p > start; p--)
+ {
+ if (*p == ':' && was_digit)
+ {
+ trunc = p;
+ break;
+ }
+ was_digit = g_ascii_isdigit(*p);
+ }
+
+ if (trunc) limit = atoi(trunc+1);
+
+ name = g_strndup(start+1, ((limit > 0) ? trunc : end)-start-1);
+
pos = start-new->str;
data = g_strdup(g_hash_table_lookup(vars, name));
+ if (data && strcmp(name, "zoom") == 0) imd->overlay_show_zoom = TRUE;
if (!data && exif)
data = exif_get_data_as_text(exif, name);
+ if (data && *data && limit > 0 && strlen(data) > limit + 3)
+ {
+ gchar *new_data = g_strdup_printf("%-*.*s...", limit, limit, data);
+ g_free(data);
+ data = new_data;
+ }
g_string_erase(new, pos, end-start+1);
if (data)
g_free(name);
g_free(data);
}
-
+
/* search and destroy empty lines */
end = new->str;
while ((start = strchr(end, '\n')))
static GdkPixbuf *image_osd_info_render(ImageWindow *imd)
{
- GdkPixbuf *pixbuf;
+ GdkPixbuf *pixbuf = NULL;
gint width, height;
PangoLayout *layout;
const gchar *name;
gchar *name_escaped;
- gchar *text, *text2;
+ gchar *text;
gchar *size;
gint n, t;
CollectionData *cd;
CollectInfo *info;
+ GdkPixbuf *imgpixbuf = NULL;
+ LayoutWindow *lw = NULL;
+ gint with_hist = 0;
gchar *ct;
- int i;
- gint w, h;
+ gint w, h;
GHashTable *vars;
vars = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, g_free);
}
else
{
- LayoutWindow *lw;
-
lw = layout_find_by_image(imd);
if (lw)
{
{
w = gdk_pixbuf_get_width(imd->il->pixbuf);
h = gdk_pixbuf_get_height(imd->il->pixbuf);
+ imgpixbuf = imd->il->pixbuf;
}
else
{
pixbuf_renderer_get_image_size(PIXBUF_RENDERER(imd->pr), &w, &h);
+ imgpixbuf = (PIXBUF_RENDERER(imd->pr))->pixbuf;
}
+ if (!lw)
+ lw = layout_find_by_image(imd);
+
+ if (imgpixbuf && lw && lw->histogram && lw->histogram_enabled
+ && (!imd->il || imd->il->done))
+ with_hist=1;
g_hash_table_insert(vars, "width", g_strdup_printf("%d", w));
g_hash_table_insert(vars, "height", g_strdup_printf("%d", h));
g_hash_table_insert(vars, "res", g_strdup_printf("%d × %d", w, h));
}
-
+
g_hash_table_insert(vars, "collection", g_strdup(ct));
g_hash_table_insert(vars, "number", g_strdup_printf("%d", n));
g_hash_table_insert(vars, "total", g_strdup_printf("%d", t));
g_hash_table_insert(vars, "name", g_strdup(name_escaped));
g_hash_table_insert(vars, "date", g_strdup(text_from_time(imd->mtime)));
g_hash_table_insert(vars, "size", g_strdup(size));
-
+ g_hash_table_insert(vars, "zoom", image_zoom_get_as_text(imd));
+
if (!name_escaped)
{
text = g_strdup_printf(_("Untitled"));
}
else
{
- text = image_osd_mkinfo(fullscreen_info, imd, vars);
+ text = image_osd_mkinfo(options->image_overlay.common.template_string, imd, vars);
}
g_free(size);
g_hash_table_destroy(vars);
{
- GString *buf = g_string_sized_new(FILEDATA_MARKS_SIZE * 2);
FileData *fd = image_get_fd(imd);
-
- for (i=0; i < FILEDATA_MARKS_SIZE; i++)
+
+ if (fd) /* fd may be null after file deletion */
{
-
- g_string_append_printf(buf, fd->marks[i] ? " <span background='#FF00FF'>%c</span>" : " %c", '1' + i);
- }
- text2 = g_strdup_printf("%s\n%s", text, buf->str);
+ gint active_marks = 0;
+ gint mark;
+ gchar *text2;
+
+ for (mark = 0; mark < FILEDATA_MARKS_SIZE; mark++)
+ {
+ active_marks += fd->marks[mark];
+ }
+
+
+ if (active_marks > 0)
+ {
+ GString *buf = g_string_sized_new(FILEDATA_MARKS_SIZE * 2);
+
+ for (mark = 0; mark < FILEDATA_MARKS_SIZE; mark++)
+ {
+ g_string_append_printf(buf, fd->marks[mark] ? " <span background='#FF00FF'>%c</span>" : " %c", '1' + mark);
+ }
+
+ if (*text)
+ text2 = g_strdup_printf("%s\n%s", text, buf->str);
+ else
+ text2 = g_strdup(buf->str);
+ g_string_free(buf, TRUE);
+ g_free(text);
+ text = text2;
+ }
+
+ if (with_hist)
+ {
+ if (*text)
+ text2 = g_strdup_printf("%s\n%s", text, histogram_label(lw->histogram));
+ else
+ text2 = g_strdup(histogram_label(lw->histogram));
+ g_free(text);
+ text = text2;
+ }
+ }
}
-
+
layout = gtk_widget_create_pango_layout(imd->pr, NULL);
- pango_layout_set_markup(layout, text2, -1);
- g_free(text2);
+ pango_layout_set_markup(layout, text, -1);
g_free(text);
-
- pango_layout_get_pixel_size(layout, &width, &height);
- width += 10;
- height += 10;
-
- /* TODO: make osd color configurable --Zas */
- pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8, width, height);
- pixbuf_set_rect_fill(pixbuf, 3, 3, width-6, height-6, 240, 240, 240, 210);
- pixbuf_set_rect(pixbuf, 0, 0, width, height, 240, 240, 240, 80, 1, 1, 1, 1);
- pixbuf_set_rect(pixbuf, 1, 1, width-2, height-2, 240, 240, 240, 130, 1, 1, 1, 1);
- pixbuf_set_rect(pixbuf, 2, 2, width-4, height-4, 240, 240, 240, 180, 1, 1, 1, 1);
- pixbuf_pixel_set(pixbuf, 0, 0, 0, 0, 0, 0);
- pixbuf_pixel_set(pixbuf, width - 1, 0, 0, 0, 0, 0);
- pixbuf_pixel_set(pixbuf, 0, height - 1, 0, 0, 0, 0);
- pixbuf_pixel_set(pixbuf, width - 1, height - 1, 0, 0, 0, 0);
+ pango_layout_get_pixel_size(layout, &width, &height);
+ /* with empty text width is set to 0, but not height) */
+ if (width == 0)
+ height = 0;
+ else if (height == 0)
+ width = 0;
+ if (width > 0) width += 10;
+ if (height > 0) height += 10;
+
+ if (with_hist)
+ {
+ histogram_read(lw->histogram, imgpixbuf);
+ if (width < 266) width = 266;
+ height += HISTOGRAM_HEIGHT + 5;
+ }
- pixbuf_draw_layout(pixbuf, layout, imd->pr, 5, 5, 0, 0, 0, 255);
+ if (width > 0 && height > 0)
+ {
+ /* TODO: make osd color configurable --Zas */
+ pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8, width, height);
+ pixbuf_set_rect_fill(pixbuf, 3, 3, width-6, height-6, 240, 240, 240, 210);
+ pixbuf_set_rect(pixbuf, 0, 0, width, height, 240, 240, 240, 80, 1, 1, 1, 1);
+ pixbuf_set_rect(pixbuf, 1, 1, width-2, height-2, 240, 240, 240, 130, 1, 1, 1, 1);
+ pixbuf_set_rect(pixbuf, 2, 2, width-4, height-4, 240, 240, 240, 180, 1, 1, 1, 1);
+ pixbuf_pixel_set(pixbuf, 0, 0, 0, 0, 0, 0);
+ pixbuf_pixel_set(pixbuf, width - 1, 0, 0, 0, 0, 0);
+ pixbuf_pixel_set(pixbuf, 0, height - 1, 0, 0, 0, 0);
+ pixbuf_pixel_set(pixbuf, width - 1, height - 1, 0, 0, 0, 0);
+
+ if (with_hist)
+ histogram_draw(lw->histogram, pixbuf, 5, height - HISTOGRAM_HEIGHT - 5 , width - 10, HISTOGRAM_HEIGHT);
+
+ pixbuf_draw_layout(pixbuf, layout, imd->pr, 5, 5, 0, 0, 0, 255);
+ }
g_object_unref(G_OBJECT(layout));
{
OverlayStateData *osd = data;
+ osd->imd->overlay_show_zoom = FALSE;
+
if (osd->show_info)
{
if (osd->changed_states & IMAGE_STATE_IMAGE)
GdkPixbuf *pixbuf;
pixbuf = image_osd_info_render(osd->imd);
- if (osd->ovl_info == 0)
+ if (pixbuf)
{
- osd->ovl_info = image_overlay_add(osd->imd, pixbuf,
- OSD_INFO_X, OSD_INFO_Y, TRUE, FALSE);
+ 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
+ else if (osd->ovl_info)
{
- image_overlay_set(osd->imd, osd->ovl_info, pixbuf, OSD_INFO_X, OSD_INFO_Y);
+ image_overlay_remove(osd->imd, osd->ovl_info);
+ osd->ovl_info = 0;
}
- g_object_unref(pixbuf);
}
}
else
}
}
- osd->changed_states = IMAGE_STATE_NONE;
+ if (osd->imd->il && osd->imd->il->done)
+ osd->changed_states = IMAGE_STATE_NONE;
osd->idle_id = -1;
return FALSE;
}