X-Git-Url: http://geeqie.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fbar_histogram.c;h=9a218e2f655a1004ef6bd94fcb1dd0c1a0664907;hb=2d84366d1d5bfa920a9565f224aafc632f552f09;hp=f4c6038e97aac6f7e3a988610babecfc1b6f4128;hpb=75ad70e81b5f541c6b57bf514a6363df919c102b;p=geeqie.git diff --git a/src/bar_histogram.c b/src/bar_histogram.c index f4c6038e..9a218e2f 100644 --- a/src/bar_histogram.c +++ b/src/bar_histogram.c @@ -1,7 +1,7 @@ /* * Geeqie * (C) 2004 John Ellis - * Copyright (C) 2008 - 2009 The Geeqie Team + * Copyright (C) 2008 - 2012 The Geeqie Team * * Author: Vladimir Nadvornik * @@ -43,7 +43,7 @@ struct _PaneHistogramData GdkPixbuf *pixbuf; FileData *fd; gboolean need_update; - gint idle_id; + guint idle_id; /* event source id */ }; static gboolean bar_pane_histogram_update_cb(gpointer data); @@ -61,9 +61,12 @@ static void bar_pane_histogram_update(PaneHistogramData *phd) /* histmap_get is relatively expensive, run it only when we really need it and with lower priority than pixbuf_renderer FIXME: this does not work for fullscreen*/ - if (GTK_WIDGET_DRAWABLE(phd->drawing_area)) + if (gtk_widget_is_drawable(phd->drawing_area)) { - if (phd->idle_id == -1) phd->idle_id = g_idle_add_full(G_PRIORITY_DEFAULT_IDLE, bar_pane_histogram_update_cb, phd, NULL); + if (!phd->idle_id) + { + phd->idle_id = g_idle_add_full(G_PRIORITY_DEFAULT_IDLE, bar_pane_histogram_update_cb, phd, NULL); + } } else { @@ -76,11 +79,12 @@ static gboolean bar_pane_histogram_update_cb(gpointer data) const HistMap *histmap; PaneHistogramData *phd = data; - phd->idle_id = -1; + phd->idle_id = 0; phd->need_update = FALSE; gtk_widget_queue_draw_area(GTK_WIDGET(phd->drawing_area), 0, 0, phd->histogram_width, phd->histogram_height); + if (phd->fd == NULL) return FALSE; histmap = histmap_get(phd->fd); if (!histmap) @@ -118,8 +122,9 @@ static void bar_pane_histogram_write_config(GtkWidget *pane, GString *outstr, gi if (!phd) return; WRITE_NL(); WRITE_STRING("pane.title))); - WRITE_BOOL(*phd, pane.expanded); + write_char_option(outstr, indent, "id", phd->pane.id); + write_char_option(outstr, indent, "title", gtk_label_get_text(GTK_LABEL(phd->pane.title))); + WRITE_BOOL(phd->pane, expanded); WRITE_INT(*phd->histogram, histogram_channel); WRITE_INT(*phd->histogram, histogram_mode); WRITE_STRING("/>"); @@ -128,9 +133,33 @@ static void bar_pane_histogram_write_config(GtkWidget *pane, GString *outstr, gi static void bar_pane_histogram_notify_cb(FileData *fd, NotifyType type, gpointer data) { PaneHistogramData *phd = data; - if ((type & (NOTIFY_REREAD | NOTIFY_CHANGE | NOTIFY_HISTMAP | NOTIFY_PIXBUF)) && fd == phd->fd) bar_pane_histogram_update(phd); + if ((type & (NOTIFY_REREAD | NOTIFY_CHANGE | NOTIFY_HISTMAP | NOTIFY_PIXBUF)) && fd == phd->fd) + { + DEBUG_1("Notify pane_histogram: %s %04x", fd->path, type); + bar_pane_histogram_update(phd); + } } +#if GTK_CHECK_VERSION(3,0,0) +static gboolean bar_pane_histogram_draw_cb(GtkWidget *widget, cairo_t *cr, gpointer data) +{ + PaneHistogramData *phd = data; + if (!phd) return TRUE; + + if (phd->need_update) + { + bar_pane_histogram_update(phd); + } + + if (!phd->pixbuf) return TRUE; + + gdk_cairo_set_source_pixbuf(cr, phd->pixbuf, 0, 0); + cairo_paint (cr); + + return TRUE; +} + +#else static gboolean bar_pane_histogram_expose_event_cb(GtkWidget *widget, GdkEventExpose *event, gpointer data) { PaneHistogramData *phd = data; @@ -143,15 +172,14 @@ static gboolean bar_pane_histogram_expose_event_cb(GtkWidget *widget, GdkEventEx if (!phd->pixbuf) return TRUE; - gdk_draw_pixbuf(widget->window, - widget->style->fg_gc[GTK_WIDGET_STATE (widget)], - phd->pixbuf, - 0, 0, - 0, 0, - -1, -1, - GDK_RGB_DITHER_NORMAL, 0, 0); + cairo_t *cr = gdk_cairo_create(gtk_widget_get_window(widget)); + gdk_cairo_set_source_pixbuf (cr, phd->pixbuf, 0, 0); + cairo_paint (cr); + cairo_destroy (cr); + return TRUE; } +#endif static void bar_pane_histogram_size_cb(GtkWidget *widget, GtkAllocation *allocation, gpointer data) { @@ -162,149 +190,72 @@ static void bar_pane_histogram_size_cb(GtkWidget *widget, GtkAllocation *allocat bar_pane_histogram_update(phd); } -static void bar_pane_histogram_close(GtkWidget *pane) -{ - PaneHistogramData *phd; - - phd = g_object_get_data(G_OBJECT(pane), "pane_data"); - if (!phd) return; - - gtk_widget_destroy(phd->widget); -} - static void bar_pane_histogram_destroy(GtkWidget *widget, gpointer data) { PaneHistogramData *phd = data; - g_source_remove(phd->idle_id); + if (phd->idle_id) g_source_remove(phd->idle_id); file_data_unregister_notify_func(bar_pane_histogram_notify_cb, phd); file_data_unref(phd->fd); histogram_free(phd->histogram); if (phd->pixbuf) g_object_unref(phd->pixbuf); + g_free(phd->pane.id); g_free(phd); } static void bar_pane_histogram_popup_channels_cb(GtkWidget *widget, gpointer data) { - PaneHistogramData *phd; + PaneHistogramData *phd = data; gint channel; if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget))) return; - phd = submenu_item_get_data(widget); - if (!phd) return; - channel = GPOINTER_TO_INT(data); + channel = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(widget), "menu_item_radio_data")); if (channel == histogram_get_channel(phd->histogram)) return; histogram_set_channel(phd->histogram, channel); bar_pane_histogram_update(phd); } -static void bar_pane_histogram_popup_logmode_cb(GtkWidget *widget, gpointer data) +static void bar_pane_histogram_popup_mode_cb(GtkWidget *widget, gpointer data) { - PaneHistogramData *phd; + PaneHistogramData *phd = data; gint logmode; if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget))) return; - phd = submenu_item_get_data(widget); - if (!phd) return; - logmode = GPOINTER_TO_INT(data); + logmode = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(widget), "menu_item_radio_data")); if (logmode == histogram_get_mode(phd->histogram)) return; histogram_set_mode(phd->histogram, logmode); bar_pane_histogram_update(phd); } -static GtkWidget *bar_pane_histogram_add_radio(GtkWidget *menu, GtkWidget *parent, - const gchar *label, - GCallback func, gint value, - gboolean show_current, gint current_value) -{ - GtkWidget *item; - - if (show_current) - { - item = menu_item_add_radio(menu, parent, - label, (value == current_value), - func, GINT_TO_POINTER((gint)value)); - } - else - { - item = menu_item_add(menu, label, - func, GINT_TO_POINTER((gint)value)); - } - - return item; -} - -GtkWidget *bar_pane_histogram_add_channels(GtkWidget *menu, GCallback func, gpointer data, - gboolean show_current, gint current_value) -{ - GtkWidget *submenu; - GtkWidget *parent; - - submenu = gtk_menu_new(); - g_object_set_data(G_OBJECT(submenu), "submenu_data", data); - - parent = bar_pane_histogram_add_radio(submenu, NULL, _("_Red"), func, HCHAN_R, show_current, current_value); - bar_pane_histogram_add_radio(submenu, parent, _("_Green"), func, HCHAN_G, show_current, current_value); - bar_pane_histogram_add_radio(submenu, parent, _("_Blue"),func, HCHAN_B, show_current, current_value); - bar_pane_histogram_add_radio(submenu, parent, _("_RGB"),func, HCHAN_RGB, show_current, current_value); - bar_pane_histogram_add_radio(submenu, parent, _("_Value"),func, HCHAN_MAX, show_current, current_value); - - if (menu) - { - GtkWidget *item; - - item = menu_item_add(menu, _("Channels"), NULL, NULL); - gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), submenu); - return item; - } - - return submenu; -} -GtkWidget *bar_pane_histogram_add_logmode(GtkWidget *menu, GCallback func, gpointer data, - gboolean show_current, gint current_value) -{ - GtkWidget *submenu; - GtkWidget *parent; - - submenu = gtk_menu_new(); - g_object_set_data(G_OBJECT(submenu), "submenu_data", data); - - parent = bar_pane_histogram_add_radio(submenu, NULL, _("_Linear"), func, 0, show_current, current_value); - bar_pane_histogram_add_radio(submenu, parent, _("Lo_garithmical"), func, 1, show_current, current_value); - - if (menu) - { - GtkWidget *item; - - item = menu_item_add(menu, _("Mode"), NULL, NULL); - gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), submenu); - return item; - } - - return submenu; -} - - static GtkWidget *bar_pane_histogram_menu(PaneHistogramData *phd) { GtkWidget *menu; - static gboolean show_current = TRUE; + gint channel = histogram_get_channel(phd->histogram); + gint mode = histogram_get_mode(phd->histogram); menu = popup_menu_short_lived(); - bar_pane_histogram_add_channels(menu, G_CALLBACK(bar_pane_histogram_popup_channels_cb), phd, - show_current, histogram_get_channel(phd->histogram)); - bar_pane_histogram_add_logmode(menu, G_CALLBACK(bar_pane_histogram_popup_logmode_cb), phd, - show_current, histogram_get_mode(phd->histogram)); + + /* use the same strings as in layout_util.c */ + menu_item_add_radio(menu, _("Histogram on _Red"), GINT_TO_POINTER(HCHAN_R), (channel == HCHAN_R), G_CALLBACK(bar_pane_histogram_popup_channels_cb), phd); + menu_item_add_radio(menu, _("Histogram on _Green"), GINT_TO_POINTER(HCHAN_G), (channel == HCHAN_G), G_CALLBACK(bar_pane_histogram_popup_channels_cb), phd); + menu_item_add_radio(menu, _("Histogram on _Blue"), GINT_TO_POINTER(HCHAN_B), (channel == HCHAN_B), G_CALLBACK(bar_pane_histogram_popup_channels_cb), phd); + menu_item_add_radio(menu, _("_Histogram on RGB"), GINT_TO_POINTER(HCHAN_RGB), (channel == HCHAN_RGB), G_CALLBACK(bar_pane_histogram_popup_channels_cb), phd); + menu_item_add_radio(menu, _("Histogram on _Value"), GINT_TO_POINTER(HCHAN_MAX), (channel == HCHAN_MAX), G_CALLBACK(bar_pane_histogram_popup_channels_cb), phd); + + menu_item_add_divider(menu); + + menu_item_add_radio(menu, _("Li_near Histogram"), GINT_TO_POINTER(0), (mode == 0), G_CALLBACK(bar_pane_histogram_popup_mode_cb), phd); + menu_item_add_radio(menu, _("L_og Histogram"), GINT_TO_POINTER(1), (mode == 1), G_CALLBACK(bar_pane_histogram_popup_mode_cb), phd); return menu; } @@ -326,7 +277,7 @@ static gboolean bar_pane_histogram_press_cb(GtkWidget *widget, GdkEventButton *b } -GtkWidget *bar_pane_histogram_new(const gchar *title, gint height, gboolean expanded, gint histogram_channel, gint histogram_mode) +static GtkWidget *bar_pane_histogram_new(const gchar *id, const gchar *title, gint height, gboolean expanded, gint histogram_channel, gint histogram_mode) { PaneHistogramData *phd; @@ -335,9 +286,10 @@ GtkWidget *bar_pane_histogram_new(const gchar *title, gint height, gboolean expa phd->pane.pane_set_fd = bar_pane_histogram_set_fd; phd->pane.pane_write_config = bar_pane_histogram_write_config; phd->pane.title = bar_pane_expander_title(title); + phd->pane.id = g_strdup(id); + phd->pane.type = PANE_HISTOGRAM; phd->pane.expanded = expanded; - phd->idle_id = -1; phd->histogram = histogram_new(); @@ -357,8 +309,13 @@ GtkWidget *bar_pane_histogram_new(const gchar *title, gint height, gboolean expa g_signal_connect_after(G_OBJECT(phd->drawing_area), "size_allocate", G_CALLBACK(bar_pane_histogram_size_cb), phd); +#if GTK_CHECK_VERSION(3,0,0) + g_signal_connect(G_OBJECT(phd->drawing_area), "draw", + G_CALLBACK(bar_pane_histogram_draw_cb), phd); +#else g_signal_connect(G_OBJECT(phd->drawing_area), "expose_event", G_CALLBACK(bar_pane_histogram_expose_event_cb), phd); +#endif gtk_box_pack_start(GTK_BOX(phd->widget), phd->drawing_area, TRUE, TRUE, 0); gtk_widget_show(phd->drawing_area); @@ -375,26 +332,66 @@ GtkWidget *bar_pane_histogram_new(const gchar *title, gint height, gboolean expa GtkWidget *bar_pane_histogram_new_from_config(const gchar **attribute_names, const gchar **attribute_values) { - gchar *title = g_strdup(_("NoName")); + gchar *title = NULL; + gchar *id = g_strdup("histogram"); gboolean expanded = TRUE; gint height = 80; gint histogram_channel = HCHAN_RGB; gint histogram_mode = 0; + GtkWidget *ret; while (*attribute_names) { const gchar *option = *attribute_names++; const gchar *value = *attribute_values++; - if (READ_CHAR_FULL("pane.title", title)) continue; - if (READ_BOOL_FULL("pane.expanded", expanded)) continue; + if (READ_CHAR_FULL("id", id)) continue; + if (READ_CHAR_FULL("title", title)) continue; + if (READ_BOOL_FULL("expanded", expanded)) continue; if (READ_INT_FULL("histogram_channel", histogram_channel)) continue; if (READ_INT_FULL("histogram_mode", histogram_mode)) continue; - DEBUG_1("unknown attribute %s = %s", option, value); + log_printf("unknown attribute %s = %s\n", option, value); } - return bar_pane_histogram_new(title, height, expanded, histogram_channel, histogram_mode); + bar_pane_translate_title(PANE_HISTOGRAM, id, &title); + ret = bar_pane_histogram_new(id, title, height, expanded, histogram_channel, histogram_mode); + g_free(title); + g_free(id); + return ret; } +void bar_pane_histogram_update_from_config(GtkWidget *pane, const gchar **attribute_names, const gchar **attribute_values) +{ + PaneHistogramData *phd; + + phd = g_object_get_data(G_OBJECT(pane), "pane_data"); + if (!phd) return; + + gint histogram_channel = phd->histogram->histogram_channel; + gint histogram_mode = phd->histogram->histogram_mode; + + while (*attribute_names) + { + const gchar *option = *attribute_names++; + const gchar *value = *attribute_values++; + + if (READ_CHAR_FULL("id", phd->pane.id)) continue; +// if (READ_CHAR_FULL("pane.title", title)) continue; + if (READ_BOOL_FULL("expanded", phd->pane.expanded)) continue; + if (READ_INT_FULL("histogram_channel", histogram_channel)) continue; + if (READ_INT_FULL("histogram_mode", histogram_mode)) continue; + + + log_printf("unknown attribute %s = %s\n", option, value); + } + + histogram_set_channel(phd->histogram, histogram_channel); + histogram_set_mode(phd->histogram, histogram_mode); + + bar_update_expander(pane); + bar_pane_histogram_update(phd); +} + + /* vim: set shiftwidth=8 softtabstop=0 cindent cinoptions={1s: */