From dccf7bf421ca62ec8f1c470be4aa72d60dd7201d Mon Sep 17 00:00:00 2001 From: Tom Smeding Date: Mon, 13 Apr 2020 09:52:16 +0200 Subject: More usable --- window.h | 61 ++++++++++++++++++++++++++++++++++++++++++------------------- 1 file changed, 42 insertions(+), 19 deletions(-) diff --git a/window.h b/window.h index d9ac9d9..5d67a9a 100644 --- a/window.h +++ b/window.h @@ -60,14 +60,19 @@ public: std::vector &arr; }; - /// The draw buffer will be of size 3 * width * height; row-major order, RGB pixels. + enum Action { + ACT_REDRAW, + ACT_STOP, + ACT_OK, + }; + + /// The draw buffer will be of size 3 * width * height; row-major order, + /// RGB pixels. The draw handler will be invoked if the event handler + /// returns ACT_REDRAW, but also possibly in other circumstances (e.g. + /// window resize). using DrawHandler = std::function; - /// Return true to stop the event loop. - using EventHandler = std::function; + using EventHandler = std::function; - /// The draw function will be called after each invocation of the event - /// function, and might also be invoked more often as the user re-focuses the - /// window. inline void event_loop(EventHandler eventfunc, DrawHandler drawfunc); private: @@ -124,7 +129,23 @@ inline void Window::event_loop(EventHandler eventfunc, DrawHandler drawfunc) { if (e.type == SDL_QUIT) break; - if (eventfunc(e)) break; + bool need_redraw = false; + bool need_refresh = false; + + if (e.type == SDL_WINDOWEVENT) { + if (e.window.event == SDL_WINDOWEVENT_FOCUS_GAINED) { + need_refresh = true; + } + } + + Action act = eventfunc(e); + switch (act) { + case ACT_STOP: return; + case ACT_REDRAW: need_redraw = true; break; + case ACT_OK: break; + default: + throw std::logic_error("Invalid Action from EventHandler"); + } int width, height; SDL_GetWindowSize(win, &width, &height); @@ -139,19 +160,22 @@ inline void Window::event_loop(EventHandler eventfunc, DrawHandler drawfunc) { drawbuf.data(), surf_wid, surf_hei, 24, 3 * surf_wid, 255, 255 << 8, 255 << 16, 0 ); + need_redraw = true; } - { + if (need_redraw) { Buffer buffer{width, height, drawbuf}; drawfunc(buffer); } - SDL_Surface *winsurf = SDL_GetWindowSurface(win); - if (SDL_MUSTLOCK(winsurf)) SDL_LockSurface(winsurf); - SDL_BlitSurface(surface, nullptr, winsurf, nullptr); - if (SDL_MUSTLOCK(winsurf)) SDL_UnlockSurface(winsurf); + if (need_redraw || need_refresh) { + SDL_Surface *winsurf = SDL_GetWindowSurface(win); + if (SDL_MUSTLOCK(winsurf)) SDL_LockSurface(winsurf); + SDL_BlitSurface(surface, nullptr, winsurf, nullptr); + if (SDL_MUSTLOCK(winsurf)) SDL_UnlockSurface(winsurf); - SDL_UpdateWindowSurface(win); + SDL_UpdateWindowSurface(win); + } } } @@ -180,10 +204,9 @@ inline void Window::Buffer::plot(int x, int y, Clr clr, float alpha) { inline void Window::Buffer::plotf(float x, float y, Clr clr, float alpha) { const int x0 = x, y0 = y; - const float xal = (x - x0) * alpha; - const float yal = (y - y0) * alpha; - plot(x0 , y0 , clr, (1 - xal) * (1 - yal)); - plot(x0 + 1, y0 , clr, xal * (1 - yal)); - plot(x0 , y0 + 1, clr, (1 - xal) * yal ); - plot(x0 + 1, y0 + 1, clr, xal * yal ); + const float xal = x - x0, yal = y - y0; + plot(x0 , y0 , clr, (1 - xal) * (1 - yal) * alpha); + plot(x0 + 1, y0 , clr, xal * (1 - yal) * alpha); + plot(x0 , y0 + 1, clr, (1 - xal) * yal * alpha); + plot(x0 + 1, y0 + 1, clr, xal * yal * alpha); } -- cgit v1.2.3