2022-07-02 16:22:38 +02:00
|
|
|
#include <hex/api/imhex_api.hpp>
|
2021-08-29 14:18:45 +02:00
|
|
|
#include <hex/api/content_registry.hpp>
|
|
|
|
#include <hex/api/imhex_api.hpp>
|
2022-02-01 18:09:40 +01:00
|
|
|
#include <hex/api/localization.hpp>
|
2022-12-29 19:26:00 +01:00
|
|
|
#include <hex/api/theme_manager.hpp>
|
2021-09-08 15:18:24 +02:00
|
|
|
|
2022-07-02 16:22:38 +02:00
|
|
|
#include <hex/helpers/utils.hpp>
|
2023-03-23 11:23:07 +01:00
|
|
|
#include <hex/helpers/http_requests.hpp>
|
2022-07-02 16:22:38 +02:00
|
|
|
#include <hex/helpers/logger.hpp>
|
|
|
|
|
2021-08-29 14:18:45 +02:00
|
|
|
#include <imgui.h>
|
2022-02-18 22:34:54 +01:00
|
|
|
#include <hex/ui/imgui_imhex_extensions.h>
|
|
|
|
#include <fonts/codicons_font.h>
|
2021-08-29 14:18:45 +02:00
|
|
|
|
|
|
|
#include <nlohmann/json.hpp>
|
2021-01-22 18:01:39 +01:00
|
|
|
|
2023-01-08 16:06:26 +01:00
|
|
|
#include <ui/pattern_drawer.hpp>
|
|
|
|
|
2023-03-12 18:27:29 +01:00
|
|
|
#include <wolv/utils/guards.hpp>
|
|
|
|
|
2022-07-14 11:38:23 +02:00
|
|
|
namespace {
|
2022-10-02 17:30:26 +02:00
|
|
|
|
|
|
|
std::vector<std::fs::path> userFolders;
|
|
|
|
|
2023-03-21 15:33:43 +01:00
|
|
|
void loadUserFoldersFromSetting(const std::vector<std::string> &paths) {
|
2022-07-14 11:38:23 +02:00
|
|
|
userFolders.clear();
|
|
|
|
for (const auto &path : paths) {
|
2023-03-21 15:33:43 +01:00
|
|
|
userFolders.emplace_back(
|
|
|
|
reinterpret_cast<const char8_t*>(path.data()),
|
|
|
|
reinterpret_cast<const char8_t*>(path.data() + path.size())
|
|
|
|
);
|
2022-07-14 11:38:23 +02:00
|
|
|
}
|
|
|
|
}
|
2022-10-02 17:30:26 +02:00
|
|
|
|
|
|
|
}
|
2022-07-14 11:38:23 +02:00
|
|
|
|
2021-01-22 18:01:39 +01:00
|
|
|
namespace hex::plugin::builtin {
|
|
|
|
|
|
|
|
void registerSettings() {
|
|
|
|
|
2021-08-22 21:11:01 +02:00
|
|
|
/* General */
|
|
|
|
|
2022-10-29 23:43:40 +02:00
|
|
|
/* Values of this setting :
|
|
|
|
0 - do not check for updates on startup
|
|
|
|
1 - check for updates on startup
|
|
|
|
2 - default value - ask the user if he wants to check for updates. This value should only be encountered on the first startup.
|
|
|
|
*/
|
2023-05-05 22:03:45 +02:00
|
|
|
#if defined(HEX_UPDATE_CHECK)
|
2022-10-29 23:43:40 +02:00
|
|
|
ContentRegistry::Settings::add("hex.builtin.setting.general", "hex.builtin.setting.general.check_for_updates", 2, [](auto name, nlohmann::json &setting) {
|
|
|
|
static bool enabled = static_cast<int>(setting) == 1;
|
|
|
|
|
|
|
|
if (ImGui::Checkbox(name.data(), &enabled)) {
|
|
|
|
setting = static_cast<int>(enabled);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
});
|
2023-05-05 22:03:45 +02:00
|
|
|
#endif
|
2022-10-29 23:43:40 +02:00
|
|
|
|
2021-08-22 21:11:01 +02:00
|
|
|
ContentRegistry::Settings::add("hex.builtin.setting.general", "hex.builtin.setting.general.show_tips", 1, [](auto name, nlohmann::json &setting) {
|
2021-09-12 13:59:23 +02:00
|
|
|
static bool enabled = static_cast<int>(setting);
|
2021-08-22 21:11:01 +02:00
|
|
|
|
|
|
|
if (ImGui::Checkbox(name.data(), &enabled)) {
|
|
|
|
setting = static_cast<int>(enabled);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
});
|
|
|
|
|
2021-09-30 12:00:11 +02:00
|
|
|
ContentRegistry::Settings::add("hex.builtin.setting.general", "hex.builtin.setting.general.auto_load_patterns", 1, [](auto name, nlohmann::json &setting) {
|
|
|
|
static bool enabled = static_cast<int>(setting);
|
|
|
|
|
|
|
|
if (ImGui::Checkbox(name.data(), &enabled)) {
|
|
|
|
setting = static_cast<int>(enabled);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
});
|
|
|
|
|
2022-07-31 20:07:15 +02:00
|
|
|
ContentRegistry::Settings::add("hex.builtin.setting.general", "hex.builtin.setting.general.sync_pattern_source", 0, [](auto name, nlohmann::json &setting) {
|
|
|
|
static bool enabled = static_cast<int>(setting);
|
|
|
|
|
|
|
|
if (ImGui::Checkbox(name.data(), &enabled)) {
|
|
|
|
setting = static_cast<int>(enabled);
|
2022-10-27 13:11:09 +02:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
});
|
|
|
|
|
|
|
|
ContentRegistry::Settings::add("hex.builtin.setting.general", "hex.builtin.setting.general.enable_unicode", 1, [](auto name, nlohmann::json &setting) {
|
|
|
|
static bool enabled = static_cast<int>(setting);
|
|
|
|
|
|
|
|
if (ImGui::Checkbox(name.data(), &enabled)) {
|
|
|
|
setting = static_cast<int>(enabled);
|
2022-07-31 20:07:15 +02:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
});
|
|
|
|
|
2023-03-14 14:07:18 +01:00
|
|
|
ContentRegistry::Settings::add("hex.builtin.setting.general", "hex.builtin.setting.general.save_recent_providers", 1, [](auto name, nlohmann::json &setting) {
|
|
|
|
static bool enabled = static_cast<int>(setting);
|
|
|
|
|
|
|
|
if (ImGui::Checkbox(name.data(), &enabled)) {
|
|
|
|
setting = static_cast<int>(enabled);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
});
|
|
|
|
|
2023-05-15 11:30:24 +02:00
|
|
|
ContentRegistry::Settings::add("hex.builtin.setting.general", "hex.builtin.setting.general.network_interface", 0, [](auto name, nlohmann::json &setting) {
|
|
|
|
static bool enabled = static_cast<int>(setting);
|
|
|
|
|
|
|
|
if (ImGui::Checkbox(name.data(), &enabled)) {
|
|
|
|
setting = static_cast<int>(enabled);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
});
|
|
|
|
|
2021-08-22 21:11:01 +02:00
|
|
|
/* Interface */
|
|
|
|
|
2022-12-29 19:26:00 +01:00
|
|
|
ContentRegistry::Settings::add("hex.builtin.setting.interface", "hex.builtin.setting.interface.color", "Dark", [](auto name, nlohmann::json &setting) {
|
|
|
|
static auto selection = static_cast<std::string>(setting);
|
2021-02-13 15:15:32 +01:00
|
|
|
|
2023-03-23 20:35:16 +01:00
|
|
|
const auto themeNames = ThemeManager::getThemeNames();
|
2022-12-29 19:26:00 +01:00
|
|
|
bool changed = false;
|
2021-02-13 15:15:32 +01:00
|
|
|
|
2022-12-29 19:26:00 +01:00
|
|
|
if (ImGui::BeginCombo(name.data(), selection.c_str())) {
|
2023-03-23 20:35:16 +01:00
|
|
|
if (ImGui::Selectable(ThemeManager::NativeTheme, selection == ThemeManager::NativeTheme)) {
|
|
|
|
selection = ThemeManager::NativeTheme;
|
2022-12-29 19:26:00 +01:00
|
|
|
setting = selection;
|
|
|
|
ImHexApi::System::enableSystemThemeDetection(true);
|
|
|
|
changed = true;
|
|
|
|
}
|
2022-07-02 16:22:38 +02:00
|
|
|
|
2022-12-29 19:26:00 +01:00
|
|
|
for (const auto &themeName : themeNames) {
|
|
|
|
if (ImGui::Selectable(themeName.c_str(), selection == themeName)) {
|
|
|
|
selection = themeName;
|
|
|
|
setting = selection;
|
|
|
|
ImHexApi::System::enableSystemThemeDetection(false);
|
2023-03-23 20:35:16 +01:00
|
|
|
ThemeManager::changeTheme(selection);
|
2022-12-29 19:26:00 +01:00
|
|
|
changed = true;
|
|
|
|
}
|
|
|
|
}
|
2022-07-02 16:22:38 +02:00
|
|
|
|
2022-12-29 19:26:00 +01:00
|
|
|
ImGui::EndCombo();
|
2021-02-10 18:17:09 +01:00
|
|
|
}
|
|
|
|
|
2022-12-29 19:26:00 +01:00
|
|
|
return changed;
|
2021-02-10 18:17:09 +01:00
|
|
|
});
|
|
|
|
|
2022-02-21 21:46:25 +01:00
|
|
|
ContentRegistry::Settings::add(
|
|
|
|
"hex.builtin.setting.interface", "hex.builtin.setting.interface.scaling", 0, [](auto name, nlohmann::json &setting) {
|
|
|
|
static int selection = static_cast<int>(setting);
|
2021-08-21 13:55:21 +02:00
|
|
|
|
2022-02-21 21:46:25 +01:00
|
|
|
const char *scaling[] = {
|
|
|
|
"hex.builtin.setting.interface.scaling.native"_lang,
|
|
|
|
"hex.builtin.setting.interface.scaling.x0_5"_lang,
|
|
|
|
"hex.builtin.setting.interface.scaling.x1_0"_lang,
|
|
|
|
"hex.builtin.setting.interface.scaling.x1_5"_lang,
|
|
|
|
"hex.builtin.setting.interface.scaling.x2_0"_lang,
|
|
|
|
};
|
2021-08-21 13:55:21 +02:00
|
|
|
|
2022-02-21 21:46:25 +01:00
|
|
|
if (ImGui::Combo(name.data(), &selection, scaling, IM_ARRAYSIZE(scaling))) {
|
|
|
|
setting = selection;
|
2021-08-27 09:57:03 +02:00
|
|
|
|
2023-03-21 15:33:43 +01:00
|
|
|
ImHexApi::System::restartImHex();
|
2021-08-27 09:57:03 +02:00
|
|
|
|
2022-02-21 21:46:25 +01:00
|
|
|
return true;
|
|
|
|
}
|
2021-08-21 13:55:21 +02:00
|
|
|
|
2022-02-21 21:46:25 +01:00
|
|
|
return false;
|
|
|
|
},
|
|
|
|
true);
|
2021-08-21 13:55:21 +02:00
|
|
|
|
2021-02-13 15:15:32 +01:00
|
|
|
ContentRegistry::Settings::add("hex.builtin.setting.interface", "hex.builtin.setting.interface.language", "en-US", [](auto name, nlohmann::json &setting) {
|
2021-02-10 18:17:09 +01:00
|
|
|
auto &languages = LangEntry::getSupportedLanguages();
|
|
|
|
|
|
|
|
static int selection = [&]() -> int {
|
|
|
|
u16 index = 0;
|
2022-01-24 20:53:17 +01:00
|
|
|
for (auto &[languageCode, languageName] : languages) {
|
2023-02-02 20:54:38 +01:00
|
|
|
if (setting.get<std::string>() == languageCode)
|
2021-02-10 18:17:09 +01:00
|
|
|
return index;
|
|
|
|
index++;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}();
|
|
|
|
|
|
|
|
static auto languageNames = [&]() {
|
2022-01-24 20:53:17 +01:00
|
|
|
std::vector<const char *> result;
|
2021-09-20 12:44:12 +02:00
|
|
|
result.reserve(languages.size());
|
|
|
|
|
2021-02-11 00:35:30 +01:00
|
|
|
for (auto &[languageCode, languageName] : languages)
|
2021-02-10 18:17:09 +01:00
|
|
|
result.push_back(languageName.c_str());
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}();
|
|
|
|
|
|
|
|
|
2021-02-13 15:15:32 +01:00
|
|
|
if (ImGui::Combo(name.data(), &selection, languageNames.data(), languageNames.size())) {
|
2021-02-10 18:17:09 +01:00
|
|
|
|
|
|
|
u16 index = 0;
|
2022-01-24 20:53:17 +01:00
|
|
|
for (auto &[languageCode, languageName] : languages) {
|
2021-02-10 18:17:09 +01:00
|
|
|
if (selection == index) {
|
2021-02-11 00:35:30 +01:00
|
|
|
setting = languageCode;
|
2021-02-10 18:17:09 +01:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
index++;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
});
|
|
|
|
|
2022-05-22 23:26:46 +02:00
|
|
|
ContentRegistry::Settings::add("hex.builtin.setting.interface", "hex.builtin.setting.interface.wiki_explain_language", "en", [](auto name, nlohmann::json &setting) {
|
|
|
|
static auto lang = std::string(setting);
|
|
|
|
|
|
|
|
if (ImGui::InputText(name.data(), lang, ImGuiInputTextFlags_CharsNoBlank)) {
|
|
|
|
setting = std::string(lang.c_str()); // remove following zero bytes
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
});
|
|
|
|
|
2021-03-06 13:09:20 +01:00
|
|
|
ContentRegistry::Settings::add("hex.builtin.setting.interface", "hex.builtin.setting.interface.fps", 60, [](auto name, nlohmann::json &setting) {
|
2021-09-12 13:59:23 +02:00
|
|
|
static int fps = static_cast<int>(setting);
|
2021-03-06 13:09:20 +01:00
|
|
|
|
2023-04-13 17:12:40 +02:00
|
|
|
auto format = [] -> std::string {
|
|
|
|
if (fps > 200)
|
|
|
|
return "hex.builtin.setting.interface.fps.unlocked"_lang;
|
|
|
|
else if (fps < 15)
|
|
|
|
return "hex.builtin.setting.interface.fps.native"_lang;
|
|
|
|
else
|
|
|
|
return "%d FPS";
|
|
|
|
}();
|
2021-10-23 12:59:13 +02:00
|
|
|
|
2023-04-13 17:12:40 +02:00
|
|
|
if (ImGui::SliderInt(name.data(), &fps, 14, 201, format.c_str(), ImGuiSliderFlags_AlwaysClamp)) {
|
2021-03-06 13:09:20 +01:00
|
|
|
setting = fps;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
});
|
|
|
|
|
2022-10-06 21:26:24 +02:00
|
|
|
ContentRegistry::Settings::add("hex.builtin.setting.interface", "hex.builtin.setting.interface.multi_windows", 1, [](auto name, nlohmann::json &setting) {
|
|
|
|
static bool enabled = static_cast<int>(setting);
|
|
|
|
|
|
|
|
if (ImGui::Checkbox(name.data(), &enabled)) {
|
|
|
|
setting = static_cast<int>(enabled);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}, true);
|
|
|
|
|
2023-01-08 16:06:26 +01:00
|
|
|
ContentRegistry::Settings::add("hex.builtin.setting.interface", "hex.builtin.setting.interface.pattern_tree_style", 0, [](auto name, nlohmann::json &setting) {
|
|
|
|
static int selection = static_cast<int>(setting);
|
|
|
|
|
|
|
|
const char *style[] = {
|
|
|
|
"hex.builtin.setting.interface.pattern_tree_style.tree"_lang,
|
|
|
|
"hex.builtin.setting.interface.pattern_tree_style.auto_expanded"_lang,
|
|
|
|
"hex.builtin.setting.interface.pattern_tree_style.flattened"_lang,
|
|
|
|
};
|
|
|
|
|
|
|
|
if (ImGui::Combo(name.data(), &selection, style, IM_ARRAYSIZE(style))) {
|
|
|
|
setting = selection;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
});
|
|
|
|
|
2022-05-27 20:42:07 +02:00
|
|
|
ContentRegistry::Settings::add("hex.builtin.setting.hex_editor", "hex.builtin.setting.hex_editor.highlight_color", 0x60C08080, [](auto name, nlohmann::json &setting) {
|
|
|
|
static auto color = static_cast<color_t>(setting);
|
|
|
|
|
|
|
|
std::array<float, 4> colorArray = {
|
|
|
|
((color >> 0) & 0x000000FF) / float(0xFF),
|
|
|
|
((color >> 8) & 0x000000FF) / float(0xFF),
|
|
|
|
((color >> 16) & 0x000000FF) / float(0xFF),
|
|
|
|
((color >> 24) & 0x000000FF) / float(0xFF)
|
|
|
|
};
|
|
|
|
|
|
|
|
if (ImGui::ColorEdit4(name.data(), colorArray.data(), ImGuiColorEditFlags_AlphaBar | ImGuiColorEditFlags_AlphaPreviewHalf | ImGuiColorEditFlags_NoDragDrop | ImGuiColorEditFlags_NoInputs)) {
|
|
|
|
color =
|
|
|
|
(color_t(colorArray[0] * 0xFF) << 0) |
|
|
|
|
(color_t(colorArray[1] * 0xFF) << 8) |
|
|
|
|
(color_t(colorArray[2] * 0xFF) << 16) |
|
|
|
|
(color_t(colorArray[3] * 0xFF) << 24);
|
|
|
|
|
|
|
|
setting = color;
|
2021-03-29 23:07:18 +02:00
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
});
|
|
|
|
|
2022-05-27 20:42:07 +02:00
|
|
|
ContentRegistry::Settings::add("hex.builtin.setting.hex_editor", "hex.builtin.setting.hex_editor.bytes_per_row", 16, [](auto name, nlohmann::json &setting) {
|
2021-09-20 23:40:36 +02:00
|
|
|
static int columns = static_cast<int>(setting);
|
|
|
|
|
|
|
|
if (ImGui::SliderInt(name.data(), &columns, 1, 32)) {
|
|
|
|
setting = columns;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
});
|
|
|
|
|
|
|
|
ContentRegistry::Settings::add("hex.builtin.setting.hex_editor", "hex.builtin.setting.hex_editor.ascii", 1, [](auto name, nlohmann::json &setting) {
|
|
|
|
static bool ascii = static_cast<int>(setting);
|
|
|
|
|
|
|
|
if (ImGui::Checkbox(name.data(), &ascii)) {
|
|
|
|
setting = static_cast<int>(ascii);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
});
|
|
|
|
|
2022-01-15 23:44:15 +01:00
|
|
|
ContentRegistry::Settings::add("hex.builtin.setting.hex_editor", "hex.builtin.setting.hex_editor.advanced_decoding", 1, [](auto name, nlohmann::json &setting) {
|
2021-09-20 23:40:36 +02:00
|
|
|
static bool advancedDecoding = static_cast<int>(setting);
|
|
|
|
|
|
|
|
if (ImGui::Checkbox(name.data(), &advancedDecoding)) {
|
|
|
|
setting = static_cast<int>(advancedDecoding);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
});
|
|
|
|
|
|
|
|
ContentRegistry::Settings::add("hex.builtin.setting.hex_editor", "hex.builtin.setting.hex_editor.grey_zeros", 1, [](auto name, nlohmann::json &setting) {
|
|
|
|
static bool greyZeros = static_cast<int>(setting);
|
|
|
|
|
|
|
|
if (ImGui::Checkbox(name.data(), &greyZeros)) {
|
|
|
|
setting = static_cast<int>(greyZeros);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
});
|
|
|
|
|
|
|
|
ContentRegistry::Settings::add("hex.builtin.setting.hex_editor", "hex.builtin.setting.hex_editor.uppercase_hex", 1, [](auto name, nlohmann::json &setting) {
|
|
|
|
static bool upperCaseHex = static_cast<int>(setting);
|
|
|
|
|
|
|
|
if (ImGui::Checkbox(name.data(), &upperCaseHex)) {
|
|
|
|
setting = static_cast<int>(upperCaseHex);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
});
|
|
|
|
|
2022-05-27 20:42:07 +02:00
|
|
|
ContentRegistry::Settings::add("hex.builtin.setting.hex_editor", "hex.builtin.setting.hex_editor.visualizer", "hex.builtin.visualizer.hexadecimal.8bit", [](auto name, nlohmann::json &setting) {
|
|
|
|
auto &visualizers = ContentRegistry::HexEditor::impl::getVisualizers();
|
2021-09-20 23:40:36 +02:00
|
|
|
|
2022-05-27 20:42:07 +02:00
|
|
|
auto selectedVisualizer = setting;
|
|
|
|
|
|
|
|
bool result = false;
|
|
|
|
if (ImGui::BeginCombo(name.data(), LangEntry(selectedVisualizer))) {
|
|
|
|
|
|
|
|
for (const auto &[unlocalizedName, visualizer] : visualizers) {
|
|
|
|
if (ImGui::Selectable(LangEntry(unlocalizedName))) {
|
|
|
|
setting = unlocalizedName;
|
2022-07-14 11:38:23 +02:00
|
|
|
result = true;
|
2022-05-27 20:42:07 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
ImGui::EndCombo();
|
2021-09-20 23:40:36 +02:00
|
|
|
}
|
|
|
|
|
2022-05-27 20:42:07 +02:00
|
|
|
return result;
|
2021-09-20 23:40:36 +02:00
|
|
|
});
|
2022-02-18 22:34:54 +01:00
|
|
|
|
2022-09-18 16:22:08 +02:00
|
|
|
ContentRegistry::Settings::add("hex.builtin.setting.hex_editor", "hex.builtin.setting.hex_editor.sync_scrolling", 0, [](auto name, nlohmann::json &setting) {
|
|
|
|
static bool syncScrolling = static_cast<int>(setting);
|
|
|
|
|
|
|
|
if (ImGui::Checkbox(name.data(), &syncScrolling)) {
|
|
|
|
setting = static_cast<int>(syncScrolling);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
});
|
|
|
|
|
2022-10-07 11:28:44 +02:00
|
|
|
ContentRegistry::Settings::add("hex.builtin.setting.hex_editor", "hex.builtin.setting.hex_editor.byte_padding", 0, [](auto name, nlohmann::json &setting) {
|
|
|
|
static int padding = static_cast<int>(setting);
|
|
|
|
|
|
|
|
if (ImGui::SliderInt(name.data(), &padding, 0, 50)) {
|
|
|
|
setting = padding;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
});
|
|
|
|
|
|
|
|
ContentRegistry::Settings::add("hex.builtin.setting.hex_editor", "hex.builtin.setting.hex_editor.char_padding", 0, [](auto name, nlohmann::json &setting) {
|
|
|
|
static int padding = static_cast<int>(setting);
|
|
|
|
|
|
|
|
if (ImGui::SliderInt(name.data(), &padding, 0, 50)) {
|
|
|
|
setting = padding;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
});
|
|
|
|
|
2022-02-21 21:46:25 +01:00
|
|
|
|
2022-05-27 20:42:07 +02:00
|
|
|
/* Fonts */
|
|
|
|
|
2022-02-21 21:46:25 +01:00
|
|
|
static std::string fontPath;
|
|
|
|
ContentRegistry::Settings::add(
|
|
|
|
"hex.builtin.setting.font", "hex.builtin.setting.font.font_path", "", [](auto name, nlohmann::json &setting) {
|
|
|
|
fontPath = static_cast<std::string>(setting);
|
|
|
|
|
2022-03-03 09:24:09 +01:00
|
|
|
if (ImGui::InputText("##font_path", fontPath)) {
|
2022-02-21 21:46:25 +01:00
|
|
|
setting = fontPath;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
ImGui::SameLine();
|
|
|
|
|
|
|
|
if (ImGui::IconButton(ICON_VS_FOLDER_OPENED, ImGui::GetStyleColorVec4(ImGuiCol_Text))) {
|
2023-01-12 11:37:19 +01:00
|
|
|
return fs::openFileBrowser(fs::DialogMode::Open, { { "TTF Font", "ttf" }, { "OTF Font", "otf" } },
|
2022-03-04 11:36:37 +01:00
|
|
|
[&](const std::fs::path &path) {
|
2023-03-12 18:43:05 +01:00
|
|
|
fontPath = wolv::util::toUTF8String(path);
|
2022-02-21 21:46:25 +01:00
|
|
|
setting = fontPath;
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
ImGui::SameLine();
|
|
|
|
|
|
|
|
ImGui::TextFormatted("{}", name);
|
|
|
|
|
|
|
|
return false;
|
|
|
|
},
|
|
|
|
true);
|
|
|
|
|
|
|
|
ContentRegistry::Settings::add(
|
|
|
|
"hex.builtin.setting.font", "hex.builtin.setting.font.font_size", 13, [](auto name, nlohmann::json &setting) {
|
|
|
|
static int fontSize = static_cast<int>(setting);
|
|
|
|
|
|
|
|
ImGui::BeginDisabled(fontPath.empty());
|
2022-02-23 10:16:27 +01:00
|
|
|
ON_SCOPE_EXIT { ImGui::EndDisabled(); };
|
2022-02-21 21:46:25 +01:00
|
|
|
|
|
|
|
if (ImGui::SliderInt(name.data(), &fontSize, 0, 100, "%d", ImGuiSliderFlags_NoInput)) {
|
|
|
|
setting = fontSize;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2023-03-22 16:30:49 +01:00
|
|
|
if (fontPath.empty() && ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled)) {
|
|
|
|
ImGui::SetNextWindowSize(scaled(ImVec2(300, 0)));
|
|
|
|
ImGui::BeginTooltip();
|
|
|
|
ImGui::TextFormattedWrapped("{}", "hex.builtin.setting.font.font_size.tooltip"_lang);
|
|
|
|
ImGui::EndTooltip();
|
|
|
|
}
|
|
|
|
|
2022-02-21 21:46:25 +01:00
|
|
|
return false;
|
|
|
|
},
|
|
|
|
true);
|
|
|
|
|
|
|
|
|
2022-05-27 20:42:07 +02:00
|
|
|
/* Folders */
|
|
|
|
|
2022-02-18 22:34:54 +01:00
|
|
|
static const std::string dirsSetting { "hex.builtin.setting.folders" };
|
|
|
|
|
2022-02-21 21:46:25 +01:00
|
|
|
ContentRegistry::Settings::addCategoryDescription(dirsSetting, "hex.builtin.setting.folders.description");
|
2022-02-18 22:34:54 +01:00
|
|
|
|
|
|
|
ContentRegistry::Settings::add(dirsSetting, dirsSetting, std::vector<std::string> {}, [](auto name, nlohmann::json &setting) {
|
2022-03-27 00:01:28 +01:00
|
|
|
hex::unused(name);
|
|
|
|
|
2022-07-14 11:38:23 +02:00
|
|
|
static size_t currentItemIndex = [&setting] {loadUserFoldersFromSetting(setting); return 0; }();
|
2022-07-02 17:53:13 +02:00
|
|
|
|
2022-07-14 11:38:23 +02:00
|
|
|
auto saveToSetting = [&setting] {
|
|
|
|
std::vector<std::string> folderStrings;
|
|
|
|
for (const auto &folder : userFolders) {
|
|
|
|
auto utfString = folder.u8string();
|
|
|
|
// JSON stores char8_t as array, char8_t is not supported as of now
|
|
|
|
folderStrings.emplace_back(reinterpret_cast<const char *>(&utfString.front()), reinterpret_cast<const char *>(std::next(&utfString.back())));
|
|
|
|
}
|
2022-07-02 17:53:13 +02:00
|
|
|
setting = folderStrings;
|
2022-07-14 11:38:23 +02:00
|
|
|
ImHexApi::System::setAdditionalFolderPaths(userFolders);
|
2022-07-02 17:53:13 +02:00
|
|
|
};
|
|
|
|
|
2022-07-14 11:38:23 +02:00
|
|
|
bool result = false;
|
|
|
|
|
2022-02-18 22:34:54 +01:00
|
|
|
if (!ImGui::BeginListBox("", ImVec2(-38, -FLT_MIN))) {
|
|
|
|
return false;
|
|
|
|
} else {
|
2022-07-14 11:38:23 +02:00
|
|
|
for (size_t n = 0; n < userFolders.size(); n++) {
|
2022-02-18 22:34:54 +01:00
|
|
|
const bool isSelected = (currentItemIndex == n);
|
2023-03-12 18:43:05 +01:00
|
|
|
if (ImGui::Selectable(wolv::util::toUTF8String(userFolders.at(n)).c_str(), isSelected)) { currentItemIndex = n; }
|
2022-02-18 22:34:54 +01:00
|
|
|
if (isSelected) { ImGui::SetItemDefaultFocus(); }
|
|
|
|
}
|
|
|
|
ImGui::EndListBox();
|
|
|
|
}
|
|
|
|
ImGui::SameLine();
|
|
|
|
ImGui::BeginGroup();
|
|
|
|
|
|
|
|
if (ImGui::IconButton(ICON_VS_NEW_FOLDER, ImGui::GetCustomColorVec4(ImGuiCustomCol_DescButton), ImVec2(30, 30))) {
|
2022-03-27 00:01:28 +01:00
|
|
|
fs::openFileBrowser(fs::DialogMode::Folder, {}, [&](const std::fs::path &path) {
|
2022-07-14 11:38:23 +02:00
|
|
|
if (std::find(userFolders.begin(), userFolders.end(), path) == userFolders.end()) {
|
|
|
|
userFolders.emplace_back(path);
|
|
|
|
saveToSetting();
|
2022-04-17 23:05:03 +02:00
|
|
|
result = true;
|
2022-02-18 22:34:54 +01:00
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
2022-03-05 23:32:30 +01:00
|
|
|
ImGui::InfoTooltip("hex.builtin.setting.folders.add_folder"_lang);
|
2022-02-18 22:34:54 +01:00
|
|
|
|
|
|
|
if (ImGui::IconButton(ICON_VS_REMOVE_CLOSE, ImGui::GetCustomColorVec4(ImGuiCustomCol_DescButton), ImVec2(30, 30))) {
|
2022-07-14 11:38:23 +02:00
|
|
|
if (!userFolders.empty()) {
|
|
|
|
userFolders.erase(std::next(userFolders.begin(), currentItemIndex));
|
|
|
|
saveToSetting();
|
2022-07-02 17:53:13 +02:00
|
|
|
|
2022-04-17 23:05:03 +02:00
|
|
|
result = true;
|
2022-02-18 22:34:54 +01:00
|
|
|
}
|
|
|
|
}
|
2022-03-05 23:32:30 +01:00
|
|
|
ImGui::InfoTooltip("hex.builtin.setting.folders.remove_folder"_lang);
|
2022-02-18 22:34:54 +01:00
|
|
|
|
|
|
|
ImGui::EndGroup();
|
|
|
|
|
2022-04-17 23:05:03 +02:00
|
|
|
return result;
|
2022-02-18 22:34:54 +01:00
|
|
|
});
|
2022-07-01 14:05:32 +02:00
|
|
|
|
|
|
|
/* Proxy */
|
|
|
|
|
|
|
|
static const std::string proxySetting { "hex.builtin.setting.proxy" };
|
|
|
|
|
2023-03-23 11:23:07 +01:00
|
|
|
HttpRequest::setProxy(ContentRegistry::Settings::read(proxySetting, "hex.builtin.setting.proxy.url", ""));
|
2022-07-01 14:05:32 +02:00
|
|
|
|
|
|
|
ContentRegistry::Settings::addCategoryDescription(proxySetting, "hex.builtin.setting.proxy.description");
|
|
|
|
|
|
|
|
ContentRegistry::Settings::add(
|
|
|
|
proxySetting, "hex.builtin.setting.proxy.url", "", [](auto name, nlohmann::json &setting) {
|
|
|
|
static std::string proxyUrl = static_cast<std::string>(setting);
|
|
|
|
static bool enableProxy = !proxyUrl.empty();
|
|
|
|
|
|
|
|
bool result = false;
|
|
|
|
|
|
|
|
if (ImGui::Checkbox("hex.builtin.setting.proxy.enable"_lang, &enableProxy)) {
|
|
|
|
setting = enableProxy ? proxyUrl : "";
|
2023-03-23 11:23:07 +01:00
|
|
|
HttpRequest::setProxy(enableProxy ? proxyUrl : "");
|
2022-07-01 14:05:32 +02:00
|
|
|
result = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
ImGui::BeginDisabled(!enableProxy);
|
|
|
|
if (ImGui::InputText("##proxy_url", proxyUrl)) {
|
|
|
|
setting = proxyUrl;
|
2023-03-23 11:23:07 +01:00
|
|
|
HttpRequest::setProxy(proxyUrl);
|
2022-07-01 14:05:32 +02:00
|
|
|
result = true;
|
|
|
|
}
|
|
|
|
ImGui::EndDisabled();
|
|
|
|
|
|
|
|
ImGui::InfoTooltip("hex.builtin.setting.proxy.url.tooltip"_lang);
|
|
|
|
|
|
|
|
ImGui::SameLine();
|
|
|
|
|
|
|
|
ImGui::TextFormatted("{}", name);
|
|
|
|
return result;
|
|
|
|
},
|
|
|
|
false);
|
2021-01-22 18:01:39 +01:00
|
|
|
}
|
|
|
|
|
2022-07-02 16:22:38 +02:00
|
|
|
|
|
|
|
static void loadInterfaceScalingSetting() {
|
|
|
|
float interfaceScaling = 1.0F;
|
|
|
|
switch (ContentRegistry::Settings::read("hex.builtin.setting.interface", "hex.builtin.setting.interface.scaling", 0)) {
|
|
|
|
default:
|
|
|
|
case 0:
|
2022-07-29 17:37:30 +02:00
|
|
|
interfaceScaling = ImHexApi::System::getNativeScale();
|
2022-07-02 16:22:38 +02:00
|
|
|
break;
|
|
|
|
case 1:
|
|
|
|
interfaceScaling = 0.5F;
|
|
|
|
break;
|
|
|
|
case 2:
|
|
|
|
interfaceScaling = 1.0F;
|
|
|
|
break;
|
|
|
|
case 3:
|
|
|
|
interfaceScaling = 1.5F;
|
|
|
|
break;
|
|
|
|
case 4:
|
|
|
|
interfaceScaling = 2.0F;
|
|
|
|
break;
|
2022-07-30 21:38:46 +02:00
|
|
|
case 5:
|
|
|
|
interfaceScaling = 3.0F;
|
|
|
|
break;
|
|
|
|
case 6:
|
|
|
|
interfaceScaling = 4.0F;
|
|
|
|
break;
|
2022-07-02 16:22:38 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
ImHexApi::System::impl::setGlobalScale(interfaceScaling);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void loadFontSettings() {
|
|
|
|
std::fs::path fontFile = ContentRegistry::Settings::read("hex.builtin.setting.font", "hex.builtin.setting.font.font_path", "");
|
2023-03-12 18:27:29 +01:00
|
|
|
if (!wolv::io::fs::exists(fontFile) || !wolv::io::fs::isRegularFile(fontFile))
|
2022-07-02 16:22:38 +02:00
|
|
|
fontFile.clear();
|
|
|
|
|
|
|
|
// If no custom font has been specified, search for a file called "font.ttf" in one of the resource folders
|
|
|
|
if (fontFile.empty()) {
|
|
|
|
for (const auto &dir : fs::getDefaultPaths(fs::ImHexPath::Resources)) {
|
|
|
|
auto path = dir / "font.ttf";
|
2023-03-12 18:27:29 +01:00
|
|
|
if (wolv::io::fs::exists(path)) {
|
2023-03-12 18:43:05 +01:00
|
|
|
log::info("Loading custom front from {}", wolv::util::toUTF8String(path));
|
2022-07-02 16:22:38 +02:00
|
|
|
|
|
|
|
fontFile = path;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-09-20 15:47:28 +02:00
|
|
|
ImHexApi::System::impl::setCustomFontPath(fontFile);
|
|
|
|
|
2022-07-02 16:22:38 +02:00
|
|
|
// If a custom font has been loaded now, also load the font size
|
2023-02-16 20:53:58 +01:00
|
|
|
float fontSize = ImHexApi::System::DefaultFontSize * std::round(ImHexApi::System::getGlobalScale());
|
2022-07-02 16:22:38 +02:00
|
|
|
if (!fontFile.empty()) {
|
|
|
|
fontSize = ContentRegistry::Settings::read("hex.builtin.setting.font", "hex.builtin.setting.font.font_size", 13) * ImHexApi::System::getGlobalScale();
|
|
|
|
}
|
|
|
|
|
|
|
|
ImHexApi::System::impl::setFontSize(fontSize);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void loadThemeSettings() {
|
2023-03-23 20:35:16 +01:00
|
|
|
auto theme = ContentRegistry::Settings::read("hex.builtin.setting.interface", "hex.builtin.setting.interface.color", ThemeManager::NativeTheme);
|
2022-07-02 16:22:38 +02:00
|
|
|
|
2023-03-23 20:35:16 +01:00
|
|
|
if (theme == ThemeManager::NativeTheme)
|
2022-12-29 19:26:00 +01:00
|
|
|
ImHexApi::System::enableSystemThemeDetection(true);
|
|
|
|
else {
|
|
|
|
ImHexApi::System::enableSystemThemeDetection(false);
|
2023-03-23 20:35:16 +01:00
|
|
|
ThemeManager::changeTheme(theme);
|
2022-12-29 19:26:00 +01:00
|
|
|
}
|
2022-07-02 16:22:38 +02:00
|
|
|
}
|
|
|
|
|
2022-07-14 11:38:23 +02:00
|
|
|
static void loadFoldersSettings() {
|
2023-03-21 15:33:43 +01:00
|
|
|
auto directories = ContentRegistry::Settings::read("hex.builtin.setting.folders", "hex.builtin.setting.folders", std::vector<std::string> { });
|
|
|
|
|
|
|
|
loadUserFoldersFromSetting(directories);
|
2022-07-14 11:38:23 +02:00
|
|
|
ImHexApi::System::setAdditionalFolderPaths(userFolders);
|
|
|
|
}
|
|
|
|
|
2022-07-02 16:22:38 +02:00
|
|
|
void loadSettings() {
|
|
|
|
loadInterfaceScalingSetting();
|
|
|
|
loadFontSettings();
|
|
|
|
loadThemeSettings();
|
2022-07-14 11:38:23 +02:00
|
|
|
loadFoldersSettings();
|
2022-07-02 16:22:38 +02:00
|
|
|
}
|
|
|
|
|
2022-02-18 22:34:54 +01:00
|
|
|
}
|