diff options
Diffstat (limited to 'source/blender/windowmanager/intern/wm_playanim.c')
-rw-r--r-- | source/blender/windowmanager/intern/wm_playanim.c | 190 |
1 files changed, 137 insertions, 53 deletions
diff --git a/source/blender/windowmanager/intern/wm_playanim.c b/source/blender/windowmanager/intern/wm_playanim.c index 8b387196da7..e4e529ace71 100644 --- a/source/blender/windowmanager/intern/wm_playanim.c +++ b/source/blender/windowmanager/intern/wm_playanim.c @@ -49,12 +49,12 @@ #include "PIL_time.h" +#include "BLI_utildefines.h" #include "BLI_fileops.h" #include "BLI_listbase.h" #include "BLI_path_util.h" #include "BLI_rect.h" #include "BLI_string.h" -#include "BLI_utildefines.h" #include "IMB_imbuf_types.h" #include "IMB_imbuf.h" @@ -76,10 +76,16 @@ #include "WM_api.h" /* only for WM_main_playanim */ struct PlayState; -static void playanim_window_zoom(const struct PlayState *ps, const float zoom_offset); +static void playanim_window_zoom(struct PlayState *ps, const float zoom_offset); typedef struct PlayState { + /* window and viewport size */ + int win_x, win_y; + + /* current zoom level */ + float zoom; + /* playback state */ short direction; short next_frame; @@ -91,7 +97,7 @@ typedef struct PlayState { short wait2; short stopped; short go; - + int fstep; /* current picture */ @@ -103,6 +109,9 @@ typedef struct PlayState { /* saves passing args */ struct ImBuf *curframe_ibuf; + + /* restarts player for file drop */ + char dropped_file[FILE_MAX]; } PlayState; /* for debugging */ @@ -204,7 +213,6 @@ typedef struct PlayAnimPict { static struct ListBase picsbase = {NULL, NULL}; static int fromdisk = FALSE; -static float zoomx = 1.0, zoomy = 1.0; static double ptottime = 0.0, swaptime = 0.04; static PlayAnimPict *playanim_step(PlayAnimPict *playanim, int step) @@ -234,8 +242,9 @@ static int pupdate_time(void) return (ptottime < 0); } -static void playanim_toscreen(PlayAnimPict *picture, struct ImBuf *ibuf, int fontid, int fstep) +static void playanim_toscreen(PlayState *ps, PlayAnimPict *picture, struct ImBuf *ibuf, int fontid, int fstep) { + float offsx, offsy; if (ibuf == NULL) { printf("%s: no ibuf for picture '%s'\n", __func__, picture ? picture->name : "<NIL>"); @@ -250,10 +259,29 @@ static void playanim_toscreen(PlayAnimPict *picture, struct ImBuf *ibuf, int fon GHOST_ActivateWindowDrawingContext(g_WS.ghost_window); - glRasterPos2f(0.0f, 0.0f); + /* offset within window */ + offsx = 0.5f * (((float)ps->win_x - ps->zoom * ibuf->x) / (float)ps->win_x); + offsy = 0.5f * (((float)ps->win_y - ps->zoom * ibuf->y) / (float)ps->win_y); + + CLAMP(offsx, 0.0f, 1.0f); + CLAMP(offsy, 0.0f, 1.0f); + glRasterPos2f(offsx, offsy); + + glClearColor(0.1, 0.1, 0.1, 0.0); + glClear(GL_COLOR_BUFFER_BIT); + + /* checkerboard for case alpha */ + if (ibuf->planes == 32) { + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + fdrawcheckerboard(offsx, offsy, offsx + (ps->zoom * ibuf->x) / (float)ps->win_x, offsy + (ps->zoom * ibuf->y) / (float)ps->win_y); + } + glDrawPixels(ibuf->x, ibuf->y, GL_RGBA, GL_UNSIGNED_BYTE, ibuf->rect); + glDisable(GL_BLEND); + pupdate_time(); if (picture && (g_WS.qual & (WS_QUAL_SHIFT | WS_QUAL_LMOUSE)) && (fontid != -1)) { @@ -276,7 +304,7 @@ static void playanim_toscreen(PlayAnimPict *picture, struct ImBuf *ibuf, int fon GHOST_SwapWindowBuffers(g_WS.ghost_window); } -static void build_pict_list(char *first, int totframes, int fstep, int fontid) +static void build_pict_list(PlayState *ps, char *first, int totframes, int fstep, int fontid) { char *mem, filepath[FILE_MAX]; // short val; @@ -292,7 +320,7 @@ static void build_pict_list(char *first, int totframes, int fstep, int fontid) int pic; ibuf = IMB_anim_absolute(anim, 0, IMB_TC_NONE, IMB_PROXY_NONE); if (ibuf) { - playanim_toscreen(NULL, ibuf, fontid, fstep); + playanim_toscreen(ps, NULL, ibuf, fontid, fstep); IMB_freeImBuf(ibuf); } @@ -395,7 +423,7 @@ static void build_pict_list(char *first, int totframes, int fstep, int fontid) ibuf = IMB_loadiffname(picture->name, picture->IB_flags, NULL); } if (ibuf) { - playanim_toscreen(picture, ibuf, fontid, fstep); + playanim_toscreen(ps, picture, ibuf, fontid, fstep); IMB_freeImBuf(ibuf); } pupdate_time(); @@ -580,7 +608,9 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr ps_void) case GHOST_kKeyPeriod: case GHOST_kKeyNumpadPeriod: if (val) { - if (ps->sstep) ps->wait2 = FALSE; + if (ps->sstep) { + ps->wait2 = FALSE; + } else { ps->sstep = TRUE; ps->wait2 = !ps->wait2; @@ -689,35 +719,41 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr ps_void) break; } case GHOST_kEventWindowActivate: - case GHOST_kEventWindowDeactivate: { + case GHOST_kEventWindowDeactivate: + { g_WS.qual &= ~WS_QUAL_MOUSE; break; } case GHOST_kEventWindowSize: case GHOST_kEventWindowMove: { - int sizex, sizey; - - playanim_window_get_size(&sizex, &sizey); + float zoomx, zoomy; + + playanim_window_get_size(&ps->win_x, &ps->win_y); GHOST_ActivateWindowDrawingContext(g_WS.ghost_window); - glViewport(0, 0, sizex, sizey); - glScissor(0, 0, sizex, sizey); - - zoomx = (float) sizex / ps->ibufx; - zoomy = (float) sizey / ps->ibufy; - zoomx = floor(zoomx + 0.5f); - zoomy = floor(zoomy + 0.5f); - if (zoomx < 1.0f) zoomx = 1.0f; - if (zoomy < 1.0f) zoomy = 1.0f; - - sizex = zoomx * ps->ibufx; - sizey = zoomy * ps->ibufy; + zoomx = (float) ps->win_x / ps->ibufx; + zoomy = (float) ps->win_y / ps->ibufy; + + /* zoom always show entire image */ + ps->zoom = MIN2(zoomx, zoomy); + + /* zoom steps of 2 for speed */ + ps->zoom = floor(ps->zoom + 0.5f); + if (ps->zoom < 1.0f) ps->zoom = 1.0f; + + glViewport(0, 0, ps->win_x, ps->win_y); + glScissor(0, 0, ps->win_x, ps->win_y); + + /* unified matrix, note it affects offset for drawing */ + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrtho(0.0f, 1.0f, 0.0f, 1.0f, -1.0f, 1.0f); + glMatrixMode(GL_MODELVIEW); - glPixelZoom(zoomx, zoomy); - glEnable(GL_DITHER); + glPixelZoom(ps->zoom, ps->zoom); ptottime = 0.0; - playanim_toscreen(ps->picture, ps->curframe_ibuf, ps->fontid, ps->fstep); + playanim_toscreen(ps, ps->picture, ps->curframe_ibuf, ps->fontid, ps->fstep); break; } @@ -727,6 +763,23 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr ps_void) ps->go = FALSE; break; } + case GHOST_kEventDraggingDropDone: + { + GHOST_TEventDragnDropData *ddd = GHOST_GetEventData(evt); + + if (ddd->dataType == GHOST_kDragnDropTypeFilenames) { + GHOST_TStringArray *stra = ddd->data; + int a; + + for (a = 0; a < stra->count; a++) { + BLI_strncpy(ps->dropped_file, (char *)stra->strings[a], sizeof(ps->dropped_file)); + ps->go = FALSE; + printf("drop file %s\n", stra->strings[a]); + break; /* only one drop element supported now */ + } + } + break; + } default: /* quiet warnings */ break; @@ -757,32 +810,31 @@ static void playanim_window_open(const char *title, int posx, int posy, int size FALSE /* no stereo */, FALSE); } -static void playanim_window_zoom(const PlayState *ps, const float zoom_offset) +static void playanim_window_zoom(PlayState *ps, const float zoom_offset) { int sizex, sizey; /* int ofsx, ofsy; */ /* UNUSED */ - if (zoomx + zoom_offset > 0.0f) zoomx += zoom_offset; - if (zoomy + zoom_offset > 0.0f) zoomy += zoom_offset; + if (ps->zoom + zoom_offset > 0.0f) ps->zoom += zoom_offset; // playanim_window_get_position(&ofsx, &ofsy); playanim_window_get_size(&sizex, &sizey); /* ofsx += sizex / 2; */ /* UNUSED */ /* ofsy += sizey / 2; */ /* UNUSED */ - sizex = zoomx * ps->ibufx; - sizey = zoomy * ps->ibufy; + sizex = ps->zoom * ps->ibufx; + sizey = ps->zoom * ps->ibufy; /* ofsx -= sizex / 2; */ /* UNUSED */ /* ofsy -= sizey / 2; */ /* UNUSED */ - // window_set_position(g_WS.ghost_window,sizex,sizey); + // window_set_position(g_WS.ghost_window, sizex, sizey); GHOST_SetClientSize(g_WS.ghost_window, sizex, sizey); } -void WM_main_playanim(int argc, const char **argv) +/* return path for restart */ +static char *wm_main_playanim_intern(int argc, const char **argv) { struct ImBuf *ibuf = NULL; - char filepath[FILE_MAX]; + static char filepath[FILE_MAX]; /* abused to return dropped file path */ GHOST_TUns32 maxwinx, maxwiny; - /* short c233 = FALSE, yuvx = FALSE; */ /* UNUSED */ int i; /* This was done to disambiguate the name for use under c++. */ struct anim *anim = NULL; @@ -790,7 +842,7 @@ void WM_main_playanim(int argc, const char **argv) int sfra = -1; int efra = -1; int totblock; - + PlayState ps = {0}; /* ps.doubleb = TRUE;*/ /* UNUSED */ @@ -805,6 +857,8 @@ void WM_main_playanim(int argc, const char **argv) ps.wait2 = FALSE; ps.stopped = FALSE; ps.picture = NULL; + ps.dropped_file[0] = 0; + ps.zoom = 1.0f; /* resetmap = FALSE */ ps.fstep = 1; @@ -910,20 +964,16 @@ void WM_main_playanim(int argc, const char **argv) #endif #endif //XXX25 - /* XXX, fixme zr */ { -// extern void add_to_mainqueue(wmWindow *win, void *user_data, short evt, short val, char ascii); GHOST_EventConsumerHandle consumer = GHOST_CreateEventConsumer(ghost_event_proc, &ps); g_WS.ghost_system = GHOST_CreateSystem(); GHOST_AddEventConsumer(g_WS.ghost_system, consumer); - - playanim_window_open("Blender:Anim", start_x, start_y, ibuf->x, ibuf->y, 0); -//XXX25 window_set_handler(g_WS.ghost_window, add_to_mainqueue, NULL); + /* unified matrix, note it affects offset for drawing */ glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(0.0f, 1.0f, 0.0f, 1.0f, -1.0f, 1.0f); @@ -941,11 +991,15 @@ void WM_main_playanim(int argc, const char **argv) ps.ibufx = ibuf->x; ps.ibufy = ibuf->y; + + ps.win_x = ps.ibufx; + ps.win_y = ps.ibufy; if (maxwinx % ibuf->x) maxwinx = ibuf->x * (1 + (maxwinx / ibuf->x)); if (maxwiny % ibuf->y) maxwiny = ibuf->y * (1 + (maxwiny / ibuf->y)); - glClearColor(0.0, 0.0, 0.0, 0.0); + + glClearColor(0.1, 0.1, 0.1, 0.0); glClear(GL_COLOR_BUFFER_BIT); GHOST_SwapWindowBuffers(g_WS.ghost_window); @@ -956,11 +1010,11 @@ void WM_main_playanim(int argc, const char **argv) efra = MAXFRAME; } - build_pict_list(filepath, (efra - sfra) + 1, ps.fstep, ps.fontid); + build_pict_list(&ps, filepath, (efra - sfra) + 1, ps.fstep, ps.fontid); for (i = 2; i < argc; i++) { BLI_strncpy(filepath, argv[i], sizeof(filepath)); - build_pict_list(filepath, (efra - sfra) + 1, ps.fstep, ps.fontid); + build_pict_list(&ps, filepath, (efra - sfra) + 1, ps.fstep, ps.fontid); } IMB_freeImBuf(ibuf); @@ -1033,8 +1087,8 @@ void WM_main_playanim(int argc, const char **argv) while (pupdate_time()) PIL_sleep_ms(1); ptottime -= swaptime; - playanim_toscreen(ps.picture, ibuf, ps.fontid, ps.fstep); - } /* else deleten */ + playanim_toscreen(&ps, ps.picture, ibuf, ps.fontid, ps.fstep); + } /* else delete */ else { printf("error: can't play this image type\n"); exit(0); @@ -1052,16 +1106,17 @@ void WM_main_playanim(int argc, const char **argv) ps.next_frame = ps.direction; - while ((hasevent = GHOST_ProcessEvents(g_WS.ghost_system, 0) || ps.wait2 != 0)) { + while ( (hasevent = GHOST_ProcessEvents(g_WS.ghost_system, 0)) || ps.wait2 != 0) { if (hasevent) { GHOST_DispatchEvents(g_WS.ghost_system); } + /* Note, this still draws for mousemoves on pause */ if (ps.wait2) { if (hasevent) { if (ibuf) { while (pupdate_time()) PIL_sleep_ms(1); ptottime -= swaptime; - playanim_toscreen(ps.picture, ibuf, ps.fontid, ps.fstep); + playanim_toscreen(&ps, ps.picture, ibuf, ps.fontid, ps.fstep); } } } @@ -1134,12 +1189,20 @@ void WM_main_playanim(int argc, const char **argv) #else /* we still miss freeing a lot!, * but many areas could skip initialization too for anim play */ - IMB_exit(); - BKE_images_exit(); + BLF_exit(); #endif GHOST_DisposeWindow(g_WS.ghost_system, g_WS.ghost_window); + /* early exit, IMB and BKE should be exited only in end */ + if (ps.dropped_file) { + BLI_strncpy(filepath, ps.dropped_file, sizeof(filepath)); + return filepath; + } + + IMB_exit(); + BKE_images_exit(); + totblock = MEM_get_memory_blocks_in_use(); if (totblock != 0) { /* prints many bAKey, bArgument's which are tricky to fix */ @@ -1148,4 +1211,25 @@ void WM_main_playanim(int argc, const char **argv) MEM_printmemlist(); #endif } + + return NULL; +} + + +void WM_main_playanim(int argc, const char **argv) +{ + bool looping = true; + + while (looping) { + char *filepath = wm_main_playanim_intern(argc, argv); + + if (filepath) { /* use simple args */ + argv[1] = "-a"; + argv[2] = filepath; + argc = 3; + } + else { + looping = false; + } + } } |