summaryrefslogtreecommitdiff
path: root/window.h
diff options
context:
space:
mode:
Diffstat (limited to 'window.h')
-rw-r--r--window.h61
1 files 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<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);
}