From 6ff50cb5212739e378011060d1d3a7c93b3bf9c0 Mon Sep 17 00:00:00 2001 From: John Alanbrook Date: Fri, 11 Jul 2025 14:11:34 -0500 Subject: [PATCH] add combo box to imgui --- prosperon/prosperon.ce | 2 -- source/qjs_imgui.cpp | 77 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 77 insertions(+), 2 deletions(-) diff --git a/prosperon/prosperon.ce b/prosperon/prosperon.ce index edce3bf1..26efc632 100644 --- a/prosperon/prosperon.ce +++ b/prosperon/prosperon.ce @@ -323,8 +323,6 @@ function translate_draw_commands(commands) { tempMap.tiles[arrayX][arrayY] = img }) - - // Generate geometry for this texture group var geom = geometry.tilemap_to_data(tempMap) geom.texture_id = parseInt(texId) diff --git a/source/qjs_imgui.cpp b/source/qjs_imgui.cpp index 31c21b08..a55072b8 100644 --- a/source/qjs_imgui.cpp +++ b/source/qjs_imgui.cpp @@ -160,6 +160,82 @@ JSC_SSCALL(imgui_textbox, ret = JS_DupValue(js,argv[1]); ) +JSC_SCALL(imgui_combo, + // argv[0] = label (str) + // argv[1] = current selection index or string + // argv[2] = array of options or single string with \0 separators + + int current_item = 0; + const char *preview_str = NULL; + + if (JS_IsNumber(argv[1])) { + current_item = js2number(js, argv[1]); + } else if (JS_IsString(argv[1])) { + preview_str = JS_ToCString(js, argv[1]); + } + + if (JS_IsArray(js, argv[2])) { + // Handle array of strings + int item_count = JS_ArrayLength(js, argv[2]); + const char **items = (const char**)malloc(sizeof(char*) * item_count); + + for (int i = 0; i < item_count; i++) { + JSValue item = JS_GetPropertyUint32(js, argv[2], i); + items[i] = JS_ToCString(js, item); + JS_FreeValue(js, item); + } + + // If preview_str is set, find its index + if (preview_str) { + for (int i = 0; i < item_count; i++) { + if (strcmp(items[i], preview_str) == 0) { + current_item = i; + break; + } + } + } + + if (ImGui::Combo(str, ¤t_item, items, item_count)) { + ret = JS_NewString(js, items[current_item]); + } else { + if (preview_str) { + ret = JS_DupValue(js, argv[1]); + } else { + ret = JS_NewString(js, items[current_item]); + } + } + + // Free the strings + for (int i = 0; i < item_count; i++) { + JS_FreeCString(js, items[i]); + } + free(items); + + } else if (JS_IsString(argv[2])) { + // Handle single string with \0 separators + const char *items_str = JS_ToCString(js, argv[2]); + + if (ImGui::Combo(str, ¤t_item, items_str)) { + // Find the selected item string + const char *p = items_str; + for (int i = 0; i < current_item; i++) { + p += strlen(p) + 1; + } + ret = JS_NewString(js, p); + } else { + ret = JS_DupValue(js, argv[1]); + } + + JS_FreeCString(js, items_str); + } else { + ret = JS_DupValue(js, argv[1]); + } + + if (preview_str) { + JS_FreeCString(js, preview_str); + } +) + JSC_SCALL(imgui_text, ImGui::Text("%s", str) ) JSC_SCALL(imgui_button, @@ -837,6 +913,7 @@ const JSCFunctionListEntry js_imgui_funcs[] = { MIST_FUNC_DEF(imgui, slider, 4), MIST_FUNC_DEF(imgui, intslider, 4), MIST_FUNC_DEF(imgui, checkbox, 2), + MIST_FUNC_DEF(imgui, combo, 3), // Basic widgets MIST_FUNC_DEF(imgui, text, 1),