mirror of
https://github.com/WerWolv/ImHex.git
synced 2026-03-28 15:57:03 -05:00
Compare commits
1 Commits
v1.37.4
...
feature/mu
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
efe0928fc6 |
111
.github/workflows/build.yml
vendored
111
.github/workflows/build.yml
vendored
@@ -15,8 +15,8 @@ env:
|
||||
|
||||
jobs:
|
||||
|
||||
# Windows MINGW build
|
||||
win_mingw:
|
||||
# Windows build
|
||||
win:
|
||||
runs-on: windows-2022
|
||||
name: 🪟 Windows MINGW64
|
||||
|
||||
@@ -41,8 +41,8 @@ jobs:
|
||||
uses: hendrikmuhs/ccache-action@v1
|
||||
id: cache-ccache
|
||||
with:
|
||||
key: ${{ runner.os }}-mingw-ccache-${{ github.run_id }}
|
||||
restore-keys: ${{ runner.os }}-mingw-ccache
|
||||
key: ${{ runner.os }}-ccache-${{ github.run_id }}
|
||||
restore-keys: ${{ runner.os }}-ccache
|
||||
max-size: 1G
|
||||
|
||||
- name: 🟦 Install msys2
|
||||
@@ -140,7 +140,7 @@ jobs:
|
||||
|
||||
- name: 🗝️ Generate build provenance attestations
|
||||
uses: actions/attest-build-provenance@v2
|
||||
if: ${{ github.event.repository.fork == false && github.event_name != 'pull_request' }}
|
||||
if: github.event.pull_request.head.repo.full_name == github.repository
|
||||
with:
|
||||
subject-path: |
|
||||
imhex-*.msi
|
||||
@@ -178,80 +178,6 @@ jobs:
|
||||
path: |
|
||||
build/install/*
|
||||
|
||||
win_msvc:
|
||||
runs-on: windows-2022
|
||||
name: 🪟 Windows MSVC
|
||||
|
||||
env:
|
||||
CCACHE_DIR: "${{ github.workspace }}/.ccache"
|
||||
|
||||
permissions:
|
||||
id-token: write
|
||||
attestations: write
|
||||
|
||||
steps:
|
||||
- name: 🧰 Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- name: 🫧 Setup Visual Studio Dev Environment
|
||||
uses: ilammy/msvc-dev-cmd@v1
|
||||
with:
|
||||
arch: amd64
|
||||
|
||||
- name: 📜 Setup ccache
|
||||
uses: hendrikmuhs/ccache-action@v1
|
||||
id: cache-ccache
|
||||
with:
|
||||
key: ${{ runner.os }}-msvc-ccache-${{ github.run_id }}
|
||||
restore-keys: ${{ runner.os }}-msvc-ccache
|
||||
max-size: 1G
|
||||
|
||||
- name: 📦 Install vcpkg
|
||||
uses: friendlyanon/setup-vcpkg@v1
|
||||
with: { committish: 7e21420f775f72ae938bdeb5e6068f722088f06a }
|
||||
|
||||
- name: ⬇️ Install dependencies
|
||||
run: |
|
||||
cp dist/vcpkg.json vcpkg.json
|
||||
|
||||
- name: ⬇️ Install CMake and Ninja
|
||||
uses: lukka/get-cmake@latest
|
||||
|
||||
- name: ⬇️ Install .NET
|
||||
uses: actions/setup-dotnet@v4
|
||||
with:
|
||||
dotnet-version: '8.0.100'
|
||||
|
||||
- name: 📜 Set version variable
|
||||
run: |
|
||||
"IMHEX_VERSION=$(Get-Content VERSION -Raw)" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
|
||||
|
||||
# Windows cmake build
|
||||
- name: 🛠️ Configure CMake
|
||||
run: |
|
||||
mkdir -p build
|
||||
|
||||
cmake -G "Ninja" -B build `
|
||||
--preset vs2022 `
|
||||
-DCMAKE_TOOLCHAIN_FILE="$env:VCPKG_ROOT/scripts/buildsystems/vcpkg.cmake" `
|
||||
-DCMAKE_C_COMPILER="$($(Get-Command cl.exe).Path)" `
|
||||
-DCMAKE_CXX_COMPILER="$($(Get-Command cl.exe).Path)" `
|
||||
-DCMAKE_C_COMPILER_LAUNCHER=ccache `
|
||||
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache `
|
||||
-DCMAKE_BUILD_TYPE="$env:BUILD_TYPE" `
|
||||
-DIMHEX_PATTERNS_PULL_MASTER=ON `
|
||||
-DIMHEX_COMMIT_HASH_LONG="$env:GITHUB_SHA" `
|
||||
-DIMHEX_COMMIT_BRANCH="$($env:GITHUB_REF -replace '.*/', '')" `
|
||||
-DDOTNET_EXECUTABLE="C:/Program Files/dotnet/dotnet.exe" `
|
||||
.
|
||||
|
||||
- name: 🛠️ Build
|
||||
run: |
|
||||
cd build
|
||||
ninja
|
||||
|
||||
win-plugin-template-test:
|
||||
runs-on: windows-2022
|
||||
name: 🧪 Plugin Template Test
|
||||
@@ -260,7 +186,7 @@ jobs:
|
||||
run:
|
||||
shell: msys2 {0}
|
||||
|
||||
needs: win_mingw
|
||||
needs: win
|
||||
|
||||
env:
|
||||
IMHEX_SDK_PATH: "${{ github.workspace }}/out/sdk"
|
||||
@@ -443,7 +369,7 @@ jobs:
|
||||
|
||||
- name: 📦 Create DMG
|
||||
run: |
|
||||
brew install graphicsmagick imagemagick
|
||||
brew install imagemagick
|
||||
git clone https://github.com/sindresorhus/create-dmg
|
||||
cd create-dmg
|
||||
npm i && npm -g i
|
||||
@@ -458,7 +384,7 @@ jobs:
|
||||
|
||||
- name: 🗝️ Generate build provenance attestations
|
||||
uses: actions/attest-build-provenance@v2
|
||||
if: ${{ github.event.repository.fork == false && github.event_name != 'pull_request' }}
|
||||
if: github.event.pull_request.head.repo.full_name == github.repository
|
||||
with:
|
||||
subject-path: |
|
||||
./*.dmg
|
||||
@@ -500,7 +426,6 @@ jobs:
|
||||
run: |
|
||||
echo "IMHEX_VERSION=`cat VERSION`" >> $GITHUB_OUTPUT
|
||||
docker buildx build . -f dist/macOS/arm64.Dockerfile --progress=plain --build-arg 'JOBS=4' --build-arg "BUILD_TYPE=$(BUILD_TYPE)" --build-context imhex=$(pwd) --output out
|
||||
cp resources/dist/macos/Entitlements.plist out/Entitlements.plist
|
||||
|
||||
- name: ⬆️ Upload artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
@@ -523,7 +448,7 @@ jobs:
|
||||
needs: macos-arm64
|
||||
|
||||
env:
|
||||
IMHEX_VERSION: ${{ needs.macos-arm64.outputs.IMHEX_VERSION }}
|
||||
IMHEX_VERSION: ${{ needs.macos-arm64-build.outputs.IMHEX_VERSION }}
|
||||
|
||||
permissions:
|
||||
id-token: write
|
||||
@@ -547,7 +472,7 @@ jobs:
|
||||
cd out
|
||||
mv imhex.app ImHex.app
|
||||
codesign --remove-signature ImHex.app
|
||||
codesign --force --deep --entitlements Entitlements.plist --sign - ImHex.app
|
||||
codesign --force --deep --sign - ImHex.app
|
||||
|
||||
- name: 📁 Fix permissions
|
||||
run: |
|
||||
@@ -563,7 +488,7 @@ jobs:
|
||||
|
||||
- name: 📦 Create DMG
|
||||
run: |
|
||||
brew install graphicsmagick imagemagick
|
||||
brew install imagemagick
|
||||
git clone https://github.com/sindresorhus/create-dmg
|
||||
cd create-dmg
|
||||
npm i && npm -g i
|
||||
@@ -578,7 +503,7 @@ jobs:
|
||||
|
||||
- name: 🗝️ Generate build provenance attestations
|
||||
uses: actions/attest-build-provenance@v2
|
||||
if: ${{ github.event.repository.fork == false && github.event_name != 'pull_request' }}
|
||||
if: github.event.pull_request.head.repo.full_name == github.repository
|
||||
with:
|
||||
subject-path: |
|
||||
./*.dmg
|
||||
@@ -672,7 +597,7 @@ jobs:
|
||||
|
||||
- name: 🗝️ Generate build provenance attestations
|
||||
uses: actions/attest-build-provenance@v2
|
||||
if: ${{ github.event.repository.fork == false && github.event_name != 'pull_request' }}
|
||||
if: github.event.pull_request.head.repo.full_name == github.repository
|
||||
with:
|
||||
subject-path: |
|
||||
./*.deb
|
||||
@@ -716,8 +641,8 @@ jobs:
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: cache
|
||||
key: appimage-ccache-${{ matrix.architecture }}-${{ github.run_id }}
|
||||
restore-keys: appimage-ccache-${{ matrix.architecture }}
|
||||
key: appimage-ccache-${{ github.run_id }}
|
||||
restore-keys: appimage-cache
|
||||
|
||||
- name: 🐳 Inject /cache into docker
|
||||
uses: reproducible-containers/buildkit-cache-dance@v2
|
||||
@@ -734,7 +659,7 @@ jobs:
|
||||
|
||||
- name: 🗝️ Generate build provenance attestations
|
||||
uses: actions/attest-build-provenance@v2
|
||||
if: ${{ github.event.repository.fork == false && github.event_name != 'pull_request' }}
|
||||
if: github.event.pull_request.head.repo.full_name == github.repository
|
||||
with:
|
||||
subject-path: |
|
||||
out/*.AppImage
|
||||
@@ -851,7 +776,7 @@ jobs:
|
||||
|
||||
- name: 🗝️ Generate build provenance attestations
|
||||
uses: actions/attest-build-provenance@v2
|
||||
if: ${{ github.event.repository.fork == false && github.event_name != 'pull_request' }}
|
||||
if: github.event.pull_request.head.repo.full_name == github.repository
|
||||
with:
|
||||
subject-path: |
|
||||
build/imhex-${{ env.IMHEX_VERSION }}-ArchLinux-x86_64.pkg.tar.zst
|
||||
@@ -995,7 +920,7 @@ jobs:
|
||||
|
||||
- name: 🗝️ Generate build provenance attestations
|
||||
uses: actions/attest-build-provenance@v2
|
||||
if: ${{ github.event.repository.fork == false && github.event_name != 'pull_request' }}
|
||||
if: github.event.pull_request.head.repo.full_name == github.repository
|
||||
with:
|
||||
subject-path: |
|
||||
imhex-${{ env.IMHEX_VERSION }}-${{ matrix.name }}-${{ matrix.release_num }}-x86_64.rpm
|
||||
|
||||
2
.gitignore
vendored
2
.gitignore
vendored
@@ -7,7 +7,6 @@ build*/
|
||||
local/
|
||||
venv/
|
||||
.cache/
|
||||
install/
|
||||
|
||||
*.mgc
|
||||
*.kdev4
|
||||
@@ -17,4 +16,3 @@ CMakeUserPresets.json
|
||||
Brewfile.lock.json
|
||||
|
||||
.vs/
|
||||
vcpkg.json
|
||||
|
||||
@@ -49,8 +49,12 @@
|
||||
{
|
||||
"name": "vs2022",
|
||||
"displayName": "Visual Studio 2022",
|
||||
"generator": "Ninja",
|
||||
"generator": "Visual Studio 17 2022",
|
||||
"binaryDir": "${sourceDir}/build/${presetName}",
|
||||
"architecture": {
|
||||
"strategy": "set",
|
||||
"value": "x64"
|
||||
},
|
||||
"cacheVariables": {
|
||||
"CMAKE_TOOLCHAIN_FILE": "$env{VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake"
|
||||
}
|
||||
|
||||
@@ -381,10 +381,6 @@ endfunction()
|
||||
macro(configureCMake)
|
||||
message(STATUS "Configuring ImHex v${IMHEX_VERSION}")
|
||||
|
||||
if (DEFINED CMAKE_TOOLCHAIN_FILE)
|
||||
message(STATUS "Using toolchain file: \"${CMAKE_TOOLCHAIN_FILE}\"")
|
||||
endif()
|
||||
|
||||
set(CMAKE_POSITION_INDEPENDENT_CODE ON CACHE BOOL "Enable position independent code for all targets" FORCE)
|
||||
|
||||
# Configure use of recommended build tools
|
||||
@@ -632,25 +628,21 @@ endmacro()
|
||||
|
||||
macro(setupCompilerFlags target)
|
||||
if (CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
|
||||
addCommonFlag("/W4" ${target})
|
||||
addCommonFlag("/wd4127" ${target}) # conditional expression is constant
|
||||
addCommonFlag("/wd4242" ${target}) # 'identifier': conversion from 'type1' to 'type2', possible loss of data
|
||||
addCommonFlag("/wd4244" ${target}) # 'conversion': conversion from 'type1' to 'type2', possible loss of data
|
||||
addCommonFlag("/wd4267" ${target}) # 'var': conversion from 'size_t' to 'type', possible loss of data
|
||||
addCommonFlag("/wd4305" ${target}) # truncation from 'double' to 'float'
|
||||
addCommonFlag("/wd4996" ${target}) # 'function': was declared deprecated
|
||||
|
||||
if (IMHEX_STRICT_WARNINGS)
|
||||
addCommonFlag("/WX" ${target})
|
||||
addCommonFlag("/W4" ${target})
|
||||
addCommonFlag("/wd4242" ${target})
|
||||
addCommonFlag("/wd4244" ${target})
|
||||
addCommonFlag("/wd4267" ${target})
|
||||
addCommonFlag("/wd4996" ${target})
|
||||
addCommonFlag("/wd4127" ${target})
|
||||
endif()
|
||||
elseif (CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
|
||||
addCommonFlag("-Wall" ${target})
|
||||
addCommonFlag("-Wextra" ${target})
|
||||
addCommonFlag("-Wpedantic" ${target})
|
||||
|
||||
# Define strict compilation flags
|
||||
if (IMHEX_STRICT_WARNINGS)
|
||||
addCommonFlag("-Werror" ${target})
|
||||
addCommonFlag("-Wall" ${target})
|
||||
addCommonFlag("-Wextra" ${target})
|
||||
addCommonFlag("-Wpedantic" ${target})
|
||||
addCommonFlag("-Werror" ${target})
|
||||
endif()
|
||||
|
||||
if (UNIX AND NOT APPLE AND CMAKE_CXX_COMPILER_ID MATCHES "GNU")
|
||||
@@ -664,17 +656,6 @@ macro(setupCompilerFlags target)
|
||||
addCCXXFlag("-Wno-array-bounds" ${target})
|
||||
addCCXXFlag("-Wno-deprecated-declarations" ${target})
|
||||
addCCXXFlag("-Wno-unknown-pragmas" ${target})
|
||||
|
||||
# Enable hardening flags
|
||||
if (NOT CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||
addCommonFlag("-U_FORTIFY_SOURCE" ${target})
|
||||
addCommonFlag("-D_FORTIFY_SOURCE=3" ${target})
|
||||
|
||||
if (NOT EMSCRIPTEN)
|
||||
addCommonFlag("-fstack-protector-strong" ${target})
|
||||
endif()
|
||||
endif()
|
||||
|
||||
endif()
|
||||
|
||||
if (CMAKE_CXX_COMPILER_ID MATCHES "GNU")
|
||||
@@ -688,12 +669,6 @@ macro(setupCompilerFlags target)
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -L${LLVM_PREFIX}/lib/c++")
|
||||
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -L${LLVM_PREFIX}/lib/c++")
|
||||
addCCXXFlag("-Wno-unknown-warning-option" ${target})
|
||||
|
||||
if (CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||
add_compile_definitions(_LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_DEBUG)
|
||||
else()
|
||||
add_compile_definitions(_LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_EXTENSIVE)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if (CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
|
||||
@@ -803,8 +778,8 @@ macro(addBundledLibraries)
|
||||
add_subdirectory(${THIRD_PARTY_LIBS_FOLDER}/lunasvg EXCLUDE_FROM_ALL)
|
||||
set(LUNASVG_LIBRARIES lunasvg)
|
||||
else()
|
||||
find_package(lunasvg REQUIRED)
|
||||
set(LUNASVG_LIBRARIES lunasvg::lunasvg)
|
||||
find_package(LunaSVG REQUIRED)
|
||||
set(LUNASVG_LIBRARIES lunasvg)
|
||||
endif()
|
||||
|
||||
if (NOT USE_SYSTEM_LLVM)
|
||||
@@ -928,17 +903,11 @@ function(generateSDKDirectory)
|
||||
install(DIRECTORY ${CMAKE_SOURCE_DIR}/cmake/sdk/ DESTINATION "${SDK_PATH}")
|
||||
install(TARGETS libimhex ARCHIVE DESTINATION "${SDK_PATH}/lib")
|
||||
|
||||
install(DIRECTORY ${CMAKE_SOURCE_DIR}/plugins/ui/include DESTINATION "${SDK_PATH}/lib/ui/include")
|
||||
install(FILES ${CMAKE_SOURCE_DIR}/plugins/ui/CMakeLists.txt DESTINATION "${SDK_PATH}/lib/ui/")
|
||||
if (WIN32)
|
||||
install(TARGETS ui ARCHIVE DESTINATION "${SDK_PATH}/lib")
|
||||
endif()
|
||||
install(DIRECTORY ${CMAKE_SOURCE_DIR}/plugins/ui DESTINATION "${SDK_PATH}/lib" PATTERN "**/source/*" EXCLUDE)
|
||||
install(TARGETS ui ARCHIVE DESTINATION "${SDK_PATH}/lib")
|
||||
|
||||
install(DIRECTORY ${CMAKE_SOURCE_DIR}/plugins/fonts/include DESTINATION "${SDK_PATH}/lib/fonts/include")
|
||||
install(FILES ${CMAKE_SOURCE_DIR}/plugins/fonts/CMakeLists.txt DESTINATION "${SDK_PATH}/lib/fonts/")
|
||||
if (WIN32)
|
||||
install(TARGETS fonts ARCHIVE DESTINATION "${SDK_PATH}/lib")
|
||||
endif()
|
||||
install(DIRECTORY ${CMAKE_SOURCE_DIR}/plugins/fonts DESTINATION "${SDK_PATH}/lib" PATTERN "**/source/*" EXCLUDE)
|
||||
install(TARGETS fonts ARCHIVE DESTINATION "${SDK_PATH}/lib")
|
||||
endfunction()
|
||||
|
||||
function(addIncludesFromLibrary target library)
|
||||
|
||||
1
dist/rpm/imhex.spec
vendored
1
dist/rpm/imhex.spec
vendored
@@ -128,5 +128,6 @@ cp -a lib/third_party/xdgpp/LICENSE %{buildroot
|
||||
%{_datadir}/mime/packages/%{name}.xml
|
||||
%{_libdir}/libimhex.so*
|
||||
%{_libdir}/%{name}/
|
||||
%{_libdir}/*.hexpluglib
|
||||
/usr/lib/debug/%{_libdir}/*.debug
|
||||
%{_metainfodir}/net.werwolv.%{name}.metainfo.xml
|
||||
2
lib/external/disassembler
vendored
2
lib/external/disassembler
vendored
Submodule lib/external/disassembler updated: a2217dd3bc...bc4a5d9975
2
lib/external/libwolv
vendored
2
lib/external/libwolv
vendored
Submodule lib/external/libwolv updated: 00021679c2...75c6693441
2
lib/external/pattern_language
vendored
2
lib/external/pattern_language
vendored
Submodule lib/external/pattern_language updated: 9833500589...bc002793b0
@@ -22,6 +22,9 @@ set(LIBIMHEX_SOURCES
|
||||
source/data_processor/link.cpp
|
||||
source/data_processor/node.cpp
|
||||
|
||||
source/project/project.cpp
|
||||
source/project/project_manager.cpp
|
||||
|
||||
source/helpers/utils.cpp
|
||||
source/helpers/utils_linux.cpp
|
||||
source/helpers/fs.cpp
|
||||
@@ -66,10 +69,7 @@ if (APPLE)
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
set(LIBIMHEX_SOURCES ${LIBIMHEX_SOURCES}
|
||||
source/helpers/utils_macos.m
|
||||
source/helpers/macos_menu.m
|
||||
)
|
||||
set(LIBIMHEX_SOURCES ${LIBIMHEX_SOURCES} source/helpers/utils_macos.m)
|
||||
endif ()
|
||||
|
||||
if (IMHEX_EXTERNAL_PLUGIN_BUILD)
|
||||
|
||||
@@ -81,6 +81,7 @@ void* PluginSubCommandsFunctionHelper<T>::getSubCommands() {
|
||||
#define IMHEX_LIBRARY_SETUP(name) IMHEX_LIBRARY_SETUP_IMPL(name)
|
||||
|
||||
#define IMHEX_LIBRARY_SETUP_IMPL(name) \
|
||||
namespace { static struct EXIT_HANDLER { ~EXIT_HANDLER() { hex::log::info("Unloaded library '{}'", name); } } HANDLER; } \
|
||||
IMHEX_PLUGIN_VISIBILITY_PREFIX void WOLV_TOKEN_CONCAT(initializeLibrary_, IMHEX_PLUGIN_NAME)(); \
|
||||
IMHEX_PLUGIN_VISIBILITY_PREFIX const char *WOLV_TOKEN_CONCAT(getLibraryName_, IMHEX_PLUGIN_NAME)() { return name; } \
|
||||
IMHEX_PLUGIN_VISIBILITY_PREFIX void WOLV_TOKEN_CONCAT(setImGuiContext_, IMHEX_PLUGIN_NAME)(ImGuiContext *ctx) { \
|
||||
@@ -106,6 +107,7 @@ void* PluginSubCommandsFunctionHelper<T>::getSubCommands() {
|
||||
IMHEX_PLUGIN_VISIBILITY_PREFIX void WOLV_TOKEN_CONCAT(initializeLibrary_, IMHEX_PLUGIN_NAME)()
|
||||
|
||||
#define IMHEX_PLUGIN_SETUP_IMPL(name, author, description) \
|
||||
namespace { static struct EXIT_HANDLER { ~EXIT_HANDLER() { hex::log::debug("Unloaded plugin '{}'", name); } } HANDLER; } \
|
||||
IMHEX_PLUGIN_VISIBILITY_PREFIX const char *getPluginName() { return name; } \
|
||||
IMHEX_PLUGIN_VISIBILITY_PREFIX const char *getPluginAuthor() { return author; } \
|
||||
IMHEX_PLUGIN_VISIBILITY_PREFIX const char *getPluginDescription() { return description; } \
|
||||
|
||||
57
lib/libimhex/include/hex/project/project.hpp
Normal file
57
lib/libimhex/include/hex/project/project.hpp
Normal file
@@ -0,0 +1,57 @@
|
||||
#pragma once
|
||||
|
||||
#include <hex.hpp>
|
||||
#include <hex/api/localization_manager.hpp>
|
||||
|
||||
#include <memory>
|
||||
#include <list>
|
||||
#include <string>
|
||||
|
||||
namespace hex::proj {
|
||||
|
||||
class Content {
|
||||
public:
|
||||
explicit Content(UnlocalizedString type, std::string name)
|
||||
: m_type(std::move(type)), m_name(std::move(name)) { }
|
||||
|
||||
void setData(std::string data) { m_data = std::move(data); }
|
||||
const std::string& getData() const { return m_data; }
|
||||
|
||||
const std::string& getName() const { return m_name; }
|
||||
void setName(std::string name) { m_name = std::move(name); }
|
||||
|
||||
const UnlocalizedString& getType() const { return m_type; }
|
||||
|
||||
bool isOpen() const { return m_open; }
|
||||
void setOpen(bool open) { m_open = open; }
|
||||
|
||||
bool isEmpty() const { return m_data.empty(); }
|
||||
|
||||
private:
|
||||
UnlocalizedString m_type;
|
||||
std::string m_name;
|
||||
std::string m_data;
|
||||
bool m_open = false;
|
||||
};
|
||||
|
||||
class Project {
|
||||
public:
|
||||
explicit Project(std::string name) : m_name(std::move(name)) {}
|
||||
Project(const Project &) = delete;
|
||||
Project(Project &&) = delete;
|
||||
~Project();
|
||||
|
||||
Project &operator=(const Project &) = delete;
|
||||
Project &operator=(Project &&) = delete;
|
||||
|
||||
const std::string &getName() const { return m_name; }
|
||||
|
||||
void addContent(UnlocalizedString type);
|
||||
const std::list<std::unique_ptr<Content>>& getContents() const { return m_contents; }
|
||||
|
||||
private:
|
||||
std::string m_name;
|
||||
std::list<std::unique_ptr<Content>> m_contents;
|
||||
};
|
||||
|
||||
}
|
||||
43
lib/libimhex/include/hex/project/project_manager.hpp
Normal file
43
lib/libimhex/include/hex/project/project_manager.hpp
Normal file
@@ -0,0 +1,43 @@
|
||||
#pragma once
|
||||
|
||||
#include <hex.hpp>
|
||||
#include <hex/project/project.hpp>
|
||||
|
||||
#include <list>
|
||||
#include <string>
|
||||
#include <filesystem>
|
||||
#include <functional>
|
||||
|
||||
namespace hex::proj {
|
||||
|
||||
class ProjectManager {
|
||||
ProjectManager() = default;
|
||||
|
||||
public:
|
||||
static void createProject(std::string name);
|
||||
static void loadProject(const std::filesystem::path &path);
|
||||
static void removeProject(const Project &project);
|
||||
|
||||
using LoadFunction = std::function<void(const Content&)>;
|
||||
using StoreFunction = std::function<void(Content&)>;
|
||||
|
||||
struct ContentHandler {
|
||||
UnlocalizedString type;
|
||||
bool allowMultiple = false;
|
||||
LoadFunction load;
|
||||
StoreFunction store;
|
||||
};
|
||||
|
||||
static void registerContentHandler(ContentHandler handler);
|
||||
static const std::list<ContentHandler>& getContentHandlers();
|
||||
static const ContentHandler* getContentHandler(const UnlocalizedString &typeName);
|
||||
|
||||
static const std::list<std::unique_ptr<Project>> &getProjects();
|
||||
|
||||
static void storeContent(Content &content);
|
||||
static void loadContent(Content &content);
|
||||
|
||||
static Content* getLoadedContent(const UnlocalizedString &type);
|
||||
};
|
||||
|
||||
}
|
||||
@@ -749,14 +749,13 @@ namespace hex {
|
||||
DSROLE_PRIMARY_DOMAIN_INFO_BASIC * info;
|
||||
if ((DsRoleGetPrimaryDomainInformation(NULL, DsRolePrimaryDomainInfoBasic, (PBYTE *)&info) == ERROR_SUCCESS) && (info != nullptr))
|
||||
{
|
||||
bool result = std::wstring(info->DomainNameFlat) != L"WORKGROUP";
|
||||
bool result = std::wstring(info->DomainNameFlat).empty();
|
||||
DsRoleFreeMemory(info);
|
||||
|
||||
return result;
|
||||
} else {
|
||||
DWORD size = 128;
|
||||
char buffer[128];
|
||||
::GetComputerNameExA(ComputerNameDnsDomain, buffer, &size);
|
||||
DWORD size = 1024;
|
||||
::GetComputerNameExA(ComputerNameDnsDomain, nullptr, &size);
|
||||
return size > 0;
|
||||
}
|
||||
}
|
||||
@@ -872,8 +871,7 @@ namespace hex {
|
||||
|
||||
SemanticVersion getImHexVersion() {
|
||||
#if defined IMHEX_VERSION
|
||||
static auto version = SemanticVersion(IMHEX_VERSION);
|
||||
return version;
|
||||
return SemanticVersion(IMHEX_VERSION);
|
||||
#else
|
||||
return {};
|
||||
#endif
|
||||
@@ -937,7 +935,7 @@ namespace hex {
|
||||
}
|
||||
|
||||
EventImHexClosing::subscribe([executablePath, updateTypeString] {
|
||||
hex::startProgram(
|
||||
hex::executeCommand(
|
||||
hex::format("\"{}\" \"{}\"",
|
||||
wolv::util::toUTF8String(executablePath),
|
||||
updateTypeString
|
||||
|
||||
@@ -30,11 +30,7 @@ namespace hex {
|
||||
|
||||
return handle;
|
||||
#else
|
||||
const auto pathString = wolv::util::toUTF8String(path);
|
||||
|
||||
auto handle = uintptr_t(dlopen(pathString.c_str(), RTLD_NOLOAD));
|
||||
if (handle == 0)
|
||||
handle = uintptr_t(dlopen(pathString.c_str(), RTLD_NOW | RTLD_GLOBAL));
|
||||
auto handle = uintptr_t(dlopen(wolv::util::toUTF8String(path).c_str(), RTLD_LAZY));
|
||||
|
||||
if (handle == 0) {
|
||||
log::error("Loading library '{}' failed: {}!", wolv::util::toUTF8String(path.filename()), dlerror());
|
||||
|
||||
@@ -327,7 +327,6 @@ namespace hex {
|
||||
}
|
||||
|
||||
ImGui::SetNextWindowPos(position, ImGuiCond_Always, pivot);
|
||||
ImGui::SetNextWindowViewport(ImGui::GetMainViewport()->ID);
|
||||
if (ImGui::Begin("##TutorialMessage", nullptr, ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoScrollWithMouse | ImGuiWindowFlags_NoDocking | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoFocusOnAppearing)) {
|
||||
ImGui::BringWindowToDisplayFront(ImGui::GetCurrentWindowRead());
|
||||
|
||||
|
||||
@@ -44,7 +44,7 @@ namespace hex::paths {
|
||||
|
||||
if (includeSystemFolders) {
|
||||
if (auto executablePath = wolv::io::fs::getExecutablePath(); executablePath.has_value()) {
|
||||
paths.push_back(executablePath->parent_path());
|
||||
paths.push_back(*executablePath);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -339,9 +339,9 @@ namespace hex {
|
||||
void startProgram(const std::string &command) {
|
||||
|
||||
#if defined(OS_WINDOWS)
|
||||
std::ignore = system(hex::format("start \"\" {0}", command).c_str());
|
||||
std::ignore = system(hex::format("start {0}", command).c_str());
|
||||
#elif defined(OS_MACOS)
|
||||
std::ignore = system(hex::format("{0}", command).c_str());
|
||||
std::ignore = system(hex::format("open {0}", command).c_str());
|
||||
#elif defined(OS_LINUX)
|
||||
executeCmd({"xdg-open", command});
|
||||
#elif defined(OS_WEB)
|
||||
|
||||
28
lib/libimhex/source/project/project.cpp
Normal file
28
lib/libimhex/source/project/project.cpp
Normal file
@@ -0,0 +1,28 @@
|
||||
#include <hex/project/project.hpp>
|
||||
#include <hex/project/project_manager.hpp>
|
||||
|
||||
namespace hex::proj {
|
||||
|
||||
Project::~Project() {
|
||||
for (auto &content : m_contents) {
|
||||
ProjectManager::storeContent(*content);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Project::addContent(UnlocalizedString type) {
|
||||
const auto &content = m_contents.emplace_back(
|
||||
std::make_unique<Content>(
|
||||
type,
|
||||
fmt::format("Unnamed {}", Lang(type))
|
||||
)
|
||||
);
|
||||
|
||||
const auto loadedContent = ProjectManager::getLoadedContent(type);
|
||||
ProjectManager::storeContent(loadedContent == nullptr ? *content : *loadedContent);
|
||||
|
||||
ProjectManager::loadContent(*content);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
89
lib/libimhex/source/project/project_manager.cpp
Normal file
89
lib/libimhex/source/project/project_manager.cpp
Normal file
@@ -0,0 +1,89 @@
|
||||
#include <hex/helpers/auto_reset.hpp>
|
||||
#include <hex/project/project_manager.hpp>
|
||||
|
||||
namespace hex::proj {
|
||||
|
||||
static AutoReset<std::list<std::unique_ptr<Project>>> s_projects;
|
||||
static AutoReset<std::list<ProjectManager::ContentHandler>> s_contentHandlers;
|
||||
|
||||
void ProjectManager::createProject(std::string name) {
|
||||
s_projects->emplace_back(std::make_unique<Project>(std::move(name)));
|
||||
}
|
||||
|
||||
void ProjectManager::loadProject(const std::filesystem::path &path) {
|
||||
std::ignore = path;
|
||||
}
|
||||
|
||||
void ProjectManager::removeProject(const Project &projectToClose) {
|
||||
std::erase_if(*s_projects, [&](const std::unique_ptr<Project> &project) {
|
||||
return project.get() == &projectToClose;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
const std::list<std::unique_ptr<Project>> &ProjectManager::getProjects() {
|
||||
return *s_projects;
|
||||
}
|
||||
|
||||
const std::list<ProjectManager::ContentHandler> &ProjectManager::getContentHandlers() {
|
||||
return *s_contentHandlers;
|
||||
}
|
||||
|
||||
void ProjectManager::registerContentHandler(ContentHandler handler) {
|
||||
s_contentHandlers->emplace_back(std::move(handler));
|
||||
}
|
||||
|
||||
const ProjectManager::ContentHandler* ProjectManager::getContentHandler(const UnlocalizedString &typeName) {
|
||||
for (const auto &handler : getContentHandlers()) {
|
||||
if (handler.type == typeName) {
|
||||
return &handler;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void ProjectManager::storeContent(Content &content) {
|
||||
const auto *handler = getContentHandler(content.getType());
|
||||
if (handler != nullptr) {
|
||||
handler->store(content);
|
||||
}
|
||||
}
|
||||
|
||||
void ProjectManager::loadContent(Content &content) {
|
||||
const auto *handler = getContentHandler(content.getType());
|
||||
|
||||
if (handler != nullptr) {
|
||||
if (!handler->allowMultiple) {
|
||||
for (const auto &project : getProjects()) {
|
||||
for (const auto &projectContent : project->getContents()) {
|
||||
if (projectContent->isOpen() && projectContent->getType() == content.getType()) {
|
||||
storeContent(*projectContent);
|
||||
projectContent->setOpen(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (handler->type == content.getType()) {
|
||||
handler->load(content);
|
||||
content.setOpen(true);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Content* ProjectManager::getLoadedContent(const UnlocalizedString& type) {
|
||||
for (const auto &project : getProjects()) {
|
||||
for (const auto &projectContent : project->getContents()) {
|
||||
if (projectContent->isOpen() && projectContent->getType() == type) {
|
||||
return projectContent.get();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -260,6 +260,9 @@ namespace ImGuiExt {
|
||||
}
|
||||
|
||||
Texture::Texture(Texture&& other) noexcept {
|
||||
if (m_textureId != 0)
|
||||
glDeleteTextures(1, reinterpret_cast<GLuint*>(&m_textureId));
|
||||
|
||||
m_textureId = other.m_textureId;
|
||||
m_width = other.m_width;
|
||||
m_height = other.m_height;
|
||||
@@ -268,10 +271,8 @@ namespace ImGuiExt {
|
||||
}
|
||||
|
||||
Texture& Texture::operator=(Texture&& other) noexcept {
|
||||
if (this == &other)
|
||||
return *this;
|
||||
|
||||
this->reset();
|
||||
if (m_textureId != 0)
|
||||
glDeleteTextures(1, reinterpret_cast<GLuint*>(&m_textureId));
|
||||
|
||||
m_textureId = other.m_textureId;
|
||||
m_width = other.m_width;
|
||||
@@ -287,11 +288,6 @@ namespace ImGuiExt {
|
||||
}
|
||||
|
||||
void Texture::reset() {
|
||||
#if !defined(OS_WEB)
|
||||
if (glDeleteTextures == nullptr)
|
||||
return;
|
||||
#endif
|
||||
|
||||
if (m_textureId != 0) {
|
||||
glDeleteTextures(1, reinterpret_cast<GLuint*>(&m_textureId));
|
||||
m_textureId = 0;
|
||||
@@ -334,21 +330,16 @@ namespace ImGuiExt {
|
||||
bool pressed = ButtonBehavior(bb, id, &hovered, &held, flags);
|
||||
|
||||
// Render
|
||||
BeginGroup();
|
||||
TextDisabled("%s", icon);
|
||||
SameLine();
|
||||
|
||||
const ImU32 col = hovered ? GetColorU32(ImGuiCol_ButtonHovered) : GetColorU32(ImGuiCol_ButtonActive);
|
||||
PushStyleColor(ImGuiCol_Text, ImU32(col));
|
||||
TextUnformatted(label);
|
||||
|
||||
Text("%s %s", icon, label);
|
||||
|
||||
if (hovered)
|
||||
GetWindowDrawList()->AddLine(ImVec2(pos.x, pos.y + size.y), pos + size, ImU32(col));
|
||||
|
||||
PopStyleColor();
|
||||
|
||||
EndGroup();
|
||||
|
||||
IMGUI_TEST_ENGINE_ITEM_INFO(id, label, g.LastItemData.StatusFlags);
|
||||
return pressed;
|
||||
}
|
||||
@@ -830,11 +821,8 @@ namespace ImGuiExt {
|
||||
PushStyleColor(ImGuiCol_Text, color);
|
||||
|
||||
// Render
|
||||
ImU32 col = 0x00;
|
||||
if (held)
|
||||
col = GetColorU32(ImGuiCol_ScrollbarGrabActive);
|
||||
else if (hovered)
|
||||
col = GetColorU32(ImGuiCol_ScrollbarGrabHovered);
|
||||
const ImU32 col = GetColorU32((held && hovered) ? ImGuiCol_ScrollbarGrabActive : hovered ? ImGuiCol_ScrollbarGrabHovered
|
||||
: ImGuiCol_MenuBarBg);
|
||||
RenderNavCursor(bb, id);
|
||||
RenderFrame(bb.Min, bb.Max, col, false, style.FrameRounding);
|
||||
RenderTextClipped(bb.Min + padding, bb.Max - padding, symbol, nullptr, &size, style.ButtonTextAlign, &bb);
|
||||
|
||||
@@ -299,7 +299,7 @@ public:
|
||||
|
||||
void Render(const char* aTitle, const ImVec2& aSize = ImVec2(), bool aBorder = false);
|
||||
void SetText(const std::string& aText);
|
||||
void JumpToLine(int line=-1);
|
||||
void JumpToLine(int line);
|
||||
void JumpToCoords(const Coordinates &coords);
|
||||
std::string GetText() const;
|
||||
bool isEmpty() const {
|
||||
@@ -352,7 +352,6 @@ public:
|
||||
void SetReadOnly(bool aValue);
|
||||
bool IsReadOnly() const { return mReadOnly; }
|
||||
bool IsTextChanged() const { return mTextChanged; }
|
||||
void SetTextChanged(bool aValue=false) { mTextChanged = aValue; }
|
||||
bool IsCursorPositionChanged() const { return mCursorPositionChanged; }
|
||||
bool IsBreakpointsChanged() const { return mBreakPointsChanged; }
|
||||
void ClearBreakpointsChanged() { mBreakPointsChanged = false; }
|
||||
@@ -579,7 +578,7 @@ private:
|
||||
void HandleKeyboardInputs();
|
||||
void HandleMouseInputs();
|
||||
void RenderText(const char *aTitle, const ImVec2 &lineNumbersStartPos, const ImVec2 &textEditorSize);
|
||||
void SetFocus();
|
||||
|
||||
float mLineSpacing = 1.0F;
|
||||
Lines mLines;
|
||||
EditorState mState = {};
|
||||
|
||||
@@ -865,18 +865,6 @@ inline void TextUnformattedColoredAt(const ImVec2 &pos, const ImU32 &color, cons
|
||||
ImGui::PopStyleColor();
|
||||
}
|
||||
|
||||
void TextEditor::SetFocus() {
|
||||
mState.mCursorPosition = mInteractiveStart = mInteractiveEnd = mFocusAtCoords;
|
||||
mSelectionMode = SelectionMode::Normal;
|
||||
SetSelection(mInteractiveStart, mInteractiveEnd, mSelectionMode);
|
||||
ResetCursorBlinkTime();
|
||||
EnsureCursorVisible();
|
||||
if (!this->mReadOnly) {
|
||||
ImGui::SetKeyboardFocusHere(-1);
|
||||
mUpdateFocus = false;
|
||||
}
|
||||
}
|
||||
|
||||
void TextEditor::RenderText(const char *aTitle, const ImVec2 &lineNumbersStartPos, const ImVec2 &textEditorSize) {
|
||||
/* Compute mCharAdvance regarding scaled font size (Ctrl + mouse wheel)*/
|
||||
const float fontSize = ImGui::GetFont()->CalcTextSizeA(ImGui::GetFontSize(), FLT_MAX, -1.0f, "#", nullptr, nullptr).x;
|
||||
@@ -1080,10 +1068,6 @@ void TextEditor::RenderText(const char *aTitle, const ImVec2 &lineNumbersStartPo
|
||||
auto prevColor = line.empty() ? mPalette[(int)PaletteIndex::Default] : GetGlyphColor(line[0]);
|
||||
ImVec2 bufferOffset;
|
||||
|
||||
if (mUpdateFocus && mFocusAtCoords == Coordinates(lineNo, 0)) {
|
||||
SetFocus();
|
||||
}
|
||||
|
||||
for (int i = 0; i < line.size();) {
|
||||
auto &glyph = line[i];
|
||||
auto color = GetGlyphColor(glyph);
|
||||
@@ -1122,7 +1106,13 @@ void TextEditor::RenderText(const char *aTitle, const ImVec2 &lineNumbersStartPo
|
||||
prevColor = color;
|
||||
|
||||
if (mUpdateFocus && mFocusAtCoords == Coordinates(lineNo, i)) {
|
||||
SetFocus();
|
||||
mState.mCursorPosition = mInteractiveStart = mInteractiveEnd = mFocusAtCoords;
|
||||
mSelectionMode = SelectionMode::Normal;
|
||||
SetSelection(mInteractiveStart, mInteractiveEnd, mSelectionMode);
|
||||
ResetCursorBlinkTime();
|
||||
EnsureCursorVisible();
|
||||
ImGui::SetKeyboardFocusHere(-1);
|
||||
mUpdateFocus = false;
|
||||
}
|
||||
|
||||
if (glyph.mChar == '\t') {
|
||||
@@ -1216,6 +1206,7 @@ void TextEditor::RenderText(const char *aTitle, const ImVec2 &lineNumbersStartPo
|
||||
|
||||
void TextEditor::Render(const char *aTitle, const ImVec2 &aSize, bool aBorder) {
|
||||
mWithinRender = true;
|
||||
mTextChanged = false;
|
||||
mCursorPositionChanged = false;
|
||||
|
||||
auto scrollBg = ImGui::GetStyleColorVec4(ImGuiCol_ScrollbarBg);
|
||||
@@ -1643,10 +1634,7 @@ void TextEditor::DeleteSelection() {
|
||||
}
|
||||
|
||||
void TextEditor::JumpToLine(int line) {
|
||||
auto newPos = mState.mCursorPosition;
|
||||
if (line != -1) {
|
||||
newPos = Coordinates(line , 0);
|
||||
}
|
||||
auto newPos = Coordinates(line, 0);
|
||||
JumpToCoords(newPos);
|
||||
}
|
||||
|
||||
@@ -1870,11 +1858,8 @@ void TextEditor::TextEditor::MoveBottom(bool aSelect) {
|
||||
void TextEditor::MoveHome(bool aSelect) {
|
||||
ResetCursorBlinkTime();
|
||||
auto oldPos = mState.mCursorPosition;
|
||||
auto &line = mLines[mState.mCursorPosition.mLine];
|
||||
auto home=0;
|
||||
while (isspace(line[home].mChar))
|
||||
home++;
|
||||
SetCursorPosition(Coordinates(mState.mCursorPosition.mLine, home));
|
||||
SetCursorPosition(Coordinates(mState.mCursorPosition.mLine, 0));
|
||||
|
||||
if (mState.mCursorPosition != oldPos) {
|
||||
if (aSelect) {
|
||||
if (oldPos == mInteractiveStart)
|
||||
|
||||
@@ -53,9 +53,6 @@ namespace hex {
|
||||
void drawImGui();
|
||||
void drawWithShader();
|
||||
|
||||
void unlockFrameRate();
|
||||
void forceNewFrame();
|
||||
|
||||
GLFWwindow *m_window = nullptr;
|
||||
|
||||
std::string m_windowTitle, m_windowTitleFull;
|
||||
@@ -67,22 +64,17 @@ namespace hex {
|
||||
std::list<std::string> m_popupsToOpen;
|
||||
std::set<int> m_pressedKeys;
|
||||
|
||||
std::atomic<bool> m_unlockFrameRate = true;
|
||||
|
||||
ImGuiExt::ImHexCustomData m_imguiCustomData;
|
||||
|
||||
u32 m_searchBarPosition = 0;
|
||||
bool m_emergencyPopupOpen = false;
|
||||
|
||||
std::jthread m_frameRateThread;
|
||||
std::chrono::duration<double, std::nano> m_remainingUnlockedTime;
|
||||
|
||||
std::mutex m_sleepMutex;
|
||||
std::atomic<bool> m_sleepFlag;
|
||||
std::condition_variable m_sleepCondVar;
|
||||
|
||||
std::mutex m_wakeupMutex;
|
||||
std::atomic<bool> m_wakeupFlag;
|
||||
std::condition_variable m_wakeupCondVar;
|
||||
|
||||
std::mutex m_sleepMutex;
|
||||
|
||||
gl::Shader m_postProcessingShader;
|
||||
};
|
||||
|
||||
@@ -40,20 +40,16 @@ namespace hex::init {
|
||||
// On Windows, argv contains UTF-16 encoded strings, so we need to convert them to UTF-8
|
||||
auto convertedCommandLine = ::CommandLineToArgvW(::GetCommandLineW(), &argc);
|
||||
if (convertedCommandLine == nullptr) {
|
||||
log::error("Failed to get command line arguments");
|
||||
log::error("Failed to convert command line arguments to UTF-8");
|
||||
std::exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
// Skip the first argument (the executable path) and convert the rest to a vector of UTF-8 strings
|
||||
for (int i = 1; i < argc; i += 1) {
|
||||
std::wstring wcharArg = convertedCommandLine[i];
|
||||
auto utf8Arg = wolv::util::wstringToUtf8(wcharArg);
|
||||
if (!utf8Arg.has_value()) {
|
||||
log::error("Failed to convert command line arguments to UTF-8");
|
||||
std::exit(EXIT_FAILURE);
|
||||
}
|
||||
std::string utf8Arg = wolv::util::wstringToUtf8(wcharArg);
|
||||
|
||||
args.push_back(*utf8Arg);
|
||||
args.push_back(utf8Arg);
|
||||
}
|
||||
|
||||
::LocalFree(convertedCommandLine);
|
||||
|
||||
@@ -488,13 +488,7 @@ namespace hex::init {
|
||||
if (meanScale <= 0.0F)
|
||||
meanScale = 1.0F;
|
||||
|
||||
#if defined(OS_WEB)
|
||||
meanScale = 1.0F;
|
||||
#endif
|
||||
|
||||
#if !defined(OS_LINUX)
|
||||
meanScale /= hex::ImHexApi::System::getBackingScaleFactor();
|
||||
#endif
|
||||
meanScale /= hex::ImHexApi::System::getBackingScaleFactor();
|
||||
|
||||
ImHexApi::System::impl::setGlobalScale(meanScale);
|
||||
ImHexApi::System::impl::setNativeScale(meanScale);
|
||||
|
||||
@@ -42,18 +42,12 @@ namespace hex::messaging {
|
||||
|
||||
static auto listenerThread = std::jthread([](const std::stop_token &stopToken){
|
||||
std::vector<u8> buffer(0xFFFF);
|
||||
|
||||
while (true) {
|
||||
while (!stopToken.stop_requested()) {
|
||||
int result = ::read(fifo, buffer.data(), buffer.size());
|
||||
if (result > 0) {
|
||||
EventNativeMessageReceived::post(std::vector<u8>{ buffer.begin(), buffer.begin() + result });
|
||||
}
|
||||
|
||||
if (stopToken.stop_requested())
|
||||
break;
|
||||
|
||||
if (result <= 0) {
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(10));
|
||||
} else {
|
||||
std::this_thread::sleep_for(std::chrono::seconds(1));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -161,7 +161,7 @@ namespace hex {
|
||||
FILE *pipe = popen("dbus-send --session --print-reply --dest=org.freedesktop.portal.Desktop /org/freedesktop/portal/desktop org.freedesktop.portal.Settings.Read string:'org.freedesktop.appearance' string:'color-scheme' 2>&1", "r");
|
||||
if (pipe == nullptr) return;
|
||||
|
||||
while (fgets(buffer.data(), buffer.size() - 1, pipe) != nullptr)
|
||||
while (fgets(buffer.data(), buffer.size(), pipe) != nullptr)
|
||||
result += buffer.data();
|
||||
|
||||
auto exitCode = WEXITSTATUS(pclose(pipe));
|
||||
|
||||
@@ -161,11 +161,12 @@ namespace hex {
|
||||
|
||||
const float currScaleFactor = MAIN_THREAD_EM_ASM_DOUBLE({
|
||||
try {
|
||||
return window.devicePixelRatio;
|
||||
// Take square root of scaling to counter scaling applied by Browser
|
||||
return Math.sqrt(window.devicePixelRatio);
|
||||
} catch (e) {
|
||||
return 1.0;
|
||||
}
|
||||
}) / ImHexApi::System::getBackingScaleFactor();
|
||||
});
|
||||
if (prevScaleFactor != 0 && prevScaleFactor != currScaleFactor) {
|
||||
EventDPIChanged::post(prevScaleFactor, currScaleFactor);
|
||||
resizeCanvas();
|
||||
|
||||
@@ -70,9 +70,6 @@ namespace hex {
|
||||
const auto newScale = LOWORD(wParam) / 96.0F;
|
||||
const auto oldScale = ImHexApi::System::getNativeScale();
|
||||
|
||||
if (u32(oldScale * 10) == u32(newScale * 10))
|
||||
break;
|
||||
|
||||
EventDPIChanged::post(oldScale, newScale);
|
||||
ImHexApi::System::impl::setNativeScale(newScale);
|
||||
|
||||
@@ -204,20 +201,17 @@ namespace hex {
|
||||
|
||||
i64 sleepTicks = 0;
|
||||
i64 sleepMilliSeconds = 0;
|
||||
if (period > 0) {
|
||||
if (delta >= 0) {
|
||||
sleepTicks = delta / period;
|
||||
} else {
|
||||
sleepTicks = -1 + delta / period;
|
||||
}
|
||||
|
||||
sleepMilliSeconds = delta - (period * sleepTicks);
|
||||
const double sleepTime = std::round(1000.0 * double(sleepMilliSeconds) / double(performanceFrequency.QuadPart));
|
||||
if (sleepTime >= 0.0) {
|
||||
Sleep(DWORD(sleepTime));
|
||||
}
|
||||
if (delta >= 0) {
|
||||
sleepTicks = delta / period;
|
||||
} else {
|
||||
sleepTicks = -1 + delta / period;
|
||||
}
|
||||
|
||||
sleepMilliSeconds = delta - (period * sleepTicks);
|
||||
const double sleepTime = std::round(1000.0 * double(sleepMilliSeconds) / double(performanceFrequency.QuadPart));
|
||||
if (sleepTime >= 0.0) {
|
||||
Sleep(DWORD(sleepTime));
|
||||
}
|
||||
timeEndPeriod(granularity);
|
||||
|
||||
return WVR_REDRAW;
|
||||
@@ -617,7 +611,7 @@ namespace hex {
|
||||
|
||||
glfwSetFramebufferSizeCallback(m_window, [](GLFWwindow* window, int width, int height) {
|
||||
auto *win = static_cast<Window *>(glfwGetWindowUserPointer(window));
|
||||
win->unlockFrameRate();
|
||||
win->m_unlockFrameRate = true;
|
||||
|
||||
glViewport(0, 0, width, height);
|
||||
ImHexApi::System::impl::setMainWindowSize(width, height);
|
||||
|
||||
@@ -100,9 +100,6 @@ namespace hex {
|
||||
}
|
||||
|
||||
Window::~Window() {
|
||||
m_frameRateThread.request_stop();
|
||||
m_frameRateThread.join();
|
||||
|
||||
EventProviderDeleted::unsubscribe(this);
|
||||
RequestCloseImHex::unsubscribe(this);
|
||||
RequestUpdateWindowTitle::unsubscribe(this);
|
||||
@@ -303,7 +300,7 @@ namespace hex {
|
||||
|
||||
{
|
||||
std::unique_lock lock(m_sleepMutex);
|
||||
m_sleepCondVar.wait(lock);
|
||||
m_sleepCondVar.wait_for(lock, std::chrono::microseconds(100));
|
||||
if (m_sleepFlag.exchange(false))
|
||||
break;
|
||||
}
|
||||
@@ -314,7 +311,7 @@ namespace hex {
|
||||
|
||||
// Unlock frame rate if any mouse button is being held down to allow drag scrolling to be smooth
|
||||
if (ImGui::IsAnyMouseDown())
|
||||
this->unlockFrameRate();
|
||||
m_unlockFrameRate = true;
|
||||
|
||||
// Unlock frame rate if any modifier key is held down since they don't generate key repeat events
|
||||
if (
|
||||
@@ -323,12 +320,12 @@ namespace hex {
|
||||
ImGui::IsKeyPressed(ImGuiKey_LeftSuper) || ImGui::IsKeyPressed(ImGuiKey_RightSuper) ||
|
||||
ImGui::IsKeyPressed(ImGuiKey_LeftAlt) || ImGui::IsKeyPressed(ImGuiKey_RightAlt)
|
||||
) {
|
||||
this->unlockFrameRate();
|
||||
m_unlockFrameRate = true;
|
||||
}
|
||||
|
||||
// Unlock frame rate if there's more than one viewport since these don't call the glfw callbacks registered here
|
||||
if (ImGui::GetPlatformIO().Viewports.size() > 1)
|
||||
this->unlockFrameRate();
|
||||
m_unlockFrameRate = true;
|
||||
}
|
||||
|
||||
// Hide the window as soon as the render loop exits to make the window
|
||||
@@ -337,9 +334,6 @@ namespace hex {
|
||||
}
|
||||
|
||||
void Window::frameBegin() {
|
||||
// Run all deferred calls
|
||||
TaskManager::runDeferredCalls();
|
||||
|
||||
ImGui_ImplOpenGL3_NewFrame();
|
||||
ImGui_ImplGlfw_NewFrame();
|
||||
|
||||
@@ -349,7 +343,7 @@ namespace hex {
|
||||
auto ¤tFont = ImGui::GetIO().Fonts;
|
||||
for (const auto &[name, font] : fontDefinitions) {
|
||||
// If the texture for this atlas has been built already, don't do it again
|
||||
if (font == nullptr || font->ContainerAtlas == nullptr || font->ContainerAtlas->TexID != 0)
|
||||
if (font == nullptr || font->ContainerAtlas->TexID != 0)
|
||||
continue;
|
||||
|
||||
currentFont = font->ContainerAtlas;
|
||||
@@ -359,7 +353,7 @@ namespace hex {
|
||||
}
|
||||
|
||||
{
|
||||
auto font = ImHexApi::Fonts::getFont("hex.fonts.font.default");
|
||||
const auto &font = ImHexApi::Fonts::getFont("hex.fonts.font.default");
|
||||
|
||||
if (font == nullptr) {
|
||||
const auto &io = ImGui::GetIO();
|
||||
@@ -368,15 +362,13 @@ namespace hex {
|
||||
ImFontConfig cfg;
|
||||
cfg.OversampleH = cfg.OversampleV = 1, cfg.PixelSnapH = true;
|
||||
cfg.SizePixels = ImHexApi::Fonts::DefaultFontSize;
|
||||
font = io.Fonts->AddFontDefault(&cfg);
|
||||
io.Fonts->AddFontDefault(&cfg);
|
||||
ImGui_ImplOpenGL3_CreateFontsTexture();
|
||||
io.Fonts->ClearInputData();
|
||||
io.Fonts->ClearTexData();
|
||||
} else {
|
||||
currentFont = font->ContainerAtlas;
|
||||
}
|
||||
|
||||
ImGui::SetCurrentFont(font);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -690,6 +682,9 @@ namespace hex {
|
||||
return banner->shouldClose();
|
||||
});
|
||||
}
|
||||
|
||||
// Run all deferred calls
|
||||
TaskManager::runDeferredCalls();
|
||||
}
|
||||
|
||||
void Window::frame() {
|
||||
@@ -932,23 +927,6 @@ namespace hex {
|
||||
#endif
|
||||
}
|
||||
|
||||
void Window::unlockFrameRate() {
|
||||
{
|
||||
std::scoped_lock lock(m_wakeupMutex);
|
||||
m_remainingUnlockedTime = std::chrono::seconds(2);
|
||||
}
|
||||
|
||||
this->forceNewFrame();
|
||||
}
|
||||
|
||||
void Window::forceNewFrame() {
|
||||
std::scoped_lock lock(m_wakeupMutex);
|
||||
m_wakeupFlag = true;
|
||||
m_wakeupCondVar.notify_all();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void Window::initGLFW() {
|
||||
auto initialWindowProperties = ImHexApi::System::getInitialWindowProperties();
|
||||
glfwSetErrorCallback([](int error, const char *desc) {
|
||||
@@ -1049,7 +1027,7 @@ namespace hex {
|
||||
if (win == nullptr)
|
||||
return;
|
||||
|
||||
win->unlockFrameRate();
|
||||
win->m_unlockFrameRate = true;
|
||||
};
|
||||
|
||||
static const auto isMainWindow = [](GLFWwindow *window) {
|
||||
@@ -1185,7 +1163,7 @@ namespace hex {
|
||||
Duration passedTime = {};
|
||||
|
||||
std::chrono::steady_clock::time_point startTime = {}, endTime = {};
|
||||
Duration requestedFrameTime = {};
|
||||
Duration requestedFrameTime = {}, remainingUnlockedTime = {};
|
||||
float targetFps = 0;
|
||||
|
||||
const auto nativeFps = []() -> float {
|
||||
@@ -1204,37 +1182,32 @@ namespace hex {
|
||||
|
||||
targetFps = ImHexApi::System::getTargetFPS();
|
||||
|
||||
if (m_unlockFrameRate.exchange(false)) {
|
||||
remainingUnlockedTime = std::chrono::seconds(2);
|
||||
}
|
||||
|
||||
// If the target frame rate is below 15, use the current monitor's refresh rate
|
||||
if (targetFps < 15) {
|
||||
targetFps = nativeFps;
|
||||
}
|
||||
|
||||
passedTime += iterationTime;
|
||||
{
|
||||
if (remainingUnlockedTime > std::chrono::nanoseconds(0)) {
|
||||
remainingUnlockedTime -= iterationTime;
|
||||
} else {
|
||||
targetFps = 5;
|
||||
}
|
||||
|
||||
requestedFrameTime = (Duration(1.0E9) / targetFps) / 1.3;
|
||||
if (passedTime >= requestedFrameTime) {
|
||||
std::scoped_lock lock(m_sleepMutex);
|
||||
m_sleepFlag = true;
|
||||
m_sleepCondVar.notify_all();
|
||||
|
||||
if (m_remainingUnlockedTime > std::chrono::nanoseconds(0)) {
|
||||
m_remainingUnlockedTime -= iterationTime;
|
||||
} else {
|
||||
targetFps = 5;
|
||||
}
|
||||
|
||||
requestedFrameTime = (Duration(1.0E9) / targetFps) / 1.3;
|
||||
if (passedTime >= requestedFrameTime) {
|
||||
m_sleepFlag = true;
|
||||
m_sleepCondVar.notify_all();
|
||||
|
||||
passedTime = {};
|
||||
}
|
||||
passedTime = {};
|
||||
}
|
||||
|
||||
{
|
||||
std::unique_lock lock(m_wakeupMutex);
|
||||
m_wakeupCondVar.wait_for(lock, requestedFrameTime, [&] {
|
||||
return m_wakeupFlag || stopToken.stop_requested();
|
||||
});
|
||||
m_wakeupFlag = false;
|
||||
}
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
||||
|
||||
endTime = std::chrono::steady_clock::now();
|
||||
}
|
||||
|
||||
@@ -7,10 +7,14 @@ add_executable(updater
|
||||
target_compile_definitions(updater PRIVATE IMHEX_PROJECT_NAME="${PROJECT_NAME}")
|
||||
target_link_libraries(updater PRIVATE libimhex ${FMT_LIBRARIES})
|
||||
add_dependencies(main updater)
|
||||
setupCompilerFlags(updater)
|
||||
|
||||
if (APPLE)
|
||||
set(OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/${BUNDLE_NAME}/Contents/MacOS")
|
||||
else ()
|
||||
set(OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}")
|
||||
endif()
|
||||
|
||||
set_target_properties(updater PROPERTIES
|
||||
OUTPUT_NAME "imhex-updater"
|
||||
RUNTIME_OUTPUT_DIRECTORY ${IMHEX_MAIN_OUTPUT_DIRECTORY}
|
||||
RUNTIME_OUTPUT_DIRECTORY ${OUTPUT_DIRECTORY}
|
||||
)
|
||||
@@ -79,26 +79,13 @@ std::string getUpdateType() {
|
||||
if (!hex::ImHexApi::System::isPortableVersion())
|
||||
return "win-msi";
|
||||
#elif defined (OS_MACOS)
|
||||
#if defined(__x86_64__)
|
||||
return "macos-dmg-x86";
|
||||
#elif defined(__arm64__)
|
||||
return "macos-dmg-arm";
|
||||
#endif
|
||||
return "mac-dmg";
|
||||
#elif defined (OS_LINUX)
|
||||
if (hex::executeCommand("grep 'ID=ubuntu' /etc/os-release") == 0) {
|
||||
if (hex::executeCommand("grep 'VERSION_ID=\"24.04\"' /etc/os-release") == 0)
|
||||
return "linux-deb-24.04";
|
||||
else if (hex::executeCommand("grep 'VERSION_ID=\"24.10\"' /etc/os-release") == 0)
|
||||
return "linux-deb-24.10";
|
||||
} else if (hex::executeCommand("grep 'ID=fedora' /etc/os-release") == 0) {
|
||||
if (hex::executeCommand("grep 'VERSION_ID=\"40\"' /etc/os-release") == 0)
|
||||
return "linux-rpm-40";
|
||||
else if (hex::executeCommand("grep 'VERSION_ID=\"41\"' /etc/os-release") == 0)
|
||||
return "linux-rpm-41";
|
||||
else if (hex::executeCommand("grep 'VERSION_ID=\"rawhide\"' /etc/os-release") == 0)
|
||||
return "linux-rpm-rawhide";
|
||||
} else if (hex::executeCommand("grep '^NAME=\"Arch Linux\"' /etc/os-release") == 0) {
|
||||
return "linux-arch";
|
||||
if (hex::executeCommand("lsb_release -a | grep Ubuntu") == 0) {
|
||||
if (hex::executeCommand("lsb_release -a | grep 22.") == 0)
|
||||
return "linux-deb-22.04";
|
||||
else if (hex::executeCommand("lsb_release -a | grep 23.") == 0)
|
||||
return "linux-deb-23.04";
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -113,15 +100,10 @@ int installUpdate(const std::string &type, std::fs::path updatePath) {
|
||||
};
|
||||
|
||||
constexpr static auto UpdateHandlers = {
|
||||
UpdateHandler { "win-msi", ".msi", "msiexec /i \"{}\" /qb" },
|
||||
UpdateHandler { "macos-dmg-x86", ".dmg", "hdiutil attach -autoopen \"{}\"" },
|
||||
UpdateHandler { "macos-dmg-arm", ".dmg", "hdiutil attach -autoopen \"{}\"" },
|
||||
UpdateHandler { "linux-deb-24.04", ".deb", "sudo apt update && sudo apt install -y --fix-broken \"{}\"" },
|
||||
UpdateHandler { "linux-deb-24.10", ".deb", "sudo apt update && sudo apt install -y --fix-broken \"{}\"" },
|
||||
UpdateHandler { "linux-rpm-40", ".rpm", "sudo rpm -i \"{}\"" },
|
||||
UpdateHandler { "linux-rpm-41", ".rpm", "sudo rpm -i \"{}\"" },
|
||||
UpdateHandler { "linux-rpm-rawhide", ".rpm", "sudo rpm -i \"{}\"" },
|
||||
UpdateHandler { "linux-arch", ".zst", "sudo pacman -Syy && sudo pacman -U --noconfirm \"{}\"" }
|
||||
UpdateHandler { "win-msi", ".msi", "msiexec /passive /package {}" },
|
||||
UpdateHandler { "macos-dmg", ".dmg", "hdiutil attach {}" },
|
||||
UpdateHandler { "linux-deb-22.04", ".deb", "sudo apt update && sudo apt install -y --fix-broken {}" },
|
||||
UpdateHandler { "linux-deb-23.04", ".deb", "sudo apt update && sudo apt install -y --fix-broken {}" },
|
||||
};
|
||||
|
||||
for (const auto &handler : UpdateHandlers) {
|
||||
|
||||
@@ -51,6 +51,8 @@ add_imhex_plugin(
|
||||
|
||||
source/content/helpers/demangle.cpp
|
||||
|
||||
source/content/sidebar/project_explorer.cpp
|
||||
|
||||
source/content/data_processor_nodes/basic_nodes.cpp
|
||||
source/content/data_processor_nodes/control_nodes.cpp
|
||||
source/content/data_processor_nodes/decode_nodes.cpp
|
||||
|
||||
@@ -32,8 +32,8 @@ namespace hex::plugin::builtin {
|
||||
private:
|
||||
std::string m_currFilter;
|
||||
|
||||
PerProvider<std::list<Bookmark>> m_bookmarks;
|
||||
PerProvider<u64> m_currBookmarkId;
|
||||
std::list<Bookmark> m_bookmarks;
|
||||
u64 m_currBookmarkId;
|
||||
};
|
||||
|
||||
}
|
||||
@@ -56,7 +56,7 @@ namespace hex::plugin::builtin {
|
||||
void reloadCustomNodes();
|
||||
void updateNodePositions();
|
||||
|
||||
std::vector<Workspace*> &getWorkspaceStack() { return *m_workspaceStack; }
|
||||
std::vector<Workspace*> &getWorkspaceStack() { return m_workspaceStack; }
|
||||
|
||||
private:
|
||||
void drawContextMenus(ViewDataProcessor::Workspace &workspace);
|
||||
@@ -76,8 +76,8 @@ namespace hex::plugin::builtin {
|
||||
|
||||
std::vector<CustomNode> m_customNodes;
|
||||
|
||||
PerProvider<Workspace> m_mainWorkspace;
|
||||
PerProvider<std::vector<Workspace*>> m_workspaceStack;
|
||||
Workspace m_mainWorkspace;
|
||||
std::vector<Workspace*> m_workspaceStack;
|
||||
TaskHolder m_evaluationTask;
|
||||
};
|
||||
|
||||
|
||||
@@ -286,7 +286,6 @@ namespace hex::plugin::builtin {
|
||||
bool m_replaceMode = false;
|
||||
bool m_openFindReplacePopUp = false;
|
||||
bool m_openGotoLinePopUp = false;
|
||||
bool m_patternEvaluating = false;
|
||||
std::map<std::fs::path, std::string> m_patternNames;
|
||||
|
||||
ImRect m_textEditorHoverBox;
|
||||
|
||||
@@ -17,7 +17,6 @@ namespace hex::plugin::builtin {
|
||||
|
||||
ImVec2 getMinSize() const override { return { -1, -1 }; }
|
||||
ImVec2 getMaxSize() const override { return this->getMinSize(); }
|
||||
ImGuiWindowFlags getWindowFlags() const override { return ImGuiWindowFlags_AlwaysAutoResize; }
|
||||
|
||||
bool hasCloseButton() const override {
|
||||
return false;
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 4.6 KiB After Width: | Height: | Size: 644 B |
@@ -94,7 +94,7 @@
|
||||
"hex.builtin.inspector.rgba8": "RGBA8 Farbe",
|
||||
"hex.builtin.inspector.sleb128": "Signed LEB128",
|
||||
"hex.builtin.inspector.string": "String",
|
||||
"hex.builtin.inspector.wstring": "Wide String",
|
||||
"hex.builtin.inspector.string16": "Wide String",
|
||||
"hex.builtin.inspector.time": "time_t",
|
||||
"hex.builtin.inspector.time32": "time32_t",
|
||||
"hex.builtin.inspector.time64": "time64_t",
|
||||
@@ -106,7 +106,7 @@
|
||||
"hex.builtin.inspector.u8": "uint8_t",
|
||||
"hex.builtin.inspector.uleb128": "Unsigned LEB128",
|
||||
"hex.builtin.inspector.utf8": "UTF-8 code point",
|
||||
"hex.builtin.inspector.wide": "wchar_t",
|
||||
"hex.builtin.inspector.wide": "Wide Character",
|
||||
"hex.builtin.layouts.default": "Standard",
|
||||
"hex.builtin.layouts.none.restore_default": "Standard-Layout wiederherstellen",
|
||||
"hex.builtin.menu.edit": "Bearbeiten",
|
||||
@@ -781,8 +781,8 @@
|
||||
"hex.builtin.view.hex_editor.menu.file.load_encoding_file": "Benutzerdefinierte Enkodierung laden...",
|
||||
"hex.builtin.view.hex_editor.menu.file.save": "Speichern",
|
||||
"hex.builtin.view.hex_editor.menu.file.save_as": "Speichern unter...",
|
||||
"hex.builtin.view.hex_editor.menu.file.search": "Suchen...",
|
||||
"hex.builtin.view.hex_editor.menu.edit.select": "Auswählen...",
|
||||
"hex.builtin.view.hex_editor.menu.file.search": "Suchen",
|
||||
"hex.builtin.view.hex_editor.menu.edit.select": "Auswählen",
|
||||
"hex.builtin.view.hex_editor.name": "Hex Editor",
|
||||
"hex.builtin.view.hex_editor.search.find": "Suchen",
|
||||
"hex.builtin.view.hex_editor.search.hex": "Hex",
|
||||
@@ -1000,7 +1000,7 @@
|
||||
"hex.builtin.welcome.learn.pattern.link": "https://docs.werwolv.net/pattern-language/",
|
||||
"hex.builtin.welcome.learn.pattern.title": "Pattern Language Dokumentation",
|
||||
"hex.builtin.welcome.learn.plugins.desc": "Erweitere ImHex mit neuen Funktionen mit Plugins",
|
||||
"hex.builtin.welcome.learn.plugins.link": "https://docs.werwolv.net/imhex/common/extending-imhex",
|
||||
"hex.builtin.welcome.learn.plugins.link": "https://github.com/WerWolv/ImHex/wiki/Plugins-Development-Guide",
|
||||
"hex.builtin.welcome.learn.plugins.title": "Plugins API",
|
||||
"hex.builtin.welcome.quick_settings.simplified": "Simple Ansicht",
|
||||
"hex.builtin.welcome.start.create_file": "Neue Datei erstellen",
|
||||
@@ -1011,7 +1011,7 @@
|
||||
"hex.builtin.welcome.start.recent.auto_backups": "Auto Backups",
|
||||
"hex.builtin.welcome.start.recent.auto_backups.backup": "Backup vom {:%Y-%m-%d %H:%M:%S}",
|
||||
"hex.builtin.welcome.tip_of_the_day": "Tipp des Tages",
|
||||
"hex.builtin.welcome.update.desc": "ImHex {0} wurde gerade released!",
|
||||
"hex.builtin.welcome.update.desc": "ImHex {0} wurde gerade released! Downloade die neue Version hier",
|
||||
"hex.builtin.welcome.update.link": "https://github.com/WerWolv/ImHex/releases/latest",
|
||||
"hex.builtin.welcome.update.title": "Neues Update verfügbar!"
|
||||
}
|
||||
|
||||
@@ -97,9 +97,7 @@
|
||||
"hex.builtin.inspector.rgba8": "RGBA8 Color",
|
||||
"hex.builtin.inspector.sleb128": "Signed LEB128",
|
||||
"hex.builtin.inspector.string": "String",
|
||||
"hex.builtin.inspector.wstring": "Wide String",
|
||||
"hex.builtin.inspector.string16": "String16",
|
||||
"hex.builtin.inspector.string32": "String32",
|
||||
"hex.builtin.inspector.string16": "Wide String",
|
||||
"hex.builtin.inspector.time": "time_t",
|
||||
"hex.builtin.inspector.time32": "time32_t",
|
||||
"hex.builtin.inspector.time64": "time64_t",
|
||||
@@ -111,9 +109,7 @@
|
||||
"hex.builtin.inspector.u8": "uint8_t",
|
||||
"hex.builtin.inspector.uleb128": "Unsigned LEB128",
|
||||
"hex.builtin.inspector.utf8": "UTF-8 code point",
|
||||
"hex.builtin.inspector.wide": "wchar_t",
|
||||
"hex.builtin.inspector.char16": "char16_t",
|
||||
"hex.builtin.inspector.char32": "char32_t",
|
||||
"hex.builtin.inspector.wide": "Wide Character",
|
||||
"hex.builtin.layouts.default": "Default",
|
||||
"hex.builtin.layouts.none.restore_default": "Restore default layout",
|
||||
"hex.builtin.menu.edit": "Edit",
|
||||
@@ -403,6 +399,10 @@
|
||||
"hex.builtin.popup.save_layout.title": "Save Layout",
|
||||
"hex.builtin.popup.save_layout.desc": "Enter a name under which to save the current layout.",
|
||||
"hex.builtin.popup.waiting_for_tasks.desc": "There are still tasks running in the background.\nImHex will close after they are finished.",
|
||||
"hex.builtin.project.content_type.pattern": "Pattern Source Code",
|
||||
"hex.builtin.project.content_type.bookmarks": "Bookmarks",
|
||||
"hex.builtin.project.content_type.data_processor": "Data Processor Nodes",
|
||||
"hex.builtin.project.free_items": "Free Items",
|
||||
"hex.builtin.provider.rename": "Rename",
|
||||
"hex.builtin.provider.rename.desc": "Enter a name for this provider.",
|
||||
"hex.builtin.provider.tooltip.show_more": "Hold SHIFT for more information",
|
||||
@@ -514,7 +514,6 @@
|
||||
"hex.builtin.setting.interface.scaling.native": "Native",
|
||||
"hex.builtin.setting.interface.scaling.fractional_warning": "The default font does not support fractional scaling. For better results, select a custom font in the 'Font' tab.",
|
||||
"hex.builtin.setting.interface.show_header_command_palette": "Show Command Palette in Window Header",
|
||||
"hex.builtin.setting.interface.show_titlebar_backdrop": "Show titlebar backdrop color",
|
||||
"hex.builtin.setting.interface.style": "Styling",
|
||||
"hex.builtin.setting.interface.use_native_menu_bar": "Use native menu bar",
|
||||
"hex.builtin.setting.interface.window": "Window",
|
||||
@@ -850,7 +849,7 @@
|
||||
"hex.builtin.view.hex_editor.menu.file.save": "Save",
|
||||
"hex.builtin.view.hex_editor.menu.file.save_as": "Save As...",
|
||||
"hex.builtin.view.hex_editor.menu.file.search": "Search...",
|
||||
"hex.builtin.view.hex_editor.menu.edit.select": "Select...",
|
||||
"hex.builtin.view.hex_editor.menu.edit.select": "Select",
|
||||
"hex.builtin.view.hex_editor.name": "Hex editor",
|
||||
"hex.builtin.view.hex_editor.search.find": "Find",
|
||||
"hex.builtin.view.hex_editor.search.hex": "Hex",
|
||||
@@ -1059,7 +1058,6 @@
|
||||
"hex.builtin.view.store.row.authors": "Authors",
|
||||
"hex.builtin.view.store.row.name": "Name",
|
||||
"hex.builtin.view.store.tab.constants": "Constants",
|
||||
"hex.builtin.view.store.tab.disassemblers": "Disassemblers",
|
||||
"hex.builtin.view.store.tab.encodings": "Encodings",
|
||||
"hex.builtin.view.store.tab.includes": "Libraries",
|
||||
"hex.builtin.view.store.tab.magic": "Magic Files",
|
||||
@@ -1143,7 +1141,7 @@
|
||||
"hex.builtin.welcome.learn.imhex.link": "https://docs.werwolv.net/imhex/",
|
||||
"hex.builtin.welcome.learn.imhex.title": "ImHex Documentation",
|
||||
"hex.builtin.welcome.learn.plugins.desc": "Extend ImHex with additional features using plugins",
|
||||
"hex.builtin.welcome.learn.plugins.link": "https://docs.werwolv.net/imhex/common/extending-imhex",
|
||||
"hex.builtin.welcome.learn.plugins.link": "https://github.com/WerWolv/ImHex/wiki/Plugins-Development-Guide",
|
||||
"hex.builtin.welcome.learn.plugins.title": "Plugins API",
|
||||
"hex.builtin.popup.create_workspace.title": "Create new Workspace",
|
||||
"hex.builtin.popup.create_workspace.desc": "Enter a name for the new Workspace",
|
||||
@@ -1161,7 +1159,7 @@
|
||||
"hex.builtin.welcome.start.recent.auto_backups": "Auto Backups",
|
||||
"hex.builtin.welcome.start.recent.auto_backups.backup": "Backup from {:%Y-%m-%d %H:%M:%S}",
|
||||
"hex.builtin.welcome.tip_of_the_day": "Tip of the Day",
|
||||
"hex.builtin.welcome.update.desc": "ImHex {0} just released!",
|
||||
"hex.builtin.welcome.update.desc": "ImHex {0} just released! Download it here.",
|
||||
"hex.builtin.welcome.update.link": "https://github.com/WerWolv/ImHex/releases/latest",
|
||||
"hex.builtin.welcome.update.title": "New Update available!",
|
||||
"hex.builtin.welcome.quick_settings.simplified": "Simplified"
|
||||
|
||||
@@ -94,7 +94,7 @@
|
||||
"hex.builtin.inspector.rgba8": "Color RGBA8",
|
||||
"hex.builtin.inspector.sleb128": "LEB128 con Signo",
|
||||
"hex.builtin.inspector.string": "Cadena ",
|
||||
"hex.builtin.inspector.wstring": "Cadena (wide)",
|
||||
"hex.builtin.inspector.string16": "Cadena (wide)",
|
||||
"hex.builtin.inspector.time": "time_t",
|
||||
"hex.builtin.inspector.time32": "time32_t",
|
||||
"hex.builtin.inspector.time64": "time64_t",
|
||||
@@ -106,7 +106,7 @@
|
||||
"hex.builtin.inspector.u8": "",
|
||||
"hex.builtin.inspector.uleb128": "LEB128 sin Signo",
|
||||
"hex.builtin.inspector.utf8": "Código UTF-8",
|
||||
"hex.builtin.inspector.wide": "wchar_t",
|
||||
"hex.builtin.inspector.wide": "Carácter (wide)",
|
||||
"hex.builtin.layouts.default": "Por defecto",
|
||||
"hex.builtin.layouts.none.restore_default": "",
|
||||
"hex.builtin.menu.edit": "Editar",
|
||||
@@ -777,8 +777,8 @@
|
||||
"hex.builtin.view.hex_editor.menu.file.load_encoding_file": "Cargar codificación personalizada...",
|
||||
"hex.builtin.view.hex_editor.menu.file.save": "Guardar",
|
||||
"hex.builtin.view.hex_editor.menu.file.save_as": "Guardar como...",
|
||||
"hex.builtin.view.hex_editor.menu.file.search": "Buscar...",
|
||||
"hex.builtin.view.hex_editor.menu.edit.select": "Seleccionar...",
|
||||
"hex.builtin.view.hex_editor.menu.file.search": "Buscar",
|
||||
"hex.builtin.view.hex_editor.menu.edit.select": "Seleccionar",
|
||||
"hex.builtin.view.hex_editor.name": "Editor hexadecimal",
|
||||
"hex.builtin.view.hex_editor.search.find": "Buscar",
|
||||
"hex.builtin.view.hex_editor.search.hex": "Hexadecimal",
|
||||
@@ -994,7 +994,7 @@
|
||||
"hex.builtin.welcome.learn.pattern.link": "https://docs.werwolv.net/pattern-language/",
|
||||
"hex.builtin.welcome.learn.pattern.title": "Documentación de Pattern Language",
|
||||
"hex.builtin.welcome.learn.plugins.desc": "Extienda ImHex con características adicionales mediante plugins",
|
||||
"hex.builtin.welcome.learn.plugins.link": "https://docs.werwolv.net/imhex/common/extending-imhex",
|
||||
"hex.builtin.welcome.learn.plugins.link": "https://github.com/WerWolv/ImHex/wiki/Plugins-Development-Guide",
|
||||
"hex.builtin.welcome.learn.plugins.title": "API de Plugins",
|
||||
"hex.builtin.welcome.quick_settings.simplified": "",
|
||||
"hex.builtin.welcome.start.create_file": "Crear Nuevo Archivo",
|
||||
@@ -1005,7 +1005,7 @@
|
||||
"hex.builtin.welcome.start.recent.auto_backups": "",
|
||||
"hex.builtin.welcome.start.recent.auto_backups.backup": "",
|
||||
"hex.builtin.welcome.tip_of_the_day": "Consejo del día",
|
||||
"hex.builtin.welcome.update.desc": "¡ImHex {0} está disponible!",
|
||||
"hex.builtin.welcome.update.desc": "¡ImHex {0} está disponible! Descárguelo aquí.",
|
||||
"hex.builtin.welcome.update.link": "https://github.com/WerWolv/ImHex/releases/latest",
|
||||
"hex.builtin.welcome.update.title": "Nueva actualización disponible!"
|
||||
}
|
||||
|
||||
@@ -94,7 +94,7 @@
|
||||
"hex.builtin.inspector.rgba8": "RGBA8 Szín",
|
||||
"hex.builtin.inspector.sleb128": "Előjeles LEB128",
|
||||
"hex.builtin.inspector.string": "String",
|
||||
"hex.builtin.inspector.wstring": "Széles string",
|
||||
"hex.builtin.inspector.string16": "Széles string",
|
||||
"hex.builtin.inspector.time": "time_t",
|
||||
"hex.builtin.inspector.time32": "time32_t",
|
||||
"hex.builtin.inspector.time64": "time64_t",
|
||||
@@ -106,7 +106,7 @@
|
||||
"hex.builtin.inspector.u8": "uint8_t",
|
||||
"hex.builtin.inspector.uleb128": "Előjeletlen LEB128",
|
||||
"hex.builtin.inspector.utf8": "UTF-8 kód pont",
|
||||
"hex.builtin.inspector.wide": "wchar_t",
|
||||
"hex.builtin.inspector.wide": "Széles karakter",
|
||||
"hex.builtin.layouts.default": "Alapértelmezett",
|
||||
"hex.builtin.layouts.none.restore_default": "Alapértelmezett elrendezés visszaállítása",
|
||||
"hex.builtin.menu.edit": "Szerkesztés",
|
||||
@@ -778,8 +778,8 @@
|
||||
"hex.builtin.view.hex_editor.menu.file.load_encoding_file": "Saját kódolás betöltése...",
|
||||
"hex.builtin.view.hex_editor.menu.file.save": "Mentés",
|
||||
"hex.builtin.view.hex_editor.menu.file.save_as": "Mentés másként...",
|
||||
"hex.builtin.view.hex_editor.menu.file.search": "Keresés...",
|
||||
"hex.builtin.view.hex_editor.menu.edit.select": "Kijelölés...",
|
||||
"hex.builtin.view.hex_editor.menu.file.search": "Keresés",
|
||||
"hex.builtin.view.hex_editor.menu.edit.select": "Kijelölés",
|
||||
"hex.builtin.view.hex_editor.name": "Hex szerkesztő",
|
||||
"hex.builtin.view.hex_editor.search.find": "Kereső",
|
||||
"hex.builtin.view.hex_editor.search.hex": "Hex",
|
||||
@@ -1015,7 +1015,7 @@
|
||||
"hex.builtin.welcome.learn.imhex.link": "https://docs.werwolv.net/imhex/",
|
||||
"hex.builtin.welcome.learn.imhex.title": "ImHex dokumentáció",
|
||||
"hex.builtin.welcome.learn.plugins.desc": "ImHex funkcióinak bővítése bővítményekkel",
|
||||
"hex.builtin.welcome.learn.plugins.link": "https://docs.werwolv.net/imhex/common/extending-imhex",
|
||||
"hex.builtin.welcome.learn.plugins.link": "https://github.com/WerWolv/ImHex/wiki/Plugins-Development-Guide",
|
||||
"hex.builtin.welcome.learn.plugins.title": "Bővítmény API",
|
||||
"hex.builtin.popup.create_workspace.title": "Új munkaterület létrehozása",
|
||||
"hex.builtin.popup.create_workspace.desc": "Adjon nevet az új munkaterületnek",
|
||||
@@ -1033,7 +1033,7 @@
|
||||
"hex.builtin.welcome.start.recent.auto_backups": "Automatikus mentések",
|
||||
"hex.builtin.welcome.start.recent.auto_backups.backup": "Biztonsági mentés: {:%Y-%m-%d %H:%M:%S}",
|
||||
"hex.builtin.welcome.tip_of_the_day": "A nap tippje",
|
||||
"hex.builtin.welcome.update.desc": "Megjelent az ImHex {0}!.",
|
||||
"hex.builtin.welcome.update.desc": "Megjelent az ImHex {0}! Itt töltheted le.",
|
||||
"hex.builtin.welcome.update.link": "https://github.com/WerWolv/ImHex/releases/latest",
|
||||
"hex.builtin.welcome.update.title": "Elérhető egy új frissítés!",
|
||||
"hex.builtin.welcome.quick_settings.simplified": "Egyszerűsített"
|
||||
|
||||
@@ -94,7 +94,7 @@
|
||||
"hex.builtin.inspector.rgba8": "Colori RGBA8",
|
||||
"hex.builtin.inspector.sleb128": "",
|
||||
"hex.builtin.inspector.string": "String",
|
||||
"hex.builtin.inspector.wstring": "Wide String",
|
||||
"hex.builtin.inspector.string16": "Wide String",
|
||||
"hex.builtin.inspector.time": "time_t",
|
||||
"hex.builtin.inspector.time32": "time32_t",
|
||||
"hex.builtin.inspector.time64": "time64_t",
|
||||
@@ -106,7 +106,7 @@
|
||||
"hex.builtin.inspector.u8": "uint8_t",
|
||||
"hex.builtin.inspector.uleb128": "",
|
||||
"hex.builtin.inspector.utf8": "UTF-8 code point",
|
||||
"hex.builtin.inspector.wide": "wchar_t",
|
||||
"hex.builtin.inspector.wide": "Wide Character",
|
||||
"hex.builtin.layouts.default": "Default",
|
||||
"hex.builtin.layouts.none.restore_default": "",
|
||||
"hex.builtin.menu.edit": "Modifica",
|
||||
@@ -995,7 +995,7 @@
|
||||
"hex.builtin.welcome.learn.pattern.link": "https://docs.werwolv.net/pattern-language/",
|
||||
"hex.builtin.welcome.learn.pattern.title": "Documentazione dei Pattern",
|
||||
"hex.builtin.welcome.learn.plugins.desc": "Espandi l'utilizzo di ImHex con i Plugin",
|
||||
"hex.builtin.welcome.learn.plugins.link": "https://docs.werwolv.net/imhex/common/extending-imhex",
|
||||
"hex.builtin.welcome.learn.plugins.link": "https://github.com/WerWolv/ImHex/wiki/Plugins-Development-Guide",
|
||||
"hex.builtin.welcome.learn.plugins.title": "Plugins API",
|
||||
"hex.builtin.welcome.quick_settings.simplified": "",
|
||||
"hex.builtin.welcome.start.create_file": "Crea un nuovo File",
|
||||
@@ -1006,7 +1006,7 @@
|
||||
"hex.builtin.welcome.start.recent.auto_backups": "",
|
||||
"hex.builtin.welcome.start.recent.auto_backups.backup": "",
|
||||
"hex.builtin.welcome.tip_of_the_day": "Consiglio del giorno",
|
||||
"hex.builtin.welcome.update.desc": "ImHex {0} è appena stato rilasciato!",
|
||||
"hex.builtin.welcome.update.desc": "ImHex {0} è appena stato rilasciato! Scaricalo qua",
|
||||
"hex.builtin.welcome.update.link": "https://github.com/WerWolv/ImHex/releases/latest",
|
||||
"hex.builtin.welcome.update.title": "Nuovo aggiornamento disponibile!"
|
||||
}
|
||||
|
||||
@@ -94,7 +94,7 @@
|
||||
"hex.builtin.inspector.rgba8": "RGBA8 Color",
|
||||
"hex.builtin.inspector.sleb128": "",
|
||||
"hex.builtin.inspector.string": "String",
|
||||
"hex.builtin.inspector.wstring": "Wide String",
|
||||
"hex.builtin.inspector.string16": "Wide String",
|
||||
"hex.builtin.inspector.time": "time_t",
|
||||
"hex.builtin.inspector.time32": "time32_t",
|
||||
"hex.builtin.inspector.time64": "time64_t",
|
||||
@@ -106,7 +106,7 @@
|
||||
"hex.builtin.inspector.u8": "uint8_t",
|
||||
"hex.builtin.inspector.uleb128": "",
|
||||
"hex.builtin.inspector.utf8": "UTF-8 code point",
|
||||
"hex.builtin.inspector.wide": "wchar_t",
|
||||
"hex.builtin.inspector.wide": "Wide Character",
|
||||
"hex.builtin.layouts.default": "標準",
|
||||
"hex.builtin.layouts.none.restore_default": "",
|
||||
"hex.builtin.menu.edit": "編集",
|
||||
@@ -995,7 +995,7 @@
|
||||
"hex.builtin.welcome.learn.pattern.link": "https://docs.werwolv.net/pattern-language/",
|
||||
"hex.builtin.welcome.learn.pattern.title": "ImHexオリジナル言語について",
|
||||
"hex.builtin.welcome.learn.plugins.desc": "ImHexの機能を拡張する",
|
||||
"hex.builtin.welcome.learn.plugins.link": "https://docs.werwolv.net/imhex/common/extending-imhex",
|
||||
"hex.builtin.welcome.learn.plugins.link": "https://github.com/WerWolv/ImHex/wiki/Plugins-Development-Guide",
|
||||
"hex.builtin.welcome.learn.plugins.title": "プラグインAPI",
|
||||
"hex.builtin.welcome.quick_settings.simplified": "",
|
||||
"hex.builtin.welcome.start.create_file": "新規ファイルを作成",
|
||||
@@ -1006,7 +1006,7 @@
|
||||
"hex.builtin.welcome.start.recent.auto_backups": "",
|
||||
"hex.builtin.welcome.start.recent.auto_backups.backup": "",
|
||||
"hex.builtin.welcome.tip_of_the_day": "今日の豆知識",
|
||||
"hex.builtin.welcome.update.desc": "ImHex {0} がリリースされました。",
|
||||
"hex.builtin.welcome.update.desc": "ImHex {0} がリリースされました。ここからダウンロードできます。",
|
||||
"hex.builtin.welcome.update.link": "https://github.com/WerWolv/ImHex/releases/latest",
|
||||
"hex.builtin.welcome.update.title": "新しいアップデートが利用可能です。"
|
||||
}
|
||||
|
||||
@@ -94,7 +94,7 @@
|
||||
"hex.builtin.inspector.rgba8": "RGBA8 색상",
|
||||
"hex.builtin.inspector.sleb128": "부호 있는 LEB128",
|
||||
"hex.builtin.inspector.string": "문자열",
|
||||
"hex.builtin.inspector.wstring": "와이드 문자열",
|
||||
"hex.builtin.inspector.string16": "와이드 문자열",
|
||||
"hex.builtin.inspector.time": "time_t",
|
||||
"hex.builtin.inspector.time32": "time32_t",
|
||||
"hex.builtin.inspector.time64": "time64_t",
|
||||
@@ -106,7 +106,7 @@
|
||||
"hex.builtin.inspector.u8": "uint8_t",
|
||||
"hex.builtin.inspector.uleb128": "부호 없는 LEB128",
|
||||
"hex.builtin.inspector.utf8": "UTF-8 코드 포인트",
|
||||
"hex.builtin.inspector.wide": "wchar_t",
|
||||
"hex.builtin.inspector.wide": "와이드 문자",
|
||||
"hex.builtin.layouts.default": "기본",
|
||||
"hex.builtin.layouts.none.restore_default": "기본 레이아웃 복원",
|
||||
"hex.builtin.menu.edit": "편집",
|
||||
@@ -777,8 +777,8 @@
|
||||
"hex.builtin.view.hex_editor.menu.file.load_encoding_file": "사용자 정의 인코딩 불러오기...",
|
||||
"hex.builtin.view.hex_editor.menu.file.save": "저장",
|
||||
"hex.builtin.view.hex_editor.menu.file.save_as": "다른 이름으로 저장...",
|
||||
"hex.builtin.view.hex_editor.menu.file.search": "검색...",
|
||||
"hex.builtin.view.hex_editor.menu.edit.select": "선택...",
|
||||
"hex.builtin.view.hex_editor.menu.file.search": "검색",
|
||||
"hex.builtin.view.hex_editor.menu.edit.select": "선택",
|
||||
"hex.builtin.view.hex_editor.name": "헥스 편집기",
|
||||
"hex.builtin.view.hex_editor.search.find": "찾기",
|
||||
"hex.builtin.view.hex_editor.search.hex": "헥스",
|
||||
@@ -995,7 +995,7 @@
|
||||
"hex.builtin.welcome.learn.pattern.link": "https://docs.werwolv.net/pattern-language/",
|
||||
"hex.builtin.welcome.learn.pattern.title": "패턴 언어 문서",
|
||||
"hex.builtin.welcome.learn.plugins.desc": "플러그인을 사용하여 추가 기능으로 ImHex를 확장하세요",
|
||||
"hex.builtin.welcome.learn.plugins.link": "https://docs.werwolv.net/imhex/common/extending-imhex",
|
||||
"hex.builtin.welcome.learn.plugins.link": "https://github.com/WerWolv/ImHex/wiki/Plugins-Development-Guide",
|
||||
"hex.builtin.welcome.learn.plugins.title": "플러그인 API",
|
||||
"hex.builtin.welcome.quick_settings.simplified": "단순화",
|
||||
"hex.builtin.welcome.start.create_file": "새 파일 만들기",
|
||||
@@ -1006,7 +1006,7 @@
|
||||
"hex.builtin.welcome.start.recent.auto_backups": "",
|
||||
"hex.builtin.welcome.start.recent.auto_backups.backup": "",
|
||||
"hex.builtin.welcome.tip_of_the_day": "오늘의 팁",
|
||||
"hex.builtin.welcome.update.desc": "ImHex {0}이(가) 출시되었습니다!",
|
||||
"hex.builtin.welcome.update.desc": "ImHex {0}이(가) 출시되었습니다! 여기서 다운로드하세요.",
|
||||
"hex.builtin.welcome.update.link": "https://github.com/WerWolv/ImHex/releases/latest",
|
||||
"hex.builtin.welcome.update.title": "새 업데이트를 사용할 수 있습니다!"
|
||||
}
|
||||
|
||||
@@ -94,7 +94,7 @@
|
||||
"hex.builtin.inspector.rgba8": "RGBA8 Color",
|
||||
"hex.builtin.inspector.sleb128": "",
|
||||
"hex.builtin.inspector.string": "String",
|
||||
"hex.builtin.inspector.wstring": "Wide String",
|
||||
"hex.builtin.inspector.string16": "Wide String",
|
||||
"hex.builtin.inspector.time": "time_t",
|
||||
"hex.builtin.inspector.time32": "time32_t",
|
||||
"hex.builtin.inspector.time64": "time64_t",
|
||||
@@ -106,7 +106,7 @@
|
||||
"hex.builtin.inspector.u8": "uint8_t",
|
||||
"hex.builtin.inspector.uleb128": "",
|
||||
"hex.builtin.inspector.utf8": "UTF-8 code point",
|
||||
"hex.builtin.inspector.wide": "wchar_t",
|
||||
"hex.builtin.inspector.wide": "Wide Character",
|
||||
"hex.builtin.layouts.default": "Default",
|
||||
"hex.builtin.layouts.none.restore_default": "",
|
||||
"hex.builtin.menu.edit": "Editar",
|
||||
@@ -995,7 +995,7 @@
|
||||
"hex.builtin.welcome.learn.pattern.link": "https://docs.werwolv.net/pattern-language/",
|
||||
"hex.builtin.welcome.learn.pattern.title": "Documentação da linguagem padrão",
|
||||
"hex.builtin.welcome.learn.plugins.desc": "Estenda o ImHex com recursos adicionais usando plugins",
|
||||
"hex.builtin.welcome.learn.plugins.link": "https://docs.werwolv.net/imhex/common/extending-imhex",
|
||||
"hex.builtin.welcome.learn.plugins.link": "https://github.com/WerWolv/ImHex/wiki/Plugins-Development-Guide",
|
||||
"hex.builtin.welcome.learn.plugins.title": "Plugins API",
|
||||
"hex.builtin.welcome.quick_settings.simplified": "",
|
||||
"hex.builtin.welcome.start.create_file": "Criar Novo Arquivo",
|
||||
@@ -1006,7 +1006,7 @@
|
||||
"hex.builtin.welcome.start.recent.auto_backups": "",
|
||||
"hex.builtin.welcome.start.recent.auto_backups.backup": "",
|
||||
"hex.builtin.welcome.tip_of_the_day": "Dica do Dia",
|
||||
"hex.builtin.welcome.update.desc": "ImHex {0} acabou de lançar!",
|
||||
"hex.builtin.welcome.update.desc": "ImHex {0} acabou de lançar! Baixe aqui.",
|
||||
"hex.builtin.welcome.update.link": "https://github.com/WerWolv/ImHex/releases/latest",
|
||||
"hex.builtin.welcome.update.title": "Nova atualização disponivel!"
|
||||
}
|
||||
|
||||
@@ -96,7 +96,7 @@
|
||||
"hex.builtin.inspector.rgba8": "RGBA8 цвет",
|
||||
"hex.builtin.inspector.sleb128": "Знаковый LEB128",
|
||||
"hex.builtin.inspector.string": "Строка",
|
||||
"hex.builtin.inspector.wstring": "Wide строка",
|
||||
"hex.builtin.inspector.string16": "Wide строка",
|
||||
"hex.builtin.inspector.time": "time_t",
|
||||
"hex.builtin.inspector.time32": "time32_t",
|
||||
"hex.builtin.inspector.time64": "time64_t",
|
||||
@@ -108,7 +108,7 @@
|
||||
"hex.builtin.inspector.u8": "uint8_t",
|
||||
"hex.builtin.inspector.uleb128": "Беззнаковый LEB128",
|
||||
"hex.builtin.inspector.utf8": "UTF-8 код",
|
||||
"hex.builtin.inspector.wide": "wchar_t",
|
||||
"hex.builtin.inspector.wide": "Wide символ",
|
||||
"hex.builtin.layouts.default": "По умолчанию",
|
||||
"hex.builtin.layouts.none.restore_default": "Восстановить макет по умолчанию",
|
||||
"hex.builtin.menu.edit": "Правка",
|
||||
@@ -1111,7 +1111,7 @@
|
||||
"hex.builtin.welcome.learn.imhex.link": "https://docs.werwolv.net/imhex/",
|
||||
"hex.builtin.welcome.learn.imhex.title": "Документация ImHex",
|
||||
"hex.builtin.welcome.learn.plugins.desc": "Расширьте возможности ImHex с помощью плагинов",
|
||||
"hex.builtin.welcome.learn.plugins.link": "https://docs.werwolv.net/imhex/common/extending-imhex",
|
||||
"hex.builtin.welcome.learn.plugins.link": "https://github.com/WerWolv/ImHex/wiki/Plugins-Development-Guide",
|
||||
"hex.builtin.welcome.learn.plugins.title": "API плагинов",
|
||||
"hex.builtin.popup.create_workspace.title": "Создать новое пространство",
|
||||
"hex.builtin.popup.create_workspace.desc": "Введите имя нового пространства",
|
||||
@@ -1129,7 +1129,7 @@
|
||||
"hex.builtin.welcome.start.recent.auto_backups": "Резервные копии",
|
||||
"hex.builtin.welcome.start.recent.auto_backups.backup": "Резервная копия от {:%Y-%m-%d %H:%M:%S}",
|
||||
"hex.builtin.welcome.tip_of_the_day": "Подсказка дня",
|
||||
"hex.builtin.welcome.update.desc": "ImHex {0} только что вышел!",
|
||||
"hex.builtin.welcome.update.desc": "ImHex {0} только что вышел! Его можно скачать здесь.",
|
||||
"hex.builtin.welcome.update.link": "https://github.com/WerWolv/ImHex/releases/latest",
|
||||
"hex.builtin.welcome.update.title": "Доступно новое обновление!",
|
||||
"hex.builtin.welcome.quick_settings.simplified": "Простой режим"
|
||||
|
||||
@@ -123,7 +123,7 @@
|
||||
"hex.builtin.inspector.rgba8": "RGBA8 颜色",
|
||||
"hex.builtin.inspector.sleb128": "有符号LEB128",
|
||||
"hex.builtin.inspector.string": "字符串",
|
||||
"hex.builtin.inspector.wstring": "宽字符串",
|
||||
"hex.builtin.inspector.string16": "宽字符串",
|
||||
"hex.builtin.inspector.time": "time_t",
|
||||
"hex.builtin.inspector.time32": "time32_t",
|
||||
"hex.builtin.inspector.time64": "time64_t",
|
||||
@@ -135,7 +135,7 @@
|
||||
"hex.builtin.inspector.u8": "uint8_t",
|
||||
"hex.builtin.inspector.uleb128": "无符号LEB128",
|
||||
"hex.builtin.inspector.utf8": "UTF-8 码位",
|
||||
"hex.builtin.inspector.wide": "wchar_t",
|
||||
"hex.builtin.inspector.wide": "宽字符",
|
||||
"hex.builtin.layouts.default": "默认",
|
||||
"hex.builtin.layouts.none.restore_default": "恢复默认布局",
|
||||
"hex.builtin.menu.edit": "编辑",
|
||||
@@ -849,7 +849,7 @@
|
||||
"hex.builtin.view.hex_editor.menu.edit.paste_all": "粘贴全部",
|
||||
"hex.builtin.view.hex_editor.menu.edit.remove": "删除……",
|
||||
"hex.builtin.view.hex_editor.menu.edit.resize": "修改大小……",
|
||||
"hex.builtin.view.hex_editor.menu.edit.select": "选择……",
|
||||
"hex.builtin.view.hex_editor.menu.edit.select": "选择",
|
||||
"hex.builtin.view.hex_editor.menu.edit.select_all": "全选",
|
||||
"hex.builtin.view.hex_editor.menu.edit.set_base": "设置基地址",
|
||||
"hex.builtin.view.hex_editor.menu.edit.set_page_size": "设置页面大小",
|
||||
@@ -1058,7 +1058,7 @@
|
||||
"hex.builtin.welcome.learn.pattern.link": "https://docs.werwolv.net/pattern-language/",
|
||||
"hex.builtin.welcome.learn.pattern.title": "模式文档",
|
||||
"hex.builtin.welcome.learn.plugins.desc": "通过插件扩展 ImHex 获得更多功能",
|
||||
"hex.builtin.welcome.learn.plugins.link": "https://docs.werwolv.net/imhex/common/extending-imhex",
|
||||
"hex.builtin.welcome.learn.plugins.link": "https://github.com/WerWolv/ImHex/wiki/Plugins-Development-Guide",
|
||||
"hex.builtin.welcome.learn.plugins.title": "插件 API",
|
||||
"hex.builtin.welcome.nightly_build": "你正在运行ImHex的夜间构建。\n\n请在GitHub问题跟踪器上报告您遇到的任何错误!",
|
||||
"hex.builtin.welcome.quick_settings.simplified": "简化",
|
||||
@@ -1070,7 +1070,7 @@
|
||||
"hex.builtin.welcome.start.recent.auto_backups": "自动备份",
|
||||
"hex.builtin.welcome.start.recent.auto_backups.backup": "备份于 {:%年-%月-%日 %时:%分:%秒}",
|
||||
"hex.builtin.welcome.tip_of_the_day": "每日提示",
|
||||
"hex.builtin.welcome.update.desc": "ImHex {0} 已发布!",
|
||||
"hex.builtin.welcome.update.desc": "ImHex {0} 已发布!在这里下载。",
|
||||
"hex.builtin.welcome.update.link": "https://github.com/WerWolv/ImHex/releases/latest",
|
||||
"hex.builtin.welcome.update.title": "新的更新可用!"
|
||||
}
|
||||
|
||||
@@ -94,7 +94,7 @@
|
||||
"hex.builtin.inspector.rgba8": "RGBA8 顏色",
|
||||
"hex.builtin.inspector.sleb128": "有號數 LEB128",
|
||||
"hex.builtin.inspector.string": "字串",
|
||||
"hex.builtin.inspector.wstring": "寬字串",
|
||||
"hex.builtin.inspector.string16": "寬字串",
|
||||
"hex.builtin.inspector.time": "time_t",
|
||||
"hex.builtin.inspector.time32": "time32_t",
|
||||
"hex.builtin.inspector.time64": "time64_t",
|
||||
@@ -106,7 +106,7 @@
|
||||
"hex.builtin.inspector.u8": "uint8_t",
|
||||
"hex.builtin.inspector.uleb128": "無號數 LEB128",
|
||||
"hex.builtin.inspector.utf8": "UTF-8 code point",
|
||||
"hex.builtin.inspector.wide": "wchar_t",
|
||||
"hex.builtin.inspector.wide": "框字元",
|
||||
"hex.builtin.layouts.default": "預設",
|
||||
"hex.builtin.layouts.none.restore_default": "還原預設版面配置",
|
||||
"hex.builtin.menu.edit": "編輯",
|
||||
@@ -777,8 +777,8 @@
|
||||
"hex.builtin.view.hex_editor.menu.file.load_encoding_file": "載入自訂編碼...",
|
||||
"hex.builtin.view.hex_editor.menu.file.save": "儲存",
|
||||
"hex.builtin.view.hex_editor.menu.file.save_as": "另存為...",
|
||||
"hex.builtin.view.hex_editor.menu.file.search": "搜尋...",
|
||||
"hex.builtin.view.hex_editor.menu.edit.select": "選取...",
|
||||
"hex.builtin.view.hex_editor.menu.file.search": "搜尋",
|
||||
"hex.builtin.view.hex_editor.menu.edit.select": "選取",
|
||||
"hex.builtin.view.hex_editor.name": "十六進位編輯器",
|
||||
"hex.builtin.view.hex_editor.search.find": "尋找",
|
||||
"hex.builtin.view.hex_editor.search.hex": "十六進位",
|
||||
@@ -995,7 +995,7 @@
|
||||
"hex.builtin.welcome.learn.pattern.link": "https://docs.werwolv.net/pattern-language/",
|
||||
"hex.builtin.welcome.learn.pattern.title": "模式語言說明文件",
|
||||
"hex.builtin.welcome.learn.plugins.desc": " 使用外掛程式來拓展 ImHex 的功能",
|
||||
"hex.builtin.welcome.learn.plugins.link": "https://docs.werwolv.net/imhex/common/extending-imhex",
|
||||
"hex.builtin.welcome.learn.plugins.link": "https://github.com/WerWolv/ImHex/wiki/Plugins-Development-Guide",
|
||||
"hex.builtin.welcome.learn.plugins.title": "外掛程式 API",
|
||||
"hex.builtin.welcome.quick_settings.simplified": "",
|
||||
"hex.builtin.welcome.start.create_file": "建立新檔案",
|
||||
@@ -1006,7 +1006,7 @@
|
||||
"hex.builtin.welcome.start.recent.auto_backups": "",
|
||||
"hex.builtin.welcome.start.recent.auto_backups.backup": "",
|
||||
"hex.builtin.welcome.tip_of_the_day": "今日提示",
|
||||
"hex.builtin.welcome.update.desc": "ImHex {0} 發布了!",
|
||||
"hex.builtin.welcome.update.desc": "ImHex {0} 發布了!點此下載。",
|
||||
"hex.builtin.welcome.update.link": "https://github.com/WerWolv/ImHex/releases/latest",
|
||||
"hex.builtin.welcome.update.title": "有可用更新!"
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
"header-active": "*#8787DDCC",
|
||||
"header-hovered": "*#7272E5CC",
|
||||
"menu-bar-background": "#535371FF",
|
||||
"modal-window-dim-background": "#33333330",
|
||||
"modal-window-dim-background": "#33333359",
|
||||
"nav-highlight": "*#7272E5CC",
|
||||
"nav-windowing-background": "#CCCCCC33",
|
||||
"nav-windowing-highlight": "#FFFFFFB2",
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
"header-active": "*#4296F9FF",
|
||||
"header-hovered": "*#4296F9CC",
|
||||
"menu-bar-background": "#232323FF",
|
||||
"modal-window-dim-background": "#CCCCCC30",
|
||||
"modal-window-dim-background": "#CCCCCC59",
|
||||
"nav-highlight": "*#4296F9FF",
|
||||
"nav-windowing-background": "#CCCCCC33",
|
||||
"nav-windowing-highlight": "#FFFFFFB2",
|
||||
@@ -68,10 +68,10 @@
|
||||
"IEEE-tool-sign": "#5D5D7FFF",
|
||||
"IEEE-tool-exp": "#5D7F5DFF",
|
||||
"IEEE-tool-mantissa": "#7F5D5DFF",
|
||||
"toolbar-blue": "#267BC9FF",
|
||||
"toolbar-blue": "#06539BFF",
|
||||
"toolbar-brown": "#DBB377FF",
|
||||
"toolbar-gray": "#E6E6E6FF",
|
||||
"toolbar-green": "#59B364FF",
|
||||
"toolbar-green": "#388B42FF",
|
||||
"toolbar-purple": "#672A78FF",
|
||||
"toolbar-red": "#E74C3CFF",
|
||||
"toolbar-yellow": "#F1C40FFF",
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
"header-active": "*#4296F9FF",
|
||||
"header-hovered": "*#4296F9CC",
|
||||
"menu-bar-background": "#DBDBDBFF",
|
||||
"modal-window-dim-background": "#33333330",
|
||||
"modal-window-dim-background": "#33333359",
|
||||
"nav-highlight": "*#4296F9CC",
|
||||
"nav-windowing-background": "#33333333",
|
||||
"nav-windowing-highlight": "#B2B2B2B2",
|
||||
|
||||
@@ -435,10 +435,10 @@ namespace hex::plugin::builtin {
|
||||
hex::subcommands::registerSubCommand("select", [](const std::vector<std::string> &args){
|
||||
try {
|
||||
if (args.size() == 1)
|
||||
ImHexApi::HexEditor::setSelection(std::stoull(args[0], nullptr, 0), 1);
|
||||
ImHexApi::HexEditor::setSelection(std::stoull(args[0]), 1);
|
||||
else if (args.size() == 2) {
|
||||
const auto start = std::stoull(args[0], nullptr, 0);
|
||||
const auto size = (std::stoull(args[1], nullptr, 0) - start) + 1;
|
||||
const auto start = std::stoull(args[0]);
|
||||
const auto size = (std::stoull(args[1]) - start) + 1;
|
||||
ImHexApi::HexEditor::setSelection(start, size);
|
||||
} else {
|
||||
log::error("Invalid number of arguments for select command!");
|
||||
|
||||
@@ -363,73 +363,16 @@ namespace hex::plugin::builtin {
|
||||
|
||||
auto c = hex::changeEndianness(wideChar, endian);
|
||||
|
||||
auto value = hex::format("{0}", c <= 255 ? makePrintable(c) : wolv::util::wstringToUtf8(std::wstring(&c, 1)).value_or("???"));
|
||||
auto value = hex::format("{0}", c <= 255 ? makePrintable(c) : wolv::util::wstringToUtf8(std::wstring(&c, 1)));
|
||||
return [value] { ImGuiExt::TextFormatted("'{0}'", value.c_str()); return value; };
|
||||
},
|
||||
[](const std::string &value, std::endian endian) -> std::vector<u8> {
|
||||
std::vector<u8> bytes;
|
||||
auto wideString = wolv::util::utf8ToWstring(value.c_str());
|
||||
if (!wideString.has_value())
|
||||
return bytes;
|
||||
auto wideString = wolv::util::utf8ToWstring(value.c_str(), "");
|
||||
if (wideString.empty()) return bytes;
|
||||
|
||||
bytes.resize(wideString->size() * sizeof(wchar_t));
|
||||
std::memcpy(bytes.data(), wideString->data(), bytes.size());
|
||||
|
||||
if (endian != std::endian::native)
|
||||
std::reverse(bytes.begin(), bytes.end());
|
||||
|
||||
return bytes;
|
||||
}
|
||||
);
|
||||
|
||||
ContentRegistry::DataInspector::add("hex.builtin.inspector.char16", sizeof(char16_t),
|
||||
[](auto buffer, auto endian, auto style) {
|
||||
std::ignore = style;
|
||||
|
||||
char16_t wideChar = '\x00';
|
||||
std::memcpy(&wideChar, buffer.data(), std::min(sizeof(char16_t), buffer.size()));
|
||||
|
||||
auto c = hex::changeEndianness(wideChar, endian);
|
||||
|
||||
auto value = hex::format("{0}", c <= 255 ? makePrintable(c) : wolv::util::utf16ToUtf8(std::u16string(&c, 1)).value_or("???"));
|
||||
return [value] { ImGuiExt::TextFormatted("'{0}'", value.c_str()); return value; };
|
||||
},
|
||||
[](const std::string &value, std::endian endian) -> std::vector<u8> {
|
||||
std::vector<u8> bytes;
|
||||
auto wideString = wolv::util::utf8ToUtf16(value);
|
||||
if (!wideString.has_value())
|
||||
return bytes;
|
||||
|
||||
bytes.resize(wideString->size() * sizeof(char16_t));
|
||||
std::memcpy(bytes.data(), wideString->data(), bytes.size());
|
||||
|
||||
if (endian != std::endian::native)
|
||||
std::reverse(bytes.begin(), bytes.end());
|
||||
|
||||
return bytes;
|
||||
}
|
||||
);
|
||||
|
||||
ContentRegistry::DataInspector::add("hex.builtin.inspector.char32", sizeof(char32_t),
|
||||
[](auto buffer, auto endian, auto style) {
|
||||
std::ignore = style;
|
||||
|
||||
char32_t wideChar = '\x00';
|
||||
std::memcpy(&wideChar, buffer.data(), std::min(sizeof(char32_t), buffer.size()));
|
||||
|
||||
auto c = hex::changeEndianness(wideChar, endian);
|
||||
|
||||
auto value = hex::format("{0}", c <= 255 ? makePrintable(c) : wolv::util::utf32ToUtf8(std::u32string(&c, 1)).value_or("???"));
|
||||
return [value] { ImGuiExt::TextFormatted("'{0}'", value.c_str()); return value; };
|
||||
},
|
||||
[](const std::string &value, std::endian endian) -> std::vector<u8> {
|
||||
std::vector<u8> bytes;
|
||||
auto wideString = wolv::util::utf8ToUtf32(value);
|
||||
if (!wideString.has_value())
|
||||
return bytes;
|
||||
|
||||
bytes.resize(wideString->size() * sizeof(char32_t));
|
||||
std::memcpy(bytes.data(), wideString->data(), bytes.size());
|
||||
bytes.resize(wideString.size() * sizeof(wchar_t));
|
||||
std::memcpy(bytes.data(), wideString.data(), bytes.size());
|
||||
|
||||
if (endian != std::endian::native)
|
||||
std::reverse(bytes.begin(), bytes.end());
|
||||
@@ -496,7 +439,7 @@ namespace hex::plugin::builtin {
|
||||
}
|
||||
);
|
||||
|
||||
ContentRegistry::DataInspector::add("hex.builtin.inspector.wstring", sizeof(wchar_t),
|
||||
ContentRegistry::DataInspector::add("hex.builtin.inspector.string16", 2,
|
||||
[](auto buffer, auto endian, auto style) {
|
||||
std::ignore = buffer;
|
||||
std::ignore = endian;
|
||||
@@ -507,15 +450,17 @@ namespace hex::plugin::builtin {
|
||||
std::string value, copyValue;
|
||||
|
||||
if (currSelection.has_value()) {
|
||||
std::wstring stringBuffer(std::min<size_t>(currSelection->size * sizeof(wchar_t), 0x1000), 0x00);
|
||||
std::u16string stringBuffer(std::min<size_t>(currSelection->size, 0x1000), 0x00);
|
||||
ImHexApi::Provider::get()->read(currSelection->address, stringBuffer.data(), stringBuffer.size());
|
||||
|
||||
for (auto &c : stringBuffer)
|
||||
c = hex::changeEndianness(c, endian);
|
||||
|
||||
std::erase_if(buffer, [](auto c) { return c == 0x00; });
|
||||
auto it = std::remove_if(buffer.begin(), buffer.end(),
|
||||
[](auto c) { return c == 0x00; });
|
||||
buffer.erase(it, buffer.end());
|
||||
|
||||
auto string = wolv::util::wstringToUtf8(stringBuffer).value_or("Invalid");
|
||||
auto string = wolv::util::utf16ToUtf8(stringBuffer, "Invalid");
|
||||
value = copyValue = hex::encodeByteString({ string.begin(), string.end() });
|
||||
|
||||
if (value.size() > MaxStringLength) {
|
||||
@@ -536,86 +481,6 @@ namespace hex::plugin::builtin {
|
||||
}
|
||||
);
|
||||
|
||||
ContentRegistry::DataInspector::add("hex.builtin.inspector.string16", sizeof(char16_t),
|
||||
[](auto buffer, auto endian, auto style) {
|
||||
std::ignore = buffer;
|
||||
std::ignore = endian;
|
||||
std::ignore = style;
|
||||
|
||||
auto currSelection = ImHexApi::HexEditor::getSelection();
|
||||
|
||||
std::string value, copyValue;
|
||||
|
||||
if (currSelection.has_value()) {
|
||||
std::u16string stringBuffer(std::min<size_t>(currSelection->size * sizeof(char16_t), 0x1000), 0x00);
|
||||
ImHexApi::Provider::get()->read(currSelection->address, stringBuffer.data(), stringBuffer.size());
|
||||
|
||||
for (auto &c : stringBuffer)
|
||||
c = hex::changeEndianness(c, endian);
|
||||
|
||||
std::erase_if(buffer, [](auto c) { return c == 0x00; });
|
||||
|
||||
auto string = wolv::util::utf16ToUtf8(stringBuffer).value_or("Invalid");
|
||||
value = copyValue = hex::encodeByteString({ string.begin(), string.end() });
|
||||
|
||||
if (value.size() > MaxStringLength) {
|
||||
value.resize(MaxStringLength);
|
||||
value += "...";
|
||||
}
|
||||
} else {
|
||||
value = "";
|
||||
copyValue = "";
|
||||
}
|
||||
|
||||
return [value, copyValue] { ImGuiExt::TextFormatted("u\"{0}\"", value.c_str()); return copyValue; };
|
||||
},
|
||||
[](const std::string &value, std::endian endian) -> std::vector<u8> {
|
||||
std::ignore = endian;
|
||||
|
||||
return hex::decodeByteString(value);
|
||||
}
|
||||
);
|
||||
|
||||
ContentRegistry::DataInspector::add("hex.builtin.inspector.string32", sizeof(char32_t),
|
||||
[](auto buffer, auto endian, auto style) {
|
||||
std::ignore = buffer;
|
||||
std::ignore = endian;
|
||||
std::ignore = style;
|
||||
|
||||
auto currSelection = ImHexApi::HexEditor::getSelection();
|
||||
|
||||
std::string value, copyValue;
|
||||
|
||||
if (currSelection.has_value()) {
|
||||
std::u32string stringBuffer(std::min<size_t>(currSelection->size * sizeof(char32_t), 0x1000), 0x00);
|
||||
ImHexApi::Provider::get()->read(currSelection->address, stringBuffer.data(), stringBuffer.size());
|
||||
|
||||
for (auto &c : stringBuffer)
|
||||
c = hex::changeEndianness(c, endian);
|
||||
|
||||
std::erase_if(buffer, [](auto c) { return c == 0x00; });
|
||||
|
||||
auto string = wolv::util::utf32ToUtf8(stringBuffer).value_or("Invalid");
|
||||
value = copyValue = hex::encodeByteString({ string.begin(), string.end() });
|
||||
|
||||
if (value.size() > MaxStringLength) {
|
||||
value.resize(MaxStringLength);
|
||||
value += "...";
|
||||
}
|
||||
} else {
|
||||
value = "";
|
||||
copyValue = "";
|
||||
}
|
||||
|
||||
return [value, copyValue] { ImGuiExt::TextFormatted("U\"{0}\"", value.c_str()); return copyValue; };
|
||||
},
|
||||
[](const std::string &value, std::endian endian) -> std::vector<u8> {
|
||||
std::ignore = endian;
|
||||
|
||||
return hex::decodeByteString(value);
|
||||
}
|
||||
);
|
||||
|
||||
#if defined(OS_WINDOWS)
|
||||
|
||||
ContentRegistry::DataInspector::add("hex.builtin.inspector.time32", sizeof(u32), [](auto buffer, auto endian, auto style) {
|
||||
@@ -747,7 +612,7 @@ namespace hex::plugin::builtin {
|
||||
auto copyValue = hex::format("#{:02X}{:02X}{:02X}", u8(0xFF * (color.Value.x)), u8(0xFF * (color.Value.y)), u8(0xFF * (color.Value.z)), 0xFF);
|
||||
|
||||
return [color, copyValue] {
|
||||
ImGui::ColorButton("##inspectorColor", color, ImGuiColorEditFlags_AlphaOpaque, ImVec2(ImGui::GetColumnWidth(), ImGui::GetTextLineHeight()));
|
||||
ImGui::ColorButton("##inspectorColor", color, ImGuiColorEditFlags_None, ImVec2(ImGui::GetColumnWidth(), ImGui::GetTextLineHeight()));
|
||||
return copyValue;
|
||||
};
|
||||
});
|
||||
|
||||
@@ -247,13 +247,9 @@ namespace hex::plugin::builtin {
|
||||
EventFirstLaunch::post();
|
||||
}
|
||||
|
||||
const auto prevLaunchVersionParsed = SemanticVersion(prevLaunchVersion);
|
||||
EventImHexUpdated::post(SemanticVersion(prevLaunchVersion), currVersion);
|
||||
|
||||
if (currVersion != prevLaunchVersionParsed) {
|
||||
EventImHexUpdated::post(prevLaunchVersionParsed, currVersion);
|
||||
|
||||
ContentRegistry::Settings::write<std::string>("hex.builtin.setting.general", "hex.builtin.setting.general.prev_launch_version", currVersion.get(false));
|
||||
}
|
||||
ContentRegistry::Settings::write<std::string>("hex.builtin.setting.general", "hex.builtin.setting.general.prev_launch_version", currVersion.get(false));
|
||||
});
|
||||
|
||||
EventWindowDeinitializing::subscribe([](GLFWwindow *window) {
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
#include <wolv/literals.hpp>
|
||||
|
||||
#include <romfs/romfs.hpp>
|
||||
#include <hex/helpers/menu_items.hpp>
|
||||
#include <ui/menu_items.hpp>
|
||||
|
||||
#include <GLFW/glfw3.h>
|
||||
|
||||
|
||||
@@ -45,7 +45,7 @@ namespace hex::plugin::builtin {
|
||||
ImGui::EndTabBar();
|
||||
}
|
||||
|
||||
if (ImGuiExt::IconHyperlink(ICON_VS_SEARCH, "hex.builtin.view.hex_editor.search.advanced"_lang)) {
|
||||
if(ImGuiExt::IconHyperlink(ICON_VS_SEARCH, "hex.builtin.view.hex_editor.search.advanced"_lang)) {
|
||||
TaskManager::doLater([editor] {
|
||||
const auto& view = ContentRegistry::Views::getViewByName("hex.builtin.view.find.name");
|
||||
|
||||
@@ -286,29 +286,25 @@ namespace hex::plugin::builtin {
|
||||
}
|
||||
case Encoding::UTF16: {
|
||||
auto utf16 = wolv::util::utf8ToUtf16(s_inputString);
|
||||
if (!utf16.has_value())
|
||||
return;
|
||||
|
||||
for (auto &c : *utf16) {
|
||||
for (auto &c: utf16) {
|
||||
swapEndianness(c, Encoding::UTF16, m_stringEndianness);
|
||||
}
|
||||
|
||||
std::copy(reinterpret_cast<const u8 *>(utf16->data()),
|
||||
reinterpret_cast<const u8 *>(utf16->data() + utf16->size()),
|
||||
std::copy(reinterpret_cast<const u8 *>(utf16.data()),
|
||||
reinterpret_cast<const u8 *>(utf16.data() + utf16.size()),
|
||||
std::back_inserter(m_searchByteSequence));
|
||||
break;
|
||||
}
|
||||
case Encoding::UTF32: {
|
||||
auto utf32 = wolv::util::utf8ToUtf32(s_inputString);
|
||||
if (!utf32.has_value())
|
||||
return;
|
||||
|
||||
for (auto &c : *utf32) {
|
||||
for (auto &c: utf32) {
|
||||
swapEndianness(c, Encoding::UTF32, m_stringEndianness);
|
||||
}
|
||||
|
||||
std::copy(reinterpret_cast<const u8 *>(utf32->data()),
|
||||
reinterpret_cast<const u8 *>(utf32->data() + utf32->size()),
|
||||
std::copy(reinterpret_cast<const u8 *>(utf32.data()),
|
||||
reinterpret_cast<const u8 *>(utf32.data() + utf32.size()),
|
||||
std::back_inserter(m_searchByteSequence));
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -463,16 +463,16 @@ namespace hex::plugin::builtin {
|
||||
|
||||
ImGui::PushItemWidth(300_scaled);
|
||||
if (ImGui::BeginListBox("hex.builtin.provider.disk.selected_disk"_lang)) {
|
||||
ImGui::PushID(1);
|
||||
for (const auto &[path, friendlyName] : m_availableDrives) {
|
||||
ImGui::PushID(path.c_str());
|
||||
if (ImGui::Selectable(friendlyName.c_str(), m_path == path)) {
|
||||
m_path = path;
|
||||
m_friendlyName = friendlyName;
|
||||
}
|
||||
ImGui::PopID();
|
||||
|
||||
ImGuiExt::InfoTooltip(path.c_str());
|
||||
}
|
||||
ImGui::PopID();
|
||||
|
||||
ImGui::EndListBox();
|
||||
}
|
||||
|
||||
@@ -33,9 +33,6 @@
|
||||
namespace hex::plugin::builtin {
|
||||
|
||||
bool ProcessMemoryProvider::open() {
|
||||
if (m_selectedProcess == nullptr)
|
||||
return false;
|
||||
|
||||
#if defined(OS_WINDOWS)
|
||||
m_processHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, m_selectedProcess->id);
|
||||
if (m_processHandle == nullptr)
|
||||
|
||||
@@ -52,10 +52,9 @@ namespace hex::plugin::builtin {
|
||||
return false;
|
||||
|
||||
EventProviderClosing::subscribe(this, [this](const prv::Provider *provider, bool*) {
|
||||
if (m_provider == provider) {
|
||||
if (m_provider == provider)
|
||||
ImHexApi::Provider::remove(this, false);
|
||||
m_provider = nullptr;
|
||||
}
|
||||
m_provider = nullptr;
|
||||
});
|
||||
|
||||
return true;
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
|
||||
#include <ranges>
|
||||
#include <unordered_set>
|
||||
#include <hex/helpers/menu_items.hpp>
|
||||
#include <ui/menu_items.hpp>
|
||||
|
||||
namespace hex::plugin::builtin::recent {
|
||||
|
||||
@@ -280,7 +280,7 @@ namespace hex::plugin::builtin::recent {
|
||||
icon = ICON_VS_FILE_BINARY;
|
||||
}
|
||||
|
||||
if (ImGuiExt::IconHyperlink(icon, hex::limitStringLength(recentEntry.displayName, 32).c_str())) {
|
||||
if (ImGuiExt::Hyperlink(hex::format("{} {}", icon, hex::limitStringLength(recentEntry.displayName, 32)).c_str())) {
|
||||
loadRecentEntry(recentEntry);
|
||||
break;
|
||||
}
|
||||
@@ -341,7 +341,7 @@ namespace hex::plugin::builtin::recent {
|
||||
|
||||
if (s_autoBackupsFound) {
|
||||
ImGui::Separator();
|
||||
if (ImGuiExt::IconHyperlink(ICON_VS_ARCHIVE, "hex.builtin.welcome.start.recent.auto_backups"_lang))
|
||||
if (ImGuiExt::Hyperlink(hex::format("{} {}", ICON_VS_ARCHIVE, "hex.builtin.welcome.start.recent.auto_backups"_lang).c_str()))
|
||||
PopupAutoBackups::open();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,6 +27,8 @@ namespace hex::plugin::builtin {
|
||||
|
||||
namespace {
|
||||
|
||||
bool s_showScalingWarning = true;
|
||||
|
||||
/*
|
||||
Values of this setting:
|
||||
0 - do not check for updates on startup
|
||||
@@ -189,6 +191,11 @@ namespace hex::plugin::builtin {
|
||||
else if (m_value > 10)
|
||||
m_value = 10;
|
||||
|
||||
if (s_showScalingWarning && (u32(m_value * 10) % 10) != 0) {
|
||||
ImGui::SameLine();
|
||||
ImGuiExt::HelpHover("hex.builtin.setting.interface.scaling.fractional_warning"_lang, ICON_VS_WARNING, ImGuiExt::GetCustomColorU32(ImGuiCustomCol_ToolbarRed));
|
||||
}
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
||||
@@ -750,8 +757,6 @@ namespace hex::plugin::builtin {
|
||||
ThemeManager::setAccentColor(colorPicker->getColor());
|
||||
});
|
||||
|
||||
ContentRegistry::Settings::add<Widgets::Checkbox>("hex.builtin.setting.interface", "hex.builtin.setting.interface.style", "hex.builtin.setting.interface.show_titlebar_backdrop", true);
|
||||
|
||||
ContentRegistry::Settings::add<ScalingWidget>("hex.builtin.setting.interface", "hex.builtin.setting.interface.style", "hex.builtin.setting.interface.scaling_factor")
|
||||
.requiresRestart();
|
||||
|
||||
@@ -909,7 +914,7 @@ namespace hex::plugin::builtin {
|
||||
ContentRegistry::Settings::add<ToolbarIconsWidget>("hex.builtin.setting.toolbar", "", "hex.builtin.setting.toolbar.icons");
|
||||
}
|
||||
|
||||
ImHexApi::System::addMigrationRoutine("v1.37.0", [] {
|
||||
ImHexApi::System::addMigrationRoutine("v1.36.3", [] {
|
||||
log::warn("Resetting shortcut key settings for them to work with this version of ImHex");
|
||||
|
||||
for (const auto &category : ContentRegistry::Settings::impl::getSettings()) {
|
||||
|
||||
145
plugins/builtin/source/content/sidebar/project_explorer.cpp
Normal file
145
plugins/builtin/source/content/sidebar/project_explorer.cpp
Normal file
@@ -0,0 +1,145 @@
|
||||
#include <imgui.h>
|
||||
#include <imgui_internal.h>
|
||||
#include <hex/ui/imgui_imhex_extensions.h>
|
||||
|
||||
#include <fonts/vscode_icons.hpp>
|
||||
#include <hex/api/content_registry.hpp>
|
||||
#include <hex/api/task_manager.hpp>
|
||||
|
||||
#include <hex/project/project.hpp>
|
||||
#include <hex/project/project_manager.hpp>
|
||||
#include <hex/helpers/utils.hpp>
|
||||
|
||||
namespace hex::plugin::builtin {
|
||||
|
||||
namespace {
|
||||
|
||||
void drawContent(proj::Content &content) {
|
||||
static proj::Content *rightClickedContent = nullptr;
|
||||
static proj::Content *renamingContent = nullptr;
|
||||
static std::string renameText;
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
|
||||
if (renamingContent != &content) {
|
||||
ImGui::Selectable(content.getName().c_str(), content.isOpen(), ImGuiSelectableFlags_SpanAllColumns);
|
||||
} else {
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2());
|
||||
if (ImGui::InputText("##ContentName", renameText)) {
|
||||
renamingContent->setName(renameText);
|
||||
}
|
||||
ImGui::SetKeyboardFocusHere(-1);
|
||||
ImGui::PopStyleVar();
|
||||
|
||||
if (ImGui::IsKeyPressed(ImGuiKey_Enter) || ImGui::IsKeyPressed(ImGuiKey_KeypadEnter)) {
|
||||
renamingContent->setName(renameText);
|
||||
renamingContent = nullptr;
|
||||
}
|
||||
if (ImGui::IsKeyPressed(ImGuiKey_Escape)) {
|
||||
renamingContent = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
if (ImGui::IsItemHovered()) {
|
||||
if (ImGui::IsMouseDoubleClicked(ImGuiMouseButton_Left)) {
|
||||
proj::ProjectManager::loadContent(content);
|
||||
}
|
||||
if (ImGui::IsMouseClicked(ImGuiMouseButton_Right)) {
|
||||
rightClickedContent = &content;
|
||||
ImGui::OpenPopup("ContentContextMenu");
|
||||
}
|
||||
} else {
|
||||
if (ImGui::IsMouseClicked(ImGuiMouseButton_Left) && renamingContent == &content)
|
||||
renamingContent = nullptr;
|
||||
}
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::TextUnformatted(Lang(content.getType()));
|
||||
|
||||
if (rightClickedContent == &content) {
|
||||
if (ImGui::BeginPopup("ContentContextMenu")) {
|
||||
if (ImGui::MenuItemEx("Open", ICON_VS_OPEN_PREVIEW)) {
|
||||
proj::ProjectManager::loadContent(content);
|
||||
}
|
||||
if (ImGui::MenuItemEx("Rename", ICON_VS_DIFF_RENAMED)) {
|
||||
renamingContent = &content;
|
||||
renameText = content.getName();
|
||||
}
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void drawProject(proj::Project &project) {
|
||||
static proj::Project *rightClickedProject = nullptr;
|
||||
|
||||
bool open = ImGui::TreeNodeEx(project.getName().c_str(), ImGuiTreeNodeFlags_Framed | ImGuiTreeNodeFlags_DefaultOpen | ImGuiTreeNodeFlags_SpanAllColumns);
|
||||
|
||||
if (ImGui::IsItemClicked(ImGuiMouseButton_Right)) {
|
||||
rightClickedProject = &project;
|
||||
ImGui::OpenPopup("ProjectContextMenu");
|
||||
}
|
||||
if (rightClickedProject == &project) {
|
||||
if (ImGui::BeginPopup("ProjectContextMenu")) {
|
||||
if (ImGui::BeginMenuEx("Add", ICON_VS_FILE_ADD)) {
|
||||
for (const auto &handler : proj::ProjectManager::getContentHandlers()) {
|
||||
if (ImGui::MenuItem(Lang(handler.type))) {
|
||||
rightClickedProject->addContent(handler.type);
|
||||
}
|
||||
}
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
|
||||
if (ImGui::MenuItemEx("Close", ICON_VS_CLOSE)) {
|
||||
TaskManager::doLater([project = rightClickedProject] {
|
||||
proj::ProjectManager::removeProject(*project);
|
||||
});
|
||||
}
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
}
|
||||
|
||||
if (open) {
|
||||
for (const auto &content : project.getContents()) {
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
|
||||
ImGui::PushID(content.get());
|
||||
|
||||
drawContent(*content);
|
||||
|
||||
ImGui::PopID();
|
||||
}
|
||||
ImGui::TreePop();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void registerProjectExplorer() {
|
||||
ContentRegistry::Interface::addSidebarItem(ICON_VS_PROJECT, [] {
|
||||
if (ImGui::BeginTable("Projects", 3, ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg | ImGuiTableFlags_ScrollY)) {
|
||||
ImGui::TableSetupColumn("##Icon", ImGuiTableColumnFlags_WidthFixed, 20_scaled);
|
||||
ImGui::TableSetupColumn("##Name", ImGuiTableColumnFlags_WidthStretch, 20_scaled);
|
||||
ImGui::TableSetupColumn("##Type", ImGuiTableColumnFlags_WidthFixed, 100_scaled);
|
||||
for (auto &project : proj::ProjectManager::getProjects()) {
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::TableNextColumn();
|
||||
|
||||
ImGui::PushID(project.get());
|
||||
drawProject(*project);
|
||||
ImGui::PopID();
|
||||
|
||||
ImGui::NewLine();
|
||||
}
|
||||
ImGui::EndTable();
|
||||
}
|
||||
});
|
||||
|
||||
proj::ProjectManager::createProject("Project 1");
|
||||
proj::ProjectManager::createProject("Project 2");
|
||||
proj::ProjectManager::createProject("Free Items");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -248,7 +248,7 @@ namespace hex::plugin::builtin {
|
||||
}, nullptr);
|
||||
ImPlot::SetupAxisTicks(ImAxis_Y1, 0, largestFrameTime * 1.25F, 3);
|
||||
|
||||
static std::vector<double> values(100, 0.0);
|
||||
static std::vector<double> values(100);
|
||||
|
||||
values.push_back(ImHexApi::System::getLastFrameTime());
|
||||
if (values.size() > 100)
|
||||
@@ -541,15 +541,6 @@ namespace hex::plugin::builtin {
|
||||
ContentRegistry::Interface::addMenuItemToToolbar("hex.builtin.view.hex_editor.menu.file.save", ImGuiCustomCol_ToolbarBlue);
|
||||
ContentRegistry::Interface::addMenuItemToToolbar("hex.builtin.view.hex_editor.menu.file.save_as", ImGuiCustomCol_ToolbarBlue);
|
||||
ContentRegistry::Interface::addMenuItemToToolbar("hex.builtin.menu.edit.bookmark.create", ImGuiCustomCol_ToolbarGreen);
|
||||
|
||||
const auto &initArgs = ImHexApi::System::getInitArguments();
|
||||
if (auto it = initArgs.find("update-available"); it != initArgs.end()) {
|
||||
ContentRegistry::Interface::addTitleBarButton(ICON_VS_GIFT, "hex.builtin.welcome.update.title", [] {
|
||||
ImHexApi::System::updateImHex(ImHexApi::System::UpdateType::Stable);
|
||||
});
|
||||
|
||||
ui::ToastInfo::open(hex::format("hex.builtin.welcome.update.desc"_lang, it->second));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
#include <wolv/utils/string.hpp>
|
||||
|
||||
#include <string>
|
||||
#include <hex/helpers/menu_items.hpp>
|
||||
#include <ui/menu_items.hpp>
|
||||
|
||||
namespace hex::plugin::builtin {
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include <content/providers/view_provider.hpp>
|
||||
|
||||
#include <fonts/vscode_icons.hpp>
|
||||
#include <hex/project/project_manager.hpp>
|
||||
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
@@ -45,16 +46,16 @@ namespace hex::plugin::builtin {
|
||||
bookmarkId
|
||||
};
|
||||
|
||||
m_bookmarks->emplace_back(std::move(bookmark), true);
|
||||
m_bookmarks.emplace_back(std::move(bookmark), true);
|
||||
|
||||
ImHexApi::Provider::markDirty();
|
||||
|
||||
EventBookmarkCreated::post(m_bookmarks->back().entry);
|
||||
EventBookmarkCreated::post(m_bookmarks.back().entry);
|
||||
EventHighlightingChanged::post();
|
||||
});
|
||||
|
||||
RequestRemoveBookmark::subscribe([this](u64 id) {
|
||||
std::erase_if(m_bookmarks.get(), [id](const auto &bookmark) {
|
||||
std::erase_if(m_bookmarks, [id](const auto &bookmark) {
|
||||
return bookmark.entry.id == id;
|
||||
});
|
||||
});
|
||||
@@ -65,7 +66,7 @@ namespace hex::plugin::builtin {
|
||||
|
||||
// Check all bookmarks for potential overlaps with the current address
|
||||
std::optional<ImColor> color;
|
||||
for (const auto &bookmark : *m_bookmarks) {
|
||||
for (const auto &bookmark : m_bookmarks) {
|
||||
if (!bookmark.highlightVisible)
|
||||
continue;
|
||||
|
||||
@@ -82,7 +83,7 @@ namespace hex::plugin::builtin {
|
||||
std::ignore = data;
|
||||
|
||||
// Loop over all bookmarks
|
||||
for (const auto &[bookmark, highlightVisible] : *m_bookmarks) {
|
||||
for (const auto &[bookmark, highlightVisible] : m_bookmarks) {
|
||||
if (!highlightVisible)
|
||||
continue;
|
||||
|
||||
@@ -100,7 +101,7 @@ namespace hex::plugin::builtin {
|
||||
|
||||
{
|
||||
// Draw bookmark header
|
||||
ImGui::ColorButton("##color", ImColor(bookmark.color), ImGuiColorEditFlags_AlphaOpaque);
|
||||
ImGui::ColorButton("##color", ImColor(bookmark.color));
|
||||
ImGui::SameLine(0, 10);
|
||||
ImGuiExt::TextFormatted("{} ", bookmark.name);
|
||||
|
||||
@@ -158,7 +159,7 @@ namespace hex::plugin::builtin {
|
||||
return true;
|
||||
|
||||
auto data = nlohmann::json::parse(fileContent.begin(), fileContent.end());
|
||||
m_bookmarks.get(provider).clear();
|
||||
m_bookmarks.clear();
|
||||
return this->importBookmarks(provider, data);
|
||||
},
|
||||
.store = [this](prv::Provider *provider, const std::fs::path &basePath, const Tar &tar) -> bool {
|
||||
@@ -170,11 +171,26 @@ namespace hex::plugin::builtin {
|
||||
return result;
|
||||
}
|
||||
});
|
||||
proj::ProjectManager::registerContentHandler({
|
||||
.type = "hex.builtin.project.content_type.bookmarks",
|
||||
.load = [this](const proj::Content &content) {
|
||||
m_bookmarks.clear();
|
||||
|
||||
const auto data = content.isEmpty() ? nlohmann::json() : nlohmann::json::parse(content.getData());
|
||||
this->importBookmarks(ImHexApi::Provider::get(), data);
|
||||
EventHighlightingChanged::post();
|
||||
},
|
||||
.store = [this](proj::Content &content) {
|
||||
nlohmann::json data;
|
||||
this->exportBookmarks(ImHexApi::Provider::get(), data);
|
||||
content.setData(data.dump(4));
|
||||
}
|
||||
});
|
||||
|
||||
ContentRegistry::Reports::addReportProvider([this](prv::Provider *provider) -> std::string {
|
||||
std::string result;
|
||||
|
||||
const auto &bookmarks = m_bookmarks.get(provider);
|
||||
const auto &bookmarks = m_bookmarks;
|
||||
if (bookmarks.empty())
|
||||
return "";
|
||||
|
||||
@@ -252,7 +268,7 @@ namespace hex::plugin::builtin {
|
||||
void ViewBookmarks::drawDropTarget(std::list<Bookmark>::iterator it, float height) {
|
||||
height = std::max(height, 1.0F);
|
||||
|
||||
if (it != m_bookmarks->begin()) {
|
||||
if (it != m_bookmarks.begin()) {
|
||||
ImGui::SetCursorPosY(ImGui::GetCursorPosY() - height);
|
||||
} else {
|
||||
ImGui::SetCursorPosY(ImGui::GetCursorPosY() + height);
|
||||
@@ -261,7 +277,7 @@ namespace hex::plugin::builtin {
|
||||
ImGui::InvisibleButton("##DropTarget", ImVec2(ImGui::GetContentRegionAvail().x, height * 2.0F));
|
||||
const auto dropTarget = ImRect(ImGui::GetItemRectMin(), ImVec2(ImGui::GetItemRectMax().x, ImGui::GetItemRectMin().y + 2_scaled));
|
||||
|
||||
if (it == m_bookmarks->begin()) {
|
||||
if (it == m_bookmarks.begin()) {
|
||||
ImGui::SetCursorPosY(ImGui::GetCursorPosY() - height);
|
||||
}
|
||||
|
||||
@@ -274,13 +290,13 @@ namespace hex::plugin::builtin {
|
||||
u64 droppedBookmarkId = *static_cast<const u64*>(payload->Data);
|
||||
|
||||
// Find the correct bookmark with that id
|
||||
auto droppedIter = std::ranges::find_if(m_bookmarks->begin(), m_bookmarks->end(), [droppedBookmarkId](const auto &bookmarkItem) {
|
||||
auto droppedIter = std::ranges::find_if(m_bookmarks.begin(), m_bookmarks.end(), [droppedBookmarkId](const auto &bookmarkItem) {
|
||||
return bookmarkItem.entry.id == droppedBookmarkId;
|
||||
});
|
||||
|
||||
// Swap the two bookmarks
|
||||
if (droppedIter != m_bookmarks->end()) {
|
||||
m_bookmarks->splice(it, m_bookmarks, droppedIter);
|
||||
if (droppedIter != m_bookmarks.end()) {
|
||||
m_bookmarks.splice(it, m_bookmarks, droppedIter);
|
||||
|
||||
EventHighlightingChanged::post();
|
||||
}
|
||||
@@ -298,18 +314,18 @@ namespace hex::plugin::builtin {
|
||||
ImGui::PopItemWidth();
|
||||
|
||||
if (ImGui::BeginChild("##bookmarks")) {
|
||||
if (m_bookmarks->empty()) {
|
||||
if (m_bookmarks.empty()) {
|
||||
ImGuiExt::TextOverlay("hex.builtin.view.bookmarks.no_bookmarks"_lang, ImGui::GetWindowPos() + ImGui::GetWindowSize() / 2, ImGui::GetWindowWidth() * 0.7);
|
||||
}
|
||||
|
||||
auto bookmarkToRemove = m_bookmarks->end();
|
||||
auto bookmarkToRemove = m_bookmarks.end();
|
||||
const auto defaultItemSpacing = ImGui::GetStyle().ItemSpacing.y;
|
||||
|
||||
ImGui::Dummy({ ImGui::GetContentRegionAvail().x, 0 });
|
||||
drawDropTarget(m_bookmarks->begin(), defaultItemSpacing);
|
||||
drawDropTarget(m_bookmarks.begin(), defaultItemSpacing);
|
||||
|
||||
// Draw all bookmarks
|
||||
for (auto it = m_bookmarks->begin(); it != m_bookmarks->end(); ++it) {
|
||||
for (auto it = m_bookmarks.begin(); it != m_bookmarks.end(); ++it) {
|
||||
auto &[bookmark, highlightVisible] = *it;
|
||||
auto &[region, name, comment, color, locked, bookmarkId] = bookmark;
|
||||
|
||||
@@ -529,15 +545,15 @@ namespace hex::plugin::builtin {
|
||||
}
|
||||
|
||||
// Remove the bookmark that was marked for removal
|
||||
if (bookmarkToRemove != m_bookmarks->end()) {
|
||||
m_bookmarks->erase(bookmarkToRemove);
|
||||
if (bookmarkToRemove != m_bookmarks.end()) {
|
||||
m_bookmarks.erase(bookmarkToRemove);
|
||||
EventHighlightingChanged::post();
|
||||
}
|
||||
}
|
||||
ImGui::EndChild();
|
||||
}
|
||||
|
||||
bool ViewBookmarks::importBookmarks(prv::Provider *provider, const nlohmann::json &json) {
|
||||
bool ViewBookmarks::importBookmarks(prv::Provider *, const nlohmann::json &json) {
|
||||
if (!json.contains("bookmarks"))
|
||||
return false;
|
||||
|
||||
@@ -549,30 +565,32 @@ namespace hex::plugin::builtin {
|
||||
if (!region.contains("address") || !region.contains("size"))
|
||||
continue;
|
||||
|
||||
m_bookmarks.get(provider).push_back({
|
||||
m_bookmarks.push_back({
|
||||
{
|
||||
.region = { region["address"], region["size"] },
|
||||
.name = bookmark["name"],
|
||||
.comment = bookmark["comment"],
|
||||
.color = bookmark["color"],
|
||||
.locked = bookmark["locked"],
|
||||
.id = bookmark.contains("id") ? bookmark["id"].get<u64>() : m_currBookmarkId.get(provider),
|
||||
.id = bookmark.contains("id") ? bookmark["id"].get<u64>() : m_currBookmarkId,
|
||||
},
|
||||
bookmark.contains("highlightVisible") ? bookmark["highlightVisible"].get<bool>() : true,
|
||||
});
|
||||
if (bookmark.contains("id"))
|
||||
m_currBookmarkId.get(provider) = std::max<u64>(m_currBookmarkId.get(provider), bookmark["id"].get<i64>() + 1);
|
||||
m_currBookmarkId = std::max<u64>(m_currBookmarkId, bookmark["id"].get<i64>() + 1);
|
||||
else
|
||||
m_currBookmarkId.get(provider) += 1;
|
||||
m_currBookmarkId += 1;
|
||||
}
|
||||
|
||||
EventHighlightingChanged::post();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ViewBookmarks::exportBookmarks(prv::Provider *provider, nlohmann::json &json) {
|
||||
bool ViewBookmarks::exportBookmarks(prv::Provider *, nlohmann::json &json) {
|
||||
json["bookmarks"] = nlohmann::json::array();
|
||||
size_t index = 0;
|
||||
for (const auto &[bookmark, highlightVisible] : m_bookmarks.get(provider)) {
|
||||
for (const auto &[bookmark, highlightVisible] : m_bookmarks) {
|
||||
json["bookmarks"][index] = {
|
||||
{ "name", bookmark.name },
|
||||
{ "comment", bookmark.comment },
|
||||
@@ -627,7 +645,7 @@ namespace hex::plugin::builtin {
|
||||
wolv::io::File(path, wolv::io::File::Mode::Create).writeString(json.dump(4));
|
||||
});
|
||||
}, [this]{
|
||||
return ImHexApi::Provider::isValid() && !m_bookmarks->empty();
|
||||
return ImHexApi::Provider::isValid() && !m_bookmarks.empty();
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
|
||||
#include <imnodes.h>
|
||||
#include <imnodes_internal.h>
|
||||
#include <hex/project/project_manager.hpp>
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
#include <wolv/io/file.hpp>
|
||||
@@ -361,28 +362,39 @@ namespace hex::plugin::builtin {
|
||||
ProjectFile::registerPerProviderHandler({
|
||||
.basePath = "data_processor.json",
|
||||
.required = false,
|
||||
.load = [this](prv::Provider *provider, const std::fs::path &basePath, const Tar &tar) {
|
||||
.load = [this](prv::Provider *, const std::fs::path &basePath, const Tar &tar) {
|
||||
std::string save = tar.readString(basePath);
|
||||
|
||||
ViewDataProcessor::loadNodes(m_mainWorkspace.get(provider), nlohmann::json::parse(save));
|
||||
this->loadNodes(m_mainWorkspace, nlohmann::json::parse(save));
|
||||
m_updateNodePositions = true;
|
||||
|
||||
return true;
|
||||
},
|
||||
.store = [this](prv::Provider *provider, const std::fs::path &basePath, const Tar &tar) {
|
||||
tar.writeString(basePath, ViewDataProcessor::saveNodes(m_mainWorkspace.get(provider)).dump(4));
|
||||
.store = [this](prv::Provider *, const std::fs::path &basePath, const Tar &tar) {
|
||||
tar.writeString(basePath, this->saveNodes(m_mainWorkspace).dump(4));
|
||||
|
||||
return true;
|
||||
}
|
||||
});
|
||||
proj::ProjectManager::registerContentHandler({
|
||||
.type = "hex.builtin.project.content_type.data_processor",
|
||||
.load = [this](const proj::Content &content) {
|
||||
const nlohmann::json data = content.isEmpty() ? nlohmann::json() : nlohmann::json::parse(content.getData());
|
||||
this->loadNodes(m_mainWorkspace, data);
|
||||
m_updateNodePositions = true;
|
||||
},
|
||||
.store = [this](proj::Content &content) {
|
||||
content.setData(this->saveNodes(m_mainWorkspace).dump(4));
|
||||
}
|
||||
});
|
||||
|
||||
EventProviderOpened::subscribe(this, [this](auto *provider) {
|
||||
m_mainWorkspace.get(provider) = { };
|
||||
m_workspaceStack.get(provider).push_back(&m_mainWorkspace.get(provider));
|
||||
EventProviderOpened::subscribe(this, [this](auto *) {
|
||||
m_mainWorkspace = { };
|
||||
m_workspaceStack.push_back(&m_mainWorkspace);
|
||||
});
|
||||
|
||||
EventProviderChanged::subscribe(this, [this](const auto *, const auto *) {
|
||||
for (auto *workspace : *m_workspaceStack) {
|
||||
for (auto *workspace : m_workspaceStack) {
|
||||
for (auto &node : workspace->nodes) {
|
||||
node->setCurrentOverlay(nullptr);
|
||||
}
|
||||
@@ -399,7 +411,7 @@ namespace hex::plugin::builtin {
|
||||
[&](const std::fs::path &path) {
|
||||
wolv::io::File file(path, wolv::io::File::Mode::Read);
|
||||
if (file.isValid()) {
|
||||
ViewDataProcessor::loadNodes(*m_mainWorkspace, nlohmann::json::parse(file.readString()));
|
||||
ViewDataProcessor::loadNodes(m_mainWorkspace, nlohmann::json::parse(file.readString()));
|
||||
m_updateNodePositions = true;
|
||||
}
|
||||
});
|
||||
@@ -411,17 +423,17 @@ namespace hex::plugin::builtin {
|
||||
[&, this](const std::fs::path &path) {
|
||||
wolv::io::File file(path, wolv::io::File::Mode::Create);
|
||||
if (file.isValid())
|
||||
file.writeString(ViewDataProcessor::saveNodes(*m_mainWorkspace).dump(4));
|
||||
file.writeString(ViewDataProcessor::saveNodes(m_mainWorkspace).dump(4));
|
||||
});
|
||||
}, [this]{
|
||||
return !m_workspaceStack->empty() && !m_workspaceStack->back()->nodes.empty() && ImHexApi::Provider::isValid();
|
||||
return !m_workspaceStack.empty() && !m_workspaceStack.back()->nodes.empty() && ImHexApi::Provider::isValid();
|
||||
});
|
||||
|
||||
ContentRegistry::FileHandler::add({ ".hexnode" }, [this](const auto &path) {
|
||||
wolv::io::File file(path, wolv::io::File::Mode::Read);
|
||||
if (!file.isValid()) return false;
|
||||
|
||||
ViewDataProcessor::loadNodes(*m_mainWorkspace, file.readString());
|
||||
ViewDataProcessor::loadNodes(m_mainWorkspace, file.readString());
|
||||
m_updateNodePositions = true;
|
||||
|
||||
return true;
|
||||
@@ -884,7 +896,7 @@ namespace hex::plugin::builtin {
|
||||
}
|
||||
|
||||
void ViewDataProcessor::drawContent() {
|
||||
auto &workspace = *m_workspaceStack->back();
|
||||
auto &workspace = *m_workspaceStack.back();
|
||||
|
||||
ImGui::BeginDisabled(m_evaluationTask.isRunning());
|
||||
|
||||
@@ -962,7 +974,7 @@ namespace hex::plugin::builtin {
|
||||
ImGuiExt::TextFormattedCentered("{}", "hex.builtin.view.data_processor.help_text"_lang);
|
||||
|
||||
// Draw a close button if there is more than one workspace on the stack
|
||||
if (m_workspaceStack->size() > 1) {
|
||||
if (m_workspaceStack.size() > 1) {
|
||||
ImGui::SetCursorPos(ImVec2(ImGui::GetContentRegionAvail().x - ImGui::GetTextLineHeightWithSpacing() * 1.5F, ImGui::GetTextLineHeightWithSpacing() * 0.2F));
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(4.0F, 4.0F));
|
||||
if (ImGuiExt::DimmedIconButton(ICON_VS_CLOSE, ImGuiExt::GetCustomColorVec4(ImGuiCustomCol_ToolbarRed))) {
|
||||
@@ -1079,7 +1091,7 @@ namespace hex::plugin::builtin {
|
||||
|
||||
// Remove the top-most workspace from the stack if requested
|
||||
if (popWorkspace) {
|
||||
m_workspaceStack->pop_back();
|
||||
m_workspaceStack.pop_back();
|
||||
m_updateNodePositions = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,7 +56,7 @@ namespace hex::plugin::builtin {
|
||||
auto region = occurrence.value.region;
|
||||
const auto value = this->decodeValue(ImHexApi::Provider::get(), occurrence.value, 256);
|
||||
|
||||
ImGui::ColorButton("##color", ImColor(HighlightColor()), ImGuiColorEditFlags_AlphaOpaque);
|
||||
ImGui::ColorButton("##color", ImColor(HighlightColor()));
|
||||
ImGui::SameLine(0, 10);
|
||||
ImGuiExt::TextFormatted("{} ", value);
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
#include <content/popups/popup_blocking_task.hpp>
|
||||
#include <content/popups/hex_editor/popup_hex_editor_find.hpp>
|
||||
#include <pl/patterns/pattern.hpp>
|
||||
#include <hex/helpers/menu_items.hpp>
|
||||
#include <ui/menu_items.hpp>
|
||||
#include <wolv/literals.hpp>
|
||||
|
||||
using namespace std::literals::string_literals;
|
||||
@@ -622,7 +622,7 @@ namespace hex::plugin::builtin {
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
|
||||
ImGui::ColorButton(tooltip.getValue().c_str(), ImColor(tooltip.getColor()), ImGuiColorEditFlags_AlphaOpaque);
|
||||
ImGui::ColorButton(tooltip.getValue().c_str(), ImColor(tooltip.getColor()));
|
||||
ImGui::SameLine(0, 10);
|
||||
ImGui::TextUnformatted(tooltip.getValue().c_str());
|
||||
|
||||
|
||||
@@ -36,7 +36,9 @@
|
||||
|
||||
#include <content/global_actions.hpp>
|
||||
#include <fonts/fonts.hpp>
|
||||
#include <hex/helpers/menu_items.hpp>
|
||||
#include <hex/project/project.hpp>
|
||||
#include <hex/project/project_manager.hpp>
|
||||
#include <ui/menu_items.hpp>
|
||||
|
||||
namespace hex::plugin::builtin {
|
||||
|
||||
@@ -579,7 +581,7 @@ namespace hex::plugin::builtin {
|
||||
}
|
||||
}
|
||||
|
||||
if (m_textEditor.IsTextChanged() && !m_hasUnevaluatedChanges) {
|
||||
if (m_textEditor.IsTextChanged()) {
|
||||
m_hasUnevaluatedChanges = true;
|
||||
m_lastEditorChangeTime = std::chrono::steady_clock::now();
|
||||
ImHexApi::Provider::markDirty();
|
||||
@@ -587,6 +589,7 @@ namespace hex::plugin::builtin {
|
||||
|
||||
if (m_hasUnevaluatedChanges && m_runningEvaluators == 0 && m_runningParsers == 0) {
|
||||
if ((std::chrono::steady_clock::now() - m_lastEditorChangeTime) > std::chrono::seconds(1LL)) {
|
||||
m_hasUnevaluatedChanges = false;
|
||||
|
||||
auto code = m_textEditor.GetText();
|
||||
EventPatternEditorChanged::post(code);
|
||||
@@ -597,8 +600,6 @@ namespace hex::plugin::builtin {
|
||||
if (m_runAutomatically)
|
||||
m_triggerAutoEvaluate = true;
|
||||
});
|
||||
m_hasUnevaluatedChanges = false;
|
||||
m_textEditor.SetTextChanged();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1692,7 +1693,7 @@ namespace hex::plugin::builtin {
|
||||
ImGui::PushID(pattern);
|
||||
{
|
||||
const bool shiftHeld = ImGui::GetIO().KeyShift;
|
||||
ImGui::ColorButton(pattern->getVariableName().c_str(), ImColor(pattern->getColor()), ImGuiColorEditFlags_AlphaOpaque);
|
||||
ImGui::ColorButton(pattern->getVariableName().c_str(), ImColor(pattern->getColor()));
|
||||
ImGui::SameLine(0, 10);
|
||||
ImGuiExt::TextFormattedColored(TextEditor::GetPalette()[u32(TextEditor::PaletteIndex::KnownIdentifier)], "{} ", pattern->getFormattedName());
|
||||
ImGui::SameLine(0, 5);
|
||||
@@ -1900,7 +1901,6 @@ namespace hex::plugin::builtin {
|
||||
|
||||
m_accessHistory = {};
|
||||
m_accessHistoryIndex = 0;
|
||||
m_patternEvaluating = true;
|
||||
|
||||
EventHighlightingChanged::post();
|
||||
|
||||
@@ -1949,8 +1949,7 @@ namespace hex::plugin::builtin {
|
||||
runtime.setLogCallback([this, provider](auto level, auto message) {
|
||||
std::scoped_lock lock(m_logMutex);
|
||||
|
||||
auto lines = wolv::util::splitString(message, "\n");
|
||||
for (auto &line : lines) {
|
||||
for (auto line : wolv::util::splitString(message, "\n")) {
|
||||
if (!wolv::util::trim(line).empty()) {
|
||||
switch (level) {
|
||||
using enum pl::core::LogConsole::Level;
|
||||
@@ -2302,6 +2301,16 @@ namespace hex::plugin::builtin {
|
||||
}
|
||||
});
|
||||
|
||||
proj::ProjectManager::registerContentHandler({
|
||||
.type = "hex.builtin.project.content_type.pattern",
|
||||
.load = [this](const proj::Content &content) {
|
||||
m_textEditor.SetText(content.getData());
|
||||
},
|
||||
.store = [this](proj::Content &content) {
|
||||
content.setData(wolv::util::trim(m_textEditor.GetText()));
|
||||
}
|
||||
});
|
||||
|
||||
ShortcutManager::addShortcut(this, CTRLCMD + Keys::G + AllowWhileTyping, "hex.builtin.view.pattern_editor.shortcut.goto_line", [this] {
|
||||
m_openGotoLinePopUp = true;
|
||||
});
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
namespace hex::plugin::builtin {
|
||||
|
||||
ViewProviderSettings::ViewProviderSettings() : View::Modal("hex.builtin.view.provider_settings.name") {
|
||||
EventProviderCreated::subscribe(this, [this](const hex::prv::Provider *provider) {
|
||||
EventProviderOpened::subscribe(this, [this](const hex::prv::Provider *provider) {
|
||||
if (provider->hasLoadInterface() && !provider->shouldSkipLoadInterface())
|
||||
this->getWindowOpenState() = true;
|
||||
});
|
||||
@@ -28,7 +28,7 @@ namespace hex::plugin::builtin {
|
||||
}
|
||||
|
||||
ViewProviderSettings::~ViewProviderSettings() {
|
||||
EventProviderCreated::unsubscribe(this);
|
||||
EventProviderOpened::unsubscribe(this);
|
||||
}
|
||||
|
||||
void ViewProviderSettings::drawContent() {
|
||||
|
||||
@@ -38,16 +38,15 @@ namespace hex::plugin::builtin {
|
||||
|
||||
m_httpRequest.setTimeout(30'0000);
|
||||
|
||||
addCategory("hex.builtin.view.store.tab.patterns", "patterns", &paths::Patterns);
|
||||
addCategory("hex.builtin.view.store.tab.includes", "includes", &paths::PatternsInclude);
|
||||
addCategory("hex.builtin.view.store.tab.magic", "magic", &paths::Magic, []{
|
||||
addCategory("hex.builtin.view.store.tab.patterns", "patterns", &paths::Patterns);
|
||||
addCategory("hex.builtin.view.store.tab.includes", "includes", &paths::PatternsInclude);
|
||||
addCategory("hex.builtin.view.store.tab.magic", "magic", &paths::Magic, []{
|
||||
magic::compile();
|
||||
});
|
||||
addCategory("hex.builtin.view.store.tab.nodes", "nodes", &paths::Nodes);
|
||||
addCategory("hex.builtin.view.store.tab.encodings", "encodings", &paths::Encodings);
|
||||
addCategory("hex.builtin.view.store.tab.disassemblers","disassemblers", &paths::Disassemblers);
|
||||
addCategory("hex.builtin.view.store.tab.constants", "constants", &paths::Constants);
|
||||
addCategory("hex.builtin.view.store.tab.themes", "themes", &paths::Themes, [this]{
|
||||
addCategory("hex.builtin.view.store.tab.nodes", "nodes", &paths::Nodes);
|
||||
addCategory("hex.builtin.view.store.tab.encodings", "encodings", &paths::Encodings);
|
||||
addCategory("hex.builtin.view.store.tab.constants", "constants", &paths::Constants);
|
||||
addCategory("hex.builtin.view.store.tab.themes", "themes", &paths::Themes, [this]{
|
||||
auto themeFile = wolv::io::File(m_downloadPath, wolv::io::File::Mode::Read);
|
||||
|
||||
ThemeManager::addTheme(themeFile.readString());
|
||||
|
||||
@@ -37,8 +37,6 @@
|
||||
|
||||
#include <string>
|
||||
#include <random>
|
||||
#include <banners/banner_button.hpp>
|
||||
#include <banners/banner_icon.hpp>
|
||||
|
||||
namespace hex::plugin::builtin {
|
||||
|
||||
@@ -379,6 +377,14 @@ namespace hex::plugin::builtin {
|
||||
}
|
||||
ImGuiExt::EndSubWindow();
|
||||
|
||||
if (ImHexApi::System::getInitArguments().contains("update-available")) {
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
|
||||
if (ImGuiExt::DescriptionButton("hex.builtin.welcome.update.title"_lang, hex::format("hex.builtin.welcome.update.desc"_lang, ImHexApi::System::getInitArgument("update-available")).c_str(), ImVec2(ImGui::GetContentRegionAvail().x * 0.8F, 0)))
|
||||
ImHexApi::System::updateImHex(ImHexApi::System::UpdateType::Stable);
|
||||
}
|
||||
|
||||
ImGui::EndTable();
|
||||
}
|
||||
ImGui::SameLine();
|
||||
@@ -759,21 +765,6 @@ namespace hex::plugin::builtin {
|
||||
TaskManager::doLater([]{
|
||||
AchievementManager::unlockAchievement("hex.builtin.achievement.starting_out", "hex.builtin.achievement.starting_out.crash.name");
|
||||
});
|
||||
} else {
|
||||
std::random_device rd;
|
||||
if (ImHexApi::System::isCorporateEnvironment()) {
|
||||
if (rd() % 25 == 0) {
|
||||
ui::BannerButton::open(ICON_VS_HEART, "Using ImHex for professional work? Ask your boss to sponsor us and get private E-Mail support and more!", ImColor(0x68, 0xA7, 0x70), "Donate Now!", [] {
|
||||
hex::openWebpage("https://imhex.werwolv.net/donate_work");
|
||||
});
|
||||
}
|
||||
} else {
|
||||
if (rd() % 75 == 0) {
|
||||
ui::BannerButton::open(ICON_VS_HEART, "ImHex needs your help to stay alive! Donate now to fund infrastructure and further development", ImColor(0x68, 0xA7, 0x70), "Donate Now!", [] {
|
||||
hex::openWebpage("https://github.com/sponsors/WerWolv");
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Load info banner texture either locally or from the server
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
#include <imgui_internal.h>
|
||||
#include <random>
|
||||
#include <hex/ui/imgui_imhex_extensions.h>
|
||||
#include <hex/helpers/menu_items.hpp>
|
||||
#include <ui/menu_items.hpp>
|
||||
|
||||
#include <fonts/vscode_icons.hpp>
|
||||
#include <hex/api/tutorial_manager.hpp>
|
||||
@@ -35,16 +35,6 @@ namespace hex::plugin::builtin {
|
||||
bool s_showSearchBar = true;
|
||||
bool s_displayShortcutHighlights = true;
|
||||
bool s_useNativeMenuBar = false;
|
||||
bool s_showTitlebarBackDrop = true;
|
||||
|
||||
void drawTitleBarBackDrop() {
|
||||
if (!s_showTitlebarBackDrop)
|
||||
return;
|
||||
|
||||
const auto diameter = 800_scaled;
|
||||
const auto pos = ImHexApi::System::getMainWindowPosition() - ImVec2(0, diameter / 2);
|
||||
ImGui::GetWindowDrawList()->AddShadowCircle(pos, diameter / 2, ImGui::GetColorU32(ImGuiCol_ButtonActive, 0.8F), diameter / 4, ImVec2());
|
||||
}
|
||||
|
||||
void createNestedMenu(std::span<const UnlocalizedString> menuItems, const char *icon, const Shortcut &shortcut, View *view, const ContentRegistry::Interface::impl::MenuCallback &callback, const ContentRegistry::Interface::impl::EnabledCallback &enabledCallback, const ContentRegistry::Interface::impl::SelectedCallback &selectedCallback) {
|
||||
const auto &name = menuItems.front();
|
||||
@@ -412,7 +402,7 @@ namespace hex::plugin::builtin {
|
||||
if (ImHexApi::System::isBorderlessWindowModeEnabled()) {
|
||||
#if defined(OS_WINDOWS)
|
||||
ImGui::SetCursorPosX(5_scaled);
|
||||
ImGui::Image(*s_logoTexture, s_logoTexture->getSize() * 0.1_scaled);
|
||||
ImGui::Image(*s_logoTexture, s_logoTexture->getSize() * u32(1_scaled));
|
||||
ImGui::SetCursorPosX(5_scaled);
|
||||
ImGui::InvisibleButton("##logo", ImVec2(menuBarHeight, menuBarHeight));
|
||||
if (ImGui::IsItemHovered() && ImGui::IsAnyMouseDown())
|
||||
@@ -448,7 +438,6 @@ namespace hex::plugin::builtin {
|
||||
menu::enableNativeMenuBar(false);
|
||||
|
||||
if (ImGui::BeginMainMenuBar()) {
|
||||
drawTitleBarBackDrop();
|
||||
ImGui::Dummy({});
|
||||
|
||||
ImGui::PopStyleVar(2);
|
||||
@@ -488,7 +477,6 @@ namespace hex::plugin::builtin {
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, 0.0F);
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 0.0F);
|
||||
if (ImGui::BeginMenuBar()) {
|
||||
drawTitleBarBackDrop();
|
||||
for (const auto &callback : ContentRegistry::Interface::impl::getToolbarItems()) {
|
||||
callback();
|
||||
ImGui::SameLine();
|
||||
@@ -664,10 +652,6 @@ namespace hex::plugin::builtin {
|
||||
s_useNativeMenuBar = value.get<bool>(true);
|
||||
});
|
||||
|
||||
ContentRegistry::Settings::onChange("hex.builtin.setting.interface", "hex.builtin.setting.interface.show_titlebar_backdrop", [](const ContentRegistry::Settings::SettingsValue &value) {
|
||||
s_showTitlebarBackDrop = value.get<bool>(true);
|
||||
});
|
||||
|
||||
ContentRegistry::Settings::onChange("hex.builtin.setting.interface", "hex.builtin.setting.interface.randomize_window_title", [](const ContentRegistry::Settings::SettingsValue &value) {
|
||||
const bool randomTitle = value.get<bool>(false);
|
||||
if (randomTitle) {
|
||||
|
||||
@@ -45,6 +45,7 @@ namespace hex::plugin::builtin {
|
||||
void registerReportGenerators();
|
||||
void registerTutorials();
|
||||
void registerDataInformationSections();
|
||||
void registerProjectExplorer();
|
||||
void loadWorkspaces();
|
||||
|
||||
void addWindowDecoration();
|
||||
@@ -140,6 +141,7 @@ IMHEX_PLUGIN_SETUP("Built-in", "WerWolv", "Default ImHex functionality") {
|
||||
registerReportGenerators();
|
||||
registerTutorials();
|
||||
registerDataInformationSections();
|
||||
registerProjectExplorer();
|
||||
loadWorkspaces();
|
||||
addWindowDecoration();
|
||||
createWelcomeScreen();
|
||||
|
||||
@@ -122,7 +122,6 @@ namespace hex::plugin::diffing {
|
||||
column.provider = -1;
|
||||
column.hexEditor.setSelectionUnchecked(std::nullopt, std::nullopt);
|
||||
column.diffTree.clear();
|
||||
column.differences.clear();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -355,34 +354,32 @@ namespace hex::plugin::diffing {
|
||||
// Draw changes
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Indent();
|
||||
if (a.provider != -1 && b.provider != -1) {
|
||||
switch (typeA) {
|
||||
case DifferenceType::Insertion:
|
||||
data.resize(std::min<u64>(17, (regionA.end - regionA.start) + 1));
|
||||
providers[a.provider]->read(regionA.start, data.data(), data.size());
|
||||
drawByteString(data);
|
||||
break;
|
||||
case DifferenceType::Mismatch:
|
||||
data.resize(std::min<u64>(17, (regionA.end - regionA.start) + 1));
|
||||
providers[a.provider]->read(regionA.start, data.data(), data.size());
|
||||
drawByteString(data);
|
||||
switch (typeA) {
|
||||
case DifferenceType::Insertion:
|
||||
data.resize(std::min<u64>(17, (regionA.end - regionA.start) + 1));
|
||||
providers[a.provider]->read(regionA.start, data.data(), data.size());
|
||||
drawByteString(data);
|
||||
break;
|
||||
case DifferenceType::Mismatch:
|
||||
data.resize(std::min<u64>(17, (regionA.end - regionA.start) + 1));
|
||||
providers[a.provider]->read(regionA.start, data.data(), data.size());
|
||||
drawByteString(data);
|
||||
|
||||
ImGui::SameLine(0, 0);
|
||||
ImGuiExt::TextFormatted(" {} ", ICON_VS_ARROW_RIGHT);
|
||||
ImGui::SameLine(0, 0);
|
||||
ImGui::SameLine(0, 0);
|
||||
ImGuiExt::TextFormatted(" {} ", ICON_VS_ARROW_RIGHT);
|
||||
ImGui::SameLine(0, 0);
|
||||
|
||||
data.resize(std::min<u64>(17, (regionB.end - regionB.start) + 1));
|
||||
providers[b.provider]->read(regionB.start, data.data(), data.size());
|
||||
drawByteString(data);
|
||||
break;
|
||||
case DifferenceType::Deletion:
|
||||
data.resize(std::min<u64>(17, (regionB.end - regionB.start) + 1));
|
||||
providers[b.provider]->read(regionB.start, data.data(), data.size());
|
||||
drawByteString(data);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
data.resize(std::min<u64>(17, (regionB.end - regionB.start) + 1));
|
||||
providers[b.provider]->read(regionB.start, data.data(), data.size());
|
||||
drawByteString(data);
|
||||
break;
|
||||
case DifferenceType::Deletion:
|
||||
data.resize(std::min<u64>(17, (regionB.end - regionB.start) + 1));
|
||||
providers[b.provider]->read(regionB.start, data.data(), data.size());
|
||||
drawByteString(data);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
ImGui::Unindent();
|
||||
|
||||
|
||||
@@ -46,8 +46,7 @@ namespace hex::plugin::disasm {
|
||||
|
||||
for (u8 byte : instruction.bytes)
|
||||
disassembly.bytes += hex::format("{0:02X} ", byte);
|
||||
if (!disassembly.bytes.empty())
|
||||
disassembly.bytes.pop_back();
|
||||
disassembly.bytes.pop_back();
|
||||
|
||||
return disassembly;
|
||||
}
|
||||
|
||||
@@ -34,6 +34,8 @@ namespace hex::plugin::disasm {
|
||||
}
|
||||
|
||||
ViewDisassembler::~ViewDisassembler() {
|
||||
EventDataChanged::unsubscribe(this);
|
||||
EventRegionSelected::unsubscribe(this);
|
||||
EventProviderDeleted::unsubscribe(this);
|
||||
}
|
||||
|
||||
@@ -52,10 +54,6 @@ namespace hex::plugin::disasm {
|
||||
|
||||
// Create a capstone disassembler instance
|
||||
if (currArchitecture->start()) {
|
||||
ON_SCOPE_EXIT {
|
||||
currArchitecture->end();
|
||||
};
|
||||
|
||||
std::vector<u8> buffer(1_MiB, 0x00);
|
||||
|
||||
const u64 codeOffset = region.getStartAddress() - m_imageBaseAddress;
|
||||
@@ -82,9 +80,6 @@ namespace hex::plugin::disasm {
|
||||
|
||||
disassembly.push_back(instruction.value());
|
||||
|
||||
if (instruction->size == 0 || instruction->size > code.size())
|
||||
break;
|
||||
|
||||
code = code.subspan(instruction->size);
|
||||
instructionDataAddress += instruction->size;
|
||||
instructionLoadAddress += instruction->size;
|
||||
@@ -97,6 +92,8 @@ namespace hex::plugin::disasm {
|
||||
if (hadError) break;
|
||||
hadError = true;
|
||||
}
|
||||
|
||||
currArchitecture->end();
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -138,64 +135,59 @@ namespace hex::plugin::disasm {
|
||||
auto ®ion = m_regionToDisassemble.get(provider);
|
||||
auto &range = m_range.get(provider);
|
||||
|
||||
ImGui::BeginDisabled(m_disassemblerTask.isRunning());
|
||||
// Draw region selection picker
|
||||
ui::regionSelectionPicker(®ion, provider, &range, true, true);
|
||||
|
||||
ImGuiExt::Header("hex.disassembler.view.disassembler.position"_lang);
|
||||
|
||||
// Draw base address input
|
||||
{
|
||||
// Draw region selection picker
|
||||
ui::regionSelectionPicker(®ion, provider, &range, true, true);
|
||||
auto &address = m_imageLoadAddress.get(provider);
|
||||
ImGuiExt::InputHexadecimal("hex.disassembler.view.disassembler.image_load_address"_lang, &address, ImGuiInputTextFlags_CharsHexadecimal);
|
||||
ImGui::SameLine();
|
||||
ImGuiExt::HelpHover("hex.disassembler.view.disassembler.image_load_address.hint"_lang, ICON_VS_INFO);
|
||||
}
|
||||
|
||||
ImGuiExt::Header("hex.disassembler.view.disassembler.position"_lang);
|
||||
|
||||
// Draw base address input
|
||||
{
|
||||
auto &address = m_imageLoadAddress.get(provider);
|
||||
ImGuiExt::InputHexadecimal("hex.disassembler.view.disassembler.image_load_address"_lang, &address, ImGuiInputTextFlags_CharsHexadecimal);
|
||||
ImGui::SameLine();
|
||||
ImGuiExt::HelpHover("hex.disassembler.view.disassembler.image_load_address.hint"_lang, ICON_VS_INFO);
|
||||
}
|
||||
|
||||
// Draw code region start address input
|
||||
ImGui::BeginDisabled(m_range == ui::RegionType::EntireData);
|
||||
{
|
||||
auto &address = m_imageBaseAddress.get(provider);
|
||||
ImGuiExt::InputHexadecimal("hex.disassembler.view.disassembler.image_base_address"_lang, &address, ImGuiInputTextFlags_CharsHexadecimal);
|
||||
ImGui::SameLine();
|
||||
ImGuiExt::HelpHover("hex.disassembler.view.disassembler.image_base_address.hint"_lang, ICON_VS_INFO);
|
||||
}
|
||||
ImGui::EndDisabled();
|
||||
|
||||
// Draw settings
|
||||
{
|
||||
ImGuiExt::Header("hex.ui.common.settings"_lang);
|
||||
|
||||
// Draw architecture selector
|
||||
const auto &architectures = ContentRegistry::Disassembler::impl::getArchitectures();
|
||||
if (architectures.empty()) {
|
||||
ImGuiExt::TextSpinner("hex.disassembler.view.disassembler.arch"_lang);
|
||||
} else {
|
||||
const auto &currArchitecture = m_currArchitecture.get(provider);
|
||||
if (currArchitecture == nullptr) {
|
||||
m_currArchitecture = architectures.begin()->second();
|
||||
}
|
||||
|
||||
if (ImGui::BeginCombo("hex.disassembler.view.disassembler.arch"_lang, currArchitecture->getName().c_str())) {
|
||||
for (const auto &[name, creator] : architectures) {
|
||||
if (ImGui::Selectable(name.c_str(), name == currArchitecture->getName())) {
|
||||
m_currArchitecture = creator();
|
||||
}
|
||||
}
|
||||
ImGui::EndCombo();
|
||||
}
|
||||
|
||||
// Draw sub-settings for each architecture
|
||||
if (ImGuiExt::BeginBox()) {
|
||||
currArchitecture->drawSettings();
|
||||
}
|
||||
ImGuiExt::EndBox();
|
||||
}
|
||||
}
|
||||
// Draw code region start address input
|
||||
ImGui::BeginDisabled(m_range == ui::RegionType::EntireData);
|
||||
{
|
||||
auto &address = m_imageBaseAddress.get(provider);
|
||||
ImGuiExt::InputHexadecimal("hex.disassembler.view.disassembler.image_base_address"_lang, &address, ImGuiInputTextFlags_CharsHexadecimal);
|
||||
ImGui::SameLine();
|
||||
ImGuiExt::HelpHover("hex.disassembler.view.disassembler.image_base_address.hint"_lang, ICON_VS_INFO);
|
||||
}
|
||||
ImGui::EndDisabled();
|
||||
|
||||
// Draw settings
|
||||
{
|
||||
ImGuiExt::Header("hex.ui.common.settings"_lang);
|
||||
|
||||
// Draw architecture selector
|
||||
const auto &architectures = ContentRegistry::Disassembler::impl::getArchitectures();
|
||||
if (architectures.empty()) {
|
||||
ImGuiExt::TextSpinner("hex.disassembler.view.disassembler.arch"_lang);
|
||||
} else {
|
||||
const auto &currArchitecture = m_currArchitecture.get(provider);
|
||||
if (currArchitecture == nullptr) {
|
||||
m_currArchitecture = architectures.begin()->second();
|
||||
}
|
||||
|
||||
if (ImGui::BeginCombo("hex.disassembler.view.disassembler.arch"_lang, currArchitecture->getName().c_str())) {
|
||||
for (const auto &[name, creator] : architectures) {
|
||||
if (ImGui::Selectable(name.c_str(), name == currArchitecture->getName())) {
|
||||
m_currArchitecture = creator();
|
||||
}
|
||||
}
|
||||
ImGui::EndCombo();
|
||||
}
|
||||
|
||||
// Draw sub-settings for each architecture
|
||||
if (ImGuiExt::BeginBox()) {
|
||||
currArchitecture->drawSettings();
|
||||
}
|
||||
ImGuiExt::EndBox();
|
||||
}
|
||||
}
|
||||
|
||||
// Draw disassemble button
|
||||
ImGui::BeginDisabled(m_disassemblerTask.isRunning() || region.getStartAddress() < m_imageBaseAddress);
|
||||
|
||||
@@ -37,18 +37,13 @@ namespace hex::fonts {
|
||||
});
|
||||
}
|
||||
|
||||
u32 index = 0;
|
||||
for (const auto &[path, fontName] : hex::getFonts()) {
|
||||
ImGui::PushID(index);
|
||||
if (ImGui::Selectable(limitStringLength(fontName, 50).c_str(), m_path == path)) {
|
||||
m_path = path;
|
||||
m_pixelPerfectFont = false;
|
||||
changed = true;
|
||||
}
|
||||
ImGui::SetItemTooltip("%s", fontName.c_str());
|
||||
ImGui::PopID();
|
||||
|
||||
index += 1;
|
||||
}
|
||||
|
||||
ImGui::EndCombo();
|
||||
|
||||
@@ -65,9 +65,7 @@ namespace hex::fonts {
|
||||
return;
|
||||
}
|
||||
|
||||
TaskManager::doLater([&name, &font, &widget] {
|
||||
loadFont(widget, name, &font, ImHexApi::System::getGlobalScale() * ImHexApi::System::getBackingScaleFactor());
|
||||
});
|
||||
loadFont(widget, name, &font, ImHexApi::System::getGlobalScale() * ImHexApi::System::getBackingScaleFactor());
|
||||
});
|
||||
|
||||
loadFont(widget.getWidget(), name, &font, ImHexApi::System::getGlobalScale() * ImHexApi::System::getBackingScaleFactor());
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
#include <hex/api/localization_manager.hpp>
|
||||
|
||||
#include <hex/helpers/logger.hpp>
|
||||
#include <hex/helpers/menu_items.hpp>
|
||||
#include <hex/ui/imgui_imhex_extensions.h>
|
||||
|
||||
#include <loaders/dotnet/dotnet_loader.hpp>
|
||||
@@ -89,7 +88,7 @@ std::vector<const Script*> loadAllScripts() {
|
||||
hex::ContentRegistry::Interface::addMenuItemSubMenu({ "hex.builtin.menu.extras" }, 5000, [] {
|
||||
static bool menuJustOpened = true;
|
||||
|
||||
if (menu::beginMenuEx("hex.script_loader.menu.run_script"_lang, ICON_VS_LIBRARY)) {
|
||||
if (ImGui::BeginMenuEx("hex.script_loader.menu.run_script"_lang, ICON_VS_LIBRARY)) {
|
||||
if (menuJustOpened) {
|
||||
menuJustOpened = false;
|
||||
if (!updaterTask.isRunning()) {
|
||||
@@ -100,9 +99,9 @@ std::vector<const Script*> loadAllScripts() {
|
||||
}
|
||||
|
||||
if (updaterTask.isRunning()) {
|
||||
menu::menuItem("hex.script_loader.menu.loading"_lang, Shortcut::None, false, false);
|
||||
ImGuiExt::TextSpinner("hex.script_loader.menu.loading"_lang);
|
||||
} else if (scripts.empty()) {
|
||||
menu::menuItem("hex.script_loader.menu.no_scripts"_lang, Shortcut::None, false, false);
|
||||
ImGui::TextUnformatted("hex.script_loader.menu.no_scripts"_lang);
|
||||
}
|
||||
|
||||
for (const auto &script : scripts) {
|
||||
@@ -110,14 +109,14 @@ std::vector<const Script*> loadAllScripts() {
|
||||
if (background)
|
||||
continue;
|
||||
|
||||
if (menu::menuItem(name.c_str())) {
|
||||
if (ImGui::MenuItem(name.c_str(), loader->getTypeName().c_str())) {
|
||||
runnerTask = TaskManager::createTask("hex.script_loader.task.running", TaskManager::NoProgress, [entryPoint](auto&) {
|
||||
entryPoint();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
menu::endMenu();
|
||||
ImGui::EndMenu();
|
||||
} else {
|
||||
menuJustOpened = true;
|
||||
}
|
||||
|
||||
@@ -17,4 +17,11 @@ add_imhex_plugin(
|
||||
LIBRARIES
|
||||
fonts
|
||||
LIBRARY_PLUGIN
|
||||
)
|
||||
)
|
||||
|
||||
if (APPLE)
|
||||
target_sources(ui PRIVATE source/ui/macos_menu.m)
|
||||
find_library(FOUNDATION NAMES Foundation REQUIRED)
|
||||
find_library(COCOA NAMES Cocoa REQUIRED)
|
||||
target_link_libraries(ui PUBLIC ${FOUNDATION} ${COCOA})
|
||||
endif()
|
||||
@@ -13,7 +13,7 @@ namespace hex::ui {
|
||||
: Banner(color), m_icon(icon), m_message(std::move(message)), m_buttonText(std::move(buttonText)), m_buttonCallback(std::move(buttonCallback)) { }
|
||||
|
||||
void drawContent() override {
|
||||
const std::string buttonText = hex::format(" {} ", Lang(m_buttonText).get());
|
||||
const std::string buttonText = Lang(m_buttonText);
|
||||
const auto buttonSize = ImGui::CalcTextSize(buttonText.c_str());
|
||||
const auto iconSize = ImGui::CalcTextSize(m_icon);
|
||||
const auto textHeight = std::max(ImGui::CalcTextSize(Lang(m_message)).y, iconSize.y);
|
||||
@@ -37,14 +37,11 @@ namespace hex::ui {
|
||||
|
||||
ImGui::SetCursorPosX(ImGui::GetCursorPosX() + ImGui::GetContentRegionAvail().x - buttonSize.x - 20_scaled);
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 2_scaled);
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 1_scaled);
|
||||
ImGui::PushStyleColor(ImGuiCol_Button, ImGui::GetColorU32(ImGuiCol_Tab));
|
||||
if (ImGui::SmallButton(buttonText.c_str())) {
|
||||
m_buttonCallback();
|
||||
this->close();
|
||||
}
|
||||
ImGui::PopStyleColor();
|
||||
ImGui::PopStyleVar(2);
|
||||
ImGui::PopStyleVar(1);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
@@ -564,7 +564,7 @@ namespace hex::ui {
|
||||
ImGui::TableSetupColumn("");
|
||||
|
||||
// Byte columns
|
||||
for (u64 i = 0; i < columnCount; i++) {
|
||||
for (u16 i = 0; i < columnCount; i++) {
|
||||
if (isColumnSeparatorColumn(i, columnCount))
|
||||
ImGui::TableSetupColumn("", ImGuiTableColumnFlags_WidthFixed, SeparatorColumWidth);
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#include <../../../../lib/libimhex/include/hex/helpers/menu_items.hpp>
|
||||
#include <ui/menu_items.hpp>
|
||||
|
||||
#include <imgui.h>
|
||||
#include <imgui_internal.h>
|
||||
|
||||
@@ -119,7 +119,7 @@ namespace hex::ui {
|
||||
|
||||
void drawOffsetColumns(const pl::ptrn::Pattern& pattern) {
|
||||
auto *bitfieldMember = dynamic_cast<const pl::ptrn::PatternBitfieldMember*>(&pattern);
|
||||
if (bitfieldMember != nullptr && bitfieldMember->getParent() != nullptr) {
|
||||
if (bitfieldMember != nullptr && bitfieldMember->getParentBitfield() != nullptr) {
|
||||
drawOffsetColumnForBitfieldMember(*bitfieldMember);
|
||||
return;
|
||||
}
|
||||
@@ -179,7 +179,7 @@ namespace hex::ui {
|
||||
return;
|
||||
}
|
||||
|
||||
if (auto *bitfieldMember = dynamic_cast<const pl::ptrn::PatternBitfieldMember*>(&pattern); bitfieldMember != nullptr && bitfieldMember->getParent() != nullptr)
|
||||
if (auto *bitfieldMember = dynamic_cast<const pl::ptrn::PatternBitfieldMember*>(&pattern); bitfieldMember != nullptr && bitfieldMember->getParentBitfield() != nullptr)
|
||||
drawSizeColumnForBitfieldMember(*bitfieldMember);
|
||||
else {
|
||||
ImGui::TableNextColumn();
|
||||
|
||||
Reference in New Issue
Block a user