#include #include #include #include #include #include namespace module_manager_menu { char modName[1024]; std::vector modTypes; std::string toBeRemoved; std::string modTypesTxt; std::string errorMessage; int modTypeId; bool confirmOpened = false; bool errorOpen = false; void init() { modName[0] = 0; modTypes.clear(); modTypesTxt = ""; for (auto& [name, mod] : core::moduleManager.modules) { modTypes.push_back(name); modTypesTxt += name; modTypesTxt += '\0'; } modTypeId = 0; } void draw(void* ctx) { bool modified = false; // Calculate delete button size and cell size ImVec2 cellpad = ImGui::GetStyle().CellPadding; float lheight = ImGui::GetTextLineHeight(); float cellWidth = lheight - (2.0f * cellpad.y); float hdiff = cellpad.x - cellpad.y; ImVec2 btnSize = ImVec2(lheight, lheight - 1); ImVec2 textOff = ImVec2(3.0f * style::uiScale, -5.0f * style::uiScale); if (ImGui::BeginTable("Module Manager Table", 3, ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg | ImGuiTableFlags_ScrollY, ImVec2(0, 200.0f * style::uiScale))) { ImGui::TableSetupColumn("Name"); ImGui::TableSetupColumn("Type"); ImGui::TableSetupColumn("", ImGuiTableColumnFlags_WidthFixed, cellWidth); ImGui::TableSetupScrollFreeze(3, 1); ImGui::TableHeadersRow(); for (auto& [name, inst] : core::moduleManager.instances) { ImGui::TableNextRow(); ImGui::TableSetColumnIndex(0); ImGui::TextUnformatted(name.c_str()); ImGui::TableSetColumnIndex(1); ImGui::TextUnformatted(inst.module.info->name); ImGui::TableSetColumnIndex(2); ImVec2 cpos = ImGui::GetCursorPos(); ImGui::SetCursorPos(ImVec2(cpos.x - hdiff, cpos.y + 1)); if (ImGui::Button(("##module_mgr_" + name).c_str(), btnSize)) { toBeRemoved = name; confirmOpened = true; } ImGui::SetCursorPos(ImVec2(cpos.x + textOff.x, cpos.y + textOff.y)); ImGui::TextUnformatted("_"); } ImGui::EndTable(); } if (ImGui::GenericDialog("module_mgr_confirm_", confirmOpened, GENERIC_DIALOG_BUTTONS_YES_NO, []() { ImGui::Text("Deleting \"%s\". Are you sure?", toBeRemoved.c_str()); }) == GENERIC_DIALOG_BUTTON_YES) { core::moduleManager.deleteInstance(toBeRemoved); modified = true; } ImGui::GenericDialog("module_mgr_error_", errorOpen, GENERIC_DIALOG_BUTTONS_OK, []() { ImGui::TextUnformatted(errorMessage.c_str()); }); // Add module row with slightly different settings if (ImGui::BeginTable("Module Manager Add Table", 3)) { ImGui::TableSetupColumn("Name"); ImGui::TableSetupColumn("Type"); ImGui::TableSetupColumn("", ImGuiTableColumnFlags_WidthFixed, cellWidth + cellpad.x); ImGui::TableNextRow(); ImGui::TableSetColumnIndex(0); ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x + cellpad.x); ImGui::InputText("##module_mod_name", modName, 1000); ImGui::TableSetColumnIndex(1); ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x + cellpad.x); ImGui::Combo("##module_mgr_type", &modTypeId, modTypesTxt.c_str()); ImGui::TableSetColumnIndex(2); if (strlen(modName) == 0) { style::beginDisabled(); } if (ImGui::Button("+##module_mgr_add_btn", ImVec2(btnSize.x, 0))) { if (!core::moduleManager.createInstance(modName, modTypes[modTypeId])) { core::moduleManager.postInit(modName); modified = true; } else { errorMessage = "Could not create new instance of " + modTypes[modTypeId]; errorOpen = true; } } if (strlen(modName) == 0) { style::endDisabled(); } ImGui::EndTable(); } if (modified) { // Update enabled and disabled modules core::configManager.acquire(); json instances; for (auto [_name, inst] : core::moduleManager.instances) { instances[_name]["module"] = inst.module.info->name; instances[_name]["enabled"] = inst.instance->isEnabled(); } core::configManager.conf["moduleInstances"] = instances; core::configManager.release(true); } } }