Skip to content
This repository has been archived by the owner on Oct 4, 2024. It is now read-only.

Commit

Permalink
ui: refactor widget creation and freeing
Browse files Browse the repository at this point in the history
  • Loading branch information
rr- committed Sep 7, 2024
1 parent da30f79 commit eb2ab7e
Show file tree
Hide file tree
Showing 16 changed files with 396 additions and 416 deletions.
23 changes: 11 additions & 12 deletions src/game/option/option_controls.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@

#include <libtrx/utils.h>

static bool m_Ready = false;
static UI_WIDGET m_ControlsDialog;
static UI_WIDGET *m_ControlsDialog;
static UI_CONTROLS_CONTROLLER m_ControlsDialogController;

void __cdecl Option_Controls_DefaultConflict(void)
Expand All @@ -24,23 +23,23 @@ void __cdecl Option_Controls_DefaultConflict(void)

void Option_Controls_Shutdown(void)
{
m_ControlsDialog.free(&m_ControlsDialog);
m_Ready = false;
m_ControlsDialog->free(m_ControlsDialog);
m_ControlsDialog = NULL;
Option_Controls_DefaultConflict();
}

void __cdecl Option_Controls(INVENTORY_ITEM *const item)
{
if (!m_Ready) {
UI_ControlsDialog_Init(&m_ControlsDialog, &m_ControlsDialogController);
m_ControlsDialog.set_position(
&m_ControlsDialog,
(640 - m_ControlsDialog.get_width(&m_ControlsDialog)) / 2,
(480 - m_ControlsDialog.get_height(&m_ControlsDialog)) * 2 / 3);
m_Ready = true;
if (m_ControlsDialog == NULL) {
m_ControlsDialog =
UI_ControlsDialog_Create(&m_ControlsDialogController);
m_ControlsDialog->set_position(
m_ControlsDialog,
(640 - m_ControlsDialog->get_width(m_ControlsDialog)) / 2,
(480 - m_ControlsDialog->get_height(m_ControlsDialog)) * 2 / 3);
}

m_ControlsDialog.control(&m_ControlsDialog);
m_ControlsDialog->control(m_ControlsDialog);
if (m_ControlsDialogController.state == UI_CONTROLS_STATE_EXIT) {
Option_Controls_Shutdown();
} else {
Expand Down
24 changes: 16 additions & 8 deletions src/game/ui/base.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,21 @@
#include <stdbool.h>
#include <stdint.h>

struct UI_WIDGET;

typedef void (*UI_WIDGET_CONTROL)(struct UI_WIDGET *self);
typedef int32_t (*UI_WIDGET_GET_WIDTH)(const struct UI_WIDGET *self);
typedef int32_t (*UI_WIDGET_GET_HEIGHT)(const struct UI_WIDGET *self);
typedef void (*UI_WIDGET_SET_POSITION)(
struct UI_WIDGET *self, int32_t x, int32_t y);
typedef void (*UI_WIDGET_FREE)(struct UI_WIDGET *self);

typedef struct UI_WIDGET {
void (*control)(struct UI_WIDGET *widget);
int32_t (*get_width)(const struct UI_WIDGET *widget);
int32_t (*get_height)(const struct UI_WIDGET *widget);
void (*set_position)(struct UI_WIDGET *widget, int32_t x, int32_t y);
void (*free)(struct UI_WIDGET *widget);
void *data;
int32_t x;
int32_t y;
UI_WIDGET_CONTROL control;
UI_WIDGET_GET_WIDTH get_width;
UI_WIDGET_GET_HEIGHT get_height;
UI_WIDGET_SET_POSITION set_position;
UI_WIDGET_FREE free;
} UI_WIDGET;

typedef UI_WIDGET UI_WIDGET_VTABLE;
87 changes: 41 additions & 46 deletions src/game/ui/controls_column.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,76 +6,71 @@
#include <libtrx/memory.h>

typedef struct {
UI_WIDGET_VTABLE vtable;
UI_WIDGET *container;
int32_t selector_count;
UI_WIDGET *selectors;
UI_WIDGET container;
} UI_CONTROLS_COLUMN_DATA;
UI_WIDGET **selectors;
} UI_CONTROLS_COLUMN;

static int32_t UI_ControlsColumn_GetWidth(const UI_WIDGET *widget);
static int32_t UI_ControlsColumn_GetHeight(const UI_WIDGET *widget);
static int32_t UI_ControlsColumn_GetWidth(const UI_CONTROLS_COLUMN *self);
static int32_t UI_ControlsColumn_GetHeight(const UI_CONTROLS_COLUMN *self);
static void UI_ControlsColumn_SetPosition(
UI_WIDGET *widget, int32_t x, int32_t y);
static void UI_ControlsColumn_Control(UI_WIDGET *widget);
static void UI_ControlsColumn_Free(UI_WIDGET *widget);
UI_CONTROLS_COLUMN *self, int32_t x, int32_t y);
static void UI_ControlsColumn_Control(UI_CONTROLS_COLUMN *self);
static void UI_ControlsColumn_Free(UI_CONTROLS_COLUMN *self);

static int32_t UI_ControlsColumn_GetWidth(const UI_WIDGET *const widget)
static int32_t UI_ControlsColumn_GetWidth(const UI_CONTROLS_COLUMN *const self)
{
const UI_CONTROLS_COLUMN_DATA *const data = widget->data;
return data->container.get_width(&data->container);
return self->container->get_width(self->container);
}

static int32_t UI_ControlsColumn_GetHeight(const UI_WIDGET *const widget)
static int32_t UI_ControlsColumn_GetHeight(const UI_CONTROLS_COLUMN *const self)
{
const UI_CONTROLS_COLUMN_DATA *const data = widget->data;
return data->container.get_height(&data->container);
return self->container->get_height(self->container);
}

static void UI_ControlsColumn_SetPosition(
UI_WIDGET *const widget, const int32_t x, const int32_t y)
UI_CONTROLS_COLUMN *const self, const int32_t x, const int32_t y)
{
UI_CONTROLS_COLUMN_DATA *const data = widget->data;
return data->container.set_position(&data->container, x, y);
return self->container->set_position(self->container, x, y);
}

static void UI_ControlsColumn_Control(UI_WIDGET *const widget)
static void UI_ControlsColumn_Control(UI_CONTROLS_COLUMN *const self)
{
UI_CONTROLS_COLUMN_DATA *const data = widget->data;
data->container.control(&data->container);
self->container->control(self->container);
}

static void UI_ControlsColumn_Free(UI_WIDGET *const widget)
static void UI_ControlsColumn_Free(UI_CONTROLS_COLUMN *const self)
{
UI_CONTROLS_COLUMN_DATA *const data = widget->data;
for (int32_t i = 0; i < data->selector_count; i++) {
data->selectors[i].free(&data->selectors[i]);
for (int32_t i = 0; i < self->selector_count; i++) {
self->selectors[i]->free(self->selectors[i]);
}
data->container.free(&data->container);
Memory_FreePointer(&data->selectors);
Memory_Free(data);
self->container->free(self->container);
Memory_FreePointer(&self->selectors);
Memory_Free(self);
}

void UI_ControlsColumn_Init(
UI_WIDGET *const widget, const int32_t column,
UI_CONTROLS_CONTROLLER *const controller)
UI_WIDGET *UI_ControlsColumn_Create(
const int32_t column, UI_CONTROLS_CONTROLLER *const controller)
{
UI_CONTROLS_COLUMN_DATA *const data =
Memory_Alloc(sizeof(UI_CONTROLS_COLUMN_DATA));
UI_CONTROLS_COLUMN *const self = Memory_Alloc(sizeof(UI_CONTROLS_COLUMN));
self->vtable = (UI_WIDGET_VTABLE) {
.control = (UI_WIDGET_CONTROL)UI_ControlsColumn_Control,
.get_width = (UI_WIDGET_GET_WIDTH)UI_ControlsColumn_GetWidth,
.get_height = (UI_WIDGET_GET_HEIGHT)UI_ControlsColumn_GetHeight,
.set_position = (UI_WIDGET_SET_POSITION)UI_ControlsColumn_SetPosition,
.free = (UI_WIDGET_FREE)UI_ControlsColumn_Free,
};

data->selector_count = UI_ControlsController_GetInputRoleCount(column);
self->selector_count = UI_ControlsController_GetInputRoleCount(column);
self->container = UI_Stack_Create(UI_STACK_LAYOUT_VERTICAL);
self->selectors = Memory_Alloc(sizeof(UI_WIDGET *) * self->selector_count);

UI_Stack_Init(&data->container, UI_STACK_LAYOUT_VERTICAL);
data->selectors = Memory_Alloc(sizeof(UI_WIDGET) * data->selector_count);
for (int32_t i = 0; i < data->selector_count; i++) {
UI_ControlsInputSelector_Init(
&data->selectors[i], UI_ControlsController_GetInputRole(column, i),
controller);
UI_Stack_AddChild(&data->container, &data->selectors[i]);
for (int32_t i = 0; i < self->selector_count; i++) {
self->selectors[i] = UI_ControlsInputSelector_Create(
UI_ControlsController_GetInputRole(column, i), controller);
UI_Stack_AddChild(self->container, self->selectors[i]);
}

widget->data = data;
widget->control = UI_ControlsColumn_Control;
widget->get_width = UI_ControlsColumn_GetWidth;
widget->get_height = UI_ControlsColumn_GetHeight;
widget->set_position = UI_ControlsColumn_SetPosition;
widget->free = UI_ControlsColumn_Free;
return (UI_WIDGET *)self;
}
4 changes: 2 additions & 2 deletions src/game/ui/controls_column.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@
#include "game/ui/base.h"
#include "game/ui/controllers/controls.h"

void UI_ControlsColumn_Init(
UI_WIDGET *widget, int32_t column, UI_CONTROLS_CONTROLLER *controller);
UI_WIDGET *UI_ControlsColumn_Create(
int32_t column, UI_CONTROLS_CONTROLLER *controller);
109 changes: 48 additions & 61 deletions src/game/ui/controls_dialog.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,101 +7,88 @@

#include <libtrx/memory.h>

#define WIDGET_COUNT 6

typedef struct {
UI_WIDGET_VTABLE vtable;
UI_CONTROLS_CONTROLLER *controller;
UI_WIDGET widgets[WIDGET_COUNT];
UI_WIDGET *window;
UI_WIDGET *layout_selector;
UI_WIDGET *outer_stack;
UI_WIDGET *column_stack;
UI_WIDGET *left_column;
UI_WIDGET *right_column;
UI_WIDGET *layout_selector;
} UI_CONTROLS_DIALOG_DATA;
} UI_CONTROLS_DIALOG;

static int32_t UI_ControlsDialog_GetWidth(const UI_WIDGET *widget);
static int32_t UI_ControlsDialog_GetHeight(const UI_WIDGET *widget);
static int32_t UI_ControlsDialog_GetWidth(const UI_CONTROLS_DIALOG *self);
static int32_t UI_ControlsDialog_GetHeight(const UI_CONTROLS_DIALOG *self);
static void UI_ControlsDialog_SetPosition(
UI_WIDGET *widget, int32_t x, int32_t y);
static void UI_ControlsDialog_Control(UI_WIDGET *widget);
static void UI_ControlsDialog_Free(UI_WIDGET *widget);
UI_CONTROLS_DIALOG *self, int32_t x, int32_t y);
static void UI_ControlsDialog_Control(UI_CONTROLS_DIALOG *self);
static void UI_ControlsDialog_Free(UI_CONTROLS_DIALOG *self);

static int32_t UI_ControlsDialog_GetWidth(const UI_WIDGET *const widget)
static int32_t UI_ControlsDialog_GetWidth(const UI_CONTROLS_DIALOG *const self)
{
const UI_CONTROLS_DIALOG_DATA *const data = widget->data;
return data->window->get_width(data->window);
return self->window->get_width(self->window);
}

static int32_t UI_ControlsDialog_GetHeight(const UI_WIDGET *const widget)
static int32_t UI_ControlsDialog_GetHeight(const UI_CONTROLS_DIALOG *const self)
{
const UI_CONTROLS_DIALOG_DATA *const data = widget->data;
return data->window->get_height(data->window);
return self->window->get_height(self->window);
}

static void UI_ControlsDialog_SetPosition(
UI_WIDGET *const widget, const int32_t x, const int32_t y)
UI_CONTROLS_DIALOG *const self, const int32_t x, const int32_t y)
{
UI_CONTROLS_DIALOG_DATA *const data = widget->data;
return data->window->set_position(data->window, x, y);
return self->window->set_position(self->window, x, y);
}

static void UI_ControlsDialog_Control(UI_WIDGET *const widget)
static void UI_ControlsDialog_Control(UI_CONTROLS_DIALOG *const self)
{
UI_CONTROLS_DIALOG_DATA *const data = widget->data;
if (UI_ControlsController_Control(data->controller)) {
if (UI_ControlsController_Control(self->controller)) {
// Trigger the UI updates only if anything has changed.
data->window->control(data->window);
self->window->control(self->window);
// Reposition the header.
UI_Stack_DoLayout(data->outer_stack);
UI_Stack_DoLayout(self->outer_stack);
}
}

static void UI_ControlsDialog_Free(UI_WIDGET *const widget)
static void UI_ControlsDialog_Free(UI_CONTROLS_DIALOG *const self)
{
UI_CONTROLS_DIALOG_DATA *const data = widget->data;
for (int32_t i = 0; i < WIDGET_COUNT; i++) {
data->widgets[i].free(&data->widgets[i]);
}
Memory_Free(data);
self->left_column->free(self->left_column);
self->right_column->free(self->right_column);
self->column_stack->free(self->column_stack);
self->outer_stack->free(self->outer_stack);
self->layout_selector->free(self->layout_selector);
self->window->free(self->window);
Memory_Free(self);
}

void UI_ControlsDialog_Init(
UI_WIDGET *const widget, UI_CONTROLS_CONTROLLER *const controller)
UI_WIDGET *UI_ControlsDialog_Create(UI_CONTROLS_CONTROLLER *const controller)
{
UI_CONTROLS_DIALOG_DATA *const data =
Memory_Alloc(sizeof(UI_CONTROLS_DIALOG_DATA));

UI_WIDGET *child_ptr = data->widgets;
data->controller = controller;
data->controller->state = UI_CONTROLS_STATE_NAVIGATE_LAYOUT;

data->window = child_ptr++;
data->outer_stack = child_ptr++;
data->layout_selector = child_ptr++;
data->column_stack = child_ptr++;
data->left_column = child_ptr++;
data->right_column = child_ptr++;
UI_CONTROLS_DIALOG *const self = Memory_Alloc(sizeof(UI_CONTROLS_DIALOG));
self->vtable = (UI_WIDGET_VTABLE) {
.control = (UI_WIDGET_CONTROL)UI_ControlsDialog_Control,
.get_width = (UI_WIDGET_GET_WIDTH)UI_ControlsDialog_GetWidth,
.get_height = (UI_WIDGET_GET_HEIGHT)UI_ControlsDialog_GetHeight,
.set_position = (UI_WIDGET_SET_POSITION)UI_ControlsDialog_SetPosition,
.free = (UI_WIDGET_FREE)UI_ControlsDialog_Free,
};

UI_ControlsLayoutSelector_Init(data->layout_selector, data->controller);
self->controller = controller;
self->controller->state = UI_CONTROLS_STATE_NAVIGATE_LAYOUT;

UI_ControlsColumn_Init(data->left_column, 0, data->controller);
UI_ControlsColumn_Init(data->right_column, 1, data->controller);
self->layout_selector = UI_ControlsLayoutSelector_Create(self->controller);
self->left_column = UI_ControlsColumn_Create(0, self->controller);
self->right_column = UI_ControlsColumn_Create(1, self->controller);

UI_Stack_Init(data->column_stack, UI_STACK_LAYOUT_HORIZONTAL);
UI_Stack_AddChild(data->column_stack, data->left_column);
UI_Stack_AddChild(data->column_stack, data->right_column);
self->column_stack = UI_Stack_Create(UI_STACK_LAYOUT_HORIZONTAL);
UI_Stack_AddChild(self->column_stack, self->left_column);
UI_Stack_AddChild(self->column_stack, self->right_column);

UI_Stack_Init(data->outer_stack, UI_STACK_LAYOUT_VERTICAL);
UI_Stack_AddChild(data->outer_stack, data->layout_selector);
UI_Stack_AddChild(data->outer_stack, data->column_stack);
self->outer_stack = UI_Stack_Create(UI_STACK_LAYOUT_VERTICAL);
UI_Stack_AddChild(self->outer_stack, self->layout_selector);
UI_Stack_AddChild(self->outer_stack, self->column_stack);

UI_Window_Init(data->window, data->outer_stack, 5, 5, 15, 5);
self->window = UI_Window_Create(self->outer_stack, 5, 5, 15, 5);

widget->data = data;
widget->control = UI_ControlsDialog_Control;
widget->get_width = UI_ControlsDialog_GetWidth;
widget->get_height = UI_ControlsDialog_GetHeight;
widget->set_position = UI_ControlsDialog_SetPosition;
widget->free = UI_ControlsDialog_Free;
return (UI_WIDGET *)self;
}
3 changes: 1 addition & 2 deletions src/game/ui/controls_dialog.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,4 @@
#include "game/ui/base.h"
#include "game/ui/controllers/controls.h"

void UI_ControlsDialog_Init(
UI_WIDGET *widget, UI_CONTROLS_CONTROLLER *controller);
UI_WIDGET *UI_ControlsDialog_Create(UI_CONTROLS_CONTROLLER *controller);
Loading

0 comments on commit eb2ab7e

Please sign in to comment.