diff --git a/lib/libimhex/include/hex/api/content_registry.hpp b/lib/libimhex/include/hex/api/content_registry.hpp index becb662f1..481a2c9a9 100644 --- a/lib/libimhex/include/hex/api/content_registry.hpp +++ b/lib/libimhex/include/hex/api/content_registry.hpp @@ -99,7 +99,7 @@ namespace hex { bool m_requiresRestart = false; std::function m_enabledCallback; std::function m_changedCallback; - std::optional m_tooltip; + std::optional m_tooltip; }; [[nodiscard]] @@ -113,7 +113,7 @@ namespace hex { } [[nodiscard]] - const std::optional& getTooltip() const { + const std::optional& getTooltip() const { return m_interface.m_tooltip; } @@ -176,6 +176,21 @@ namespace hex { float m_min, m_max; }; + class SliderDataSize : public Widget { + public: + SliderDataSize(u64 defaultValue, u64 min, u64 max) : m_value(defaultValue), m_min(min), m_max(max) { } + bool draw(const std::string &name) override; + + void load(const nlohmann::json &data) override; + nlohmann::json store() override; + + [[nodiscard]] i32 getValue() const { return m_value; } + + protected: + u64 m_value; + u64 m_min, m_max; + }; + class ColorPicker : public Widget { public: explicit ColorPicker(ImColor defaultColor); diff --git a/lib/libimhex/source/api/content_registry.cpp b/lib/libimhex/source/api/content_registry.cpp index b866831c4..752b4380c 100644 --- a/lib/libimhex/source/api/content_registry.cpp +++ b/lib/libimhex/source/api/content_registry.cpp @@ -312,6 +312,23 @@ namespace hex { } + bool SliderDataSize::draw(const std::string &name) { + return ImGuiExt::SliderBytes(name.c_str(), &m_value, m_min, m_max); + } + + void SliderDataSize::load(const nlohmann::json &data) { + if (data.is_number_integer()) { + m_value = data.get(); + } else { + log::warn("Invalid data type loaded from settings for slider!"); + } + } + + nlohmann::json SliderDataSize::store() { + return m_value; + } + + ColorPicker::ColorPicker(ImColor defaultColor) { m_value = { defaultColor.Value.x, diff --git a/lib/libimhex/source/ui/imgui_imhex_extensions.cpp b/lib/libimhex/source/ui/imgui_imhex_extensions.cpp index 94641cce2..e0710c01f 100644 --- a/lib/libimhex/source/ui/imgui_imhex_extensions.cpp +++ b/lib/libimhex/source/ui/imgui_imhex_extensions.cpp @@ -573,12 +573,16 @@ namespace ImGuiExt { bool result = false; if (IsItemHovered() && (currTime - lastMoveTime) >= 0.5 && hoveredID == lastHoveredID) { if (!std::string_view(text).empty()) { - BeginTooltip(); - if (isSeparator) - SeparatorText(text); - else - TextUnformatted(text); - EndTooltip(); + const auto width = 300 * hex::ImHexApi::System::getGlobalScale(); + ImGui::SetNextWindowSizeConstraints(ImVec2(width, 0), ImVec2(width, FLT_MAX)); + if (BeginTooltip()) { + if (isSeparator) + SeparatorText(text); + else + TextFormattedWrapped("{}", text); + + EndTooltip(); + } } result = true; diff --git a/plugins/builtin/include/content/providers/file_provider.hpp b/plugins/builtin/include/content/providers/file_provider.hpp index 9e737faf2..c3a7604a9 100644 --- a/plugins/builtin/include/content/providers/file_provider.hpp +++ b/plugins/builtin/include/content/providers/file_provider.hpp @@ -11,8 +11,6 @@ namespace hex::plugin::builtin { class FileProvider : public hex::prv::Provider { public: - constexpr static u64 MaxMemoryFileSize = 128 * 1024 * 1024; - FileProvider() = default; ~FileProvider() override = default; diff --git a/plugins/builtin/romfs/lang/en_US.json b/plugins/builtin/romfs/lang/en_US.json index 1f3d31e87..27535699f 100644 --- a/plugins/builtin/romfs/lang/en_US.json +++ b/plugins/builtin/romfs/lang/en_US.json @@ -459,6 +459,8 @@ "hex.builtin.setting.general.auto_backup_time.format.extended": "Every {0}m {1}s", "hex.builtin.setting.general.auto_load_patterns": "Auto-load supported pattern", "hex.builtin.setting.general.server_contact": "Enable update checks and usage statistics", + "hex.builtin.setting.general.max_mem_file_size": "Maximum size of file to load into memory", + "hex.builtin.setting.general.max_mem_file_size.desc": "Small files are loaded into memory to prevent them from being modified directly on disk.\n\nIncreasing this size allows larger files to be loaded into memory before ImHex resorts streaming in data from disk.", "hex.builtin.setting.general.network_interface": "Enable network interface", "hex.builtin.setting.general.save_recent_providers": "Save recently used providers", "hex.builtin.setting.general.show_tips": "Show tips on startup", diff --git a/plugins/builtin/source/content/providers/file_provider.cpp b/plugins/builtin/source/content/providers/file_provider.cpp index aaf28cb68..556d31e17 100644 --- a/plugins/builtin/source/content/providers/file_provider.cpp +++ b/plugins/builtin/source/content/providers/file_provider.cpp @@ -1,11 +1,13 @@ #include "content/providers/file_provider.hpp" #include "content/providers/memory_file_provider.hpp" +#include #include #include #include #include +#include #include #include @@ -13,10 +15,10 @@ #include #include +#include #include #include -#include #if defined(OS_WINDOWS) #include @@ -24,6 +26,8 @@ namespace hex::plugin::builtin { + using namespace wolv::literals; + std::set FileProvider::s_openedFiles; bool FileProvider::isAvailable() const { @@ -223,8 +227,10 @@ namespace hex::plugin::builtin { } } + size_t maxMemoryFileSize = ContentRegistry::Settings::read("hex.builtin.setting.general", "hex.builtin.setting.general.max_mem_file_size", 128_MiB); + if (m_writable) { - if (m_fileSize < MaxMemoryFileSize) { + if (m_fileSize < maxMemoryFileSize) { m_data = m_file.readVectorAtomic(0x00, m_fileSize); if (!m_data.empty()) { m_changeTracker = wolv::io::ChangeTracker(m_file); diff --git a/plugins/builtin/source/content/settings_entries.cpp b/plugins/builtin/source/content/settings_entries.cpp index 6ec58ad35..d770b091e 100644 --- a/plugins/builtin/source/content/settings_entries.cpp +++ b/plugins/builtin/source/content/settings_entries.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include #include @@ -12,14 +13,17 @@ #include #include +#include +#include + #include #include -#include -#include namespace hex::plugin::builtin { + using namespace wolv::literals; + namespace { /* @@ -683,6 +687,8 @@ namespace hex::plugin::builtin { ContentRegistry::Settings::add("hex.builtin.setting.general", "", "hex.builtin.setting.general.show_tips", false); ContentRegistry::Settings::add("hex.builtin.setting.general", "", "hex.builtin.setting.general.save_recent_providers", true); ContentRegistry::Settings::add("hex.builtin.setting.general", "", "hex.builtin.setting.general.auto_backup_time"); + ContentRegistry::Settings::add("hex.builtin.setting.general", "", "hex.builtin.setting.general.max_mem_file_size", 128_MiB, 0_bytes, 32_GiB) + .setTooltip("hex.builtin.setting.general.max_mem_file_size.desc"); ContentRegistry::Settings::add("hex.builtin.setting.general", "hex.builtin.setting.general.patterns", "hex.builtin.setting.general.auto_load_patterns", true); ContentRegistry::Settings::add("hex.builtin.setting.general", "hex.builtin.setting.general.patterns", "hex.builtin.setting.general.sync_pattern_source", false); ContentRegistry::Settings::add("hex.builtin.setting.general", "hex.builtin.setting.general.network", "hex.builtin.setting.general.network_interface", false); @@ -854,7 +860,7 @@ namespace hex::plugin::builtin { EventImHexStartupFinished::subscribe([]{ for (const auto &[name, experiment] : ContentRegistry::Experiments::impl::getExperiments()) { ContentRegistry::Settings::add("hex.builtin.setting.experiments", "", experiment.unlocalizedName, false) - .setTooltip(Lang(experiment.unlocalizedDescription)) + .setTooltip(experiment.unlocalizedDescription) .setChangedCallback([name](Widgets::Widget &widget) { auto checkBox = static_cast(&widget); diff --git a/plugins/builtin/source/content/views/view_settings.cpp b/plugins/builtin/source/content/views/view_settings.cpp index 439099fa9..8dbaa4c03 100644 --- a/plugins/builtin/source/content/views/view_settings.cpp +++ b/plugins/builtin/source/content/views/view_settings.cpp @@ -106,7 +106,7 @@ namespace hex::plugin::builtin { ImGui::PopItemWidth(); ImGui::EndDisabled(); - if (auto tooltip = setting.widget->getTooltip(); tooltip.has_value() && ImGui::IsItemHovered()) + if (const auto &tooltip = setting.widget->getTooltip(); tooltip.has_value() && ImGui::IsItemHovered()) ImGuiExt::InfoTooltip(Lang(tooltip.value())); auto &widget = setting.widget;