ref: 15b1463567d2173d93838aeabac10d86a76c2c0c
parent: 40583e8b975a1d6170f8259e03bb7f5166d7de3e
author: phil9 <telephil9@gmail.com>
date: Tue Jan 19 00:24:07 EST 2021
implement image panning pressing and holding mouse 1 now allows for panning the image within the window. crop area selection is now triggered by a click on button 2 then a sweep of button 1.
--- a/vcrop.c
+++ b/vcrop.c
@@ -12,9 +12,10 @@
Image *bg;
Image *p;
Image *n;
+Point pos;
+enum { Mcrop, Mundo, Msave, Mexit };
char *menustr[] = { "crop", "undo", "save", "exit", 0 };
Menu menu = { menustr };
-enum { Mcrop, Mundo, Msave, Mexit };
void
eresized(int new)
@@ -26,6 +27,20 @@
}
void
+translate(Point d)
+{
+ Rectangle r, nr;
+
+ if(d.x==0 && d.y==0)
+ return;
+ r = rectaddpt(n->r, addpt(pos, screen->r.min));
+ pos = addpt(pos, d);
+ nr = rectaddpt(r, d);
+ draw(screen, screen->r, bg, nil, ZP);
+ draw(screen, nr, n, nil, n->r.min);
+}
+
+void
crop(Mouse *m)
{
Rectangle r;
@@ -42,6 +57,7 @@
freeimage(p);
p = n;
n = i;
+ pos = subpt(ZP, n->r.min);
eresized(0);
}
@@ -107,6 +123,8 @@
main(int argc, char *argv[])
{
Event ev;
+ Mouse m;
+ Point o;
int e, fd;
if(argc > 2)
@@ -126,14 +144,25 @@
sysfatal("readimage: %r");
close(fd);
p = nil;
+ pos = subpt(ZP, n->r.min);
eresized(0);
for(;;){
e = event(&ev);
switch(e){
case Emouse:
- if(ev.mouse.buttons==1)
+ if(ev.mouse.buttons==1){
+ m = ev.mouse;
+ for(;;) {
+ o = m.xy;
+ m = emouse();
+ if((m.buttons & 1) == 0)
+ break;
+ translate(subpt(m.xy, o));
+ }
+ }else if(ev.mouse.buttons==2){
+ ev.mouse.buttons = 1;
crop(&ev.mouse);
- else if(ev.mouse.buttons==4)
+ }else if(ev.mouse.buttons==4)
menu3hit(&ev.mouse);
break;
case Ekeyboard:
--- a/vcrop.man
+++ b/vcrop.man
@@ -14,7 +14,9 @@
.B standard input
and allows to crop it interactively.
.PP
-Button 1 initiate the selection of the area to preserve.
+Button 1 pans the image within the window
+.PP
+Button 2 triggers the cropping area selection. Area can then selected by sweeping Button 1.
.PP
Button 3 brings up a menu of actions.
.SH "SEE ALSO"