From 0cd8c9c0278d22b530dbbef0fe9b3c8c4b899688 Mon Sep 17 00:00:00 2001 From: John Ellis Date: Thu, 19 Oct 2006 19:27:20 +0000 Subject: [PATCH] Thu Oct 19 15:20:51 2006 John Ellis * 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. --- ChangeLog | 9 +++++++++ TODO | 7 +++++++ src/image.c | 5 +++++ src/img-view.c | 9 ++++++++- src/layout_image.c | 9 ++++++++- src/layout_util.c | 9 +++++++++ src/menu.c | 4 ++++ src/pixbuf_util.c | 47 ++++++++++++++++++++++++++++++++++++++++++++++ src/pixbuf_util.h | 4 ++++ src/typedefs.h | 3 ++- 10 files changed, 103 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index a82800e9..498d63c7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +Thu Oct 19 15:20:51 2006 John Ellis + + * 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 * layout.[ch] (layout_new_with_geometry): New function to create a diff --git a/TODO b/TODO index 458332da..47857b51 100644 --- a/TODO +++ b/TODO @@ -90,6 +90,7 @@ Major: > 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 @@ -107,6 +108,12 @@ d> allow multiple command line dirs to work as expected > 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 diff --git a/src/image.c b/src/image.c index d6a0a7e2..8fcea281 100644 --- a/src/image.c +++ b/src/image.c @@ -206,6 +206,11 @@ static void image_alter_real(ImageWindow *imd, AlterType type, gint clamp) 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; diff --git a/src/img-view.c b/src/img-view.c index 65e9e165..79cf4c1d 100644 --- a/src/img-view.c +++ b/src/img-view.c @@ -413,7 +413,10 @@ static gint view_window_key_press_cb(GtkWidget *widget, GdkEventKey *event, gpoi 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) @@ -552,6 +555,10 @@ static gint view_window_key_press_cb(GtkWidget *widget, GdkEventKey *event, gpoi image_alter(imd, ALTER_FLIP); stop_signal = TRUE; break; + case 'G': case 'g': + image_alter(imd, ALTER_DESATURATE); + stop_signal = TRUE; + break; default: break; } diff --git a/src/layout_image.c b/src/layout_image.c index c7c5056f..d2d20fcb 100644 --- a/src/layout_image.c +++ b/src/layout_image.c @@ -203,7 +203,10 @@ static gint layout_image_full_screen_key_press_cb(GtkWidget *widget, GdkEventKey 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); @@ -305,6 +308,10 @@ static gint layout_image_full_screen_key_press_cb(GtkWidget *widget, GdkEventKey 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; } diff --git a/src/layout_util.c b/src/layout_util.c index b76e44b8..68663da1 100644 --- a/src/layout_util.c +++ b/src/layout_util.c @@ -383,6 +383,13 @@ static void layout_menu_alter_flip_cb(GtkAction *action, gpointer data) 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; @@ -776,6 +783,7 @@ static GtkActionEntry menu_entries[] = { { "Rotate180", NULL, N_("Rotate 1_80"), "R", NULL, CB(layout_menu_alter_180_cb) }, { "Mirror", NULL, N_("_Mirror"), "M", NULL, CB(layout_menu_alter_mirror_cb) }, { "Flip", NULL, N_("_Flip"), "F", NULL, CB(layout_menu_alter_flip_cb) }, + { "Grayscale", NULL, N_("_Grayscale"), "G", NULL, CB(layout_menu_alter_desaturate_cb) }, { "Properties",GTK_STOCK_PROPERTIES, N_("_Properties"), "P", NULL, CB(layout_menu_info_cb) }, { "SelectAll", NULL, N_("Select _all"), "A", NULL, CB(layout_menu_select_all_cb) }, { "SelectNone", NULL, N_("Select _none"), "A",NULL, CB(layout_menu_unselect_all_cb) }, @@ -857,6 +865,7 @@ static const char *menu_ui_description = " " " " " " +" " " " " " " " diff --git a/src/menu.c b/src/menu.c index c355f68b..1803ba24 100644 --- a/src/menu.c +++ b/src/menu.c @@ -205,6 +205,9 @@ gchar *alter_type_get_text(AlterType type) case ALTER_FLIP: return _("_Flip"); break; + case ALTER_DESATURATE: + return _("_Grayscale"); + break; default: break; } @@ -240,6 +243,7 @@ static GtkWidget *real_submenu_add_alter(GtkWidget *menu, GCallback func, gpoint 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) { diff --git a/src/pixbuf_util.c b/src/pixbuf_util.c index 047112fc..9634245c 100644 --- a/src/pixbuf_util.c +++ b/src/pixbuf_util.c @@ -1177,3 +1177,50 @@ void pixbuf_draw_shadow(GdkPixbuf *pb, } +/* + *----------------------------------------------------------------------------- + * 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++; + } + } +} + + diff --git a/src/pixbuf_util.h b/src/pixbuf_util.h index fa052e39..0384ce83 100644 --- a/src/pixbuf_util.h +++ b/src/pixbuf_util.h @@ -77,6 +77,10 @@ void pixbuf_draw_shadow(GdkPixbuf *pb, 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, diff --git a/src/typedefs.h b/src/typedefs.h index 21baf985..d68a25a2 100644 --- a/src/typedefs.h +++ b/src/typedefs.h @@ -29,7 +29,8 @@ typedef enum { ALTER_ROTATE_90_CC, /* counterclockwise */ ALTER_ROTATE_180, ALTER_MIRROR, - ALTER_FLIP + ALTER_FLIP, + ALTER_DESATURATE } AlterType; typedef enum { -- 2.20.1