From: Vladimir Nadvornik Date: Wed, 4 Mar 2009 18:53:47 +0000 (+0000) Subject: Display pixel coordinates and rgb - patch by Ruben Stein X-Git-Tag: v1.0.0~428 X-Git-Url: http://geeqie.org/cgi-bin/gitweb.cgi?p=geeqie.git;a=commitdiff_plain;h=ed17579e62a6cfe5a18915d3bfba80f8bc2ee564 Display pixel coordinates and rgb - patch by Ruben Stein --- diff --git a/src/layout.c b/src/layout.c index 3e3fadfe..7ea51558 100644 --- a/src/layout.c +++ b/src/layout.c @@ -51,6 +51,7 @@ #define TOOLWINDOW_DEF_HEIGHT 450 #define PROGRESS_WIDTH 150 +#define PIXEL_LABEL_WIDTH 130 #define ZOOM_LABEL_WIDTH 64 #define PANE_DIVIDER_SIZE 10 @@ -705,6 +706,8 @@ void layout_status_update_image(LayoutWindow *lw) width, height, b); } + g_signal_emit_by_name (lw->image->pr, "update-pixel"); + g_free(b); gtk_label_set_text(GTK_LABEL(lw->info_details), text); @@ -805,6 +808,8 @@ static void layout_status_setup(LayoutWindow *lw, GtkWidget *box, gint small_for lw->info_details = layout_status_label(NULL, hbox, TRUE, 0, TRUE); if (!small_format) gtk_box_pack_start(GTK_BOX(hbox), lw->info_color, FALSE, FALSE, 0); if (!small_format) gtk_box_pack_start(GTK_BOX(hbox), lw->info_write, FALSE, FALSE, 0); + lw->info_pixel = layout_status_label(NULL, hbox, FALSE, PIXEL_LABEL_WIDTH, TRUE); + if (lw->options.info_pixel_hidden) gtk_widget_hide(gtk_widget_get_parent(lw->info_pixel)); lw->info_zoom = layout_status_label(NULL, hbox, FALSE, ZOOM_LABEL_WIDTH, FALSE); } @@ -1742,6 +1747,7 @@ void layout_style_set(LayoutWindow *lw, gint style, const gchar *order) lw->info_color = NULL; lw->info_status = NULL; lw->info_details = NULL; + lw->info_pixel = NULL; lw->info_zoom = NULL; if (lw->ui_manager) g_object_unref(lw->ui_manager); @@ -1900,6 +1906,33 @@ gint layout_toolbar_hidden(LayoutWindow *lw) return lw->options.toolbar_hidden; } +void layout_info_pixel_toggle(LayoutWindow *lw) +{ + GtkWidget *frame; + + if (!layout_valid(&lw)) return; + if (!lw->info_pixel) return; + + lw->options.info_pixel_hidden = !lw->options.info_pixel_hidden; + + frame = gtk_widget_get_parent(lw->info_pixel); + if (lw->options.info_pixel_hidden) + { + if (GTK_WIDGET_VISIBLE(frame)) gtk_widget_hide(frame); + } + else + { + if (!GTK_WIDGET_VISIBLE(frame)) gtk_widget_show(frame); + } +} + +gint layout_info_pixel_hidden(LayoutWindow *lw) +{ + if (!layout_valid(&lw)) return TRUE; + + return lw->options.info_pixel_hidden; +} + /* *----------------------------------------------------------------------------- * base @@ -2164,7 +2197,8 @@ void layout_write_attributes(LayoutOptions *layout, GString *outstr, gint indent WRITE_SEPARATOR(); WRITE_BOOL(*layout, toolbar_hidden); - + WRITE_BOOL(*layout, info_pixel_hidden); + WRITE_UINT(*layout, image_overlay.state); WRITE_INT(*layout, image_overlay.histogram_channel); WRITE_INT(*layout, image_overlay.histogram_mode); @@ -2231,6 +2265,7 @@ void layout_load_attributes(LayoutOptions *layout, const gchar **attribute_names if (READ_BOOL(*layout, tools_hidden)) continue; if (READ_BOOL(*layout, tools_restore_state)) continue; if (READ_BOOL(*layout, toolbar_hidden)) continue; + if (READ_BOOL(*layout, info_pixel_hidden)) continue; if (READ_UINT(*layout, image_overlay.state)) continue; if (READ_INT(*layout, image_overlay.histogram_channel)) continue; diff --git a/src/layout.h b/src/layout.h index 1ce668dd..03446629 100644 --- a/src/layout.h +++ b/src/layout.h @@ -101,6 +101,8 @@ void layout_tools_hide_toggle(LayoutWindow *lw); void layout_toolbar_toggle(LayoutWindow *lw); gint layout_toolbar_hidden(LayoutWindow *lw); +void layout_info_pixel_toggle(LayoutWindow *lw); +gint layout_info_pixel_hidden(LayoutWindow *lw); void layout_split_change(LayoutWindow *lw, ImageSplitMode mode); diff --git a/src/layout_image.c b/src/layout_image.c index caedd220..bc190f8f 100644 --- a/src/layout_image.c +++ b/src/layout_image.c @@ -26,6 +26,7 @@ #include "menu.h" #include "misc.h" #include "pixbuf_util.h" +#include "pixbuf-renderer.h" #include "slideshow.h" #include "ui_fileops.h" #include "ui_menu.h" @@ -1481,6 +1482,46 @@ static void layout_image_set_buttons_inactive(LayoutWindow *lw, gint i) image_set_scroll_func(lw->split_images[i], layout_image_scroll_cb, lw); } + +void layout_status_update_pixel_cb(PixbufRenderer *pr, gpointer data) +{ + LayoutWindow *lw = data; + gchar *text; + + if (!data || !layout_valid(&lw) || !lw->image || lw->options.info_pixel_hidden) return; + + if (!lw->image->unknown) + { + gint x_pixel, y_pixel; + + pixbuf_renderer_get_mouse_position(pr, &x_pixel, &y_pixel); + + if(x_pixel > 0 && y_pixel > 0) + { + gint r_mouse, g_mouse, b_mouse; + gint width, height, slen_width, slen_height; + gchar str_temp[10]; + + pixbuf_renderer_get_pixel_colors(pr, x_pixel, y_pixel, + &r_mouse, &g_mouse, &b_mouse); + pixbuf_renderer_get_image_size(pr, &width, &height); + slen_width = sprintf(str_temp, "%d", width - 1); + slen_height = sprintf(str_temp, "%d", height - 1); + + text = g_strdup_printf(_("pos(%*d,%*d) rgb(%3d,%3d,%3d)"), + slen_width, x_pixel, slen_height, y_pixel, + r_mouse, g_mouse, b_mouse); + } + else + { + text = g_strdup(""); + } + gtk_label_set_markup(GTK_LABEL(lw->info_pixel), text); + g_free(text); + } +} + + /* *---------------------------------------------------------------------------- * setup @@ -1506,6 +1547,10 @@ GtkWidget *layout_image_new(LayoutWindow *lw, gint i) #else gtk_widget_ref(lw->split_images[i]->widget); #endif + + g_signal_connect(G_OBJECT(lw->split_images[i]->pr), "update-pixel", + G_CALLBACK(layout_status_update_pixel_cb), lw); + image_background_set_color(lw->split_images[i], options->image.use_custom_border_color ? &options->image.border_color : NULL); image_auto_refresh_enable(lw->split_images[i], TRUE); diff --git a/src/layout_util.c b/src/layout_util.c index fa163a57..6eee3adc 100644 --- a/src/layout_util.c +++ b/src/layout_util.c @@ -666,6 +666,16 @@ static void layout_menu_toolbar_cb(GtkToggleAction *action, gpointer data) layout_toolbar_toggle(lw); } +static void layout_menu_info_pixel_cb(GtkToggleAction *action, gpointer data) +{ + LayoutWindow *lw = data; + + if (lw->options.info_pixel_hidden == gtk_toggle_action_get_active(action)) return; + + layout_exit_fullscreen(lw); + layout_info_pixel_toggle(lw); +} + /* NOTE: these callbacks are called also from layout_util_sync_views */ static void layout_menu_bar_cb(GtkToggleAction *action, gpointer data) { @@ -1260,6 +1270,7 @@ static GtkToggleActionEntry menu_toggle_entries[] = { { "ShowMarks", NULL, N_("Show _Marks"), "M", NULL, CB(layout_menu_marks_cb), FALSE }, { "FloatTools", PIXBUF_INLINE_ICON_FLOAT, N_("_Float file list"), "L", NULL, CB(layout_menu_float_cb), FALSE }, { "HideToolbar", NULL, N_("Hide tool_bar"), NULL, NULL, CB(layout_menu_toolbar_cb), FALSE }, + { "HideInfoPixel", NULL, N_("Hide Pi_xel Info"), NULL, NULL, CB(layout_menu_info_pixel_cb), FALSE }, { "SBar", NULL, N_("_Info"), "K", NULL, CB(layout_menu_bar_cb), FALSE }, { "ExifWin", NULL, N_("E_xif window"), "E", NULL, CB(layout_menu_bar_exif_cb), FALSE }, { "SBarSort", NULL, N_("Sort _manager"), "S", NULL, CB(layout_menu_bar_sort_cb), FALSE }, @@ -1418,6 +1429,7 @@ static const gchar *menu_ui_description = " " " " " " +" " " " " " " " @@ -1852,6 +1864,9 @@ static void layout_util_sync_views(LayoutWindow *lw) action = gtk_action_group_get_action(lw->action_group, "HideToolbar"); gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(action), lw->options.toolbar_hidden); + + action = gtk_action_group_get_action(lw->action_group, "HideInfoPixel"); + gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(action), lw->options.info_pixel_hidden); action = gtk_action_group_get_action(lw->action_group, "ShowMarks"); gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(action), lw->options.show_marks); diff --git a/src/options.c b/src/options.c index e8e30dd9..029bfc04 100644 --- a/src/options.c +++ b/src/options.c @@ -105,6 +105,7 @@ ConfOptions *init_options(ConfOptions *options) options->layout.show_marks = FALSE; options->layout.show_thumbnails = FALSE; options->layout.style = 0; + options->layout.info_pixel_hidden = TRUE; options->layout.toolbar_hidden = FALSE; options->layout.tools_float = FALSE; options->layout.tools_hidden = FALSE; diff --git a/src/pixbuf-renderer.c b/src/pixbuf-renderer.c index ad65d959..668c0459 100644 --- a/src/pixbuf-renderer.c +++ b/src/pixbuf-renderer.c @@ -15,8 +15,11 @@ #include #include +#include "main.h" #include "pixbuf-renderer.h" + #include "intl.h" +#include "layout.h" #include @@ -151,6 +154,7 @@ enum { SIGNAL_SCROLL_NOTIFY, SIGNAL_RENDER_COMPLETE, SIGNAL_DRAG, + SIGNAL_UPDATE_PIXEL, SIGNAL_COUNT }; @@ -475,6 +479,15 @@ static void pixbuf_renderer_class_init(PixbufRendererClass *class) g_cclosure_marshal_VOID__BOXED, G_TYPE_NONE, 1, GDK_TYPE_EVENT); + + signals[SIGNAL_UPDATE_PIXEL] = + g_signal_new("update-pixel", + G_OBJECT_CLASS_TYPE(gobject_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET(PixbufRendererClass, update_pixel), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); } static void pixbuf_renderer_init(PixbufRenderer *pr) @@ -507,6 +520,9 @@ static void pixbuf_renderer_init(PixbufRenderer *pr) pr->scroller_id = -1; pr->scroller_overlay = -1; + + pr->x_mouse = -1; + pr->y_mouse = -1; pr->source_tiles_enabled = FALSE; pr->source_tiles = NULL; @@ -3129,6 +3145,11 @@ static void pr_drag_signal(PixbufRenderer *pr, GdkEventButton *bevent) g_signal_emit(pr, signals[SIGNAL_DRAG], 0, bevent); } +static void pr_update_pixel_signal(PixbufRenderer *pr) +{ + g_signal_emit(pr, signals[SIGNAL_UPDATE_PIXEL], 0); +} + /* *------------------------------------------------------------------- * sync and clamp @@ -3672,7 +3693,6 @@ void pixbuf_renderer_set_scroll_center(PixbufRenderer *pr, gdouble x, gdouble y) pixbuf_renderer_scroll(pr, (gint)dst_x, (gint)dst_y); } - /* *------------------------------------------------------------------- * mouse @@ -3691,7 +3711,11 @@ static gint pr_mouse_motion_cb(GtkWidget *widget, GdkEventButton *bevent, gpoint pr->scroller_xpos = bevent->x; pr->scroller_ypos = bevent->y; } - + + pr->x_mouse = bevent->x; + pr->y_mouse = bevent->y; + pr_update_pixel_signal(pr); + if (!pr->in_drag || !gdk_pointer_is_grabbed()) return FALSE; if (pr->drag_moved < PR_DRAG_SCROLL_THRESHHOLD) @@ -3980,6 +4004,8 @@ void pixbuf_renderer_move(PixbufRenderer *pr, PixbufRenderer *source) pr->x_scroll = source->x_scroll; pr->y_scroll = source->y_scroll; + pr->x_mouse = source->x_mouse; + pr->y_mouse = source->y_mouse; scroll_reset = pr->scroll_reset; pr->scroll_reset = PR_SCROLL_RESET_NOCHANGE; @@ -4110,6 +4136,82 @@ void pixbuf_renderer_zoom_set_limits(PixbufRenderer *pr, gdouble min, gdouble ma } } +gint pixbuf_renderer_get_pixel_colors(PixbufRenderer *pr, gint x_pixel, gint y_pixel, + gint *r_mouse, gint *g_mouse, gint *b_mouse) +{ + GdkPixbuf *pb = pr->pixbuf; + gint p_alpha, prs; + guchar *p_pix, *pp; + gint map_x, map_y, map_w, map_h; + + g_return_val_if_fail(IS_PIXBUF_RENDERER(pr), FALSE); + g_return_val_if_fail(r_mouse != NULL && g_mouse != NULL && b_mouse != NULL, FALSE); + + if (!pr->pixbuf && !pr->source_tiles_enabled) + { + *r_mouse = -1; + *g_mouse = -1; + *b_mouse = -1; + return FALSE; + } + + if (!pb) return FALSE; + + pr_tile_region_map_orientation(pr, + x_pixel, y_pixel, + pr->image_width, pr->image_height, + 1, 1, /*single pixel */ + &map_x, &map_y, + &map_w, &map_h); + + if (map_x < 0 || map_x > gdk_pixbuf_get_width(pr->pixbuf) - 1) return FALSE; + if (map_y < 0 || map_y > gdk_pixbuf_get_height(pr->pixbuf) - 1) return FALSE; + + p_alpha = gdk_pixbuf_get_has_alpha(pb); + prs = gdk_pixbuf_get_rowstride(pb); + p_pix = gdk_pixbuf_get_pixels(pb); + + pp = p_pix + map_y * prs + (map_x * (p_alpha ? 4 : 3)); + *r_mouse = *pp; + pp++; + *g_mouse = *pp; + pp++; + *b_mouse = *pp; + + return TRUE; +} + +gint pixbuf_renderer_get_mouse_position(PixbufRenderer *pr, gint *x_pixel_return, gint *y_pixel_return) +{ + gint x_pixel, y_pixel, x_pixel_clamped, y_pixel_clamped; + + g_return_val_if_fail(IS_PIXBUF_RENDERER(pr), FALSE); + g_return_val_if_fail(x_pixel_return != NULL && y_pixel_return != NULL, FALSE); + + if (!pr->pixbuf && !pr->source_tiles_enabled) + { + *x_pixel_return = -1; + *y_pixel_return = -1; + return FALSE; + } + + x_pixel = (gint)((gdouble)(pr->x_mouse - pr->x_offset + pr->x_scroll) / pr->scale); + y_pixel = (gint)((gdouble)(pr->y_mouse - pr->y_offset + pr->y_scroll) / pr->scale); + x_pixel_clamped = CLAMP(x_pixel, 0, pr->image_width - 1); + y_pixel_clamped = CLAMP(y_pixel, 0, pr->image_height - 1); + + if(x_pixel != x_pixel_clamped || y_pixel != y_pixel_clamped) + { + /* mouse is not on pr */ + x_pixel = y_pixel = -1; + } + + *x_pixel_return = x_pixel; + *y_pixel_return = y_pixel; + + return TRUE; +} + gint pixbuf_renderer_get_image_size(PixbufRenderer *pr, gint *width, gint *height) { g_return_val_if_fail(IS_PIXBUF_RENDERER(pr), FALSE); diff --git a/src/pixbuf-renderer.h b/src/pixbuf-renderer.h index ad484a2a..6fc84eea 100644 --- a/src/pixbuf-renderer.h +++ b/src/pixbuf-renderer.h @@ -58,6 +58,9 @@ struct _PixbufRenderer gint x_offset; /* offset of image start (non-zero when image < window) */ gint y_offset; + + gint x_mouse; /* coordinates of the mouse taken from GtkEvent */ + gint y_mouse; gint vis_width; /* dimensions of visible part of image */ gint vis_height; @@ -163,6 +166,7 @@ struct _PixbufRendererClass void (*zoom)(PixbufRenderer *pr, gdouble zoom); void (*clicked)(PixbufRenderer *pr, GdkEventButton *event); void (*scroll_notify)(PixbufRenderer *pr); + void (*update_pixel)(PixbufRenderer *pr); void (*render_complete)(PixbufRenderer *pr); void (*drag)(PixbufRenderer *pr, GdkEventButton *event); @@ -258,6 +262,10 @@ void pixbuf_renderer_overlay_set(PixbufRenderer *pr, gint id, GdkPixbuf *pixbuf, gint pixbuf_renderer_overlay_get(PixbufRenderer *pr, gint id, GdkPixbuf **pixbuf, gint *x, gint *y); void pixbuf_renderer_overlay_remove(PixbufRenderer *pr, gint id); +gint pixbuf_renderer_get_mouse_position(PixbufRenderer *pr, gint *x_pixel, gint *y_pixel); +/* x_pixel and y_pixel are the pixel coordinates \see pixbuf_renderer_get_mouse_position */ +gint pixbuf_renderer_get_pixel_colors(PixbufRenderer *pr, gint x_pixel, gint y_pixel, + gint *r_mouse, gint *g_mouse, gint *b_mouse); #endif /* vim: set shiftwidth=8 softtabstop=0 cindent cinoptions={1s: */ diff --git a/src/typedefs.h b/src/typedefs.h index 06a26f59..bc05f85e 100644 --- a/src/typedefs.h +++ b/src/typedefs.h @@ -532,7 +532,8 @@ struct _LayoutOptions gboolean tools_restore_state; gboolean toolbar_hidden; - + gboolean info_pixel_hidden; + gchar *home_path; }; @@ -625,7 +626,8 @@ struct _LayoutWindow GtkWidget *info_details; GtkWidget *info_zoom; GtkWidget *info_write; - + GtkWidget *info_pixel; + /* slide show */ SlideShowData *slideshow;