aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2022-05-20 14:23:41 -0400
committerDavid Robillard <d@drobilla.net>2022-05-21 16:49:47 -0400
commit1cd37cad0a06fbb15c44fd59dd6b2c12a0812a76 (patch)
treed7760c11195b003dc27a6f86f0c47df51c0a32da /src
parent0fc1422e858bf9849b84aee2abeca3b553214b73 (diff)
downloadpugl-1cd37cad0a06fbb15c44fd59dd6b2c12a0812a76.tar.gz
pugl-1cd37cad0a06fbb15c44fd59dd6b2c12a0812a76.tar.bz2
pugl-1cd37cad0a06fbb15c44fd59dd6b2c12a0812a76.zip
Add a uniform API for setting size hints
This collapses many functions into one, which makes the API more easily extensible and reduces code size.
Diffstat (limited to 'src')
-rw-r--r--src/implementation.c6
-rw-r--r--src/mac.m140
-rw-r--r--src/types.h17
-rw-r--r--src/win.c72
-rw-r--r--src/x11.c91
5 files changed, 145 insertions, 181 deletions
diff --git a/src/implementation.c b/src/implementation.c
index 166aebd..c3394ce 100644
--- a/src/implementation.c
+++ b/src/implementation.c
@@ -139,9 +139,9 @@ puglNewView(PuglWorld* const world)
return NULL;
}
- view->world = world;
- view->minWidth = 1;
- view->minHeight = 1;
+ view->world = world;
+ view->sizeHints[PUGL_MIN_SIZE].width = 1;
+ view->sizeHints[PUGL_MIN_SIZE].height = 1;
puglSetDefaultHints(view->hints);
diff --git a/src/mac.m b/src/mac.m
index 1040aa7..5f60339 100644
--- a/src/mac.m
+++ b/src/mac.m
@@ -220,12 +220,11 @@ updateViewRect(PuglView* view)
- (NSSize)intrinsicContentSize
{
- if (puglview->defaultWidth || puglview->defaultHeight) {
- return sizePoints(
- puglview, puglview->defaultWidth, puglview->defaultHeight);
- }
+ const PuglViewSize defaultSize = puglview->sizeHints[PUGL_DEFAULT_SIZE];
- return NSMakeSize(NSViewNoInstrinsicMetric, NSViewNoInstrinsicMetric);
+ return (defaultSize.width && defaultSize.height)
+ ? sizePoints(puglview, defaultSize.width, defaultSize.height)
+ : NSMakeSize(NSViewNoInstrinsicMetric, NSViewNoInstrinsicMetric);
}
- (BOOL)isFlipped
@@ -889,6 +888,47 @@ puglConstraint(const id item,
constant:(CGFloat)constant];
}
+static PuglStatus
+updateSizeHint(PuglView* const view, const PuglSizeHint hint)
+{
+ const PuglSpan width = view->sizeHints[hint].width;
+ const PuglSpan height = view->sizeHints[hint].height;
+ if (!width || !height) {
+ return PUGL_FAILURE;
+ }
+
+ switch (hint) {
+ case PUGL_DEFAULT_SIZE:
+ break;
+
+ case PUGL_MIN_SIZE:
+ [view->impl->window setContentMinSize:sizePoints(view, width, height)];
+ break;
+
+ case PUGL_MAX_SIZE:
+ [view->impl->window setContentMaxSize:sizePoints(view, width, height)];
+ break;
+
+ case PUGL_FIXED_ASPECT:
+ [view->impl->window setContentAspectRatio:sizePoints(view, width, height)];
+ break;
+
+ case PUGL_MIN_ASPECT:
+ case PUGL_MAX_ASPECT:
+ break;
+ }
+
+ return PUGL_SUCCESS;
+}
+
+static void
+updateSizeHints(PuglView* const view)
+{
+ for (unsigned i = 0u; i <= PUGL_MAX_ASPECT; ++i) {
+ updateSizeHint(view, (PuglSizeHint)i);
+ }
+}
+
PuglStatus
puglRealize(PuglView* view)
{
@@ -935,15 +975,16 @@ puglRealize(PuglView* view)
}
if (view->frame.width == 0.0 && view->frame.height == 0.0) {
- if (view->defaultWidth == 0.0 && view->defaultHeight == 0.0) {
+ const PuglViewSize defaultSize = view->sizeHints[PUGL_DEFAULT_SIZE];
+ if (!defaultSize.width || !defaultSize.height) {
return PUGL_BAD_CONFIGURATION;
}
const double screenWidthPx = [screen frame].size.width * scaleFactor;
const double screenHeightPx = [screen frame].size.height * scaleFactor;
- view->frame.width = view->defaultWidth;
- view->frame.height = view->defaultHeight;
+ view->frame.width = defaultSize.width;
+ view->frame.height = defaultSize.height;
view->frame.x = screenWidthPx / 2.0 - view->frame.width / 2.0;
view->frame.y = screenHeightPx / 2.0 - view->frame.height / 2.0;
}
@@ -966,26 +1007,27 @@ puglRealize(PuglView* view)
addConstraint:puglConstraint(impl->wrapperView,
NSLayoutAttributeWidth,
NSLayoutRelationGreaterThanOrEqual,
- view->minWidth)];
+ view->sizeHints[PUGL_MIN_SIZE].width)];
[impl->wrapperView
addConstraint:puglConstraint(impl->wrapperView,
NSLayoutAttributeHeight,
NSLayoutRelationGreaterThanOrEqual,
- view->minHeight)];
+ view->sizeHints[PUGL_MIN_SIZE].height)];
- if (view->maxWidth && view->maxHeight) {
+ if (view->sizeHints[PUGL_MAX_SIZE].width &&
+ view->sizeHints[PUGL_MAX_SIZE].height) {
[impl->wrapperView
addConstraint:puglConstraint(impl->wrapperView,
NSLayoutAttributeWidth,
NSLayoutRelationLessThanOrEqual,
- view->maxWidth)];
+ view->sizeHints[PUGL_MAX_SIZE].width)];
[impl->wrapperView
addConstraint:puglConstraint(impl->wrapperView,
NSLayoutAttributeHeight,
NSLayoutRelationLessThanOrEqual,
- view->maxHeight)];
+ view->sizeHints[PUGL_MAX_SIZE].height)];
}
// Create draw view to be rendered to
@@ -1028,21 +1070,12 @@ puglRealize(PuglView* view)
[window setTitle:titleString];
}
- if (view->minWidth || view->minHeight) {
- [window
- setContentMinSize:sizePoints(view, view->minWidth, view->minHeight)];
- }
- impl->window = window;
-
((NSWindow*)window).delegate =
[[PuglWindowDelegate alloc] initWithPuglWindow:window];
- if (view->minAspectX && view->minAspectY) {
- [window setContentAspectRatio:sizePoints(view,
- view->minAspectX,
- view->minAspectY)];
- }
+ impl->window = window;
+ updateSizeHints(view);
puglSetFrame(view, view->frame);
[window setContentView:impl->wrapperView];
@@ -1358,60 +1391,19 @@ puglSetFrame(PuglView* view, const PuglRect frame)
}
PuglStatus
-puglSetDefaultSize(PuglView* const view, const int width, const int height)
-{
- view->defaultWidth = width;
- view->defaultHeight = height;
- return PUGL_SUCCESS;
-}
-
-PuglStatus
-puglSetMinSize(PuglView* const view, const int width, const int height)
-{
- view->minWidth = width;
- view->minHeight = height;
-
- if (view->impl->window && (view->minWidth || view->minHeight)) {
- [view->impl->window
- setContentMinSize:sizePoints(view, view->minWidth, view->minHeight)];
- }
-
- return PUGL_SUCCESS;
-}
-
-PuglStatus
-puglSetMaxSize(PuglView* const view, const int width, const int height)
+puglSetSizeHint(PuglView* const view,
+ const PuglSizeHint hint,
+ const PuglSpan width,
+ const PuglSpan height)
{
- view->maxWidth = width;
- view->maxHeight = height;
-
- if (view->impl->window && (view->maxWidth || view->maxHeight)) {
- [view->impl->window
- setContentMaxSize:sizePoints(view, view->maxWidth, view->maxHeight)];
+ if ((unsigned)hint > (unsigned)PUGL_MAX_ASPECT) {
+ return PUGL_BAD_PARAMETER;
}
- return PUGL_SUCCESS;
-}
+ view->sizeHints[hint].width = width;
+ view->sizeHints[hint].height = height;
-PuglStatus
-puglSetAspectRatio(PuglView* const view,
- const int minX,
- const int minY,
- const int maxX,
- const int maxY)
-{
- view->minAspectX = minX;
- view->minAspectY = minY;
- view->maxAspectX = maxX;
- view->maxAspectY = maxY;
-
- if (view->impl->window && view->minAspectX && view->minAspectY) {
- [view->impl->window setContentAspectRatio:sizePoints(view,
- view->minAspectX,
- view->minAspectY)];
- }
-
- return PUGL_SUCCESS;
+ return view->impl->window ? updateSizeHint(view, hint) : PUGL_SUCCESS;
}
PuglStatus
diff --git a/src/types.h b/src/types.h
index 67e9eef..0187dad 100644
--- a/src/types.h
+++ b/src/types.h
@@ -21,6 +21,12 @@ typedef struct PuglInternalsImpl PuglInternals;
/// View hints
typedef int PuglHints[PUGL_NUM_VIEW_HINTS];
+/// View size (both X and Y coordinates)
+typedef struct {
+ PuglSpan width;
+ PuglSpan height;
+} PuglViewSize;
+
/// Blob of arbitrary data
typedef struct {
void* data; ///< Dynamically allocated data
@@ -41,16 +47,7 @@ struct PuglViewImpl {
PuglRect frame;
PuglConfigureEvent lastConfigure;
PuglHints hints;
- int defaultWidth;
- int defaultHeight;
- int minWidth;
- int minHeight;
- int maxWidth;
- int maxHeight;
- int minAspectX;
- int minAspectY;
- int maxAspectX;
- int maxAspectY;
+ PuglViewSize sizeHints[(unsigned)PUGL_MAX_ASPECT + 1u];
bool visible;
};
diff --git a/src/win.c b/src/win.c
index 40a5cb7..4c36afe 100644
--- a/src/win.c
+++ b/src/win.c
@@ -522,8 +522,11 @@ constrainAspect(const PuglView* const view,
RECT* const size,
const WPARAM wParam)
{
- const float minA = (float)view->minAspectX / (float)view->minAspectY;
- const float maxA = (float)view->maxAspectX / (float)view->maxAspectY;
+ const PuglViewSize minAspect = view->sizeHints[PUGL_MIN_ASPECT];
+ const PuglViewSize maxAspect = view->sizeHints[PUGL_MAX_ASPECT];
+
+ const float minA = (float)minAspect.width / (float)minAspect.height;
+ const float maxA = (float)maxAspect.width / (float)maxAspect.height;
const float w = (float)(size->right - size->left);
const float h = (float)(size->bottom - size->top);
const float a = w / h;
@@ -602,7 +605,7 @@ handleMessage(PuglView* view, UINT message, WPARAM wParam, LPARAM lParam)
}
break;
case WM_SIZING:
- if (view->minAspectX) {
+ if (view->sizeHints[PUGL_MIN_ASPECT].width) {
constrainAspect(view, (RECT*)lParam, wParam);
return TRUE;
}
@@ -624,11 +627,12 @@ handleMessage(PuglView* view, UINT message, WPARAM wParam, LPARAM lParam)
break;
case WM_GETMINMAXINFO:
mmi = (MINMAXINFO*)lParam;
- mmi->ptMinTrackSize.x = view->minWidth;
- mmi->ptMinTrackSize.y = view->minHeight;
- if (view->maxWidth > 0 && view->maxHeight > 0) {
- mmi->ptMaxTrackSize.x = view->maxWidth;
- mmi->ptMaxTrackSize.y = view->maxHeight;
+ mmi->ptMinTrackSize.x = view->sizeHints[PUGL_MIN_SIZE].width;
+ mmi->ptMinTrackSize.y = view->sizeHints[PUGL_MIN_SIZE].height;
+ if (view->sizeHints[PUGL_MAX_SIZE].width &&
+ view->sizeHints[PUGL_MAX_SIZE].height) {
+ mmi->ptMaxTrackSize.x = view->sizeHints[PUGL_MAX_SIZE].width;
+ mmi->ptMaxTrackSize.y = view->sizeHints[PUGL_MAX_SIZE].height;
}
break;
case WM_PAINT:
@@ -1008,40 +1012,17 @@ puglSetFrame(PuglView* view, const PuglRect frame)
}
PuglStatus
-puglSetDefaultSize(PuglView* const view, const int width, const int height)
+puglSetSizeHint(PuglView* const view,
+ const PuglSizeHint hint,
+ const PuglSpan width,
+ const PuglSpan height)
{
- view->defaultWidth = width;
- view->defaultHeight = height;
- return PUGL_SUCCESS;
-}
-
-PuglStatus
-puglSetMinSize(PuglView* const view, const int width, const int height)
-{
- view->minWidth = width;
- view->minHeight = height;
- return PUGL_SUCCESS;
-}
-
-PuglStatus
-puglSetMaxSize(PuglView* const view, const int width, const int height)
-{
- view->maxWidth = width;
- view->maxHeight = height;
- return PUGL_SUCCESS;
-}
+ if ((unsigned)hint > (unsigned)PUGL_MAX_ASPECT || width < 0 || height < 0) {
+ return PUGL_BAD_PARAMETER;
+ }
-PuglStatus
-puglSetAspectRatio(PuglView* const view,
- const int minX,
- const int minY,
- const int maxX,
- const int maxY)
-{
- view->minAspectX = minX;
- view->minAspectY = minY;
- view->maxAspectX = maxX;
- view->maxAspectY = maxY;
+ view->sizeHints[hint].width = width;
+ view->sizeHints[hint].height = height;
return PUGL_SUCCESS;
}
@@ -1206,7 +1187,8 @@ puglWinCreateWindow(PuglView* const view,
const unsigned winExFlags = puglWinGetWindowExFlags(view);
if (view->frame.width <= 0.0 && view->frame.height <= 0.0) {
- if (view->defaultWidth <= 0.0 && view->defaultHeight <= 0.0) {
+ const PuglViewSize defaultSize = view->sizeHints[PUGL_DEFAULT_SIZE];
+ if (!defaultSize.width || !defaultSize.height) {
return PUGL_BAD_CONFIGURATION;
}
@@ -1216,10 +1198,10 @@ puglWinCreateWindow(PuglView* const view,
const int screenWidth = desktopRect.right - desktopRect.left;
const int screenHeight = desktopRect.bottom - desktopRect.top;
- view->frame.width = view->defaultWidth;
- view->frame.height = view->defaultHeight;
- view->frame.x = screenWidth / 2.0 - view->frame.width / 2.0;
- view->frame.y = screenHeight / 2.0 - view->frame.height / 2.0;
+ view->frame.width = defaultSize.width;
+ view->frame.height = defaultSize.height;
+ view->frame.x = (screenWidth - view->frame.width) / 2.0;
+ view->frame.y = (screenHeight - view->frame.height) / 2.0;
}
// The meaning of "parent" depends on the window type (WS_CHILD)
diff --git a/src/x11.c b/src/x11.c
index 64397bd..76a23de 100644
--- a/src/x11.c
+++ b/src/x11.c
@@ -224,30 +224,45 @@ updateSizeHints(const PuglView* const view)
sizeHints.max_width = (int)view->frame.width;
sizeHints.max_height = (int)view->frame.height;
} else {
- if (view->defaultWidth || view->defaultHeight) {
+ const PuglViewSize defaultSize = view->sizeHints[PUGL_DEFAULT_SIZE];
+ if (defaultSize.width && defaultSize.height) {
sizeHints.flags |= PBaseSize;
- sizeHints.base_width = view->defaultWidth;
- sizeHints.base_height = view->defaultHeight;
+ sizeHints.base_width = defaultSize.width;
+ sizeHints.base_height = defaultSize.height;
}
- if (view->minWidth || view->minHeight) {
+ const PuglViewSize minSize = view->sizeHints[PUGL_MIN_SIZE];
+ if (minSize.width && minSize.height) {
sizeHints.flags |= PMinSize;
- sizeHints.min_width = view->minWidth;
- sizeHints.min_height = view->minHeight;
+ sizeHints.min_width = minSize.width;
+ sizeHints.min_height = minSize.height;
}
- if (view->maxWidth || view->maxHeight) {
+ const PuglViewSize maxSize = view->sizeHints[PUGL_MAX_SIZE];
+ if (maxSize.width && maxSize.height) {
sizeHints.flags |= PMaxSize;
- sizeHints.max_width = view->maxWidth;
- sizeHints.max_height = view->maxHeight;
+ sizeHints.max_width = maxSize.width;
+ sizeHints.max_height = maxSize.height;
}
- if (view->minAspectX) {
+ const PuglViewSize minAspect = view->sizeHints[PUGL_MIN_ASPECT];
+ const PuglViewSize maxAspect = view->sizeHints[PUGL_MAX_ASPECT];
+ if (minAspect.width && minAspect.height && maxAspect.width &&
+ maxAspect.height) {
sizeHints.flags |= PAspect;
- sizeHints.min_aspect.x = view->minAspectX;
- sizeHints.min_aspect.y = view->minAspectY;
- sizeHints.max_aspect.x = view->maxAspectX;
- sizeHints.max_aspect.y = view->maxAspectY;
+ sizeHints.min_aspect.x = minAspect.width;
+ sizeHints.min_aspect.y = minAspect.height;
+ sizeHints.max_aspect.x = maxAspect.width;
+ sizeHints.max_aspect.y = maxAspect.height;
+ }
+
+ const PuglViewSize fixedAspect = view->sizeHints[PUGL_FIXED_ASPECT];
+ if (fixedAspect.width && fixedAspect.height) {
+ sizeHints.flags |= PAspect;
+ sizeHints.min_aspect.x = fixedAspect.width;
+ sizeHints.min_aspect.y = fixedAspect.height;
+ sizeHints.max_aspect.x = fixedAspect.width;
+ sizeHints.max_aspect.y = fixedAspect.height;
}
}
@@ -314,12 +329,13 @@ puglRealize(PuglView* const view)
// Set the size to the default if it has not already been set
if (view->frame.width <= 0.0 && view->frame.height <= 0.0) {
- if (view->defaultWidth <= 0.0 || view->defaultHeight <= 0.0) {
+ const PuglViewSize defaultSize = view->sizeHints[PUGL_DEFAULT_SIZE];
+ if (!defaultSize.width || !defaultSize.height) {
return PUGL_BAD_CONFIGURATION;
}
- view->frame.width = view->defaultWidth;
- view->frame.height = view->defaultHeight;
+ view->frame.width = defaultSize.width;
+ view->frame.height = defaultSize.height;
}
// Center top-level windows if a position has not been set
@@ -1366,40 +1382,17 @@ puglSetFrame(PuglView* const view, const PuglRect frame)
}
PuglStatus
-puglSetDefaultSize(PuglView* const view, const int width, const int height)
-{
- view->defaultWidth = width;
- view->defaultHeight = height;
- return updateSizeHints(view);
-}
-
-PuglStatus
-puglSetMinSize(PuglView* const view, const int width, const int height)
+puglSetSizeHint(PuglView* const view,
+ const PuglSizeHint hint,
+ const PuglSpan width,
+ const PuglSpan height)
{
- view->minWidth = width;
- view->minHeight = height;
- return updateSizeHints(view);
-}
-
-PuglStatus
-puglSetMaxSize(PuglView* const view, const int width, const int height)
-{
- view->maxWidth = width;
- view->maxHeight = height;
- return updateSizeHints(view);
-}
+ if ((unsigned)hint > (unsigned)PUGL_MAX_ASPECT) {
+ return PUGL_BAD_PARAMETER;
+ }
-PuglStatus
-puglSetAspectRatio(PuglView* const view,
- const int minX,
- const int minY,
- const int maxX,
- const int maxY)
-{
- view->minAspectX = minX;
- view->minAspectY = minY;
- view->maxAspectX = maxX;
- view->maxAspectY = maxY;
+ view->sizeHints[hint].width = width;
+ view->sizeHints[hint].height = height;
return updateSizeHints(view);
}