From b5034d3c81db915343ac6870514fef52d3fcb16f Mon Sep 17 00:00:00 2001 From: Martin Fouilleul Date: Mon, 28 Aug 2023 15:48:24 +0200 Subject: [PATCH] [osx] implement oc_surface_bring_to_front() and oc_surface_send_to_back() --- sketches/multi_surface/main.c | 18 +++- src/app/osx_app.h | 5 ++ src/app/osx_app.m | 52 ++++++++++- src/graphics/graphics.h | 3 + src/graphics/graphics_surface.c | 18 ++++ src/graphics/graphics_surface.h | 155 ++++++++++++++++---------------- 6 files changed, 173 insertions(+), 78 deletions(-) diff --git a/sketches/multi_surface/main.c b/sketches/multi_surface/main.c index 80d8e99..4c36fe5 100644 --- a/sketches/multi_surface/main.c +++ b/sketches/multi_surface/main.c @@ -65,6 +65,22 @@ int main() } break; + case OC_EVENT_KEYBOARD_KEY: + { + if(event->key.action == OC_KEY_PRESS) + { + if(event->key.code == OC_KEY_UP) + { + oc_surface_bring_to_front(surface2); + } + else if(event->key.code == OC_KEY_DOWN) + { + oc_surface_send_to_back(surface2); + } + } + } + break; + default: break; } @@ -89,7 +105,7 @@ int main() oc_clear(); oc_set_color_rgba(0, 0, 1, 1); - oc_rectangle_fill(300, 300, 300, 200); + oc_rectangle_fill(200, 200, 300, 200); oc_render(surface2, canvas2); //*/ diff --git a/src/app/osx_app.h b/src/app/osx_app.h index 9fdb9ca..de87bd8 100644 --- a/src/app/osx_app.h +++ b/src/app/osx_app.h @@ -32,6 +32,8 @@ typedef struct oc_osx_window_data NSView* nsView; NSObject* nsWindowDelegate; + oc_list layers; + } oc_osx_window_data; #define OC_PLATFORM_WINDOW_DATA oc_osx_window_data osx; @@ -78,6 +80,9 @@ typedef uint32_t CAContextID; typedef struct oc_layer { + oc_window window; + oc_list_elt listElt; + CALayer* caLayer; CAContext* caContext; } oc_layer; diff --git a/src/app/osx_app.m b/src/app/osx_app.m index 57f570c..11d7c24 100644 --- a/src/app/osx_app.m +++ b/src/app/osx_app.m @@ -1311,10 +1311,10 @@ oc_window oc_window_create(oc_rect contentRect, oc_str8 title, oc_window_style s oc_log_error("Could not allocate window data\n"); return ((oc_window){ 0 }); } - window->style = style; window->shouldClose = false; window->hidden = true; + window->osx.layers = (oc_list){ 0 }; u32 styleMask = oc_osx_get_window_style_mask(style); @@ -1735,10 +1735,51 @@ void oc_osx_surface_set_hidden(oc_surface_data* surface, bool hidden) } } +void oc_osx_update_layers(oc_window_data* window) +{ + @autoreleasepool + { + int z = 0; + oc_list_for(&window->osx.layers, layer, oc_layer, listElt) + { + layer->caLayer.zPosition = (CGFloat)z; + z++; + } + } +} + +void oc_osx_surface_bring_to_front(oc_surface_data* surface) +{ + oc_window_data* window = oc_window_ptr_from_handle(surface->layer.window); + if(window) + { + oc_list_remove(&window->osx.layers, &surface->layer.listElt); + oc_list_push_back(&window->osx.layers, &surface->layer.listElt); + oc_osx_update_layers(window); + } +} + +void oc_osx_surface_send_to_back(oc_surface_data* surface) +{ + oc_window_data* window = oc_window_ptr_from_handle(surface->layer.window); + if(window) + { + oc_list_remove(&window->osx.layers, &surface->layer.listElt); + oc_list_push(&window->osx.layers, &surface->layer.listElt); + oc_osx_update_layers(window); + } +} + void oc_surface_cleanup(oc_surface_data* surface) { @autoreleasepool { + oc_window_data* window = oc_window_ptr_from_handle(surface->layer.window); + if(window) + { + oc_list_remove(&window->osx.layers, &surface->layer.listElt); + oc_osx_update_layers(window); + } [surface->layer.caLayer release]; } } @@ -1747,12 +1788,17 @@ void oc_surface_init_for_window(oc_surface_data* surface, oc_window_data* window { @autoreleasepool { + surface->layer.window = oc_window_handle_from_ptr(window); + surface->nativeLayer = oc_osx_surface_native_layer; surface->contentsScaling = oc_osx_surface_contents_scaling; surface->getSize = oc_osx_surface_get_size; surface->getHidden = oc_osx_surface_get_hidden; surface->setHidden = oc_osx_surface_set_hidden; + surface->bringToFront = oc_osx_surface_bring_to_front; + surface->sendToBack = oc_osx_surface_send_to_back; + surface->layer.caLayer = [[CALayer alloc] init]; [surface->layer.caLayer retain]; @@ -1760,10 +1806,12 @@ void oc_surface_init_for_window(oc_surface_data* surface, oc_window_data* window CGSize size = frame.size; surface->layer.caLayer.frame = (CGRect){ { 0, 0 }, size }; surface->layer.caLayer.contentsScale = window->osx.nsView.layer.contentsScale; - surface->layer.caLayer.autoresizingMask = kCALayerWidthSizable | kCALayerHeightSizable; [window->osx.nsView.layer addSublayer:surface->layer.caLayer]; + + oc_list_push_back(&window->osx.layers, &surface->layer.listElt); + oc_osx_update_layers(window); } } diff --git a/src/graphics/graphics.h b/src/graphics/graphics.h index 7598db8..46761a8 100644 --- a/src/graphics/graphics.h +++ b/src/graphics/graphics.h @@ -115,6 +115,9 @@ ORCA_API oc_vec2 oc_surface_contents_scaling(oc_surface surface); ORCA_API bool oc_surface_get_hidden(oc_surface surface); ORCA_API void oc_surface_set_hidden(oc_surface surface, bool hidden); +ORCA_API void oc_surface_bring_to_front(oc_surface surface); +ORCA_API void oc_surface_send_to_back(oc_surface surface); + //NOTE(martin): surface sharing typedef u64 oc_surface_id; diff --git a/src/graphics/graphics_surface.c b/src/graphics/graphics_surface.c index a022523..446f819 100644 --- a/src/graphics/graphics_surface.c +++ b/src/graphics/graphics_surface.c @@ -372,6 +372,24 @@ void oc_surface_render_commands(oc_surface surface, } } +void oc_surface_bring_to_front(oc_surface handle) +{ + oc_surface_data* surface = oc_surface_data_from_handle(handle); + if(surface && surface->bringToFront) + { + surface->bringToFront(surface); + } +} + +void oc_surface_send_to_back(oc_surface handle) +{ + oc_surface_data* surface = oc_surface_data_from_handle(handle); + if(surface && surface->sendToBack) + { + surface->sendToBack(surface); + } +} + //------------------------------------------------------------------------------------------ //NOTE(martin): images //------------------------------------------------------------------------------------------ diff --git a/src/graphics/graphics_surface.h b/src/graphics/graphics_surface.h index ad059dd..7bce53b 100644 --- a/src/graphics/graphics_surface.h +++ b/src/graphics/graphics_surface.h @@ -12,99 +12,104 @@ #include "graphics_common.h" #ifdef __cplusplus -extern "C" -{ +extern "C" { #endif - //--------------------------------------------------------------- - // surface interface - //--------------------------------------------------------------- - typedef struct oc_surface_data oc_surface_data; - typedef struct oc_canvas_backend oc_canvas_backend; +//--------------------------------------------------------------- +// surface interface +//--------------------------------------------------------------- +typedef struct oc_surface_data oc_surface_data; +typedef struct oc_canvas_backend oc_canvas_backend; - typedef void (*oc_surface_destroy_proc)(oc_surface_data* surface); - typedef void (*oc_surface_select_proc)(oc_surface_data* surface); - typedef void (*oc_surface_deselect_proc)(oc_surface_data* surface); - typedef void (*oc_surface_present_proc)(oc_surface_data* surface); - typedef void (*oc_surface_swap_interval_proc)(oc_surface_data* surface, int swap); - typedef oc_vec2 (*oc_surface_get_size_proc)(oc_surface_data* surface); - typedef oc_vec2 (*oc_surface_contents_scaling_proc)(oc_surface_data* surface); - typedef bool (*oc_surface_get_hidden_proc)(oc_surface_data* surface); - typedef void (*oc_surface_set_hidden_proc)(oc_surface_data* surface, bool hidden); - typedef void* (*oc_surface_native_layer_proc)(oc_surface_data* surface); - typedef oc_surface_id (*oc_surface_remote_id_proc)(oc_surface_data* surface); - typedef void (*oc_surface_host_connect_proc)(oc_surface_data* surface, oc_surface_id remoteId); +typedef void (*oc_surface_destroy_proc)(oc_surface_data* surface); +typedef void (*oc_surface_select_proc)(oc_surface_data* surface); +typedef void (*oc_surface_deselect_proc)(oc_surface_data* surface); +typedef void (*oc_surface_present_proc)(oc_surface_data* surface); +typedef void (*oc_surface_swap_interval_proc)(oc_surface_data* surface, int swap); +typedef oc_vec2 (*oc_surface_get_size_proc)(oc_surface_data* surface); +typedef oc_vec2 (*oc_surface_contents_scaling_proc)(oc_surface_data* surface); +typedef bool (*oc_surface_get_hidden_proc)(oc_surface_data* surface); +typedef void (*oc_surface_set_hidden_proc)(oc_surface_data* surface, bool hidden); +typedef void* (*oc_surface_native_layer_proc)(oc_surface_data* surface); +typedef oc_surface_id (*oc_surface_remote_id_proc)(oc_surface_data* surface); +typedef void (*oc_surface_host_connect_proc)(oc_surface_data* surface, oc_surface_id remoteId); - typedef struct oc_surface_data - { - oc_surface_api api; - oc_layer layer; +typedef void (*oc_surface_bring_to_front_proc)(oc_surface_data* surface); +typedef void (*oc_surface_send_to_back_proc)(oc_surface_data* surface); - oc_surface_destroy_proc destroy; - oc_surface_select_proc prepare; - oc_surface_present_proc present; - oc_surface_deselect_proc deselect; - oc_surface_swap_interval_proc swapInterval; - oc_surface_get_size_proc getSize; - oc_surface_contents_scaling_proc contentsScaling; - oc_surface_get_hidden_proc getHidden; - oc_surface_set_hidden_proc setHidden; - oc_surface_native_layer_proc nativeLayer; - oc_surface_remote_id_proc remoteID; - oc_surface_host_connect_proc hostConnect; +typedef struct oc_surface_data +{ + oc_surface_api api; + oc_layer layer; - oc_canvas_backend* backend; + oc_surface_destroy_proc destroy; + oc_surface_select_proc prepare; + oc_surface_present_proc present; + oc_surface_deselect_proc deselect; + oc_surface_swap_interval_proc swapInterval; + oc_surface_get_size_proc getSize; + oc_surface_contents_scaling_proc contentsScaling; + oc_surface_get_hidden_proc getHidden; + oc_surface_set_hidden_proc setHidden; + oc_surface_native_layer_proc nativeLayer; + oc_surface_remote_id_proc remoteID; + oc_surface_host_connect_proc hostConnect; - } oc_surface_data; + oc_surface_bring_to_front_proc bringToFront; + oc_surface_send_to_back_proc sendToBack; - oc_surface oc_surface_handle_alloc(oc_surface_data* surface); - oc_surface_data* oc_surface_data_from_handle(oc_surface handle); + oc_canvas_backend* backend; - void oc_surface_init_for_window(oc_surface_data* surface, oc_window_data* window); - void oc_surface_init_remote(oc_surface_data* surface, u32 width, u32 height); - void oc_surface_init_host(oc_surface_data* surface, oc_window_data* window); - void oc_surface_cleanup(oc_surface_data* surface); - void* oc_surface_native_layer(oc_surface surface); +} oc_surface_data; - //--------------------------------------------------------------- - // canvas backend interface - //--------------------------------------------------------------- - typedef struct oc_image_data - { - oc_list_elt listElt; - u32 generation; - oc_surface surface; - oc_vec2 size; +oc_surface oc_surface_handle_alloc(oc_surface_data* surface); +oc_surface_data* oc_surface_data_from_handle(oc_surface handle); - } oc_image_data; +void oc_surface_init_for_window(oc_surface_data* surface, oc_window_data* window); +void oc_surface_init_remote(oc_surface_data* surface, u32 width, u32 height); +void oc_surface_init_host(oc_surface_data* surface, oc_window_data* window); +void oc_surface_cleanup(oc_surface_data* surface); +void* oc_surface_native_layer(oc_surface surface); - typedef void (*oc_canvas_backend_destroy_proc)(oc_canvas_backend* backend); +//--------------------------------------------------------------- +// canvas backend interface +//--------------------------------------------------------------- +typedef struct oc_image_data +{ + oc_list_elt listElt; + u32 generation; + oc_surface surface; + oc_vec2 size; - typedef oc_image_data* (*oc_canvas_backend_image_create_proc)(oc_canvas_backend* backend, oc_vec2 size); - typedef void (*oc_canvas_backend_image_destroy_proc)(oc_canvas_backend* backend, oc_image_data* image); - typedef void (*oc_canvas_backend_image_upload_region_proc)(oc_canvas_backend* backend, - oc_image_data* image, - oc_rect region, - u8* pixels); +} oc_image_data; - typedef void (*oc_canvas_backend_render_proc)(oc_canvas_backend* backend, - oc_color clearColor, - u32 primitiveCount, - oc_primitive* primitives, - u32 eltCount, - oc_path_elt* pathElements); +typedef void (*oc_canvas_backend_destroy_proc)(oc_canvas_backend* backend); - typedef struct oc_canvas_backend - { - oc_canvas_backend_destroy_proc destroy; +typedef oc_image_data* (*oc_canvas_backend_image_create_proc)(oc_canvas_backend* backend, oc_vec2 size); +typedef void (*oc_canvas_backend_image_destroy_proc)(oc_canvas_backend* backend, oc_image_data* image); +typedef void (*oc_canvas_backend_image_upload_region_proc)(oc_canvas_backend* backend, + oc_image_data* image, + oc_rect region, + u8* pixels); - oc_canvas_backend_image_create_proc imageCreate; - oc_canvas_backend_image_destroy_proc imageDestroy; - oc_canvas_backend_image_upload_region_proc imageUploadRegion; +typedef void (*oc_canvas_backend_render_proc)(oc_canvas_backend* backend, + oc_color clearColor, + u32 primitiveCount, + oc_primitive* primitives, + u32 eltCount, + oc_path_elt* pathElements); - oc_canvas_backend_render_proc render; +typedef struct oc_canvas_backend +{ + oc_canvas_backend_destroy_proc destroy; - } oc_canvas_backend; + oc_canvas_backend_image_create_proc imageCreate; + oc_canvas_backend_image_destroy_proc imageDestroy; + oc_canvas_backend_image_upload_region_proc imageUploadRegion; + + oc_canvas_backend_render_proc render; + +} oc_canvas_backend; #ifdef __cplusplus } // extern "C"