On Sun, 01 Mar 2009 00:38:28 +0100
Ruben Stein <m...@grumb.net> wrote:
> I missed a feature in gqview, so I implemented it today. It is an
> optional status-bar add-on showing the pixel-coordinates of the mouse
> and the rgb-values of this pixel. I also added %x and %y as
> editor-macros working together with %p to use the pixel values for a
> call to a script. Furthermore I added a checkbox in the view-menu to
> turn off the feature as it may be disturbing to see the permanently
> changing values if you do not need them.
>
> Referring to former feature requests I think maybe someone might want
> to use it:
> https://sourceforge.net/tracker/index.php?func=detail&aid=1145036&group_id=4050&atid=354050
> https://sourceforge.net/mailarchive/message.php?msg_name=40F9E2BE.9080606%40techspecs.com
>
> It was my first try adding _senseful_ ;) features to an open source
> project, so any advices are appreciated. Unfortunately I did not
> recogise that gqview is outdated, so I learned my first lesson. Anyway
> ... the attached patch applies to GQView 2.1.5 src-dir, diffed against
> the svn-tag in the geeqie-repository of that version.
>
> Greetings, Ruben
>
>
Hi Ruben,
this is an interesting patch but i fear it may never be committed to gqview
devel tree
since there were no activity since a long time there.
It's why the Geeqie project was started.
I adapted your patch to match current Geeqie devel tree (but the editors part
which has changed a lot).
This will permit to all to test it and comment.
Regards,
--
Laurent MONIN aka Zas
Index: layout.c
===================================================================
--- layout.c (révision 1447)
+++ layout.c (copie de travail)
@@ -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
@@ -720,12 +721,38 @@
}
}
+void layout_status_update_pixel(LayoutWindow *lw)
+{
+ gchar *text;
+
+ if (!layout_valid(&lw) || !lw->image) return;
+
+ if (!lw->image->unknown)
+ {
+ gint x_pixel, y_pixel, r_mouse, g_mouse, b_mouse;
+ pixbuf_renderer_get_mouse_position(PIXBUF_RENDERER(lw->image->pr), &x_pixel, &y_pixel);
+ pixbuf_renderer_get_mouse_colors(PIXBUF_RENDERER(lw->image->pr), &r_mouse, &g_mouse, &b_mouse);
+ if(x_pixel > 0 && y_pixel > 0)
+ {
+ text = g_strdup_printf(_("pos (%d,%d) rgb (%d,%d,%d)"),
+ x_pixel, y_pixel, r_mouse, g_mouse, b_mouse);
+ }
+ else
+ {
+ text = g_strdup("");
+ }
+ gtk_label_set_text(GTK_LABEL(lw->info_pixel), text);
+ g_free(text);
+ }
+}
+
void layout_status_update_all(LayoutWindow *lw)
{
layout_status_update_progress(lw, 0.0, NULL);
layout_status_update_info(lw, NULL);
layout_status_update_image(lw);
layout_status_update_write(lw);
+ layout_status_update_pixel(lw);
}
static GtkWidget *layout_status_label(gchar *text, GtkWidget *box, gint start, gint size, gint expand)
@@ -813,6 +840,8 @@
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);
}
@@ -833,6 +862,7 @@
LayoutWindow *lw = data;
layout_status_update_info(lw, NULL);
+ layout_status_update_pixel(lw);
}
static void layout_list_thumb_cb(ViewFile *vf, gdouble val, const gchar *text, gpointer data)
@@ -1747,6 +1777,7 @@
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);
@@ -1905,6 +1936,31 @@
return lw->options.toolbar_hidden;
}
+void layout_info_pixel_toggle(LayoutWindow *lw)
+{
+ if (!layout_valid(&lw)) return;
+ if (!lw->info_pixel) return;
+
+ lw->options.info_pixel_hidden = !lw->options.info_pixel_hidden;
+
+ GtkWidget *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
@@ -2175,7 +2231,8 @@
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);
@@ -2242,6 +2299,7 @@
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;
Index: layout.h
===================================================================
--- layout.h (révision 1447)
+++ layout.h (copie de travail)
@@ -42,6 +42,7 @@
void layout_status_update_progress(LayoutWindow *lw, gdouble val, const gchar *text);
void layout_status_update_info(LayoutWindow *lw, const gchar *text);
+void layout_status_update_pixel(LayoutWindow *lw);
void layout_status_update_image(LayoutWindow *lw);
void layout_status_update_write(LayoutWindow *lw);
void layout_status_update_all(LayoutWindow *lw);
@@ -101,6 +102,8 @@
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);
Index: options.c
===================================================================
--- options.c (révision 1447)
+++ options.c (copie de travail)
@@ -105,6 +105,7 @@
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;
Index: pixbuf-renderer.c
===================================================================
--- pixbuf-renderer.c (révision 1447)
+++ pixbuf-renderer.c (copie de travail)
@@ -15,8 +15,11 @@
#include <string.h>
#include <math.h>
+#include "main.h"
#include "pixbuf-renderer.h"
+
#include "intl.h"
+#include "layout.h"
#include <gtk/gtk.h>
@@ -506,6 +509,12 @@
pr->scroller_id = -1;
pr->scroller_overlay = -1;
+
+ pr->x_mouse = -1;
+ pr->y_mouse = -1;
+ pr->r_mouse = -1;
+ pr->g_mouse = -1;
+ pr->b_mouse = -1;
pr->source_tiles_enabled = FALSE;
pr->source_tiles = NULL;
@@ -3027,6 +3036,7 @@
h -= (ny - y);
w = CLAMP(w, 0, pr->width - nx);
h = CLAMP(h, 0, pr->height - ny);
+
if (w < 1 || h < 1) return;
if (pr_queue_to_tiles(pr, nx, ny, w, h, clamp, render, new_data, only_existing) &&
@@ -3092,8 +3102,79 @@
g_signal_emit(pr, signals[SIGNAL_DRAG], 0, bevent);
}
+
/*
*-------------------------------------------------------------------
+ * pixel information at mouse position
+ *-------------------------------------------------------------------
+ */
+
+ /* put color information if mouse is on valid pixel */
+static void pr_pixel_color_update(PixbufRenderer *pr)
+{
+ GdkPixbuf *pb = pr->pixbuf;
+ gint p_alpha;
+ gint prs;
+ guchar *p_pix;
+ guchar *pp;
+
+ if (!pb) return;
+
+ if (pr->x_pixel < 0 || pr->x_pixel > pr->image_width) return;
+ if (pr->y_pixel < 0 || pr->y_pixel > pr->image_height) return;
+
+ p_alpha = gdk_pixbuf_get_has_alpha(pb);
+ prs = gdk_pixbuf_get_rowstride(pb);
+ p_pix = gdk_pixbuf_get_pixels(pb);
+
+ pp = p_pix + pr->y_pixel * prs + (pr->x_pixel * (p_alpha ? 4 : 3));
+ pr->r_mouse = *pp;
+ pp++;
+ pr->g_mouse = *pp;
+ pp++;
+ pr->b_mouse = *pp;
+}
+
+
+/* update pixel coordinates on layout bar if mouse is above pr*/
+static void pr_pixel_update(PixbufRenderer *pr)
+{
+ gboolean update = FALSE;
+ gboolean valid = FALSE;
+ gint x_pixel = (gint)((gdouble)(pr->x_mouse - pr->x_offset + pr->x_scroll) / pr->scale);
+ gint y_pixel = (gint)((gdouble)(pr->y_mouse - pr->y_offset + pr->y_scroll) / pr->scale);
+ gint x_pixel_clamped = CLAMP(x_pixel, 0, pr->image_width - 1);
+ gint y_pixel_clamped = CLAMP(y_pixel, 0, pr->image_height - 1);
+
+ if(x_pixel == x_pixel_clamped && y_pixel == y_pixel_clamped)
+ {
+ pr->x_pixel = x_pixel;
+ pr->y_pixel = y_pixel;
+ update = TRUE;
+ valid = TRUE;
+ }
+ else
+ {
+ if(pr->x_pixel != -1 || pr->y_pixel != -1)
+ {
+ pr->x_pixel = pr->y_pixel = -1;
+ update = TRUE;
+ }
+ }
+
+ if(update == TRUE)
+ {
+ if(valid == TRUE)
+ {
+ pr_pixel_color_update(pr);
+ }
+ /* update status bar */
+ layout_status_update_pixel((LayoutWindow *)pixbuf_renderer_get_parent(pr));
+ }
+}
+
+/*
+ *-------------------------------------------------------------------
* sync and clamp
*-------------------------------------------------------------------
*/
@@ -3347,12 +3428,14 @@
/* center new image */
pr->x_scroll = ((gdouble)pr->image_width / 2.0 * pr->scale) - pr->vis_width / 2;
pr->y_scroll = ((gdouble)pr->image_height / 2.0 * pr->scale) - pr->vis_height / 2;
+ pr_pixel_update(pr);
break;
case PR_SCROLL_RESET_TOPLEFT:
default:
/* reset to upper left */
pr->x_scroll = 0;
pr->y_scroll = 0;
+ pr_pixel_update(pr);
break;
}
}
@@ -3654,7 +3737,11 @@
pr->scroller_xpos = bevent->x;
pr->scroller_ypos = bevent->y;
}
-
+
+ pr->x_mouse = bevent->x;
+ pr->y_mouse = bevent->y;
+ pr_pixel_update(pr);
+
if (!pr->in_drag || !gdk_pointer_is_grabbed()) return FALSE;
if (pr->drag_moved < PR_DRAG_SCROLL_THRESHHOLD)
@@ -3941,6 +4028,11 @@
pr->x_scroll = source->x_scroll;
pr->y_scroll = source->y_scroll;
+ pr->x_mouse = source->x_mouse;
+ pr->y_mouse = source->y_mouse;
+ pr->r_mouse = source->r_mouse;
+ pr->g_mouse = source->g_mouse;
+ pr->b_mouse = source->b_mouse;
scroll_reset = pr->scroll_reset;
pr->scroll_reset = PR_SCROLL_RESET_NOCHANGE;
@@ -4071,6 +4163,42 @@
}
}
+gint pixbuf_renderer_get_mouse_colors(PixbufRenderer *pr, gint *r_mouse, gint *g_mouse, gint *b_mouse)
+{
+ 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;
+ }
+
+ *r_mouse = pr->r_mouse;
+ *g_mouse = pr->g_mouse;
+ *b_mouse = pr->b_mouse;
+ return TRUE;
+}
+
+gint pixbuf_renderer_get_mouse_position(PixbufRenderer *pr, gint *x_pixel, gint *y_pixel)
+{
+ g_return_val_if_fail(IS_PIXBUF_RENDERER(pr), FALSE);
+ g_return_val_if_fail(x_pixel != NULL && y_pixel != NULL, FALSE);
+
+ if (!pr->pixbuf && !pr->source_tiles_enabled)
+ {
+ *x_pixel = -1;
+ *y_pixel = -1;
+ return FALSE;
+ }
+
+ *x_pixel = pr->x_pixel;
+ *y_pixel = pr->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);
Index: pixbuf-renderer.h
===================================================================
--- pixbuf-renderer.h (révision 1447)
+++ pixbuf-renderer.h (copie de travail)
@@ -59,6 +59,16 @@
gint x_offset; /* offset of image start (non-zero when image < window) */
gint y_offset;
+ gint x_mouse; /* last position of mouse on image */
+ gint y_mouse;
+
+ gint x_pixel; /* pixel coordinates of the mouse */
+ gint y_pixel;
+
+ gint r_mouse; /* color information at mouse position */
+ gint g_mouse;
+ gint b_mouse;
+
gint vis_width; /* dimensions of visible part of image */
gint vis_height;
@@ -258,6 +268,8 @@
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);
+gint pixbuf_renderer_get_mouse_colors(PixbufRenderer *pr, gint *r_mouse, gint *g_mouse, gint *b_mouse);
#endif
/* vim: set shiftwidth=8 softtabstop=0 cindent cinoptions={1s: */
Index: layout_util.c
===================================================================
--- layout_util.c (révision 1447)
+++ layout_util.c (copie de travail)
@@ -666,6 +666,16 @@
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 @@
{ "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"), "<control>K", NULL, CB(layout_menu_bar_cb), FALSE },
{ "ExifWin", NULL, N_("E_xif window"), "<control>E", NULL, CB(layout_menu_bar_exif_cb), FALSE },
{ "SBarSort", NULL, N_("Sort _manager"), "<control>S", NULL, CB(layout_menu_bar_sort_cb), FALSE },
@@ -1418,6 +1429,7 @@
" <menuitem action='FloatTools'/>"
" <menuitem action='HideTools'/>"
" <menuitem action='HideToolbar'/>"
+" <menuitem action='HideInfoPixel'/>"
" <placeholder name='ToolsSection'/>"
" <separator/>"
" <menuitem action='SBar'/>"
@@ -1852,6 +1864,9 @@
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);
Index: typedefs.h
===================================================================
--- typedefs.h (révision 1447)
+++ typedefs.h (copie de travail)
@@ -532,7 +532,8 @@
gboolean tools_restore_state;
gboolean toolbar_hidden;
-
+ gboolean info_pixel_hidden;
+
gchar *home_path;
};
@@ -625,7 +626,8 @@
GtkWidget *info_details;
GtkWidget *info_zoom;
GtkWidget *info_write;
-
+ GtkWidget *info_pixel;
+
/* slide show */
SlideShowData *slideshow;
------------------------------------------------------------------------------
Open Source Business Conference (OSBC), March 24-25, 2009, San Francisco, CA
-OSBC tackles the biggest issue in open source: Open Sourcing the Enterprise
-Strategies to boost innovation and cut costs with open source participation
-Receive a $600 discount off the registration fee with the source code: SFAD
http://p.sf.net/sfu/XcvMzF8H
_______________________________________________
Geeqie-devel mailing list
Geeqie-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/geeqie-devel