aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2022-05-20 19:44:23 -0400
committerDavid Robillard <d@drobilla.net>2022-05-21 17:05:51 -0400
commit82405e8c177de446d03c340b4b6876370d79883a (patch)
tree8b58d94ce03810d95558d725f9a3394d2e7d0fc7 /src
parenta136586a339032126540ceb24f7c3f15eaba68c8 (diff)
downloadpugl-82405e8c177de446d03c340b4b6876370d79883a.tar.gz
pugl-82405e8c177de446d03c340b4b6876370d79883a.tar.bz2
pugl-82405e8c177de446d03c340b4b6876370d79883a.zip
Add puglSetPosition() and puglSetSize()
These are redundant with puglSetFrame in a sense, but allow setting the size of a view without the position, or vice-versa. This API also maps more nicely to Wayland, where applications can not position themselves (but can resize).
Diffstat (limited to 'src')
-rw-r--r--src/mac.m82
-rw-r--r--src/win.c82
-rw-r--r--src/x11.c53
3 files changed, 193 insertions, 24 deletions
diff --git a/src/mac.m b/src/mac.m
index 7608ec8..67422a5 100644
--- a/src/mac.m
+++ b/src/mac.m
@@ -1368,28 +1368,88 @@ puglSetWindowTitle(PuglView* view, const char* title)
PuglStatus
puglSetFrame(PuglView* view, const PuglRect frame)
{
- PuglInternals* const impl = view->impl;
+ PuglInternals* const impl = view->impl;
+ const NSRect framePx = rectToNsRect(frame);
+ const NSRect framePt = nsRectToPoints(view, framePx);
- // Update view frame to exactly the requested frame in Pugl coordinates
+ // Update view frame to exactly the requested frame
view->frame = frame;
- const NSRect framePx = rectToNsRect(frame);
- const NSRect framePt = nsRectToPoints(view, framePx);
if (impl->window) {
- // Resize window to fit new content rect
const NSRect screenPt = rectToScreen(viewScreen(view), framePt);
- const NSRect winFrame = [impl->window frameRectForContentRect:screenPt];
+ // Move and resize window to fit new content rect
+ const NSRect winFrame = [impl->window frameRectForContentRect:screenPt];
[impl->window setFrame:winFrame display:NO];
+
+ // Resize views
+ const NSRect sizePx = NSMakeRect(0, 0, frame.width, frame.height);
+ const NSRect sizePt = [impl->drawView convertRectFromBacking:sizePx];
+ [impl->wrapperView setFrame:sizePt];
+ [impl->drawView setFrame:sizePt];
+ } else {
+ // Resize view
+ const NSRect sizePx = NSMakeRect(0, 0, frame.width, frame.height);
+ const NSRect sizePt = [impl->drawView convertRectFromBacking:sizePx];
+
+ [impl->wrapperView setFrame:framePt];
+ [impl->drawView setFrame:sizePt];
+ }
+
+ return PUGL_SUCCESS;
+}
+
+PuglStatus
+puglSetPosition(PuglView* const view, const int x, const int y)
+{
+ if (x > INT16_MAX || y > INT16_MAX) {
+ return PUGL_BAD_PARAMETER;
+ }
+
+ const PuglRect frame = {
+ (PuglCoord)x, (PuglCoord)y, view->frame.height, view->frame.height};
+
+ PuglInternals* const impl = view->impl;
+ if (impl->window) {
+ return puglSetFrame(view, frame);
}
- // Resize views
- const NSRect sizePx = NSMakeRect(0, 0, frame.width, frame.height);
- const NSRect sizePt = [impl->drawView convertRectFromBacking:sizePx];
+ const NSRect framePx = rectToNsRect(frame);
+ const NSRect framePt = nsRectToPoints(view, framePx);
+ [impl->wrapperView setFrameOrigin:framePt.origin];
+
+ const NSRect drawPx = NSMakeRect(0, 0, frame.width, frame.height);
+ const NSRect drawPt = [impl->drawView convertRectFromBacking:drawPx];
+ [impl->drawView setFrameOrigin:drawPt.origin];
- [impl->wrapperView setFrame:(impl->window ? sizePt : framePt)];
- [impl->drawView setFrame:sizePt];
+ view->frame = frame;
+ return PUGL_SUCCESS;
+}
+
+PuglStatus
+puglSetSize(PuglView* const view, const unsigned width, const unsigned height)
+{
+ if (width > INT16_MAX || height > INT16_MAX) {
+ return PUGL_BAD_PARAMETER;
+ }
+ const PuglRect frame = {
+ view->frame.x, view->frame.y, (PuglSpan)width, (PuglSpan)height};
+
+ PuglInternals* const impl = view->impl;
+ if (impl->window) {
+ return puglSetFrame(view, frame);
+ }
+
+ const NSRect framePx = rectToNsRect(frame);
+ const NSRect framePt = nsRectToPoints(view, framePx);
+ [impl->wrapperView setFrameSize:framePt.size];
+
+ const NSRect drawPx = NSMakeRect(0, 0, frame.width, frame.height);
+ const NSRect drawPt = [impl->drawView convertRectFromBacking:drawPx];
+ [impl->drawView setFrameSize:drawPt.size];
+
+ view->frame = frame;
return PUGL_SUCCESS;
}
diff --git a/src/win.c b/src/win.c
index 34f46d9..26dd4c8 100644
--- a/src/win.c
+++ b/src/win.c
@@ -984,17 +984,27 @@ puglSetWindowTitle(PuglView* view, const char* title)
return PUGL_SUCCESS;
}
+static RECT
+adjustedWindowRect(PuglView* const view,
+ const long x,
+ const long y,
+ const long width,
+ const long height)
+{
+ const unsigned flags = puglWinGetWindowFlags(view);
+ const unsigned exFlags = puglWinGetWindowExFlags(view);
+
+ RECT rect = {(long)x, (long)y, (long)x + (long)width, (long)y + (long)height};
+ AdjustWindowRectEx(&rect, flags, FALSE, exFlags);
+ return rect;
+}
+
PuglStatus
puglSetFrame(PuglView* view, const PuglRect frame)
{
if (view->impl->hwnd) {
- RECT rect = {(long)frame.x,
- (long)frame.y,
- (long)frame.x + (long)frame.width,
- (long)frame.y + (long)frame.height};
-
- AdjustWindowRectEx(
- &rect, puglWinGetWindowFlags(view), FALSE, puglWinGetWindowExFlags(view));
+ const RECT rect =
+ adjustedWindowRect(view, frame.x, frame.y, frame.width, frame.height);
if (!SetWindowPos(view->impl->hwnd,
HWND_TOP,
@@ -1012,12 +1022,68 @@ puglSetFrame(PuglView* view, const PuglRect frame)
}
PuglStatus
+puglSetPosition(PuglView* const view, const int x, const int y)
+{
+ if (x > INT16_MAX || y > INT16_MAX) {
+ return PUGL_BAD_PARAMETER;
+ }
+
+ if (view->impl->hwnd) {
+ const RECT rect =
+ adjustedWindowRect(view, x, y, view->frame.width, view->frame.height);
+
+ if (!SetWindowPos(view->impl->hwnd,
+ HWND_TOP,
+ rect.left,
+ rect.top,
+ 0,
+ 0,
+ SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOZORDER |
+ SWP_NOSIZE)) {
+ return PUGL_UNKNOWN_ERROR;
+ }
+ }
+
+ view->frame.x = (PuglCoord)x;
+ view->frame.y = (PuglCoord)y;
+ return PUGL_SUCCESS;
+}
+
+PuglStatus
+puglSetSize(PuglView* const view, const unsigned width, const unsigned height)
+{
+ if (width > INT16_MAX || height > INT16_MAX) {
+ return PUGL_BAD_PARAMETER;
+ }
+
+ if (view->impl->hwnd) {
+ const RECT rect = adjustedWindowRect(
+ view, view->frame.x, view->frame.y, (long)width, (long)height);
+
+ if (!SetWindowPos(view->impl->hwnd,
+ HWND_TOP,
+ 0,
+ 0,
+ rect.right - rect.left,
+ rect.bottom - rect.top,
+ SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOZORDER |
+ SWP_NOMOVE)) {
+ return PUGL_UNKNOWN_ERROR;
+ }
+ }
+
+ view->frame.width = (PuglSpan)width;
+ view->frame.height = (PuglSpan)height;
+ return PUGL_SUCCESS;
+}
+
+PuglStatus
puglSetSizeHint(PuglView* const view,
const PuglSizeHint hint,
const PuglSpan width,
const PuglSpan height)
{
- if ((unsigned)hint > (unsigned)PUGL_MAX_ASPECT || width < 0 || height < 0) {
+ if ((unsigned)hint > (unsigned)PUGL_MAX_ASPECT) {
return PUGL_BAD_PARAMETER;
}
diff --git a/src/x11.c b/src/x11.c
index f5a5461..5ae6b12 100644
--- a/src/x11.c
+++ b/src/x11.c
@@ -1026,11 +1026,15 @@ mergeExposeEvents(PuglExposeEvent* const dst, const PuglExposeEvent* const src)
if (!dst->type) {
*dst = *src;
} else {
- const double max_x = MAX(dst->x + dst->width, src->x + src->width);
- const double max_y = MAX(dst->y + dst->height, src->y + src->height);
-
- dst->x = MIN(dst->x, src->x);
- dst->y = MIN(dst->y, src->y);
+ const int dst_r = dst->x + dst->width;
+ const int src_r = src->x + src->width;
+ const int max_x = MAX(dst_r, src_r);
+ const int dst_b = dst->y + dst->height;
+ const int src_b = src->y + src->height;
+ const int max_y = MAX(dst_b, src_b);
+
+ dst->x = (PuglCoord)MIN(dst->x, src->x);
+ dst->y = (PuglCoord)MIN(dst->y, src->y);
dst->width = (PuglSpan)(max_x - dst->x);
dst->height = (PuglSpan)(max_y - dst->y);
}
@@ -1382,6 +1386,45 @@ puglSetFrame(PuglView* const view, const PuglRect frame)
}
PuglStatus
+puglSetPosition(PuglView* const view, const int x, const int y)
+{
+ Display* const display = view->world->impl->display;
+ const Window win = view->impl->win;
+
+ if (x > INT16_MAX || y > INT16_MAX) {
+ return PUGL_BAD_PARAMETER;
+ }
+
+ if (win && !XMoveWindow(display, win, x, y)) {
+ return PUGL_UNKNOWN_ERROR;
+ }
+
+ view->frame.x = (PuglCoord)x;
+ view->frame.y = (PuglCoord)y;
+ return PUGL_SUCCESS;
+}
+
+PuglStatus
+puglSetSize(PuglView* const view, const unsigned width, const unsigned height)
+{
+ Display* const display = view->world->impl->display;
+ const Window win = view->impl->win;
+
+ if (width > INT16_MAX || height > INT16_MAX) {
+ return PUGL_BAD_PARAMETER;
+ }
+
+ if (win) {
+ return XResizeWindow(display, win, width, height) ? PUGL_SUCCESS
+ : PUGL_UNKNOWN_ERROR;
+ }
+
+ view->frame.width = (PuglSpan)width;
+ view->frame.height = (PuglSpan)height;
+ return PUGL_SUCCESS;
+}
+
+PuglStatus
puglSetSizeHint(PuglView* const view,
const PuglSizeHint hint,
const PuglSpan width,