Mouse-panning while pressing button2

This commit is contained in:
Bert 2011-01-29 22:37:40 +01:00
parent 4ab4be31a7
commit c52c4fa69e
6 changed files with 97 additions and 19 deletions

View file

@ -1,6 +1,6 @@
all: sxiv all: sxiv
VERSION=0.3 VERSION=git-20110129
CC?=gcc CC?=gcc
PREFIX?=/usr/local PREFIX?=/usr/local

36
image.c
View file

@ -230,7 +230,7 @@ int img_zoom_out(img_t *img) {
return 0; 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; int ox, oy;
if (!img || !win) if (!img || !win)
@ -239,26 +239,32 @@ int img_pan(img_t *img, win_t *win, pandir_t dir) {
ox = img->x; ox = img->x;
oy = img->y; oy = img->y;
switch (dir) { img->x += dx;
case PAN_LEFT: img->y += dy;
img->x += win->w / 5;
break;
case PAN_RIGHT:
img->x -= win->w / 5;
break;
case PAN_UP:
img->y += win->h / 5;
break;
case PAN_DOWN:
img->y -= win->h / 5;
break;
}
img_check_pan(img, win); img_check_pan(img, win);
return ox != img->x || oy != img->y; 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:
return img_move(img, win, win->w / 5, 0);
case PAN_RIGHT:
return img_move(img, win, -win->w / 5, 0);
case PAN_UP:
return img_move(img, win, 0, win->h / 5);
case PAN_DOWN:
return img_move(img, win, 0, -win->h / 5);
}
return 0;
}
int img_rotate(img_t *img, win_t *win, int d) { int img_rotate(img_t *img, win_t *win, int d) {
int ox, oy, tmp; int ox, oy, tmp;

View file

@ -58,6 +58,7 @@ void img_center(img_t*, win_t*);
int img_zoom_in(img_t*); int img_zoom_in(img_t*);
int img_zoom_out(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_pan(img_t*, win_t*, pandir_t);
int img_rotate_left(img_t*, win_t*); int img_rotate_left(img_t*, win_t*);

37
main.c
View file

@ -31,6 +31,8 @@
void on_keypress(XEvent*); void on_keypress(XEvent*);
void on_buttonpress(XEvent*); void on_buttonpress(XEvent*);
void on_buttonrelease(XEvent*);
void on_motionnotify(XEvent*);
void on_configurenotify(XEvent*); void on_configurenotify(XEvent*);
void update_title(); void update_title();
@ -38,6 +40,8 @@ void update_title();
static void (*handler[LASTEvent])(XEvent*) = { static void (*handler[LASTEvent])(XEvent*) = {
[KeyPress] = on_keypress, [KeyPress] = on_keypress,
[ButtonPress] = on_buttonpress, [ButtonPress] = on_buttonpress,
[ButtonRelease] = on_buttonrelease,
[MotionNotify] = on_motionnotify,
[ConfigureNotify] = on_configurenotify [ConfigureNotify] = on_configurenotify
}; };
@ -49,6 +53,9 @@ int filecnt, fileidx;
unsigned char timeout; unsigned char timeout;
int mox;
int moy;
#define TITLE_LEN 256 #define TITLE_LEN 256
char win_title[TITLE_LEN]; char win_title[TITLE_LEN];
@ -276,6 +283,11 @@ void on_buttonpress(XEvent *ev) {
changed = 1; changed = 1;
} }
break; break;
case Button2:
mox = ev->xbutton.x;
moy = ev->xbutton.y;
win_set_cursor(&win, CURSOR_HAND);
break;
case Button3: case Button3:
if (fileidx > 0) { if (fileidx > 0) {
img_load(&img, filenames[--fileidx]); 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) { void on_configurenotify(XEvent *ev) {
if (!ev) if (!ev)
return; return;

View file

@ -21,12 +21,16 @@
#include <string.h> #include <string.h>
#include <X11/Xutil.h> #include <X11/Xutil.h>
#include <X11/cursorfont.h>
#include "sxiv.h" #include "sxiv.h"
#include "options.h" #include "options.h"
#include "window.h" #include "window.h"
GC bgc; static Cursor arrow;
static Cursor hand;
static GC bgc;
void win_open(win_t *win) { void win_open(win_t *win) {
win_env_t *e; win_env_t *e;
@ -66,8 +70,11 @@ void win_open(win_t *win) {
if (win->xwin == None) if (win->xwin == None)
DIE("could not create window"); DIE("could not create window");
XSelectInput(e->dpy, win->xwin, XSelectInput(e->dpy, win->xwin, StructureNotifyMask | KeyPressMask |
StructureNotifyMask | KeyPressMask | ButtonPressMask); ButtonPressMask | ButtonReleaseMask | Button2MotionMask);
arrow = XCreateFontCursor(e->dpy, XC_left_ptr);
hand = XCreateFontCursor(e->dpy, XC_fleur);
bgc = XCreateGC(e->dpy, win->xwin, 0, None); bgc = XCreateGC(e->dpy, win->xwin, 0, None);
@ -91,6 +98,11 @@ void win_close(win_t *win) {
if (!win) if (!win)
return; return;
XFreeCursor(win->env.dpy, arrow);
XFreeCursor(win->env.dpy, hand);
XFreeGC(win->env.dpy, bgc);
XDestroyWindow(win->env.dpy, win->xwin); XDestroyWindow(win->env.dpy, win->xwin);
XCloseDisplay(win->env.dpy); XCloseDisplay(win->env.dpy);
} }
@ -174,3 +186,18 @@ void win_draw(win_t *win) {
XSetWindowBackgroundPixmap(win->env.dpy, win->xwin, win->pm); XSetWindowBackgroundPixmap(win->env.dpy, win->xwin, win->pm);
XClearWindow(win->env.dpy, win->xwin); 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;
}
}

View file

@ -23,6 +23,11 @@
#define CLEANMASK(mask) ((mask) & ~LockMask) #define CLEANMASK(mask) ((mask) & ~LockMask)
typedef enum win_cur_e {
CURSOR_ARROW = 0,
CURSOR_HAND
} win_cur_t;
typedef struct win_env_s { typedef struct win_env_s {
Display *dpy; Display *dpy;
int scr; int scr;
@ -59,4 +64,6 @@ void win_toggle_fullscreen(win_t*);
void win_clear(win_t*); void win_clear(win_t*);
void win_draw(win_t*); void win_draw(win_t*);
void win_set_cursor(win_t*, win_cur_t);
#endif /* WINDOW_H */ #endif /* WINDOW_H */