commit ab4ae60ad89cba4cca0d2f9b802628358fefaf0a
parent b89bcf2956326f4ff6f11e2f105f8301b8adc3ba
Author: lumidify <nobody@lumidify.org>
Date: Tue, 21 Sep 2021 14:47:41 +0200
Don't allow coordinates below 0; allow rectangle to be kept when going backwards
Diffstat:
6 files changed, 42 insertions(+), 18 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
@@ -2,6 +2,7 @@
* Rewrite using Xlib and Imlib2
* Add command-line options and man pages
* Add automatic resizing of image when resizing window
+* Allow the rectangle to be kept when going backwards (Shift + Return)
* Add croptool_crop
1.0 -> 1.1
diff --git a/LICENSE b/LICENSE
@@ -1,6 +1,6 @@
Copyright (c) 2021 lumidify <nobody@lumidify.org>
-Permission to use, copy, modify, and distribute this software for any
+Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
diff --git a/TODO b/TODO
@@ -1,3 +1,5 @@
* Proper path handling (allow paths including "'", etc.)
* Draw pixmap on exposure events instead of doing the
expensive image resizing each time
+* Maybe add zooming support
+* Maybe optionally show rectangle coordinates on screen
diff --git a/croptool.1 b/croptool.1
@@ -1,4 +1,4 @@
-.Dd April 1, 2021
+.Dd September 21, 2021
.Dt CROPTOOL 1
.Os
.Sh NAME
@@ -94,6 +94,9 @@ that is printed for the cropping command.
In other words, when switching to an image that is a different size and
thus scaled differently, the displayed rectangle will stay the same even
though the pixels covered in the original image are different.
+.It SHIFT + RETURN
+Go to the last image, copying the current cropping rectangle.
+The same caveat as above applies.
.It TAB
Switch the color of the cropping rectangle between the primary and secondary colors.
.It DELETE
diff --git a/croptool.c b/croptool.c
@@ -1,7 +1,7 @@
/*
* Copyright (c) 2021 lumidify <nobody@lumidify.org>
*
- * Permission to use, copy, modify, and distribute this software for any
+ * Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
@@ -144,8 +144,8 @@ static int collide_line(int x, int y, int x0, int y0, int x1, int y1);
static int collide_rect(int x, int y, struct Rect rect);
static void switch_color(void);
static void clear_selection(void);
-static void last_picture(void);
static void next_picture(int copy_box);
+static void last_picture(int copy_box);
static void change_picture(Imlib_Image new_image, int new_selection, int copy_box);
static void get_scaled_size(int orig_w, int orig_h, int *scaled_w, int *scaled_h);
static void set_selection(
@@ -860,9 +860,19 @@ static void
drag_motion(XEvent event) {
if (state.cur_selection < 0 || !state.selections[state.cur_selection].valid)
return;
- struct Rect *rect = &state.selections[state.cur_selection].rect;
- state.cursor_x = event.xbutton.x;
- state.cursor_y = event.xbutton.y;
+ struct Selection *sel = &state.selections[state.cur_selection];
+ struct Rect *rect = &sel->rect;
+
+ /* don't allow coordinates to go below 0 */
+ if (event.xbutton.x >= 0)
+ state.cursor_x = event.xbutton.x;
+ else
+ state.cursor_x = 0;
+ if (event.xbutton.y >= 0)
+ state.cursor_y = event.xbutton.y;
+ else
+ state.cursor_y = 0;
+
int x0 = rect->x0, x1 = rect->x1;
int y0 = rect->y0, y1 = rect->y1;
sort_coordinates(&x0, &y0, &x1, &y1);
@@ -872,10 +882,13 @@ drag_motion(XEvent event) {
if (state.moving) {
int x_delta = state.cursor_x - state.move_handle.x;
int y_delta = state.cursor_y - state.move_handle.y;
- rect->x0 += x_delta;
- rect->y0 += y_delta;
- rect->x1 += x_delta;
- rect->y1 += y_delta;
+ /* don't allow coordinates to go below 0 */
+ int x_realdelta = x0 + x_delta >= 0 ? x_delta : -x0;
+ int y_realdelta = y0 + y_delta >= 0 ? y_delta : -y0;
+ rect->x0 += x_realdelta;
+ rect->x1 += x_realdelta;
+ rect->y0 += y_realdelta;
+ rect->y1 += y_realdelta;
state.move_handle.x = state.cursor_x;
state.move_handle.y = state.cursor_y;
} else if (state.resizing) {
@@ -1011,6 +1024,7 @@ next_picture(int copy_box) {
state.filenames[tmp_cur_selection] = NULL;
}
}
+ /* immediately exit program if no loadable image is found on startup */
if (state.cur_selection < 0 && !tmp_image) {
fprintf(stderr, "No loadable images found.\n");
cleanup();
@@ -1022,9 +1036,10 @@ next_picture(int copy_box) {
change_picture(tmp_image, tmp_cur_selection, copy_box);
}
-/* show the previous image in the argument list - unloadable files are skipped */
+/* show the previous image in the argument list - unloadable files are skipped
+ * copy_box determines whether the current selection is copied */
static void
-last_picture(void) {
+last_picture(int copy_box) {
if (state.cur_selection <= 0)
return;
Imlib_Image tmp_image = NULL;
@@ -1047,7 +1062,7 @@ last_picture(void) {
if (!tmp_image)
return;
- change_picture(tmp_image, tmp_cur_selection, 0);
+ change_picture(tmp_image, tmp_cur_selection, copy_box);
}
static void
@@ -1075,13 +1090,16 @@ key_press(XEvent event) {
XLookupString(&event.xkey, buf, sizeof(buf), &sym, NULL);
switch (sym) {
case XK_Left:
- last_picture();
+ last_picture(0);
break;
case XK_Right:
next_picture(0);
break;
case XK_Return:
- next_picture(1);
+ if (event.xkey.state & ShiftMask)
+ last_picture(1);
+ else
+ next_picture(1);
break;
case XK_Delete:
clear_selection();
@@ -1092,7 +1110,7 @@ key_press(XEvent event) {
case XK_space:
XGetWindowAttributes(state.dpy, state.win, &attrs);
resize_window(attrs.width, attrs.height);
- /* queue update separately to it also redraws when
+ /* queue update separately so it also redraws when
size didn't change */
queue_update(0, 0, state.window_w, state.window_h);
break;
diff --git a/croptool_crop.c b/croptool_crop.c
@@ -1,7 +1,7 @@
/*
* Copyright (c) 2021 lumidify <nobody@lumidify.org>
*
- * Permission to use, copy, modify, and distribute this software for any
+ * Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*