aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/main.c6
-rw-r--r--src/viewport.c36
-rw-r--r--src/viewport.h7
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*);