diff options
author | David Robillard <d@drobilla.net> | 2019-07-26 00:57:49 +0200 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2019-07-26 01:05:37 +0200 |
commit | eada1042452e8708ca6c65f7c23ac3c59e4c53f0 (patch) | |
tree | 2155469130ef05d42f49a02c0af3abedf66fe9f1 /pugl/pugl_win.c | |
parent | 55199fe97d7866a0c8998455e43bb5b1f2989eb7 (diff) | |
download | pugl-eada1042452e8708ca6c65f7c23ac3c59e4c53f0.tar.gz pugl-eada1042452e8708ca6c65f7c23ac3c59e4c53f0.tar.bz2 pugl-eada1042452e8708ca6c65f7c23ac3c59e4c53f0.zip |
Windows: Implement size constraints
There are two possible approaches to take here: try to expand dimensions that
are not being explicitly resized (for example expand the bottom when dragging
right), or just stop single-dimension resizes if they would go out of range.
I chose the latter here for two reasons: it's hard to always do something
smooth and unsurprising with the first approach (and it would require more
code), and it can be nice from the user's perspective to easily be able to
resize the window to exactly one of its aspect ratio limits. For example, it
is very easy to drag pugl_test to 1:1 or 16:9.
In other words, simplicity and user power wins.
Diffstat (limited to 'pugl/pugl_win.c')
-rw-r--r-- | pugl/pugl_win.c | 45 |
1 files changed, 45 insertions, 0 deletions
diff --git a/pugl/pugl_win.c b/pugl/pugl_win.c index 1c93ea6..b691295 100644 --- a/pugl/pugl_win.c +++ b/pugl/pugl_win.c @@ -634,6 +634,45 @@ stopFlashing(PuglView* view) } } +static void +constrainAspect(const PuglView* const view, + RECT* const size, + const WPARAM wParam) +{ + const float minAspect = view->min_aspect_x / (float)view->min_aspect_y; + const float maxAspect = view->max_aspect_x / (float)view->max_aspect_y; + const int w = size->right - size->left; + const int h = size->bottom - size->top; + const float a = w / (float)h; + + switch (wParam) { + case WMSZ_TOP: + size->top = (a < minAspect ? (LONG)(size->bottom - w * minAspect) : + a > maxAspect ? (LONG)(size->bottom - w * maxAspect) : + size->top); + break; + case WMSZ_TOPRIGHT: + case WMSZ_RIGHT: + case WMSZ_BOTTOMRIGHT: + size->right = (a < minAspect ? (LONG)(size->left + h * minAspect) : + a > maxAspect ? (LONG)(size->left + h * maxAspect) : + size->right); + break; + case WMSZ_BOTTOM: + size->bottom = (a < minAspect ? (LONG)(size->top + w * minAspect) : + a > maxAspect ? (LONG)(size->top + w * maxAspect) : + size->bottom); + break; + case WMSZ_BOTTOMLEFT: + case WMSZ_LEFT: + case WMSZ_TOPLEFT: + size->left = (a < minAspect ? (LONG)(size->right - h * minAspect) : + a > maxAspect ? (LONG)(size->right - h * maxAspect) : + size->left); + break; + } +} + static LRESULT handleMessage(PuglView* view, UINT message, WPARAM wParam, LPARAM lParam) { @@ -661,6 +700,12 @@ handleMessage(PuglView* view, UINT message, WPARAM wParam, LPARAM lParam) RDW_INVALIDATE|RDW_ALLCHILDREN|RDW_INTERNALPAINT| RDW_UPDATENOW); break; + case WM_SIZING: + if (view->min_aspect_x) { + constrainAspect(view, (RECT*)lParam, wParam); + return TRUE; + } + break; case WM_ENTERSIZEMOVE: view->impl->resizing = true; SetTimer(view->impl->hwnd, |