add proper fnl modules to demo
This commit is contained in:
parent
9bb9fa5f5b
commit
47c4f2045c
14 changed files with 510 additions and 240 deletions
|
|
@ -107,19 +107,33 @@ function pxl8.trace(msg)
|
|||
end
|
||||
|
||||
function pxl8.key_down(key)
|
||||
if type(key) == "string" then
|
||||
key = string.byte(key)
|
||||
end
|
||||
return C.pxl8_key_down(input, key)
|
||||
end
|
||||
|
||||
function pxl8.key_pressed(key)
|
||||
if type(key) == "string" then
|
||||
key = string.byte(key)
|
||||
end
|
||||
return C.pxl8_key_pressed(input, key)
|
||||
end
|
||||
|
||||
function pxl8.key_released(key)
|
||||
return C.pxl8_key_released(input, key)
|
||||
end
|
||||
|
||||
function pxl8.mouse_wheel_x()
|
||||
return C.pxl8_mouse_wheel_x(input)
|
||||
end
|
||||
|
||||
function pxl8.mouse_wheel_y()
|
||||
return C.pxl8_mouse_wheel_y(input)
|
||||
end
|
||||
|
||||
function pxl8.mouse_x()
|
||||
return C.pxl8_mouse_x(input)
|
||||
end
|
||||
|
||||
function pxl8.mouse_y()
|
||||
return C.pxl8_mouse_y(input)
|
||||
end
|
||||
|
||||
function pxl8.vfx_raster_bars(bars, time)
|
||||
local c_bars = ffi.new("pxl8_raster_bar[?]", #bars)
|
||||
for i, bar in ipairs(bars) do
|
||||
|
|
@ -363,19 +377,20 @@ function pxl8.bounds(x, y, w, h)
|
|||
return ffi.new("pxl8_bounds", {x = x, y = y, w = w, h = h})
|
||||
end
|
||||
|
||||
function pxl8.ui_window_begin(title, x, y, w, h, options)
|
||||
local rect = ffi.new("pxl8_bounds", {x = x, y = y, w = w, h = h})
|
||||
return C.pxl8_ui_window_begin(_pxl8_ui, title, rect, options or 0)
|
||||
end
|
||||
|
||||
function pxl8.ui_window_end()
|
||||
C.pxl8_ui_window_end(_pxl8_ui)
|
||||
end
|
||||
|
||||
function pxl8.ui_button(label)
|
||||
return C.pxl8_ui_button(_pxl8_ui, label)
|
||||
end
|
||||
|
||||
function pxl8.ui_checkbox(label, state)
|
||||
local state_ptr = ffi.new("bool[1]", state)
|
||||
local changed = C.pxl8_ui_checkbox(_pxl8_ui, label, state_ptr)
|
||||
return changed, state_ptr[0]
|
||||
end
|
||||
|
||||
function pxl8.ui_indent(amount)
|
||||
C.pxl8_ui_indent(_pxl8_ui, amount)
|
||||
end
|
||||
|
||||
function pxl8.ui_label(text)
|
||||
C.pxl8_ui_label(_pxl8_ui, text)
|
||||
end
|
||||
|
|
@ -390,4 +405,17 @@ function pxl8.ui_layout_row(item_count, widths, height)
|
|||
C.pxl8_ui_layout_row(_pxl8_ui, item_count, widths_array, height)
|
||||
end
|
||||
|
||||
function pxl8.ui_window_begin(title, x, y, w, h, options)
|
||||
local rect = ffi.new("pxl8_bounds", {x = x, y = y, w = w, h = h})
|
||||
return C.pxl8_ui_window_begin(_pxl8_ui, title, rect, options or 0)
|
||||
end
|
||||
|
||||
function pxl8.ui_window_end()
|
||||
C.pxl8_ui_window_end(_pxl8_ui)
|
||||
end
|
||||
|
||||
function pxl8.ui_window_set_open(title, open)
|
||||
C.pxl8_ui_window_set_open(_pxl8_ui, title, open)
|
||||
end
|
||||
|
||||
return pxl8
|
||||
|
|
|
|||
63
src/pxl8.c
63
src/pxl8.c
|
|
@ -44,8 +44,6 @@ typedef struct pxl8_state {
|
|||
pxl8_script* script;
|
||||
pxl8_ui* ui;
|
||||
|
||||
f32 current_fps;
|
||||
f32 fps_timer;
|
||||
i32 frame_count;
|
||||
u64 last_time;
|
||||
f32 time;
|
||||
|
|
@ -53,7 +51,6 @@ typedef struct pxl8_state {
|
|||
bool repl_mode;
|
||||
bool running;
|
||||
bool script_loaded;
|
||||
bool show_fps;
|
||||
char script_path[256];
|
||||
|
||||
pxl8_input_state input;
|
||||
|
|
@ -319,16 +316,8 @@ SDL_AppResult SDL_AppIterate(void* appstate) {
|
|||
u64 current_time = SDL_GetTicksNS();
|
||||
f32 dt = (f32)(current_time - app->last_time) / 1000000000.0f;
|
||||
|
||||
app->frame_count++;
|
||||
app->fps_timer += dt;
|
||||
app->last_time = current_time;
|
||||
app->time += dt;
|
||||
|
||||
if (app->fps_timer >= 1.0f) {
|
||||
app->current_fps = app->frame_count / app->fps_timer;
|
||||
app->frame_count = 0;
|
||||
app->fps_timer = 0.0f;
|
||||
}
|
||||
|
||||
pxl8_script_check_reload(app->script);
|
||||
|
||||
|
|
@ -344,23 +333,24 @@ SDL_AppResult SDL_AppIterate(void* appstate) {
|
|||
}
|
||||
|
||||
if (app->ui) {
|
||||
pxl8_ui_input_mousemove(app->ui, app->input.mouse_x, app->input.mouse_y);
|
||||
|
||||
pxl8_ui_frame_begin(app->ui);
|
||||
|
||||
for (i32 i = 0; i < 3; i++) {
|
||||
if (app->input.mouse_buttons[i] && app->input.mouse_buttons_pressed[i]) {
|
||||
if (app->input.mouse_buttons_pressed[i]) {
|
||||
pxl8_ui_input_mousedown(app->ui, app->input.mouse_x, app->input.mouse_y, i + 1);
|
||||
}
|
||||
if (!app->input.mouse_buttons[i]) {
|
||||
if (app->input.mouse_buttons_released[i]) {
|
||||
pxl8_ui_input_mouseup(app->ui, app->input.mouse_x, app->input.mouse_y, i + 1);
|
||||
}
|
||||
}
|
||||
pxl8_ui_input_mousemove(app->ui, app->input.mouse_x, app->input.mouse_y);
|
||||
|
||||
for (i32 key = 0; key < 256; key++) {
|
||||
if (app->input.keys_pressed[key]) {
|
||||
pxl8_ui_input_keydown(app->ui, key);
|
||||
}
|
||||
if (!app->input.keys[key] && app->input.keys_pressed[key]) {
|
||||
if (!app->input.keys_down[key] && app->input.keys_pressed[key]) {
|
||||
pxl8_ui_input_keyup(app->ui, key);
|
||||
}
|
||||
}
|
||||
|
|
@ -390,12 +380,6 @@ SDL_AppResult SDL_AppIterate(void* appstate) {
|
|||
i32 render_width, render_height;
|
||||
pxl8_gfx_get_resolution_dimensions(app->resolution, &render_width, &render_height);
|
||||
|
||||
if (app->show_fps && app->current_fps > 0.0f) {
|
||||
char fps_text[32];
|
||||
SDL_snprintf(fps_text, sizeof(fps_text), "FPS: %d", (i32)(app->current_fps + 0.5f));
|
||||
pxl8_text(app->gfx, fps_text, render_width - 80, 10, 15);
|
||||
}
|
||||
|
||||
if (app->ui) {
|
||||
pxl8_ui_frame_end(app->ui);
|
||||
}
|
||||
|
|
@ -406,7 +390,9 @@ SDL_AppResult SDL_AppIterate(void* appstate) {
|
|||
pxl8_gfx_present(app->gfx);
|
||||
|
||||
SDL_memset(app->input.keys_pressed, 0, sizeof(app->input.keys_pressed));
|
||||
SDL_memset(app->input.keys_released, 0, sizeof(app->input.keys_released));
|
||||
SDL_memset(app->input.mouse_buttons_pressed, 0, sizeof(app->input.mouse_buttons_pressed));
|
||||
SDL_memset(app->input.mouse_buttons_released, 0, sizeof(app->input.mouse_buttons_released));
|
||||
app->input.mouse_wheel_x = 0;
|
||||
app->input.mouse_wheel_y = 0;
|
||||
|
||||
|
|
@ -427,25 +413,23 @@ SDL_AppResult SDL_AppEvent(void* appstate, SDL_Event* event) {
|
|||
return SDL_APP_SUCCESS;
|
||||
}
|
||||
|
||||
if (event->key.key == SDLK_F3) {
|
||||
app->show_fps = !app->show_fps;
|
||||
}
|
||||
|
||||
SDL_Keycode key = event->key.key;
|
||||
if (key < 256) {
|
||||
if (!app->input.keys[key]) {
|
||||
app->input.keys_pressed[key] = true;
|
||||
SDL_Scancode scancode = event->key.scancode;
|
||||
if (scancode < 256) {
|
||||
if (!app->input.keys_down[scancode]) {
|
||||
app->input.keys_pressed[scancode] = true;
|
||||
}
|
||||
app->input.keys[key] = true;
|
||||
app->input.keys_down[scancode] = true;
|
||||
app->input.keys_released[scancode] = false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case SDL_EVENT_KEY_UP: {
|
||||
SDL_Keycode key = event->key.key;
|
||||
if (key < 256) {
|
||||
app->input.keys[key] = false;
|
||||
app->input.keys_pressed[key] = false;
|
||||
SDL_Scancode scancode = event->key.scancode;
|
||||
if (scancode < 256) {
|
||||
app->input.keys_down[scancode] = false;
|
||||
app->input.keys_pressed[scancode] = false;
|
||||
app->input.keys_released[scancode] = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
@ -453,10 +437,11 @@ SDL_AppResult SDL_AppEvent(void* appstate, SDL_Event* event) {
|
|||
case SDL_EVENT_MOUSE_BUTTON_DOWN: {
|
||||
u8 button = event->button.button - 1;
|
||||
if (button < 3) {
|
||||
if (!app->input.mouse_buttons[button]) {
|
||||
if (!app->input.mouse_buttons_down[button]) {
|
||||
app->input.mouse_buttons_pressed[button] = true;
|
||||
}
|
||||
app->input.mouse_buttons[button] = true;
|
||||
app->input.mouse_buttons_down[button] = true;
|
||||
app->input.mouse_buttons_released[button] = false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
@ -464,7 +449,9 @@ SDL_AppResult SDL_AppEvent(void* appstate, SDL_Event* event) {
|
|||
case SDL_EVENT_MOUSE_BUTTON_UP: {
|
||||
u8 button = event->button.button - 1;
|
||||
if (button < 3) {
|
||||
app->input.mouse_buttons[button] = false;
|
||||
app->input.mouse_buttons_down[button] = false;
|
||||
app->input.mouse_buttons_pressed[button] = false;
|
||||
app->input.mouse_buttons_released[button] = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
#include <ctype.h>
|
||||
#include <SDL3/SDL.h>
|
||||
|
||||
#include "pxl8_io.h"
|
||||
|
|
@ -97,12 +98,50 @@ void pxl8_io_free_binary_data(u8* data) {
|
|||
}
|
||||
}
|
||||
|
||||
bool pxl8_key_down(const pxl8_input_state* input, i32 key) {
|
||||
if (!input || key < 0 || key >= 256) return false;
|
||||
return input->keys[key];
|
||||
static i32 pxl8_key_code(const char* key_name) {
|
||||
if (!key_name || !key_name[0]) return 0;
|
||||
|
||||
SDL_Scancode scancode = SDL_GetScancodeFromName(key_name);
|
||||
return (i32)scancode;
|
||||
}
|
||||
|
||||
bool pxl8_key_pressed(const pxl8_input_state* input, i32 key) {
|
||||
if (!input || key < 0 || key >= 256) return false;
|
||||
bool pxl8_key_down(const pxl8_input_state* input, const char* key_name) {
|
||||
if (!input) return false;
|
||||
i32 key = pxl8_key_code(key_name);
|
||||
if (key < 0 || key >= 256) return false;
|
||||
return input->keys_down[key];
|
||||
}
|
||||
|
||||
bool pxl8_key_pressed(const pxl8_input_state* input, const char* key_name) {
|
||||
if (!input) return false;
|
||||
i32 key = pxl8_key_code(key_name);
|
||||
if (key < 0 || key >= 256) return false;
|
||||
return input->keys_pressed[key];
|
||||
}
|
||||
|
||||
bool pxl8_key_released(const pxl8_input_state* input, const char* key_name) {
|
||||
if (!input) return false;
|
||||
i32 key = pxl8_key_code(key_name);
|
||||
if (key < 0 || key >= 256) return false;
|
||||
return input->keys_released[key];
|
||||
}
|
||||
|
||||
i32 pxl8_mouse_wheel_x(const pxl8_input_state* input) {
|
||||
if (!input) return 0;
|
||||
return input->mouse_wheel_x;
|
||||
}
|
||||
|
||||
i32 pxl8_mouse_wheel_y(const pxl8_input_state* input) {
|
||||
if (!input) return 0;
|
||||
return input->mouse_wheel_y;
|
||||
}
|
||||
|
||||
i32 pxl8_mouse_x(const pxl8_input_state* input) {
|
||||
if (!input) return 0;
|
||||
return input->mouse_x;
|
||||
}
|
||||
|
||||
i32 pxl8_mouse_y(const pxl8_input_state* input) {
|
||||
if (!input) return 0;
|
||||
return input->mouse_y;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,8 +19,14 @@ pxl8_result pxl8_io_read_file(const char* path, char** content, size_t* size);
|
|||
pxl8_result pxl8_io_write_binary_file(const char* path, const u8* data, size_t size);
|
||||
pxl8_result pxl8_io_write_file(const char* path, const char* content, size_t size);
|
||||
|
||||
bool pxl8_key_down(const pxl8_input_state* input, i32 key);
|
||||
bool pxl8_key_pressed(const pxl8_input_state* input, i32 key);
|
||||
bool pxl8_key_down(const pxl8_input_state* input, const char* key_name);
|
||||
bool pxl8_key_pressed(const pxl8_input_state* input, const char* key_name);
|
||||
bool pxl8_key_released(const pxl8_input_state* input, const char* key_name);
|
||||
|
||||
i32 pxl8_mouse_wheel_x(const pxl8_input_state* input);
|
||||
i32 pxl8_mouse_wheel_y(const pxl8_input_state* input);
|
||||
i32 pxl8_mouse_x(const pxl8_input_state* input);
|
||||
i32 pxl8_mouse_y(const pxl8_input_state* input);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
|||
|
|
@ -59,8 +59,13 @@ static const char* pxl8_ffi_cdefs =
|
|||
"i32 pxl8_gfx_create_texture(pxl8_gfx* ctx, const u8* pixels, u32 width, u32 height);\n"
|
||||
"void pxl8_gfx_upload_atlas(pxl8_gfx* ctx);\n"
|
||||
"typedef struct pxl8_input_state pxl8_input_state;\n"
|
||||
"bool pxl8_key_down(const pxl8_input_state* input, i32 key);\n"
|
||||
"bool pxl8_key_pressed(const pxl8_input_state* input, i32 key);\n"
|
||||
"bool pxl8_key_down(const pxl8_input_state* input, const char* key_name);\n"
|
||||
"bool pxl8_key_pressed(const pxl8_input_state* input, const char* key_name);\n"
|
||||
"bool pxl8_key_released(const pxl8_input_state* input, const char* key_name);\n"
|
||||
"int pxl8_mouse_wheel_x(const pxl8_input_state* input);\n"
|
||||
"int pxl8_mouse_wheel_y(const pxl8_input_state* input);\n"
|
||||
"int pxl8_mouse_x(const pxl8_input_state* input);\n"
|
||||
"int pxl8_mouse_y(const pxl8_input_state* input);\n"
|
||||
"void pxl8_lua_debug(const char* msg);\n"
|
||||
"void pxl8_lua_error(const char* msg);\n"
|
||||
"void pxl8_lua_info(const char* msg);\n"
|
||||
|
|
@ -168,12 +173,15 @@ static const char* pxl8_ffi_cdefs =
|
|||
"void pxl8_ui_input_scroll(pxl8_ui* ui, int x, int y);\n"
|
||||
"void pxl8_ui_input_text(pxl8_ui* ui, const char* text);\n"
|
||||
"bool pxl8_ui_button(pxl8_ui* ui, const char* label);\n"
|
||||
"bool pxl8_ui_checkbox(pxl8_ui* ui, const char* label, bool* state);\n"
|
||||
"void pxl8_ui_indent(pxl8_ui* ui, int amount);\n"
|
||||
"void pxl8_ui_label(pxl8_ui* ui, const char* text);\n"
|
||||
"void pxl8_ui_layout_row(pxl8_ui* ui, int item_count, const int* widths, int height);\n"
|
||||
"int pxl8_ui_menu(pxl8_ui* ui, pxl8_menu_item* items, int item_count);\n"
|
||||
"void pxl8_ui_panel(pxl8_ui* ui, pxl8_bounds rect, pxl8_frame_theme* theme);\n"
|
||||
"bool pxl8_ui_window_begin(pxl8_ui* ui, const char* title, pxl8_bounds rect, int options);\n"
|
||||
"void pxl8_ui_window_end(pxl8_ui* ui);\n"
|
||||
"void pxl8_ui_window_set_open(pxl8_ui* ui, const char* title, bool open);\n"
|
||||
"pxl8_frame_theme pxl8_ui_theme_default(void);\n";
|
||||
|
||||
void pxl8_lua_info(const char* msg) {
|
||||
|
|
@ -246,6 +254,18 @@ pxl8_script* pxl8_script_create(void) {
|
|||
|
||||
if (luaL_dofile(script->L, "lib/fennel/fennel.lua") == 0) {
|
||||
lua_setglobal(script->L, "fennel");
|
||||
|
||||
lua_getglobal(script->L, "fennel");
|
||||
lua_getfield(script->L, -1, "install");
|
||||
if (lua_isfunction(script->L, -1)) {
|
||||
if (lua_pcall(script->L, 0, 0, 0) != 0) {
|
||||
pxl8_warn("Failed to install fennel searcher: %s", lua_tostring(script->L, -1));
|
||||
lua_pop(script->L, 1);
|
||||
}
|
||||
} else {
|
||||
lua_pop(script->L, 1);
|
||||
}
|
||||
lua_pop(script->L, 1);
|
||||
}
|
||||
|
||||
script->last_error[0] = '\0';
|
||||
|
|
|
|||
|
|
@ -64,11 +64,13 @@ typedef struct pxl8_bounds {
|
|||
} pxl8_bounds;
|
||||
|
||||
typedef struct pxl8_input_state {
|
||||
bool keys[256];
|
||||
bool keys_down[256];
|
||||
bool keys_pressed[256];
|
||||
bool keys_released[256];
|
||||
|
||||
bool mouse_buttons[3];
|
||||
bool mouse_buttons_down[3];
|
||||
bool mouse_buttons_pressed[3];
|
||||
bool mouse_buttons_released[3];
|
||||
i32 mouse_wheel_x;
|
||||
i32 mouse_wheel_y;
|
||||
i32 mouse_x;
|
||||
|
|
|
|||
|
|
@ -38,26 +38,47 @@ static int mu_text_height(mu_Font font) {
|
|||
return f->default_height;
|
||||
}
|
||||
|
||||
static void pxl8_ui_render_icon(pxl8_gfx* gfx, i32 id, i32 x, i32 y, i32 w, i32 h, u8 color) {
|
||||
switch (id) {
|
||||
case 2: {
|
||||
i32 cx = x + w / 2;
|
||||
i32 cy = y + h / 2;
|
||||
i32 size = (w < h ? w : h) / 3;
|
||||
pxl8_line(gfx, cx - size, cy, cx, cy + size, color);
|
||||
pxl8_line(gfx, cx, cy + size, cx + size, cy - size, color);
|
||||
break;
|
||||
}
|
||||
case 1: {
|
||||
i32 cx = x + w / 2;
|
||||
i32 cy = y + h / 2;
|
||||
i32 size = (w < h ? w : h) / 4;
|
||||
pxl8_line(gfx, cx - size, cy - size, cx + size, cy + size, color);
|
||||
pxl8_line(gfx, cx + size, cy - size, cx - size, cy + size, color);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void pxl8_ui_render_commands(pxl8_ui* ui) {
|
||||
mu_Command* cmd = NULL;
|
||||
while (mu_next_command(&ui->mu_ctx, &cmd)) {
|
||||
switch (cmd->type) {
|
||||
case MU_COMMAND_RECT: {
|
||||
mu_RectCommand* rc = (mu_RectCommand*)cmd;
|
||||
u8 color = rc->color.r;
|
||||
pxl8_rect_fill(ui->gfx, rc->rect.x, rc->rect.y, rc->rect.w, rc->rect.h, color);
|
||||
pxl8_rect_fill(ui->gfx, rc->rect.x, rc->rect.y, rc->rect.w, rc->rect.h, rc->color.r);
|
||||
break;
|
||||
}
|
||||
case MU_COMMAND_TEXT: {
|
||||
mu_TextCommand* tc = (mu_TextCommand*)cmd;
|
||||
u8 color = tc->color.r;
|
||||
pxl8_text(ui->gfx, tc->str, tc->pos.x, tc->pos.y, color);
|
||||
pxl8_text(ui->gfx, tc->str, tc->pos.x, tc->pos.y, tc->color.r);
|
||||
break;
|
||||
}
|
||||
case MU_COMMAND_CLIP: {
|
||||
break;
|
||||
}
|
||||
case MU_COMMAND_ICON: {
|
||||
mu_IconCommand* ic = (mu_IconCommand*)cmd;
|
||||
pxl8_ui_render_icon(ui->gfx, ic->id, ic->rect.x, ic->rect.y, ic->rect.w, ic->rect.h, ic->color.r);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -104,6 +125,21 @@ pxl8_ui* pxl8_ui_create(pxl8_gfx* gfx) {
|
|||
ui->mu_ctx.text_height = mu_text_height;
|
||||
ui->mu_ctx.text_width = mu_text_width;
|
||||
|
||||
ui->mu_ctx.style->colors[0] = (mu_Color){15, 0, 0, 255};
|
||||
ui->mu_ctx.style->colors[1] = (mu_Color){8, 0, 0, 255};
|
||||
ui->mu_ctx.style->colors[2] = (mu_Color){1, 0, 0, 255};
|
||||
ui->mu_ctx.style->colors[3] = (mu_Color){2, 0, 0, 255};
|
||||
ui->mu_ctx.style->colors[4] = (mu_Color){15, 0, 0, 255};
|
||||
ui->mu_ctx.style->colors[5] = (mu_Color){0, 0, 0, 0};
|
||||
ui->mu_ctx.style->colors[6] = (mu_Color){7, 0, 0, 255};
|
||||
ui->mu_ctx.style->colors[7] = (mu_Color){8, 0, 0, 255};
|
||||
ui->mu_ctx.style->colors[8] = (mu_Color){10, 0, 0, 255};
|
||||
ui->mu_ctx.style->colors[9] = (mu_Color){2, 0, 0, 255};
|
||||
ui->mu_ctx.style->colors[10] = (mu_Color){3, 0, 0, 255};
|
||||
ui->mu_ctx.style->colors[11] = (mu_Color){10, 0, 0, 255};
|
||||
ui->mu_ctx.style->colors[12] = (mu_Color){7, 0, 0, 255};
|
||||
ui->mu_ctx.style->colors[13] = (mu_Color){8, 0, 0, 255};
|
||||
|
||||
return ui;
|
||||
}
|
||||
|
||||
|
|
@ -163,6 +199,48 @@ bool pxl8_ui_button(pxl8_ui* ui, const char* label) {
|
|||
return mu_button(&ui->mu_ctx, label) & MU_RES_SUBMIT;
|
||||
}
|
||||
|
||||
bool pxl8_ui_checkbox(pxl8_ui* ui, const char* label, bool* state) {
|
||||
if (!ui || !state || !label) return false;
|
||||
|
||||
mu_Context* ctx = &ui->mu_ctx;
|
||||
mu_push_id(ctx, label, (int)strlen(label));
|
||||
|
||||
mu_Id id = mu_get_id(ctx, label, (int)strlen(label));
|
||||
mu_Rect r = mu_layout_next(ctx);
|
||||
mu_Rect box = mu_rect(r.x, r.y, r.h, r.h);
|
||||
|
||||
int had_focus_before = (ctx->focus == id);
|
||||
mu_update_control(ctx, id, r, 0);
|
||||
int has_focus_after = (ctx->focus == id);
|
||||
int mouseover = mu_mouse_over(ctx, r);
|
||||
|
||||
int res = 0;
|
||||
int int_state = *state ? 1 : 0;
|
||||
|
||||
if (had_focus_before && !has_focus_after && !ctx->mouse_down && mouseover) {
|
||||
res |= MU_RES_CHANGE;
|
||||
int_state = !int_state;
|
||||
}
|
||||
|
||||
mu_draw_control_frame(ctx, id, box, MU_COLOR_BASE, 0);
|
||||
if (int_state) {
|
||||
mu_draw_icon(ctx, MU_ICON_CHECK, box, ctx->style->colors[MU_COLOR_TEXT]);
|
||||
}
|
||||
r = mu_rect(r.x + box.w, r.y, r.w - box.w, r.h);
|
||||
mu_draw_control_text(ctx, label, r, MU_COLOR_TEXT, 0);
|
||||
|
||||
mu_pop_id(ctx);
|
||||
|
||||
*state = int_state != 0;
|
||||
return res & MU_RES_CHANGE;
|
||||
}
|
||||
|
||||
void pxl8_ui_indent(pxl8_ui* ui, i32 amount) {
|
||||
if (!ui) return;
|
||||
mu_Layout* layout = &ui->mu_ctx.layout_stack.items[ui->mu_ctx.layout_stack.idx - 1];
|
||||
layout->indent += amount;
|
||||
}
|
||||
|
||||
void pxl8_ui_label(pxl8_ui* ui, const char* text) {
|
||||
if (!ui || !text) return;
|
||||
mu_label(&ui->mu_ctx, text);
|
||||
|
|
@ -205,6 +283,14 @@ void pxl8_ui_window_end(pxl8_ui* ui) {
|
|||
mu_end_window(&ui->mu_ctx);
|
||||
}
|
||||
|
||||
void pxl8_ui_window_set_open(pxl8_ui* ui, const char* title, bool open) {
|
||||
if (!ui || !title) return;
|
||||
mu_Container* win = mu_get_container(&ui->mu_ctx, title);
|
||||
if (win) {
|
||||
win->open = open ? 1 : 0;
|
||||
}
|
||||
}
|
||||
|
||||
pxl8_frame_theme pxl8_ui_theme_default(void) {
|
||||
pxl8_frame_theme theme = {0};
|
||||
theme.bg_color = 0;
|
||||
|
|
|
|||
|
|
@ -5,6 +5,23 @@
|
|||
|
||||
typedef struct pxl8_ui pxl8_ui;
|
||||
|
||||
typedef struct pxl8_ui_theme {
|
||||
u8 text;
|
||||
u8 border;
|
||||
u8 window_bg;
|
||||
u8 title_bg;
|
||||
u8 title_text;
|
||||
u8 panel_bg;
|
||||
u8 button;
|
||||
u8 button_hover;
|
||||
u8 button_focus;
|
||||
u8 base;
|
||||
u8 base_hover;
|
||||
u8 base_focus;
|
||||
u8 scroll_base;
|
||||
u8 scroll_thumb;
|
||||
} pxl8_ui_theme;
|
||||
|
||||
typedef struct pxl8_frame_theme {
|
||||
u8 bg_color;
|
||||
u32 sprite_id;
|
||||
|
|
@ -44,12 +61,15 @@ void pxl8_ui_input_scroll(pxl8_ui* ui, i32 x, i32 y);
|
|||
void pxl8_ui_input_text(pxl8_ui* ui, const char* text);
|
||||
|
||||
bool pxl8_ui_button(pxl8_ui* ui, const char* label);
|
||||
bool pxl8_ui_checkbox(pxl8_ui* ui, const char* label, bool* state);
|
||||
void pxl8_ui_indent(pxl8_ui* ui, i32 amount);
|
||||
void pxl8_ui_label(pxl8_ui* ui, const char* text);
|
||||
void pxl8_ui_layout_row(pxl8_ui* ui, i32 item_count, const i32* widths, i32 height);
|
||||
i32 pxl8_ui_menu(pxl8_ui* ui, pxl8_menu_item* items, i32 item_count);
|
||||
void pxl8_ui_panel(pxl8_ui* ui, pxl8_bounds rect, pxl8_frame_theme* theme);
|
||||
bool pxl8_ui_window_begin(pxl8_ui* ui, const char* title, pxl8_bounds rect, i32 options);
|
||||
void pxl8_ui_window_end(pxl8_ui* ui);
|
||||
void pxl8_ui_window_set_open(pxl8_ui* ui, const char* title, bool open);
|
||||
|
||||
pxl8_frame_theme pxl8_ui_theme_default(void);
|
||||
|
||||
|
|
|
|||
|
|
@ -30,6 +30,10 @@ typedef struct pxl8_raster_bar {
|
|||
f32 speed;
|
||||
} pxl8_raster_bar;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
pxl8_particles* pxl8_particles_create(u32 max_count);
|
||||
void pxl8_particles_destroy(pxl8_particles* particles);
|
||||
|
||||
|
|
@ -51,3 +55,7 @@ void pxl8_vfx_raster_bars(pxl8_gfx* gfx, pxl8_raster_bar* bars, u32 bar_count, f
|
|||
void pxl8_vfx_rotozoom(pxl8_gfx* gfx, f32 angle, f32 zoom, i32 cx, i32 cy);
|
||||
void pxl8_vfx_tunnel(pxl8_gfx* gfx, f32 time, f32 speed, f32 twist);
|
||||
void pxl8_vfx_water_ripple(pxl8_gfx* gfx, f32* height_map, i32 drop_x, i32 drop_y, f32 damping);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue