Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,11 @@ ctest --test-dir build --output-on-failure
- `src/main.c`: main loop (fixed-timestep update + render).
- `src/snake.c`, `src/snake.h`: game state, movement, collisions, rendering.
- `src/modules/window.c`, `src/modules/window.h`: SDL window/renderer + SDL_ttf init/teardown + timing.
- `src/modules/audio.c`, `src/modules/audio.h`: audio manager + sound loading/playing.
- `src/modules/ui.c`, `src/modules/ui.h`: reusable UI widgets (buttons/panels).
- `src/utils/*`: `vector2i_*` + `dynamic_array_*`.
- `tests/dynamic_array_tests.c`: only unit test target (`dynamic_array_tests`).
- `tests/dynamic_array_tests.c`: unit test target (`dynamic_array_tests`).
- `tests/vector_tests.c`: unit test target (`vector_tests`).

## Conventions (follow these)

Expand All @@ -24,6 +27,7 @@ ctest --test-dir build --output-on-failure
- Lifetimes: `*_destroy()` must be safe after partial init; free resources once, then set pointers to `NULL`.
- Avoid unbounded loops; random placement must have an upper bound + a deterministic fallback.
- Prefer `snprintf` over `sprintf`; avoid implicit truncation.
- Commit messages: use Conventional Commit prefixes (`feat:`, `fix:`, `refactor:`, `chore:`, etc.) with a short summary.

## CMake notes

Expand Down
46 changes: 46 additions & 0 deletions src/modules/ui.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,3 +56,49 @@ bool ui_button_render(SDL_Renderer* renderer, const ui_button_t* button) {

return true;
}

void ui_panel_init(ui_panel_t* panel, SDL_Color fill_color, SDL_Color border_color) {
SDL_assert(panel != NULL);

panel->rect.x = 0.f;
panel->rect.y = 0.f;
panel->rect.w = 0.f;
panel->rect.h = 0.f;
panel->fill_color = fill_color;
panel->border_color = border_color;
}

void ui_panel_layout_from_content(ui_panel_t* panel, const vector2i_t* screen_size, const vector2i_t* content_size,
float padding_x, float padding_y) {
SDL_assert(panel != NULL);
SDL_assert(screen_size != NULL);
SDL_assert(content_size != NULL);

panel->rect.w = (float)content_size->x + padding_x * 2.f;
panel->rect.h = (float)content_size->y + padding_y * 2.f;
panel->rect.x = ((float)screen_size->x - panel->rect.w) * 0.5f;
panel->rect.y = ((float)screen_size->y - panel->rect.h) * 0.5f;
}

bool ui_panel_render(SDL_Renderer* renderer, const ui_panel_t* panel) {
SDL_assert(renderer != NULL);
SDL_assert(panel != NULL);

SDL_SetRenderDrawColor(renderer, panel->fill_color.r, panel->fill_color.g, panel->fill_color.b,
panel->fill_color.a);
if (SDL_RenderFillRect(renderer, &panel->rect) == false) {
return false;
}

if (panel->border_color.a == 0) {
return true;
}

SDL_SetRenderDrawColor(renderer, panel->border_color.r, panel->border_color.g, panel->border_color.b,
panel->border_color.a);
if (SDL_RenderRect(renderer, &panel->rect) == false) {
return false;
}

return true;
}
36 changes: 36 additions & 0 deletions src/modules/ui.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,12 @@ typedef struct {
SDL_Color border_color;
} ui_button_t;

typedef struct {
SDL_FRect rect;
SDL_Color fill_color;
SDL_Color border_color;
} ui_panel_t;

/**
* @brief Initialize a button with colors and zeroed geometry.
*
Expand Down Expand Up @@ -63,4 +69,34 @@ bool ui_button_contains(const ui_button_t* button, float x, float y);
*/
bool ui_button_render(SDL_Renderer* renderer, const ui_button_t* button);

/**
* @brief Initialize a panel with colors and zeroed geometry.
*
* @param panel Panel to initialize.
* @param fill_color Fill color for the panel body.
* @param border_color Border color for the panel outline.
*/
void ui_panel_init(ui_panel_t* panel, SDL_Color fill_color, SDL_Color border_color);

/**
* @brief Size and center a panel based on content size and padding.
*
* @param panel Panel to size and position.
* @param screen_size Screen size in pixels.
* @param content_size Content size in pixels.
* @param padding_x Horizontal padding around the content.
* @param padding_y Vertical padding around the content.
*/
void ui_panel_layout_from_content(ui_panel_t* panel, const vector2i_t* screen_size, const vector2i_t* content_size,
float padding_x, float padding_y);

/**
* @brief Render the panel body and optional border.
*
* @param renderer SDL renderer to draw with.
* @param panel Panel to draw.
* @return true if rendering succeeded, false otherwise.
*/
bool ui_panel_render(SDL_Renderer* renderer, const ui_panel_t* panel);

#endif // UI_H
Loading