1
0
mirror of synced 2024-11-24 07:40:17 +01:00

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

* sys: Initial refactoring of the SharedData class

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

* sys: Finished up refactoring. No more SharedData!

* sys: Fixed compile on Unix

* tests: Fixed unit tests

* sys: Moved view and lang files

* pattern: Added assignment operator support to for loops

* tests: Fixed compile issue
This commit is contained in:
WerWolv 2022-02-01 18:09:40 +01:00 committed by GitHub
parent 61fc479c79
commit 1991afb87b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
110 changed files with 1592 additions and 1259 deletions

View File

@ -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)

View File

@ -47,6 +47,7 @@
//#define IMGUI_DISABLE_DEFAULT_FILE_FUNCTIONS // Don't implement ImFileOpen/ImFileClose/ImFileRead/ImFileWrite and ImFileHandle so you can implement them yourself if you don't want to link with fopen/fclose/fread/fwrite. This will also disable the LogToTTY() function.
//#define IMGUI_DISABLE_DEFAULT_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

View File

@ -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)

View File

@ -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 {

View File

@ -92,6 +92,15 @@ namespace hex {
/* Pattern Language Function Registry. Allows adding of new functions that may be used inside the pattern language */
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();
}

View File

@ -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);

View File

@ -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 &region, 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();
}
}
}

View File

@ -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;
};
}

View File

@ -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);
}
inline LangEntry operator""_lang(const char *string, size_t) {
return LangEntry(string);
}
}

View File

@ -24,6 +24,7 @@ namespace hex {
[[nodiscard]] std::string getPluginDescription() const;
[[nodiscard]] std::string 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;
};
}

View File

@ -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;
};
}

View File

@ -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;
};
}

View File

@ -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;
};
}

View File

@ -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!");

View File

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

View File

@ -400,21 +400,21 @@ namespace hex::pl {
PatternData *pattern;
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);

View File

@ -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) {

View File

@ -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;
};
}

View File

@ -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;
};
}

View File

@ -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;
};

View File

@ -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;
}
}

View File

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

View File

@ -1,13 +1,14 @@
#include <hex/api/keybinding.hpp>
#include <hex/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();
}
}

View File

@ -1,10 +1,11 @@
#include "hex/helpers/lang.hpp"
#include <hex/api/localization.hpp>
#include "hex/helpers/shared_data.hpp"
#include <hex/api/content_registry.hpp>
namespace hex {
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();
}
}

View File

@ -1,4 +1,4 @@
#include "helpers/plugin_manager.hpp"
#include <hex/api/plugin_manager.hpp>
#include <hex/helpers/logger.hpp>
@ -17,32 +17,35 @@ namespace hex {
auto pluginName = fs::path(path).stem().string();
this->m_initializePluginFunction = getPluginFunction<InitializePluginFunc>("initializePlugin");
this->m_getPluginNameFunction = getPluginFunction<GetPluginNameFunc>("getPluginName");
this->m_getPluginAuthorFunction = getPluginFunction<GetPluginAuthorFunc>("getPluginAuthor");
this->m_getPluginDescriptionFunction = getPluginFunction<GetPluginDescriptionFunc>("getPluginDescription");
this->m_getCompatibleVersionFunction = getPluginFunction<GetCompatibleVersionFunc>("getCompatibleVersion");
this->m_setImGuiContextFunction = getPluginFunction<SetImGuiContextFunc>("setImGuiContext");
this->m_initializePluginFunction = getPluginFunction<InitializePluginFunc>("initializePlugin");
this->m_getPluginNameFunction = getPluginFunction<GetPluginNameFunc>("getPluginName");
this->m_getPluginAuthorFunction = getPluginFunction<GetPluginAuthorFunc>("getPluginAuthor");
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 {
this->m_handle = other.m_handle;
this->m_path = std::move(other.m_path);
this->m_initializePluginFunction = other.m_initializePluginFunction;
this->m_getPluginNameFunction = other.m_getPluginNameFunction;
this->m_getPluginAuthorFunction = other.m_getPluginAuthorFunction;
this->m_getPluginDescriptionFunction = other.m_getPluginDescriptionFunction;
this->m_getCompatibleVersionFunction = other.m_getCompatibleVersionFunction;
this->m_setImGuiContextFunction = other.m_setImGuiContextFunction;
this->m_initializePluginFunction = other.m_initializePluginFunction;
this->m_getPluginNameFunction = other.m_getPluginNameFunction;
this->m_getPluginAuthorFunction = other.m_getPluginAuthorFunction;
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;
other.m_getPluginNameFunction = nullptr;
other.m_getPluginAuthorFunction = nullptr;
other.m_getPluginDescriptionFunction = nullptr;
other.m_getCompatibleVersionFunction = nullptr;
other.m_setImGuiContextFunction = nullptr;
other.m_handle = nullptr;
other.m_initializePluginFunction = nullptr;
other.m_getPluginNameFunction = nullptr;
other.m_getPluginAuthorFunction = nullptr;
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;

View File

@ -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();
}
}

View File

@ -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() {

View File

@ -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) { }
}

View File

@ -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);
}

View File

@ -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))) {

View File

@ -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) {

View File

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

View File

@ -5,8 +5,13 @@
#include <locale>
#include <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) {

View File

@ -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);

View File

@ -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;

View File

@ -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();
}
}

View File

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

View File

@ -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);

View File

@ -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 ()

View File

@ -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();
}

View File

@ -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;

View File

@ -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();

View File

@ -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},
{ "Unloading plugins...", unloadPlugins },
{ "Saving settings...", storeSettings },
{ "Cleaning up shared data...", deleteSharedData },
{ "Unloading plugins...", unloadPlugins },
};
}
std::vector<Argument> &getInitArguments() {
static std::vector<Argument> initArguments;
return initArguments;
}
}

View File

@ -2,7 +2,6 @@
#include <hex/helpers/utils.hpp>
#include <hex/helpers/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

View File

@ -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>

View File

@ -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>

View File

@ -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));

View File

@ -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)
assert(false);
#else
std::raise(signalNumber);
#endif
#if defined(DEBUG)
assert(false);
#else
std::raise(signalNumber);
#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;

View File

@ -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

View File

@ -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;
};
}

View File

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

View File

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

View File

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

View File

@ -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>

View File

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

View File

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

View File

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

View File

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

View File

@ -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>

View File

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

View File

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

View File

@ -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;
};
}

View File

@ -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;

View File

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

View File

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

View File

@ -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>

View File

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

View File

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

View File

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

View File

@ -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>

View File

@ -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>

View File

@ -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 {

View File

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

View File

@ -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;

View File

@ -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...) */

View File

@ -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>

View File

@ -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 {

View File

@ -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 {

View File

@ -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>

View File

@ -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>

View File

@ -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);
}
}

View File

@ -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();
}
}

View File

@ -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();

View File

@ -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)) {

View File

@ -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);
}
}

View File

@ -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;
}

View File

@ -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 &region = 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 &region = 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);

View File

@ -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);

View File

@ -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);
}

View File

@ -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()) {
TextEditor::ErrorMarkers errorMarkers = { { error->getLineNumber(), error->what() } };
this->m_textEditor.SetErrorMarkers(errorMarkers);
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();
}

View File

@ -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;
}
});

View File

@ -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;
}
});

View File

@ -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();
}

View File

@ -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 {

View File

@ -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;

View File

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

View File

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

View File

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

View File

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

View File

@ -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