From 79281774a6f1e72aa6fba99dd9b3524b3cd5a2cd Mon Sep 17 00:00:00 2001 From: Jose Diez Date: Wed, 11 Nov 2015 15:02:07 +0000 Subject: Improved zoom behaviour --- src/main.c | 6 +++--- src/viewport.c | 36 +++++++++++++++++++++++++++++++++++- src/viewport.h | 7 ++++++- 3 files changed, 44 insertions(+), 5 deletions(-) diff --git a/src/main.c b/src/main.c index cbbe493..a7b115c 100644 --- a/src/main.c +++ b/src/main.c @@ -184,10 +184,10 @@ int main(int argc, char** argv) case SDLK_RIGHT: imv_navigator_next_path(&nav); break; case SDLK_EQUALS: case SDLK_i: - case SDLK_UP: imv_viewport_zoom(&view, 1); break; + case SDLK_UP: imv_viewport_zoom(&view, &img, KBD, 1); break; case SDLK_MINUS: case SDLK_o: - case SDLK_DOWN: imv_viewport_zoom(&view, -1); break; + case SDLK_DOWN: imv_viewport_zoom(&view, &img, KBD, -1); break; case SDLK_a: imv_viewport_scale_to_actual(&view, &img);break; case SDLK_r: imv_viewport_scale_to_window(&view, &img);break; case SDLK_c: imv_viewport_center(&view, &img); break; @@ -203,7 +203,7 @@ int main(int argc, char** argv) } break; case SDL_MOUSEWHEEL: - imv_viewport_zoom(&view, e.wheel.y); + imv_viewport_zoom(&view, &img, MOUSE, e.wheel.y); break; case SDL_MOUSEMOTION: if(e.motion.state & SDL_BUTTON_LMASK) { diff --git a/src/viewport.c b/src/viewport.c index bb2e92e..38deabc 100644 --- a/src/viewport.c +++ b/src/viewport.c @@ -71,13 +71,47 @@ void imv_viewport_move(struct imv_viewport *view, int x, int y) view->locked = 1; } -void imv_viewport_zoom(struct imv_viewport *view, int amount) +void imv_viewport_zoom(struct imv_viewport *view, const struct imv_image *img, enum imv_zoom_source src, int amount) { + double prevScale = view->scale; + int x, y; + + if(src == MOUSE) { + SDL_GetMouseState(&x, &y); + /* Translate mouse coordinates to projected coordinates */ + x -= view->x; + y -= view->y; + } else x = y = 0; + + int scaledWidth = img->width * view->scale; + int scaledHeight = img->height * view->scale; + if(x > scaledWidth) { + x = scaledWidth; + } + + if(y > scaledHeight) { + y = scaledHeight; + } + view->scale += amount * 0.1; if(view->scale > 100) view->scale = 10; else if (view->scale < 0.01) view->scale = 0.1; + + double changeX = x - (x * (view->scale / prevScale)); + double changeY = y - (y * (view->scale / prevScale)); + + if(amount < 0 && + (view->x <= 0 && (view->x + changeX > 0 || !changeX))) { + view->x = 0; + } else view->x += changeX; + + if(amount < 0 && + (view->y <= 0 && (view->y + changeY > 0 || !changeY))) { + view->y = 0; + } else view->y += changeY; + view->redraw = 1; view->locked = 1; } diff --git a/src/viewport.h b/src/viewport.h index 8538e33..6dd17fb 100644 --- a/src/viewport.h +++ b/src/viewport.h @@ -33,6 +33,11 @@ struct imv_viewport { int locked; }; +enum imv_zoom_source { + MOUSE, + KBD +}; + void imv_init_viewport(struct imv_viewport *view, SDL_Window *window); void imv_destroy_viewport(struct imv_viewport *view); @@ -40,7 +45,7 @@ void imv_viewport_toggle_fullscreen(struct imv_viewport*); void imv_viewport_toggle_playing(struct imv_viewport*, struct imv_image*); void imv_viewport_reset(struct imv_viewport*); void imv_viewport_move(struct imv_viewport*, int, int); -void imv_viewport_zoom(struct imv_viewport*, int); +void imv_viewport_zoom(struct imv_viewport*, const struct imv_image*, enum imv_zoom_source, int); void imv_viewport_center(struct imv_viewport*, const struct imv_image*); void imv_viewport_scale_to_actual(struct imv_viewport*, const struct imv_image*); void imv_viewport_scale_to_window(struct imv_viewport*, const struct imv_image*); -- cgit v1.2.3