added basic gui widgets
This commit is contained in:
parent
8dd01f9dfc
commit
ff07cbc572
@ -59,6 +59,13 @@ void RunThreadFunc(pthread_t *th, u32 *u, void *func)
|
||||
pthread_create(th, NULL, func, u);
|
||||
}
|
||||
|
||||
#define BIL 1000000000L
|
||||
|
||||
u64 GetDiff(struct timespec *start, struct timespec *end)
|
||||
{
|
||||
return BIL * (end->tv_sec - start->tv_sec) + end->tv_nsec - start->tv_nsec;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
u8 *mem = (u8 *)MemAllocZeroed(MB(64));
|
||||
|
||||
209
src/game.c
209
src/game.c
@ -8,11 +8,11 @@ static void InitializeGame(Arena *arena, GameContext *ctx, Arena *ctx_arena)
|
||||
ctx->gui.indices_len = 0;
|
||||
ctx->gui.instance_count = 0;
|
||||
|
||||
ctx->window.p0.x = 0.0f;
|
||||
ctx->window.p0.y = 0.0f;
|
||||
ctx->windows = ArenaAlloc(ctx_arena, sizeof(GUIWindow) * 32);
|
||||
ctx->window_len = 0;
|
||||
|
||||
ctx->window.p1.x = 100.0f;
|
||||
ctx->window.p1.y = 100.0f;
|
||||
ctx->buttons = ArenaAlloc(ctx_arena, sizeof(GUIButton) * 64);
|
||||
ctx->btn_len = 0;
|
||||
|
||||
ctx->arena = arena;
|
||||
}
|
||||
@ -24,6 +24,7 @@ static void DestroyGame()
|
||||
|
||||
u32 selected_rect = 0;
|
||||
b8 mouse_pressed = false;
|
||||
b8 mouse_clicked = false;
|
||||
i16 mouse_prev_pos_x = 0;
|
||||
i16 mouse_prev_pos_y = 0;
|
||||
i16 mouse_pos_x = 0;
|
||||
@ -31,6 +32,8 @@ i16 mouse_pos_y = 0;
|
||||
|
||||
static void HandleInputs(GameInput *inputs, u32 count)
|
||||
{
|
||||
mouse_clicked = false;
|
||||
|
||||
for (u32 i = 0; i < count; i++)
|
||||
{
|
||||
if (inputs[i].type == GI_KEYBOARD)
|
||||
@ -59,7 +62,11 @@ static void HandleInputs(GameInput *inputs, u32 count)
|
||||
else if (inputs[i].type == GI_MOUSE)
|
||||
{
|
||||
if (inputs[i].m_code == M_LEFT_CLICK)
|
||||
{
|
||||
mouse_pressed = inputs[i].pressed;
|
||||
if (!inputs[i].pressed)
|
||||
mouse_clicked = true;
|
||||
}
|
||||
}
|
||||
else if (inputs[i].type == GI_MOTION)
|
||||
{
|
||||
@ -71,46 +78,188 @@ static void HandleInputs(GameInput *inputs, u32 count)
|
||||
}
|
||||
}
|
||||
|
||||
static inline void PrepareGUICtx(GameContext *ctx)
|
||||
{
|
||||
ctx->gui.has_grabbed = false;
|
||||
}
|
||||
|
||||
static inline u32 StrToU32(char *str)
|
||||
{
|
||||
u32 result = 0;
|
||||
for (; *str != '\0'; str++)
|
||||
{
|
||||
result += (u32)(*str);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static b32 UIButton(GameContext *ctx, char *label, f32 x0, f32 y0, f32 x1, f32 y1)
|
||||
{
|
||||
GUIButton *btn = NULL;
|
||||
u32 id = StrToU32(label) + (u32)(x0 + y0 + x1 + y1);
|
||||
if (ctx->btn_len == 0)
|
||||
{
|
||||
ctx->buttons[0].p0.x = x0;
|
||||
ctx->buttons[0].p0.y = y0;
|
||||
ctx->buttons[0].p1.x = x1;
|
||||
ctx->buttons[0].p1.y = y1;
|
||||
ctx->buttons[0].id = id;
|
||||
ctx->buttons[0].pressed = false;
|
||||
ctx->buttons[0].pressed_prev = false;
|
||||
|
||||
btn = &ctx->buttons[0];
|
||||
ctx->btn_len += 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (u32 i = 0; i < ctx->btn_len; i++)
|
||||
{
|
||||
if (ctx->buttons[i].id == id)
|
||||
{
|
||||
btn = &ctx->buttons[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (btn == NULL)
|
||||
{
|
||||
ctx->btn_len += 1;
|
||||
btn = &ctx->buttons[ctx->btn_len];
|
||||
|
||||
btn->p0.x = x0;
|
||||
btn->p0.y = y0;
|
||||
btn->p1.x = x1;
|
||||
btn->p1.y = y1;
|
||||
btn->id = id;
|
||||
btn->pressed = false;
|
||||
btn->pressed_prev = false;
|
||||
}
|
||||
}
|
||||
|
||||
Assert(btn != NULL, "button is null");
|
||||
|
||||
if (mouse_clicked
|
||||
&& !ctx->gui.has_grabbed
|
||||
&& mouse_pos_x > btn->p0.x
|
||||
&& mouse_pos_x < btn->p1.x
|
||||
&& mouse_pos_y > btn->p0.y
|
||||
&& mouse_pos_y < btn->p1.y)
|
||||
{
|
||||
btn->pressed = !btn->pressed;
|
||||
}
|
||||
|
||||
DrawRect(&ctx->gui, btn->p0, btn->p1, (Vec4){ .r = 0.1f, .g = 0.9f, .b = 0.4f, .a = 1.0f });
|
||||
|
||||
return btn->pressed;
|
||||
}
|
||||
|
||||
static b32 UIWindow(GameContext *ctx, char *title, f32 x0, f32 y0, f32 x1, f32 y1)
|
||||
{
|
||||
GUIWindow *win = NULL;
|
||||
u32 id = StrToU32(title) + (u32)(x0 + y0 + x1 + y1);
|
||||
if (ctx->window_len == 0)
|
||||
{
|
||||
ctx->windows[0].p0.x = x0;
|
||||
ctx->windows[0].p0.y = y0;
|
||||
ctx->windows[0].p1.x = x1;
|
||||
ctx->windows[0].p1.y = y1;
|
||||
ctx->windows[0].id = id;
|
||||
|
||||
win = &ctx->windows[0];
|
||||
ctx->window_len += 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (u32 i = 0; i < ctx->window_len; i++)
|
||||
{
|
||||
if (ctx->windows[i].id == id)
|
||||
{
|
||||
win = &ctx->windows[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (win == NULL)
|
||||
{
|
||||
ctx->window_len += 1;
|
||||
win = &ctx->windows[ctx->window_len];
|
||||
|
||||
win->p0.x = x0;
|
||||
win->p0.y = y0;
|
||||
win->p1.x = x1;
|
||||
win->p1.y = y1;
|
||||
win->id = id;
|
||||
}
|
||||
}
|
||||
|
||||
Assert(win != NULL, "window is null");
|
||||
|
||||
if (mouse_pressed && !win->grabbed
|
||||
&& mouse_pos_x > win->p0.x
|
||||
&& mouse_pos_x < win->p1.x
|
||||
&& mouse_pos_y > win->p0.y
|
||||
&& mouse_pos_y < win->p1.y
|
||||
&& !ctx->gui.has_grabbed)
|
||||
{
|
||||
win->grabbed = true;
|
||||
ctx->gui.has_grabbed = true;
|
||||
|
||||
win->grabbed_pos.x = (f32)mouse_pos_x - win->p0.x;
|
||||
win->grabbed_pos.y = (f32)mouse_pos_y - win->p0.y;
|
||||
}
|
||||
else if (!mouse_pressed && win->grabbed)
|
||||
{
|
||||
win->grabbed = false;
|
||||
|
||||
win->grabbed_pos.x = 0.0f;
|
||||
win->grabbed_pos.y = 0.0f;
|
||||
}
|
||||
|
||||
if (win->grabbed)
|
||||
{
|
||||
f32 w = win->p1.x - win->p0.x;
|
||||
f32 h = win->p1.y - win->p0.y;
|
||||
|
||||
win->p0.x = (f32)(mouse_pos_x) - win->grabbed_pos.x;
|
||||
win->p0.y = (f32)(mouse_pos_y) - win->grabbed_pos.y;
|
||||
win->p1.x = win->p0.x + w;
|
||||
win->p1.y = win->p0.y + h;
|
||||
|
||||
ctx->gui.has_grabbed = true;
|
||||
}
|
||||
|
||||
DrawRect(&ctx->gui, win->p0, win->p1, (Vec4){ .r = 0.1f, .g = 0.3f, .b = 0.8f, .a = 1.0f });
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void RunCycle(GameContext *ctx, GameInput *inputs, u32 i_count)
|
||||
{
|
||||
__atomic_store_n(&renderer.vk.imm.job_count, 0, __ATOMIC_RELEASE);
|
||||
__atomic_store_n(&renderer.vk.imm.remaining_count, 0, __ATOMIC_RELEASE);
|
||||
|
||||
GetViewportSize(&ctx->pc.res);
|
||||
PrepareGUICtx(ctx);
|
||||
|
||||
HandleInputs(inputs, i_count);
|
||||
|
||||
if (mouse_pressed && !ctx->window.grabbed
|
||||
&& mouse_pos_x > ctx->window.p0.x
|
||||
&& mouse_pos_x < ctx->window.p1.x
|
||||
&& mouse_pos_y > ctx->window.p0.y
|
||||
&& mouse_pos_y < ctx->window.p1.y)
|
||||
if (UIButton(ctx, "Show 2", 150.0f, 150.0f, 200.0f, 200.0f))
|
||||
{
|
||||
ctx->window.grabbed = true;
|
||||
|
||||
ctx->window.grabbed_pos.x = (f32)mouse_pos_x - ctx->window.p0.x;
|
||||
ctx->window.grabbed_pos.y = (f32)mouse_pos_y - ctx->window.p0.y;
|
||||
}
|
||||
else if (!mouse_pressed && ctx->window.grabbed)
|
||||
{
|
||||
ctx->window.grabbed = false;
|
||||
|
||||
ctx->window.grabbed_pos.x = 0.0f;
|
||||
ctx->window.grabbed_pos.y = 0.0f;
|
||||
UIWindow(ctx, "Window 2", 500.0f, 500.0f, 600.0f, 600.0f);
|
||||
}
|
||||
|
||||
if (ctx->window.grabbed)
|
||||
if (UIButton(ctx, "Show 1", 50.0f, 50.0f, 100.0f, 100.0f))
|
||||
{
|
||||
f32 w = ctx->window.p1.x - ctx->window.p0.x;
|
||||
f32 h = ctx->window.p1.y - ctx->window.p0.y;
|
||||
|
||||
ctx->window.p0.x = (f32)(mouse_pos_x) - ctx->window.grabbed_pos.x;
|
||||
ctx->window.p0.y = (f32)(mouse_pos_y) - ctx->window.grabbed_pos.y;
|
||||
ctx->window.p1.x = ctx->window.p0.x + w;
|
||||
ctx->window.p1.y = ctx->window.p0.y + h;
|
||||
UIWindow(ctx, "Window 1", 200.0f, 200.0f, 400.0f, 400.0f);
|
||||
}
|
||||
|
||||
DrawRect(&ctx->gui, ctx->window.p0, ctx->window.p1, (Vec4){ .r = 0.1f, .g = 0.3f, .b = 0.8f, .a = 1.0f });
|
||||
if (UIButton(ctx, "Show 3", 150.0f, 300.0f, 200.0f, 350.0f))
|
||||
{
|
||||
UIWindow(ctx, "Window 3", 250.0f, 500.0f, 400.0f, 650.0f);
|
||||
}
|
||||
|
||||
|
||||
GetViewportSize(&ctx->pc.res);
|
||||
|
||||
|
||||
RenderBuffer *vertex_buffer = ArenaAlloc(ctx->arena, sizeof(RenderBuffer));
|
||||
vertex_buffer->type = RENDER_BUFFER_TYPE_VERTEX;
|
||||
|
||||
19
src/game.h
19
src/game.h
@ -5,15 +5,28 @@ typedef struct GUIWindow_t
|
||||
Vec2 p0;
|
||||
Vec2 p1;
|
||||
Vec2 grabbed_pos;
|
||||
u32 id;
|
||||
b8 grabbed;
|
||||
} GUIWindow;
|
||||
|
||||
typedef struct GUIButton_t
|
||||
{
|
||||
Vec2 p0;
|
||||
Vec2 p1;
|
||||
u32 id;
|
||||
b8 pressed;
|
||||
b8 pressed_prev;
|
||||
} GUIButton;
|
||||
|
||||
typedef struct GameContext_t
|
||||
{
|
||||
GUIContext gui;
|
||||
PushConst pc;
|
||||
Arena *arena;
|
||||
GUIWindow window;
|
||||
PushConst pc;
|
||||
Arena *arena;
|
||||
GUIWindow *windows;
|
||||
u32 window_len;
|
||||
GUIButton *buttons;
|
||||
u32 btn_len;
|
||||
} GameContext;
|
||||
|
||||
static void RunCycle(GameContext *ctx, GameInput *inputs, u32 i_count);
|
||||
|
||||
@ -323,7 +323,7 @@ u8 *OSOpenFile(const char *)
|
||||
return bytes;
|
||||
}
|
||||
|
||||
b32 _ShouldQuit()
|
||||
b32 ShouldQuit()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -201,7 +201,7 @@ void WaitForWindowEvent()
|
||||
}
|
||||
}
|
||||
|
||||
b32 _ShouldQuit()
|
||||
b32 ShouldQuit()
|
||||
{
|
||||
return global_quit;
|
||||
}
|
||||
|
||||
@ -255,4 +255,5 @@ typedef struct
|
||||
u32 *indices;
|
||||
u32 indices_len;
|
||||
u32 instance_count;
|
||||
b8 has_grabbed;
|
||||
} GUIContext;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user