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:
parent
61fc479c79
commit
1991afb87b
@ -268,7 +268,7 @@ macro(setDefaultBuiltTypeIfUnset)
|
||||
endmacro()
|
||||
|
||||
macro(detectBadClone)
|
||||
file (GLOB EXTERNAL_DIRS "external/*")
|
||||
file (GLOB EXTERNAL_DIRS "lib/external/*")
|
||||
foreach (EXTERNAL_DIR ${EXTERNAL_DIRS})
|
||||
file(GLOB RESULT "${EXTERNAL_DIR}/*")
|
||||
list(LENGTH RESULT ENTRY_COUNT)
|
||||
|
1
lib/external/imgui/include/imconfig.h
vendored
1
lib/external/imgui/include/imconfig.h
vendored
@ -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_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_DEFINE_MATH_OPERATORS
|
||||
|
||||
//---- Include imgui_user.h at the end of imgui.h as a convenience
|
||||
//#define IMGUI_INCLUDE_IMGUI_USER_H
|
||||
|
@ -105,6 +105,8 @@ set(LIBIMHEX_SOURCES
|
||||
source/api/content_registry.cpp
|
||||
source/api/task.cpp
|
||||
source/api/keybinding.cpp
|
||||
source/api/plugin_manager.cpp
|
||||
source/api/localization.cpp
|
||||
|
||||
source/data_processor/attribute.cpp
|
||||
source/data_processor/link.cpp
|
||||
@ -113,9 +115,7 @@ set(LIBIMHEX_SOURCES
|
||||
source/helpers/utils.cpp
|
||||
source/helpers/paths.cpp
|
||||
source/helpers/magic.cpp
|
||||
source/helpers/shared_data.cpp
|
||||
source/helpers/crypto.cpp
|
||||
source/helpers/lang.cpp
|
||||
source/helpers/net.cpp
|
||||
source/helpers/file.cpp
|
||||
source/helpers/socket.cpp
|
||||
@ -136,8 +136,7 @@ set(LIBIMHEX_SOURCES
|
||||
source/providers/provider.cpp
|
||||
|
||||
source/ui/imgui_imhex_extensions.cpp
|
||||
|
||||
source/views/view.cpp
|
||||
source/ui/view.cpp
|
||||
)
|
||||
|
||||
if (APPLE)
|
||||
@ -164,4 +163,4 @@ if (APPLE)
|
||||
target_link_libraries(libimhex PUBLIC ${FOUNDATION})
|
||||
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)
|
||||
|
@ -18,6 +18,8 @@ using i32 = std::int32_t;
|
||||
using i64 = std::int64_t;
|
||||
using i128 = __int128_t;
|
||||
|
||||
using color_t = u32;
|
||||
|
||||
namespace hex {
|
||||
|
||||
struct Region {
|
||||
|
@ -92,6 +92,15 @@ namespace hex {
|
||||
/* Pattern Language Function Registry. Allows adding of new functions that may be used inside the pattern language */
|
||||
namespace PatternLanguage {
|
||||
|
||||
namespace impl {
|
||||
|
||||
struct ColorPalette {
|
||||
std::string name;
|
||||
std::vector<u32> colors;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
constexpr static u32 UnlimitedParameters = 0xFFFF'FFFF;
|
||||
constexpr static u32 MoreParametersThan = 0x8000'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 addDangerousFunction(const Namespace &ns, const std::string &name, u32 parameterCount, const Callback &func);
|
||||
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 */
|
||||
@ -249,8 +264,6 @@ namespace hex {
|
||||
|
||||
}
|
||||
|
||||
u32 getDockSpaceId();
|
||||
|
||||
void registerMainMenuItem(const std::string &unlocalizedName, u32 priority);
|
||||
void addMenuItem(const std::string &unlocalizedMainMenuName, u32 priority, const impl::DrawCallback &function);
|
||||
|
||||
@ -298,7 +311,7 @@ namespace hex {
|
||||
impl::addProviderName(unlocalizedName);
|
||||
}
|
||||
|
||||
const std::vector<std::string> &getEntries();
|
||||
std::vector<std::string> &getEntries();
|
||||
|
||||
}
|
||||
|
||||
|
@ -113,12 +113,13 @@ namespace hex {
|
||||
EVENT_DEF(EventAbnormalTermination, int);
|
||||
EVENT_DEF(EventOSThemeChanged);
|
||||
EVENT_DEF(EventProviderCreated, prv::Provider *);
|
||||
EVENT_DEF(EventProviderChanged, prv::Provider *, prv::Provider *);
|
||||
EVENT_DEF(EventFrameBegin);
|
||||
EVENT_DEF(EventFrameEnd);
|
||||
|
||||
EVENT_DEF(RequestOpenWindow, std::string);
|
||||
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(RequestChangeWindowTitle, std::string);
|
||||
EVENT_DEF(RequestCloseImHex, bool);
|
||||
|
@ -10,6 +10,8 @@
|
||||
#include <hex/api/task.hpp>
|
||||
#include <hex/api/keybinding.hpp>
|
||||
|
||||
#include <imgui.h>
|
||||
|
||||
namespace hex {
|
||||
|
||||
namespace prv {
|
||||
@ -17,34 +19,62 @@ namespace hex {
|
||||
}
|
||||
|
||||
namespace ImHexApi {
|
||||
|
||||
namespace Common {
|
||||
|
||||
void closeImHex(bool noQuestions = false);
|
||||
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 ®ion, color_t color, std::string tooltip = "");
|
||||
void removeHighlight(u32 id);
|
||||
std::map<u32, Highlighting> &getHighlights();
|
||||
|
||||
}
|
||||
|
||||
namespace Bookmarks {
|
||||
|
||||
struct Entry {
|
||||
Region region;
|
||||
|
||||
std::vector<char> name;
|
||||
std::vector<char> comment;
|
||||
std::string name;
|
||||
std::string comment;
|
||||
u32 color;
|
||||
bool locked;
|
||||
|
||||
u32 highlightId;
|
||||
};
|
||||
|
||||
void add(Region region, const std::string &name, const std::string &comment, u32 color = 0x00000000);
|
||||
void add(u64 addr, size_t size, 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 address, size_t size, const std::string &name, const std::string &comment, color_t color = 0x00000000);
|
||||
|
||||
std::list<Entry> &getEntries();
|
||||
};
|
||||
}
|
||||
|
||||
namespace Provider {
|
||||
|
||||
prv::Provider *get();
|
||||
const std::vector<prv::Provider *> &getProviders();
|
||||
|
||||
void setCurrentProvider(u32 index);
|
||||
|
||||
bool isValid();
|
||||
|
||||
void add(prv::Provider *provider);
|
||||
@ -56,14 +86,51 @@ namespace hex {
|
||||
|
||||
void remove(prv::Provider *provider);
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
namespace Tasks {
|
||||
|
||||
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();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -185,6 +185,10 @@ namespace hex {
|
||||
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 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;
|
||||
};
|
||||
|
||||
}
|
@ -35,10 +35,13 @@ namespace hex {
|
||||
static void setFallbackLanguage(const std::string &language);
|
||||
static const std::string &getFallbackLanguage();
|
||||
|
||||
static void resetLanguageStrings();
|
||||
|
||||
private:
|
||||
std::string m_unlocalizedString;
|
||||
|
||||
static std::string s_fallbackLanguage;
|
||||
static std::map<std::string, std::string> s_currStrings;
|
||||
};
|
||||
|
||||
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 LangEntry &&right);
|
||||
|
||||
namespace lang_literals {
|
||||
|
||||
inline LangEntry operator""_lang(const char *string, size_t) {
|
||||
return LangEntry(string);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -24,6 +24,7 @@ namespace hex {
|
||||
[[nodiscard]] std::string getPluginDescription() const;
|
||||
[[nodiscard]] std::string getCompatibleVersion() const;
|
||||
void setImGuiContext(ImGuiContext *ctx) const;
|
||||
[[nodiscard]] bool isBuiltinPlugin() const;
|
||||
|
||||
[[nodiscard]] const fs::path &getPath() const;
|
||||
|
||||
@ -36,6 +37,7 @@ namespace hex {
|
||||
using GetPluginDescriptionFunc = const char *(*)();
|
||||
using GetCompatibleVersionFunc = const char *(*)();
|
||||
using SetImGuiContextFunc = void (*)(ImGuiContext *);
|
||||
using IsBuiltinPluginFunc = bool(*)();
|
||||
|
||||
void *m_handle = nullptr;
|
||||
fs::path m_path;
|
||||
@ -48,6 +50,7 @@ namespace hex {
|
||||
GetPluginDescriptionFunc m_getPluginDescriptionFunction = nullptr;
|
||||
GetCompatibleVersionFunc m_getCompatibleVersionFunction = nullptr;
|
||||
SetImGuiContextFunc m_setImGuiContextFunction = nullptr;
|
||||
IsBuiltinPluginFunc m_isBuiltinPluginFunction = nullptr;
|
||||
|
||||
template<typename T>
|
||||
[[nodiscard]] auto getPluginFunction(const std::string &symbol) {
|
||||
@ -71,8 +74,8 @@ namespace hex {
|
||||
}
|
||||
|
||||
private:
|
||||
static inline fs::path s_pluginFolder;
|
||||
static inline std::vector<Plugin> s_plugins;
|
||||
static fs::path s_pluginFolder;
|
||||
static std::vector<Plugin> s_plugins;
|
||||
};
|
||||
|
||||
}
|
@ -2,6 +2,8 @@
|
||||
|
||||
#include <hex.hpp>
|
||||
|
||||
#include <list>
|
||||
#include <mutex>
|
||||
#include <string>
|
||||
|
||||
namespace hex {
|
||||
@ -21,9 +23,16 @@ namespace hex {
|
||||
|
||||
[[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:
|
||||
std::string m_name;
|
||||
u64 m_maxValue, m_currValue;
|
||||
|
||||
static std::list<Task *> s_runningTasks;
|
||||
static std::mutex s_taskMutex;
|
||||
};
|
||||
|
||||
}
|
@ -27,8 +27,8 @@ namespace hex::dp {
|
||||
Attribute(IOType ioType, Type type, std::string unlocalizedName);
|
||||
~Attribute();
|
||||
|
||||
[[nodiscard]] u32 getID() const { return this->m_id; }
|
||||
void setID(u32 id) { this->m_id = id; }
|
||||
[[nodiscard]] u32 getId() const { return this->m_id; }
|
||||
void setId(u32 id) { this->m_id = id; }
|
||||
|
||||
[[nodiscard]] IOType getIOType() const { return this->m_ioType; }
|
||||
[[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; }
|
||||
|
||||
static void setIdCounter(u32 id) {
|
||||
if (id > Attribute::s_idCounter)
|
||||
Attribute::s_idCounter = id;
|
||||
}
|
||||
|
||||
private:
|
||||
u32 m_id;
|
||||
IOType m_ioType;
|
||||
@ -54,6 +59,8 @@ namespace hex::dp {
|
||||
|
||||
friend class Node;
|
||||
void setParentNode(Node *node) { this->m_parentNode = node; }
|
||||
|
||||
static u32 s_idCounter;
|
||||
};
|
||||
|
||||
}
|
@ -8,15 +8,22 @@ namespace hex::dp {
|
||||
public:
|
||||
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; }
|
||||
|
||||
[[nodiscard]] u32 getFromID() const { return this->m_from; }
|
||||
[[nodiscard]] u32 getToID() const { return this->m_to; }
|
||||
[[nodiscard]] u32 getFromId() const { return this->m_from; }
|
||||
[[nodiscard]] u32 getToId() const { return this->m_to; }
|
||||
|
||||
static void setIdCounter(u32 id) {
|
||||
if (id > Link::s_idCounter)
|
||||
Link::s_idCounter = id;
|
||||
}
|
||||
|
||||
private:
|
||||
u32 m_id;
|
||||
u32 m_from, m_to;
|
||||
|
||||
static u32 s_idCounter;
|
||||
};
|
||||
|
||||
}
|
@ -22,8 +22,8 @@ namespace hex::dp {
|
||||
|
||||
virtual ~Node() = default;
|
||||
|
||||
[[nodiscard]] u32 getID() const { return this->m_id; }
|
||||
void setID(u32 id) { this->m_id = id; }
|
||||
[[nodiscard]] u32 getId() const { return this->m_id; }
|
||||
void setId(u32 id) { this->m_id = id; }
|
||||
|
||||
[[nodiscard]] const std::string &getUnlocalizedName() const { return this->m_unlocalizedName; }
|
||||
void setUnlocalizedName(const std::string &unlocalizedName) { this->m_unlocalizedName = unlocalizedName; }
|
||||
@ -52,6 +52,11 @@ namespace hex::dp {
|
||||
this->m_processedInputs.clear();
|
||||
}
|
||||
|
||||
static void setIdCounter(u32 id) {
|
||||
if (id > Node::s_idCounter)
|
||||
Node::s_idCounter = id;
|
||||
}
|
||||
|
||||
private:
|
||||
u32 m_id;
|
||||
std::string m_unlocalizedTitle, m_unlocalizedName;
|
||||
@ -59,6 +64,8 @@ namespace hex::dp {
|
||||
std::set<u32> m_processedInputs;
|
||||
prv::Overlay *m_overlay = nullptr;
|
||||
|
||||
static u32 s_idCounter;
|
||||
|
||||
Attribute *getConnectedInputAttribute(u32 index) {
|
||||
if (index >= this->getAttributes().size())
|
||||
throw std::runtime_error("Attribute index out of bounds!");
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
}
|
@ -400,21 +400,21 @@ namespace hex::pl {
|
||||
|
||||
PatternData *pattern;
|
||||
if (Token::isUnsigned(this->m_type))
|
||||
pattern = new PatternDataUnsigned(offset, size);
|
||||
pattern = new PatternDataUnsigned(evaluator, offset, size);
|
||||
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))
|
||||
pattern = new PatternDataFloat(offset, size);
|
||||
pattern = new PatternDataFloat(evaluator, offset, size);
|
||||
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)
|
||||
pattern = new PatternDataCharacter(offset);
|
||||
pattern = new PatternDataCharacter(evaluator, offset);
|
||||
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)
|
||||
pattern = new PatternDataPadding(offset, 1);
|
||||
pattern = new PatternDataPadding(evaluator, offset, 1);
|
||||
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)
|
||||
return { nullptr };
|
||||
else
|
||||
@ -972,13 +972,13 @@ namespace hex::pl {
|
||||
|
||||
PatternData *outputPattern;
|
||||
if (dynamic_cast<PatternDataPadding *>(templatePattern)) {
|
||||
outputPattern = new PatternDataPadding(startOffset, 0);
|
||||
outputPattern = new PatternDataPadding(evaluator, startOffset, 0);
|
||||
} else if (dynamic_cast<PatternDataCharacter *>(templatePattern)) {
|
||||
outputPattern = new PatternDataString(startOffset, 0);
|
||||
outputPattern = new PatternDataString(evaluator, startOffset, 0);
|
||||
} else if (dynamic_cast<PatternDataCharacter16 *>(templatePattern)) {
|
||||
outputPattern = new PatternDataString16(startOffset, 0);
|
||||
outputPattern = new PatternDataString16(evaluator, startOffset, 0);
|
||||
} else {
|
||||
auto arrayPattern = new PatternDataStaticArray(startOffset, 0);
|
||||
auto arrayPattern = new PatternDataStaticArray(evaluator, startOffset, 0);
|
||||
arrayPattern->setEntries(templatePattern->clone(), entryCount);
|
||||
outputPattern = arrayPattern;
|
||||
}
|
||||
@ -995,7 +995,7 @@ namespace hex::pl {
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
std::vector<PatternData *> entries;
|
||||
@ -1192,7 +1192,7 @@ namespace hex::pl {
|
||||
auto sizePattern = this->m_sizeType->createPatterns(evaluator).front();
|
||||
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);
|
||||
|
||||
auto endOffset = evaluator->dataOffset();
|
||||
@ -1298,7 +1298,7 @@ namespace hex::pl {
|
||||
}
|
||||
|
||||
[[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();
|
||||
std::vector<PatternData *> memberPatterns;
|
||||
@ -1370,7 +1370,7 @@ namespace hex::pl {
|
||||
}
|
||||
|
||||
[[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;
|
||||
std::vector<PatternData *> memberPatterns;
|
||||
@ -1430,7 +1430,7 @@ namespace hex::pl {
|
||||
}
|
||||
|
||||
[[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; };
|
||||
|
||||
|
||||
@ -1487,7 +1487,7 @@ namespace hex::pl {
|
||||
void addEntry(const std::string &name, ASTNode *size) { this->m_entries.emplace_back(name, size); }
|
||||
|
||||
[[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;
|
||||
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 (name != "padding") {
|
||||
auto field = new PatternDataBitfieldField(evaluator->dataOffset(), bitOffset, bitSize, pattern);
|
||||
auto field = new PatternDataBitfieldField(evaluator, evaluator->dataOffset(), bitOffset, bitSize, pattern);
|
||||
field->setVariableName(name);
|
||||
fields.push_back(field);
|
||||
}
|
||||
@ -1627,7 +1627,7 @@ namespace hex::pl {
|
||||
|
||||
std::visit(overloaded {
|
||||
[&](char assignmentValue) { if (assignmentValue != 0x00) value = std::string({ assignmentValue }); },
|
||||
[&](const std::string &assignmentValue) { value = assignmentValue; },
|
||||
[&](std::string assignmentValue) { value = assignmentValue; },
|
||||
[&, this](PatternData *const &assignmentValue) {
|
||||
if (!dynamic_cast<PatternDataString *>(assignmentValue) && !dynamic_cast<PatternDataCharacter *>(assignmentValue))
|
||||
LogConsole::abortEvaluation(hex::format("cannot assign '{}' to string", pattern->getTypeName()), this);
|
||||
|
@ -8,7 +8,7 @@
|
||||
#include <hex/pattern_language/token.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/fmt.hpp>
|
||||
#include <hex/helpers/concepts.hpp>
|
||||
@ -55,47 +55,39 @@ namespace hex::pl {
|
||||
|
||||
class PatternCreationLimiter {
|
||||
public:
|
||||
explicit PatternCreationLimiter() {
|
||||
if (PatternCreationLimiter::s_evaluator == nullptr) return;
|
||||
explicit PatternCreationLimiter(Evaluator *evaluator) : m_evaluator(evaluator) {
|
||||
if (getEvaluator() == nullptr) return;
|
||||
|
||||
PatternCreationLimiter::s_evaluator->patternCreated();
|
||||
getEvaluator()->patternCreated();
|
||||
}
|
||||
|
||||
PatternCreationLimiter(const PatternCreationLimiter &other) {
|
||||
if (PatternCreationLimiter::s_evaluator == nullptr) return;
|
||||
|
||||
PatternCreationLimiter::s_evaluator->patternCreated();
|
||||
}
|
||||
PatternCreationLimiter(const PatternCreationLimiter &other) : PatternCreationLimiter(other.m_evaluator) { }
|
||||
|
||||
virtual ~PatternCreationLimiter() {
|
||||
if (PatternCreationLimiter::s_evaluator == nullptr) return;
|
||||
if (getEvaluator() == nullptr) return;
|
||||
|
||||
PatternCreationLimiter::s_evaluator->patternDestroyed();
|
||||
getEvaluator()->patternDestroyed();
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
static Evaluator *getEvaluator() {
|
||||
return PatternCreationLimiter::s_evaluator;
|
||||
Evaluator* getEvaluator() const {
|
||||
return this->m_evaluator;
|
||||
}
|
||||
|
||||
public:
|
||||
static Evaluator *s_evaluator;
|
||||
private:
|
||||
Evaluator *m_evaluator = nullptr;
|
||||
};
|
||||
|
||||
class PatternData : public PatternCreationLimiter, public Cloneable<PatternData> {
|
||||
public:
|
||||
PatternData(u64 offset, size_t size, u32 color = 0)
|
||||
: PatternCreationLimiter(), m_offset(offset), m_size(size), m_color(color) {
|
||||
PatternData(Evaluator *evaluator, u64 offset, size_t size, u32 color = 0)
|
||||
: PatternCreationLimiter(evaluator), m_offset(offset), m_size(size), m_color(color) {
|
||||
constexpr u32 Palette[] = { 0x70b4771f, 0x700e7fff, 0x702ca02c, 0x702827d6, 0x70bd6794, 0x704b568c, 0x70c277e3, 0x707f7f7f, 0x7022bdbc, 0x70cfbe17 };
|
||||
|
||||
if (color != 0)
|
||||
return;
|
||||
|
||||
this->m_color = Palette[SharedData::patternPaletteOffset++];
|
||||
this->m_color = ContentRegistry::PatternLanguage::getNextColor();
|
||||
this->m_manualColor = false;
|
||||
|
||||
if (SharedData::patternPaletteOffset >= (sizeof(Palette) / sizeof(u32)))
|
||||
SharedData::patternPaletteOffset = 0;
|
||||
}
|
||||
|
||||
PatternData(const PatternData &other) = default;
|
||||
@ -125,8 +117,8 @@ namespace hex::pl {
|
||||
[[nodiscard]] bool hasOverriddenColor() const { return this->m_manualColor; }
|
||||
|
||||
[[nodiscard]] std::endian getEndian() const {
|
||||
if (PatternData::getEvaluator() == nullptr) return std::endian::native;
|
||||
else return this->m_endian.value_or(PatternData::getEvaluator()->getDefaultEndian());
|
||||
if (this->getEvaluator() == nullptr) return std::endian::native;
|
||||
else return this->m_endian.value_or(this->getEvaluator()->getDefaultEndian());
|
||||
}
|
||||
virtual void setEndian(std::endian endian) { this->m_endian = endian; }
|
||||
[[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++)
|
||||
highlight.insert({ this->getOffset() + i, this->getColor() });
|
||||
|
||||
PatternData::getEvaluator()->handleAbort();
|
||||
this->getEvaluator()->handleAbort();
|
||||
}
|
||||
|
||||
virtual void sort(ImGuiTableSortSpecs *sortSpecs, prv::Provider *provider) { }
|
||||
@ -217,8 +209,6 @@ namespace hex::pl {
|
||||
this->createEntry(provider);
|
||||
}
|
||||
|
||||
static void resetPalette() { SharedData::patternPaletteOffset = 0; }
|
||||
|
||||
void setHidden(bool hidden) {
|
||||
this->m_hidden = hidden;
|
||||
}
|
||||
@ -256,7 +246,7 @@ namespace hex::pl {
|
||||
return value;
|
||||
else {
|
||||
try {
|
||||
auto result = this->m_formatterFunction->func(PatternData::getEvaluator(), { literal });
|
||||
auto result = this->m_formatterFunction->func(this->getEvaluator(), { literal });
|
||||
|
||||
if (result.has_value()) {
|
||||
if (auto displayValue = std::get_if<std::string>(&result.value()); displayValue != nullptr)
|
||||
@ -326,7 +316,7 @@ namespace hex::pl {
|
||||
|
||||
class PatternDataPadding : public PatternData {
|
||||
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]]
|
||||
PatternData *clone() const override {
|
||||
@ -345,8 +335,8 @@ namespace hex::pl {
|
||||
|
||||
class PatternDataPointer : public PatternData {
|
||||
public:
|
||||
PatternDataPointer(u64 offset, size_t size, u32 color = 0)
|
||||
: PatternData(offset, size, color), m_pointedAt(nullptr) {
|
||||
PatternDataPointer(Evaluator *evaluator, u64 offset, size_t size, u32 color = 0)
|
||||
: PatternData(evaluator, offset, size, color), m_pointedAt(nullptr) {
|
||||
}
|
||||
|
||||
PatternDataPointer(const PatternDataPointer &other) : PatternData(other) {
|
||||
@ -476,8 +466,8 @@ namespace hex::pl {
|
||||
|
||||
class PatternDataUnsigned : public PatternData {
|
||||
public:
|
||||
PatternDataUnsigned(u64 offset, size_t size, u32 color = 0)
|
||||
: PatternData(offset, size, color) { }
|
||||
PatternDataUnsigned(Evaluator *evaluator, u64 offset, size_t size, u32 color = 0)
|
||||
: PatternData(evaluator, offset, size, color) { }
|
||||
|
||||
[[nodiscard]]
|
||||
PatternData *clone() const override {
|
||||
@ -514,8 +504,8 @@ namespace hex::pl {
|
||||
|
||||
class PatternDataSigned : public PatternData {
|
||||
public:
|
||||
PatternDataSigned(u64 offset, size_t size, u32 color = 0)
|
||||
: PatternData(offset, size, color) { }
|
||||
PatternDataSigned(Evaluator *evaluator, u64 offset, size_t size, u32 color = 0)
|
||||
: PatternData(evaluator, offset, size, color) { }
|
||||
|
||||
[[nodiscard]]
|
||||
PatternData *clone() const override {
|
||||
@ -553,8 +543,8 @@ namespace hex::pl {
|
||||
|
||||
class PatternDataFloat : public PatternData {
|
||||
public:
|
||||
PatternDataFloat(u64 offset, size_t size, u32 color = 0)
|
||||
: PatternData(offset, size, color) { }
|
||||
PatternDataFloat(Evaluator *evaluator, u64 offset, size_t size, u32 color = 0)
|
||||
: PatternData(evaluator, offset, size, color) { }
|
||||
|
||||
[[nodiscard]]
|
||||
PatternData *clone() const override {
|
||||
@ -593,8 +583,8 @@ namespace hex::pl {
|
||||
|
||||
class PatternDataBoolean : public PatternData {
|
||||
public:
|
||||
explicit PatternDataBoolean(u64 offset, u32 color = 0)
|
||||
: PatternData(offset, 1, color) { }
|
||||
explicit PatternDataBoolean(Evaluator *evaluator, u64 offset, u32 color = 0)
|
||||
: PatternData(evaluator, offset, 1, color) { }
|
||||
|
||||
[[nodiscard]]
|
||||
PatternData *clone() const override {
|
||||
@ -622,8 +612,8 @@ namespace hex::pl {
|
||||
|
||||
class PatternDataCharacter : public PatternData {
|
||||
public:
|
||||
explicit PatternDataCharacter(u64 offset, u32 color = 0)
|
||||
: PatternData(offset, 1, color) { }
|
||||
explicit PatternDataCharacter(Evaluator *evaluator, u64 offset, u32 color = 0)
|
||||
: PatternData(evaluator, offset, 1, color) { }
|
||||
|
||||
[[nodiscard]]
|
||||
PatternData *clone() const override {
|
||||
@ -646,8 +636,8 @@ namespace hex::pl {
|
||||
|
||||
class PatternDataCharacter16 : public PatternData {
|
||||
public:
|
||||
explicit PatternDataCharacter16(u64 offset, u32 color = 0)
|
||||
: PatternData(offset, 2, color) { }
|
||||
explicit PatternDataCharacter16(Evaluator *evaluator, u64 offset, u32 color = 0)
|
||||
: PatternData(evaluator, offset, 2, color) { }
|
||||
|
||||
[[nodiscard]]
|
||||
PatternData *clone() const override {
|
||||
@ -680,8 +670,8 @@ namespace hex::pl {
|
||||
|
||||
class PatternDataString : public PatternData {
|
||||
public:
|
||||
PatternDataString(u64 offset, size_t size, u32 color = 0)
|
||||
: PatternData(offset, size, color) { }
|
||||
PatternDataString(Evaluator *evaluator, u64 offset, size_t size, u32 color = 0)
|
||||
: PatternData(evaluator, offset, size, color) { }
|
||||
|
||||
[[nodiscard]]
|
||||
PatternData *clone() const override {
|
||||
@ -721,8 +711,8 @@ namespace hex::pl {
|
||||
|
||||
class PatternDataString16 : public PatternData {
|
||||
public:
|
||||
PatternDataString16(u64 offset, size_t size, u32 color = 0)
|
||||
: PatternData(offset, size, color) { }
|
||||
PatternDataString16(Evaluator *evaluator, u64 offset, size_t size, u32 color = 0)
|
||||
: PatternData(evaluator, offset, size, color) { }
|
||||
|
||||
[[nodiscard]]
|
||||
PatternData *clone() const override {
|
||||
@ -774,8 +764,8 @@ namespace hex::pl {
|
||||
class PatternDataDynamicArray : public PatternData,
|
||||
public Inlinable {
|
||||
public:
|
||||
PatternDataDynamicArray(u64 offset, size_t size, u32 color = 0)
|
||||
: PatternData(offset, size, color) {
|
||||
PatternDataDynamicArray(Evaluator *evaluator, u64 offset, size_t size, u32 color = 0)
|
||||
: PatternData(evaluator, offset, size, color) {
|
||||
}
|
||||
|
||||
PatternDataDynamicArray(const PatternDataDynamicArray &other) : PatternData(other) {
|
||||
@ -931,8 +921,8 @@ namespace hex::pl {
|
||||
class PatternDataStaticArray : public PatternData,
|
||||
public Inlinable {
|
||||
public:
|
||||
PatternDataStaticArray(u64 offset, size_t size, u32 color = 0)
|
||||
: PatternData(offset, size, color) {
|
||||
PatternDataStaticArray(Evaluator *evaluator, u64 offset, size_t size, u32 color = 0)
|
||||
: PatternData(evaluator, offset, size, color) {
|
||||
}
|
||||
|
||||
PatternDataStaticArray(const PatternDataStaticArray &other) : PatternData(other) {
|
||||
@ -1089,8 +1079,8 @@ namespace hex::pl {
|
||||
class PatternDataStruct : public PatternData,
|
||||
public Inlinable {
|
||||
public:
|
||||
PatternDataStruct(u64 offset, size_t size, u32 color = 0)
|
||||
: PatternData(offset, size, color) {
|
||||
PatternDataStruct(Evaluator *evaluator, u64 offset, size_t size, u32 color = 0)
|
||||
: PatternData(evaluator, offset, size, color) {
|
||||
}
|
||||
|
||||
PatternDataStruct(const PatternDataStruct &other) : PatternData(other) {
|
||||
@ -1237,8 +1227,8 @@ namespace hex::pl {
|
||||
class PatternDataUnion : public PatternData,
|
||||
public Inlinable {
|
||||
public:
|
||||
PatternDataUnion(u64 offset, size_t size, u32 color = 0)
|
||||
: PatternData(offset, size, color) {
|
||||
PatternDataUnion(Evaluator *evaluator, u64 offset, size_t size, u32 color = 0)
|
||||
: PatternData(evaluator, offset, size, color) {
|
||||
}
|
||||
|
||||
PatternDataUnion(const PatternDataUnion &other) : PatternData(other) {
|
||||
@ -1386,8 +1376,8 @@ namespace hex::pl {
|
||||
|
||||
class PatternDataEnum : public PatternData {
|
||||
public:
|
||||
PatternDataEnum(u64 offset, size_t size, u32 color = 0)
|
||||
: PatternData(offset, size, color) {
|
||||
PatternDataEnum(Evaluator *evaluator, u64 offset, size_t size, u32 color = 0)
|
||||
: PatternData(evaluator, offset, size, color) {
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
@ -1482,8 +1472,8 @@ namespace hex::pl {
|
||||
|
||||
class PatternDataBitfieldField : public PatternData {
|
||||
public:
|
||||
PatternDataBitfieldField(u64 offset, u8 bitOffset, u8 bitSize, PatternData *bitField, u32 color = 0)
|
||||
: m_bitOffset(bitOffset), m_bitSize(bitSize), m_bitField(bitField), PatternData(offset, 0, color) {
|
||||
PatternDataBitfieldField(Evaluator *evaluator, u64 offset, u8 bitOffset, u8 bitSize, PatternData *bitField, u32 color = 0)
|
||||
: PatternData(evaluator, offset, 0, color), m_bitOffset(bitOffset), m_bitSize(bitSize), m_bitField(bitField) {
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
@ -1552,8 +1542,8 @@ namespace hex::pl {
|
||||
class PatternDataBitfield : public PatternData,
|
||||
public Inlinable {
|
||||
public:
|
||||
PatternDataBitfield(u64 offset, size_t size, u32 color = 0)
|
||||
: PatternData(offset, size, color) {
|
||||
PatternDataBitfield(Evaluator *evaluator, u64 offset, size_t size, u32 color = 0)
|
||||
: PatternData(evaluator, offset, size, color) {
|
||||
}
|
||||
|
||||
PatternDataBitfield(const PatternDataBitfield &other) : PatternData(other) {
|
||||
|
@ -33,8 +33,8 @@ namespace hex::pl {
|
||||
~PatternLanguage();
|
||||
|
||||
[[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]] 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 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 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;
|
||||
|
||||
void abort();
|
||||
@ -49,6 +49,13 @@ namespace hex::pl {
|
||||
[[nodiscard]] bool hasDangerousFunctionBeenCalled() const;
|
||||
void allowDangerousFunctions(bool allow);
|
||||
|
||||
[[nodiscard]] std::vector<PatternData*> &getPatterns() {
|
||||
return this->m_patterns;
|
||||
}
|
||||
|
||||
void reset();
|
||||
bool isRunning() const { return this->m_running; }
|
||||
|
||||
private:
|
||||
Preprocessor *m_preprocessor;
|
||||
Lexer *m_lexer;
|
||||
@ -59,6 +66,10 @@ namespace hex::pl {
|
||||
std::vector<ASTNode *> m_currAST;
|
||||
|
||||
std::optional<PatternLanguageError> m_currError;
|
||||
|
||||
std::vector<PatternData*> m_patterns;
|
||||
|
||||
bool m_running = false;
|
||||
};
|
||||
|
||||
}
|
@ -2,13 +2,14 @@
|
||||
|
||||
#include <hex.hpp>
|
||||
|
||||
#include <list>
|
||||
#include <map>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <hex/helpers/shared_data.hpp>
|
||||
#include <hex/providers/overlay.hpp>
|
||||
#include <hex/pattern_language/pattern_language.hpp>
|
||||
|
||||
namespace hex::prv {
|
||||
|
||||
@ -78,6 +79,9 @@ namespace hex::prv {
|
||||
virtual void drawLoadInterface();
|
||||
virtual void drawInterface();
|
||||
|
||||
pl::PatternLanguage& getPatternLanguageRuntime() { return this->m_patternLanguageRuntime; }
|
||||
std::string& getPatternLanguageSourceCode() { return this->m_patternLanguageSourceCode; }
|
||||
|
||||
protected:
|
||||
u32 m_currPage = 0;
|
||||
u64 m_baseAddress = 0;
|
||||
@ -85,6 +89,9 @@ namespace hex::prv {
|
||||
u32 m_patchTreeOffset = 0;
|
||||
std::list<std::map<u64, u8>> m_patches;
|
||||
std::list<Overlay *> m_overlays;
|
||||
|
||||
pl::PatternLanguage m_patternLanguageRuntime;
|
||||
std::string m_patternLanguageSourceCode;
|
||||
};
|
||||
|
||||
}
|
@ -14,7 +14,7 @@
|
||||
#include <hex/api/event.hpp>
|
||||
#include <hex/providers/provider.hpp>
|
||||
|
||||
#include <hex/helpers/lang.hpp>
|
||||
#include <hex/api/localization.hpp>
|
||||
|
||||
#include <functional>
|
||||
#include <string>
|
||||
@ -23,8 +23,6 @@
|
||||
|
||||
namespace hex {
|
||||
|
||||
using namespace hex::lang_literals;
|
||||
|
||||
class View {
|
||||
public:
|
||||
explicit View(std::string unlocalizedViewName);
|
||||
@ -32,11 +30,8 @@ namespace hex {
|
||||
|
||||
virtual void drawContent() = 0;
|
||||
virtual void drawAlwaysVisible() { }
|
||||
virtual bool isAvailable() const;
|
||||
virtual bool shouldProcess() const { return this->isAvailable() && this->getWindowOpenState(); }
|
||||
|
||||
static void doLater(std::function<void()> &&function);
|
||||
static std::vector<std::function<void()>> &getDeferedCalls();
|
||||
[[nodiscard]] virtual bool isAvailable() const;
|
||||
[[nodiscard]] virtual bool shouldProcess() const { return this->isAvailable() && this->getWindowOpenState(); }
|
||||
|
||||
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);
|
||||
|
||||
virtual bool hasViewMenuItemEntry() const;
|
||||
virtual ImVec2 getMinSize() const;
|
||||
virtual ImVec2 getMaxSize() const;
|
||||
[[nodiscard]] virtual bool hasViewMenuItemEntry() const;
|
||||
[[nodiscard]] virtual ImVec2 getMinSize() const;
|
||||
[[nodiscard]] virtual ImVec2 getMaxSize() const;
|
||||
|
||||
bool &getWindowOpenState();
|
||||
const bool &getWindowOpenState() const;
|
||||
[[nodiscard]] bool &getWindowOpenState();
|
||||
[[nodiscard]] const bool &getWindowOpenState() const;
|
||||
|
||||
[[nodiscard]] const std::string &getUnlocalizedName() const;
|
||||
[[nodiscard]] std::string getName() const;
|
||||
@ -63,11 +58,27 @@ namespace hex {
|
||||
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:
|
||||
std::string m_unlocalizedViewName;
|
||||
bool m_windowOpen = false;
|
||||
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;
|
||||
};
|
||||
|
@ -1,9 +1,10 @@
|
||||
#include <hex/api/content_registry.hpp>
|
||||
|
||||
#include <hex/helpers/shared_data.hpp>
|
||||
#include <hex/helpers/paths.hpp>
|
||||
#include <hex/helpers/logger.hpp>
|
||||
|
||||
#include <hex/ui/view.hpp>
|
||||
|
||||
#include <filesystem>
|
||||
#include <fstream>
|
||||
|
||||
@ -141,7 +142,9 @@ namespace hex {
|
||||
|
||||
|
||||
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) {
|
||||
@ -154,7 +157,9 @@ namespace hex {
|
||||
}
|
||||
|
||||
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() {
|
||||
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() {
|
||||
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() {
|
||||
return SharedData::views;
|
||||
static std::map<std::string, View *> views;
|
||||
|
||||
return views;
|
||||
}
|
||||
|
||||
View *ContentRegistry::Views::getViewByName(const std::string &unlocalizedName) {
|
||||
@ -232,7 +284,9 @@ namespace hex {
|
||||
}
|
||||
|
||||
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() {
|
||||
return SharedData::dataInspectorEntries;
|
||||
static std::vector<ContentRegistry::DataInspector::impl::Entry> entries;
|
||||
|
||||
return entries;
|
||||
}
|
||||
|
||||
/* Data Processor Nodes */
|
||||
@ -261,7 +317,9 @@ namespace hex {
|
||||
}
|
||||
|
||||
std::vector<ContentRegistry::DataProcessorNode::impl::Entry> &ContentRegistry::DataProcessorNode::getEntries() {
|
||||
return SharedData::dataProcessorNodes;
|
||||
static std::vector<ContentRegistry::DataProcessorNode::impl::Entry> nodes;
|
||||
|
||||
return nodes;
|
||||
}
|
||||
|
||||
/* Languages */
|
||||
@ -279,20 +337,20 @@ namespace hex {
|
||||
}
|
||||
|
||||
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() {
|
||||
return SharedData::languageDefinitions;
|
||||
static std::map<std::string, std::vector<LanguageDefinition>> definitions;
|
||||
|
||||
return definitions;
|
||||
}
|
||||
|
||||
|
||||
/* Interface */
|
||||
|
||||
u32 ContentRegistry::Interface::getDockSpaceId() {
|
||||
return SharedData::dockSpaceId;
|
||||
}
|
||||
|
||||
void ContentRegistry::Interface::registerMainMenuItem(const std::string &unlocalizedName, u32 priority) {
|
||||
log::info("Registered new main menu item: {}", unlocalizedName);
|
||||
|
||||
@ -331,27 +389,41 @@ namespace hex {
|
||||
|
||||
|
||||
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() {
|
||||
return SharedData::menuItems;
|
||||
static std::multimap<u32, ContentRegistry::Interface::impl::MenuItem> items;
|
||||
|
||||
return items;
|
||||
}
|
||||
|
||||
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() {
|
||||
return SharedData::footerItems;
|
||||
static std::vector<ContentRegistry::Interface::impl::DrawCallback> items;
|
||||
|
||||
return items;
|
||||
}
|
||||
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() {
|
||||
return SharedData::sidebarItems;
|
||||
static std::vector<ContentRegistry::Interface::impl::SidebarItem> items;
|
||||
|
||||
return items;
|
||||
}
|
||||
|
||||
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) {
|
||||
log::info("Registered new provider: {}", unlocalizedName);
|
||||
|
||||
SharedData::providerNames.push_back(unlocalizedName);
|
||||
getEntries().push_back(unlocalizedName);
|
||||
}
|
||||
|
||||
const std::vector<std::string> &ContentRegistry::Provider::getEntries() {
|
||||
return SharedData::providerNames;
|
||||
std::vector<std::string> &ContentRegistry::Provider::getEntries() {
|
||||
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) {
|
||||
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() {
|
||||
return SharedData::dataFormatters;
|
||||
static std::vector<ContentRegistry::DataFormatter::impl::Entry> entries;
|
||||
|
||||
return entries;
|
||||
}
|
||||
|
||||
|
||||
@ -387,10 +463,12 @@ namespace hex {
|
||||
for (const auto &extension : extensions)
|
||||
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() {
|
||||
return SharedData::fileHandlers;
|
||||
static std::vector<ContentRegistry::FileHandler::impl::Entry> entries;
|
||||
|
||||
return entries;
|
||||
}
|
||||
}
|
@ -1,89 +1,213 @@
|
||||
#include <hex/api/imhex_api.hpp>
|
||||
|
||||
#include <hex/api/event.hpp>
|
||||
#include <hex/helpers/shared_data.hpp>
|
||||
#include <hex/providers/provider.hpp>
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
#include <hex/helpers/logger.hpp>
|
||||
|
||||
namespace hex {
|
||||
|
||||
void ImHexApi::Common::closeImHex(bool noQuestions) {
|
||||
namespace ImHexApi::Common {
|
||||
|
||||
void closeImHex(bool noQuestions) {
|
||||
EventManager::post<RequestCloseImHex>(noQuestions);
|
||||
}
|
||||
|
||||
void ImHexApi::Common::restartImHex() {
|
||||
void restartImHex() {
|
||||
EventManager::post<RequestCloseImHex>(false);
|
||||
std::atexit([] {
|
||||
execve(SharedData::mainArgv[0], SharedData::mainArgv, SharedData::mainEnvp);
|
||||
auto &programArgs = ImHexApi::System::getProgramArguments();
|
||||
execve(programArgs.argv[0], programArgs.argv, programArgs.envp);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
void ImHexApi::Bookmarks::add(Region region, const std::string &name, const std::string &comment, u32 color) {
|
||||
Entry entry;
|
||||
|
||||
entry.region = region;
|
||||
|
||||
entry.name.reserve(name.length());
|
||||
entry.comment.reserve(comment.length());
|
||||
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;
|
||||
|
||||
EventManager::post<RequestAddBookmark>(entry);
|
||||
}
|
||||
|
||||
void ImHexApi::Bookmarks::add(u64 addr, size_t size, const std::string &name, const std::string &comment, u32 color) {
|
||||
Bookmarks::add(Region { addr, size }, name, comment, color);
|
||||
}
|
||||
|
||||
std::list<ImHexApi::Bookmarks::Entry> &ImHexApi::Bookmarks::getEntries() {
|
||||
return SharedData::bookmarkEntries;
|
||||
}
|
||||
|
||||
|
||||
prv::Provider *ImHexApi::Provider::get() {
|
||||
namespace ImHexApi::HexEditor {
|
||||
|
||||
static std::map<u32, ImHexApi::HexEditor::Highlighting> s_highlights;
|
||||
|
||||
Highlighting::Highlighting(Region region, color_t color, const std::string &tooltip)
|
||||
: m_region(region), m_color(color), m_tooltip(tooltip) {
|
||||
}
|
||||
|
||||
u32 addHighlight(const Region ®ion, color_t color, std::string tooltip) {
|
||||
auto id = s_highlights.size();
|
||||
|
||||
s_highlights.insert({ id, Highlighting{ region, color, tooltip } });
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
void removeHighlight(u32 id) {
|
||||
s_highlights.erase(id);
|
||||
}
|
||||
|
||||
std::map<u32, Highlighting> &getHighlights() {
|
||||
return s_highlights;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
namespace ImHexApi::Bookmarks {
|
||||
|
||||
void add(Region region, const std::string &name, const std::string &comment, u32 color) {
|
||||
EventManager::post<RequestAddBookmark>(region, name, comment, color);
|
||||
}
|
||||
|
||||
void add(u64 address, size_t size, const std::string &name, const std::string &comment, u32 color) {
|
||||
add(Region { address, size }, name, comment, color);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
namespace ImHexApi::Provider {
|
||||
|
||||
static u32 s_currentProvider;
|
||||
static std::vector<prv::Provider*> s_providers;
|
||||
|
||||
prv::Provider *get() {
|
||||
if (!ImHexApi::Provider::isValid())
|
||||
return nullptr;
|
||||
|
||||
return SharedData::providers[SharedData::currentProvider];
|
||||
return s_providers[s_currentProvider];
|
||||
}
|
||||
|
||||
const std::vector<prv::Provider *> &ImHexApi::Provider::getProviders() {
|
||||
return SharedData::providers;
|
||||
const std::vector<prv::Provider *> &getProviders() {
|
||||
return s_providers;
|
||||
}
|
||||
|
||||
bool ImHexApi::Provider::isValid() {
|
||||
return !SharedData::providers.empty();
|
||||
void setCurrentProvider(u32 index) {
|
||||
if (index < s_providers.size()) {
|
||||
auto oldProvider = get();
|
||||
s_currentProvider = index;
|
||||
EventManager::post<EventProviderChanged>(oldProvider, get());
|
||||
}
|
||||
}
|
||||
|
||||
void ImHexApi::Provider::add(prv::Provider *provider) {
|
||||
SharedData::providers.push_back(provider);
|
||||
SharedData::currentProvider = SharedData::providers.size() - 1;
|
||||
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 ImHexApi::Provider::remove(prv::Provider *provider) {
|
||||
auto &providers = SharedData::providers;
|
||||
void remove(prv::Provider *provider) {
|
||||
auto it = std::find(s_providers.begin(), s_providers.end(), provider);
|
||||
|
||||
auto it = std::find(providers.begin(), providers.end(), provider);
|
||||
s_providers.erase(it);
|
||||
|
||||
providers.erase(it);
|
||||
|
||||
if (it - providers.begin() == SharedData::currentProvider)
|
||||
SharedData::currentProvider = 0;
|
||||
if (it - s_providers.begin() == s_currentProvider)
|
||||
s_currentProvider = 0;
|
||||
|
||||
delete provider;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Task ImHexApi::Tasks::createTask(const std::string &unlocalizedName, u64 maxValue) {
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,13 +1,14 @@
|
||||
#include <hex/api/keybinding.hpp>
|
||||
#include <hex/helpers/shared_data.hpp>
|
||||
#include <imgui.h>
|
||||
|
||||
#include <hex/views/view.hpp>
|
||||
#include <hex/ui/view.hpp>
|
||||
|
||||
namespace hex {
|
||||
|
||||
std::map<Shortcut, std::function<void()>> ShortcutManager::s_globalShortcuts;
|
||||
|
||||
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) {
|
||||
@ -30,8 +31,12 @@ namespace hex {
|
||||
|
||||
if (focused && currentView->m_shortcuts.contains(pressedShortcut))
|
||||
currentView->m_shortcuts[pressedShortcut]();
|
||||
else if (SharedData::globalShortcuts.contains(pressedShortcut))
|
||||
SharedData::globalShortcuts[pressedShortcut]();
|
||||
else if (ShortcutManager::s_globalShortcuts.contains(pressedShortcut))
|
||||
ShortcutManager::s_globalShortcuts[pressedShortcut]();
|
||||
}
|
||||
|
||||
void ShortcutManager::clearShortcuts() {
|
||||
ShortcutManager::s_globalShortcuts.clear();
|
||||
}
|
||||
|
||||
}
|
@ -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 {
|
||||
|
||||
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) {
|
||||
for (auto pair : entries)
|
||||
@ -60,7 +61,7 @@ namespace hex {
|
||||
}
|
||||
|
||||
const std::string &LangEntry::get() const {
|
||||
auto &lang = SharedData::loadedLanguageStrings;
|
||||
auto &lang = LangEntry::s_currStrings;
|
||||
if (lang.contains(this->m_unlocalizedString))
|
||||
return lang[this->m_unlocalizedString];
|
||||
else
|
||||
@ -68,7 +69,7 @@ namespace hex {
|
||||
}
|
||||
|
||||
void LangEntry::loadLanguage(const std::string &language) {
|
||||
SharedData::loadedLanguageStrings.clear();
|
||||
LangEntry::s_currStrings.clear();
|
||||
|
||||
auto &definitions = ContentRegistry::Language::getLanguageDefinitions();
|
||||
|
||||
@ -76,12 +77,12 @@ namespace hex {
|
||||
return;
|
||||
|
||||
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();
|
||||
if (language != 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;
|
||||
}
|
||||
|
||||
void LangEntry::resetLanguageStrings() {
|
||||
LangEntry::s_currStrings.clear();
|
||||
}
|
||||
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
#include "helpers/plugin_manager.hpp"
|
||||
#include <hex/api/plugin_manager.hpp>
|
||||
|
||||
#include <hex/helpers/logger.hpp>
|
||||
|
||||
@ -23,6 +23,7 @@ namespace hex {
|
||||
this->m_getPluginDescriptionFunction = getPluginFunction<GetPluginDescriptionFunc>("getPluginDescription");
|
||||
this->m_getCompatibleVersionFunction = getPluginFunction<GetCompatibleVersionFunc>("getCompatibleVersion");
|
||||
this->m_setImGuiContextFunction = getPluginFunction<SetImGuiContextFunc>("setImGuiContext");
|
||||
this->m_isBuiltinPluginFunction = getPluginFunction<IsBuiltinPluginFunc>("isBuiltinPlugin");
|
||||
}
|
||||
|
||||
Plugin::Plugin(Plugin &&other) noexcept {
|
||||
@ -35,6 +36,7 @@ namespace hex {
|
||||
this->m_getPluginDescriptionFunction = other.m_getPluginDescriptionFunction;
|
||||
this->m_getCompatibleVersionFunction = other.m_getCompatibleVersionFunction;
|
||||
this->m_setImGuiContextFunction = other.m_setImGuiContextFunction;
|
||||
this->m_isBuiltinPluginFunction = other.m_isBuiltinPluginFunction;
|
||||
|
||||
other.m_handle = nullptr;
|
||||
other.m_initializePluginFunction = nullptr;
|
||||
@ -43,6 +45,7 @@ namespace hex {
|
||||
other.m_getPluginDescriptionFunction = nullptr;
|
||||
other.m_getCompatibleVersionFunction = nullptr;
|
||||
other.m_setImGuiContextFunction = nullptr;
|
||||
other.m_isBuiltinPluginFunction = nullptr;
|
||||
}
|
||||
|
||||
Plugin::~Plugin() {
|
||||
@ -100,6 +103,13 @@ namespace hex {
|
||||
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 {
|
||||
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) {
|
||||
if (!fs::exists(pluginFolder))
|
||||
return false;
|
@ -1,11 +1,16 @@
|
||||
#include <hex/api/task.hpp>
|
||||
|
||||
#include <hex/helpers/shared_data.hpp>
|
||||
#include <hex/api/localization.hpp>
|
||||
|
||||
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) {
|
||||
SharedData::runningTasks.push_back(this);
|
||||
std::scoped_lock lock(Task::s_taskMutex);
|
||||
|
||||
Task::s_runningTasks.push_back(this);
|
||||
}
|
||||
|
||||
Task::~Task() {
|
||||
@ -13,7 +18,9 @@ namespace hex {
|
||||
}
|
||||
|
||||
void Task::finish() {
|
||||
SharedData::runningTasks.remove(this);
|
||||
std::scoped_lock lock(Task::s_taskMutex);
|
||||
|
||||
Task::s_runningTasks.remove(this);
|
||||
}
|
||||
|
||||
void Task::setMaxValue(u64 maxValue) {
|
||||
@ -40,4 +47,10 @@ namespace hex {
|
||||
return this->m_name;
|
||||
}
|
||||
|
||||
size_t Task::getRunningTaskCount() {
|
||||
std::scoped_lock lock(Task::s_taskMutex);
|
||||
|
||||
return Task::s_runningTasks.size();
|
||||
}
|
||||
|
||||
}
|
@ -1,10 +1,11 @@
|
||||
#include <hex/data_processor/attribute.hpp>
|
||||
|
||||
#include <hex/helpers/shared_data.hpp>
|
||||
|
||||
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() {
|
||||
|
@ -1,10 +1,11 @@
|
||||
#include <hex/data_processor/link.hpp>
|
||||
|
||||
#include <hex/helpers/shared_data.hpp>
|
||||
|
||||
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) { }
|
||||
|
||||
|
||||
}
|
@ -1,12 +1,15 @@
|
||||
#include <hex/data_processor/node.hpp>
|
||||
|
||||
#include <hex/helpers/shared_data.hpp>
|
||||
|
||||
#include <hex/helpers/fmt.hpp>
|
||||
|
||||
#include <hex/api/localization.hpp>
|
||||
#include <hex/providers/provider.hpp>
|
||||
|
||||
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)
|
||||
attr.setParentNode(this);
|
||||
}
|
||||
|
@ -3,7 +3,7 @@
|
||||
#include <hex/helpers/utils.hpp>
|
||||
#include <hex/helpers/paths.hpp>
|
||||
#include <hex/helpers/file.hpp>
|
||||
#include <hex/views/view.hpp>
|
||||
#include <hex/ui/view.hpp>
|
||||
#include <hex/providers/provider.hpp>
|
||||
|
||||
#define PY_SSIZE_T_CLEAN
|
||||
@ -179,7 +179,7 @@ namespace hex {
|
||||
}
|
||||
|
||||
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)) {
|
||||
if (fs::exists(fs::path(dir / "lib" / "python" PYTHON_VERSION_MAJOR_MINOR))) {
|
||||
|
@ -64,7 +64,7 @@ namespace hex {
|
||||
for (auto &element : projectFileData["bookmarks"].items()) {
|
||||
ImHexApi::Bookmarks::Entry entry;
|
||||
from_json(element.value(), entry);
|
||||
ProjectFile::s_bookmarks.push_back(entry);
|
||||
ProjectFile::s_bookmarks.emplace_back(std::move(entry));
|
||||
}
|
||||
|
||||
} catch (json::exception &e) {
|
||||
|
@ -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;
|
||||
}
|
@ -5,8 +5,13 @@
|
||||
#include <locale>
|
||||
#include <filesystem>
|
||||
|
||||
#include <hex/api/imhex_api.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)
|
||||
#include <windows.h>
|
||||
@ -20,15 +25,15 @@
|
||||
namespace hex {
|
||||
|
||||
long double operator""_scaled(long double value) {
|
||||
return value * SharedData::globalScale;
|
||||
return value * ImHexApi::System::getGlobalScale();
|
||||
}
|
||||
|
||||
long double operator""_scaled(unsigned long long value) {
|
||||
return value * SharedData::globalScale;
|
||||
return value * ImHexApi::System::getGlobalScale();
|
||||
}
|
||||
|
||||
ImVec2 scaled(const ImVec2 &vector) {
|
||||
return vector * SharedData::globalScale;
|
||||
return vector * ImHexApi::System::getGlobalScale();
|
||||
}
|
||||
|
||||
std::string to_string(u128 value) {
|
||||
|
@ -4,8 +4,6 @@
|
||||
|
||||
namespace hex::pl {
|
||||
|
||||
Evaluator *PatternCreationLimiter::s_evaluator = nullptr;
|
||||
|
||||
void Evaluator::createParameterPack(const std::string &name, const std::vector<Token::Literal> &values) {
|
||||
this->getScope(0).parameterPack = ParameterPack {
|
||||
name,
|
||||
@ -31,19 +29,19 @@ namespace hex::pl {
|
||||
LogConsole::abortEvaluation("cannot determine type of auto variable", type);
|
||||
|
||||
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)
|
||||
pattern = new PatternDataSigned(0, sizeof(i128));
|
||||
pattern = new PatternDataSigned(this, 0, sizeof(i128));
|
||||
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)
|
||||
pattern = new PatternDataBoolean(0);
|
||||
pattern = new PatternDataBoolean(this, 0);
|
||||
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)
|
||||
pattern = std::get<PatternData *>(value.value())->clone();
|
||||
else if (std::get_if<std::string>(&value.value()) != nullptr)
|
||||
pattern = new PatternDataString(0, 1);
|
||||
pattern = new PatternDataString(this, 0, 1);
|
||||
else
|
||||
LogConsole::abortEvaluation("cannot determine type of auto variable", type);
|
||||
}
|
||||
@ -154,8 +152,6 @@ namespace hex::pl {
|
||||
|
||||
std::vector<PatternData *> patterns;
|
||||
|
||||
PatternCreationLimiter::s_evaluator = this;
|
||||
|
||||
try {
|
||||
this->setCurrentControlFlowStatement(ControlFlowStatement::None);
|
||||
pushScope(nullptr, patterns);
|
||||
|
@ -663,10 +663,18 @@ namespace hex::pl {
|
||||
if (!MATCHES(sequence(SEPARATOR_COMMA)))
|
||||
throwParserError("expected ',' after for loop condition");
|
||||
|
||||
if (!MATCHES(sequence(IDENTIFIER, OPERATOR_ASSIGNMENT)))
|
||||
throwParserError("expected for loop variable assignment");
|
||||
ASTNode *postExpression = nullptr;
|
||||
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; };
|
||||
|
||||
std::vector<ASTNode *> body;
|
||||
|
@ -123,7 +123,10 @@ namespace hex::pl {
|
||||
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_evaluator->getConsole().clear();
|
||||
this->m_evaluator->setProvider(provider);
|
||||
@ -143,20 +146,22 @@ namespace hex::pl {
|
||||
|
||||
auto ast = this->parseString(code);
|
||||
if (!ast)
|
||||
return std::nullopt;
|
||||
return false;
|
||||
|
||||
this->m_currAST = ast.value();
|
||||
|
||||
auto patterns = this->m_evaluator->evaluate(ast.value());
|
||||
if (!patterns.has_value()) {
|
||||
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);
|
||||
|
||||
return this->executeString(provider, file.readString(), envVars, inVariables);
|
||||
@ -200,4 +205,12 @@ namespace hex::pl {
|
||||
return this->m_evaluator->hasDangerousFunctionBeenCalled();
|
||||
}
|
||||
|
||||
void PatternLanguage::reset() {
|
||||
for (auto &pattern : this->m_patterns)
|
||||
delete pattern;
|
||||
this->m_patterns.clear();
|
||||
|
||||
this->m_currAST.clear();
|
||||
}
|
||||
|
||||
}
|
@ -2,6 +2,7 @@
|
||||
|
||||
#include <hex.hpp>
|
||||
#include <hex/api/event.hpp>
|
||||
#include <hex/pattern_language/pattern_data.hpp>
|
||||
|
||||
#include <cmath>
|
||||
#include <cstring>
|
||||
|
@ -1,4 +1,4 @@
|
||||
#include <hex/views/view.hpp>
|
||||
#include <hex/ui/view.hpp>
|
||||
|
||||
#include <imgui.h>
|
||||
|
||||
@ -6,48 +6,54 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <hex/helpers/shared_data.hpp>
|
||||
|
||||
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) { }
|
||||
|
||||
bool View::isAvailable() const {
|
||||
return ImHexApi::Provider::isValid() && ImHexApi::Provider::get()->isAvailable();
|
||||
}
|
||||
|
||||
std::vector<std::function<void()>> &View::getDeferedCalls() {
|
||||
return SharedData::deferredCalls;
|
||||
}
|
||||
|
||||
void View::drawCommonInterfaces() {
|
||||
auto windowSize = ImHexApi::System::getMainWindowSize();
|
||||
|
||||
ImGui::SetNextWindowSizeConstraints(scaled(ImVec2(400, 100)), scaled(ImVec2(600, 300)));
|
||||
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::Separator();
|
||||
if (ImGui::Button("hex.common.okay"_lang) || ImGui::IsKeyDown(ImGuiKey_Escape))
|
||||
ImGui::CloseCurrentPopup();
|
||||
|
||||
ImGui::SetWindowPos((SharedData::windowSize - ImGui::GetWindowSize()) / 2, ImGuiCond_Appearing);
|
||||
ImGui::SetWindowPos((windowSize - ImGui::GetWindowSize()) / 2, ImGuiCond_Appearing);
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
|
||||
ImGui::SetNextWindowSizeConstraints(scaled(ImVec2(400, 100)), scaled(ImVec2(600, 300)));
|
||||
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::Separator();
|
||||
if (ImGui::Button("hex.common.okay"_lang) || ImGui::IsKeyDown(ImGuiKey_Escape))
|
||||
ImGui::CloseCurrentPopup();
|
||||
|
||||
ImGui::SetWindowPos((SharedData::windowSize - ImGui::GetWindowSize()) / 2, ImGuiCond_Appearing);
|
||||
ImGui::SetWindowPos((windowSize - ImGui::GetWindowSize()) / 2, ImGuiCond_Appearing);
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
|
||||
ImGui::SetNextWindowSizeConstraints(scaled(ImVec2(400, 100)), scaled(ImVec2(600, 300)));
|
||||
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::Separator();
|
||||
if (ImGui::Button("hex.common.okay"_lang) || ImGui::IsKeyDown(ImGuiKey_Escape)) {
|
||||
@ -55,7 +61,7 @@ namespace hex {
|
||||
ImGui::CloseCurrentPopup();
|
||||
}
|
||||
|
||||
ImGui::SetWindowPos((SharedData::windowSize - ImGui::GetWindowSize()) / 2, ImGuiCond_Appearing);
|
||||
ImGui::SetWindowPos((windowSize - ImGui::GetWindowSize()) / 2, ImGuiCond_Appearing);
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
|
||||
@ -66,9 +72,9 @@ namespace hex {
|
||||
if (ImGui::BeginListBox("##files", ImVec2(300_scaled, 0))) {
|
||||
|
||||
u32 index = 0;
|
||||
for (auto &path : SharedData::selectableFiles) {
|
||||
if (ImGui::Selectable(path.filename().string().c_str(), index == SharedData::selectableFileIndex))
|
||||
SharedData::selectableFileIndex = index;
|
||||
for (auto &path : View::s_selectableFiles) {
|
||||
if (ImGui::Selectable(path.filename().string().c_str(), index == View::s_selectableFileIndex))
|
||||
View::s_selectableFileIndex = index;
|
||||
index++;
|
||||
}
|
||||
|
||||
@ -76,15 +82,15 @@ namespace hex {
|
||||
}
|
||||
|
||||
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::SameLine();
|
||||
|
||||
if (ImGui::Button("hex.common.browse"_lang)) {
|
||||
hex::openFileBrowser("hex.common.open"_lang, DialogMode::Open, SharedData::selectableFilesValidExtensions, [](const auto &path) {
|
||||
SharedData::selectableFileOpenCallback(path);
|
||||
hex::openFileBrowser("hex.common.open"_lang, DialogMode::Open, View::s_selectableFilesValidExtensions, [](const auto &path) {
|
||||
View::s_selectableFileOpenCallback(path);
|
||||
ImGui::CloseCurrentPopup();
|
||||
});
|
||||
}
|
||||
@ -94,30 +100,30 @@ namespace hex {
|
||||
}
|
||||
|
||||
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) {
|
||||
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) {
|
||||
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) {
|
||||
SharedData::selectableFileIndex = 0;
|
||||
SharedData::selectableFiles = paths;
|
||||
SharedData::selectableFilesValidExtensions = validExtensions;
|
||||
SharedData::selectableFileOpenCallback = callback;
|
||||
View::s_selectableFileIndex = 0;
|
||||
View::s_selectableFiles = paths;
|
||||
View::s_selectableFilesValidExtensions = validExtensions;
|
||||
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 {
|
||||
@ -154,10 +160,6 @@ namespace hex {
|
||||
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) {
|
||||
auto width = ImGui::GetWindowWidth();
|
||||
ImGui::SetCursorPosX(width / 9);
|
@ -11,8 +11,6 @@ add_executable(main ${application_type}
|
||||
source/init/splash_window.cpp
|
||||
source/init/tasks.cpp
|
||||
|
||||
source/helpers/plugin_manager.cpp
|
||||
|
||||
${IMHEX_ICON}
|
||||
)
|
||||
|
||||
@ -25,7 +23,7 @@ set_target_properties(main PROPERTIES
|
||||
POSITION_INDEPENDENT_CODE ON)
|
||||
|
||||
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 ()
|
||||
target_link_libraries(main PUBLIC dl libimhex pthread)
|
||||
target_link_libraries(main PUBLIC libimhex pthread)
|
||||
endif ()
|
@ -11,12 +11,6 @@ namespace hex::init {
|
||||
std::function<bool()> function;
|
||||
};
|
||||
|
||||
struct Argument {
|
||||
std::string name, value;
|
||||
};
|
||||
|
||||
std::vector<Task> getInitTasks();
|
||||
std::vector<Task> getExitTasks();
|
||||
|
||||
std::vector<Argument> &getInitArguments();
|
||||
}
|
@ -6,7 +6,7 @@
|
||||
#include <list>
|
||||
#include <vector>
|
||||
|
||||
#include <hex/views/view.hpp>
|
||||
#include <hex/ui/view.hpp>
|
||||
|
||||
struct GLFWwindow;
|
||||
struct ImGuiSettingsHandler;
|
||||
@ -47,7 +47,6 @@ namespace hex {
|
||||
|
||||
GLFWwindow *m_window = nullptr;
|
||||
|
||||
double m_targetFps = 60.0;
|
||||
bool m_layoutConfigured = false;
|
||||
|
||||
std::string m_windowTitle;
|
||||
|
@ -1,9 +1,9 @@
|
||||
#include "init/splash_window.hpp"
|
||||
|
||||
#include <hex/api/imhex_api.hpp>
|
||||
#include <hex/helpers/utils.hpp>
|
||||
#include <hex/helpers/fmt.hpp>
|
||||
#include <hex/helpers/logger.hpp>
|
||||
#include <hex/helpers/shared_data.hpp>
|
||||
|
||||
#include <romfs/romfs.hpp>
|
||||
|
||||
@ -80,7 +80,7 @@ namespace hex::init {
|
||||
|
||||
auto tasksSucceeded = processTasksAsync();
|
||||
|
||||
auto scale = SharedData::globalScale;
|
||||
auto scale = ImHexApi::System::getGlobalScale();
|
||||
|
||||
while (!glfwWindowShouldClose(this->m_window)) {
|
||||
glfwPollEvents();
|
||||
@ -168,18 +168,20 @@ namespace hex::init {
|
||||
float xScale = 0, yScale = 0;
|
||||
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
|
||||
// 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.
|
||||
#if defined(OS_MACOS)
|
||||
SharedData::globalScale /= 2;
|
||||
#endif
|
||||
// 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
|
||||
// extremely huge with native scaling on MacOS.
|
||||
#if defined(OS_MACOS)
|
||||
meanScale /= 2;
|
||||
#endif
|
||||
|
||||
if (SharedData::globalScale <= 0) {
|
||||
SharedData::globalScale = 1.0;
|
||||
if (meanScale <= 0) {
|
||||
meanScale = 1.0;
|
||||
}
|
||||
|
||||
ImHexApi::System::impl::setGlobalScale(meanScale);
|
||||
}
|
||||
|
||||
this->m_window = glfwCreateWindow(640_scaled, 400_scaled, "Starting ImHex...", nullptr, nullptr);
|
||||
@ -204,7 +206,7 @@ namespace hex::init {
|
||||
|
||||
auto &io = ImGui::GetIO();
|
||||
|
||||
ImGui::GetStyle().ScaleAllSizes(SharedData::globalScale);
|
||||
ImGui::GetStyle().ScaleAllSizes(ImHexApi::System::getGlobalScale());
|
||||
|
||||
io.Fonts->Clear();
|
||||
|
||||
|
@ -12,7 +12,7 @@
|
||||
#include <codicons_font.h>
|
||||
#include <unifont_font.h>
|
||||
|
||||
#include "helpers/plugin_manager.hpp"
|
||||
#include <hex/api/plugin_manager.hpp>
|
||||
|
||||
#include <filesystem>
|
||||
|
||||
@ -37,7 +37,7 @@ namespace hex::init {
|
||||
auto latestVersion = releases.body["tag_name"].get<std::string_view>();
|
||||
|
||||
if (latestVersion != currVersion)
|
||||
getInitArguments().push_back({ "update-available", latestVersion.data() });
|
||||
ImHexApi::System::getInitArguments().insert({ "update-available", latestVersion.data() });
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -49,7 +49,7 @@ namespace hex::init {
|
||||
if (tip.code != 200)
|
||||
return false;
|
||||
|
||||
getInitArguments().push_back({ "tip-of-the-day", tip.body });
|
||||
ImHexApi::System::getInitArguments().insert({ "tip-of-the-day", tip.body });
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -83,17 +83,14 @@ namespace hex::init {
|
||||
}
|
||||
|
||||
if (!result)
|
||||
getInitArguments().push_back({ "folder-creation-error", {} });
|
||||
ImHexApi::System::getInitArguments().insert({ "folder-creation-error", {} });
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool loadFonts() {
|
||||
auto &fonts = SharedData::fontAtlas;
|
||||
auto &cfg = SharedData::fontConfig;
|
||||
|
||||
fonts = IM_NEW(ImFontAtlas)();
|
||||
cfg = {};
|
||||
auto fonts = IM_NEW(ImFontAtlas)();
|
||||
ImFontConfig cfg = {};
|
||||
|
||||
fs::path fontFile;
|
||||
for (const auto &dir : hex::getPath(ImHexPath::Resources)) {
|
||||
@ -131,84 +128,79 @@ namespace hex::init {
|
||||
0x0020, 0xFFF0, 0
|
||||
};
|
||||
|
||||
|
||||
float fontSize = 13.0F * ImHexApi::System::getGlobalScale();
|
||||
if (fontFile.empty()) {
|
||||
// Load default font
|
||||
|
||||
fonts->Clear();
|
||||
|
||||
cfg.OversampleH = cfg.OversampleV = 1, cfg.PixelSnapH = true;
|
||||
cfg.SizePixels = 13.0F * SharedData::fontScale;
|
||||
cfg.SizePixels = fontSize;
|
||||
fonts->AddFontDefault(&cfg);
|
||||
} else {
|
||||
// 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.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;
|
||||
|
||||
fonts->AddFontFromMemoryCompressedTTF(font_awesome_compressed_data, font_awesome_compressed_size, 13.0F * SharedData::fontScale, &cfg, fontAwesomeRange);
|
||||
fonts->AddFontFromMemoryCompressedTTF(codicons_compressed_data, codicons_compressed_size, 13.0F * SharedData::fontScale, &cfg, codiconsRange);
|
||||
fonts->AddFontFromMemoryCompressedTTF(unifont_compressed_data, unifont_compressed_size, 13.0F * SharedData::fontScale, &cfg, unifontRange);
|
||||
fonts->AddFontFromMemoryCompressedTTF(font_awesome_compressed_data, font_awesome_compressed_size, fontSize, &cfg, fontAwesomeRange);
|
||||
fonts->AddFontFromMemoryCompressedTTF(codicons_compressed_data, codicons_compressed_size, fontSize, &cfg, codiconsRange);
|
||||
fonts->AddFontFromMemoryCompressedTTF(unifont_compressed_data, unifont_compressed_size, fontSize, &cfg, unifontRange);
|
||||
|
||||
ImGuiFreeType::BuildFontAtlas(fonts);
|
||||
|
||||
View::setFontAtlas(fonts);
|
||||
View::setFontConfig(cfg);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool deleteSharedData() {
|
||||
SharedData::deferredCalls.clear();
|
||||
ImHexApi::Tasks::getDeferredCalls().clear();
|
||||
|
||||
while (ImHexApi::Provider::isValid())
|
||||
ImHexApi::Provider::remove(ImHexApi::Provider::get());
|
||||
ContentRegistry::Provider::getEntries().clear();
|
||||
|
||||
SharedData::settingsEntries.clear();
|
||||
SharedData::settingsJson.clear();
|
||||
ContentRegistry::Settings::getEntries().clear();
|
||||
ContentRegistry::Settings::getSettingsData().clear();
|
||||
|
||||
SharedData::commandPaletteCommands.clear();
|
||||
SharedData::patternLanguageFunctions.clear();
|
||||
ContentRegistry::CommandPaletteCommands::getEntries().clear();
|
||||
ContentRegistry::PatternLanguage::getFunctions().clear();
|
||||
ContentRegistry::PatternLanguage::getPalettes().clear();
|
||||
|
||||
for (auto &[name, view] : ContentRegistry::Views::getEntries())
|
||||
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)
|
||||
delete pattern;
|
||||
SharedData::patternData.clear();
|
||||
ShortcutManager::clearShortcuts();
|
||||
|
||||
SharedData::languageNames.clear();
|
||||
SharedData::languageDefinitions.clear();
|
||||
SharedData::loadedLanguageStrings.clear();
|
||||
hex::Task::getRunningTasks().clear();
|
||||
|
||||
SharedData::welcomeScreenEntries.clear();
|
||||
SharedData::footerItems.clear();
|
||||
SharedData::toolbarItems.clear();
|
||||
SharedData::mainMenuItems.clear();
|
||||
SharedData::menuItems.clear();
|
||||
ContentRegistry::DataProcessorNode::getEntries().clear();
|
||||
|
||||
SharedData::globalShortcuts.clear();
|
||||
SharedData::runningTasks.clear();
|
||||
|
||||
SharedData::dataProcessorNodes.clear();
|
||||
|
||||
SharedData::recentFilePaths.clear();
|
||||
|
||||
SharedData::dataFormatters.clear();
|
||||
SharedData::fileHandlers.clear();
|
||||
|
||||
SharedData::clearVariables();
|
||||
ContentRegistry::DataFormatter::getEntries().clear();
|
||||
ContentRegistry::FileHandler::getEntries().clear();
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -218,16 +210,41 @@ namespace hex::init {
|
||||
PluginManager::load(dir);
|
||||
}
|
||||
|
||||
if (PluginManager::getPlugins().empty()) {
|
||||
auto &plugins = PluginManager::getPlugins();
|
||||
|
||||
if (plugins.empty()) {
|
||||
log::error("No plugins found!");
|
||||
|
||||
getInitArguments().push_back({ "no-plugins", {} });
|
||||
ImHexApi::System::getInitArguments().insert({ "no-plugins", {} });
|
||||
return false;
|
||||
}
|
||||
|
||||
for (const auto &plugin : PluginManager::getPlugins()) {
|
||||
if (!plugin.initializePlugin())
|
||||
u32 builtinPlugins = 0;
|
||||
u32 loadErrors = 0;
|
||||
for (const auto &plugin : plugins) {
|
||||
if (!plugin.initializePlugin()) {
|
||||
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;
|
||||
@ -247,25 +264,28 @@ namespace hex::init {
|
||||
return false;
|
||||
}
|
||||
|
||||
float interfaceScaling = 1.0F;
|
||||
switch (ContentRegistry::Settings::read("hex.builtin.setting.interface", "hex.builtin.setting.interface.scaling", 0)) {
|
||||
default:
|
||||
case 0:
|
||||
// Native scaling
|
||||
break;
|
||||
case 1:
|
||||
SharedData::globalScale = SharedData::fontScale = 0.5F;
|
||||
interfaceScaling = 0.5F;
|
||||
break;
|
||||
case 2:
|
||||
SharedData::globalScale = SharedData::fontScale = 1.0F;
|
||||
interfaceScaling = 1.0F;
|
||||
break;
|
||||
case 3:
|
||||
SharedData::globalScale = SharedData::fontScale = 1.5F;
|
||||
interfaceScaling = 1.5F;
|
||||
break;
|
||||
case 4:
|
||||
SharedData::globalScale = SharedData::fontScale = 2.0F;
|
||||
interfaceScaling = 2.0F;
|
||||
break;
|
||||
}
|
||||
|
||||
ImHexApi::System::impl::setGlobalScale(interfaceScaling);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -281,7 +301,7 @@ namespace hex::init {
|
||||
|
||||
std::vector<Task> getInitTasks() {
|
||||
return {
|
||||
{"Checking for updates...", checkForUpdates },
|
||||
{ "Checking for updates...", checkForUpdates },
|
||||
{ "Downloading information...", downloadInformation},
|
||||
{ "Creating directories...", createDirectories },
|
||||
{ "Loading settings...", loadSettings },
|
||||
@ -292,16 +312,10 @@ namespace hex::init {
|
||||
|
||||
std::vector<Task> getExitTasks() {
|
||||
return {
|
||||
{"Saving settings...", storeSettings },
|
||||
{ "Cleaning up shared data...", deleteSharedData},
|
||||
{ "Saving settings...", storeSettings },
|
||||
{ "Cleaning up shared data...", deleteSharedData },
|
||||
{ "Unloading plugins...", unloadPlugins },
|
||||
};
|
||||
}
|
||||
|
||||
std::vector<Argument> &getInitArguments() {
|
||||
static std::vector<Argument> initArguments;
|
||||
|
||||
return initArguments;
|
||||
}
|
||||
|
||||
}
|
@ -2,7 +2,6 @@
|
||||
|
||||
#include <hex/helpers/utils.hpp>
|
||||
#include <hex/helpers/logger.hpp>
|
||||
#include <hex/helpers/shared_data.hpp>
|
||||
|
||||
#include "window.hpp"
|
||||
|
||||
@ -12,11 +11,8 @@
|
||||
#include <hex/helpers/file.hpp>
|
||||
|
||||
int main(int argc, char **argv, char **envp) {
|
||||
hex::SharedData::mainArgc = argc;
|
||||
hex::SharedData::mainArgv = argv;
|
||||
hex::SharedData::mainEnvp = envp;
|
||||
|
||||
using namespace hex;
|
||||
ImHexApi::System::impl::setProgramArguments(argc, argv, envp);
|
||||
|
||||
// Initialization
|
||||
{
|
||||
@ -30,7 +26,7 @@ int main(int argc, char **argv, char **envp) {
|
||||
splashWindow.addStartupTask(name, task);
|
||||
|
||||
if (!splashWindow.loop())
|
||||
init::getInitArguments().push_back({ "tasks-failed", {} });
|
||||
ImHexApi::System::getInitArguments().insert({ "tasks-failed", {} });
|
||||
}
|
||||
|
||||
// Clean up
|
||||
|
@ -2,6 +2,9 @@
|
||||
|
||||
#if defined(OS_LINUX)
|
||||
|
||||
#include <hex/api/content_registry.hpp>
|
||||
#include <hex/api/event.hpp>
|
||||
|
||||
#include <hex/helpers/utils.hpp>
|
||||
#include <hex/helpers/logger.hpp>
|
||||
|
||||
|
@ -2,6 +2,9 @@
|
||||
|
||||
#if defined(OS_MACOS)
|
||||
|
||||
#include <hex/api/content_registry.hpp>
|
||||
#include <hex/api/event.hpp>
|
||||
|
||||
#include <hex/helpers/logger.hpp>
|
||||
|
||||
#include <nlohmann/json.hpp>
|
||||
|
@ -1,5 +1,6 @@
|
||||
#include "window.hpp"
|
||||
|
||||
#include <hex/api/content_registry.hpp>
|
||||
|
||||
#if defined(OS_WINDOWS)
|
||||
|
||||
@ -89,8 +90,8 @@ namespace hex {
|
||||
POINT cursor = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) };
|
||||
|
||||
const POINT border {
|
||||
static_cast<LONG>((::GetSystemMetrics(SM_CXFRAME) + ::GetSystemMetrics(SM_CXPADDEDBORDER)) * SharedData::globalScale / 1.5F),
|
||||
static_cast<LONG>((::GetSystemMetrics(SM_CYFRAME) + ::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)) * ImHexApi::System::getGlobalScale() / 1.5F)
|
||||
};
|
||||
|
||||
RECT window;
|
||||
@ -205,8 +206,10 @@ namespace hex {
|
||||
if (!globalMutex) {
|
||||
globalMutex = CreateMutex(nullptr, FALSE, UniqueMutexId);
|
||||
} else {
|
||||
if (SharedData::mainArgc > 1) {
|
||||
if (ImHexApi::System::getProgramArguments().argc > 1) {
|
||||
::EnumWindows([](HWND hWnd, LPARAM lparam) -> BOOL {
|
||||
auto &programArgs = ImHexApi::System::getProgramArguments();
|
||||
|
||||
auto length = ::GetWindowTextLength(hWnd);
|
||||
std::string windowName(length + 1, '\x00');
|
||||
::GetWindowText(hWnd, windowName.data(), windowName.size());
|
||||
@ -215,8 +218,8 @@ namespace hex {
|
||||
if (windowName.starts_with("ImHex")) {
|
||||
COPYDATASTRUCT message = {
|
||||
.dwData = 0,
|
||||
.cbData = static_cast<DWORD>(std::strlen(SharedData::mainArgv[1])) + 1,
|
||||
.lpData = SharedData::mainArgv[1]
|
||||
.cbData = static_cast<DWORD>(std::strlen(programArgs.argv[1])) + 1,
|
||||
.lpData = programArgs.argv[1]
|
||||
};
|
||||
|
||||
SendMessage(hWnd, WM_COPYDATA, reinterpret_cast<WPARAM>(hWnd), reinterpret_cast<LPARAM>(&message));
|
||||
|
@ -2,6 +2,10 @@
|
||||
|
||||
#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/paths.hpp>
|
||||
#include <hex/helpers/logger.hpp>
|
||||
@ -33,7 +37,6 @@
|
||||
#include <codicons_font.h>
|
||||
#include <unifont_font.h>
|
||||
|
||||
#include "helpers/plugin_manager.hpp"
|
||||
#include <hex/helpers/project_file_handler.hpp>
|
||||
#include "init/tasks.hpp"
|
||||
|
||||
@ -70,17 +73,9 @@ namespace hex {
|
||||
|
||||
Window::Window() {
|
||||
{
|
||||
for (const auto &[argument, value] : init::getInitArguments()) {
|
||||
if (argument == "update-available") {
|
||||
this->m_availableUpdate = value;
|
||||
} 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); });
|
||||
for (const auto &[argument, value] : ImHexApi::System::getInitArguments()) {
|
||||
if (argument == "no-plugins") {
|
||||
ImHexApi::Tasks::doLater([] { ImGui::OpenPopup("No Plugins"); });
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -89,127 +84,6 @@ namespace hex {
|
||||
this->initImGui();
|
||||
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) {
|
||||
glfwSetWindowShouldClose(this->m_window, true);
|
||||
|
||||
@ -217,6 +91,10 @@ namespace hex {
|
||||
EventManager::post<EventWindowClosing>(this->m_window);
|
||||
});
|
||||
|
||||
EventManager::subscribe<EventFileUnloaded>(this, [] {
|
||||
EventManager::post<RequestChangeWindowTitle>("");
|
||||
});
|
||||
|
||||
EventManager::subscribe<RequestChangeWindowTitle>(this, [this](std::string windowTitle) {
|
||||
std::string title = "ImHex";
|
||||
|
||||
@ -248,17 +126,6 @@ namespace hex {
|
||||
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) {
|
||||
EventManager::post<EventAbnormalTermination>(signalNumber);
|
||||
|
||||
@ -269,11 +136,11 @@ namespace hex {
|
||||
// Let's not loop on this...
|
||||
std::signal(signalNumber, nullptr);
|
||||
|
||||
#if defined(DEBUG)
|
||||
#if defined(DEBUG)
|
||||
assert(false);
|
||||
#else
|
||||
#else
|
||||
std::raise(signalNumber);
|
||||
#endif
|
||||
#endif
|
||||
};
|
||||
|
||||
std::signal(SIGTERM, signalHandler);
|
||||
@ -294,17 +161,11 @@ namespace hex {
|
||||
this->exitImGui();
|
||||
this->exitGLFW();
|
||||
|
||||
EventManager::unsubscribe<EventSettingsChanged>(this);
|
||||
EventManager::unsubscribe<EventFileLoaded>(this);
|
||||
EventManager::unsubscribe<EventFileUnloaded>(this);
|
||||
EventManager::unsubscribe<RequestCloseImHex>(this);
|
||||
EventManager::unsubscribe<RequestChangeWindowTitle>(this);
|
||||
EventManager::unsubscribe<EventAbnormalTermination>(this);
|
||||
EventManager::unsubscribe<RequestChangeTheme>(this);
|
||||
EventManager::unsubscribe<RequestOpenPopup>(this);
|
||||
|
||||
ImGui::UnloadImage(this->m_bannerTexture);
|
||||
ImGui::UnloadImage(this->m_logoTexture);
|
||||
}
|
||||
|
||||
void Window::loop() {
|
||||
@ -316,7 +177,7 @@ namespace hex {
|
||||
} else {
|
||||
double timeout = (1.0 / 5.0) - (glfwGetTime() - this->m_lastFrameTime);
|
||||
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);
|
||||
|
||||
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));
|
||||
|
||||
@ -461,23 +323,6 @@ namespace hex {
|
||||
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();
|
||||
|
||||
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::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));
|
||||
if (ImGui::BeginPopupModal("No Plugins", nullptr, ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoMove)) {
|
||||
ImGui::TextUnformatted("No ImHex plugins loaded (including the built-in plugin)!");
|
||||
@ -516,34 +339,6 @@ namespace hex {
|
||||
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) {
|
||||
if (ImGui::IsPopupOpen(name.c_str()))
|
||||
return true;
|
||||
@ -557,9 +352,12 @@ namespace hex {
|
||||
}
|
||||
|
||||
void Window::frame() {
|
||||
for (const auto &call : View::getDeferedCalls())
|
||||
call();
|
||||
View::getDeferedCalls().clear();
|
||||
{
|
||||
auto &calls = ImHexApi::Tasks::getDeferredCalls();
|
||||
for (const auto &callback : calls)
|
||||
callback();
|
||||
calls.clear();
|
||||
}
|
||||
|
||||
View::drawCommonInterfaces();
|
||||
|
||||
@ -619,169 +417,15 @@ namespace hex {
|
||||
|
||||
glfwSwapBuffers(this->m_window);
|
||||
|
||||
if (this->m_targetFps <= 200)
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(u64((this->m_lastFrameTime + 1 / this->m_targetFps - glfwGetTime()) * 1000)));
|
||||
const auto targetFps = ImHexApi::System::getTargetFPS();
|
||||
if (targetFps <= 200)
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(u64((this->m_lastFrameTime + 1 / targetFps - glfwGetTime()) * 1000)));
|
||||
|
||||
this->m_lastFrameTime = glfwGetTime();
|
||||
}
|
||||
|
||||
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 {
|
||||
@ -789,7 +433,7 @@ namespace hex {
|
||||
if (auto &layouts = ContentRegistry::Interface::getLayouts(); !layouts.empty()) {
|
||||
auto &[name, function] = layouts[0];
|
||||
|
||||
function(ContentRegistry::Interface::getDockSpaceId());
|
||||
function(ImHexApi::System::getMainDockSpaceId());
|
||||
}
|
||||
}
|
||||
|
||||
@ -845,18 +489,19 @@ namespace hex {
|
||||
{
|
||||
int x = 0, y = 0;
|
||||
glfwGetWindowPos(this->m_window, &x, &y);
|
||||
SharedData::windowPos = ImVec2(x, y);
|
||||
|
||||
ImHexApi::System::impl::setMainWindowPosition(x, y);
|
||||
}
|
||||
|
||||
{
|
||||
int width = 0, height = 0;
|
||||
glfwGetWindowSize(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) {
|
||||
SharedData::windowPos = ImVec2(x, y);
|
||||
ImHexApi::System::impl::setMainWindowPosition(x, y);
|
||||
|
||||
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) {
|
||||
SharedData::windowSize = ImVec2(width, height);
|
||||
ImHexApi::System::impl::setMainWindowSize(width, height);
|
||||
|
||||
if (auto g = ImGui::GetCurrentContext(); g == nullptr || g->WithinFrameScope) return;
|
||||
|
||||
@ -913,7 +558,7 @@ namespace hex {
|
||||
for (const auto &extension : extensions) {
|
||||
if (path.extension() == extension) {
|
||||
if (!handler(path))
|
||||
View::showMessagePopup("hex.message.file_handler_failed"_lang);
|
||||
log::error("Handler for extensions '{}' failed to process file!", extension);
|
||||
|
||||
handled = true;
|
||||
break;
|
||||
@ -938,7 +583,9 @@ namespace hex {
|
||||
void Window::initImGui() {
|
||||
IMGUI_CHECKVERSION();
|
||||
|
||||
GImGui = ImGui::CreateContext(SharedData::fontAtlas);
|
||||
auto fonts = View::getFontAtlas();
|
||||
|
||||
GImGui = ImGui::CreateContext(fonts);
|
||||
GImPlot = ImPlot::CreateContext();
|
||||
GImNodes = ImNodes::CreateContext();
|
||||
|
||||
@ -953,7 +600,7 @@ namespace hex {
|
||||
io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable;
|
||||
#endif
|
||||
|
||||
for (auto &entry : SharedData::fontAtlas->ConfigData)
|
||||
for (auto &entry : fonts->ConfigData)
|
||||
io.Fonts->ConfigData.push_back(entry);
|
||||
|
||||
io.ConfigViewportsNoTaskBarIcon = false;
|
||||
@ -990,7 +637,7 @@ namespace hex {
|
||||
|
||||
io.UserData = new ImGui::ImHexCustomData();
|
||||
|
||||
style.ScaleAllSizes(SharedData::globalScale);
|
||||
style.ScaleAllSizes(ImHexApi::System::getGlobalScale());
|
||||
|
||||
{
|
||||
GLsizei width, height;
|
||||
|
@ -18,6 +18,7 @@ add_library(${PROJECT_NAME} SHARED
|
||||
source/content/data_formatters.cpp
|
||||
source/content/layouts.cpp
|
||||
source/content/main_menu_items.cpp
|
||||
source/content/welcome_screen.cpp
|
||||
|
||||
source/content/providers/file_provider.cpp
|
||||
source/content/providers/gdb_provider.cpp
|
||||
|
@ -1,22 +1,21 @@
|
||||
#pragma once
|
||||
|
||||
#include <hex/views/view.hpp>
|
||||
#include <hex/ui/view.hpp>
|
||||
|
||||
#include <vector>
|
||||
#include <list>
|
||||
|
||||
namespace hex::plugin::builtin {
|
||||
|
||||
namespace prv {
|
||||
class Provider;
|
||||
}
|
||||
|
||||
class ViewBookmarks : public View {
|
||||
public:
|
||||
ViewBookmarks();
|
||||
~ViewBookmarks() override;
|
||||
|
||||
void drawContent() override;
|
||||
|
||||
private:
|
||||
std::list<ImHexApi::Bookmarks::Entry> m_bookmarks;
|
||||
};
|
||||
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <hex.hpp>
|
||||
#include <hex/views/view.hpp>
|
||||
#include <hex/ui/view.hpp>
|
||||
|
||||
#include <imgui.h>
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <hex/views/view.hpp>
|
||||
#include <hex/ui/view.hpp>
|
||||
|
||||
#include <cstdio>
|
||||
#include <string>
|
||||
|
@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <hex/views/view.hpp>
|
||||
#include <hex/ui/view.hpp>
|
||||
|
||||
#include <hex/api/content_registry.hpp>
|
||||
|
||||
|
@ -3,7 +3,7 @@
|
||||
#include <hex.hpp>
|
||||
|
||||
#include <imgui.h>
|
||||
#include <hex/views/view.hpp>
|
||||
#include <hex/ui/view.hpp>
|
||||
#include <hex/data_processor/node.hpp>
|
||||
#include <hex/data_processor/link.hpp>
|
||||
|
||||
|
@ -3,7 +3,7 @@
|
||||
#include <hex.hpp>
|
||||
|
||||
#include <imgui.h>
|
||||
#include <hex/views/view.hpp>
|
||||
#include <hex/ui/view.hpp>
|
||||
|
||||
#include <array>
|
||||
#include <string>
|
||||
|
@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <hex/views/view.hpp>
|
||||
#include <hex/ui/view.hpp>
|
||||
|
||||
#include <hex/helpers/disassembler.hpp>
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <hex/views/view.hpp>
|
||||
#include <hex/ui/view.hpp>
|
||||
|
||||
#include <array>
|
||||
#include <utility>
|
||||
|
@ -3,7 +3,7 @@
|
||||
#include <hex.hpp>
|
||||
|
||||
#include <imgui.h>
|
||||
#include <hex/views/view.hpp>
|
||||
#include <hex/ui/view.hpp>
|
||||
|
||||
#include <vector>
|
||||
#include <tuple>
|
||||
|
@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <hex/views/view.hpp>
|
||||
#include <hex/ui/view.hpp>
|
||||
#include <hex/helpers/encoding_file.hpp>
|
||||
|
||||
#include <imgui_memory_editor.h>
|
||||
|
@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <hex/views/view.hpp>
|
||||
#include <hex/ui/view.hpp>
|
||||
|
||||
#include <array>
|
||||
#include <atomic>
|
||||
|
@ -3,7 +3,7 @@
|
||||
#include <hex.hpp>
|
||||
|
||||
#include <imgui.h>
|
||||
#include <hex/views/view.hpp>
|
||||
#include <hex/ui/view.hpp>
|
||||
|
||||
#include <optional>
|
||||
|
||||
|
@ -3,24 +3,12 @@
|
||||
#include <hex.hpp>
|
||||
|
||||
#include <imgui.h>
|
||||
#include <hex/views/view.hpp>
|
||||
#include <hex/ui/view.hpp>
|
||||
|
||||
#include <vector>
|
||||
#include <tuple>
|
||||
#include <cstdio>
|
||||
|
||||
namespace hex {
|
||||
|
||||
namespace prv {
|
||||
class Provider;
|
||||
}
|
||||
namespace lang {
|
||||
class PatternData;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
namespace hex::plugin::builtin {
|
||||
|
||||
class ViewPatternData : public View {
|
||||
@ -31,7 +19,7 @@ namespace hex::plugin::builtin {
|
||||
void drawContent() override;
|
||||
|
||||
private:
|
||||
std::vector<pl::PatternData *> m_sortedPatternData;
|
||||
std::map<prv::Provider*, std::vector<pl::PatternData*>> m_sortedPatterns;
|
||||
};
|
||||
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <hex/views/view.hpp>
|
||||
#include <hex/ui/view.hpp>
|
||||
#include <hex/pattern_language/pattern_language.hpp>
|
||||
#include <hex/pattern_language/log_console.hpp>
|
||||
#include <hex/providers/provider.hpp>
|
||||
@ -24,14 +24,14 @@ namespace hex::plugin::builtin {
|
||||
void drawContent() override;
|
||||
|
||||
private:
|
||||
pl::PatternLanguage *m_parserRuntime, *m_evaluatorRuntime;
|
||||
pl::PatternLanguage *m_parserRuntime;
|
||||
|
||||
std::vector<fs::path> m_possiblePatternFiles;
|
||||
u32 m_selectedPatternFile = 0;
|
||||
bool m_runAutomatically = false;
|
||||
|
||||
bool m_evaluatorRunning = false;
|
||||
bool m_parserRunning = false;
|
||||
std::atomic<u32> m_runningEvaluators = 0;
|
||||
std::atomic<u32> m_runningParsers = 0;
|
||||
|
||||
bool m_hasUnevaluatedChanges = false;
|
||||
|
||||
|
@ -3,7 +3,7 @@
|
||||
#include <hex.hpp>
|
||||
|
||||
#include <imgui.h>
|
||||
#include <hex/views/view.hpp>
|
||||
#include <hex/ui/view.hpp>
|
||||
|
||||
#include <array>
|
||||
#include <string>
|
||||
|
@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <hex/views/view.hpp>
|
||||
#include <hex/ui/view.hpp>
|
||||
|
||||
#include <cstdio>
|
||||
#include <string>
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
#include <hex.hpp>
|
||||
|
||||
#include <hex/views/view.hpp>
|
||||
#include <hex/ui/view.hpp>
|
||||
#include <hex/helpers/net.hpp>
|
||||
#include <hex/helpers/paths.hpp>
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <hex/views/view.hpp>
|
||||
#include <hex/ui/view.hpp>
|
||||
|
||||
#include <cstdio>
|
||||
#include <string>
|
||||
|
@ -3,7 +3,7 @@
|
||||
#include <hex.hpp>
|
||||
|
||||
#include <imgui.h>
|
||||
#include <hex/views/view.hpp>
|
||||
#include <hex/ui/view.hpp>
|
||||
|
||||
#include <array>
|
||||
#include <string>
|
||||
|
@ -3,7 +3,7 @@
|
||||
#include <hex.hpp>
|
||||
|
||||
#include <imgui.h>
|
||||
#include <hex/views/view.hpp>
|
||||
#include <hex/ui/view.hpp>
|
||||
|
||||
namespace hex::plugin::builtin {
|
||||
|
||||
|
@ -1,7 +1,6 @@
|
||||
#include <hex/api/content_registry.hpp>
|
||||
|
||||
#include <hex/helpers/lang.hpp>
|
||||
using namespace hex::lang_literals;
|
||||
#include <hex/api/localization.hpp>
|
||||
|
||||
#include <hex/helpers/utils.hpp>
|
||||
#include <hex/helpers/fmt.hpp>
|
||||
|
@ -2,9 +2,10 @@
|
||||
|
||||
#include <hex/helpers/utils.hpp>
|
||||
#include <hex/helpers/fmt.hpp>
|
||||
#include <hex/helpers/shared_data.hpp>
|
||||
#include <hex/api/event.hpp>
|
||||
|
||||
#include <hex/providers/provider.hpp>
|
||||
|
||||
#include <cstring>
|
||||
#include <codecvt>
|
||||
#include <locale>
|
||||
|
@ -2,14 +2,17 @@
|
||||
#include <hex/data_processor/node.hpp>
|
||||
|
||||
#include <hex/helpers/crypto.hpp>
|
||||
#include <hex/helpers/shared_data.hpp>
|
||||
#include <hex/helpers/utils.hpp>
|
||||
#include <hex/api/localization.hpp>
|
||||
|
||||
#include <hex/providers/provider.hpp>
|
||||
|
||||
#include <cctype>
|
||||
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
#include <imgui.h>
|
||||
#include <hex/ui/imgui_imhex_extensions.h>
|
||||
|
||||
namespace hex::plugin::builtin {
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
#include <hex/api/content_registry.hpp>
|
||||
|
||||
#include <hex/views/view.hpp>
|
||||
#include <hex/ui/view.hpp>
|
||||
|
||||
namespace hex::plugin::builtin {
|
||||
|
||||
|
@ -3,7 +3,7 @@
|
||||
#include <imgui.h>
|
||||
#include <implot.h>
|
||||
|
||||
#include <hex/views/view.hpp>
|
||||
#include <hex/ui/view.hpp>
|
||||
|
||||
namespace hex::plugin::builtin {
|
||||
|
||||
@ -33,7 +33,7 @@ namespace hex::plugin::builtin {
|
||||
ContentRegistry::Interface::addMenuItem("hex.builtin.menu.layout", 1000, [] {
|
||||
for (auto &[layoutName, func] : ContentRegistry::Interface::getLayouts()) {
|
||||
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()) {
|
||||
view->getWindowOpenState() = false;
|
||||
|
@ -44,6 +44,8 @@ namespace hex::plugin::builtin {
|
||||
void registerPatternLanguageFunctions() {
|
||||
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" };
|
||||
{
|
||||
/* print(format, args...) */
|
||||
|
@ -1,10 +1,14 @@
|
||||
#include "content/providers/disk_provider.hpp"
|
||||
|
||||
#include <hex/helpers/fmt.hpp>
|
||||
#include <hex/api/localization.hpp>
|
||||
|
||||
#include <bitset>
|
||||
#include <filesystem>
|
||||
|
||||
#include <imgui.h>
|
||||
#include <hex/ui/imgui_imhex_extensions.h>
|
||||
|
||||
#if defined(OS_LINUX)
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
|
@ -3,8 +3,10 @@
|
||||
#include <ctime>
|
||||
#include <cstring>
|
||||
|
||||
#include <hex/api/localization.hpp>
|
||||
#include <hex/helpers/utils.hpp>
|
||||
#include <hex/helpers/file.hpp>
|
||||
#include <hex/helpers/fmt.hpp>
|
||||
#include <hex/helpers/project_file_handler.hpp>
|
||||
|
||||
namespace hex::plugin::builtin::prv {
|
||||
|
@ -4,8 +4,12 @@
|
||||
#include <thread>
|
||||
#include <chrono>
|
||||
|
||||
#include <imgui.h>
|
||||
#include <hex/ui/imgui_imhex_extensions.h>
|
||||
|
||||
#include <hex/helpers/fmt.hpp>
|
||||
#include <hex/helpers/crypto.hpp>
|
||||
#include <hex/api/localization.hpp>
|
||||
|
||||
namespace hex::plugin::builtin::prv {
|
||||
|
||||
|
@ -1,8 +1,7 @@
|
||||
#include <hex/api/content_registry.hpp>
|
||||
#include <hex/api/imhex_api.hpp>
|
||||
|
||||
#include <hex/helpers/lang.hpp>
|
||||
using namespace hex::lang_literals;
|
||||
#include <hex/api/localization.hpp>
|
||||
|
||||
#include <imgui.h>
|
||||
|
||||
|
@ -2,12 +2,15 @@
|
||||
#include <hex/api/imhex_api.hpp>
|
||||
|
||||
#include <hex/helpers/net.hpp>
|
||||
#include <hex/helpers/shared_data.hpp>
|
||||
#include <hex/helpers/utils.hpp>
|
||||
#include <hex/helpers/fmt.hpp>
|
||||
#include <hex/helpers/file.hpp>
|
||||
#include <hex/helpers/literals.hpp>
|
||||
#include <hex/helpers/paths.hpp>
|
||||
#include <hex/api/localization.hpp>
|
||||
|
||||
#include <hex/ui/view.hpp>
|
||||
#include <hex/providers/provider.hpp>
|
||||
|
||||
#include <algorithm>
|
||||
#include <chrono>
|
||||
@ -20,6 +23,7 @@
|
||||
#include <imgui.h>
|
||||
#define IMGUI_DEFINE_MATH_OPERATORS
|
||||
#include <imgui_internal.h>
|
||||
#include <hex/ui/imgui_imhex_extensions.h>
|
||||
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
|
@ -1,8 +1,10 @@
|
||||
#include <hex/api/content_registry.hpp>
|
||||
#include <hex/helpers/shared_data.hpp>
|
||||
|
||||
#include <hex/helpers/utils.hpp>
|
||||
#include <hex/helpers/fmt.hpp>
|
||||
#include <hex/api/localization.hpp>
|
||||
|
||||
#include <hex/providers/provider.hpp>
|
||||
|
||||
#include <codicons_font.h>
|
||||
#include <imgui.h>
|
||||
@ -36,12 +38,13 @@ namespace hex::plugin::builtin {
|
||||
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) {
|
||||
taskProgress = SharedData::runningTasks.front()->getProgress();
|
||||
taskName = SharedData::runningTasks.front()->getName();
|
||||
auto frontTask = Task::getRunningTasks().front();
|
||||
taskProgress = frontTask->getProgress();
|
||||
taskName = frontTask->getName();
|
||||
}
|
||||
}
|
||||
|
||||
@ -132,14 +135,14 @@ namespace hex::plugin::builtin {
|
||||
|
||||
std::string preview;
|
||||
if (ImHexApi::Provider::isValid())
|
||||
preview = providers[SharedData::currentProvider]->getName();
|
||||
preview = ImHexApi::Provider::get()->getName();
|
||||
|
||||
ImGui::SetNextItemWidth(200_scaled);
|
||||
if (ImGui::BeginCombo("", preview.c_str())) {
|
||||
|
||||
for (int i = 0; i < providers.size(); i++) {
|
||||
if (ImGui::Selectable(providers[i]->getName().c_str())) {
|
||||
SharedData::currentProvider = i;
|
||||
ImHexApi::Provider::setCurrentProvider(i);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -10,34 +10,38 @@
|
||||
namespace hex::plugin::builtin {
|
||||
|
||||
ViewBookmarks::ViewBookmarks() : View("hex.builtin.view.bookmarks.name") {
|
||||
EventManager::subscribe<RequestAddBookmark>(this, [](ImHexApi::Bookmarks::Entry bookmark) {
|
||||
bookmark.comment.resize(0xF'FFFF);
|
||||
|
||||
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());
|
||||
EventManager::subscribe<RequestAddBookmark>(this, [this](Region region, std::string name, std::string comment, color_t color) {
|
||||
if (name.empty()) {
|
||||
name = hex::format("hex.builtin.view.bookmarks.default_title"_lang, region.address, region.address + region.size - 1);
|
||||
}
|
||||
|
||||
if (bookmark.comment.empty())
|
||||
std::memset(bookmark.comment.data(), 0x00, 0xF'FFFF);
|
||||
if (color == 0x00)
|
||||
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();
|
||||
});
|
||||
|
||||
EventManager::subscribe<EventProjectFileLoad>(this, [] {
|
||||
SharedData::bookmarkEntries = ProjectFile::getBookmarks();
|
||||
EventManager::subscribe<EventProjectFileLoad>(this, [this] {
|
||||
this->m_bookmarks = ProjectFile::getBookmarks();
|
||||
});
|
||||
|
||||
EventManager::subscribe<EventProjectFileStore>(this, [] {
|
||||
ProjectFile::setBookmarks(SharedData::bookmarkEntries);
|
||||
EventManager::subscribe<EventProjectFileStore>(this, [this] {
|
||||
ProjectFile::setBookmarks(this->m_bookmarks);
|
||||
});
|
||||
|
||||
EventManager::subscribe<EventFileUnloaded>(this, [] {
|
||||
ImHexApi::Bookmarks::getEntries().clear();
|
||||
EventManager::subscribe<EventFileUnloaded>(this, [this] {
|
||||
this->m_bookmarks.clear();
|
||||
});
|
||||
}
|
||||
|
||||
@ -46,22 +50,22 @@ namespace hex::plugin::builtin {
|
||||
EventManager::unsubscribe<EventProjectFileLoad>(this);
|
||||
EventManager::unsubscribe<EventProjectFileStore>(this);
|
||||
EventManager::unsubscribe<EventFileUnloaded>(this);
|
||||
|
||||
this->m_bookmarks.clear();
|
||||
}
|
||||
|
||||
void ViewBookmarks::drawContent() {
|
||||
if (ImGui::Begin(View::toWindowName("hex.builtin.view.bookmarks.name").c_str(), &this->getWindowOpenState())) {
|
||||
if (ImGui::BeginChild("##scrolling")) {
|
||||
|
||||
auto &bookmarks = ImHexApi::Bookmarks::getEntries();
|
||||
|
||||
if (bookmarks.empty()) {
|
||||
if (this->m_bookmarks.empty()) {
|
||||
ImGui::TextFormattedCentered("hex.builtin.view.bookmarks.no_bookmarks"_lang);
|
||||
}
|
||||
|
||||
u32 id = 1;
|
||||
auto bookmarkToRemove = bookmarks.end();
|
||||
for (auto iter = bookmarks.begin(); iter != bookmarks.end(); iter++) {
|
||||
auto &[region, name, comment, color, locked] = *iter;
|
||||
auto bookmarkToRemove = this->m_bookmarks.end();
|
||||
for (auto iter = this->m_bookmarks.begin(); iter != this->m_bookmarks.end(); iter++) {
|
||||
auto &[region, name, comment, color, locked, highlight] = *iter;
|
||||
|
||||
auto headerColor = ImColor(color);
|
||||
auto hoverColor = ImColor(color);
|
||||
@ -71,7 +75,7 @@ namespace hex::plugin::builtin {
|
||||
ImGui::PushStyleColor(ImGuiCol_Header, color);
|
||||
ImGui::PushStyleColor(ImGuiCol_HeaderActive, color);
|
||||
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::Separator();
|
||||
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)
|
||||
ImGui::TextUnformatted(name.data());
|
||||
else
|
||||
ImGui::InputText("##nameInput", name.data(), 64);
|
||||
ImGui::InputText("##nameInput", name.data(), name.capacity(), ImGuiInputTextFlags_CallbackResize, ImGui::UpdateStringSizeCallback, &name);
|
||||
|
||||
ImGui::NewLine();
|
||||
ImGui::TextUnformatted("hex.builtin.view.bookmarks.header.comment"_lang);
|
||||
@ -155,7 +159,7 @@ namespace hex::plugin::builtin {
|
||||
if (locked)
|
||||
ImGui::TextFormattedWrapped("{}", comment.data());
|
||||
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();
|
||||
}
|
||||
@ -164,8 +168,9 @@ namespace hex::plugin::builtin {
|
||||
id++;
|
||||
}
|
||||
|
||||
if (bookmarkToRemove != bookmarks.end()) {
|
||||
bookmarks.erase(bookmarkToRemove);
|
||||
if (bookmarkToRemove != this->m_bookmarks.end()) {
|
||||
ImHexApi::HexEditor::removeHighlight(bookmarkToRemove->highlightId);
|
||||
this->m_bookmarks.erase(bookmarkToRemove);
|
||||
ProjectFile::markDirty();
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,7 @@
|
||||
#include "content/views/view_command_palette.hpp"
|
||||
|
||||
#include <hex/api/content_registry.hpp>
|
||||
|
||||
#include <cstring>
|
||||
|
||||
namespace hex::plugin::builtin {
|
||||
@ -21,7 +23,10 @@ namespace hex::plugin::builtin {
|
||||
|
||||
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::IsKeyDown(ImGui::GetKeyIndex(ImGuiKey_Escape)))
|
||||
ImGui::CloseCurrentPopup();
|
||||
|
@ -24,7 +24,7 @@ namespace hex::plugin::builtin {
|
||||
this->m_constants.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;
|
||||
|
||||
for (auto &file : fs::directory_iterator(path)) {
|
||||
|
@ -1,5 +1,7 @@
|
||||
#include "content/views/view_data_processor.hpp"
|
||||
|
||||
#include <hex/api/content_registry.hpp>
|
||||
|
||||
#include <hex/helpers/file.hpp>
|
||||
|
||||
#include <hex/providers/provider.hpp>
|
||||
@ -83,7 +85,7 @@ namespace hex::plugin::builtin {
|
||||
|
||||
|
||||
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())
|
||||
return;
|
||||
@ -101,7 +103,7 @@ namespace hex::plugin::builtin {
|
||||
|
||||
void ViewDataProcessor::eraseNodes(const std::vector<int> &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()) {
|
||||
std::vector<u32> linksToRemove;
|
||||
@ -114,9 +116,9 @@ namespace hex::plugin::builtin {
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
@ -238,7 +240,7 @@ namespace hex::plugin::builtin {
|
||||
if (hasInput && !hasOutput)
|
||||
this->m_endNodes.push_back(node);
|
||||
|
||||
ImNodes::SetNodeScreenSpacePos(node->getID(), this->m_rightClickedCoords);
|
||||
ImNodes::SetNodeScreenSpacePos(node->getId(), this->m_rightClickedCoords);
|
||||
}
|
||||
|
||||
ImGui::EndPopup();
|
||||
@ -260,7 +262,7 @@ namespace hex::plugin::builtin {
|
||||
|
||||
{
|
||||
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::TextUnformatted("hex.common.error"_lang);
|
||||
ImGui::Separator();
|
||||
@ -277,7 +279,7 @@ namespace hex::plugin::builtin {
|
||||
if (hasError)
|
||||
ImNodes::PushColorStyle(ImNodesCol_NodeOutline, 0xFF0000FF);
|
||||
|
||||
ImNodes::BeginNode(node->getID());
|
||||
ImNodes::BeginNode(node->getId());
|
||||
|
||||
ImNodes::BeginNodeTitleBar();
|
||||
ImGui::TextUnformatted(LangEntry(node->getUnlocalizedTitle()));
|
||||
@ -301,11 +303,11 @@ namespace hex::plugin::builtin {
|
||||
}
|
||||
|
||||
if (attribute.getIOType() == dp::Attribute::IOType::In) {
|
||||
ImNodes::BeginInputAttribute(attribute.getID(), pinShape);
|
||||
ImNodes::BeginInputAttribute(attribute.getId(), pinShape);
|
||||
ImGui::TextUnformatted(LangEntry(attribute.getUnlocalizedName()));
|
||||
ImNodes::EndInputAttribute();
|
||||
} 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()));
|
||||
ImNodes::EndOutputAttribute();
|
||||
}
|
||||
@ -318,7 +320,7 @@ namespace hex::plugin::builtin {
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
@ -339,9 +341,9 @@ namespace hex::plugin::builtin {
|
||||
dp::Attribute *fromAttr, *toAttr;
|
||||
for (auto &node : this->m_nodes) {
|
||||
for (auto &attribute : node->getAttributes()) {
|
||||
if (attribute.getID() == from)
|
||||
if (attribute.getId() == from)
|
||||
fromAttr = &attribute;
|
||||
else if (attribute.getID() == to)
|
||||
else if (attribute.getId() == to)
|
||||
toAttr = &attribute;
|
||||
}
|
||||
}
|
||||
@ -360,8 +362,8 @@ namespace hex::plugin::builtin {
|
||||
|
||||
auto newLink = this->m_links.emplace_back(from, to);
|
||||
|
||||
fromAttr->addConnectedAttribute(newLink.getID(), toAttr);
|
||||
toAttr->addConnectedAttribute(newLink.getID(), fromAttr);
|
||||
fromAttr->addConnectedAttribute(newLink.getId(), toAttr);
|
||||
toAttr->addConnectedAttribute(newLink.getId(), fromAttr);
|
||||
} while (false);
|
||||
}
|
||||
}
|
||||
@ -401,7 +403,7 @@ namespace hex::plugin::builtin {
|
||||
|
||||
output["nodes"] = json::object();
|
||||
for (auto &node : this->m_nodes) {
|
||||
auto id = node->getID();
|
||||
auto id = node->getId();
|
||||
auto &currNodeOutput = output["nodes"][std::to_string(id)];
|
||||
auto pos = ImNodes::GetNodeGridSpacePos(id);
|
||||
|
||||
@ -419,19 +421,19 @@ namespace hex::plugin::builtin {
|
||||
|
||||
u32 attrIndex = 0;
|
||||
for (auto &attr : node->getAttributes()) {
|
||||
currNodeOutput["attrs"][attrIndex] = attr.getID();
|
||||
currNodeOutput["attrs"][attrIndex] = attr.getId();
|
||||
attrIndex++;
|
||||
}
|
||||
}
|
||||
|
||||
output["links"] = json::object();
|
||||
for (auto &link : this->m_links) {
|
||||
auto id = link.getID();
|
||||
auto id = link.getId();
|
||||
auto &currOutput = output["links"][std::to_string(id)];
|
||||
|
||||
currOutput["id"] = id;
|
||||
currOutput["from"] = link.getFromID();
|
||||
currOutput["to"] = link.getToID();
|
||||
currOutput["from"] = link.getFromId();
|
||||
currOutput["to"] = link.getToId();
|
||||
}
|
||||
|
||||
return output.dump();
|
||||
@ -467,7 +469,7 @@ namespace hex::plugin::builtin {
|
||||
u32 nodeId = node["id"];
|
||||
maxNodeId = std::max(nodeId, maxNodeId);
|
||||
|
||||
newNode->setID(nodeId);
|
||||
newNode->setId(nodeId);
|
||||
|
||||
bool hasOutput = false;
|
||||
bool hasInput = false;
|
||||
@ -482,7 +484,7 @@ namespace hex::plugin::builtin {
|
||||
u32 attrId = node["attrs"][attrIndex];
|
||||
maxAttrId = std::max(attrId, maxAttrId);
|
||||
|
||||
attr.setID(attrId);
|
||||
attr.setId(attrId);
|
||||
attrIndex++;
|
||||
}
|
||||
|
||||
@ -508,9 +510,9 @@ namespace hex::plugin::builtin {
|
||||
dp::Attribute *fromAttr, *toAttr;
|
||||
for (auto &node : this->m_nodes) {
|
||||
for (auto &attribute : node->getAttributes()) {
|
||||
if (attribute.getID() == newLink.getFromID())
|
||||
if (attribute.getId() == newLink.getFromId())
|
||||
fromAttr = &attribute;
|
||||
else if (attribute.getID() == newLink.getToID())
|
||||
else if (attribute.getId() == newLink.getToId())
|
||||
toAttr = &attribute;
|
||||
}
|
||||
}
|
||||
@ -527,13 +529,13 @@ namespace hex::plugin::builtin {
|
||||
if (!toAttr->getConnectedAttributes().empty())
|
||||
break;
|
||||
|
||||
fromAttr->addConnectedAttribute(newLink.getID(), toAttr);
|
||||
toAttr->addConnectedAttribute(newLink.getID(), fromAttr);
|
||||
fromAttr->addConnectedAttribute(newLink.getId(), toAttr);
|
||||
toAttr->addConnectedAttribute(newLink.getId(), fromAttr);
|
||||
}
|
||||
|
||||
SharedData::dataProcessorNodeIdCounter = maxNodeId + 1;
|
||||
SharedData::dataProcessorAttrIdCounter = maxAttrId + 1;
|
||||
SharedData::dataProcessorLinkIdCounter = maxLinkId + 1;
|
||||
dp::Node::setIdCounter(maxNodeId + 1);
|
||||
dp::Attribute::setIdCounter(maxAttrId + 1);
|
||||
dp::Link::setIdCounter(maxLinkId + 1);
|
||||
}
|
||||
|
||||
}
|
@ -1,9 +1,11 @@
|
||||
#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/utils.hpp>
|
||||
#include <hex/helpers/logger.hpp>
|
||||
#include <hex/helpers/paths.hpp>
|
||||
#include <hex/helpers/utils.hpp>
|
||||
|
||||
#include <romfs/romfs.hpp>
|
||||
|
||||
@ -13,7 +15,7 @@ namespace hex::plugin::builtin {
|
||||
|
||||
ContentRegistry::Interface::addMenuItem("hex.builtin.menu.help", 1000, [&, this] {
|
||||
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->getWindowOpenState() = true;
|
||||
}
|
||||
|
@ -59,7 +59,7 @@ namespace hex::plugin::builtin {
|
||||
};
|
||||
|
||||
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;
|
||||
|
||||
@ -69,7 +69,10 @@ namespace hex::plugin::builtin {
|
||||
|
||||
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 ®ion = highlight.getRegion();
|
||||
auto &color = highlight.getColor();
|
||||
|
||||
if (off >= region.address && off < (region.address + region.size))
|
||||
currColor = (color & 0x00FFFFFF) | alpha;
|
||||
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);
|
||||
if (child != nullptr) {
|
||||
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);
|
||||
if (child != nullptr) {
|
||||
auto color = (child->getColor() & 0x00FFFFFF) | alpha;
|
||||
@ -114,15 +118,19 @@ namespace hex::plugin::builtin {
|
||||
|
||||
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 ®ion = highlight.getRegion();
|
||||
auto &color = highlight.getColor();
|
||||
auto &tooltip = highlight.getTooltip();
|
||||
|
||||
if (off >= region.address && off < (region.address + region.size)) {
|
||||
if (!tooltipShown) {
|
||||
if (!tooltipShown && !tooltip.empty()) {
|
||||
ImGui::BeginTooltip();
|
||||
tooltipShown = true;
|
||||
}
|
||||
ImGui::ColorButton(name.data(), ImColor(color).Value);
|
||||
ImGui::ColorButton(tooltip.c_str(), ImColor(color).Value);
|
||||
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())) {
|
||||
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())) {
|
||||
View::doLater([this] {
|
||||
ImHexApi::Tasks::doLater([this] {
|
||||
this->m_resizeSize = ImHexApi::Provider::get()->getActualSize();
|
||||
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())) {
|
||||
View::doLater([this] {
|
||||
ImHexApi::Tasks::doLater([this] {
|
||||
this->m_resizeSize = 0;
|
||||
ImGui::OpenPopup("hex.builtin.view.hexeditor.menu.edit.insert"_lang);
|
||||
});
|
||||
@ -800,7 +808,7 @@ namespace hex::plugin::builtin {
|
||||
EventManager::subscribe<EventWindowClosing>(this, [](GLFWwindow *window) {
|
||||
if (ProjectFile::hasUnsavedChanges()) {
|
||||
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() {
|
||||
|
||||
/* Basic operations */
|
||||
ContentRegistry::Interface::addMenuItem("hex.builtin.menu.file", 1000, [&] {
|
||||
|
||||
ContentRegistry::Interface::addMenuItem("hex.builtin.menu.file", 1100, [&] {
|
||||
auto provider = ImHexApi::Provider::get();
|
||||
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())) {
|
||||
save();
|
||||
@ -1020,7 +994,7 @@ namespace hex::plugin::builtin {
|
||||
|
||||
|
||||
/* 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();
|
||||
bool providerValid = ImHexApi::Provider::isValid();
|
||||
|
||||
@ -1070,7 +1044,7 @@ namespace hex::plugin::builtin {
|
||||
|
||||
|
||||
/* 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();
|
||||
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)) {
|
||||
this->m_loaderScriptFilePath.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();
|
||||
@ -1185,7 +1159,7 @@ namespace hex::plugin::builtin {
|
||||
this->m_dataToSave = generateIPSPatch(patches);
|
||||
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) {
|
||||
auto file = File(path, File::Mode::Create);
|
||||
if (!file.isValid()) {
|
||||
@ -1214,7 +1188,7 @@ namespace hex::plugin::builtin {
|
||||
this->m_dataToSave = generateIPS32Patch(patches);
|
||||
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) {
|
||||
auto file = File(path, File::Mode::Create);
|
||||
if (!file.isValid()) {
|
||||
@ -1234,7 +1208,7 @@ namespace hex::plugin::builtin {
|
||||
|
||||
|
||||
/* 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")) {
|
||||
this->getWindowOpenState() = true;
|
||||
ImGui::OpenPopupInWindow(View::toWindowName("hex.builtin.view.hexeditor.name").c_str(), "hex.builtin.view.hexeditor.menu.file.search"_lang);
|
||||
|
@ -1,5 +1,7 @@
|
||||
#include "content/views/view_information.hpp"
|
||||
|
||||
#include <hex/api/content_registry.hpp>
|
||||
|
||||
#include <hex/providers/provider.hpp>
|
||||
#include <hex/helpers/paths.hpp>
|
||||
#include <hex/helpers/fmt.hpp>
|
||||
@ -44,7 +46,7 @@ namespace hex::plugin::builtin {
|
||||
});
|
||||
|
||||
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;
|
||||
if (fs::copy_file(path, destPath / path.filename(), fs::copy_options::overwrite_existing, error)) {
|
||||
View::showMessagePopup("hex.builtin.view.information.magic_db_added"_lang);
|
||||
|
@ -8,7 +8,9 @@ namespace hex::plugin::builtin {
|
||||
ViewPatternData::ViewPatternData() : View("hex.builtin.view.pattern_data.name") {
|
||||
|
||||
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();
|
||||
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();
|
||||
if (this->m_sortedPatternData.size() > 0) {
|
||||
if (!sortedPatterns.empty()) {
|
||||
|
||||
for (auto &patternData : this->m_sortedPatternData)
|
||||
for (auto &patternData : sortedPatterns)
|
||||
patternData->draw(provider);
|
||||
}
|
||||
|
||||
|
@ -73,7 +73,6 @@ namespace hex::plugin::builtin {
|
||||
|
||||
|
||||
ViewPatternEditor::ViewPatternEditor() : View("hex.builtin.view.pattern_editor.name") {
|
||||
this->m_evaluatorRuntime = new pl::PatternLanguage();
|
||||
this->m_parserRuntime = new pl::PatternLanguage();
|
||||
|
||||
this->m_textEditor.SetLanguageDefinition(PatternLanguage());
|
||||
@ -148,7 +147,16 @@ namespace hex::plugin::builtin {
|
||||
|
||||
EventManager::subscribe<EventFileUnloaded>(this, [this] {
|
||||
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 */
|
||||
@ -186,7 +194,7 @@ namespace hex::plugin::builtin {
|
||||
|
||||
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;
|
||||
|
||||
for (auto &entry : fs::recursive_directory_iterator(imhexPath)) {
|
||||
@ -218,7 +226,6 @@ namespace hex::plugin::builtin {
|
||||
}
|
||||
|
||||
ViewPatternEditor::~ViewPatternEditor() {
|
||||
delete this->m_evaluatorRuntime;
|
||||
delete this->m_parserRuntime;
|
||||
|
||||
EventManager::unsubscribe<EventProjectFileStore>(this);
|
||||
@ -261,9 +268,10 @@ namespace hex::plugin::builtin {
|
||||
|
||||
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)))
|
||||
this->m_evaluatorRuntime->abort();
|
||||
runtime.abort();
|
||||
} else {
|
||||
if (ImGui::IconButton(ICON_VS_DEBUG_START, ImGui::GetCustomColorVec4(ImGuiCustomCol_ToolbarGreen)))
|
||||
this->evaluatePattern(this->m_textEditor.GetText());
|
||||
@ -273,7 +281,7 @@ namespace hex::plugin::builtin {
|
||||
ImGui::PopStyleVar();
|
||||
|
||||
ImGui::SameLine();
|
||||
if (this->m_evaluatorRunning)
|
||||
if (this->m_runningEvaluators > 0)
|
||||
ImGui::TextSpinner("hex.builtin.view.pattern_editor.evaluating"_lang);
|
||||
else {
|
||||
if (ImGui::Checkbox("hex.builtin.view.pattern_editor.auto"_lang, &this->m_runAutomatically)) {
|
||||
@ -286,8 +294,8 @@ namespace hex::plugin::builtin {
|
||||
ImGui::SameLine();
|
||||
|
||||
ImGui::TextFormatted("{} / {}",
|
||||
this->m_evaluatorRuntime->getCreatedPatternCount(),
|
||||
this->m_evaluatorRuntime->getMaximumPatternCount());
|
||||
provider->getPatternLanguageRuntime().getCreatedPatternCount(),
|
||||
provider->getPatternLanguageRuntime().getMaximumPatternCount());
|
||||
}
|
||||
|
||||
if (this->m_textEditor.IsTextChanged()) {
|
||||
@ -295,7 +303,7 @@ namespace hex::plugin::builtin {
|
||||
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;
|
||||
|
||||
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());
|
||||
}
|
||||
|
||||
@ -315,11 +323,15 @@ namespace hex::plugin::builtin {
|
||||
ImGui::NewLine();
|
||||
|
||||
View::confirmButtons(
|
||||
"hex.common.yes"_lang, "hex.common.no"_lang, [this] {
|
||||
this->m_evaluatorRuntime->allowDangerousFunctions(true);
|
||||
ImGui::CloseCurrentPopup(); }, [this] {
|
||||
this->m_evaluatorRuntime->allowDangerousFunctions(false);
|
||||
ImGui::CloseCurrentPopup(); });
|
||||
"hex.common.yes"_lang, "hex.common.no"_lang,
|
||||
[] {
|
||||
ImHexApi::Provider::get()->getPatternLanguageRuntime().allowDangerousFunctions(true);
|
||||
ImGui::CloseCurrentPopup();
|
||||
},
|
||||
[] {
|
||||
ImHexApi::Provider::get()->getPatternLanguageRuntime().allowDangerousFunctions(false);
|
||||
ImGui::CloseCurrentPopup();
|
||||
});
|
||||
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
@ -567,16 +579,15 @@ namespace hex::plugin::builtin {
|
||||
}
|
||||
|
||||
void ViewPatternEditor::clearPatternData() {
|
||||
for (auto &data : SharedData::patternData)
|
||||
delete data;
|
||||
if (!ImHexApi::Provider::isValid()) return;
|
||||
|
||||
SharedData::patternData.clear();
|
||||
pl::PatternData::resetPalette();
|
||||
ImHexApi::Provider::get()->getPatternLanguageRuntime().reset();
|
||||
ContentRegistry::PatternLanguage::resetPalette();
|
||||
}
|
||||
|
||||
|
||||
void ViewPatternEditor::parsePattern(const std::string &code) {
|
||||
this->m_parserRunning = true;
|
||||
this->m_runningParsers++;
|
||||
std::thread([this, code] {
|
||||
auto ast = this->m_parserRuntime->parseString(code);
|
||||
|
||||
@ -606,12 +617,12 @@ namespace hex::plugin::builtin {
|
||||
}
|
||||
}
|
||||
|
||||
this->m_parserRunning = false;
|
||||
this->m_runningParsers--;
|
||||
}).detach();
|
||||
}
|
||||
|
||||
void ViewPatternEditor::evaluatePattern(const std::string &code) {
|
||||
this->m_evaluatorRunning = true;
|
||||
this->m_runningEvaluators++;
|
||||
|
||||
this->m_textEditor.SetErrorMarkers({});
|
||||
this->m_console.clear();
|
||||
@ -633,28 +644,31 @@ namespace hex::plugin::builtin {
|
||||
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();
|
||||
if (error.has_value()) {
|
||||
auto result = runtime.executeString(provider, code, envVars, inVariables);
|
||||
if (!result) {
|
||||
auto error = runtime.getError();
|
||||
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) {
|
||||
if (variable.outVariable && outVariables.contains(name))
|
||||
variable.value = outVariables.at(name);
|
||||
}
|
||||
|
||||
if (result.has_value()) {
|
||||
SharedData::patternData = std::move(result.value());
|
||||
EventManager::post<EventPatternChanged>(SharedData::patternData);
|
||||
if (result) {
|
||||
EventManager::post<EventPatternChanged>(runtime.getPatterns());
|
||||
}
|
||||
|
||||
this->m_evaluatorRunning = false;
|
||||
this->m_runningEvaluators--;
|
||||
}).detach();
|
||||
}
|
||||
|
||||
|
@ -9,14 +9,14 @@ namespace hex::plugin::builtin {
|
||||
ViewSettings::ViewSettings() : View("hex.builtin.view.settings.name") {
|
||||
EventManager::subscribe<RequestOpenWindow>(this, [this](const std::string &name) {
|
||||
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;
|
||||
}
|
||||
});
|
||||
|
||||
ContentRegistry::Interface::addMenuItem("hex.builtin.menu.help", 2000, [&, this] {
|
||||
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;
|
||||
}
|
||||
});
|
||||
|
@ -1,5 +1,7 @@
|
||||
#include "content/views/view_store.hpp"
|
||||
|
||||
#include <hex/api/content_registry.hpp>
|
||||
|
||||
#include <imgui.h>
|
||||
#define IMGUI_DEFINE_MATH_OPERATORS
|
||||
#include <imgui_internal.h>
|
||||
@ -27,7 +29,7 @@ namespace hex::plugin::builtin {
|
||||
|
||||
ContentRegistry::Interface::addMenuItem("hex.builtin.menu.help", 3000, [&, this] {
|
||||
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;
|
||||
}
|
||||
});
|
||||
|
@ -52,7 +52,7 @@ namespace hex::plugin::builtin {
|
||||
if (ImGui::MenuItem("hex.builtin.view.strings.demangle"_lang)) {
|
||||
this->m_demangledName = llvm::demangle(this->m_selectedString);
|
||||
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();
|
||||
}
|
||||
|
@ -1,5 +1,7 @@
|
||||
#include "content/views/view_tools.hpp"
|
||||
|
||||
#include <hex/api/content_registry.hpp>
|
||||
|
||||
#include <hex/providers/provider.hpp>
|
||||
|
||||
namespace hex::plugin::builtin {
|
||||
|
@ -1,5 +1,7 @@
|
||||
#include "content/views/view_yara.hpp"
|
||||
|
||||
#include <hex/api/content_registry.hpp>
|
||||
|
||||
#include <hex/providers/provider.hpp>
|
||||
#include <hex/helpers/utils.hpp>
|
||||
#include <hex/helpers/file.hpp>
|
||||
@ -20,7 +22,7 @@ namespace hex::plugin::builtin {
|
||||
this->reloadRules();
|
||||
|
||||
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;
|
||||
if (fs::copy_file(path, destPath / path.filename(), fs::copy_options::overwrite_existing, error)) {
|
||||
View::showMessagePopup("hex.builtin.view.yara.rule_added"_lang);
|
||||
@ -132,7 +134,7 @@ namespace hex::plugin::builtin {
|
||||
void ViewYara::reloadRules() {
|
||||
this->m_rules.clear();
|
||||
|
||||
for (auto path : hex::getPath(ImHexPath::Yara)) {
|
||||
for (const auto path : hex::getPath(ImHexPath::Yara)) {
|
||||
if (!fs::exists(path))
|
||||
continue;
|
||||
|
||||
|
449
plugins/builtin/source/content/welcome_screen.cpp
Normal file
449
plugins/builtin/source/content/welcome_screen.cpp
Normal 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); });
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
#include <hex/api/content_registry.hpp>
|
||||
#include <hex/helpers/lang.hpp>
|
||||
#include <hex/api/localization.hpp>
|
||||
|
||||
namespace hex::plugin::builtin {
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
#include <hex/api/content_registry.hpp>
|
||||
#include <hex/helpers/lang.hpp>
|
||||
#include <hex/api/localization.hpp>
|
||||
|
||||
namespace hex::plugin::builtin {
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
#include <hex/api/content_registry.hpp>
|
||||
#include <hex/helpers/lang.hpp>
|
||||
#include <hex/api/localization.hpp>
|
||||
|
||||
namespace hex::plugin::builtin {
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
#include <hex/api/content_registry.hpp>
|
||||
#include <hex/helpers/lang.hpp>
|
||||
#include <hex/api/localization.hpp>
|
||||
|
||||
namespace hex::plugin::builtin {
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user