From 4152fbecb6ee8360575aa4c24e9cedf822f159dc Mon Sep 17 00:00:00 2001 From: 3gg <3gg@shellblade.net> Date: Wed, 25 Mar 2026 19:59:14 -0700 Subject: Implement vertical and horizontal layouts. Use widget position properly when rendering. Toolbar, buttons and edit bars WIP --- src/render.c | 61 ++++++++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 43 insertions(+), 18 deletions(-) (limited to 'src/render.c') diff --git a/src/render.c b/src/render.c index 51112a9..2fcade6 100644 --- a/src/render.c +++ b/src/render.c @@ -19,9 +19,9 @@ static const uiPixel uiPink = {128, 0, 128, 255}; /// We store a subsurface separate from the surface so that we can always check /// whether a given coordinate is within the bounds of the physical surface. typedef struct RenderState { - uiSurface surface; /// Surface of pixels on which the UI is rendered. - uiRect subsurface; /// Subregion where the current UI widget is rendered. - uiPoint pen; /// Current pen position relative to subsurface. + uiSurface surface; ///< Surface of pixels on which the UI is rendered. + uiRect subsurface; ///< Subregion where the current UI widget is rendered. + uiPoint pen; ///< Current pen position relative to subsurface. } RenderState; static void RenderWidget(RenderState* state, const uiWidget* widget); @@ -165,6 +165,13 @@ static void RenderFrame(const uiFrame* frame, RenderState* state) { FillRect(&frame->widget.rect, uiBlack, state); } +/// Render a button. +static void RenderButton(const uiButton* button, RenderState* state) { + assert(button); + assert(state); + RenderText(string_data(button->text), string_length(button->text), state); +} + /// Render a label. static void RenderLabel(const uiLabel* label, RenderState* state) { assert(label); @@ -253,14 +260,43 @@ static void RenderTable(const uiTable* table, RenderState* state) { } } +void uiRender(const uiFrame* frame, uiSurface* surface) { + assert(frame); + assert(surface); + + RenderWidget( + &(RenderState){ + .surface = *surface, + .subsurface = (uiRect){.x = 0, + .y = 0, + .width = surface->width, + .height = surface->height}, + .pen = {.x = 0, .y = 0}, + }, + (const uiWidget*)frame); +} + /// Render a widget. static void RenderWidget(RenderState* state, const uiWidget* widget) { assert(state); assert(widget); + // A widget's position is relative to its parent's position. + // The pen currently points at the parent. Move it to this widget's position + // before rendering it, then render the widget's children using this new + // position. + // The pen's original position must be restored before returning, so save a + // copy here. + const uiPoint pen = state->pen; + state->pen = + (uiPoint){state->pen.x + widget->rect.x, state->pen.y + widget->rect.y}; + // Render this widget. switch (widget->type) { + case uiTypeLayout: + break; case uiTypeButton: + RenderButton((const uiButton*)widget, state); break; case uiTypeFrame: RenderFrame((const uiFrame*)widget, state); @@ -268,6 +304,8 @@ static void RenderWidget(RenderState* state, const uiWidget* widget) { case uiTypeLabel: RenderLabel((const uiLabel*)widget, state); break; + case uiTypeEdit: + break; case uiTypeTable: RenderTable((const uiTable*)widget, state); break; @@ -278,20 +316,7 @@ static void RenderWidget(RenderState* state, const uiWidget* widget) { // Render children. list_foreach(widget->children, child, { RenderWidget(state, child); }); -} -void uiRender(const uiFrame* frame, uiSurface* surface) { - assert(frame); - assert(surface); - - RenderWidget( - &(RenderState){ - .surface = *surface, - .subsurface = (uiRect){.x = 0, - .y = 0, - .width = surface->width, - .height = surface->height}, - .pen = {.x = 0, .y = 0}, - }, - (const uiWidget*)frame); + // Restore the pen. + state->pen = pen; } -- cgit v1.2.3