mirror of
https://github.com/WerWolv/ImHex.git
synced 2026-03-28 15:57:03 -05:00
Compare commits
34 Commits
feature/ap
...
v1.36.2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
77c1ee3e7a | ||
|
|
4be2c33985 | ||
|
|
3034d79373 | ||
|
|
e7daa586ba | ||
|
|
3f4bdfdf61 | ||
|
|
ab5860dc9a | ||
|
|
53b2347358 | ||
|
|
a195179101 | ||
|
|
fdccc55805 | ||
|
|
55dce338b2 | ||
|
|
03c217addb | ||
|
|
a3a3f52b48 | ||
|
|
477b284041 | ||
|
|
b52495bc33 | ||
|
|
46ed451712 | ||
|
|
963afdce96 | ||
|
|
3f18a9a536 | ||
|
|
64b226e12d | ||
|
|
b74dc3d8b9 | ||
|
|
9668a885e8 | ||
|
|
b7afbf4a74 | ||
|
|
4784a82d51 | ||
|
|
a1ff1af754 | ||
|
|
5c6b20c0ec | ||
|
|
79af360822 | ||
|
|
fb23708220 | ||
|
|
93f6ab25e6 | ||
|
|
6faefed4f4 | ||
|
|
6a159be861 | ||
|
|
d7b43b54f9 | ||
|
|
1a92425995 | ||
|
|
347bdd9508 | ||
|
|
b80e8b63c9 | ||
|
|
621d529682 |
300
.github/workflows/build.yml
vendored
300
.github/workflows/build.yml
vendored
@@ -6,7 +6,6 @@ on:
|
||||
- 'master'
|
||||
- 'releases/**'
|
||||
- 'tests/**'
|
||||
- 'feature/**'
|
||||
pull_request:
|
||||
workflow_dispatch:
|
||||
|
||||
@@ -19,18 +18,11 @@ jobs:
|
||||
win:
|
||||
runs-on: windows-2022
|
||||
name: 🪟 Windows MINGW64
|
||||
|
||||
defaults:
|
||||
run:
|
||||
shell: msys2 {0}
|
||||
|
||||
env:
|
||||
CCACHE_DIR: "${{ github.workspace }}/.ccache"
|
||||
|
||||
permissions:
|
||||
id-token: write
|
||||
attestations: write
|
||||
|
||||
steps:
|
||||
- name: 🧰 Checkout
|
||||
uses: actions/checkout@v4
|
||||
@@ -89,64 +81,11 @@ jobs:
|
||||
run: |
|
||||
cd build
|
||||
ninja install
|
||||
|
||||
- name: 🪲 Create PDBs for MSI
|
||||
run: |
|
||||
cd build
|
||||
|
||||
mkdir cv2pdb
|
||||
cd cv2pdb
|
||||
wget https://github.com/rainers/cv2pdb/releases/download/v0.52/cv2pdb-0.52.zip
|
||||
unzip cv2pdb-0.52.zip
|
||||
cd ..
|
||||
|
||||
cv2pdb/cv2pdb.exe imhex.exe
|
||||
cv2pdb/cv2pdb.exe imhex-gui.exe
|
||||
cv2pdb/cv2pdb.exe libimhex.dll
|
||||
cv2pdb/cv2pdb.exe libpl.dll
|
||||
|
||||
for plugin in plugins/*.hexplug; do
|
||||
cv2pdb/cv2pdb.exe $plugin
|
||||
done
|
||||
|
||||
rm -rf cv2pdb
|
||||
|
||||
- name: 📦 Bundle MSI
|
||||
run: |
|
||||
cd build
|
||||
cpack
|
||||
mv ImHex-*.msi ../imhex-${{ env.IMHEX_VERSION }}-Windows-x86_64.msi
|
||||
|
||||
echo "ImHex checks for the existence of this file to determine if it is running in portable mode. You should not delete this file" > $PWD/install/PORTABLE
|
||||
|
||||
- name: 🪲 Create PDBs for ZIP
|
||||
run: |
|
||||
cd build/install
|
||||
|
||||
mkdir cv2pdb
|
||||
cd cv2pdb
|
||||
wget https://github.com/rainers/cv2pdb/releases/download/v0.52/cv2pdb-0.52.zip
|
||||
unzip cv2pdb-0.52.zip
|
||||
cd ..
|
||||
|
||||
cv2pdb/cv2pdb.exe imhex.exe
|
||||
cv2pdb/cv2pdb.exe imhex-gui.exe
|
||||
cv2pdb/cv2pdb.exe libimhex.dll
|
||||
cv2pdb/cv2pdb.exe libpl.dll
|
||||
|
||||
for plugin in plugins/*.hexplug; do
|
||||
cv2pdb/cv2pdb.exe $plugin
|
||||
done
|
||||
|
||||
rm -rf cv2pdb
|
||||
|
||||
- name: 🗝️ Generate build provenance attestations
|
||||
uses: actions/attest-build-provenance@v2
|
||||
if: github.event.pull_request.head.repo.full_name == github.repository
|
||||
with:
|
||||
subject-path: |
|
||||
imhex-*.msi
|
||||
|
||||
- name: ⬆️ Upload Windows Installer
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
@@ -183,16 +122,12 @@ jobs:
|
||||
win-plugin-template-test:
|
||||
runs-on: windows-2022
|
||||
name: 🧪 Plugin Template Test
|
||||
|
||||
defaults:
|
||||
run:
|
||||
shell: msys2 {0}
|
||||
|
||||
needs: win
|
||||
|
||||
env:
|
||||
IMHEX_SDK_PATH: "${{ github.workspace }}/out/sdk"
|
||||
|
||||
steps:
|
||||
- name: 🧰 Checkout ImHex
|
||||
uses: actions/checkout@v4
|
||||
@@ -238,13 +173,9 @@ jobs:
|
||||
ninja
|
||||
|
||||
# MacOS build
|
||||
macos-x86:
|
||||
macos:
|
||||
runs-on: macos-13
|
||||
|
||||
permissions:
|
||||
id-token: write
|
||||
attestations: write
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
@@ -274,13 +205,10 @@ jobs:
|
||||
max-size: 1G
|
||||
|
||||
- name: ⬇️ Install dependencies
|
||||
env:
|
||||
# Make brew not display useless errors
|
||||
HOMEBREW_TESTS: 1
|
||||
run: |
|
||||
brew reinstall python --quiet || true
|
||||
brew link --overwrite --quiet python 2>/dev/null || true
|
||||
brew bundle --no-lock --quiet --file dist/macOS/Brewfile || true
|
||||
brew link --overwrite --quiet python || true
|
||||
brew bundle --no-lock --quiet --file dist/Brewfile || true
|
||||
rm -rf /usr/local/Cellar/capstone
|
||||
|
||||
- name: ⬇️ Install classic glfw
|
||||
@@ -371,20 +299,19 @@ jobs:
|
||||
|
||||
- name: 📦 Create DMG
|
||||
run: |
|
||||
brew install imagemagick
|
||||
git clone https://github.com/sindresorhus/create-dmg
|
||||
cd create-dmg
|
||||
npm i && npm -g i
|
||||
cd ../build/install
|
||||
create-dmg ImHex.app || true
|
||||
mv *.dmg ../../imhex-${{ env.IMHEX_VERSION }}-macOS${{ matrix.suffix }}-x86_64.dmg
|
||||
|
||||
- name: 🗝️ Generate build provenance attestations
|
||||
uses: actions/attest-build-provenance@v2
|
||||
if: github.event.pull_request.head.repo.full_name == github.repository
|
||||
with:
|
||||
subject-path: |
|
||||
./*.dmg
|
||||
set -x
|
||||
mkdir bundle
|
||||
mv build/install/ImHex.app bundle
|
||||
cd bundle
|
||||
ln -s /Applications Applications
|
||||
cd ..
|
||||
for i in $(seq 1 10); do
|
||||
if hdiutil create -volname "ImHex" -srcfolder bundle -ov -format UDZO imhex-${{ env.IMHEX_VERSION }}-macOS${{ matrix.suffix }}-x86_64.dmg; then
|
||||
echo "Created dmg after ${i} attempts"
|
||||
break
|
||||
fi
|
||||
sleep 10
|
||||
done
|
||||
|
||||
- name: ⬆️ Upload DMG
|
||||
uses: actions/upload-artifact@v4
|
||||
@@ -393,13 +320,11 @@ jobs:
|
||||
name: macOS DMG${{ matrix.suffix }} x86_64
|
||||
path: ./*.dmg
|
||||
|
||||
macos-arm64:
|
||||
macos-arm64-build:
|
||||
runs-on: ubuntu-24.04
|
||||
name: 🍎 macOS 13 arm64
|
||||
|
||||
outputs:
|
||||
IMHEX_VERSION: ${{ steps.build.outputs.IMHEX_VERSION }}
|
||||
|
||||
steps:
|
||||
- name: 🧰 Checkout
|
||||
uses: actions/checkout@v4
|
||||
@@ -442,15 +367,9 @@ jobs:
|
||||
macos-arm64-package:
|
||||
runs-on: macos-13
|
||||
name: 🍎 macOS 13 arm64 Packaging
|
||||
needs: macos-arm64
|
||||
|
||||
needs: macos-arm64-build
|
||||
env:
|
||||
IMHEX_VERSION: ${{ needs.macos-arm64-build.outputs.IMHEX_VERSION }}
|
||||
|
||||
permissions:
|
||||
id-token: write
|
||||
attestations: write
|
||||
|
||||
steps:
|
||||
- name: ⬇️ Download artifact
|
||||
uses: actions/download-artifact@v4
|
||||
@@ -485,20 +404,19 @@ jobs:
|
||||
|
||||
- name: 📦 Create DMG
|
||||
run: |
|
||||
brew install imagemagick
|
||||
git clone https://github.com/sindresorhus/create-dmg
|
||||
cd create-dmg
|
||||
npm i && npm -g i
|
||||
cd ../out
|
||||
create-dmg ImHex.app || true
|
||||
mv *.dmg ../imhex-${{ env.IMHEX_VERSION }}-macOS${{ matrix.suffix }}-arm64.dmg
|
||||
|
||||
- name: 🗝️ Generate build provenance attestations
|
||||
uses: actions/attest-build-provenance@v2
|
||||
if: github.event.pull_request.head.repo.full_name == github.repository
|
||||
with:
|
||||
subject-path: |
|
||||
./*.dmg
|
||||
set -x
|
||||
mkdir bundle
|
||||
mv out/ImHex.app bundle
|
||||
cd bundle
|
||||
ln -s /Applications Applications
|
||||
cd ..
|
||||
for i in $(seq 1 10); do
|
||||
if hdiutil create -volname "ImHex" -srcfolder bundle -ov -format UDZO imhex-${{ env.IMHEX_VERSION }}-macOS-arm64.dmg; then
|
||||
echo "Created dmg after ${i} attempts"
|
||||
break
|
||||
fi
|
||||
sleep 10
|
||||
done
|
||||
|
||||
- name: ⬆️ Upload DMG
|
||||
uses: actions/upload-artifact@v4
|
||||
@@ -523,10 +441,6 @@ jobs:
|
||||
image: "ubuntu:${{ matrix.release_num }}"
|
||||
options: --privileged
|
||||
|
||||
permissions:
|
||||
id-token: write
|
||||
attestations: write
|
||||
|
||||
steps:
|
||||
- name: ⬇️ Install setup dependencies
|
||||
run: apt update && apt install -y git curl
|
||||
@@ -584,16 +498,9 @@ jobs:
|
||||
- name: 📦 Bundle DEB
|
||||
run: |
|
||||
cp -r build/DEBIAN build/DebDir
|
||||
dpkg-deb -Zzstd --build build/DebDir
|
||||
dpkg-deb -Zgzip --build build/DebDir
|
||||
mv build/DebDir.deb imhex-${{ env.IMHEX_VERSION }}-Ubuntu-${{ matrix.release_num }}-x86_64.deb
|
||||
|
||||
- name: 🗝️ Generate build provenance attestations
|
||||
uses: actions/attest-build-provenance@v2
|
||||
if: github.event.pull_request.head.repo.full_name == github.repository
|
||||
with:
|
||||
subject-path: |
|
||||
./*.deb
|
||||
|
||||
- name: ⬆️ Upload DEB
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
@@ -603,26 +510,8 @@ jobs:
|
||||
|
||||
# AppImage build
|
||||
appimage:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- architecture: "x86_64"
|
||||
architecture_package: "amd64"
|
||||
architecture_appimage_builder: "x86_64"
|
||||
image: ubuntu-24.04
|
||||
- architecture: "arm64"
|
||||
architecture_package: "arm64"
|
||||
architecture_appimage_builder: "aarch64"
|
||||
image: ubuntu-24.04-arm
|
||||
|
||||
runs-on: ${{ matrix.image }}
|
||||
name: ⬇️ AppImage ${{ matrix.architecture }}
|
||||
|
||||
permissions:
|
||||
id-token: write
|
||||
attestations: write
|
||||
|
||||
runs-on: ubuntu-24.04
|
||||
name: ⬇️ AppImage
|
||||
steps:
|
||||
- name: 🧰 Checkout
|
||||
uses: actions/checkout@v4
|
||||
@@ -644,31 +533,22 @@ jobs:
|
||||
|
||||
- name: 🛠️ Build using docker
|
||||
run: |
|
||||
docker buildx build . -f dist/AppImage/Dockerfile --progress=plain --build-arg "BUILD_TYPE=$BUILD_TYPE" \
|
||||
--build-arg "GIT_COMMIT_HASH=$GITHUB_SHA" --build-arg "GIT_BRANCH=${GITHUB_REF##*/}" \
|
||||
--build-arg "ARCHITECTURE_PACKAGE=${{ matrix.architecture_package }}" --build-arg "ARCHITECTURE_FILE_NAME=${{ matrix.architecture }}" --build-arg "ARCHITECTURE_APPIMAGE_BUILDER=${{ matrix.architecture_appimage_builder }}" \
|
||||
--output out
|
||||
docker buildx build . -f dist/appimage/Dockerfile --progress=plain --build-arg "BUILD_TYPE=$BUILD_TYPE" \
|
||||
--build-arg "GIT_COMMIT_HASH=$GITHUB_SHA" --build-arg "GIT_BRANCH=${GITHUB_REF##*/}" --output out
|
||||
|
||||
- name: 🗝️ Generate build provenance attestations
|
||||
uses: actions/attest-build-provenance@v2
|
||||
if: github.event.pull_request.head.repo.full_name == github.repository
|
||||
with:
|
||||
subject-path: |
|
||||
out/*.AppImage
|
||||
out/*.AppImage.zsync
|
||||
|
||||
- name: ⬆️ Upload AppImage
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
if-no-files-found: error
|
||||
name: Linux AppImage ${{ matrix.architecture }}
|
||||
name: Linux AppImage x86_64
|
||||
path: 'out/*.AppImage'
|
||||
|
||||
- name: ⬆️ Upload AppImage zsync
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
if-no-files-found: error
|
||||
name: Linux AppImage zsync ${{ matrix.architecture }}
|
||||
name: Linux AppImage zsync x86_64
|
||||
path: 'out/*.AppImage.zsync'
|
||||
|
||||
# ArchLinux build
|
||||
@@ -679,10 +559,6 @@ jobs:
|
||||
container:
|
||||
image: archlinux:base-devel
|
||||
|
||||
permissions:
|
||||
id-token: write
|
||||
attestations: write
|
||||
|
||||
steps:
|
||||
- name: ⬇️ Update all packages
|
||||
run: |
|
||||
@@ -766,13 +642,6 @@ jobs:
|
||||
rm *imhex-bin-debug* # rm debug package which is created for some reason
|
||||
mv *.pkg.tar.zst imhex-${{ env.IMHEX_VERSION }}-ArchLinux-x86_64.pkg.tar.zst
|
||||
|
||||
- name: 🗝️ Generate build provenance attestations
|
||||
uses: actions/attest-build-provenance@v2
|
||||
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
|
||||
|
||||
- name: ⬆️ Upload imhex-archlinux.pkg.tar.zst
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
@@ -811,10 +680,6 @@ jobs:
|
||||
image: "almalinux:9"
|
||||
options: --privileged --pid=host --security-opt apparmor=unconfined
|
||||
|
||||
permissions:
|
||||
id-token: write
|
||||
attestations: write
|
||||
|
||||
steps:
|
||||
# This, together with the `--pid=host --security-opt apparmor=unconfined` docker options is required to allow
|
||||
# fedpkg to work inside a Docker container running on Ubuntu again.
|
||||
@@ -910,13 +775,6 @@ jobs:
|
||||
mv $GITHUB_WORKSPACE/results_imhex/${{ env.IMHEX_VERSION }}/*/imhex-${{ env.IMHEX_VERSION }}-0.*.x86_64.rpm \
|
||||
$GITHUB_WORKSPACE/imhex-${{ env.IMHEX_VERSION }}-${{ matrix.name }}-${{ matrix.release_num }}-x86_64.rpm
|
||||
|
||||
- name: 🗝️ Generate build provenance attestations
|
||||
uses: actions/attest-build-provenance@v2
|
||||
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
|
||||
|
||||
- name: ⬆️ Upload RPM
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
@@ -924,85 +782,3 @@ jobs:
|
||||
name: ${{ matrix.name }} ${{ matrix.release_num }} RPM x86_64
|
||||
path: |
|
||||
imhex-${{ env.IMHEX_VERSION }}-${{ matrix.name }}-${{ matrix.release_num }}-x86_64.rpm
|
||||
|
||||
webassembly-build:
|
||||
runs-on: ubuntu-24.04
|
||||
name: 🌍 Web
|
||||
permissions:
|
||||
pages: write
|
||||
id-token: write
|
||||
actions: write
|
||||
steps:
|
||||
- name: 🧰 Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- name: 📁 Restore docker /cache
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: cache
|
||||
key: web-cache-${{ hashFiles('**/CMakeLists.txt') }}
|
||||
|
||||
- name: 🐳 Inject /cache into docker
|
||||
uses: reproducible-containers/buildkit-cache-dance@v2
|
||||
with:
|
||||
cache-source: cache
|
||||
cache-target: /cache
|
||||
|
||||
- name: 🛠️ Build using docker
|
||||
run: |
|
||||
docker buildx build . -f dist/web/Dockerfile --progress=plain --build-arg 'JOBS=4' --output out --target raw
|
||||
|
||||
- name: 🔨 Fix permissions
|
||||
run: |
|
||||
chmod -c -R +rX "out/"
|
||||
|
||||
- name: ⬆️ Upload artifacts
|
||||
uses: actions/upload-pages-artifact@v3
|
||||
with:
|
||||
path: out/
|
||||
|
||||
- name: 🔨 Copy necessary files
|
||||
run: |
|
||||
cp dist/web/serve.py out/start_imhex_web.py
|
||||
|
||||
- name: ⬆️ Upload package
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
if-no-files-found: error
|
||||
name: ImHex Web
|
||||
path: out/*
|
||||
|
||||
# See https://github.com/actions/cache/issues/342#issuecomment-1711054115
|
||||
- name: 🗑️ Delete old cache
|
||||
continue-on-error: true
|
||||
env:
|
||||
GH_TOKEN: ${{ github.token }}
|
||||
run: |
|
||||
gh extension install actions/gh-actions-cache || true
|
||||
gh actions-cache delete "build-web-cache" --confirm || true
|
||||
|
||||
webassembly-deploy:
|
||||
environment:
|
||||
name: github-pages
|
||||
url: ${{ steps.deployment.outputs.page_url }}
|
||||
permissions:
|
||||
pages: write
|
||||
id-token: write
|
||||
actions: write
|
||||
name: 📃 Deploy to GitHub Pages
|
||||
runs-on: ubuntu-24.04
|
||||
|
||||
if: ${{ github.ref == 'refs/heads/master' && github.event.repository.fork == false }}
|
||||
needs: webassembly-build
|
||||
|
||||
steps:
|
||||
- name: 🌍 Deploy WebAssembly Build to GitHub Pages
|
||||
id: deployment
|
||||
uses: actions/deploy-pages@v4
|
||||
|
||||
- name: 🗑️ Delete artifact
|
||||
uses: geekyeggo/delete-artifact@v5
|
||||
with:
|
||||
name: github-pages
|
||||
|
||||
79
.github/workflows/build_web.yml
vendored
Normal file
79
.github/workflows/build_web.yml
vendored
Normal file
@@ -0,0 +1,79 @@
|
||||
name: Build for the web
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- 'master'
|
||||
- 'releases/**'
|
||||
- 'tests/**'
|
||||
pull_request:
|
||||
workflow_dispatch:
|
||||
|
||||
env:
|
||||
BUILD_TYPE: Release
|
||||
|
||||
permissions:
|
||||
pages: write
|
||||
id-token: write
|
||||
actions: write
|
||||
|
||||
jobs:
|
||||
|
||||
build:
|
||||
runs-on: ubuntu-24.04
|
||||
name: 🌍 WebAssembly
|
||||
steps:
|
||||
- name: 🧰 Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- name: 📁 Restore docker /cache
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: cache
|
||||
key: web-cache-${{ hashFiles('**/CMakeLists.txt') }}
|
||||
|
||||
- name: 🐳 Inject /cache into docker
|
||||
uses: reproducible-containers/buildkit-cache-dance@v2
|
||||
with:
|
||||
cache-source: cache
|
||||
cache-target: /cache
|
||||
|
||||
- name: 🛠️ Build using docker
|
||||
run: |
|
||||
docker buildx build . -f dist/web/Dockerfile --progress=plain --build-arg 'JOBS=4' --output out --target raw
|
||||
|
||||
- name: 🔨 Fix permissions
|
||||
run: |
|
||||
chmod -c -R +rX "out/"
|
||||
|
||||
- name: ⬆️ Upload artifacts
|
||||
uses: actions/upload-pages-artifact@v3
|
||||
with:
|
||||
path: out/
|
||||
|
||||
# See https://github.com/actions/cache/issues/342#issuecomment-1711054115
|
||||
- name: 🗑️ Delete old cache
|
||||
continue-on-error: true
|
||||
env:
|
||||
GH_TOKEN: ${{ github.token }}
|
||||
run: |
|
||||
gh extension install actions/gh-actions-cache || true
|
||||
gh actions-cache delete "build-web-cache" --confirm || true
|
||||
|
||||
deploy:
|
||||
environment:
|
||||
name: github-pages
|
||||
url: ${{ steps.deployment.outputs.page_url }}
|
||||
|
||||
name: 📃 Deploy to GitHub Pages
|
||||
runs-on: ubuntu-24.04
|
||||
|
||||
if: ${{ github.ref == 'refs/heads/master' && github.event.repository.fork == false }}
|
||||
needs: build
|
||||
|
||||
steps:
|
||||
- name: 🌍 Deploy
|
||||
id: deployment
|
||||
uses: actions/deploy-pages@v4
|
||||
3
.github/workflows/release.yml
vendored
3
.github/workflows/release.yml
vendored
@@ -63,7 +63,7 @@ jobs:
|
||||
token: ${{ secrets.RELEASE_TOKEN }}
|
||||
|
||||
release-upload-artifacts:
|
||||
runs-on: ubuntu-24.04
|
||||
runs-on: ubuntu-latest
|
||||
name: Release Upload Artifacts
|
||||
|
||||
steps:
|
||||
@@ -117,7 +117,6 @@ jobs:
|
||||
run: |
|
||||
mv "Windows Portable x86_64.zip" imhex-${{ env.IMHEX_VERSION }}-Windows-Portable-x86_64.zip
|
||||
mv "Windows Portable NoGPU x86_64.zip" imhex-${{ env.IMHEX_VERSION }}-Windows-Portable-NoGPU-x86_64.zip
|
||||
mv "ImHex Web.zip" imhex-${{ env.IMHEX_VERSION }}-web.zip
|
||||
|
||||
- name: ⬆️ Upload everything to release
|
||||
uses: softprops/action-gh-release@4634c16e79c963813287e889244c50009e7f0981
|
||||
|
||||
2
.github/workflows/stale_issues.yml
vendored
2
.github/workflows/stale_issues.yml
vendored
@@ -6,7 +6,7 @@ on:
|
||||
|
||||
jobs:
|
||||
close-issues:
|
||||
runs-on: ubuntu-24.04
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
issues: write
|
||||
pull-requests: write
|
||||
|
||||
1
.github/workflows/tests.yml
vendored
1
.github/workflows/tests.yml
vendored
@@ -6,7 +6,6 @@ on:
|
||||
- 'master'
|
||||
- 'releases/**'
|
||||
- 'tests/**'
|
||||
- 'feature/**'
|
||||
pull_request:
|
||||
branches:
|
||||
- 'master'
|
||||
|
||||
5
.gitmodules
vendored
5
.gitmodules
vendored
@@ -43,7 +43,4 @@
|
||||
|
||||
[submodule "lib/third_party/HashLibPlus"]
|
||||
path = lib/third_party/HashLibPlus
|
||||
url = https://github.com/WerWolv/HashLibPlus
|
||||
[submodule "lib/external/disassembler"]
|
||||
path = lib/external/disassembler
|
||||
url = https://github.com/WerWolv/Disassembler
|
||||
url = https://github.com/WerWolv/HashLibPlus
|
||||
@@ -81,6 +81,7 @@ if (IMHEX_ENABLE_UNIT_TESTS)
|
||||
endif ()
|
||||
|
||||
# Configure more resources that will be added to the install package
|
||||
generatePDBs()
|
||||
generateSDKDirectory()
|
||||
|
||||
# Handle package generation
|
||||
|
||||
@@ -27,11 +27,6 @@ chmod +x imhex-*.AppImage
|
||||
./imhex-*.AppImage
|
||||
```
|
||||
|
||||
If you're experiencing glib / libgtk assertion failures, you might need to setup your `XDG_DATA_DIRS` env var correctly. In this case, run the following command before executing the AppImage. (See issue [ImHex/#2038](https://github.com/WerWolv/ImHex/issues/2038))
|
||||
```bash
|
||||
export XDG_DATA_DIRS="/usr/local/share:/usr/share"
|
||||
```
|
||||
|
||||
#### Flatpak
|
||||
To install the Flatpak, make sure you have the Flathub repository added to your system. Then simply run the following command:
|
||||
|
||||
|
||||
16
README.md
16
README.md
@@ -38,8 +38,8 @@ If you like my work, please consider supporting me on GitHub Sponsors, Patreon o
|
||||
</p>
|
||||
|
||||
## Screenshots
|
||||

|
||||

|
||||

|
||||

|
||||
|
||||
<details>
|
||||
<summary><strong>More Screenshots</strong></summary>
|
||||
@@ -328,12 +328,12 @@ To use ImHex, the following minimal system requirements need to be met.
|
||||
- RHEL/AlmaLinux
|
||||
- Arch Linux
|
||||
- Basically any other distro will work as well when compiling ImHex from sources.
|
||||
- **CPU**: Officially supported are x86_64 and ARM64, though any Little Endian 64 bit CPU should work.
|
||||
- **CPU**: x86_64 (64 Bit)
|
||||
- **GPU**: OpenGL 3.0 or higher
|
||||
- Integrated Intel HD iGPUs are supported, however certain drivers are known to cause various graphical artifacts, especially on Windows. Use at your own risk.
|
||||
- In case you don't have a GPU available, there are software rendered releases available for Windows and macOS
|
||||
- **RAM**: ~150MiB, more is required for more complex analysis
|
||||
- **Storage**: 150MiB
|
||||
- **RAM**: 256MB, more may be required for more complicated analysis
|
||||
- **Storage**: 150MB
|
||||
|
||||
## Installing
|
||||
|
||||
@@ -342,10 +342,8 @@ Information on how to install ImHex can be found in the [Install](/INSTALL.md) g
|
||||
## Compiling
|
||||
|
||||
To compile ImHex on any platform, GCC (or Clang) is required with a version that supports C++23 or higher.
|
||||
Windows and Linux releases are being built using latest available GCC.
|
||||
MacOS releases are being built using latest available LLVM Clang.
|
||||
|
||||
Important to note is, the MSVC and AppleClang compilers are both **NOT** supported since they're both generally severely outdated and lack features GCC and LLVM Clang have.
|
||||
On macOS, Clang is also required to compile some ObjC code.
|
||||
All releases are being built using latest available GCC.
|
||||
|
||||
> [!NOTE]
|
||||
> Many dependencies are bundled into the repository using submodules so make sure to clone it using the `--recurse-submodules` option.
|
||||
|
||||
@@ -1,17 +1,3 @@
|
||||
# Some libraries we use set the BUILD_SHARED_LIBS variable to ON, which causes CMake to
|
||||
# display a warning about options being set using set() instead of option().
|
||||
# Explicitly set the policy to NEW to suppress the warning.
|
||||
set(CMAKE_POLICY_DEFAULT_CMP0077 NEW)
|
||||
|
||||
set(CMAKE_POLICY_DEFAULT_CMP0063 NEW)
|
||||
|
||||
if (POLICY CMP0177)
|
||||
set(CMAKE_POLICY_DEFAULT_CMP0177 OLD)
|
||||
cmake_policy(SET CMP0177 OLD)
|
||||
endif()
|
||||
|
||||
set(CMAKE_WARN_DEPRECATED OFF CACHE BOOL "Disable deprecated warnings" FORCE)
|
||||
|
||||
include(FetchContent)
|
||||
|
||||
if(IMHEX_STRIP_RELEASE)
|
||||
@@ -240,7 +226,7 @@ macro(createPackage)
|
||||
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/LICENSE DESTINATION ${CMAKE_INSTALL_PREFIX}/share/licenses/imhex)
|
||||
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/dist/imhex.desktop DESTINATION ${CMAKE_INSTALL_PREFIX}/share/applications)
|
||||
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/dist/imhex.mime.xml DESTINATION ${CMAKE_INSTALL_PREFIX}/share/mime/packages RENAME imhex.xml)
|
||||
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/resources/icon.svg DESTINATION ${CMAKE_INSTALL_PREFIX}/share/pixmaps RENAME imhex.svg)
|
||||
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/resources/icon.png DESTINATION ${CMAKE_INSTALL_PREFIX}/share/pixmaps RENAME imhex.png)
|
||||
downloadImHexPatternsFiles("./share/imhex")
|
||||
|
||||
# install AppStream file
|
||||
@@ -384,6 +370,15 @@ macro(configureCMake)
|
||||
message(WARNING "LTO is not supported: ${output_error}")
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
# Some libraries we use set the BUILD_SHARED_LIBS variable to ON, which causes CMake to
|
||||
# display a warning about options being set using set() instead of option().
|
||||
# Explicitly set the policy to NEW to suppress the warning.
|
||||
set(CMAKE_POLICY_DEFAULT_CMP0077 NEW)
|
||||
|
||||
set(CMAKE_POLICY_DEFAULT_CMP0063 NEW)
|
||||
|
||||
set(CMAKE_WARN_DEPRECATED OFF CACHE BOOL "Disable deprecated warnings" FORCE)
|
||||
endmacro()
|
||||
|
||||
function(configureProject)
|
||||
@@ -654,7 +649,6 @@ macro(addBundledLibraries)
|
||||
set(FPHSA_NAME_MISMATCHED ON CACHE BOOL "")
|
||||
|
||||
if(NOT USE_SYSTEM_FMT)
|
||||
set(FMT_INSTALL OFF CACHE BOOL "Disable install targets for libfmt" FORCE)
|
||||
add_subdirectory(${THIRD_PARTY_LIBS_FOLDER}/fmt EXCLUDE_FROM_ALL)
|
||||
set(FMT_LIBRARIES fmt::fmt-header-only)
|
||||
else()
|
||||
@@ -734,7 +728,6 @@ macro(addBundledLibraries)
|
||||
endif()
|
||||
|
||||
add_subdirectory(${EXTERNAL_LIBS_FOLDER}/pattern_language EXCLUDE_FROM_ALL)
|
||||
add_subdirectory(${EXTERNAL_LIBS_FOLDER}/disassembler EXCLUDE_FROM_ALL)
|
||||
|
||||
if (LIBPL_SHARED_LIBRARY)
|
||||
install(
|
||||
@@ -791,6 +784,59 @@ function(enableUnityBuild TARGET)
|
||||
endif ()
|
||||
endfunction()
|
||||
|
||||
function(generatePDBs)
|
||||
if (NOT IMHEX_GENERATE_PDBS)
|
||||
return()
|
||||
endif ()
|
||||
|
||||
if (NOT WIN32 OR CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||
return()
|
||||
endif ()
|
||||
|
||||
include(FetchContent)
|
||||
FetchContent_Declare(
|
||||
cv2pdb
|
||||
URL "https://github.com/rainers/cv2pdb/releases/download/v0.52/cv2pdb-0.52.zip"
|
||||
DOWNLOAD_EXTRACT_TIMESTAMP ON
|
||||
)
|
||||
FetchContent_Populate(cv2pdb)
|
||||
|
||||
set(PDBS_TO_GENERATE main main-forwarder libimhex ${PLUGINS})
|
||||
foreach (PDB ${PDBS_TO_GENERATE})
|
||||
if (PDB STREQUAL "main")
|
||||
set(GENERATED_PDB imhex)
|
||||
elseif (PDB STREQUAL "main-forwarder")
|
||||
set(GENERATED_PDB imhex-gui)
|
||||
elseif (PDB STREQUAL "libimhex")
|
||||
set(GENERATED_PDB libimhex)
|
||||
else ()
|
||||
set(GENERATED_PDB plugins/${PDB})
|
||||
endif ()
|
||||
|
||||
if (IMHEX_REPLACE_DWARF_WITH_PDB)
|
||||
set(PDB_OUTPUT_PATH ${CMAKE_BINARY_DIR}/${GENERATED_PDB})
|
||||
else ()
|
||||
set(PDB_OUTPUT_PATH)
|
||||
endif()
|
||||
|
||||
add_custom_target(${PDB}_pdb DEPENDS ${CMAKE_BINARY_DIR}/${GENERATED_PDB}.pdb)
|
||||
add_custom_command(OUTPUT ${CMAKE_BINARY_DIR}/${GENERATED_PDB}.pdb
|
||||
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
|
||||
COMMAND
|
||||
(
|
||||
${CMAKE_COMMAND} -E remove -f ${CMAKE_BINARY_DIR}/${GENERATED_PDB}.pdb &&
|
||||
${cv2pdb_SOURCE_DIR}/cv2pdb64.exe $<TARGET_FILE:${PDB}> ${PDB_OUTPUT_PATH} &&
|
||||
${CMAKE_COMMAND} -E remove -f ${CMAKE_BINARY_DIR}/${GENERATED_PDB}
|
||||
) || (exit 0)
|
||||
COMMAND_EXPAND_LISTS)
|
||||
|
||||
install(FILES ${CMAKE_BINARY_DIR}/${GENERATED_PDB}.pdb DESTINATION ".")
|
||||
|
||||
add_dependencies(imhex_all ${PDB}_pdb)
|
||||
endforeach ()
|
||||
|
||||
endfunction()
|
||||
|
||||
function(generateSDKDirectory)
|
||||
if (WIN32)
|
||||
set(SDK_PATH "./sdk")
|
||||
@@ -819,12 +865,6 @@ function(generateSDKDirectory)
|
||||
install(FILES ${CMAKE_SOURCE_DIR}/cmake/build_helpers.cmake DESTINATION "${SDK_PATH}/cmake")
|
||||
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 DESTINATION "${SDK_PATH}/lib" PATTERN "**/source/*" EXCLUDE)
|
||||
install(TARGETS ui ARCHIVE DESTINATION "${SDK_PATH}/lib")
|
||||
|
||||
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)
|
||||
|
||||
@@ -11,23 +11,32 @@ AppDir:
|
||||
exec_args: $@
|
||||
apt:
|
||||
arch:
|
||||
- "{{ARCHITECTURE_PACKAGE}}"
|
||||
- amd64
|
||||
allow_unauthenticated: true
|
||||
sources:
|
||||
- sourceline: 'deb [arch=amd64] http://us.archive.ubuntu.com/ubuntu/ oracular main restricted universe multiverse'
|
||||
- sourceline: 'deb [arch=arm64] http://ports.ubuntu.com/ubuntu-ports/ oracular main restricted universe multiverse'
|
||||
- sourceline: deb http://us.archive.ubuntu.com/ubuntu/ oracular main restricted
|
||||
- sourceline: deb http://us.archive.ubuntu.com/ubuntu/ oracular-updates main restricted
|
||||
- sourceline: deb http://us.archive.ubuntu.com/ubuntu/ oracular universe
|
||||
- sourceline: deb http://us.archive.ubuntu.com/ubuntu/ oracular-updates universe
|
||||
- sourceline: deb http://us.archive.ubuntu.com/ubuntu/ oracular multiverse
|
||||
- sourceline: deb http://us.archive.ubuntu.com/ubuntu/ oracular-updates multiverse
|
||||
- sourceline: deb http://us.archive.ubuntu.com/ubuntu/ oracular-backports main restricted
|
||||
universe multiverse
|
||||
- sourceline: deb http://security.ubuntu.com/ubuntu oracular-security main restricted
|
||||
- sourceline: deb http://security.ubuntu.com/ubuntu oracular-security universe
|
||||
- sourceline: deb http://security.ubuntu.com/ubuntu oracular-security multiverse
|
||||
include:
|
||||
- librsvg2-common
|
||||
- libbz2-1.0
|
||||
- libcap2
|
||||
- libdbus-1-3
|
||||
- libfontconfig1
|
||||
- libgpg-error0
|
||||
- liblzma5
|
||||
- libnss-mdns
|
||||
- libpcre3
|
||||
- libselinux1
|
||||
- libtinfo6
|
||||
- libbz2-1.0:amd64
|
||||
- libcap2:amd64
|
||||
- libdbus-1-3:amd64
|
||||
- libfontconfig1:amd64
|
||||
- libgpg-error0:amd64
|
||||
- liblzma5:amd64
|
||||
- libnss-mdns:amd64
|
||||
- libpcre3:amd64
|
||||
- libselinux1:amd64
|
||||
- libtinfo6:amd64
|
||||
files:
|
||||
include:
|
||||
- /lib/x86_64-linux-gnu/libLLVM-13.so.1
|
||||
@@ -124,6 +133,6 @@ AppDir:
|
||||
- usr/share/doc/*/NEWS.*
|
||||
- usr/share/doc/*/TODO.*
|
||||
AppImage:
|
||||
arch: "{{ARCHITECTURE_APPIMAGE_BUILDER}}"
|
||||
update-information: gh-releases-zsync|WerWolv|ImHex|latest|imhex-*-{{ARCHITECTURE_FILE_NAME}}.AppImage.zsync
|
||||
file_name: imhex-{{VERSION}}-{{ARCHITECTURE_FILE_NAME}}.AppImage
|
||||
arch: x86_64
|
||||
update-information: gh-releases-zsync|WerWolv|ImHex|latest|imhex-*-x86_64.AppImage.zsync
|
||||
file_name: imhex-{{VERSION}}-x86_64.AppImage
|
||||
0
dist/macOS/Brewfile → dist/Brewfile
vendored
0
dist/macOS/Brewfile → dist/Brewfile
vendored
@@ -30,14 +30,8 @@ ARG LTO=ON
|
||||
ARG BUILD_TYPE=RelWithDebInfo
|
||||
ARG GIT_COMMIT_HASH
|
||||
ARG GIT_BRANCH
|
||||
ARG ARCHITECTURE_PACKAGE
|
||||
ARG ARCHITECTURE_FILE_NAME
|
||||
ARG ARCHITECTURE_APPIMAGE_BUILDER
|
||||
WORKDIR /build
|
||||
|
||||
# Ubuntu sh doesnt support string substitution
|
||||
SHELL ["bash", "-c"]
|
||||
|
||||
SHELL ["bash", "-c"] # Ubuntu sh doesnt support string substitution
|
||||
RUN <<EOF
|
||||
# Prepare ImHex build
|
||||
set -xe
|
||||
@@ -79,10 +73,7 @@ pip3 install git+https://github.com/AppImageCrafters/appimage-builder@f38699e
|
||||
|
||||
# Package ImHex as AppImage
|
||||
export VERSION=$(cat /imhex/VERSION)
|
||||
export ARCHITECTURE_PACKAGE=${ARCHITECTURE_PACKAGE}
|
||||
export ARCHITECTURE_FILE_NAME=${ARCHITECTURE_FILE_NAME}
|
||||
export ARCHITECTURE_APPIMAGE_BUILDER=${ARCHITECTURE_APPIMAGE_BUILDER}
|
||||
appimage-builder --recipe /imhex/dist/AppImage/AppImageBuilder.yml
|
||||
appimage-builder --recipe /imhex/dist/AppImageBuilder.yml
|
||||
EOF
|
||||
|
||||
FROM scratch
|
||||
2
dist/get_deps_msys2.sh
vendored
2
dist/get_deps_msys2.sh
vendored
@@ -1,6 +1,6 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
pacman -S --needed --noconfirm pactoys unzip
|
||||
pacman -S --needed --noconfirm pactoys
|
||||
pacboy -S --needed --noconfirm \
|
||||
gcc:p \
|
||||
lld:p \
|
||||
|
||||
6
dist/imhex.desktop
vendored
6
dist/imhex.desktop
vendored
@@ -1,5 +1,4 @@
|
||||
[Desktop Entry]
|
||||
Version=1.0
|
||||
Name=ImHex
|
||||
Comment=ImHex Hex Editor
|
||||
GenericName=Hex Editor
|
||||
@@ -11,8 +10,3 @@ Categories=Development;IDE;
|
||||
StartupWMClass=imhex
|
||||
Keywords=static-analysis;reverse-engineering;disassembler;disassembly;hacking;forensics;hex-editor;cybersecurity;security;binary-analysis;
|
||||
MimeType=application/vnd.imhex.proj;
|
||||
Actions=NewFile;
|
||||
|
||||
[Desktop Action NewFile]
|
||||
Exec=imhex --new
|
||||
Name=Create New File
|
||||
2
dist/macOS/arm64.Dockerfile
vendored
2
dist/macOS/arm64.Dockerfile
vendored
@@ -1,5 +1,5 @@
|
||||
# This base image is also known as "crosscompile". See arm64.crosscompile.Dockerfile
|
||||
FROM ghcr.io/itrooz/macos-crosscompile:clang19-nosdk as build
|
||||
FROM ghcr.io/itrooz/macos-crosscompile:clang17-nosdk as build
|
||||
|
||||
ENV MACOSX_DEPLOYMENT_TARGET 13.0
|
||||
|
||||
|
||||
2
dist/macOS/arm64.crosscompile.Dockerfile
vendored
2
dist/macOS/arm64.crosscompile.Dockerfile
vendored
@@ -1,4 +1,4 @@
|
||||
# This image is provided for reference, but a (probably more up to date) image should be available at https://github.com/iTrooz/macos-crosscompile
|
||||
# This image is is provided for reference, but a (probably more up to date) image should be available at https://github.com/iTrooz/macos-crosscompile
|
||||
FROM ubuntu:22.04
|
||||
|
||||
ENV PATH $PATH:/osxcross/target/bin
|
||||
|
||||
4
dist/rpm/imhex.spec
vendored
4
dist/rpm/imhex.spec
vendored
@@ -123,11 +123,9 @@ cp -a lib/third_party/xdgpp/LICENSE %{buildroot
|
||||
%doc README.md
|
||||
%{_bindir}/imhex
|
||||
%{_bindir}/imhex-updater
|
||||
%{_datadir}/pixmaps/%{name}.svg
|
||||
%{_datadir}/pixmaps/%{name}.png
|
||||
%{_datadir}/applications/%{name}.desktop
|
||||
%{_datadir}/mime/packages/%{name}.xml
|
||||
%{_libdir}/libimhex.so*
|
||||
%{_libdir}/%{name}/
|
||||
%{_libdir}/*.hexpluglib
|
||||
/usr/lib/debug/%{_libdir}/*.debug
|
||||
%{_metainfodir}/net.werwolv.%{name}.metainfo.xml
|
||||
11
dist/web/Dockerfile
vendored
11
dist/web/Dockerfile
vendored
@@ -1,4 +1,4 @@
|
||||
FROM emscripten/emsdk:3.1.51 AS build
|
||||
FROM emscripten/emsdk:3.1.51 as build
|
||||
|
||||
# Used to invalidate layer cache but not mount cache
|
||||
# See https://github.com/moby/moby/issues/41715#issuecomment-733976493
|
||||
@@ -27,7 +27,7 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread")
|
||||
' >> /emsdk/upstream/emscripten/cmake/Modules/Platform/Emscripten.cmake
|
||||
EOF
|
||||
|
||||
ENV VCPKG_DEFAULT_BINARY_CACHE=/cache/vcpkg
|
||||
ENV VCPKG_DEFAULT_BINARY_CACHE /cache/vcpkg
|
||||
RUN --mount=type=cache,target=/cache <<EOF
|
||||
# Install dependencies with vcpkg
|
||||
set -xe
|
||||
@@ -45,7 +45,7 @@ EOF
|
||||
|
||||
# Build ImHex
|
||||
ARG JOBS=4
|
||||
ENV CCACHE_DIR=/cache/ccache
|
||||
ENV CCACHE_DIR /cache/ccache
|
||||
|
||||
RUN mkdir /build
|
||||
WORKDIR /build
|
||||
@@ -67,7 +67,6 @@ cmake /imhex
|
||||
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache \
|
||||
-DCMAKE_TOOLCHAIN_FILE=/vcpkg/scripts/buildsystems/vcpkg.cmake \
|
||||
-DVCPKG_CHAINLOAD_TOOLCHAIN_FILE=/emsdk/upstream/emscripten/cmake/Modules/Platform/Emscripten.cmake \
|
||||
-DLIBROMFS_COMPRESS_RESOURCES=OFF \
|
||||
-DCMAKE_BUILD_TYPE=Release
|
||||
|
||||
ninja -j $JOBS
|
||||
@@ -80,7 +79,7 @@ EOF
|
||||
# See https://stackoverflow.com/questions/41701849/cannot-modify-accept-encoding-with-fetch https://github.com/AnthumChris/fetch-progress-indicators/issues/13
|
||||
RUN du -b /build/imhex.wasm | cut -f1 > imhex.wasm.size
|
||||
|
||||
FROM scratch AS raw
|
||||
FROM scratch as raw
|
||||
COPY --from=build [ \
|
||||
# ImHex \
|
||||
"/build/imhex.wasm", \
|
||||
@@ -94,7 +93,7 @@ COPY --from=build [ \
|
||||
"/build/wasm-config.js", \
|
||||
"/build/enable-threads.js", \
|
||||
"/build/favicon.ico", \
|
||||
"/build/icon.svg", \
|
||||
"/build/icon.png", \
|
||||
"/build/manifest.json", \
|
||||
"/build/robots.txt", \
|
||||
"/build/sitemap.xml", \
|
||||
|
||||
BIN
dist/web/source/favicon.ico
vendored
BIN
dist/web/source/favicon.ico
vendored
Binary file not shown.
|
Before Width: | Height: | Size: 162 KiB After Width: | Height: | Size: 122 KiB |
BIN
dist/web/source/icon.png
vendored
Normal file
BIN
dist/web/source/icon.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 157 KiB |
11
dist/web/source/icon.svg
vendored
11
dist/web/source/icon.svg
vendored
@@ -1,11 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="64" height="64" version="1">
|
||||
<rect style="opacity:0.2" width="55" height="10" x="5" y="-60" rx="1.41" transform="rotate(90)"/>
|
||||
<rect style="fill:#2b50a1" width="55" height="10" x="4" y="-60" rx="1.41" transform="rotate(90)"/>
|
||||
<rect style="fill:#2b50a1" width="55" height="10" x="4" y="-14" rx="1.41" transform="rotate(90)"/>
|
||||
<rect style="fill:#2b50a1" width="55" height="10" x="4" y="-33" rx="1.41" transform="rotate(90)"/>
|
||||
<path style="opacity:0.2" d="M 5.3808594,5 C 4.6158118,5 4,5.6158118 4,6.3808594 V 13.619141 C 4,14.384188 4.6158118,15 5.3808594,15 H 31.619141 C 32.384188,15 33,14.384188 33,13.619141 V 6.3808594 C 33,5.6158118 32.384188,5 31.619141,5 Z M 40.400391,5 C 39.624791,5 39,5.6247906 39,6.4003906 V 13.599609 C 39,14.375209 39.624791,15 40.400391,15 H 58.599609 C 59.375209,15 60,14.375209 60,13.599609 V 6.4003906 C 60,5.6247906 59.375209,5 58.599609,5 Z M 5.3808594,50 C 4.6158118,50 4,50.615812 4,51.380859 v 7.238282 C 4,59.384188 4.6158118,60 5.3808594,60 H 31.619141 C 32.384188,60 33,59.384188 33,58.619141 V 51.380859 C 33,50.615812 32.384188,50 31.619141,50 Z"/>
|
||||
<rect style="fill:#3a6be0" width="29" height="10" x="4" y="4" rx="1.381"/>
|
||||
<rect style="fill:#3a6be0" width="21" height="10" x="39" y="4" rx="1.4"/>
|
||||
<rect style="fill:#3a6be0" width="29" height="10" x="4" y="49" rx="1.381"/>
|
||||
<path style="fill:#ffffff;opacity:0.1" d="M 5.3808594 4 C 4.6158118 4 4 4.6158118 4 5.3808594 L 4 6.3808594 C 4 5.6158118 4.6158118 5 5.3808594 5 L 31.619141 5 C 32.384188 5 33 5.6158118 33 6.3808594 L 33 5.3808594 C 33 4.6158118 32.384188 4 31.619141 4 L 5.3808594 4 z M 40.400391 4 C 39.624791 4 39 4.6247906 39 5.4003906 L 39 6.4003906 C 39 5.6247906 39.624791 5 40.400391 5 L 58.599609 5 C 59.375209 5 60 5.6247906 60 6.4003906 L 60 5.4003906 C 60 4.6247906 59.375209 4 58.599609 4 L 40.400391 4 z M 5.3808594 49 C 4.6158118 49 4 49.615812 4 50.380859 L 4 51.380859 C 4 50.615812 4.6158118 50 5.3808594 50 L 31.619141 50 C 32.384188 50 33 50.615812 33 51.380859 L 33 50.380859 C 33 49.615812 32.384188 49 31.619141 49 L 5.3808594 49 z"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 2.1 KiB |
4
dist/web/source/index.html
vendored
4
dist/web/source/index.html
vendored
@@ -11,7 +11,7 @@
|
||||
<meta name="title" content="ImHex">
|
||||
<meta name="description" content="Free and extremely powerful Online Hex Editor for your Web Browser. ImHex is a free and open source Hex Editor for Reverse Engineers and Developers and Data Analysts.">
|
||||
<link rel="icon" type="image/x-icon" href="favicon.ico">
|
||||
<link rel="apple-touch-icon" href="icon.svg">
|
||||
<link rel="apple-touch-icon" href="icon.png">
|
||||
|
||||
<!-- Open Graph / Facebook -->
|
||||
<meta property="og:type" content="website">
|
||||
@@ -38,7 +38,7 @@
|
||||
"founder": "WerWolv",
|
||||
"slogan": "A Hex Editor for Reverse Engineers, Programmers and people who value their retinas when working at 3 AM.",
|
||||
"url": "https://imhex.werwolv.net",
|
||||
"logo": "https://imhex.werwolv.net/assets/logos/logo.svg"
|
||||
"logo": "https://imhex.werwolv.net/assets/logos/logo.png"
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
4
dist/web/source/manifest.json
vendored
4
dist/web/source/manifest.json
vendored
@@ -10,8 +10,8 @@
|
||||
],
|
||||
"icons": [
|
||||
{
|
||||
"src": "icon.svg",
|
||||
"type": "image/svg",
|
||||
"src": "icon.png",
|
||||
"type": "image/png",
|
||||
"sizes": "640x640"
|
||||
}
|
||||
],
|
||||
|
||||
1
lib/external/disassembler
vendored
1
lib/external/disassembler
vendored
Submodule lib/external/disassembler deleted from 172c61ec3f
2
lib/external/libromfs
vendored
2
lib/external/libromfs
vendored
Submodule lib/external/libromfs updated: 60ba28a53b...03adcfdde0
2
lib/external/libwolv
vendored
2
lib/external/libwolv
vendored
Submodule lib/external/libwolv updated: 323ad9e4f0...b9d7f4abaf
2
lib/external/pattern_language
vendored
2
lib/external/pattern_language
vendored
Submodule lib/external/pattern_language updated: 947b99cbe7...f45156a55c
@@ -50,7 +50,6 @@ set(LIBIMHEX_SOURCES
|
||||
source/ui/view.cpp
|
||||
source/ui/popup.cpp
|
||||
source/ui/toast.cpp
|
||||
source/ui/banner.cpp
|
||||
|
||||
source/subcommands/subcommands.cpp
|
||||
)
|
||||
@@ -135,14 +134,13 @@ if (NOT IMHEX_EXTERNAL_PLUGIN_BUILD)
|
||||
if (WIN32)
|
||||
set_target_properties(libimhex PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS TRUE)
|
||||
target_link_options(libimhex PRIVATE -Wl,--export-all-symbols)
|
||||
target_link_libraries(libimhex PRIVATE Netapi32.lib)
|
||||
elseif (APPLE)
|
||||
find_library(FOUNDATION NAMES Foundation)
|
||||
target_link_libraries(libimhex PUBLIC ${FOUNDATION})
|
||||
endif ()
|
||||
|
||||
target_link_libraries(libimhex PRIVATE microtar libwolv ${NFD_LIBRARIES} magic dl)
|
||||
target_link_libraries(libimhex PUBLIC libpl ${IMGUI_LIBRARIES} ${JTHREAD_LIBRARIES})
|
||||
target_link_libraries(libimhex PRIVATE microtar libwolv ${NFD_LIBRARIES} magic dl ${JTHREAD_LIBRARIES})
|
||||
target_link_libraries(libimhex PUBLIC libpl ${IMGUI_LIBRARIES})
|
||||
|
||||
precompileHeaders(libimhex "${CMAKE_CURRENT_SOURCE_DIR}/include")
|
||||
endif()
|
||||
|
||||
@@ -20,7 +20,6 @@ using ImGuiDataType = int;
|
||||
using ImGuiInputTextFlags = int;
|
||||
struct ImColor;
|
||||
enum ImGuiCustomCol : int;
|
||||
typedef int ImGuiColorEditFlags;
|
||||
|
||||
namespace hex {
|
||||
|
||||
@@ -44,6 +43,7 @@ namespace hex {
|
||||
plugins when needed.
|
||||
*/
|
||||
namespace ContentRegistry {
|
||||
|
||||
/* Settings Registry. Allows adding of new entries into the ImHex preferences window. */
|
||||
namespace Settings {
|
||||
|
||||
@@ -177,7 +177,7 @@ namespace hex {
|
||||
|
||||
class SliderDataSize : public Widget {
|
||||
public:
|
||||
SliderDataSize(u64 defaultValue, u64 min, u64 max, u64 stepSize) : m_value(defaultValue), m_min(min), m_max(max), m_stepSize(stepSize) { }
|
||||
SliderDataSize(u64 defaultValue, u64 min, u64 max) : m_value(defaultValue), m_min(min), m_max(max) { }
|
||||
bool draw(const std::string &name) override;
|
||||
|
||||
void load(const nlohmann::json &data) override;
|
||||
@@ -188,12 +188,11 @@ namespace hex {
|
||||
protected:
|
||||
u64 m_value;
|
||||
u64 m_min, m_max;
|
||||
u64 m_stepSize;
|
||||
};
|
||||
|
||||
class ColorPicker : public Widget {
|
||||
public:
|
||||
explicit ColorPicker(ImColor defaultColor, ImGuiColorEditFlags flags = 0);
|
||||
explicit ColorPicker(ImColor defaultColor);
|
||||
|
||||
bool draw(const std::string &name) override;
|
||||
|
||||
@@ -203,14 +202,12 @@ namespace hex {
|
||||
[[nodiscard]] ImColor getColor() const;
|
||||
|
||||
protected:
|
||||
std::array<float, 4> m_value = {}, m_defaultValue = {};
|
||||
ImGuiColorEditFlags m_flags;
|
||||
std::array<float, 4> m_value{};
|
||||
};
|
||||
|
||||
class DropDown : public Widget {
|
||||
public:
|
||||
explicit DropDown(const std::vector<std::string> &items, const std::vector<nlohmann::json> &settingsValues, const nlohmann::json &defaultItem) : m_items(items.begin(), items.end()), m_settingsValues(settingsValues), m_defaultItem(defaultItem) { }
|
||||
explicit DropDown(const std::vector<UnlocalizedString> &items, const std::vector<nlohmann::json> &settingsValues, const nlohmann::json &defaultItem) : m_items(items), m_settingsValues(settingsValues), m_defaultItem(defaultItem) { }
|
||||
explicit DropDown(const std::vector<std::string> &items, const std::vector<nlohmann::json> &settingsValues, const nlohmann::json &defaultItem) : m_items(items), m_settingsValues(settingsValues), m_defaultItem(defaultItem) { }
|
||||
|
||||
bool draw(const std::string &name) override;
|
||||
|
||||
@@ -221,7 +218,7 @@ namespace hex {
|
||||
const nlohmann::json& getValue() const;
|
||||
|
||||
protected:
|
||||
std::vector<UnlocalizedString> m_items;
|
||||
std::vector<std::string> m_items;
|
||||
std::vector<nlohmann::json> m_settingsValues;
|
||||
nlohmann::json m_defaultItem;
|
||||
|
||||
@@ -626,7 +623,8 @@ namespace hex {
|
||||
/* Data Inspector Registry. Allows adding of new types to the data inspector */
|
||||
namespace DataInspector {
|
||||
|
||||
enum class NumberDisplayStyle : u8 {
|
||||
enum class NumberDisplayStyle
|
||||
{
|
||||
Decimal,
|
||||
Hexadecimal,
|
||||
Octal
|
||||
@@ -680,13 +678,6 @@ namespace hex {
|
||||
std::optional<impl::EditingFunction> editingFunction = std::nullopt
|
||||
);
|
||||
|
||||
/**
|
||||
* @brief Allows adding new menu items to data inspector row context menus. Call this function inside the
|
||||
* draw function of the data inspector row definition.
|
||||
* @param function Callback that will draw menu items
|
||||
*/
|
||||
void drawMenuItems(const std::function<void()> &function);
|
||||
|
||||
}
|
||||
|
||||
/* Data Processor Node Registry. Allows adding new processor nodes to be used in the data processor */
|
||||
@@ -1017,7 +1008,7 @@ namespace hex {
|
||||
|
||||
namespace impl {
|
||||
|
||||
using Callback = std::function<std::string(prv::Provider *provider, u64 address, size_t size, bool preview)>;
|
||||
using Callback = std::function<std::string(prv::Provider *provider, u64 address, size_t size)>;
|
||||
struct ExportMenuEntry {
|
||||
UnlocalizedString unlocalizedName;
|
||||
Callback callback;
|
||||
@@ -1025,7 +1016,7 @@ namespace hex {
|
||||
|
||||
struct FindOccurrence {
|
||||
Region region;
|
||||
enum class DecodeType { ASCII, UTF8, Binary, UTF16, Unsigned, Signed, Float, Double } decodeType;
|
||||
enum class DecodeType { ASCII, Binary, UTF16, Unsigned, Signed, Float, Double } decodeType;
|
||||
std::endian endian = std::endian::native;
|
||||
bool selected;
|
||||
};
|
||||
@@ -1363,7 +1354,6 @@ namespace hex {
|
||||
|
||||
}
|
||||
|
||||
/* Data Information Registry. Allows adding new analyzers to the data information view */
|
||||
namespace DataInformation {
|
||||
|
||||
class InformationSection {
|
||||
@@ -1430,54 +1420,6 @@ namespace hex {
|
||||
|
||||
}
|
||||
|
||||
/* Disassembler Registry. Allows adding new disassembler architectures */
|
||||
namespace Disassembler {
|
||||
|
||||
struct Instruction {
|
||||
u64 address;
|
||||
u64 offset;
|
||||
size_t size;
|
||||
std::string bytes;
|
||||
std::string mnemonic;
|
||||
std::string operators;
|
||||
};
|
||||
|
||||
class Architecture {
|
||||
public:
|
||||
explicit Architecture(std::string name) : m_name(std::move(name)) {}
|
||||
virtual ~Architecture() = default;
|
||||
|
||||
virtual bool start() = 0;
|
||||
virtual void end() = 0;
|
||||
|
||||
virtual std::optional<Instruction> disassemble(u64 imageBaseAddress, u64 instructionLoadAddress, u64 instructionDataAddress, std::span<const u8> code) = 0;
|
||||
virtual void drawSettings() = 0;
|
||||
|
||||
[[nodiscard]] const std::string& getName() const { return m_name; }
|
||||
|
||||
private:
|
||||
std::string m_name;
|
||||
};
|
||||
|
||||
namespace impl {
|
||||
|
||||
using CreatorFunction = std::function<std::unique_ptr<Architecture>()>;
|
||||
|
||||
void addArchitectureCreator(CreatorFunction function);
|
||||
|
||||
const std::map<std::string, CreatorFunction>& getArchitectures();
|
||||
|
||||
}
|
||||
|
||||
template<std::derived_from<Architecture> T>
|
||||
void add(auto && ...args) {
|
||||
impl::addArchitectureCreator([...args = std::move(args)] {
|
||||
return std::make_unique<T>(args...);
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
|
||||
#include <hex/api/imhex_api.hpp>
|
||||
#include <hex/helpers/logger.hpp>
|
||||
#include <hex/helpers/patches.hpp>
|
||||
|
||||
#include <wolv/types/type_name.hpp>
|
||||
|
||||
@@ -31,6 +32,15 @@
|
||||
#define EVENT_DEF_NO_LOG(event_name, ...) EVENT_DEF_IMPL(event_name, #event_name, false, __VA_ARGS__)
|
||||
|
||||
|
||||
/* Forward declarations */
|
||||
struct GLFWwindow;
|
||||
namespace hex {
|
||||
class Achievement;
|
||||
class View;
|
||||
}
|
||||
|
||||
namespace pl::ptrn { class Pattern; }
|
||||
|
||||
namespace hex {
|
||||
|
||||
namespace impl {
|
||||
@@ -90,8 +100,7 @@ namespace hex {
|
||||
|
||||
/**
|
||||
* @brief The EventManager allows subscribing to and posting events to different parts of the program.
|
||||
* To create a new event, use the EVENT_DEF macro. This will create a new event type with the given name and parameters.
|
||||
* Events should be created in an `events_*.hpp` category file under the `events` folder, and never directly here.
|
||||
* To create a new event, use the EVENT_DEF macro. This will create a new event type with the given name and parameters
|
||||
*/
|
||||
class EventManager {
|
||||
public:
|
||||
@@ -191,4 +200,123 @@ namespace hex {
|
||||
static void unsubscribe(void *token, impl::EventId id);
|
||||
};
|
||||
|
||||
/* Default Events */
|
||||
|
||||
/**
|
||||
* @brief Called when Imhex finished startup, and will enter the main window rendering loop
|
||||
*/
|
||||
EVENT_DEF(EventImHexStartupFinished);
|
||||
|
||||
EVENT_DEF(EventFileLoaded, std::fs::path);
|
||||
EVENT_DEF(EventDataChanged, prv::Provider *);
|
||||
EVENT_DEF(EventHighlightingChanged);
|
||||
EVENT_DEF(EventWindowClosing, GLFWwindow *);
|
||||
EVENT_DEF(EventRegionSelected, ImHexApi::HexEditor::ProviderRegion);
|
||||
EVENT_DEF(EventAbnormalTermination, int);
|
||||
EVENT_DEF(EventThemeChanged);
|
||||
EVENT_DEF(EventOSThemeChanged);
|
||||
EVENT_DEF(EventDPIChanged, float, float);
|
||||
EVENT_DEF(EventWindowFocused, bool);
|
||||
EVENT_DEF(EventImHexUpdated, SemanticVersion, SemanticVersion);
|
||||
|
||||
/**
|
||||
* @brief Called when the provider is created.
|
||||
* This event is responsible for (optionally) initializing the provider and calling EventProviderOpened
|
||||
* (although the event can also be called manually without problem)
|
||||
*/
|
||||
EVENT_DEF(EventProviderCreated, prv::Provider *);
|
||||
EVENT_DEF(EventProviderChanged, prv::Provider *, prv::Provider *);
|
||||
|
||||
/**
|
||||
* @brief Called as a continuation of EventProviderCreated
|
||||
* this event is normally called immediately after EventProviderCreated successfully initialized the provider.
|
||||
* If no initialization (Provider::skipLoadInterface() has been set), this event should be called manually
|
||||
* If skipLoadInterface failed, this event is not called
|
||||
*
|
||||
* @note this is not related to Provider::open()
|
||||
*/
|
||||
EVENT_DEF(EventProviderOpened, prv::Provider *);
|
||||
EVENT_DEF(EventProviderClosing, prv::Provider *, bool *);
|
||||
EVENT_DEF(EventProviderClosed, prv::Provider *);
|
||||
EVENT_DEF(EventProviderDeleted, prv::Provider *);
|
||||
EVENT_DEF(EventProviderSaved, prv::Provider *);
|
||||
EVENT_DEF(EventWindowInitialized);
|
||||
EVENT_DEF(EventWindowDeinitializing, GLFWwindow *);
|
||||
EVENT_DEF(EventBookmarkCreated, ImHexApi::Bookmarks::Entry&);
|
||||
|
||||
/**
|
||||
* @brief Called upon creation of an IPS patch.
|
||||
* As for now, the event only serves a purpose for the achievement unlock.
|
||||
*/
|
||||
EVENT_DEF(EventPatchCreated, const u8*, u64, const PatchKind);
|
||||
EVENT_DEF(EventPatternEvaluating);
|
||||
EVENT_DEF(EventPatternExecuted, const std::string&);
|
||||
EVENT_DEF(EventPatternEditorChanged, const std::string&);
|
||||
EVENT_DEF(EventStoreContentDownloaded, const std::fs::path&);
|
||||
EVENT_DEF(EventStoreContentRemoved, const std::fs::path&);
|
||||
EVENT_DEF(EventImHexClosing);
|
||||
EVENT_DEF(EventAchievementUnlocked, const Achievement&);
|
||||
EVENT_DEF(EventSearchBoxClicked, u32);
|
||||
EVENT_DEF(EventViewOpened, View*);
|
||||
EVENT_DEF(EventFirstLaunch);
|
||||
|
||||
EVENT_DEF(EventFileDragged, bool);
|
||||
EVENT_DEF(EventFileDropped, std::fs::path);
|
||||
|
||||
EVENT_DEF(EventProviderDataModified, prv::Provider *, u64, u64, const u8*);
|
||||
EVENT_DEF(EventProviderDataInserted, prv::Provider *, u64, u64);
|
||||
EVENT_DEF(EventProviderDataRemoved, prv::Provider *, u64, u64);
|
||||
EVENT_DEF(EventProviderDirtied, prv::Provider *);
|
||||
|
||||
/**
|
||||
* @brief Called when a project has been loaded
|
||||
*/
|
||||
EVENT_DEF(EventProjectOpened);
|
||||
|
||||
EVENT_DEF_NO_LOG(EventFrameBegin);
|
||||
EVENT_DEF_NO_LOG(EventFrameEnd);
|
||||
EVENT_DEF_NO_LOG(EventSetTaskBarIconState, u32, u32, u32);
|
||||
EVENT_DEF_NO_LOG(EventImGuiElementRendered, ImGuiID, const std::array<float, 4>&);
|
||||
|
||||
EVENT_DEF(RequestAddInitTask, std::string, bool, std::function<bool()>);
|
||||
EVENT_DEF(RequestAddExitTask, std::string, std::function<bool()>);
|
||||
EVENT_DEF(RequestOpenWindow, std::string);
|
||||
EVENT_DEF(RequestHexEditorSelectionChange, Region);
|
||||
EVENT_DEF(RequestPatternEditorSelectionChange, u32, u32);
|
||||
EVENT_DEF(RequestJumpToPattern, const pl::ptrn::Pattern*);
|
||||
EVENT_DEF(RequestAddBookmark, Region, std::string, std::string, color_t, u64*);
|
||||
EVENT_DEF(RequestRemoveBookmark, u64);
|
||||
EVENT_DEF(RequestSetPatternLanguageCode, std::string);
|
||||
EVENT_DEF(RequestRunPatternCode);
|
||||
EVENT_DEF(RequestLoadPatternLanguageFile, std::fs::path);
|
||||
EVENT_DEF(RequestSavePatternLanguageFile, std::fs::path);
|
||||
EVENT_DEF(RequestUpdateWindowTitle);
|
||||
EVENT_DEF(RequestCloseImHex, bool);
|
||||
EVENT_DEF(RequestRestartImHex);
|
||||
EVENT_DEF(RequestOpenFile, std::fs::path);
|
||||
EVENT_DEF(RequestChangeTheme, std::string);
|
||||
EVENT_DEF(RequestOpenPopup, std::string);
|
||||
EVENT_DEF(RequestAddVirtualFile, std::fs::path, std::vector<u8>, Region);
|
||||
|
||||
/**
|
||||
* @brief Creates a provider from it's unlocalized name, and add it to the provider list
|
||||
*/
|
||||
EVENT_DEF(RequestCreateProvider, std::string, bool, bool, hex::prv::Provider **);
|
||||
EVENT_DEF(RequestInitThemeHandlers);
|
||||
|
||||
/**
|
||||
* @brief Send an event to the main Imhex instance
|
||||
*/
|
||||
EVENT_DEF(SendMessageToMainInstance, const std::string, const std::vector<u8>&);
|
||||
|
||||
/**
|
||||
* Move the data from all PerProvider instances from one provider to another.
|
||||
* The 'from' provider should not have any per provider data after this, and should be immediately deleted
|
||||
*/
|
||||
EVENT_DEF(MovePerProviderData, prv::Provider *, prv::Provider *);
|
||||
|
||||
/**
|
||||
* Called when ImHex managed to catch an error in a general try/catch to prevent/recover from a crash
|
||||
*/
|
||||
EVENT_DEF(EventCrashRecovered, const std::exception &);
|
||||
}
|
||||
@@ -1,120 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <hex/api/event_manager.hpp>
|
||||
|
||||
/* Forward declarations */
|
||||
struct GLFWwindow;
|
||||
namespace hex { class View; }
|
||||
|
||||
/* GUI events definitions */
|
||||
namespace hex {
|
||||
|
||||
/**
|
||||
* @brief Signals a newly opened window
|
||||
*
|
||||
* This event is sent when the window has just been opened and docked by the Window manager.
|
||||
*
|
||||
* FIXME: In the event that a newly created window is already docked, this will not be sent.
|
||||
*
|
||||
* FIXME: This is currently only used for the introduction tutorial.
|
||||
* If the event's only purpose is this, maybe rename it?
|
||||
*
|
||||
* @param view the new view reference
|
||||
*/
|
||||
EVENT_DEF(EventViewOpened, View*);
|
||||
|
||||
/**
|
||||
* @brief Signals a change in the DPI scale.
|
||||
*
|
||||
* This event is called once at startup to signal native scale definition (by passing the same value twice).
|
||||
* On Windows OS, this event can also be posted if the window DPI has been changed.
|
||||
*
|
||||
* @param oldScale the old scale
|
||||
* @param newScale the current scale that's now in use
|
||||
*/
|
||||
EVENT_DEF(EventDPIChanged, float, float);
|
||||
|
||||
/**
|
||||
* @brief Signals the focus of the ImHex main window.
|
||||
*
|
||||
* This is directly tied as a GLFW window focus callback, and will be called accordingly when GLFW detects
|
||||
* a change in focus.
|
||||
*
|
||||
* @param isFocused true if the window is focused
|
||||
*/
|
||||
EVENT_DEF(EventWindowFocused, bool);
|
||||
|
||||
/**
|
||||
* @brief Signals a window being closed.
|
||||
*
|
||||
* Allows reactive clean up of running tasks, and prevents ImHex from closing
|
||||
* by displaying an exit confirmation popup.
|
||||
*
|
||||
* @param window The window reference
|
||||
*/
|
||||
EVENT_DEF(EventWindowClosing, GLFWwindow*);
|
||||
|
||||
/**
|
||||
* @brief Informs that the main window is initialized
|
||||
*
|
||||
* On Windows OS, it is used to initialize system theme, if ImHex's theme is following it.
|
||||
*
|
||||
* FIXME: Change event name to reflect Theme detection, if it's only used for that purpose?
|
||||
*/
|
||||
EVENT_DEF(EventWindowInitialized);
|
||||
|
||||
/**
|
||||
* @brief Informs that the main window is deinitializing
|
||||
*
|
||||
* Allows for lifecycle cleanup before ImHex shutdown.
|
||||
*
|
||||
* @param window The window reference
|
||||
*/
|
||||
EVENT_DEF(EventWindowDeinitializing, GLFWwindow*);
|
||||
|
||||
/**
|
||||
* @brief Signals a theme change in the host OS
|
||||
*
|
||||
* Allows ImHex to react to OS theme changes dynamically during execution.
|
||||
*/
|
||||
EVENT_DEF(EventOSThemeChanged);
|
||||
|
||||
}
|
||||
|
||||
/* silent (no-logging) GUI events definitions */
|
||||
namespace hex {
|
||||
|
||||
/**
|
||||
* @brief Signals the start of a new ImGui frame
|
||||
*/
|
||||
EVENT_DEF_NO_LOG(EventFrameBegin);
|
||||
|
||||
/**
|
||||
* @brief Signals the end of an ImGui frame
|
||||
*/
|
||||
EVENT_DEF_NO_LOG(EventFrameEnd);
|
||||
|
||||
/**
|
||||
* @brief Windows OS: Sets the taskbar icon state
|
||||
*
|
||||
* This event is used on Windows OS to display progress through the taskbar icon (the famous "green loading bar"
|
||||
* in the taskbar).
|
||||
*
|
||||
* @param progressState the progress state (converted from the TaskProgressState enum)
|
||||
* @param progressType the type of progress (converted from the TaskProgressType enum)
|
||||
* @param percentage actual progress percentage (expected from 0 to 100)
|
||||
*
|
||||
* @see hex::ImHexApi::System::TaskProgressState
|
||||
* @see hex::ImHexApi::System::TaskProgressType
|
||||
*/
|
||||
EVENT_DEF_NO_LOG(EventSetTaskBarIconState, u32, u32, u32);
|
||||
|
||||
/**
|
||||
* @brief Informs of an ImGui element being rendered
|
||||
*
|
||||
* @param elementId the element's ID
|
||||
* @param boundingBox the bounding box (composed of 4 floats)
|
||||
*/
|
||||
EVENT_DEF_NO_LOG(EventImGuiElementRendered, ImGuiID, const std::array<float, 4>&);
|
||||
|
||||
}
|
||||
@@ -1,158 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <hex/api/event_manager.hpp>
|
||||
#include <hex/helpers/patches.hpp>
|
||||
|
||||
/* Forward declarations */
|
||||
namespace hex { class Achievement; }
|
||||
|
||||
/* Interaction events definitions */
|
||||
namespace hex {
|
||||
|
||||
/**
|
||||
* @brief Signals a file was loaded
|
||||
*
|
||||
* FIXME: this event is unused and should be scrapped.
|
||||
*
|
||||
* @param path the loaded file's path
|
||||
*/
|
||||
EVENT_DEF(EventFileLoaded, std::fs::path);
|
||||
|
||||
/**
|
||||
* @brief Signals a change in the current data
|
||||
*
|
||||
* Enables provider reaction to data change, especially the data inspector.
|
||||
*
|
||||
* This is caused by the following:
|
||||
* - an explicit provider reload, requested by the user (Ctrl+R)
|
||||
* - any user action that results in the creation of an "undo" stack action (generally a data modification)
|
||||
*
|
||||
* @param provider the Provider subject to the data change
|
||||
*/
|
||||
EVENT_DEF(EventDataChanged, prv::Provider *);
|
||||
|
||||
/**
|
||||
* @brief Signals a change in highlighting
|
||||
*
|
||||
* The event's only purpose is for the Hex editor to clear highlights when receiving this event.
|
||||
*/
|
||||
EVENT_DEF(EventHighlightingChanged);
|
||||
|
||||
/**
|
||||
* @brief Informs of a provider region being selected
|
||||
*
|
||||
* This is very generally used to signal user actions that select a specific region within the provider.
|
||||
* It is also used to pass on regions when the provider changes.
|
||||
*
|
||||
* @param providerRegion the provider-aware region being selected
|
||||
*/
|
||||
EVENT_DEF(EventRegionSelected, ImHexApi::HexEditor::ProviderRegion);
|
||||
|
||||
/**
|
||||
* @brief Signals a theme change
|
||||
*
|
||||
* On Windows OS, this is used to reflect the theme color onto the window frame.
|
||||
*/
|
||||
EVENT_DEF(EventThemeChanged);
|
||||
|
||||
/**
|
||||
* @brief Signals that a bookmark was created
|
||||
*
|
||||
* For now, this event's only purpose is to unlock an achievement.
|
||||
*
|
||||
* @param entry the new bookmark
|
||||
*/
|
||||
EVENT_DEF(EventBookmarkCreated, ImHexApi::Bookmarks::Entry&);
|
||||
|
||||
/**
|
||||
* @brief Called upon creation of an IPS patch.
|
||||
* As for now, the event only serves a purpose for the achievement unlock.
|
||||
*
|
||||
* @param data the pointer to the patch content's start
|
||||
* @param size the patch data size
|
||||
* @param kind the patch's kind
|
||||
*/
|
||||
EVENT_DEF(EventPatchCreated, const u8*, u64, const PatchKind);
|
||||
|
||||
/**
|
||||
* @brief Signals the beginning of evaluation of the current pattern
|
||||
*
|
||||
* This allows resetting the drawer view for the pattern data while we wait for the execution completion.
|
||||
*/
|
||||
EVENT_DEF(EventPatternEvaluating);
|
||||
|
||||
/**
|
||||
* @brief Signals the completion of the pattern evaluation
|
||||
*
|
||||
* This causes another reset in the drawer view, to refresh the table displayed to the user.
|
||||
*
|
||||
* @param code the execution's status code
|
||||
*/
|
||||
EVENT_DEF(EventPatternExecuted, const std::string&);
|
||||
|
||||
/**
|
||||
* @brief Denotes when pattern editor has changed
|
||||
*
|
||||
* FIXME: this event is unused and should be scrapped.
|
||||
*/
|
||||
EVENT_DEF(EventPatternEditorChanged, const std::string&);
|
||||
|
||||
/**
|
||||
* @brief Signals that a Content Store item was downloaded
|
||||
*
|
||||
* FIXME: this event is unused and should be scrapped.
|
||||
*
|
||||
* @param path the item's path on the filesystem
|
||||
*/
|
||||
EVENT_DEF(EventStoreContentDownloaded, const std::fs::path&);
|
||||
|
||||
/**
|
||||
* @brief Signals the removal of a Content Store item
|
||||
*
|
||||
* Note: at the time of the event firing, the item has already been removed from the filesystem.
|
||||
*
|
||||
* FIXME: this event is unused and should be scrapped.
|
||||
*
|
||||
* @param path the item's old file path where it used to be in the filesystem
|
||||
*/
|
||||
EVENT_DEF(EventStoreContentRemoved, const std::fs::path&);
|
||||
|
||||
/**
|
||||
* @brief Signals the unlocking of an achievement
|
||||
*
|
||||
* This is used by the achievement manager to refresh the achievement display, as well as store progress to
|
||||
* the appropriate storage file.
|
||||
*
|
||||
* @param achievement the achievement that was unlocked
|
||||
*/
|
||||
EVENT_DEF(EventAchievementUnlocked, const Achievement&);
|
||||
|
||||
/**
|
||||
* @brief Signals a click on the search box
|
||||
*
|
||||
* As there are different behaviours depending on the click (left or right) done by the user,
|
||||
* this allows the consequences of said click to be registered in their own components.
|
||||
*
|
||||
* @param button the ImGuiMouseButton's value
|
||||
*/
|
||||
EVENT_DEF(EventSearchBoxClicked, u32);
|
||||
|
||||
/**
|
||||
* @brief Updates on whether a file is being dragged into ImHex
|
||||
*
|
||||
* Allows ImGUi to display a file dragging information on screen when a file is being dragged.
|
||||
*
|
||||
* @param isFileDragged true if a file is being dragged
|
||||
*/
|
||||
EVENT_DEF(EventFileDragged, bool);
|
||||
|
||||
/**
|
||||
* @brief Triggers loading when a file is dropped
|
||||
*
|
||||
* The event fires when a file is dropped into ImHex, which passes it to file handlers to load it.
|
||||
*
|
||||
* @param path the dropped file's path
|
||||
*/
|
||||
EVENT_DEF(EventFileDropped, std::fs::path);
|
||||
|
||||
}
|
||||
@@ -1,72 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <hex/api/event_manager.hpp>
|
||||
|
||||
/* Lifecycle events definitions */
|
||||
namespace hex {
|
||||
|
||||
/**
|
||||
* @brief Called when Imhex finished startup, and will enter the main window rendering loop
|
||||
*/
|
||||
EVENT_DEF(EventImHexStartupFinished);
|
||||
|
||||
/**
|
||||
* @brief Called when ImHex is closing, to trigger the last shutdown hooks
|
||||
*
|
||||
* This is the last event to fire before complete graceful shutdown.
|
||||
*/
|
||||
EVENT_DEF(EventImHexClosing);
|
||||
|
||||
/**
|
||||
* @brief Signals that it's ImHex first launch ever
|
||||
*
|
||||
* This event allows for the launch of the ImHex tutorial (also called Out of Box experience).
|
||||
*/
|
||||
EVENT_DEF(EventFirstLaunch);
|
||||
|
||||
/**
|
||||
* FIXME: this event is unused and should be scrapped.
|
||||
*/
|
||||
EVENT_DEF(EventAnySettingChanged);
|
||||
|
||||
/**
|
||||
* @brief Ensures correct plugin cleanup on crash
|
||||
*
|
||||
* This event is fired when catching an unexpected error that cannot be recovered and
|
||||
* which forces Imhex to close immediately.
|
||||
*
|
||||
* Subscribing to this event ensures that the plugin can correctly clean up any mission-critical tasks
|
||||
* before forceful shutdown.
|
||||
*
|
||||
* @param signal the POSIX signal code
|
||||
*/
|
||||
EVENT_DEF(EventAbnormalTermination, int);
|
||||
|
||||
/**
|
||||
* @brief Informs of the ImHex versions (and difference, if any)
|
||||
*
|
||||
* Called on every startup to inform subscribers of the two versions picked up:
|
||||
* - the version of the previous launch, gathered from the settings file
|
||||
* - the current version, gathered directly from C++ code
|
||||
*
|
||||
* In most cases, and unless ImHex was updated, the two parameters will be the same.
|
||||
*
|
||||
* FIXME: Maybe rename the event to signal a startup information, instead of the misleading
|
||||
* title that the event could be fired when ImHex detects that it was updated since last launch?
|
||||
*
|
||||
* @param previousLaunchVersion ImHex's version during the previous launch
|
||||
* @param currentVersion ImHex's current version for this startup
|
||||
*/
|
||||
EVENT_DEF(EventImHexUpdated, SemanticVersion, SemanticVersion);
|
||||
|
||||
/**
|
||||
* @brief Called when ImHex managed to catch an error in a general try/catch to prevent/recover from a crash
|
||||
*/
|
||||
EVENT_DEF(EventCrashRecovered, const std::exception &);
|
||||
|
||||
/**
|
||||
* @brief Called when a project has been loaded
|
||||
*/
|
||||
EVENT_DEF(EventProjectOpened);
|
||||
|
||||
}
|
||||
@@ -1,113 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <hex.hpp>
|
||||
#include <hex/api/event_manager.hpp>
|
||||
|
||||
/* Provider events definitions */
|
||||
namespace hex {
|
||||
/**
|
||||
* @brief Called when the provider is created.
|
||||
* This event is responsible for (optionally) initializing the provider and calling EventProviderOpened
|
||||
* (although the event can also be called manually without problem)
|
||||
*/
|
||||
EVENT_DEF(EventProviderCreated, prv::Provider *);
|
||||
|
||||
/**
|
||||
* @brief Called as a continuation of EventProviderCreated
|
||||
* this event is normally called immediately after EventProviderCreated successfully initialized the provider.
|
||||
* If no initialization (Provider::skipLoadInterface() has been set), this event should be called manually
|
||||
* If skipLoadInterface failed, this event is not called
|
||||
*
|
||||
* @note this is not related to Provider::open()
|
||||
*/
|
||||
EVENT_DEF(EventProviderOpened, prv::Provider *);
|
||||
|
||||
/**
|
||||
* @brief Signals a change in provider (in-place)
|
||||
*
|
||||
* Note: if the provider was deleted, the new ("current") provider will be `nullptr`
|
||||
*
|
||||
* @param oldProvider the old provider
|
||||
* @param currentProvider the current provider
|
||||
*/
|
||||
EVENT_DEF(EventProviderChanged, prv::Provider *, prv::Provider *);
|
||||
|
||||
/**
|
||||
* @brief Signals that a provider was saved
|
||||
*
|
||||
* @param provider the saved provider
|
||||
*/
|
||||
EVENT_DEF(EventProviderSaved, prv::Provider *);
|
||||
|
||||
/**
|
||||
* @brief Signals a provider is closing
|
||||
*
|
||||
* FIXME: as for now, this behaves as a request more than an event. Also, the boolean is always set to true,
|
||||
* and serves no purpose. This should be moved into the Provider requests section and declared accordingly.
|
||||
*
|
||||
* @param provider the closing provider
|
||||
* @param shouldClose whether the provider should close
|
||||
*/
|
||||
EVENT_DEF(EventProviderClosing, prv::Provider *, bool *);
|
||||
|
||||
/**
|
||||
* @brief Signals that a provider was closed
|
||||
*
|
||||
* As this is a closure information broadcast, the provider should generally not be accessed, as it could
|
||||
* result in problems.
|
||||
*
|
||||
* @param provider the now-closed provider
|
||||
*/
|
||||
EVENT_DEF(EventProviderClosed, prv::Provider *);
|
||||
|
||||
/**
|
||||
* @brief Signals that a provider is being deleted
|
||||
*
|
||||
* Provider's data should not be accessed.
|
||||
*
|
||||
* @param provider the provider
|
||||
*/
|
||||
EVENT_DEF(EventProviderDeleted, prv::Provider *);
|
||||
|
||||
}
|
||||
|
||||
/* Provider data events definitions */
|
||||
namespace hex {
|
||||
|
||||
/**
|
||||
* @brief Signals the dirtying of a provider
|
||||
*
|
||||
* Any data modification that occurs in a provider dirties it, until its state is either saved or restored.
|
||||
* This event signals that fact to subscribers so additional code can be executed for certain cases.
|
||||
*/
|
||||
EVENT_DEF(EventProviderDirtied, prv::Provider *);
|
||||
|
||||
/**
|
||||
* @brief Signals an insertion of new data into a provider
|
||||
*
|
||||
* @param provider the provider
|
||||
* @param offset the start of the insertion
|
||||
* @param size the new data's size
|
||||
*/
|
||||
EVENT_DEF(EventProviderDataInserted, prv::Provider *, u64, u64);
|
||||
|
||||
/**
|
||||
* @brief Signals a modification in the provider's data
|
||||
*
|
||||
* @param provider the provider
|
||||
* @param offset the data modification's offset (start address)
|
||||
* @param size the buffer's size
|
||||
* @param buffer the modified data written at this address
|
||||
*/
|
||||
EVENT_DEF(EventProviderDataModified, prv::Provider *, u64, u64, const u8*);
|
||||
|
||||
/**
|
||||
* @brief Signals a removal of some of the provider's data
|
||||
*
|
||||
* @param provider the provider
|
||||
* @param offset the deletion offset (start address)
|
||||
* @param size the deleted data's size
|
||||
*/
|
||||
EVENT_DEF(EventProviderDataRemoved, prv::Provider *, u64, u64);
|
||||
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <hex/api/event_manager.hpp>
|
||||
|
||||
/* GUI requests definitions */
|
||||
namespace hex {
|
||||
|
||||
/**
|
||||
* @brief Requests the opening of a new window.
|
||||
*
|
||||
* @param name the window's name
|
||||
*/
|
||||
EVENT_DEF(RequestOpenWindow, std::string);
|
||||
|
||||
/**
|
||||
* @brief Centralized request to update ImHex's main window title
|
||||
*
|
||||
* This request can be called to make ImHex refresh its main window title, taking into account a new project
|
||||
* or file opened/closed.
|
||||
*/
|
||||
EVENT_DEF(RequestUpdateWindowTitle);
|
||||
|
||||
/**
|
||||
* @brief Requests a theme type (light or dark) change
|
||||
*
|
||||
* @param themeType either `Light` or `Dark`
|
||||
*/
|
||||
EVENT_DEF(RequestChangeTheme, std::string);
|
||||
|
||||
/**
|
||||
* @brief Requests the opening of a popup
|
||||
*
|
||||
* @param name the popup's name
|
||||
*/
|
||||
EVENT_DEF(RequestOpenPopup, std::string);
|
||||
|
||||
}
|
||||
@@ -1,116 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <hex.hpp>
|
||||
#include <hex/api/event_manager.hpp>
|
||||
|
||||
/* Forward declarations */
|
||||
namespace pl::ptrn { class Pattern; }
|
||||
|
||||
/* Interaction requests definitions */
|
||||
namespace hex {
|
||||
|
||||
/**
|
||||
* @brief Requests a selection change in the Hex editor
|
||||
*
|
||||
* This request is handled by the Hex editor, which proceeds to check if the selection is valid.
|
||||
* If it is invalid, the Hex editor fires the `EventRegionSelected` event with nullptr region info.
|
||||
*
|
||||
* @param region the region that should be selected
|
||||
*/
|
||||
EVENT_DEF(RequestHexEditorSelectionChange, Region);
|
||||
|
||||
/**
|
||||
* @brief Requests the Pattern editor to move selection
|
||||
*
|
||||
* Requests the Pattern editor to move the cursor's position to reflect the user's click or movement.
|
||||
*
|
||||
* @param line the target line
|
||||
* @param column the target column
|
||||
*/
|
||||
EVENT_DEF(RequestPatternEditorSelectionChange, u32, u32);
|
||||
|
||||
/**
|
||||
* @brief Requests a jump to a given pattern
|
||||
*
|
||||
* This request is fired by the Hex editor when the user asks to jump to the pattern.
|
||||
* It is then caught and reflected by the Pattern data component.
|
||||
*
|
||||
* @param pattern the pattern to jump to
|
||||
*/
|
||||
EVENT_DEF(RequestJumpToPattern, const pl::ptrn::Pattern*);
|
||||
|
||||
/**
|
||||
* @brief Requests to add a bookmark
|
||||
*
|
||||
* @param region the region to be bookmarked
|
||||
* @param name the bookmark's name
|
||||
* @param comment a comment
|
||||
* @param color the color
|
||||
* @param id the bookmark's unique ID
|
||||
*/
|
||||
EVENT_DEF(RequestAddBookmark, Region, std::string, std::string, color_t, u64*);
|
||||
|
||||
/**
|
||||
* @brief Requests a bookmark removal
|
||||
*
|
||||
* @param id the bookmark's unique ID
|
||||
*/
|
||||
EVENT_DEF(RequestRemoveBookmark, u64);
|
||||
|
||||
/**
|
||||
* @brief Request the Pattern editor to set its code
|
||||
*
|
||||
* This request allows the rest of ImHex to interface with the Pattern editor component, by setting its code.
|
||||
* This allows for `.hexpat` file loading, and more.
|
||||
*
|
||||
* @param code the code's string
|
||||
*/
|
||||
EVENT_DEF(RequestSetPatternLanguageCode, std::string);
|
||||
|
||||
/**
|
||||
* @brief Requests the Pattern editor to run the current code
|
||||
*
|
||||
* This is only ever used in the introduction tutorial.
|
||||
*
|
||||
* FIXME: the name is misleading, as for now this activates the pattern's auto-evaluation rather than a
|
||||
* one-off execution
|
||||
*/
|
||||
EVENT_DEF(RequestRunPatternCode);
|
||||
|
||||
/**
|
||||
* @brief Request to load a pattern language file
|
||||
*
|
||||
* FIXME: this request is unused, as now another component is responsible for pattern file loading.
|
||||
* This request should be scrapped.
|
||||
*
|
||||
* @param path the pattern file's path
|
||||
*/
|
||||
EVENT_DEF(RequestLoadPatternLanguageFile, std::fs::path);
|
||||
|
||||
/**
|
||||
* @brief Request to save a pattern language file
|
||||
*
|
||||
* FIXME: this request is unused, as now another component is responsible for pattern file saving.
|
||||
* This request should be scrapped.
|
||||
*
|
||||
* @param path the pattern file's path
|
||||
*/
|
||||
EVENT_DEF(RequestSavePatternLanguageFile, std::fs::path);
|
||||
|
||||
/**
|
||||
* @brief Requests ImHex to open and process a file
|
||||
*
|
||||
* @param path the file's path
|
||||
*/
|
||||
EVENT_DEF(RequestOpenFile, std::fs::path);
|
||||
|
||||
/**
|
||||
* @brief Adds a virtual file in the Pattern editor
|
||||
*
|
||||
* @param path the file's path
|
||||
* @param data the file's data
|
||||
* @param region the impacted region
|
||||
*/
|
||||
EVENT_DEF(RequestAddVirtualFile, std::fs::path, std::vector<u8>, Region);
|
||||
|
||||
}
|
||||
@@ -1,84 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <hex.hpp>
|
||||
#include <hex/api/event_manager.hpp>
|
||||
|
||||
/* Lifecycle requests definitions */
|
||||
namespace hex {
|
||||
|
||||
/**
|
||||
* @brief Emit a request to add an initialization task to the list
|
||||
*
|
||||
* These tasks will be executed at startup.
|
||||
*
|
||||
* @param name Name of the init task
|
||||
* @param isAsync Whether the task is asynchronous (true if yes)
|
||||
* @param callbackFunction The function to call to execute the task
|
||||
*/
|
||||
EVENT_DEF(RequestAddInitTask, std::string, bool, std::function<bool()>);
|
||||
|
||||
/**
|
||||
* @brief Emit a request to add an exit task to the list
|
||||
*
|
||||
* These tasks will be executed during the exit phase.
|
||||
*
|
||||
* FIXME: request is unused and should be scrapped.
|
||||
*
|
||||
* @param name Name of the exit task
|
||||
* @param callbackFunction The function to call to execute the task
|
||||
*/
|
||||
EVENT_DEF(RequestAddExitTask, std::string, std::function<bool()>);
|
||||
|
||||
/**
|
||||
* @brief Requests ImHex's graceful shutdown
|
||||
*
|
||||
* If there are no questions (bool set to true), ImHex closes immediately.
|
||||
* If set to false, there is a procedure run to prompt a confirmation to the user.
|
||||
*
|
||||
* @param noQuestions true if no questions
|
||||
*/
|
||||
EVENT_DEF(RequestCloseImHex, bool);
|
||||
|
||||
/**
|
||||
* @brief Requests ImHex's restart
|
||||
*
|
||||
* This event is necessary for ImHex to restart in the main loop for native and web platforms,
|
||||
* as ImHex cannot simply close and re-open.
|
||||
*
|
||||
* This event serves no purpose on Linux, Windows and macOS platforms.
|
||||
*/
|
||||
EVENT_DEF(RequestRestartImHex);
|
||||
|
||||
/**
|
||||
* @brief Requests the initialization of theme handlers
|
||||
*
|
||||
* This is called during ImGui bootstrapping, and should not be called at any other time.
|
||||
*/
|
||||
EVENT_DEF(RequestInitThemeHandlers);
|
||||
|
||||
/**
|
||||
* @brief Requests version and first-startup checks
|
||||
*
|
||||
* This request is called during ImHex's startup, and allows ImHex to check if it was updated since last launch.
|
||||
* It also ensures newcomers (that open ImHex for the first time) are greeted with the tutorial.
|
||||
*
|
||||
* FIXME: the name is misleading, as this request does not effectively start any migration. It only executes
|
||||
* checks about ImHex's version. The name should be changed to reflect this behaviour.
|
||||
*/
|
||||
EVENT_DEF(RequestStartMigration);
|
||||
|
||||
/**
|
||||
* @brief Send a subcommand to the main Imhex instance
|
||||
*
|
||||
* This request is called to send a subcommand to the main ImHex instance.
|
||||
* This subcommand will then be executed by a handler when ImHex finishing initializing
|
||||
* (`EventImHexStartupFinished`).
|
||||
*
|
||||
* FIXME: change the name so that it is prefixed with "Request" like every other request.
|
||||
*
|
||||
* @param name the subcommand's name
|
||||
* @param data the subcommand's data
|
||||
*/
|
||||
EVENT_DEF(SendMessageToMainInstance, const std::string, const std::vector<u8>&);
|
||||
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <hex/api/event_manager.hpp>
|
||||
|
||||
/* Provider requests definitions */
|
||||
namespace hex {
|
||||
|
||||
/**
|
||||
* @brief Creates a provider from its unlocalized name, and add it to the provider list
|
||||
*/
|
||||
EVENT_DEF(RequestCreateProvider, std::string, bool, bool, hex::prv::Provider **);
|
||||
|
||||
/**
|
||||
* @brief Move the data from all PerProvider instances from one provider to another
|
||||
*
|
||||
* The 'from' provider should not have any per provider data after this, and should be immediately deleted
|
||||
*
|
||||
* FIXME: rename with the "Request" prefix to apply standard naming convention.
|
||||
*/
|
||||
EVENT_DEF(MovePerProviderData, prv::Provider *, prv::Provider *);
|
||||
|
||||
}
|
||||
@@ -493,7 +493,6 @@ namespace hex {
|
||||
*/
|
||||
float getNativeScale();
|
||||
|
||||
float getBackingScaleFactor();
|
||||
|
||||
/**
|
||||
* @brief Gets the current main window position
|
||||
@@ -582,14 +581,6 @@ namespace hex {
|
||||
*/
|
||||
const std::string& getGLRenderer();
|
||||
|
||||
/**
|
||||
* @brief Checks if ImHex is being run in a "Corporate Environment"
|
||||
* This function simply checks for common telltale signs such as if the machine is joined a
|
||||
* domain. It's not super accurate, but it's still useful for statistics
|
||||
* @return True if it is
|
||||
*/
|
||||
bool isCorporateEnvironment();
|
||||
|
||||
/**
|
||||
* @brief Checks if ImHex is running in portable mode
|
||||
* @return Whether ImHex is running in portable mode
|
||||
@@ -753,8 +744,11 @@ namespace hex {
|
||||
|
||||
const std::vector<Font>& getFonts();
|
||||
|
||||
std::map<UnlocalizedString, ImFont*>& getFontDefinitions();
|
||||
void setCustomFontPath(const std::fs::path &path);
|
||||
void setFontSize(float size);
|
||||
void setFontAtlas(ImFontAtlas *fontAtlas);
|
||||
|
||||
void setFonts(ImFont *bold, ImFont *italic);
|
||||
}
|
||||
|
||||
GlyphRange glyph(const char *glyph);
|
||||
@@ -767,8 +761,26 @@ namespace hex {
|
||||
|
||||
constexpr static float DefaultFontSize = 13.0;
|
||||
|
||||
void registerFont(const UnlocalizedString &fontName);
|
||||
ImFont* getFont(const UnlocalizedString &fontName);
|
||||
ImFont* Bold();
|
||||
ImFont* Italic();
|
||||
|
||||
/**
|
||||
* @brief Gets the current custom font path
|
||||
* @return The current custom font path
|
||||
*/
|
||||
const std::filesystem::path& getCustomFontPath();
|
||||
|
||||
/**
|
||||
* @brief Gets the current font size
|
||||
* @return The current font size
|
||||
*/
|
||||
float getFontSize();
|
||||
|
||||
/**
|
||||
* @brief Gets the current font atlas
|
||||
* @return Current font atlas
|
||||
*/
|
||||
ImFontAtlas* getFontAtlas();
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ namespace hex {
|
||||
|
||||
}
|
||||
|
||||
void loadLanguage(std::string language);
|
||||
void loadLanguage(const std::string &language);
|
||||
std::string getLocalizedString(const std::string &unlocalizedString, const std::string &language = "");
|
||||
|
||||
[[nodiscard]] const std::map<std::string, std::string> &getSupportedLanguages();
|
||||
|
||||
@@ -2,25 +2,137 @@
|
||||
|
||||
#include <hex.hpp>
|
||||
#include <hex/api/localization_manager.hpp>
|
||||
#include <hex/helpers/keys.hpp>
|
||||
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <set>
|
||||
#include <string>
|
||||
|
||||
struct ImGuiWindow;
|
||||
#include <GLFW/glfw3.h>
|
||||
|
||||
struct KeyEquivalent {
|
||||
bool valid;
|
||||
bool ctrl, opt, cmd, shift;
|
||||
int key;
|
||||
};
|
||||
struct ImGuiWindow;
|
||||
|
||||
namespace hex {
|
||||
|
||||
class View;
|
||||
|
||||
enum class Keys : u32 {
|
||||
Space = GLFW_KEY_SPACE,
|
||||
Apostrophe = GLFW_KEY_APOSTROPHE,
|
||||
Comma = GLFW_KEY_COMMA,
|
||||
Minus = GLFW_KEY_MINUS,
|
||||
Period = GLFW_KEY_PERIOD,
|
||||
Slash = GLFW_KEY_SLASH,
|
||||
Num0 = GLFW_KEY_0,
|
||||
Num1 = GLFW_KEY_1,
|
||||
Num2 = GLFW_KEY_2,
|
||||
Num3 = GLFW_KEY_3,
|
||||
Num4 = GLFW_KEY_4,
|
||||
Num5 = GLFW_KEY_5,
|
||||
Num6 = GLFW_KEY_6,
|
||||
Num7 = GLFW_KEY_7,
|
||||
Num8 = GLFW_KEY_8,
|
||||
Num9 = GLFW_KEY_9,
|
||||
Semicolon = GLFW_KEY_SEMICOLON,
|
||||
Equals = GLFW_KEY_EQUAL,
|
||||
A = GLFW_KEY_A,
|
||||
B = GLFW_KEY_B,
|
||||
C = GLFW_KEY_C,
|
||||
D = GLFW_KEY_D,
|
||||
E = GLFW_KEY_E,
|
||||
F = GLFW_KEY_F,
|
||||
G = GLFW_KEY_G,
|
||||
H = GLFW_KEY_H,
|
||||
I = GLFW_KEY_I,
|
||||
J = GLFW_KEY_J,
|
||||
K = GLFW_KEY_K,
|
||||
L = GLFW_KEY_L,
|
||||
M = GLFW_KEY_M,
|
||||
N = GLFW_KEY_N,
|
||||
O = GLFW_KEY_O,
|
||||
P = GLFW_KEY_P,
|
||||
Q = GLFW_KEY_Q,
|
||||
R = GLFW_KEY_R,
|
||||
S = GLFW_KEY_S,
|
||||
T = GLFW_KEY_T,
|
||||
U = GLFW_KEY_U,
|
||||
V = GLFW_KEY_V,
|
||||
W = GLFW_KEY_W,
|
||||
X = GLFW_KEY_X,
|
||||
Y = GLFW_KEY_Y,
|
||||
Z = GLFW_KEY_Z,
|
||||
LeftBracket = GLFW_KEY_LEFT_BRACKET,
|
||||
Backslash = GLFW_KEY_BACKSLASH,
|
||||
RightBracket = GLFW_KEY_RIGHT_BRACKET,
|
||||
GraveAccent = GLFW_KEY_GRAVE_ACCENT,
|
||||
World1 = GLFW_KEY_WORLD_1,
|
||||
World2 = GLFW_KEY_WORLD_2,
|
||||
Escape = GLFW_KEY_ESCAPE,
|
||||
Enter = GLFW_KEY_ENTER,
|
||||
Tab = GLFW_KEY_TAB,
|
||||
Backspace = GLFW_KEY_BACKSPACE,
|
||||
Insert = GLFW_KEY_INSERT,
|
||||
Delete = GLFW_KEY_DELETE,
|
||||
Right = GLFW_KEY_RIGHT,
|
||||
Left = GLFW_KEY_LEFT,
|
||||
Down = GLFW_KEY_DOWN,
|
||||
Up = GLFW_KEY_UP,
|
||||
PageUp = GLFW_KEY_PAGE_UP,
|
||||
PageDown = GLFW_KEY_PAGE_DOWN,
|
||||
Home = GLFW_KEY_HOME,
|
||||
End = GLFW_KEY_END,
|
||||
CapsLock = GLFW_KEY_CAPS_LOCK,
|
||||
ScrollLock = GLFW_KEY_SCROLL_LOCK,
|
||||
NumLock = GLFW_KEY_NUM_LOCK,
|
||||
PrintScreen = GLFW_KEY_PRINT_SCREEN,
|
||||
Pause = GLFW_KEY_PAUSE,
|
||||
F1 = GLFW_KEY_F1,
|
||||
F2 = GLFW_KEY_F2,
|
||||
F3 = GLFW_KEY_F3,
|
||||
F4 = GLFW_KEY_F4,
|
||||
F5 = GLFW_KEY_F5,
|
||||
F6 = GLFW_KEY_F6,
|
||||
F7 = GLFW_KEY_F7,
|
||||
F8 = GLFW_KEY_F8,
|
||||
F9 = GLFW_KEY_F9,
|
||||
F10 = GLFW_KEY_F10,
|
||||
F11 = GLFW_KEY_F11,
|
||||
F12 = GLFW_KEY_F12,
|
||||
F13 = GLFW_KEY_F13,
|
||||
F14 = GLFW_KEY_F14,
|
||||
F15 = GLFW_KEY_F15,
|
||||
F16 = GLFW_KEY_F16,
|
||||
F17 = GLFW_KEY_F17,
|
||||
F18 = GLFW_KEY_F18,
|
||||
F19 = GLFW_KEY_F19,
|
||||
F20 = GLFW_KEY_F20,
|
||||
F21 = GLFW_KEY_F21,
|
||||
F22 = GLFW_KEY_F22,
|
||||
F23 = GLFW_KEY_F23,
|
||||
F24 = GLFW_KEY_F24,
|
||||
F25 = GLFW_KEY_F25,
|
||||
KeyPad0 = GLFW_KEY_KP_0,
|
||||
KeyPad1 = GLFW_KEY_KP_1,
|
||||
KeyPad2 = GLFW_KEY_KP_2,
|
||||
KeyPad3 = GLFW_KEY_KP_3,
|
||||
KeyPad4 = GLFW_KEY_KP_4,
|
||||
KeyPad5 = GLFW_KEY_KP_5,
|
||||
KeyPad6 = GLFW_KEY_KP_6,
|
||||
KeyPad7 = GLFW_KEY_KP_7,
|
||||
KeyPad8 = GLFW_KEY_KP_8,
|
||||
KeyPad9 = GLFW_KEY_KP_9,
|
||||
KeyPadDecimal = GLFW_KEY_KP_DECIMAL,
|
||||
KeyPadDivide = GLFW_KEY_KP_DIVIDE,
|
||||
KeyPadMultiply = GLFW_KEY_KP_MULTIPLY,
|
||||
KeyPadSubtract = GLFW_KEY_KP_SUBTRACT,
|
||||
KeyPadAdd = GLFW_KEY_KP_ADD,
|
||||
KeyPadEnter = GLFW_KEY_KP_ENTER,
|
||||
KeyPadEqual = GLFW_KEY_KP_EQUAL,
|
||||
Menu = GLFW_KEY_MENU,
|
||||
};
|
||||
|
||||
|
||||
class Key {
|
||||
public:
|
||||
constexpr Key() = default;
|
||||
@@ -63,7 +175,6 @@ namespace hex {
|
||||
|
||||
bool isLocal() const;
|
||||
std::string toString() const;
|
||||
KeyEquivalent toKeyEquivalent() const;
|
||||
const std::set<Key>& getKeys() const;
|
||||
bool has(Key key) const;
|
||||
bool matches(const Shortcut &other) const;
|
||||
@@ -83,12 +194,10 @@ namespace hex {
|
||||
class ShortcutManager {
|
||||
public:
|
||||
using Callback = std::function<void()>;
|
||||
using EnabledCallback = std::function<bool()>;
|
||||
struct ShortcutEntry {
|
||||
Shortcut shortcut;
|
||||
std::vector<UnlocalizedString> unlocalizedName;
|
||||
Callback callback;
|
||||
EnabledCallback enabledCallback;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -96,10 +205,9 @@ namespace hex {
|
||||
* @param shortcut The shortcut to add.
|
||||
* @param unlocalizedName The unlocalized name of the shortcut
|
||||
* @param callback The callback to call when the shortcut is triggered.
|
||||
* @param enabledCallback Callback that's called to check if this shortcut is enabled
|
||||
*/
|
||||
static void addGlobalShortcut(const Shortcut &shortcut, const std::vector<UnlocalizedString> &unlocalizedName, const Callback &callback, const EnabledCallback &enabledCallback = []{ return true; });
|
||||
static void addGlobalShortcut(const Shortcut &shortcut, const UnlocalizedString &unlocalizedName, const Callback &callback, const EnabledCallback &enabledCallback = []{ return true; });
|
||||
static void addGlobalShortcut(const Shortcut &shortcut, const std::vector<UnlocalizedString> &unlocalizedName, const Callback &callback);
|
||||
static void addGlobalShortcut(const Shortcut &shortcut, const UnlocalizedString &unlocalizedName, const Callback &callback);
|
||||
|
||||
/**
|
||||
* @brief Add a view-specific shortcut. View-specific shortcuts can only be triggered when the specified view is focused.
|
||||
@@ -107,10 +215,9 @@ namespace hex {
|
||||
* @param shortcut The shortcut to add.
|
||||
* @param unlocalizedName The unlocalized name of the shortcut
|
||||
* @param callback The callback to call when the shortcut is triggered.
|
||||
* @param enabledCallback Callback that's called to check if this shortcut is enabled
|
||||
*/
|
||||
static void addShortcut(View *view, const Shortcut &shortcut, const std::vector<UnlocalizedString> &unlocalizedName, const Callback &callback, const EnabledCallback &enabledCallback = []{ return true; });
|
||||
static void addShortcut(View *view, const Shortcut &shortcut, const UnlocalizedString &unlocalizedName, const Callback &callback, const EnabledCallback &enabledCallback = []{ return true; });
|
||||
static void addShortcut(View *view, const Shortcut &shortcut, const std::vector<UnlocalizedString> &unlocalizedName, const Callback &callback);
|
||||
static void addShortcut(View *view, const Shortcut &shortcut, const UnlocalizedString &unlocalizedName, const Callback &callback);
|
||||
|
||||
|
||||
/**
|
||||
@@ -145,9 +252,6 @@ namespace hex {
|
||||
|
||||
static void enableMacOSMode();
|
||||
|
||||
[[nodiscard]] static std::optional<UnlocalizedString> getLastActivatedMenu();
|
||||
static void resetLastActivatedMenu();
|
||||
|
||||
[[nodiscard]] static std::optional<Shortcut> getPreviousShortcut();
|
||||
|
||||
[[nodiscard]] static std::vector<ShortcutEntry> getGlobalShortcuts();
|
||||
|
||||
@@ -67,7 +67,6 @@ namespace hex {
|
||||
|
||||
static void reset();
|
||||
|
||||
static void setAccentColor(const ImColor &color);
|
||||
|
||||
public:
|
||||
struct ThemeHandler {
|
||||
@@ -83,7 +82,6 @@ namespace hex {
|
||||
static const std::map<std::string, ThemeHandler>& getThemeHandlers();
|
||||
static const std::map<std::string, StyleHandler>& getStyleHandlers();
|
||||
|
||||
|
||||
private:
|
||||
ThemeManager() = default;
|
||||
};
|
||||
|
||||
@@ -151,9 +151,6 @@ namespace hex {
|
||||
static void addInteractiveHelpText(std::initializer_list<std::variant<Lang, std::string, int>> &&ids, UnlocalizedString unlocalizedString);
|
||||
static void addInteractiveHelpLink(std::initializer_list<std::variant<Lang, std::string, int>> &&ids, std::string link);
|
||||
|
||||
static void setLastItemInteractiveHelpPopup(std::function<void()> callback);
|
||||
static void setLastItemInteractiveHelpLink(std::string link);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Draws the tutorial
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <hex/api/event_manager.hpp>
|
||||
#include <hex/api/imhex_api.hpp>
|
||||
|
||||
namespace hex {
|
||||
|
||||
@@ -44,7 +44,4 @@ namespace hex::dbg {
|
||||
}
|
||||
}
|
||||
|
||||
bool debugModeEnabled();
|
||||
void setDebugModeEnabled(bool enabled);
|
||||
|
||||
}
|
||||
@@ -82,9 +82,8 @@ namespace hex::paths {
|
||||
const static inline impl::DataPath Nodes("scripts/nodes");
|
||||
const static inline impl::DataPath Layouts("layouts");
|
||||
const static inline impl::DataPath Workspaces("workspaces");
|
||||
const static inline impl::DataPath Disassemblers("disassemblers");
|
||||
|
||||
constexpr static inline std::array<const impl::DefaultPath*, 21> All = {
|
||||
constexpr static inline std::array<const impl::DefaultPath*, 20> All = {
|
||||
&Config,
|
||||
&Recent,
|
||||
|
||||
@@ -107,7 +106,6 @@ namespace hex::paths {
|
||||
&Nodes,
|
||||
&Layouts,
|
||||
&Workspaces,
|
||||
&Disassemblers
|
||||
};
|
||||
|
||||
}
|
||||
@@ -1,122 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <GLFW/glfw3.h>
|
||||
|
||||
#if defined(__cplusplus)
|
||||
enum class Keys {
|
||||
#else
|
||||
enum Keys {
|
||||
#endif
|
||||
Space = GLFW_KEY_SPACE,
|
||||
Apostrophe = GLFW_KEY_APOSTROPHE,
|
||||
Comma = GLFW_KEY_COMMA,
|
||||
Minus = GLFW_KEY_MINUS,
|
||||
Period = GLFW_KEY_PERIOD,
|
||||
Slash = GLFW_KEY_SLASH,
|
||||
Num0 = GLFW_KEY_0,
|
||||
Num1 = GLFW_KEY_1,
|
||||
Num2 = GLFW_KEY_2,
|
||||
Num3 = GLFW_KEY_3,
|
||||
Num4 = GLFW_KEY_4,
|
||||
Num5 = GLFW_KEY_5,
|
||||
Num6 = GLFW_KEY_6,
|
||||
Num7 = GLFW_KEY_7,
|
||||
Num8 = GLFW_KEY_8,
|
||||
Num9 = GLFW_KEY_9,
|
||||
Semicolon = GLFW_KEY_SEMICOLON,
|
||||
Equals = GLFW_KEY_EQUAL,
|
||||
A = GLFW_KEY_A,
|
||||
B = GLFW_KEY_B,
|
||||
C = GLFW_KEY_C,
|
||||
D = GLFW_KEY_D,
|
||||
E = GLFW_KEY_E,
|
||||
F = GLFW_KEY_F,
|
||||
G = GLFW_KEY_G,
|
||||
H = GLFW_KEY_H,
|
||||
I = GLFW_KEY_I,
|
||||
J = GLFW_KEY_J,
|
||||
K = GLFW_KEY_K,
|
||||
L = GLFW_KEY_L,
|
||||
M = GLFW_KEY_M,
|
||||
N = GLFW_KEY_N,
|
||||
O = GLFW_KEY_O,
|
||||
P = GLFW_KEY_P,
|
||||
Q = GLFW_KEY_Q,
|
||||
R = GLFW_KEY_R,
|
||||
S = GLFW_KEY_S,
|
||||
T = GLFW_KEY_T,
|
||||
U = GLFW_KEY_U,
|
||||
V = GLFW_KEY_V,
|
||||
W = GLFW_KEY_W,
|
||||
X = GLFW_KEY_X,
|
||||
Y = GLFW_KEY_Y,
|
||||
Z = GLFW_KEY_Z,
|
||||
LeftBracket = GLFW_KEY_LEFT_BRACKET,
|
||||
Backslash = GLFW_KEY_BACKSLASH,
|
||||
RightBracket = GLFW_KEY_RIGHT_BRACKET,
|
||||
GraveAccent = GLFW_KEY_GRAVE_ACCENT,
|
||||
World1 = GLFW_KEY_WORLD_1,
|
||||
World2 = GLFW_KEY_WORLD_2,
|
||||
Escape = GLFW_KEY_ESCAPE,
|
||||
Enter = GLFW_KEY_ENTER,
|
||||
Tab = GLFW_KEY_TAB,
|
||||
Backspace = GLFW_KEY_BACKSPACE,
|
||||
Insert = GLFW_KEY_INSERT,
|
||||
Delete = GLFW_KEY_DELETE,
|
||||
Right = GLFW_KEY_RIGHT,
|
||||
Left = GLFW_KEY_LEFT,
|
||||
Down = GLFW_KEY_DOWN,
|
||||
Up = GLFW_KEY_UP,
|
||||
PageUp = GLFW_KEY_PAGE_UP,
|
||||
PageDown = GLFW_KEY_PAGE_DOWN,
|
||||
Home = GLFW_KEY_HOME,
|
||||
End = GLFW_KEY_END,
|
||||
CapsLock = GLFW_KEY_CAPS_LOCK,
|
||||
ScrollLock = GLFW_KEY_SCROLL_LOCK,
|
||||
NumLock = GLFW_KEY_NUM_LOCK,
|
||||
PrintScreen = GLFW_KEY_PRINT_SCREEN,
|
||||
Pause = GLFW_KEY_PAUSE,
|
||||
F1 = GLFW_KEY_F1,
|
||||
F2 = GLFW_KEY_F2,
|
||||
F3 = GLFW_KEY_F3,
|
||||
F4 = GLFW_KEY_F4,
|
||||
F5 = GLFW_KEY_F5,
|
||||
F6 = GLFW_KEY_F6,
|
||||
F7 = GLFW_KEY_F7,
|
||||
F8 = GLFW_KEY_F8,
|
||||
F9 = GLFW_KEY_F9,
|
||||
F10 = GLFW_KEY_F10,
|
||||
F11 = GLFW_KEY_F11,
|
||||
F12 = GLFW_KEY_F12,
|
||||
F13 = GLFW_KEY_F13,
|
||||
F14 = GLFW_KEY_F14,
|
||||
F15 = GLFW_KEY_F15,
|
||||
F16 = GLFW_KEY_F16,
|
||||
F17 = GLFW_KEY_F17,
|
||||
F18 = GLFW_KEY_F18,
|
||||
F19 = GLFW_KEY_F19,
|
||||
F20 = GLFW_KEY_F20,
|
||||
F21 = GLFW_KEY_F21,
|
||||
F22 = GLFW_KEY_F22,
|
||||
F23 = GLFW_KEY_F23,
|
||||
F24 = GLFW_KEY_F24,
|
||||
F25 = GLFW_KEY_F25,
|
||||
KeyPad0 = GLFW_KEY_KP_0,
|
||||
KeyPad1 = GLFW_KEY_KP_1,
|
||||
KeyPad2 = GLFW_KEY_KP_2,
|
||||
KeyPad3 = GLFW_KEY_KP_3,
|
||||
KeyPad4 = GLFW_KEY_KP_4,
|
||||
KeyPad5 = GLFW_KEY_KP_5,
|
||||
KeyPad6 = GLFW_KEY_KP_6,
|
||||
KeyPad7 = GLFW_KEY_KP_7,
|
||||
KeyPad8 = GLFW_KEY_KP_8,
|
||||
KeyPad9 = GLFW_KEY_KP_9,
|
||||
KeyPadDecimal = GLFW_KEY_KP_DECIMAL,
|
||||
KeyPadDivide = GLFW_KEY_KP_DIVIDE,
|
||||
KeyPadMultiply = GLFW_KEY_KP_MULTIPLY,
|
||||
KeyPadSubtract = GLFW_KEY_KP_SUBTRACT,
|
||||
KeyPadAdd = GLFW_KEY_KP_ADD,
|
||||
KeyPadEnter = GLFW_KEY_KP_ENTER,
|
||||
KeyPadEqual = GLFW_KEY_KP_EQUAL,
|
||||
Menu = GLFW_KEY_MENU,
|
||||
};
|
||||
@@ -807,8 +807,6 @@ namespace hex::gl {
|
||||
void bind() const;
|
||||
void unbind() const;
|
||||
|
||||
bool isValid() const { return m_program != 0; }
|
||||
|
||||
void setUniform(std::string_view name, const int &value);
|
||||
void setUniform(std::string_view name, const float &value);
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
#include <hex/helpers/utils_linux.hpp>
|
||||
#endif
|
||||
|
||||
#include <imgui.h>
|
||||
struct ImVec2;
|
||||
|
||||
namespace hex {
|
||||
|
||||
@@ -340,6 +340,4 @@ namespace hex {
|
||||
*/
|
||||
[[nodiscard]] void* getContainingModule(void* symbol);
|
||||
|
||||
[[nodiscard]] std::optional<ImColor> blendColors(const std::optional<ImColor> &a, const std::optional<ImColor> &b);
|
||||
|
||||
}
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include <hex/helpers/keys.hpp>
|
||||
|
||||
#if defined(OS_MACOS)
|
||||
|
||||
struct GLFWwindow;
|
||||
@@ -19,11 +17,8 @@
|
||||
void enumerateFontsMacos();
|
||||
|
||||
void macosHandleTitlebarDoubleClickGesture(GLFWwindow *window);
|
||||
void macosSetWindowMovable(GLFWwindow *window, bool movable);
|
||||
bool macosIsWindowBeingResizedByUser(GLFWwindow *window);
|
||||
void macosMarkContentEdited(GLFWwindow *window, bool edited = true);
|
||||
|
||||
void macosGetKey(Keys key, int *output);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -38,7 +38,7 @@ namespace hex::prv {
|
||||
|
||||
[[nodiscard]] std::string getName() const override { return m_name; }
|
||||
|
||||
[[nodiscard]] UnlocalizedString getTypeName() const override { return "MemoryProvider"; }
|
||||
[[nodiscard]] std::string getTypeName() const override { return "MemoryProvider"; }
|
||||
private:
|
||||
void renameFile();
|
||||
|
||||
|
||||
@@ -30,7 +30,6 @@ namespace hex::prv {
|
||||
|
||||
struct MenuEntry {
|
||||
std::string name;
|
||||
const char *icon;
|
||||
std::function<void()> callback;
|
||||
};
|
||||
|
||||
@@ -152,7 +151,7 @@ namespace hex::prv {
|
||||
* like "hex.builtin.provider.mem_file" or "hex.builtin.provider.file"
|
||||
* @return The provider's type name
|
||||
*/
|
||||
[[nodiscard]] virtual UnlocalizedString getTypeName() const = 0;
|
||||
[[nodiscard]] virtual std::string getTypeName() const = 0;
|
||||
|
||||
/**
|
||||
* @brief Gets a human readable representation of the current provider
|
||||
|
||||
@@ -1,10 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <hex/api/imhex_api.hpp>
|
||||
#include <hex/api/events/events_provider.hpp>
|
||||
#include <hex/api/events/events_lifecycle.hpp>
|
||||
#include <hex/api/events/requests_provider.hpp>
|
||||
|
||||
#include <hex/api/event_manager.hpp>
|
||||
|
||||
#include <map>
|
||||
#include <ranges>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
#include <hex.hpp>
|
||||
#include <hex/api/localization_manager.hpp>
|
||||
#include <hex/api/events/events_interaction.hpp>
|
||||
#include <hex/api/event_manager.hpp>
|
||||
|
||||
#include <hex/providers/undo_redo/operations/operation.hpp>
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@ namespace hex::test {
|
||||
return m_data->size();
|
||||
}
|
||||
|
||||
[[nodiscard]] UnlocalizedString getTypeName() const override { return "hex.test.provider.test"; }
|
||||
[[nodiscard]] std::string getTypeName() const override { return "hex.test.provider.test"; }
|
||||
|
||||
bool open() override { return true; }
|
||||
void close() override { }
|
||||
|
||||
@@ -1,57 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <hex.hpp>
|
||||
#include <imgui.h>
|
||||
#include <imgui_internal.h>
|
||||
#include <hex/helpers/utils.hpp>
|
||||
|
||||
#include <list>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include "hex/api/localization_manager.hpp"
|
||||
|
||||
namespace hex {
|
||||
|
||||
namespace impl {
|
||||
|
||||
class BannerBase {
|
||||
public:
|
||||
BannerBase(ImColor color) : m_color(color) {}
|
||||
virtual ~BannerBase() = default;
|
||||
|
||||
virtual void draw() { drawContent(); }
|
||||
virtual void drawContent() = 0;
|
||||
|
||||
[[nodiscard]] static std::list<std::unique_ptr<BannerBase>> &getOpenBanners();
|
||||
|
||||
[[nodiscard]] const ImColor& getColor() const {
|
||||
return m_color;
|
||||
}
|
||||
|
||||
void close() { m_shouldClose = true; }
|
||||
[[nodiscard]] bool shouldClose() const { return m_shouldClose; }
|
||||
|
||||
protected:
|
||||
static std::mutex& getMutex();
|
||||
|
||||
bool m_shouldClose = false;
|
||||
ImColor m_color;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
class Banner : public impl::BannerBase {
|
||||
public:
|
||||
using impl::BannerBase::BannerBase;
|
||||
|
||||
template<typename ...Args>
|
||||
static void open(Args && ... args) {
|
||||
std::lock_guard lock(getMutex());
|
||||
|
||||
auto toast = std::make_unique<T>(std::forward<Args>(args)...);
|
||||
getOpenBanners().emplace_back(std::move(toast));
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
@@ -79,16 +79,16 @@ namespace ImGuiExt {
|
||||
Texture(const Texture&) = delete;
|
||||
Texture(Texture&& other) noexcept;
|
||||
|
||||
[[nodiscard]] static Texture fromImage(const ImU8 *buffer, int size, Filter filter = Filter::Nearest);
|
||||
[[nodiscard]] static Texture fromImage(std::span<const std::byte> buffer, Filter filter = Filter::Nearest);
|
||||
[[nodiscard]] static Texture fromImage(const char *path, Filter filter = Filter::Nearest);
|
||||
[[nodiscard]] static Texture fromImage(const std::fs::path &path, Filter filter = Filter::Nearest);
|
||||
[[nodiscard]] static Texture fromGLTexture(unsigned int texture, int width, int height);
|
||||
[[nodiscard]] static Texture fromBitmap(const ImU8 *buffer, int size, int width, int height, Filter filter = Filter::Nearest);
|
||||
[[nodiscard]] static Texture fromBitmap(std::span<const std::byte> buffer, int width, int height, Filter filter = Filter::Nearest);
|
||||
[[nodiscard]] static Texture fromSVG(const char *path, int width = 0, int height = 0, Filter filter = Filter::Nearest);
|
||||
[[nodiscard]] static Texture fromSVG(const std::fs::path &path, int width = 0, int height = 0, Filter filter = Filter::Nearest);
|
||||
[[nodiscard]] static Texture fromSVG(std::span<const std::byte> buffer, int width = 0, int height = 0, Filter filter = Filter::Nearest);
|
||||
static Texture fromImage(const ImU8 *buffer, int size, Filter filter = Filter::Nearest);
|
||||
static Texture fromImage(std::span<const std::byte> buffer, Filter filter = Filter::Nearest);
|
||||
static Texture fromImage(const char *path, Filter filter = Filter::Nearest);
|
||||
static Texture fromImage(const std::fs::path &path, Filter filter = Filter::Nearest);
|
||||
static Texture fromGLTexture(unsigned int texture, int width, int height);
|
||||
static Texture fromBitmap(const ImU8 *buffer, int size, int width, int height, Filter filter = Filter::Nearest);
|
||||
static Texture fromBitmap(std::span<const std::byte> buffer, int width, int height, Filter filter = Filter::Nearest);
|
||||
static Texture fromSVG(const char *path, int width = 0, int height = 0, Filter filter = Filter::Nearest);
|
||||
static Texture fromSVG(const std::fs::path &path, int width = 0, int height = 0, Filter filter = Filter::Nearest);
|
||||
static Texture fromSVG(std::span<const std::byte> buffer, int width = 0, int height = 0, Filter filter = Filter::Nearest);
|
||||
|
||||
|
||||
~Texture();
|
||||
@@ -144,13 +144,13 @@ namespace ImGuiExt {
|
||||
|
||||
bool TitleBarButton(const char *label, ImVec2 size_arg);
|
||||
bool ToolBarButton(const char *symbol, ImVec4 color);
|
||||
bool IconButton(const char *symbol, ImVec4 color, ImVec2 size_arg = ImVec2(0, 0), ImVec2 iconOffset = ImVec2(0, 0));
|
||||
bool IconButton(const char *symbol, ImVec4 color, ImVec2 size_arg = ImVec2(0, 0));
|
||||
|
||||
bool InputIntegerPrefix(const char* label, const char *prefix, void *value, ImGuiDataType type, const char *format, ImGuiInputTextFlags flags = ImGuiInputTextFlags_None);
|
||||
bool InputHexadecimal(const char* label, u32 *value, ImGuiInputTextFlags flags = ImGuiInputTextFlags_None);
|
||||
bool InputHexadecimal(const char* label, u64 *value, ImGuiInputTextFlags flags = ImGuiInputTextFlags_None);
|
||||
|
||||
bool SliderBytes(const char *label, u64 *value, u64 min, u64 max, u64 stepSize = 1, ImGuiSliderFlags flags = ImGuiSliderFlags_None);
|
||||
bool SliderBytes(const char *label, u64 *value, u64 min, u64 max, ImGuiSliderFlags flags = ImGuiSliderFlags_None);
|
||||
|
||||
inline bool HasSecondPassed() {
|
||||
return static_cast<ImU32>(ImGui::GetTime() * 100) % 100 <= static_cast<ImU32>(ImGui::GetIO().DeltaTime * 100);
|
||||
@@ -203,7 +203,7 @@ namespace ImGuiExt {
|
||||
ImGui::PushStyleColor(ImGuiCol_FrameBg, ImVec4());
|
||||
|
||||
ImGui::PushItemWidth(ImGui::CalcTextSize(text.c_str()).x + ImGui::GetStyle().FramePadding.x * 2);
|
||||
ImGui::InputText("##", const_cast<char *>(text.c_str()), text.size() + 1, ImGuiInputTextFlags_ReadOnly | ImGuiInputTextFlags_NoHorizontalScroll);
|
||||
ImGui::InputText("##", const_cast<char *>(text.c_str()), text.size(), ImGuiInputTextFlags_ReadOnly | ImGuiInputTextFlags_NoHorizontalScroll);
|
||||
ImGui::PopItemWidth();
|
||||
|
||||
ImGui::PopStyleColor();
|
||||
@@ -235,13 +235,11 @@ namespace ImGuiExt {
|
||||
|
||||
inline void TextFormattedWrappedSelectable(std::string_view fmt, auto &&...args) {
|
||||
// Manually wrap text, using the letter M (generally the widest character in non-monospaced fonts) to calculate the character width to use.
|
||||
auto text = wolv::util::trim(wolv::util::wrapMonospacedString(
|
||||
auto text = wolv::util::wrapMonospacedString(
|
||||
hex::format(fmt, std::forward<decltype(args)>(args)...),
|
||||
ImGui::CalcTextSize("M").x,
|
||||
ImGui::GetContentRegionAvail().x - ImGui::GetStyle().ScrollbarSize - ImGui::GetStyle().FrameBorderSize
|
||||
));
|
||||
|
||||
auto textSize = ImGui::CalcTextSize(text.c_str());
|
||||
);
|
||||
|
||||
ImGui::PushID(text.c_str());
|
||||
|
||||
@@ -252,8 +250,8 @@ namespace ImGuiExt {
|
||||
ImGui::InputTextMultiline(
|
||||
"##",
|
||||
const_cast<char *>(text.c_str()),
|
||||
text.size() + 1,
|
||||
ImVec2(0, textSize.y),
|
||||
text.size(),
|
||||
ImVec2(0, -FLT_MIN),
|
||||
ImGuiInputTextFlags_ReadOnly | ImGuiInputTextFlags_NoHorizontalScroll
|
||||
);
|
||||
ImGui::PopItemWidth();
|
||||
@@ -293,8 +291,8 @@ namespace ImGuiExt {
|
||||
bool BitCheckbox(const char* label, bool* v);
|
||||
|
||||
bool DimmedButton(const char* label, ImVec2 size = ImVec2(0, 0));
|
||||
bool DimmedIconButton(const char *symbol, ImVec4 color, ImVec2 size = ImVec2(0, 0), ImVec2 iconOffset = ImVec2(0, 0));
|
||||
bool DimmedButtonToggle(const char *icon, bool *v, ImVec2 size = ImVec2(0, 0), ImVec2 iconOffset = ImVec2(0, 0));
|
||||
bool DimmedIconButton(const char *symbol, ImVec4 color, ImVec2 size = ImVec2(0, 0));
|
||||
bool DimmedButtonToggle(const char *icon, bool *v, ImVec2 size);
|
||||
bool DimmedIconToggle(const char *icon, bool *v);
|
||||
bool DimmedIconToggle(const char *iconOn, const char *iconOff, bool *v);
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
#include <hex/api/imhex_api.hpp>
|
||||
#include <hex/api/shortcut_manager.hpp>
|
||||
#include <hex/api/event_manager.hpp>
|
||||
#include <hex/api/localization_manager.hpp>
|
||||
|
||||
#include <hex/providers/provider.hpp>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#include <hex/api/achievement_manager.hpp>
|
||||
#include <hex/api/events/events_interaction.hpp>
|
||||
#include <hex/api/event_manager.hpp>
|
||||
|
||||
#include <hex/helpers/auto_reset.hpp>
|
||||
#include <hex/helpers/default_paths.hpp>
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
#include <hex/api/content_registry.hpp>
|
||||
#include <hex/api/shortcut_manager.hpp>
|
||||
#include <hex/api/events/requests_provider.hpp>
|
||||
|
||||
#include <hex/helpers/fs.hpp>
|
||||
#include <hex/helpers/logger.hpp>
|
||||
@@ -39,34 +38,6 @@ namespace hex {
|
||||
|
||||
static AutoReset<std::map<std::string, std::map<std::string, std::vector<OnChange>>>> s_onChangeCallbacks;
|
||||
|
||||
static void runAllOnChangeCallbacks() {
|
||||
for (const auto &[category, rest] : *impl::s_onChangeCallbacks) {
|
||||
for (const auto &[name, callbacks] : rest) {
|
||||
for (const auto &[id, callback] : callbacks) {
|
||||
try {
|
||||
callback(getSetting(category, name, {}));
|
||||
} catch (const std::exception &e) {
|
||||
log::error("Failed to load setting [{}/{}]: {}", category, name, e.what());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void runOnChangeHandlers(const UnlocalizedString &unlocalizedCategory, const UnlocalizedString &unlocalizedName, const nlohmann::json &value) {
|
||||
if (auto categoryIt = s_onChangeCallbacks->find(unlocalizedCategory); categoryIt != s_onChangeCallbacks->end()) {
|
||||
if (auto nameIt = categoryIt->second.find(unlocalizedName); nameIt != categoryIt->second.end()) {
|
||||
for (const auto &[id, callback] : nameIt->second) {
|
||||
try {
|
||||
callback(value);
|
||||
} catch (const nlohmann::json::exception &e) {
|
||||
log::error("Failed to run onChange handler for setting {}/{}: {}", unlocalizedCategory.get(), unlocalizedName.get(), e.what());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static AutoReset<nlohmann::json> s_settings;
|
||||
const nlohmann::json& getSettingsData() {
|
||||
return s_settings;
|
||||
@@ -101,28 +72,24 @@ namespace hex {
|
||||
s_settings = nlohmann::json::parse(data);
|
||||
}
|
||||
|
||||
runAllOnChangeCallbacks();
|
||||
for (const auto &[category, rest] : *impl::s_onChangeCallbacks) {
|
||||
for (const auto &[name, callbacks] : rest) {
|
||||
for (const auto &[id, callback] : callbacks) {
|
||||
try {
|
||||
callback(getSetting(category, name, {}));
|
||||
} catch (const std::exception &e) {
|
||||
log::error("Failed to load setting [{}/{}]: {}", category, name, e.what());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void store() {
|
||||
if (!s_settings.isValid())
|
||||
return;
|
||||
|
||||
const auto &settingsData = *s_settings;
|
||||
|
||||
// During a crash settings can be empty, causing them to be overwritten.
|
||||
if (settingsData.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
const auto result = settingsData.dump(4);
|
||||
if (result.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto data = s_settings->dump();
|
||||
MAIN_THREAD_EM_ASM({
|
||||
localStorage.setItem("config", UTF8ToString($0));
|
||||
}, result.c_str());
|
||||
}, data.c_str());
|
||||
}
|
||||
|
||||
void clear() {
|
||||
@@ -148,7 +115,17 @@ namespace hex {
|
||||
if (!loaded)
|
||||
store();
|
||||
|
||||
runAllOnChangeCallbacks();
|
||||
for (const auto &[category, rest] : *impl::s_onChangeCallbacks) {
|
||||
for (const auto &[name, callbacks] : rest) {
|
||||
for (const auto &[id, callback] : callbacks) {
|
||||
try {
|
||||
callback(getSetting(category, name, {}));
|
||||
} catch (const std::exception &e) {
|
||||
log::error("Failed to load setting [{}/{}]: {}", category, name, e.what());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void store() {
|
||||
@@ -158,7 +135,7 @@ namespace hex {
|
||||
const auto &settingsData = *s_settings;
|
||||
|
||||
// During a crash settings can be empty, causing them to be overwritten.
|
||||
if (s_settings->empty()) {
|
||||
if (settingsData.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -224,8 +201,6 @@ namespace hex {
|
||||
log::error("Failed to load setting [{} / {}]: {}", unlocalizedCategory.get(), unlocalizedName.get(), e.what());
|
||||
}
|
||||
});
|
||||
|
||||
runOnChangeHandlers(unlocalizedCategory, unlocalizedName, getSetting(unlocalizedCategory, unlocalizedName, entry->widget->store()));
|
||||
}
|
||||
|
||||
return entry->widget.get();
|
||||
@@ -235,6 +210,20 @@ namespace hex {
|
||||
hex::log::error("Failed to read setting {}/{}: {}", unlocalizedCategory.get(), unlocalizedName.get(), e.what());
|
||||
}
|
||||
|
||||
void runOnChangeHandlers(const UnlocalizedString &unlocalizedCategory, const UnlocalizedString &unlocalizedName, const nlohmann::json &value) {
|
||||
if (auto categoryIt = s_onChangeCallbacks->find(unlocalizedCategory); categoryIt != s_onChangeCallbacks->end()) {
|
||||
if (auto nameIt = categoryIt->second.find(unlocalizedName); nameIt != categoryIt->second.end()) {
|
||||
for (const auto &[id, callback] : nameIt->second) {
|
||||
try {
|
||||
callback(value);
|
||||
} catch (const nlohmann::json::exception &e) {
|
||||
log::error("Failed to run onChange handler for setting {}/{}: {}", unlocalizedCategory.get(), unlocalizedName.get(), e.what());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void setCategoryDescription(const UnlocalizedString &unlocalizedCategory, const UnlocalizedString &unlocalizedDescription) {
|
||||
@@ -336,7 +325,7 @@ namespace hex {
|
||||
|
||||
|
||||
bool SliderDataSize::draw(const std::string &name) {
|
||||
return ImGuiExt::SliderBytes(name.c_str(), &m_value, m_min, m_max, m_stepSize);
|
||||
return ImGuiExt::SliderBytes(name.c_str(), &m_value, m_min, m_max);
|
||||
}
|
||||
|
||||
void SliderDataSize::load(const nlohmann::json &data) {
|
||||
@@ -352,34 +341,17 @@ namespace hex {
|
||||
}
|
||||
|
||||
|
||||
ColorPicker::ColorPicker(ImColor defaultColor, ImGuiColorEditFlags flags) {
|
||||
m_defaultValue = m_value = {
|
||||
defaultColor.Value.x,
|
||||
defaultColor.Value.y,
|
||||
defaultColor.Value.z,
|
||||
defaultColor.Value.w
|
||||
ColorPicker::ColorPicker(ImColor defaultColor) {
|
||||
m_value = {
|
||||
defaultColor.Value.x,
|
||||
defaultColor.Value.y,
|
||||
defaultColor.Value.z,
|
||||
defaultColor.Value.w
|
||||
};
|
||||
m_flags = flags;
|
||||
}
|
||||
|
||||
bool ColorPicker::draw(const std::string &name) {
|
||||
ImGui::PushID(name.c_str());
|
||||
auto result = ImGui::ColorEdit4("##color_picker", m_value.data(), ImGuiColorEditFlags_NoInputs | m_flags);
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
if (ImGui::Button("X", ImGui::GetStyle().FramePadding * 2 + ImVec2(ImGui::GetTextLineHeight(), ImGui::GetTextLineHeight()))) {
|
||||
m_value = m_defaultValue;
|
||||
result = true;
|
||||
}
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
ImGui::TextUnformatted(name.c_str());
|
||||
|
||||
ImGui::PopID();
|
||||
|
||||
return result;
|
||||
return ImGui::ColorEdit4(name.c_str(), m_value.data(), ImGuiColorEditFlags_NoInputs);
|
||||
}
|
||||
|
||||
void ColorPicker::load(const nlohmann::json &data) {
|
||||
@@ -405,7 +377,7 @@ namespace hex {
|
||||
bool DropDown::draw(const std::string &name) {
|
||||
auto preview = "";
|
||||
if (static_cast<size_t>(m_value) < m_items.size())
|
||||
preview = m_items[m_value].get().c_str();
|
||||
preview = m_items[m_value].c_str();
|
||||
|
||||
bool changed = false;
|
||||
if (ImGui::BeginCombo(name.c_str(), Lang(preview))) {
|
||||
@@ -780,14 +752,6 @@ namespace hex {
|
||||
impl::s_entries->push_back({ unlocalizedName, requiredSize, maxSize, std::move(displayGeneratorFunction), std::move(editingFunction) });
|
||||
}
|
||||
|
||||
void drawMenuItems(const std::function<void()> &function) {
|
||||
if (ImGui::BeginPopup("##DataInspectorRowContextMenu")) {
|
||||
function();
|
||||
ImGui::Separator();
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
namespace ContentRegistry::DataProcessorNode {
|
||||
@@ -953,10 +917,17 @@ namespace hex {
|
||||
});
|
||||
|
||||
if (shortcut != Shortcut::None) {
|
||||
auto callbackIfEnabled = [enabledCallback, function]{ if (enabledCallback()) { function(); } };
|
||||
|
||||
const auto unlocalizedShortcutName =
|
||||
unlocalizedMainMenuNames.size() == 1 ?
|
||||
std::vector { unlocalizedMainMenuNames.back() } :
|
||||
std::vector(unlocalizedMainMenuNames.begin() + 1, unlocalizedMainMenuNames.end());
|
||||
|
||||
if (shortcut.isLocal() && view != nullptr)
|
||||
ShortcutManager::addShortcut(view, shortcut, unlocalizedMainMenuNames, function, enabledCallback);
|
||||
ShortcutManager::addShortcut(view, shortcut, unlocalizedShortcutName, callbackIfEnabled);
|
||||
else
|
||||
ShortcutManager::addGlobalShortcut(shortcut, unlocalizedMainMenuNames, function, enabledCallback);
|
||||
ShortcutManager::addGlobalShortcut(shortcut, unlocalizedShortcutName, callbackIfEnabled);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1420,23 +1391,4 @@ namespace hex {
|
||||
|
||||
}
|
||||
|
||||
namespace ContentRegistry::Disassembler {
|
||||
|
||||
namespace impl {
|
||||
|
||||
static AutoReset<std::map<std::string, impl::CreatorFunction>> s_architectures;
|
||||
|
||||
void addArchitectureCreator(impl::CreatorFunction function) {
|
||||
const auto arch = function();
|
||||
(*s_architectures)[arch->getName()] = std::move(function);
|
||||
}
|
||||
|
||||
const std::map<std::string, impl::CreatorFunction>& getArchitectures() {
|
||||
return *s_architectures;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,13 +1,6 @@
|
||||
#include <hex/api/imhex_api.hpp>
|
||||
|
||||
#include <hex/api/events/events_provider.hpp>
|
||||
#include <hex/api/events/events_lifecycle.hpp>
|
||||
#include <hex/api/events/events_gui.hpp>
|
||||
#include <hex/api/events/requests_interaction.hpp>
|
||||
#include <hex/api/events/requests_lifecycle.hpp>
|
||||
#include <hex/api/events/requests_provider.hpp>
|
||||
#include <hex/api/events/requests_gui.hpp>
|
||||
|
||||
#include <hex/api/event_manager.hpp>
|
||||
#include <hex/api/task_manager.hpp>
|
||||
#include <hex/helpers/fmt.hpp>
|
||||
#include <hex/helpers/utils.hpp>
|
||||
@@ -18,7 +11,6 @@
|
||||
#include <wolv/utils/string.hpp>
|
||||
|
||||
#include <utility>
|
||||
#include <numeric>
|
||||
|
||||
#include <imgui.h>
|
||||
#include <imgui_internal.h>
|
||||
@@ -26,20 +18,13 @@
|
||||
#include <algorithm>
|
||||
#include <GLFW/glfw3.h>
|
||||
|
||||
#include <hex/helpers/utils_macos.hpp>
|
||||
|
||||
#if defined(OS_WINDOWS)
|
||||
#include <windows.h>
|
||||
#include <DSRole.h>
|
||||
#else
|
||||
#include <sys/utsname.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#if defined(OS_WEB)
|
||||
#include <emscripten.h>
|
||||
#endif
|
||||
|
||||
namespace hex {
|
||||
|
||||
|
||||
@@ -623,27 +608,6 @@ namespace hex {
|
||||
return impl::s_nativeScale;
|
||||
}
|
||||
|
||||
float getBackingScaleFactor() {
|
||||
#if defined(OS_WINDOWS)
|
||||
return 1.0F;
|
||||
#elif defined(OS_MACOS)
|
||||
return ::getBackingScaleFactor();
|
||||
#elif defined(OS_LINUX)
|
||||
if (std::string_view(::getenv("XDG_SESSION_TYPE")) == "x11")
|
||||
return 1.0F;
|
||||
else {
|
||||
float xScale = 0, yScale = 0;
|
||||
glfwGetMonitorContentScale(glfwGetPrimaryMonitor(), &xScale, &yScale);
|
||||
|
||||
return std::midpoint(xScale, yScale);
|
||||
}
|
||||
#elif defined(OS_WEB)
|
||||
return 1.0F;
|
||||
#else
|
||||
return 1.0F;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
ImVec2 getMainWindowPosition() {
|
||||
if ((ImGui::GetIO().ConfigFlags & ImGuiConfigFlags_ViewportsEnable) != ImGuiConfigFlags_None)
|
||||
@@ -733,27 +697,6 @@ namespace hex {
|
||||
return impl::s_glRenderer;
|
||||
}
|
||||
|
||||
bool isCorporateEnvironment() {
|
||||
#if defined(OS_WINDOWS)
|
||||
{
|
||||
DSROLE_PRIMARY_DOMAIN_INFO_BASIC * info;
|
||||
if ((DsRoleGetPrimaryDomainInformation(NULL, DsRolePrimaryDomainInfoBasic, (PBYTE *)&info) == ERROR_SUCCESS) && (info != nullptr))
|
||||
{
|
||||
bool result = std::wstring(info->DomainNameFlat).empty();
|
||||
DsRoleFreeMemory(info);
|
||||
|
||||
return result;
|
||||
} else {
|
||||
DWORD size = 1024;
|
||||
::GetComputerNameExA(ComputerNameDnsDomain, nullptr, &size);
|
||||
return size > 0;
|
||||
}
|
||||
}
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool isPortableVersion() {
|
||||
static std::optional<bool> portable;
|
||||
if (portable.has_value())
|
||||
@@ -995,6 +938,11 @@ namespace hex {
|
||||
return *s_fonts;
|
||||
}
|
||||
|
||||
static AutoReset<std::fs::path> s_customFontPath;
|
||||
void setCustomFontPath(const std::fs::path &path) {
|
||||
s_customFontPath = path;
|
||||
}
|
||||
|
||||
static float s_fontSize = DefaultFontSize;
|
||||
void setFontSize(float size) {
|
||||
s_fontSize = size;
|
||||
@@ -1012,10 +960,6 @@ namespace hex {
|
||||
s_italicFont = italic;
|
||||
}
|
||||
|
||||
static AutoReset<std::map<UnlocalizedString, ImFont*>> s_fontDefinitions;
|
||||
std::map<UnlocalizedString, ImFont*>& getFontDefinitions() {
|
||||
return *s_fontDefinitions;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1080,6 +1024,10 @@ namespace hex {
|
||||
});
|
||||
}
|
||||
|
||||
const std::fs::path& getCustomFontPath() {
|
||||
return impl::s_customFontPath;
|
||||
}
|
||||
|
||||
float getFontSize() {
|
||||
return impl::s_fontSize;
|
||||
}
|
||||
@@ -1088,14 +1036,6 @@ namespace hex {
|
||||
return impl::s_fontAtlas;
|
||||
}
|
||||
|
||||
void registerFont(const UnlocalizedString &fontName) {
|
||||
(*impl::s_fontDefinitions)[fontName] = nullptr;
|
||||
}
|
||||
|
||||
ImFont* getFont(const UnlocalizedString &fontName) {
|
||||
return (*impl::s_fontDefinitions)[fontName];
|
||||
}
|
||||
|
||||
ImFont* Bold() {
|
||||
return impl::s_boldFont;
|
||||
}
|
||||
|
||||
@@ -56,19 +56,18 @@ namespace hex {
|
||||
}
|
||||
}
|
||||
|
||||
void loadLanguage(std::string language) {
|
||||
void loadLanguage(const std::string &language) {
|
||||
auto &definitions = ContentRegistry::Language::impl::getLanguageDefinitions();
|
||||
|
||||
const auto& fallbackLanguage = getFallbackLanguage();
|
||||
if (!definitions.contains(language))
|
||||
language = fallbackLanguage;
|
||||
return;
|
||||
|
||||
s_currStrings->clear();
|
||||
|
||||
loadLanguageDefinitions(definitions.at(language));
|
||||
|
||||
if (language != fallbackLanguage)
|
||||
loadLanguageDefinitions(definitions.at(fallbackLanguage));
|
||||
const auto& fallbackLanguage = getFallbackLanguage();
|
||||
loadLanguageDefinitions(definitions.at(fallbackLanguage));
|
||||
|
||||
s_selectedLanguage = language;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#include <hex/api/shortcut_manager.hpp>
|
||||
#include <imgui.h>
|
||||
#include <hex/api/content_registry.hpp>
|
||||
#include <hex/api/task_manager.hpp>
|
||||
#include <hex/helpers/auto_reset.hpp>
|
||||
|
||||
#include <hex/ui/view.hpp>
|
||||
@@ -14,7 +13,6 @@ namespace hex {
|
||||
std::atomic<bool> s_paused;
|
||||
std::optional<Shortcut> s_prevShortcut;
|
||||
bool s_macOSMode = false;
|
||||
AutoReset<std::optional<UnlocalizedString>> s_lastShortcutMainMenu;
|
||||
|
||||
}
|
||||
|
||||
@@ -233,66 +231,28 @@ namespace hex {
|
||||
return result;
|
||||
}
|
||||
|
||||
KeyEquivalent Shortcut::toKeyEquivalent() const {
|
||||
#if defined(OS_MACOS)
|
||||
if (*this == None)
|
||||
return { };
|
||||
|
||||
KeyEquivalent result = {};
|
||||
result.valid = true;
|
||||
|
||||
for (const auto &key : m_keys) {
|
||||
switch (key.getKeyCode()) {
|
||||
case CTRL.getKeyCode():
|
||||
result.ctrl = true;
|
||||
break;
|
||||
case SHIFT.getKeyCode():
|
||||
result.shift = true;
|
||||
break;
|
||||
case ALT.getKeyCode():
|
||||
result.opt = true;
|
||||
break;
|
||||
case SUPER.getKeyCode():
|
||||
case CTRLCMD.getKeyCode():
|
||||
result.cmd = true;
|
||||
break;
|
||||
case CurrentView.getKeyCode(): break;
|
||||
case AllowWhileTyping.getKeyCode(): break;
|
||||
default:
|
||||
macosGetKey(Keys(key.getKeyCode()), &result.key);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
#else
|
||||
return { };
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
void ShortcutManager::addGlobalShortcut(const Shortcut &shortcut, const std::vector<UnlocalizedString> &unlocalizedName, const std::function<void()> &callback, const EnabledCallback &enabledCallback) {
|
||||
void ShortcutManager::addGlobalShortcut(const Shortcut &shortcut, const std::vector<UnlocalizedString> &unlocalizedName, const std::function<void()> &callback) {
|
||||
log::debug("Adding global shortcut {} for {}", shortcut.toString(), unlocalizedName.back().get());
|
||||
auto [it, inserted] = s_globalShortcuts->insert({ shortcut, { shortcut, unlocalizedName, callback, enabledCallback } });
|
||||
auto [it, inserted] = s_globalShortcuts->insert({ shortcut, { shortcut, unlocalizedName, callback } });
|
||||
if (!inserted) log::error("Failed to add shortcut!");
|
||||
}
|
||||
|
||||
void ShortcutManager::addGlobalShortcut(const Shortcut &shortcut, const UnlocalizedString &unlocalizedName, const std::function<void()> &callback, const EnabledCallback &enabledCallback) {
|
||||
void ShortcutManager::addGlobalShortcut(const Shortcut &shortcut, const UnlocalizedString &unlocalizedName, const std::function<void()> &callback) {
|
||||
log::debug("Adding global shortcut {} for {}", shortcut.toString(), unlocalizedName.get());
|
||||
auto [it, inserted] = s_globalShortcuts->insert({ shortcut, { shortcut, { unlocalizedName }, callback, enabledCallback } });
|
||||
auto [it, inserted] = s_globalShortcuts->insert({ shortcut, { shortcut, { unlocalizedName }, callback } });
|
||||
if (!inserted) log::error("Failed to add shortcut!");
|
||||
}
|
||||
|
||||
void ShortcutManager::addShortcut(View *view, const Shortcut &shortcut, const std::vector<UnlocalizedString> &unlocalizedName, const std::function<void()> &callback, const EnabledCallback &enabledCallback) {
|
||||
void ShortcutManager::addShortcut(View *view, const Shortcut &shortcut, const std::vector<UnlocalizedString> &unlocalizedName, const std::function<void()> &callback) {
|
||||
log::debug("Adding shortcut {} for {}", shortcut.toString(), unlocalizedName.back().get());
|
||||
auto [it, inserted] = view->m_shortcuts.insert({ shortcut + CurrentView, { shortcut, unlocalizedName, callback, enabledCallback } });
|
||||
auto [it, inserted] = view->m_shortcuts.insert({ shortcut + CurrentView, { shortcut, unlocalizedName, callback } });
|
||||
if (!inserted) log::error("Failed to add shortcut!");
|
||||
}
|
||||
|
||||
void ShortcutManager::addShortcut(View *view, const Shortcut &shortcut, const UnlocalizedString &unlocalizedName, const std::function<void()> &callback, const EnabledCallback &enabledCallback) {
|
||||
void ShortcutManager::addShortcut(View *view, const Shortcut &shortcut, const UnlocalizedString &unlocalizedName, const std::function<void()> &callback) {
|
||||
log::debug("Adding shortcut {} for {}", shortcut.toString(), unlocalizedName.get());
|
||||
auto [it, inserted] = view->m_shortcuts.insert({ shortcut + CurrentView, { shortcut, { unlocalizedName }, callback, enabledCallback } });
|
||||
auto [it, inserted] = view->m_shortcuts.insert({ shortcut + CurrentView, { shortcut, { unlocalizedName }, callback } });
|
||||
if (!inserted) log::error("Failed to add shortcut!");
|
||||
}
|
||||
|
||||
@@ -309,36 +269,23 @@ namespace hex {
|
||||
pressedShortcut += s_macOSMode ? CTRLCMD : SUPER;
|
||||
if (focused)
|
||||
pressedShortcut += CurrentView;
|
||||
if (ImGui::GetIO().WantTextInput)
|
||||
pressedShortcut += AllowWhileTyping;
|
||||
|
||||
pressedShortcut += static_cast<Keys>(keyCode);
|
||||
|
||||
return pressedShortcut;
|
||||
}
|
||||
|
||||
static void processShortcut(Shortcut shortcut, const std::map<Shortcut, ShortcutManager::ShortcutEntry> &shortcuts) {
|
||||
static void processShortcut(const Shortcut &shortcut, const std::map<Shortcut, ShortcutManager::ShortcutEntry> &shortcuts) {
|
||||
if (s_paused) return;
|
||||
|
||||
if (ImGui::IsPopupOpen(ImGuiID(0), ImGuiPopupFlags_AnyPopupId))
|
||||
return;
|
||||
|
||||
const bool currentlyTyping = ImGui::GetIO().WantTextInput;
|
||||
|
||||
auto it = shortcuts.find(shortcut + AllowWhileTyping);
|
||||
if (!currentlyTyping && it == shortcuts.end()) {
|
||||
if (it == shortcuts.end())
|
||||
it = shortcuts.find(shortcut);
|
||||
}
|
||||
|
||||
if (it != shortcuts.end()) {
|
||||
if (auto it = shortcuts.find(shortcut); it != shortcuts.end()) {
|
||||
const auto &[foundShortcut, entry] = *it;
|
||||
|
||||
if (entry.enabledCallback()) {
|
||||
entry.callback();
|
||||
|
||||
if (!entry.unlocalizedName.empty()) {
|
||||
s_lastShortcutMainMenu = entry.unlocalizedName.front();
|
||||
}
|
||||
}
|
||||
entry.callback();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -358,15 +305,6 @@ namespace hex {
|
||||
processShortcut(pressedShortcut, s_globalShortcuts);
|
||||
}
|
||||
|
||||
std::optional<UnlocalizedString> ShortcutManager::getLastActivatedMenu() {
|
||||
return *s_lastShortcutMainMenu;
|
||||
}
|
||||
|
||||
void ShortcutManager::resetLastActivatedMenu() {
|
||||
s_lastShortcutMainMenu->reset();
|
||||
}
|
||||
|
||||
|
||||
void ShortcutManager::clearShortcuts() {
|
||||
s_globalShortcuts->clear();
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#include <hex/api/theme_manager.hpp>
|
||||
#include <hex/api/events/events_interaction.hpp>
|
||||
#include <hex/api/event_manager.hpp>
|
||||
|
||||
#include <hex/helpers/logger.hpp>
|
||||
#include <hex/helpers/utils.hpp>
|
||||
@@ -16,7 +16,6 @@ namespace hex {
|
||||
AutoReset<std::map<std::string, ThemeManager::StyleHandler>> s_styleHandlers;
|
||||
AutoReset<std::string> s_imageTheme;
|
||||
AutoReset<std::string> s_currTheme;
|
||||
AutoReset<std::optional<float>> s_accentColor;
|
||||
|
||||
std::recursive_mutex s_themeMutex;
|
||||
}
|
||||
@@ -156,28 +155,12 @@ namespace hex {
|
||||
continue;
|
||||
}
|
||||
|
||||
auto colorString = value.get<std::string>();
|
||||
bool accentableColor = false;
|
||||
if (colorString.starts_with("*")) {
|
||||
colorString = colorString.substr(1);
|
||||
accentableColor = true;
|
||||
}
|
||||
auto color = parseColorString(colorString);
|
||||
|
||||
auto color = parseColorString(value.get<std::string>());
|
||||
if (!color.has_value()) {
|
||||
log::warn("Invalid color '{}' for '{}.{}'", colorString, type, key);
|
||||
log::warn("Invalid color '{}' for '{}.{}'", value.get<std::string>(), type, key);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (accentableColor && s_accentColor->has_value()) {
|
||||
float h, s, v;
|
||||
ImGui::ColorConvertRGBtoHSV(color->Value.x, color->Value.y, color->Value.z, h, s, v);
|
||||
|
||||
h = s_accentColor->value();
|
||||
|
||||
ImGui::ColorConvertHSVtoRGB(h, s, v, color->Value.x, color->Value.y, color->Value.z);
|
||||
}
|
||||
|
||||
(*s_themeHandlers)[type].setFunction((*s_themeHandlers)[type].colorMap.at(key), color.value());
|
||||
}
|
||||
}
|
||||
@@ -253,14 +236,6 @@ namespace hex {
|
||||
s_currTheme->clear();
|
||||
}
|
||||
|
||||
void ThemeManager::setAccentColor(const ImColor &color) {
|
||||
float h, s, v;
|
||||
ImGui::ColorConvertRGBtoHSV(color.Value.x, color.Value.y, color.Value.z, h, s, v);
|
||||
|
||||
s_accentColor = h;
|
||||
reapplyCurrentTheme();
|
||||
}
|
||||
|
||||
|
||||
const std::map<std::string, ThemeManager::ThemeHandler> &ThemeManager::getThemeHandlers() {
|
||||
return s_themeHandlers;
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
#include <hex/api/imhex_api.hpp>
|
||||
#include <hex/api/localization_manager.hpp>
|
||||
#include <hex/api/task_manager.hpp>
|
||||
#include <hex/api/events/events_gui.hpp>
|
||||
|
||||
#include <hex/helpers/auto_reset.hpp>
|
||||
|
||||
@@ -12,8 +11,6 @@
|
||||
|
||||
#include <map>
|
||||
|
||||
#include <imgui.h>
|
||||
|
||||
namespace hex {
|
||||
|
||||
namespace {
|
||||
@@ -23,12 +20,10 @@ namespace hex {
|
||||
|
||||
AutoReset<std::map<ImGuiID, std::string>> s_highlights;
|
||||
AutoReset<std::vector<std::pair<ImRect, std::string>>> s_highlightDisplays;
|
||||
AutoReset<std::map<ImGuiID, ImRect>> s_interactiveHelpDisplays;
|
||||
|
||||
AutoReset<std::map<ImGuiID, std::function<void()>>> s_interactiveHelpItems;
|
||||
ImRect s_hoveredRect;
|
||||
ImGuiID s_hoveredId;
|
||||
ImGuiID s_activeHelpId;
|
||||
bool s_helpHoverActive = false;
|
||||
|
||||
|
||||
@@ -96,23 +91,13 @@ namespace hex {
|
||||
EventImGuiElementRendered::subscribe([](ImGuiID id, const std::array<float, 4> bb){
|
||||
const auto boundingBox = ImRect(bb[0], bb[1], bb[2], bb[3]);
|
||||
|
||||
{
|
||||
const auto element = hex::s_highlights->find(id);
|
||||
if (element != hex::s_highlights->end()) {
|
||||
hex::s_highlightDisplays->emplace_back(boundingBox, element->second);
|
||||
|
||||
const auto window = ImGui::GetCurrentWindow();
|
||||
if (window != nullptr && window->DockNode != nullptr && window->DockNode->TabBar != nullptr)
|
||||
window->DockNode->TabBar->NextSelectedTabId = window->TabId;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
const auto element = s_interactiveHelpItems->find(id);
|
||||
if (element != s_interactiveHelpItems->end()) {
|
||||
(*s_interactiveHelpDisplays)[id] = boundingBox;
|
||||
}
|
||||
const auto element = hex::s_highlights->find(id);
|
||||
if (element != hex::s_highlights->end()) {
|
||||
hex::s_highlightDisplays->emplace_back(boundingBox, element->second);
|
||||
|
||||
const auto window = ImGui::GetCurrentWindow();
|
||||
if (window != nullptr && window->DockNode != nullptr && window->DockNode->TabBar != nullptr)
|
||||
window->DockNode->TabBar->NextSelectedTabId = window->TabId;
|
||||
}
|
||||
|
||||
if (id != 0 && boundingBox.Contains(ImGui::GetMousePos())) {
|
||||
@@ -143,10 +128,10 @@ namespace hex {
|
||||
});
|
||||
}
|
||||
|
||||
void TutorialManager::addInteractiveHelpText(std::initializer_list<std::variant<Lang, std::string, int>> &&ids, UnlocalizedString unlocalizedString) {
|
||||
void TutorialManager::addInteractiveHelpText(std::initializer_list<std::variant<Lang, std::string, int>> &&ids, UnlocalizedString text) {
|
||||
auto id = calculateId(ids);
|
||||
|
||||
s_interactiveHelpItems->emplace(id, [text = std::move(unlocalizedString)]{
|
||||
s_interactiveHelpItems->emplace(id, [text = std::move(text)]{
|
||||
log::info("{}", Lang(text).get());
|
||||
});
|
||||
}
|
||||
@@ -159,39 +144,6 @@ namespace hex {
|
||||
});
|
||||
}
|
||||
|
||||
void TutorialManager::setLastItemInteractiveHelpPopup(std::function<void()> callback) {
|
||||
auto id = ImGui::GetItemID();
|
||||
|
||||
if (!s_interactiveHelpItems->contains(id)) {
|
||||
s_interactiveHelpItems->emplace(id, [id]{
|
||||
s_activeHelpId = id;
|
||||
});
|
||||
}
|
||||
|
||||
if (id == s_activeHelpId) {
|
||||
ImGui::SetNextWindowSize(scaled({ 400, 0 }));
|
||||
if (ImGui::BeginTooltip()) {
|
||||
callback();
|
||||
ImGui::EndTooltip();
|
||||
}
|
||||
|
||||
if (ImGui::IsMouseClicked(ImGuiMouseButton_Left) || ImGui::IsKeyPressed(ImGuiKey_Escape))
|
||||
s_activeHelpId = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void TutorialManager::setLastItemInteractiveHelpLink(std::string link) {
|
||||
auto id = ImGui::GetItemID();
|
||||
|
||||
if (s_interactiveHelpItems->contains(id))
|
||||
return;
|
||||
|
||||
s_interactiveHelpItems->emplace(id, [link = std::move(link)]{
|
||||
hex::openWebpage(link);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
void TutorialManager::startTutorial(const UnlocalizedString &unlocalizedName) {
|
||||
s_currentTutorial = s_tutorials->find(unlocalizedName);
|
||||
if (s_currentTutorial == s_tutorials->end())
|
||||
@@ -205,19 +157,6 @@ namespace hex {
|
||||
const auto &drawList = ImGui::GetForegroundDrawList();
|
||||
drawList->AddText(ImGui::GetMousePos() + scaled({ 10, -5, }), ImGui::GetColorU32(ImGuiCol_Text), "?");
|
||||
|
||||
for (const auto &[id, boundingBox] : *s_interactiveHelpDisplays) {
|
||||
drawList->AddRect(
|
||||
boundingBox.Min - ImVec2(5, 5),
|
||||
boundingBox.Max + ImVec2(5, 5),
|
||||
ImGui::GetColorU32(ImGuiCol_PlotHistogram),
|
||||
5.0F,
|
||||
ImDrawFlags_None,
|
||||
2.0F
|
||||
);
|
||||
}
|
||||
|
||||
s_interactiveHelpDisplays->clear();
|
||||
|
||||
const bool mouseClicked = ImGui::IsMouseClicked(ImGuiMouseButton_Left);
|
||||
if (s_hoveredId != 0) {
|
||||
drawList->AddRectFilled(s_hoveredRect.Min, s_hoveredRect.Max, 0x30FFFFFF);
|
||||
@@ -236,11 +175,6 @@ namespace hex {
|
||||
if (mouseClicked || ImGui::IsKeyPressed(ImGuiKey_Escape)) {
|
||||
s_helpHoverActive = false;
|
||||
}
|
||||
|
||||
// Discard mouse click so it doesn't activate clicked item
|
||||
ImGui::GetIO().MouseDown[ImGuiMouseButton_Left] = false;
|
||||
ImGui::GetIO().MouseReleased[ImGuiMouseButton_Left] = false;
|
||||
ImGui::GetIO().MouseClicked[ImGuiMouseButton_Left] = false;
|
||||
}
|
||||
|
||||
for (const auto &[rect, unlocalizedText] : *s_highlightDisplays) {
|
||||
|
||||
@@ -12,13 +12,4 @@ namespace hex::dbg {
|
||||
|
||||
}
|
||||
|
||||
static bool s_debugMode = false;
|
||||
bool debugModeEnabled() {
|
||||
return s_debugMode;
|
||||
}
|
||||
|
||||
void setDebugModeEnabled(bool enabled) {
|
||||
s_debugMode = enabled;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
#include <hex/api/events/events_gui.hpp>
|
||||
#include <hex/api/event_manager.hpp>
|
||||
|
||||
#include <imgui.h>
|
||||
#include <imgui_internal.h>
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include <hex/helpers/logger.hpp>
|
||||
|
||||
#include <hex/api/task_manager.hpp>
|
||||
#include <hex/api/event_manager.hpp>
|
||||
|
||||
#include <hex/helpers/fs.hpp>
|
||||
#include <hex/helpers/fmt.hpp>
|
||||
|
||||
@@ -81,9 +81,6 @@ namespace hex::gl {
|
||||
std::vector<char> log(512);
|
||||
glGetShaderInfoLog(m_program, log.size(), nullptr, log.data());
|
||||
log::error("Failed to link shader: {}", log.data());
|
||||
|
||||
glDeleteProgram(m_program);
|
||||
m_program = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -81,7 +81,7 @@ namespace hex {
|
||||
return "";
|
||||
}
|
||||
|
||||
[[nodiscard]] UnlocalizedString getTypeName() const override { return ""; }
|
||||
[[nodiscard]] std::string getTypeName() const override { return ""; }
|
||||
|
||||
const std::map<u64, u8>& getPatches() const {
|
||||
return m_patches;
|
||||
|
||||
@@ -8,9 +8,6 @@
|
||||
#include <hex/providers/buffered_reader.hpp>
|
||||
|
||||
#include <imgui.h>
|
||||
#include <imgui_internal.h>
|
||||
|
||||
#include <GLFW/glfw3.h>
|
||||
|
||||
#if defined(OS_WINDOWS)
|
||||
#include <windows.h>
|
||||
@@ -688,7 +685,7 @@ namespace hex {
|
||||
return string;
|
||||
|
||||
// If the string is longer than the max length, find the last space before the max length
|
||||
auto it = string.begin() + maxLength / 2;
|
||||
auto it = string.begin() + maxLength;
|
||||
while (it != string.begin() && !std::isspace(*it)) --it;
|
||||
|
||||
// If there's no space before the max length, just cut the string
|
||||
@@ -847,22 +844,4 @@ namespace hex {
|
||||
#endif
|
||||
}
|
||||
|
||||
std::optional<ImColor> blendColors(const std::optional<ImColor> &a, const std::optional<ImColor> &b) {
|
||||
if (!a.has_value() && !b.has_value())
|
||||
return std::nullopt;
|
||||
else if (a.has_value() && !b.has_value())
|
||||
return a;
|
||||
else if (!a.has_value() && b.has_value())
|
||||
return b;
|
||||
else
|
||||
return ImAlphaBlendColors(a.value(), b.value());
|
||||
}
|
||||
|
||||
extern "C" void macOSCloseButtonPressed() {
|
||||
auto windowHandle = ImHexApi::System::getMainWindowHandle();
|
||||
|
||||
glfwHideWindow(windowHandle);
|
||||
glfwIconifyWindow(windowHandle);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -18,8 +18,6 @@
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#include <hex/helpers/keys.hpp>
|
||||
|
||||
void errorMessageMacos(const char *cMessage) {
|
||||
CFStringRef strMessage = CFStringCreateWithCString(NULL, cMessage, kCFStringEncodingUTF8);
|
||||
CFUserNotificationDisplayAlert(0, kCFUserNotificationStopAlertLevel, NULL, NULL, NULL, strMessage, NULL, NULL, NULL, NULL, NULL);
|
||||
@@ -48,33 +46,6 @@
|
||||
return [[NSScreen mainScreen] backingScaleFactor];
|
||||
}
|
||||
|
||||
void macOSCloseButtonPressed(void);
|
||||
|
||||
@interface CloseButtonHandler : NSObject
|
||||
@end
|
||||
|
||||
@implementation CloseButtonHandler
|
||||
- (void)pressed:(id)sender {
|
||||
macOSCloseButtonPressed();
|
||||
}
|
||||
@end
|
||||
|
||||
@interface ImHexAppDelegate : NSObject<NSApplicationDelegate>
|
||||
@end
|
||||
|
||||
@implementation ImHexAppDelegate
|
||||
- (void) application:(NSApplication*)sender openFiles:(NSArray*)filenames
|
||||
{
|
||||
NSLog(@"A");
|
||||
|
||||
[NSApp replyToOpenOrPrint:NSApplicationDelegateReplySuccess];
|
||||
}
|
||||
|
||||
- (IBAction) clickAction:(id)sender {
|
||||
NSLog(@"B");
|
||||
}
|
||||
@end
|
||||
|
||||
void setupMacosWindowStyle(GLFWwindow *window, bool borderlessWindowMode) {
|
||||
NSWindow* cocoaWindow = glfwGetCocoaWindow(window);
|
||||
|
||||
@@ -88,13 +59,6 @@
|
||||
[cocoaWindow setHasShadow:YES];
|
||||
[cocoaWindow setBackgroundColor:[NSColor colorWithWhite: 0 alpha: 0.001f]];
|
||||
}
|
||||
|
||||
NSButton *closeButton = [cocoaWindow standardWindowButton:NSWindowCloseButton];
|
||||
[closeButton setAction:@selector(pressed:)];
|
||||
[closeButton setTarget:[CloseButtonHandler alloc]];
|
||||
|
||||
NSApplication *app = [NSApplication sharedApplication];
|
||||
[app setDelegate:[ImHexAppDelegate alloc]];
|
||||
}
|
||||
|
||||
bool isMacosFullScreenModeEnabled(GLFWwindow *window) {
|
||||
@@ -148,12 +112,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
void macosSetWindowMovable(GLFWwindow *window, bool movable) {
|
||||
NSWindow* cocoaWindow = glfwGetCocoaWindow(window);
|
||||
|
||||
[cocoaWindow setMovable:movable];
|
||||
}
|
||||
|
||||
bool macosIsWindowBeingResizedByUser(GLFWwindow *window) {
|
||||
NSWindow* cocoaWindow = glfwGetCocoaWindow(window);
|
||||
|
||||
@@ -187,123 +145,4 @@
|
||||
|
||||
@end
|
||||
|
||||
void macosGetKey(enum Keys key, int *output) {
|
||||
*output = 0x00;
|
||||
switch (key) {
|
||||
case Space: *output = ' '; break;
|
||||
case Apostrophe: *output = '\''; break;
|
||||
case Comma: *output = ','; break;
|
||||
case Minus: *output = '-'; break;
|
||||
case Period: *output = '.'; break;
|
||||
case Slash: *output = '/'; break;
|
||||
case Num0: *output = '0'; break;
|
||||
case Num1: *output = '1'; break;
|
||||
case Num2: *output = '2'; break;
|
||||
case Num3: *output = '3'; break;
|
||||
case Num4: *output = '4'; break;
|
||||
case Num5: *output = '5'; break;
|
||||
case Num6: *output = '6'; break;
|
||||
case Num7: *output = '7'; break;
|
||||
case Num8: *output = '8'; break;
|
||||
case Num9: *output = '9'; break;
|
||||
case Semicolon: *output = ';'; break;
|
||||
case Equals: *output = '='; break;
|
||||
case A: *output = 'a'; break;
|
||||
case B: *output = 'b'; break;
|
||||
case C: *output = 'c'; break;
|
||||
case D: *output = 'd'; break;
|
||||
case E: *output = 'e'; break;
|
||||
case F: *output = 'f'; break;
|
||||
case G: *output = 'g'; break;
|
||||
case H: *output = 'h'; break;
|
||||
case I: *output = 'i'; break;
|
||||
case J: *output = 'j'; break;
|
||||
case K: *output = 'k'; break;
|
||||
case L: *output = 'l'; break;
|
||||
case M: *output = 'm'; break;
|
||||
case N: *output = 'n'; break;
|
||||
case O: *output = 'o'; break;
|
||||
case P: *output = 'p'; break;
|
||||
case Q: *output = 'q'; break;
|
||||
case R: *output = 'r'; break;
|
||||
case S: *output = 's'; break;
|
||||
case T: *output = 't'; break;
|
||||
case U: *output = 'u'; break;
|
||||
case V: *output = 'v'; break;
|
||||
case W: *output = 'w'; break;
|
||||
case X: *output = 'x'; break;
|
||||
case Y: *output = 'y'; break;
|
||||
case Z: *output = 'z'; break;
|
||||
case LeftBracket: *output = '/'; break;
|
||||
case Backslash: *output = '\\'; break;
|
||||
case RightBracket: *output = ']'; break;
|
||||
case GraveAccent: *output = '`'; break;
|
||||
case World1: break;
|
||||
case World2: break;
|
||||
case Escape: break;
|
||||
case Enter: *output = NSEnterCharacter; break;
|
||||
case Tab: *output = NSTabCharacter; break;
|
||||
case Backspace: *output = NSBackspaceCharacter; break;
|
||||
case Insert: *output = NSInsertFunctionKey; break;
|
||||
case Delete: *output = NSDeleteCharacter; break;
|
||||
case Right: *output = NSRightArrowFunctionKey; break;
|
||||
case Left: *output = NSLeftArrowFunctionKey; break;
|
||||
case Down: *output = NSDownArrowFunctionKey; break;
|
||||
case Up: *output = NSUpArrowFunctionKey; break;
|
||||
case PageUp: *output = NSPageUpFunctionKey; break;
|
||||
case PageDown: *output = NSPageDownFunctionKey; break;
|
||||
case Home: *output = NSHomeFunctionKey; break;
|
||||
case End: *output = NSEndFunctionKey; break;
|
||||
case CapsLock: break;
|
||||
case ScrollLock: *output = NSScrollLockFunctionKey; break;
|
||||
case NumLock: break;
|
||||
case PrintScreen: *output = NSPrintScreenFunctionKey; break;
|
||||
case Pause: *output = NSPauseFunctionKey; break;
|
||||
case F1: *output = NSF1FunctionKey; break;
|
||||
case F2: *output = NSF2FunctionKey; break;
|
||||
case F3: *output = NSF3FunctionKey; break;
|
||||
case F4: *output = NSF4FunctionKey; break;
|
||||
case F5: *output = NSF5FunctionKey; break;
|
||||
case F6: *output = NSF6FunctionKey; break;
|
||||
case F7: *output = NSF7FunctionKey; break;
|
||||
case F8: *output = NSF8FunctionKey; break;
|
||||
case F9: *output = NSF9FunctionKey; break;
|
||||
case F10: *output = NSF10FunctionKey; break;
|
||||
case F11: *output = NSF11FunctionKey; break;
|
||||
case F12: *output = NSF12FunctionKey; break;
|
||||
case F13: *output = NSF13FunctionKey; break;
|
||||
case F14: *output = NSF14FunctionKey; break;
|
||||
case F15: *output = NSF15FunctionKey; break;
|
||||
case F16: *output = NSF16FunctionKey; break;
|
||||
case F17: *output = NSF17FunctionKey; break;
|
||||
case F18: *output = NSF18FunctionKey; break;
|
||||
case F19: *output = NSF19FunctionKey; break;
|
||||
case F20: *output = NSF20FunctionKey; break;
|
||||
case F21: *output = NSF21FunctionKey; break;
|
||||
case F22: *output = NSF22FunctionKey; break;
|
||||
case F23: *output = NSF23FunctionKey; break;
|
||||
case F24: *output = NSF24FunctionKey; break;
|
||||
case F25: *output = NSF25FunctionKey; break;
|
||||
case KeyPad0: *output = '0'; break;
|
||||
case KeyPad1: *output = '1'; break;
|
||||
case KeyPad2: *output = '2'; break;
|
||||
case KeyPad3: *output = '3'; break;
|
||||
case KeyPad4: *output = '4'; break;
|
||||
case KeyPad5: *output = '5'; break;
|
||||
case KeyPad6: *output = '6'; break;
|
||||
case KeyPad7: *output = '7'; break;
|
||||
case KeyPad8: *output = '8'; break;
|
||||
case KeyPad9: *output = '9'; break;
|
||||
case KeyPadDecimal: *output = '.'; break;
|
||||
case KeyPadDivide: *output = '/'; break;
|
||||
case KeyPadMultiply: *output = '*'; break;
|
||||
case KeyPadSubtract: *output = '-'; break;
|
||||
case KeyPadAdd: *output = '+'; break;
|
||||
case KeyPadEnter: *output = NSEnterCharacter; break;
|
||||
case KeyPadEqual: *output = '='; break;
|
||||
case Menu: *output = NSMenuFunctionKey; break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#include <hex/providers/provider.hpp>
|
||||
|
||||
#include <hex.hpp>
|
||||
#include <hex/api/events/events_provider.hpp>
|
||||
#include <hex/api/event_manager.hpp>
|
||||
|
||||
#include <cmath>
|
||||
#include <cstring>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
#include "hex/subcommands/subcommands.hpp"
|
||||
|
||||
#include <hex/api/events/requests_lifecycle.hpp>
|
||||
#include <hex/api/event_manager.hpp>
|
||||
#include <hex/api/plugin_manager.hpp>
|
||||
#include <hex/api/imhex_api.hpp>
|
||||
#include <hex/helpers/logger.hpp>
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
#include <hex/ui/banner.hpp>
|
||||
#include <hex/helpers/auto_reset.hpp>
|
||||
|
||||
namespace hex::impl {
|
||||
|
||||
[[nodiscard]] std::list<std::unique_ptr<BannerBase>> &BannerBase::getOpenBanners() {
|
||||
static AutoReset<std::list<std::unique_ptr<BannerBase>>> openBanners;
|
||||
|
||||
return openBanners;
|
||||
}
|
||||
|
||||
std::mutex& BannerBase::getMutex() {
|
||||
static std::mutex mutex;
|
||||
|
||||
return mutex;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -23,7 +23,6 @@
|
||||
#include <hex/api/task_manager.hpp>
|
||||
#include <hex/api/theme_manager.hpp>
|
||||
#include <hex/helpers/logger.hpp>
|
||||
#include <hex/helpers/utils_macos.hpp>
|
||||
|
||||
|
||||
namespace ImGuiExt {
|
||||
@@ -223,16 +222,14 @@ namespace ImGuiExt {
|
||||
}
|
||||
|
||||
Texture Texture::fromSVG(const char *path, int width, int height, Filter filter) {
|
||||
const auto scaleFactor = hex::ImHexApi::System::getBackingScaleFactor();
|
||||
|
||||
auto document = lunasvg::Document::loadFromFile(path);
|
||||
auto bitmap = document->renderToBitmap(width * scaleFactor, height * scaleFactor);
|
||||
auto bitmap = document->renderToBitmap(width, height);
|
||||
|
||||
auto texture = createMultisampleTextureFromRGBA8Array(bitmap.data(), bitmap.width(), bitmap.height(), filter);
|
||||
|
||||
Texture result;
|
||||
result.m_width = bitmap.width() / scaleFactor;
|
||||
result.m_height = bitmap.height() / scaleFactor;
|
||||
result.m_width = bitmap.width();
|
||||
result.m_height = bitmap.height();
|
||||
result.m_textureId = texture;
|
||||
|
||||
return result;
|
||||
@@ -243,17 +240,15 @@ namespace ImGuiExt {
|
||||
}
|
||||
|
||||
Texture Texture::fromSVG(std::span<const std::byte> buffer, int width, int height, Filter filter) {
|
||||
const auto scaleFactor = hex::ImHexApi::System::getBackingScaleFactor();
|
||||
|
||||
auto document = lunasvg::Document::loadFromData(reinterpret_cast<const char*>(buffer.data()), buffer.size());
|
||||
auto bitmap = document->renderToBitmap(width * scaleFactor, height * scaleFactor);
|
||||
auto bitmap = document->renderToBitmap(width, height);
|
||||
bitmap.convertToRGBA();
|
||||
|
||||
auto texture = createMultisampleTextureFromRGBA8Array(bitmap.data(), bitmap.width(), bitmap.height(), filter);
|
||||
|
||||
Texture result;
|
||||
result.m_width = bitmap.width() / scaleFactor;
|
||||
result.m_height = bitmap.height() / scaleFactor;
|
||||
result.m_width = bitmap.width();
|
||||
result.m_height = bitmap.height();
|
||||
result.m_textureId = texture;
|
||||
|
||||
return result;
|
||||
@@ -824,7 +819,7 @@ namespace ImGuiExt {
|
||||
return pressed;
|
||||
}
|
||||
|
||||
bool IconButton(const char *symbol, ImVec4 color, ImVec2 size_arg, ImVec2 iconOffset) {
|
||||
bool IconButton(const char *symbol, ImVec4 color, ImVec2 size_arg) {
|
||||
ImGuiWindow *window = GetCurrentWindow();
|
||||
if (window->SkipItems)
|
||||
return false;
|
||||
@@ -855,7 +850,7 @@ namespace ImGuiExt {
|
||||
: ImGuiCol_Button);
|
||||
RenderNavCursor(bb, id);
|
||||
RenderFrame(bb.Min, bb.Max, col, true, style.FrameRounding);
|
||||
RenderTextClipped(bb.Min + style.FramePadding * ImVec2(1.3, 1) + iconOffset, bb.Max - style.FramePadding, symbol, nullptr, &label_size, style.ButtonTextAlign, &bb);
|
||||
RenderTextClipped(bb.Min + style.FramePadding * ImVec2(1.3, 1), bb.Max - style.FramePadding, symbol, nullptr, &label_size, style.ButtonTextAlign, &bb);
|
||||
|
||||
PopStyleColor();
|
||||
|
||||
@@ -913,9 +908,8 @@ namespace ImGuiExt {
|
||||
return InputIntegerPrefix(label, "0x", value, ImGuiDataType_U64, "%llX", flags | ImGuiInputTextFlags_CharsHexadecimal);
|
||||
}
|
||||
|
||||
bool SliderBytes(const char *label, u64 *value, u64 min, u64 max, u64 stepSize, ImGuiSliderFlags flags) {
|
||||
bool SliderBytes(const char *label, u64 *value, u64 min, u64 max, ImGuiSliderFlags flags) {
|
||||
std::string format;
|
||||
|
||||
if (*value < 1024) {
|
||||
format = hex::format("{} Bytes", *value);
|
||||
} else if (*value < 1024 * 1024) {
|
||||
@@ -926,15 +920,7 @@ namespace ImGuiExt {
|
||||
format = hex::format("{:.2f} GB", *value / (1024.0 * 1024.0 * 1024.0));
|
||||
}
|
||||
|
||||
*value /= stepSize;
|
||||
min /= stepSize;
|
||||
max /= stepSize;
|
||||
|
||||
auto result = ImGui::SliderScalar(label, ImGuiDataType_U64, value, &min, &max, format.c_str(), flags | ImGuiSliderFlags_Logarithmic);
|
||||
|
||||
*value *= stepSize;
|
||||
|
||||
return result;
|
||||
return ImGui::SliderScalar(label, ImGuiDataType_U64, value, &min, &max, format.c_str(), flags | ImGuiSliderFlags_Logarithmic);
|
||||
}
|
||||
|
||||
void SmallProgressBar(float fraction, float yOffset) {
|
||||
@@ -1110,14 +1096,14 @@ namespace ImGuiExt {
|
||||
return res;
|
||||
}
|
||||
|
||||
bool DimmedIconButton(const char *symbol, ImVec4 color, ImVec2 size, ImVec2 iconOffset) {
|
||||
bool DimmedIconButton(const char *symbol, ImVec4 color, ImVec2 size){
|
||||
PushStyleColor(ImGuiCol_ButtonHovered, GetCustomColorU32(ImGuiCustomCol_DescButtonHovered));
|
||||
PushStyleColor(ImGuiCol_Button, GetCustomColorU32(ImGuiCustomCol_DescButton));
|
||||
PushStyleColor(ImGuiCol_Text, GetColorU32(ImGuiCol_ButtonActive));
|
||||
PushStyleColor(ImGuiCol_ButtonActive, GetCustomColorU32(ImGuiCustomCol_DescButtonActive));
|
||||
PushStyleVar(ImGuiStyleVar_FrameBorderSize, 1);
|
||||
|
||||
bool res = IconButton(symbol, color, size, iconOffset);
|
||||
bool res = IconButton(symbol, color, size);
|
||||
|
||||
PopStyleColor(4);
|
||||
PopStyleVar(1);
|
||||
@@ -1125,7 +1111,7 @@ namespace ImGuiExt {
|
||||
return res;
|
||||
}
|
||||
|
||||
bool DimmedButtonToggle(const char *icon, bool *v, ImVec2 size, ImVec2 iconOffset) {
|
||||
bool DimmedButtonToggle(const char *icon, bool *v, ImVec2 size) {
|
||||
bool pushed = false;
|
||||
bool toggled = false;
|
||||
|
||||
@@ -1134,7 +1120,7 @@ namespace ImGuiExt {
|
||||
pushed = true;
|
||||
}
|
||||
|
||||
if (DimmedIconButton(icon, GetStyleColorVec4(ImGuiCol_Text), size, iconOffset)) {
|
||||
if (DimmedIconButton(icon, GetStyleColorVec4(ImGuiCol_Text), size)) {
|
||||
*v = !*v;
|
||||
toggled = true;
|
||||
}
|
||||
|
||||
2
lib/third_party/edlib
vendored
2
lib/third_party/edlib
vendored
Submodule lib/third_party/edlib updated: 42aa8fa705...931be2b090
2
lib/third_party/fmt
vendored
2
lib/third_party/fmt
vendored
Submodule lib/third_party/fmt updated: 8303d140a1...0e8aad961d
4
lib/third_party/imgui/CMakeLists.txt
vendored
4
lib/third_party/imgui/CMakeLists.txt
vendored
@@ -10,7 +10,7 @@ add_subdirectory(cimgui)
|
||||
add_subdirectory(implot)
|
||||
add_subdirectory(implot3d)
|
||||
add_subdirectory(imnodes)
|
||||
add_subdirectory(backend)
|
||||
add_subdirectory(custom)
|
||||
add_subdirectory(ColorTextEditor)
|
||||
|
||||
set(IMGUI_LIBRARIES imgui_imgui imgui_cimgui imgui_implot imgui_implot3d imgui_imnodes imgui_backend imgui_color_text_editor PARENT_SCOPE)
|
||||
set(IMGUI_LIBRARIES imgui_imgui imgui_cimgui imgui_implot imgui_implot3d imgui_imnodes imgui_custom imgui_color_text_editor PARENT_SCOPE)
|
||||
@@ -629,6 +629,7 @@ private:
|
||||
uint64_t mStartTime = 0;
|
||||
std::vector<std::string> mDefines;
|
||||
TextEditor *mSourceCodeEditor = nullptr;
|
||||
float mSavedScrollY = 0;
|
||||
float mShiftedScrollY = 0;
|
||||
float mScrollY = 0;
|
||||
float mScrollYIncrement = 0.0F;
|
||||
|
||||
@@ -1179,6 +1179,8 @@ void TextEditor::RenderText(const char *aTitle, const ImVec2 &lineNumbersStartPo
|
||||
|
||||
if (mTopMarginChanged) {
|
||||
mTopMarginChanged = false;
|
||||
if (mTopMargin == 0)
|
||||
mSavedScrollY = ImGui::GetScrollY();
|
||||
auto window = ImGui::GetCurrentWindow();
|
||||
auto maxScroll = window->ScrollMax.y;
|
||||
if (maxScroll > 0) {
|
||||
@@ -1194,8 +1196,10 @@ void TextEditor::RenderText(const char *aTitle, const ImVec2 &lineNumbersStartPo
|
||||
|
||||
if (mNewTopMargin > mTopMargin)
|
||||
mShiftedScrollY = oldScrollY + pixelCount;
|
||||
else
|
||||
else if (mNewTopMargin > 0)
|
||||
mShiftedScrollY = oldScrollY - pixelCount;
|
||||
else
|
||||
mShiftedScrollY = mSavedScrollY;
|
||||
ImGui::SetScrollY(mShiftedScrollY);
|
||||
mTopMargin = mNewTopMargin;
|
||||
}
|
||||
@@ -2518,6 +2522,7 @@ bool TextEditor::FindReplaceHandler::Replace(TextEditor *editor, bool next) {
|
||||
u.mAfter = editor->mState;
|
||||
editor->AddUndo(u);
|
||||
editor->mTextChanged = true;
|
||||
mMatches.erase(mMatches.begin() + matchIndex - 1);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
# https://github.com/ocornut/imgui backends with custom modifications made to the OpenGL 3 and GLFW backends
|
||||
project(imgui_backend)
|
||||
# https://github.com/ocornut/imgui with custom modifications made to the OpenGL 3 and GLFW backends
|
||||
project(imgui_custom)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
|
||||
if (NOT IMHEX_EXTERNAL_PLUGIN_BUILD)
|
||||
add_library(imgui_backend OBJECT
|
||||
add_library(imgui_custom OBJECT
|
||||
source/imgui_impl_opengl3.cpp
|
||||
source/imgui_impl_glfw.cpp
|
||||
)
|
||||
|
||||
target_include_directories(imgui_backend PUBLIC
|
||||
target_include_directories(imgui_custom PUBLIC
|
||||
include
|
||||
)
|
||||
|
||||
target_link_libraries(imgui_backend PRIVATE imgui_includes)
|
||||
target_link_libraries(imgui_custom PRIVATE imgui_includes)
|
||||
|
||||
find_package(OpenGL REQUIRED)
|
||||
find_package(Freetype REQUIRED)
|
||||
@@ -35,9 +35,9 @@ if (NOT IMHEX_EXTERNAL_PLUGIN_BUILD)
|
||||
set(GLFW_LIBRARIES "glfw3")
|
||||
endif ()
|
||||
|
||||
target_include_directories(imgui_backend PUBLIC ${FREETYPE_INCLUDE_DIRS} ${OpenGL_INCLUDE_DIRS})
|
||||
target_link_directories(imgui_backend PUBLIC ${FREETYPE_LIBRARY_DIRS} ${OpenGL_LIBRARY_DIRS})
|
||||
target_link_libraries(imgui_backend PUBLIC ${GLFW_LIBRARIES} ${OPENGL_LIBRARIES})
|
||||
target_include_directories(imgui_custom PUBLIC ${FREETYPE_INCLUDE_DIRS} ${OpenGL_INCLUDE_DIRS})
|
||||
target_link_directories(imgui_custom PUBLIC ${FREETYPE_LIBRARY_DIRS} ${OpenGL_LIBRARY_DIRS})
|
||||
target_link_libraries(imgui_custom PUBLIC ${GLFW_LIBRARIES} ${OPENGL_LIBRARIES})
|
||||
endif()
|
||||
|
||||
target_include_directories(imgui_all_includes INTERFACE include)
|
||||
@@ -122,11 +122,6 @@
|
||||
#include <unistd.h> // for usleep()
|
||||
#endif
|
||||
|
||||
#ifdef __linux__
|
||||
#include <string_view>
|
||||
#include <cstdlib>
|
||||
#endif
|
||||
|
||||
#ifdef __EMSCRIPTEN__
|
||||
#include <emscripten.h>
|
||||
#include <emscripten/html5.h>
|
||||
@@ -385,33 +380,17 @@ ImGuiKey ImGui_ImplGlfw_KeyToImGuiKey(int keycode, int scancode)
|
||||
|
||||
// X11 does not include current pressed/released modifier key in 'mods' flags submitted by GLFW
|
||||
// See https://github.com/ocornut/imgui/issues/6034 and https://github.com/glfw/glfw/issues/1630
|
||||
static void ImGui_ImplGlfw_UpdateKeyModifiers(GLFWwindow* window, int mods)
|
||||
static void ImGui_ImplGlfw_UpdateKeyModifiers(int mods)
|
||||
{
|
||||
// IMHEX PATCH BEGIN
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
|
||||
#ifdef __linux__
|
||||
static bool isX11 = [] {
|
||||
const auto sessionType = std::getenv("XDG_SESSION_TYPE");
|
||||
if (sessionType == nullptr)
|
||||
return false;
|
||||
|
||||
return std::string_view(sessionType) == "x11";
|
||||
}();
|
||||
|
||||
if (isX11) {
|
||||
io.AddKeyEvent(ImGuiMod_Ctrl, (glfwGetKey(window, GLFW_KEY_LEFT_CONTROL) == GLFW_PRESS) || (glfwGetKey(window, GLFW_KEY_RIGHT_CONTROL) == GLFW_PRESS));
|
||||
io.AddKeyEvent(ImGuiMod_Shift, (glfwGetKey(window, GLFW_KEY_LEFT_SHIFT) == GLFW_PRESS) || (glfwGetKey(window, GLFW_KEY_RIGHT_SHIFT) == GLFW_PRESS));
|
||||
io.AddKeyEvent(ImGuiMod_Alt, (glfwGetKey(window, GLFW_KEY_LEFT_ALT) == GLFW_PRESS) || (glfwGetKey(window, GLFW_KEY_RIGHT_ALT) == GLFW_PRESS));
|
||||
io.AddKeyEvent(ImGuiMod_Super, (glfwGetKey(window, GLFW_KEY_LEFT_SUPER) == GLFW_PRESS) || (glfwGetKey(window, GLFW_KEY_RIGHT_SUPER) == GLFW_PRESS));
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
io.AddKeyEvent(ImGuiMod_Ctrl, (mods & GLFW_MOD_CONTROL) != 0);
|
||||
io.AddKeyEvent(ImGuiMod_Shift, (mods & GLFW_MOD_SHIFT) != 0);
|
||||
io.AddKeyEvent(ImGuiMod_Alt, (mods & GLFW_MOD_ALT) != 0);
|
||||
io.AddKeyEvent(ImGuiMod_Super, (mods & GLFW_MOD_SUPER) != 0);
|
||||
}
|
||||
// IMHEX PATCH BEGIN
|
||||
// The original version of this caused the CTRL key to sometimes get stuck when pressing ALT GR, SHIFT and Enter
|
||||
// together in some ways
|
||||
io.AddKeyEvent(ImGuiMod_Ctrl, (mods & GLFW_MOD_CONTROL) != 0);
|
||||
io.AddKeyEvent(ImGuiMod_Shift, (mods & GLFW_MOD_SHIFT) != 0);
|
||||
io.AddKeyEvent(ImGuiMod_Alt, (mods & GLFW_MOD_ALT) != 0);
|
||||
io.AddKeyEvent(ImGuiMod_Super, (mods & GLFW_MOD_SUPER) != 0);
|
||||
// IMHEX PATCH END
|
||||
}
|
||||
|
||||
@@ -431,7 +410,7 @@ void ImGui_ImplGlfw_MouseButtonCallback(GLFWwindow* window, int button, int acti
|
||||
if (bd->MouseIgnoreButtonUp && action == GLFW_RELEASE)
|
||||
return;
|
||||
|
||||
ImGui_ImplGlfw_UpdateKeyModifiers(window, mods);
|
||||
ImGui_ImplGlfw_UpdateKeyModifiers(mods);
|
||||
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
if (button >= 0 && button < ImGuiMouseButton_COUNT)
|
||||
@@ -496,7 +475,7 @@ void ImGui_ImplGlfw_KeyCallback(GLFWwindow* window, int keycode, int scancode, i
|
||||
if (action != GLFW_PRESS && action != GLFW_RELEASE)
|
||||
return;
|
||||
|
||||
ImGui_ImplGlfw_UpdateKeyModifiers(window, mods);
|
||||
ImGui_ImplGlfw_UpdateKeyModifiers(mods);
|
||||
|
||||
if (keycode >= 0 && keycode < IM_ARRAYSIZE(bd->KeyOwnerWindows))
|
||||
bd->KeyOwnerWindows[keycode] = (action == GLFW_PRESS) ? window : nullptr;
|
||||
29
lib/third_party/imgui/imgui/include/imgui.h
vendored
29
lib/third_party/imgui/imgui/include/imgui.h
vendored
@@ -1,4 +1,4 @@
|
||||
// dear imgui, v1.91.7
|
||||
// dear imgui, v1.91.6
|
||||
// (headers)
|
||||
|
||||
// Help:
|
||||
@@ -28,8 +28,8 @@
|
||||
|
||||
// Library Version
|
||||
// (Integer encoded as XYYZZ for use in #if preprocessor conditionals, e.g. '#if IMGUI_VERSION_NUM >= 12345')
|
||||
#define IMGUI_VERSION "1.91.7"
|
||||
#define IMGUI_VERSION_NUM 19170
|
||||
#define IMGUI_VERSION "1.91.6"
|
||||
#define IMGUI_VERSION_NUM 19160
|
||||
#define IMGUI_HAS_TABLE
|
||||
#define IMGUI_HAS_VIEWPORT // Viewport WIP branch
|
||||
#define IMGUI_HAS_DOCK // Docking WIP branch
|
||||
@@ -141,7 +141,6 @@ Index of this file:
|
||||
#elif defined(__GNUC__)
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wpragmas" // warning: unknown option after '#pragma GCC diagnostic' kind
|
||||
#pragma GCC diagnostic ignored "-Wfloat-equal" // warning: comparing floating-point with '==' or '!=' is unsafe
|
||||
#pragma GCC diagnostic ignored "-Wclass-memaccess" // [__GNUC__ >= 8] warning: 'memset/memcpy' clearing/writing an object of type 'xxxx' with no trivial copy-assignment; use assignment or value-initialization instead
|
||||
#endif
|
||||
|
||||
@@ -701,7 +700,6 @@ namespace ImGui
|
||||
|
||||
// Widgets: List Boxes
|
||||
// - This is essentially a thin wrapper to using BeginChild/EndChild with the ImGuiChildFlags_FrameStyle flag for stylistic changes + displaying a label.
|
||||
// - If you don't need a label you can probably simply use BeginChild() with the ImGuiChildFlags_FrameStyle flag for the same result.
|
||||
// - You can submit contents and manage your selection state however you want it, by creating e.g. Selectable() or any other items.
|
||||
// - The simplified/old ListBox() api are helpers over BeginListBox()/EndListBox() which are kept available for convenience purpose. This is analoguous to how Combos are created.
|
||||
// - Choose frame width: size.x > 0.0f: custom / size.x < 0.0f or -FLT_MIN: right-align / size.x = 0.0f (default): use current ItemWidth
|
||||
@@ -1138,8 +1136,8 @@ enum ImGuiWindowFlags_
|
||||
|
||||
// Obsolete names
|
||||
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
|
||||
ImGuiWindowFlags_NavFlattened = 1 << 29, // Obsoleted in 1.90.9: Use ImGuiChildFlags_NavFlattened in BeginChild() call.
|
||||
ImGuiWindowFlags_AlwaysUseWindowPadding = 1 << 30, // Obsoleted in 1.90.0: Use ImGuiChildFlags_AlwaysUseWindowPadding in BeginChild() call.
|
||||
ImGuiWindowFlags_NavFlattened = 1 << 31, // Obsoleted in 1.90.9: Use ImGuiChildFlags_NavFlattened in BeginChild() call.
|
||||
#endif
|
||||
};
|
||||
|
||||
@@ -1221,7 +1219,7 @@ enum ImGuiInputTextFlags_
|
||||
ImGuiInputTextFlags_CallbackAlways = 1 << 20, // Callback on each iteration. User code may query cursor position, modify text buffer.
|
||||
ImGuiInputTextFlags_CallbackCharFilter = 1 << 21, // Callback on character inputs to replace or discard them. Modify 'EventChar' to replace or discard, or return 1 in callback to discard.
|
||||
ImGuiInputTextFlags_CallbackResize = 1 << 22, // Callback on buffer capacity changes request (beyond 'buf_size' parameter value), allowing the string to grow. Notify when the string wants to be resized (for string types which hold a cache of their Size). You will be provided a new BufSize in the callback and NEED to honor it. (see misc/cpp/imgui_stdlib.h for an example of using this)
|
||||
ImGuiInputTextFlags_CallbackEdit = 1 << 23, // Callback on any edit. Note that InputText() already returns true on edit + you can always use IsItemEdited(). The callback is useful to manipulate the underlying buffer while focus is active.
|
||||
ImGuiInputTextFlags_CallbackEdit = 1 << 23, // Callback on any edit (note that InputText() already returns true on edit, the callback is useful mainly to manipulate the underlying buffer while focus is active)
|
||||
|
||||
// Obsolete names
|
||||
//ImGuiInputTextFlags_AlwaysInsertMode = ImGuiInputTextFlags_AlwaysOverwrite // [renamed in 1.82] name was not matching behavior
|
||||
@@ -1244,16 +1242,14 @@ enum ImGuiTreeNodeFlags_
|
||||
ImGuiTreeNodeFlags_FramePadding = 1 << 10, // Use FramePadding (even for an unframed text node) to vertically align text baseline to regular widget height. Equivalent to calling AlignTextToFramePadding() before the node.
|
||||
ImGuiTreeNodeFlags_SpanAvailWidth = 1 << 11, // Extend hit box to the right-most edge, even if not framed. This is not the default in order to allow adding other items on the same line without using AllowOverlap mode.
|
||||
ImGuiTreeNodeFlags_SpanFullWidth = 1 << 12, // Extend hit box to the left-most and right-most edges (cover the indent area).
|
||||
ImGuiTreeNodeFlags_SpanLabelWidth = 1 << 13, // Narrow hit box + narrow hovering highlight, will only cover the label text.
|
||||
ImGuiTreeNodeFlags_SpanAllColumns = 1 << 14, // Frame will span all columns of its container table (label will still fit in current column)
|
||||
ImGuiTreeNodeFlags_LabelSpanAllColumns = 1 << 15, // Label will span all columns of its container table
|
||||
ImGuiTreeNodeFlags_SpanTextWidth = 1 << 13, // Narrow hit box + narrow hovering highlight, will only cover the label text.
|
||||
ImGuiTreeNodeFlags_SpanAllColumns = 1 << 14, // Frame will span all columns of its container table (text will still fit in current column)
|
||||
ImGuiTreeNodeFlags_NavLeftJumpsBackHere = 1 << 15, // (WIP) Nav: left direction may move to this TreeNode() from any of its child (items submitted between TreeNode and TreePop)
|
||||
//ImGuiTreeNodeFlags_NoScrollOnOpen = 1 << 16, // FIXME: TODO: Disable automatic scroll on TreePop() if node got just open and contents is not visible
|
||||
ImGuiTreeNodeFlags_NavLeftJumpsBackHere = 1 << 17, // (WIP) Nav: left direction may move to this TreeNode() from any of its child (items submitted between TreeNode and TreePop)
|
||||
ImGuiTreeNodeFlags_CollapsingHeader = ImGuiTreeNodeFlags_Framed | ImGuiTreeNodeFlags_NoTreePushOnOpen | ImGuiTreeNodeFlags_NoAutoOpenOnLog,
|
||||
|
||||
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
|
||||
ImGuiTreeNodeFlags_AllowItemOverlap = ImGuiTreeNodeFlags_AllowOverlap, // Renamed in 1.89.7
|
||||
ImGuiTreeNodeFlags_SpanTextWidth = ImGuiTreeNodeFlags_SpanLabelWidth,// Renamed in 1.90.7
|
||||
#endif
|
||||
};
|
||||
|
||||
@@ -1461,7 +1457,6 @@ enum ImGuiDataType_
|
||||
ImGuiDataType_Float, // float
|
||||
ImGuiDataType_Double, // double
|
||||
ImGuiDataType_Bool, // bool (provided for user convenience, not supported by scalar widgets)
|
||||
ImGuiDataType_String, // char* (provided for user convenience, not supported by scalar widgets)
|
||||
ImGuiDataType_COUNT
|
||||
};
|
||||
|
||||
@@ -1870,7 +1865,6 @@ enum ImGuiSliderFlags_
|
||||
ImGuiSliderFlags_WrapAround = 1 << 8, // Enable wrapping around from max to min and from min to max. Only supported by DragXXX() functions for now.
|
||||
ImGuiSliderFlags_ClampOnInput = 1 << 9, // Clamp value to min/max bounds when input manually with CTRL+Click. By default CTRL+Click allows going out of bounds.
|
||||
ImGuiSliderFlags_ClampZeroRange = 1 << 10, // Clamp even if min==max==0.0f. Otherwise due to legacy reason DragXXX functions don't clamp with those values. When your clamping limits are dynamic you almost always want to use it.
|
||||
ImGuiSliderFlags_NoSpeedTweaks = 1 << 11, // Disable keyboard modifiers altering tweak speed. Useful if you want to alter tweak speed yourself based on your own logic.
|
||||
ImGuiSliderFlags_AlwaysClamp = ImGuiSliderFlags_ClampOnInput | ImGuiSliderFlags_ClampZeroRange,
|
||||
ImGuiSliderFlags_InvalidMask_ = 0x7000000F, // [Internal] We treat using those bits as being potentially a 'float power' argument from the previous API that has got miscast to this enum, and will trigger an assert if needed.
|
||||
};
|
||||
@@ -2541,7 +2535,7 @@ struct ImGuiIO
|
||||
// Shared state of InputText(), passed as an argument to your callback when a ImGuiInputTextFlags_Callback* flag is used.
|
||||
// The callback function should return 0 by default.
|
||||
// Callbacks (follow a flag name and see comments in ImGuiInputTextFlags_ declarations for more details)
|
||||
// - ImGuiInputTextFlags_CallbackEdit: Callback on buffer edit. Note that InputText() already returns true on edit + you can always use IsItemEdited(). The callback is useful to manipulate the underlying buffer while focus is active.
|
||||
// - ImGuiInputTextFlags_CallbackEdit: Callback on buffer edit (note that InputText() already returns true on edit, the callback is useful mainly to manipulate the underlying buffer while focus is active)
|
||||
// - ImGuiInputTextFlags_CallbackAlways: Callback on each iteration
|
||||
// - ImGuiInputTextFlags_CallbackCompletion: Callback on pressing TAB
|
||||
// - ImGuiInputTextFlags_CallbackHistory: Callback on pressing Up/Down arrows
|
||||
@@ -2816,7 +2810,6 @@ struct ImGuiListClipper
|
||||
// - It is important that we are keeping those disabled by default so they don't leak in user space.
|
||||
// - This is in order to allow user enabling implicit cast operators between ImVec2/ImVec4 and their own types (using IM_VEC2_CLASS_EXTRA in imconfig.h)
|
||||
// - Add '#define IMGUI_DEFINE_MATH_OPERATORS' before including this file (or in imconfig.h) to access courtesy maths operators for ImVec2 and ImVec4.
|
||||
// - We intentionally provide ImVec2*float but not float*ImVec2: this is rare enough and we want to reduce the surface for possible user mistake.
|
||||
#ifdef IMGUI_DEFINE_MATH_OPERATORS
|
||||
#define IMGUI_DEFINE_MATH_OPERATORS_IMPLEMENTED
|
||||
IM_MSVC_RUNTIME_CHECKS_OFF
|
||||
@@ -3018,7 +3011,7 @@ struct ImGuiSelectionBasicStorage
|
||||
IMGUI_API void Clear(); // Clear selection
|
||||
IMGUI_API void Swap(ImGuiSelectionBasicStorage& r); // Swap two selections
|
||||
IMGUI_API void SetItemSelected(ImGuiID id, bool selected); // Add/remove an item from selection (generally done by ApplyRequests() function)
|
||||
IMGUI_API bool GetNextSelectedItem(void** opaque_it, ImGuiID* out_id); // Iterate selection with 'void* it = NULL; ImGuiID id; while (selection.GetNextSelectedItem(&it, &id)) { ... }'
|
||||
IMGUI_API bool GetNextSelectedItem(void** opaque_it, ImGuiID* out_id); // Iterate selection with 'void* it = NULL; ImGuiId id; while (selection.GetNextSelectedItem(&it, &id)) { ... }'
|
||||
inline ImGuiID GetStorageIdFromIndex(int idx) { return AdapterIndexToStorageId(this, idx); } // Convert index to item id based on provided adapter.
|
||||
};
|
||||
|
||||
@@ -3406,7 +3399,7 @@ struct ImFontConfig
|
||||
unsigned int FontBuilderFlags; // 0 // Settings for custom font builder. THIS IS BUILDER IMPLEMENTATION DEPENDENT. Leave as zero if unsure.
|
||||
float RasterizerMultiply; // 1.0f // Linearly brighten (>1.0f) or darken (<1.0f) font output. Brightening small fonts may be a good workaround to make them more readable. This is a silly thing we may remove in the future.
|
||||
float RasterizerDensity; // 1.0f // DPI scale for rasterization, not altering other font metrics: make it easy to swap between e.g. a 100% and a 400% fonts for a zooming display. IMPORTANT: If you increase this it is expected that you increase font scale accordingly, otherwise quality may look lowered.
|
||||
ImWchar EllipsisChar; // 0 // Explicitly specify unicode codepoint of ellipsis character. When fonts are being merged first specified ellipsis will be used.
|
||||
ImWchar EllipsisChar; // -1 // Explicitly specify unicode codepoint of ellipsis character. When fonts are being merged first specified ellipsis will be used.
|
||||
|
||||
// [Internal]
|
||||
char Name[40]; // Name (strictly to ease debugging)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// dear imgui, v1.91.7
|
||||
// dear imgui, v1.91.6
|
||||
// (internal structures/api)
|
||||
|
||||
// You may use this file to debug, understand or extend Dear ImGui features but we don't provide any guarantee of forward compatibility.
|
||||
@@ -101,7 +101,6 @@ Index of this file:
|
||||
#elif defined(__GNUC__)
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wpragmas" // warning: unknown option after '#pragma GCC diagnostic' kind
|
||||
#pragma GCC diagnostic ignored "-Wfloat-equal" // warning: comparing floating-point with '==' or '!=' is unsafe
|
||||
#pragma GCC diagnostic ignored "-Wclass-memaccess" // [__GNUC__ >= 8] warning: 'memset/memcpy' clearing/writing an object of type 'xxxx' with no trivial copy-assignment; use assignment or value-initialization instead
|
||||
#pragma GCC diagnostic ignored "-Wdeprecated-enum-enum-conversion" // warning: bitwise operation between different enumeration types ('XXXFlags_' and 'XXXFlagsPrivate_') is deprecated
|
||||
#endif
|
||||
@@ -140,7 +139,6 @@ struct ImGuiContext; // Main Dear ImGui context
|
||||
struct ImGuiContextHook; // Hook for extensions like ImGuiTestEngine
|
||||
struct ImGuiDataVarInfo; // Variable information (e.g. to access style variables from an enum)
|
||||
struct ImGuiDataTypeInfo; // Type information associated to a ImGuiDataType enum
|
||||
struct ImGuiDeactivatedItemData; // Data for IsItemDeactivated()/IsItemDeactivatedAfterEdit() function.
|
||||
struct ImGuiDockContext; // Docking system context
|
||||
struct ImGuiDockRequest; // Docking system dock/undock queued request
|
||||
struct ImGuiDockNode; // Docking system node (hold a list of Windows OR two child dock nodes)
|
||||
@@ -474,7 +472,7 @@ static inline double ImRsqrt(double x) { return 1.0 / sqrt(x); }
|
||||
template<typename T> static inline T ImMin(T lhs, T rhs) { return lhs < rhs ? lhs : rhs; }
|
||||
template<typename T> static inline T ImMax(T lhs, T rhs) { return lhs >= rhs ? lhs : rhs; }
|
||||
template<typename T> static inline T ImClamp(T v, T mn, T mx) { return (v < mn) ? mn : (v > mx) ? mx : v; }
|
||||
template<typename T> static inline T ImLerp(T a, T b, float t) { return (T)(a + (b - a) * (T)t); }
|
||||
template<typename T> static inline T ImLerp(T a, T b, float t) { return (T)(a + (b - a) * t); }
|
||||
template<typename T> static inline void ImSwap(T& a, T& b) { T tmp = a; a = b; b = tmp; }
|
||||
template<typename T> static inline T ImAddClampOverflow(T a, T b, T mn, T mx) { if (b < 0 && (a < mn - b)) return mn; if (b > 0 && (a > mx - b)) return mx; return a + b; }
|
||||
template<typename T> static inline T ImSubClampOverflow(T a, T b, T mn, T mx) { if (b > 0 && (a < mn + b)) return mn; if (b < 0 && (a > mx + b)) return mx; return a - b; }
|
||||
@@ -844,7 +842,8 @@ struct ImGuiDataTypeInfo
|
||||
// Extend ImGuiDataType_
|
||||
enum ImGuiDataTypePrivate_
|
||||
{
|
||||
ImGuiDataType_Pointer = ImGuiDataType_COUNT + 1,
|
||||
ImGuiDataType_String = ImGuiDataType_COUNT + 1,
|
||||
ImGuiDataType_Pointer,
|
||||
ImGuiDataType_ID,
|
||||
};
|
||||
|
||||
@@ -930,7 +929,7 @@ enum ImGuiButtonFlagsPrivate_
|
||||
ImGuiButtonFlags_PressedOnRelease = 1 << 7, // return true on release (default requires click+release)
|
||||
ImGuiButtonFlags_PressedOnDoubleClick = 1 << 8, // return true on double-click (default requires click+release)
|
||||
ImGuiButtonFlags_PressedOnDragDropHold = 1 << 9, // return true when held into while we are drag and dropping another item (used by e.g. tree nodes, collapsing headers)
|
||||
//ImGuiButtonFlags_Repeat = 1 << 10, // hold to repeat -> use ImGuiItemFlags_ButtonRepeat instead.
|
||||
//ImGuiButtonFlags_Repeat = 1 << 10, // hold to repeat
|
||||
ImGuiButtonFlags_FlattenChildren = 1 << 11, // allow interactions even if a child window is overlapping
|
||||
ImGuiButtonFlags_AllowOverlap = 1 << 12, // require previous frame HoveredId to either match id or be null before being usable.
|
||||
//ImGuiButtonFlags_DontClosePopups = 1 << 13, // disable automatically closing parent popup on press
|
||||
@@ -1087,7 +1086,7 @@ struct IMGUI_API ImGuiGroupData
|
||||
ImVec2 BackupCurrLineSize;
|
||||
float BackupCurrLineTextBaseOffset;
|
||||
ImGuiID BackupActiveIdIsAlive;
|
||||
bool BackupDeactivatedIdIsAlive;
|
||||
bool BackupActiveIdPreviousFrameIsAlive;
|
||||
bool BackupHoveredIdIsAlive;
|
||||
bool BackupIsSameLine;
|
||||
bool EmitItem;
|
||||
@@ -1138,10 +1137,8 @@ struct IMGUI_API ImGuiInputTextState
|
||||
{
|
||||
ImGuiContext* Ctx; // parent UI context (needs to be set explicitly by parent).
|
||||
ImStbTexteditState* Stb; // State for stb_textedit.h
|
||||
ImGuiInputTextFlags Flags; // copy of InputText() flags. may be used to check if e.g. ImGuiInputTextFlags_Password is set.
|
||||
ImGuiID ID; // widget id owning the text state
|
||||
int TextLen; // UTF-8 length of the string in TextA (in bytes)
|
||||
const char* TextSrc; // == TextA.Data unless read-only, in which case == buf passed to InputText(). Field only set and valid _inside_ the call InputText() call.
|
||||
ImVector<char> TextA; // main UTF8 buffer. TextA.Size is a buffer size! Should always be >= buf_size passed by user (and of course >= CurLenA + 1).
|
||||
ImVector<char> TextToRevertTo; // value to revert to when pressing Escape = backup of end-user buffer at the time of focus (in UTF-8, unaltered)
|
||||
ImVector<char> CallbackTextBackup; // temporary storage for callback to support automatic reconcile of undo-stack
|
||||
@@ -1151,8 +1148,9 @@ struct IMGUI_API ImGuiInputTextState
|
||||
bool CursorFollow; // set when we want scrolling to follow the current cursor position (not always!)
|
||||
bool SelectedAllMouseLock; // after a double-click to select all, we ignore further mouse drags to update selection
|
||||
bool Edited; // edited this frame
|
||||
bool WantReloadUserBuf; // force a reload of user buf so it may be modified externally. may be automatic in future version.
|
||||
int ReloadSelectionStart;
|
||||
ImGuiInputTextFlags Flags; // copy of InputText() flags. may be used to check if e.g. ImGuiInputTextFlags_Password is set.
|
||||
bool ReloadUserBuf; // force a reload of user buf so it may be modified externally. may be automatic in future version.
|
||||
int ReloadSelectionStart; // POSITIONS ARE IN IMWCHAR units *NOT* UTF-8 this is why this is not exposed yet.
|
||||
int ReloadSelectionEnd;
|
||||
|
||||
ImGuiInputTextState();
|
||||
@@ -1272,11 +1270,11 @@ struct ImGuiNextItemData
|
||||
struct ImGuiLastItemData
|
||||
{
|
||||
ImGuiID ID;
|
||||
ImGuiItemFlags ItemFlags; // See ImGuiItemFlags_ (called 'InFlags' before v1.91.4).
|
||||
ImGuiItemFlags ItemFlags; // See ImGuiItemFlags_
|
||||
ImGuiItemStatusFlags StatusFlags; // See ImGuiItemStatusFlags_
|
||||
ImRect Rect; // Full rectangle
|
||||
ImRect NavRect; // Navigation scoring rectangle (not displayed)
|
||||
// Rarely used fields are not explicitly cleared, only valid when the corresponding ImGuiItemStatusFlags are set.
|
||||
// Rarely used fields are not explicitly cleared, only valid when the corresponding ImGuiItemStatusFlags ar set.
|
||||
ImRect DisplayRect; // Display rectangle. ONLY VALID IF (StatusFlags & ImGuiItemStatusFlags_HasDisplayRect) is set.
|
||||
ImRect ClipRect; // Clip rectangle at the time of submitting item. ONLY VALID IF (StatusFlags & ImGuiItemStatusFlags_HasClipRect) is set..
|
||||
ImGuiKeyChord Shortcut; // Shortcut at the time of submitting item. ONLY VALID IF (StatusFlags & ImGuiItemStatusFlags_HasShortcut) is set..
|
||||
@@ -1339,15 +1337,6 @@ struct ImGuiPtrOrIndex
|
||||
ImGuiPtrOrIndex(int index) { Ptr = NULL; Index = index; }
|
||||
};
|
||||
|
||||
// Data used by IsItemDeactivated()/IsItemDeactivatedAfterEdit() functions
|
||||
struct ImGuiDeactivatedItemData
|
||||
{
|
||||
ImGuiID ID;
|
||||
int ElapseFrame;
|
||||
bool HasBeenEditedBefore;
|
||||
bool IsAlive;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// [SECTION] Popup support
|
||||
//-----------------------------------------------------------------------------
|
||||
@@ -2255,9 +2244,9 @@ struct ImGuiContext
|
||||
int FrameCountEnded;
|
||||
int FrameCountPlatformEnded;
|
||||
int FrameCountRendered;
|
||||
ImGuiID WithinEndChildID; // Set within EndChild()
|
||||
bool WithinFrameScope; // Set by NewFrame(), cleared by EndFrame()
|
||||
bool WithinFrameScopeWithImplicitWindow; // Set by NewFrame(), cleared by EndFrame() when the implicit debug window has been pushed
|
||||
bool WithinEndChild; // Set within EndChild()
|
||||
bool GcCompactAll; // Request full GC
|
||||
bool TestEngineHookItems; // Will call test engine hooks: ImGuiTestEngineHook_ItemAdd(), ImGuiTestEngineHook_ItemInfo(), ImGuiTestEngineHook_Log()
|
||||
void* TestEngine; // Test engine user data
|
||||
@@ -2317,8 +2306,9 @@ struct ImGuiContext
|
||||
ImGuiWindow* ActiveIdWindow;
|
||||
ImGuiInputSource ActiveIdSource; // Activating source: ImGuiInputSource_Mouse OR ImGuiInputSource_Keyboard OR ImGuiInputSource_Gamepad
|
||||
ImGuiID ActiveIdPreviousFrame;
|
||||
ImGuiDeactivatedItemData DeactivatedItemData;
|
||||
ImGuiDataTypeStorage ActiveIdValueOnActivation; // Backup of initial value at the time of activation. ONLY SET BY SPECIFIC WIDGETS: DragXXX and SliderXXX.
|
||||
bool ActiveIdPreviousFrameIsAlive;
|
||||
bool ActiveIdPreviousFrameHasBeenEditedBefore;
|
||||
ImGuiWindow* ActiveIdPreviousFrameWindow;
|
||||
ImGuiID LastActiveId; // Store the last non-zero ActiveId, useful for animation.
|
||||
float LastActiveIdTimer; // Store the last non-zero ActiveId timer since the beginning of activation, useful for animation.
|
||||
|
||||
|
||||
776
lib/third_party/imgui/imgui/source/imgui.cpp
vendored
776
lib/third_party/imgui/imgui/source/imgui.cpp
vendored
File diff suppressed because it is too large
Load Diff
@@ -1,4 +1,4 @@
|
||||
// dear imgui, v1.91.7
|
||||
// dear imgui, v1.91.6
|
||||
// (demo code)
|
||||
|
||||
// Help:
|
||||
@@ -147,15 +147,11 @@ Index of this file:
|
||||
#pragma clang diagnostic ignored "-Wunsafe-buffer-usage" // warning: 'xxx' is an unsafe pointer used for buffer access
|
||||
#elif defined(__GNUC__)
|
||||
#pragma GCC diagnostic ignored "-Wpragmas" // warning: unknown option after '#pragma GCC diagnostic' kind
|
||||
#pragma GCC diagnostic ignored "-Wfloat-equal" // warning: comparing floating-point with '==' or '!=' is unsafe
|
||||
#pragma GCC diagnostic ignored "-Wint-to-pointer-cast" // warning: cast to pointer from integer of different size
|
||||
#pragma GCC diagnostic ignored "-Wformat" // warning: format '%p' expects argument of type 'int'/'void*', but argument X has type 'unsigned int'/'ImGuiWindow*'
|
||||
#pragma GCC diagnostic ignored "-Wformat-security" // warning: format string is not a string literal (potentially insecure)
|
||||
#pragma GCC diagnostic ignored "-Wdouble-promotion" // warning: implicit conversion from 'float' to 'double' when passing argument to function
|
||||
#pragma GCC diagnostic ignored "-Wconversion" // warning: conversion to 'xxxx' from 'xxxx' may alter its value
|
||||
#pragma GCC diagnostic ignored "-Wmisleading-indentation" // [__GNUC__ >= 6] warning: this 'if' clause does not guard this statement // GCC 6.0+ only. See #883 on GitHub.
|
||||
#pragma GCC diagnostic ignored "-Wstrict-overflow" // warning: assuming signed overflow does not occur when simplifying division / ..when changing X +- C1 cmp C2 to X cmp C2 -+ C1
|
||||
#pragma GCC diagnostic ignored "-Wcast-qual" // warning: cast from type 'const xxxx *' to type 'xxxx *' casts away qualifiers
|
||||
#endif
|
||||
|
||||
// Play it nice with Windows users (Update: May 2018, Notepad now supports Unix-style carriage returns!)
|
||||
@@ -307,7 +303,6 @@ struct ExampleMemberInfo
|
||||
// Metadata description of ExampleTreeNode struct.
|
||||
static const ExampleMemberInfo ExampleTreeNodeMemberInfos[]
|
||||
{
|
||||
{ "MyName", ImGuiDataType_String, 1, offsetof(ExampleTreeNode, Name) },
|
||||
{ "MyBool", ImGuiDataType_Bool, 1, offsetof(ExampleTreeNode, DataMyBool) },
|
||||
{ "MyInt", ImGuiDataType_S32, 1, offsetof(ExampleTreeNode, DataMyInt) },
|
||||
{ "MyVec2", ImGuiDataType_Float, 2, offsetof(ExampleTreeNode, DataMyVec2) },
|
||||
@@ -804,25 +799,18 @@ static void ShowDemoWindowMenuBar(ImGuiDemoWindowData* demo_data)
|
||||
const bool has_debug_tools = false;
|
||||
#endif
|
||||
ImGui::MenuItem("Metrics/Debugger", NULL, &demo_data->ShowMetrics, has_debug_tools);
|
||||
if (ImGui::BeginMenu("Debug Options"))
|
||||
{
|
||||
ImGui::BeginDisabled(!has_debug_tools);
|
||||
ImGui::Checkbox("Highlight ID Conflicts", &io.ConfigDebugHighlightIdConflicts);
|
||||
ImGui::EndDisabled();
|
||||
ImGui::Checkbox("Assert on error recovery", &io.ConfigErrorRecoveryEnableAssert);
|
||||
ImGui::TextDisabled("(see Demo->Configuration for details & more)");
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
ImGui::MenuItem("Debug Log", NULL, &demo_data->ShowDebugLog, has_debug_tools);
|
||||
ImGui::MenuItem("ID Stack Tool", NULL, &demo_data->ShowIDStackTool, has_debug_tools);
|
||||
bool is_debugger_present = io.ConfigDebugIsDebuggerPresent;
|
||||
if (ImGui::MenuItem("Item Picker", NULL, false, has_debug_tools))// && is_debugger_present))
|
||||
if (ImGui::MenuItem("Item Picker", NULL, false, has_debug_tools && is_debugger_present))
|
||||
ImGui::DebugStartItemPicker();
|
||||
if (!is_debugger_present)
|
||||
ImGui::SetItemTooltip("Requires io.ConfigDebugIsDebuggerPresent=true to be set.\n\nWe otherwise disable some extra features to avoid casual users crashing the application.");
|
||||
ImGui::SetItemTooltip("Requires io.ConfigDebugIsDebuggerPresent=true to be set.\n\nWe otherwise disable the menu option to avoid casual users crashing the application.\n\nYou can however always access the Item Picker in Metrics->Tools.");
|
||||
ImGui::MenuItem("Style Editor", NULL, &demo_data->ShowStyleEditor);
|
||||
ImGui::MenuItem("About Dear ImGui", NULL, &demo_data->ShowAbout);
|
||||
|
||||
ImGui::SeparatorText("Debug Options");
|
||||
ImGui::MenuItem("Highlight ID Conflicts", NULL, &io.ConfigDebugHighlightIdConflicts, has_debug_tools);
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
ImGui::EndMenuBar();
|
||||
@@ -1182,7 +1170,7 @@ static void ShowDemoWindowWidgets(ImGuiDemoWindowData* demo_data)
|
||||
ImGui::CheckboxFlags("ImGuiTreeNodeFlags_OpenOnDoubleClick", &base_flags, ImGuiTreeNodeFlags_OpenOnDoubleClick);
|
||||
ImGui::CheckboxFlags("ImGuiTreeNodeFlags_SpanAvailWidth", &base_flags, ImGuiTreeNodeFlags_SpanAvailWidth); ImGui::SameLine(); HelpMarker("Extend hit area to all available width instead of allowing more items to be laid out after the node.");
|
||||
ImGui::CheckboxFlags("ImGuiTreeNodeFlags_SpanFullWidth", &base_flags, ImGuiTreeNodeFlags_SpanFullWidth);
|
||||
ImGui::CheckboxFlags("ImGuiTreeNodeFlags_SpanLabelWidth", &base_flags, ImGuiTreeNodeFlags_SpanLabelWidth); ImGui::SameLine(); HelpMarker("Reduce hit area to the text label and a bit of margin.");
|
||||
ImGui::CheckboxFlags("ImGuiTreeNodeFlags_SpanTextWidth", &base_flags, ImGuiTreeNodeFlags_SpanTextWidth); ImGui::SameLine(); HelpMarker("Reduce hit area to the text label and a bit of margin.");
|
||||
ImGui::CheckboxFlags("ImGuiTreeNodeFlags_SpanAllColumns", &base_flags, ImGuiTreeNodeFlags_SpanAllColumns); ImGui::SameLine(); HelpMarker("For use in Tables only.");
|
||||
ImGui::CheckboxFlags("ImGuiTreeNodeFlags_AllowOverlap", &base_flags, ImGuiTreeNodeFlags_AllowOverlap);
|
||||
ImGui::CheckboxFlags("ImGuiTreeNodeFlags_Framed", &base_flags, ImGuiTreeNodeFlags_Framed); ImGui::SameLine(); HelpMarker("Draw frame with background (e.g. for CollapsingHeader)");
|
||||
@@ -1219,9 +1207,9 @@ static void ShowDemoWindowWidgets(ImGuiDemoWindowData* demo_data)
|
||||
ImGui::Text("This is a drag and drop source");
|
||||
ImGui::EndDragDropSource();
|
||||
}
|
||||
if (i == 2 && (base_flags & ImGuiTreeNodeFlags_SpanLabelWidth))
|
||||
if (i == 2 && (base_flags & ImGuiTreeNodeFlags_SpanTextWidth))
|
||||
{
|
||||
// Item 2 has an additional inline button to help demonstrate SpanLabelWidth.
|
||||
// Item 2 has an additional inline button to help demonstrate SpanTextWidth.
|
||||
ImGui::SameLine();
|
||||
if (ImGui::SmallButton("button")) {}
|
||||
}
|
||||
@@ -2382,8 +2370,6 @@ static void ShowDemoWindowWidgets(ImGuiDemoWindowData* demo_data)
|
||||
ImGui::SameLine(); HelpMarker("Disable rounding underlying value to match precision of the format string (e.g. %.3f values are rounded to those 3 digits).");
|
||||
ImGui::CheckboxFlags("ImGuiSliderFlags_NoInput", &flags, ImGuiSliderFlags_NoInput);
|
||||
ImGui::SameLine(); HelpMarker("Disable CTRL+Click or Enter key allowing to input text directly into the widget.");
|
||||
ImGui::CheckboxFlags("ImGuiSliderFlags_NoSpeedTweaks", &flags, ImGuiSliderFlags_NoSpeedTweaks);
|
||||
ImGui::SameLine(); HelpMarker("Disable keyboard modifiers altering tweak speed. Useful if you want to alter tweak speed yourself based on your own logic.");
|
||||
ImGui::CheckboxFlags("ImGuiSliderFlags_WrapAround", &flags, ImGuiSliderFlags_WrapAround);
|
||||
ImGui::SameLine(); HelpMarker("Enable wrapping around from max to min and from min to max (only supported by DragXXX() functions)");
|
||||
|
||||
@@ -6432,17 +6418,15 @@ static void ShowDemoWindowTables()
|
||||
IMGUI_DEMO_MARKER("Tables/Tree view");
|
||||
if (ImGui::TreeNode("Tree view"))
|
||||
{
|
||||
static ImGuiTableFlags table_flags = ImGuiTableFlags_BordersV | ImGuiTableFlags_BordersOuterH | ImGuiTableFlags_Resizable | ImGuiTableFlags_RowBg | ImGuiTableFlags_NoBordersInBody;
|
||||
static ImGuiTableFlags flags = ImGuiTableFlags_BordersV | ImGuiTableFlags_BordersOuterH | ImGuiTableFlags_Resizable | ImGuiTableFlags_RowBg | ImGuiTableFlags_NoBordersInBody;
|
||||
|
||||
static ImGuiTreeNodeFlags tree_node_flags_base = ImGuiTreeNodeFlags_SpanAllColumns;
|
||||
ImGui::CheckboxFlags("ImGuiTreeNodeFlags_SpanFullWidth", &tree_node_flags_base, ImGuiTreeNodeFlags_SpanFullWidth);
|
||||
ImGui::CheckboxFlags("ImGuiTreeNodeFlags_SpanLabelWidth", &tree_node_flags_base, ImGuiTreeNodeFlags_SpanLabelWidth);
|
||||
ImGui::CheckboxFlags("ImGuiTreeNodeFlags_SpanAllColumns", &tree_node_flags_base, ImGuiTreeNodeFlags_SpanAllColumns);
|
||||
ImGui::CheckboxFlags("ImGuiTreeNodeFlags_LabelSpanAllColumns", &tree_node_flags_base, ImGuiTreeNodeFlags_LabelSpanAllColumns);
|
||||
ImGui::SameLine(); HelpMarker("Useful if you know that you aren't displaying contents in other columns");
|
||||
static ImGuiTreeNodeFlags tree_node_flags = ImGuiTreeNodeFlags_SpanAllColumns;
|
||||
ImGui::CheckboxFlags("ImGuiTreeNodeFlags_SpanFullWidth", &tree_node_flags, ImGuiTreeNodeFlags_SpanFullWidth);
|
||||
ImGui::CheckboxFlags("ImGuiTreeNodeFlags_SpanTextWidth", &tree_node_flags, ImGuiTreeNodeFlags_SpanTextWidth);
|
||||
ImGui::CheckboxFlags("ImGuiTreeNodeFlags_SpanAllColumns", &tree_node_flags, ImGuiTreeNodeFlags_SpanAllColumns);
|
||||
|
||||
HelpMarker("See \"Columns flags\" section to configure how indentation is applied to individual columns.");
|
||||
if (ImGui::BeginTable("3ways", 3, table_flags))
|
||||
if (ImGui::BeginTable("3ways", 3, flags))
|
||||
{
|
||||
// The first column will use the default _WidthStretch when ScrollX is Off and _WidthFixed when ScrollX is On
|
||||
ImGui::TableSetupColumn("Name", ImGuiTableColumnFlags_NoHide);
|
||||
@@ -6463,21 +6447,13 @@ static void ShowDemoWindowTables()
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
const bool is_folder = (node->ChildCount > 0);
|
||||
|
||||
ImGuiTreeNodeFlags node_flags = tree_node_flags_base;
|
||||
if (node != &all_nodes[0])
|
||||
node_flags &= ~ImGuiTreeNodeFlags_LabelSpanAllColumns; // Only demonstrate this on the root node.
|
||||
|
||||
if (is_folder)
|
||||
{
|
||||
bool open = ImGui::TreeNodeEx(node->Name, node_flags);
|
||||
if ((node_flags & ImGuiTreeNodeFlags_LabelSpanAllColumns) == 0)
|
||||
{
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::TextDisabled("--");
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::TextUnformatted(node->Type);
|
||||
}
|
||||
bool open = ImGui::TreeNodeEx(node->Name, tree_node_flags);
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::TextDisabled("--");
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::TextUnformatted(node->Type);
|
||||
if (open)
|
||||
{
|
||||
for (int child_n = 0; child_n < node->ChildCount; child_n++)
|
||||
@@ -6487,7 +6463,7 @@ static void ShowDemoWindowTables()
|
||||
}
|
||||
else
|
||||
{
|
||||
ImGui::TreeNodeEx(node->Name, node_flags | ImGuiTreeNodeFlags_Leaf | ImGuiTreeNodeFlags_Bullet | ImGuiTreeNodeFlags_NoTreePushOnOpen);
|
||||
ImGui::TreeNodeEx(node->Name, tree_node_flags | ImGuiTreeNodeFlags_Leaf | ImGuiTreeNodeFlags_Bullet | ImGuiTreeNodeFlags_NoTreePushOnOpen);
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("%d", node->Size);
|
||||
ImGui::TableNextColumn();
|
||||
@@ -6497,7 +6473,7 @@ static void ShowDemoWindowTables()
|
||||
};
|
||||
static const MyTreeNode nodes[] =
|
||||
{
|
||||
{ "Root with Long Name", "Folder", -1, 1, 3 }, // 0
|
||||
{ "Root", "Folder", -1, 1, 3 }, // 0
|
||||
{ "Music", "Folder", -1, 4, 2 }, // 1
|
||||
{ "Textures", "Folder", -1, 6, 3 }, // 2
|
||||
{ "desktop.ini", "System file", 1024, -1,-1 }, // 3
|
||||
@@ -7785,8 +7761,7 @@ void ImGui::ShowAboutWindow(bool* p_open)
|
||||
ImGui::TextLinkOpenURL("Funding", "https://github.com/ocornut/imgui/wiki/Funding");
|
||||
|
||||
ImGui::Separator();
|
||||
ImGui::Text("(c) 2014-2025 Omar Cornut");
|
||||
ImGui::Text("Developed by Omar Cornut and all Dear ImGui contributors.");
|
||||
ImGui::Text("By Omar Cornut and all Dear ImGui contributors.");
|
||||
ImGui::Text("Dear ImGui is licensed under the MIT License, see LICENSE for more information.");
|
||||
ImGui::Text("If your company uses this, please consider funding the project.");
|
||||
|
||||
@@ -7964,8 +7939,6 @@ void ImGui::ShowFontSelector(const char* label)
|
||||
ImGui::PushID((void*)font);
|
||||
if (ImGui::Selectable(font->GetDebugName(), font == font_current))
|
||||
io.FontDefault = font;
|
||||
if (font == font_current)
|
||||
ImGui::SetItemDefaultFocus();
|
||||
ImGui::PopID();
|
||||
}
|
||||
ImGui::EndCombo();
|
||||
@@ -9092,8 +9065,6 @@ struct ExampleAppPropertyEditor
|
||||
ImGui::Separator();
|
||||
if (ImGui::BeginTable("##properties", 2, ImGuiTableFlags_Resizable | ImGuiTableFlags_ScrollY))
|
||||
{
|
||||
// Push object ID after we entered the table, so table is shared for all objects
|
||||
ImGui::PushID((int)node->UID);
|
||||
ImGui::TableSetupColumn("", ImGuiTableColumnFlags_WidthFixed);
|
||||
ImGui::TableSetupColumn("", ImGuiTableColumnFlags_WidthStretch, 2.0f); // Default twice larger
|
||||
if (node->HasData)
|
||||
@@ -9132,16 +9103,10 @@ struct ExampleAppPropertyEditor
|
||||
ImGui::SliderScalarN("##Editor", field_desc.DataType, field_ptr, field_desc.DataCount, &v_min, &v_max);
|
||||
break;
|
||||
}
|
||||
case ImGuiDataType_String:
|
||||
{
|
||||
ImGui::InputText("##Editor", reinterpret_cast<char*>(field_ptr), 28);
|
||||
break;
|
||||
}
|
||||
}
|
||||
ImGui::PopID();
|
||||
}
|
||||
}
|
||||
ImGui::PopID();
|
||||
ImGui::EndTable();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// dear imgui, v1.91.7
|
||||
// dear imgui, v1.91.6
|
||||
// (drawing and font code)
|
||||
|
||||
/*
|
||||
@@ -69,17 +69,13 @@ Index of this file:
|
||||
#pragma clang diagnostic ignored "-Wreserved-identifier" // warning: identifier '_Xxx' is reserved because it starts with '_' followed by a capital letter
|
||||
#pragma clang diagnostic ignored "-Wunsafe-buffer-usage" // warning: 'xxx' is an unsafe pointer used for buffer access
|
||||
#pragma clang diagnostic ignored "-Wnontrivial-memaccess" // warning: first argument in call to 'memset' is a pointer to non-trivially copyable type
|
||||
#pragma clang diagnostic ignored "-Wcast-qual" // warning: cast from 'const xxxx *' to 'xxx *' drops const qualifier
|
||||
#elif defined(__GNUC__)
|
||||
#pragma GCC diagnostic ignored "-Wpragmas" // warning: unknown option after '#pragma GCC diagnostic' kind
|
||||
#pragma GCC diagnostic ignored "-Wunused-function" // warning: 'xxxx' defined but not used
|
||||
#pragma GCC diagnostic ignored "-Wfloat-equal" // warning: comparing floating-point with '==' or '!=' is unsafe
|
||||
#pragma GCC diagnostic ignored "-Wdouble-promotion" // warning: implicit conversion from 'float' to 'double' when passing argument to function
|
||||
#pragma GCC diagnostic ignored "-Wconversion" // warning: conversion to 'xxxx' from 'xxxx' may alter its value
|
||||
#pragma GCC diagnostic ignored "-Wstack-protector" // warning: stack protector not protecting local variables: variable length buffer
|
||||
#pragma GCC diagnostic ignored "-Wstrict-overflow" // warning: assuming signed overflow does not occur when simplifying division / ..when changing X +- C1 cmp C2 to X cmp C2 -+ C1
|
||||
#pragma GCC diagnostic ignored "-Wclass-memaccess" // [__GNUC__ >= 8] warning: 'memset/memcpy' clearing/writing an object of type 'xxxx' with no trivial copy-assignment; use assignment or value-initialization instead
|
||||
#pragma GCC diagnostic ignored "-Wcast-qual" // warning: cast from type 'const xxxx *' to type 'xxxx *' casts away qualifiers
|
||||
#endif
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
@@ -111,12 +107,13 @@ namespace IMGUI_STB_NAMESPACE
|
||||
#pragma clang diagnostic ignored "-Wunused-function" // warning: 'xxxx' defined but not used
|
||||
#pragma clang diagnostic ignored "-Wmissing-prototypes"
|
||||
#pragma clang diagnostic ignored "-Wimplicit-fallthrough"
|
||||
#pragma clang diagnostic ignored "-Wcast-qual" // warning: cast from 'const xxxx *' to 'xxx *' drops const qualifier
|
||||
#endif
|
||||
|
||||
#if defined(__GNUC__)
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wtype-limits" // warning: comparison is always true due to limited range of data type [-Wtype-limits]
|
||||
#pragma GCC diagnostic ignored "-Wimplicit-fallthrough" // warning: this statement may fall through
|
||||
#pragma GCC diagnostic ignored "-Wcast-qual" // warning: cast from type 'const xxxx *' to type 'xxxx *' casts away qualifiers
|
||||
#endif
|
||||
|
||||
#ifndef STB_RECT_PACK_IMPLEMENTATION // in case the user already have an implementation in the _same_ compilation unit (e.g. unity builds)
|
||||
@@ -3133,44 +3130,12 @@ ImFontConfig::ImFontConfig()
|
||||
GlyphMaxAdvanceX = FLT_MAX;
|
||||
RasterizerMultiply = 1.0f;
|
||||
RasterizerDensity = 1.0f;
|
||||
EllipsisChar = 0;
|
||||
EllipsisChar = (ImWchar)-1;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// [SECTION] ImFontAtlas
|
||||
//-----------------------------------------------------------------------------
|
||||
// - Default texture data encoded in ASCII
|
||||
// - ImFontAtlas::ClearInputData()
|
||||
// - ImFontAtlas::ClearTexData()
|
||||
// - ImFontAtlas::ClearFonts()
|
||||
// - ImFontAtlas::Clear()
|
||||
// - ImFontAtlas::GetTexDataAsAlpha8()
|
||||
// - ImFontAtlas::GetTexDataAsRGBA32()
|
||||
// - ImFontAtlas::AddFont()
|
||||
// - ImFontAtlas::AddFontDefault()
|
||||
// - ImFontAtlas::AddFontFromFileTTF()
|
||||
// - ImFontAtlas::AddFontFromMemoryTTF()
|
||||
// - ImFontAtlas::AddFontFromMemoryCompressedTTF()
|
||||
// - ImFontAtlas::AddFontFromMemoryCompressedBase85TTF()
|
||||
// - ImFontAtlas::AddCustomRectRegular()
|
||||
// - ImFontAtlas::AddCustomRectFontGlyph()
|
||||
// - ImFontAtlas::CalcCustomRectUV()
|
||||
// - ImFontAtlas::GetMouseCursorTexData()
|
||||
// - ImFontAtlas::Build()
|
||||
// - ImFontAtlasBuildMultiplyCalcLookupTable()
|
||||
// - ImFontAtlasBuildMultiplyRectAlpha8()
|
||||
// - ImFontAtlasBuildWithStbTruetype()
|
||||
// - ImFontAtlasGetBuilderForStbTruetype()
|
||||
// - ImFontAtlasUpdateConfigDataPointers()
|
||||
// - ImFontAtlasBuildSetupFont()
|
||||
// - ImFontAtlasBuildPackCustomRects()
|
||||
// - ImFontAtlasBuildRender8bppRectFromString()
|
||||
// - ImFontAtlasBuildRender32bppRectFromString()
|
||||
// - ImFontAtlasBuildRenderDefaultTexData()
|
||||
// - ImFontAtlasBuildRenderLinesTexData()
|
||||
// - ImFontAtlasBuildInit()
|
||||
// - ImFontAtlasBuildFinish()
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// A work of art lies ahead! (. = white layer, X = black layer, others are blank)
|
||||
// The 2x2 white texels on the top left are the ones we'll use everywhere in Dear ImGui to render filled shapes.
|
||||
@@ -3355,6 +3320,9 @@ ImFont* ImFontAtlas::AddFont(const ImFontConfig* font_cfg)
|
||||
// - We may support it better later and remove this rounding.
|
||||
new_font_cfg.SizePixels = ImTrunc(new_font_cfg.SizePixels);
|
||||
|
||||
if (new_font_cfg.DstFont->EllipsisChar == (ImWchar)-1)
|
||||
new_font_cfg.DstFont->EllipsisChar = font_cfg->EllipsisChar;
|
||||
|
||||
// Pointers to ConfigData and BuilderData are otherwise dangling
|
||||
ImFontAtlasUpdateConfigDataPointers(this);
|
||||
|
||||
@@ -4336,16 +4304,6 @@ void ImFontAtlasBuildFinish(ImFontAtlas* atlas)
|
||||
//-------------------------------------------------------------------------
|
||||
// [SECTION] ImFontAtlas: glyph ranges helpers
|
||||
//-------------------------------------------------------------------------
|
||||
// - GetGlyphRangesDefault()
|
||||
// - GetGlyphRangesGreek()
|
||||
// - GetGlyphRangesKorean()
|
||||
// - GetGlyphRangesChineseFull()
|
||||
// - GetGlyphRangesChineseSimplifiedCommon()
|
||||
// - GetGlyphRangesJapanese()
|
||||
// - GetGlyphRangesCyrillic()
|
||||
// - GetGlyphRangesThai()
|
||||
// - GetGlyphRangesVietnamese()
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// Retrieve list of range (2 int per range, values are inclusive)
|
||||
const ImWchar* ImFontAtlas::GetGlyphRangesDefault()
|
||||
@@ -4654,8 +4612,8 @@ ImFont::ImFont()
|
||||
{
|
||||
FontSize = 0.0f;
|
||||
FallbackAdvanceX = 0.0f;
|
||||
FallbackChar = 0;
|
||||
EllipsisChar = 0;
|
||||
FallbackChar = (ImWchar)-1;
|
||||
EllipsisChar = (ImWchar)-1;
|
||||
EllipsisWidth = EllipsisCharStep = 0.0f;
|
||||
EllipsisCharCount = 0;
|
||||
FallbackGlyph = NULL;
|
||||
@@ -4694,7 +4652,7 @@ static ImWchar FindFirstExistingGlyph(ImFont* font, const ImWchar* candidate_cha
|
||||
for (int n = 0; n < candidate_chars_count; n++)
|
||||
if (font->FindGlyphNoFallback(candidate_chars[n]) != NULL)
|
||||
return candidate_chars[n];
|
||||
return 0;
|
||||
return (ImWchar)-1;
|
||||
}
|
||||
|
||||
void ImFont::BuildLookupTable()
|
||||
@@ -4761,23 +4719,23 @@ void ImFont::BuildLookupTable()
|
||||
// Setup Ellipsis character. It is required for rendering elided text. We prefer using U+2026 (horizontal ellipsis).
|
||||
// However some old fonts may contain ellipsis at U+0085. Here we auto-detect most suitable ellipsis character.
|
||||
// FIXME: Note that 0x2026 is rarely included in our font ranges. Because of this we are more likely to use three individual dots.
|
||||
const ImWchar ellipsis_chars[] = { ConfigData->EllipsisChar, (ImWchar)0x2026, (ImWchar)0x0085 };
|
||||
const ImWchar ellipsis_chars[] = { (ImWchar)0x2026, (ImWchar)0x0085 };
|
||||
const ImWchar dots_chars[] = { (ImWchar)'.', (ImWchar)0xFF0E };
|
||||
if (EllipsisChar == 0)
|
||||
if (EllipsisChar == (ImWchar)-1)
|
||||
EllipsisChar = FindFirstExistingGlyph(this, ellipsis_chars, IM_ARRAYSIZE(ellipsis_chars));
|
||||
const ImWchar dot_char = FindFirstExistingGlyph(this, dots_chars, IM_ARRAYSIZE(dots_chars));
|
||||
if (EllipsisChar != 0)
|
||||
if (EllipsisChar != (ImWchar)-1)
|
||||
{
|
||||
EllipsisCharCount = 1;
|
||||
EllipsisWidth = EllipsisCharStep = FindGlyph(EllipsisChar)->X1;
|
||||
}
|
||||
else if (dot_char != 0)
|
||||
else if (dot_char != (ImWchar)-1)
|
||||
{
|
||||
const ImFontGlyph* dot_glyph = FindGlyph(dot_char);
|
||||
const ImFontGlyph* glyph = FindGlyph(dot_char);
|
||||
EllipsisChar = dot_char;
|
||||
EllipsisCharCount = 3;
|
||||
EllipsisCharStep = (float)(int)(dot_glyph->X1 - dot_glyph->X0) + 1.0f;
|
||||
EllipsisWidth = ImMax(dot_glyph->AdvanceX, dot_glyph->X0 + EllipsisCharStep * 3.0f - 1.0f); // FIXME: Slightly odd for normally mono-space fonts but since this is used for trailing contents.
|
||||
EllipsisCharStep = (glyph->X1 - glyph->X0) + 1.0f;
|
||||
EllipsisWidth = EllipsisCharStep * 3.0f - 1.0f;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// dear imgui, v1.91.7
|
||||
// dear imgui, v1.91.6
|
||||
// (tables and columns code)
|
||||
|
||||
/*
|
||||
@@ -232,11 +232,7 @@ Index of this file:
|
||||
#pragma clang diagnostic ignored "-Wnontrivial-memaccess" // warning: first argument in call to 'memset' is a pointer to non-trivially copyable type
|
||||
#elif defined(__GNUC__)
|
||||
#pragma GCC diagnostic ignored "-Wpragmas" // warning: unknown option after '#pragma GCC diagnostic' kind
|
||||
#pragma GCC diagnostic ignored "-Wfloat-equal" // warning: comparing floating-point with '==' or '!=' is unsafe
|
||||
#pragma GCC diagnostic ignored "-Wformat-nonliteral" // warning: format not a string literal, format string not checked
|
||||
#pragma GCC diagnostic ignored "-Wdouble-promotion" // warning: implicit conversion from 'float' to 'double' when passing argument to function
|
||||
#pragma GCC diagnostic ignored "-Wformat" // warning: format '%p' expects argument of type 'int'/'void*', but argument X has type 'unsigned int'/'ImGuiWindow*'
|
||||
#pragma GCC diagnostic ignored "-Wstrict-overflow"
|
||||
#pragma GCC diagnostic ignored "-Wclass-memaccess" // [__GNUC__ >= 8] warning: 'memset/memcpy' clearing/writing an object of type 'xxxx' with no trivial copy-assignment; use assignment or value-initialization instead
|
||||
#endif
|
||||
|
||||
@@ -1337,11 +1333,7 @@ void ImGui::EndTable()
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiTable* table = g.CurrentTable;
|
||||
if (table == NULL)
|
||||
{
|
||||
IM_ASSERT_USER_ERROR(table != NULL, "EndTable() call should only be done while in BeginTable() scope!");
|
||||
return;
|
||||
}
|
||||
IM_ASSERT(table != NULL && "Only call EndTable() if BeginTable() returns true!");
|
||||
|
||||
// This assert would be very useful to catch a common error... unfortunately it would probably trigger in some
|
||||
// cases, and for consistency user may sometimes output empty tables (and still benefit from e.g. outer border)
|
||||
@@ -1564,12 +1556,8 @@ void ImGui::TableSetupColumn(const char* label, ImGuiTableColumnFlags flags, flo
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiTable* table = g.CurrentTable;
|
||||
if (table == NULL)
|
||||
{
|
||||
IM_ASSERT_USER_ERROR(table != NULL, "Call should only be done while in BeginTable() scope!");
|
||||
return;
|
||||
}
|
||||
IM_ASSERT(table->IsLayoutLocked == false && "Need to call TableSetupColumn() before first row!");
|
||||
IM_ASSERT(table != NULL && "Need to call TableSetupColumn() after BeginTable()!");
|
||||
IM_ASSERT(table->IsLayoutLocked == false && "Need to call call TableSetupColumn() before first row!");
|
||||
IM_ASSERT((flags & ImGuiTableColumnFlags_StatusMask_) == 0 && "Illegal to pass StatusMask values to TableSetupColumn()");
|
||||
if (table->DeclColumnsCount >= table->ColumnsCount)
|
||||
{
|
||||
@@ -1642,11 +1630,7 @@ void ImGui::TableSetupScrollFreeze(int columns, int rows)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiTable* table = g.CurrentTable;
|
||||
if (table == NULL)
|
||||
{
|
||||
IM_ASSERT_USER_ERROR(table != NULL, "Call should only be done while in BeginTable() scope!");
|
||||
return;
|
||||
}
|
||||
IM_ASSERT(table != NULL && "Need to call TableSetupColumn() after BeginTable()!");
|
||||
IM_ASSERT(table->IsLayoutLocked == false && "Need to call TableSetupColumn() before first row!");
|
||||
IM_ASSERT(columns >= 0 && columns < IMGUI_TABLE_MAX_COLUMNS);
|
||||
IM_ASSERT(rows >= 0 && rows < 128); // Arbitrary limit
|
||||
@@ -1723,11 +1707,9 @@ void ImGui::TableSetColumnEnabled(int column_n, bool enabled)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiTable* table = g.CurrentTable;
|
||||
if (table == NULL)
|
||||
{
|
||||
IM_ASSERT_USER_ERROR(table != NULL, "Call should only be done while in BeginTable() scope!");
|
||||
IM_ASSERT(table != NULL);
|
||||
if (!table)
|
||||
return;
|
||||
}
|
||||
IM_ASSERT(table->Flags & ImGuiTableFlags_Hideable); // See comments above
|
||||
if (column_n < 0)
|
||||
column_n = table->CurrentColumn;
|
||||
@@ -3048,11 +3030,7 @@ void ImGui::TableHeadersRow()
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiTable* table = g.CurrentTable;
|
||||
if (table == NULL)
|
||||
{
|
||||
IM_ASSERT_USER_ERROR(table != NULL, "Call should only be done while in BeginTable() scope!");
|
||||
return;
|
||||
}
|
||||
IM_ASSERT(table != NULL && "Need to call TableHeadersRow() after BeginTable()!");
|
||||
|
||||
// Call layout if not already done. This is automatically done by TableNextRow: we do it here _only_ to make
|
||||
// it easier to debug-step in TableUpdateLayout(). Your own version of this function doesn't need this.
|
||||
@@ -3097,12 +3075,7 @@ void ImGui::TableHeader(const char* label)
|
||||
return;
|
||||
|
||||
ImGuiTable* table = g.CurrentTable;
|
||||
if (table == NULL)
|
||||
{
|
||||
IM_ASSERT_USER_ERROR(table != NULL, "Call should only be done while in BeginTable() scope!");
|
||||
return;
|
||||
}
|
||||
|
||||
IM_ASSERT(table != NULL && "Need to call TableHeader() after BeginTable()!");
|
||||
IM_ASSERT(table->CurrentColumn != -1);
|
||||
const int column_n = table->CurrentColumn;
|
||||
ImGuiTableColumn* column = &table->Columns[column_n];
|
||||
@@ -3277,11 +3250,7 @@ void ImGui::TableAngledHeadersRowEx(ImGuiID row_id, float angle, float max_label
|
||||
ImGuiTable* table = g.CurrentTable;
|
||||
ImGuiWindow* window = g.CurrentWindow;
|
||||
ImDrawList* draw_list = window->DrawList;
|
||||
if (table == NULL)
|
||||
{
|
||||
IM_ASSERT_USER_ERROR(table != NULL, "Call should only be done while in BeginTable() scope!");
|
||||
return;
|
||||
}
|
||||
IM_ASSERT(table != NULL && "Need to call TableHeadersRow() after BeginTable()!");
|
||||
IM_ASSERT(table->CurrentRow == -1 && "Must be first row");
|
||||
|
||||
if (max_label_width == 0.0f)
|
||||
@@ -3326,7 +3295,7 @@ void ImGui::TableAngledHeadersRowEx(ImGuiID row_id, float angle, float max_label
|
||||
const ImVec2 align = g.Style.TableAngledHeadersTextAlign;
|
||||
|
||||
// Draw background and labels in first pass, then all borders.
|
||||
float max_x = -FLT_MAX;
|
||||
float max_x = 0.0f;
|
||||
for (int pass = 0; pass < 2; pass++)
|
||||
for (int order_n = 0; order_n < data_count; order_n++)
|
||||
{
|
||||
|
||||
263
lib/third_party/imgui/imgui/source/imgui_widgets.cpp
vendored
263
lib/third_party/imgui/imgui/source/imgui_widgets.cpp
vendored
@@ -1,4 +1,4 @@
|
||||
// dear imgui, v1.91.7
|
||||
// dear imgui, v1.91.6
|
||||
// (widgets code)
|
||||
|
||||
/*
|
||||
@@ -82,14 +82,9 @@ Index of this file:
|
||||
#pragma clang diagnostic ignored "-Wnontrivial-memaccess" // warning: first argument in call to 'memset' is a pointer to non-trivially copyable type
|
||||
#elif defined(__GNUC__)
|
||||
#pragma GCC diagnostic ignored "-Wpragmas" // warning: unknown option after '#pragma GCC diagnostic' kind
|
||||
#pragma GCC diagnostic ignored "-Wfloat-equal" // warning: comparing floating-point with '==' or '!=' is unsafe
|
||||
#pragma GCC diagnostic ignored "-Wformat" // warning: format '%p' expects argument of type 'int'/'void*', but argument X has type 'unsigned int'/'ImGuiWindow*'
|
||||
#pragma GCC diagnostic ignored "-Wformat-nonliteral" // warning: format not a string literal, format string not checked
|
||||
#pragma GCC diagnostic ignored "-Wdeprecated-enum-enum-conversion" // warning: bitwise operation between different enumeration types ('XXXFlags_' and 'XXXFlagsPrivate_') is deprecated
|
||||
#pragma GCC diagnostic ignored "-Wdouble-promotion" // warning: implicit conversion from 'float' to 'double' when passing argument to function
|
||||
#pragma GCC diagnostic ignored "-Wstrict-overflow" // warning: assuming signed overflow does not occur when simplifying division / ..when changing X +- C1 cmp C2 to X cmp C2 -+ C1
|
||||
#pragma GCC diagnostic ignored "-Wclass-memaccess" // [__GNUC__ >= 8] warning: 'memset/memcpy' clearing/writing an object of type 'xxxx' with no trivial copy-assignment; use assignment or value-initialization instead
|
||||
#pragma GCC diagnostic ignored "-Wcast-qual" // warning: cast from type 'const xxxx *' to type 'xxxx *' casts away qualifiers
|
||||
#pragma GCC diagnostic ignored "-Wdeprecated-enum-enum-conversion" // warning: bitwise operation between different enumeration types ('XXXFlags_' and 'XXXFlagsPrivate_') is deprecated
|
||||
#endif
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
@@ -477,7 +472,7 @@ void ImGui::BulletTextV(const char* fmt, va_list args)
|
||||
// - PressedOnDragDropHold can generally be associated with any flag.
|
||||
// - PressedOnDoubleClick can be associated by PressedOnClickRelease/PressedOnRelease, in which case the second release event won't be reported.
|
||||
//------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
// The behavior of the return-value changes when ImGuiItemFlags_ButtonRepeat is set:
|
||||
// The behavior of the return-value changes when ImGuiButtonFlags_Repeat is set:
|
||||
// Repeat+ Repeat+ Repeat+ Repeat+
|
||||
// PressedOnClickRelease PressedOnClick PressedOnRelease PressedOnDoubleClick
|
||||
//-------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
@@ -2177,7 +2172,6 @@ static const ImGuiDataTypeInfo GDataTypeInfo[] =
|
||||
{ sizeof(float), "float", "%.3f","%f" }, // ImGuiDataType_Float (float are promoted to double in va_arg)
|
||||
{ sizeof(double), "double","%f", "%lf" }, // ImGuiDataType_Double
|
||||
{ sizeof(bool), "bool", "%d", "%d" }, // ImGuiDataType_Bool
|
||||
{ 0, "char*","%s", "%s" }, // ImGuiDataType_String
|
||||
};
|
||||
IM_STATIC_ASSERT(IM_ARRAYSIZE(GDataTypeInfo) == ImGuiDataType_COUNT);
|
||||
|
||||
@@ -2446,9 +2440,9 @@ bool ImGui::DragBehaviorT(ImGuiDataType data_type, TYPE* v, float v_speed, const
|
||||
if (g.ActiveIdSource == ImGuiInputSource_Mouse && IsMousePosValid() && IsMouseDragPastThreshold(0, g.IO.MouseDragThreshold * DRAG_MOUSE_THRESHOLD_FACTOR))
|
||||
{
|
||||
adjust_delta = g.IO.MouseDelta[axis];
|
||||
if (g.IO.KeyAlt && !(flags & ImGuiSliderFlags_NoSpeedTweaks))
|
||||
if (g.IO.KeyAlt)
|
||||
adjust_delta *= 1.0f / 100.0f;
|
||||
if (g.IO.KeyShift && !(flags & ImGuiSliderFlags_NoSpeedTweaks))
|
||||
if (g.IO.KeyShift)
|
||||
adjust_delta *= 10.0f;
|
||||
}
|
||||
else if (g.ActiveIdSource == ImGuiInputSource_Keyboard || g.ActiveIdSource == ImGuiInputSource_Gamepad)
|
||||
@@ -2456,7 +2450,7 @@ bool ImGui::DragBehaviorT(ImGuiDataType data_type, TYPE* v, float v_speed, const
|
||||
const int decimal_precision = is_floating_point ? ImParseFormatPrecision(format, 3) : 0;
|
||||
const bool tweak_slow = IsKeyDown((g.NavInputSource == ImGuiInputSource_Gamepad) ? ImGuiKey_NavGamepadTweakSlow : ImGuiKey_NavKeyboardTweakSlow);
|
||||
const bool tweak_fast = IsKeyDown((g.NavInputSource == ImGuiInputSource_Gamepad) ? ImGuiKey_NavGamepadTweakFast : ImGuiKey_NavKeyboardTweakFast);
|
||||
const float tweak_factor = (flags & ImGuiSliderFlags_NoSpeedTweaks) ? 1.0f : tweak_slow ? 1.0f / 10.0f : tweak_fast ? 10.0f : 1.0f;
|
||||
const float tweak_factor = tweak_slow ? 1.0f / 10.0f : tweak_fast ? 10.0f : 1.0f;
|
||||
adjust_delta = GetNavTweakPressedAmount(axis) * tweak_factor;
|
||||
v_speed = ImMax(v_speed, GetMinimumStepAtDecimalPrecision(decimal_precision));
|
||||
}
|
||||
@@ -2644,10 +2638,6 @@ bool ImGui::DragScalar(const char* label, ImGuiDataType data_type, void* p_data,
|
||||
temp_input_is_active = true;
|
||||
}
|
||||
|
||||
// Store initial value (not used by main lib but available as a convenience but some mods e.g. to revert)
|
||||
if (make_active)
|
||||
memcpy(&g.ActiveIdValueOnActivation, p_data, DataTypeGetInfo(data_type)->Size);
|
||||
|
||||
if (make_active && !temp_input_is_active)
|
||||
{
|
||||
SetActiveID(id, window);
|
||||
@@ -3238,10 +3228,6 @@ bool ImGui::SliderScalar(const char* label, ImGuiDataType data_type, void* p_dat
|
||||
if ((clicked && g.IO.KeyCtrl) || (g.NavActivateId == id && (g.NavActivateFlags & ImGuiActivateFlags_PreferInput)))
|
||||
temp_input_is_active = true;
|
||||
|
||||
// Store initial value (not used by main lib but available as a convenience but some mods e.g. to revert)
|
||||
if (make_active)
|
||||
memcpy(&g.ActiveIdValueOnActivation, p_data, DataTypeGetInfo(data_type)->Size);
|
||||
|
||||
if (make_active && !temp_input_is_active)
|
||||
{
|
||||
SetActiveID(id, window);
|
||||
@@ -3950,12 +3936,12 @@ static ImVec2 InputTextCalcTextSize(ImGuiContext* ctx, const char* text_begin, c
|
||||
namespace ImStb
|
||||
{
|
||||
static int STB_TEXTEDIT_STRINGLEN(const ImGuiInputTextState* obj) { return obj->TextLen; }
|
||||
static char STB_TEXTEDIT_GETCHAR(const ImGuiInputTextState* obj, int idx) { IM_ASSERT(idx <= obj->TextLen); return obj->TextSrc[idx]; }
|
||||
static float STB_TEXTEDIT_GETWIDTH(ImGuiInputTextState* obj, int line_start_idx, int char_idx) { unsigned int c; ImTextCharFromUtf8(&c, obj->TextSrc + line_start_idx + char_idx, obj->TextSrc + obj->TextLen); if ((ImWchar)c == '\n') return IMSTB_TEXTEDIT_GETWIDTH_NEWLINE; ImGuiContext& g = *obj->Ctx; return g.Font->GetCharAdvance((ImWchar)c) * g.FontScale; }
|
||||
static char STB_TEXTEDIT_GETCHAR(const ImGuiInputTextState* obj, int idx) { IM_ASSERT(idx <= obj->TextLen); return obj->TextA[idx]; }
|
||||
static float STB_TEXTEDIT_GETWIDTH(ImGuiInputTextState* obj, int line_start_idx, int char_idx) { unsigned int c; ImTextCharFromUtf8(&c, obj->TextA.Data + line_start_idx + char_idx, obj->TextA.Data + obj->TextLen); if ((ImWchar)c == '\n') return IMSTB_TEXTEDIT_GETWIDTH_NEWLINE; ImGuiContext& g = *obj->Ctx; return g.Font->GetCharAdvance((ImWchar)c) * g.FontScale; }
|
||||
static char STB_TEXTEDIT_NEWLINE = '\n';
|
||||
static void STB_TEXTEDIT_LAYOUTROW(StbTexteditRow* r, ImGuiInputTextState* obj, int line_start_idx)
|
||||
{
|
||||
const char* text = obj->TextSrc;
|
||||
const char* text = obj->TextA.Data;
|
||||
const char* text_remaining = NULL;
|
||||
const ImVec2 size = InputTextCalcTextSize(obj->Ctx, text + line_start_idx, text + obj->TextLen, &text_remaining, NULL, true);
|
||||
r->x0 = 0.0f;
|
||||
@@ -3974,15 +3960,15 @@ static int IMSTB_TEXTEDIT_GETNEXTCHARINDEX_IMPL(ImGuiInputTextState* obj, int id
|
||||
if (idx >= obj->TextLen)
|
||||
return obj->TextLen + 1;
|
||||
unsigned int c;
|
||||
return idx + ImTextCharFromUtf8(&c, obj->TextSrc + idx, obj->TextSrc + obj->TextLen);
|
||||
return idx + ImTextCharFromUtf8(&c, obj->TextA.Data + idx, obj->TextA.Data + obj->TextLen);
|
||||
}
|
||||
|
||||
static int IMSTB_TEXTEDIT_GETPREVCHARINDEX_IMPL(ImGuiInputTextState* obj, int idx)
|
||||
{
|
||||
if (idx <= 0)
|
||||
return -1;
|
||||
const char* p = ImTextFindPreviousUtf8Codepoint(obj->TextSrc, obj->TextSrc + idx);
|
||||
return (int)(p - obj->TextSrc);
|
||||
const char* p = ImTextFindPreviousUtf8Codepoint(obj->TextA.Data, obj->TextA.Data + idx);
|
||||
return (int)(p - obj->TextA.Data);
|
||||
}
|
||||
|
||||
static bool ImCharIsSeparatorW(unsigned int c)
|
||||
@@ -4005,10 +3991,10 @@ static int is_word_boundary_from_right(ImGuiInputTextState* obj, int idx)
|
||||
if ((obj->Flags & ImGuiInputTextFlags_Password) || idx <= 0)
|
||||
return 0;
|
||||
|
||||
const char* curr_p = obj->TextSrc + idx;
|
||||
const char* prev_p = ImTextFindPreviousUtf8Codepoint(obj->TextSrc, curr_p);
|
||||
unsigned int curr_c; ImTextCharFromUtf8(&curr_c, curr_p, obj->TextSrc + obj->TextLen);
|
||||
unsigned int prev_c; ImTextCharFromUtf8(&prev_c, prev_p, obj->TextSrc + obj->TextLen);
|
||||
const char* curr_p = obj->TextA.Data + idx;
|
||||
const char* prev_p = ImTextFindPreviousUtf8Codepoint(obj->TextA.Data, curr_p);
|
||||
unsigned int curr_c; ImTextCharFromUtf8(&curr_c, curr_p, obj->TextA.Data + obj->TextLen);
|
||||
unsigned int prev_c; ImTextCharFromUtf8(&prev_c, prev_p, obj->TextA.Data + obj->TextLen);
|
||||
|
||||
bool prev_white = ImCharIsBlankW(prev_c);
|
||||
bool prev_separ = ImCharIsSeparatorW(prev_c);
|
||||
@@ -4021,10 +4007,10 @@ static int is_word_boundary_from_left(ImGuiInputTextState* obj, int idx)
|
||||
if ((obj->Flags & ImGuiInputTextFlags_Password) || idx <= 0)
|
||||
return 0;
|
||||
|
||||
const char* curr_p = obj->TextSrc + idx;
|
||||
const char* prev_p = ImTextFindPreviousUtf8Codepoint(obj->TextSrc, curr_p);
|
||||
unsigned int prev_c; ImTextCharFromUtf8(&prev_c, curr_p, obj->TextSrc + obj->TextLen);
|
||||
unsigned int curr_c; ImTextCharFromUtf8(&curr_c, prev_p, obj->TextSrc + obj->TextLen);
|
||||
const char* curr_p = obj->TextA.Data + idx;
|
||||
const char* prev_p = ImTextFindPreviousUtf8Codepoint(obj->TextA.Data, curr_p);
|
||||
unsigned int prev_c; ImTextCharFromUtf8(&prev_c, curr_p, obj->TextA.Data + obj->TextLen);
|
||||
unsigned int curr_c; ImTextCharFromUtf8(&curr_c, prev_p, obj->TextA.Data + obj->TextLen);
|
||||
|
||||
bool prev_white = ImCharIsBlankW(prev_c);
|
||||
bool prev_separ = ImCharIsSeparatorW(prev_c);
|
||||
@@ -4061,13 +4047,16 @@ static int STB_TEXTEDIT_MOVEWORDRIGHT_IMPL(ImGuiInputTextState* obj, int idx)
|
||||
|
||||
static void STB_TEXTEDIT_DELETECHARS(ImGuiInputTextState* obj, int pos, int n)
|
||||
{
|
||||
// Offset remaining text (+ copy zero terminator)
|
||||
IM_ASSERT(obj->TextSrc == obj->TextA.Data);
|
||||
char* dst = obj->TextA.Data + pos;
|
||||
char* src = obj->TextA.Data + pos + n;
|
||||
memmove(dst, src, obj->TextLen - n - pos + 1);
|
||||
|
||||
obj->Edited = true;
|
||||
obj->TextLen -= n;
|
||||
|
||||
// Offset remaining text (FIXME-OPT: Use memmove)
|
||||
const char* src = obj->TextA.Data + pos + n;
|
||||
while (char c = *src++)
|
||||
*dst++ = c;
|
||||
*dst = '\0';
|
||||
}
|
||||
|
||||
static bool STB_TEXTEDIT_INSERTCHARS(ImGuiInputTextState* obj, int pos, const char* new_text, int new_text_len)
|
||||
@@ -4080,13 +4069,11 @@ static bool STB_TEXTEDIT_INSERTCHARS(ImGuiInputTextState* obj, int pos, const ch
|
||||
return false;
|
||||
|
||||
// Grow internal buffer if needed
|
||||
IM_ASSERT(obj->TextSrc == obj->TextA.Data);
|
||||
if (new_text_len + text_len + 1 > obj->TextA.Size)
|
||||
{
|
||||
if (!is_resizable)
|
||||
return false;
|
||||
obj->TextA.resize(text_len + ImClamp(new_text_len, 32, ImMax(256, new_text_len)) + 1);
|
||||
obj->TextSrc = obj->TextA.Data;
|
||||
}
|
||||
|
||||
char* text = obj->TextA.Data;
|
||||
@@ -4184,25 +4171,26 @@ int ImGuiInputTextState::GetCursorPos() const { return Stb->cursor
|
||||
int ImGuiInputTextState::GetSelectionStart() const { return Stb->select_start; }
|
||||
int ImGuiInputTextState::GetSelectionEnd() const { return Stb->select_end; }
|
||||
void ImGuiInputTextState::SelectAll() { Stb->select_start = 0; Stb->cursor = Stb->select_end = TextLen; Stb->has_preferred_x = 0; }
|
||||
void ImGuiInputTextState::ReloadUserBufAndSelectAll() { WantReloadUserBuf = true; ReloadSelectionStart = 0; ReloadSelectionEnd = INT_MAX; }
|
||||
void ImGuiInputTextState::ReloadUserBufAndKeepSelection() { WantReloadUserBuf = true; ReloadSelectionStart = Stb->select_start; ReloadSelectionEnd = Stb->select_end; }
|
||||
void ImGuiInputTextState::ReloadUserBufAndMoveToEnd() { WantReloadUserBuf = true; ReloadSelectionStart = ReloadSelectionEnd = INT_MAX; }
|
||||
void ImGuiInputTextState::ReloadUserBufAndSelectAll() { ReloadUserBuf = true; ReloadSelectionStart = 0; ReloadSelectionEnd = INT_MAX; }
|
||||
void ImGuiInputTextState::ReloadUserBufAndKeepSelection() { ReloadUserBuf = true; ReloadSelectionStart = Stb->select_start; ReloadSelectionEnd = Stb->select_end; }
|
||||
void ImGuiInputTextState::ReloadUserBufAndMoveToEnd() { ReloadUserBuf = true; ReloadSelectionStart = ReloadSelectionEnd = INT_MAX; }
|
||||
|
||||
ImGuiInputTextCallbackData::ImGuiInputTextCallbackData()
|
||||
{
|
||||
memset(this, 0, sizeof(*this));
|
||||
}
|
||||
|
||||
// Public API to manipulate UTF-8 text from within a callback.
|
||||
// Public API to manipulate UTF-8 text
|
||||
// We expose UTF-8 to the user (unlike the STB_TEXTEDIT_* functions which are manipulating wchar)
|
||||
// FIXME: The existence of this rarely exercised code path is a bit of a nuisance.
|
||||
// Historically they existed because STB_TEXTEDIT_INSERTCHARS() etc. worked on our ImWchar
|
||||
// buffer, but nowadays they both work on UTF-8 data. Should aim to merge both.
|
||||
void ImGuiInputTextCallbackData::DeleteChars(int pos, int bytes_count)
|
||||
{
|
||||
IM_ASSERT(pos + bytes_count <= BufTextLen);
|
||||
char* dst = Buf + pos;
|
||||
const char* src = Buf + pos + bytes_count;
|
||||
memmove(dst, src, BufTextLen - bytes_count - pos + 1);
|
||||
while (char c = *src++)
|
||||
*dst++ = c;
|
||||
*dst = '\0';
|
||||
|
||||
if (CursorPos >= pos + bytes_count)
|
||||
CursorPos -= bytes_count;
|
||||
@@ -4227,13 +4215,13 @@ void ImGuiInputTextCallbackData::InsertChars(int pos, const char* new_text, cons
|
||||
if (!is_resizable)
|
||||
return;
|
||||
|
||||
// Contrary to STB_TEXTEDIT_INSERTCHARS() this is working in the UTF8 buffer, hence the mildly similar code (until we remove the U16 buffer altogether!)
|
||||
ImGuiContext& g = *Ctx;
|
||||
ImGuiInputTextState* edit_state = &g.InputTextState;
|
||||
IM_ASSERT(edit_state->ID != 0 && g.ActiveId == edit_state->ID);
|
||||
IM_ASSERT(Buf == edit_state->TextA.Data);
|
||||
int new_buf_size = BufTextLen + ImClamp(new_text_len * 4, 32, ImMax(256, new_text_len)) + 1;
|
||||
edit_state->TextA.resize(new_buf_size + 1);
|
||||
edit_state->TextSrc = edit_state->TextA.Data;
|
||||
Buf = edit_state->TextA.Data;
|
||||
BufSize = edit_state->BufCapacity = new_buf_size;
|
||||
}
|
||||
@@ -4351,23 +4339,26 @@ static bool InputTextFilterCharacter(ImGuiContext* ctx, unsigned int* p_char, Im
|
||||
return true;
|
||||
}
|
||||
|
||||
// Find the shortest single replacement we can make to get from old_buf to new_buf
|
||||
// Note that this doesn't directly alter state->TextA, state->TextLen. They are expected to be made valid separately.
|
||||
// Find the shortest single replacement we can make to get the new text from the old text.
|
||||
// Important: needs to be run before TextW is rewritten with the new characters because calling STB_TEXTEDIT_GETCHAR() at the end.
|
||||
// FIXME: Ideally we should transition toward (1) making InsertChars()/DeleteChars() update undo-stack (2) discourage (and keep reconcile) or obsolete (and remove reconcile) accessing buffer directly.
|
||||
static void InputTextReconcileUndoState(ImGuiInputTextState* state, const char* old_buf, int old_length, const char* new_buf, int new_length)
|
||||
static void InputTextReconcileUndoStateAfterUserCallback(ImGuiInputTextState* state, const char* new_buf_a, int new_length_a)
|
||||
{
|
||||
const int shorter_length = ImMin(old_length, new_length);
|
||||
const char* old_buf = state->CallbackTextBackup.Data;
|
||||
const int old_length = state->CallbackTextBackup.Size - 1;
|
||||
|
||||
const int shorter_length = ImMin(old_length, new_length_a);
|
||||
int first_diff;
|
||||
for (first_diff = 0; first_diff < shorter_length; first_diff++)
|
||||
if (old_buf[first_diff] != new_buf[first_diff])
|
||||
if (old_buf[first_diff] != new_buf_a[first_diff])
|
||||
break;
|
||||
if (first_diff == old_length && first_diff == new_length)
|
||||
if (first_diff == old_length && first_diff == new_length_a)
|
||||
return;
|
||||
|
||||
int old_last_diff = old_length - 1;
|
||||
int new_last_diff = new_length - 1;
|
||||
int new_last_diff = new_length_a - 1;
|
||||
for (; old_last_diff >= first_diff && new_last_diff >= first_diff; old_last_diff--, new_last_diff--)
|
||||
if (old_buf[old_last_diff] != new_buf[new_last_diff])
|
||||
if (old_buf[old_last_diff] != new_buf_a[new_last_diff])
|
||||
break;
|
||||
|
||||
const int insert_len = new_last_diff - first_diff + 1;
|
||||
@@ -4396,7 +4387,6 @@ void ImGui::InputTextDeactivateHook(ImGuiID id)
|
||||
else
|
||||
{
|
||||
IM_ASSERT(state->TextA.Data != 0);
|
||||
IM_ASSERT(state->TextA[state->TextLen] == 0);
|
||||
g.InputTextDeactivatedState.TextA.resize(state->TextLen + 1);
|
||||
memcpy(g.InputTextDeactivatedState.TextA.Data, state->TextA.Data, state->TextLen + 1);
|
||||
}
|
||||
@@ -4520,67 +4510,64 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
||||
|
||||
float scroll_y = is_multiline ? draw_window->Scroll.y : FLT_MAX;
|
||||
|
||||
const bool init_reload_from_user_buf = (state != NULL && state->WantReloadUserBuf);
|
||||
const bool init_reload_from_user_buf = (state != NULL && state->ReloadUserBuf);
|
||||
const bool init_changed_specs = (state != NULL && state->Stb->single_line != !is_multiline); // state != NULL means its our state.
|
||||
const bool init_make_active = (user_clicked || user_scroll_finish || input_requested_by_nav);
|
||||
const bool init_state = (init_make_active || user_scroll_active);
|
||||
if (init_reload_from_user_buf)
|
||||
{
|
||||
int new_len = (int)strlen(buf);
|
||||
IM_ASSERT(new_len + 1 <= buf_size && "Is your input buffer properly zero-terminated?");
|
||||
state->WantReloadUserBuf = false;
|
||||
InputTextReconcileUndoState(state, state->TextA.Data, state->TextLen, buf, new_len);
|
||||
state->TextA.resize(buf_size + 1); // we use +1 to make sure that .Data is always pointing to at least an empty string.
|
||||
state->TextLen = new_len;
|
||||
memcpy(state->TextA.Data, buf, state->TextLen + 1);
|
||||
state->Stb->select_start = state->ReloadSelectionStart;
|
||||
state->Stb->cursor = state->Stb->select_end = state->ReloadSelectionEnd;
|
||||
state->CursorClamp();
|
||||
}
|
||||
else if ((init_state && g.ActiveId != id) || init_changed_specs)
|
||||
if ((init_state && g.ActiveId != id) || init_changed_specs || init_reload_from_user_buf)
|
||||
{
|
||||
// Access state even if we don't own it yet.
|
||||
state = &g.InputTextState;
|
||||
state->CursorAnimReset();
|
||||
state->ReloadUserBuf = false;
|
||||
|
||||
// Backup state of deactivating item so they'll have a chance to do a write to output buffer on the same frame they report IsItemDeactivatedAfterEdit (#4714)
|
||||
InputTextDeactivateHook(state->ID);
|
||||
|
||||
// Take a copy of the initial buffer value.
|
||||
// From the moment we focused we are normally ignoring the content of 'buf' (unless we are in read-only mode)
|
||||
const int buf_len = (int)strlen(buf);
|
||||
IM_ASSERT(buf_len + 1 <= buf_size && "Is your input buffer properly zero-terminated?");
|
||||
state->TextToRevertTo.resize(buf_len + 1); // UTF-8. we use +1 to make sure that .Data is always pointing to at least an empty string.
|
||||
memcpy(state->TextToRevertTo.Data, buf, buf_len + 1);
|
||||
if (!init_reload_from_user_buf)
|
||||
{
|
||||
// Take a copy of the initial buffer value.
|
||||
state->TextToRevertTo.resize(buf_len + 1); // UTF-8. we use +1 to make sure that .Data is always pointing to at least an empty string.
|
||||
memcpy(state->TextToRevertTo.Data, buf, buf_len + 1);
|
||||
}
|
||||
|
||||
// Preserve cursor position and undo/redo stack if we come back to same widget
|
||||
// FIXME: Since we reworked this on 2022/06, may want to differentiate recycle_cursor vs recycle_undostate?
|
||||
bool recycle_state = (state->ID == id && !init_changed_specs);
|
||||
if (recycle_state && (state->TextLen != buf_len || (state->TextA.Data == NULL || strncmp(state->TextA.Data, buf, buf_len) != 0)))
|
||||
bool recycle_state = (state->ID == id && !init_changed_specs && !init_reload_from_user_buf);
|
||||
if (recycle_state && (state->TextLen != buf_len || (strncmp(state->TextA.Data, buf, buf_len) != 0)))
|
||||
recycle_state = false;
|
||||
|
||||
// Start edition
|
||||
state->ID = id;
|
||||
state->TextLen = buf_len;
|
||||
if (!is_readonly)
|
||||
{
|
||||
state->TextA.resize(buf_size + 1); // we use +1 to make sure that .Data is always pointing to at least an empty string.
|
||||
memcpy(state->TextA.Data, buf, state->TextLen + 1);
|
||||
}
|
||||
state->TextA.resize(buf_size + 1); // we use +1 to make sure that .Data is always pointing to at least an empty string.
|
||||
state->TextLen = (int)strlen(buf);
|
||||
memcpy(state->TextA.Data, buf, state->TextLen + 1);
|
||||
|
||||
// Find initial scroll position for right alignment
|
||||
state->Scroll = ImVec2(0.0f, 0.0f);
|
||||
if (flags & ImGuiInputTextFlags_ElideLeft)
|
||||
state->Scroll.x += ImMax(0.0f, CalcTextSize(buf).x - frame_size.x + style.FramePadding.x * 2.0f);
|
||||
|
||||
// Recycle existing cursor/selection/undo stack but clamp position
|
||||
// Note a single mouse click will override the cursor/position immediately by calling stb_textedit_click handler.
|
||||
if (recycle_state)
|
||||
{
|
||||
// Recycle existing cursor/selection/undo stack but clamp position
|
||||
// Note a single mouse click will override the cursor/position immediately by calling stb_textedit_click handler.
|
||||
state->CursorClamp();
|
||||
}
|
||||
else
|
||||
{
|
||||
stb_textedit_initialize_state(state->Stb, !is_multiline);
|
||||
}
|
||||
|
||||
if (!is_multiline)
|
||||
if (init_reload_from_user_buf)
|
||||
{
|
||||
state->Stb->select_start = state->ReloadSelectionStart;
|
||||
state->Stb->cursor = state->Stb->select_end = state->ReloadSelectionEnd;
|
||||
state->CursorClamp();
|
||||
}
|
||||
else if (!is_multiline)
|
||||
{
|
||||
if (flags & ImGuiInputTextFlags_AutoSelectAll)
|
||||
select_all = true;
|
||||
@@ -4630,15 +4617,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
||||
// Expose scroll in a manner that is agnostic to us using a child window
|
||||
if (is_multiline && state != NULL)
|
||||
state->Scroll.y = draw_window->Scroll.y;
|
||||
|
||||
// Read-only mode always ever read from source buffer. Refresh TextLen when active.
|
||||
if (is_readonly && state != NULL)
|
||||
state->TextLen = (int)strlen(buf);
|
||||
//if (is_readonly && state != NULL)
|
||||
// state->TextA.clear(); // Uncomment to facilitate debugging, but we otherwise prefer to keep/amortize th allocation.
|
||||
}
|
||||
if (state != NULL)
|
||||
state->TextSrc = is_readonly ? buf : state->TextA.Data;
|
||||
|
||||
// We have an edge case if ActiveId was set through another widget (e.g. widget being swapped), clear id immediately (don't wait until the end of the function)
|
||||
if (g.ActiveId == id && state == NULL)
|
||||
@@ -4903,13 +4882,13 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
||||
// Cut, Copy
|
||||
if (g.PlatformIO.Platform_SetClipboardTextFn != NULL)
|
||||
{
|
||||
// SetClipboardText() only takes null terminated strings + state->TextSrc may point to read-only user buffer, so we need to make a copy.
|
||||
const int ib = state->HasSelection() ? ImMin(state->Stb->select_start, state->Stb->select_end) : 0;
|
||||
const int ie = state->HasSelection() ? ImMax(state->Stb->select_start, state->Stb->select_end) : state->TextLen;
|
||||
g.TempBuffer.reserve(ie - ib + 1);
|
||||
memcpy(g.TempBuffer.Data, state->TextSrc + ib, ie - ib);
|
||||
g.TempBuffer.Data[ie - ib] = 0;
|
||||
SetClipboardText(g.TempBuffer.Data);
|
||||
|
||||
char backup = state->TextA.Data[ie];
|
||||
state->TextA.Data[ie] = 0; // A bit of a hack since SetClipboardText only takes null terminated strings
|
||||
SetClipboardText(state->TextA.Data + ib);
|
||||
state->TextA.Data[ie] = backup;
|
||||
}
|
||||
if (is_cut)
|
||||
{
|
||||
@@ -4925,27 +4904,25 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
||||
{
|
||||
// Filter pasted buffer
|
||||
const int clipboard_len = (int)strlen(clipboard);
|
||||
ImVector<char> clipboard_filtered;
|
||||
clipboard_filtered.reserve(clipboard_len + 1);
|
||||
char* clipboard_filtered = (char*)IM_ALLOC(clipboard_len + 1);
|
||||
int clipboard_filtered_len = 0;
|
||||
for (const char* s = clipboard; *s != 0; )
|
||||
{
|
||||
unsigned int c;
|
||||
int in_len = ImTextCharFromUtf8(&c, s, NULL);
|
||||
s += in_len;
|
||||
int len = ImTextCharFromUtf8(&c, s, NULL);
|
||||
s += len;
|
||||
if (!InputTextFilterCharacter(&g, &c, flags, callback, callback_user_data, true))
|
||||
continue;
|
||||
char c_utf8[5];
|
||||
ImTextCharToUtf8(c_utf8, c);
|
||||
int out_len = (int)strlen(c_utf8);
|
||||
clipboard_filtered.resize(clipboard_filtered.Size + out_len);
|
||||
memcpy(clipboard_filtered.Data + clipboard_filtered.Size - out_len, c_utf8, out_len);
|
||||
memcpy(clipboard_filtered + clipboard_filtered_len, s - len, len);
|
||||
clipboard_filtered_len += len;
|
||||
}
|
||||
if (clipboard_filtered.Size > 0) // If everything was filtered, ignore the pasting operation
|
||||
clipboard_filtered[clipboard_filtered_len] = 0;
|
||||
if (clipboard_filtered_len > 0) // If everything was filtered, ignore the pasting operation
|
||||
{
|
||||
clipboard_filtered.push_back(0);
|
||||
stb_textedit_paste(state, state->Stb, clipboard_filtered.Data, clipboard_filtered.Size - 1);
|
||||
stb_textedit_paste(state, state->Stb, clipboard_filtered, clipboard_filtered_len);
|
||||
state->CursorFollow = true;
|
||||
}
|
||||
MemFree(clipboard_filtered);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4983,17 +4960,19 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME-OPT: We always reapply the live buffer back to the input buffer before clearing ActiveId,
|
||||
// even though strictly speaking it wasn't modified on this frame. Should mark dirty state from the stb_textedit callbacks.
|
||||
// If we do that, need to ensure that as special case, 'validated == true' also writes back.
|
||||
// This also allows the user to use InputText() without maintaining any user-side storage.
|
||||
// When using 'ImGuiInputTextFlags_EnterReturnsTrue' as a special case we reapply the live buffer back to the input buffer
|
||||
// before clearing ActiveId, even though strictly speaking it wasn't modified on this frame.
|
||||
// If we didn't do that, code like InputInt() with ImGuiInputTextFlags_EnterReturnsTrue would fail.
|
||||
// This also allows the user to use InputText() with ImGuiInputTextFlags_EnterReturnsTrue without maintaining any user-side storage
|
||||
// (please note that if you use this property along ImGuiInputTextFlags_CallbackResize you can end up with your temporary string object
|
||||
// unnecessarily allocating once a frame, either store your string data, either if you don't then don't use ImGuiInputTextFlags_CallbackResize).
|
||||
const bool apply_edit_back_to_user_buffer = true;// !revert_edit || (validated && (flags & ImGuiInputTextFlags_EnterReturnsTrue) != 0);
|
||||
const bool apply_edit_back_to_user_buffer = !revert_edit || (validated && (flags & ImGuiInputTextFlags_EnterReturnsTrue) != 0);
|
||||
if (apply_edit_back_to_user_buffer)
|
||||
{
|
||||
// Apply current edited text immediately.
|
||||
// Apply new value immediately - copy modified buffer back
|
||||
// Note that as soon as the input box is active, the in-widget value gets priority over any underlying modification of the input buffer
|
||||
// FIXME: We actually always render 'buf' when calling DrawList->AddText, making the comment above incorrect.
|
||||
// FIXME-OPT: CPU waste to do this every time the widget is active, should mark dirty state from the stb_textedit callbacks.
|
||||
|
||||
// User callback
|
||||
if ((flags & (ImGuiInputTextFlags_CallbackCompletion | ImGuiInputTextFlags_CallbackHistory | ImGuiInputTextFlags_CallbackEdit | ImGuiInputTextFlags_CallbackAlways)) != 0)
|
||||
@@ -5036,11 +5015,10 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
||||
callback_data.UserData = callback_user_data;
|
||||
|
||||
// FIXME-OPT: Undo stack reconcile needs a backup of the data until we rework API, see #7925
|
||||
char* callback_buf = is_readonly ? buf : state->TextA.Data;
|
||||
IM_ASSERT(callback_buf == state->TextSrc);
|
||||
state->CallbackTextBackup.resize(state->TextLen + 1);
|
||||
memcpy(state->CallbackTextBackup.Data, callback_buf, state->TextLen + 1);
|
||||
memcpy(state->CallbackTextBackup.Data, state->TextA.Data, state->TextLen + 1);
|
||||
|
||||
char* callback_buf = is_readonly ? buf : state->TextA.Data;
|
||||
callback_data.EventKey = event_key;
|
||||
callback_data.Buf = callback_buf;
|
||||
callback_data.BufTextLen = state->TextLen;
|
||||
@@ -5067,7 +5045,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
||||
{
|
||||
// Callback may update buffer and thus set buf_dirty even in read-only mode.
|
||||
IM_ASSERT(callback_data.BufTextLen == (int)strlen(callback_data.Buf)); // You need to maintain BufTextLen if you change the text!
|
||||
InputTextReconcileUndoState(state, state->CallbackTextBackup.Data, state->CallbackTextBackup.Size - 1, callback_data.Buf, callback_data.BufTextLen);
|
||||
InputTextReconcileUndoStateAfterUserCallback(state, callback_data.Buf, callback_data.BufTextLen); // FIXME: Move the rest of this block inside function and rename to InputTextReconcileStateAfterUserCallback() ?
|
||||
state->TextLen = callback_data.BufTextLen; // Assume correct length and valid UTF-8 from user, saves us an extra strlen()
|
||||
state->CursorAnimReset();
|
||||
}
|
||||
@@ -5075,9 +5053,9 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
||||
}
|
||||
|
||||
// Will copy result string if modified
|
||||
if (!is_readonly && strcmp(state->TextSrc, buf) != 0)
|
||||
if (!is_readonly && strcmp(state->TextA.Data, buf) != 0)
|
||||
{
|
||||
apply_new_text = state->TextSrc;
|
||||
apply_new_text = state->TextA.Data;
|
||||
apply_new_text_length = state->TextLen;
|
||||
value_changed = true;
|
||||
}
|
||||
@@ -5171,7 +5149,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
||||
// - Measure text height (for scrollbar)
|
||||
// We are attempting to do most of that in **one main pass** to minimize the computation cost (non-negligible for large amount of text) + 2nd pass for selection rendering (we could merge them by an extra refactoring effort)
|
||||
// FIXME: This should occur on buf_display but we'd need to maintain cursor/select_start/select_end for UTF-8.
|
||||
const char* text_begin = buf_display;
|
||||
const char* text_begin = state->TextA.Data;
|
||||
const char* text_end = text_begin + state->TextLen;
|
||||
ImVec2 cursor_offset, select_start_offset;
|
||||
|
||||
@@ -5352,8 +5330,6 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
||||
g.LastItemData.StatusFlags = item_data_backup.StatusFlags;
|
||||
}
|
||||
}
|
||||
if (state)
|
||||
state->TextSrc = NULL;
|
||||
|
||||
// Log as text
|
||||
if (g.LogEnabled && (!is_password || is_displaying_hint))
|
||||
@@ -6539,11 +6515,10 @@ bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* l
|
||||
// We vertically grow up to current line height up the typical widget height.
|
||||
const float frame_height = ImMax(ImMin(window->DC.CurrLineSize.y, g.FontSize + style.FramePadding.y * 2), label_size.y + padding.y * 2);
|
||||
const bool span_all_columns = (flags & ImGuiTreeNodeFlags_SpanAllColumns) != 0 && (g.CurrentTable != NULL);
|
||||
const bool span_all_columns_label = (flags & ImGuiTreeNodeFlags_LabelSpanAllColumns) != 0 && (g.CurrentTable != NULL);
|
||||
ImRect frame_bb;
|
||||
frame_bb.Min.x = span_all_columns ? window->ParentWorkRect.Min.x : (flags & ImGuiTreeNodeFlags_SpanFullWidth) ? window->WorkRect.Min.x : window->DC.CursorPos.x;
|
||||
frame_bb.Min.y = window->DC.CursorPos.y;
|
||||
frame_bb.Max.x = span_all_columns ? window->ParentWorkRect.Max.x : (flags & ImGuiTreeNodeFlags_SpanLabelWidth) ? window->DC.CursorPos.x + text_width + padding.x : window->WorkRect.Max.x;
|
||||
frame_bb.Max.x = span_all_columns ? window->ParentWorkRect.Max.x : (flags & ImGuiTreeNodeFlags_SpanTextWidth) ? window->DC.CursorPos.x + text_width + padding.x : window->WorkRect.Max.x;
|
||||
frame_bb.Max.y = window->DC.CursorPos.y + frame_height;
|
||||
if (display_frame)
|
||||
{
|
||||
@@ -6557,7 +6532,7 @@ bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* l
|
||||
|
||||
// For regular tree nodes, we arbitrary allow to click past 2 worth of ItemSpacing
|
||||
ImRect interact_bb = frame_bb;
|
||||
if ((flags & (ImGuiTreeNodeFlags_Framed | ImGuiTreeNodeFlags_SpanAvailWidth | ImGuiTreeNodeFlags_SpanFullWidth | ImGuiTreeNodeFlags_SpanLabelWidth | ImGuiTreeNodeFlags_SpanAllColumns)) == 0)
|
||||
if ((flags & (ImGuiTreeNodeFlags_Framed | ImGuiTreeNodeFlags_SpanAvailWidth | ImGuiTreeNodeFlags_SpanFullWidth | ImGuiTreeNodeFlags_SpanTextWidth | ImGuiTreeNodeFlags_SpanAllColumns)) == 0)
|
||||
interact_bb.Max.x = frame_bb.Min.x + text_width + (label_size.x > 0.0f ? style.ItemSpacing.x * 2.0f : 0.0f);
|
||||
|
||||
// Compute open and multi-select states before ItemAdd() as it clear NextItem data.
|
||||
@@ -6565,7 +6540,7 @@ bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* l
|
||||
bool is_open = TreeNodeUpdateNextOpen(storage_id, flags);
|
||||
|
||||
bool is_visible;
|
||||
if (span_all_columns || span_all_columns_label)
|
||||
if (span_all_columns)
|
||||
{
|
||||
// Modify ClipRect for the ItemAdd(), faster than doing a PushColumnsBackground/PushTableBackgroundChannel for every Selectable..
|
||||
const float backup_clip_rect_min_x = window->ClipRect.Min.x;
|
||||
@@ -6606,7 +6581,7 @@ bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* l
|
||||
return is_open;
|
||||
}
|
||||
|
||||
if (span_all_columns || span_all_columns_label)
|
||||
if (span_all_columns)
|
||||
{
|
||||
TablePushBackgroundChannel();
|
||||
g.LastItemData.StatusFlags |= ImGuiItemStatusFlags_HasClipRect;
|
||||
@@ -6759,7 +6734,7 @@ bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* l
|
||||
LogSetNextTextDecoration(">", NULL);
|
||||
}
|
||||
|
||||
if (span_all_columns && !span_all_columns_label)
|
||||
if (span_all_columns)
|
||||
TablePopBackgroundChannel();
|
||||
|
||||
// Label
|
||||
@@ -6767,9 +6742,6 @@ bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* l
|
||||
RenderTextClipped(text_pos, frame_bb.Max, label, label_end, &label_size);
|
||||
else
|
||||
RenderText(text_pos, label, label_end, false);
|
||||
|
||||
if (span_all_columns_label)
|
||||
TablePopBackgroundChannel();
|
||||
}
|
||||
|
||||
if (store_tree_node_stack_data && is_open)
|
||||
@@ -7528,12 +7500,6 @@ ImGuiMultiSelectIO* ImGui::BeginMultiSelect(ImGuiMultiSelectFlags flags, int sel
|
||||
if (flags & ImGuiMultiSelectFlags_BoxSelect2d)
|
||||
flags &= ~ImGuiMultiSelectFlags_BoxSelect1d;
|
||||
|
||||
// FIXME: Workaround to the fact we override CursorMaxPos, meaning size measurement are lost. (#8250)
|
||||
// They should perhaps be stacked properly?
|
||||
if (ImGuiTable* table = g.CurrentTable)
|
||||
if (table->CurrentColumn != -1)
|
||||
TableEndCell(table); // This is currently safe to call multiple time. If that properly is lost we can extract the "save measurement" part of it.
|
||||
|
||||
// FIXME: BeginFocusScope()
|
||||
const ImGuiID id = window->IDStack.back();
|
||||
ms->Clear();
|
||||
@@ -8247,10 +8213,15 @@ void ImGuiSelectionExternalStorage::ApplyRequests(ImGuiMultiSelectIO* ms_io)
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
// This is essentially a thin wrapper to using BeginChild/EndChild with the ImGuiChildFlags_FrameStyle flag for stylistic changes + displaying a label.
|
||||
// This handle some subtleties with capturing info from the label.
|
||||
// If you don't need a label you can pretty much directly use ImGui::BeginChild() with ImGuiChildFlags_FrameStyle.
|
||||
// This handle some subtleties with capturing info from the label, but for 99% uses it could essentially be rewritten as:
|
||||
// if (ImGui::BeginChild("...", ImVec2(ImGui::CalcItemWidth(), ImGui::GetTextLineHeight() * 7.5f), ImGuiChildFlags_FrameStyle))
|
||||
// { .... }
|
||||
// ImGui::EndChild();
|
||||
// ImGui::SameLine();
|
||||
// ImGui::AlignTextToFramePadding();
|
||||
// ImGui::Text("Label");
|
||||
// Tip: To have a list filling the entire window width, use size.x = -FLT_MIN and pass an non-visible label e.g. "##empty"
|
||||
// Tip: If your vertical size is calculated from an item count (e.g. 10 * item_height) consider adding a fractional part to facilitate seeing scrolling boundaries (e.g. 10.5f * item_height).
|
||||
// Tip: If your vertical size is calculated from an item count (e.g. 10 * item_height) consider adding a fractional part to facilitate seeing scrolling boundaries (e.g. 10.25 * item_height).
|
||||
bool ImGui::BeginListBox(const char* label, const ImVec2& size_arg)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
@@ -8730,7 +8701,7 @@ bool ImGui::BeginViewportSideBar(const char* name, ImGuiViewport* viewport_p, Im
|
||||
viewport->BuildWorkInsetMax[axis] += axis_size;
|
||||
}
|
||||
|
||||
window_flags |= ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove;
|
||||
window_flags |= ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoDocking;
|
||||
|
||||
// Create window
|
||||
SetNextWindowViewport(viewport->ID); // Enforce viewport so we don't create our own viewport when ImGuiConfigFlags_ViewportsNoMerge is set.
|
||||
|
||||
@@ -44,7 +44,7 @@ if (EMSCRIPTEN)
|
||||
target_link_options(main PRIVATE -sEXPORTED_RUNTIME_METHODS=ccall)
|
||||
target_link_options(main PRIVATE -sFETCH)
|
||||
target_link_options(main PRIVATE -sWASM_BIGINT)
|
||||
target_link_options(main PRIVATE -O2)
|
||||
target_link_options(main PRIVATE -O1)
|
||||
target_link_options(main PRIVATE -sLEGACY_GL_EMULATION)
|
||||
target_link_options(main PRIVATE -fsanitize=null)
|
||||
target_link_options(main PRIVATE -fsanitize-minimal-runtime)
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user