149 lines
4.9 KiB
C
149 lines
4.9 KiB
C
#pragma once
|
|
|
|
#include "types.h"
|
|
#include "util/vector.h"
|
|
#include <stdint.h>
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
|
|
typedef struct _App App;
|
|
|
|
typedef enum {
|
|
ui_Running,
|
|
ui_Paused,
|
|
ui_TitleMenu,
|
|
ui_SceneSelect,
|
|
ui_Options,
|
|
ui_InterMission,
|
|
ui_Leaderboards,
|
|
ui_StateCount // Keep at last
|
|
} ui_State;
|
|
|
|
extern const char *ui_StateTitle[ui_StateCount];
|
|
|
|
|
|
// Forward declarations
|
|
typedef struct _System_UI System_UI;
|
|
|
|
// a Part of the UI.
|
|
typedef struct _ui_Part {
|
|
Box2 box; // bounding box of the UI element
|
|
float progress; // hover process, from 0 to 1
|
|
bool hovered; // Whether the part is hovered
|
|
uintptr_t user; // user data
|
|
void (*draw)(System_UI *sys, struct _ui_Part *part, uintptr_t user); // called when the UI is to be drawn
|
|
void (*update)(System_UI *sys, struct _ui_Part *part, uintptr_t user, Duration deltatime); // called when the element is to be updated
|
|
void (*free)(System_UI *sys, struct _ui_Part *part, uintptr_t user); // called when the element is to be deleted, dont free part!
|
|
} ui_Part;
|
|
|
|
// UI system with its own state machine.
|
|
typedef struct _System_UI {
|
|
App *super;
|
|
vector_Vector *parts[ui_StateCount]; // A vector of ui_Parts
|
|
vector_Vector *state; // A stack of ui_States
|
|
|
|
Box2 bg, bg_target;
|
|
} System_UI;
|
|
|
|
System_UI *ui_NewSystem(App *super);
|
|
void ui_DeleteSystem(System_UI *sys);
|
|
|
|
// Clears and refills every menu with its widgets
|
|
void ui_RebuildUI(System_UI *sys);
|
|
|
|
void ui_PushPart(System_UI *sys, ui_State layer, ui_Part part);
|
|
|
|
void ui_Advance(System_UI *sys, Duration deltaTime);
|
|
void ui_Render(System_UI *sys);
|
|
|
|
void ui_PushState(System_UI *sys, ui_State push_state);
|
|
void ui_PopState(System_UI *sys);
|
|
ui_State ui_CurrentState(System_UI *sys);
|
|
|
|
|
|
// Called when the level is finished
|
|
// If next_level is NULL, there are no next level and the
|
|
// button returns to title screen
|
|
void ui_EnterIntermission(System_UI *sys, const char *next_level);
|
|
|
|
|
|
#define UI_PADDING (16)
|
|
#define UI_BACKGROUND (0)
|
|
|
|
#define UI_BACKGROUND_FADE_MOVE_SPEED (20.0)
|
|
#define UI_BUTTON_HOVER_SPEED (5.0)
|
|
|
|
#define UI_BUTTON_BACKGROUND (RGB(50, 50, 50))
|
|
#define UI_BUTTON_HOVERED (RGB(75, 75, 75))
|
|
#define UI_BUTTON_CLICKED (RGB(90, 90, 90))
|
|
|
|
typedef void (*ui_ActionCallback)(System_UI *sys, ui_Part *part, uintptr_t data);
|
|
|
|
// An Action to pop the UI state stack once
|
|
void ui_Action_PopState(System_UI *sys, ui_Part *part, uintptr_t data);
|
|
// An Action to push the state, casted directly from data
|
|
void ui_Action_PushState(System_UI *sys, ui_Part *part, uintptr_t data);
|
|
|
|
|
|
// Allocated & passed in as user data for ui part
|
|
typedef struct _ui_Button {
|
|
ui_ActionCallback callback;
|
|
uintptr_t callback_data;
|
|
|
|
uint32_t bg, bg_hover, clicked;
|
|
char *label; // Allocated & copied
|
|
bool left_aligned;
|
|
} ui_Button;
|
|
|
|
ui_Part ui_Button_New(Box2 box, const char *label, ui_ActionCallback callback, uintptr_t data);
|
|
ui_Part ui_Button_NewLeftAligned(Box2 box, const char *label, ui_ActionCallback callback, uintptr_t data);
|
|
// ui_Part ui_Button_NewColored(Box2 box, const char *label, uint32_t bg, uint32_t hover, uint32_t clicked, ui_ActionCallback callback, uintptr_t data);
|
|
|
|
|
|
typedef struct {
|
|
char *label; // Allocated & copied, NULL means no label
|
|
int align; // <0: left aligned; ==0: center aligned; >0: right aligned
|
|
uint32_t color;
|
|
} ui_Label;
|
|
ui_Part ui_Label_New(Box2 box, const char *label, int alignment);
|
|
void ui_Label_SetLabel(ui_Part *part, const char *label);
|
|
|
|
// Creates a new box fill with the given color
|
|
ui_Part ui_Fill_New(Box2 box, uint32_t color);
|
|
|
|
|
|
// Box organizer
|
|
typedef struct {
|
|
vector_Vector *rows; // vector of vector_Vector* of Box2
|
|
vector_Vector *row_counts; // vector of Ints
|
|
double width; // Total width, excluding external padding
|
|
double line_height; // Line height
|
|
Vec2 position; // Position of the entire bounding box on screen
|
|
Vec2 pivot; // Pivot or Origin of the position, [0, 1]
|
|
} ui_BoxBuilder;
|
|
|
|
#define UI_BOXBUILDER_DEFAULT_LINEHEIGHT (48)
|
|
#define UI_BOXBUILDER_DEFAULT_WIDTH (400)
|
|
#define UI_BOXBUILDER_DEFAULT_PIVOT_X (0.5)
|
|
#define UI_BOXBUILDER_DEFAULT_PIVOT_Y (0.0)
|
|
|
|
ui_BoxBuilder *ui_BoxBuilder_New();
|
|
void ui_BoxBuilder_Delete(ui_BoxBuilder *builder);
|
|
|
|
// Set that this row should have this many columns
|
|
void ui_BoxBuilder_SetCount(ui_BoxBuilder *builder, int row, int num_cols);
|
|
|
|
// Assemble everything
|
|
void ui_BoxBuilder_Assemble(ui_BoxBuilder *builder);
|
|
|
|
// Every number starts from 1
|
|
Box2 ui_BoxBuilder_At(ui_BoxBuilder *builder, int row, int col);
|
|
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|