adding gfx and ui stuff

This commit is contained in:
Daniel Ledda
2026-06-04 18:22:30 +02:00
parent d676c50961
commit 4dfac3f82f
48 changed files with 26734 additions and 3 deletions

181
gfx/ui.h Normal file
View File

@@ -0,0 +1,181 @@
#ifndef UI_H
#define UI_H
#include "platform.h"
#include "render.h"
#include "../core.h"
#include "GLFW/glfw3.h"
enum UI_Flag {
UI_Flag_WidthGrow=1<<0, // Default is fixed
UI_Flag_HeightGrow=1<<1, // Default is fixed
UI_Flag_Vertical=1<<2, // Default is horizontal
UI_Flag_3DScene=1<<3,
UI_Flag_Center=1<<4,
UI_Flag_Ignore=1<<7, // For optional parameters
UI_Flag_Pos_Absolute=1<<8, // Default is relative
// ..
UI_Flag_COUNT,
};
typedef struct UI_Padding UI_Padding;
struct UI_Padding {
real32 top;
real32 right;
real32 bottom;
real32 left;
};
enum UI_Cursor {
UI_Cursor_Arrow=1<<0,
UI_Cursor_Pointer=1<<1,
UI_Cursor_Forbidden=1<<2,
UI_Cursor_Count=1<<3,
};
enum UI_TxtAlign {
UI_TxtAlign_Left=1<<0, // Default
UI_TxtAlign_Center=1<<1,
UI_TxtAlign_Right=1<<2,
};
typedef struct UI_RectStr UI_RectStr;
struct UI_RectStr {
string s;
real32 xOffset;
real32 yOffset;
real32 lineHeight;
real32 fontSize;
Vec4 color;
enum UI_TxtAlign alignment;
};
typedef struct UI_Rect UI_Rect;
struct UI_Rect {
enum UI_Flag flags;
int32 parent;
int32 firstChild;
int32 lastChild;
int32 nextSibling;
real32 xOffset;
real32 yOffset;
real32 width;
real32 minWidth;
real32 maxWidth;
real32 height;
real32 minHeight;
real32 maxHeight;
real32 borderRadius;
real32 borderThickness;
Vec4 color;
Vec4 borderColor;
UI_Padding padding;
real32 childGap;
real32 x;
real32 y;
real32 resolvedWidth;
real32 resolvedHeight;
UI_RectStr *stringData;
/**
* Inherited from parent to propagate attributes. Actual string is ignored, only used for filling out defaults in
* the next stringData pointer that is set.
* This pointer is always set, as the global UI context will set it on the root node if it does not present its own
* text data.
*/
UI_RectStr *inheritedTextAttr;
};
DefineList(UI_Rect, UI_Rect);
typedef struct UI_Context UI_Context;
struct UI_Context {
Arena *arena;
UI_RectList prevRects;
UI_RectList rects;
int32 hotNode;
int32 hoveredNode;
int32 prevHoveredNode;
int32 scene3DHandle;
int32 prevHotNode;
Renderer *renderer;
OS_Input *prevInput;
OS_Input *input;
enum UI_Cursor cursorType;
int32 rootRect;
int32 currRect;
};
void ui_begin(UI_Context *ui);
void ui_end(UI_Context *ui);
UI_Context ui_initContext(Arena *arena, Renderer *renderer);
void ui_resolve();
void ui_rect(UI_Context *ui, UI_Rect rect);
void ui_placeText(UI_Context *ui, UI_RectStr strData);
void ui_attachTextAttr(UI_Context *ui, UI_Rect *rect, UI_RectStr strData);
void ui_openElement(UI_Context *ui, UI_Rect rect);
void ui_closeElement(UI_Context *ui);
bool ui_CheckboxRect(UI_Context *ui, bool *value, UI_Rect rect);
bool ui_Button(UI_Context *ui, UI_Rect rect, UI_RectStr textAttr);
bool ui_ButtonWithHover(UI_Context *ui, UI_Rect rect, UI_Rect hovered, UI_RectStr textAttr);
UI_Rect ui_HoverRect(UI_Context *ui, UI_Rect rect, UI_Rect hovered);
extern UI_Context *__UI_current_ctx__;
#if 0
#define UI_DEBUG_ATTR .borderColor=COLOR_RED, .borderThickness=1,
#else
#define UI_DEBUG_ATTR
#endif
#define UI_Pass(ui) DeferLoop(ui_begin((ui)), ui_end((ui)))
#define UI_PadUniform(padding) ((UI_Padding){ (padding), (padding), (padding), (padding) })
#define UI_NextID() ((__UI_current_ctx__)->rects.length)
#define UI(...)\
/** Place a UI_Rect defined in-place in the current position in the UI tree */\
DeferLoop(ui_openElement((__UI_current_ctx__), UI_RectAttr(__VA_ARGS__)), ui_closeElement((__UI_current_ctx__)))
#define UI_RectAttr(...)\
/** Generate a UI_Rect to be passed as a value */\
((UI_Rect){UI_DEBUG_ATTR .minHeight=-1, .minWidth=-1, .width=-1, .height=-1, .inheritedTextAttr=(__UI_current_ctx__->rects.data[(__UI_current_ctx__)->currRect].inheritedTextAttr), __VA_ARGS__})
#define UI_FromRect(rect)\
/** Place a UI_Rect in the current position in the UI tree, as defined by an existing value */\
DeferLoop(ui_openElement((__UI_current_ctx__), (rect)), ui_closeElement((__UI_current_ctx__)))
#define UI_TxtAttrS(str, ...)\
/** Generate UI text to be used as a value */\
((UI_RectStr){ .color={-1,-1,-1,-1}, .alignment=-1, .xOffset=0, .yOffset=0, .fontSize=-1, .lineHeight=-1, .s=(str), __VA_ARGS__ })
#define UI_TxtAttr(...)\
/** Generate UI text to be used as a value, attributes only, no string */\
((UI_RectStr){ .color={-1,-1,-1,-1}, .alignment=-1, .xOffset=0, .yOffset=0, .fontSize=-1, .lineHeight=-1, .s=((string){.str=NULL,.length=0}), __VA_ARGS__ })
#define UI_Txt(str, ...)\
/** Place UI text in the current position in the UI tree. Attaches to the current UI_Rect */\
(ui_placeText((__UI_current_ctx__), (UI_TxtAttrS(str, __VA_ARGS__))))
#define UI_AttachTxtAttr(rect, txtAttr)\
/** Attach "phantom" text to the specified rect in order to set its heritable attributes for subsequent text in the UI subtrees */\
(ui_attachTextAttr((__UI_current_ctx__), (rect), (txtAttr)))
#define UI_SetTxtAttr(...)\
/** Attach "phantom" text to the current rect in order to set its heritable attributes for subsequent text in the UI subtrees */\
(ui_placeText((__UI_current_ctx__), (UI_TxtAttr(__VA_ARGS__))))
#define UI_TxtSeg(str, ...)\
/** Place a text fragment in its own box (useful for placing many text fragments in a row */\
UI() (UI_Txt((str), __VA_ARGS__))
#endif