sys: Get rid of SharedData struct and cleanup code structure (#411)

* sys: Initial refactoring of the SharedData class

* sys/pattern: More refactoring, make every provider have its own patterns

* sys: Finished up refactoring. No more SharedData!

* sys: Fixed compile on Unix

* tests: Fixed unit tests

* sys: Moved view and lang files

* pattern: Added assignment operator support to for loops

* tests: Fixed compile issue
This commit is contained in:
WerWolv
2022-02-01 18:09:40 +01:00
committed by GitHub
parent 61fc479c79
commit 1991afb87b
110 changed files with 1592 additions and 1259 deletions

View File

@@ -268,7 +268,7 @@ macro(setDefaultBuiltTypeIfUnset)
endmacro() endmacro()
macro(detectBadClone) macro(detectBadClone)
file (GLOB EXTERNAL_DIRS "external/*") file (GLOB EXTERNAL_DIRS "lib/external/*")
foreach (EXTERNAL_DIR ${EXTERNAL_DIRS}) foreach (EXTERNAL_DIR ${EXTERNAL_DIRS})
file(GLOB RESULT "${EXTERNAL_DIR}/*") file(GLOB RESULT "${EXTERNAL_DIR}/*")
list(LENGTH RESULT ENTRY_COUNT) list(LENGTH RESULT ENTRY_COUNT)

View File

@@ -47,6 +47,7 @@
//#define IMGUI_DISABLE_DEFAULT_FILE_FUNCTIONS // Don't implement ImFileOpen/ImFileClose/ImFileRead/ImFileWrite and ImFileHandle so you can implement them yourself if you don't want to link with fopen/fclose/fread/fwrite. This will also disable the LogToTTY() function. //#define IMGUI_DISABLE_DEFAULT_FILE_FUNCTIONS // Don't implement ImFileOpen/ImFileClose/ImFileRead/ImFileWrite and ImFileHandle so you can implement them yourself if you don't want to link with fopen/fclose/fread/fwrite. This will also disable the LogToTTY() function.
//#define IMGUI_DISABLE_DEFAULT_ALLOCATORS // Don't implement default allocators calling malloc()/free() to avoid linking with them. You will need to call ImGui::SetAllocatorFunctions(). //#define IMGUI_DISABLE_DEFAULT_ALLOCATORS // Don't implement default allocators calling malloc()/free() to avoid linking with them. You will need to call ImGui::SetAllocatorFunctions().
//#define IMGUI_DISABLE_SSE // Disable use of SSE intrinsics even if available //#define IMGUI_DISABLE_SSE // Disable use of SSE intrinsics even if available
#define IMGUI_DEFINE_MATH_OPERATORS
//---- Include imgui_user.h at the end of imgui.h as a convenience //---- Include imgui_user.h at the end of imgui.h as a convenience
//#define IMGUI_INCLUDE_IMGUI_USER_H //#define IMGUI_INCLUDE_IMGUI_USER_H

View File

@@ -105,6 +105,8 @@ set(LIBIMHEX_SOURCES
source/api/content_registry.cpp source/api/content_registry.cpp
source/api/task.cpp source/api/task.cpp
source/api/keybinding.cpp source/api/keybinding.cpp
source/api/plugin_manager.cpp
source/api/localization.cpp
source/data_processor/attribute.cpp source/data_processor/attribute.cpp
source/data_processor/link.cpp source/data_processor/link.cpp
@@ -113,9 +115,7 @@ set(LIBIMHEX_SOURCES
source/helpers/utils.cpp source/helpers/utils.cpp
source/helpers/paths.cpp source/helpers/paths.cpp
source/helpers/magic.cpp source/helpers/magic.cpp
source/helpers/shared_data.cpp
source/helpers/crypto.cpp source/helpers/crypto.cpp
source/helpers/lang.cpp
source/helpers/net.cpp source/helpers/net.cpp
source/helpers/file.cpp source/helpers/file.cpp
source/helpers/socket.cpp source/helpers/socket.cpp
@@ -136,8 +136,7 @@ set(LIBIMHEX_SOURCES
source/providers/provider.cpp source/providers/provider.cpp
source/ui/imgui_imhex_extensions.cpp source/ui/imgui_imhex_extensions.cpp
source/ui/view.cpp
source/views/view.cpp
) )
if (APPLE) if (APPLE)
@@ -164,4 +163,4 @@ if (APPLE)
target_link_libraries(libimhex PUBLIC ${FOUNDATION}) target_link_libraries(libimhex PUBLIC ${FOUNDATION})
endif () endif ()
target_link_libraries(libimhex PUBLIC imgui nfd magic ${CAPSTONE_LIBRARIES} LLVMDemangle microtar ${NLOHMANN_JSON_LIBRARIES} ${YARA_LIBRARIES} ${LIBCURL_LIBRARIES} ${MBEDTLS_LIBRARIES} ${FMT_LIBRARIES} ${Python_LIBRARIES} libromfs) target_link_libraries(libimhex PUBLIC dl imgui nfd magic ${CAPSTONE_LIBRARIES} LLVMDemangle microtar ${NLOHMANN_JSON_LIBRARIES} ${YARA_LIBRARIES} ${LIBCURL_LIBRARIES} ${MBEDTLS_LIBRARIES} ${FMT_LIBRARIES} ${Python_LIBRARIES} libromfs)

View File

@@ -18,6 +18,8 @@ using i32 = std::int32_t;
using i64 = std::int64_t; using i64 = std::int64_t;
using i128 = __int128_t; using i128 = __int128_t;
using color_t = u32;
namespace hex { namespace hex {
struct Region { struct Region {

View File

@@ -92,6 +92,15 @@ namespace hex {
/* Pattern Language Function Registry. Allows adding of new functions that may be used inside the pattern language */ /* Pattern Language Function Registry. Allows adding of new functions that may be used inside the pattern language */
namespace PatternLanguage { namespace PatternLanguage {
namespace impl {
struct ColorPalette {
std::string name;
std::vector<u32> colors;
};
}
constexpr static u32 UnlimitedParameters = 0xFFFF'FFFF; constexpr static u32 UnlimitedParameters = 0xFFFF'FFFF;
constexpr static u32 MoreParametersThan = 0x8000'0000; constexpr static u32 MoreParametersThan = 0x8000'0000;
constexpr static u32 LessParametersThan = 0x4000'0000; constexpr static u32 LessParametersThan = 0x4000'0000;
@@ -110,6 +119,12 @@ namespace hex {
void addFunction(const Namespace &ns, const std::string &name, u32 parameterCount, const Callback &func); void addFunction(const Namespace &ns, const std::string &name, u32 parameterCount, const Callback &func);
void addDangerousFunction(const Namespace &ns, const std::string &name, u32 parameterCount, const Callback &func); void addDangerousFunction(const Namespace &ns, const std::string &name, u32 parameterCount, const Callback &func);
std::map<std::string, ContentRegistry::PatternLanguage::Function> &getFunctions(); std::map<std::string, ContentRegistry::PatternLanguage::Function> &getFunctions();
std::vector<impl::ColorPalette>& getPalettes();
void addColorPalette(const std::string &unlocalizedName, const std::vector<u32> &colors);
void setSelectedPalette(u32 index);
u32 getNextColor();
void resetPalette();
} }
/* View Registry. Allows adding of new windows */ /* View Registry. Allows adding of new windows */
@@ -249,8 +264,6 @@ namespace hex {
} }
u32 getDockSpaceId();
void registerMainMenuItem(const std::string &unlocalizedName, u32 priority); void registerMainMenuItem(const std::string &unlocalizedName, u32 priority);
void addMenuItem(const std::string &unlocalizedMainMenuName, u32 priority, const impl::DrawCallback &function); void addMenuItem(const std::string &unlocalizedMainMenuName, u32 priority, const impl::DrawCallback &function);
@@ -298,7 +311,7 @@ namespace hex {
impl::addProviderName(unlocalizedName); impl::addProviderName(unlocalizedName);
} }
const std::vector<std::string> &getEntries(); std::vector<std::string> &getEntries();
} }

View File

@@ -113,12 +113,13 @@ namespace hex {
EVENT_DEF(EventAbnormalTermination, int); EVENT_DEF(EventAbnormalTermination, int);
EVENT_DEF(EventOSThemeChanged); EVENT_DEF(EventOSThemeChanged);
EVENT_DEF(EventProviderCreated, prv::Provider *); EVENT_DEF(EventProviderCreated, prv::Provider *);
EVENT_DEF(EventProviderChanged, prv::Provider *, prv::Provider *);
EVENT_DEF(EventFrameBegin); EVENT_DEF(EventFrameBegin);
EVENT_DEF(EventFrameEnd); EVENT_DEF(EventFrameEnd);
EVENT_DEF(RequestOpenWindow, std::string); EVENT_DEF(RequestOpenWindow, std::string);
EVENT_DEF(RequestSelectionChange, Region); EVENT_DEF(RequestSelectionChange, Region);
EVENT_DEF(RequestAddBookmark, ImHexApi::Bookmarks::Entry); EVENT_DEF(RequestAddBookmark, Region, std::string, std::string, color_t);
EVENT_DEF(RequestSetPatternLanguageCode, std::string); EVENT_DEF(RequestSetPatternLanguageCode, std::string);
EVENT_DEF(RequestChangeWindowTitle, std::string); EVENT_DEF(RequestChangeWindowTitle, std::string);
EVENT_DEF(RequestCloseImHex, bool); EVENT_DEF(RequestCloseImHex, bool);

View File

@@ -10,6 +10,8 @@
#include <hex/api/task.hpp> #include <hex/api/task.hpp>
#include <hex/api/keybinding.hpp> #include <hex/api/keybinding.hpp>
#include <imgui.h>
namespace hex { namespace hex {
namespace prv { namespace prv {
@@ -17,34 +19,62 @@ namespace hex {
} }
namespace ImHexApi { namespace ImHexApi {
namespace Common { namespace Common {
void closeImHex(bool noQuestions = false); void closeImHex(bool noQuestions = false);
void restartImHex(); void restartImHex();
}; }
namespace HexEditor {
class Highlighting {
public:
Highlighting() = default;
Highlighting(Region region, color_t color, const std::string &tooltip = "");
[[nodiscard]] const Region &getRegion() const { return this->m_region; }
[[nodiscard]] const color_t &getColor() const { return this->m_color; }
[[nodiscard]] const std::string &getTooltip() const { return this->m_tooltip; }
private:
Region m_region;
color_t m_color;
std::string m_tooltip;
};
u32 addHighlight(const Region &region, color_t color, std::string tooltip = "");
void removeHighlight(u32 id);
std::map<u32, Highlighting> &getHighlights();
}
namespace Bookmarks { namespace Bookmarks {
struct Entry { struct Entry {
Region region; Region region;
std::vector<char> name; std::string name;
std::vector<char> comment; std::string comment;
u32 color; u32 color;
bool locked; bool locked;
u32 highlightId;
}; };
void add(Region region, const std::string &name, const std::string &comment, u32 color = 0x00000000); void add(Region region, const std::string &name, const std::string &comment, color_t color = 0x00000000);
void add(u64 addr, size_t size, const std::string &name, const std::string &comment, u32 color = 0x00000000); void add(u64 address, size_t size, const std::string &name, const std::string &comment, color_t color = 0x00000000);
std::list<Entry> &getEntries(); }
};
namespace Provider { namespace Provider {
prv::Provider *get(); prv::Provider *get();
const std::vector<prv::Provider *> &getProviders(); const std::vector<prv::Provider *> &getProviders();
void setCurrentProvider(u32 index);
bool isValid(); bool isValid();
void add(prv::Provider *provider); void add(prv::Provider *provider);
@@ -56,14 +86,51 @@ namespace hex {
void remove(prv::Provider *provider); void remove(prv::Provider *provider);
}; }
namespace Tasks { namespace Tasks {
Task createTask(const std::string &unlocalizedName, u64 maxValue); Task createTask(const std::string &unlocalizedName, u64 maxValue);
void doLater(const std::function<void()> &function);
std::vector<std::function<void()>>& getDeferredCalls();
} }
}; namespace System {
namespace impl {
void setMainWindowPosition(u32 x, u32 y);
void setMainWindowSize(u32 width, u32 height);
void setMainDockSpaceId(ImGuiID id);
void setGlobalScale(float scale);
void setProgramArguments(int argc, char **argv, char **envp);
}
struct ProgramArguments {
int argc;
char **argv;
char **envp;
};
const ProgramArguments& getProgramArguments();
float getTargetFPS();
void setTargetFPS(float fps);
float getGlobalScale();
ImVec2 getMainWindowPosition();
ImVec2 getMainWindowSize();
ImGuiID getMainDockSpaceId();
std::map<std::string, std::string>& getInitArguments();
}
}
} }

View File

@@ -185,6 +185,10 @@ namespace hex {
static void addGlobalShortcut(const Shortcut &shortcut, const std::function<void()> &callback); static void addGlobalShortcut(const Shortcut &shortcut, const std::function<void()> &callback);
static void addShortcut(View *view, const Shortcut &shortcut, const std::function<void()> &callback); static void addShortcut(View *view, const Shortcut &shortcut, const std::function<void()> &callback);
static void process(View *currentView, bool ctrl, bool alt, bool shift, bool super, bool focused, u32 keyCode); static void process(View *currentView, bool ctrl, bool alt, bool shift, bool super, bool focused, u32 keyCode);
static void clearShortcuts();
private:
static std::map<Shortcut, std::function<void()>> s_globalShortcuts;
}; };
} }

View File

@@ -35,10 +35,13 @@ namespace hex {
static void setFallbackLanguage(const std::string &language); static void setFallbackLanguage(const std::string &language);
static const std::string &getFallbackLanguage(); static const std::string &getFallbackLanguage();
static void resetLanguageStrings();
private: private:
std::string m_unlocalizedString; std::string m_unlocalizedString;
static std::string s_fallbackLanguage; static std::string s_fallbackLanguage;
static std::map<std::string, std::string> s_currStrings;
}; };
std::string operator+(const std::string &&left, const LangEntry &&right); std::string operator+(const std::string &&left, const LangEntry &&right);
@@ -49,13 +52,8 @@ namespace hex {
std::string operator+(const LangEntry &&left, const char *right); std::string operator+(const LangEntry &&left, const char *right);
std::string operator+(const LangEntry &&left, const LangEntry &&right); std::string operator+(const LangEntry &&left, const LangEntry &&right);
namespace lang_literals { inline LangEntry operator""_lang(const char *string, size_t) {
return LangEntry(string);
inline LangEntry operator""_lang(const char *string, size_t) {
return LangEntry(string);
}
} }
} }

View File

@@ -24,6 +24,7 @@ namespace hex {
[[nodiscard]] std::string getPluginDescription() const; [[nodiscard]] std::string getPluginDescription() const;
[[nodiscard]] std::string getCompatibleVersion() const; [[nodiscard]] std::string getCompatibleVersion() const;
void setImGuiContext(ImGuiContext *ctx) const; void setImGuiContext(ImGuiContext *ctx) const;
[[nodiscard]] bool isBuiltinPlugin() const;
[[nodiscard]] const fs::path &getPath() const; [[nodiscard]] const fs::path &getPath() const;
@@ -36,6 +37,7 @@ namespace hex {
using GetPluginDescriptionFunc = const char *(*)(); using GetPluginDescriptionFunc = const char *(*)();
using GetCompatibleVersionFunc = const char *(*)(); using GetCompatibleVersionFunc = const char *(*)();
using SetImGuiContextFunc = void (*)(ImGuiContext *); using SetImGuiContextFunc = void (*)(ImGuiContext *);
using IsBuiltinPluginFunc = bool(*)();
void *m_handle = nullptr; void *m_handle = nullptr;
fs::path m_path; fs::path m_path;
@@ -48,6 +50,7 @@ namespace hex {
GetPluginDescriptionFunc m_getPluginDescriptionFunction = nullptr; GetPluginDescriptionFunc m_getPluginDescriptionFunction = nullptr;
GetCompatibleVersionFunc m_getCompatibleVersionFunction = nullptr; GetCompatibleVersionFunc m_getCompatibleVersionFunction = nullptr;
SetImGuiContextFunc m_setImGuiContextFunction = nullptr; SetImGuiContextFunc m_setImGuiContextFunction = nullptr;
IsBuiltinPluginFunc m_isBuiltinPluginFunction = nullptr;
template<typename T> template<typename T>
[[nodiscard]] auto getPluginFunction(const std::string &symbol) { [[nodiscard]] auto getPluginFunction(const std::string &symbol) {
@@ -71,8 +74,8 @@ namespace hex {
} }
private: private:
static inline fs::path s_pluginFolder; static fs::path s_pluginFolder;
static inline std::vector<Plugin> s_plugins; static std::vector<Plugin> s_plugins;
}; };
} }

View File

@@ -2,6 +2,8 @@
#include <hex.hpp> #include <hex.hpp>
#include <list>
#include <mutex>
#include <string> #include <string>
namespace hex { namespace hex {
@@ -21,9 +23,16 @@ namespace hex {
[[nodiscard]] bool isPending() const; [[nodiscard]] bool isPending() const;
static size_t getRunningTaskCount();
static std::list<Task *>& getRunningTasks() { return Task::s_runningTasks; }
static std::mutex& getTaskMutex() { return Task::s_taskMutex; }
private: private:
std::string m_name; std::string m_name;
u64 m_maxValue, m_currValue; u64 m_maxValue, m_currValue;
static std::list<Task *> s_runningTasks;
static std::mutex s_taskMutex;
}; };
} }

View File

@@ -27,8 +27,8 @@ namespace hex::dp {
Attribute(IOType ioType, Type type, std::string unlocalizedName); Attribute(IOType ioType, Type type, std::string unlocalizedName);
~Attribute(); ~Attribute();
[[nodiscard]] u32 getID() const { return this->m_id; } [[nodiscard]] u32 getId() const { return this->m_id; }
void setID(u32 id) { this->m_id = id; } void setId(u32 id) { this->m_id = id; }
[[nodiscard]] IOType getIOType() const { return this->m_ioType; } [[nodiscard]] IOType getIOType() const { return this->m_ioType; }
[[nodiscard]] Type getType() const { return this->m_type; } [[nodiscard]] Type getType() const { return this->m_type; }
@@ -42,6 +42,11 @@ namespace hex::dp {
[[nodiscard]] std::optional<std::vector<u8>> &getOutputData() { return this->m_outputData; } [[nodiscard]] std::optional<std::vector<u8>> &getOutputData() { return this->m_outputData; }
static void setIdCounter(u32 id) {
if (id > Attribute::s_idCounter)
Attribute::s_idCounter = id;
}
private: private:
u32 m_id; u32 m_id;
IOType m_ioType; IOType m_ioType;
@@ -54,6 +59,8 @@ namespace hex::dp {
friend class Node; friend class Node;
void setParentNode(Node *node) { this->m_parentNode = node; } void setParentNode(Node *node) { this->m_parentNode = node; }
static u32 s_idCounter;
}; };
} }

View File

@@ -8,15 +8,22 @@ namespace hex::dp {
public: public:
Link(u32 from, u32 to); Link(u32 from, u32 to);
[[nodiscard]] u32 getID() const { return this->m_id; } [[nodiscard]] u32 getId() const { return this->m_id; }
void setID(u32 id) { this->m_id = id; } void setID(u32 id) { this->m_id = id; }
[[nodiscard]] u32 getFromID() const { return this->m_from; } [[nodiscard]] u32 getFromId() const { return this->m_from; }
[[nodiscard]] u32 getToID() const { return this->m_to; } [[nodiscard]] u32 getToId() const { return this->m_to; }
static void setIdCounter(u32 id) {
if (id > Link::s_idCounter)
Link::s_idCounter = id;
}
private: private:
u32 m_id; u32 m_id;
u32 m_from, m_to; u32 m_from, m_to;
static u32 s_idCounter;
}; };
} }

View File

@@ -22,8 +22,8 @@ namespace hex::dp {
virtual ~Node() = default; virtual ~Node() = default;
[[nodiscard]] u32 getID() const { return this->m_id; } [[nodiscard]] u32 getId() const { return this->m_id; }
void setID(u32 id) { this->m_id = id; } void setId(u32 id) { this->m_id = id; }
[[nodiscard]] const std::string &getUnlocalizedName() const { return this->m_unlocalizedName; } [[nodiscard]] const std::string &getUnlocalizedName() const { return this->m_unlocalizedName; }
void setUnlocalizedName(const std::string &unlocalizedName) { this->m_unlocalizedName = unlocalizedName; } void setUnlocalizedName(const std::string &unlocalizedName) { this->m_unlocalizedName = unlocalizedName; }
@@ -52,6 +52,11 @@ namespace hex::dp {
this->m_processedInputs.clear(); this->m_processedInputs.clear();
} }
static void setIdCounter(u32 id) {
if (id > Node::s_idCounter)
Node::s_idCounter = id;
}
private: private:
u32 m_id; u32 m_id;
std::string m_unlocalizedTitle, m_unlocalizedName; std::string m_unlocalizedTitle, m_unlocalizedName;
@@ -59,6 +64,8 @@ namespace hex::dp {
std::set<u32> m_processedInputs; std::set<u32> m_processedInputs;
prv::Overlay *m_overlay = nullptr; prv::Overlay *m_overlay = nullptr;
static u32 s_idCounter;
Attribute *getConnectedInputAttribute(u32 index) { Attribute *getConnectedInputAttribute(u32 index) {
if (index >= this->getAttributes().size()) if (index >= this->getAttributes().size())
throw std::runtime_error("Attribute index out of bounds!"); throw std::runtime_error("Attribute index out of bounds!");

View File

@@ -1,135 +0,0 @@
#pragma once
#include <any>
#include <functional>
#include <list>
#include <map>
#include <memory>
#include <mutex>
#include <vector>
#include <hex/api/content_registry.hpp>
#include <hex/api/imhex_api.hpp>
#include <hex/api/task.hpp>
#include <hex/views/view.hpp>
#include <imgui.h>
#include <nlohmann/json_fwd.hpp>
namespace hex {
class SharedData;
}
namespace hex::plugin::internal {
void initializePlugin(SharedData &sharedData);
}
namespace hex {
namespace prv {
class Provider;
}
namespace dp {
class Node;
}
namespace pl {
class PatternData;
}
class View;
class SharedData {
SharedData() = default;
public:
SharedData(const SharedData &) = delete;
SharedData(SharedData &&) = delete;
friend class Window;
template<typename T>
static T &getVariable(std::string variableName) {
return std::any_cast<T &>(SharedData::sharedVariables[variableName]);
}
template<typename T>
static void setVariable(std::string variableName, T value) {
SharedData::sharedVariables[variableName] = value;
}
static void clearVariables() {
SharedData::sharedVariables.clear();
}
public:
static std::vector<std::function<void()>> deferredCalls;
static std::vector<prv::Provider *> providers;
static u32 currentProvider;
static std::map<std::string, std::vector<ContentRegistry::Settings::Entry>> settingsEntries;
static nlohmann::json settingsJson;
static std::vector<ContentRegistry::CommandPaletteCommands::Entry> commandPaletteCommands;
static std::map<std::string, ContentRegistry::PatternLanguage::Function> patternLanguageFunctions;
static std::map<std::string, View *> views;
static std::vector<ContentRegistry::Tools::impl::Entry> toolsEntries;
static std::vector<ContentRegistry::DataInspector::impl::Entry> dataInspectorEntries;
static u32 patternPaletteOffset;
static std::string popupMessage;
static std::list<ImHexApi::Bookmarks::Entry> bookmarkEntries;
static std::vector<pl::PatternData *> patternData;
static u32 selectableFileIndex;
static std::vector<fs::path> selectableFiles;
static std::function<void(fs::path)> selectableFileOpenCallback;
static std::vector<nfdfilteritem_t> selectableFilesValidExtensions;
static std::map<std::string, std::string> languageNames;
static std::map<std::string, std::vector<LanguageDefinition>> languageDefinitions;
static std::map<std::string, std::string> loadedLanguageStrings;
static ImGuiID dockSpaceId;
static std::multimap<u32, ContentRegistry::Interface::impl::MainMenuItem> mainMenuItems;
static std::multimap<u32, ContentRegistry::Interface::impl::MenuItem> menuItems;
static std::vector<ContentRegistry::Interface::impl::DrawCallback> welcomeScreenEntries;
static std::vector<ContentRegistry::Interface::impl::DrawCallback> footerItems;
static std::vector<ContentRegistry::Interface::impl::DrawCallback> toolbarItems;
static std::vector<ContentRegistry::Interface::impl::SidebarItem> sidebarItems;
static std::vector<ContentRegistry::Interface::impl::Layout> layouts;
static std::map<Shortcut, std::function<void()>> globalShortcuts;
static std::mutex tasksMutex;
static std::list<Task *> runningTasks;
static std::vector<std::string> providerNames;
static std::vector<ContentRegistry::DataProcessorNode::impl::Entry> dataProcessorNodes;
static u32 dataProcessorNodeIdCounter;
static u32 dataProcessorLinkIdCounter;
static u32 dataProcessorAttrIdCounter;
static std::vector<ContentRegistry::DataFormatter::impl::Entry> dataFormatters;
static std::vector<ContentRegistry::FileHandler::impl::Entry> fileHandlers;
static std::list<fs::path> recentFilePaths;
static int mainArgc;
static char **mainArgv;
static char **mainEnvp;
static ImFontAtlas *fontAtlas;
static ImFontConfig fontConfig;
static ImVec2 windowPos;
static ImVec2 windowSize;
static float globalScale;
static float fontScale;
private:
static std::map<std::string, std::any> sharedVariables;
};
}

View File

@@ -400,21 +400,21 @@ namespace hex::pl {
PatternData *pattern; PatternData *pattern;
if (Token::isUnsigned(this->m_type)) if (Token::isUnsigned(this->m_type))
pattern = new PatternDataUnsigned(offset, size); pattern = new PatternDataUnsigned(evaluator, offset, size);
else if (Token::isSigned(this->m_type)) else if (Token::isSigned(this->m_type))
pattern = new PatternDataSigned(offset, size); pattern = new PatternDataSigned(evaluator, offset, size);
else if (Token::isFloatingPoint(this->m_type)) else if (Token::isFloatingPoint(this->m_type))
pattern = new PatternDataFloat(offset, size); pattern = new PatternDataFloat(evaluator, offset, size);
else if (this->m_type == Token::ValueType::Boolean) else if (this->m_type == Token::ValueType::Boolean)
pattern = new PatternDataBoolean(offset); pattern = new PatternDataBoolean(evaluator, offset);
else if (this->m_type == Token::ValueType::Character) else if (this->m_type == Token::ValueType::Character)
pattern = new PatternDataCharacter(offset); pattern = new PatternDataCharacter(evaluator, offset);
else if (this->m_type == Token::ValueType::Character16) else if (this->m_type == Token::ValueType::Character16)
pattern = new PatternDataCharacter16(offset); pattern = new PatternDataCharacter16(evaluator, offset);
else if (this->m_type == Token::ValueType::Padding) else if (this->m_type == Token::ValueType::Padding)
pattern = new PatternDataPadding(offset, 1); pattern = new PatternDataPadding(evaluator, offset, 1);
else if (this->m_type == Token::ValueType::String) else if (this->m_type == Token::ValueType::String)
pattern = new PatternDataString(offset, 1); pattern = new PatternDataString(evaluator, offset, 1);
else if (this->m_type == Token::ValueType::Auto) else if (this->m_type == Token::ValueType::Auto)
return { nullptr }; return { nullptr };
else else
@@ -972,13 +972,13 @@ namespace hex::pl {
PatternData *outputPattern; PatternData *outputPattern;
if (dynamic_cast<PatternDataPadding *>(templatePattern)) { if (dynamic_cast<PatternDataPadding *>(templatePattern)) {
outputPattern = new PatternDataPadding(startOffset, 0); outputPattern = new PatternDataPadding(evaluator, startOffset, 0);
} else if (dynamic_cast<PatternDataCharacter *>(templatePattern)) { } else if (dynamic_cast<PatternDataCharacter *>(templatePattern)) {
outputPattern = new PatternDataString(startOffset, 0); outputPattern = new PatternDataString(evaluator, startOffset, 0);
} else if (dynamic_cast<PatternDataCharacter16 *>(templatePattern)) { } else if (dynamic_cast<PatternDataCharacter16 *>(templatePattern)) {
outputPattern = new PatternDataString16(startOffset, 0); outputPattern = new PatternDataString16(evaluator, startOffset, 0);
} else { } else {
auto arrayPattern = new PatternDataStaticArray(startOffset, 0); auto arrayPattern = new PatternDataStaticArray(evaluator, startOffset, 0);
arrayPattern->setEntries(templatePattern->clone(), entryCount); arrayPattern->setEntries(templatePattern->clone(), entryCount);
outputPattern = arrayPattern; outputPattern = arrayPattern;
} }
@@ -995,7 +995,7 @@ namespace hex::pl {
} }
PatternData *createDynamicArray(Evaluator *evaluator) const { PatternData *createDynamicArray(Evaluator *evaluator) const {
auto arrayPattern = new PatternDataDynamicArray(evaluator->dataOffset(), 0); auto arrayPattern = new PatternDataDynamicArray(evaluator, evaluator->dataOffset(), 0);
arrayPattern->setVariableName(this->m_name); arrayPattern->setVariableName(this->m_name);
std::vector<PatternData *> entries; std::vector<PatternData *> entries;
@@ -1192,7 +1192,7 @@ namespace hex::pl {
auto sizePattern = this->m_sizeType->createPatterns(evaluator).front(); auto sizePattern = this->m_sizeType->createPatterns(evaluator).front();
ON_SCOPE_EXIT { delete sizePattern; }; ON_SCOPE_EXIT { delete sizePattern; };
auto pattern = new PatternDataPointer(startOffset, sizePattern->getSize()); auto pattern = new PatternDataPointer(evaluator, startOffset, sizePattern->getSize());
pattern->setVariableName(this->m_name); pattern->setVariableName(this->m_name);
auto endOffset = evaluator->dataOffset(); auto endOffset = evaluator->dataOffset();
@@ -1298,7 +1298,7 @@ namespace hex::pl {
} }
[[nodiscard]] std::vector<PatternData *> createPatterns(Evaluator *evaluator) const override { [[nodiscard]] std::vector<PatternData *> createPatterns(Evaluator *evaluator) const override {
auto pattern = new PatternDataStruct(evaluator->dataOffset(), 0); auto pattern = new PatternDataStruct(evaluator, evaluator->dataOffset(), 0);
u64 startOffset = evaluator->dataOffset(); u64 startOffset = evaluator->dataOffset();
std::vector<PatternData *> memberPatterns; std::vector<PatternData *> memberPatterns;
@@ -1370,7 +1370,7 @@ namespace hex::pl {
} }
[[nodiscard]] std::vector<PatternData *> createPatterns(Evaluator *evaluator) const override { [[nodiscard]] std::vector<PatternData *> createPatterns(Evaluator *evaluator) const override {
auto pattern = new PatternDataUnion(evaluator->dataOffset(), 0); auto pattern = new PatternDataUnion(evaluator, evaluator->dataOffset(), 0);
size_t size = 0; size_t size = 0;
std::vector<PatternData *> memberPatterns; std::vector<PatternData *> memberPatterns;
@@ -1430,7 +1430,7 @@ namespace hex::pl {
} }
[[nodiscard]] std::vector<PatternData *> createPatterns(Evaluator *evaluator) const override { [[nodiscard]] std::vector<PatternData *> createPatterns(Evaluator *evaluator) const override {
auto pattern = new PatternDataEnum(evaluator->dataOffset(), 0); auto pattern = new PatternDataEnum(evaluator, evaluator->dataOffset(), 0);
auto enumCleanup = SCOPE_GUARD { delete pattern; }; auto enumCleanup = SCOPE_GUARD { delete pattern; };
@@ -1487,7 +1487,7 @@ namespace hex::pl {
void addEntry(const std::string &name, ASTNode *size) { this->m_entries.emplace_back(name, size); } void addEntry(const std::string &name, ASTNode *size) { this->m_entries.emplace_back(name, size); }
[[nodiscard]] std::vector<PatternData *> createPatterns(Evaluator *evaluator) const override { [[nodiscard]] std::vector<PatternData *> createPatterns(Evaluator *evaluator) const override {
auto pattern = new PatternDataBitfield(evaluator->dataOffset(), 0); auto pattern = new PatternDataBitfield(evaluator, evaluator->dataOffset(), 0);
size_t bitOffset = 0; size_t bitOffset = 0;
std::vector<PatternData *> fields; std::vector<PatternData *> fields;
@@ -1511,7 +1511,7 @@ namespace hex::pl {
// If a field is named padding, it was created through a padding expression and only advances the bit position // If a field is named padding, it was created through a padding expression and only advances the bit position
if (name != "padding") { if (name != "padding") {
auto field = new PatternDataBitfieldField(evaluator->dataOffset(), bitOffset, bitSize, pattern); auto field = new PatternDataBitfieldField(evaluator, evaluator->dataOffset(), bitOffset, bitSize, pattern);
field->setVariableName(name); field->setVariableName(name);
fields.push_back(field); fields.push_back(field);
} }
@@ -1627,7 +1627,7 @@ namespace hex::pl {
std::visit(overloaded { std::visit(overloaded {
[&](char assignmentValue) { if (assignmentValue != 0x00) value = std::string({ assignmentValue }); }, [&](char assignmentValue) { if (assignmentValue != 0x00) value = std::string({ assignmentValue }); },
[&](const std::string &assignmentValue) { value = assignmentValue; }, [&](std::string assignmentValue) { value = assignmentValue; },
[&, this](PatternData *const &assignmentValue) { [&, this](PatternData *const &assignmentValue) {
if (!dynamic_cast<PatternDataString *>(assignmentValue) && !dynamic_cast<PatternDataCharacter *>(assignmentValue)) if (!dynamic_cast<PatternDataString *>(assignmentValue) && !dynamic_cast<PatternDataCharacter *>(assignmentValue))
LogConsole::abortEvaluation(hex::format("cannot assign '{}' to string", pattern->getTypeName()), this); LogConsole::abortEvaluation(hex::format("cannot assign '{}' to string", pattern->getTypeName()), this);

View File

@@ -8,7 +8,7 @@
#include <hex/pattern_language/token.hpp> #include <hex/pattern_language/token.hpp>
#include <hex/pattern_language/evaluator.hpp> #include <hex/pattern_language/evaluator.hpp>
#include <hex/views/view.hpp> #include <hex/ui/view.hpp>
#include <hex/helpers/utils.hpp> #include <hex/helpers/utils.hpp>
#include <hex/helpers/fmt.hpp> #include <hex/helpers/fmt.hpp>
#include <hex/helpers/concepts.hpp> #include <hex/helpers/concepts.hpp>
@@ -55,47 +55,39 @@ namespace hex::pl {
class PatternCreationLimiter { class PatternCreationLimiter {
public: public:
explicit PatternCreationLimiter() { explicit PatternCreationLimiter(Evaluator *evaluator) : m_evaluator(evaluator) {
if (PatternCreationLimiter::s_evaluator == nullptr) return; if (getEvaluator() == nullptr) return;
PatternCreationLimiter::s_evaluator->patternCreated(); getEvaluator()->patternCreated();
} }
PatternCreationLimiter(const PatternCreationLimiter &other) { PatternCreationLimiter(const PatternCreationLimiter &other) : PatternCreationLimiter(other.m_evaluator) { }
if (PatternCreationLimiter::s_evaluator == nullptr) return;
PatternCreationLimiter::s_evaluator->patternCreated();
}
virtual ~PatternCreationLimiter() { virtual ~PatternCreationLimiter() {
if (PatternCreationLimiter::s_evaluator == nullptr) return; if (getEvaluator() == nullptr) return;
PatternCreationLimiter::s_evaluator->patternDestroyed(); getEvaluator()->patternDestroyed();
} }
[[nodiscard]] [[nodiscard]]
static Evaluator *getEvaluator() { Evaluator* getEvaluator() const {
return PatternCreationLimiter::s_evaluator; return this->m_evaluator;
} }
private:
public: Evaluator *m_evaluator = nullptr;
static Evaluator *s_evaluator;
}; };
class PatternData : public PatternCreationLimiter, public Cloneable<PatternData> { class PatternData : public PatternCreationLimiter, public Cloneable<PatternData> {
public: public:
PatternData(u64 offset, size_t size, u32 color = 0) PatternData(Evaluator *evaluator, u64 offset, size_t size, u32 color = 0)
: PatternCreationLimiter(), m_offset(offset), m_size(size), m_color(color) { : PatternCreationLimiter(evaluator), m_offset(offset), m_size(size), m_color(color) {
constexpr u32 Palette[] = { 0x70b4771f, 0x700e7fff, 0x702ca02c, 0x702827d6, 0x70bd6794, 0x704b568c, 0x70c277e3, 0x707f7f7f, 0x7022bdbc, 0x70cfbe17 }; constexpr u32 Palette[] = { 0x70b4771f, 0x700e7fff, 0x702ca02c, 0x702827d6, 0x70bd6794, 0x704b568c, 0x70c277e3, 0x707f7f7f, 0x7022bdbc, 0x70cfbe17 };
if (color != 0) if (color != 0)
return; return;
this->m_color = Palette[SharedData::patternPaletteOffset++]; this->m_color = ContentRegistry::PatternLanguage::getNextColor();
this->m_manualColor = false; this->m_manualColor = false;
if (SharedData::patternPaletteOffset >= (sizeof(Palette) / sizeof(u32)))
SharedData::patternPaletteOffset = 0;
} }
PatternData(const PatternData &other) = default; PatternData(const PatternData &other) = default;
@@ -125,8 +117,8 @@ namespace hex::pl {
[[nodiscard]] bool hasOverriddenColor() const { return this->m_manualColor; } [[nodiscard]] bool hasOverriddenColor() const { return this->m_manualColor; }
[[nodiscard]] std::endian getEndian() const { [[nodiscard]] std::endian getEndian() const {
if (PatternData::getEvaluator() == nullptr) return std::endian::native; if (this->getEvaluator() == nullptr) return std::endian::native;
else return this->m_endian.value_or(PatternData::getEvaluator()->getDefaultEndian()); else return this->m_endian.value_or(this->getEvaluator()->getDefaultEndian());
} }
virtual void setEndian(std::endian endian) { this->m_endian = endian; } virtual void setEndian(std::endian endian) { this->m_endian = endian; }
[[nodiscard]] bool hasOverriddenEndian() const { return this->m_endian.has_value(); } [[nodiscard]] bool hasOverriddenEndian() const { return this->m_endian.has_value(); }
@@ -155,7 +147,7 @@ namespace hex::pl {
for (u64 i = 0; i < this->getSize(); i++) for (u64 i = 0; i < this->getSize(); i++)
highlight.insert({ this->getOffset() + i, this->getColor() }); highlight.insert({ this->getOffset() + i, this->getColor() });
PatternData::getEvaluator()->handleAbort(); this->getEvaluator()->handleAbort();
} }
virtual void sort(ImGuiTableSortSpecs *sortSpecs, prv::Provider *provider) { } virtual void sort(ImGuiTableSortSpecs *sortSpecs, prv::Provider *provider) { }
@@ -217,8 +209,6 @@ namespace hex::pl {
this->createEntry(provider); this->createEntry(provider);
} }
static void resetPalette() { SharedData::patternPaletteOffset = 0; }
void setHidden(bool hidden) { void setHidden(bool hidden) {
this->m_hidden = hidden; this->m_hidden = hidden;
} }
@@ -256,7 +246,7 @@ namespace hex::pl {
return value; return value;
else { else {
try { try {
auto result = this->m_formatterFunction->func(PatternData::getEvaluator(), { literal }); auto result = this->m_formatterFunction->func(this->getEvaluator(), { literal });
if (result.has_value()) { if (result.has_value()) {
if (auto displayValue = std::get_if<std::string>(&result.value()); displayValue != nullptr) if (auto displayValue = std::get_if<std::string>(&result.value()); displayValue != nullptr)
@@ -326,7 +316,7 @@ namespace hex::pl {
class PatternDataPadding : public PatternData { class PatternDataPadding : public PatternData {
public: public:
PatternDataPadding(u64 offset, size_t size) : PatternData(offset, size, 0xFF000000) { } PatternDataPadding(Evaluator *evaluator, u64 offset, size_t size) : PatternData(evaluator, offset, size, 0xFF000000) { }
[[nodiscard]] [[nodiscard]]
PatternData *clone() const override { PatternData *clone() const override {
@@ -345,8 +335,8 @@ namespace hex::pl {
class PatternDataPointer : public PatternData { class PatternDataPointer : public PatternData {
public: public:
PatternDataPointer(u64 offset, size_t size, u32 color = 0) PatternDataPointer(Evaluator *evaluator, u64 offset, size_t size, u32 color = 0)
: PatternData(offset, size, color), m_pointedAt(nullptr) { : PatternData(evaluator, offset, size, color), m_pointedAt(nullptr) {
} }
PatternDataPointer(const PatternDataPointer &other) : PatternData(other) { PatternDataPointer(const PatternDataPointer &other) : PatternData(other) {
@@ -476,8 +466,8 @@ namespace hex::pl {
class PatternDataUnsigned : public PatternData { class PatternDataUnsigned : public PatternData {
public: public:
PatternDataUnsigned(u64 offset, size_t size, u32 color = 0) PatternDataUnsigned(Evaluator *evaluator, u64 offset, size_t size, u32 color = 0)
: PatternData(offset, size, color) { } : PatternData(evaluator, offset, size, color) { }
[[nodiscard]] [[nodiscard]]
PatternData *clone() const override { PatternData *clone() const override {
@@ -514,8 +504,8 @@ namespace hex::pl {
class PatternDataSigned : public PatternData { class PatternDataSigned : public PatternData {
public: public:
PatternDataSigned(u64 offset, size_t size, u32 color = 0) PatternDataSigned(Evaluator *evaluator, u64 offset, size_t size, u32 color = 0)
: PatternData(offset, size, color) { } : PatternData(evaluator, offset, size, color) { }
[[nodiscard]] [[nodiscard]]
PatternData *clone() const override { PatternData *clone() const override {
@@ -553,8 +543,8 @@ namespace hex::pl {
class PatternDataFloat : public PatternData { class PatternDataFloat : public PatternData {
public: public:
PatternDataFloat(u64 offset, size_t size, u32 color = 0) PatternDataFloat(Evaluator *evaluator, u64 offset, size_t size, u32 color = 0)
: PatternData(offset, size, color) { } : PatternData(evaluator, offset, size, color) { }
[[nodiscard]] [[nodiscard]]
PatternData *clone() const override { PatternData *clone() const override {
@@ -593,8 +583,8 @@ namespace hex::pl {
class PatternDataBoolean : public PatternData { class PatternDataBoolean : public PatternData {
public: public:
explicit PatternDataBoolean(u64 offset, u32 color = 0) explicit PatternDataBoolean(Evaluator *evaluator, u64 offset, u32 color = 0)
: PatternData(offset, 1, color) { } : PatternData(evaluator, offset, 1, color) { }
[[nodiscard]] [[nodiscard]]
PatternData *clone() const override { PatternData *clone() const override {
@@ -622,8 +612,8 @@ namespace hex::pl {
class PatternDataCharacter : public PatternData { class PatternDataCharacter : public PatternData {
public: public:
explicit PatternDataCharacter(u64 offset, u32 color = 0) explicit PatternDataCharacter(Evaluator *evaluator, u64 offset, u32 color = 0)
: PatternData(offset, 1, color) { } : PatternData(evaluator, offset, 1, color) { }
[[nodiscard]] [[nodiscard]]
PatternData *clone() const override { PatternData *clone() const override {
@@ -646,8 +636,8 @@ namespace hex::pl {
class PatternDataCharacter16 : public PatternData { class PatternDataCharacter16 : public PatternData {
public: public:
explicit PatternDataCharacter16(u64 offset, u32 color = 0) explicit PatternDataCharacter16(Evaluator *evaluator, u64 offset, u32 color = 0)
: PatternData(offset, 2, color) { } : PatternData(evaluator, offset, 2, color) { }
[[nodiscard]] [[nodiscard]]
PatternData *clone() const override { PatternData *clone() const override {
@@ -680,8 +670,8 @@ namespace hex::pl {
class PatternDataString : public PatternData { class PatternDataString : public PatternData {
public: public:
PatternDataString(u64 offset, size_t size, u32 color = 0) PatternDataString(Evaluator *evaluator, u64 offset, size_t size, u32 color = 0)
: PatternData(offset, size, color) { } : PatternData(evaluator, offset, size, color) { }
[[nodiscard]] [[nodiscard]]
PatternData *clone() const override { PatternData *clone() const override {
@@ -721,8 +711,8 @@ namespace hex::pl {
class PatternDataString16 : public PatternData { class PatternDataString16 : public PatternData {
public: public:
PatternDataString16(u64 offset, size_t size, u32 color = 0) PatternDataString16(Evaluator *evaluator, u64 offset, size_t size, u32 color = 0)
: PatternData(offset, size, color) { } : PatternData(evaluator, offset, size, color) { }
[[nodiscard]] [[nodiscard]]
PatternData *clone() const override { PatternData *clone() const override {
@@ -774,8 +764,8 @@ namespace hex::pl {
class PatternDataDynamicArray : public PatternData, class PatternDataDynamicArray : public PatternData,
public Inlinable { public Inlinable {
public: public:
PatternDataDynamicArray(u64 offset, size_t size, u32 color = 0) PatternDataDynamicArray(Evaluator *evaluator, u64 offset, size_t size, u32 color = 0)
: PatternData(offset, size, color) { : PatternData(evaluator, offset, size, color) {
} }
PatternDataDynamicArray(const PatternDataDynamicArray &other) : PatternData(other) { PatternDataDynamicArray(const PatternDataDynamicArray &other) : PatternData(other) {
@@ -931,8 +921,8 @@ namespace hex::pl {
class PatternDataStaticArray : public PatternData, class PatternDataStaticArray : public PatternData,
public Inlinable { public Inlinable {
public: public:
PatternDataStaticArray(u64 offset, size_t size, u32 color = 0) PatternDataStaticArray(Evaluator *evaluator, u64 offset, size_t size, u32 color = 0)
: PatternData(offset, size, color) { : PatternData(evaluator, offset, size, color) {
} }
PatternDataStaticArray(const PatternDataStaticArray &other) : PatternData(other) { PatternDataStaticArray(const PatternDataStaticArray &other) : PatternData(other) {
@@ -1089,8 +1079,8 @@ namespace hex::pl {
class PatternDataStruct : public PatternData, class PatternDataStruct : public PatternData,
public Inlinable { public Inlinable {
public: public:
PatternDataStruct(u64 offset, size_t size, u32 color = 0) PatternDataStruct(Evaluator *evaluator, u64 offset, size_t size, u32 color = 0)
: PatternData(offset, size, color) { : PatternData(evaluator, offset, size, color) {
} }
PatternDataStruct(const PatternDataStruct &other) : PatternData(other) { PatternDataStruct(const PatternDataStruct &other) : PatternData(other) {
@@ -1237,8 +1227,8 @@ namespace hex::pl {
class PatternDataUnion : public PatternData, class PatternDataUnion : public PatternData,
public Inlinable { public Inlinable {
public: public:
PatternDataUnion(u64 offset, size_t size, u32 color = 0) PatternDataUnion(Evaluator *evaluator, u64 offset, size_t size, u32 color = 0)
: PatternData(offset, size, color) { : PatternData(evaluator, offset, size, color) {
} }
PatternDataUnion(const PatternDataUnion &other) : PatternData(other) { PatternDataUnion(const PatternDataUnion &other) : PatternData(other) {
@@ -1386,8 +1376,8 @@ namespace hex::pl {
class PatternDataEnum : public PatternData { class PatternDataEnum : public PatternData {
public: public:
PatternDataEnum(u64 offset, size_t size, u32 color = 0) PatternDataEnum(Evaluator *evaluator, u64 offset, size_t size, u32 color = 0)
: PatternData(offset, size, color) { : PatternData(evaluator, offset, size, color) {
} }
[[nodiscard]] [[nodiscard]]
@@ -1482,8 +1472,8 @@ namespace hex::pl {
class PatternDataBitfieldField : public PatternData { class PatternDataBitfieldField : public PatternData {
public: public:
PatternDataBitfieldField(u64 offset, u8 bitOffset, u8 bitSize, PatternData *bitField, u32 color = 0) PatternDataBitfieldField(Evaluator *evaluator, u64 offset, u8 bitOffset, u8 bitSize, PatternData *bitField, u32 color = 0)
: m_bitOffset(bitOffset), m_bitSize(bitSize), m_bitField(bitField), PatternData(offset, 0, color) { : PatternData(evaluator, offset, 0, color), m_bitOffset(bitOffset), m_bitSize(bitSize), m_bitField(bitField) {
} }
[[nodiscard]] [[nodiscard]]
@@ -1552,8 +1542,8 @@ namespace hex::pl {
class PatternDataBitfield : public PatternData, class PatternDataBitfield : public PatternData,
public Inlinable { public Inlinable {
public: public:
PatternDataBitfield(u64 offset, size_t size, u32 color = 0) PatternDataBitfield(Evaluator *evaluator, u64 offset, size_t size, u32 color = 0)
: PatternData(offset, size, color) { : PatternData(evaluator, offset, size, color) {
} }
PatternDataBitfield(const PatternDataBitfield &other) : PatternData(other) { PatternDataBitfield(const PatternDataBitfield &other) : PatternData(other) {

View File

@@ -33,8 +33,8 @@ namespace hex::pl {
~PatternLanguage(); ~PatternLanguage();
[[nodiscard]] std::optional<std::vector<ASTNode *>> parseString(const std::string &code); [[nodiscard]] std::optional<std::vector<ASTNode *>> parseString(const std::string &code);
[[nodiscard]] std::optional<std::vector<PatternData *>> executeString(prv::Provider *provider, const std::string &string, const std::map<std::string, Token::Literal> &envVars = {}, const std::map<std::string, Token::Literal> &inVariables = {}); [[nodiscard]] bool executeString(prv::Provider *provider, const std::string &string, const std::map<std::string, Token::Literal> &envVars = {}, const std::map<std::string, Token::Literal> &inVariables = {});
[[nodiscard]] std::optional<std::vector<PatternData *>> executeFile(prv::Provider *provider, const fs::path &path, const std::map<std::string, Token::Literal> &envVars = {}, const std::map<std::string, Token::Literal> &inVariables = {}); [[nodiscard]] bool executeFile(prv::Provider *provider, const fs::path &path, const std::map<std::string, Token::Literal> &envVars = {}, const std::map<std::string, Token::Literal> &inVariables = {});
[[nodiscard]] const std::vector<ASTNode *> &getCurrentAST() const; [[nodiscard]] const std::vector<ASTNode *> &getCurrentAST() const;
void abort(); void abort();
@@ -49,6 +49,13 @@ namespace hex::pl {
[[nodiscard]] bool hasDangerousFunctionBeenCalled() const; [[nodiscard]] bool hasDangerousFunctionBeenCalled() const;
void allowDangerousFunctions(bool allow); void allowDangerousFunctions(bool allow);
[[nodiscard]] std::vector<PatternData*> &getPatterns() {
return this->m_patterns;
}
void reset();
bool isRunning() const { return this->m_running; }
private: private:
Preprocessor *m_preprocessor; Preprocessor *m_preprocessor;
Lexer *m_lexer; Lexer *m_lexer;
@@ -59,6 +66,10 @@ namespace hex::pl {
std::vector<ASTNode *> m_currAST; std::vector<ASTNode *> m_currAST;
std::optional<PatternLanguageError> m_currError; std::optional<PatternLanguageError> m_currError;
std::vector<PatternData*> m_patterns;
bool m_running = false;
}; };
} }

View File

@@ -2,13 +2,14 @@
#include <hex.hpp> #include <hex.hpp>
#include <list>
#include <map> #include <map>
#include <optional> #include <optional>
#include <string> #include <string>
#include <vector> #include <vector>
#include <hex/helpers/shared_data.hpp>
#include <hex/providers/overlay.hpp> #include <hex/providers/overlay.hpp>
#include <hex/pattern_language/pattern_language.hpp>
namespace hex::prv { namespace hex::prv {
@@ -78,6 +79,9 @@ namespace hex::prv {
virtual void drawLoadInterface(); virtual void drawLoadInterface();
virtual void drawInterface(); virtual void drawInterface();
pl::PatternLanguage& getPatternLanguageRuntime() { return this->m_patternLanguageRuntime; }
std::string& getPatternLanguageSourceCode() { return this->m_patternLanguageSourceCode; }
protected: protected:
u32 m_currPage = 0; u32 m_currPage = 0;
u64 m_baseAddress = 0; u64 m_baseAddress = 0;
@@ -85,6 +89,9 @@ namespace hex::prv {
u32 m_patchTreeOffset = 0; u32 m_patchTreeOffset = 0;
std::list<std::map<u64, u8>> m_patches; std::list<std::map<u64, u8>> m_patches;
std::list<Overlay *> m_overlays; std::list<Overlay *> m_overlays;
pl::PatternLanguage m_patternLanguageRuntime;
std::string m_patternLanguageSourceCode;
}; };
} }

View File

@@ -14,7 +14,7 @@
#include <hex/api/event.hpp> #include <hex/api/event.hpp>
#include <hex/providers/provider.hpp> #include <hex/providers/provider.hpp>
#include <hex/helpers/lang.hpp> #include <hex/api/localization.hpp>
#include <functional> #include <functional>
#include <string> #include <string>
@@ -23,8 +23,6 @@
namespace hex { namespace hex {
using namespace hex::lang_literals;
class View { class View {
public: public:
explicit View(std::string unlocalizedViewName); explicit View(std::string unlocalizedViewName);
@@ -32,11 +30,8 @@ namespace hex {
virtual void drawContent() = 0; virtual void drawContent() = 0;
virtual void drawAlwaysVisible() { } virtual void drawAlwaysVisible() { }
virtual bool isAvailable() const; [[nodiscard]] virtual bool isAvailable() const;
virtual bool shouldProcess() const { return this->isAvailable() && this->getWindowOpenState(); } [[nodiscard]] virtual bool shouldProcess() const { return this->isAvailable() && this->getWindowOpenState(); }
static void doLater(std::function<void()> &&function);
static std::vector<std::function<void()>> &getDeferedCalls();
static void drawCommonInterfaces(); static void drawCommonInterfaces();
@@ -46,12 +41,12 @@ namespace hex {
static void showFileChooserPopup(const std::vector<fs::path> &paths, const std::vector<nfdfilteritem_t> &validExtensions, const std::function<void(fs::path)> &callback); static void showFileChooserPopup(const std::vector<fs::path> &paths, const std::vector<nfdfilteritem_t> &validExtensions, const std::function<void(fs::path)> &callback);
virtual bool hasViewMenuItemEntry() const; [[nodiscard]] virtual bool hasViewMenuItemEntry() const;
virtual ImVec2 getMinSize() const; [[nodiscard]] virtual ImVec2 getMinSize() const;
virtual ImVec2 getMaxSize() const; [[nodiscard]] virtual ImVec2 getMaxSize() const;
bool &getWindowOpenState(); [[nodiscard]] bool &getWindowOpenState();
const bool &getWindowOpenState() const; [[nodiscard]] const bool &getWindowOpenState() const;
[[nodiscard]] const std::string &getUnlocalizedName() const; [[nodiscard]] const std::string &getUnlocalizedName() const;
[[nodiscard]] std::string getName() const; [[nodiscard]] std::string getName() const;
@@ -63,11 +58,27 @@ namespace hex {
return LangEntry(unlocalizedName) + "###" + unlocalizedName; return LangEntry(unlocalizedName) + "###" + unlocalizedName;
} }
static ImFontAtlas *getFontAtlas() { return View::s_fontAtlas; }
static void setFontAtlas(ImFontAtlas *atlas) { View::s_fontAtlas = atlas; }
static ImFontConfig getFontConfig() { return View::s_fontConfig; }
static void setFontConfig(ImFontConfig config) { View::s_fontConfig = config; }
private: private:
std::string m_unlocalizedViewName; std::string m_unlocalizedViewName;
bool m_windowOpen = false; bool m_windowOpen = false;
std::map<Shortcut, std::function<void()>> m_shortcuts; std::map<Shortcut, std::function<void()>> m_shortcuts;
static std::string s_popupMessage;
static u32 s_selectableFileIndex;
static std::vector<fs::path> s_selectableFiles;
static std::function<void(fs::path)> s_selectableFileOpenCallback;
static std::vector<nfdfilteritem_t> s_selectableFilesValidExtensions;
static ImFontAtlas *s_fontAtlas;
static ImFontConfig s_fontConfig;
friend class ShortcutManager; friend class ShortcutManager;
}; };

View File

@@ -1,9 +1,10 @@
#include <hex/api/content_registry.hpp> #include <hex/api/content_registry.hpp>
#include <hex/helpers/shared_data.hpp>
#include <hex/helpers/paths.hpp> #include <hex/helpers/paths.hpp>
#include <hex/helpers/logger.hpp> #include <hex/helpers/logger.hpp>
#include <hex/ui/view.hpp>
#include <filesystem> #include <filesystem>
#include <fstream> #include <fstream>
@@ -141,7 +142,9 @@ namespace hex {
std::map<std::string, std::vector<ContentRegistry::Settings::Entry>> &ContentRegistry::Settings::getEntries() { std::map<std::string, std::vector<ContentRegistry::Settings::Entry>> &ContentRegistry::Settings::getEntries() {
return SharedData::settingsEntries; static std::map<std::string, std::vector<ContentRegistry::Settings::Entry>> entries;
return entries;
} }
nlohmann::json ContentRegistry::Settings::getSetting(const std::string &unlocalizedCategory, const std::string &unlocalizedName) { nlohmann::json ContentRegistry::Settings::getSetting(const std::string &unlocalizedCategory, const std::string &unlocalizedName) {
@@ -154,7 +157,9 @@ namespace hex {
} }
nlohmann::json &ContentRegistry::Settings::getSettingsData() { nlohmann::json &ContentRegistry::Settings::getSettingsData() {
return SharedData::settingsJson; static nlohmann::json settings;
return settings;
} }
@@ -167,7 +172,9 @@ namespace hex {
} }
std::vector<ContentRegistry::CommandPaletteCommands::Entry> &ContentRegistry::CommandPaletteCommands::getEntries() { std::vector<ContentRegistry::CommandPaletteCommands::Entry> &ContentRegistry::CommandPaletteCommands::getEntries() {
return SharedData::commandPaletteCommands; static std::vector<ContentRegistry::CommandPaletteCommands::Entry> commands;
return commands;
} }
@@ -197,7 +204,50 @@ namespace hex {
} }
std::map<std::string, ContentRegistry::PatternLanguage::Function> &ContentRegistry::PatternLanguage::getFunctions() { std::map<std::string, ContentRegistry::PatternLanguage::Function> &ContentRegistry::PatternLanguage::getFunctions() {
return SharedData::patternLanguageFunctions; static std::map<std::string, ContentRegistry::PatternLanguage::Function> functions;
return functions;
}
static std::vector<ContentRegistry::PatternLanguage::impl::ColorPalette> s_colorPalettes;
static u32 s_colorIndex;
static u32 s_selectedColorPalette;
std::vector<ContentRegistry::PatternLanguage::impl::ColorPalette> &ContentRegistry::PatternLanguage::getPalettes() {
return s_colorPalettes;
}
void ContentRegistry::PatternLanguage::addColorPalette(const std::string &unlocalizedName, const std::vector<u32> &colors) {
s_colorPalettes.push_back({
unlocalizedName,
colors
});
}
void ContentRegistry::PatternLanguage::setSelectedPalette(u32 index) {
if (index < s_colorPalettes.size())
s_selectedColorPalette = index;
resetPalette();
}
u32 ContentRegistry::PatternLanguage::getNextColor() {
if (s_colorPalettes.empty())
return 0x00;
auto &currColors = s_colorPalettes[s_selectedColorPalette].colors;
u32 color = currColors[s_colorIndex];
s_colorIndex++;
s_colorIndex %= currColors.size();
return color;
}
void ContentRegistry::PatternLanguage::resetPalette() {
s_colorIndex = 0;
} }
@@ -210,7 +260,9 @@ namespace hex {
} }
std::map<std::string, View *> &ContentRegistry::Views::getEntries() { std::map<std::string, View *> &ContentRegistry::Views::getEntries() {
return SharedData::views; static std::map<std::string, View *> views;
return views;
} }
View *ContentRegistry::Views::getViewByName(const std::string &unlocalizedName) { View *ContentRegistry::Views::getViewByName(const std::string &unlocalizedName) {
@@ -232,7 +284,9 @@ namespace hex {
} }
std::vector<ContentRegistry::Tools::impl::Entry> &ContentRegistry::Tools::getEntries() { std::vector<ContentRegistry::Tools::impl::Entry> &ContentRegistry::Tools::getEntries() {
return SharedData::toolsEntries; static std::vector<ContentRegistry::Tools::impl::Entry> entries;
return entries;
} }
@@ -245,7 +299,9 @@ namespace hex {
} }
std::vector<ContentRegistry::DataInspector::impl::Entry> &ContentRegistry::DataInspector::getEntries() { std::vector<ContentRegistry::DataInspector::impl::Entry> &ContentRegistry::DataInspector::getEntries() {
return SharedData::dataInspectorEntries; static std::vector<ContentRegistry::DataInspector::impl::Entry> entries;
return entries;
} }
/* Data Processor Nodes */ /* Data Processor Nodes */
@@ -261,7 +317,9 @@ namespace hex {
} }
std::vector<ContentRegistry::DataProcessorNode::impl::Entry> &ContentRegistry::DataProcessorNode::getEntries() { std::vector<ContentRegistry::DataProcessorNode::impl::Entry> &ContentRegistry::DataProcessorNode::getEntries() {
return SharedData::dataProcessorNodes; static std::vector<ContentRegistry::DataProcessorNode::impl::Entry> nodes;
return nodes;
} }
/* Languages */ /* Languages */
@@ -279,20 +337,20 @@ namespace hex {
} }
std::map<std::string, std::string> &ContentRegistry::Language::getLanguages() { std::map<std::string, std::string> &ContentRegistry::Language::getLanguages() {
return SharedData::languageNames; static std::map<std::string, std::string> languages;
return languages;
} }
std::map<std::string, std::vector<LanguageDefinition>> &ContentRegistry::Language::getLanguageDefinitions() { std::map<std::string, std::vector<LanguageDefinition>> &ContentRegistry::Language::getLanguageDefinitions() {
return SharedData::languageDefinitions; static std::map<std::string, std::vector<LanguageDefinition>> definitions;
return definitions;
} }
/* Interface */ /* Interface */
u32 ContentRegistry::Interface::getDockSpaceId() {
return SharedData::dockSpaceId;
}
void ContentRegistry::Interface::registerMainMenuItem(const std::string &unlocalizedName, u32 priority) { void ContentRegistry::Interface::registerMainMenuItem(const std::string &unlocalizedName, u32 priority) {
log::info("Registered new main menu item: {}", unlocalizedName); log::info("Registered new main menu item: {}", unlocalizedName);
@@ -331,27 +389,41 @@ namespace hex {
std::multimap<u32, ContentRegistry::Interface::impl::MainMenuItem> &ContentRegistry::Interface::getMainMenuItems() { std::multimap<u32, ContentRegistry::Interface::impl::MainMenuItem> &ContentRegistry::Interface::getMainMenuItems() {
return SharedData::mainMenuItems; static std::multimap<u32, ContentRegistry::Interface::impl::MainMenuItem> items;
return items;
} }
std::multimap<u32, ContentRegistry::Interface::impl::MenuItem> &ContentRegistry::Interface::getMenuItems() { std::multimap<u32, ContentRegistry::Interface::impl::MenuItem> &ContentRegistry::Interface::getMenuItems() {
return SharedData::menuItems; static std::multimap<u32, ContentRegistry::Interface::impl::MenuItem> items;
return items;
} }
std::vector<ContentRegistry::Interface::impl::DrawCallback> &ContentRegistry::Interface::getWelcomeScreenEntries() { std::vector<ContentRegistry::Interface::impl::DrawCallback> &ContentRegistry::Interface::getWelcomeScreenEntries() {
return SharedData::welcomeScreenEntries; static std::vector<ContentRegistry::Interface::impl::DrawCallback> entries;
return entries;
} }
std::vector<ContentRegistry::Interface::impl::DrawCallback> &ContentRegistry::Interface::getFooterItems() { std::vector<ContentRegistry::Interface::impl::DrawCallback> &ContentRegistry::Interface::getFooterItems() {
return SharedData::footerItems; static std::vector<ContentRegistry::Interface::impl::DrawCallback> items;
return items;
} }
std::vector<ContentRegistry::Interface::impl::DrawCallback> &ContentRegistry::Interface::getToolbarItems() { std::vector<ContentRegistry::Interface::impl::DrawCallback> &ContentRegistry::Interface::getToolbarItems() {
return SharedData::toolbarItems; static std::vector<ContentRegistry::Interface::impl::DrawCallback> items;
return items;
} }
std::vector<ContentRegistry::Interface::impl::SidebarItem> &ContentRegistry::Interface::getSidebarItems() { std::vector<ContentRegistry::Interface::impl::SidebarItem> &ContentRegistry::Interface::getSidebarItems() {
return SharedData::sidebarItems; static std::vector<ContentRegistry::Interface::impl::SidebarItem> items;
return items;
} }
std::vector<ContentRegistry::Interface::impl::Layout> &ContentRegistry::Interface::getLayouts() { std::vector<ContentRegistry::Interface::impl::Layout> &ContentRegistry::Interface::getLayouts() {
return SharedData::layouts; static std::vector<ContentRegistry::Interface::impl::Layout> layouts;
return layouts;
} }
@@ -360,11 +432,13 @@ namespace hex {
void ContentRegistry::Provider::impl::addProviderName(const std::string &unlocalizedName) { void ContentRegistry::Provider::impl::addProviderName(const std::string &unlocalizedName) {
log::info("Registered new provider: {}", unlocalizedName); log::info("Registered new provider: {}", unlocalizedName);
SharedData::providerNames.push_back(unlocalizedName); getEntries().push_back(unlocalizedName);
} }
const std::vector<std::string> &ContentRegistry::Provider::getEntries() { std::vector<std::string> &ContentRegistry::Provider::getEntries() {
return SharedData::providerNames; static std::vector<std::string> providerNames;
return providerNames;
} }
@@ -373,11 +447,13 @@ namespace hex {
void ContentRegistry::DataFormatter::add(const std::string &unlocalizedName, const impl::Callback &callback) { void ContentRegistry::DataFormatter::add(const std::string &unlocalizedName, const impl::Callback &callback) {
log::info("Registered new data formatter: {}", unlocalizedName); log::info("Registered new data formatter: {}", unlocalizedName);
ContentRegistry::DataFormatter::getEntries().push_back({ unlocalizedName, callback }); getEntries().push_back({ unlocalizedName, callback });
} }
std::vector<ContentRegistry::DataFormatter::impl::Entry> &ContentRegistry::DataFormatter::getEntries() { std::vector<ContentRegistry::DataFormatter::impl::Entry> &ContentRegistry::DataFormatter::getEntries() {
return SharedData::dataFormatters; static std::vector<ContentRegistry::DataFormatter::impl::Entry> entries;
return entries;
} }
@@ -387,10 +463,12 @@ namespace hex {
for (const auto &extension : extensions) for (const auto &extension : extensions)
log::info("Registered new data handler for extensions: {}", extension); log::info("Registered new data handler for extensions: {}", extension);
ContentRegistry::FileHandler::getEntries().push_back({ extensions, callback }); getEntries().push_back({ extensions, callback });
} }
std::vector<ContentRegistry::FileHandler::impl::Entry> &ContentRegistry::FileHandler::getEntries() { std::vector<ContentRegistry::FileHandler::impl::Entry> &ContentRegistry::FileHandler::getEntries() {
return SharedData::fileHandlers; static std::vector<ContentRegistry::FileHandler::impl::Entry> entries;
return entries;
} }
} }

View File

@@ -1,89 +1,213 @@
#include <hex/api/imhex_api.hpp> #include <hex/api/imhex_api.hpp>
#include <hex/api/event.hpp> #include <hex/api/event.hpp>
#include <hex/helpers/shared_data.hpp> #include <hex/providers/provider.hpp>
#include <unistd.h> #include <unistd.h>
#include <hex/helpers/logger.hpp>
namespace hex { namespace hex {
void ImHexApi::Common::closeImHex(bool noQuestions) { namespace ImHexApi::Common {
EventManager::post<RequestCloseImHex>(noQuestions);
} void closeImHex(bool noQuestions) {
EventManager::post<RequestCloseImHex>(noQuestions);
}
void restartImHex() {
EventManager::post<RequestCloseImHex>(false);
std::atexit([] {
auto &programArgs = ImHexApi::System::getProgramArguments();
execve(programArgs.argv[0], programArgs.argv, programArgs.envp);
});
}
void ImHexApi::Common::restartImHex() {
EventManager::post<RequestCloseImHex>(false);
std::atexit([] {
execve(SharedData::mainArgv[0], SharedData::mainArgv, SharedData::mainEnvp);
});
} }
void ImHexApi::Bookmarks::add(Region region, const std::string &name, const std::string &comment, u32 color) { namespace ImHexApi::HexEditor {
Entry entry;
entry.region = region; static std::map<u32, ImHexApi::HexEditor::Highlighting> s_highlights;
entry.name.reserve(name.length()); Highlighting::Highlighting(Region region, color_t color, const std::string &tooltip)
entry.comment.reserve(comment.length()); : m_region(region), m_color(color), m_tooltip(tooltip) {
std::copy(name.begin(), name.end(), std::back_inserter(entry.name)); }
std::copy(comment.begin(), comment.end(), std::back_inserter(entry.comment));
entry.locked = false;
entry.color = color; u32 addHighlight(const Region &region, color_t color, std::string tooltip) {
auto id = s_highlights.size();
EventManager::post<RequestAddBookmark>(entry); s_highlights.insert({ id, Highlighting{ region, color, tooltip } });
}
void ImHexApi::Bookmarks::add(u64 addr, size_t size, const std::string &name, const std::string &comment, u32 color) { return id;
Bookmarks::add(Region { addr, size }, name, comment, color); }
}
void removeHighlight(u32 id) {
s_highlights.erase(id);
}
std::map<u32, Highlighting> &getHighlights() {
return s_highlights;
}
std::list<ImHexApi::Bookmarks::Entry> &ImHexApi::Bookmarks::getEntries() {
return SharedData::bookmarkEntries;
} }
prv::Provider *ImHexApi::Provider::get() { namespace ImHexApi::Bookmarks {
if (!ImHexApi::Provider::isValid())
return nullptr;
return SharedData::providers[SharedData::currentProvider]; void add(Region region, const std::string &name, const std::string &comment, u32 color) {
} EventManager::post<RequestAddBookmark>(region, name, comment, color);
}
const std::vector<prv::Provider *> &ImHexApi::Provider::getProviders() { void add(u64 address, size_t size, const std::string &name, const std::string &comment, u32 color) {
return SharedData::providers; add(Region { address, size }, name, comment, color);
} }
bool ImHexApi::Provider::isValid() {
return !SharedData::providers.empty();
}
void ImHexApi::Provider::add(prv::Provider *provider) {
SharedData::providers.push_back(provider);
SharedData::currentProvider = SharedData::providers.size() - 1;
EventManager::post<EventProviderCreated>(provider);
}
void ImHexApi::Provider::remove(prv::Provider *provider) {
auto &providers = SharedData::providers;
auto it = std::find(providers.begin(), providers.end(), provider);
providers.erase(it);
if (it - providers.begin() == SharedData::currentProvider)
SharedData::currentProvider = 0;
delete provider;
} }
Task ImHexApi::Tasks::createTask(const std::string &unlocalizedName, u64 maxValue) { namespace ImHexApi::Provider {
return Task(unlocalizedName, maxValue);
static u32 s_currentProvider;
static std::vector<prv::Provider*> s_providers;
prv::Provider *get() {
if (!ImHexApi::Provider::isValid())
return nullptr;
return s_providers[s_currentProvider];
}
const std::vector<prv::Provider *> &getProviders() {
return s_providers;
}
void setCurrentProvider(u32 index) {
if (index < s_providers.size()) {
auto oldProvider = get();
s_currentProvider = index;
EventManager::post<EventProviderChanged>(oldProvider, get());
}
}
bool isValid() {
return !s_providers.empty();
}
void add(prv::Provider *provider) {
s_providers.push_back(provider);
setCurrentProvider(s_providers.size() - 1);
EventManager::post<EventProviderCreated>(provider);
}
void remove(prv::Provider *provider) {
auto it = std::find(s_providers.begin(), s_providers.end(), provider);
s_providers.erase(it);
if (it - s_providers.begin() == s_currentProvider)
s_currentProvider = 0;
delete provider;
}
}
namespace ImHexApi::Tasks {
Task createTask(const std::string &unlocalizedName, u64 maxValue) {
return Task(unlocalizedName, maxValue);
}
std::vector<std::function<void()>> s_deferredCalls;
void doLater(const std::function<void()> &function) {
getDeferredCalls().push_back(function);
}
std::vector<std::function<void()>>& getDeferredCalls() {
return s_deferredCalls;
}
}
namespace ImHexApi::System {
namespace impl {
static ImVec2 s_mainWindowPos;
static ImVec2 s_mainWindowSize;
void setMainWindowPosition(u32 x, u32 y) {
s_mainWindowPos = ImVec2(x, y);
}
void setMainWindowSize(u32 width, u32 height) {
s_mainWindowSize = ImVec2(width, height);
}
static ImGuiID s_mainDockSpaceId;
void setMainDockSpaceId(ImGuiID id) {
s_mainDockSpaceId = id;
}
static float s_globalScale;
void setGlobalScale(float scale) {
s_globalScale = scale;
}
static ProgramArguments s_programArguments;
void setProgramArguments(int argc, char **argv, char **envp) {
s_programArguments.argc = argc;
s_programArguments.argv = argv;
s_programArguments.envp = envp;
}
}
const ProgramArguments& getProgramArguments() {
return impl::s_programArguments;
}
static float s_targetFPS = 60.0F;
float getTargetFPS() {
return s_targetFPS;
}
void setTargetFPS(float fps) {
s_targetFPS = fps;
}
float getGlobalScale() {
return impl::s_globalScale;
}
ImVec2 getMainWindowPosition() {
return impl::s_mainWindowPos;
}
ImVec2 getMainWindowSize() {
return impl::s_mainWindowSize;
}
ImGuiID getMainDockSpaceId() {
return impl::s_mainDockSpaceId;
}
std::map<std::string, std::string>& getInitArguments() {
static std::map<std::string, std::string> initArgs;
return initArgs;
}
} }
} }

View File

@@ -1,13 +1,14 @@
#include <hex/api/keybinding.hpp> #include <hex/api/keybinding.hpp>
#include <hex/helpers/shared_data.hpp>
#include <imgui.h> #include <imgui.h>
#include <hex/views/view.hpp> #include <hex/ui/view.hpp>
namespace hex { namespace hex {
std::map<Shortcut, std::function<void()>> ShortcutManager::s_globalShortcuts;
void ShortcutManager::addGlobalShortcut(const Shortcut &shortcut, const std::function<void()> &callback) { void ShortcutManager::addGlobalShortcut(const Shortcut &shortcut, const std::function<void()> &callback) {
SharedData::globalShortcuts.insert({ shortcut, callback }); ShortcutManager::s_globalShortcuts.insert({ shortcut, callback });
} }
void ShortcutManager::addShortcut(View *view, const Shortcut &shortcut, const std::function<void()> &callback) { void ShortcutManager::addShortcut(View *view, const Shortcut &shortcut, const std::function<void()> &callback) {
@@ -30,8 +31,12 @@ namespace hex {
if (focused && currentView->m_shortcuts.contains(pressedShortcut)) if (focused && currentView->m_shortcuts.contains(pressedShortcut))
currentView->m_shortcuts[pressedShortcut](); currentView->m_shortcuts[pressedShortcut]();
else if (SharedData::globalShortcuts.contains(pressedShortcut)) else if (ShortcutManager::s_globalShortcuts.contains(pressedShortcut))
SharedData::globalShortcuts[pressedShortcut](); ShortcutManager::s_globalShortcuts[pressedShortcut]();
}
void ShortcutManager::clearShortcuts() {
ShortcutManager::s_globalShortcuts.clear();
} }
} }

View File

@@ -1,10 +1,11 @@
#include "hex/helpers/lang.hpp" #include <hex/api/localization.hpp>
#include "hex/helpers/shared_data.hpp" #include <hex/api/content_registry.hpp>
namespace hex { namespace hex {
std::string LangEntry::s_fallbackLanguage; std::string LangEntry::s_fallbackLanguage;
std::map<std::string, std::string> LangEntry::s_currStrings;
LanguageDefinition::LanguageDefinition(std::initializer_list<std::pair<std::string, std::string>> entries) { LanguageDefinition::LanguageDefinition(std::initializer_list<std::pair<std::string, std::string>> entries) {
for (auto pair : entries) for (auto pair : entries)
@@ -60,7 +61,7 @@ namespace hex {
} }
const std::string &LangEntry::get() const { const std::string &LangEntry::get() const {
auto &lang = SharedData::loadedLanguageStrings; auto &lang = LangEntry::s_currStrings;
if (lang.contains(this->m_unlocalizedString)) if (lang.contains(this->m_unlocalizedString))
return lang[this->m_unlocalizedString]; return lang[this->m_unlocalizedString];
else else
@@ -68,7 +69,7 @@ namespace hex {
} }
void LangEntry::loadLanguage(const std::string &language) { void LangEntry::loadLanguage(const std::string &language) {
SharedData::loadedLanguageStrings.clear(); LangEntry::s_currStrings.clear();
auto &definitions = ContentRegistry::Language::getLanguageDefinitions(); auto &definitions = ContentRegistry::Language::getLanguageDefinitions();
@@ -76,12 +77,12 @@ namespace hex {
return; return;
for (auto &definition : definitions[language]) for (auto &definition : definitions[language])
SharedData::loadedLanguageStrings.insert(definition.getEntries().begin(), definition.getEntries().end()); LangEntry::s_currStrings.insert(definition.getEntries().begin(), definition.getEntries().end());
const auto fallbackLanguage = LangEntry::getFallbackLanguage(); const auto fallbackLanguage = LangEntry::getFallbackLanguage();
if (language != fallbackLanguage) { if (language != fallbackLanguage) {
for (auto &definition : definitions[fallbackLanguage]) for (auto &definition : definitions[fallbackLanguage])
SharedData::loadedLanguageStrings.insert(definition.getEntries().begin(), definition.getEntries().end()); LangEntry::s_currStrings.insert(definition.getEntries().begin(), definition.getEntries().end());
} }
} }
@@ -97,4 +98,8 @@ namespace hex {
return LangEntry::s_fallbackLanguage; return LangEntry::s_fallbackLanguage;
} }
void LangEntry::resetLanguageStrings() {
LangEntry::s_currStrings.clear();
}
} }

View File

@@ -1,4 +1,4 @@
#include "helpers/plugin_manager.hpp" #include <hex/api/plugin_manager.hpp>
#include <hex/helpers/logger.hpp> #include <hex/helpers/logger.hpp>
@@ -17,32 +17,35 @@ namespace hex {
auto pluginName = fs::path(path).stem().string(); auto pluginName = fs::path(path).stem().string();
this->m_initializePluginFunction = getPluginFunction<InitializePluginFunc>("initializePlugin"); this->m_initializePluginFunction = getPluginFunction<InitializePluginFunc>("initializePlugin");
this->m_getPluginNameFunction = getPluginFunction<GetPluginNameFunc>("getPluginName"); this->m_getPluginNameFunction = getPluginFunction<GetPluginNameFunc>("getPluginName");
this->m_getPluginAuthorFunction = getPluginFunction<GetPluginAuthorFunc>("getPluginAuthor"); this->m_getPluginAuthorFunction = getPluginFunction<GetPluginAuthorFunc>("getPluginAuthor");
this->m_getPluginDescriptionFunction = getPluginFunction<GetPluginDescriptionFunc>("getPluginDescription"); this->m_getPluginDescriptionFunction = getPluginFunction<GetPluginDescriptionFunc>("getPluginDescription");
this->m_getCompatibleVersionFunction = getPluginFunction<GetCompatibleVersionFunc>("getCompatibleVersion"); this->m_getCompatibleVersionFunction = getPluginFunction<GetCompatibleVersionFunc>("getCompatibleVersion");
this->m_setImGuiContextFunction = getPluginFunction<SetImGuiContextFunc>("setImGuiContext"); this->m_setImGuiContextFunction = getPluginFunction<SetImGuiContextFunc>("setImGuiContext");
this->m_isBuiltinPluginFunction = getPluginFunction<IsBuiltinPluginFunc>("isBuiltinPlugin");
} }
Plugin::Plugin(Plugin &&other) noexcept { Plugin::Plugin(Plugin &&other) noexcept {
this->m_handle = other.m_handle; this->m_handle = other.m_handle;
this->m_path = std::move(other.m_path); this->m_path = std::move(other.m_path);
this->m_initializePluginFunction = other.m_initializePluginFunction; this->m_initializePluginFunction = other.m_initializePluginFunction;
this->m_getPluginNameFunction = other.m_getPluginNameFunction; this->m_getPluginNameFunction = other.m_getPluginNameFunction;
this->m_getPluginAuthorFunction = other.m_getPluginAuthorFunction; this->m_getPluginAuthorFunction = other.m_getPluginAuthorFunction;
this->m_getPluginDescriptionFunction = other.m_getPluginDescriptionFunction; this->m_getPluginDescriptionFunction = other.m_getPluginDescriptionFunction;
this->m_getCompatibleVersionFunction = other.m_getCompatibleVersionFunction; this->m_getCompatibleVersionFunction = other.m_getCompatibleVersionFunction;
this->m_setImGuiContextFunction = other.m_setImGuiContextFunction; this->m_setImGuiContextFunction = other.m_setImGuiContextFunction;
this->m_isBuiltinPluginFunction = other.m_isBuiltinPluginFunction;
other.m_handle = nullptr; other.m_handle = nullptr;
other.m_initializePluginFunction = nullptr; other.m_initializePluginFunction = nullptr;
other.m_getPluginNameFunction = nullptr; other.m_getPluginNameFunction = nullptr;
other.m_getPluginAuthorFunction = nullptr; other.m_getPluginAuthorFunction = nullptr;
other.m_getPluginDescriptionFunction = nullptr; other.m_getPluginDescriptionFunction = nullptr;
other.m_getCompatibleVersionFunction = nullptr; other.m_getCompatibleVersionFunction = nullptr;
other.m_setImGuiContextFunction = nullptr; other.m_setImGuiContextFunction = nullptr;
other.m_isBuiltinPluginFunction = nullptr;
} }
Plugin::~Plugin() { Plugin::~Plugin() {
@@ -100,6 +103,13 @@ namespace hex {
this->m_setImGuiContextFunction(ctx); this->m_setImGuiContextFunction(ctx);
} }
[[nodiscard]] bool Plugin::isBuiltinPlugin() const {
if (this->m_isBuiltinPluginFunction != nullptr)
return this->m_isBuiltinPluginFunction();
else
return false;
}
const fs::path &Plugin::getPath() const { const fs::path &Plugin::getPath() const {
return this->m_path; return this->m_path;
} }
@@ -114,6 +124,9 @@ namespace hex {
} }
fs::path PluginManager::s_pluginFolder;
std::vector<Plugin> PluginManager::s_plugins;
bool PluginManager::load(const fs::path &pluginFolder) { bool PluginManager::load(const fs::path &pluginFolder) {
if (!fs::exists(pluginFolder)) if (!fs::exists(pluginFolder))
return false; return false;

View File

@@ -1,11 +1,16 @@
#include <hex/api/task.hpp> #include <hex/api/task.hpp>
#include <hex/helpers/shared_data.hpp> #include <hex/api/localization.hpp>
namespace hex { namespace hex {
std::list<Task *> Task::s_runningTasks;
std::mutex Task::s_taskMutex;
Task::Task(const std::string &unlocalizedName, u64 maxValue) : m_name(LangEntry(unlocalizedName)), m_maxValue(maxValue), m_currValue(0) { Task::Task(const std::string &unlocalizedName, u64 maxValue) : m_name(LangEntry(unlocalizedName)), m_maxValue(maxValue), m_currValue(0) {
SharedData::runningTasks.push_back(this); std::scoped_lock lock(Task::s_taskMutex);
Task::s_runningTasks.push_back(this);
} }
Task::~Task() { Task::~Task() {
@@ -13,7 +18,9 @@ namespace hex {
} }
void Task::finish() { void Task::finish() {
SharedData::runningTasks.remove(this); std::scoped_lock lock(Task::s_taskMutex);
Task::s_runningTasks.remove(this);
} }
void Task::setMaxValue(u64 maxValue) { void Task::setMaxValue(u64 maxValue) {
@@ -40,4 +47,10 @@ namespace hex {
return this->m_name; return this->m_name;
} }
size_t Task::getRunningTaskCount() {
std::scoped_lock lock(Task::s_taskMutex);
return Task::s_runningTasks.size();
}
} }

View File

@@ -1,10 +1,11 @@
#include <hex/data_processor/attribute.hpp> #include <hex/data_processor/attribute.hpp>
#include <hex/helpers/shared_data.hpp>
namespace hex::dp { namespace hex::dp {
Attribute::Attribute(IOType ioType, Type type, std::string unlocalizedName) : m_id(SharedData::dataProcessorAttrIdCounter++), m_ioType(ioType), m_type(type), m_unlocalizedName(std::move(unlocalizedName)) { u32 Attribute::s_idCounter = 1;
Attribute::Attribute(IOType ioType, Type type, std::string unlocalizedName) : m_id(Attribute::s_idCounter++), m_ioType(ioType), m_type(type), m_unlocalizedName(std::move(unlocalizedName)) {
} }
Attribute::~Attribute() { Attribute::~Attribute() {

View File

@@ -1,10 +1,11 @@
#include <hex/data_processor/link.hpp> #include <hex/data_processor/link.hpp>
#include <hex/helpers/shared_data.hpp>
namespace hex::dp { namespace hex::dp {
Link::Link(u32 from, u32 to) : m_id(SharedData::dataProcessorLinkIdCounter++), m_from(from), m_to(to) { } u32 Link::s_idCounter = 1;
Link::Link(u32 from, u32 to) : m_id(Link::s_idCounter++), m_from(from), m_to(to) { }
} }

View File

@@ -1,12 +1,15 @@
#include <hex/data_processor/node.hpp> #include <hex/data_processor/node.hpp>
#include <hex/helpers/shared_data.hpp>
#include <hex/helpers/fmt.hpp> #include <hex/helpers/fmt.hpp>
#include <hex/api/localization.hpp>
#include <hex/providers/provider.hpp>
namespace hex::dp { namespace hex::dp {
Node::Node(std::string unlocalizedTitle, std::vector<Attribute> attributes) : m_id(SharedData::dataProcessorNodeIdCounter++), m_unlocalizedTitle(std::move(unlocalizedTitle)), m_attributes(std::move(attributes)) { u32 Node::s_idCounter = 1;
Node::Node(std::string unlocalizedTitle, std::vector<Attribute> attributes) : m_id(Node::s_idCounter++), m_unlocalizedTitle(std::move(unlocalizedTitle)), m_attributes(std::move(attributes)) {
for (auto &attr : this->m_attributes) for (auto &attr : this->m_attributes)
attr.setParentNode(this); attr.setParentNode(this);
} }

View File

@@ -3,7 +3,7 @@
#include <hex/helpers/utils.hpp> #include <hex/helpers/utils.hpp>
#include <hex/helpers/paths.hpp> #include <hex/helpers/paths.hpp>
#include <hex/helpers/file.hpp> #include <hex/helpers/file.hpp>
#include <hex/views/view.hpp> #include <hex/ui/view.hpp>
#include <hex/providers/provider.hpp> #include <hex/providers/provider.hpp>
#define PY_SSIZE_T_CLEAN #define PY_SSIZE_T_CLEAN
@@ -179,7 +179,7 @@ namespace hex {
} }
bool LoaderScript::processFile(const fs::path &scriptPath) { bool LoaderScript::processFile(const fs::path &scriptPath) {
Py_SetProgramName(Py_DecodeLocale((SharedData::mainArgv)[0], nullptr)); Py_SetProgramName(Py_DecodeLocale("ImHex", nullptr));
for (const auto &dir : hex::getPath(ImHexPath::Python)) { for (const auto &dir : hex::getPath(ImHexPath::Python)) {
if (fs::exists(fs::path(dir / "lib" / "python" PYTHON_VERSION_MAJOR_MINOR))) { if (fs::exists(fs::path(dir / "lib" / "python" PYTHON_VERSION_MAJOR_MINOR))) {

View File

@@ -64,7 +64,7 @@ namespace hex {
for (auto &element : projectFileData["bookmarks"].items()) { for (auto &element : projectFileData["bookmarks"].items()) {
ImHexApi::Bookmarks::Entry entry; ImHexApi::Bookmarks::Entry entry;
from_json(element.value(), entry); from_json(element.value(), entry);
ProjectFile::s_bookmarks.push_back(entry); ProjectFile::s_bookmarks.emplace_back(std::move(entry));
} }
} catch (json::exception &e) { } catch (json::exception &e) {

View File

@@ -1,74 +0,0 @@
#include <hex/helpers/shared_data.hpp>
#include <nlohmann/json.hpp>
namespace hex {
std::vector<std::function<void()>> SharedData::deferredCalls;
std::vector<prv::Provider *> SharedData::providers;
u32 SharedData::currentProvider;
std::map<std::string, std::vector<ContentRegistry::Settings::Entry>> SharedData::settingsEntries;
nlohmann::json SharedData::settingsJson;
std::vector<ContentRegistry::CommandPaletteCommands::Entry> SharedData::commandPaletteCommands;
std::map<std::string, ContentRegistry::PatternLanguage::Function> SharedData::patternLanguageFunctions;
std::map<std::string, View *> SharedData::views;
std::vector<ContentRegistry::Tools::impl::Entry> SharedData::toolsEntries;
std::vector<ContentRegistry::DataInspector::impl::Entry> SharedData::dataInspectorEntries;
u32 SharedData::patternPaletteOffset;
std::string SharedData::popupMessage;
std::list<ImHexApi::Bookmarks::Entry> SharedData::bookmarkEntries;
std::vector<pl::PatternData *> SharedData::patternData;
u32 SharedData::selectableFileIndex;
std::vector<fs::path> SharedData::selectableFiles;
std::function<void(fs::path)> SharedData::selectableFileOpenCallback;
std::vector<nfdfilteritem_t> SharedData::selectableFilesValidExtensions;
std::map<std::string, std::string> SharedData::languageNames;
std::map<std::string, std::vector<LanguageDefinition>> SharedData::languageDefinitions;
std::map<std::string, std::string> SharedData::loadedLanguageStrings;
ImGuiID SharedData::dockSpaceId;
std::multimap<u32, ContentRegistry::Interface::impl::MainMenuItem> SharedData::mainMenuItems;
std::multimap<u32, ContentRegistry::Interface::impl::MenuItem> SharedData::menuItems;
std::vector<ContentRegistry::Interface::impl::DrawCallback> SharedData::welcomeScreenEntries;
std::vector<ContentRegistry::Interface::impl::DrawCallback> SharedData::footerItems;
std::vector<ContentRegistry::Interface::impl::SidebarItem> SharedData::sidebarItems;
std::vector<ContentRegistry::Interface::impl::DrawCallback> SharedData::toolbarItems;
std::vector<ContentRegistry::Interface::impl::Layout> SharedData::layouts;
std::map<Shortcut, std::function<void()>> SharedData::globalShortcuts;
std::mutex SharedData::tasksMutex;
std::list<Task *> SharedData::runningTasks;
std::vector<std::string> SharedData::providerNames;
std::vector<ContentRegistry::DataProcessorNode::impl::Entry> SharedData::dataProcessorNodes;
u32 SharedData::dataProcessorNodeIdCounter = 1;
u32 SharedData::dataProcessorLinkIdCounter = 1;
u32 SharedData::dataProcessorAttrIdCounter = 1;
std::vector<ContentRegistry::DataFormatter::impl::Entry> SharedData::dataFormatters;
std::vector<ContentRegistry::FileHandler::impl::Entry> SharedData::fileHandlers;
std::list<fs::path> SharedData::recentFilePaths;
int SharedData::mainArgc;
char **SharedData::mainArgv;
char **SharedData::mainEnvp;
ImFontAtlas *SharedData::fontAtlas;
ImFontConfig SharedData::fontConfig;
ImVec2 SharedData::windowPos;
ImVec2 SharedData::windowSize;
float SharedData::globalScale;
float SharedData::fontScale;
std::map<std::string, std::any> SharedData::sharedVariables;
}

View File

@@ -5,8 +5,13 @@
#include <locale> #include <locale>
#include <filesystem> #include <filesystem>
#include <hex/api/imhex_api.hpp>
#include <hex/helpers/fmt.hpp> #include <hex/helpers/fmt.hpp>
#include <hex/helpers/shared_data.hpp>
#include <imgui.h>
#define IMGUI_DEFINE_MATH_OPERATORS
#include <imgui_internal.h>
#if defined(OS_WINDOWS) #if defined(OS_WINDOWS)
#include <windows.h> #include <windows.h>
@@ -20,15 +25,15 @@
namespace hex { namespace hex {
long double operator""_scaled(long double value) { long double operator""_scaled(long double value) {
return value * SharedData::globalScale; return value * ImHexApi::System::getGlobalScale();
} }
long double operator""_scaled(unsigned long long value) { long double operator""_scaled(unsigned long long value) {
return value * SharedData::globalScale; return value * ImHexApi::System::getGlobalScale();
} }
ImVec2 scaled(const ImVec2 &vector) { ImVec2 scaled(const ImVec2 &vector) {
return vector * SharedData::globalScale; return vector * ImHexApi::System::getGlobalScale();
} }
std::string to_string(u128 value) { std::string to_string(u128 value) {

View File

@@ -4,8 +4,6 @@
namespace hex::pl { namespace hex::pl {
Evaluator *PatternCreationLimiter::s_evaluator = nullptr;
void Evaluator::createParameterPack(const std::string &name, const std::vector<Token::Literal> &values) { void Evaluator::createParameterPack(const std::string &name, const std::vector<Token::Literal> &values) {
this->getScope(0).parameterPack = ParameterPack { this->getScope(0).parameterPack = ParameterPack {
name, name,
@@ -31,19 +29,19 @@ namespace hex::pl {
LogConsole::abortEvaluation("cannot determine type of auto variable", type); LogConsole::abortEvaluation("cannot determine type of auto variable", type);
if (std::get_if<u128>(&value.value()) != nullptr) if (std::get_if<u128>(&value.value()) != nullptr)
pattern = new PatternDataUnsigned(0, sizeof(u128)); pattern = new PatternDataUnsigned(this, 0, sizeof(u128));
else if (std::get_if<i128>(&value.value()) != nullptr) else if (std::get_if<i128>(&value.value()) != nullptr)
pattern = new PatternDataSigned(0, sizeof(i128)); pattern = new PatternDataSigned(this, 0, sizeof(i128));
else if (std::get_if<double>(&value.value()) != nullptr) else if (std::get_if<double>(&value.value()) != nullptr)
pattern = new PatternDataFloat(0, sizeof(double)); pattern = new PatternDataFloat(this, 0, sizeof(double));
else if (std::get_if<bool>(&value.value()) != nullptr) else if (std::get_if<bool>(&value.value()) != nullptr)
pattern = new PatternDataBoolean(0); pattern = new PatternDataBoolean(this, 0);
else if (std::get_if<char>(&value.value()) != nullptr) else if (std::get_if<char>(&value.value()) != nullptr)
pattern = new PatternDataCharacter(0); pattern = new PatternDataCharacter(this, 0);
else if (std::get_if<PatternData *>(&value.value()) != nullptr) else if (std::get_if<PatternData *>(&value.value()) != nullptr)
pattern = std::get<PatternData *>(value.value())->clone(); pattern = std::get<PatternData *>(value.value())->clone();
else if (std::get_if<std::string>(&value.value()) != nullptr) else if (std::get_if<std::string>(&value.value()) != nullptr)
pattern = new PatternDataString(0, 1); pattern = new PatternDataString(this, 0, 1);
else else
LogConsole::abortEvaluation("cannot determine type of auto variable", type); LogConsole::abortEvaluation("cannot determine type of auto variable", type);
} }
@@ -154,8 +152,6 @@ namespace hex::pl {
std::vector<PatternData *> patterns; std::vector<PatternData *> patterns;
PatternCreationLimiter::s_evaluator = this;
try { try {
this->setCurrentControlFlowStatement(ControlFlowStatement::None); this->setCurrentControlFlowStatement(ControlFlowStatement::None);
pushScope(nullptr, patterns); pushScope(nullptr, patterns);

View File

@@ -663,10 +663,18 @@ namespace hex::pl {
if (!MATCHES(sequence(SEPARATOR_COMMA))) if (!MATCHES(sequence(SEPARATOR_COMMA)))
throwParserError("expected ',' after for loop condition"); throwParserError("expected ',' after for loop condition");
if (!MATCHES(sequence(IDENTIFIER, OPERATOR_ASSIGNMENT))) ASTNode *postExpression = nullptr;
throwParserError("expected for loop variable assignment"); if (MATCHES(sequence(IDENTIFIER, OPERATOR_ASSIGNMENT)))
postExpression = parseFunctionVariableAssignment(getValue<Token::Identifier>(-2).get());
else if (MATCHES(sequence(OPERATOR_DOLLAR, OPERATOR_ASSIGNMENT)))
postExpression = parseFunctionVariableAssignment("$");
else if (MATCHES(oneOf(IDENTIFIER) && oneOf(OPERATOR_PLUS, OPERATOR_MINUS, OPERATOR_STAR, OPERATOR_SLASH, OPERATOR_PERCENT, OPERATOR_SHIFTLEFT, OPERATOR_SHIFTRIGHT, OPERATOR_BITOR, OPERATOR_BITAND, OPERATOR_BITXOR) && sequence(OPERATOR_ASSIGNMENT)))
postExpression = parseFunctionVariableCompoundAssignment(getValue<Token::Identifier>(-3).get());
else if (MATCHES(oneOf(OPERATOR_DOLLAR) && oneOf(OPERATOR_PLUS, OPERATOR_MINUS, OPERATOR_STAR, OPERATOR_SLASH, OPERATOR_PERCENT, OPERATOR_SHIFTLEFT, OPERATOR_SHIFTRIGHT, OPERATOR_BITOR, OPERATOR_BITAND, OPERATOR_BITXOR) && sequence(OPERATOR_ASSIGNMENT)))
postExpression = parseFunctionVariableCompoundAssignment("$");
else
throwParserError("expected variable assignment in for loop post expression");
auto postExpression = parseFunctionVariableAssignment(getValue<Token::Identifier>(-2).get());
auto postExpressionCleanup = SCOPE_GUARD { delete postExpression; }; auto postExpressionCleanup = SCOPE_GUARD { delete postExpression; };
std::vector<ASTNode *> body; std::vector<ASTNode *> body;

View File

@@ -123,7 +123,10 @@ namespace hex::pl {
return ast; return ast;
} }
std::optional<std::vector<PatternData *>> PatternLanguage::executeString(prv::Provider *provider, const std::string &code, const std::map<std::string, Token::Literal> &envVars, const std::map<std::string, Token::Literal> &inVariables) { bool PatternLanguage::executeString(prv::Provider *provider, const std::string &code, const std::map<std::string, Token::Literal> &envVars, const std::map<std::string, Token::Literal> &inVariables) {
this->m_running = true;
ON_SCOPE_EXIT { this->m_running = false; };
this->m_currError.reset(); this->m_currError.reset();
this->m_evaluator->getConsole().clear(); this->m_evaluator->getConsole().clear();
this->m_evaluator->setProvider(provider); this->m_evaluator->setProvider(provider);
@@ -143,20 +146,22 @@ namespace hex::pl {
auto ast = this->parseString(code); auto ast = this->parseString(code);
if (!ast) if (!ast)
return std::nullopt; return false;
this->m_currAST = ast.value(); this->m_currAST = ast.value();
auto patterns = this->m_evaluator->evaluate(ast.value()); auto patterns = this->m_evaluator->evaluate(ast.value());
if (!patterns.has_value()) { if (!patterns.has_value()) {
this->m_currError = this->m_evaluator->getConsole().getLastHardError(); this->m_currError = this->m_evaluator->getConsole().getLastHardError();
return std::nullopt; return false;
} }
return patterns; this->m_patterns = std::move(patterns.value());
return true;
} }
std::optional<std::vector<PatternData *>> PatternLanguage::executeFile(prv::Provider *provider, const fs::path &path, const std::map<std::string, Token::Literal> &envVars, const std::map<std::string, Token::Literal> &inVariables) { bool PatternLanguage::executeFile(prv::Provider *provider, const fs::path &path, const std::map<std::string, Token::Literal> &envVars, const std::map<std::string, Token::Literal> &inVariables) {
File file(path, File::Mode::Read); File file(path, File::Mode::Read);
return this->executeString(provider, file.readString(), envVars, inVariables); return this->executeString(provider, file.readString(), envVars, inVariables);
@@ -200,4 +205,12 @@ namespace hex::pl {
return this->m_evaluator->hasDangerousFunctionBeenCalled(); return this->m_evaluator->hasDangerousFunctionBeenCalled();
} }
void PatternLanguage::reset() {
for (auto &pattern : this->m_patterns)
delete pattern;
this->m_patterns.clear();
this->m_currAST.clear();
}
} }

View File

@@ -2,6 +2,7 @@
#include <hex.hpp> #include <hex.hpp>
#include <hex/api/event.hpp> #include <hex/api/event.hpp>
#include <hex/pattern_language/pattern_data.hpp>
#include <cmath> #include <cmath>
#include <cstring> #include <cstring>

View File

@@ -1,4 +1,4 @@
#include <hex/views/view.hpp> #include <hex/ui/view.hpp>
#include <imgui.h> #include <imgui.h>
@@ -6,48 +6,54 @@
#include <string> #include <string>
#include <vector> #include <vector>
#include <hex/helpers/shared_data.hpp>
namespace hex { namespace hex {
std::string View::s_popupMessage;
u32 View::s_selectableFileIndex;
std::vector<fs::path> View::s_selectableFiles;
std::function<void(fs::path)> View::s_selectableFileOpenCallback;
std::vector<nfdfilteritem_t> View::s_selectableFilesValidExtensions;
ImFontAtlas *View::s_fontAtlas;
ImFontConfig View::s_fontConfig;
View::View(std::string unlocalizedName) : m_unlocalizedViewName(unlocalizedName) { } View::View(std::string unlocalizedName) : m_unlocalizedViewName(unlocalizedName) { }
bool View::isAvailable() const { bool View::isAvailable() const {
return ImHexApi::Provider::isValid() && ImHexApi::Provider::get()->isAvailable(); return ImHexApi::Provider::isValid() && ImHexApi::Provider::get()->isAvailable();
} }
std::vector<std::function<void()>> &View::getDeferedCalls() {
return SharedData::deferredCalls;
}
void View::drawCommonInterfaces() { void View::drawCommonInterfaces() {
auto windowSize = ImHexApi::System::getMainWindowSize();
ImGui::SetNextWindowSizeConstraints(scaled(ImVec2(400, 100)), scaled(ImVec2(600, 300))); ImGui::SetNextWindowSizeConstraints(scaled(ImVec2(400, 100)), scaled(ImVec2(600, 300)));
if (ImGui::BeginPopupModal("hex.common.info"_lang, nullptr, ImGuiWindowFlags_AlwaysAutoResize)) { if (ImGui::BeginPopupModal("hex.common.info"_lang, nullptr, ImGuiWindowFlags_AlwaysAutoResize)) {
ImGui::TextFormattedWrapped("{}", SharedData::popupMessage.c_str()); ImGui::TextFormattedWrapped("{}", s_popupMessage.c_str());
ImGui::NewLine(); ImGui::NewLine();
ImGui::Separator(); ImGui::Separator();
if (ImGui::Button("hex.common.okay"_lang) || ImGui::IsKeyDown(ImGuiKey_Escape)) if (ImGui::Button("hex.common.okay"_lang) || ImGui::IsKeyDown(ImGuiKey_Escape))
ImGui::CloseCurrentPopup(); ImGui::CloseCurrentPopup();
ImGui::SetWindowPos((SharedData::windowSize - ImGui::GetWindowSize()) / 2, ImGuiCond_Appearing); ImGui::SetWindowPos((windowSize - ImGui::GetWindowSize()) / 2, ImGuiCond_Appearing);
ImGui::EndPopup(); ImGui::EndPopup();
} }
ImGui::SetNextWindowSizeConstraints(scaled(ImVec2(400, 100)), scaled(ImVec2(600, 300))); ImGui::SetNextWindowSizeConstraints(scaled(ImVec2(400, 100)), scaled(ImVec2(600, 300)));
if (ImGui::BeginPopupModal("hex.common.error"_lang, nullptr, ImGuiWindowFlags_AlwaysAutoResize)) { if (ImGui::BeginPopupModal("hex.common.error"_lang, nullptr, ImGuiWindowFlags_AlwaysAutoResize)) {
ImGui::TextFormattedWrapped("{}", SharedData::popupMessage.c_str()); ImGui::TextFormattedWrapped("{}", s_popupMessage.c_str());
ImGui::NewLine(); ImGui::NewLine();
ImGui::Separator(); ImGui::Separator();
if (ImGui::Button("hex.common.okay"_lang) || ImGui::IsKeyDown(ImGuiKey_Escape)) if (ImGui::Button("hex.common.okay"_lang) || ImGui::IsKeyDown(ImGuiKey_Escape))
ImGui::CloseCurrentPopup(); ImGui::CloseCurrentPopup();
ImGui::SetWindowPos((SharedData::windowSize - ImGui::GetWindowSize()) / 2, ImGuiCond_Appearing); ImGui::SetWindowPos((windowSize - ImGui::GetWindowSize()) / 2, ImGuiCond_Appearing);
ImGui::EndPopup(); ImGui::EndPopup();
} }
ImGui::SetNextWindowSizeConstraints(scaled(ImVec2(400, 100)), scaled(ImVec2(600, 300))); ImGui::SetNextWindowSizeConstraints(scaled(ImVec2(400, 100)), scaled(ImVec2(600, 300)));
if (ImGui::BeginPopupModal("hex.common.fatal"_lang, nullptr, ImGuiWindowFlags_AlwaysAutoResize)) { if (ImGui::BeginPopupModal("hex.common.fatal"_lang, nullptr, ImGuiWindowFlags_AlwaysAutoResize)) {
ImGui::TextFormattedWrapped("{}", SharedData::popupMessage.c_str()); ImGui::TextFormattedWrapped("{}", s_popupMessage.c_str());
ImGui::NewLine(); ImGui::NewLine();
ImGui::Separator(); ImGui::Separator();
if (ImGui::Button("hex.common.okay"_lang) || ImGui::IsKeyDown(ImGuiKey_Escape)) { if (ImGui::Button("hex.common.okay"_lang) || ImGui::IsKeyDown(ImGuiKey_Escape)) {
@@ -55,7 +61,7 @@ namespace hex {
ImGui::CloseCurrentPopup(); ImGui::CloseCurrentPopup();
} }
ImGui::SetWindowPos((SharedData::windowSize - ImGui::GetWindowSize()) / 2, ImGuiCond_Appearing); ImGui::SetWindowPos((windowSize - ImGui::GetWindowSize()) / 2, ImGuiCond_Appearing);
ImGui::EndPopup(); ImGui::EndPopup();
} }
@@ -66,9 +72,9 @@ namespace hex {
if (ImGui::BeginListBox("##files", ImVec2(300_scaled, 0))) { if (ImGui::BeginListBox("##files", ImVec2(300_scaled, 0))) {
u32 index = 0; u32 index = 0;
for (auto &path : SharedData::selectableFiles) { for (auto &path : View::s_selectableFiles) {
if (ImGui::Selectable(path.filename().string().c_str(), index == SharedData::selectableFileIndex)) if (ImGui::Selectable(path.filename().string().c_str(), index == View::s_selectableFileIndex))
SharedData::selectableFileIndex = index; View::s_selectableFileIndex = index;
index++; index++;
} }
@@ -76,15 +82,15 @@ namespace hex {
} }
if (ImGui::Button("hex.common.open"_lang)) { if (ImGui::Button("hex.common.open"_lang)) {
SharedData::selectableFileOpenCallback(SharedData::selectableFiles[SharedData::selectableFileIndex]); View::s_selectableFileOpenCallback(View::s_selectableFiles[View::s_selectableFileIndex]);
ImGui::CloseCurrentPopup(); ImGui::CloseCurrentPopup();
} }
ImGui::SameLine(); ImGui::SameLine();
if (ImGui::Button("hex.common.browse"_lang)) { if (ImGui::Button("hex.common.browse"_lang)) {
hex::openFileBrowser("hex.common.open"_lang, DialogMode::Open, SharedData::selectableFilesValidExtensions, [](const auto &path) { hex::openFileBrowser("hex.common.open"_lang, DialogMode::Open, View::s_selectableFilesValidExtensions, [](const auto &path) {
SharedData::selectableFileOpenCallback(path); View::s_selectableFileOpenCallback(path);
ImGui::CloseCurrentPopup(); ImGui::CloseCurrentPopup();
}); });
} }
@@ -94,30 +100,30 @@ namespace hex {
} }
void View::showMessagePopup(const std::string &message) { void View::showMessagePopup(const std::string &message) {
SharedData::popupMessage = message; s_popupMessage = message;
View::doLater([] { ImGui::OpenPopup("hex.common.info"_lang); }); ImHexApi::Tasks::doLater([] { ImGui::OpenPopup("hex.common.info"_lang); });
} }
void View::showErrorPopup(const std::string &errorMessage) { void View::showErrorPopup(const std::string &errorMessage) {
SharedData::popupMessage = errorMessage; s_popupMessage = errorMessage;
View::doLater([] { ImGui::OpenPopup("hex.common.error"_lang); }); ImHexApi::Tasks::doLater([] { ImGui::OpenPopup("hex.common.error"_lang); });
} }
void View::showFatalPopup(const std::string &errorMessage) { void View::showFatalPopup(const std::string &errorMessage) {
SharedData::popupMessage = errorMessage; s_popupMessage = errorMessage;
View::doLater([] { ImGui::OpenPopup("hex.common.fatal"_lang); }); ImHexApi::Tasks::doLater([] { ImGui::OpenPopup("hex.common.fatal"_lang); });
} }
void View::showFileChooserPopup(const std::vector<fs::path> &paths, const std::vector<nfdfilteritem_t> &validExtensions, const std::function<void(fs::path)> &callback) { void View::showFileChooserPopup(const std::vector<fs::path> &paths, const std::vector<nfdfilteritem_t> &validExtensions, const std::function<void(fs::path)> &callback) {
SharedData::selectableFileIndex = 0; View::s_selectableFileIndex = 0;
SharedData::selectableFiles = paths; View::s_selectableFiles = paths;
SharedData::selectableFilesValidExtensions = validExtensions; View::s_selectableFilesValidExtensions = validExtensions;
SharedData::selectableFileOpenCallback = callback; View::s_selectableFileOpenCallback = callback;
View::doLater([] { ImGui::OpenPopup("hex.common.choose_file"_lang); }); ImHexApi::Tasks::doLater([] { ImGui::OpenPopup("hex.common.choose_file"_lang); });
} }
bool View::hasViewMenuItemEntry() const { bool View::hasViewMenuItemEntry() const {
@@ -154,10 +160,6 @@ namespace hex {
ImGui::GetIO().ConfigFlags &= ~ImGuiConfigFlags_NavEnableKeyboard; ImGui::GetIO().ConfigFlags &= ~ImGuiConfigFlags_NavEnableKeyboard;
} }
void View::doLater(std::function<void()> &&function) {
SharedData::deferredCalls.push_back(function);
}
void View::confirmButtons(const std::string &textLeft, const std::string &textRight, const std::function<void()> &leftButtonFn, const std::function<void()> &rightButtonFn) { void View::confirmButtons(const std::string &textLeft, const std::string &textRight, const std::function<void()> &leftButtonFn, const std::function<void()> &rightButtonFn) {
auto width = ImGui::GetWindowWidth(); auto width = ImGui::GetWindowWidth();
ImGui::SetCursorPosX(width / 9); ImGui::SetCursorPosX(width / 9);

View File

@@ -11,8 +11,6 @@ add_executable(main ${application_type}
source/init/splash_window.cpp source/init/splash_window.cpp
source/init/tasks.cpp source/init/tasks.cpp
source/helpers/plugin_manager.cpp
${IMHEX_ICON} ${IMHEX_ICON}
) )
@@ -25,7 +23,7 @@ set_target_properties(main PROPERTIES
POSITION_INDEPENDENT_CODE ON) POSITION_INDEPENDENT_CODE ON)
if (WIN32) if (WIN32)
target_link_libraries(main PUBLIC dl libimhex wsock32 ws2_32 Dwmapi.lib) target_link_libraries(main PUBLIC libimhex wsock32 ws2_32 Dwmapi.lib)
else () else ()
target_link_libraries(main PUBLIC dl libimhex pthread) target_link_libraries(main PUBLIC libimhex pthread)
endif () endif ()

View File

@@ -11,12 +11,6 @@ namespace hex::init {
std::function<bool()> function; std::function<bool()> function;
}; };
struct Argument {
std::string name, value;
};
std::vector<Task> getInitTasks(); std::vector<Task> getInitTasks();
std::vector<Task> getExitTasks(); std::vector<Task> getExitTasks();
std::vector<Argument> &getInitArguments();
} }

View File

@@ -6,7 +6,7 @@
#include <list> #include <list>
#include <vector> #include <vector>
#include <hex/views/view.hpp> #include <hex/ui/view.hpp>
struct GLFWwindow; struct GLFWwindow;
struct ImGuiSettingsHandler; struct ImGuiSettingsHandler;
@@ -47,7 +47,6 @@ namespace hex {
GLFWwindow *m_window = nullptr; GLFWwindow *m_window = nullptr;
double m_targetFps = 60.0;
bool m_layoutConfigured = false; bool m_layoutConfigured = false;
std::string m_windowTitle; std::string m_windowTitle;

View File

@@ -1,9 +1,9 @@
#include "init/splash_window.hpp" #include "init/splash_window.hpp"
#include <hex/api/imhex_api.hpp>
#include <hex/helpers/utils.hpp> #include <hex/helpers/utils.hpp>
#include <hex/helpers/fmt.hpp> #include <hex/helpers/fmt.hpp>
#include <hex/helpers/logger.hpp> #include <hex/helpers/logger.hpp>
#include <hex/helpers/shared_data.hpp>
#include <romfs/romfs.hpp> #include <romfs/romfs.hpp>
@@ -80,7 +80,7 @@ namespace hex::init {
auto tasksSucceeded = processTasksAsync(); auto tasksSucceeded = processTasksAsync();
auto scale = SharedData::globalScale; auto scale = ImHexApi::System::getGlobalScale();
while (!glfwWindowShouldClose(this->m_window)) { while (!glfwWindowShouldClose(this->m_window)) {
glfwPollEvents(); glfwPollEvents();
@@ -168,18 +168,20 @@ namespace hex::init {
float xScale = 0, yScale = 0; float xScale = 0, yScale = 0;
glfwGetMonitorContentScale(monitor, &xScale, &yScale); glfwGetMonitorContentScale(monitor, &xScale, &yScale);
SharedData::globalScale = SharedData::fontScale = std::midpoint(xScale, yScale); auto meanScale = std::midpoint(xScale, yScale);
// On Macs with a retina display (basically all modern ones we care about), the OS reports twice // On Macs with a retina display (basically all modern ones we care about), the OS reports twice
// the actual monitor scale for some obscure reason. Get rid of this here so ImHex doesn't look // the actual monitor scale for some obscure reason. Get rid of this here so ImHex doesn't look
// extremely huge with native scaling on MacOS. // extremely huge with native scaling on MacOS.
#if defined(OS_MACOS) #if defined(OS_MACOS)
SharedData::globalScale /= 2; meanScale /= 2;
#endif #endif
if (SharedData::globalScale <= 0) { if (meanScale <= 0) {
SharedData::globalScale = 1.0; meanScale = 1.0;
} }
ImHexApi::System::impl::setGlobalScale(meanScale);
} }
this->m_window = glfwCreateWindow(640_scaled, 400_scaled, "Starting ImHex...", nullptr, nullptr); this->m_window = glfwCreateWindow(640_scaled, 400_scaled, "Starting ImHex...", nullptr, nullptr);
@@ -204,7 +206,7 @@ namespace hex::init {
auto &io = ImGui::GetIO(); auto &io = ImGui::GetIO();
ImGui::GetStyle().ScaleAllSizes(SharedData::globalScale); ImGui::GetStyle().ScaleAllSizes(ImHexApi::System::getGlobalScale());
io.Fonts->Clear(); io.Fonts->Clear();

View File

@@ -12,7 +12,7 @@
#include <codicons_font.h> #include <codicons_font.h>
#include <unifont_font.h> #include <unifont_font.h>
#include "helpers/plugin_manager.hpp" #include <hex/api/plugin_manager.hpp>
#include <filesystem> #include <filesystem>
@@ -37,7 +37,7 @@ namespace hex::init {
auto latestVersion = releases.body["tag_name"].get<std::string_view>(); auto latestVersion = releases.body["tag_name"].get<std::string_view>();
if (latestVersion != currVersion) if (latestVersion != currVersion)
getInitArguments().push_back({ "update-available", latestVersion.data() }); ImHexApi::System::getInitArguments().insert({ "update-available", latestVersion.data() });
return true; return true;
} }
@@ -49,7 +49,7 @@ namespace hex::init {
if (tip.code != 200) if (tip.code != 200)
return false; return false;
getInitArguments().push_back({ "tip-of-the-day", tip.body }); ImHexApi::System::getInitArguments().insert({ "tip-of-the-day", tip.body });
return true; return true;
} }
@@ -83,17 +83,14 @@ namespace hex::init {
} }
if (!result) if (!result)
getInitArguments().push_back({ "folder-creation-error", {} }); ImHexApi::System::getInitArguments().insert({ "folder-creation-error", {} });
return result; return result;
} }
bool loadFonts() { bool loadFonts() {
auto &fonts = SharedData::fontAtlas; auto fonts = IM_NEW(ImFontAtlas)();
auto &cfg = SharedData::fontConfig; ImFontConfig cfg = {};
fonts = IM_NEW(ImFontAtlas)();
cfg = {};
fs::path fontFile; fs::path fontFile;
for (const auto &dir : hex::getPath(ImHexPath::Resources)) { for (const auto &dir : hex::getPath(ImHexPath::Resources)) {
@@ -131,84 +128,79 @@ namespace hex::init {
0x0020, 0xFFF0, 0 0x0020, 0xFFF0, 0
}; };
float fontSize = 13.0F * ImHexApi::System::getGlobalScale();
if (fontFile.empty()) { if (fontFile.empty()) {
// Load default font // Load default font
fonts->Clear(); fonts->Clear();
cfg.OversampleH = cfg.OversampleV = 1, cfg.PixelSnapH = true; cfg.OversampleH = cfg.OversampleV = 1, cfg.PixelSnapH = true;
cfg.SizePixels = 13.0F * SharedData::fontScale; cfg.SizePixels = fontSize;
fonts->AddFontDefault(&cfg); fonts->AddFontDefault(&cfg);
} else { } else {
// Load custom font // Load custom font
auto fontSize = ContentRegistry::Settings::read("hex.builtin.setting.interface", "hex.builtin.setting.interface.font_size", 14); fontSize = ContentRegistry::Settings::read("hex.builtin.setting.interface", "hex.builtin.setting.interface.font_size", 14) * ImHexApi::System::getGlobalScale();
cfg.OversampleH = cfg.OversampleV = 1, cfg.PixelSnapH = true; cfg.OversampleH = cfg.OversampleV = 1, cfg.PixelSnapH = true;
cfg.SizePixels = fontSize * SharedData::fontScale; cfg.SizePixels = fontSize;
fonts->AddFontFromFileTTF(fontFile.string().c_str(), std::floor(fontSize * SharedData::fontScale), &cfg, ranges.Data); // Needs conversion to char for Windows fonts->AddFontFromFileTTF(fontFile.string().c_str(), std::floor(fontSize), &cfg, ranges.Data); // Needs conversion to char for Windows
} }
cfg.MergeMode = true; cfg.MergeMode = true;
fonts->AddFontFromMemoryCompressedTTF(font_awesome_compressed_data, font_awesome_compressed_size, 13.0F * SharedData::fontScale, &cfg, fontAwesomeRange); fonts->AddFontFromMemoryCompressedTTF(font_awesome_compressed_data, font_awesome_compressed_size, fontSize, &cfg, fontAwesomeRange);
fonts->AddFontFromMemoryCompressedTTF(codicons_compressed_data, codicons_compressed_size, 13.0F * SharedData::fontScale, &cfg, codiconsRange); fonts->AddFontFromMemoryCompressedTTF(codicons_compressed_data, codicons_compressed_size, fontSize, &cfg, codiconsRange);
fonts->AddFontFromMemoryCompressedTTF(unifont_compressed_data, unifont_compressed_size, 13.0F * SharedData::fontScale, &cfg, unifontRange); fonts->AddFontFromMemoryCompressedTTF(unifont_compressed_data, unifont_compressed_size, fontSize, &cfg, unifontRange);
ImGuiFreeType::BuildFontAtlas(fonts); ImGuiFreeType::BuildFontAtlas(fonts);
View::setFontAtlas(fonts);
View::setFontConfig(cfg);
return true; return true;
} }
bool deleteSharedData() { bool deleteSharedData() {
SharedData::deferredCalls.clear(); ImHexApi::Tasks::getDeferredCalls().clear();
while (ImHexApi::Provider::isValid()) while (ImHexApi::Provider::isValid())
ImHexApi::Provider::remove(ImHexApi::Provider::get()); ImHexApi::Provider::remove(ImHexApi::Provider::get());
ContentRegistry::Provider::getEntries().clear();
SharedData::settingsEntries.clear(); ContentRegistry::Settings::getEntries().clear();
SharedData::settingsJson.clear(); ContentRegistry::Settings::getSettingsData().clear();
SharedData::commandPaletteCommands.clear(); ContentRegistry::CommandPaletteCommands::getEntries().clear();
SharedData::patternLanguageFunctions.clear(); ContentRegistry::PatternLanguage::getFunctions().clear();
ContentRegistry::PatternLanguage::getPalettes().clear();
for (auto &[name, view] : ContentRegistry::Views::getEntries()) for (auto &[name, view] : ContentRegistry::Views::getEntries())
delete view; delete view;
SharedData::views.clear(); ContentRegistry::Views::getEntries().clear();
SharedData::toolsEntries.clear(); ContentRegistry::Tools::getEntries().clear();
ContentRegistry::DataInspector::getEntries().clear();
SharedData::dataInspectorEntries.clear(); ContentRegistry::Language::getLanguages().clear();
ContentRegistry::Language::getLanguageDefinitions().clear();
LangEntry::resetLanguageStrings();
SharedData::bookmarkEntries.clear(); ContentRegistry::Interface::getWelcomeScreenEntries().clear();
ContentRegistry::Interface::getFooterItems().clear();
ContentRegistry::Interface::getToolbarItems().clear();
ContentRegistry::Interface::getMainMenuItems().clear();
ContentRegistry::Interface::getMenuItems().clear();
for (auto &pattern : SharedData::patternData) ShortcutManager::clearShortcuts();
delete pattern;
SharedData::patternData.clear();
SharedData::languageNames.clear(); hex::Task::getRunningTasks().clear();
SharedData::languageDefinitions.clear();
SharedData::loadedLanguageStrings.clear();
SharedData::welcomeScreenEntries.clear(); ContentRegistry::DataProcessorNode::getEntries().clear();
SharedData::footerItems.clear();
SharedData::toolbarItems.clear();
SharedData::mainMenuItems.clear();
SharedData::menuItems.clear();
SharedData::globalShortcuts.clear(); ContentRegistry::DataFormatter::getEntries().clear();
SharedData::runningTasks.clear(); ContentRegistry::FileHandler::getEntries().clear();
SharedData::dataProcessorNodes.clear();
SharedData::recentFilePaths.clear();
SharedData::dataFormatters.clear();
SharedData::fileHandlers.clear();
SharedData::clearVariables();
return true; return true;
} }
@@ -218,16 +210,41 @@ namespace hex::init {
PluginManager::load(dir); PluginManager::load(dir);
} }
if (PluginManager::getPlugins().empty()) { auto &plugins = PluginManager::getPlugins();
if (plugins.empty()) {
log::error("No plugins found!"); log::error("No plugins found!");
getInitArguments().push_back({ "no-plugins", {} }); ImHexApi::System::getInitArguments().insert({ "no-plugins", {} });
return false; return false;
} }
for (const auto &plugin : PluginManager::getPlugins()) { u32 builtinPlugins = 0;
if (!plugin.initializePlugin()) u32 loadErrors = 0;
for (const auto &plugin : plugins) {
if (!plugin.initializePlugin()) {
log::error("Failed to initialize plugin {}", plugin.getPath().filename().string()); log::error("Failed to initialize plugin {}", plugin.getPath().filename().string());
loadErrors++;
} else {
if (plugin.isBuiltinPlugin())
builtinPlugins++;
}
}
if (loadErrors == plugins.size()) {
log::error("No plugins loaded successfully!");
ImHexApi::System::getInitArguments().insert({ "no-plugins", {} });
return false;
}
if (builtinPlugins == 0) {
log::error("Built-in plugin not found!");
ImHexApi::System::getInitArguments().insert({ "no-plugins", {} });
return false;
} else if (builtinPlugins > 1) {
log::error("Found more than one built-in plugin!");
ImHexApi::System::getInitArguments().insert({ "no-plugins", {} });
return false;
} }
return true; return true;
@@ -247,25 +264,28 @@ namespace hex::init {
return false; return false;
} }
float interfaceScaling = 1.0F;
switch (ContentRegistry::Settings::read("hex.builtin.setting.interface", "hex.builtin.setting.interface.scaling", 0)) { switch (ContentRegistry::Settings::read("hex.builtin.setting.interface", "hex.builtin.setting.interface.scaling", 0)) {
default: default:
case 0: case 0:
// Native scaling // Native scaling
break; break;
case 1: case 1:
SharedData::globalScale = SharedData::fontScale = 0.5F; interfaceScaling = 0.5F;
break; break;
case 2: case 2:
SharedData::globalScale = SharedData::fontScale = 1.0F; interfaceScaling = 1.0F;
break; break;
case 3: case 3:
SharedData::globalScale = SharedData::fontScale = 1.5F; interfaceScaling = 1.5F;
break; break;
case 4: case 4:
SharedData::globalScale = SharedData::fontScale = 2.0F; interfaceScaling = 2.0F;
break; break;
} }
ImHexApi::System::impl::setGlobalScale(interfaceScaling);
return true; return true;
} }
@@ -281,7 +301,7 @@ namespace hex::init {
std::vector<Task> getInitTasks() { std::vector<Task> getInitTasks() {
return { return {
{"Checking for updates...", checkForUpdates }, { "Checking for updates...", checkForUpdates },
{ "Downloading information...", downloadInformation}, { "Downloading information...", downloadInformation},
{ "Creating directories...", createDirectories }, { "Creating directories...", createDirectories },
{ "Loading settings...", loadSettings }, { "Loading settings...", loadSettings },
@@ -292,16 +312,10 @@ namespace hex::init {
std::vector<Task> getExitTasks() { std::vector<Task> getExitTasks() {
return { return {
{"Saving settings...", storeSettings }, { "Saving settings...", storeSettings },
{ "Cleaning up shared data...", deleteSharedData}, { "Cleaning up shared data...", deleteSharedData },
{ "Unloading plugins...", unloadPlugins }, { "Unloading plugins...", unloadPlugins },
}; };
} }
std::vector<Argument> &getInitArguments() {
static std::vector<Argument> initArguments;
return initArguments;
}
} }

View File

@@ -2,7 +2,6 @@
#include <hex/helpers/utils.hpp> #include <hex/helpers/utils.hpp>
#include <hex/helpers/logger.hpp> #include <hex/helpers/logger.hpp>
#include <hex/helpers/shared_data.hpp>
#include "window.hpp" #include "window.hpp"
@@ -12,11 +11,8 @@
#include <hex/helpers/file.hpp> #include <hex/helpers/file.hpp>
int main(int argc, char **argv, char **envp) { int main(int argc, char **argv, char **envp) {
hex::SharedData::mainArgc = argc;
hex::SharedData::mainArgv = argv;
hex::SharedData::mainEnvp = envp;
using namespace hex; using namespace hex;
ImHexApi::System::impl::setProgramArguments(argc, argv, envp);
// Initialization // Initialization
{ {
@@ -30,7 +26,7 @@ int main(int argc, char **argv, char **envp) {
splashWindow.addStartupTask(name, task); splashWindow.addStartupTask(name, task);
if (!splashWindow.loop()) if (!splashWindow.loop())
init::getInitArguments().push_back({ "tasks-failed", {} }); ImHexApi::System::getInitArguments().insert({ "tasks-failed", {} });
} }
// Clean up // Clean up

View File

@@ -2,6 +2,9 @@
#if defined(OS_LINUX) #if defined(OS_LINUX)
#include <hex/api/content_registry.hpp>
#include <hex/api/event.hpp>
#include <hex/helpers/utils.hpp> #include <hex/helpers/utils.hpp>
#include <hex/helpers/logger.hpp> #include <hex/helpers/logger.hpp>

View File

@@ -2,6 +2,9 @@
#if defined(OS_MACOS) #if defined(OS_MACOS)
#include <hex/api/content_registry.hpp>
#include <hex/api/event.hpp>
#include <hex/helpers/logger.hpp> #include <hex/helpers/logger.hpp>
#include <nlohmann/json.hpp> #include <nlohmann/json.hpp>

View File

@@ -1,5 +1,6 @@
#include "window.hpp" #include "window.hpp"
#include <hex/api/content_registry.hpp>
#if defined(OS_WINDOWS) #if defined(OS_WINDOWS)
@@ -89,8 +90,8 @@ namespace hex {
POINT cursor = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) }; POINT cursor = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) };
const POINT border { const POINT border {
static_cast<LONG>((::GetSystemMetrics(SM_CXFRAME) + ::GetSystemMetrics(SM_CXPADDEDBORDER)) * SharedData::globalScale / 1.5F), static_cast<LONG>((::GetSystemMetrics(SM_CXFRAME) + ::GetSystemMetrics(SM_CXPADDEDBORDER)) * ImHexApi::System::getGlobalScale() / 1.5F),
static_cast<LONG>((::GetSystemMetrics(SM_CYFRAME) + ::GetSystemMetrics(SM_CXPADDEDBORDER)) * SharedData::globalScale / 1.5F) static_cast<LONG>((::GetSystemMetrics(SM_CYFRAME) + ::GetSystemMetrics(SM_CXPADDEDBORDER)) * ImHexApi::System::getGlobalScale() / 1.5F)
}; };
RECT window; RECT window;
@@ -205,8 +206,10 @@ namespace hex {
if (!globalMutex) { if (!globalMutex) {
globalMutex = CreateMutex(nullptr, FALSE, UniqueMutexId); globalMutex = CreateMutex(nullptr, FALSE, UniqueMutexId);
} else { } else {
if (SharedData::mainArgc > 1) { if (ImHexApi::System::getProgramArguments().argc > 1) {
::EnumWindows([](HWND hWnd, LPARAM lparam) -> BOOL { ::EnumWindows([](HWND hWnd, LPARAM lparam) -> BOOL {
auto &programArgs = ImHexApi::System::getProgramArguments();
auto length = ::GetWindowTextLength(hWnd); auto length = ::GetWindowTextLength(hWnd);
std::string windowName(length + 1, '\x00'); std::string windowName(length + 1, '\x00');
::GetWindowText(hWnd, windowName.data(), windowName.size()); ::GetWindowText(hWnd, windowName.data(), windowName.size());
@@ -215,8 +218,8 @@ namespace hex {
if (windowName.starts_with("ImHex")) { if (windowName.starts_with("ImHex")) {
COPYDATASTRUCT message = { COPYDATASTRUCT message = {
.dwData = 0, .dwData = 0,
.cbData = static_cast<DWORD>(std::strlen(SharedData::mainArgv[1])) + 1, .cbData = static_cast<DWORD>(std::strlen(programArgs.argv[1])) + 1,
.lpData = SharedData::mainArgv[1] .lpData = programArgs.argv[1]
}; };
SendMessage(hWnd, WM_COPYDATA, reinterpret_cast<WPARAM>(hWnd), reinterpret_cast<LPARAM>(&message)); SendMessage(hWnd, WM_COPYDATA, reinterpret_cast<WPARAM>(hWnd), reinterpret_cast<LPARAM>(&message));

View File

@@ -2,6 +2,10 @@
#include <hex.hpp> #include <hex.hpp>
#include <hex/api/plugin_manager.hpp>
#include <hex/api/content_registry.hpp>
#include <hex/api/imhex_api.hpp>
#include <hex/helpers/utils.hpp> #include <hex/helpers/utils.hpp>
#include <hex/helpers/paths.hpp> #include <hex/helpers/paths.hpp>
#include <hex/helpers/logger.hpp> #include <hex/helpers/logger.hpp>
@@ -33,7 +37,6 @@
#include <codicons_font.h> #include <codicons_font.h>
#include <unifont_font.h> #include <unifont_font.h>
#include "helpers/plugin_manager.hpp"
#include <hex/helpers/project_file_handler.hpp> #include <hex/helpers/project_file_handler.hpp>
#include "init/tasks.hpp" #include "init/tasks.hpp"
@@ -70,17 +73,9 @@ namespace hex {
Window::Window() { Window::Window() {
{ {
for (const auto &[argument, value] : init::getInitArguments()) { for (const auto &[argument, value] : ImHexApi::System::getInitArguments()) {
if (argument == "update-available") { if (argument == "no-plugins") {
this->m_availableUpdate = value; ImHexApi::Tasks::doLater([] { ImGui::OpenPopup("No Plugins"); });
} else if (argument == "no-plugins") {
View::doLater([] { ImGui::OpenPopup("No Plugins"); });
} else if (argument == "tip-of-the-day") {
this->m_tipOfTheDay = value;
this->m_showTipOfTheDay = ContentRegistry::Settings::read("hex.builtin.setting.general", "hex.builtin.setting.general.show_tips", 1);
if (this->m_showTipOfTheDay)
View::doLater([] { ImGui::OpenPopup("hex.welcome.tip_of_the_day"_lang); });
} }
} }
} }
@@ -89,127 +84,6 @@ namespace hex {
this->initImGui(); this->initImGui();
this->setupNativeWindow(); this->setupNativeWindow();
EventManager::subscribe<EventSettingsChanged>(this, [this]() {
{
auto theme = ContentRegistry::Settings::getSetting("hex.builtin.setting.interface", "hex.builtin.setting.interface.color");
if (theme.is_number())
EventManager::post<RequestChangeTheme>(theme.get<int>());
}
{
auto language = ContentRegistry::Settings::getSetting("hex.builtin.setting.interface", "hex.builtin.setting.interface.language");
if (language.is_string()) {
LangEntry::loadLanguage(static_cast<std::string>(language));
} else {
// If no language is specified, fall back to English.
LangEntry::loadLanguage("en-US");
}
}
{
auto targetFps = ContentRegistry::Settings::getSetting("hex.builtin.setting.interface", "hex.builtin.setting.interface.fps");
if (targetFps.is_number())
this->m_targetFps = targetFps;
}
{
if (ContentRegistry::Settings::read("hex.builtin.setting.imhex", "hex.builtin.setting.imhex.launched", 0) == 1)
this->m_layoutConfigured = true;
else
ContentRegistry::Settings::write("hex.builtin.setting.imhex", "hex.builtin.setting.imhex.launched", 1);
}
});
EventManager::subscribe<RequestChangeTheme>(this, [this](u32 theme) {
if (this->m_bannerTexture.valid())
ImGui::UnloadImage(this->m_bannerTexture);
switch (theme) {
default:
case 1: /* Dark theme */
{
ImGui::StyleColorsDark();
ImGui::StyleCustomColorsDark();
ImPlot::StyleColorsDark();
auto banner = romfs::get("banner_dark.png");
this->m_bannerTexture = ImGui::LoadImageFromMemory(reinterpret_cast<const ImU8 *>(banner.data()), banner.size());
break;
}
case 2: /* Light theme */
{
ImGui::StyleColorsLight();
ImGui::StyleCustomColorsLight();
ImPlot::StyleColorsLight();
auto banner = romfs::get("banner_light.png");
this->m_bannerTexture = ImGui::LoadImageFromMemory(reinterpret_cast<const ImU8 *>(banner.data()), banner.size());
break;
}
case 3: /* Classic theme */
{
ImGui::StyleColorsClassic();
ImGui::StyleCustomColorsClassic();
ImPlot::StyleColorsClassic();
auto banner = romfs::get("banner_dark.png");
this->m_bannerTexture = ImGui::LoadImageFromMemory(reinterpret_cast<const ImU8 *>(banner.data()), banner.size());
break;
}
}
ImGui::GetStyle().Colors[ImGuiCol_DockingEmptyBg] = ImGui::GetStyle().Colors[ImGuiCol_WindowBg];
ImGui::GetStyle().Colors[ImGuiCol_TitleBg] = ImGui::GetStyle().Colors[ImGuiCol_MenuBarBg];
ImGui::GetStyle().Colors[ImGuiCol_TitleBgActive] = ImGui::GetStyle().Colors[ImGuiCol_MenuBarBg];
ImGui::GetStyle().Colors[ImGuiCol_TitleBgCollapsed] = ImGui::GetStyle().Colors[ImGuiCol_MenuBarBg];
if (!this->m_bannerTexture.valid()) {
log::fatal("Failed to load banner texture!");
std::abort();
}
});
EventManager::subscribe<EventFileLoaded>(this, [](const auto &path) {
SharedData::recentFilePaths.push_front(path);
{
std::list<fs::path> uniques;
for (auto &file : SharedData::recentFilePaths) {
bool exists = false;
for (auto &unique : uniques) {
if (file == unique)
exists = true;
}
if (!exists && !file.empty())
uniques.push_back(file);
if (uniques.size() > 5)
break;
}
SharedData::recentFilePaths = uniques;
}
{
std::vector<std::string> recentFilesVector;
for (const auto &recentPath : SharedData::recentFilePaths)
recentFilesVector.push_back(recentPath.string());
ContentRegistry::Settings::write("hex.builtin.setting.imhex", "hex.builtin.setting.imhex.recent_files", recentFilesVector);
}
});
EventManager::subscribe<EventFileUnloaded>(this, [] {
EventManager::post<RequestChangeWindowTitle>("");
});
EventManager::subscribe<RequestCloseImHex>(this, [this](bool noQuestions) { EventManager::subscribe<RequestCloseImHex>(this, [this](bool noQuestions) {
glfwSetWindowShouldClose(this->m_window, true); glfwSetWindowShouldClose(this->m_window, true);
@@ -217,6 +91,10 @@ namespace hex {
EventManager::post<EventWindowClosing>(this->m_window); EventManager::post<EventWindowClosing>(this->m_window);
}); });
EventManager::subscribe<EventFileUnloaded>(this, [] {
EventManager::post<RequestChangeWindowTitle>("");
});
EventManager::subscribe<RequestChangeWindowTitle>(this, [this](std::string windowTitle) { EventManager::subscribe<RequestChangeWindowTitle>(this, [this](std::string windowTitle) {
std::string title = "ImHex"; std::string title = "ImHex";
@@ -248,17 +126,6 @@ namespace hex {
this->m_popupsToOpen.push_back(name); this->m_popupsToOpen.push_back(name);
}); });
for (const auto &path : hex::getPath(ImHexPath::Config)) {
if (auto filePath = fs::path(path) / CrashBackupFileName; fs::exists(filePath)) {
this->m_safetyBackupPath = filePath;
View::doLater([] { ImGui::OpenPopup("hex.safety_backup.title"_lang); });
}
}
for (const auto &path : ContentRegistry::Settings::read("hex.builtin.setting.imhex", "hex.builtin.setting.imhex.recent_files"))
SharedData::recentFilePaths.push_back(path);
auto signalHandler = [](int signalNumber) { auto signalHandler = [](int signalNumber) {
EventManager::post<EventAbnormalTermination>(signalNumber); EventManager::post<EventAbnormalTermination>(signalNumber);
@@ -269,11 +136,11 @@ namespace hex {
// Let's not loop on this... // Let's not loop on this...
std::signal(signalNumber, nullptr); std::signal(signalNumber, nullptr);
#if defined(DEBUG) #if defined(DEBUG)
assert(false); assert(false);
#else #else
std::raise(signalNumber); std::raise(signalNumber);
#endif #endif
}; };
std::signal(SIGTERM, signalHandler); std::signal(SIGTERM, signalHandler);
@@ -294,17 +161,11 @@ namespace hex {
this->exitImGui(); this->exitImGui();
this->exitGLFW(); this->exitGLFW();
EventManager::unsubscribe<EventSettingsChanged>(this);
EventManager::unsubscribe<EventFileLoaded>(this);
EventManager::unsubscribe<EventFileUnloaded>(this); EventManager::unsubscribe<EventFileUnloaded>(this);
EventManager::unsubscribe<RequestCloseImHex>(this); EventManager::unsubscribe<RequestCloseImHex>(this);
EventManager::unsubscribe<RequestChangeWindowTitle>(this); EventManager::unsubscribe<RequestChangeWindowTitle>(this);
EventManager::unsubscribe<EventAbnormalTermination>(this); EventManager::unsubscribe<EventAbnormalTermination>(this);
EventManager::unsubscribe<RequestChangeTheme>(this);
EventManager::unsubscribe<RequestOpenPopup>(this); EventManager::unsubscribe<RequestOpenPopup>(this);
ImGui::UnloadImage(this->m_bannerTexture);
ImGui::UnloadImage(this->m_logoTexture);
} }
void Window::loop() { void Window::loop() {
@@ -316,7 +177,7 @@ namespace hex {
} else { } else {
double timeout = (1.0 / 5.0) - (glfwGetTime() - this->m_lastFrameTime); double timeout = (1.0 / 5.0) - (glfwGetTime() - this->m_lastFrameTime);
timeout = timeout > 0 ? timeout : 0; timeout = timeout > 0 ? timeout : 0;
glfwWaitEventsTimeout(ImGui::IsPopupOpen(ImGuiID(0), ImGuiPopupFlags_AnyPopupId) || !SharedData::runningTasks.empty() ? 0 : timeout); glfwWaitEventsTimeout(ImGui::IsPopupOpen(ImGuiID(0), ImGuiPopupFlags_AnyPopupId) || Task::getRunningTaskCount() > 0 ? 0 : timeout);
} }
@@ -353,9 +214,10 @@ namespace hex {
ImGui::SetCursorPosX(sidebarWidth); ImGui::SetCursorPosX(sidebarWidth);
auto footerHeight = ImGui::GetTextLineHeightWithSpacing() + ImGui::GetStyle().FramePadding.y * 2 + 1_scaled; auto footerHeight = ImGui::GetTextLineHeightWithSpacing() + ImGui::GetStyle().FramePadding.y * 2 + 1_scaled;
auto dockSpaceSize = ImVec2(SharedData::windowSize.x - sidebarWidth, ImGui::GetContentRegionAvail().y - footerHeight); auto dockSpaceSize = ImVec2(ImHexApi::System::getMainWindowSize().x - sidebarWidth, ImGui::GetContentRegionAvail().y - footerHeight);
SharedData::dockSpaceId = ImGui::DockSpace(ImGui::GetID("MainDock"), dockSpaceSize); auto dockId = ImGui::DockSpace(ImGui::GetID("MainDock"), dockSpaceSize);
ImHexApi::System::impl::setMainDockSpaceId(dockId);
drawList->AddRectFilled(ImGui::GetWindowPos(), ImGui::GetWindowPos() + ImGui::GetWindowSize() - ImVec2(dockSpaceSize.x, footerHeight - ImGui::GetStyle().FramePadding.y - 1_scaled), ImGui::GetColorU32(ImGuiCol_MenuBarBg)); drawList->AddRectFilled(ImGui::GetWindowPos(), ImGui::GetWindowPos() + ImGui::GetWindowSize() - ImVec2(dockSpaceSize.x, footerHeight - ImGui::GetStyle().FramePadding.y - 1_scaled), ImGui::GetColorU32(ImGuiCol_MenuBarBg));
@@ -461,23 +323,6 @@ namespace hex {
ImGui::EndMenuBar(); ImGui::EndMenuBar();
} }
if (!ImHexApi::Provider::isValid()) {
static char title[256];
ImFormatString(title, IM_ARRAYSIZE(title), "%s/DockSpace_%08X", ImGui::GetCurrentWindow()->Name, ImGui::GetID("MainDock"));
if (ImGui::Begin(title)) {
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(10_scaled, 10_scaled));
if (ImGui::BeginChild("Welcome Screen", ImVec2(0, 0), false, ImGuiWindowFlags_AlwaysUseWindowPadding | ImGuiWindowFlags_NoScrollWithMouse)) {
this->drawWelcomeScreen();
}
ImGui::EndChild();
ImGui::PopStyleVar();
}
ImGui::End();
} else if (!this->m_layoutConfigured) {
this->m_layoutConfigured = true;
this->resetLayout();
}
this->beginNativeWindowFrame(); this->beginNativeWindowFrame();
drawList->AddLine(ImGui::GetWindowPos() + ImVec2(sidebarWidth - 2, 0), ImGui::GetWindowPos() + ImGui::GetWindowSize() - ImVec2(dockSpaceSize.x + 2, footerHeight - ImGui::GetStyle().FramePadding.y - 2), ImGui::GetColorU32(ImGuiCol_Separator)); drawList->AddLine(ImGui::GetWindowPos() + ImVec2(sidebarWidth - 2, 0), ImGui::GetWindowPos() + ImGui::GetWindowSize() - ImVec2(dockSpaceSize.x + 2, footerHeight - ImGui::GetStyle().FramePadding.y - 2), ImGui::GetColorU32(ImGuiCol_Separator));
@@ -486,28 +331,6 @@ namespace hex {
ImGui::End(); ImGui::End();
ImGui::PopStyleVar(2); ImGui::PopStyleVar(2);
ImGui::SetNextWindowPos(ImGui::GetMainViewport()->GetCenter(), ImGuiCond_Appearing, ImVec2(0.5F, 0.5F));
ImGui::SetNextWindowSize(ImGui::GetMainViewport()->Size / 3, ImGuiCond_Appearing);
if (ImGui::BeginPopup("hex.welcome.tip_of_the_day"_lang)) {
ImGui::Header("hex.welcome.tip_of_the_day"_lang, true);
ImGui::TextFormattedWrapped("{}", this->m_tipOfTheDay.c_str());
ImGui::NewLine();
bool dontShowAgain = !this->m_showTipOfTheDay;
if (ImGui::Checkbox("hex.common.dont_show_again"_lang, &dontShowAgain)) {
this->m_showTipOfTheDay = !dontShowAgain;
ContentRegistry::Settings::write("hex.builtin.setting.general", "hex.builtin.setting.general.show_tips", this->m_showTipOfTheDay);
}
ImGui::SameLine((ImGui::GetMainViewport()->Size / 3 - ImGui::CalcTextSize("hex.common.close"_lang) - ImGui::GetStyle().FramePadding).x);
if (ImGui::Button("hex.common.close"_lang))
ImGui::CloseCurrentPopup();
ImGui::EndPopup();
}
ImGui::SetNextWindowPos(ImGui::GetMainViewport()->GetCenter(), ImGuiCond_Appearing, ImVec2(0.5F, 0.5F)); ImGui::SetNextWindowPos(ImGui::GetMainViewport()->GetCenter(), ImGuiCond_Appearing, ImVec2(0.5F, 0.5F));
if (ImGui::BeginPopupModal("No Plugins", nullptr, ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoMove)) { if (ImGui::BeginPopupModal("No Plugins", nullptr, ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoMove)) {
ImGui::TextUnformatted("No ImHex plugins loaded (including the built-in plugin)!"); ImGui::TextUnformatted("No ImHex plugins loaded (including the built-in plugin)!");
@@ -516,34 +339,6 @@ namespace hex {
ImGui::EndPopup(); ImGui::EndPopup();
} }
// Popup for if there is a safety backup present because ImHex crashed
ImGui::SetNextWindowPos(ImGui::GetMainViewport()->GetCenter(), ImGuiCond_Appearing, ImVec2(0.5F, 0.5F));
if (ImGui::BeginPopupModal("hex.safety_backup.title"_lang, nullptr, ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoMove)) {
ImGui::TextUnformatted("hex.safety_backup.desc"_lang);
ImGui::NewLine();
auto width = ImGui::GetWindowWidth();
ImGui::SetCursorPosX(width / 9);
if (ImGui::Button("hex.safety_backup.restore"_lang, ImVec2(width / 3, 0))) {
ProjectFile::load(this->m_safetyBackupPath.string());
ProjectFile::markDirty();
ProjectFile::clearProjectFilePath();
fs::remove(this->m_safetyBackupPath);
ImGui::CloseCurrentPopup();
}
ImGui::SameLine();
ImGui::SetCursorPosX(width / 9 * 5);
if (ImGui::Button("hex.safety_backup.delete"_lang, ImVec2(width / 3, 0))) {
fs::remove(this->m_safetyBackupPath);
ImGui::CloseCurrentPopup();
}
ImGui::EndPopup();
}
this->m_popupsToOpen.remove_if([](const auto &name) { this->m_popupsToOpen.remove_if([](const auto &name) {
if (ImGui::IsPopupOpen(name.c_str())) if (ImGui::IsPopupOpen(name.c_str()))
return true; return true;
@@ -557,9 +352,12 @@ namespace hex {
} }
void Window::frame() { void Window::frame() {
for (const auto &call : View::getDeferedCalls()) {
call(); auto &calls = ImHexApi::Tasks::getDeferredCalls();
View::getDeferedCalls().clear(); for (const auto &callback : calls)
callback();
calls.clear();
}
View::drawCommonInterfaces(); View::drawCommonInterfaces();
@@ -619,169 +417,15 @@ namespace hex {
glfwSwapBuffers(this->m_window); glfwSwapBuffers(this->m_window);
if (this->m_targetFps <= 200) const auto targetFps = ImHexApi::System::getTargetFPS();
std::this_thread::sleep_for(std::chrono::milliseconds(u64((this->m_lastFrameTime + 1 / this->m_targetFps - glfwGetTime()) * 1000))); if (targetFps <= 200)
std::this_thread::sleep_for(std::chrono::milliseconds(u64((this->m_lastFrameTime + 1 / targetFps - glfwGetTime()) * 1000)));
this->m_lastFrameTime = glfwGetTime(); this->m_lastFrameTime = glfwGetTime();
} }
void Window::drawWelcomeScreen() { void Window::drawWelcomeScreen() {
const auto availableSpace = ImGui::GetContentRegionAvail();
ImGui::Image(this->m_bannerTexture, this->m_bannerTexture.size() / (2 * (1.0F / SharedData::globalScale)));
ImGui::Indent();
if (ImGui::BeginTable("Welcome Left", 1, ImGuiTableFlags_NoBordersInBody, ImVec2(availableSpace.x / 2, 0))) {
ImGui::TableNextRow(ImGuiTableRowFlags_None, ImGui::GetTextLineHeightWithSpacing() * 3);
ImGui::TableNextColumn();
ImGui::TextFormattedWrapped("A Hex Editor for Reverse Engineers, Programmers and people who value their retinas when working at 3 AM.");
ImGui::TableNextRow(ImGuiTableRowFlags_None, ImGui::GetTextLineHeightWithSpacing() * 6);
ImGui::TableNextColumn();
ImGui::UnderlinedText("hex.welcome.header.start"_lang);
ImGui::SetCursorPosY(ImGui::GetCursorPosY() + 5_scaled);
{
if (ImGui::IconHyperlink(ICON_VS_NEW_FILE, "hex.welcome.start.create_file"_lang))
EventManager::post<RequestOpenWindow>("Create File");
if (ImGui::IconHyperlink(ICON_VS_GO_TO_FILE, "hex.welcome.start.open_file"_lang))
EventManager::post<RequestOpenWindow>("Open File");
if (ImGui::IconHyperlink(ICON_VS_NOTEBOOK, "hex.welcome.start.open_project"_lang))
EventManager::post<RequestOpenWindow>("Open Project");
if (ImGui::IconHyperlink(ICON_VS_TELESCOPE, "hex.welcome.start.open_other"_lang))
ImGui::OpenPopup("hex.welcome.start.popup.open_other"_lang);
}
ImGui::SetNextWindowPos(ImGui::GetWindowPos() + ImGui::GetCursorPos());
if (ImGui::BeginPopup("hex.welcome.start.popup.open_other"_lang)) {
for (const auto &unlocalizedProviderName : ContentRegistry::Provider::getEntries()) {
if (ImGui::Hyperlink(LangEntry(unlocalizedProviderName))) {
EventManager::post<RequestCreateProvider>(unlocalizedProviderName, nullptr);
ImGui::CloseCurrentPopup();
}
}
ImGui::EndPopup();
}
ImGui::TableNextRow(ImGuiTableRowFlags_None, ImGui::GetTextLineHeightWithSpacing() * 9);
ImGui::TableNextColumn();
ImGui::UnderlinedText("hex.welcome.start.recent"_lang);
ImGui::SetCursorPosY(ImGui::GetCursorPosY() + 5_scaled);
{
if (!SharedData::recentFilePaths.empty()) {
for (auto &path : SharedData::recentFilePaths) {
if (ImGui::BulletHyperlink(fs::path(path).filename().string().c_str())) {
EventManager::post<RequestOpenFile>(path);
break;
}
}
}
}
if (!this->m_availableUpdate.empty()) {
ImGui::TableNextRow(ImGuiTableRowFlags_None, ImGui::GetTextLineHeightWithSpacing() * 5);
ImGui::TableNextColumn();
ImGui::UnderlinedText("hex.welcome.header.update"_lang);
{
if (ImGui::DescriptionButton("hex.welcome.update.title"_lang, hex::format("hex.welcome.update.desc"_lang, this->m_availableUpdate).c_str(), ImVec2(ImGui::GetContentRegionAvail().x * 0.8F, 0)))
hex::openWebpage("hex.welcome.update.link"_lang);
}
}
ImGui::TableNextRow(ImGuiTableRowFlags_None, ImGui::GetTextLineHeightWithSpacing() * 6);
ImGui::TableNextColumn();
ImGui::UnderlinedText("hex.welcome.header.help"_lang);
ImGui::SetCursorPosY(ImGui::GetCursorPosY() + 5_scaled);
{
if (ImGui::IconHyperlink(ICON_VS_GITHUB, "hex.welcome.help.repo"_lang)) hex::openWebpage("hex.welcome.help.repo.link"_lang);
if (ImGui::IconHyperlink(ICON_VS_ORGANIZATION, "hex.welcome.help.gethelp"_lang)) hex::openWebpage("hex.welcome.help.gethelp.link"_lang);
if (ImGui::IconHyperlink(ICON_VS_COMMENT_DISCUSSION, "hex.welcome.help.discord"_lang)) hex::openWebpage("hex.welcome.help.discord.link"_lang);
}
ImGui::TableNextRow(ImGuiTableRowFlags_None, ImGui::GetTextLineHeightWithSpacing() * 5);
ImGui::TableNextColumn();
ImGui::UnderlinedText("hex.welcome.header.plugins"_lang);
{
const auto &plugins = PluginManager::getPlugins();
if (!plugins.empty()) {
if (ImGui::BeginTable("plugins", 4, ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg | ImGuiTableFlags_ScrollY | ImGuiTableFlags_SizingFixedFit, ImVec2((ImGui::GetContentRegionAvail().x * 5) / 6, ImGui::GetTextLineHeightWithSpacing() * 5))) {
ImGui::TableSetupScrollFreeze(0, 1);
ImGui::TableSetupColumn("hex.welcome.plugins.plugin"_lang, ImGuiTableColumnFlags_WidthStretch, 0.2);
ImGui::TableSetupColumn("hex.welcome.plugins.author"_lang, ImGuiTableColumnFlags_WidthStretch, 0.2);
ImGui::TableSetupColumn("hex.welcome.plugins.desc"_lang, ImGuiTableColumnFlags_WidthStretch, 0.6);
ImGui::TableSetupColumn("##loaded", ImGuiTableColumnFlags_WidthFixed, ImGui::GetTextLineHeight());
ImGui::TableHeadersRow();
ImGuiListClipper clipper;
clipper.Begin(plugins.size());
while (clipper.Step()) {
for (u64 i = clipper.DisplayStart; i < clipper.DisplayEnd; i++) {
const auto &plugin = plugins[i];
ImGui::TableNextRow();
ImGui::TableNextColumn();
ImGui::TextUnformatted(plugin.getPluginName().c_str());
ImGui::TableNextColumn();
ImGui::TextUnformatted(plugin.getPluginAuthor().c_str());
ImGui::TableNextColumn();
ImGui::TextUnformatted(plugin.getPluginDescription().c_str());
ImGui::TableNextColumn();
ImGui::TextUnformatted(plugin.isLoaded() ? ICON_VS_CHECK : ICON_VS_CLOSE);
}
}
clipper.End();
ImGui::EndTable();
}
}
}
ImGui::EndTable();
}
ImGui::SameLine();
if (ImGui::BeginTable("Welcome Right", 1, ImGuiTableFlags_NoBordersInBody, ImVec2(availableSpace.x / 2, 0))) {
ImGui::TableNextRow(ImGuiTableRowFlags_None, ImGui::GetTextLineHeightWithSpacing() * 5);
ImGui::TableNextColumn();
ImGui::UnderlinedText("hex.welcome.header.customize"_lang);
{
if (ImGui::DescriptionButton("hex.welcome.customize.settings.title"_lang, "hex.welcome.customize.settings.desc"_lang, ImVec2(ImGui::GetContentRegionAvail().x * 0.8F, 0)))
EventManager::post<RequestOpenWindow>("Settings");
}
ImGui::TableNextRow(ImGuiTableRowFlags_None, ImGui::GetTextLineHeightWithSpacing() * 5);
ImGui::TableNextColumn();
ImGui::UnderlinedText("hex.welcome.header.learn"_lang);
{
if (ImGui::DescriptionButton("hex.welcome.learn.latest.title"_lang, "hex.welcome.learn.latest.desc"_lang, ImVec2(ImGui::GetContentRegionAvail().x * 0.8F, 0)))
hex::openWebpage("hex.welcome.learn.latest.link"_lang);
if (ImGui::DescriptionButton("hex.welcome.learn.pattern.title"_lang, "hex.welcome.learn.pattern.desc"_lang, ImVec2(ImGui::GetContentRegionAvail().x * 0.8F, 0)))
hex::openWebpage("hex.welcome.learn.pattern.link"_lang);
if (ImGui::DescriptionButton("hex.welcome.learn.plugins.title"_lang, "hex.welcome.learn.plugins.desc"_lang, ImVec2(ImGui::GetContentRegionAvail().x * 0.8F, 0)))
hex::openWebpage("hex.welcome.learn.plugins.link"_lang);
}
auto extraWelcomeScreenEntries = ContentRegistry::Interface::getWelcomeScreenEntries();
if (!extraWelcomeScreenEntries.empty()) {
ImGui::TableNextRow(ImGuiTableRowFlags_None, ImGui::GetTextLineHeightWithSpacing() * 5);
ImGui::TableNextColumn();
ImGui::UnderlinedText("hex.welcome.header.various"_lang);
{
for (const auto &callback : extraWelcomeScreenEntries)
callback();
}
}
ImGui::EndTable();
}
} }
void Window::resetLayout() const { void Window::resetLayout() const {
@@ -789,7 +433,7 @@ namespace hex {
if (auto &layouts = ContentRegistry::Interface::getLayouts(); !layouts.empty()) { if (auto &layouts = ContentRegistry::Interface::getLayouts(); !layouts.empty()) {
auto &[name, function] = layouts[0]; auto &[name, function] = layouts[0];
function(ContentRegistry::Interface::getDockSpaceId()); function(ImHexApi::System::getMainDockSpaceId());
} }
} }
@@ -845,18 +489,19 @@ namespace hex {
{ {
int x = 0, y = 0; int x = 0, y = 0;
glfwGetWindowPos(this->m_window, &x, &y); glfwGetWindowPos(this->m_window, &x, &y);
SharedData::windowPos = ImVec2(x, y);
ImHexApi::System::impl::setMainWindowPosition(x, y);
} }
{ {
int width = 0, height = 0; int width = 0, height = 0;
glfwGetWindowSize(this->m_window, &width, &height); glfwGetWindowSize(this->m_window, &width, &height);
glfwSetWindowSize(this->m_window, width, height); glfwSetWindowSize(this->m_window, width, height);
SharedData::windowSize = ImVec2(width, height); ImHexApi::System::impl::setMainWindowSize(width, height);
} }
glfwSetWindowPosCallback(this->m_window, [](GLFWwindow *window, int x, int y) { glfwSetWindowPosCallback(this->m_window, [](GLFWwindow *window, int x, int y) {
SharedData::windowPos = ImVec2(x, y); ImHexApi::System::impl::setMainWindowPosition(x, y);
if (auto g = ImGui::GetCurrentContext(); g == nullptr || g->WithinFrameScope) return; if (auto g = ImGui::GetCurrentContext(); g == nullptr || g->WithinFrameScope) return;
@@ -867,7 +512,7 @@ namespace hex {
}); });
glfwSetWindowSizeCallback(this->m_window, [](GLFWwindow *window, int width, int height) { glfwSetWindowSizeCallback(this->m_window, [](GLFWwindow *window, int width, int height) {
SharedData::windowSize = ImVec2(width, height); ImHexApi::System::impl::setMainWindowSize(width, height);
if (auto g = ImGui::GetCurrentContext(); g == nullptr || g->WithinFrameScope) return; if (auto g = ImGui::GetCurrentContext(); g == nullptr || g->WithinFrameScope) return;
@@ -913,7 +558,7 @@ namespace hex {
for (const auto &extension : extensions) { for (const auto &extension : extensions) {
if (path.extension() == extension) { if (path.extension() == extension) {
if (!handler(path)) if (!handler(path))
View::showMessagePopup("hex.message.file_handler_failed"_lang); log::error("Handler for extensions '{}' failed to process file!", extension);
handled = true; handled = true;
break; break;
@@ -938,7 +583,9 @@ namespace hex {
void Window::initImGui() { void Window::initImGui() {
IMGUI_CHECKVERSION(); IMGUI_CHECKVERSION();
GImGui = ImGui::CreateContext(SharedData::fontAtlas); auto fonts = View::getFontAtlas();
GImGui = ImGui::CreateContext(fonts);
GImPlot = ImPlot::CreateContext(); GImPlot = ImPlot::CreateContext();
GImNodes = ImNodes::CreateContext(); GImNodes = ImNodes::CreateContext();
@@ -953,7 +600,7 @@ namespace hex {
io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable; io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable;
#endif #endif
for (auto &entry : SharedData::fontAtlas->ConfigData) for (auto &entry : fonts->ConfigData)
io.Fonts->ConfigData.push_back(entry); io.Fonts->ConfigData.push_back(entry);
io.ConfigViewportsNoTaskBarIcon = false; io.ConfigViewportsNoTaskBarIcon = false;
@@ -990,7 +637,7 @@ namespace hex {
io.UserData = new ImGui::ImHexCustomData(); io.UserData = new ImGui::ImHexCustomData();
style.ScaleAllSizes(SharedData::globalScale); style.ScaleAllSizes(ImHexApi::System::getGlobalScale());
{ {
GLsizei width, height; GLsizei width, height;

View File

@@ -18,6 +18,7 @@ add_library(${PROJECT_NAME} SHARED
source/content/data_formatters.cpp source/content/data_formatters.cpp
source/content/layouts.cpp source/content/layouts.cpp
source/content/main_menu_items.cpp source/content/main_menu_items.cpp
source/content/welcome_screen.cpp
source/content/providers/file_provider.cpp source/content/providers/file_provider.cpp
source/content/providers/gdb_provider.cpp source/content/providers/gdb_provider.cpp

View File

@@ -1,22 +1,21 @@
#pragma once #pragma once
#include <hex/views/view.hpp> #include <hex/ui/view.hpp>
#include <vector> #include <vector>
#include <list> #include <list>
namespace hex::plugin::builtin { namespace hex::plugin::builtin {
namespace prv {
class Provider;
}
class ViewBookmarks : public View { class ViewBookmarks : public View {
public: public:
ViewBookmarks(); ViewBookmarks();
~ViewBookmarks() override; ~ViewBookmarks() override;
void drawContent() override; void drawContent() override;
private:
std::list<ImHexApi::Bookmarks::Entry> m_bookmarks;
}; };
} }

View File

@@ -1,7 +1,7 @@
#pragma once #pragma once
#include <hex.hpp> #include <hex.hpp>
#include <hex/views/view.hpp> #include <hex/ui/view.hpp>
#include <imgui.h> #include <imgui.h>

View File

@@ -1,6 +1,6 @@
#pragma once #pragma once
#include <hex/views/view.hpp> #include <hex/ui/view.hpp>
#include <cstdio> #include <cstdio>
#include <string> #include <string>

View File

@@ -1,6 +1,6 @@
#pragma once #pragma once
#include <hex/views/view.hpp> #include <hex/ui/view.hpp>
#include <hex/api/content_registry.hpp> #include <hex/api/content_registry.hpp>

View File

@@ -3,7 +3,7 @@
#include <hex.hpp> #include <hex.hpp>
#include <imgui.h> #include <imgui.h>
#include <hex/views/view.hpp> #include <hex/ui/view.hpp>
#include <hex/data_processor/node.hpp> #include <hex/data_processor/node.hpp>
#include <hex/data_processor/link.hpp> #include <hex/data_processor/link.hpp>

View File

@@ -3,7 +3,7 @@
#include <hex.hpp> #include <hex.hpp>
#include <imgui.h> #include <imgui.h>
#include <hex/views/view.hpp> #include <hex/ui/view.hpp>
#include <array> #include <array>
#include <string> #include <string>

View File

@@ -1,6 +1,6 @@
#pragma once #pragma once
#include <hex/views/view.hpp> #include <hex/ui/view.hpp>
#include <hex/helpers/disassembler.hpp> #include <hex/helpers/disassembler.hpp>

View File

@@ -1,6 +1,6 @@
#pragma once #pragma once
#include <hex/views/view.hpp> #include <hex/ui/view.hpp>
#include <array> #include <array>
#include <utility> #include <utility>

View File

@@ -3,7 +3,7 @@
#include <hex.hpp> #include <hex.hpp>
#include <imgui.h> #include <imgui.h>
#include <hex/views/view.hpp> #include <hex/ui/view.hpp>
#include <vector> #include <vector>
#include <tuple> #include <tuple>

View File

@@ -1,6 +1,6 @@
#pragma once #pragma once
#include <hex/views/view.hpp> #include <hex/ui/view.hpp>
#include <hex/helpers/encoding_file.hpp> #include <hex/helpers/encoding_file.hpp>
#include <imgui_memory_editor.h> #include <imgui_memory_editor.h>

View File

@@ -1,6 +1,6 @@
#pragma once #pragma once
#include <hex/views/view.hpp> #include <hex/ui/view.hpp>
#include <array> #include <array>
#include <atomic> #include <atomic>

View File

@@ -3,7 +3,7 @@
#include <hex.hpp> #include <hex.hpp>
#include <imgui.h> #include <imgui.h>
#include <hex/views/view.hpp> #include <hex/ui/view.hpp>
#include <optional> #include <optional>

View File

@@ -3,24 +3,12 @@
#include <hex.hpp> #include <hex.hpp>
#include <imgui.h> #include <imgui.h>
#include <hex/views/view.hpp> #include <hex/ui/view.hpp>
#include <vector> #include <vector>
#include <tuple> #include <tuple>
#include <cstdio> #include <cstdio>
namespace hex {
namespace prv {
class Provider;
}
namespace lang {
class PatternData;
}
}
namespace hex::plugin::builtin { namespace hex::plugin::builtin {
class ViewPatternData : public View { class ViewPatternData : public View {
@@ -31,7 +19,7 @@ namespace hex::plugin::builtin {
void drawContent() override; void drawContent() override;
private: private:
std::vector<pl::PatternData *> m_sortedPatternData; std::map<prv::Provider*, std::vector<pl::PatternData*>> m_sortedPatterns;
}; };
} }

View File

@@ -1,6 +1,6 @@
#pragma once #pragma once
#include <hex/views/view.hpp> #include <hex/ui/view.hpp>
#include <hex/pattern_language/pattern_language.hpp> #include <hex/pattern_language/pattern_language.hpp>
#include <hex/pattern_language/log_console.hpp> #include <hex/pattern_language/log_console.hpp>
#include <hex/providers/provider.hpp> #include <hex/providers/provider.hpp>
@@ -24,14 +24,14 @@ namespace hex::plugin::builtin {
void drawContent() override; void drawContent() override;
private: private:
pl::PatternLanguage *m_parserRuntime, *m_evaluatorRuntime; pl::PatternLanguage *m_parserRuntime;
std::vector<fs::path> m_possiblePatternFiles; std::vector<fs::path> m_possiblePatternFiles;
u32 m_selectedPatternFile = 0; u32 m_selectedPatternFile = 0;
bool m_runAutomatically = false; bool m_runAutomatically = false;
bool m_evaluatorRunning = false; std::atomic<u32> m_runningEvaluators = 0;
bool m_parserRunning = false; std::atomic<u32> m_runningParsers = 0;
bool m_hasUnevaluatedChanges = false; bool m_hasUnevaluatedChanges = false;

View File

@@ -3,7 +3,7 @@
#include <hex.hpp> #include <hex.hpp>
#include <imgui.h> #include <imgui.h>
#include <hex/views/view.hpp> #include <hex/ui/view.hpp>
#include <array> #include <array>
#include <string> #include <string>

View File

@@ -1,6 +1,6 @@
#pragma once #pragma once
#include <hex/views/view.hpp> #include <hex/ui/view.hpp>
#include <cstdio> #include <cstdio>
#include <string> #include <string>

View File

@@ -2,7 +2,7 @@
#include <hex.hpp> #include <hex.hpp>
#include <hex/views/view.hpp> #include <hex/ui/view.hpp>
#include <hex/helpers/net.hpp> #include <hex/helpers/net.hpp>
#include <hex/helpers/paths.hpp> #include <hex/helpers/paths.hpp>

View File

@@ -1,6 +1,6 @@
#pragma once #pragma once
#include <hex/views/view.hpp> #include <hex/ui/view.hpp>
#include <cstdio> #include <cstdio>
#include <string> #include <string>

View File

@@ -3,7 +3,7 @@
#include <hex.hpp> #include <hex.hpp>
#include <imgui.h> #include <imgui.h>
#include <hex/views/view.hpp> #include <hex/ui/view.hpp>
#include <array> #include <array>
#include <string> #include <string>

View File

@@ -3,7 +3,7 @@
#include <hex.hpp> #include <hex.hpp>
#include <imgui.h> #include <imgui.h>
#include <hex/views/view.hpp> #include <hex/ui/view.hpp>
namespace hex::plugin::builtin { namespace hex::plugin::builtin {

View File

@@ -1,7 +1,6 @@
#include <hex/api/content_registry.hpp> #include <hex/api/content_registry.hpp>
#include <hex/helpers/lang.hpp> #include <hex/api/localization.hpp>
using namespace hex::lang_literals;
#include <hex/helpers/utils.hpp> #include <hex/helpers/utils.hpp>
#include <hex/helpers/fmt.hpp> #include <hex/helpers/fmt.hpp>

View File

@@ -2,9 +2,10 @@
#include <hex/helpers/utils.hpp> #include <hex/helpers/utils.hpp>
#include <hex/helpers/fmt.hpp> #include <hex/helpers/fmt.hpp>
#include <hex/helpers/shared_data.hpp>
#include <hex/api/event.hpp> #include <hex/api/event.hpp>
#include <hex/providers/provider.hpp>
#include <cstring> #include <cstring>
#include <codecvt> #include <codecvt>
#include <locale> #include <locale>

View File

@@ -2,14 +2,17 @@
#include <hex/data_processor/node.hpp> #include <hex/data_processor/node.hpp>
#include <hex/helpers/crypto.hpp> #include <hex/helpers/crypto.hpp>
#include <hex/helpers/shared_data.hpp>
#include <hex/helpers/utils.hpp> #include <hex/helpers/utils.hpp>
#include <hex/api/localization.hpp>
#include <hex/providers/provider.hpp>
#include <cctype> #include <cctype>
#include <nlohmann/json.hpp> #include <nlohmann/json.hpp>
#include <imgui.h> #include <imgui.h>
#include <hex/ui/imgui_imhex_extensions.h>
namespace hex::plugin::builtin { namespace hex::plugin::builtin {

View File

@@ -1,6 +1,6 @@
#include <hex/api/content_registry.hpp> #include <hex/api/content_registry.hpp>
#include <hex/views/view.hpp> #include <hex/ui/view.hpp>
namespace hex::plugin::builtin { namespace hex::plugin::builtin {

View File

@@ -3,7 +3,7 @@
#include <imgui.h> #include <imgui.h>
#include <implot.h> #include <implot.h>
#include <hex/views/view.hpp> #include <hex/ui/view.hpp>
namespace hex::plugin::builtin { namespace hex::plugin::builtin {
@@ -33,7 +33,7 @@ namespace hex::plugin::builtin {
ContentRegistry::Interface::addMenuItem("hex.builtin.menu.layout", 1000, [] { ContentRegistry::Interface::addMenuItem("hex.builtin.menu.layout", 1000, [] {
for (auto &[layoutName, func] : ContentRegistry::Interface::getLayouts()) { for (auto &[layoutName, func] : ContentRegistry::Interface::getLayouts()) {
if (ImGui::MenuItem(LangEntry(layoutName), "", false, ImHexApi::Provider::isValid())) { if (ImGui::MenuItem(LangEntry(layoutName), "", false, ImHexApi::Provider::isValid())) {
auto dock = ContentRegistry::Interface::getDockSpaceId(); auto dock = ImHexApi::System::getMainDockSpaceId();
for (auto &[viewName, view] : ContentRegistry::Views::getEntries()) { for (auto &[viewName, view] : ContentRegistry::Views::getEntries()) {
view->getWindowOpenState() = false; view->getWindowOpenState() = false;

View File

@@ -44,6 +44,8 @@ namespace hex::plugin::builtin {
void registerPatternLanguageFunctions() { void registerPatternLanguageFunctions() {
using namespace hex::pl; using namespace hex::pl;
ContentRegistry::PatternLanguage::addColorPalette("hex.builtin.palette.pastel", { 0x70B4771F, 0x700E7FFF, 0x702CA02C, 0x702827D6, 0x70BD6794, 0x704B568C, 0x70C277E3, 0x707F7F7F, 0x7022BDBC, 0x70CFBE17 });
ContentRegistry::PatternLanguage::Namespace nsStd = { "builtin", "std" }; ContentRegistry::PatternLanguage::Namespace nsStd = { "builtin", "std" };
{ {
/* print(format, args...) */ /* print(format, args...) */

View File

@@ -1,10 +1,14 @@
#include "content/providers/disk_provider.hpp" #include "content/providers/disk_provider.hpp"
#include <hex/helpers/fmt.hpp> #include <hex/helpers/fmt.hpp>
#include <hex/api/localization.hpp>
#include <bitset> #include <bitset>
#include <filesystem> #include <filesystem>
#include <imgui.h>
#include <hex/ui/imgui_imhex_extensions.h>
#if defined(OS_LINUX) #if defined(OS_LINUX)
#include <fcntl.h> #include <fcntl.h>
#include <unistd.h> #include <unistd.h>

View File

@@ -3,8 +3,10 @@
#include <ctime> #include <ctime>
#include <cstring> #include <cstring>
#include <hex/api/localization.hpp>
#include <hex/helpers/utils.hpp> #include <hex/helpers/utils.hpp>
#include <hex/helpers/file.hpp> #include <hex/helpers/file.hpp>
#include <hex/helpers/fmt.hpp>
#include <hex/helpers/project_file_handler.hpp> #include <hex/helpers/project_file_handler.hpp>
namespace hex::plugin::builtin::prv { namespace hex::plugin::builtin::prv {

View File

@@ -4,8 +4,12 @@
#include <thread> #include <thread>
#include <chrono> #include <chrono>
#include <imgui.h>
#include <hex/ui/imgui_imhex_extensions.h>
#include <hex/helpers/fmt.hpp> #include <hex/helpers/fmt.hpp>
#include <hex/helpers/crypto.hpp> #include <hex/helpers/crypto.hpp>
#include <hex/api/localization.hpp>
namespace hex::plugin::builtin::prv { namespace hex::plugin::builtin::prv {

View File

@@ -1,8 +1,7 @@
#include <hex/api/content_registry.hpp> #include <hex/api/content_registry.hpp>
#include <hex/api/imhex_api.hpp> #include <hex/api/imhex_api.hpp>
#include <hex/helpers/lang.hpp> #include <hex/api/localization.hpp>
using namespace hex::lang_literals;
#include <imgui.h> #include <imgui.h>

View File

@@ -2,12 +2,15 @@
#include <hex/api/imhex_api.hpp> #include <hex/api/imhex_api.hpp>
#include <hex/helpers/net.hpp> #include <hex/helpers/net.hpp>
#include <hex/helpers/shared_data.hpp>
#include <hex/helpers/utils.hpp> #include <hex/helpers/utils.hpp>
#include <hex/helpers/fmt.hpp> #include <hex/helpers/fmt.hpp>
#include <hex/helpers/file.hpp> #include <hex/helpers/file.hpp>
#include <hex/helpers/literals.hpp> #include <hex/helpers/literals.hpp>
#include <hex/helpers/paths.hpp> #include <hex/helpers/paths.hpp>
#include <hex/api/localization.hpp>
#include <hex/ui/view.hpp>
#include <hex/providers/provider.hpp>
#include <algorithm> #include <algorithm>
#include <chrono> #include <chrono>
@@ -20,6 +23,7 @@
#include <imgui.h> #include <imgui.h>
#define IMGUI_DEFINE_MATH_OPERATORS #define IMGUI_DEFINE_MATH_OPERATORS
#include <imgui_internal.h> #include <imgui_internal.h>
#include <hex/ui/imgui_imhex_extensions.h>
#include <nlohmann/json.hpp> #include <nlohmann/json.hpp>

View File

@@ -1,8 +1,10 @@
#include <hex/api/content_registry.hpp> #include <hex/api/content_registry.hpp>
#include <hex/helpers/shared_data.hpp>
#include <hex/helpers/utils.hpp> #include <hex/helpers/utils.hpp>
#include <hex/helpers/fmt.hpp> #include <hex/helpers/fmt.hpp>
#include <hex/api/localization.hpp>
#include <hex/providers/provider.hpp>
#include <codicons_font.h> #include <codicons_font.h>
#include <imgui.h> #include <imgui.h>
@@ -36,12 +38,13 @@ namespace hex::plugin::builtin {
std::string taskName; std::string taskName;
{ {
std::scoped_lock lock(SharedData::tasksMutex); std::scoped_lock lock(Task::getTaskMutex());
taskCount = SharedData::runningTasks.size(); taskCount = Task::getRunningTasks().size();
if (taskCount > 0) { if (taskCount > 0) {
taskProgress = SharedData::runningTasks.front()->getProgress(); auto frontTask = Task::getRunningTasks().front();
taskName = SharedData::runningTasks.front()->getName(); taskProgress = frontTask->getProgress();
taskName = frontTask->getName();
} }
} }
@@ -132,14 +135,14 @@ namespace hex::plugin::builtin {
std::string preview; std::string preview;
if (ImHexApi::Provider::isValid()) if (ImHexApi::Provider::isValid())
preview = providers[SharedData::currentProvider]->getName(); preview = ImHexApi::Provider::get()->getName();
ImGui::SetNextItemWidth(200_scaled); ImGui::SetNextItemWidth(200_scaled);
if (ImGui::BeginCombo("", preview.c_str())) { if (ImGui::BeginCombo("", preview.c_str())) {
for (int i = 0; i < providers.size(); i++) { for (int i = 0; i < providers.size(); i++) {
if (ImGui::Selectable(providers[i]->getName().c_str())) { if (ImGui::Selectable(providers[i]->getName().c_str())) {
SharedData::currentProvider = i; ImHexApi::Provider::setCurrentProvider(i);
} }
} }

View File

@@ -10,34 +10,38 @@
namespace hex::plugin::builtin { namespace hex::plugin::builtin {
ViewBookmarks::ViewBookmarks() : View("hex.builtin.view.bookmarks.name") { ViewBookmarks::ViewBookmarks() : View("hex.builtin.view.bookmarks.name") {
EventManager::subscribe<RequestAddBookmark>(this, [](ImHexApi::Bookmarks::Entry bookmark) { EventManager::subscribe<RequestAddBookmark>(this, [this](Region region, std::string name, std::string comment, color_t color) {
bookmark.comment.resize(0xF'FFFF); if (name.empty()) {
name = hex::format("hex.builtin.view.bookmarks.default_title"_lang, region.address, region.address + region.size - 1);
if (bookmark.name.empty()) {
bookmark.name.resize(64);
std::memset(bookmark.name.data(), 0x00, 64);
std::strcpy(bookmark.name.data(), hex::format("hex.builtin.view.bookmarks.default_title"_lang, bookmark.region.address, bookmark.region.address + bookmark.region.size - 1).c_str());
} }
if (bookmark.comment.empty()) if (color == 0x00)
std::memset(bookmark.comment.data(), 0x00, 0xF'FFFF); color = ImGui::GetColorU32(ImGuiCol_Header);
bookmark.color = ImGui::GetColorU32(ImGuiCol_Header);
SharedData::bookmarkEntries.push_back(bookmark); this->m_bookmarks.push_back({
region,
name,
std::move(comment),
color,
false,
ImHexApi::HexEditor::addHighlight(region, color, name)
});
ProjectFile::markDirty(); ProjectFile::markDirty();
}); });
EventManager::subscribe<EventProjectFileLoad>(this, [] { EventManager::subscribe<EventProjectFileLoad>(this, [this] {
SharedData::bookmarkEntries = ProjectFile::getBookmarks(); this->m_bookmarks = ProjectFile::getBookmarks();
}); });
EventManager::subscribe<EventProjectFileStore>(this, [] { EventManager::subscribe<EventProjectFileStore>(this, [this] {
ProjectFile::setBookmarks(SharedData::bookmarkEntries); ProjectFile::setBookmarks(this->m_bookmarks);
}); });
EventManager::subscribe<EventFileUnloaded>(this, [] { EventManager::subscribe<EventFileUnloaded>(this, [this] {
ImHexApi::Bookmarks::getEntries().clear(); this->m_bookmarks.clear();
}); });
} }
@@ -46,22 +50,22 @@ namespace hex::plugin::builtin {
EventManager::unsubscribe<EventProjectFileLoad>(this); EventManager::unsubscribe<EventProjectFileLoad>(this);
EventManager::unsubscribe<EventProjectFileStore>(this); EventManager::unsubscribe<EventProjectFileStore>(this);
EventManager::unsubscribe<EventFileUnloaded>(this); EventManager::unsubscribe<EventFileUnloaded>(this);
this->m_bookmarks.clear();
} }
void ViewBookmarks::drawContent() { void ViewBookmarks::drawContent() {
if (ImGui::Begin(View::toWindowName("hex.builtin.view.bookmarks.name").c_str(), &this->getWindowOpenState())) { if (ImGui::Begin(View::toWindowName("hex.builtin.view.bookmarks.name").c_str(), &this->getWindowOpenState())) {
if (ImGui::BeginChild("##scrolling")) { if (ImGui::BeginChild("##scrolling")) {
auto &bookmarks = ImHexApi::Bookmarks::getEntries(); if (this->m_bookmarks.empty()) {
if (bookmarks.empty()) {
ImGui::TextFormattedCentered("hex.builtin.view.bookmarks.no_bookmarks"_lang); ImGui::TextFormattedCentered("hex.builtin.view.bookmarks.no_bookmarks"_lang);
} }
u32 id = 1; u32 id = 1;
auto bookmarkToRemove = bookmarks.end(); auto bookmarkToRemove = this->m_bookmarks.end();
for (auto iter = bookmarks.begin(); iter != bookmarks.end(); iter++) { for (auto iter = this->m_bookmarks.begin(); iter != this->m_bookmarks.end(); iter++) {
auto &[region, name, comment, color, locked] = *iter; auto &[region, name, comment, color, locked, highlight] = *iter;
auto headerColor = ImColor(color); auto headerColor = ImColor(color);
auto hoverColor = ImColor(color); auto hoverColor = ImColor(color);
@@ -71,7 +75,7 @@ namespace hex::plugin::builtin {
ImGui::PushStyleColor(ImGuiCol_Header, color); ImGui::PushStyleColor(ImGuiCol_Header, color);
ImGui::PushStyleColor(ImGuiCol_HeaderActive, color); ImGui::PushStyleColor(ImGuiCol_HeaderActive, color);
ImGui::PushStyleColor(ImGuiCol_HeaderHovered, u32(hoverColor)); ImGui::PushStyleColor(ImGuiCol_HeaderHovered, u32(hoverColor));
if (ImGui::CollapsingHeader((std::string(name.data()) + "###bookmark").c_str())) { if (ImGui::CollapsingHeader((name + "###bookmark").c_str())) {
ImGui::TextUnformatted("hex.builtin.view.bookmarks.title.info"_lang); ImGui::TextUnformatted("hex.builtin.view.bookmarks.title.info"_lang);
ImGui::Separator(); ImGui::Separator();
ImGui::TextFormatted("hex.builtin.view.bookmarks.address"_lang, region.address, region.address + region.size - 1, region.size); ImGui::TextFormatted("hex.builtin.view.bookmarks.address"_lang, region.address, region.address + region.size - 1, region.size);
@@ -146,7 +150,7 @@ namespace hex::plugin::builtin {
if (locked) if (locked)
ImGui::TextUnformatted(name.data()); ImGui::TextUnformatted(name.data());
else else
ImGui::InputText("##nameInput", name.data(), 64); ImGui::InputText("##nameInput", name.data(), name.capacity(), ImGuiInputTextFlags_CallbackResize, ImGui::UpdateStringSizeCallback, &name);
ImGui::NewLine(); ImGui::NewLine();
ImGui::TextUnformatted("hex.builtin.view.bookmarks.header.comment"_lang); ImGui::TextUnformatted("hex.builtin.view.bookmarks.header.comment"_lang);
@@ -155,7 +159,7 @@ namespace hex::plugin::builtin {
if (locked) if (locked)
ImGui::TextFormattedWrapped("{}", comment.data()); ImGui::TextFormattedWrapped("{}", comment.data());
else else
ImGui::InputTextMultiline("##commentInput", comment.data(), 0xF'FFFF); ImGui::InputTextMultiline("##commentInput", comment.data(), comment.capacity(), ImVec2(0, 0), ImGuiInputTextFlags_CallbackResize, ImGui::UpdateStringSizeCallback, &comment);
ImGui::NewLine(); ImGui::NewLine();
} }
@@ -164,8 +168,9 @@ namespace hex::plugin::builtin {
id++; id++;
} }
if (bookmarkToRemove != bookmarks.end()) { if (bookmarkToRemove != this->m_bookmarks.end()) {
bookmarks.erase(bookmarkToRemove); ImHexApi::HexEditor::removeHighlight(bookmarkToRemove->highlightId);
this->m_bookmarks.erase(bookmarkToRemove);
ProjectFile::markDirty(); ProjectFile::markDirty();
} }
} }

View File

@@ -1,5 +1,7 @@
#include "content/views/view_command_palette.hpp" #include "content/views/view_command_palette.hpp"
#include <hex/api/content_registry.hpp>
#include <cstring> #include <cstring>
namespace hex::plugin::builtin { namespace hex::plugin::builtin {
@@ -21,7 +23,10 @@ namespace hex::plugin::builtin {
if (!this->m_commandPaletteOpen) return; if (!this->m_commandPaletteOpen) return;
ImGui::SetNextWindowPos(ImVec2(SharedData::windowPos.x + SharedData::windowSize.x * 0.5F, SharedData::windowPos.y), ImGuiCond_Always, ImVec2(0.5F, 0.0F)); auto windowPos = ImHexApi::System::getMainWindowPosition();
auto windowSize = ImHexApi::System::getMainWindowSize();
ImGui::SetNextWindowPos(ImVec2(windowPos.x + windowSize.x * 0.5F, windowPos.y), ImGuiCond_Always, ImVec2(0.5F, 0.0F));
if (ImGui::BeginPopup("hex.builtin.view.command_palette.name"_lang)) { if (ImGui::BeginPopup("hex.builtin.view.command_palette.name"_lang)) {
if (ImGui::IsKeyDown(ImGui::GetKeyIndex(ImGuiKey_Escape))) if (ImGui::IsKeyDown(ImGui::GetKeyIndex(ImGuiKey_Escape)))
ImGui::CloseCurrentPopup(); ImGui::CloseCurrentPopup();

View File

@@ -24,7 +24,7 @@ namespace hex::plugin::builtin {
this->m_constants.clear(); this->m_constants.clear();
this->m_filterIndices.clear(); this->m_filterIndices.clear();
for (auto &path : hex::getPath(ImHexPath::Constants)) { for (const auto &path : hex::getPath(ImHexPath::Constants)) {
if (!fs::exists(path)) continue; if (!fs::exists(path)) continue;
for (auto &file : fs::directory_iterator(path)) { for (auto &file : fs::directory_iterator(path)) {

View File

@@ -1,5 +1,7 @@
#include "content/views/view_data_processor.hpp" #include "content/views/view_data_processor.hpp"
#include <hex/api/content_registry.hpp>
#include <hex/helpers/file.hpp> #include <hex/helpers/file.hpp>
#include <hex/providers/provider.hpp> #include <hex/providers/provider.hpp>
@@ -83,7 +85,7 @@ namespace hex::plugin::builtin {
void ViewDataProcessor::eraseLink(u32 id) { void ViewDataProcessor::eraseLink(u32 id) {
auto link = std::find_if(this->m_links.begin(), this->m_links.end(), [&id](auto link) { return link.getID() == id; }); auto link = std::find_if(this->m_links.begin(), this->m_links.end(), [&id](auto link) { return link.getId() == id; });
if (link == this->m_links.end()) if (link == this->m_links.end())
return; return;
@@ -101,7 +103,7 @@ namespace hex::plugin::builtin {
void ViewDataProcessor::eraseNodes(const std::vector<int> &ids) { void ViewDataProcessor::eraseNodes(const std::vector<int> &ids) {
for (const int id : ids) { for (const int id : ids) {
auto node = std::find_if(this->m_nodes.begin(), this->m_nodes.end(), [&id](auto node) { return node->getID() == id; }); auto node = std::find_if(this->m_nodes.begin(), this->m_nodes.end(), [&id](auto node) { return node->getId() == id; });
for (auto &attr : (*node)->getAttributes()) { for (auto &attr : (*node)->getAttributes()) {
std::vector<u32> linksToRemove; std::vector<u32> linksToRemove;
@@ -114,9 +116,9 @@ namespace hex::plugin::builtin {
} }
for (const int id : ids) { for (const int id : ids) {
auto node = std::find_if(this->m_nodes.begin(), this->m_nodes.end(), [&id](auto node) { return node->getID() == id; }); auto node = std::find_if(this->m_nodes.begin(), this->m_nodes.end(), [&id](auto node) { return node->getId() == id; });
std::erase_if(this->m_endNodes, [&id](auto node) { return node->getID() == id; }); std::erase_if(this->m_endNodes, [&id](auto node) { return node->getId() == id; });
delete *node; delete *node;
@@ -238,7 +240,7 @@ namespace hex::plugin::builtin {
if (hasInput && !hasOutput) if (hasInput && !hasOutput)
this->m_endNodes.push_back(node); this->m_endNodes.push_back(node);
ImNodes::SetNodeScreenSpacePos(node->getID(), this->m_rightClickedCoords); ImNodes::SetNodeScreenSpacePos(node->getId(), this->m_rightClickedCoords);
} }
ImGui::EndPopup(); ImGui::EndPopup();
@@ -260,7 +262,7 @@ namespace hex::plugin::builtin {
{ {
int nodeId; int nodeId;
if (ImNodes::IsNodeHovered(&nodeId) && this->m_currNodeError.has_value() && this->m_currNodeError->first->getID() == nodeId) { if (ImNodes::IsNodeHovered(&nodeId) && this->m_currNodeError.has_value() && this->m_currNodeError->first->getId() == nodeId) {
ImGui::BeginTooltip(); ImGui::BeginTooltip();
ImGui::TextUnformatted("hex.common.error"_lang); ImGui::TextUnformatted("hex.common.error"_lang);
ImGui::Separator(); ImGui::Separator();
@@ -277,7 +279,7 @@ namespace hex::plugin::builtin {
if (hasError) if (hasError)
ImNodes::PushColorStyle(ImNodesCol_NodeOutline, 0xFF0000FF); ImNodes::PushColorStyle(ImNodesCol_NodeOutline, 0xFF0000FF);
ImNodes::BeginNode(node->getID()); ImNodes::BeginNode(node->getId());
ImNodes::BeginNodeTitleBar(); ImNodes::BeginNodeTitleBar();
ImGui::TextUnformatted(LangEntry(node->getUnlocalizedTitle())); ImGui::TextUnformatted(LangEntry(node->getUnlocalizedTitle()));
@@ -301,11 +303,11 @@ namespace hex::plugin::builtin {
} }
if (attribute.getIOType() == dp::Attribute::IOType::In) { if (attribute.getIOType() == dp::Attribute::IOType::In) {
ImNodes::BeginInputAttribute(attribute.getID(), pinShape); ImNodes::BeginInputAttribute(attribute.getId(), pinShape);
ImGui::TextUnformatted(LangEntry(attribute.getUnlocalizedName())); ImGui::TextUnformatted(LangEntry(attribute.getUnlocalizedName()));
ImNodes::EndInputAttribute(); ImNodes::EndInputAttribute();
} else if (attribute.getIOType() == dp::Attribute::IOType::Out) { } else if (attribute.getIOType() == dp::Attribute::IOType::Out) {
ImNodes::BeginOutputAttribute(attribute.getID(), ImNodesPinShape(pinShape + 1)); ImNodes::BeginOutputAttribute(attribute.getId(), ImNodesPinShape(pinShape + 1));
ImGui::TextUnformatted(LangEntry(attribute.getUnlocalizedName())); ImGui::TextUnformatted(LangEntry(attribute.getUnlocalizedName()));
ImNodes::EndOutputAttribute(); ImNodes::EndOutputAttribute();
} }
@@ -318,7 +320,7 @@ namespace hex::plugin::builtin {
} }
for (const auto &link : this->m_links) for (const auto &link : this->m_links)
ImNodes::Link(link.getID(), link.getFromID(), link.getToID()); ImNodes::Link(link.getId(), link.getFromId(), link.getToId());
ImNodes::MiniMap(0.2F, ImNodesMiniMapLocation_BottomRight); ImNodes::MiniMap(0.2F, ImNodesMiniMapLocation_BottomRight);
@@ -339,9 +341,9 @@ namespace hex::plugin::builtin {
dp::Attribute *fromAttr, *toAttr; dp::Attribute *fromAttr, *toAttr;
for (auto &node : this->m_nodes) { for (auto &node : this->m_nodes) {
for (auto &attribute : node->getAttributes()) { for (auto &attribute : node->getAttributes()) {
if (attribute.getID() == from) if (attribute.getId() == from)
fromAttr = &attribute; fromAttr = &attribute;
else if (attribute.getID() == to) else if (attribute.getId() == to)
toAttr = &attribute; toAttr = &attribute;
} }
} }
@@ -360,8 +362,8 @@ namespace hex::plugin::builtin {
auto newLink = this->m_links.emplace_back(from, to); auto newLink = this->m_links.emplace_back(from, to);
fromAttr->addConnectedAttribute(newLink.getID(), toAttr); fromAttr->addConnectedAttribute(newLink.getId(), toAttr);
toAttr->addConnectedAttribute(newLink.getID(), fromAttr); toAttr->addConnectedAttribute(newLink.getId(), fromAttr);
} while (false); } while (false);
} }
} }
@@ -401,7 +403,7 @@ namespace hex::plugin::builtin {
output["nodes"] = json::object(); output["nodes"] = json::object();
for (auto &node : this->m_nodes) { for (auto &node : this->m_nodes) {
auto id = node->getID(); auto id = node->getId();
auto &currNodeOutput = output["nodes"][std::to_string(id)]; auto &currNodeOutput = output["nodes"][std::to_string(id)];
auto pos = ImNodes::GetNodeGridSpacePos(id); auto pos = ImNodes::GetNodeGridSpacePos(id);
@@ -419,19 +421,19 @@ namespace hex::plugin::builtin {
u32 attrIndex = 0; u32 attrIndex = 0;
for (auto &attr : node->getAttributes()) { for (auto &attr : node->getAttributes()) {
currNodeOutput["attrs"][attrIndex] = attr.getID(); currNodeOutput["attrs"][attrIndex] = attr.getId();
attrIndex++; attrIndex++;
} }
} }
output["links"] = json::object(); output["links"] = json::object();
for (auto &link : this->m_links) { for (auto &link : this->m_links) {
auto id = link.getID(); auto id = link.getId();
auto &currOutput = output["links"][std::to_string(id)]; auto &currOutput = output["links"][std::to_string(id)];
currOutput["id"] = id; currOutput["id"] = id;
currOutput["from"] = link.getFromID(); currOutput["from"] = link.getFromId();
currOutput["to"] = link.getToID(); currOutput["to"] = link.getToId();
} }
return output.dump(); return output.dump();
@@ -467,7 +469,7 @@ namespace hex::plugin::builtin {
u32 nodeId = node["id"]; u32 nodeId = node["id"];
maxNodeId = std::max(nodeId, maxNodeId); maxNodeId = std::max(nodeId, maxNodeId);
newNode->setID(nodeId); newNode->setId(nodeId);
bool hasOutput = false; bool hasOutput = false;
bool hasInput = false; bool hasInput = false;
@@ -482,7 +484,7 @@ namespace hex::plugin::builtin {
u32 attrId = node["attrs"][attrIndex]; u32 attrId = node["attrs"][attrIndex];
maxAttrId = std::max(attrId, maxAttrId); maxAttrId = std::max(attrId, maxAttrId);
attr.setID(attrId); attr.setId(attrId);
attrIndex++; attrIndex++;
} }
@@ -508,9 +510,9 @@ namespace hex::plugin::builtin {
dp::Attribute *fromAttr, *toAttr; dp::Attribute *fromAttr, *toAttr;
for (auto &node : this->m_nodes) { for (auto &node : this->m_nodes) {
for (auto &attribute : node->getAttributes()) { for (auto &attribute : node->getAttributes()) {
if (attribute.getID() == newLink.getFromID()) if (attribute.getId() == newLink.getFromId())
fromAttr = &attribute; fromAttr = &attribute;
else if (attribute.getID() == newLink.getToID()) else if (attribute.getId() == newLink.getToId())
toAttr = &attribute; toAttr = &attribute;
} }
} }
@@ -527,13 +529,13 @@ namespace hex::plugin::builtin {
if (!toAttr->getConnectedAttributes().empty()) if (!toAttr->getConnectedAttributes().empty())
break; break;
fromAttr->addConnectedAttribute(newLink.getID(), toAttr); fromAttr->addConnectedAttribute(newLink.getId(), toAttr);
toAttr->addConnectedAttribute(newLink.getID(), fromAttr); toAttr->addConnectedAttribute(newLink.getId(), fromAttr);
} }
SharedData::dataProcessorNodeIdCounter = maxNodeId + 1; dp::Node::setIdCounter(maxNodeId + 1);
SharedData::dataProcessorAttrIdCounter = maxAttrId + 1; dp::Attribute::setIdCounter(maxAttrId + 1);
SharedData::dataProcessorLinkIdCounter = maxLinkId + 1; dp::Link::setIdCounter(maxLinkId + 1);
} }
} }

View File

@@ -1,9 +1,11 @@
#include "content/views/view_help.hpp" #include "content/views/view_help.hpp"
#include <hex/helpers/paths.hpp>
#include <hex/api/content_registry.hpp>
#include <hex/helpers/fmt.hpp> #include <hex/helpers/fmt.hpp>
#include <hex/helpers/utils.hpp>
#include <hex/helpers/logger.hpp> #include <hex/helpers/logger.hpp>
#include <hex/helpers/paths.hpp>
#include <hex/helpers/utils.hpp>
#include <romfs/romfs.hpp> #include <romfs/romfs.hpp>
@@ -13,7 +15,7 @@ namespace hex::plugin::builtin {
ContentRegistry::Interface::addMenuItem("hex.builtin.menu.help", 1000, [&, this] { ContentRegistry::Interface::addMenuItem("hex.builtin.menu.help", 1000, [&, this] {
if (ImGui::MenuItem("hex.builtin.view.help.about.name"_lang, "")) { if (ImGui::MenuItem("hex.builtin.view.help.about.name"_lang, "")) {
View::doLater([] { ImGui::OpenPopup(View::toWindowName("hex.builtin.view.help.about.name").c_str()); }); ImHexApi::Tasks::doLater([] { ImGui::OpenPopup(View::toWindowName("hex.builtin.view.help.about.name").c_str()); });
this->m_aboutWindowOpen = true; this->m_aboutWindowOpen = true;
this->getWindowOpenState() = true; this->getWindowOpenState() = true;
} }

View File

@@ -59,7 +59,7 @@ namespace hex::plugin::builtin {
}; };
this->m_memoryEditor.HighlightFn = [](const ImU8 *data, size_t off, bool next) -> bool { this->m_memoryEditor.HighlightFn = [](const ImU8 *data, size_t off, bool next) -> bool {
ViewHexEditor *_this = (ViewHexEditor *)data; auto _this = (ViewHexEditor*)(data);
std::optional<u32> currColor, prevColor; std::optional<u32> currColor, prevColor;
@@ -69,7 +69,10 @@ namespace hex::plugin::builtin {
u32 alpha = static_cast<u32>(_this->m_highlightAlpha) << 24; u32 alpha = static_cast<u32>(_this->m_highlightAlpha) << 24;
for (const auto &[region, name, comment, color, locked] : ImHexApi::Bookmarks::getEntries()) { for (const auto &[id, highlight] : ImHexApi::HexEditor::getHighlights()) {
auto &region = highlight.getRegion();
auto &color = highlight.getColor();
if (off >= region.address && off < (region.address + region.size)) if (off >= region.address && off < (region.address + region.size))
currColor = (color & 0x00FFFFFF) | alpha; currColor = (color & 0x00FFFFFF) | alpha;
if ((off - 1) >= region.address && (off - 1) < (region.address + region.size)) if ((off - 1) >= region.address && (off - 1) < (region.address + region.size))
@@ -77,7 +80,8 @@ namespace hex::plugin::builtin {
} }
{ {
for (const auto &pattern : SharedData::patternData) { auto patterns = provider->getPatternLanguageRuntime().getPatterns();
for (const auto &pattern : patterns) {
auto child = pattern->getPattern(off); auto child = pattern->getPattern(off);
if (child != nullptr) { if (child != nullptr) {
auto color = (child->getColor() & 0x00FFFFFF) | alpha; auto color = (child->getColor() & 0x00FFFFFF) | alpha;
@@ -86,7 +90,7 @@ namespace hex::plugin::builtin {
} }
} }
for (const auto &pattern : SharedData::patternData) { for (const auto &pattern : patterns) {
auto child = pattern->getPattern(off - 1); auto child = pattern->getPattern(off - 1);
if (child != nullptr) { if (child != nullptr) {
auto color = (child->getColor() & 0x00FFFFFF) | alpha; auto color = (child->getColor() & 0x00FFFFFF) | alpha;
@@ -114,15 +118,19 @@ namespace hex::plugin::builtin {
off += ImHexApi::Provider::get()->getBaseAddress(); off += ImHexApi::Provider::get()->getBaseAddress();
for (const auto &[region, name, comment, color, locked] : ImHexApi::Bookmarks::getEntries()) { for (const auto &[id, highlight] : ImHexApi::HexEditor::getHighlights()) {
auto &region = highlight.getRegion();
auto &color = highlight.getColor();
auto &tooltip = highlight.getTooltip();
if (off >= region.address && off < (region.address + region.size)) { if (off >= region.address && off < (region.address + region.size)) {
if (!tooltipShown) { if (!tooltipShown && !tooltip.empty()) {
ImGui::BeginTooltip(); ImGui::BeginTooltip();
tooltipShown = true; tooltipShown = true;
} }
ImGui::ColorButton(name.data(), ImColor(color).Value); ImGui::ColorButton(tooltip.c_str(), ImColor(color).Value);
ImGui::SameLine(0, 10); ImGui::SameLine(0, 10);
ImGui::TextUnformatted(name.data()); ImGui::TextUnformatted(tooltip.c_str());
} }
} }
@@ -753,18 +761,18 @@ namespace hex::plugin::builtin {
if (ImGui::MenuItem("hex.builtin.view.hexeditor.menu.edit.set_base"_lang, nullptr, false, providerValid && provider->isReadable())) { if (ImGui::MenuItem("hex.builtin.view.hexeditor.menu.edit.set_base"_lang, nullptr, false, providerValid && provider->isReadable())) {
std::memset(this->m_baseAddressBuffer, 0x00, sizeof(this->m_baseAddressBuffer)); std::memset(this->m_baseAddressBuffer, 0x00, sizeof(this->m_baseAddressBuffer));
View::doLater([] { ImGui::OpenPopup("hex.builtin.view.hexeditor.menu.edit.set_base"_lang); }); ImHexApi::Tasks::doLater([] { ImGui::OpenPopup("hex.builtin.view.hexeditor.menu.edit.set_base"_lang); });
} }
if (ImGui::MenuItem("hex.builtin.view.hexeditor.menu.edit.resize"_lang, nullptr, false, providerValid && provider->isResizable())) { if (ImGui::MenuItem("hex.builtin.view.hexeditor.menu.edit.resize"_lang, nullptr, false, providerValid && provider->isResizable())) {
View::doLater([this] { ImHexApi::Tasks::doLater([this] {
this->m_resizeSize = ImHexApi::Provider::get()->getActualSize(); this->m_resizeSize = ImHexApi::Provider::get()->getActualSize();
ImGui::OpenPopup("hex.builtin.view.hexeditor.menu.edit.resize"_lang); ImGui::OpenPopup("hex.builtin.view.hexeditor.menu.edit.resize"_lang);
}); });
} }
if (ImGui::MenuItem("hex.builtin.view.hexeditor.menu.edit.insert"_lang, nullptr, false, providerValid && provider->isResizable())) { if (ImGui::MenuItem("hex.builtin.view.hexeditor.menu.edit.insert"_lang, nullptr, false, providerValid && provider->isResizable())) {
View::doLater([this] { ImHexApi::Tasks::doLater([this] {
this->m_resizeSize = 0; this->m_resizeSize = 0;
ImGui::OpenPopup("hex.builtin.view.hexeditor.menu.edit.insert"_lang); ImGui::OpenPopup("hex.builtin.view.hexeditor.menu.edit.insert"_lang);
}); });
@@ -800,7 +808,7 @@ namespace hex::plugin::builtin {
EventManager::subscribe<EventWindowClosing>(this, [](GLFWwindow *window) { EventManager::subscribe<EventWindowClosing>(this, [](GLFWwindow *window) {
if (ProjectFile::hasUnsavedChanges()) { if (ProjectFile::hasUnsavedChanges()) {
glfwSetWindowShouldClose(window, GLFW_FALSE); glfwSetWindowShouldClose(window, GLFW_FALSE);
View::doLater([] { ImGui::OpenPopup("hex.builtin.view.hexeditor.exit_application.title"_lang); }); ImHexApi::Tasks::doLater([] { ImGui::OpenPopup("hex.builtin.view.hexeditor.exit_application.title"_lang); });
} }
}); });
@@ -958,46 +966,12 @@ namespace hex::plugin::builtin {
void ViewHexEditor::registerMenuItems() { void ViewHexEditor::registerMenuItems() {
/* Basic operations */ /* Basic operations */
ContentRegistry::Interface::addMenuItem("hex.builtin.menu.file", 1000, [&] {
ContentRegistry::Interface::addMenuItem("hex.builtin.menu.file", 1100, [&] {
auto provider = ImHexApi::Provider::get(); auto provider = ImHexApi::Provider::get();
bool providerValid = ImHexApi::Provider::isValid(); bool providerValid = ImHexApi::Provider::isValid();
if (ImGui::MenuItem("hex.builtin.view.hexeditor.menu.file.open_file"_lang, "CTRL + O")) {
hex::openFileBrowser("hex.builtin.view.hexeditor.open_file"_lang, DialogMode::Open, {}, [](const auto &path) {
EventManager::post<RequestOpenFile>(path);
});
}
if (ImGui::BeginMenu("hex.builtin.view.hexeditor.menu.file.open_recent"_lang, !SharedData::recentFilePaths.empty())) {
for (auto &path : SharedData::recentFilePaths) {
if (ImGui::MenuItem(fs::path(path).filename().string().c_str())) {
EventManager::post<RequestOpenFile>(path);
}
}
ImGui::Separator();
if (ImGui::MenuItem("hex.builtin.view.hexeditor.menu.file.clear_recent"_lang)) {
SharedData::recentFilePaths.clear();
ContentRegistry::Settings::write(
"hex.builtin.setting.imhex",
"hex.builtin.setting.imhex.recent_files",
std::vector<std::string> {});
}
ImGui::EndMenu();
}
if (ImGui::BeginMenu("hex.builtin.view.hexeditor.menu.file.open_other"_lang)) {
for (const auto &unlocalizedProviderName : ContentRegistry::Provider::getEntries()) {
if (ImGui::MenuItem(LangEntry(unlocalizedProviderName))) {
EventManager::post<RequestCreateProvider>(unlocalizedProviderName, nullptr);
}
}
ImGui::EndMenu();
}
if (ImGui::MenuItem("hex.builtin.view.hexeditor.menu.file.save"_lang, "CTRL + S", false, providerValid && provider->isWritable())) { if (ImGui::MenuItem("hex.builtin.view.hexeditor.menu.file.save"_lang, "CTRL + S", false, providerValid && provider->isWritable())) {
save(); save();
@@ -1020,7 +994,7 @@ namespace hex::plugin::builtin {
/* Metadata save/load */ /* Metadata save/load */
ContentRegistry::Interface::addMenuItem("hex.builtin.menu.file", 1100, [&, this] { ContentRegistry::Interface::addMenuItem("hex.builtin.menu.file", 1200, [&, this] {
auto provider = ImHexApi::Provider::get(); auto provider = ImHexApi::Provider::get();
bool providerValid = ImHexApi::Provider::isValid(); bool providerValid = ImHexApi::Provider::isValid();
@@ -1070,7 +1044,7 @@ namespace hex::plugin::builtin {
/* Import / Export */ /* Import / Export */
ContentRegistry::Interface::addMenuItem("hex.builtin.menu.file", 1200, [&, this] { ContentRegistry::Interface::addMenuItem("hex.builtin.menu.file", 1300, [&, this] {
auto provider = ImHexApi::Provider::get(); auto provider = ImHexApi::Provider::get();
bool providerValid = ImHexApi::Provider::isValid(); bool providerValid = ImHexApi::Provider::isValid();
@@ -1161,7 +1135,7 @@ namespace hex::plugin::builtin {
if (ImGui::MenuItem("hex.builtin.view.hexeditor.menu.file.import.script"_lang)) { if (ImGui::MenuItem("hex.builtin.view.hexeditor.menu.file.import.script"_lang)) {
this->m_loaderScriptFilePath.clear(); this->m_loaderScriptFilePath.clear();
this->m_loaderScriptScriptPath.clear(); this->m_loaderScriptScriptPath.clear();
View::doLater([] { ImGui::OpenPopup("hex.builtin.view.hexeditor.script.title"_lang); }); ImHexApi::Tasks::doLater([] { ImGui::OpenPopup("hex.builtin.view.hexeditor.script.title"_lang); });
} }
ImGui::EndMenu(); ImGui::EndMenu();
@@ -1185,7 +1159,7 @@ namespace hex::plugin::builtin {
this->m_dataToSave = generateIPSPatch(patches); this->m_dataToSave = generateIPSPatch(patches);
this->m_processingImportExport = false; this->m_processingImportExport = false;
View::doLater([this] { ImHexApi::Tasks::doLater([this] {
hex::openFileBrowser("hex.builtin.view.hexeditor.menu.file.export.title"_lang, DialogMode::Save, {}, [this](const auto &path) { hex::openFileBrowser("hex.builtin.view.hexeditor.menu.file.export.title"_lang, DialogMode::Save, {}, [this](const auto &path) {
auto file = File(path, File::Mode::Create); auto file = File(path, File::Mode::Create);
if (!file.isValid()) { if (!file.isValid()) {
@@ -1214,7 +1188,7 @@ namespace hex::plugin::builtin {
this->m_dataToSave = generateIPS32Patch(patches); this->m_dataToSave = generateIPS32Patch(patches);
this->m_processingImportExport = false; this->m_processingImportExport = false;
View::doLater([this] { ImHexApi::Tasks::doLater([this] {
hex::openFileBrowser("hex.builtin.view.hexeditor.menu.file.export.title"_lang, DialogMode::Save, {}, [this](const auto &path) { hex::openFileBrowser("hex.builtin.view.hexeditor.menu.file.export.title"_lang, DialogMode::Save, {}, [this](const auto &path) {
auto file = File(path, File::Mode::Create); auto file = File(path, File::Mode::Create);
if (!file.isValid()) { if (!file.isValid()) {
@@ -1234,7 +1208,7 @@ namespace hex::plugin::builtin {
/* Search / Goto */ /* Search / Goto */
ContentRegistry::Interface::addMenuItem("hex.builtin.menu.file", 1300, [&, this] { ContentRegistry::Interface::addMenuItem("hex.builtin.menu.file", 1400, [&, this] {
if (ImGui::MenuItem("hex.builtin.view.hexeditor.menu.file.search"_lang, "CTRL + F")) { if (ImGui::MenuItem("hex.builtin.view.hexeditor.menu.file.search"_lang, "CTRL + F")) {
this->getWindowOpenState() = true; this->getWindowOpenState() = true;
ImGui::OpenPopupInWindow(View::toWindowName("hex.builtin.view.hexeditor.name").c_str(), "hex.builtin.view.hexeditor.menu.file.search"_lang); ImGui::OpenPopupInWindow(View::toWindowName("hex.builtin.view.hexeditor.name").c_str(), "hex.builtin.view.hexeditor.menu.file.search"_lang);

View File

@@ -1,5 +1,7 @@
#include "content/views/view_information.hpp" #include "content/views/view_information.hpp"
#include <hex/api/content_registry.hpp>
#include <hex/providers/provider.hpp> #include <hex/providers/provider.hpp>
#include <hex/helpers/paths.hpp> #include <hex/helpers/paths.hpp>
#include <hex/helpers/fmt.hpp> #include <hex/helpers/fmt.hpp>
@@ -44,7 +46,7 @@ namespace hex::plugin::builtin {
}); });
ContentRegistry::FileHandler::add({ ".mgc" }, [](const auto &path) { ContentRegistry::FileHandler::add({ ".mgc" }, [](const auto &path) {
for (auto &destPath : hex::getPath(ImHexPath::Magic)) { for (const auto &destPath : hex::getPath(ImHexPath::Magic)) {
std::error_code error; std::error_code error;
if (fs::copy_file(path, destPath / path.filename(), fs::copy_options::overwrite_existing, error)) { if (fs::copy_file(path, destPath / path.filename(), fs::copy_options::overwrite_existing, error)) {
View::showMessagePopup("hex.builtin.view.information.magic_db_added"_lang); View::showMessagePopup("hex.builtin.view.information.magic_db_added"_lang);

View File

@@ -8,7 +8,9 @@ namespace hex::plugin::builtin {
ViewPatternData::ViewPatternData() : View("hex.builtin.view.pattern_data.name") { ViewPatternData::ViewPatternData() : View("hex.builtin.view.pattern_data.name") {
EventManager::subscribe<EventPatternChanged>(this, [this](auto &) { EventManager::subscribe<EventPatternChanged>(this, [this](auto &) {
this->m_sortedPatternData.clear(); if (!ImHexApi::Provider::isValid()) return;
this->m_sortedPatterns[ImHexApi::Provider::get()].clear();
}); });
} }
@@ -52,11 +54,12 @@ namespace hex::plugin::builtin {
auto provider = ImHexApi::Provider::get(); auto provider = ImHexApi::Provider::get();
if (ImHexApi::Provider::isValid() && provider->isReadable()) { if (ImHexApi::Provider::isValid() && provider->isReadable()) {
if (beginPatternDataTable(provider, SharedData::patternData, this->m_sortedPatternData)) { auto &sortedPatterns = this->m_sortedPatterns[ImHexApi::Provider::get()];
if (beginPatternDataTable(provider, provider->getPatternLanguageRuntime().getPatterns(), sortedPatterns)) {
ImGui::TableHeadersRow(); ImGui::TableHeadersRow();
if (this->m_sortedPatternData.size() > 0) { if (!sortedPatterns.empty()) {
for (auto &patternData : this->m_sortedPatternData) for (auto &patternData : sortedPatterns)
patternData->draw(provider); patternData->draw(provider);
} }

View File

@@ -73,7 +73,6 @@ namespace hex::plugin::builtin {
ViewPatternEditor::ViewPatternEditor() : View("hex.builtin.view.pattern_editor.name") { ViewPatternEditor::ViewPatternEditor() : View("hex.builtin.view.pattern_editor.name") {
this->m_evaluatorRuntime = new pl::PatternLanguage();
this->m_parserRuntime = new pl::PatternLanguage(); this->m_parserRuntime = new pl::PatternLanguage();
this->m_textEditor.SetLanguageDefinition(PatternLanguage()); this->m_textEditor.SetLanguageDefinition(PatternLanguage());
@@ -148,7 +147,16 @@ namespace hex::plugin::builtin {
EventManager::subscribe<EventFileUnloaded>(this, [this] { EventManager::subscribe<EventFileUnloaded>(this, [this] {
this->m_textEditor.SetText(""); this->m_textEditor.SetText("");
this->m_evaluatorRuntime->abort(); ImHexApi::Provider::get()->getPatternLanguageRuntime().abort();
});
EventManager::subscribe<EventProviderChanged>(this, [this](prv::Provider *oldProvider, prv::Provider *newProvider) {
if (oldProvider != nullptr) oldProvider->getPatternLanguageSourceCode() = this->m_textEditor.GetText();
if (newProvider != nullptr) this->m_textEditor.SetText(newProvider->getPatternLanguageSourceCode());
auto lines = this->m_textEditor.GetTextLines();
lines.pop_back();
this->m_textEditor.SetTextLines(lines);
}); });
/* Settings */ /* Settings */
@@ -186,7 +194,7 @@ namespace hex::plugin::builtin {
std::vector<fs::path> paths; std::vector<fs::path> paths;
for (auto &imhexPath : hex::getPath(ImHexPath::Patterns)) { for (const auto &imhexPath : hex::getPath(ImHexPath::Patterns)) {
if (!fs::exists(imhexPath)) continue; if (!fs::exists(imhexPath)) continue;
for (auto &entry : fs::recursive_directory_iterator(imhexPath)) { for (auto &entry : fs::recursive_directory_iterator(imhexPath)) {
@@ -218,7 +226,6 @@ namespace hex::plugin::builtin {
} }
ViewPatternEditor::~ViewPatternEditor() { ViewPatternEditor::~ViewPatternEditor() {
delete this->m_evaluatorRuntime;
delete this->m_parserRuntime; delete this->m_parserRuntime;
EventManager::unsubscribe<EventProjectFileStore>(this); EventManager::unsubscribe<EventProjectFileStore>(this);
@@ -261,9 +268,10 @@ namespace hex::plugin::builtin {
ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 1); ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 1);
if (this->m_evaluatorRunning) { auto &runtime = provider->getPatternLanguageRuntime();
if (runtime.isRunning()) {
if (ImGui::IconButton(ICON_VS_DEBUG_STOP, ImGui::GetCustomColorVec4(ImGuiCustomCol_ToolbarRed))) if (ImGui::IconButton(ICON_VS_DEBUG_STOP, ImGui::GetCustomColorVec4(ImGuiCustomCol_ToolbarRed)))
this->m_evaluatorRuntime->abort(); runtime.abort();
} else { } else {
if (ImGui::IconButton(ICON_VS_DEBUG_START, ImGui::GetCustomColorVec4(ImGuiCustomCol_ToolbarGreen))) if (ImGui::IconButton(ICON_VS_DEBUG_START, ImGui::GetCustomColorVec4(ImGuiCustomCol_ToolbarGreen)))
this->evaluatePattern(this->m_textEditor.GetText()); this->evaluatePattern(this->m_textEditor.GetText());
@@ -273,7 +281,7 @@ namespace hex::plugin::builtin {
ImGui::PopStyleVar(); ImGui::PopStyleVar();
ImGui::SameLine(); ImGui::SameLine();
if (this->m_evaluatorRunning) if (this->m_runningEvaluators > 0)
ImGui::TextSpinner("hex.builtin.view.pattern_editor.evaluating"_lang); ImGui::TextSpinner("hex.builtin.view.pattern_editor.evaluating"_lang);
else { else {
if (ImGui::Checkbox("hex.builtin.view.pattern_editor.auto"_lang, &this->m_runAutomatically)) { if (ImGui::Checkbox("hex.builtin.view.pattern_editor.auto"_lang, &this->m_runAutomatically)) {
@@ -286,8 +294,8 @@ namespace hex::plugin::builtin {
ImGui::SameLine(); ImGui::SameLine();
ImGui::TextFormatted("{} / {}", ImGui::TextFormatted("{} / {}",
this->m_evaluatorRuntime->getCreatedPatternCount(), provider->getPatternLanguageRuntime().getCreatedPatternCount(),
this->m_evaluatorRuntime->getMaximumPatternCount()); provider->getPatternLanguageRuntime().getMaximumPatternCount());
} }
if (this->m_textEditor.IsTextChanged()) { if (this->m_textEditor.IsTextChanged()) {
@@ -295,7 +303,7 @@ namespace hex::plugin::builtin {
this->m_hasUnevaluatedChanges = true; this->m_hasUnevaluatedChanges = true;
} }
if (this->m_hasUnevaluatedChanges && !this->m_evaluatorRunning && !this->m_parserRunning) { if (this->m_hasUnevaluatedChanges && this->m_runningEvaluators == 0 && this->m_runningParsers == 0) {
this->m_hasUnevaluatedChanges = false; this->m_hasUnevaluatedChanges = false;
if (this->m_runAutomatically) if (this->m_runAutomatically)
@@ -305,7 +313,7 @@ namespace hex::plugin::builtin {
} }
} }
if (this->m_evaluatorRuntime->hasDangerousFunctionBeenCalled() && !ImGui::IsPopupOpen(View::toWindowName("hex.builtin.view.pattern_editor.dangerous_function.name").c_str())) { if (provider->getPatternLanguageRuntime().hasDangerousFunctionBeenCalled() && !ImGui::IsPopupOpen(View::toWindowName("hex.builtin.view.pattern_editor.dangerous_function.name").c_str())) {
ImGui::OpenPopup(View::toWindowName("hex.builtin.view.pattern_editor.dangerous_function.name").c_str()); ImGui::OpenPopup(View::toWindowName("hex.builtin.view.pattern_editor.dangerous_function.name").c_str());
} }
@@ -315,11 +323,15 @@ namespace hex::plugin::builtin {
ImGui::NewLine(); ImGui::NewLine();
View::confirmButtons( View::confirmButtons(
"hex.common.yes"_lang, "hex.common.no"_lang, [this] { "hex.common.yes"_lang, "hex.common.no"_lang,
this->m_evaluatorRuntime->allowDangerousFunctions(true); [] {
ImGui::CloseCurrentPopup(); }, [this] { ImHexApi::Provider::get()->getPatternLanguageRuntime().allowDangerousFunctions(true);
this->m_evaluatorRuntime->allowDangerousFunctions(false); ImGui::CloseCurrentPopup();
ImGui::CloseCurrentPopup(); }); },
[] {
ImHexApi::Provider::get()->getPatternLanguageRuntime().allowDangerousFunctions(false);
ImGui::CloseCurrentPopup();
});
ImGui::EndPopup(); ImGui::EndPopup();
} }
@@ -567,16 +579,15 @@ namespace hex::plugin::builtin {
} }
void ViewPatternEditor::clearPatternData() { void ViewPatternEditor::clearPatternData() {
for (auto &data : SharedData::patternData) if (!ImHexApi::Provider::isValid()) return;
delete data;
SharedData::patternData.clear(); ImHexApi::Provider::get()->getPatternLanguageRuntime().reset();
pl::PatternData::resetPalette(); ContentRegistry::PatternLanguage::resetPalette();
} }
void ViewPatternEditor::parsePattern(const std::string &code) { void ViewPatternEditor::parsePattern(const std::string &code) {
this->m_parserRunning = true; this->m_runningParsers++;
std::thread([this, code] { std::thread([this, code] {
auto ast = this->m_parserRuntime->parseString(code); auto ast = this->m_parserRuntime->parseString(code);
@@ -606,12 +617,12 @@ namespace hex::plugin::builtin {
} }
} }
this->m_parserRunning = false; this->m_runningParsers--;
}).detach(); }).detach();
} }
void ViewPatternEditor::evaluatePattern(const std::string &code) { void ViewPatternEditor::evaluatePattern(const std::string &code) {
this->m_evaluatorRunning = true; this->m_runningEvaluators++;
this->m_textEditor.SetErrorMarkers({}); this->m_textEditor.SetErrorMarkers({});
this->m_console.clear(); this->m_console.clear();
@@ -633,28 +644,31 @@ namespace hex::plugin::builtin {
inVariables[name] = variable.value; inVariables[name] = variable.value;
} }
auto result = this->m_evaluatorRuntime->executeString(ImHexApi::Provider::get(), code, envVars, inVariables); auto provider = ImHexApi::Provider::get();
auto &runtime = provider->getPatternLanguageRuntime();
auto error = this->m_evaluatorRuntime->getError(); auto result = runtime.executeString(provider, code, envVars, inVariables);
if (error.has_value()) { if (!result) {
TextEditor::ErrorMarkers errorMarkers = { { error->getLineNumber(), error->what() } }; auto error = runtime.getError();
this->m_textEditor.SetErrorMarkers(errorMarkers); if (error) {
TextEditor::ErrorMarkers errorMarkers = { { error->getLineNumber(), error->what() } };
this->m_textEditor.SetErrorMarkers(errorMarkers);
}
} }
this->m_console = this->m_evaluatorRuntime->getConsoleLog(); this->m_console = runtime.getConsoleLog();
auto outVariables = this->m_evaluatorRuntime->getOutVariables(); auto outVariables = runtime.getOutVariables();
for (auto &[name, variable] : this->m_patternVariables) { for (auto &[name, variable] : this->m_patternVariables) {
if (variable.outVariable && outVariables.contains(name)) if (variable.outVariable && outVariables.contains(name))
variable.value = outVariables.at(name); variable.value = outVariables.at(name);
} }
if (result.has_value()) { if (result) {
SharedData::patternData = std::move(result.value()); EventManager::post<EventPatternChanged>(runtime.getPatterns());
EventManager::post<EventPatternChanged>(SharedData::patternData);
} }
this->m_evaluatorRunning = false; this->m_runningEvaluators--;
}).detach(); }).detach();
} }

View File

@@ -9,14 +9,14 @@ namespace hex::plugin::builtin {
ViewSettings::ViewSettings() : View("hex.builtin.view.settings.name") { ViewSettings::ViewSettings() : View("hex.builtin.view.settings.name") {
EventManager::subscribe<RequestOpenWindow>(this, [this](const std::string &name) { EventManager::subscribe<RequestOpenWindow>(this, [this](const std::string &name) {
if (name == "Settings") { if (name == "Settings") {
View::doLater([] { ImGui::OpenPopup(View::toWindowName("hex.builtin.view.settings.name").c_str()); }); ImHexApi::Tasks::doLater([] { ImGui::OpenPopup(View::toWindowName("hex.builtin.view.settings.name").c_str()); });
this->getWindowOpenState() = true; this->getWindowOpenState() = true;
} }
}); });
ContentRegistry::Interface::addMenuItem("hex.builtin.menu.help", 2000, [&, this] { ContentRegistry::Interface::addMenuItem("hex.builtin.menu.help", 2000, [&, this] {
if (ImGui::MenuItem("hex.builtin.view.settings.name"_lang)) { if (ImGui::MenuItem("hex.builtin.view.settings.name"_lang)) {
View::doLater([] { ImGui::OpenPopup(View::toWindowName("hex.builtin.view.settings.name").c_str()); }); ImHexApi::Tasks::doLater([] { ImGui::OpenPopup(View::toWindowName("hex.builtin.view.settings.name").c_str()); });
this->getWindowOpenState() = true; this->getWindowOpenState() = true;
} }
}); });

View File

@@ -1,5 +1,7 @@
#include "content/views/view_store.hpp" #include "content/views/view_store.hpp"
#include <hex/api/content_registry.hpp>
#include <imgui.h> #include <imgui.h>
#define IMGUI_DEFINE_MATH_OPERATORS #define IMGUI_DEFINE_MATH_OPERATORS
#include <imgui_internal.h> #include <imgui_internal.h>
@@ -27,7 +29,7 @@ namespace hex::plugin::builtin {
ContentRegistry::Interface::addMenuItem("hex.builtin.menu.help", 3000, [&, this] { ContentRegistry::Interface::addMenuItem("hex.builtin.menu.help", 3000, [&, this] {
if (ImGui::MenuItem("hex.builtin.view.store.name"_lang)) { if (ImGui::MenuItem("hex.builtin.view.store.name"_lang)) {
View::doLater([] { ImGui::OpenPopup(View::toWindowName("hex.builtin.view.store.name").c_str()); }); ImHexApi::Tasks::doLater([] { ImGui::OpenPopup(View::toWindowName("hex.builtin.view.store.name").c_str()); });
this->getWindowOpenState() = true; this->getWindowOpenState() = true;
} }
}); });

View File

@@ -52,7 +52,7 @@ namespace hex::plugin::builtin {
if (ImGui::MenuItem("hex.builtin.view.strings.demangle"_lang)) { if (ImGui::MenuItem("hex.builtin.view.strings.demangle"_lang)) {
this->m_demangledName = llvm::demangle(this->m_selectedString); this->m_demangledName = llvm::demangle(this->m_selectedString);
if (!this->m_demangledName.empty()) if (!this->m_demangledName.empty())
View::doLater([] { ImGui::OpenPopup("hex.builtin.view.strings.demangle.name"_lang); }); ImHexApi::Tasks::doLater([] { ImGui::OpenPopup("hex.builtin.view.strings.demangle.name"_lang); });
} }
ImGui::EndPopup(); ImGui::EndPopup();
} }

View File

@@ -1,5 +1,7 @@
#include "content/views/view_tools.hpp" #include "content/views/view_tools.hpp"
#include <hex/api/content_registry.hpp>
#include <hex/providers/provider.hpp> #include <hex/providers/provider.hpp>
namespace hex::plugin::builtin { namespace hex::plugin::builtin {

View File

@@ -1,5 +1,7 @@
#include "content/views/view_yara.hpp" #include "content/views/view_yara.hpp"
#include <hex/api/content_registry.hpp>
#include <hex/providers/provider.hpp> #include <hex/providers/provider.hpp>
#include <hex/helpers/utils.hpp> #include <hex/helpers/utils.hpp>
#include <hex/helpers/file.hpp> #include <hex/helpers/file.hpp>
@@ -20,7 +22,7 @@ namespace hex::plugin::builtin {
this->reloadRules(); this->reloadRules();
ContentRegistry::FileHandler::add({ ".yar" }, [](const auto &path) { ContentRegistry::FileHandler::add({ ".yar" }, [](const auto &path) {
for (auto &destPath : hex::getPath(ImHexPath::Yara)) { for (const auto &destPath : hex::getPath(ImHexPath::Yara)) {
std::error_code error; std::error_code error;
if (fs::copy_file(path, destPath / path.filename(), fs::copy_options::overwrite_existing, error)) { if (fs::copy_file(path, destPath / path.filename(), fs::copy_options::overwrite_existing, error)) {
View::showMessagePopup("hex.builtin.view.yara.rule_added"_lang); View::showMessagePopup("hex.builtin.view.yara.rule_added"_lang);
@@ -132,7 +134,7 @@ namespace hex::plugin::builtin {
void ViewYara::reloadRules() { void ViewYara::reloadRules() {
this->m_rules.clear(); this->m_rules.clear();
for (auto path : hex::getPath(ImHexPath::Yara)) { for (const auto path : hex::getPath(ImHexPath::Yara)) {
if (!fs::exists(path)) if (!fs::exists(path))
continue; continue;

View File

@@ -0,0 +1,449 @@
#include <hex.hpp>
#include <hex/api/event.hpp>
#include <hex/api/content_registry.hpp>
#include <nlohmann/json.hpp>
#include <hex/api/localization.hpp>
#include <hex/helpers/paths.hpp>
#include <hex/helpers/logger.hpp>
#include <hex/api/plugin_manager.hpp>
#include <hex/helpers/project_file_handler.hpp>
#include <imgui.h>
#include <implot.h>
#include <imnodes.h>
#include <hex/ui/imgui_imhex_extensions.h>
#include <romfs/romfs.hpp>
#include <fontawesome_font.h>
#include <codicons_font.h>
#include <list>
namespace hex::plugin::builtin {
static bool s_layoutConfigured = false;
static ImGui::Texture s_bannerTexture;
static std::list<fs::path> s_recentFilePaths;
static fs::path s_safetyBackupPath;
static std::string s_tipOfTheDay;
static void drawPopups() {
ImGui::SetNextWindowPos(ImGui::GetMainViewport()->GetCenter(), ImGuiCond_Appearing, ImVec2(0.5F, 0.5F));
ImGui::SetNextWindowSize(ImGui::GetMainViewport()->Size / 3, ImGuiCond_Appearing);
if (ImGui::BeginPopup("hex.welcome.tip_of_the_day"_lang)) {
ImGui::Header("hex.welcome.tip_of_the_day"_lang, true);
ImGui::TextFormattedWrapped("{}", s_tipOfTheDay.c_str());
ImGui::NewLine();
static bool dontShowAgain = false;
if (ImGui::Checkbox("hex.common.dont_show_again"_lang, &dontShowAgain)) {
ContentRegistry::Settings::write("hex.builtin.setting.general", "hex.builtin.setting.general.show_tips", dontShowAgain);
}
ImGui::SameLine((ImGui::GetMainViewport()->Size / 3 - ImGui::CalcTextSize("hex.common.close"_lang) - ImGui::GetStyle().FramePadding).x);
if (ImGui::Button("hex.common.close"_lang))
ImGui::CloseCurrentPopup();
ImGui::EndPopup();
}
// Popup for if there is a safety backup present because ImHex crashed
ImGui::SetNextWindowPos(ImGui::GetMainViewport()->GetCenter(), ImGuiCond_Appearing, ImVec2(0.5F, 0.5F));
if (ImGui::BeginPopupModal("hex.safety_backup.title"_lang, nullptr, ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoMove)) {
ImGui::TextUnformatted("hex.safety_backup.desc"_lang);
ImGui::NewLine();
auto width = ImGui::GetWindowWidth();
ImGui::SetCursorPosX(width / 9);
if (ImGui::Button("hex.safety_backup.restore"_lang, ImVec2(width / 3, 0))) {
ProjectFile::load(s_safetyBackupPath.string());
ProjectFile::markDirty();
ProjectFile::clearProjectFilePath();
fs::remove(s_safetyBackupPath);
ImGui::CloseCurrentPopup();
}
ImGui::SameLine();
ImGui::SetCursorPosX(width / 9 * 5);
if (ImGui::Button("hex.safety_backup.delete"_lang, ImVec2(width / 3, 0))) {
fs::remove(s_safetyBackupPath);
ImGui::CloseCurrentPopup();
}
ImGui::EndPopup();
}
}
static void drawWelcomeScreenContent() {
const auto availableSpace = ImGui::GetContentRegionAvail();
ImGui::Image(s_bannerTexture, s_bannerTexture.size() / (2 * (1.0F / ImHexApi::System::getGlobalScale())));
ImGui::Indent();
if (ImGui::BeginTable("Welcome Left", 1, ImGuiTableFlags_NoBordersInBody, ImVec2(availableSpace.x / 2, 0))) {
ImGui::TableNextRow(ImGuiTableRowFlags_None, ImGui::GetTextLineHeightWithSpacing() * 3);
ImGui::TableNextColumn();
ImGui::TextFormattedWrapped("A Hex Editor for Reverse Engineers, Programmers and people who value their retinas when working at 3 AM.");
ImGui::TableNextRow(ImGuiTableRowFlags_None, ImGui::GetTextLineHeightWithSpacing() * 6);
ImGui::TableNextColumn();
ImGui::UnderlinedText("hex.welcome.header.start"_lang);
ImGui::SetCursorPosY(ImGui::GetCursorPosY() + 5_scaled);
{
if (ImGui::IconHyperlink(ICON_VS_NEW_FILE, "hex.welcome.start.create_file"_lang))
EventManager::post<RequestOpenWindow>("Create File");
if (ImGui::IconHyperlink(ICON_VS_GO_TO_FILE, "hex.welcome.start.open_file"_lang))
EventManager::post<RequestOpenWindow>("Open File");
if (ImGui::IconHyperlink(ICON_VS_NOTEBOOK, "hex.welcome.start.open_project"_lang))
EventManager::post<RequestOpenWindow>("Open Project");
if (ImGui::IconHyperlink(ICON_VS_TELESCOPE, "hex.welcome.start.open_other"_lang))
ImGui::OpenPopup("hex.welcome.start.popup.open_other"_lang);
}
ImGui::SetNextWindowPos(ImGui::GetWindowPos() + ImGui::GetCursorPos());
if (ImGui::BeginPopup("hex.welcome.start.popup.open_other"_lang)) {
for (const auto &unlocalizedProviderName : ContentRegistry::Provider::getEntries()) {
if (ImGui::Hyperlink(LangEntry(unlocalizedProviderName))) {
EventManager::post<RequestCreateProvider>(unlocalizedProviderName, nullptr);
ImGui::CloseCurrentPopup();
}
}
ImGui::EndPopup();
}
ImGui::TableNextRow(ImGuiTableRowFlags_None, ImGui::GetTextLineHeightWithSpacing() * 9);
ImGui::TableNextColumn();
ImGui::UnderlinedText("hex.welcome.start.recent"_lang);
ImGui::SetCursorPosY(ImGui::GetCursorPosY() + 5_scaled);
{
for (auto &path : s_recentFilePaths) {
if (ImGui::BulletHyperlink(fs::path(path).filename().string().c_str())) {
EventManager::post<RequestOpenFile>(path);
break;
}
}
}
if (ImHexApi::System::getInitArguments().contains("update-available")) {
ImGui::TableNextRow(ImGuiTableRowFlags_None, ImGui::GetTextLineHeightWithSpacing() * 5);
ImGui::TableNextColumn();
ImGui::UnderlinedText("hex.welcome.header.update"_lang);
{
if (ImGui::DescriptionButton("hex.welcome.update.title"_lang, hex::format("hex.welcome.update.desc"_lang, ImHexApi::System::getInitArguments()["update-available"]).c_str(), ImVec2(ImGui::GetContentRegionAvail().x * 0.8F, 0)))
hex::openWebpage("hex.welcome.update.link"_lang);
}
}
ImGui::TableNextRow(ImGuiTableRowFlags_None, ImGui::GetTextLineHeightWithSpacing() * 6);
ImGui::TableNextColumn();
ImGui::UnderlinedText("hex.welcome.header.help"_lang);
ImGui::SetCursorPosY(ImGui::GetCursorPosY() + 5_scaled);
{
if (ImGui::IconHyperlink(ICON_VS_GITHUB, "hex.welcome.help.repo"_lang)) hex::openWebpage("hex.welcome.help.repo.link"_lang);
if (ImGui::IconHyperlink(ICON_VS_ORGANIZATION, "hex.welcome.help.gethelp"_lang)) hex::openWebpage("hex.welcome.help.gethelp.link"_lang);
if (ImGui::IconHyperlink(ICON_VS_COMMENT_DISCUSSION, "hex.welcome.help.discord"_lang)) hex::openWebpage("hex.welcome.help.discord.link"_lang);
}
ImGui::TableNextRow(ImGuiTableRowFlags_None, ImGui::GetTextLineHeightWithSpacing() * 5);
ImGui::TableNextColumn();
ImGui::UnderlinedText("hex.welcome.header.plugins"_lang);
{
const auto &plugins = PluginManager::getPlugins();
if (!plugins.empty()) {
if (ImGui::BeginTable("plugins", 4, ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg | ImGuiTableFlags_ScrollY | ImGuiTableFlags_SizingFixedFit, ImVec2((ImGui::GetContentRegionAvail().x * 5) / 6, ImGui::GetTextLineHeightWithSpacing() * 5))) {
ImGui::TableSetupScrollFreeze(0, 1);
ImGui::TableSetupColumn("hex.welcome.plugins.plugin"_lang, ImGuiTableColumnFlags_WidthStretch, 0.2);
ImGui::TableSetupColumn("hex.welcome.plugins.author"_lang, ImGuiTableColumnFlags_WidthStretch, 0.2);
ImGui::TableSetupColumn("hex.welcome.plugins.desc"_lang, ImGuiTableColumnFlags_WidthStretch, 0.6);
ImGui::TableSetupColumn("##loaded", ImGuiTableColumnFlags_WidthFixed, ImGui::GetTextLineHeight());
ImGui::TableHeadersRow();
ImGuiListClipper clipper;
clipper.Begin(plugins.size());
while (clipper.Step()) {
for (u64 i = clipper.DisplayStart; i < clipper.DisplayEnd; i++) {
const auto &plugin = plugins[i];
ImGui::TableNextRow();
ImGui::TableNextColumn();
ImGui::TextUnformatted(plugin.getPluginName().c_str());
ImGui::TableNextColumn();
ImGui::TextUnformatted(plugin.getPluginAuthor().c_str());
ImGui::TableNextColumn();
ImGui::TextUnformatted(plugin.getPluginDescription().c_str());
ImGui::TableNextColumn();
ImGui::TextUnformatted(plugin.isLoaded() ? ICON_VS_CHECK : ICON_VS_CLOSE);
}
}
clipper.End();
ImGui::EndTable();
}
}
}
ImGui::EndTable();
}
ImGui::SameLine();
if (ImGui::BeginTable("Welcome Right", 1, ImGuiTableFlags_NoBordersInBody, ImVec2(availableSpace.x / 2, 0))) {
ImGui::TableNextRow(ImGuiTableRowFlags_None, ImGui::GetTextLineHeightWithSpacing() * 5);
ImGui::TableNextColumn();
ImGui::UnderlinedText("hex.welcome.header.customize"_lang);
{
if (ImGui::DescriptionButton("hex.welcome.customize.settings.title"_lang, "hex.welcome.customize.settings.desc"_lang, ImVec2(ImGui::GetContentRegionAvail().x * 0.8F, 0)))
EventManager::post<RequestOpenWindow>("Settings");
}
ImGui::TableNextRow(ImGuiTableRowFlags_None, ImGui::GetTextLineHeightWithSpacing() * 5);
ImGui::TableNextColumn();
ImGui::UnderlinedText("hex.welcome.header.learn"_lang);
{
if (ImGui::DescriptionButton("hex.welcome.learn.latest.title"_lang, "hex.welcome.learn.latest.desc"_lang, ImVec2(ImGui::GetContentRegionAvail().x * 0.8F, 0)))
hex::openWebpage("hex.welcome.learn.latest.link"_lang);
if (ImGui::DescriptionButton("hex.welcome.learn.pattern.title"_lang, "hex.welcome.learn.pattern.desc"_lang, ImVec2(ImGui::GetContentRegionAvail().x * 0.8F, 0)))
hex::openWebpage("hex.welcome.learn.pattern.link"_lang);
if (ImGui::DescriptionButton("hex.welcome.learn.plugins.title"_lang, "hex.welcome.learn.plugins.desc"_lang, ImVec2(ImGui::GetContentRegionAvail().x * 0.8F, 0)))
hex::openWebpage("hex.welcome.learn.plugins.link"_lang);
}
auto extraWelcomeScreenEntries = ContentRegistry::Interface::getWelcomeScreenEntries();
if (!extraWelcomeScreenEntries.empty()) {
ImGui::TableNextRow(ImGuiTableRowFlags_None, ImGui::GetTextLineHeightWithSpacing() * 5);
ImGui::TableNextColumn();
ImGui::UnderlinedText("hex.welcome.header.various"_lang);
{
for (const auto &callback : extraWelcomeScreenEntries)
callback();
}
}
ImGui::EndTable();
}
}
static void drawWelcomeScreen() {
if (ImGui::Begin("DockSpace")) {
if (!ImHexApi::Provider::isValid()) {
static char title[256];
ImFormatString(title, IM_ARRAYSIZE(title), "%s/DockSpace_%08X", ImGui::GetCurrentWindow()->Name, ImGui::GetID("MainDock"));
if (ImGui::Begin(title)) {
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(10_scaled, 10_scaled));
if (ImGui::BeginChild("Welcome Screen", ImVec2(0, 0), false, ImGuiWindowFlags_AlwaysUseWindowPadding | ImGuiWindowFlags_NoScrollWithMouse)) {
drawWelcomeScreenContent();
}
ImGui::EndChild();
ImGui::PopStyleVar();
}
ImGui::End();
} else if (!s_layoutConfigured) {
s_layoutConfigured = true;
// TODO: FIX RESET LAYOUT
}
}
ImGui::End();
drawPopups();
}
void createWelcomeScreen() {
(void)EventManager::subscribe<EventFrameBegin>(drawWelcomeScreen);
(void)EventManager::subscribe<EventSettingsChanged>([]() {
{
auto theme = ContentRegistry::Settings::getSetting("hex.builtin.setting.interface", "hex.builtin.setting.interface.color");
if (theme.is_number())
EventManager::post<RequestChangeTheme>(theme.get<int>());
}
{
auto language = ContentRegistry::Settings::getSetting("hex.builtin.setting.interface", "hex.builtin.setting.interface.language");
if (language.is_string()) {
LangEntry::loadLanguage(static_cast<std::string>(language));
} else {
// If no language is specified, fall back to English.
LangEntry::loadLanguage("en-US");
}
}
{
auto targetFps = ContentRegistry::Settings::getSetting("hex.builtin.setting.interface", "hex.builtin.setting.interface.fps");
if (targetFps.is_number())
ImHexApi::System::setTargetFPS(targetFps);
}
{
if (ContentRegistry::Settings::read("hex.builtin.setting.imhex", "hex.builtin.setting.imhex.launched", 0) == 1)
s_layoutConfigured = true;
else
ContentRegistry::Settings::write("hex.builtin.setting.imhex", "hex.builtin.setting.imhex.launched", 1);
}
});
(void)EventManager::subscribe<RequestChangeTheme>([](u32 theme) {
if (s_bannerTexture.valid())
ImGui::UnloadImage(s_bannerTexture);
switch (theme) {
default:
case 1: /* Dark theme */
{
ImGui::StyleColorsDark();
ImGui::StyleCustomColorsDark();
ImPlot::StyleColorsDark();
auto banner = romfs::get("banner_dark.png");
s_bannerTexture = ImGui::LoadImageFromMemory(reinterpret_cast<const ImU8 *>(banner.data()), banner.size());
break;
}
case 2: /* Light theme */
{
ImGui::StyleColorsLight();
ImGui::StyleCustomColorsLight();
ImPlot::StyleColorsLight();
auto banner = romfs::get("banner_light.png");
s_bannerTexture = ImGui::LoadImageFromMemory(reinterpret_cast<const ImU8 *>(banner.data()), banner.size());
break;
}
case 3: /* Classic theme */
{
ImGui::StyleColorsClassic();
ImGui::StyleCustomColorsClassic();
ImPlot::StyleColorsClassic();
auto banner = romfs::get("banner_dark.png");
s_bannerTexture = ImGui::LoadImageFromMemory(reinterpret_cast<const ImU8 *>(banner.data()), banner.size());
break;
}
}
ImGui::GetStyle().Colors[ImGuiCol_DockingEmptyBg] = ImGui::GetStyle().Colors[ImGuiCol_WindowBg];
ImGui::GetStyle().Colors[ImGuiCol_TitleBg] = ImGui::GetStyle().Colors[ImGuiCol_MenuBarBg];
ImGui::GetStyle().Colors[ImGuiCol_TitleBgActive] = ImGui::GetStyle().Colors[ImGuiCol_MenuBarBg];
ImGui::GetStyle().Colors[ImGuiCol_TitleBgCollapsed] = ImGui::GetStyle().Colors[ImGuiCol_MenuBarBg];
if (!s_bannerTexture.valid()) {
log::error("Failed to load banner texture!");
}
});
(void)EventManager::subscribe<EventFileLoaded>([](const auto &path) {
s_recentFilePaths.push_front(path);
{
std::list<fs::path> uniques;
for (auto &file : s_recentFilePaths) {
bool exists = false;
for (auto &unique : uniques) {
if (file == unique)
exists = true;
}
if (!exists && !file.empty())
uniques.push_back(file);
if (uniques.size() > 5)
break;
}
s_recentFilePaths = uniques;
}
{
std::vector<std::string> recentFilesVector;
for (const auto &recentPath : s_recentFilePaths)
recentFilesVector.push_back(recentPath.string());
ContentRegistry::Settings::write("hex.builtin.setting.imhex", "hex.builtin.setting.imhex.recent_files", recentFilesVector);
}
});
ContentRegistry::Interface::addMenuItem("hex.builtin.menu.file", 1050, [&] {
if (ImGui::MenuItem("hex.builtin.view.hexeditor.menu.file.open_file"_lang, "CTRL + O")) {
hex::openFileBrowser("hex.builtin.view.hexeditor.open_file"_lang, DialogMode::Open, {},
[](const auto &path) {
EventManager::post<RequestOpenFile>(path);
});
}
if (ImGui::BeginMenu("hex.builtin.view.hexeditor.menu.file.open_recent"_lang, !s_recentFilePaths.empty())) {
for (auto &path : s_recentFilePaths) {
if (ImGui::MenuItem(fs::path(path).filename().string().c_str())) {
EventManager::post<RequestOpenFile>(path);
}
}
ImGui::Separator();
if (ImGui::MenuItem("hex.builtin.view.hexeditor.menu.file.clear_recent"_lang)) {
s_recentFilePaths.clear();
ContentRegistry::Settings::write(
"hex.builtin.setting.imhex",
"hex.builtin.setting.imhex.recent_files",
std::vector<std::string>{});
}
ImGui::EndMenu();
}
if (ImGui::BeginMenu("hex.builtin.view.hexeditor.menu.file.open_other"_lang)) {
for (const auto &unlocalizedProviderName : ContentRegistry::Provider::getEntries()) {
if (ImGui::MenuItem(LangEntry(unlocalizedProviderName))) {
EventManager::post<RequestCreateProvider>(unlocalizedProviderName, nullptr);
}
}
ImGui::EndMenu();
}
});
constexpr auto CrashBackupFileName = "crash_backup.hexproj";
for (const auto &path : hex::getPath(ImHexPath::Config)) {
if (auto filePath = fs::path(path) / CrashBackupFileName; fs::exists(filePath)) {
s_safetyBackupPath = filePath;
ImHexApi::Tasks::doLater([] { ImGui::OpenPopup("hex.safety_backup.title"_lang); });
}
}
for (const auto &path : ContentRegistry::Settings::read("hex.builtin.setting.imhex", "hex.builtin.setting.imhex.recent_files"))
s_recentFilePaths.emplace_back(path);
if (ImHexApi::System::getInitArguments().contains("tip-of-the-day")) {
s_tipOfTheDay = ImHexApi::System::getInitArguments()["tip-of-the-day"];
bool showTipOfTheDay = ContentRegistry::Settings::read("hex.builtin.setting.general", "hex.builtin.setting.general.show_tips", 1);
if (showTipOfTheDay)
ImHexApi::Tasks::doLater([] { ImGui::OpenPopup("hex.welcome.tip_of_the_day"_lang); });
}
}
}

View File

@@ -1,5 +1,5 @@
#include <hex/api/content_registry.hpp> #include <hex/api/content_registry.hpp>
#include <hex/helpers/lang.hpp> #include <hex/api/localization.hpp>
namespace hex::plugin::builtin { namespace hex::plugin::builtin {

View File

@@ -1,5 +1,5 @@
#include <hex/api/content_registry.hpp> #include <hex/api/content_registry.hpp>
#include <hex/helpers/lang.hpp> #include <hex/api/localization.hpp>
namespace hex::plugin::builtin { namespace hex::plugin::builtin {

View File

@@ -1,5 +1,5 @@
#include <hex/api/content_registry.hpp> #include <hex/api/content_registry.hpp>
#include <hex/helpers/lang.hpp> #include <hex/api/localization.hpp>
namespace hex::plugin::builtin { namespace hex::plugin::builtin {

View File

@@ -1,5 +1,5 @@
#include <hex/api/content_registry.hpp> #include <hex/api/content_registry.hpp>
#include <hex/helpers/lang.hpp> #include <hex/api/localization.hpp>
namespace hex::plugin::builtin { namespace hex::plugin::builtin {

Some files were not shown because too many files have changed in this diff Show More