mirror of
https://github.com/WerWolv/ImHex.git
synced 2026-03-28 07:47:03 -05:00
impr: Various web build improvements, API cleanup (#1541)
This commit is contained in:
1
dist/web/source/style.css
vendored
1
dist/web/source/style.css
vendored
@@ -17,6 +17,7 @@ body {
|
||||
margin-right: auto;
|
||||
display: none;
|
||||
border: 0 none;
|
||||
image-rendering: smooth;
|
||||
}
|
||||
|
||||
h1, h2, h5 {
|
||||
|
||||
6
dist/web/source/wasm-config.js
vendored
6
dist/web/source/wasm-config.js
vendored
@@ -2,7 +2,7 @@ let wasmSize = null;
|
||||
// See comment in dist/web/Dockerfile about imhex.wasm.size
|
||||
fetch("imhex.wasm.size").then(async (resp) => {
|
||||
wasmSize = parseInt((await resp.text()).trim());
|
||||
console.log(`wasm size was found to be ${wasmSize} bytes`);
|
||||
console.log(`Real WASM binary size is ${wasmSize} bytes`);
|
||||
});
|
||||
|
||||
// Monkeypatch WebAssembly to have a progress bar
|
||||
@@ -49,9 +49,9 @@ function monkeyPatch(progressFun) {
|
||||
monkeyPatch((file, done) => {
|
||||
if (!wasmSize) return;
|
||||
if (done > wasmSize) {
|
||||
console.log(`Warning: downloaded size ${done} is larger than wasm size ${wasmSize}`);
|
||||
console.warn(`Downloaded binary size ${done} is larger than expected WASM size ${wasmSize}`);
|
||||
return;
|
||||
};
|
||||
}
|
||||
|
||||
const percent = ((done / wasmSize) * 100).toFixed(0);
|
||||
const mibNow = (done / 1024**2).toFixed(1);
|
||||
|
||||
@@ -331,18 +331,7 @@ namespace hex {
|
||||
static Achievement& addAchievement(auto && ... args) {
|
||||
auto newAchievement = std::make_unique<T>(std::forward<decltype(args)>(args)...);
|
||||
|
||||
const auto &category = newAchievement->getUnlocalizedCategory();
|
||||
const auto &name = newAchievement->getUnlocalizedName();
|
||||
|
||||
auto [categoryIter, categoryInserted] = getAchievements().insert({ category, std::unordered_map<std::string, std::unique_ptr<Achievement>>{} });
|
||||
auto &[categoryKey, achievements] = *categoryIter;
|
||||
|
||||
auto [achievementIter, achievementInserted] = achievements.insert({ name, std::move(newAchievement) });
|
||||
auto &[achievementKey, achievement] = *achievementIter;
|
||||
|
||||
achievementAdded();
|
||||
|
||||
return *achievement;
|
||||
return addAchievementImpl(std::move(newAchievement));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -371,7 +360,7 @@ namespace hex {
|
||||
* @brief Returns all registered achievements
|
||||
* @return All achievements
|
||||
*/
|
||||
static std::unordered_map<std::string, std::unordered_map<std::string, std::unique_ptr<Achievement>>>& getAchievements();
|
||||
static const std::unordered_map<std::string, std::unordered_map<std::string, std::unique_ptr<Achievement>>>& getAchievements();
|
||||
|
||||
/**
|
||||
* @brief Returns all achievement start nodes
|
||||
@@ -379,14 +368,14 @@ namespace hex {
|
||||
* @param rebuild Whether to rebuild the list of start nodes
|
||||
* @return All achievement start nodes
|
||||
*/
|
||||
static std::unordered_map<std::string, std::vector<AchievementNode*>>& getAchievementStartNodes(bool rebuild = true);
|
||||
static const std::unordered_map<std::string, std::vector<AchievementNode*>>& getAchievementStartNodes(bool rebuild = true);
|
||||
|
||||
/**
|
||||
* @brief Returns all achievement nodes
|
||||
* @param rebuild Whether to rebuild the list of nodes
|
||||
* @return All achievement nodes
|
||||
*/
|
||||
static std::unordered_map<std::string, std::list<AchievementNode>>& getAchievementNodes(bool rebuild = true);
|
||||
static const std::unordered_map<std::string, std::list<AchievementNode>>& getAchievementNodes(bool rebuild = true);
|
||||
|
||||
/**
|
||||
* @brief Loads the progress of all achievements from the achievements save file
|
||||
@@ -398,11 +387,6 @@ namespace hex {
|
||||
*/
|
||||
static void storeProgress();
|
||||
|
||||
/**
|
||||
* @brief Removes all registered achievements from the tree
|
||||
*/
|
||||
static void clear();
|
||||
|
||||
/**
|
||||
* @brief Removes all temporary achievements from the tree
|
||||
*/
|
||||
@@ -416,6 +400,8 @@ namespace hex {
|
||||
|
||||
private:
|
||||
static void achievementAdded();
|
||||
|
||||
static Achievement& addAchievementImpl(std::unique_ptr<Achievement> &&newAchievement);
|
||||
};
|
||||
|
||||
}
|
||||
@@ -272,9 +272,9 @@ namespace hex {
|
||||
void store();
|
||||
void clear();
|
||||
|
||||
std::vector<Category> &getSettings();
|
||||
const std::vector<Category>& getSettings();
|
||||
nlohmann::json& getSetting(const UnlocalizedString &unlocalizedCategory, const UnlocalizedString &unlocalizedName, const nlohmann::json &defaultValue);
|
||||
nlohmann::json &getSettingsData();
|
||||
const nlohmann::json& getSettingsData();
|
||||
|
||||
Widgets::Widget* add(const UnlocalizedString &unlocalizedCategory, const UnlocalizedString &unlocalizedSubCategory, const UnlocalizedString &unlocalizedName, std::unique_ptr<Widgets::Widget> &&widget);
|
||||
|
||||
@@ -352,8 +352,8 @@ namespace hex {
|
||||
DisplayCallback displayCallback;
|
||||
};
|
||||
|
||||
std::vector<Entry> &getEntries();
|
||||
std::vector<Handler> &getHandlers();
|
||||
const std::vector<Entry>& getEntries();
|
||||
const std::vector<Handler>& getHandlers();
|
||||
|
||||
}
|
||||
|
||||
@@ -408,10 +408,10 @@ namespace hex {
|
||||
VisualizerFunctionCallback callback;
|
||||
};
|
||||
|
||||
std::map<std::string, Visualizer> &getVisualizers();
|
||||
std::map<std::string, Visualizer> &getInlineVisualizers();
|
||||
std::map<std::string, pl::api::PragmaHandler> &getPragmas();
|
||||
std::vector<FunctionDefinition> &getFunctions();
|
||||
const std::map<std::string, Visualizer>& getVisualizers();
|
||||
const std::map<std::string, Visualizer>& getInlineVisualizers();
|
||||
const std::map<std::string, pl::api::PragmaHandler>& getPragmas();
|
||||
const std::vector<FunctionDefinition>& getFunctions();
|
||||
|
||||
}
|
||||
|
||||
@@ -504,7 +504,7 @@ namespace hex {
|
||||
namespace impl {
|
||||
|
||||
void add(std::unique_ptr<View> &&view);
|
||||
std::map<std::string, std::unique_ptr<View>> &getEntries();
|
||||
const std::map<std::string, std::unique_ptr<View>>& getEntries();
|
||||
|
||||
}
|
||||
|
||||
@@ -535,12 +535,11 @@ namespace hex {
|
||||
using Callback = std::function<void()>;
|
||||
|
||||
struct Entry {
|
||||
std::string name;
|
||||
UnlocalizedString unlocalizedName;
|
||||
Callback function;
|
||||
bool detached;
|
||||
};
|
||||
|
||||
std::vector<Entry> &getEntries();
|
||||
const std::vector<Entry>& getEntries();
|
||||
|
||||
}
|
||||
|
||||
@@ -576,7 +575,7 @@ namespace hex {
|
||||
std::optional<EditingFunction> editingFunction;
|
||||
};
|
||||
|
||||
std::vector<Entry> &getEntries();
|
||||
const std::vector<Entry>& getEntries();
|
||||
|
||||
}
|
||||
|
||||
@@ -627,7 +626,7 @@ namespace hex {
|
||||
|
||||
void add(const Entry &entry);
|
||||
|
||||
std::vector<Entry> &getEntries();
|
||||
const std::vector<Entry>& getEntries();
|
||||
}
|
||||
|
||||
|
||||
@@ -670,8 +669,8 @@ namespace hex {
|
||||
|
||||
namespace impl {
|
||||
|
||||
std::map<std::string, std::string> &getLanguages();
|
||||
std::map<std::string, std::vector<LocalizationManager::LanguageDefinition>> &getLanguageDefinitions();
|
||||
const std::map<std::string, std::string>& getLanguages();
|
||||
const std::map<std::string, std::vector<LocalizationManager::LanguageDefinition>>& getLanguageDefinitions();
|
||||
|
||||
}
|
||||
|
||||
@@ -725,14 +724,16 @@ namespace hex {
|
||||
constexpr static auto SeparatorValue = "$SEPARATOR$";
|
||||
constexpr static auto SubMenuValue = "$SUBMENU$";
|
||||
|
||||
std::multimap<u32, MainMenuItem> &getMainMenuItems();
|
||||
std::multimap<u32, MenuItem> &getMenuItems();
|
||||
const std::multimap<u32, MainMenuItem>& getMainMenuItems();
|
||||
|
||||
std::vector<DrawCallback> &getWelcomeScreenEntries();
|
||||
std::vector<DrawCallback> &getFooterItems();
|
||||
std::vector<DrawCallback> &getToolbarItems();
|
||||
std::vector<SidebarItem> &getSidebarItems();
|
||||
std::vector<TitleBarButton> &getTitleBarButtons();
|
||||
const std::multimap<u32, MenuItem>& getMenuItems();
|
||||
std::multimap<u32, MenuItem>& getMenuItemsMutable();
|
||||
|
||||
const std::vector<DrawCallback>& getWelcomeScreenEntries();
|
||||
const std::vector<DrawCallback>& getFooterItems();
|
||||
const std::vector<DrawCallback>& getToolbarItems();
|
||||
const std::vector<SidebarItem>& getSidebarItems();
|
||||
const std::vector<TitleBarButton>& getTitlebarButtons();
|
||||
|
||||
}
|
||||
|
||||
@@ -901,10 +902,10 @@ namespace hex {
|
||||
|
||||
void addProviderName(const UnlocalizedString &unlocalizedName);
|
||||
|
||||
using ProviderCreationFunction = prv::Provider*(*)();
|
||||
using ProviderCreationFunction = std::unique_ptr<prv::Provider>(*)();
|
||||
void add(const std::string &typeName, ProviderCreationFunction creationFunction);
|
||||
|
||||
std::vector<std::string> &getEntries();
|
||||
const std::vector<std::string>& getEntries();
|
||||
|
||||
}
|
||||
|
||||
@@ -917,8 +918,8 @@ namespace hex {
|
||||
void add(bool addToList = true) {
|
||||
auto typeName = T().getTypeName();
|
||||
|
||||
impl::add(typeName, [] -> prv::Provider* {
|
||||
return new T();
|
||||
impl::add(typeName, [] -> std::unique_ptr<prv::Provider> {
|
||||
return std::make_unique<T>();
|
||||
});
|
||||
|
||||
if (addToList)
|
||||
@@ -938,7 +939,7 @@ namespace hex {
|
||||
Callback callback;
|
||||
};
|
||||
|
||||
std::vector<Entry> &getEntries();
|
||||
const std::vector<Entry>& getEntries();
|
||||
|
||||
}
|
||||
|
||||
@@ -963,7 +964,7 @@ namespace hex {
|
||||
Callback callback;
|
||||
};
|
||||
|
||||
std::vector<Entry> &getEntries();
|
||||
const std::vector<Entry>& getEntries();
|
||||
|
||||
}
|
||||
|
||||
@@ -1019,8 +1020,8 @@ namespace hex {
|
||||
|
||||
void addDataVisualizer(std::shared_ptr<DataVisualizer> &&visualizer);
|
||||
|
||||
std::vector<std::shared_ptr<DataVisualizer>> &getVisualizers();
|
||||
std::vector<std::shared_ptr<MiniMapVisualizer>> &getMiniMapVisualizers();
|
||||
const std::vector<std::shared_ptr<DataVisualizer>>& getVisualizers();
|
||||
const std::vector<std::shared_ptr<MiniMapVisualizer>>& getMiniMapVisualizers();
|
||||
|
||||
}
|
||||
|
||||
@@ -1082,7 +1083,7 @@ namespace hex {
|
||||
|
||||
namespace impl {
|
||||
|
||||
std::vector<std::unique_ptr<Algorithm>> &getAlgorithms();
|
||||
const std::vector<std::unique_ptr<Algorithm>>& getAlgorithms();
|
||||
|
||||
void addAlgorithm(std::unique_ptr<Algorithm> &&hash);
|
||||
|
||||
@@ -1119,7 +1120,7 @@ namespace hex {
|
||||
|
||||
[[nodiscard]] Hash *getType() { return m_type; }
|
||||
[[nodiscard]] const Hash *getType() const { return m_type; }
|
||||
[[nodiscard]] const std::string &getName() const { return m_name; }
|
||||
[[nodiscard]] const std::string& getName() const { return m_name; }
|
||||
|
||||
const std::vector<u8>& get(const Region& region, prv::Provider *provider) {
|
||||
if (m_cache.empty()) {
|
||||
@@ -1147,7 +1148,7 @@ namespace hex {
|
||||
[[nodiscard]] virtual nlohmann::json store() const = 0;
|
||||
virtual void load(const nlohmann::json &json) = 0;
|
||||
|
||||
[[nodiscard]] const UnlocalizedString &getUnlocalizedName() const {
|
||||
[[nodiscard]] const UnlocalizedString& getUnlocalizedName() const {
|
||||
return m_unlocalizedName;
|
||||
}
|
||||
|
||||
@@ -1162,7 +1163,7 @@ namespace hex {
|
||||
|
||||
namespace impl {
|
||||
|
||||
std::vector<std::unique_ptr<Hash>> &getHashes();
|
||||
const std::vector<std::unique_ptr<Hash>>& getHashes();
|
||||
|
||||
void add(std::unique_ptr<Hash> &&hash);
|
||||
|
||||
@@ -1199,7 +1200,7 @@ namespace hex {
|
||||
namespace impl {
|
||||
using NetworkCallback = std::function<nlohmann::json(const nlohmann::json &)>;
|
||||
|
||||
std::map<std::string, NetworkCallback> &getNetworkEndpoints();
|
||||
const std::map<std::string, NetworkCallback>& getNetworkEndpoints();
|
||||
}
|
||||
|
||||
void registerNetworkEndpoint(const std::string &endpoint, const impl::NetworkCallback &callback);
|
||||
@@ -1216,7 +1217,7 @@ namespace hex {
|
||||
bool enabled;
|
||||
};
|
||||
|
||||
std::map<std::string, Experiment> &getExperiments();
|
||||
const std::map<std::string, Experiment>& getExperiments();
|
||||
}
|
||||
|
||||
void addExperiment(
|
||||
@@ -1240,7 +1241,7 @@ namespace hex {
|
||||
Callback callback;
|
||||
};
|
||||
|
||||
std::vector<ReportGenerator>& getGenerators();
|
||||
const std::vector<ReportGenerator>& getGenerators();
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -35,8 +35,8 @@ namespace hex {
|
||||
Highlighting() = default;
|
||||
Highlighting(Region region, color_t color);
|
||||
|
||||
[[nodiscard]] const Region &getRegion() const { return m_region; }
|
||||
[[nodiscard]] const color_t &getColor() const { return m_color; }
|
||||
[[nodiscard]] const Region& getRegion() const { return m_region; }
|
||||
[[nodiscard]] const color_t& getColor() const { return m_color; }
|
||||
|
||||
private:
|
||||
Region m_region = {};
|
||||
@@ -48,9 +48,9 @@ namespace hex {
|
||||
Tooltip() = default;
|
||||
Tooltip(Region region, std::string value, color_t color);
|
||||
|
||||
[[nodiscard]] const Region &getRegion() const { return m_region; }
|
||||
[[nodiscard]] const color_t &getColor() const { return m_color; }
|
||||
[[nodiscard]] const std::string &getValue() const { return m_value; }
|
||||
[[nodiscard]] const Region& getRegion() const { return m_region; }
|
||||
[[nodiscard]] const color_t& getColor() const { return m_color; }
|
||||
[[nodiscard]] const std::string& getValue() const { return m_value; }
|
||||
|
||||
private:
|
||||
Region m_region = {};
|
||||
@@ -70,12 +70,12 @@ namespace hex {
|
||||
|
||||
using HighlightingFunction = std::function<std::optional<color_t>(u64, const u8*, size_t, bool)>;
|
||||
|
||||
std::map<u32, Highlighting> &getBackgroundHighlights();
|
||||
std::map<u32, HighlightingFunction> &getBackgroundHighlightingFunctions();
|
||||
std::map<u32, Highlighting> &getForegroundHighlights();
|
||||
std::map<u32, HighlightingFunction> &getForegroundHighlightingFunctions();
|
||||
std::map<u32, Tooltip> &getTooltips();
|
||||
std::map<u32, TooltipFunction> &getTooltipFunctions();
|
||||
const std::map<u32, Highlighting>& getBackgroundHighlights();
|
||||
const std::map<u32, HighlightingFunction>& getBackgroundHighlightingFunctions();
|
||||
const std::map<u32, Highlighting>& getForegroundHighlights();
|
||||
const std::map<u32, HighlightingFunction>& getForegroundHighlightingFunctions();
|
||||
const std::map<u32, Tooltip>& getTooltips();
|
||||
const std::map<u32, TooltipFunction>& getTooltipFunctions();
|
||||
|
||||
void setCurrentSelection(const std::optional<ProviderRegion> ®ion);
|
||||
}
|
||||
@@ -279,7 +279,7 @@ namespace hex {
|
||||
* @brief Gets a list of all currently loaded data providers
|
||||
* @return The currently loaded data providers
|
||||
*/
|
||||
const std::vector<prv::Provider *> &getProviders();
|
||||
std::vector<prv::Provider*> getProviders();
|
||||
|
||||
/**
|
||||
* @brief Sets the currently selected data provider
|
||||
@@ -323,7 +323,7 @@ namespace hex {
|
||||
* @param skipLoadInterface Whether to skip the provider's loading interface (see property documentation)
|
||||
* @param select Whether to select the provider after adding it
|
||||
*/
|
||||
void add(prv::Provider *provider, bool skipLoadInterface = false, bool select = true);
|
||||
void add(std::unique_ptr<prv::Provider> &&provider, bool skipLoadInterface = false, bool select = true);
|
||||
|
||||
/**
|
||||
* @brief Creates a new provider and adds it to the list of providers
|
||||
@@ -332,7 +332,7 @@ namespace hex {
|
||||
*/
|
||||
template<std::derived_from<prv::Provider> T>
|
||||
void add(auto &&...args) {
|
||||
add(new T(std::forward<decltype(args)>(args)...));
|
||||
add(std::make_unique<T>(std::forward<decltype(args)>(args)...));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -497,7 +497,14 @@ namespace hex {
|
||||
* @brief Gets the init arguments passed to ImHex from the splash screen
|
||||
* @return Init arguments
|
||||
*/
|
||||
std::map<std::string, std::string> &getInitArguments();
|
||||
const std::map<std::string, std::string>& getInitArguments();
|
||||
|
||||
/**
|
||||
* @brief Gets a init arguments passed to ImHex from the splash screen
|
||||
* @param key The key of the init argument
|
||||
* @return Init argument
|
||||
*/
|
||||
std::string getInitArgument(const std::string &key);
|
||||
|
||||
/**
|
||||
* @brief Sets if ImHex should follow the system theme
|
||||
@@ -516,7 +523,7 @@ namespace hex {
|
||||
* @brief Gets the currently set additional folder paths
|
||||
* @return The currently set additional folder paths
|
||||
*/
|
||||
std::vector<std::filesystem::path> &getAdditionalFolderPaths();
|
||||
const std::vector<std::filesystem::path>& getAdditionalFolderPaths();
|
||||
|
||||
/**
|
||||
* @brief Sets the additional folder paths
|
||||
@@ -529,7 +536,7 @@ namespace hex {
|
||||
* @brief Gets the current GPU vendor
|
||||
* @return The current GPU vendor
|
||||
*/
|
||||
const std::string &getGPUVendor();
|
||||
const std::string& getGPUVendor();
|
||||
|
||||
/**
|
||||
* @brief Checks if ImHex is running in portable mode
|
||||
@@ -633,11 +640,12 @@ namespace hex {
|
||||
namespace Messaging {
|
||||
|
||||
namespace impl {
|
||||
|
||||
using MessagingHandler = std::function<void(const std::vector<u8> &)>;
|
||||
|
||||
std::map<std::string, MessagingHandler> &getHandlers();
|
||||
|
||||
const std::map<std::string, MessagingHandler>& getHandlers();
|
||||
void runHandler(const std::string &eventName, const std::vector<u8> &args);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -661,7 +669,7 @@ namespace hex {
|
||||
|
||||
namespace impl {
|
||||
|
||||
std::vector<Font>& getFonts();
|
||||
const std::vector<Font>& getFonts();
|
||||
|
||||
void setCustomFontPath(const std::fs::path &path);
|
||||
void setFontSize(float size);
|
||||
@@ -687,7 +695,7 @@ namespace hex {
|
||||
* @brief Gets the current custom font path
|
||||
* @return The current custom font path
|
||||
*/
|
||||
std::filesystem::path &getCustomFontPath();
|
||||
const std::filesystem::path& getCustomFontPath();
|
||||
|
||||
/**
|
||||
* @brief Gets the current font size
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
|
||||
#include <string>
|
||||
|
||||
struct ImGuiTextBuffer;
|
||||
|
||||
namespace hex {
|
||||
|
||||
class LayoutManager {
|
||||
@@ -13,6 +15,9 @@ namespace hex {
|
||||
std::fs::path path;
|
||||
};
|
||||
|
||||
using LoadCallback = std::function<void(std::string_view)>;
|
||||
using StoreCallback = std::function<void(ImGuiTextBuffer *)>;
|
||||
|
||||
/**
|
||||
* @brief Save the current layout
|
||||
* @param name Name of the layout
|
||||
@@ -76,6 +81,12 @@ namespace hex {
|
||||
*/
|
||||
static void closeAllViews();
|
||||
|
||||
static void registerLoadCallback(const LoadCallback &callback);
|
||||
static void registerStoreCallback(const StoreCallback &callback);
|
||||
|
||||
static void onStore(ImGuiTextBuffer *buffer);
|
||||
static void onLoad(std::string_view line);
|
||||
|
||||
private:
|
||||
LayoutManager() = default;
|
||||
};
|
||||
|
||||
@@ -6,7 +6,9 @@
|
||||
#include <string>
|
||||
|
||||
#include <wolv/io/fs.hpp>
|
||||
|
||||
#include <hex/helpers/logger.hpp>
|
||||
#include <hex/helpers/auto_reset.hpp>
|
||||
|
||||
struct ImGuiContext;
|
||||
|
||||
@@ -109,11 +111,16 @@ namespace hex {
|
||||
|
||||
static void addPlugin(const std::string &name, PluginFunctions functions);
|
||||
|
||||
static std::list<Plugin> &getPlugins();
|
||||
static std::vector<std::fs::path> &getPluginPaths();
|
||||
static std::vector<std::fs::path> &getPluginLoadPaths();
|
||||
static const std::list<Plugin>& getPlugins();
|
||||
static const std::vector<std::fs::path>& getPluginPaths();
|
||||
static const std::vector<std::fs::path>& getPluginLoadPaths();
|
||||
|
||||
static bool isPluginLoaded(const std::fs::path &path);
|
||||
|
||||
private:
|
||||
static std::list<Plugin>& getPluginsMutable();
|
||||
|
||||
static AutoReset<std::vector<std::fs::path>> s_pluginPaths, s_pluginLoadPaths;
|
||||
};
|
||||
|
||||
}
|
||||
@@ -93,30 +93,26 @@ namespace hex {
|
||||
*
|
||||
* @param handler The handler to register
|
||||
*/
|
||||
static void registerHandler(const Handler &handler) {
|
||||
getHandlers().push_back(handler);
|
||||
}
|
||||
static void registerHandler(const Handler &handler);
|
||||
|
||||
/**
|
||||
* @brief Register a handler for storing and loading per-provider data from a project file
|
||||
*
|
||||
* @param handler The handler to register
|
||||
*/
|
||||
static void registerPerProviderHandler(const ProviderHandler &handler) {
|
||||
getProviderHandlers().push_back(handler);
|
||||
}
|
||||
static void registerPerProviderHandler(const ProviderHandler &handler);
|
||||
|
||||
/**
|
||||
* @brief Get the list of registered handlers
|
||||
* @return List of registered handlers
|
||||
*/
|
||||
static std::vector<Handler>& getHandlers();
|
||||
static const std::vector<Handler>& getHandlers();
|
||||
|
||||
/**
|
||||
* @brief Get the list of registered per-provider handlers
|
||||
* @return List of registered per-provider handlers
|
||||
*/
|
||||
static std::vector<ProviderHandler>& getProviderHandlers();
|
||||
static const std::vector<ProviderHandler>& getProviderHandlers();
|
||||
|
||||
private:
|
||||
ProjectFile() = default;
|
||||
|
||||
@@ -176,7 +176,7 @@ namespace hex {
|
||||
static size_t getRunningTaskCount();
|
||||
static size_t getRunningBackgroundTaskCount();
|
||||
|
||||
static std::list<std::shared_ptr<Task>> &getRunningTasks();
|
||||
static const std::list<std::shared_ptr<Task>>& getRunningTasks();
|
||||
static void runDeferredCalls();
|
||||
|
||||
private:
|
||||
|
||||
@@ -78,8 +78,8 @@ namespace hex {
|
||||
StyleMap styleMap;
|
||||
};
|
||||
|
||||
static std::map<std::string, ThemeHandler>& getThemeHandlers();
|
||||
static std::map<std::string, StyleHandler>& getStyleHandlers();
|
||||
static const std::map<std::string, ThemeHandler>& getThemeHandlers();
|
||||
static const std::map<std::string, StyleHandler>& getStyleHandlers();
|
||||
|
||||
private:
|
||||
ThemeManager() = default;
|
||||
|
||||
@@ -7,41 +7,43 @@
|
||||
|
||||
namespace hex {
|
||||
|
||||
std::unordered_map<std::string, std::unordered_map<std::string, std::unique_ptr<Achievement>>> &AchievementManager::getAchievements() {
|
||||
static AutoReset<std::unordered_map<std::string, std::unordered_map<std::string, std::unique_ptr<Achievement>>>> achievements;
|
||||
|
||||
return achievements;
|
||||
static AutoReset<std::unordered_map<std::string, std::unordered_map<std::string, std::unique_ptr<Achievement>>>> s_achievements;
|
||||
const std::unordered_map<std::string, std::unordered_map<std::string, std::unique_ptr<Achievement>>> &AchievementManager::getAchievements() {
|
||||
return *s_achievements;
|
||||
}
|
||||
|
||||
std::unordered_map<std::string, std::list<AchievementManager::AchievementNode>>& AchievementManager::getAchievementNodes(bool rebuild) {
|
||||
static AutoReset<std::unordered_map<std::string, std::list<AchievementNode>>> nodeCategoryStorage;
|
||||
static AutoReset<std::unordered_map<std::string, std::list<AchievementManager::AchievementNode>>> s_nodeCategoryStorage;
|
||||
std::unordered_map<std::string, std::list<AchievementManager::AchievementNode>>& getAchievementNodesMutable(bool rebuild) {
|
||||
if (!s_nodeCategoryStorage->empty() || !rebuild)
|
||||
return s_nodeCategoryStorage;
|
||||
|
||||
if (!nodeCategoryStorage->empty() || !rebuild)
|
||||
return nodeCategoryStorage;
|
||||
|
||||
nodeCategoryStorage->clear();
|
||||
s_nodeCategoryStorage->clear();
|
||||
|
||||
// Add all achievements to the node storage
|
||||
for (auto &[categoryName, achievements] : getAchievements()) {
|
||||
auto &nodes = (*nodeCategoryStorage)[categoryName];
|
||||
for (auto &[categoryName, achievements] : AchievementManager::getAchievements()) {
|
||||
auto &nodes = (*s_nodeCategoryStorage)[categoryName];
|
||||
|
||||
for (auto &[achievementName, achievement] : achievements) {
|
||||
nodes.emplace_back(achievement.get());
|
||||
}
|
||||
}
|
||||
|
||||
return nodeCategoryStorage;
|
||||
return s_nodeCategoryStorage;
|
||||
}
|
||||
|
||||
std::unordered_map<std::string, std::vector<AchievementManager::AchievementNode*>>& AchievementManager::getAchievementStartNodes(bool rebuild) {
|
||||
static AutoReset<std::unordered_map<std::string, std::vector<AchievementNode*>>> startNodes;
|
||||
const std::unordered_map<std::string, std::list<AchievementManager::AchievementNode>>& AchievementManager::getAchievementNodes(bool rebuild) {
|
||||
return getAchievementNodesMutable(rebuild);
|
||||
}
|
||||
|
||||
if (!startNodes->empty() || !rebuild)
|
||||
return startNodes;
|
||||
static AutoReset<std::unordered_map<std::string, std::vector<AchievementManager::AchievementNode*>>> s_startNodes;
|
||||
const std::unordered_map<std::string, std::vector<AchievementManager::AchievementNode*>>& AchievementManager::getAchievementStartNodes(bool rebuild) {
|
||||
|
||||
auto &nodeCategoryStorage = getAchievementNodes();
|
||||
if (!s_startNodes->empty() || !rebuild)
|
||||
return s_startNodes;
|
||||
|
||||
startNodes->clear();
|
||||
auto &nodeCategoryStorage = getAchievementNodesMutable(rebuild);
|
||||
|
||||
s_startNodes->clear();
|
||||
|
||||
// Add all parents and children to the nodes
|
||||
for (auto &[categoryName, achievements] : nodeCategoryStorage) {
|
||||
@@ -76,17 +78,17 @@ namespace hex {
|
||||
for (auto &[categoryName, achievements] : nodeCategoryStorage) {
|
||||
for (auto &achievementNode : achievements) {
|
||||
if (!achievementNode.hasParents()) {
|
||||
(*startNodes)[categoryName].emplace_back(&achievementNode);
|
||||
(*s_startNodes)[categoryName].emplace_back(&achievementNode);
|
||||
}
|
||||
|
||||
for (const auto &parent : achievementNode.parents) {
|
||||
if (parent->achievement->getUnlocalizedCategory() != achievementNode.achievement->getUnlocalizedCategory())
|
||||
(*startNodes)[categoryName].emplace_back(&achievementNode);
|
||||
(*s_startNodes)[categoryName].emplace_back(&achievementNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return startNodes;
|
||||
return s_startNodes;
|
||||
}
|
||||
|
||||
void AchievementManager::unlockAchievement(const UnlocalizedString &unlocalizedCategory, const UnlocalizedString &unlocalizedName) {
|
||||
@@ -104,8 +106,11 @@ namespace hex {
|
||||
return;
|
||||
}
|
||||
|
||||
const auto &nodes = getAchievementNodes()[categoryName];
|
||||
for (const auto &node : nodes) {
|
||||
const auto &nodes = getAchievementNodes();
|
||||
if (!nodes.contains(categoryName))
|
||||
return;
|
||||
|
||||
for (const auto &node : nodes.at(categoryName)) {
|
||||
auto &achievement = node.achievement;
|
||||
|
||||
if (achievement->getUnlocalizedCategory() != unlocalizedCategory) {
|
||||
@@ -134,14 +139,8 @@ namespace hex {
|
||||
}
|
||||
}
|
||||
|
||||
void AchievementManager::clear() {
|
||||
getAchievements().clear();
|
||||
getAchievementStartNodes(false).clear();
|
||||
getAchievementNodes(false).clear();
|
||||
}
|
||||
|
||||
void AchievementManager::clearTemporary() {
|
||||
auto &categories = getAchievements();
|
||||
auto &categories = *s_achievements;
|
||||
for (auto &[categoryName, achievements] : categories) {
|
||||
std::erase_if(achievements, [](auto &data) {
|
||||
auto &[achievementName, achievement] = data;
|
||||
@@ -154,8 +153,8 @@ namespace hex {
|
||||
return achievements.empty();
|
||||
});
|
||||
|
||||
getAchievementStartNodes(false).clear();
|
||||
getAchievementNodes(false).clear();
|
||||
s_startNodes->clear();
|
||||
s_nodeCategoryStorage->clear();
|
||||
}
|
||||
|
||||
std::pair<u32, u32> AchievementManager::getProgress() {
|
||||
@@ -175,10 +174,26 @@ namespace hex {
|
||||
}
|
||||
|
||||
void AchievementManager::achievementAdded() {
|
||||
getAchievementStartNodes(false).clear();
|
||||
getAchievementNodes(false).clear();
|
||||
s_startNodes->clear();
|
||||
s_nodeCategoryStorage->clear();
|
||||
}
|
||||
|
||||
Achievement &AchievementManager::addAchievementImpl(std::unique_ptr<Achievement> &&newAchievement) {
|
||||
const auto &category = newAchievement->getUnlocalizedCategory();
|
||||
const auto &name = newAchievement->getUnlocalizedName();
|
||||
|
||||
auto [categoryIter, categoryInserted] = s_achievements->insert({ category, std::unordered_map<std::string, std::unique_ptr<Achievement>>{} });
|
||||
auto &[categoryKey, achievements] = *categoryIter;
|
||||
|
||||
auto [achievementIter, achievementInserted] = achievements.insert({ name, std::move(newAchievement) });
|
||||
auto &[achievementKey, achievement] = *achievementIter;
|
||||
|
||||
achievementAdded();
|
||||
|
||||
return *achievement;
|
||||
}
|
||||
|
||||
|
||||
constexpr static auto AchievementsFile = "achievements.json";
|
||||
|
||||
void AchievementManager::loadProgress() {
|
||||
|
||||
@@ -28,8 +28,13 @@ namespace hex {
|
||||
|
||||
namespace impl {
|
||||
|
||||
static AutoReset<nlohmann::json> s_settings;
|
||||
const nlohmann::json& getSettingsData() {
|
||||
return s_settings;
|
||||
}
|
||||
|
||||
nlohmann::json& getSetting(const UnlocalizedString &unlocalizedCategory, const UnlocalizedString &unlocalizedName, const nlohmann::json &defaultValue) {
|
||||
auto &settings = getSettingsData();
|
||||
auto &settings = *s_settings;
|
||||
|
||||
if (!settings.contains(unlocalizedCategory))
|
||||
settings[unlocalizedCategory] = {};
|
||||
@@ -40,12 +45,6 @@ namespace hex {
|
||||
return settings[unlocalizedCategory][unlocalizedName];
|
||||
}
|
||||
|
||||
nlohmann::json &getSettingsData() {
|
||||
static AutoReset<nlohmann::json> settings;
|
||||
|
||||
return settings;
|
||||
}
|
||||
|
||||
#if defined(OS_WEB)
|
||||
void load() {
|
||||
char *data = (char *) MAIN_THREAD_EM_ASM_INT({
|
||||
@@ -56,12 +55,12 @@ namespace hex {
|
||||
if (data == nullptr) {
|
||||
store();
|
||||
} else {
|
||||
getSettingsData() = nlohmann::json::parse(data);
|
||||
s_settings = nlohmann::json::parse(data);
|
||||
}
|
||||
}
|
||||
|
||||
void store() {
|
||||
auto data = getSettingsData().dump();
|
||||
auto data = s_settings->dump();
|
||||
MAIN_THREAD_EM_ASM({
|
||||
localStorage.setItem("config", UTF8ToString($0));
|
||||
}, data.c_str());
|
||||
@@ -72,14 +71,16 @@ namespace hex {
|
||||
localStorage.removeItem("config");
|
||||
});
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
void load() {
|
||||
bool loaded = false;
|
||||
for (const auto &dir : fs::getDefaultPaths(fs::ImHexPath::Config)) {
|
||||
wolv::io::File file(dir / SettingsFile, wolv::io::File::Mode::Read);
|
||||
|
||||
if (file.isValid()) {
|
||||
getSettingsData() = nlohmann::json::parse(file.readString());
|
||||
s_settings = nlohmann::json::parse(file.readString());
|
||||
loaded = true;
|
||||
break;
|
||||
}
|
||||
@@ -139,14 +140,13 @@ namespace hex {
|
||||
return foundEntry;
|
||||
}
|
||||
|
||||
std::vector<Category> &getSettings() {
|
||||
static AutoReset<std::vector<Category>> categories;
|
||||
|
||||
return categories;
|
||||
static AutoReset<std::vector<Category>> s_categories;
|
||||
const std::vector<Category>& getSettings() {
|
||||
return *s_categories;
|
||||
}
|
||||
|
||||
Widgets::Widget* add(const UnlocalizedString &unlocalizedCategory, const UnlocalizedString &unlocalizedSubCategory, const UnlocalizedString &unlocalizedName, std::unique_ptr<Widgets::Widget> &&widget) {
|
||||
const auto category = insertOrGetEntry(getSettings(), unlocalizedCategory);
|
||||
const auto category = insertOrGetEntry(*s_categories, unlocalizedCategory);
|
||||
const auto subCategory = insertOrGetEntry(category->subCategories, unlocalizedSubCategory);
|
||||
const auto entry = insertOrGetEntry(subCategory->entries, unlocalizedName);
|
||||
|
||||
@@ -163,7 +163,7 @@ namespace hex {
|
||||
}
|
||||
|
||||
void setCategoryDescription(const UnlocalizedString &unlocalizedCategory, const UnlocalizedString &unlocalizedDescription) {
|
||||
const auto category = insertOrGetEntry(impl::getSettings(), unlocalizedCategory);
|
||||
const auto category = insertOrGetEntry(*impl::s_categories, unlocalizedCategory);
|
||||
|
||||
category->unlocalizedDescription = unlocalizedDescription;
|
||||
}
|
||||
@@ -386,32 +386,30 @@ namespace hex {
|
||||
|
||||
namespace ContentRegistry::CommandPaletteCommands {
|
||||
|
||||
namespace impl {
|
||||
|
||||
static AutoReset<std::vector<Entry>> s_entries;
|
||||
const std::vector<Entry>& getEntries() {
|
||||
return *s_entries;
|
||||
}
|
||||
|
||||
static AutoReset<std::vector<Handler>> s_handlers;
|
||||
const std::vector<Handler>& getHandlers() {
|
||||
return *s_handlers;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void add(Type type, const std::string &command, const UnlocalizedString &unlocalizedDescription, const impl::DisplayCallback &displayCallback, const impl::ExecuteCallback &executeCallback) {
|
||||
log::debug("Registered new command palette command: {}", command);
|
||||
|
||||
impl::getEntries().push_back(impl::Entry { type, command, unlocalizedDescription, displayCallback, executeCallback });
|
||||
impl::s_entries->push_back(impl::Entry { type, command, unlocalizedDescription, displayCallback, executeCallback });
|
||||
}
|
||||
|
||||
void addHandler(Type type, const std::string &command, const impl::QueryCallback &queryCallback, const impl::DisplayCallback &displayCallback) {
|
||||
log::debug("Registered new command palette command handler: {}", command);
|
||||
|
||||
impl::getHandlers().push_back(impl::Handler { type, command, queryCallback, displayCallback });
|
||||
}
|
||||
|
||||
namespace impl {
|
||||
|
||||
std::vector<Entry> &getEntries() {
|
||||
static AutoReset<std::vector<Entry>> commands;
|
||||
|
||||
return commands;
|
||||
}
|
||||
|
||||
std::vector<Handler> &getHandlers() {
|
||||
static AutoReset<std::vector<Handler>> commands;
|
||||
|
||||
return commands;
|
||||
}
|
||||
|
||||
impl::s_handlers->push_back(impl::Handler { type, command, queryCallback, displayCallback });
|
||||
}
|
||||
|
||||
}
|
||||
@@ -419,6 +417,30 @@ namespace hex {
|
||||
|
||||
namespace ContentRegistry::PatternLanguage {
|
||||
|
||||
namespace impl {
|
||||
|
||||
static AutoReset<std::map<std::string, Visualizer>> s_visualizers;
|
||||
const std::map<std::string, Visualizer>& getVisualizers() {
|
||||
return *s_visualizers;
|
||||
}
|
||||
|
||||
static AutoReset<std::map<std::string, Visualizer>> s_inlineVisualizers;
|
||||
const std::map<std::string, Visualizer>& getInlineVisualizers() {
|
||||
return *s_inlineVisualizers;
|
||||
}
|
||||
|
||||
static AutoReset<std::map<std::string, pl::api::PragmaHandler>> s_pragmas;
|
||||
const std::map<std::string, pl::api::PragmaHandler>& getPragmas() {
|
||||
return *s_pragmas;
|
||||
}
|
||||
|
||||
static AutoReset<std::vector<FunctionDefinition>> s_functions;
|
||||
const std::vector<FunctionDefinition>& getFunctions() {
|
||||
return *s_functions;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static std::string getFunctionName(const pl::api::Namespace &ns, const std::string &name) {
|
||||
std::string functionName;
|
||||
for (auto &scope : ns)
|
||||
@@ -476,13 +498,13 @@ namespace hex {
|
||||
void addPragma(const std::string &name, const pl::api::PragmaHandler &handler) {
|
||||
log::debug("Registered new pattern language pragma: {}", name);
|
||||
|
||||
impl::getPragmas()[name] = handler;
|
||||
(*impl::s_pragmas)[name] = handler;
|
||||
}
|
||||
|
||||
void addFunction(const pl::api::Namespace &ns, const std::string &name, pl::api::FunctionParameterCount parameterCount, const pl::api::FunctionCallback &func) {
|
||||
log::debug("Registered new pattern language function: {}", getFunctionName(ns, name));
|
||||
|
||||
impl::getFunctions().push_back({
|
||||
impl::s_functions->push_back({
|
||||
ns, name,
|
||||
parameterCount, func,
|
||||
false
|
||||
@@ -492,7 +514,7 @@ namespace hex {
|
||||
void addDangerousFunction(const pl::api::Namespace &ns, const std::string &name, pl::api::FunctionParameterCount parameterCount, const pl::api::FunctionCallback &func) {
|
||||
log::debug("Registered new dangerous pattern language function: {}", getFunctionName(ns, name));
|
||||
|
||||
impl::getFunctions().push_back({
|
||||
impl::s_functions->push_back({
|
||||
ns, name,
|
||||
parameterCount, func,
|
||||
true
|
||||
@@ -502,44 +524,14 @@ namespace hex {
|
||||
|
||||
void addVisualizer(const std::string &name, const impl::VisualizerFunctionCallback &function, pl::api::FunctionParameterCount parameterCount) {
|
||||
log::debug("Registered new pattern visualizer function: {}", name);
|
||||
impl::getVisualizers()[name] = impl::Visualizer { parameterCount, function };
|
||||
(*impl::s_visualizers)[name] = impl::Visualizer { parameterCount, function };
|
||||
}
|
||||
|
||||
void addInlineVisualizer(const std::string &name, const impl::VisualizerFunctionCallback &function, pl::api::FunctionParameterCount parameterCount) {
|
||||
log::debug("Registered new inline pattern visualizer function: {}", name);
|
||||
impl::getInlineVisualizers()[name] = impl::Visualizer { parameterCount, function };
|
||||
(*impl::s_inlineVisualizers)[name] = impl::Visualizer { parameterCount, function };
|
||||
}
|
||||
|
||||
|
||||
namespace impl {
|
||||
|
||||
std::map<std::string, Visualizer> &getVisualizers() {
|
||||
static AutoReset<std::map<std::string, Visualizer>> visualizers;
|
||||
|
||||
return visualizers;
|
||||
}
|
||||
|
||||
std::map<std::string, Visualizer> &getInlineVisualizers() {
|
||||
static AutoReset<std::map<std::string, Visualizer>> visualizers;
|
||||
|
||||
return visualizers;
|
||||
}
|
||||
|
||||
std::map<std::string, pl::api::PragmaHandler> &getPragmas() {
|
||||
static AutoReset<std::map<std::string, pl::api::PragmaHandler>> pragmas;
|
||||
|
||||
return pragmas;
|
||||
}
|
||||
|
||||
std::vector<FunctionDefinition> &getFunctions() {
|
||||
static AutoReset<std::vector<FunctionDefinition>> functions;
|
||||
|
||||
return functions;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -547,22 +539,21 @@ namespace hex {
|
||||
|
||||
namespace impl {
|
||||
|
||||
std::map<std::string, std::unique_ptr<View>> &getEntries() {
|
||||
static AutoReset<std::map<std::string, std::unique_ptr<View>>> views;
|
||||
|
||||
return views;
|
||||
static AutoReset<std::map<std::string, std::unique_ptr<View>>> s_views;
|
||||
const std::map<std::string, std::unique_ptr<View>>& getEntries() {
|
||||
return *s_views;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void impl::add(std::unique_ptr<View> &&view) {
|
||||
void add(std::unique_ptr<View> &&view) {
|
||||
log::debug("Registered new view: {}", view->getUnlocalizedName().get());
|
||||
|
||||
getEntries().insert({ view->getUnlocalizedName(), std::move(view) });
|
||||
s_views->insert({ view->getUnlocalizedName(), std::move(view) });
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
View* getViewByName(const UnlocalizedString &unlocalizedName) {
|
||||
auto &views = impl::getEntries();
|
||||
auto &views = *impl::s_views;
|
||||
|
||||
if (views.contains(unlocalizedName))
|
||||
return views[unlocalizedName].get();
|
||||
@@ -574,77 +565,87 @@ namespace hex {
|
||||
|
||||
namespace ContentRegistry::Tools {
|
||||
|
||||
namespace impl {
|
||||
|
||||
static AutoReset<std::vector<Entry>> s_tools;
|
||||
const std::vector<Entry>& getEntries() {
|
||||
return *s_tools;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void add(const UnlocalizedString &unlocalizedName, const impl::Callback &function) {
|
||||
log::debug("Registered new tool: {}", unlocalizedName.get());
|
||||
|
||||
impl::getEntries().emplace_back(impl::Entry { unlocalizedName, function, false });
|
||||
}
|
||||
|
||||
namespace impl {
|
||||
|
||||
std::vector<Entry> &getEntries() {
|
||||
static AutoReset<std::vector<Entry>> tools;
|
||||
|
||||
return tools;
|
||||
}
|
||||
|
||||
impl::s_tools->emplace_back(impl::Entry { unlocalizedName, function });
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
namespace ContentRegistry::DataInspector {
|
||||
|
||||
namespace impl {
|
||||
|
||||
static AutoReset<std::vector<Entry>> s_entries;
|
||||
const std::vector<Entry>& getEntries() {
|
||||
return *s_entries;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void add(const UnlocalizedString &unlocalizedName, size_t requiredSize, impl::GeneratorFunction displayGeneratorFunction, std::optional<impl::EditingFunction> editingFunction) {
|
||||
log::debug("Registered new data inspector format: {}", unlocalizedName.get());
|
||||
|
||||
impl::getEntries().push_back({ unlocalizedName, requiredSize, requiredSize, std::move(displayGeneratorFunction), std::move(editingFunction) });
|
||||
impl::s_entries->push_back({ unlocalizedName, requiredSize, requiredSize, std::move(displayGeneratorFunction), std::move(editingFunction) });
|
||||
}
|
||||
|
||||
void add(const UnlocalizedString &unlocalizedName, size_t requiredSize, size_t maxSize, impl::GeneratorFunction displayGeneratorFunction, std::optional<impl::EditingFunction> editingFunction) {
|
||||
log::debug("Registered new data inspector format: {}", unlocalizedName.get());
|
||||
|
||||
impl::getEntries().push_back({ unlocalizedName, requiredSize, maxSize, std::move(displayGeneratorFunction), std::move(editingFunction) });
|
||||
impl::s_entries->push_back({ unlocalizedName, requiredSize, maxSize, std::move(displayGeneratorFunction), std::move(editingFunction) });
|
||||
}
|
||||
|
||||
namespace impl {
|
||||
|
||||
std::vector<Entry> &getEntries() {
|
||||
static AutoReset<std::vector<Entry>> entries;
|
||||
|
||||
return entries;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
namespace ContentRegistry::DataProcessorNode {
|
||||
|
||||
void impl::add(const Entry &entry) {
|
||||
log::debug("Registered new data processor node type: [{}]: {}", entry.unlocalizedCategory.get(), entry.unlocalizedName.get());
|
||||
namespace impl {
|
||||
|
||||
static AutoReset<std::vector<Entry>> s_nodes;
|
||||
const std::vector<Entry>& getEntries() {
|
||||
return *s_nodes;
|
||||
}
|
||||
|
||||
void add(const Entry &entry) {
|
||||
log::debug("Registered new data processor node type: [{}]: {}", entry.unlocalizedCategory.get(), entry.unlocalizedName.get());
|
||||
|
||||
s_nodes->push_back(entry);
|
||||
}
|
||||
|
||||
getEntries().push_back(entry);
|
||||
}
|
||||
|
||||
void addSeparator() {
|
||||
impl::getEntries().push_back({ "", "", [] { return nullptr; } });
|
||||
}
|
||||
|
||||
namespace impl {
|
||||
|
||||
std::vector<Entry> &getEntries() {
|
||||
static AutoReset<std::vector<Entry>> nodes;
|
||||
|
||||
return nodes;
|
||||
}
|
||||
|
||||
impl::s_nodes->push_back({ "", "", [] { return nullptr; } });
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
namespace ContentRegistry::Language {
|
||||
|
||||
namespace impl {
|
||||
|
||||
static AutoReset<std::map<std::string, std::string>> s_languages;
|
||||
const std::map<std::string, std::string>& getLanguages() {
|
||||
return *s_languages;
|
||||
}
|
||||
|
||||
static AutoReset<std::map<std::string, std::vector<LocalizationManager::LanguageDefinition>>> s_definitions;
|
||||
const std::map<std::string, std::vector<LocalizationManager::LanguageDefinition>>& getLanguageDefinitions() {
|
||||
return *s_definitions;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void addLocalization(const nlohmann::json &data) {
|
||||
if (!data.is_object())
|
||||
return;
|
||||
@@ -671,7 +672,7 @@ namespace hex {
|
||||
LocalizationManager::impl::setFallbackLanguage(code.get<std::string>());
|
||||
}
|
||||
|
||||
impl::getLanguages().insert({ code.get<std::string>(), hex::format("{} ({})", language.get<std::string>(), country.get<std::string>()) });
|
||||
impl::s_languages->insert({ code.get<std::string>(), hex::format("{} ({})", language.get<std::string>(), country.get<std::string>()) });
|
||||
|
||||
std::map<std::string, std::string> translationDefinitions;
|
||||
for (auto &[key, value] : translations.items()) {
|
||||
@@ -683,34 +684,60 @@ namespace hex {
|
||||
translationDefinitions[key] = value.get<std::string>();
|
||||
}
|
||||
|
||||
impl::getLanguageDefinitions()[code.get<std::string>()].emplace_back(std::move(translationDefinitions));
|
||||
(*impl::s_definitions)[code.get<std::string>()].emplace_back(std::move(translationDefinitions));
|
||||
}
|
||||
|
||||
namespace impl {
|
||||
|
||||
std::map<std::string, std::string> &getLanguages() {
|
||||
static AutoReset<std::map<std::string, std::string>> languages;
|
||||
|
||||
return languages;
|
||||
}
|
||||
|
||||
std::map<std::string, std::vector<LocalizationManager::LanguageDefinition>> &getLanguageDefinitions() {
|
||||
static AutoReset<std::map<std::string, std::vector<LocalizationManager::LanguageDefinition>>> definitions;
|
||||
|
||||
return definitions;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
namespace ContentRegistry::Interface {
|
||||
|
||||
namespace impl {
|
||||
|
||||
static AutoReset<std::multimap<u32, MainMenuItem>> s_mainMenuItems;
|
||||
const std::multimap<u32, MainMenuItem>& getMainMenuItems() {
|
||||
return *s_mainMenuItems;
|
||||
}
|
||||
|
||||
static AutoReset<std::multimap<u32, MenuItem>> s_menuItems;
|
||||
const std::multimap<u32, MenuItem>& getMenuItems() {
|
||||
return *s_menuItems;
|
||||
}
|
||||
|
||||
std::multimap<u32, MenuItem>& getMenuItemsMutable() {
|
||||
return *s_menuItems;
|
||||
}
|
||||
|
||||
static AutoReset<std::vector<DrawCallback>> s_welcomeScreenEntries;
|
||||
const std::vector<DrawCallback>& getWelcomeScreenEntries() {
|
||||
return *s_welcomeScreenEntries;
|
||||
}
|
||||
|
||||
static AutoReset<std::vector<DrawCallback>> s_footerItems;
|
||||
const std::vector<DrawCallback>& getFooterItems() {
|
||||
return *s_footerItems;
|
||||
}
|
||||
|
||||
static AutoReset<std::vector<DrawCallback>> s_toolbarItems;
|
||||
const std::vector<DrawCallback>& getToolbarItems() {
|
||||
return *s_toolbarItems;
|
||||
}
|
||||
|
||||
static AutoReset<std::vector<SidebarItem>> s_sidebarItems;
|
||||
const std::vector<SidebarItem>& getSidebarItems() {
|
||||
return *s_sidebarItems;
|
||||
}
|
||||
|
||||
static AutoReset<std::vector<TitleBarButton>> s_titlebarButtons;
|
||||
const std::vector<TitleBarButton>& getTitlebarButtons() {
|
||||
return *s_titlebarButtons;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void registerMainMenuItem(const UnlocalizedString &unlocalizedName, u32 priority) {
|
||||
log::debug("Registered new main menu item: {}", unlocalizedName.get());
|
||||
|
||||
impl::getMainMenuItems().insert({ priority, { unlocalizedName } });
|
||||
impl::s_mainMenuItems->insert({ priority, { unlocalizedName } });
|
||||
}
|
||||
|
||||
void addMenuItem(const std::vector<UnlocalizedString> &unlocalizedMainMenuNames, u32 priority, const Shortcut &shortcut, const impl::MenuCallback &function, const impl::EnabledCallback& enabledCallback, const impl::SelectedCallback &selectedCallback, View *view) {
|
||||
@@ -732,7 +759,7 @@ namespace hex {
|
||||
if (coloredIcon.color == 0x00)
|
||||
coloredIcon.color = ImGuiCustomCol_ToolbarGray;
|
||||
|
||||
impl::getMenuItems().insert({
|
||||
impl::s_menuItems->insert({
|
||||
priority, impl::MenuItem { unlocalizedMainMenuNames, coloredIcon, std::make_unique<Shortcut>(shortcut), view, function, enabledCallback, selectedCallback, -1 }
|
||||
});
|
||||
|
||||
@@ -752,28 +779,28 @@ namespace hex {
|
||||
log::debug("Added new menu item sub menu to menu {} with priority {}", unlocalizedMainMenuNames[0].get(), priority);
|
||||
|
||||
unlocalizedMainMenuNames.emplace_back(impl::SubMenuValue);
|
||||
impl::getMenuItems().insert({
|
||||
impl::s_menuItems->insert({
|
||||
priority, impl::MenuItem { unlocalizedMainMenuNames, icon, std::make_unique<Shortcut>(), nullptr, function, enabledCallback, []{ return false; }, -1 }
|
||||
});
|
||||
}
|
||||
|
||||
void addMenuItemSeparator(std::vector<UnlocalizedString> unlocalizedMainMenuNames, u32 priority) {
|
||||
unlocalizedMainMenuNames.emplace_back(impl::SeparatorValue);
|
||||
impl::getMenuItems().insert({
|
||||
impl::s_menuItems->insert({
|
||||
priority, impl::MenuItem { unlocalizedMainMenuNames, "", std::make_unique<Shortcut>(), nullptr, []{}, []{ return true; }, []{ return false; }, -1 }
|
||||
});
|
||||
}
|
||||
|
||||
void addWelcomeScreenEntry(const impl::DrawCallback &function) {
|
||||
impl::getWelcomeScreenEntries().push_back(function);
|
||||
impl::s_welcomeScreenEntries->push_back(function);
|
||||
}
|
||||
|
||||
void addFooterItem(const impl::DrawCallback &function) {
|
||||
impl::getFooterItems().push_back(function);
|
||||
impl::s_footerItems->push_back(function);
|
||||
}
|
||||
|
||||
void addToolbarItem(const impl::DrawCallback &function) {
|
||||
impl::getToolbarItems().push_back(function);
|
||||
impl::s_toolbarItems->push_back(function);
|
||||
}
|
||||
|
||||
void addMenuItemToToolbar(const UnlocalizedString& unlocalizedName, ImGuiCustomCol color) {
|
||||
@@ -781,7 +808,7 @@ namespace hex {
|
||||
return a.second.toolbarIndex < b.second.toolbarIndex;
|
||||
})->second.toolbarIndex;
|
||||
|
||||
for (auto &[priority, menuItem] : impl::getMenuItems()) {
|
||||
for (auto &[priority, menuItem] : *impl::s_menuItems) {
|
||||
if (menuItem.unlocalizedNames.back() == unlocalizedName) {
|
||||
menuItem.toolbarIndex = maxIndex + 1;
|
||||
menuItem.icon.color = color;
|
||||
@@ -792,52 +819,11 @@ namespace hex {
|
||||
|
||||
|
||||
void addSidebarItem(const std::string &icon, const impl::DrawCallback &function, const impl::EnabledCallback &enabledCallback) {
|
||||
impl::getSidebarItems().push_back({ icon, function, enabledCallback });
|
||||
impl::s_sidebarItems->push_back({ icon, function, enabledCallback });
|
||||
}
|
||||
|
||||
void addTitleBarButton(const std::string &icon, const UnlocalizedString &unlocalizedTooltip, const impl::ClickCallback &function) {
|
||||
impl::getTitleBarButtons().push_back({ icon, unlocalizedTooltip, function });
|
||||
}
|
||||
|
||||
namespace impl {
|
||||
|
||||
std::multimap<u32, MainMenuItem> &getMainMenuItems() {
|
||||
static AutoReset<std::multimap<u32, MainMenuItem>> items;
|
||||
|
||||
return items;
|
||||
}
|
||||
std::multimap<u32, MenuItem> &getMenuItems() {
|
||||
static AutoReset<std::multimap<u32, MenuItem>> items;
|
||||
|
||||
return items;
|
||||
}
|
||||
|
||||
std::vector<DrawCallback> &getWelcomeScreenEntries() {
|
||||
static AutoReset<std::vector<DrawCallback>> entries;
|
||||
|
||||
return entries;
|
||||
}
|
||||
std::vector<DrawCallback> &getFooterItems() {
|
||||
static AutoReset<std::vector<DrawCallback>> items;
|
||||
|
||||
return items;
|
||||
}
|
||||
std::vector<DrawCallback> &getToolbarItems() {
|
||||
static AutoReset<std::vector<DrawCallback>> items;
|
||||
|
||||
return items;
|
||||
}
|
||||
std::vector<SidebarItem> &getSidebarItems() {
|
||||
static AutoReset<std::vector<SidebarItem>> items;
|
||||
|
||||
return items;
|
||||
}
|
||||
std::vector<TitleBarButton> &getTitleBarButtons() {
|
||||
static AutoReset<std::vector<TitleBarButton>> buttons;
|
||||
|
||||
return buttons;
|
||||
}
|
||||
|
||||
impl::s_titlebarButtons->push_back({ icon, unlocalizedTooltip, function });
|
||||
}
|
||||
|
||||
}
|
||||
@@ -850,25 +836,24 @@ namespace hex {
|
||||
(void)RequestCreateProvider::subscribe([expectedName = typeName, creationFunction](const std::string &name, bool skipLoadInterface, bool selectProvider, prv::Provider **provider) {
|
||||
if (name != expectedName) return;
|
||||
|
||||
prv::Provider *newProvider = creationFunction();
|
||||
auto newProvider = creationFunction();
|
||||
|
||||
ImHexApi::Provider::add(newProvider, skipLoadInterface, selectProvider);
|
||||
|
||||
if (provider != nullptr)
|
||||
*provider = newProvider;
|
||||
if (provider != nullptr) {
|
||||
*provider = newProvider.get();
|
||||
ImHexApi::Provider::add(std::move(newProvider), skipLoadInterface, selectProvider);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
std::vector<std::string> &getEntries() {
|
||||
static AutoReset<std::vector<std::string>> providerNames;
|
||||
|
||||
return providerNames;
|
||||
static AutoReset<std::vector<std::string>> s_providerNames;
|
||||
const std::vector<std::string>& getEntries() {
|
||||
return *s_providerNames;
|
||||
}
|
||||
|
||||
void addProviderName(const UnlocalizedString &unlocalizedName) {
|
||||
log::debug("Registered new provider: {}", unlocalizedName.get());
|
||||
|
||||
getEntries().push_back(unlocalizedName);
|
||||
s_providerNames->push_back(unlocalizedName);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -878,41 +863,39 @@ namespace hex {
|
||||
|
||||
namespace ContentRegistry::DataFormatter {
|
||||
|
||||
namespace impl {
|
||||
|
||||
static AutoReset<std::vector<Entry>> s_entries;
|
||||
const std::vector<Entry>& getEntries() {
|
||||
return *s_entries;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void add(const UnlocalizedString &unlocalizedName, const impl::Callback &callback) {
|
||||
log::debug("Registered new data formatter: {}", unlocalizedName.get());
|
||||
|
||||
impl::getEntries().push_back({ unlocalizedName, callback });
|
||||
}
|
||||
|
||||
namespace impl {
|
||||
|
||||
std::vector<Entry> &getEntries() {
|
||||
static AutoReset<std::vector<Entry>> entries;
|
||||
|
||||
return entries;
|
||||
}
|
||||
|
||||
impl::s_entries->push_back({ unlocalizedName, callback });
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
namespace ContentRegistry::FileHandler {
|
||||
|
||||
namespace impl {
|
||||
|
||||
static AutoReset<std::vector<Entry>> s_entries;
|
||||
const std::vector<Entry>& getEntries() {
|
||||
return *s_entries;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void add(const std::vector<std::string> &extensions, const impl::Callback &callback) {
|
||||
for (const auto &extension : extensions)
|
||||
log::debug("Registered new data handler for extensions: {}", extension);
|
||||
|
||||
impl::getEntries().push_back({ extensions, callback });
|
||||
}
|
||||
|
||||
namespace impl {
|
||||
|
||||
std::vector<Entry> &getEntries() {
|
||||
static AutoReset<std::vector<Entry>> entries;
|
||||
|
||||
return entries;
|
||||
}
|
||||
|
||||
impl::s_entries->push_back({ extensions, callback });
|
||||
}
|
||||
|
||||
}
|
||||
@@ -985,23 +968,21 @@ namespace hex {
|
||||
|
||||
namespace impl {
|
||||
|
||||
static AutoReset<std::vector<std::shared_ptr<DataVisualizer>>> s_visualizers;
|
||||
const std::vector<std::shared_ptr<DataVisualizer>>& getVisualizers() {
|
||||
return *s_visualizers;
|
||||
}
|
||||
|
||||
static AutoReset<std::vector<std::shared_ptr<MiniMapVisualizer>>> s_miniMapVisualizers;
|
||||
const std::vector<std::shared_ptr<MiniMapVisualizer>>& getMiniMapVisualizers() {
|
||||
return *s_miniMapVisualizers;
|
||||
}
|
||||
|
||||
void addDataVisualizer(std::shared_ptr<DataVisualizer> &&visualizer) {
|
||||
getVisualizers().emplace_back(std::move(visualizer));
|
||||
s_visualizers->emplace_back(std::move(visualizer));
|
||||
|
||||
}
|
||||
|
||||
std::vector<std::shared_ptr<DataVisualizer>> &getVisualizers() {
|
||||
static AutoReset<std::vector<std::shared_ptr<DataVisualizer>>> visualizers;
|
||||
|
||||
return visualizers;
|
||||
}
|
||||
|
||||
std::vector<std::shared_ptr<MiniMapVisualizer>> &getMiniMapVisualizers() {
|
||||
static AutoReset<std::vector<std::shared_ptr<MiniMapVisualizer>>> visualizers;
|
||||
|
||||
return visualizers;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
std::shared_ptr<DataVisualizer> getVisualizerByName(const UnlocalizedString &unlocalizedName) {
|
||||
@@ -1014,7 +995,7 @@ namespace hex {
|
||||
}
|
||||
|
||||
void addMiniMapVisualizer(UnlocalizedString unlocalizedName, MiniMapVisualizer::Callback callback) {
|
||||
impl::getMiniMapVisualizers().emplace_back(std::make_shared<MiniMapVisualizer>(std::move(unlocalizedName), std::move(callback)));
|
||||
impl::s_miniMapVisualizers->emplace_back(std::make_shared<MiniMapVisualizer>(std::move(unlocalizedName), std::move(callback)));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1023,14 +1004,13 @@ namespace hex {
|
||||
|
||||
namespace impl {
|
||||
|
||||
std::vector<std::unique_ptr<Algorithm>>& getAlgorithms() {
|
||||
static AutoReset<std::vector<std::unique_ptr<Algorithm>>> algorithms;
|
||||
|
||||
return algorithms;
|
||||
static AutoReset<std::vector<std::unique_ptr<Algorithm>>> s_algorithms;
|
||||
const std::vector<std::unique_ptr<Algorithm>>& getAlgorithms() {
|
||||
return *s_algorithms;
|
||||
}
|
||||
|
||||
void addAlgorithm(std::unique_ptr<Algorithm> &&hash) {
|
||||
getAlgorithms().emplace_back(std::move(hash));
|
||||
s_algorithms->emplace_back(std::move(hash));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1041,14 +1021,13 @@ namespace hex {
|
||||
|
||||
namespace impl {
|
||||
|
||||
std::vector<std::unique_ptr<Hash>> &getHashes() {
|
||||
static AutoReset<std::vector<std::unique_ptr<Hash>>> hashes;
|
||||
|
||||
return hashes;
|
||||
static AutoReset<std::vector<std::unique_ptr<Hash>>> s_hashes;
|
||||
const std::vector<std::unique_ptr<Hash>>& getHashes() {
|
||||
return *s_hashes;
|
||||
}
|
||||
|
||||
void add(std::unique_ptr<Hash> &&hash) {
|
||||
getHashes().emplace_back(std::move(hash));
|
||||
s_hashes->emplace_back(std::move(hash));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1073,11 +1052,11 @@ namespace hex {
|
||||
Service& operator=(const Service&) = delete;
|
||||
Service& operator=(Service &&) = default;
|
||||
|
||||
[[nodiscard]] const std::string &getName() const {
|
||||
[[nodiscard]] const std::string& getName() const {
|
||||
return m_name;
|
||||
}
|
||||
|
||||
[[nodiscard]] const std::jthread &getThread() const {
|
||||
[[nodiscard]] const std::jthread& getThread() const {
|
||||
return m_thread;
|
||||
}
|
||||
|
||||
@@ -1086,15 +1065,13 @@ namespace hex {
|
||||
std::jthread m_thread;
|
||||
};
|
||||
|
||||
std::vector<Service> &getServices() {
|
||||
static AutoReset<std::vector<Service>> services;
|
||||
|
||||
return services;
|
||||
static AutoReset<std::vector<Service>> s_services;
|
||||
const std::vector<Service>& getServices() {
|
||||
return *s_services;
|
||||
}
|
||||
|
||||
void stopServices() {
|
||||
auto &services = getServices();
|
||||
services.clear();
|
||||
s_services->clear();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1102,7 +1079,7 @@ namespace hex {
|
||||
void registerService(const UnlocalizedString &unlocalizedName, const impl::Callback &callback) {
|
||||
log::debug("Registered new background service: {}", unlocalizedName.get());
|
||||
|
||||
impl::getServices().emplace_back(
|
||||
impl::s_services->emplace_back(
|
||||
unlocalizedName,
|
||||
std::jthread([callback = auto(callback)](const std::stop_token &stopToken){
|
||||
while (!stopToken.stop_requested()) {
|
||||
@@ -1119,10 +1096,9 @@ namespace hex {
|
||||
|
||||
namespace impl {
|
||||
|
||||
std::map<std::string, NetworkCallback> &getNetworkEndpoints() {
|
||||
static AutoReset<std::map<std::string, NetworkCallback>> endpoints;
|
||||
|
||||
return endpoints;
|
||||
static AutoReset<std::map<std::string, NetworkCallback>> s_endpoints;
|
||||
const std::map<std::string, NetworkCallback>& getNetworkEndpoints() {
|
||||
return *s_endpoints;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1130,7 +1106,7 @@ namespace hex {
|
||||
void registerNetworkEndpoint(const std::string &endpoint, const impl::NetworkCallback &callback) {
|
||||
log::debug("Registered new network endpoint: {}", endpoint);
|
||||
|
||||
impl::getNetworkEndpoints().insert({ endpoint, callback });
|
||||
impl::s_endpoints->insert({ endpoint, callback });
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1139,16 +1115,15 @@ namespace hex {
|
||||
|
||||
namespace impl {
|
||||
|
||||
std::map<std::string, Experiment> &getExperiments() {
|
||||
static AutoReset<std::map<std::string, Experiment>> experiments;
|
||||
|
||||
return experiments;
|
||||
static AutoReset<std::map<std::string, Experiment>> s_experiments;
|
||||
const std::map<std::string, Experiment>& getExperiments() {
|
||||
return *s_experiments;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void addExperiment(const std::string &experimentName, const UnlocalizedString &unlocalizedName, const UnlocalizedString &unlocalizedDescription) {
|
||||
auto &experiments = impl::getExperiments();
|
||||
auto &experiments = *impl::s_experiments;
|
||||
|
||||
if (experiments.contains(experimentName)) {
|
||||
log::error("Experiment with name '{}' already exists!", experimentName);
|
||||
@@ -1163,7 +1138,7 @@ namespace hex {
|
||||
}
|
||||
|
||||
void enableExperiement(const std::string &experimentName, bool enabled) {
|
||||
auto &experiments = impl::getExperiments();
|
||||
auto &experiments = *impl::s_experiments;
|
||||
|
||||
if (!experiments.contains(experimentName)) {
|
||||
log::error("Experiment with name '{}' does not exist!", experimentName);
|
||||
@@ -1174,7 +1149,7 @@ namespace hex {
|
||||
}
|
||||
|
||||
[[nodiscard]] bool isExperimentEnabled(const std::string &experimentName) {
|
||||
auto &experiments = impl::getExperiments();
|
||||
auto &experiments = *impl::s_experiments;
|
||||
|
||||
if (!experiments.contains(experimentName)) {
|
||||
log::error("Experiment with name '{}' does not exist!", experimentName);
|
||||
@@ -1190,16 +1165,15 @@ namespace hex {
|
||||
|
||||
namespace impl {
|
||||
|
||||
std::vector<ReportGenerator> &getGenerators() {
|
||||
static AutoReset<std::vector<ReportGenerator>> generators;
|
||||
|
||||
return generators;
|
||||
static AutoReset<std::vector<ReportGenerator>> s_generators;
|
||||
const std::vector<ReportGenerator>& getGenerators() {
|
||||
return *s_generators;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void addReportProvider(impl::Callback callback) {
|
||||
impl::getGenerators().push_back(impl::ReportGenerator { std::move(callback ) });
|
||||
impl::s_generators->push_back(impl::ReportGenerator { std::move(callback ) });
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -37,34 +37,34 @@ namespace hex {
|
||||
|
||||
namespace impl {
|
||||
|
||||
std::map<u32, Highlighting> &getBackgroundHighlights() {
|
||||
static AutoReset<std::map<u32, Highlighting>> backgroundHighlights;
|
||||
return backgroundHighlights;
|
||||
static AutoReset<std::map<u32, Highlighting>> s_backgroundHighlights;
|
||||
const std::map<u32, Highlighting>& getBackgroundHighlights() {
|
||||
return *s_backgroundHighlights;
|
||||
}
|
||||
|
||||
std::map<u32, HighlightingFunction> &getBackgroundHighlightingFunctions() {
|
||||
static AutoReset<std::map<u32, HighlightingFunction>> backgroundHighlightingFunctions;
|
||||
return backgroundHighlightingFunctions;
|
||||
static AutoReset<std::map<u32, HighlightingFunction>> s_backgroundHighlightingFunctions;
|
||||
const std::map<u32, HighlightingFunction>& getBackgroundHighlightingFunctions() {
|
||||
return *s_backgroundHighlightingFunctions;
|
||||
}
|
||||
|
||||
std::map<u32, Highlighting> &getForegroundHighlights() {
|
||||
static AutoReset<std::map<u32, Highlighting>> foregroundHighlights;
|
||||
return foregroundHighlights;
|
||||
static AutoReset<std::map<u32, Highlighting>> s_foregroundHighlights;
|
||||
const std::map<u32, Highlighting>& getForegroundHighlights() {
|
||||
return *s_foregroundHighlights;
|
||||
}
|
||||
|
||||
std::map<u32, HighlightingFunction> &getForegroundHighlightingFunctions() {
|
||||
static AutoReset<std::map<u32, HighlightingFunction>> foregroundHighlightingFunctions;
|
||||
return foregroundHighlightingFunctions;
|
||||
static AutoReset<std::map<u32, HighlightingFunction>> s_foregroundHighlightingFunctions;
|
||||
const std::map<u32, HighlightingFunction>& getForegroundHighlightingFunctions() {
|
||||
return *s_foregroundHighlightingFunctions;
|
||||
}
|
||||
|
||||
std::map<u32, Tooltip> &getTooltips() {
|
||||
static AutoReset<std::map<u32, Tooltip>> tooltips;
|
||||
return tooltips;
|
||||
static AutoReset<std::map<u32, Tooltip>> s_tooltips;
|
||||
const std::map<u32, Tooltip>& getTooltips() {
|
||||
return *s_tooltips;
|
||||
}
|
||||
|
||||
std::map<u32, TooltipFunction> &getTooltipFunctions() {
|
||||
static AutoReset<std::map<u32, TooltipFunction>> tooltipFunctions;
|
||||
return tooltipFunctions;
|
||||
static AutoReset<std::map<u32, TooltipFunction>> s_tooltipFunctions;
|
||||
const std::map<u32, TooltipFunction>& getTooltipFunctions() {
|
||||
return *s_tooltipFunctions;
|
||||
}
|
||||
|
||||
static AutoReset<std::optional<ProviderRegion>> s_currentSelection;
|
||||
@@ -79,8 +79,8 @@ namespace hex {
|
||||
|
||||
id++;
|
||||
|
||||
impl::getBackgroundHighlights().insert({
|
||||
id, Highlighting {region, color}
|
||||
impl::s_backgroundHighlights->insert({
|
||||
id, Highlighting { region, color }
|
||||
});
|
||||
|
||||
EventHighlightingChanged::post();
|
||||
@@ -89,7 +89,7 @@ namespace hex {
|
||||
}
|
||||
|
||||
void removeBackgroundHighlight(u32 id) {
|
||||
impl::getBackgroundHighlights().erase(id);
|
||||
impl::s_backgroundHighlights->erase(id);
|
||||
|
||||
EventHighlightingChanged::post();
|
||||
}
|
||||
@@ -99,7 +99,7 @@ namespace hex {
|
||||
|
||||
id++;
|
||||
|
||||
impl::getBackgroundHighlightingFunctions().insert({ id, function });
|
||||
impl::s_backgroundHighlightingFunctions->insert({ id, function });
|
||||
|
||||
EventHighlightingChanged::post();
|
||||
|
||||
@@ -107,7 +107,7 @@ namespace hex {
|
||||
}
|
||||
|
||||
void removeBackgroundHighlightingProvider(u32 id) {
|
||||
impl::getBackgroundHighlightingFunctions().erase(id);
|
||||
impl::s_backgroundHighlightingFunctions->erase(id);
|
||||
|
||||
EventHighlightingChanged::post();
|
||||
}
|
||||
@@ -117,8 +117,8 @@ namespace hex {
|
||||
|
||||
id++;
|
||||
|
||||
impl::getForegroundHighlights().insert({
|
||||
id, Highlighting {region, color}
|
||||
impl::s_foregroundHighlights->insert({
|
||||
id, Highlighting { region, color }
|
||||
});
|
||||
|
||||
EventHighlightingChanged::post();
|
||||
@@ -127,7 +127,7 @@ namespace hex {
|
||||
}
|
||||
|
||||
void removeForegroundHighlight(u32 id) {
|
||||
impl::getForegroundHighlights().erase(id);
|
||||
impl::s_foregroundHighlights->erase(id);
|
||||
|
||||
EventHighlightingChanged::post();
|
||||
}
|
||||
@@ -137,7 +137,7 @@ namespace hex {
|
||||
|
||||
id++;
|
||||
|
||||
impl::getForegroundHighlightingFunctions().insert({ id, function });
|
||||
impl::s_foregroundHighlightingFunctions->insert({ id, function });
|
||||
|
||||
EventHighlightingChanged::post();
|
||||
|
||||
@@ -145,7 +145,7 @@ namespace hex {
|
||||
}
|
||||
|
||||
void removeForegroundHighlightingProvider(u32 id) {
|
||||
impl::getForegroundHighlightingFunctions().erase(id);
|
||||
impl::s_foregroundHighlightingFunctions->erase(id);
|
||||
|
||||
EventHighlightingChanged::post();
|
||||
}
|
||||
@@ -153,25 +153,25 @@ namespace hex {
|
||||
static u32 tooltipId = 0;
|
||||
u32 addTooltip(Region region, std::string value, color_t color) {
|
||||
tooltipId++;
|
||||
impl::getTooltips().insert({ tooltipId, { region, std::move(value), color } });
|
||||
impl::s_tooltips->insert({ tooltipId, { region, std::move(value), color } });
|
||||
|
||||
return tooltipId;
|
||||
}
|
||||
|
||||
void removeTooltip(u32 id) {
|
||||
impl::getTooltips().erase(id);
|
||||
impl::s_tooltips->erase(id);
|
||||
}
|
||||
|
||||
static u32 tooltipFunctionId;
|
||||
u32 addTooltipProvider(TooltipFunction function) {
|
||||
tooltipFunctionId++;
|
||||
impl::getTooltipFunctions().insert({ tooltipFunctionId, std::move(function) });
|
||||
impl::s_tooltipFunctions->insert({ tooltipFunctionId, std::move(function) });
|
||||
|
||||
return tooltipFunctionId;
|
||||
}
|
||||
|
||||
void removeTooltipProvider(u32 id) {
|
||||
impl::getTooltipFunctions().erase(id);
|
||||
impl::s_tooltipFunctions->erase(id);
|
||||
}
|
||||
|
||||
bool isSelectionValid() {
|
||||
@@ -228,7 +228,7 @@ namespace hex {
|
||||
namespace ImHexApi::Provider {
|
||||
|
||||
static i64 s_currentProvider = -1;
|
||||
static AutoReset<std::vector<prv::Provider *>> s_providers;
|
||||
static AutoReset<std::vector<std::unique_ptr<prv::Provider>>> s_providers;
|
||||
|
||||
namespace impl {
|
||||
|
||||
@@ -247,11 +247,16 @@ namespace hex {
|
||||
if (!ImHexApi::Provider::isValid())
|
||||
return nullptr;
|
||||
|
||||
return (*s_providers)[s_currentProvider];
|
||||
return (*s_providers)[s_currentProvider].get();
|
||||
}
|
||||
|
||||
const std::vector<prv::Provider *> &getProviders() {
|
||||
return s_providers;
|
||||
std::vector<prv::Provider*> getProviders() {
|
||||
std::vector<prv::Provider*> result;
|
||||
result.reserve(s_providers->size());
|
||||
for (const auto &provider : *s_providers)
|
||||
result.push_back(provider.get());
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void setCurrentProvider(u32 index) {
|
||||
@@ -288,15 +293,15 @@ namespace hex {
|
||||
});
|
||||
}
|
||||
|
||||
void add(prv::Provider *provider, bool skipLoadInterface, bool select) {
|
||||
void add(std::unique_ptr<prv::Provider> &&provider, bool skipLoadInterface, bool select) {
|
||||
if (TaskManager::getRunningTaskCount() > 0)
|
||||
return;
|
||||
|
||||
if (skipLoadInterface)
|
||||
provider->skipLoadInterface();
|
||||
|
||||
s_providers->push_back(provider);
|
||||
EventProviderCreated::post(provider);
|
||||
EventProviderCreated::post(provider.get());
|
||||
s_providers->emplace_back(std::move(provider));
|
||||
|
||||
if (select || s_providers->size() == 1)
|
||||
setCurrentProvider(s_providers->size() - 1);
|
||||
@@ -318,7 +323,10 @@ namespace hex {
|
||||
return;
|
||||
}
|
||||
|
||||
const auto it = std::ranges::find(*s_providers, provider);
|
||||
const auto it = std::ranges::find_if(*s_providers, [provider](const auto &p) {
|
||||
return p.get() == provider;
|
||||
});
|
||||
|
||||
if (it == s_providers->end())
|
||||
return;
|
||||
|
||||
@@ -328,7 +336,7 @@ namespace hex {
|
||||
setCurrentProvider(0);
|
||||
|
||||
if (s_providers->size() > 1)
|
||||
EventProviderChanged::post(s_providers->at(0), s_providers->at(1));
|
||||
EventProviderChanged::post(s_providers->at(0).get(), s_providers->at(1).get());
|
||||
}
|
||||
else if (std::distance(s_providers->begin(), it) == s_currentProvider) {
|
||||
// If the current provider is being closed, select the one that's before it
|
||||
@@ -337,7 +345,9 @@ namespace hex {
|
||||
else {
|
||||
// If any other provider is being closed, find the current provider in the list again and select it again
|
||||
const auto currentProvider = get();
|
||||
const auto currentIt = std::ranges::find(*s_providers, currentProvider);
|
||||
const auto currentIt = std::ranges::find_if(*s_providers, [currentProvider](const auto &p) {
|
||||
return p.get() == currentProvider;
|
||||
});
|
||||
|
||||
if (currentIt != s_providers->end()) {
|
||||
auto newIndex = std::distance(s_providers->begin(), currentIt);
|
||||
@@ -353,21 +363,20 @@ namespace hex {
|
||||
}
|
||||
}
|
||||
|
||||
s_providers->erase(it);
|
||||
if (s_currentProvider >= i64(s_providers->size()))
|
||||
setCurrentProvider(0);
|
||||
|
||||
if (s_providers->empty())
|
||||
EventProviderChanged::post(provider, nullptr);
|
||||
|
||||
provider->close();
|
||||
EventProviderClosed::post(provider);
|
||||
RequestUpdateWindowTitle::post();
|
||||
|
||||
TaskManager::runWhenTasksFinished([provider] {
|
||||
TaskManager::runWhenTasksFinished([it, provider] {
|
||||
EventProviderDeleted::post(provider);
|
||||
std::erase(impl::s_closingProviders, provider);
|
||||
delete provider;
|
||||
|
||||
s_providers->erase(it);
|
||||
if (s_currentProvider >= i64(s_providers->size()))
|
||||
setCurrentProvider(0);
|
||||
|
||||
if (s_providers->empty())
|
||||
EventProviderChanged::post(provider, nullptr);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -449,11 +458,12 @@ namespace hex {
|
||||
s_portableVersion = enabled;
|
||||
}
|
||||
|
||||
static AutoReset<std::map<std::string, std::string>> s_initArguments;
|
||||
void addInitArgument(const std::string &key, const std::string &value) {
|
||||
static std::mutex initArgumentsMutex;
|
||||
std::scoped_lock lock(initArgumentsMutex);
|
||||
|
||||
getInitArguments()[key] = value;
|
||||
(*s_initArguments)[key] = value;
|
||||
}
|
||||
|
||||
static double s_lastFrameTime;
|
||||
@@ -538,12 +548,18 @@ namespace hex {
|
||||
return impl::s_initialWindowProperties;
|
||||
}
|
||||
|
||||
std::map<std::string, std::string> &getInitArguments() {
|
||||
static AutoReset<std::map<std::string, std::string>> initArgs;
|
||||
|
||||
return initArgs;
|
||||
const std::map<std::string, std::string>& getInitArguments() {
|
||||
return *impl::s_initArguments;
|
||||
}
|
||||
|
||||
std::string getInitArgument(const std::string &key) {
|
||||
if (impl::s_initArguments->contains(key))
|
||||
return impl::s_initArguments->at(key);
|
||||
else
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
|
||||
static bool s_systemThemeDetection;
|
||||
void enableSystemThemeDetection(bool enabled) {
|
||||
@@ -557,13 +573,13 @@ namespace hex {
|
||||
}
|
||||
|
||||
|
||||
std::vector<std::fs::path> &getAdditionalFolderPaths() {
|
||||
static AutoReset<std::vector<std::fs::path>> additionalFolderPaths;
|
||||
return additionalFolderPaths;
|
||||
static AutoReset<std::vector<std::fs::path>> s_additionalFolderPaths;
|
||||
const std::vector<std::fs::path>& getAdditionalFolderPaths() {
|
||||
return *s_additionalFolderPaths;
|
||||
}
|
||||
|
||||
void setAdditionalFolderPaths(const std::vector<std::fs::path> &paths) {
|
||||
getAdditionalFolderPaths() = paths;
|
||||
s_additionalFolderPaths = paths;
|
||||
}
|
||||
|
||||
|
||||
@@ -742,14 +758,13 @@ namespace hex {
|
||||
|
||||
namespace impl {
|
||||
|
||||
std::map<std::string, MessagingHandler> &getHandlers() {
|
||||
static AutoReset<std::map<std::string, MessagingHandler>> handlers;
|
||||
|
||||
return handlers;
|
||||
static AutoReset<std::map<std::string, MessagingHandler>> s_handlers;
|
||||
const std::map<std::string, MessagingHandler>& getHandlers() {
|
||||
return *s_handlers;
|
||||
}
|
||||
|
||||
void runHandler(const std::string &eventName, const std::vector<u8> &args) {
|
||||
const auto& handlers = impl::getHandlers();
|
||||
const auto& handlers = getHandlers();
|
||||
const auto matchHandler = handlers.find(eventName);
|
||||
|
||||
if (matchHandler == handlers.end()) {
|
||||
@@ -765,7 +780,7 @@ namespace hex {
|
||||
void registerHandler(const std::string &eventName, const impl::MessagingHandler &handler) {
|
||||
log::debug("Registered new forward event handler: {}", eventName);
|
||||
|
||||
impl::getHandlers().insert({ eventName, handler });
|
||||
impl::s_handlers->insert({ eventName, handler });
|
||||
}
|
||||
|
||||
}
|
||||
@@ -774,10 +789,9 @@ namespace hex {
|
||||
|
||||
namespace impl {
|
||||
|
||||
std::vector<Font>& getFonts() {
|
||||
static AutoReset<std::vector<Font>> fonts;
|
||||
|
||||
return fonts;
|
||||
static AutoReset<std::vector<Font>> s_fonts;
|
||||
const std::vector<Font>& getFonts() {
|
||||
return *s_fonts;
|
||||
}
|
||||
|
||||
static AutoReset<std::fs::path> s_customFontPath;
|
||||
@@ -845,7 +859,7 @@ namespace hex {
|
||||
return;
|
||||
}
|
||||
|
||||
impl::getFonts().emplace_back(Font {
|
||||
impl::s_fonts->emplace_back(Font {
|
||||
wolv::util::toUTF8String(path.filename()),
|
||||
fontFile.readVector(),
|
||||
glyphRanges,
|
||||
@@ -855,7 +869,7 @@ namespace hex {
|
||||
}
|
||||
|
||||
void loadFont(const std::string &name, const std::span<const u8> &data, const std::vector<GlyphRange> &glyphRanges, Offset offset, u32 flags) {
|
||||
impl::getFonts().emplace_back(Font {
|
||||
impl::s_fonts->emplace_back(Font {
|
||||
name,
|
||||
{ data.begin(), data.end() },
|
||||
glyphRanges,
|
||||
@@ -864,7 +878,7 @@ namespace hex {
|
||||
});
|
||||
}
|
||||
|
||||
std::fs::path &getCustomFontPath() {
|
||||
const std::fs::path& getCustomFontPath() {
|
||||
return impl::s_customFontPath;
|
||||
}
|
||||
|
||||
|
||||
@@ -17,6 +17,9 @@ namespace hex {
|
||||
AutoReset<std::optional<std::string>> s_layoutStringToLoad;
|
||||
AutoReset<std::vector<LayoutManager::Layout>> s_layouts;
|
||||
|
||||
AutoReset<std::vector<LayoutManager::LoadCallback>> s_loadCallbacks;
|
||||
AutoReset<std::vector<LayoutManager::StoreCallback>> s_storeCallbacks;
|
||||
|
||||
bool s_layoutLocked = false;
|
||||
|
||||
}
|
||||
@@ -130,4 +133,24 @@ namespace hex {
|
||||
s_layoutLocked = locked;
|
||||
}
|
||||
|
||||
void LayoutManager::registerLoadCallback(const LoadCallback &callback) {
|
||||
s_loadCallbacks->push_back(callback);
|
||||
}
|
||||
|
||||
void LayoutManager::registerStoreCallback(const StoreCallback &callback) {
|
||||
s_storeCallbacks->push_back(callback);
|
||||
}
|
||||
|
||||
void LayoutManager::onLoad(std::string_view line) {
|
||||
for (const auto &callback : *s_loadCallbacks)
|
||||
callback(line);
|
||||
}
|
||||
|
||||
void LayoutManager::onStore(ImGuiTextBuffer *buffer) {
|
||||
for (const auto &callback : *s_storeCallbacks)
|
||||
callback(buffer);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -49,12 +49,12 @@ namespace hex {
|
||||
|
||||
s_currStrings->clear();
|
||||
|
||||
for (auto &definition : definitions[language])
|
||||
for (const auto &definition : definitions.at(language))
|
||||
s_currStrings->insert(definition.getEntries().begin(), definition.getEntries().end());
|
||||
|
||||
const auto& fallbackLanguage = getFallbackLanguage();
|
||||
if (language != fallbackLanguage) {
|
||||
for (auto &definition : definitions[fallbackLanguage])
|
||||
if (language != fallbackLanguage && definitions.contains(fallbackLanguage)) {
|
||||
for (const auto &definition : definitions.at(fallbackLanguage))
|
||||
s_currStrings->insert(definition.getEntries().begin(), definition.getEntries().end());
|
||||
}
|
||||
|
||||
@@ -70,7 +70,7 @@ namespace hex {
|
||||
return "";
|
||||
|
||||
std::string localizedString;
|
||||
for (const auto &definition : languageDefinitions[language]) {
|
||||
for (const auto &definition : languageDefinitions.at(language)) {
|
||||
if (definition.getEntries().contains(unlocalizedString)) {
|
||||
localizedString = definition.getEntries().at(unlocalizedString);
|
||||
break;
|
||||
|
||||
@@ -228,9 +228,6 @@ namespace hex {
|
||||
return m_addedManually;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void *Plugin::getPluginFunction(const std::string &symbol) const {
|
||||
#if defined(OS_WINDOWS)
|
||||
return reinterpret_cast<void *>(GetProcAddress(HMODULE(m_handle), symbol.c_str()));
|
||||
@@ -239,8 +236,11 @@ namespace hex {
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
AutoReset<std::vector<std::fs::path>> PluginManager::s_pluginPaths, PluginManager::s_pluginLoadPaths;
|
||||
|
||||
void PluginManager::addLoadPath(const std::fs::path& path) {
|
||||
getPluginLoadPaths().emplace_back(path);
|
||||
s_pluginLoadPaths->emplace_back(path);
|
||||
}
|
||||
|
||||
|
||||
@@ -257,13 +257,13 @@ namespace hex {
|
||||
if (!wolv::io::fs::exists(pluginFolder))
|
||||
return false;
|
||||
|
||||
getPluginPaths().push_back(pluginFolder);
|
||||
s_pluginPaths->push_back(pluginFolder);
|
||||
|
||||
// Load library plugins first
|
||||
for (auto &pluginPath : std::fs::directory_iterator(pluginFolder)) {
|
||||
if (pluginPath.is_regular_file() && pluginPath.path().extension() == ".hexpluglib") {
|
||||
if (!isPluginLoaded(pluginPath.path())) {
|
||||
getPlugins().emplace_back(pluginPath.path());
|
||||
getPluginsMutable().emplace_back(pluginPath.path());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -272,12 +272,12 @@ namespace hex {
|
||||
for (auto &pluginPath : std::fs::directory_iterator(pluginFolder)) {
|
||||
if (pluginPath.is_regular_file() && pluginPath.path().extension() == ".hexplug") {
|
||||
if (!isPluginLoaded(pluginPath.path())) {
|
||||
getPlugins().emplace_back(pluginPath.path());
|
||||
getPluginsMutable().emplace_back(pluginPath.path());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::erase_if(getPlugins(), [](const Plugin &plugin) {
|
||||
std::erase_if(getPluginsMutable(), [](const Plugin &plugin) {
|
||||
return !plugin.isValid();
|
||||
});
|
||||
|
||||
@@ -292,10 +292,10 @@ namespace hex {
|
||||
}
|
||||
|
||||
void PluginManager::unload() {
|
||||
getPluginPaths().clear();
|
||||
s_pluginPaths->clear();
|
||||
|
||||
// Unload plugins in reverse order
|
||||
auto &plugins = getPlugins();
|
||||
auto &plugins = getPluginsMutable();
|
||||
|
||||
std::list<Plugin> savedPlugins;
|
||||
while (!plugins.empty()) {
|
||||
@@ -304,29 +304,29 @@ namespace hex {
|
||||
plugins.pop_back();
|
||||
}
|
||||
|
||||
getPlugins() = std::move(savedPlugins);
|
||||
getPluginsMutable() = std::move(savedPlugins);
|
||||
}
|
||||
|
||||
void PluginManager::addPlugin(const std::string &name, hex::PluginFunctions functions) {
|
||||
getPlugins().emplace_back(name, functions);
|
||||
getPluginsMutable().emplace_back(name, functions);
|
||||
}
|
||||
|
||||
std::list<Plugin> &PluginManager::getPlugins() {
|
||||
static std::list<Plugin> plugins;
|
||||
const std::list<Plugin>& PluginManager::getPlugins() {
|
||||
return getPluginsMutable();
|
||||
}
|
||||
|
||||
|
||||
std::list<Plugin>& PluginManager::getPluginsMutable() {
|
||||
static std::list<Plugin> plugins;
|
||||
return plugins;
|
||||
}
|
||||
|
||||
std::vector<std::fs::path> &PluginManager::getPluginPaths() {
|
||||
static AutoReset<std::vector<std::fs::path>> pluginPaths;
|
||||
|
||||
return pluginPaths;
|
||||
const std::vector<std::fs::path>& PluginManager::getPluginPaths() {
|
||||
return s_pluginPaths;
|
||||
}
|
||||
|
||||
std::vector<std::fs::path> &PluginManager::getPluginLoadPaths() {
|
||||
static AutoReset<std::vector<std::fs::path>> pluginPaths;
|
||||
|
||||
return pluginPaths;
|
||||
const std::vector<std::fs::path>& PluginManager::getPluginLoadPaths() {
|
||||
return s_pluginLoadPaths;
|
||||
}
|
||||
|
||||
bool PluginManager::isPluginLoaded(const std::fs::path &path) {
|
||||
|
||||
@@ -51,11 +51,19 @@ namespace hex {
|
||||
s_currProjectPath = path;
|
||||
}
|
||||
|
||||
std::vector<ProjectFile::Handler> &ProjectFile::getHandlers() {
|
||||
void ProjectFile::registerHandler(const Handler &handler) {
|
||||
s_handlers->push_back(handler);
|
||||
}
|
||||
|
||||
void ProjectFile::registerPerProviderHandler(const ProviderHandler &handler) {
|
||||
s_providerHandlers->push_back(handler);
|
||||
}
|
||||
|
||||
const std::vector<ProjectFile::Handler>& ProjectFile::getHandlers() {
|
||||
return s_handlers;
|
||||
}
|
||||
|
||||
std::vector<ProjectFile::ProviderHandler> &ProjectFile::getProviderHandlers() {
|
||||
const std::vector<ProjectFile::ProviderHandler>& ProjectFile::getProviderHandlers() {
|
||||
return s_providerHandlers;
|
||||
}
|
||||
|
||||
|
||||
@@ -335,7 +335,7 @@ namespace hex {
|
||||
}
|
||||
|
||||
|
||||
std::list<std::shared_ptr<Task>> &TaskManager::getRunningTasks() {
|
||||
const std::list<std::shared_ptr<Task>>& TaskManager::getRunningTasks() {
|
||||
return s_tasks;
|
||||
}
|
||||
|
||||
|
||||
@@ -219,11 +219,11 @@ namespace hex {
|
||||
}
|
||||
|
||||
|
||||
std::map<std::string, ThemeManager::ThemeHandler> &ThemeManager::getThemeHandlers() {
|
||||
const std::map<std::string, ThemeManager::ThemeHandler> &ThemeManager::getThemeHandlers() {
|
||||
return s_themeHandlers;
|
||||
}
|
||||
|
||||
std::map<std::string, ThemeManager::StyleHandler> &ThemeManager::getStyleHandlers() {
|
||||
const std::map<std::string, ThemeManager::StyleHandler> &ThemeManager::getStyleHandlers() {
|
||||
return s_styleHandlers;
|
||||
}
|
||||
|
||||
|
||||
@@ -107,17 +107,17 @@ namespace hex::subcommands {
|
||||
void registerSubCommand(const std::string &cmdName, const ForwardCommandHandler &handler) {
|
||||
log::debug("Registered new forward command handler: {}", cmdName);
|
||||
|
||||
ImHexApi::Messaging::impl::getHandlers().insert({ hex::format("command/{}", cmdName), [handler](const std::vector<u8> &eventData){
|
||||
std::string str(reinterpret_cast<const char *>(eventData.data()), eventData.size());
|
||||
ImHexApi::Messaging::registerHandler(hex::format("command/{}", cmdName), [handler](const std::vector<u8> &eventData){
|
||||
std::string string(reinterpret_cast<const char *>(eventData.data()), eventData.size());
|
||||
|
||||
std::vector<std::string> args;
|
||||
|
||||
for (const auto &arg_view : std::views::split(str, '\0')) {
|
||||
for (const auto &arg_view : std::views::split(string, char(0x00))) {
|
||||
std::string arg(arg_view.data(), arg_view.size());
|
||||
args.push_back(arg);
|
||||
}
|
||||
|
||||
handler(args);
|
||||
}});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,10 +17,13 @@ add_executable(main ${APPLICATION_TYPE}
|
||||
source/messaging/win.cpp
|
||||
source/messaging/web.cpp
|
||||
|
||||
|
||||
source/init/splash_window.cpp
|
||||
source/init/tasks.cpp
|
||||
|
||||
source/init/run/common.cpp
|
||||
source/init/run/native.cpp
|
||||
source/init/run/web.cpp
|
||||
|
||||
${IMHEX_ICON}
|
||||
)
|
||||
|
||||
|
||||
12
main/gui/include/init/run.hpp
Normal file
12
main/gui/include/init/run.hpp
Normal file
@@ -0,0 +1,12 @@
|
||||
#pragma once
|
||||
|
||||
#include <init/splash_window.hpp>
|
||||
|
||||
namespace hex::init {
|
||||
|
||||
void handleFileOpenRequest();
|
||||
|
||||
std::unique_ptr<WindowSplash> initializeImHex();
|
||||
void deinitializeImHex();
|
||||
|
||||
}
|
||||
48
main/gui/source/init/run/common.cpp
Normal file
48
main/gui/source/init/run/common.cpp
Normal file
@@ -0,0 +1,48 @@
|
||||
#include <hex/api/event_manager.hpp>
|
||||
#include <hex/api/task_manager.hpp>
|
||||
#include <hex/helpers/utils.hpp>
|
||||
|
||||
#include <init/splash_window.hpp>
|
||||
#include <init/tasks.hpp>
|
||||
|
||||
namespace hex::init {
|
||||
|
||||
/**
|
||||
* @brief Handles a file open request by opening the file specified by OS-specific means
|
||||
*/
|
||||
void handleFileOpenRequest() {
|
||||
if (auto path = hex::getInitialFilePath(); path.has_value()) {
|
||||
RequestOpenFile::post(path.value());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Displays ImHex's splash screen and runs all initialization tasks. The splash screen will be displayed until all tasks have finished.
|
||||
*/
|
||||
[[maybe_unused]]
|
||||
std::unique_ptr<init::WindowSplash> initializeImHex() {
|
||||
auto splashWindow = std::make_unique<init::WindowSplash>();
|
||||
|
||||
log::info("Using '{}' GPU", ImHexApi::System::getGPUVendor());
|
||||
|
||||
// Add initialization tasks to run
|
||||
TaskManager::init();
|
||||
for (const auto &[name, task, async] : init::getInitTasks())
|
||||
splashWindow->addStartupTask(name, task, async);
|
||||
|
||||
splashWindow->startStartupTasks();
|
||||
|
||||
return splashWindow;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Deinitializes ImHex by running all exit tasks
|
||||
*/
|
||||
void deinitializeImHex() {
|
||||
// Run exit tasks
|
||||
init::runExitTasks();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
46
main/gui/source/init/run/native.cpp
Normal file
46
main/gui/source/init/run/native.cpp
Normal file
@@ -0,0 +1,46 @@
|
||||
#if !defined(OS_WEB)
|
||||
|
||||
#include <hex/api/event_manager.hpp>
|
||||
#include <wolv/utils/guards.hpp>
|
||||
|
||||
#include <init/run.hpp>
|
||||
#include <window.hpp>
|
||||
|
||||
namespace hex::init {
|
||||
|
||||
int runImHex() {
|
||||
|
||||
bool shouldRestart = false;
|
||||
do {
|
||||
// Register an event handler that will make ImHex restart when requested
|
||||
shouldRestart = false;
|
||||
RequestRestartImHex::subscribe([&] {
|
||||
shouldRestart = true;
|
||||
});
|
||||
|
||||
{
|
||||
auto splashWindow = initializeImHex();
|
||||
// Draw the splash window while tasks are running
|
||||
if (!splashWindow->loop())
|
||||
ImHexApi::System::impl::addInitArgument("tasks-failed");
|
||||
|
||||
handleFileOpenRequest();
|
||||
}
|
||||
|
||||
// Clean up everything after the main window is closed
|
||||
ON_SCOPE_EXIT {
|
||||
deinitializeImHex();
|
||||
};
|
||||
|
||||
// Main window
|
||||
Window window;
|
||||
window.loop();
|
||||
|
||||
} while (shouldRestart);
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
81
main/gui/source/init/run/web.cpp
Normal file
81
main/gui/source/init/run/web.cpp
Normal file
@@ -0,0 +1,81 @@
|
||||
#if defined(OS_WEB)
|
||||
|
||||
#include <emscripten.h>
|
||||
#include <emscripten/html5.h>
|
||||
|
||||
#include <hex/api/imhex_api.hpp>
|
||||
#include <hex/api/event_manager.hpp>
|
||||
#include <hex/api/task_manager.hpp>
|
||||
|
||||
#include <window.hpp>
|
||||
|
||||
#include <init/run.hpp>
|
||||
|
||||
namespace hex::init {
|
||||
|
||||
void saveFsData() {
|
||||
EM_ASM({
|
||||
FS.syncfs(function (err) {
|
||||
if (!err)
|
||||
return;
|
||||
alert("Failed to save permanent file system: "+err);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
int runImHex() {
|
||||
static std::unique_ptr<init::WindowSplash> splashWindow;
|
||||
splashWindow = initializeImHex();
|
||||
|
||||
RequestRestartImHex::subscribe([&] {
|
||||
MAIN_THREAD_EM_ASM({
|
||||
location.reload();
|
||||
});
|
||||
});
|
||||
|
||||
// Draw the splash window while tasks are running
|
||||
emscripten_set_main_loop_arg([](void *arg) {
|
||||
auto &splashWindow = *reinterpret_cast<std::unique_ptr<init::WindowSplash>*>(arg);
|
||||
|
||||
FrameResult frameResult = splashWindow->fullFrame();
|
||||
if (frameResult == FrameResult::Success) {
|
||||
handleFileOpenRequest();
|
||||
|
||||
// Clean up everything after the main window is closed
|
||||
emscripten_set_beforeunload_callback(nullptr, [](int eventType, const void *reserved, void *userData) {
|
||||
hex::unused(eventType, reserved, userData);
|
||||
|
||||
emscripten_cancel_main_loop();
|
||||
|
||||
try {
|
||||
saveFsData();
|
||||
deinitializeImHex();
|
||||
return "";
|
||||
} catch (const std::exception &e) {
|
||||
static std::string message;
|
||||
message = hex::format("Failed to deinitialize ImHex!\nThis is just a message warning you of this, the application has already closed, you probably can't do anything about it.\n\nError: {}", e.what());
|
||||
return message.c_str();
|
||||
}
|
||||
});
|
||||
|
||||
// Delete splash window (do it before creating the main window so glfw destroys the window)
|
||||
splashWindow.reset();
|
||||
|
||||
emscripten_cancel_main_loop();
|
||||
|
||||
// Main window
|
||||
static std::optional<Window> window;
|
||||
window.emplace();
|
||||
|
||||
emscripten_set_main_loop([]() {
|
||||
window->fullFrame();
|
||||
}, 60, 0);
|
||||
}
|
||||
}, &splashWindow, 60, 0);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -7,7 +7,6 @@
|
||||
#include "messaging.hpp"
|
||||
|
||||
#include "init/splash_window.hpp"
|
||||
#include "init/tasks.hpp"
|
||||
|
||||
#include <hex/api/task_manager.hpp>
|
||||
#include <hex/api/plugin_manager.hpp>
|
||||
@@ -16,20 +15,17 @@
|
||||
#include "hex/subcommands/subcommands.hpp"
|
||||
|
||||
#include <wolv/io/fs.hpp>
|
||||
#include <wolv/utils/guards.hpp>
|
||||
#include <fcntl.h>
|
||||
|
||||
#if defined(OS_WINDOWS)
|
||||
#include <windows.h>
|
||||
#include <shellapi.h>
|
||||
#include <codecvt>
|
||||
#elif defined(OS_WEB)
|
||||
#include <emscripten.h>
|
||||
#include <emscripten/html5.h>
|
||||
#endif
|
||||
|
||||
using namespace hex;
|
||||
|
||||
namespace hex::init { int runImHex(); }
|
||||
|
||||
namespace {
|
||||
|
||||
/**
|
||||
@@ -95,150 +91,6 @@ namespace {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Displays ImHex's splash screen and runs all initialization tasks. The splash screen will be displayed until all tasks have finished.
|
||||
*/
|
||||
[[maybe_unused]]
|
||||
void initializeImHex() {
|
||||
init::WindowSplash splashWindow;
|
||||
|
||||
log::info("Using '{}' GPU", ImHexApi::System::getGPUVendor());
|
||||
|
||||
// Add initialization tasks to run
|
||||
TaskManager::init();
|
||||
for (const auto &[name, task, async] : init::getInitTasks())
|
||||
splashWindow.addStartupTask(name, task, async);
|
||||
|
||||
splashWindow.startStartupTasks();
|
||||
|
||||
// Draw the splash window while tasks are running
|
||||
if (!splashWindow.loop())
|
||||
ImHexApi::System::impl::addInitArgument("tasks-failed");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Deinitializes ImHex by running all exit tasks
|
||||
*/
|
||||
void deinitializeImHex() {
|
||||
// Run exit tasks
|
||||
init::runExitTasks();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Handles a file open request by opening the file specified by OS-specific means
|
||||
*/
|
||||
void handleFileOpenRequest() {
|
||||
if (auto path = hex::getInitialFilePath(); path.has_value()) {
|
||||
RequestOpenFile::post(path.value());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#if defined(OS_WEB)
|
||||
|
||||
using namespace hex::init;
|
||||
|
||||
void saveFsData() {
|
||||
EM_ASM({
|
||||
FS.syncfs(function (err) {
|
||||
if (!err)
|
||||
return;
|
||||
alert("Failed to save permanent file system: "+err);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
int runImHex() {
|
||||
auto splashWindow = new WindowSplash();
|
||||
|
||||
log::info("Using '{}' GPU", ImHexApi::System::getGPUVendor());
|
||||
|
||||
// Add initialization tasks to run
|
||||
TaskManager::init();
|
||||
for (const auto &[name, task, async] : init::getInitTasks())
|
||||
splashWindow->addStartupTask(name, task, async);
|
||||
|
||||
splashWindow->startStartupTasks();
|
||||
|
||||
RequestRestartImHex::subscribe([&] {
|
||||
MAIN_THREAD_EM_ASM({
|
||||
location.reload();
|
||||
});
|
||||
});
|
||||
|
||||
// Draw the splash window while tasks are running
|
||||
emscripten_set_main_loop_arg([](void *arg) {
|
||||
auto splashWindow = reinterpret_cast<WindowSplash*>(arg);
|
||||
|
||||
FrameResult frameResult = splashWindow->fullFrame();
|
||||
if (frameResult == FrameResult::Success) {
|
||||
handleFileOpenRequest();
|
||||
|
||||
// Clean up everything after the main window is closed
|
||||
emscripten_set_beforeunload_callback(nullptr, [](int eventType, const void *reserved, void *userData) {
|
||||
hex::unused(eventType, reserved, userData);
|
||||
|
||||
try {
|
||||
saveFsData();
|
||||
deinitializeImHex();
|
||||
return "";
|
||||
} catch (const std::exception &ex) {
|
||||
std::string *msg = new std::string("Failed to deinitialize ImHex. This is just a message warning you of this, the application has already closed, you probably can't do anything about it. Message: ");
|
||||
msg->append(std::string(ex.what()));
|
||||
log::fatal("{}", *msg);
|
||||
return msg->c_str();
|
||||
}
|
||||
});
|
||||
|
||||
// Delete splash window (do it before creating the main window so glfw destroys the window)
|
||||
delete splashWindow;
|
||||
|
||||
emscripten_cancel_main_loop();
|
||||
|
||||
// Main window
|
||||
static Window window;
|
||||
emscripten_set_main_loop([]() {
|
||||
window.fullFrame();
|
||||
}, 60, 0);
|
||||
}
|
||||
}, splashWindow, 60, 0);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
int runImHex() {
|
||||
|
||||
bool shouldRestart = false;
|
||||
do {
|
||||
// Register an event handler that will make ImHex restart when requested
|
||||
shouldRestart = false;
|
||||
RequestRestartImHex::subscribe([&] {
|
||||
shouldRestart = true;
|
||||
});
|
||||
|
||||
initializeImHex();
|
||||
handleFileOpenRequest();
|
||||
|
||||
// Clean up everything after the main window is closed
|
||||
ON_SCOPE_EXIT {
|
||||
deinitializeImHex();
|
||||
};
|
||||
|
||||
// Main window
|
||||
Window window;
|
||||
window.loop();
|
||||
|
||||
} while (shouldRestart);
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -262,5 +114,5 @@ int main(int argc, char **argv) {
|
||||
|
||||
ImHexApi::System::impl::setPortableVersion(isPortableVersion());
|
||||
|
||||
return runImHex();
|
||||
return init::runImHex();
|
||||
}
|
||||
|
||||
@@ -106,6 +106,17 @@ namespace hex {
|
||||
|
||||
m_popupsToOpen.push_back(name);
|
||||
});
|
||||
|
||||
LayoutManager::registerLoadCallback([this](std::string_view line) {
|
||||
int width = 0, height = 0;
|
||||
sscanf(line.data(), "MainWindowSize=%d,%d", &width, &height);
|
||||
|
||||
if (width > 0 && height > 0) {
|
||||
TaskManager::doLater([width, height, this]{
|
||||
glfwSetWindowSize(m_window, width, height);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void Window::fullFrame() {
|
||||
@@ -840,39 +851,14 @@ namespace hex {
|
||||
|
||||
handler.ReadOpenFn = [](ImGuiContext *ctx, ImGuiSettingsHandler *, const char *) -> void* { return ctx; };
|
||||
|
||||
handler.ReadLineFn = [](ImGuiContext *, ImGuiSettingsHandler *handler, void *, const char *line) {
|
||||
auto window = static_cast<Window*>(handler->UserData);
|
||||
|
||||
for (auto &[name, view] : ContentRegistry::Views::impl::getEntries()) {
|
||||
std::string format = view->getUnlocalizedName().get() + "=%d";
|
||||
sscanf(line, format.c_str(), &view->getWindowOpenState());
|
||||
}
|
||||
for (auto &[name, function, detached] : ContentRegistry::Tools::impl::getEntries()) {
|
||||
std::string format = name + "=%d";
|
||||
sscanf(line, format.c_str(), &detached);
|
||||
}
|
||||
|
||||
int width = 0, height = 0;
|
||||
sscanf(line, "MainWindowSize=%d,%d", &width, &height);
|
||||
|
||||
if (width > 0 && height > 0) {
|
||||
TaskManager::doLater([width, height, window]{
|
||||
glfwSetWindowSize(window->m_window, width, height);
|
||||
});
|
||||
}
|
||||
handler.ReadLineFn = [](ImGuiContext *, ImGuiSettingsHandler *, void *, const char *line) {
|
||||
LayoutManager::onLoad(line);
|
||||
};
|
||||
|
||||
handler.WriteAllFn = [](ImGuiContext *, ImGuiSettingsHandler *handler, ImGuiTextBuffer *buf) {
|
||||
buf->appendf("[%s][General]\n", handler->TypeName);
|
||||
|
||||
for (auto &[name, view] : ContentRegistry::Views::impl::getEntries()) {
|
||||
buf->appendf("%s=%d\n", name.c_str(), view->getWindowOpenState());
|
||||
}
|
||||
for (auto &[name, function, detached] : ContentRegistry::Tools::impl::getEntries()) {
|
||||
buf->appendf("%s=%d\n", name.c_str(), detached);
|
||||
}
|
||||
|
||||
buf->append("\n");
|
||||
handler.WriteAllFn = [](ImGuiContext *, ImGuiSettingsHandler *handler, ImGuiTextBuffer *buffer) {
|
||||
buffer->appendf("[%s][General]\n", handler->TypeName);
|
||||
LayoutManager::onStore(buffer);
|
||||
buffer->append("\n");
|
||||
};
|
||||
|
||||
handler.UserData = this;
|
||||
|
||||
@@ -16,9 +16,10 @@ namespace hex::plugin::builtin {
|
||||
void drawAlwaysVisibleContent() override;
|
||||
|
||||
private:
|
||||
std::vector<ContentRegistry::Tools::impl::Entry>::iterator m_dragStartIterator;
|
||||
std::vector<ContentRegistry::Tools::impl::Entry>::const_iterator m_dragStartIterator;
|
||||
|
||||
std::map<ImGuiWindow*, float> m_windowHeights;
|
||||
std::map<UnlocalizedString, bool> m_detachedTools;
|
||||
};
|
||||
|
||||
}
|
||||
@@ -483,6 +483,7 @@
|
||||
"hex.builtin.setting.imhex.recent_files": "Zuletzt geöffnete Dateien",
|
||||
"hex.builtin.setting.interface": "Aussehen",
|
||||
"hex.builtin.setting.interface.color": "Farbdesign",
|
||||
"hex.builtin.setting.interface.crisp_scaling": "Gestochen scharfe Skallierung aktivieren",
|
||||
"hex.builtin.setting.interface.fps": "FPS Limit",
|
||||
"hex.builtin.setting.interface.fps.native": "Nativ",
|
||||
"hex.builtin.setting.interface.fps.unlocked": "Unbegrenzt",
|
||||
|
||||
@@ -470,6 +470,7 @@
|
||||
"hex.builtin.setting.interface": "Interface",
|
||||
"hex.builtin.setting.interface.always_show_provider_tabs": "Always show Provider Tabs",
|
||||
"hex.builtin.setting.interface.color": "Color theme",
|
||||
"hex.builtin.setting.interface.crisp_scaling": "Enable crisp scaling",
|
||||
"hex.builtin.setting.interface.fps": "FPS Limit",
|
||||
"hex.builtin.setting.interface.fps.unlocked": "Unlocked",
|
||||
"hex.builtin.setting.interface.fps.native": "Native",
|
||||
|
||||
@@ -47,7 +47,7 @@ namespace hex::plugin::builtin {
|
||||
ui::PopupQuestion::open("hex.builtin.popup.exit_application.desc"_lang,
|
||||
[] {
|
||||
imhexClosing = true;
|
||||
for (const auto &provider : auto(ImHexApi::Provider::getProviders()))
|
||||
for (const auto &provider : ImHexApi::Provider::getProviders())
|
||||
ImHexApi::Provider::remove(provider);
|
||||
},
|
||||
[] { }
|
||||
|
||||
@@ -290,7 +290,7 @@ namespace hex::plugin::builtin {
|
||||
queryRange.push_back(0x00);
|
||||
|
||||
// Build the font atlas with the query range
|
||||
auto newFont = atlas.AddFontFromMemoryTTF(font.fontData.data(), int(font.fontData.size()), 0, &cfg, queryRange.Data);
|
||||
auto newFont = atlas.AddFontFromMemoryTTF(const_cast<u8 *>(font.fontData.data()), int(font.fontData.size()), 0, &cfg, queryRange.Data);
|
||||
atlas.Build();
|
||||
|
||||
return newFont->Descent;
|
||||
@@ -300,7 +300,7 @@ namespace hex::plugin::builtin {
|
||||
std::memset(cfg.Name, 0x00, sizeof(cfg.Name));
|
||||
std::strncpy(cfg.Name, font.name.c_str(), sizeof(cfg.Name) - 1);
|
||||
cfg.GlyphOffset = { font.offset.x, font.offset.y - defaultFont->Descent + descent };
|
||||
fonts->AddFontFromMemoryTTF(font.fontData.data(), int(font.fontData.size()), 0, &cfg, ranges.back().Data);
|
||||
fonts->AddFontFromMemoryTTF(const_cast<u8 *>(font.fontData.data()), int(font.fontData.size()), 0, &cfg, ranges.back().Data);
|
||||
}
|
||||
cfg.FontBuilderFlags = startFlags;
|
||||
|
||||
|
||||
@@ -57,8 +57,7 @@ namespace hex::plugin::builtin {
|
||||
}
|
||||
}
|
||||
|
||||
auto providers = auto(ImHexApi::Provider::getProviders());
|
||||
for (const auto &provider : providers) {
|
||||
for (const auto &provider : ImHexApi::Provider::getProviders()) {
|
||||
ImHexApi::Provider::remove(provider);
|
||||
}
|
||||
|
||||
|
||||
@@ -61,7 +61,7 @@ namespace hex::plugin::builtin {
|
||||
task->interrupt();
|
||||
|
||||
TaskManager::runWhenTasksFinished([]{
|
||||
for (auto provider : ImHexApi::Provider::getProviders())
|
||||
for (const auto &provider : ImHexApi::Provider::getProviders())
|
||||
ImHexApi::Provider::remove(provider, true);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -443,7 +443,7 @@ namespace hex::plugin::builtin {
|
||||
|
||||
// Find all menu items that are in the toolbar and sort them by their toolbar index
|
||||
std::set<ContentRegistry::Interface::impl::MenuItem*, MenuItemSorter> toolbarItems;
|
||||
for (auto &[priority, menuItem] : ContentRegistry::Interface::impl::getMenuItems()) {
|
||||
for (auto &[priority, menuItem] : ContentRegistry::Interface::impl::getMenuItemsMutable()) {
|
||||
if (menuItem.toolbarIndex == -1)
|
||||
continue;
|
||||
|
||||
@@ -580,10 +580,10 @@ namespace hex::plugin::builtin {
|
||||
if (toolbarItems.empty())
|
||||
return;
|
||||
|
||||
for (auto &[priority, menuItem] : ContentRegistry::Interface::impl::getMenuItems())
|
||||
for (auto &[priority, menuItem] : ContentRegistry::Interface::impl::getMenuItemsMutable())
|
||||
menuItem.toolbarIndex = -1;
|
||||
|
||||
for (auto &[priority, menuItem] : ContentRegistry::Interface::impl::getMenuItems()) {
|
||||
for (auto &[priority, menuItem] : ContentRegistry::Interface::impl::getMenuItemsMutable()) {
|
||||
for (const auto &[index, value] : toolbarItems) {
|
||||
const auto &[name, color] = value;
|
||||
if (menuItem.unlocalizedNames.back().get() == name) {
|
||||
@@ -604,184 +604,208 @@ namespace hex::plugin::builtin {
|
||||
}
|
||||
|
||||
void registerSettings() {
|
||||
|
||||
/* General */
|
||||
|
||||
namespace Widgets = ContentRegistry::Settings::Widgets;
|
||||
|
||||
ContentRegistry::Settings::add<Widgets::Checkbox>("hex.builtin.setting.general", "", "hex.builtin.setting.general.show_tips", false);
|
||||
ContentRegistry::Settings::add<Widgets::Checkbox>("hex.builtin.setting.general", "", "hex.builtin.setting.general.save_recent_providers", true);
|
||||
ContentRegistry::Settings::add<AutoBackupWidget>("hex.builtin.setting.general", "", "hex.builtin.setting.general.auto_backup_time");
|
||||
ContentRegistry::Settings::add<Widgets::Checkbox>("hex.builtin.setting.general", "hex.builtin.setting.general.patterns", "hex.builtin.setting.general.auto_load_patterns", true);
|
||||
ContentRegistry::Settings::add<Widgets::Checkbox>("hex.builtin.setting.general", "hex.builtin.setting.general.patterns", "hex.builtin.setting.general.sync_pattern_source", false);
|
||||
ContentRegistry::Settings::add<Widgets::Checkbox>("hex.builtin.setting.general", "hex.builtin.setting.general.network", "hex.builtin.setting.general.network_interface", false);
|
||||
/* General */
|
||||
{
|
||||
|
||||
#if !defined(OS_WEB)
|
||||
ContentRegistry::Settings::add<ServerContactWidget>("hex.builtin.setting.general", "hex.builtin.setting.general.network", "hex.builtin.setting.general.server_contact");
|
||||
ContentRegistry::Settings::add<Widgets::Checkbox>("hex.builtin.setting.general", "hex.builtin.setting.general.network", "hex.builtin.setting.general.upload_crash_logs", true);
|
||||
#endif
|
||||
ContentRegistry::Settings::add<Widgets::Checkbox>("hex.builtin.setting.general", "", "hex.builtin.setting.general.show_tips", false);
|
||||
ContentRegistry::Settings::add<Widgets::Checkbox>("hex.builtin.setting.general", "", "hex.builtin.setting.general.save_recent_providers", true);
|
||||
ContentRegistry::Settings::add<AutoBackupWidget>("hex.builtin.setting.general", "", "hex.builtin.setting.general.auto_backup_time");
|
||||
ContentRegistry::Settings::add<Widgets::Checkbox>("hex.builtin.setting.general", "hex.builtin.setting.general.patterns", "hex.builtin.setting.general.auto_load_patterns", true);
|
||||
ContentRegistry::Settings::add<Widgets::Checkbox>("hex.builtin.setting.general", "hex.builtin.setting.general.patterns", "hex.builtin.setting.general.sync_pattern_source", false);
|
||||
ContentRegistry::Settings::add<Widgets::Checkbox>("hex.builtin.setting.general", "hex.builtin.setting.general.network", "hex.builtin.setting.general.network_interface", false);
|
||||
|
||||
/* Interface */
|
||||
|
||||
auto themeNames = ThemeManager::getThemeNames();
|
||||
std::vector<nlohmann::json> themeJsons = { };
|
||||
for (const auto &themeName : themeNames)
|
||||
themeJsons.emplace_back(themeName);
|
||||
|
||||
themeNames.emplace(themeNames.begin(), ThemeManager::NativeTheme);
|
||||
themeJsons.emplace(themeJsons.begin(), ThemeManager::NativeTheme);
|
||||
|
||||
ContentRegistry::Settings::add<Widgets::DropDown>("hex.builtin.setting.interface", "hex.builtin.setting.interface.style", "hex.builtin.setting.interface.color",
|
||||
themeNames,
|
||||
themeJsons,
|
||||
"Dark").setChangedCallback([](auto &widget) {
|
||||
auto dropDown = static_cast<Widgets::DropDown *>(&widget);
|
||||
|
||||
if (dropDown->getValue() == ThemeManager::NativeTheme)
|
||||
ImHexApi::System::enableSystemThemeDetection(true);
|
||||
else {
|
||||
ImHexApi::System::enableSystemThemeDetection(false);
|
||||
ThemeManager::changeTheme(dropDown->getValue());
|
||||
}
|
||||
});
|
||||
|
||||
ContentRegistry::Settings::add<ScalingWidget>("hex.builtin.setting.interface", "hex.builtin.setting.interface.style", "hex.builtin.setting.interface.scaling_factor").requiresRestart();
|
||||
|
||||
ContentRegistry::Settings::add<Widgets::Checkbox>("hex.builtin.setting.interface", "hex.builtin.setting.interface.style", "hex.builtin.setting.interface.pattern_data_row_bg", false);
|
||||
ContentRegistry::Settings::add<Widgets::Checkbox>("hex.builtin.setting.interface", "hex.builtin.setting.interface.style", "hex.builtin.setting.interface.always_show_provider_tabs", false);
|
||||
|
||||
std::vector<std::string> languageNames;
|
||||
std::vector<nlohmann::json> languageCodes;
|
||||
|
||||
for (auto &[languageCode, languageName] : LocalizationManager::getSupportedLanguages()) {
|
||||
languageNames.emplace_back(languageName);
|
||||
languageCodes.emplace_back(languageCode);
|
||||
#if !defined(OS_WEB)
|
||||
ContentRegistry::Settings::add<ServerContactWidget>("hex.builtin.setting.general", "hex.builtin.setting.general.network", "hex.builtin.setting.general.server_contact");
|
||||
ContentRegistry::Settings::add<Widgets::Checkbox>("hex.builtin.setting.general", "hex.builtin.setting.general.network", "hex.builtin.setting.general.upload_crash_logs", true);
|
||||
#endif
|
||||
}
|
||||
|
||||
ContentRegistry::Settings::add<Widgets::DropDown>("hex.builtin.setting.interface", "hex.builtin.setting.interface.language", "hex.builtin.setting.interface.language", languageNames, languageCodes, "en-US");
|
||||
/* Interface */
|
||||
{
|
||||
auto themeNames = ThemeManager::getThemeNames();
|
||||
std::vector<nlohmann::json> themeJsons = { };
|
||||
for (const auto &themeName : themeNames)
|
||||
themeJsons.emplace_back(themeName);
|
||||
|
||||
ContentRegistry::Settings::add<Widgets::TextBox>("hex.builtin.setting.interface", "hex.builtin.setting.interface.language", "hex.builtin.setting.interface.wiki_explain_language", "en");
|
||||
ContentRegistry::Settings::add<FPSWidget>("hex.builtin.setting.interface", "hex.builtin.setting.interface.window", "hex.builtin.setting.interface.fps");
|
||||
themeNames.emplace(themeNames.begin(), ThemeManager::NativeTheme);
|
||||
themeJsons.emplace(themeJsons.begin(), ThemeManager::NativeTheme);
|
||||
|
||||
#if defined (OS_LINUX)
|
||||
constexpr static auto MultiWindowSupportEnabledDefault = 0;
|
||||
#else
|
||||
constexpr static auto MultiWindowSupportEnabledDefault = 1;
|
||||
#endif
|
||||
ContentRegistry::Settings::add<Widgets::DropDown>("hex.builtin.setting.interface", "hex.builtin.setting.interface.style", "hex.builtin.setting.interface.color",
|
||||
themeNames,
|
||||
themeJsons,
|
||||
"Dark").setChangedCallback([](auto &widget) {
|
||||
auto dropDown = static_cast<Widgets::DropDown *>(&widget);
|
||||
|
||||
ContentRegistry::Settings::add<Widgets::Checkbox>("hex.builtin.setting.interface", "hex.builtin.setting.interface.window", "hex.builtin.setting.interface.multi_windows", MultiWindowSupportEnabledDefault).requiresRestart();
|
||||
ContentRegistry::Settings::add<Widgets::Checkbox>("hex.builtin.setting.interface", "hex.builtin.setting.interface.window", "hex.builtin.setting.interface.restore_window_pos", false);
|
||||
if (dropDown->getValue() == ThemeManager::NativeTheme)
|
||||
ImHexApi::System::enableSystemThemeDetection(true);
|
||||
else {
|
||||
ImHexApi::System::enableSystemThemeDetection(false);
|
||||
ThemeManager::changeTheme(dropDown->getValue());
|
||||
}
|
||||
});
|
||||
|
||||
ContentRegistry::Settings::add<Widgets::ColorPicker>("hex.builtin.setting.hex_editor", "", "hex.builtin.setting.hex_editor.highlight_color", ImColor(0x80, 0x80, 0xC0, 0x60));
|
||||
ContentRegistry::Settings::add<Widgets::Checkbox>("hex.builtin.setting.hex_editor", "", "hex.builtin.setting.hex_editor.sync_scrolling", false);
|
||||
ContentRegistry::Settings::add<Widgets::SliderInteger>("hex.builtin.setting.hex_editor", "", "hex.builtin.setting.hex_editor.byte_padding", 0, 0, 50);
|
||||
ContentRegistry::Settings::add<Widgets::SliderInteger>("hex.builtin.setting.hex_editor", "", "hex.builtin.setting.hex_editor.char_padding", 0, 0, 50);
|
||||
ContentRegistry::Settings::add<ScalingWidget>("hex.builtin.setting.interface", "hex.builtin.setting.interface.style", "hex.builtin.setting.interface.scaling_factor").requiresRestart();
|
||||
|
||||
#if defined (OS_WEB)
|
||||
ContentRegistry::Settings::add<Widgets::Checkbox>("hex.builtin.setting.interface", "hex.builtin.setting.interface.style", "hex.builtin.setting.interface.crisp_scaling", false)
|
||||
.setChangedCallback([](Widgets::Widget &widget) {
|
||||
auto checkBox = static_cast<Widgets::Checkbox *>(&widget);
|
||||
|
||||
EM_ASM({
|
||||
var canvas = document.getElementById('canvas');
|
||||
if ($0)
|
||||
canvas.style.imageRendering = 'pixelated';
|
||||
else
|
||||
canvas.style.imageRendering = 'smooth';
|
||||
}, checkBox->isChecked());
|
||||
});
|
||||
#endif
|
||||
|
||||
ContentRegistry::Settings::add<Widgets::Checkbox>("hex.builtin.setting.interface", "hex.builtin.setting.interface.style", "hex.builtin.setting.interface.pattern_data_row_bg", false);
|
||||
ContentRegistry::Settings::add<Widgets::Checkbox>("hex.builtin.setting.interface", "hex.builtin.setting.interface.style", "hex.builtin.setting.interface.always_show_provider_tabs", false);
|
||||
|
||||
std::vector<std::string> languageNames;
|
||||
std::vector<nlohmann::json> languageCodes;
|
||||
|
||||
for (auto &[languageCode, languageName] : LocalizationManager::getSupportedLanguages()) {
|
||||
languageNames.emplace_back(languageName);
|
||||
languageCodes.emplace_back(languageCode);
|
||||
}
|
||||
|
||||
ContentRegistry::Settings::add<Widgets::DropDown>("hex.builtin.setting.interface", "hex.builtin.setting.interface.language", "hex.builtin.setting.interface.language", languageNames, languageCodes, "en-US");
|
||||
|
||||
ContentRegistry::Settings::add<Widgets::TextBox>("hex.builtin.setting.interface", "hex.builtin.setting.interface.language", "hex.builtin.setting.interface.wiki_explain_language", "en");
|
||||
ContentRegistry::Settings::add<FPSWidget>("hex.builtin.setting.interface", "hex.builtin.setting.interface.window", "hex.builtin.setting.interface.fps");
|
||||
|
||||
#if defined (OS_LINUX)
|
||||
constexpr static auto MultiWindowSupportEnabledDefault = 0;
|
||||
#else
|
||||
constexpr static auto MultiWindowSupportEnabledDefault = 1;
|
||||
#endif
|
||||
|
||||
ContentRegistry::Settings::add<Widgets::Checkbox>("hex.builtin.setting.interface", "hex.builtin.setting.interface.window", "hex.builtin.setting.interface.multi_windows", MultiWindowSupportEnabledDefault).requiresRestart();
|
||||
ContentRegistry::Settings::add<Widgets::Checkbox>("hex.builtin.setting.interface", "hex.builtin.setting.interface.window", "hex.builtin.setting.interface.restore_window_pos", false);
|
||||
|
||||
ContentRegistry::Settings::add<Widgets::ColorPicker>("hex.builtin.setting.hex_editor", "", "hex.builtin.setting.hex_editor.highlight_color", ImColor(0x80, 0x80, 0xC0, 0x60));
|
||||
ContentRegistry::Settings::add<Widgets::Checkbox>("hex.builtin.setting.hex_editor", "", "hex.builtin.setting.hex_editor.sync_scrolling", false);
|
||||
ContentRegistry::Settings::add<Widgets::SliderInteger>("hex.builtin.setting.hex_editor", "", "hex.builtin.setting.hex_editor.byte_padding", 0, 0, 50);
|
||||
ContentRegistry::Settings::add<Widgets::SliderInteger>("hex.builtin.setting.hex_editor", "", "hex.builtin.setting.hex_editor.char_padding", 0, 0, 50);
|
||||
}
|
||||
|
||||
/* Fonts */
|
||||
{
|
||||
|
||||
ContentRegistry::Settings::add<Widgets::Checkbox>("hex.builtin.setting.font", "hex.builtin.setting.font.glyphs", "hex.builtin.setting.font.load_all_unicode_chars", false)
|
||||
.requiresRestart();
|
||||
ContentRegistry::Settings::add<Widgets::Checkbox>("hex.builtin.setting.font", "hex.builtin.setting.font.glyphs", "hex.builtin.setting.font.load_all_unicode_chars", false)
|
||||
.requiresRestart();
|
||||
|
||||
auto customFontEnabledSetting = ContentRegistry::Settings::add<Widgets::Checkbox>("hex.builtin.setting.font", "hex.builtin.setting.font.custom_font", "hex.builtin.setting.font.custom_font_enable", false).requiresRestart();
|
||||
auto customFontEnabledSetting = ContentRegistry::Settings::add<Widgets::Checkbox>("hex.builtin.setting.font", "hex.builtin.setting.font.custom_font", "hex.builtin.setting.font.custom_font_enable", false).requiresRestart();
|
||||
|
||||
const auto customFontsEnabled = [customFontEnabledSetting] {
|
||||
auto &customFontsEnabled = static_cast<Widgets::Checkbox &>(customFontEnabledSetting.getWidget());
|
||||
const auto customFontsEnabled = [customFontEnabledSetting] {
|
||||
auto &customFontsEnabled = static_cast<Widgets::Checkbox &>(customFontEnabledSetting.getWidget());
|
||||
|
||||
return customFontsEnabled.isChecked();
|
||||
};
|
||||
return customFontsEnabled.isChecked();
|
||||
};
|
||||
|
||||
auto customFontPathSetting = ContentRegistry::Settings::add<Widgets::FilePicker>("hex.builtin.setting.font", "hex.builtin.setting.font.custom_font", "hex.builtin.setting.font.font_path")
|
||||
.requiresRestart()
|
||||
.setEnabledCallback(customFontsEnabled);
|
||||
auto customFontPathSetting = ContentRegistry::Settings::add<Widgets::FilePicker>("hex.builtin.setting.font", "hex.builtin.setting.font.custom_font", "hex.builtin.setting.font.font_path")
|
||||
.requiresRestart()
|
||||
.setEnabledCallback(customFontsEnabled);
|
||||
|
||||
const auto customFontSettingsEnabled = [customFontEnabledSetting, customFontPathSetting] {
|
||||
auto &customFontsEnabled = static_cast<Widgets::Checkbox &>(customFontEnabledSetting.getWidget());
|
||||
auto &fontPath = static_cast<Widgets::FilePicker &>(customFontPathSetting.getWidget());
|
||||
const auto customFontSettingsEnabled = [customFontEnabledSetting, customFontPathSetting] {
|
||||
auto &customFontsEnabled = static_cast<Widgets::Checkbox &>(customFontEnabledSetting.getWidget());
|
||||
auto &fontPath = static_cast<Widgets::FilePicker &>(customFontPathSetting.getWidget());
|
||||
|
||||
return customFontsEnabled.isChecked() && !fontPath.getPath().empty();
|
||||
};
|
||||
return customFontsEnabled.isChecked() && !fontPath.getPath().empty();
|
||||
};
|
||||
|
||||
ContentRegistry::Settings::add<Widgets::Label>("hex.builtin.setting.font", "hex.builtin.setting.font.custom_font", "hex.builtin.setting.font.custom_font_info")
|
||||
.setEnabledCallback(customFontsEnabled);
|
||||
|
||||
|
||||
ContentRegistry::Settings::add<Widgets::SliderInteger>("hex.builtin.setting.font", "hex.builtin.setting.font.custom_font", "hex.builtin.setting.font.font_size", 13, 0, 100)
|
||||
.requiresRestart()
|
||||
.setEnabledCallback(customFontSettingsEnabled);
|
||||
ContentRegistry::Settings::add<Widgets::Checkbox>("hex.builtin.setting.font", "hex.builtin.setting.font.custom_font", "hex.builtin.setting.font.font_bold", false)
|
||||
.requiresRestart()
|
||||
.setEnabledCallback(customFontSettingsEnabled);
|
||||
ContentRegistry::Settings::add<Widgets::Checkbox>("hex.builtin.setting.font", "hex.builtin.setting.font.custom_font", "hex.builtin.setting.font.font_italic", false)
|
||||
.requiresRestart()
|
||||
.setEnabledCallback(customFontSettingsEnabled);
|
||||
ContentRegistry::Settings::add<Widgets::Checkbox>("hex.builtin.setting.font", "hex.builtin.setting.font.custom_font", "hex.builtin.setting.font.font_antialias", true)
|
||||
.requiresRestart()
|
||||
.setEnabledCallback(customFontSettingsEnabled);
|
||||
ContentRegistry::Settings::add<Widgets::Label>("hex.builtin.setting.font", "hex.builtin.setting.font.custom_font", "hex.builtin.setting.font.custom_font_info")
|
||||
.setEnabledCallback(customFontsEnabled);
|
||||
|
||||
|
||||
ContentRegistry::Settings::add<Widgets::SliderInteger>("hex.builtin.setting.font", "hex.builtin.setting.font.custom_font", "hex.builtin.setting.font.font_size", 13, 0, 100)
|
||||
.requiresRestart()
|
||||
.setEnabledCallback(customFontSettingsEnabled);
|
||||
ContentRegistry::Settings::add<Widgets::Checkbox>("hex.builtin.setting.font", "hex.builtin.setting.font.custom_font", "hex.builtin.setting.font.font_bold", false)
|
||||
.requiresRestart()
|
||||
.setEnabledCallback(customFontSettingsEnabled);
|
||||
ContentRegistry::Settings::add<Widgets::Checkbox>("hex.builtin.setting.font", "hex.builtin.setting.font.custom_font", "hex.builtin.setting.font.font_italic", false)
|
||||
.requiresRestart()
|
||||
.setEnabledCallback(customFontSettingsEnabled);
|
||||
ContentRegistry::Settings::add<Widgets::Checkbox>("hex.builtin.setting.font", "hex.builtin.setting.font.custom_font", "hex.builtin.setting.font.font_antialias", true)
|
||||
.requiresRestart()
|
||||
.setEnabledCallback(customFontSettingsEnabled);
|
||||
}
|
||||
|
||||
/* Folders */
|
||||
|
||||
ContentRegistry::Settings::setCategoryDescription("hex.builtin.setting.folders", "hex.builtin.setting.folders.description");
|
||||
ContentRegistry::Settings::add<UserFolderWidget>("hex.builtin.setting.folders", "", "hex.builtin.setting.folders.description");
|
||||
{
|
||||
ContentRegistry::Settings::setCategoryDescription("hex.builtin.setting.folders", "hex.builtin.setting.folders.description");
|
||||
ContentRegistry::Settings::add<UserFolderWidget>("hex.builtin.setting.folders", "", "hex.builtin.setting.folders.description");
|
||||
}
|
||||
|
||||
/* Proxy */
|
||||
{
|
||||
HttpRequest::setProxyUrl(ContentRegistry::Settings::read<std::string>("hex.builtin.setting.proxy", "hex.builtin.setting.proxy.url", ""));
|
||||
|
||||
HttpRequest::setProxyUrl(ContentRegistry::Settings::read<std::string>("hex.builtin.setting.proxy", "hex.builtin.setting.proxy.url", ""));
|
||||
ContentRegistry::Settings::setCategoryDescription("hex.builtin.setting.proxy", "hex.builtin.setting.proxy.description");
|
||||
|
||||
ContentRegistry::Settings::setCategoryDescription("hex.builtin.setting.proxy", "hex.builtin.setting.proxy.description");
|
||||
auto proxyEnabledSetting = ContentRegistry::Settings::add<Widgets::Checkbox>("hex.builtin.setting.proxy", "", "hex.builtin.setting.proxy.enable", false)
|
||||
.setChangedCallback([](Widgets::Widget &widget) {
|
||||
auto checkBox = static_cast<Widgets::Checkbox *>(&widget);
|
||||
|
||||
auto proxyEnabledSetting = ContentRegistry::Settings::add<Widgets::Checkbox>("hex.builtin.setting.proxy", "", "hex.builtin.setting.proxy.enable", false).setChangedCallback([](Widgets::Widget &widget) {
|
||||
auto checkBox = static_cast<Widgets::Checkbox *>(&widget);
|
||||
HttpRequest::setProxyState(checkBox->isChecked());
|
||||
});
|
||||
|
||||
HttpRequest::setProxyState(checkBox->isChecked());
|
||||
});
|
||||
ContentRegistry::Settings::add<Widgets::TextBox>("hex.builtin.setting.proxy", "", "hex.builtin.setting.proxy.url", "")
|
||||
.setEnabledCallback([proxyEnabledSetting] {
|
||||
auto &checkBox = static_cast<Widgets::Checkbox &>(proxyEnabledSetting.getWidget());
|
||||
|
||||
ContentRegistry::Settings::add<Widgets::TextBox>("hex.builtin.setting.proxy", "", "hex.builtin.setting.proxy.url", "")
|
||||
.setEnabledCallback([proxyEnabledSetting] {
|
||||
auto &checkBox = static_cast<Widgets::Checkbox &>(proxyEnabledSetting.getWidget());
|
||||
|
||||
return checkBox.isChecked();
|
||||
})
|
||||
.setChangedCallback([](Widgets::Widget &widget) {
|
||||
auto textBox = static_cast<Widgets::TextBox *>(&widget);
|
||||
|
||||
HttpRequest::setProxyUrl(textBox->getValue());
|
||||
});
|
||||
return checkBox.isChecked();
|
||||
})
|
||||
.setChangedCallback([](Widgets::Widget &widget) {
|
||||
auto textBox = static_cast<Widgets::TextBox *>(&widget);
|
||||
|
||||
HttpRequest::setProxyUrl(textBox->getValue());
|
||||
});
|
||||
}
|
||||
|
||||
/* Experiments */
|
||||
ContentRegistry::Settings::setCategoryDescription("hex.builtin.setting.experiments", "hex.builtin.setting.experiments.description");
|
||||
EventImHexStartupFinished::subscribe([]{
|
||||
for (const auto &[name, experiment] : ContentRegistry::Experiments::impl::getExperiments()) {
|
||||
ContentRegistry::Settings::add<Widgets::Checkbox>("hex.builtin.setting.experiments", "", experiment.unlocalizedName, false)
|
||||
{
|
||||
ContentRegistry::Settings::setCategoryDescription("hex.builtin.setting.experiments", "hex.builtin.setting.experiments.description");
|
||||
EventImHexStartupFinished::subscribe([]{
|
||||
for (const auto &[name, experiment] : ContentRegistry::Experiments::impl::getExperiments()) {
|
||||
ContentRegistry::Settings::add<Widgets::Checkbox>("hex.builtin.setting.experiments", "", experiment.unlocalizedName, false)
|
||||
.setTooltip(Lang(experiment.unlocalizedDescription))
|
||||
.setChangedCallback([name](Widgets::Widget &widget) {
|
||||
auto checkBox = static_cast<Widgets::Checkbox *>(&widget);
|
||||
|
||||
ContentRegistry::Experiments::enableExperiement(name, checkBox->isChecked());
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/* Shorcuts */
|
||||
EventImHexStartupFinished::subscribe([]{
|
||||
for (const auto &shortcutEntry : ShortcutManager::getGlobalShortcuts()) {
|
||||
ContentRegistry::Settings::add<KeybindingWidget>("hex.builtin.setting.shortcuts", "hex.builtin.setting.shortcuts.global", shortcutEntry.unlocalizedName, nullptr, shortcutEntry.shortcut);
|
||||
}
|
||||
|
||||
for (auto &[viewName, view] : ContentRegistry::Views::impl::getEntries()) {
|
||||
for (const auto &shortcutEntry : ShortcutManager::getViewShortcuts(view.get())) {
|
||||
ContentRegistry::Settings::add<KeybindingWidget>("hex.builtin.setting.shortcuts", viewName, shortcutEntry.unlocalizedName, view.get(), shortcutEntry.shortcut);
|
||||
{
|
||||
EventImHexStartupFinished::subscribe([]{
|
||||
for (const auto &shortcutEntry : ShortcutManager::getGlobalShortcuts()) {
|
||||
ContentRegistry::Settings::add<KeybindingWidget>("hex.builtin.setting.shortcuts", "hex.builtin.setting.shortcuts.global", shortcutEntry.unlocalizedName, nullptr, shortcutEntry.shortcut);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
/* Toolbar icons */
|
||||
ContentRegistry::Settings::setCategoryDescription("hex.builtin.setting.toolbar", "hex.builtin.setting.toolbar.description");
|
||||
for (auto &[viewName, view] : ContentRegistry::Views::impl::getEntries()) {
|
||||
for (const auto &shortcutEntry : ShortcutManager::getViewShortcuts(view.get())) {
|
||||
ContentRegistry::Settings::add<KeybindingWidget>("hex.builtin.setting.shortcuts", viewName, shortcutEntry.unlocalizedName, view.get(), shortcutEntry.shortcut);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
ContentRegistry::Settings::add<ToolbarIconsWidget>("hex.builtin.setting.toolbar", "", "hex.builtin.setting.toolbar.icons");
|
||||
/* Toolbar icons */
|
||||
{
|
||||
ContentRegistry::Settings::setCategoryDescription("hex.builtin.setting.toolbar", "hex.builtin.setting.toolbar.description");
|
||||
|
||||
ContentRegistry::Settings::add<ToolbarIconsWidget>("hex.builtin.setting.toolbar", "", "hex.builtin.setting.toolbar.icons");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -326,7 +326,7 @@ namespace hex::plugin::builtin {
|
||||
|
||||
ImGui::BeginDisabled(!providerValid || tasksRunning);
|
||||
{
|
||||
auto &providers = ImHexApi::Provider::getProviders();
|
||||
auto providers = ImHexApi::Provider::getProviders();
|
||||
|
||||
ImGui::PushStyleColor(ImGuiCol_TabActive, ImGui::GetColorU32(ImGuiCol_MenuBarBg));
|
||||
ImGui::PushStyleColor(ImGuiCol_TabUnfocusedActive, ImGui::GetColorU32(ImGuiCol_MenuBarBg));
|
||||
|
||||
@@ -20,6 +20,8 @@
|
||||
#include "content/views/view_highlight_rules.hpp"
|
||||
#include "content/views/view_tutorials.hpp"
|
||||
|
||||
#include <hex/api/layout_manager.hpp>
|
||||
|
||||
namespace hex::plugin::builtin {
|
||||
|
||||
void registerViews() {
|
||||
@@ -44,6 +46,20 @@ namespace hex::plugin::builtin {
|
||||
ContentRegistry::Views::add<ViewAchievements>();
|
||||
ContentRegistry::Views::add<ViewHighlightRules>();
|
||||
ContentRegistry::Views::add<ViewTutorials>();
|
||||
|
||||
|
||||
LayoutManager::registerLoadCallback([](std::string_view line) {
|
||||
for (auto &[name, view] : ContentRegistry::Views::impl::getEntries()) {
|
||||
std::string format = hex::format("{}=%d", view->getUnlocalizedName().get());
|
||||
sscanf(line.data(), format.c_str(), &view->getWindowOpenState());
|
||||
}
|
||||
});
|
||||
|
||||
LayoutManager::registerStoreCallback([](ImGuiTextBuffer *buffer) {
|
||||
for (auto &[name, view] : ContentRegistry::Views::impl::getEntries()) {
|
||||
buffer->appendf("%s=%d\n", name.c_str(), view->getWindowOpenState());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
@@ -160,7 +160,7 @@ namespace hex::plugin::builtin {
|
||||
}
|
||||
|
||||
void drawOverlay(ImDrawList *drawList, ImVec2 windowMin, ImVec2 windowMax, const std::string &currCategory) {
|
||||
auto &achievements = AchievementManager::getAchievements()[currCategory];
|
||||
auto &achievements = AchievementManager::getAchievements().at(currCategory);
|
||||
|
||||
// Calculate number of achievements that have been unlocked
|
||||
const auto unlockedCount = std::count_if(achievements.begin(), achievements.end(), [](const auto &entry) {
|
||||
@@ -313,7 +313,7 @@ namespace hex::plugin::builtin {
|
||||
|
||||
// Draw each individual achievement category
|
||||
for (const auto &categoryName : categories) {
|
||||
const auto &achievements = startNodes[categoryName];
|
||||
const auto &achievements = startNodes.at(categoryName);
|
||||
|
||||
// Check if any achievements in the category are unlocked or unlockable
|
||||
bool visible = false;
|
||||
|
||||
@@ -803,7 +803,7 @@ namespace hex::plugin::builtin {
|
||||
RequestHexEditorSelectionChange::subscribe(this, [this](Region region) {
|
||||
auto provider = ImHexApi::Provider::get();
|
||||
|
||||
if (region == Region::Invalid()) {
|
||||
if (region == Region::Invalid() || provider == nullptr) {
|
||||
m_selectionStart->reset();
|
||||
m_selectionEnd->reset();
|
||||
EventRegionSelected::post(ImHexApi::HexEditor::ProviderRegion({ Region::Invalid(), nullptr }));
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#include <imgui_internal.h>
|
||||
|
||||
#include <hex/api/content_registry.hpp>
|
||||
#include <hex/api/layout_manager.hpp>
|
||||
|
||||
#include <fonts/codicons_font.h>
|
||||
|
||||
@@ -9,6 +10,21 @@ namespace hex::plugin::builtin {
|
||||
|
||||
ViewTools::ViewTools() : View::Window("hex.builtin.view.tools.name", ICON_VS_TOOLS) {
|
||||
m_dragStartIterator = ContentRegistry::Tools::impl::getEntries().end();
|
||||
|
||||
LayoutManager::registerLoadCallback([this](std::string_view line) {
|
||||
auto parts = wolv::util::splitString(std::string(line), "=");
|
||||
if (parts.size() != 2)
|
||||
return;
|
||||
|
||||
m_detachedTools[parts[0]] = parts[1] == "1";
|
||||
});
|
||||
|
||||
LayoutManager::registerStoreCallback([this](ImGuiTextBuffer *buffer) {
|
||||
for (auto &[unlocalizedName, function] : ContentRegistry::Tools::impl::getEntries()) {
|
||||
auto detached = m_detachedTools[unlocalizedName];
|
||||
buffer->appendf("%s=%d\n", unlocalizedName.get().c_str(), detached);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void ViewTools::drawContent() {
|
||||
@@ -16,13 +32,13 @@ namespace hex::plugin::builtin {
|
||||
|
||||
// Draw all tools
|
||||
for (auto iter = tools.begin(); iter != tools.end(); ++iter) {
|
||||
auto &[name, function, detached] = *iter;
|
||||
auto &[unlocalizedName, function] = *iter;
|
||||
|
||||
// If the tool has been detached from the main window, don't draw it here anymore
|
||||
if (detached) continue;
|
||||
if (m_detachedTools[unlocalizedName]) continue;
|
||||
|
||||
// Draw the tool
|
||||
if (ImGui::CollapsingHeader(Lang(name))) {
|
||||
if (ImGui::CollapsingHeader(Lang(unlocalizedName))) {
|
||||
function();
|
||||
ImGui::NewLine();
|
||||
} else {
|
||||
@@ -38,7 +54,7 @@ namespace hex::plugin::builtin {
|
||||
|
||||
// Detach the tool if the user dragged it out of the main window
|
||||
if (!ImGui::IsItemHovered() && m_dragStartIterator == iter) {
|
||||
detached = true;
|
||||
m_detachedTools[unlocalizedName] = true;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -53,19 +69,19 @@ namespace hex::plugin::builtin {
|
||||
auto &tools = ContentRegistry::Tools::impl::getEntries();
|
||||
|
||||
for (auto iter = tools.begin(); iter != tools.end(); ++iter) {
|
||||
auto &[name, function, detached] = *iter;
|
||||
auto &[unlocalizedName, function] = *iter;
|
||||
|
||||
// If the tool is still attached to the main window, don't draw it here
|
||||
if (!detached) continue;
|
||||
if (!m_detachedTools[unlocalizedName]) continue;
|
||||
|
||||
// Load the window height that is dependent on the tool content
|
||||
const auto windowName = View::toWindowName(name);
|
||||
const auto windowName = View::toWindowName(unlocalizedName);
|
||||
const auto height = m_windowHeights[ImGui::FindWindowByName(windowName.c_str())];
|
||||
if (height > 0)
|
||||
ImGui::SetNextWindowSizeConstraints(ImVec2(400_scaled, height), ImVec2(FLT_MAX, height));
|
||||
|
||||
// Create a new window for the tool
|
||||
if (ImGui::Begin(windowName.c_str(), &detached, ImGuiWindowFlags_NoCollapse)) {
|
||||
if (ImGui::Begin(windowName.c_str(), &m_detachedTools[unlocalizedName], ImGuiWindowFlags_NoCollapse)) {
|
||||
// Draw the tool content
|
||||
function();
|
||||
|
||||
|
||||
@@ -243,7 +243,7 @@ namespace hex::plugin::builtin {
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
|
||||
if (ImGuiExt::DescriptionButton("hex.builtin.welcome.update.title"_lang, hex::format("hex.builtin.welcome.update.desc"_lang, ImHexApi::System::getInitArguments()["update-available"]).c_str(), ImVec2(ImGui::GetContentRegionAvail().x * 0.8F, 0)))
|
||||
if (ImGuiExt::DescriptionButton("hex.builtin.welcome.update.title"_lang, hex::format("hex.builtin.welcome.update.desc"_lang, ImHexApi::System::getInitArgument("update-available")).c_str(), ImVec2(ImGui::GetContentRegionAvail().x * 0.8F, 0)))
|
||||
ImHexApi::System::updateImHex(ImHexApi::System::UpdateType::Stable);
|
||||
}
|
||||
|
||||
|
||||
@@ -180,7 +180,7 @@ namespace hex::plugin::builtin {
|
||||
#endif
|
||||
}
|
||||
|
||||
auto &titleBarButtons = ContentRegistry::Interface::impl::getTitleBarButtons();
|
||||
auto &titleBarButtons = ContentRegistry::Interface::impl::getTitlebarButtons();
|
||||
|
||||
// Draw custom title bar buttons
|
||||
if (!titleBarButtons.empty()) {
|
||||
|
||||
@@ -61,7 +61,7 @@ namespace hex::plugin::diffing {
|
||||
|
||||
ImGui::PushID(&column);
|
||||
|
||||
auto &providers = ImHexApi::Provider::getProviders();
|
||||
auto providers = ImHexApi::Provider::getProviders();
|
||||
auto &providerIndex = column.provider;
|
||||
|
||||
// Get the name of the currently selected provider
|
||||
|
||||
Reference in New Issue
Block a user