Skip to content
This repository has been archived by the owner on Dec 1, 2021. It is now read-only.

Enabling touch navigation #245

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,6 @@ build/
imv.1
imv.5
doc/imv-msg.1
*.png
*.jpg
src/G*
60 changes: 60 additions & 0 deletions src/imv.c
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,12 @@ struct imv {
/* if reading an image from stdin, this is the buffer for it */
void *stdin_image_data;
size_t stdin_image_data_len;

/* initial scale for correct pinch zoom*/
double initial_zoom;

/* initial view offset for correct touch pan*/
int initial_view_x, initial_view_y;
};

static void command_quit(struct list *args, const char *argstr, void *data);
Expand Down Expand Up @@ -442,6 +448,60 @@ static void event_handler(void *data, const struct imv_event *e)
case IMV_EVENT_CUSTOM:
consume_internal_event(imv, e->data.custom);
break;
case IMV_EVENT_TOUCH_TAP:
{
double current_scale;
imv_viewport_get_scale(imv->view, &current_scale);
double default_scale =
imv_viewport_get_scale_to_window(imv->view, imv->current_image);
double x = e->data.touch_tap.x;
double width = e->data.touch_tap.width;
if (current_scale <= default_scale) {
if (x < width / 4) {
imv_navigator_select_rel(imv->navigator, -1);
} else if (x > width * 3 / 4) {
imv_navigator_select_rel(imv->navigator, 1);
}
}
if (x > width / 4 && x < width * 3 / 4) {
imv->overlay_enabled = !imv->overlay_enabled;
imv->need_redraw = true;
}
}
break;
case IMV_EVENT_TOUCH_ZOOM_START:
{
double current_scale;
imv_viewport_get_scale(imv->view, &current_scale);
imv->initial_zoom = current_scale;
}
break;
case IMV_EVENT_TOUCH_ZOOM_CHANGE:
{
double new_zoom = imv->initial_zoom * e->data.touch_zoom.zoom;
int new_zoom_int = (int) (new_zoom * 100);
imv_viewport_zoom(imv->view, imv->current_image, IMV_ZOOM_TOUCH,
e->data.touch_zoom.x, e->data.touch_zoom.y,
new_zoom_int);
}
break;
case IMV_EVENT_TOUCH_PAN_START:
{
int x,y;
imv_viewport_get_offset(imv->view, &x, &y);
imv->initial_view_x = x;
imv->initial_view_y = y;
}
break;
case IMV_EVENT_TOUCH_PAN_CHANGE:
{
imv_viewport_move_relative(imv->view,
imv->initial_view_x,
imv->initial_view_y,
(int) (e->data.touch_pan.current_x - e->data.touch_pan.initial_x),
(int) (e->data.touch_pan.current_y - e->data.touch_pan.initial_y),
imv->current_image);
}
default:
break;
}
Expand Down
51 changes: 39 additions & 12 deletions src/viewport.c
Original file line number Diff line number Diff line change
Expand Up @@ -90,14 +90,9 @@ void imv_viewport_set_default_pan_factor(struct imv_viewport *view, double pan_f
view->pan_factor_y = pan_factor_y;
}

void imv_viewport_move(struct imv_viewport *view, int x, int y,
void imv_viewport_keep_onscreen(struct imv_viewport *view,
const struct imv_image *image)
{
input_xy_to_render_xy(view, &x, &y);
view->x += x;
view->y += y;
view->redraw = 1;
view->locked = 1;
int w = (int)(imv_image_width(image) * view->scale);
int h = (int)(imv_image_height(image) * view->scale);
if (view->x < -w) {
Expand All @@ -114,6 +109,29 @@ void imv_viewport_move(struct imv_viewport *view, int x, int y,
}
}

void imv_viewport_move(struct imv_viewport *view, int x, int y,
const struct imv_image *image)
{
input_xy_to_render_xy(view, &x, &y);
view->x += x;
view->y += y;
view->redraw = 1;
view->locked = 1;
imv_viewport_keep_onscreen(view, image);
}

void imv_viewport_move_relative(struct imv_viewport *view,
int initial_x, int initial_y,
int delta_x, int delta_y,
struct imv_image *image)
{
view->x = initial_x + delta_x;
view->y = initial_y + delta_y;
view->redraw = 1;
view->locked = 1;
imv_viewport_keep_onscreen(view, image);
}

void imv_viewport_zoom(struct imv_viewport *view, const struct imv_image *image,
enum imv_zoom_source src, int mouse_x, int mouse_y, int amount)
{
Expand All @@ -124,7 +142,7 @@ void imv_viewport_zoom(struct imv_viewport *view, const struct imv_image *image,
const int image_height = imv_image_height(image);

/* x and y cordinates are relative to the image */
if(src == IMV_ZOOM_MOUSE) {
if(src == IMV_ZOOM_MOUSE || src == IMV_ZOOM_TOUCH) {
input_xy_to_render_xy(view, &mouse_x, &mouse_y);
x = mouse_x - view->x;
y = mouse_y - view->y;
Expand All @@ -140,8 +158,12 @@ void imv_viewport_zoom(struct imv_viewport *view, const struct imv_image *image,
const int wc_x = view->buffer.width/2;
const int wc_y = view->buffer.height/2;

double delta_scale = 0.04 * view->buffer.width * amount / image_width;
view->scale += delta_scale;
if (src == IMV_ZOOM_TOUCH) {
view->scale = amount / 100.0f;
} else {
double delta_scale = 0.04 * view->buffer.width * amount / image_width;
view->scale += delta_scale;
}

const double min_scale = 0.1;
const double max_scale = 100;
Expand Down Expand Up @@ -203,7 +225,8 @@ void imv_viewport_center(struct imv_viewport *view, const struct imv_image *imag
view->redraw = 1;
}

void imv_viewport_scale_to_window(struct imv_viewport *view, const struct imv_image *image)
double imv_viewport_get_scale_to_window(struct imv_viewport *view,
const struct imv_image *image)
{
const int image_width = imv_image_width(image);
const int image_height = imv_image_height(image);
Expand All @@ -212,12 +235,16 @@ void imv_viewport_scale_to_window(struct imv_viewport *view, const struct imv_im

if(window_aspect > image_aspect) {
/* Image will become too tall before it becomes too wide */
view->scale = (double)view->buffer.height / (double)image_height;
return (double)view->buffer.height / (double)image_height;
} else {
/* Image will become too wide before it becomes too tall */
view->scale = (double)view->buffer.width / (double)image_width;
return (double)view->buffer.width / (double)image_width;
}
}

void imv_viewport_scale_to_window(struct imv_viewport *view, const struct imv_image *image)
{
view->scale = imv_viewport_get_scale_to_window(view, image);
imv_viewport_center(view, image);
view->locked = 0;
}
Expand Down
11 changes: 10 additions & 1 deletion src/viewport.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ enum scaling_mode {
/* Used to signify how a a user requested a zoom */
enum imv_zoom_source {
IMV_ZOOM_MOUSE,
IMV_ZOOM_KEYBOARD
IMV_ZOOM_KEYBOARD,
IMV_ZOOM_TOUCH
};

/* Creates an instance of imv_viewport */
Expand Down Expand Up @@ -50,6 +51,10 @@ void imv_viewport_set_default_pan_factor(struct imv_viewport *view, double pan_f
void imv_viewport_move(struct imv_viewport *view, int x, int y,
const struct imv_image *image);

/* Pan the view relatively by coordinates */
void imv_viewport_move_relative(struct imv_viewport *view, int initial_x,
int initial_y, int delta_x, int delta_y, struct imv_image *image);

/* Zoom the view by the given amount. imv_image* is used to get the image
* dimensions */
void imv_viewport_zoom(struct imv_viewport *view, const struct imv_image *image,
Expand All @@ -63,6 +68,10 @@ void imv_viewport_center(struct imv_viewport *view,
void imv_viewport_scale_to_actual(struct imv_viewport *view,
const struct imv_image *image);

/*get scale when scaled to window*/
double imv_viewport_get_scale_to_window(struct imv_viewport *view,
const struct imv_image *image);

/* Scale the view so that the image fits in the window */
void imv_viewport_scale_to_window(struct imv_viewport *view,
const struct imv_image *image);
Expand Down
17 changes: 17 additions & 0 deletions src/window.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@ enum imv_event_type {
IMV_EVENT_MOUSE_MOTION,
IMV_EVENT_MOUSE_BUTTON,
IMV_EVENT_MOUSE_SCROLL,
IMV_EVENT_TOUCH_TAP,
IMV_EVENT_TOUCH_ZOOM_START,
IMV_EVENT_TOUCH_ZOOM_CHANGE,
IMV_EVENT_TOUCH_PAN_START,
IMV_EVENT_TOUCH_PAN_CHANGE,
IMV_EVENT_CUSTOM
};

Expand Down Expand Up @@ -41,6 +46,18 @@ struct imv_event {
struct {
double dx, dy;
} mouse_scroll;
struct {
double x,y;
int height, width;
} touch_tap;
struct {
double x,y;
double zoom;
} touch_zoom;
struct {
double initial_x, initial_y;
double current_x, current_y;
} touch_pan;
void *custom;
} data;
};
Expand Down
Loading