[osx] settle on consistent API for getting/setting window rect
This commit is contained in:
parent
06b5d30dc6
commit
1fd9d17e82
|
@ -9,4 +9,6 @@ INCLUDES="-I$SRCDIR -I$SRCDIR/util -I$SRCDIR/platform -I$SRCDIR/app"
|
||||||
LIBS="-L$BINDIR -lmilepost -framework Carbon -framework Cocoa -framework Metal -framework QuartzCore"
|
LIBS="-L$BINDIR -lmilepost -framework Carbon -framework Cocoa -framework Metal -framework QuartzCore"
|
||||||
FLAGS="-mmacos-version-min=10.15.4 -DDEBUG -DLOG_COMPILE_DEBUG"
|
FLAGS="-mmacos-version-min=10.15.4 -DDEBUG -DLOG_COMPILE_DEBUG"
|
||||||
|
|
||||||
clang -g $FLAGS -Wl,-dead_strip $LIBS $INCLUDES -o test main.c
|
clang -g $FLAGS -Wl,-dead_strip $LIBS $INCLUDES -o $BINDIR/example_simple_window main.c
|
||||||
|
|
||||||
|
install_name_tool -add_rpath "@executable_path" $BINDIR/example_simple_window
|
||||||
|
|
|
@ -37,36 +37,44 @@ int main()
|
||||||
|
|
||||||
case MP_EVENT_WINDOW_RESIZE:
|
case MP_EVENT_WINDOW_RESIZE:
|
||||||
{
|
{
|
||||||
printf("resized, rect = {%f, %f, %f, %f}\n",
|
printf("resized, frame = {%f, %f, %f, %f}, content = {%f, %f, %f, %f}\n",
|
||||||
event->frame.rect.x,
|
event->move.frame.x,
|
||||||
event->frame.rect.y,
|
event->move.frame.y,
|
||||||
event->frame.rect.w,
|
event->move.frame.w,
|
||||||
event->frame.rect.h);
|
event->move.frame.h,
|
||||||
|
event->move.content.x,
|
||||||
|
event->move.content.y,
|
||||||
|
event->move.content.w,
|
||||||
|
event->move.content.h);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case MP_EVENT_WINDOW_MOVE:
|
case MP_EVENT_WINDOW_MOVE:
|
||||||
{
|
{
|
||||||
printf("moved, rect = {%f, %f, %f, %f}\n",
|
printf("moved, frame = {%f, %f, %f, %f}, content = {%f, %f, %f, %f}\n",
|
||||||
event->frame.rect.x,
|
event->move.frame.x,
|
||||||
event->frame.rect.y,
|
event->move.frame.y,
|
||||||
event->frame.rect.w,
|
event->move.frame.w,
|
||||||
event->frame.rect.h);
|
event->move.frame.h,
|
||||||
|
event->move.content.x,
|
||||||
|
event->move.content.y,
|
||||||
|
event->move.content.w,
|
||||||
|
event->move.content.h);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case MP_EVENT_MOUSE_MOVE:
|
case MP_EVENT_MOUSE_MOVE:
|
||||||
{
|
{
|
||||||
printf("mouse moved, pos = {%f, %f}, delta = {%f, %f}\n",
|
printf("mouse moved, pos = {%f, %f}, delta = {%f, %f}\n",
|
||||||
event->move.x,
|
event->mouse.x,
|
||||||
event->move.y,
|
event->mouse.y,
|
||||||
event->move.deltaX,
|
event->mouse.deltaX,
|
||||||
event->move.deltaY);
|
event->mouse.deltaY);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case MP_EVENT_MOUSE_WHEEL:
|
case MP_EVENT_MOUSE_WHEEL:
|
||||||
{
|
{
|
||||||
printf("mouse wheel, delta = {%f, %f}\n",
|
printf("mouse wheel, delta = {%f, %f}\n",
|
||||||
event->move.deltaX,
|
event->mouse.deltaX,
|
||||||
event->move.deltaY);
|
event->mouse.deltaY);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case MP_EVENT_MOUSE_ENTER:
|
case MP_EVENT_MOUSE_ENTER:
|
||||||
|
|
13
src/mp_app.h
13
src/mp_app.h
|
@ -234,7 +234,7 @@ typedef struct mp_mouse_event // mouse move/scroll
|
||||||
typedef struct mp_move_event // window resize / move
|
typedef struct mp_move_event // window resize / move
|
||||||
{
|
{
|
||||||
mp_rect frame;
|
mp_rect frame;
|
||||||
mp_rect contents;
|
mp_rect content;
|
||||||
} mp_move_event;
|
} mp_move_event;
|
||||||
|
|
||||||
typedef struct mp_event
|
typedef struct mp_event
|
||||||
|
@ -315,10 +315,15 @@ MP_API void mp_window_unfocus(mp_window window);
|
||||||
MP_API void mp_window_send_to_back(mp_window window);
|
MP_API void mp_window_send_to_back(mp_window window);
|
||||||
MP_API void mp_window_bring_to_front(mp_window window);
|
MP_API void mp_window_bring_to_front(mp_window window);
|
||||||
|
|
||||||
MP_API mp_rect mp_window_get_content_rect(mp_window window);
|
|
||||||
MP_API mp_rect mp_window_get_frame_rect(mp_window window);
|
MP_API mp_rect mp_window_get_frame_rect(mp_window window);
|
||||||
MP_API void mp_window_set_content_rect(mp_window window, mp_rect contentRect);
|
MP_API void mp_window_set_frame_rect(mp_window window, mp_rect rect);
|
||||||
MP_API void mp_window_set_frame_rect(mp_window window, mp_rect frameRect);
|
MP_API void mp_window_set_frame_position(mp_window window, vec2 position);
|
||||||
|
MP_API void mp_window_set_frame_size(mp_window window, vec2 size);
|
||||||
|
|
||||||
|
MP_API mp_rect mp_window_get_content_rect(mp_window window);
|
||||||
|
MP_API void mp_window_set_content_rect(mp_window window, mp_rect rect);
|
||||||
|
MP_API void mp_window_set_content_position(mp_window window, vec2 position);
|
||||||
|
MP_API void mp_window_set_content_size(mp_window window, vec2 size);
|
||||||
|
|
||||||
MP_API void mp_window_center(mp_window window);
|
MP_API void mp_window_center(mp_window window);
|
||||||
|
|
||||||
|
|
217
src/osx_app.m
217
src/osx_app.m
|
@ -26,24 +26,6 @@
|
||||||
// mp window struct and utility functions
|
// mp window struct and utility functions
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
|
|
||||||
static mp_rect mp_osx_to_user_screen_rect(NSScreen* screen, mp_rect rect)
|
|
||||||
{
|
|
||||||
@autoreleasepool
|
|
||||||
{
|
|
||||||
rect.y = screen.frame.size.height - rect.y - rect.h;
|
|
||||||
}
|
|
||||||
return(rect);
|
|
||||||
}
|
|
||||||
|
|
||||||
static mp_rect mp_user_to_osx_screen_rect(NSScreen* screen, mp_rect rect)
|
|
||||||
{
|
|
||||||
@autoreleasepool
|
|
||||||
{
|
|
||||||
rect.y = screen.frame.size.height - rect.y - rect.h;
|
|
||||||
}
|
|
||||||
return(rect);
|
|
||||||
}
|
|
||||||
|
|
||||||
static u32 mp_osx_get_window_style_mask(mp_window_style style)
|
static u32 mp_osx_get_window_style_mask(mp_window_style style)
|
||||||
{
|
{
|
||||||
u32 mask = 0;
|
u32 mask = 0;
|
||||||
|
@ -644,15 +626,15 @@ void mp_install_keyboard_layout_listener()
|
||||||
event.window = mp_window_handle_from_ptr(mpWindow);
|
event.window = mp_window_handle_from_ptr(mpWindow);
|
||||||
event.type = MP_EVENT_WINDOW_MOVE;
|
event.type = MP_EVENT_WINDOW_MOVE;
|
||||||
|
|
||||||
event.move.frame.x = contentRect.origin.x;
|
event.move.frame.x = frameRect.origin.x;
|
||||||
event.move.frame.y = screen.frame.size.height - frameRect.origin.y - frameRect.size.height;
|
event.move.frame.y = screen.frame.size.height - frameRect.origin.y - frameRect.size.height;
|
||||||
event.move.frame.w = contentRect.size.width;
|
event.move.frame.w = frameRect.size.width;
|
||||||
event.move.frame.h = contentRect.size.height;
|
event.move.frame.h = frameRect.size.height;
|
||||||
|
|
||||||
event.move.contents.x = contentRect.origin.x;
|
event.move.content.x = frameRect.origin.x + contentRect.origin.x;
|
||||||
event.move.contents.y = frameRect.size.height - contentRect.origin.y - contentRect.size.height;
|
event.move.content.y = screen.frame.size.height - frameRect.origin.y - contentRect.origin.y - contentRect.size.height;
|
||||||
event.move.contents.w = contentRect.size.width;
|
event.move.content.w = contentRect.size.width;
|
||||||
event.move.contents.h = contentRect.size.height;
|
event.move.content.h = contentRect.size.height;
|
||||||
|
|
||||||
mp_queue_event(&event);
|
mp_queue_event(&event);
|
||||||
}
|
}
|
||||||
|
@ -667,15 +649,15 @@ void mp_install_keyboard_layout_listener()
|
||||||
event.window = mp_window_handle_from_ptr(mpWindow);
|
event.window = mp_window_handle_from_ptr(mpWindow);
|
||||||
event.type = MP_EVENT_WINDOW_RESIZE;
|
event.type = MP_EVENT_WINDOW_RESIZE;
|
||||||
|
|
||||||
event.move.frame.x = contentRect.origin.x;
|
event.move.frame.x = frameRect.origin.x;
|
||||||
event.move.frame.y = screen.frame.size.height - frameRect.origin.y - frameRect.size.height;
|
event.move.frame.y = screen.frame.size.height - frameRect.origin.y - frameRect.size.height;
|
||||||
event.move.frame.w = contentRect.size.width;
|
event.move.frame.w = frameRect.size.width;
|
||||||
event.move.frame.h = contentRect.size.height;
|
event.move.frame.h = frameRect.size.height;
|
||||||
|
|
||||||
event.move.contents.x = contentRect.origin.x;
|
event.move.content.x = frameRect.origin.x + contentRect.origin.x;
|
||||||
event.move.contents.y = frameRect.size.height - contentRect.origin.y - contentRect.size.height;
|
event.move.content.y = screen.frame.size.height - frameRect.origin.y - contentRect.origin.y - contentRect.size.height;
|
||||||
event.move.contents.w = contentRect.size.width;
|
event.move.content.w = contentRect.size.width;
|
||||||
event.move.contents.h = contentRect.size.height;
|
event.move.content.h = contentRect.size.height;
|
||||||
|
|
||||||
if(__mpApp.liveResizeCallback)
|
if(__mpApp.liveResizeCallback)
|
||||||
{
|
{
|
||||||
|
@ -1323,15 +1305,6 @@ str8 mp_clipboard_get_data_for_tag(mem_arena* arena, const char* tag)
|
||||||
// Window public API
|
// Window public API
|
||||||
//---------------------------------------------------------------
|
//---------------------------------------------------------------
|
||||||
|
|
||||||
/*
|
|
||||||
//TODO(martin): review include scheme
|
|
||||||
extern "C" {
|
|
||||||
mp_graphics_surface mp_metal_surface_create_for_window_ptr(mp_window_data* window);
|
|
||||||
mp_graphics_surface mp_graphics_surface_null_handle();
|
|
||||||
mp_graphics_surface mp_graphics_surface_handle_from_ptr(mp_graphics_surface_data* surface);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
mp_window mp_window_create(mp_rect contentRect, const char* title, mp_window_style style)
|
mp_window mp_window_create(mp_rect contentRect, const char* title, mp_window_style style)
|
||||||
{@autoreleasepool{
|
{@autoreleasepool{
|
||||||
mp_window_data* window = mp_window_alloc();
|
mp_window_data* window = mp_window_alloc();
|
||||||
|
@ -1536,123 +1509,113 @@ void mp_window_bring_to_front_and_focus(mp_window window)
|
||||||
mp_window_focus(window);
|
mp_window_focus(window);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
mp_rect mp_window_content_rect_for_frame_rect(mp_rect frameRect, mp_window_style style)
|
|
||||||
{@autoreleasepool{
|
|
||||||
u32 mask = mp_osx_get_window_style_mask(style);
|
|
||||||
mp_rect nativeFrame = mp_user_to_osx_screen_rect([NSScreen mainScreen], frameRect);
|
|
||||||
NSRect frame = NSMakeRect(nativeFrame.x, nativeFrame.y, nativeFrame.w, nativeFrame.h);
|
|
||||||
NSRect content = [NSWindow contentRectForFrameRect:frame styleMask:mask];
|
|
||||||
mp_rect result = {content.origin.x, content.origin.y, content.size.width, content.size.height};
|
|
||||||
result = mp_osx_to_user_screen_rect([NSScreen mainScreen], result);
|
|
||||||
return(result);
|
|
||||||
}}
|
|
||||||
|
|
||||||
mp_rect mp_window_frame_rect_for_content_rect(mp_rect contentRect, mp_window_style style)
|
|
||||||
{@autoreleasepool{
|
|
||||||
uint32 mask = mp_osx_get_window_style_mask(style);
|
|
||||||
mp_rect nativeContent = mp_user_to_osx_screen_rect([NSScreen mainScreen], contentRect);
|
|
||||||
NSRect content = NSMakeRect(nativeContent.x, nativeContent.y, nativeContent.w, nativeContent.h);
|
|
||||||
NSRect frame = [NSWindow frameRectForContentRect:content styleMask:mask];
|
|
||||||
mp_rect result = {frame.origin.x, frame.origin.y, frame.size.width, frame.size.height};
|
|
||||||
result = mp_osx_to_user_screen_rect([NSScreen mainScreen], result);
|
|
||||||
return(result);
|
|
||||||
}}
|
|
||||||
|
|
||||||
mp_rect mp_window_get_content_rect(mp_window window)
|
|
||||||
{
|
|
||||||
mp_window_data* windowData = mp_window_ptr_from_handle(window);
|
|
||||||
if(windowData)
|
|
||||||
{
|
|
||||||
NSRect frameRect = windowData->osx.nsWindow.frame;
|
|
||||||
NSRect contentsRect = [windowData->osx.nsWindow contentView].frame;
|
|
||||||
|
|
||||||
mp_rect rect = {
|
|
||||||
contentsRect.origin.x,
|
|
||||||
frameRect.size.height - contentsRect.origin.y - contentsRect.size.height,
|
|
||||||
contentsRect.size.width,
|
|
||||||
contentsRect.size.height};
|
|
||||||
|
|
||||||
return(rect);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return((mp_rect){});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
mp_rect mp_window_get_frame_rect(mp_window window)
|
mp_rect mp_window_get_frame_rect(mp_window window)
|
||||||
{
|
{
|
||||||
|
mp_rect rect = {0};
|
||||||
mp_window_data* windowData = mp_window_ptr_from_handle(window);
|
mp_window_data* windowData = mp_window_ptr_from_handle(window);
|
||||||
if(windowData)
|
if(windowData)
|
||||||
{
|
{
|
||||||
NSRect frameRect = windowData->osx.nsWindow.frame;
|
NSRect frameRect = windowData->osx.nsWindow.frame;
|
||||||
NSScreen* screen = windowData->osx.nsWindow.screen;
|
NSScreen* screen = windowData->osx.nsWindow.screen;
|
||||||
|
|
||||||
mp_rect osxRect = (mp_rect){frameRect.origin.x, frameRect.origin.y, frameRect.size.width, frameRect.size.height};
|
rect = (mp_rect){
|
||||||
mp_rect rect = mp_osx_to_user_screen_rect(screen, osxRect);
|
frameRect.origin.x,
|
||||||
|
screen.frame.size.height - frameRect.origin.y - frameRect.size.height,
|
||||||
|
frameRect.size.width,
|
||||||
|
frameRect.size.height
|
||||||
|
};
|
||||||
|
}
|
||||||
return(rect);
|
return(rect);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
return((mp_rect){});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void mp_window_set_frame_rect(mp_window window, mp_rect frameRect)
|
void mp_window_set_frame_rect(mp_window window, mp_rect rect)
|
||||||
{@autoreleasepool{
|
{@autoreleasepool{
|
||||||
mp_window_data* windowData = mp_window_ptr_from_handle(window);
|
mp_window_data* windowData = mp_window_ptr_from_handle(window);
|
||||||
if(windowData)
|
if(windowData)
|
||||||
{
|
{
|
||||||
NSScreen* screen = windowData->osx.nsWindow.screen;
|
NSScreen* screen = windowData->osx.nsWindow.screen;
|
||||||
mp_rect nativeRect = mp_user_to_osx_screen_rect(screen, frameRect);
|
NSRect frameRect = {
|
||||||
NSRect frame = NSMakeRect(nativeRect.x, nativeRect.y, nativeRect.w, nativeRect.h);
|
rect.x,
|
||||||
[windowData->osx.nsWindow setFrame:frame display:YES];
|
screen.frame.size.height - rect.y - rect.h,
|
||||||
|
rect.w,
|
||||||
|
rect.h
|
||||||
|
};
|
||||||
|
[windowData->osx.nsWindow setFrame:frameRect display:YES];
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
|
|
||||||
void mp_window_set_content_rect(mp_window window, mp_rect contentRect)
|
void mp_window_set_frame_position(mp_window window, vec2 position)
|
||||||
{@autoreleasepool{
|
|
||||||
|
|
||||||
//TODO: this is a bit inconsistent that this takes a screen-relative rect, while mp_window_get_content_rect
|
|
||||||
// returns a rect relative to the window's frame.
|
|
||||||
|
|
||||||
mp_window_data* windowData = mp_window_ptr_from_handle(window);
|
|
||||||
if(windowData)
|
|
||||||
{
|
|
||||||
u32 mask = mp_osx_get_window_style_mask(windowData->style);
|
|
||||||
|
|
||||||
mp_rect nativeRect = mp_user_to_osx_screen_rect(windowData->osx.nsWindow.screen, contentRect);
|
|
||||||
NSRect content = NSMakeRect(nativeRect.x, nativeRect.y, nativeRect.w, nativeRect.h);
|
|
||||||
NSRect frame = [NSWindow frameRectForContentRect:content styleMask:mask];
|
|
||||||
|
|
||||||
[windowData->osx.nsWindow setFrame:frame display:YES];
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
|
|
||||||
void mp_window_set_frame_size(mp_window window, int width, int height)
|
|
||||||
{
|
{
|
||||||
mp_rect frame = mp_window_get_frame_rect(window);
|
mp_rect frame = mp_window_get_frame_rect(window);
|
||||||
frame.w = width;
|
frame.x = position.x;
|
||||||
frame.h = height;
|
frame.y = position.y;
|
||||||
mp_window_set_frame_rect(window, frame);
|
mp_window_set_frame_rect(window, frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
void mp_window_set_content_size(mp_window window, int width, int height)
|
void mp_window_set_frame_size(mp_window window, vec2 size)
|
||||||
{
|
{
|
||||||
|
mp_rect frame = mp_window_get_frame_rect(window);
|
||||||
|
frame.w = size.x;
|
||||||
|
frame.h = size.y;
|
||||||
|
mp_window_set_frame_rect(window, frame);
|
||||||
|
}
|
||||||
|
|
||||||
|
mp_rect mp_window_get_content_rect(mp_window window)
|
||||||
|
{@autoreleasepool{
|
||||||
mp_window_data* windowData = mp_window_ptr_from_handle(window);
|
mp_window_data* windowData = mp_window_ptr_from_handle(window);
|
||||||
if(windowData)
|
if(windowData)
|
||||||
{
|
{
|
||||||
mp_rect content = mp_window_get_content_rect(window);
|
NSScreen* screen = [windowData->osx.nsWindow screen];
|
||||||
mp_rect frame = mp_window_get_frame_rect(window);
|
NSView* view = [windowData->osx.nsWindow contentView];
|
||||||
|
NSRect contentRect = [windowData->osx.nsWindow convertRectToScreen: view.frame];
|
||||||
|
|
||||||
content.x += frame.x;
|
mp_rect rect = {
|
||||||
content.y += frame.y;
|
contentRect.origin.x,
|
||||||
content.w = width;
|
screen.frame.size.height - contentRect.origin.y - contentRect.size.height,
|
||||||
content.h = height;
|
contentRect.size.width,
|
||||||
|
contentRect.size.height};
|
||||||
|
|
||||||
mp_window_set_content_rect(window, frame);
|
return(rect);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return((mp_rect){});
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
|
||||||
|
void mp_window_set_content_rect(mp_window window, mp_rect rect)
|
||||||
|
{@autoreleasepool{
|
||||||
|
|
||||||
|
mp_window_data* windowData = mp_window_ptr_from_handle(window);
|
||||||
|
if(windowData)
|
||||||
|
{
|
||||||
|
NSScreen* screen = [windowData->osx.nsWindow screen];
|
||||||
|
NSRect contentRect = {
|
||||||
|
rect.x,
|
||||||
|
screen.frame.size.height - rect.y - rect.h,
|
||||||
|
rect.w,
|
||||||
|
rect.h
|
||||||
|
};
|
||||||
|
|
||||||
|
NSRect frameRect = [windowData->osx.nsWindow frameRectForContentRect: contentRect];
|
||||||
|
[windowData->osx.nsWindow setFrame:frameRect display:YES];
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
|
||||||
|
void mp_window_set_content_position(mp_window window, vec2 position)
|
||||||
|
{
|
||||||
|
mp_rect rect = mp_window_get_content_rect(window);
|
||||||
|
rect.x = position.x;
|
||||||
|
rect.y = position.y;
|
||||||
|
mp_window_set_content_rect(window, rect);
|
||||||
|
}
|
||||||
|
|
||||||
|
void mp_window_set_content_size(mp_window window, vec2 size)
|
||||||
|
{
|
||||||
|
mp_rect rect = mp_window_get_content_rect(window);
|
||||||
|
rect.w = size.x;
|
||||||
|
rect.h = size.y;
|
||||||
|
mp_window_set_content_rect(window, rect);
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
|
|
Loading…
Reference in New Issue