From 8e3ed99a47d6c1cc49448fc12678e0d8adeb27e6 Mon Sep 17 00:00:00 2001 From: ppeb Date: Thu, 16 Jan 2025 20:11:21 -0600 Subject: [PATCH] Extend SDL2 Renderer and SDL2-video-demo Implements CLAY_RENDER_COMMAND_TYPE_IMAGE and CLAY_RENDER_COMMAND_TYPE_BORDER for SDL2. Both have been added to SDL-video-demo to provide examples. --- examples/SDL2-video-demo/CMakeLists.txt | 10 ++++ examples/SDL2-video-demo/main.c | 20 ++++++- examples/SDL2-video-demo/resources/sample.png | Bin 0 -> 850 bytes renderers/SDL2/README | 4 +- renderers/SDL2/clay_renderer_SDL2.c | 50 +++++++++++++++++- 5 files changed, 79 insertions(+), 5 deletions(-) create mode 100644 examples/SDL2-video-demo/resources/sample.png diff --git a/examples/SDL2-video-demo/CMakeLists.txt b/examples/SDL2-video-demo/CMakeLists.txt index 96d278e1..ace85924 100644 --- a/examples/SDL2-video-demo/CMakeLists.txt +++ b/examples/SDL2-video-demo/CMakeLists.txt @@ -23,6 +23,15 @@ FetchContent_Declare( ) FetchContent_MakeAvailable(SDL2_ttf) +FetchContent_Declare( + SDL2_image + GIT_REPOSITORY "https://github.com/libsdl-org/SDL_image.git" + GIT_TAG "release-2.8.4" + GIT_PROGRESS TRUE + GIT_SHALLOW TRUE +) +FetchContent_MakeAvailable(SDL2_image) + add_executable(SDL2_video_demo main.c) target_compile_options(SDL2_video_demo PUBLIC) @@ -32,6 +41,7 @@ target_link_libraries(SDL2_video_demo PUBLIC SDL2::SDL2main SDL2::SDL2-static SDL2_ttf::SDL2_ttf-static + SDL2_image::SDL2_image-static ) if(MSVC) diff --git a/examples/SDL2-video-demo/main.c b/examples/SDL2-video-demo/main.c index 79800977..3bcd24d2 100644 --- a/examples/SDL2-video-demo/main.c +++ b/examples/SDL2-video-demo/main.c @@ -13,6 +13,8 @@ const int FONT_ID_BODY_16 = 0; Clay_Color COLOR_WHITE = { 255, 255, 255, 255}; +SDL_Surface *sample_image; + void RenderHeaderButton(Clay_String text) { CLAY( CLAY_LAYOUT({ .padding = { 16, 16, 8, 8 }}), @@ -111,9 +113,18 @@ static Clay_RenderCommandArray CreateLayout() { }) ) { // Header buttons go here + CLAY( + CLAY_LAYOUT({ .padding = { 16, 16, 8, 8 }}), + CLAY_BORDER_ALL({ 2, COLOR_WHITE }) + ) { + CLAY( + CLAY_LAYOUT({ .padding = { 8, 8, 8, 8 }}), + CLAY_IMAGE({ sample_image, { 23, 42 } }) + ) {} + } CLAY( CLAY_ID("FileButton"), - CLAY_LAYOUT({ .padding = { 16, 8 }}), + CLAY_LAYOUT({ .padding = { 16, 16, 8, 8 }}), CLAY_RECTANGLE({ .color = { 140, 140, 140, 255 }, .cornerRadius = 5 @@ -278,6 +289,10 @@ int main(int argc, char *argv[]) { fprintf(stderr, "Error: could not initialize TTF: %s\n", TTF_GetError()); return 1; } + if (IMG_Init(IMG_INIT_PNG) < 0) { + fprintf(stderr, "Error: could not initialize IMG: %s\n", IMG_GetError()); + return 1; + } TTF_Font *font = TTF_OpenFont("resources/Roboto-Regular.ttf", 16); if (!font) { @@ -289,6 +304,8 @@ int main(int argc, char *argv[]) { .font = font, }; + sample_image = IMG_Load("resources/sample.png"); + SDL_Window *window = NULL; SDL_Renderer *renderer = NULL; if (SDL_CreateWindowAndRenderer(800, 600, SDL_WINDOW_RESIZABLE, &window, &renderer) < 0) { @@ -352,6 +369,7 @@ int main(int argc, char *argv[]) { quit: SDL_DestroyRenderer(renderer); SDL_DestroyWindow(window); + IMG_Quit(); TTF_Quit(); SDL_Quit(); return 0; diff --git a/examples/SDL2-video-demo/resources/sample.png b/examples/SDL2-video-demo/resources/sample.png new file mode 100644 index 0000000000000000000000000000000000000000..2c008286a87772594b9518d39b5ba6adad355fa1 GIT binary patch literal 850 zcmV-Y1FigtP)8r9E;#9glOdQ`k)#XT zM9*J4&IA`jbiDE!8G?%@20IZMjQ!aN(a0dW9NNOGG@ipgRaZrHVf&(y9eSl8TnxZg zg$8L=7met?807x9vU5hBIW2UL!hKC5Xo@_QF*^}z{Q5jmK(P9qf9;@4Uvx5n{n;~} z1C0qz&7^WzSzQ25`gFbE<`}U5QH-HU}70HsbD)7x6Acvfgcr)9tyruL{ACl!ZybXdG#i zPT0?;Gg-tym=uB)SrOzxp*aCoiizA-l*{kB$!;~;3x!T?ujSDGtQme$D@b27!jp2k z|D_89T#pjF7jG^c))kx>n((z2cl>^qdS-AUfGXsoj5AD!%5f3TItyP!x=0+;X*X;4 zPIlL}xNY@3@cHC2lD#g`Wq726g^K1WS{g#P4>;~6s(CAtXV8FAKyQ9<*g zGJ;XHXypF1I8XCc|3GkIVf`6|F+#TZn1uw%XQTgiF)9}TlbN7O>9ylGo+!0hg^n@(3I$yroh=AT-(;oyD7iw>{R{7vX? ze?L<6?zMJBww-)ATBxcPHGOH_NDt`DuIr@{`;jonCyR(!ysA6bTyl34 zin|nSo;O19_25Z;JFm9h``Lrky4;{2555KX<+H6GYu+{Ku=6VFxWMJj`ksi1j(lcR z#{F69vCk^u==m}1^E9>VzC>V;viE_oB@__%i}K6Z;Fl%sXEB}l7?tP@Cv9=4bohSp cGg$ufAI3?`$SYv$U;qFB07*qoM6N<$g3J(}cK`qY literal 0 HcmV?d00001 diff --git a/renderers/SDL2/README b/renderers/SDL2/README index 582e4dbd..d962c421 100644 --- a/renderers/SDL2/README +++ b/renderers/SDL2/README @@ -1,7 +1,5 @@ Please note, the SDL2 renderer is not 100% feature complete. It is currently missing: -- Border rendering -- Image rendering - Rounded rectangle corners Note: on Mac OSX, SDL2 for some reason decides to automatically disable momentum scrolling on macbook trackpads. @@ -10,4 +8,4 @@ You can re enable it in objective C using: ```C [[NSUserDefaults standardUserDefaults] setBool: YES forKey: @"AppleMomentumScrollSupported"]; -``` \ No newline at end of file +``` diff --git a/renderers/SDL2/clay_renderer_SDL2.c b/renderers/SDL2/clay_renderer_SDL2.c index 0a0785ac..30eb8a4c 100644 --- a/renderers/SDL2/clay_renderer_SDL2.c +++ b/renderers/SDL2/clay_renderer_SDL2.c @@ -1,8 +1,11 @@ #include "../../clay.h" #include #include +#include #include +#define CLAY_COLOR_TO_SDL_COLOR_ARGS(color) color.r, color.g, color.b, color.a + typedef struct { uint32_t fontId; @@ -93,10 +96,55 @@ static void Clay_SDL2_Render(SDL_Renderer *renderer, Clay_RenderCommandArray ren SDL_RenderSetClipRect(renderer, NULL); break; } + case CLAY_RENDER_COMMAND_TYPE_IMAGE: { + SDL_Surface *image = (SDL_Surface *)renderCommand->config.imageElementConfig->imageData; + + SDL_Texture *texture = SDL_CreateTextureFromSurface(renderer, image); + + SDL_Rect destination = (SDL_Rect){ + .x = boundingBox.x, + .y = boundingBox.y, + .w = boundingBox.width, + .h = boundingBox.height, + }; + + SDL_RenderCopy(renderer, texture, NULL, &destination); + break; + } + case CLAY_RENDER_COMMAND_TYPE_BORDER: { + Clay_BorderElementConfig *config = renderCommand->config.borderElementConfig; + + if (config->left.width > 0) { + SDL_SetRenderDrawColor(renderer, CLAY_COLOR_TO_SDL_COLOR_ARGS(config->left.color)); + SDL_RenderFillRectF(renderer, &(SDL_FRect){ boundingBox.x, boundingBox.y + config->cornerRadius.topLeft, config->left.width, boundingBox.height - config->cornerRadius.topLeft - config->cornerRadius.bottomLeft }); + } + + if (config->right.width > 0) { + SDL_SetRenderDrawColor(renderer, CLAY_COLOR_TO_SDL_COLOR_ARGS(config->right.color)); + SDL_RenderFillRectF(renderer, &(SDL_FRect){ boundingBox.x + boundingBox.width - config->right.width, boundingBox.y + config->cornerRadius.topRight, config->right.width, boundingBox.height - config->cornerRadius.topRight - config->cornerRadius.bottomRight }); + } + + if (config->right.width > 0) { + SDL_SetRenderDrawColor(renderer, CLAY_COLOR_TO_SDL_COLOR_ARGS(config->right.color)); + SDL_RenderFillRectF(renderer, &(SDL_FRect){ boundingBox.x + boundingBox.width - config->right.width, boundingBox.y + config->cornerRadius.topRight, config->right.width, boundingBox.height - config->cornerRadius.topRight - config->cornerRadius.bottomRight }); + } + + if (config->top.width > 0) { + SDL_SetRenderDrawColor(renderer, CLAY_COLOR_TO_SDL_COLOR_ARGS(config->right.color)); + SDL_RenderFillRectF(renderer, &(SDL_FRect){ boundingBox.x + config->cornerRadius.topLeft, boundingBox.y, boundingBox.width - config->cornerRadius.topLeft - config->cornerRadius.topRight, config->top.width }); + } + + if (config->bottom.width > 0) { + SDL_SetRenderDrawColor(renderer, CLAY_COLOR_TO_SDL_COLOR_ARGS(config->bottom.color)); + SDL_RenderFillRectF(renderer, &(SDL_FRect){ boundingBox.x + config->cornerRadius.bottomLeft, boundingBox.y + boundingBox.height - config->bottom.width, boundingBox.width - config->cornerRadius.bottomLeft - config->cornerRadius.bottomRight, config->bottom.width }); + } + + break; + } default: { fprintf(stderr, "Error: unhandled render command: %d\n", renderCommand->commandType); exit(1); } } } -} \ No newline at end of file +}