aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile2
-rw-r--r--main.c129
-rw-r--r--viewport.c113
-rw-r--r--viewport.h47
4 files changed, 189 insertions, 102 deletions
diff --git a/Makefile b/Makefile
index 33d3724..07d476e 100644
--- a/Makefile
+++ b/Makefile
@@ -6,7 +6,7 @@ CFLAGS = -g -W -Wall -std=gnu11 `sdl2-config --cflags`
LDFLAGS = `sdl2-config --libs` -lfreeimage
TARGET = imv
-OBJECTS = main.o image.o texture.o navigator.o
+OBJECTS = main.o image.o texture.o navigator.o viewport.o
$(TARGET): $(OBJECTS)
$(CC) $(LDFLAGS) -o $@ $^ $(LDLIBS)
diff --git a/main.c b/main.c
index f38988d..0489ae8 100644
--- a/main.c
+++ b/main.c
@@ -25,6 +25,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
#include "image.h"
#include "texture.h"
#include "navigator.h"
+#include "viewport.h"
SDL_Window *g_window = NULL;
@@ -36,84 +37,6 @@ struct {
int recursive;
} g_options = {0,0,0,0,0};
-struct {
- double scale;
- int x, y;
- int fullscreen;
- int redraw;
- int playing;
-} g_view = {1,0,0,0,1,1};
-
-void toggle_fullscreen()
-{
- if(g_view.fullscreen) {
- SDL_SetWindowFullscreen(g_window, 0);
- g_view.fullscreen = 0;
- } else {
- SDL_SetWindowFullscreen(g_window, SDL_WINDOW_FULLSCREEN_DESKTOP);
- g_view.fullscreen = 1;
- }
-}
-
-void toggle_playing(struct imv_image *img)
-{
- if(g_view.playing) {
- g_view.playing = 0;
- } else if(imv_image_is_animated(img)) {
- g_view.playing = 1;
- }
-}
-
-void reset_view()
-{
- g_view.scale = 1;
- g_view.x = 0;
- g_view.y = 0;
- g_view.redraw = 1;
-}
-
-void move_view(int x, int y)
-{
- g_view.x += x;
- g_view.y += y;
- g_view.redraw = 1;
-}
-
-void zoom_view(int amount)
-{
- g_view.scale += amount * 0.1;
- if(g_view.scale > 100)
- g_view.scale = 10;
- else if (g_view.scale < 0.01)
- g_view.scale = 0.1;
- g_view.redraw = 1;
-}
-
-void center_view(int ww, int wh, int iw, int ih)
-{
- g_view.x = (ww - iw * g_view.scale) / 2;
- g_view.y = (wh - ih * g_view.scale) / 2;
- g_view.redraw = 1;
-}
-
-void scale_to_window(int ww, int wh, int iw, int ih)
-{
- double window_aspect = (double)ww/(double)wh;
- double image_aspect = (double)iw/(double)ih;
-
- if(window_aspect > image_aspect) {
- //Image will become too tall before it becomes too wide
- g_view.scale = (double)wh/(double)ih;
- } else {
- //Image will become too wide before it becomes too tall
- g_view.scale = (double)ww/(double)iw;
- }
-
- //Also center image
- center_view(ww,wh,iw,ih);
- g_view.redraw = 1;
-}
-
void print_usage(const char* name)
{
fprintf(stdout,
@@ -238,9 +161,12 @@ int main(int argc, char** argv)
struct imv_texture tex;
imv_init_texture(&tex, renderer);
+ struct imv_viewport view;
+ imv_init_viewport(&view, g_window);
+
//Put us in fullscren by default if requested
if(g_options.fullscreen) {
- toggle_fullscreen();
+ imv_viewport_toggle_fullscreen(&view);
}
const char* current_path = NULL;
@@ -270,32 +196,32 @@ int main(int argc, char** argv)
case SDLK_RIGHT: imv_navigator_next_path(&nav); break;
case SDLK_EQUALS:
case SDLK_i:
- case SDLK_UP: zoom_view(1); break;
+ case SDLK_UP: imv_viewport_zoom(&view, 1); break;
case SDLK_MINUS:
case SDLK_o:
- case SDLK_DOWN: zoom_view(-1); break;
- case SDLK_r: reset_view(); break;
- case SDLK_j: move_view(0, -50); break;
- case SDLK_k: move_view(0, 50); break;
- case SDLK_h: move_view(50, 0); break;
- case SDLK_l: move_view(-50, 0); break;
+ case SDLK_DOWN: imv_viewport_zoom(&view, -1); break;
+ case SDLK_r: imv_viewport_reset(&view); break;
+ case SDLK_j: imv_viewport_move(&view, 0, -50); break;
+ case SDLK_k: imv_viewport_move(&view, 0, 50); break;
+ case SDLK_h: imv_viewport_move(&view, 50, 0); break;
+ case SDLK_l: imv_viewport_move(&view, -50, 0); break;
case SDLK_x: imv_navigator_remove_current_path(&nav); break;
- case SDLK_f: toggle_fullscreen(); break;
+ case SDLK_f: imv_viewport_toggle_fullscreen(&view); break;
case SDLK_PERIOD: imv_image_load_next_frame(&img); break;
- case SDLK_SPACE: toggle_playing(&img); break;
- case SDLK_s: scale_to_window(ww,wh,img.width,img.height); break;
+ case SDLK_SPACE: imv_viewport_toggle_playing(&view, &img);break;
+ case SDLK_s: imv_viewport_scale_to_window(&view, &img);break;
}
break;
case SDL_MOUSEWHEEL:
- zoom_view(e.wheel.y);
+ imv_viewport_zoom(&view, e.wheel.y);
break;
case SDL_MOUSEMOTION:
if(e.motion.state & SDL_BUTTON_LMASK) {
- move_view(e.motion.xrel, e.motion.yrel);
+ imv_viewport_move(&view, e.motion.xrel, e.motion.yrel);
}
break;
case SDL_WINDOWEVENT:
- g_view.redraw = 1;
+ imv_viewport_set_redraw(&view);
break;
}
}
@@ -320,36 +246,36 @@ int main(int argc, char** argv)
char title[128];
snprintf(&title[0], sizeof(title), "imv - %s", current_path);
SDL_SetWindowTitle(g_window, (const char*)&title);
- reset_view();
+ imv_viewport_reset(&view);
}
//Autoscale if requested
if(g_options.autoscale) {
- scale_to_window(ww,wh,img.width,img.height);
+ imv_viewport_scale_to_window(&view, &img);
}
if(g_options.center) {
- center_view(ww,wh,img.width,img.height);
+ imv_viewport_center(&view, &img);
}
}
if(resend) {
imv_texture_set_image(&tex, img.cur_bmp);
- g_view.redraw = 1;
+ imv_viewport_set_redraw(&view);
}
- if(g_view.playing) {
+ if(view.playing) {
imv_image_play(&img, dt);
}
if(img.cur_frame != last_frame) {
imv_texture_set_image(&tex, img.cur_bmp);
- g_view.redraw = 1;
+ imv_viewport_set_redraw(&view);
}
last_frame = img.cur_frame;
- if(g_view.redraw) {
+ if(view.redraw) {
SDL_RenderClear(renderer);
- imv_texture_draw(&tex, g_view.x, g_view.y, g_view.scale);
+ imv_texture_draw(&tex, view.x, view.y, view.scale);
SDL_RenderPresent(renderer);
- g_view.redraw = 0;
+ view.redraw = 0;
}
last_time = SDL_GetTicks() / 1000.0;
SDL_Delay(10);
@@ -358,6 +284,7 @@ int main(int argc, char** argv)
imv_destroy_image(&img);
imv_destroy_texture(&tex);
imv_destroy_navigator(&nav);
+ imv_destroy_viewport(&view);
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(g_window);
diff --git a/viewport.c b/viewport.c
new file mode 100644
index 0000000..3ac5505
--- /dev/null
+++ b/viewport.c
@@ -0,0 +1,113 @@
+/* Copyright (c) 2015 Harry Jeffery
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+the Software, and to permit persons to whom the Software is furnished to do so,
+subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+
+#include "viewport.h"
+#include "image.h"
+
+void imv_init_viewport(struct imv_viewport *view, SDL_Window *window)
+{
+ view->window = window;
+ view->scale = 1;
+ view->x = view->y = view->fullscreen = view->redraw = 0;
+ view->playing = 1;
+}
+
+void imv_destroy_viewport(struct imv_viewport *view)
+{
+ return;
+}
+
+void imv_viewport_toggle_fullscreen(struct imv_viewport *view)
+{
+ if(view->fullscreen) {
+ SDL_SetWindowFullscreen(view->window, 0);
+ view->fullscreen = 0;
+ } else {
+ SDL_SetWindowFullscreen(view->window, SDL_WINDOW_FULLSCREEN_DESKTOP);
+ view->fullscreen = 1;
+ }
+}
+
+void imv_viewport_toggle_playing(struct imv_viewport *view, struct imv_image *img)
+{
+ if(view->playing) {
+ view->playing = 0;
+ } else if(imv_image_is_animated(img)) {
+ view->playing = 1;
+ }
+}
+
+void imv_viewport_reset(struct imv_viewport *view)
+{
+ view->scale = 1;
+ view->x = view->y = 0;
+ view->redraw = 1;
+}
+
+void imv_viewport_move(struct imv_viewport *view, int x, int y)
+{
+ view->x += x;
+ view->y += y;
+ view->redraw = 1;
+}
+
+void imv_viewport_zoom(struct imv_viewport *view, int amount)
+{
+ view->scale += amount * 0.1;
+ if(view->scale > 100)
+ view->scale = 10;
+ else if (view->scale < 0.01)
+ view->scale = 0.1;
+ view->redraw = 1;
+}
+
+void imv_viewport_center(struct imv_viewport *view, const struct imv_image* img)
+{
+ int ww, wh;
+ SDL_GetWindowSize(view->window, &ww, &wh);
+
+ view->x = (ww - img->width * view->scale) / 2;
+ view->y = (wh - img->height * view->scale) / 2;
+
+ view->redraw = 1;
+}
+
+void imv_viewport_scale_to_window(struct imv_viewport *view, const struct imv_image* img)
+{
+ int ww, wh;
+ SDL_GetWindowSize(view->window, &ww, &wh);
+
+ double window_aspect = (double)ww / (double)wh;
+ double image_aspect = (double)img->width / (double)img->height;
+
+ if(window_aspect > image_aspect) {
+ //Image will become too tall before it becomes too wide
+ view->scale = (double)wh / (double)img->height;
+ } else {
+ //Image will become too wide before it becomes too tall
+ view->scale = (double)ww / (double)img->width;
+ }
+
+ imv_viewport_center(view, img);
+}
+
+void imv_viewport_set_redraw(struct imv_viewport *view)
+{
+ view->redraw = 1;
+}
diff --git a/viewport.h b/viewport.h
new file mode 100644
index 0000000..655f109
--- /dev/null
+++ b/viewport.h
@@ -0,0 +1,47 @@
+#ifndef IMV_VIEWPORT_H
+#define IMV_VIEWPORT_H
+
+/* Copyright (c) 2015 Harry Jeffery
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+the Software, and to permit persons to whom the Software is furnished to do so,
+subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+
+#include <SDL2/SDL.h>
+#include "image.h"
+
+struct imv_viewport {
+ SDL_Window *window;
+ double scale;
+ int x, y;
+ int fullscreen;
+ int redraw;
+ int playing;
+};
+
+void imv_init_viewport(struct imv_viewport *view, SDL_Window *window);
+void imv_destroy_viewport(struct imv_viewport *view);
+
+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_center(struct imv_viewport*, const struct imv_image*);
+void imv_viewport_scale_to_window(struct imv_viewport*, const struct imv_image*);
+void imv_viewport_set_redraw(struct imv_viewport*);
+
+#endif