From c52c4fa69e2a6a58813fe35a5c4a1fe23661db03 Mon Sep 17 00:00:00 2001 From: Bert Date: Sat, 29 Jan 2011 22:37:40 +0100 Subject: Mouse-panning while pressing button2 --- Makefile | 2 +- image.c | 30 ++++++++++++++++++------------ image.h | 1 + main.c | 37 +++++++++++++++++++++++++++++++++++++ window.c | 33 ++++++++++++++++++++++++++++++--- window.h | 7 +++++++ 6 files changed, 94 insertions(+), 16 deletions(-) diff --git a/Makefile b/Makefile index e7b9c9c..97b23c1 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ all: sxiv -VERSION=0.3 +VERSION=git-20110129 CC?=gcc PREFIX?=/usr/local diff --git a/image.c b/image.c index d6488ef..4673c63 100644 --- a/image.c +++ b/image.c @@ -230,7 +230,7 @@ int img_zoom_out(img_t *img) { return 0; } -int img_pan(img_t *img, win_t *win, pandir_t dir) { +int img_move(img_t *img, win_t *win, int dx, int dy) { int ox, oy; if (!img || !win) @@ -239,24 +239,30 @@ int img_pan(img_t *img, win_t *win, pandir_t dir) { ox = img->x; oy = img->y; + img->x += dx; + img->y += dy; + + img_check_pan(img, win); + + return ox != img->x || oy != img->y; +} + +int img_pan(img_t *img, win_t *win, pandir_t dir) { + if (!img || !win) + return 0; + switch (dir) { case PAN_LEFT: - img->x += win->w / 5; - break; + return img_move(img, win, win->w / 5, 0); case PAN_RIGHT: - img->x -= win->w / 5; - break; + return img_move(img, win, -win->w / 5, 0); case PAN_UP: - img->y += win->h / 5; - break; + return img_move(img, win, 0, win->h / 5); case PAN_DOWN: - img->y -= win->h / 5; - break; + return img_move(img, win, 0, -win->h / 5); } - img_check_pan(img, win); - - return ox != img->x || oy != img->y; + return 0; } int img_rotate(img_t *img, win_t *win, int d) { diff --git a/image.h b/image.h index c3f9767..450a739 100644 --- a/image.h +++ b/image.h @@ -58,6 +58,7 @@ void img_center(img_t*, win_t*); int img_zoom_in(img_t*); int img_zoom_out(img_t*); +int img_move(img_t*, win_t*, int, int); int img_pan(img_t*, win_t*, pandir_t); int img_rotate_left(img_t*, win_t*); diff --git a/main.c b/main.c index aa21426..df4ef9e 100644 --- a/main.c +++ b/main.c @@ -31,6 +31,8 @@ void on_keypress(XEvent*); void on_buttonpress(XEvent*); +void on_buttonrelease(XEvent*); +void on_motionnotify(XEvent*); void on_configurenotify(XEvent*); void update_title(); @@ -38,6 +40,8 @@ void update_title(); static void (*handler[LASTEvent])(XEvent*) = { [KeyPress] = on_keypress, [ButtonPress] = on_buttonpress, + [ButtonRelease] = on_buttonrelease, + [MotionNotify] = on_motionnotify, [ConfigureNotify] = on_configurenotify }; @@ -49,6 +53,9 @@ int filecnt, fileidx; unsigned char timeout; +int mox; +int moy; + #define TITLE_LEN 256 char win_title[TITLE_LEN]; @@ -276,6 +283,11 @@ void on_buttonpress(XEvent *ev) { changed = 1; } break; + case Button2: + mox = ev->xbutton.x; + moy = ev->xbutton.y; + win_set_cursor(&win, CURSOR_HAND); + break; case Button3: if (fileidx > 0) { img_load(&img, filenames[--fileidx]); @@ -313,6 +325,31 @@ void on_buttonpress(XEvent *ev) { } } +void on_buttonrelease(XEvent *ev) { + if (!ev) + return; + + if (ev->xbutton.button == Button2) + win_set_cursor(&win, CURSOR_ARROW); +} + +void on_motionnotify(XEvent *ev) { + XMotionEvent *m; + + if (!ev) + return; + + m = &ev->xmotion; + + if (m->x >= 0 && m->x <= win.w && m->y >= 0 && m->y <= win.h) { + if (img_move(&img, &win, m->x - mox, m->y - moy)) + timeout = 1; + + mox = m->x; + moy = m->y; + } +} + void on_configurenotify(XEvent *ev) { if (!ev) return; diff --git a/window.c b/window.c index ea86ad3..d5f5f4f 100644 --- a/window.c +++ b/window.c @@ -21,12 +21,16 @@ #include #include +#include #include "sxiv.h" #include "options.h" #include "window.h" -GC bgc; +static Cursor arrow; +static Cursor hand; + +static GC bgc; void win_open(win_t *win) { win_env_t *e; @@ -66,8 +70,11 @@ void win_open(win_t *win) { if (win->xwin == None) DIE("could not create window"); - XSelectInput(e->dpy, win->xwin, - StructureNotifyMask | KeyPressMask | ButtonPressMask); + XSelectInput(e->dpy, win->xwin, StructureNotifyMask | KeyPressMask | + ButtonPressMask | ButtonReleaseMask | Button2MotionMask); + + arrow = XCreateFontCursor(e->dpy, XC_left_ptr); + hand = XCreateFontCursor(e->dpy, XC_fleur); bgc = XCreateGC(e->dpy, win->xwin, 0, None); @@ -91,6 +98,11 @@ void win_close(win_t *win) { if (!win) return; + XFreeCursor(win->env.dpy, arrow); + XFreeCursor(win->env.dpy, hand); + + XFreeGC(win->env.dpy, bgc); + XDestroyWindow(win->env.dpy, win->xwin); XCloseDisplay(win->env.dpy); } @@ -174,3 +186,18 @@ void win_draw(win_t *win) { XSetWindowBackgroundPixmap(win->env.dpy, win->xwin, win->pm); XClearWindow(win->env.dpy, win->xwin); } + +void win_set_cursor(win_t *win, win_cur_t cursor) { + if (!win) + return; + + switch (cursor) { + case CURSOR_HAND: + XDefineCursor(win->env.dpy, win->xwin, hand); + break; + case CURSOR_ARROW: + default: + XDefineCursor(win->env.dpy, win->xwin, arrow); + break; + } +} diff --git a/window.h b/window.h index 47de1a1..52fd759 100644 --- a/window.h +++ b/window.h @@ -23,6 +23,11 @@ #define CLEANMASK(mask) ((mask) & ~LockMask) +typedef enum win_cur_e { + CURSOR_ARROW = 0, + CURSOR_HAND +} win_cur_t; + typedef struct win_env_s { Display *dpy; int scr; @@ -59,4 +64,6 @@ void win_toggle_fullscreen(win_t*); void win_clear(win_t*); void win_draw(win_t*); +void win_set_cursor(win_t*, win_cur_t); + #endif /* WINDOW_H */ -- cgit v1.2.3-54-g00ecf