Krolyxon
Commit c52c4fa

Branches

Refs →

nsxivc52c4fa

Mouse-panning while pressing button2

Author
Bert
Date
2011-01-29 22:37 +0100
Parent
4ab4be3
Commit
c52c4fa69e2a6a58813fe35a5c4a1fe23661db03

+94 −16

6 files changed

  1. M Makefile +1 −1
  2. M image.c +18 −12
  3. M image.h +1 −0
  4. M main.c +37 −0
  5. M window.c +30 −3
  6. M window.h +7 −0
M Makefile View
@@ -1,6 +1,6 @@
11 all: sxiv
22
3−VERSION=0.3
3+VERSION=git-20110129
44
55 CC?=gcc
66 PREFIX?=/usr/local
M image.c View
@@ -230,7 +230,7 @@ int img_zoom_out(img_t *img) {
230230 return 0;
231231 }
232232
233−int img_pan(img_t *img, win_t *win, pandir_t dir) {
233+int img_move(img_t *img, win_t *win, int dx, int dy) {
234234 int ox, oy;
235235
236236 if (!img || !win)
@@ -239,24 +239,30 @@ int img_pan(img_t *img, win_t *win, pandir_t dir) {
239239 ox = img->x;
240240 oy = img->y;
241241
242+ img->x += dx;
243+ img->y += dy;
244+
245+ img_check_pan(img, win);
246+
247+ return ox != img->x || oy != img->y;
248+}
249+
250+int img_pan(img_t *img, win_t *win, pandir_t dir) {
251+ if (!img || !win)
252+ return 0;
253+
242254 switch (dir) {
243255 case PAN_LEFT:
244− img->x += win->w / 5;
245− break;
256+ return img_move(img, win, win->w / 5, 0);
246257 case PAN_RIGHT:
247− img->x -= win->w / 5;
248− break;
258+ return img_move(img, win, -win->w / 5, 0);
249259 case PAN_UP:
250− img->y += win->h / 5;
251− break;
260+ return img_move(img, win, 0, win->h / 5);
252261 case PAN_DOWN:
253− img->y -= win->h / 5;
254− break;
262+ return img_move(img, win, 0, -win->h / 5);
255263 }
256264
257− img_check_pan(img, win);
258−
259− return ox != img->x || oy != img->y;
265+ return 0;
260266 }
261267
262268 int img_rotate(img_t *img, win_t *win, int d) {
M image.h View
@@ -58,6 +58,7 @@ void img_center(img_t*, win_t*);
5858 int img_zoom_in(img_t*);
5959 int img_zoom_out(img_t*);
6060
61+int img_move(img_t*, win_t*, int, int);
6162 int img_pan(img_t*, win_t*, pandir_t);
6263
6364 int img_rotate_left(img_t*, win_t*);
M main.c View
@@ -31,6 +31,8 @@
3131
3232 void on_keypress(XEvent*);
3333 void on_buttonpress(XEvent*);
34+void on_buttonrelease(XEvent*);
35+void on_motionnotify(XEvent*);
3436 void on_configurenotify(XEvent*);
3537
3638 void update_title();
@@ -38,6 +40,8 @@ void update_title();
3840 static void (*handler[LASTEvent])(XEvent*) = {
3941 [KeyPress] = on_keypress,
4042 [ButtonPress] = on_buttonpress,
43+ [ButtonRelease] = on_buttonrelease,
44+ [MotionNotify] = on_motionnotify,
4145 [ConfigureNotify] = on_configurenotify
4246 };
4347
@@ -49,6 +53,9 @@ int filecnt, fileidx;
4953
5054 unsigned char timeout;
5155
56+int mox;
57+int moy;
58+
5259 #define TITLE_LEN 256
5360 char win_title[TITLE_LEN];
5461
@@ -276,6 +283,11 @@ void on_buttonpress(XEvent *ev) {
276283 changed = 1;
277284 }
278285 break;
286+ case Button2:
287+ mox = ev->xbutton.x;
288+ moy = ev->xbutton.y;
289+ win_set_cursor(&win, CURSOR_HAND);
290+ break;
279291 case Button3:
280292 if (fileidx > 0) {
281293 img_load(&img, filenames[--fileidx]);
@@ -313,6 +325,31 @@ void on_buttonpress(XEvent *ev) {
313325 }
314326 }
315327
328+void on_buttonrelease(XEvent *ev) {
329+ if (!ev)
330+ return;
331+
332+ if (ev->xbutton.button == Button2)
333+ win_set_cursor(&win, CURSOR_ARROW);
334+}
335+
336+void on_motionnotify(XEvent *ev) {
337+ XMotionEvent *m;
338+
339+ if (!ev)
340+ return;
341+
342+ m = &ev->xmotion;
343+
344+ if (m->x >= 0 && m->x <= win.w && m->y >= 0 && m->y <= win.h) {
345+ if (img_move(&img, &win, m->x - mox, m->y - moy))
346+ timeout = 1;
347+
348+ mox = m->x;
349+ moy = m->y;
350+ }
351+}
352+
316353 void on_configurenotify(XEvent *ev) {
317354 if (!ev)
318355 return;
M window.c View
@@ -21,12 +21,16 @@
2121 #include <string.h>
2222
2323 #include <X11/Xutil.h>
24+#include <X11/cursorfont.h>
2425
2526 #include "sxiv.h"
2627 #include "options.h"
2728 #include "window.h"
2829
29−GC bgc;
30+static Cursor arrow;
31+static Cursor hand;
32+
33+static GC bgc;
3034
3135 void win_open(win_t *win) {
3236 win_env_t *e;
@@ -66,8 +70,11 @@ void win_open(win_t *win) {
6670 if (win->xwin == None)
6771 DIE("could not create window");
6872
69− XSelectInput(e->dpy, win->xwin,
70− StructureNotifyMask | KeyPressMask | ButtonPressMask);
73+ XSelectInput(e->dpy, win->xwin, StructureNotifyMask | KeyPressMask |
74+ ButtonPressMask | ButtonReleaseMask | Button2MotionMask);
75+
76+ arrow = XCreateFontCursor(e->dpy, XC_left_ptr);
77+ hand = XCreateFontCursor(e->dpy, XC_fleur);
7178
7279 bgc = XCreateGC(e->dpy, win->xwin, 0, None);
7380
@@ -91,6 +98,11 @@ void win_close(win_t *win) {
9198 if (!win)
9299 return;
93100
101+ XFreeCursor(win->env.dpy, arrow);
102+ XFreeCursor(win->env.dpy, hand);
103+
104+ XFreeGC(win->env.dpy, bgc);
105+
94106 XDestroyWindow(win->env.dpy, win->xwin);
95107 XCloseDisplay(win->env.dpy);
96108 }
@@ -174,3 +186,18 @@ void win_draw(win_t *win) {
174186 XSetWindowBackgroundPixmap(win->env.dpy, win->xwin, win->pm);
175187 XClearWindow(win->env.dpy, win->xwin);
176188 }
189+
190+void win_set_cursor(win_t *win, win_cur_t cursor) {
191+ if (!win)
192+ return;
193+
194+ switch (cursor) {
195+ case CURSOR_HAND:
196+ XDefineCursor(win->env.dpy, win->xwin, hand);
197+ break;
198+ case CURSOR_ARROW:
199+ default:
200+ XDefineCursor(win->env.dpy, win->xwin, arrow);
201+ break;
202+ }
203+}
M window.h View
@@ -23,6 +23,11 @@
2323
2424 #define CLEANMASK(mask) ((mask) & ~LockMask)
2525
26+typedef enum win_cur_e {
27+ CURSOR_ARROW = 0,
28+ CURSOR_HAND
29+} win_cur_t;
30+
2631 typedef struct win_env_s {
2732 Display *dpy;
2833 int scr;
@@ -59,4 +64,6 @@ void win_toggle_fullscreen(win_t*);
5964 void win_clear(win_t*);
6065 void win_draw(win_t*);
6166
67+void win_set_cursor(win_t*, win_cur_t);
68+
6269 #endif /* WINDOW_H */