# HG changeset patch # User Colin Clark # Date 1532105110 -3600 # Node ID 3e9ca298bb1d7baae00138d90acf1097722a7372 # Parent 0ecd4885dc09c040e3cd0f462c51b574757c227f Fix #251: Crop simulation Menu option to draw a rectangle. Rectangle co-ordinates can be obtained with the remote command: --remote --get-rectangle diff -r 0ecd4885dc09 -r 3e9ca298bb1d src/icons/Makefile.am --- a/src/icons/Makefile.am Thu Jul 19 10:56:46 2018 +0100 +++ b/src/icons/Makefile.am Fri Jul 20 17:45:10 2018 +0100 @@ -32,7 +32,8 @@ icon_marks.png \ icon_info.png \ icon_sort.png \ - icon_pdf.png + icon_pdf.png \ + icon_draw_rectangle.png ICONS_INLINE_PAIRS = \ folder_closed $(srcdir)/folder_closed.png \ @@ -63,7 +64,8 @@ icon_marks $(srcdir)/icon_marks.png \ icon_info $(srcdir)/icon_info.png \ icon_sort $(srcdir)/icon_sort.png \ - icon_pdf $(srcdir)/icon_pdf.png + icon_pdf $(srcdir)/icon_pdf.png \ + icon_draw_rectangle $(srcdir)/icon_draw_rectangle.png icons_inline.h: $(ICONS_INLINE) Makefile.in @sh -ec "echo '/* Auto generated file, do not edit */'; echo; \ diff -r 0ecd4885dc09 -r 3e9ca298bb1d src/icons/icon_draw_rectangle.png Binary file src/icons/icon_draw_rectangle.png has changed diff -r 0ecd4885dc09 -r 3e9ca298bb1d src/image.c --- a/src/image.c Thu Jul 19 10:56:46 2018 +0100 +++ b/src/image.c Fri Jul 20 17:45:10 2018 +0100 @@ -48,6 +48,14 @@ static void image_read_ahead_start(ImageWindow *imd); static void image_cache_set(ImageWindow *imd, FileData *fd); +// For draw rectangle function +static gint pixbuf_start_x; +static gint pixbuf_start_y; +static gint image_start_x; +static gint image_start_y; +static gint rect_x1, rect_x2, rect_y1, rect_y2; +static gint rect_id = 0; + /* *------------------------------------------------------------------- * 'signals' @@ -68,10 +76,92 @@ } } +static void switch_coords_orientation(ImageWindow *imd, gint x, gint y, gint width, gint height) +{ + switch (imd->orientation) + { + case EXIF_ORIENTATION_TOP_LEFT: + /* normal -- nothing to do */ + rect_x1 = image_start_x; + rect_y1 = image_start_y; + rect_x2 = x; + rect_y2 = y; + break; + case EXIF_ORIENTATION_TOP_RIGHT: + /* mirrored */ + rect_x1 = width - x; + rect_y1 = image_start_y; + rect_x2 = width - image_start_x; + rect_y2 = y; + break; + case EXIF_ORIENTATION_BOTTOM_RIGHT: + /* upside down */ + rect_x1 = width - x; + rect_y1 = height - y; + rect_x2 = width - image_start_x; + rect_y2 = height - image_start_y; + break; + case EXIF_ORIENTATION_BOTTOM_LEFT: + /* flipped */ + rect_x1 = image_start_x; + rect_y1 = height - y; + rect_x2 = x; + rect_y2 = height - image_start_y; + break; + case EXIF_ORIENTATION_LEFT_TOP: + /* left mirrored */ + rect_x1 = image_start_y; + rect_y1 = image_start_x; + rect_x2 = y; + rect_y2 = x; + break; + case EXIF_ORIENTATION_RIGHT_TOP: + /* rotated -90 (270) */ + rect_x1 = image_start_y; + rect_y1 = width - x; + rect_x2 = y; + rect_y2 = width - image_start_x; + break; + case EXIF_ORIENTATION_RIGHT_BOTTOM: + /* right mirrored */ + rect_x1 = height - y; + rect_y1 = width - x; + rect_x2 = height - image_start_y; + rect_y2 = width - image_start_x; + break; + case EXIF_ORIENTATION_LEFT_BOTTOM: + /* rotated 90 */ + rect_x1 = height - y; + rect_y1 = image_start_x; + rect_x2 = height - image_start_y; + rect_y2 = x; + break; + default: + /* The other values are out of range */ + break; + } +} + static void image_press_cb(PixbufRenderer *pr, GdkEventButton *event, gpointer data) { ImageWindow *imd = data; LayoutWindow *lw; + gint x_pixel, y_pixel; + + if(options->draw_rectangle) + { + pixbuf_renderer_get_mouse_position(pr, &x_pixel, &y_pixel); + + pixbuf_start_x = event->x; + pixbuf_start_y = event->y; + image_start_x = x_pixel; + image_start_y = y_pixel; + } + + if (rect_id) + { + pixbuf_renderer_overlay_remove((PixbufRenderer *)imd->pr, rect_id); + } lw = layout_find_by_image(imd); if (lw && event->button == MOUSE_BUTTON_LEFT && event->type == GDK_2BUTTON_PRESS @@ -86,6 +176,40 @@ { ImageWindow *imd = data; gint width, height; + gint rect_width; + gint rect_height; + GdkPixbuf *rect_pixbuf; + gint x_pixel, y_pixel; + + if (options->draw_rectangle) + { + pixbuf_renderer_get_image_size(pr, &width, &height); + pixbuf_renderer_get_mouse_position(pr, &x_pixel, &y_pixel); + switch_coords_orientation(imd, x_pixel, y_pixel, width, height); + + if (rect_id) + { + pixbuf_renderer_overlay_remove((PixbufRenderer *)imd->pr, rect_id); + } + + rect_width = pr->drag_last_x - pixbuf_start_x; + if (rect_width <= 0) + { + rect_width = 1; + } + rect_height = pr->drag_last_y - pixbuf_start_y; + if (rect_height <= 0) + { + rect_height = 1; + } + + rect_pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8, rect_width, rect_height); + pixbuf_set_rect_fill(rect_pixbuf, 0, 0, rect_width, rect_height, 255, 255, 255, 0); + pixbuf_set_rect(rect_pixbuf, 1, 1, rect_width-2, rect_height - 2, 0, 0, 0, 255, 1, 1, 1, 1); + pixbuf_set_rect(rect_pixbuf, 2, 2, rect_width-4, rect_height - 4, 255, 255, 255, 255, 1, 1, 1, 1); + + rect_id = pixbuf_renderer_overlay_add((PixbufRenderer *)imd->pr, rect_pixbuf, pixbuf_start_x, pixbuf_start_y, OVL_NORMAL); + } pixbuf_renderer_get_scaled_size(pr, &width, &height); @@ -2024,4 +2148,13 @@ return imd; } + +void image_get_rectangle(gint *x1, gint *y1, gint *x2, gint *y2) +{ + *x1 = rect_x1; + *y1 = rect_y1; + *x2 = rect_x2; + *y2 = rect_y2; +} + /* vim: set shiftwidth=8 softtabstop=0 cindent cinoptions={1s: */ diff -r 0ecd4885dc09 -r 3e9ca298bb1d src/image.h --- a/src/image.h Thu Jul 19 10:56:46 2018 +0100 +++ b/src/image.h Fri Jul 20 17:45:10 2018 +0100 @@ -150,6 +150,7 @@ /* reset default options */ void image_options_sync(void); +void image_get_rectangle(gint *x1, gint *y1, gint *x2, gint *y2); #endif /* vim: set shiftwidth=8 softtabstop=0 cindent cinoptions={1s: */ diff -r 0ecd4885dc09 -r 3e9ca298bb1d src/layout_util.c --- a/src/layout_util.c Thu Jul 19 10:56:46 2018 +0100 +++ b/src/layout_util.c Fri Jul 20 17:45:10 2018 +0100 @@ -508,6 +508,13 @@ layout_image_reset_orientation(lw); } +static void layout_menu_select_rectangle_cb(GtkToggleAction *action, gpointer data) +{ + LayoutWindow *lw = data; + + options->draw_rectangle = gtk_toggle_action_get_active(action); +} + static void layout_menu_write_rotate(GtkToggleAction *action, gpointer data, gboolean keep_date) { LayoutWindow *lw = data; @@ -1949,6 +1956,7 @@ { "RectangularSelection", NULL, N_("Rectangular Selection"), "R", N_("Rectangular Selection"), CB(layout_menu_rectangular_selection_cb), FALSE }, { "Animate", NULL, N_("GIF _animation"), "A", N_("Toggle GIF animation"), CB(layout_menu_animate_cb), FALSE }, { "ExifRotate", GTK_STOCK_ORIENTATION_PORTRAIT, N_("_Exif rotate"), "X", N_("Exif rotate"), CB(layout_menu_exif_rotate_cb), FALSE }, + { "DrawRectangle", PIXBUF_INLINE_ICON_DRAW_RECTANGLE, N_("Draw Rectangle"), NULL, N_("Draw Rectangle"), CB(layout_menu_select_rectangle_cb), FALSE }, }; static GtkRadioActionEntry menu_radio_entries[] = { @@ -2086,6 +2094,8 @@ " " " " " " +" " +" " " " " " " " @@ -3044,6 +3054,9 @@ action = gtk_action_group_get_action(lw->action_group, "ExifRotate"); gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(action), options->image.exif_rotate_enable); + action = gtk_action_group_get_action(lw->action_group, "DrawRectangle"); + gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(action), options->draw_rectangle); + action = gtk_action_group_get_action(lw->action_group, "RectangularSelection"); gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(action), options->collections.rectangular_selection); diff -r 0ecd4885dc09 -r 3e9ca298bb1d src/options.h --- a/src/options.h Thu Jul 19 10:56:46 2018 +0100 +++ b/src/options.h Fri Jul 20 17:45:10 2018 +0100 @@ -36,6 +36,7 @@ gboolean show_icon_names; gboolean show_star_rating; gboolean show_guidelines; + gboolean draw_rectangle; /* various */ gboolean tree_descend_subdirs; diff -r 0ecd4885dc09 -r 3e9ca298bb1d src/pixbuf-renderer.c --- a/src/pixbuf-renderer.c Thu Jul 19 10:56:46 2018 +0100 +++ b/src/pixbuf-renderer.c Fri Jul 20 17:45:10 2018 +0100 @@ -2047,10 +2047,12 @@ accel = 1; } - /* do the scroll */ - pixbuf_renderer_scroll(pr, (pr->drag_last_x - event->x) * accel, - (pr->drag_last_y - event->y) * accel); - + /* do the scroll - not when drawing rectangle*/ + if (!options->draw_rectangle) + { + pixbuf_renderer_scroll(pr, (pr->drag_last_x - event->x) * accel, + (pr->drag_last_y - event->y) * accel); + } pr_drag_signal(pr, event); pr->drag_last_x = event->x; diff -r 0ecd4885dc09 -r 3e9ca298bb1d src/pixbuf_util.c --- a/src/pixbuf_util.c Thu Jul 19 10:56:46 2018 +0100 +++ b/src/pixbuf_util.c Fri Jul 20 17:45:10 2018 +0100 @@ -131,6 +131,7 @@ { PIXBUF_INLINE_ICON_INFO, icon_info }, { PIXBUF_INLINE_ICON_SORT, icon_sort }, { PIXBUF_INLINE_ICON_PDF, icon_pdf }, + { PIXBUF_INLINE_ICON_DRAW_RECTANGLE, icon_draw_rectangle }, { NULL, NULL } }; diff -r 0ecd4885dc09 -r 3e9ca298bb1d src/pixbuf_util.h --- a/src/pixbuf_util.h Thu Jul 19 10:56:46 2018 +0100 +++ b/src/pixbuf_util.h Fri Jul 20 17:45:10 2018 +0100 @@ -65,6 +65,7 @@ #define PIXBUF_INLINE_ICON_INFO "icon_info" #define PIXBUF_INLINE_ICON_SORT "icon_sort" #define PIXBUF_INLINE_ICON_PDF "icon_pdf" +#define PIXBUF_INLINE_ICON_DRAW_RECTANGLE "icon_draw_rectangle" GdkPixbuf *pixbuf_copy_rotate_90(GdkPixbuf *src, gboolean counter_clockwise); GdkPixbuf *pixbuf_copy_mirror(GdkPixbuf *src, gboolean mirror, gboolean flip); diff -r 0ecd4885dc09 -r 3e9ca298bb1d src/remote.c --- a/src/remote.c Thu Jul 19 10:56:46 2018 +0100 +++ b/src/remote.c Fri Jul 20 17:45:10 2018 +0100 @@ -690,6 +690,33 @@ } } +static void gr_rectangle(const gchar *text, GIOChannel *channel, gpointer data) +{ + gchar *rectangle_info; + PixbufRenderer *pr; + LayoutWindow *lw = NULL; + gint x1, y1, x2, y2; + + if (!layout_valid(&lw_id)) return; + + pr = (PixbufRenderer*)lw_id->image->pr; + + if (pr) + { + image_get_rectangle(&x1, &y1, &x2, &y2); + rectangle_info = g_strdup_printf(_("%dx%d+%d+%d"), + (x2 > x1) ? x2 - x1 : x1 - x2, + (y2 > y1) ? y2 - y1 : y1 - y2, + (x2 > x1) ? x1 : x2, + (y2 > y1) ? y1 : y2); + + g_io_channel_write_chars(channel, rectangle_info, -1, NULL, NULL); + g_io_channel_write_chars(channel, "\n", -1, NULL, NULL); + + g_free(rectangle_info); + } +} + static void gr_file_tell(const gchar *text, GIOChannel *channel, gpointer data) { if (!layout_valid(&lw_id)) return; @@ -881,6 +908,7 @@ { NULL, "File:", gr_file_load_no_raise, TRUE, FALSE, N_(""), N_("open FILE, do not bring Geeqie window to the top") }, { NULL, "--tell", gr_file_tell, FALSE, FALSE, NULL, N_("print filename of current image") }, { NULL, "--pixel-info", gr_pixel_info, FALSE, FALSE, NULL, N_("print pixel info of mouse pointer on current image") }, + { NULL, "--get-rectangle", gr_rectangle, FALSE, FALSE, NULL, N_("get rectangle co-ordinates") }, { NULL, "view:", gr_file_view, TRUE, FALSE, N_(""), N_("open FILE in new window") }, { NULL, "--list-clear", gr_list_clear, FALSE, FALSE, NULL, N_("clear command line collection list") }, { NULL, "--list-add:", gr_list_add, TRUE, FALSE, N_(""), N_("add FILE to command line collection list") }, diff -r 0ecd4885dc09 -r 3e9ca298bb1d src/toolbar.c --- a/src/toolbar.c Thu Jul 19 10:56:46 2018 +0100 +++ b/src/toolbar.c Fri Jul 20 17:45:10 2018 +0100 @@ -112,6 +112,7 @@ {"Thumbnails", N_("Show thumbnails"), PIXBUF_INLINE_ICON_THUMB}, {"ShowMarks", N_("Show marks"), PIXBUF_INLINE_ICON_MARKS}, {"ImageGuidelines", N_("Show guidelines"), PIXBUF_INLINE_ICON_GUIDELINES}, + {"DrawRectangle", N_("Draw Rectangle"), PIXBUF_INLINE_ICON_DRAW_RECTANGLE}, {"FloatTools", N_("Float file list"), PIXBUF_INLINE_ICON_FLOAT}, {"SBar", N_("Info sidebar"), PIXBUF_INLINE_ICON_INFO}, {"SBarSort", N_("Sort manager"), PIXBUF_INLINE_ICON_SORT},