forked from Green-Sky/tomato
222 lines
6.7 KiB
C++
222 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")) {
|
|
_show_window = true;
|
|
}
|
|
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();
|
|
}
|
|
}
|
|
|