diff options
-rw-r--r-- | window.h | 61 |
1 files changed, 42 insertions, 19 deletions
@@ -60,14 +60,19 @@ public: std::vector<uint8_t> &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<void(Buffer &buffer)>; - /// Return true to stop the event loop. - using EventHandler = std::function<bool(const SDL_Event&)>; + using EventHandler = std::function<Action(const SDL_Event&)>; - /// 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); } |