Mouse-panning while pressing button2
This commit is contained in:
		
							
								
								
									
										2
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								Makefile
									
									
									
									
									
								
							@@ -1,6 +1,6 @@
 | 
			
		||||
all: sxiv
 | 
			
		||||
 | 
			
		||||
VERSION=0.3
 | 
			
		||||
VERSION=git-20110129
 | 
			
		||||
 | 
			
		||||
CC?=gcc
 | 
			
		||||
PREFIX?=/usr/local
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										36
									
								
								image.c
									
									
									
									
									
								
							
							
						
						
									
										36
									
								
								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,26 +239,32 @@ int img_pan(img_t *img, win_t *win, pandir_t dir) {
 | 
			
		||||
	ox = img->x;
 | 
			
		||||
	oy = img->y;
 | 
			
		||||
 | 
			
		||||
	switch (dir) {
 | 
			
		||||
		case PAN_LEFT:
 | 
			
		||||
			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->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:
 | 
			
		||||
			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 ox, oy, tmp;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										1
									
								
								image.h
									
									
									
									
									
								
							
							
						
						
									
										1
									
								
								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*);
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										37
									
								
								main.c
									
									
									
									
									
								
							
							
						
						
									
										37
									
								
								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;
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										33
									
								
								window.c
									
									
									
									
									
								
							
							
						
						
									
										33
									
								
								window.c
									
									
									
									
									
								
							@@ -21,12 +21,16 @@
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
#include <X11/Xutil.h>
 | 
			
		||||
#include <X11/cursorfont.h>
 | 
			
		||||
 | 
			
		||||
#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;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										7
									
								
								window.h
									
									
									
									
									
								
							
							
						
						
									
										7
									
								
								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 */
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user