Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions demo/common/nuklear_console_demo.c
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,11 @@ void nk_console_demo_list_view_item_clicked(struct nk_console* widget, void* use
nk_console_show_message(widget, message);
}

void nk_console_demo_navigate_to_path(struct nk_console* button, void* user_data) {
NK_UNUSED(button);
nk_console_navigate_to_path(button, (const char*)user_data);
}

struct nk_console* nuklear_console_demo_init(struct nk_context* ctx, void* user_data, struct nk_image image) {
console = nk_console_init(ctx);

Expand Down Expand Up @@ -450,6 +455,22 @@ struct nk_console* nuklear_console_demo_init(struct nk_context* ctx, void* user_
calc->tooltip = "Demo rows and grids!";
}

// Open Path
struct nk_console* open_path = nk_console_button(console, "Open Path");
{
nk_console_label(open_path, "Navigate anywhere with nk_console_navigate_to_path():");
struct nk_console* b;
b = nk_console_button(open_path, "Widgets");
nk_console_add_event_handler(b, NK_CONSOLE_EVENT_CLICKED, &nk_console_demo_navigate_to_path, "Widgets", NULL);
b = nk_console_button(open_path, "Widgets/Labels");
nk_console_add_event_handler(b, NK_CONSOLE_EVENT_CLICKED, &nk_console_demo_navigate_to_path, "Widgets/Labels", NULL);
b = nk_console_button(open_path, "Widgets/Sliders");
nk_console_add_event_handler(b, NK_CONSOLE_EVENT_CLICKED, &nk_console_demo_navigate_to_path, "Widgets/Sliders", NULL);
b = nk_console_button(open_path, "Calculator");
nk_console_add_event_handler(b, NK_CONSOLE_EVENT_CLICKED, &nk_console_demo_navigate_to_path, "Calculator", NULL);
nk_console_button_onclick(open_path, "Back", &nk_console_button_back);
}

nk_console_button(console, "Save Game")->disabled = nk_true;
struct nk_console* quit_button = nk_console_button_onclick(console, "Quit Game", &button_clicked);
nk_console_add_event(quit_button, NK_CONSOLE_EVENT_FOCUS, &nk_console_quit_button_focused);
Expand Down
100 changes: 100 additions & 0 deletions nuklear_console.h
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,33 @@ NK_API void nk_console_set_user_data(nk_console* console, void* user_data);
*/
NK_API void nk_console_navigate_back(nk_console* leaving_parent);

/**
* Get a widget by a slash-separated path of labels, starting from the top-level console.
*
* Example: nk_console_find_by_path(console, "Widgets/Labels")
* A leading slash is optional: "/Widgets" and "Widgets" are equivalent.
*
* @param console Any widget within the console family.
* @param path Slash-separated widget labels (e.g. "Widgets/Labels").
*
* @return The matching widget, or NULL if not found.
*/
NK_API nk_console* nk_console_find_by_path(nk_console* console, const char* path);

/**
* Navigate to a widget by a slash-separated path of labels.
*
* If the target widget has children, it becomes the active parent. If it has no children, its parent becomes the active parent and the widget is selected as the active widget.
*
* Example: nk_console_navigate_to_path(console, "Widgets/Labels")
*
* @param console Any widget within the console family.
* @param path Slash-separated widget labels (e.g. "Widgets/Labels").
*
* @return nk_true if navigation succeeded, nk_false if the path was not found.
*/
NK_API nk_bool nk_console_navigate_to_path(nk_console* console, const char* path);

#if defined(__cplusplus)
}
#endif
Expand Down Expand Up @@ -1206,6 +1233,79 @@ NK_API void nk_console_navigate_back(nk_console* leaving_parent) {
nk_console_trigger_event(leaving_parent, NK_CONSOLE_EVENT_BACK);
}

NK_API nk_console* nk_console_find_by_path(nk_console* console, const char* path) {
if (console == NULL || path == NULL) {
return NULL;
}

nk_console* current = nk_console_get_top(console);
if (path[0] == '\0') {
return current;
}
if (path[0] == '/') {
path++;
}

char segment[256];
while (path[0] != '\0') {
const char* slash = strchr(path, '/');
int len = (slash != NULL) ? (int)(slash - path) : (int)nk_strlen(path);
if (len == 0) {
path++;
continue;
}

int copy_len = len < 255 ? len : 255;
NK_MEMCPY(segment, path, (nk_size)copy_len);
segment[copy_len] = '\0';

nk_console* found = NULL;
if (current->children != NULL) {
for (size_t i = 0; i < cvector_size(current->children); i++) {
nk_console* child = current->children[i];
if (child == NULL || child->label == NULL) {
continue;
}
int label_len = child->label_length > 0
? child->label_length
: (int)nk_strlen(child->label);
if (label_len == copy_len &&
strncmp(child->label, segment, (size_t)copy_len) == 0) {
found = child;
break;
}
}
}
if (found == NULL) {
return NULL;
}
current = found;
path += len;
if (path[0] == '/') {
path++;
}
}
return current;
}

NK_API nk_bool nk_console_navigate_to_path(nk_console* console, const char* path) {
nk_console* target = nk_console_find_by_path(console, path);
if (target == NULL) {
return nk_false;
}

if (target->children != NULL) {
nk_console_set_active_parent(target);
}
else {
if (target->parent != NULL) {
nk_console_set_active_parent(target->parent);
}
nk_console_set_active_widget(target);
}
return nk_true;
}

NK_API nk_bool nk_console_button_pushed(nk_console* console, int button) {
if (console == NULL) {
return nk_false;
Expand Down
Loading