diff options
| -rw-r--r-- | include/saffron_api.h | 1 | ||||
| -rw-r--r-- | include/saffron_widget.h | 13 | ||||
| -rw-r--r-- | src/saffron_layout.c | 15 | ||||
| -rw-r--r-- | src/saffron_widget.c | 15 | ||||
| -rw-r--r-- | src/saffron_window.c | 50 |
5 files changed, 78 insertions, 16 deletions
diff --git a/include/saffron_api.h b/include/saffron_api.h index e8fdfb8..7b6fabb 100644 --- a/include/saffron_api.h +++ b/include/saffron_api.h @@ -21,5 +21,6 @@ void saffron_window_main(SaffronWindow* window); SaffronWidget* saffron_widget_hit_test(SaffronWidget* widget, int x, int y); SaffronBox* saffron_box_new(SaffronOrientation orientation, SaffronHorizontalAlignment halign, SaffronVerticalAlignment valign, int spacing, int padding, int margin); +void saffron_box_layout(SaffronBox* box); #endif diff --git a/include/saffron_widget.h b/include/saffron_widget.h index 6d7b6bd..4461555 100644 --- a/include/saffron_widget.h +++ b/include/saffron_widget.h @@ -3,13 +3,22 @@ #include <SDL3/SDL.h> +typedef enum{ + SAFFRON_SIZE_FIXED, + SAFFRON_SIZE_STRETCH, + SAFFRON_SIZE_SCALE // scale but keep aspect ratio. this must be set on BOTH size modes (width AND height) to work +} SaffronSizeMode; + typedef struct SaffronWidget { int x, y, w, h; void (*draw)(struct SaffronWidget *self, SDL_Renderer *renderer); void (*on_click)(struct SaffronWidget *self); - struct SaffronWidget *parent; - struct SaffronWidget **children; + struct SaffronWidget* parent; + struct SaffronWidget** children; int child_count; + SaffronSizeMode width_mode; + SaffronSizeMode height_mode; + bool pixel_perfect; // Do we scale dynamically (SaffronSizeMode, etc) or use raw x, y, w, h values? If this is true, the SaffronSizeModes from earlier will be ignored } SaffronWidget; #endif diff --git a/src/saffron_layout.c b/src/saffron_layout.c index cc91246..c714bfa 100644 --- a/src/saffron_layout.c +++ b/src/saffron_layout.c @@ -23,4 +23,19 @@ SaffronBox* saffron_box_new(SaffronOrientation orientation, SaffronHorizontalAli return box; } +void saffron_box_layout(SaffronBox* box) { + if (!box || ((SaffronWidget*)box)->child_count == 0) return; + int content_x = ((SaffronWidget*)box)->x + box->margin; + int content_y = ((SaffronWidget*)box)->y + box->margin; + int content_w = ((SaffronWidget*)box)->w - (box->margin * 2); + int content_h = ((SaffronWidget*)box)->h - (box->margin * 2); + + int inner_x = content_x + box->padding; + int inner_y = content_y + box->padding; + int inner_w = content_w - (box->padding * 2); + int inner_h = content_h - (box->padding * 2); + + /* TODO actually make it layout */ + return; +} diff --git a/src/saffron_widget.c b/src/saffron_widget.c index 850d1b8..8612557 100644 --- a/src/saffron_widget.c +++ b/src/saffron_widget.c @@ -4,6 +4,7 @@ #include <saffron.h> void saffron_widget_init(SaffronWidget* widget) { + /* This function is a generic primitive for initializing widgets. You wouldn't want to do this manually unless you're a lunatic. It is meant to be wrapped around by other functions that change the default parameters, for example, what sane person makes a widget 0x0x0x0? you LUNATIC! */ widget->x = 0; widget->y = 0; widget->w = 0; @@ -15,10 +16,14 @@ void saffron_widget_init(SaffronWidget* widget) { widget->parent = NULL; widget->children = NULL; widget->child_count = 0; + + widget->width_mode = SAFFRON_SIZE_FIXED; + widget->height_mode = SAFFRON_SIZE_FIXED; + widget->pixel_perfect = false; } SaffronWidget* saffron_widget_new(void) { - /* This function is a generic primitive for creating widgets. You wouldn't want to do this manually unless you're a lunatic. It is meant to be wrapped around by other functions that change the default parameters, for example, what sane person makes a widget 0x0x0x0? you LUNATIC! */ + /* also generic primitive, refer to above comment in saffron_widget_init */ SaffronWidget* widget = malloc(sizeof(SaffronWidget)); if (widget) { saffron_widget_init(widget); @@ -63,21 +68,21 @@ void saffron_widget_add_child(SaffronWidget *parent, SaffronWidget *child) { SaffronWidget* saffron_widget_hit_test(SaffronWidget* widget, int x, int y) { if (!widget) { - printf("[saffron] hit test: widget is NULL!\n"); + printf("[Saffron] hit test: widget is NULL!\n"); return NULL; } if (x < widget->x || x > widget->x + widget->w) { - printf("[saffron] hit test: widget failed X bounds check!\n"); + printf("[Saffron] hit test: widget failed X bounds check!\n"); return NULL; } if (y < widget->y || y > widget->y + widget->h) { - printf("[saffron] hit test: widget failed Y bounds check!\n"); + printf("[Saffron] hit test: widget failed Y bounds check!\n"); return NULL; } // check children front to back for (int i = widget->child_count - 1; i >= 0; i--) { - printf("[saffron] recursing to child (%i)\n", i); + printf("[Saffron] recursing to child (%i)\n", i); SaffronWidget* hit = saffron_widget_hit_test(widget->children[i], x, y); if (hit) return hit; } diff --git a/src/saffron_window.c b/src/saffron_window.c index c595c08..74742fa 100644 --- a/src/saffron_window.c +++ b/src/saffron_window.c @@ -1,3 +1,5 @@ +#include <SDL3/SDL_render.h> +#include <SDL3/SDL_video.h> #include <stdio.h> #include <SDL3/SDL_events.h> #include <stdlib.h> @@ -7,12 +9,15 @@ SaffronWindow* saffron_window_new(const char* title, int w, int h) { SaffronWindow* window = malloc(sizeof(SaffronWindow)); - window->root = saffron_widget_new(); + window->root = (SaffronWidget*)saffron_box_new(SAFFRON_ORIENTATION_VERTICAL, SAFFRON_HALIGN_CENTER, SAFFRON_VALIGN_CENTER, 10, 10, 0); window->title = title; window->w = window->root->w = w; window->h = window->root->h = h; - window->sdl_window = SDL_CreateWindow(title, w, h, SDL_WINDOW_RESIZABLE); + + Uint32 flags = SDL_WINDOW_RESIZABLE | SDL_WINDOW_HIGH_PIXEL_DENSITY; + window->sdl_window = SDL_CreateWindow(title, w, h, flags); window->renderer = SDL_CreateRenderer(window->sdl_window, NULL); + return window; } @@ -23,10 +28,40 @@ void saffron_window_free(SaffronWindow* window) { free(window); } +static void handle_mouse_down(SDL_Event* event, SaffronWindow* window) { + if (event->type != SDL_EVENT_MOUSE_BUTTON_DOWN) return; + + printf("[Saffron] mouse down!\n"); + + if (event->button.button == SDL_BUTTON_LEFT) { + printf("[Saffron] left click at %f, %f!\n", event->button.x, event->button.y); + printf("[Saffron] calling hit test at coordinates\n"); + SaffronWidget* hit = saffron_widget_hit_test(window->root, (int)event->button.x, (int)event->button.y); + if (hit && hit->on_click) hit->on_click(hit); + } + // TODO: handle right click +} + +static void handle_window_resized(SDL_Event* event, SaffronWindow* window) { + if (event->type != SDL_EVENT_WINDOW_RESIZED) return; + + printf("[Saffron] window resized!\n"); + + int new_w, new_h; + SDL_GetWindowSize(window->sdl_window, &new_w, &new_h); + window->w = window->root->w = new_w; + window->h = window->root->h = new_h; + printf("[Saffron] new dimensions: %dx%d\n", new_w, new_h); + + printf("[Saffron] recalculating layout on window->root\n"); + saffron_box_layout((SaffronBox*)window->root); +} + void saffron_window_main(SaffronWindow *window) { if (!window) return; bool running = true; + printf("[Saffron] window running!\n"); SDL_Event event; while (running) { @@ -35,13 +70,10 @@ void saffron_window_main(SaffronWindow *window) { running = false; } if (event.type == SDL_EVENT_MOUSE_BUTTON_DOWN) { - printf("[saffron] mouse down!\n"); - if (event.button.button == SDL_BUTTON_LEFT) { - printf("[saffron] left click at %f, %f!\n", event.button.x, event.button.y); - printf("[saffron] calling hit test at coordinates\n"); - SaffronWidget* hit = saffron_widget_hit_test(window->root, (int)event.button.x, (int)event.button.y); - if (hit && hit->on_click) hit->on_click(hit); - } + handle_mouse_down(&event, window); + } + if (event.type == SDL_EVENT_WINDOW_RESIZED) { + handle_window_resized(&event, window); } } |
