diff options
author | Jose Diez <jose.manuel.diez@gmail.com> | 2015-11-10 15:46:59 +0000 |
---|---|---|
committer | Harry Jeffery <harry@exec64.co.uk> | 2015-11-10 16:17:56 +0000 |
commit | 185216adcdc62c4cc52ed6104f0bfc5e034a2ffc (patch) | |
tree | 50f771119b8ed4512fdc0a110a0d1e596e43fe73 | |
parent | 507d24d15694cae8e3313b6e02d6bac51f4ea1cb (diff) | |
download | imv-185216adcdc62c4cc52ed6104f0bfc5e034a2ffc.tar.gz |
Separate viewport logic into imv_viewport
-rw-r--r-- | Makefile | 2 | ||||
-rw-r--r-- | main.c | 129 | ||||
-rw-r--r-- | viewport.c | 113 | ||||
-rw-r--r-- | viewport.h | 47 |
4 files changed, 189 insertions, 102 deletions
@@ -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) @@ -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 |