* image.c, typedefs.h: Add ALTER_DESATURATE alteration type.
* img-view.c, layout_image.c, layout_util.c, menu.c: Allow to grayscale
the display of current image with [Shift]+[G] kyboard shortcut and
'adjust' submenu item.
* pixbuf_util.[ch] (pixbuf_desaturate_rect): Implement grayscale
function.
+Thu Oct 19 15:20:51 2006 John Ellis <johne@verizon.net>
+
+ * image.c, typedefs.h: Add ALTER_DESATURATE alteration type.
+ * img-view.c, layout_image.c, layout_util.c, menu.c: Allow to grayscale
+ the display of current image with [Shift]+[G] kyboard shortcut and
+ 'adjust' submenu item.
+ * pixbuf_util.[ch] (pixbuf_desaturate_rect): Implement grayscale
+ function.
+
Thu Oct 19 09:35:18 2006 John Ellis <johne@verizon.net>
* layout.[ch] (layout_new_with_geometry): New function to create a
> xvpics is now hidden option.
> Holding down shift will now scroll more when panning with mouse.
> add --geometry command line option
+ > add [shift]+G grayscale alteration
> add blurb about moving images between collections with shift+drag
> do not lose slideshow when reworking window layout.
+ > fix printing of transparent images to not use black for transparency (white or user settable).
+
+ > add [control]+G to display as greyscale
+
+ > fix comment field in keywords bar to a height of 2 or 3 text lines.
+
> add toolbar to: (UPDATE: these toolbars may not make it into 1.6)
> find dupes window (with button to open dialog to add new files/folders)
> collection window
new = pixbuf_copy_mirror(pr->pixbuf, FALSE, TRUE);
y = pr->height - y;
break;
+ case ALTER_DESATURATE:
+ pixbuf_desaturate_rect(pr->pixbuf,
+ 0, 0, pr->image_width, pr->image_height);
+ image_area_changed(imd, 0, 0, pr->image_width, pr->image_height);
+ break;
case ALTER_NONE:
default:
return;
image_zoom_set_fill_geometry(imd, TRUE);
break;
case 'R': case 'r':
- image_reload(imd);
+ if (!event->state & GDK_SHIFT_MASK)
+ {
+ image_reload(imd);
+ }
break;
case 'S': case 's':
if (vw->ss)
image_alter(imd, ALTER_FLIP);
stop_signal = TRUE;
break;
+ case 'G': case 'g':
+ image_alter(imd, ALTER_DESATURATE);
+ stop_signal = TRUE;
+ break;
default:
break;
}
stop_signal = TRUE;
break;
case 'R': case 'r':
- layout_refresh(lw);
+ if (!(event->state & GDK_SHIFT_MASK))
+ {
+ layout_refresh(lw);
+ }
break;
case 'S': case 's':
layout_image_slideshow_toggle(lw);
layout_image_alter(lw, ALTER_FLIP);
stop_signal = TRUE;
break;
+ case 'G': case 'g':
+ layout_image_alter(lw, ALTER_DESATURATE);
+ stop_signal = TRUE;
+ break;
default:
break;
}
layout_image_alter(lw, ALTER_FLIP);
}
+static void layout_menu_alter_desaturate_cb(GtkAction *action, gpointer data)
+{
+ LayoutWindow *lw = data;
+
+ layout_image_alter(lw, ALTER_DESATURATE);
+}
+
static void layout_menu_info_cb(GtkAction *action, gpointer data)
{
LayoutWindow *lw = data;
{ "Rotate180", NULL, N_("Rotate 1_80"), "<shift>R", NULL, CB(layout_menu_alter_180_cb) },
{ "Mirror", NULL, N_("_Mirror"), "<shift>M", NULL, CB(layout_menu_alter_mirror_cb) },
{ "Flip", NULL, N_("_Flip"), "<shift>F", NULL, CB(layout_menu_alter_flip_cb) },
+ { "Grayscale", NULL, N_("_Grayscale"), "<shift>G", NULL, CB(layout_menu_alter_desaturate_cb) },
{ "Properties",GTK_STOCK_PROPERTIES, N_("_Properties"), "<control>P", NULL, CB(layout_menu_info_cb) },
{ "SelectAll", NULL, N_("Select _all"), "<control>A", NULL, CB(layout_menu_select_all_cb) },
{ "SelectNone", NULL, N_("Select _none"), "<control><shift>A",NULL, CB(layout_menu_unselect_all_cb) },
" <menuitem action='Rotate180'/>"
" <menuitem action='Mirror'/>"
" <menuitem action='Flip'/>"
+" <menuitem action='Grayscale'/>"
" </menu>"
" <menuitem action='Properties'/>"
" <separator/>"
case ALTER_FLIP:
return _("_Flip");
break;
+ case ALTER_DESATURATE:
+ return _("_Grayscale");
+ break;
default:
break;
}
submenu_add_alter_item(submenu, func, ALTER_ROTATE_180, accel_group, 'R', GDK_SHIFT_MASK);
submenu_add_alter_item(submenu, func, ALTER_MIRROR, accel_group, 'M', GDK_SHIFT_MASK);
submenu_add_alter_item(submenu, func, ALTER_FLIP, accel_group, 'F', GDK_SHIFT_MASK);
+ submenu_add_alter_item(submenu, func, ALTER_DESATURATE, accel_group, 'G', GDK_SHIFT_MASK);
if (menu)
{
}
+/*
+ *-----------------------------------------------------------------------------
+ * pixbuf color alterations
+ *-----------------------------------------------------------------------------
+ */
+
+void pixbuf_desaturate_rect(GdkPixbuf *pb,
+ gint x, gint y, gint w, gint h)
+{
+ gint p_alpha;
+ gint pw, ph, prs;
+ guchar *p_pix;
+ guchar *pp;
+ gint i, j;
+
+ if (!pb) return;
+
+ pw = gdk_pixbuf_get_width(pb);
+ ph = gdk_pixbuf_get_height(pb);
+
+ if (x < 0 || x + w > pw) return;
+ if (y < 0 || y + h > ph) return;
+
+ p_alpha = gdk_pixbuf_get_has_alpha(pb);
+ prs = gdk_pixbuf_get_rowstride(pb);
+ p_pix = gdk_pixbuf_get_pixels(pb);
+
+ for (i = 0; i < h; i++)
+ {
+ pp = p_pix + (y + i) * prs + (x * (p_alpha ? 4 : 3));
+ for (j = 0; j < w; j++)
+ {
+ guint8 grey;
+
+ grey = (pp[0] + pp[1] + pp[2]) / 3;
+ *pp = grey;
+ pp++;
+ *pp = grey;
+ pp++;
+ *pp = grey;
+ pp++;
+ if (p_alpha) pp++;
+ }
+ }
+}
+
+
gint x, gint y, gint w, gint h, gint border,
guint8 r, guint8 g, guint8 b, guint8 a);
+void pixbuf_desaturate_rect(GdkPixbuf *pb,
+ gint x, gint y, gint w, gint h);
+
+
/* clipping utils */
gint util_clip_region(gint x, gint y, gint w, gint h,
ALTER_ROTATE_90_CC, /* counterclockwise */
ALTER_ROTATE_180,
ALTER_MIRROR,
- ALTER_FLIP
+ ALTER_FLIP,
+ ALTER_DESATURATE
} AlterType;
typedef enum {