初始化版本
This commit is contained in:
115
api/menu_api.c
Normal file
115
api/menu_api.c
Normal file
@ -0,0 +1,115 @@
|
||||
#include "menu_api.h"
|
||||
#include "../src/core/menu_core.h"
|
||||
#include "../src/core/menu_event.h"
|
||||
#include "../src/core/menu_stack.h"
|
||||
#include <stddef.h>
|
||||
|
||||
static MenuCoreCtx g_menu_ctx;
|
||||
|
||||
MenuErrCode menu_init(void) {
|
||||
return menu_core_init(&g_menu_ctx);
|
||||
}
|
||||
|
||||
void menu_deinit(void) {
|
||||
// Cleanup if needed
|
||||
}
|
||||
|
||||
void menu_main_loop(uint32_t tick) {
|
||||
menu_core_loop(&g_menu_ctx, tick);
|
||||
}
|
||||
|
||||
MenuNodeId menu_register_node(
|
||||
MenuNodeId id,
|
||||
MenuNodeId parent_id,
|
||||
const char* name,
|
||||
MenuCallback enter_cb,
|
||||
MenuCallback exit_cb
|
||||
) {
|
||||
return menu_register_node_ex(id, parent_id, name, enter_cb, exit_cb, NULL, NULL);
|
||||
}
|
||||
|
||||
MenuNodeId menu_register_node_ex(
|
||||
MenuNodeId id,
|
||||
MenuNodeId parent_id,
|
||||
const char* name,
|
||||
MenuCallback enter_cb,
|
||||
MenuCallback exit_cb,
|
||||
MenuCallback render_cb,
|
||||
void* user_data
|
||||
) {
|
||||
MenuNode node = {0};
|
||||
node.id = id;
|
||||
node.parent_id = parent_id;
|
||||
node.name = name;
|
||||
node.enter_cb = enter_cb;
|
||||
node.exit_cb = exit_cb;
|
||||
node.render_cb = render_cb;
|
||||
node.user_data = user_data;
|
||||
node.flags.is_enabled = true;
|
||||
node.flags.is_visible = true;
|
||||
node.flags.is_registered = false; // Will be set by core
|
||||
node.param_id = 0;
|
||||
node.permission_level = 0;
|
||||
|
||||
MenuNodeId new_id = 0;
|
||||
if (menu_core_register_node(&g_menu_ctx, &node, &new_id) == MENU_ERR_OK) {
|
||||
return new_id;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
MenuErrCode menu_post_event(MenuEventType type, uint32_t param) {
|
||||
return menu_event_post(&g_menu_ctx.event_queue, type, param);
|
||||
}
|
||||
|
||||
MenuErrCode menu_enter(void) {
|
||||
// We try to enter the first available root node.
|
||||
// We can trigger an event or just let the loop handle it.
|
||||
// If we rely on handle_event to enter root on NULL current,
|
||||
// we just need to ensure loop is called.
|
||||
// But explicitly:
|
||||
if (g_menu_ctx.current_node_id == 0) {
|
||||
// Force finding a root
|
||||
// Since we don't have public access to ctx nodes from here easily without exposing everything,
|
||||
// we can just call handle_event with a dummy event or NONE event if handle_event checks NULL current.
|
||||
// But handle_event checks event type.
|
||||
// We can add MENU_EVENT_NONE handling in handle_event to check entry?
|
||||
// Or just manually find root here.
|
||||
// We have access to g_menu_ctx.
|
||||
for(int i=0; i<MENU_CONFIG_MAX_NODES; i++) {
|
||||
if(g_menu_ctx.nodes[i].flags.is_registered && g_menu_ctx.nodes[i].parent_id == 0) {
|
||||
// Enter root
|
||||
MenuErrCode ret = menu_core_enter_node(&g_menu_ctx, g_menu_ctx.nodes[i].id);
|
||||
if (ret != MENU_ERR_OK) return ret;
|
||||
|
||||
// Optimization: Automatically enter first child if root has children
|
||||
// This makes the menu start with the first item selected
|
||||
if (g_menu_ctx.nodes[i].first_child_id != 0) {
|
||||
// We need to simulate Enter key or just manually transition
|
||||
// Manual transition:
|
||||
// Push root to stack
|
||||
// But menu_core_enter_node logic doesn't push to stack automatically unless via handle_event
|
||||
// So we mimic handle_event logic
|
||||
menu_stack_push(&g_menu_ctx.stack, g_menu_ctx.nodes[i].id);
|
||||
// Exit root (deselect)
|
||||
menu_core_exit_node(&g_menu_ctx, g_menu_ctx.nodes[i].id);
|
||||
// Enter child
|
||||
return menu_core_enter_node(&g_menu_ctx, g_menu_ctx.nodes[i].first_child_id);
|
||||
}
|
||||
return MENU_ERR_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
return MENU_ERR_OK;
|
||||
}
|
||||
|
||||
MenuErrCode menu_back(void) {
|
||||
return menu_post_event(MENU_EVENT_KEY_ESC, 0);
|
||||
}
|
||||
|
||||
MenuErrCode menu_node_bind_param(MenuNodeId node_id, uint16_t param_id) {
|
||||
MenuNode* node = menu_core_get_node(&g_menu_ctx, node_id);
|
||||
if (!node) return MENU_ERR_NOT_FOUND;
|
||||
node->param_id = param_id;
|
||||
return MENU_ERR_OK;
|
||||
}
|
||||
Reference in New Issue
Block a user