tomato-testing/src/chat_gui/settings_window.cpp
2024-09-22 12:35:19 +02:00

221 lines
6.7 KiB
C++

#include "./settings_window.hpp"
#include <solanaceae/util/simple_config_model.hpp>
#include <imgui/imgui.h>
#include <imgui/misc/cpp/imgui_stdlib.h>
#include <tuple>
#include <iostream>
template<typename FNCat, typename ...MapTypes>
void iterateMultMaps(FNCat&& fn_cat, MapTypes& ...map_types) {
// the iterators
std::tuple its{map_types.begin()...};
// assuming ever maps returned .begin() has a unique type
// TODO: use index instead
while ( ((std::get<decltype(map_types.begin())>(its) != map_types.end()) || ...) ) {
// figure out current module and participants
std::string_view current_module;
// find current_module
((
current_module = (
std::get<decltype(map_types.begin())>(its) != map_types.end() && (current_module.empty() || current_module >= std::get<decltype(map_types.begin())>(its)->first)
) ? std::get<decltype(map_types.begin())>(its)->first : current_module
), ...);
assert(!current_module.empty());
fn_cat(
current_module,
((
std::get<decltype(map_types.begin())>(its) != map_types.end() &&
current_module == std::get<decltype(map_types.begin())>(its)->first
) ? std::get<decltype(map_types.begin())>(its)->second : decltype(map_types.begin()->second){})...
);
// increment participanting iterators
((
(
std::get<decltype(map_types.begin())>(its) != map_types.end() &&
current_module == std::get<decltype(map_types.begin())>(its)->first
) ? void(++std::get<decltype(map_types.begin())>(its)) : void(0)
), ...);
}
}
//template<typename T>
//static void renderConfigCat(SimpleConfigModel& conf, std::string_view cmodule, std::string_view ccat, const std::pair<std::optional<T>, std::map<std::string, T>>& cat_dat) {
//if (cat_dat.first.has_value()) {
//T tmp = cat_dat.first.value();
////if (ImGui::Checkbox(ccat.data(), &tmp)) {
////conf.set(cmodule, ccat, tmp);
////}
//} else if (!cat_dat.second.empty()) {
//ImGui::Text("uhhh");
//}
//}
static void renderConfigCat(SimpleConfigModel& conf, std::string_view cmodule, std::string_view ccat, const std::pair<std::optional<bool>, std::map<std::string, bool>>& cat_dat) {
if (cat_dat.first.has_value()) {
bool tmp = cat_dat.first.value();
if (ImGui::Checkbox(ccat.data(), &tmp)) {
conf.set(cmodule, ccat, tmp);
}
} else if (!cat_dat.second.empty()) {
ImGui::Text("uhhh");
}
}
static void renderConfigCat(SimpleConfigModel& conf, std::string_view cmodule, std::string_view ccat, const std::pair<std::optional<int64_t>, std::map<std::string, int64_t>>& cat_dat) {
if (cat_dat.first.has_value()) {
int64_t tmp = cat_dat.first.value();
if (ImGui::InputScalar(ccat.data(), ImGuiDataType_S64, &tmp)) {
conf.set(cmodule, ccat, tmp);
}
} else if (!cat_dat.second.empty()) {
ImGui::Text("uhhh");
}
}
static void renderConfigCat(SimpleConfigModel& conf, std::string_view cmodule, std::string_view ccat, const std::pair<std::optional<double>, std::map<std::string, double>>& cat_dat) {
if (cat_dat.first.has_value()) {
double tmp = cat_dat.first.value();
if (ImGui::InputDouble(ccat.data(), &tmp)) {
conf.set(cmodule, ccat, tmp);
}
} else if (!cat_dat.second.empty()) {
ImGui::Text("uhhh");
}
}
static void renderConfigCat(SimpleConfigModel& conf, std::string_view cmodule, std::string_view ccat, const std::pair<std::optional<std::string>, std::map<std::string, std::string>>& cat_dat) {
if (cat_dat.first.has_value()) {
std::string tmp = cat_dat.first.value();
if (ImGui::InputText(ccat.data(), &tmp)) {
conf.set(cmodule, ccat, CM_ISV{tmp});
}
} else if (!cat_dat.second.empty()) {
ImGui::Text("uhhh");
}
}
SettingsWindow::SettingsWindow(SimpleConfigModel& conf) : _conf(conf) {
}
void SettingsWindow::render(void) {
{ // main window menubar injection
// assumes the window "tomato" was rendered already by cg
if (ImGui::Begin("tomato")) {
if (ImGui::BeginMenuBar()) {
ImGui::Separator();
if (ImGui::BeginMenu("Settings")) {
if (ImGui::MenuItem("settings window", nullptr, _show_window)) {
_show_window = !_show_window;
}
ImGui::EndMenu();
}
ImGui::EndMenuBar();
}
}
ImGui::End();
}
if (_show_window) {
if (ImGui::Begin("Settings", &_show_window)) {
ImGui::TextDisabled("most settings are only fetched once at program startup");
// ufff
// we need to iterate 4 maps, ideally in lexicographic order
// (pain)
// std::maps should be ordered more or less correctly
// (less pain)
// its recursive
// (pain)
// but the code is reusable
// (less pain)
iterateMultMaps(
[this](std::string_view cmodule, const auto& ...mod_map_types) {
if (ImGui::CollapsingHeader(cmodule.data())) {
iterateMultMaps(
[this, cmodule](std::string_view ccat, const auto& ...cat_map_types) {
(renderConfigCat(_conf, cmodule, ccat, cat_map_types), ...);
},
mod_map_types...
);
}
},
_conf._map_bool,
_conf._map_int,
_conf._map_double,
_conf._map_string
);
#if 0
auto it_b = _conf._map_bool.begin();
auto it_i = _conf._map_int.begin();
auto it_d = _conf._map_double.begin();
auto it_s = _conf._map_string.begin();
while (
it_b != _conf._map_bool.end() ||
it_i != _conf._map_int.end() ||
it_d != _conf._map_double.end() ||
it_s != _conf._map_string.end()
) {
// figure out current module
std::string_view current_module;
bool bool_is_curr = false;
bool int_is_curr = false;
bool double_is_curr = false;
bool string_is_curr = false;
if (it_b != _conf._map_bool.end() && (current_module.empty() || current_module >= it_b->first)) {
//std::cerr << "SET bool\n";
bool_is_curr = true;
current_module = it_b->first;
}
if (it_i != _conf._map_int.end() && (current_module.empty() || current_module >= it_i->first)) {
//std::cerr << "SET int\n";
int_is_curr = true;
current_module = it_i->first;
}
if (it_d != _conf._map_double.end() && (current_module.empty() || current_module >= it_d->first)) {
//std::cerr << "SET double\n";
double_is_curr = true;
current_module = it_d->first;
}
if (it_s != _conf._map_string.end() && (current_module.empty() || current_module >= it_s->first)) {
//std::cerr << "SET string\n";
string_is_curr = true;
current_module = it_s->first;
}
assert(!current_module.empty());
//ImGui::Text("module '%s'", current_module.data());
if (ImGui::CollapsingHeader(current_module.data())) {
// ... do the whole 4way iterate again but on categoy
}
// after the module, increment iterators pointing to current_module
if (bool_is_curr) {
it_b++;
}
if (int_is_curr) {
it_i++;
}
if (double_is_curr) {
it_d++;
}
if (string_is_curr) {
it_s++;
}
}
#endif
}
ImGui::End();
}
}