mirror of
https://github.com/WerWolv/ImHex.git
synced 2026-03-31 05:15:55 -05:00
Compare commits
434 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e6a08b9c18 | ||
|
|
e8027293bf | ||
|
|
0e00555703 | ||
|
|
a251c7325a | ||
|
|
e5d664bc07 | ||
|
|
460d5a9386 | ||
|
|
df06dd49c5 | ||
|
|
096bdef25a | ||
|
|
5286a2d9ae | ||
|
|
714b62049c | ||
|
|
1eb6f781b3 | ||
|
|
b4c2f7d371 | ||
|
|
424bba71f7 | ||
|
|
36a4930b35 | ||
|
|
9227fba474 | ||
|
|
4a8e59a95b | ||
|
|
bd5da4a36e | ||
|
|
a926b7b912 | ||
|
|
179e222919 | ||
|
|
1b98afe37d | ||
|
|
cfb4b5bd51 | ||
|
|
8e7bfb7f1a | ||
|
|
15bcf71aaf | ||
|
|
5b38c43b7e | ||
|
|
4d7d449cea | ||
|
|
ac100936c7 | ||
|
|
5eb289f1fe | ||
|
|
fe7ae9450b | ||
|
|
91d05c5de6 | ||
|
|
ac019a7d7e | ||
|
|
8c306a5d3d | ||
|
|
785ecb8a78 | ||
|
|
fa352b6917 | ||
|
|
29f50bb70b | ||
|
|
83bbde8d29 | ||
|
|
d69eee55dd | ||
|
|
d9ec628333 | ||
|
|
16a1ae3010 | ||
|
|
8603ec1c99 | ||
|
|
0a3cfe001d | ||
|
|
ee8e1996d9 | ||
|
|
0ab565ab02 | ||
|
|
744b9f574c | ||
|
|
f259e347aa | ||
|
|
b330829f09 | ||
|
|
5a59bc2abc | ||
|
|
8dd76a6cc8 | ||
|
|
b4cbfa02cf | ||
|
|
073eee8fab | ||
|
|
5c7a529fa1 | ||
|
|
3bd01c0d98 | ||
|
|
a3d71b1dca | ||
|
|
319068eef5 | ||
|
|
bc6d33e4fb | ||
|
|
004d99fc3a | ||
|
|
49b5deb9f4 | ||
|
|
47ca69b80e | ||
|
|
8990fad85a | ||
|
|
ab2458bdf4 | ||
|
|
97f15c04b4 | ||
|
|
a1b937b1fb | ||
|
|
896c13a612 | ||
|
|
27e5f8eeb6 | ||
|
|
362f8acb15 | ||
|
|
b58bc685e1 | ||
|
|
9ff92aeb40 | ||
|
|
0b52092eda | ||
|
|
0300d77fdb | ||
|
|
4839558429 | ||
|
|
b8e383368d | ||
|
|
51d9d37d1a | ||
|
|
8e46751e98 | ||
|
|
b0b9ce0cf8 | ||
|
|
09d3ecde2a | ||
|
|
8ed03051c3 | ||
|
|
104000fbc4 | ||
|
|
9bc569bf9a | ||
|
|
7f4cc6e5c0 | ||
|
|
0aacf1d07f | ||
|
|
b6e2bbc434 | ||
|
|
9a97c6c328 | ||
|
|
e04511269a | ||
|
|
ff566aa51f | ||
|
|
3e3a5273c0 | ||
|
|
367356f7f5 | ||
|
|
f4dd79ab43 | ||
|
|
f9fa58a6ea | ||
|
|
9c055ea1fd | ||
|
|
046a5866bf | ||
|
|
22d75ed856 | ||
|
|
a641f27b7e | ||
|
|
f0ab13ebc3 | ||
|
|
31426a289c | ||
|
|
78a87baa94 | ||
|
|
b2648afc7b | ||
|
|
be738eb5e7 | ||
|
|
740619529c | ||
|
|
441f4a9fc7 | ||
|
|
cd200b978b | ||
|
|
0a8368d639 | ||
|
|
9ade281a92 | ||
|
|
eb066b3539 | ||
|
|
00648c9673 | ||
|
|
c7d179d68e | ||
|
|
c1ad816211 | ||
|
|
4328a335ec | ||
|
|
d3e47245d6 | ||
|
|
0e32dd667d | ||
|
|
95437b2afe | ||
|
|
d15307a237 | ||
|
|
ac76e47b94 | ||
|
|
df50f1934e | ||
|
|
dc85616549 | ||
|
|
8ae15abb85 | ||
|
|
84a6fff034 | ||
|
|
c09a8bca7f | ||
|
|
90e0aa83d8 | ||
|
|
81652e3650 | ||
|
|
bdd2f51497 | ||
|
|
688e921034 | ||
|
|
e27993aff2 | ||
|
|
46388f4707 | ||
|
|
d68b931013 | ||
|
|
8807d6c6f3 | ||
|
|
14adcc0e51 | ||
|
|
a09aec032f | ||
|
|
7784fca0d4 | ||
|
|
68bd5569ce | ||
|
|
60e1c23a6b | ||
|
|
77fbb54ebc | ||
|
|
9b7b782020 | ||
|
|
bb3e0c126f | ||
|
|
3aeb9f31b0 | ||
|
|
8b19f0c3c0 | ||
|
|
73e259d6e7 | ||
|
|
f9039f4b34 | ||
|
|
5fb046ad1f | ||
|
|
7b089a1f2f | ||
|
|
867faef496 | ||
|
|
557313ae1e | ||
|
|
e4c2049975 | ||
|
|
b4ef19dac7 | ||
|
|
dc6c1fa622 | ||
|
|
d9db8401e2 | ||
|
|
9fe8a0f491 | ||
|
|
43d6b48cab | ||
|
|
ad40c53eb2 | ||
|
|
c71c610eba | ||
|
|
cf1fe04431 | ||
|
|
8f16a733b9 | ||
|
|
bc4991f915 | ||
|
|
7a8e923b41 | ||
|
|
e54dbcf574 | ||
|
|
c5d023822d | ||
|
|
e28d6e7451 | ||
|
|
9f275cc84f | ||
|
|
575903f921 | ||
|
|
02b3b94804 | ||
|
|
17ecdbf8ec | ||
|
|
80e0782fdb | ||
|
|
c505b5b9cb | ||
|
|
99f37504de | ||
|
|
69f4c6e5e9 | ||
|
|
fd98db1b70 | ||
|
|
205f3a327e | ||
|
|
750f7463cc | ||
|
|
f84b661af7 | ||
|
|
56330686be | ||
|
|
a41e91a731 | ||
|
|
e758b16ba3 | ||
|
|
e48c61cf27 | ||
|
|
08c802f733 | ||
|
|
7e4babaca8 | ||
|
|
f65c792191 | ||
|
|
e572c5776d | ||
|
|
5d1e53f469 | ||
|
|
bef20f7808 | ||
|
|
b47736b595 | ||
|
|
2dbfbe70af | ||
|
|
3f1d9ed366 | ||
|
|
b30bb21646 | ||
|
|
acfd5aa02f | ||
|
|
d8b16766f5 | ||
|
|
b902cc6531 | ||
|
|
2248cd96b1 | ||
|
|
01b7059582 | ||
|
|
7fd0d87d56 | ||
|
|
be515d4c40 | ||
|
|
ceee311efa | ||
|
|
f137d759c8 | ||
|
|
f5250d6bcf | ||
|
|
af42d2ff66 | ||
|
|
f1339f8b4a | ||
|
|
eed7ef1ac3 | ||
|
|
c7c654d310 | ||
|
|
94a7d3116a | ||
|
|
e770fcd197 | ||
|
|
5a0f965125 | ||
|
|
206be8b110 | ||
|
|
4189700a3b | ||
|
|
9a968674d6 | ||
|
|
18c9340950 | ||
|
|
78ef07cf0f | ||
|
|
d510f8c7cf | ||
|
|
2180a8faef | ||
|
|
2340ab0518 | ||
|
|
de5c6a4084 | ||
|
|
ce06d9bdfb | ||
|
|
33c11baca9 | ||
|
|
8fbdcd54aa | ||
|
|
20d3a84fc0 | ||
|
|
58a65b0004 | ||
|
|
bbd00a6020 | ||
|
|
63f544918d | ||
|
|
93938d6090 | ||
|
|
144e30775f | ||
|
|
f74eff8934 | ||
|
|
8ba96904a6 | ||
|
|
dbbc525174 | ||
|
|
b9324f44e6 | ||
|
|
d6c5e3dc3e | ||
|
|
7c350dde90 | ||
|
|
2c1759ce0a | ||
|
|
7f5a32a83b | ||
|
|
379f77af48 | ||
|
|
4b59d57f89 | ||
|
|
15b3860f83 | ||
|
|
b71a9b7d14 | ||
|
|
85352868ec | ||
|
|
310059f274 | ||
|
|
b5cc3b6f1b | ||
|
|
de9421e68f | ||
|
|
413443aa95 | ||
|
|
82d7c54a3d | ||
|
|
9123b21e18 | ||
|
|
56cca88fbd | ||
|
|
9b853350f1 | ||
|
|
e3b5a55eba | ||
|
|
366dc80dc0 | ||
|
|
ba2ee6d6e5 | ||
|
|
6afcf1a26f | ||
|
|
ee831fbcb6 | ||
|
|
4d87eefbe9 | ||
|
|
ec04fea9be | ||
|
|
1586aee2d2 | ||
|
|
226169bbbe | ||
|
|
e1e73077a1 | ||
|
|
7b5cfcb817 | ||
|
|
b3645ec945 | ||
|
|
7d06460e54 | ||
|
|
485761f45c | ||
|
|
f3d788de16 | ||
|
|
b06f5630c7 | ||
|
|
5c96a28fb6 | ||
|
|
9425569784 | ||
|
|
8b982b977b | ||
|
|
7a9d7b59e8 | ||
|
|
4720cf9fbe | ||
|
|
68f93c5e3d | ||
|
|
7b8330f8f8 | ||
|
|
63696b9f5f | ||
|
|
727b3c6b10 | ||
|
|
05cb3831a2 | ||
|
|
5b51375404 | ||
|
|
398e845e8d | ||
|
|
45c29888b4 | ||
|
|
82c5bd528c | ||
|
|
45d0b614c2 | ||
|
|
4725ff6d5f | ||
|
|
7158d4d4ad | ||
|
|
502d90b117 | ||
|
|
f0c95b3f29 | ||
|
|
d3dccace37 | ||
|
|
a30453616b | ||
|
|
168ba2ff9f | ||
|
|
2ca9a8fc79 | ||
|
|
6456a68805 | ||
|
|
e82b607fa1 | ||
|
|
7168c9ed59 | ||
|
|
d7af6934b6 | ||
|
|
b4a5a936a0 | ||
|
|
6129e0d696 | ||
|
|
a0c8424800 | ||
|
|
dc839e1ad1 | ||
|
|
59155256a9 | ||
|
|
29b7995e7f | ||
|
|
ae9ec8851c | ||
|
|
7c2df736df | ||
|
|
192e7d5060 | ||
|
|
6aed140ecf | ||
|
|
76d56c9ed4 | ||
|
|
17096055f8 | ||
|
|
c6134bc038 | ||
|
|
16f885f469 | ||
|
|
00072d0216 | ||
|
|
4878f70e58 | ||
|
|
9e8523470d | ||
|
|
7316be0bc2 | ||
|
|
8a4b663890 | ||
|
|
3276ad9979 | ||
|
|
0890043bf4 | ||
|
|
c90ef343c1 | ||
|
|
0f6e276113 | ||
|
|
1395c95831 | ||
|
|
33b70a550f | ||
|
|
985e924e9d | ||
|
|
3827919a32 | ||
|
|
d55bea7c46 | ||
|
|
2efe326fdb | ||
|
|
d43bd23e1a | ||
|
|
015ec12215 | ||
|
|
fde9dc7961 | ||
|
|
ed572ececf | ||
|
|
fd2b79bea9 | ||
|
|
acc10930c2 | ||
|
|
f17d6c2359 | ||
|
|
e21211f3f6 | ||
|
|
58deaa6b29 | ||
|
|
fcd88b4b3b | ||
|
|
3bd987ff2c | ||
|
|
45bcdc8c46 | ||
|
|
0d0b2d6962 | ||
|
|
fd6a41d219 | ||
|
|
b052429a73 | ||
|
|
1996f401e0 | ||
|
|
3b3f2226f1 | ||
|
|
5c0f6a1e50 | ||
|
|
b7438f6ab8 | ||
|
|
84f80b3e06 | ||
|
|
c281372b8d | ||
|
|
788a3cfc5e | ||
|
|
01eeb53af0 | ||
|
|
7cf69128ea | ||
|
|
c977baecc4 | ||
|
|
2ab2f5e675 | ||
|
|
6a38f1e9f3 | ||
|
|
f0eba69c4a | ||
|
|
cea366e135 | ||
|
|
d752c7434f | ||
|
|
4402120ffc | ||
|
|
b3fffdf530 | ||
|
|
8d6d959e17 | ||
|
|
43f5cc622e | ||
|
|
5f025bcbcc | ||
|
|
8297e22f10 | ||
|
|
989eade5d7 | ||
|
|
cd4de2ff96 | ||
|
|
73d66365e9 | ||
|
|
fbd4e593d2 | ||
|
|
033ef3889a | ||
|
|
0ce1b5d40b | ||
|
|
ed4ed6b433 | ||
|
|
4cd18b8358 | ||
|
|
fb85f272a1 | ||
|
|
28bb28b79c | ||
|
|
e3b6cfd54f | ||
|
|
bf6ed3d540 | ||
|
|
9c0a270d90 | ||
|
|
5112c3aa1e | ||
|
|
57dcf6cc93 | ||
|
|
48296775ae | ||
|
|
e3cb078306 | ||
|
|
2f78a10e4c | ||
|
|
f3e2e35533 | ||
|
|
0d9175dc15 | ||
|
|
302caba403 | ||
|
|
920b32b432 | ||
|
|
81e5c945b4 | ||
|
|
78ea4276ae | ||
|
|
12a36d08e2 | ||
|
|
e4879f7546 | ||
|
|
34b8f481e1 | ||
|
|
f36014194d | ||
|
|
763d1f0e2d | ||
|
|
5c6fb302d9 | ||
|
|
f748b75a19 | ||
|
|
6a815d5ebb | ||
|
|
bfb079cb4f | ||
|
|
89afbd1aef | ||
|
|
ed9922c8a9 | ||
|
|
3fe231cdb0 | ||
|
|
269af11eb4 | ||
|
|
6ed3936424 | ||
|
|
24c8fc6957 | ||
|
|
9965322505 | ||
|
|
9b04373809 | ||
|
|
6fffc589bf | ||
|
|
0889764bcc | ||
|
|
e40bb5c498 | ||
|
|
a255e062be | ||
|
|
02c3821ea7 | ||
|
|
e61dfa0927 | ||
|
|
c8304eb497 | ||
|
|
6e21f703ab | ||
|
|
7550cf394c | ||
|
|
d05805595e | ||
|
|
975c3a9276 | ||
|
|
43d5fe2f4d | ||
|
|
a2fb9306c7 | ||
|
|
4c07983834 | ||
|
|
b28d45df8a | ||
|
|
c863b2f65b | ||
|
|
896cad1fe0 | ||
|
|
8b9b284ae9 | ||
|
|
9ffd393a4a | ||
|
|
559fd28036 | ||
|
|
4452f9754e | ||
|
|
983c1b4a90 | ||
|
|
cd9d0bcf34 | ||
|
|
ec294228ae | ||
|
|
bbfb0556a6 | ||
|
|
0b8b887978 | ||
|
|
9320ffdbbd | ||
|
|
a955f522bd | ||
|
|
2526eda0db | ||
|
|
5b2dc51c07 | ||
|
|
30c0ce8d2c | ||
|
|
c758eb244b | ||
|
|
d9f5a974cb | ||
|
|
658d4ec478 | ||
|
|
72f9da2a67 | ||
|
|
41c70bce44 | ||
|
|
999db12a3a | ||
|
|
7a30072fcb | ||
|
|
0cdacc4b9f | ||
|
|
a6b04e99f6 | ||
|
|
8aa4402f88 | ||
|
|
295b32b890 | ||
|
|
0dcf02f891 | ||
|
|
15b91c1cac | ||
|
|
0bdc442bf0 | ||
|
|
d44ffde2a9 | ||
|
|
867b87415b | ||
|
|
761522a540 |
5
.github/FUNDING.yml
vendored
Normal file
5
.github/FUNDING.yml
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
# Sponsor links
|
||||
|
||||
patreon: werwolv
|
||||
custom: https://werwolv.net/donate
|
||||
github: WerWolv
|
||||
172
.github/workflows/build.yml
vendored
Normal file
172
.github/workflows/build.yml
vendored
Normal file
@@ -0,0 +1,172 @@
|
||||
name: Build
|
||||
|
||||
on:
|
||||
push:
|
||||
pull_request:
|
||||
|
||||
env:
|
||||
BUILD_TYPE: Release
|
||||
|
||||
jobs:
|
||||
|
||||
linux:
|
||||
runs-on: ubuntu-20.04
|
||||
name: 🐧 Ubuntu 20.04
|
||||
steps:
|
||||
|
||||
- name: 🧰 Checkout
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: ⬇️ Install dependencies
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y \
|
||||
build-essential \
|
||||
gcc-10 \
|
||||
g++-10 \
|
||||
pkg-config \
|
||||
cmake \
|
||||
make \
|
||||
libglfw3-dev \
|
||||
libglm-dev \
|
||||
libmagic-dev \
|
||||
libmbedtls-dev \
|
||||
libcapstone-dev \
|
||||
python3-dev \
|
||||
libfreetype-dev \
|
||||
|
||||
- name: ✋ Build
|
||||
run: |
|
||||
# Get path to magic db
|
||||
MAGICDB_PATH=$(file --version | grep -oP "(?<=magic file from ).+")
|
||||
|
||||
mkdir build
|
||||
cd build
|
||||
CC=gcc-10 CXX=g++-10 cmake \
|
||||
-DCMAKE_BUILD_TYPE=$BUILD_TYPE \
|
||||
-DCMAKE_INSTALL_PREFIX="$PWD/install" \
|
||||
-DEXTRA_MAGICDBS="$MAGICDB_PATH" \
|
||||
..
|
||||
make -j 4 install
|
||||
|
||||
- name: 📦 Upload ELF
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: Linux ELF
|
||||
path: |
|
||||
build/install/*
|
||||
|
||||
win:
|
||||
runs-on: windows-latest
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- { msystem: MINGW64, arch: x86_64 }
|
||||
#- { msystem: MINGW32, arch: i686 } # currently fail
|
||||
name: 🟦 ${{ matrix.msystem }} · ${{ matrix.arch }}
|
||||
defaults:
|
||||
run:
|
||||
shell: msys2 {0}
|
||||
env:
|
||||
MINGW_INSTALLS: ${{ matrix.msystem }}
|
||||
steps:
|
||||
|
||||
- name: 🧰 Checkout
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: ⬇️ Install dependencies
|
||||
uses: msys2/setup-msys2@v2
|
||||
with:
|
||||
msystem: ${{ matrix.msystem }}
|
||||
update: true
|
||||
install: >
|
||||
mingw-w64-${{ matrix.arch }}-gcc
|
||||
mingw-w64-${{ matrix.arch }}-cmake
|
||||
mingw-w64-${{ matrix.arch }}-make
|
||||
mingw-w64-${{ matrix.arch }}-capstone
|
||||
mingw-w64-${{ matrix.arch }}-glfw
|
||||
mingw-w64-${{ matrix.arch }}-glm
|
||||
mingw-w64-${{ matrix.arch }}-file
|
||||
mingw-w64-${{ matrix.arch }}-mbedtls
|
||||
mingw-w64-${{ matrix.arch }}-polly
|
||||
mingw-w64-${{ matrix.arch }}-python
|
||||
mingw-w64-${{ matrix.arch }}-dlfcn
|
||||
mingw-w64-${{ matrix.arch }}-freetype
|
||||
|
||||
- name: ✋ Build
|
||||
run: |
|
||||
mkdir build
|
||||
cd build
|
||||
# Get path to mingw python library
|
||||
PYTHON_LIB_NAME=$(pkg-config --libs-only-l python3 | sed 's/^-l//')
|
||||
PYTHON_LIB_PATH=$(cygpath -m $(which lib${PYTHON_LIB_NAME}.dll))
|
||||
|
||||
# Get path to magic db
|
||||
MAGICDB_PATH=$(cygpath -m $(file --version | grep -oP "(?<=magic file from ).+"))
|
||||
|
||||
echo Python_LIBRARY: $PYTHON_LIB_PATH
|
||||
echo MagicDB Path: $MAGICDB_PATH
|
||||
|
||||
cmake -G "MinGW Makefiles" \
|
||||
-DCMAKE_BUILD_TYPE=$BUILD_TYPE \
|
||||
-DCMAKE_INSTALL_PREFIX="$PWD/install" \
|
||||
-DCREATE_PACKAGE=ON \
|
||||
-DPython_LIBRARY="$PYTHON_LIB_PATH" \
|
||||
-DEXTRA_MAGICDBS="$MAGICDB_PATH" \
|
||||
..
|
||||
mingw32-make -j4
|
||||
mingw32-make install
|
||||
cpack
|
||||
|
||||
- name: 📦 Upload Portable ZIP
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: Windows Portable ZIP
|
||||
path: |
|
||||
build/install/*
|
||||
|
||||
- name: 📦 Upload Windows Installer
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: Windows Installer
|
||||
path: |
|
||||
build/*.msi
|
||||
|
||||
macos-build:
|
||||
runs-on: macos-11.0
|
||||
name: 🍎 macOS 11.0
|
||||
steps:
|
||||
|
||||
- name: 🧰 Checkout
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: ⬇️ Install dependencies
|
||||
run: |
|
||||
brew bundle --no-lock --file dist/Brewfile
|
||||
|
||||
- name: ✋ Build
|
||||
run: |
|
||||
mkdir build
|
||||
cd build
|
||||
CC=$(brew --prefix llvm)/bin/clang \
|
||||
CXX=$(brew --prefix llvm)/bin/clang++ \
|
||||
PKG_CONFIG_PATH="$(brew --prefix openssl)/lib/pkgconfig":"$(brew --prefix)/lib/pkgconfig" \
|
||||
cmake \
|
||||
-DCMAKE_BUILD_TYPE=$BUILD_TYPE \
|
||||
-DCREATE_BUNDLE=ON \
|
||||
-DCREATE_PACKAGE=ON \
|
||||
..
|
||||
make -j 4 package
|
||||
|
||||
- name: 📦 Upload DMG
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: macOS DMG
|
||||
path: build/*.dmg
|
||||
9
.gitignore
vendored
9
.gitignore
vendored
@@ -1,4 +1,13 @@
|
||||
.vscode/
|
||||
.idea/
|
||||
|
||||
cmake-build-debug/
|
||||
|
||||
cmake-build-release/
|
||||
|
||||
build-linux/
|
||||
build/
|
||||
|
||||
*.mgc
|
||||
imgui.ini
|
||||
.DS_Store
|
||||
1
.idea/.name
generated
Normal file
1
.idea/.name
generated
Normal file
@@ -0,0 +1 @@
|
||||
imhex
|
||||
2
.idea/imhex.iml
generated
Normal file
2
.idea/imhex.iml
generated
Normal file
@@ -0,0 +1,2 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module classpath="CMake" type="CPP_MODULE" version="4" />
|
||||
2
.idea/modules.xml
generated
2
.idea/modules.xml
generated
@@ -2,7 +2,7 @@
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/.idea/HexEditor.iml" filepath="$PROJECT_DIR$/.idea/HexEditor.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/.idea/imhex.iml" filepath="$PROJECT_DIR$/.idea/imhex.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
||||
@@ -1,48 +1,77 @@
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
project(HexEditor)
|
||||
|
||||
# Updating the version here will update it throughout ImHex as well
|
||||
project(imhex VERSION 1.7.0)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 20)
|
||||
set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake/modules")
|
||||
include("${CMAKE_SOURCE_DIR}/cmake/build_helpers.cmake")
|
||||
setDefaultBuiltTypeIfUnset()
|
||||
|
||||
find_package(PkgConfig REQUIRED)
|
||||
pkg_search_module(GLFW REQUIRED glfw3)
|
||||
find_package(OpenGL REQUIRED)
|
||||
# List plugin names here. Project name must match folder name
|
||||
set(PLUGINS
|
||||
example
|
||||
builtin
|
||||
)
|
||||
|
||||
include_directories(include ${GLFW_INCLUDE_DIRS} libs/ImGui/include libs/glad/include)
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_C_FLAGS} -DIMGUI_IMPL_OPENGL_LOADER_GLAD")
|
||||
# List extra magic databases to compile here
|
||||
set(MAGICDBS
|
||||
magic_dbs/nintendo_magic
|
||||
)
|
||||
|
||||
add_executable(ImHex
|
||||
findLibraries()
|
||||
|
||||
detectOS()
|
||||
detectArch()
|
||||
|
||||
# Add bundled dependencies
|
||||
add_subdirectory(external/llvm)
|
||||
add_subdirectory(plugins/libimhex)
|
||||
|
||||
# Add include directories
|
||||
include_directories(include ${MBEDTLS_INCLUDE_DIRS} ${CAPSTONE_INCLUDE_DIRS} ${MAGIC_INCLUDE_DIRS} ${Python_INCLUDE_DIRS})
|
||||
|
||||
addVersionDefines()
|
||||
configurePackageCreation()
|
||||
|
||||
add_executable(imhex ${application_type}
|
||||
source/main.cpp
|
||||
source/window.cpp
|
||||
source/utils.cpp
|
||||
source/crypto.cpp
|
||||
|
||||
source/parser/lexer.cpp
|
||||
source/parser/parser.cpp
|
||||
source/helpers/patches.cpp
|
||||
source/helpers/project_file_handler.cpp
|
||||
source/helpers/loader_script_handler.cpp
|
||||
source/helpers/plugin_handler.cpp
|
||||
source/helpers/encoding_file.cpp
|
||||
|
||||
source/provider/file_provider.cpp
|
||||
source/providers/file_provider.cpp
|
||||
|
||||
source/views/view_hexeditor.cpp
|
||||
source/views/view_pattern.cpp
|
||||
source/views/view_pattern_data.cpp
|
||||
source/views/view_hashes.cpp
|
||||
source/views/view_information.cpp
|
||||
source/views/view_help.cpp
|
||||
source/views/view_tools.cpp
|
||||
source/views/view_strings.cpp
|
||||
source/views/view_data_inspector.cpp
|
||||
source/views/view_disassembler.cpp
|
||||
source/views/view_bookmarks.cpp
|
||||
source/views/view_patches.cpp
|
||||
source/views/view_command_palette.cpp
|
||||
source/views/view_settings.cpp
|
||||
source/views/view_data_processor.cpp
|
||||
|
||||
libs/glad/source/glad.c
|
||||
|
||||
libs/ImGui/source/imgui.cpp
|
||||
libs/ImGui/source/imgui_demo.cpp
|
||||
libs/ImGui/source/imgui_draw.cpp
|
||||
libs/ImGui/source/imgui_widgets.cpp
|
||||
libs/ImGui/source/imgui_impl_glfw.cpp
|
||||
libs/ImGui/source/imgui_impl_opengl3.cpp
|
||||
|
||||
res.rc
|
||||
${imhex_icon}
|
||||
)
|
||||
|
||||
if (WIN32)
|
||||
target_link_libraries(ImHex libglfw3.a libgcc.a libstdc++.a libmagic.a libgnurx.a libtre.a libintl.a libiconv.a shlwapi.lib libcrypto.a)
|
||||
endif (WIN32)
|
||||
set_target_properties(imhex PROPERTIES CXX_VISIBILITY_PRESET hidden)
|
||||
target_link_directories(imhex PRIVATE ${CAPSTONE_LIBRARY_DIRS} ${MAGIC_LIBRARY_DIRS})
|
||||
|
||||
if (UNIX)
|
||||
target_link_libraries(ImHex libglfw.so libmagic.so libcrypto.so libdl.so)
|
||||
endif (UNIX)
|
||||
if (WIN32)
|
||||
target_link_libraries(imhex libdl.a libmagic.a libgnurx.a libtre.a libintl.a libiconv.a libshlwapi.a libcapstone.a LLVMDemangle libimhex ${Python_LIBRARIES} wsock32 ws2_32)
|
||||
elseif (UNIX)
|
||||
target_link_libraries(imhex magic ${CMAKE_DL_LIBS} capstone LLVMDemangle libimhex ${Python_LIBRARIES} dl)
|
||||
endif()
|
||||
|
||||
createPackage()
|
||||
339
LICENSE
Normal file
339
LICENSE
Normal file
@@ -0,0 +1,339 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Lesser General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License.
|
||||
163
README.md
163
README.md
@@ -1,7 +1,164 @@
|
||||
# ImHex
|
||||
<h1 align="center">:mag: ImHex</h1>
|
||||
|
||||
A Hex editor written in C++ using OpenGL, GLFW and Dear ImGui
|
||||
<p align="center">A Hex Editor for Reverse Engineers, Programmers and people that value their eye sight when working at 3 AM.</p>
|
||||
|
||||
<p align="center">
|
||||
<a title="'Build' workflow Status" href="https://github.com/WerWolv/ImHex/actions?query=workflow%3ABuild"><img alt="'Build' workflow Status" src="https://img.shields.io/github/workflow/status/WerWolv/ImHex/Build?longCache=true&style=for-the-badge&label=Build&logoColor=fff&logo=GitHub%20Actions"></a>
|
||||
<a title="Discord Server" href="https://discord.gg/X63jZ36xBY"><img alt="Discord Server" src="https://img.shields.io/discord/789833418631675954?label=Discord&logo=Discord&style=for-the-badge"></a>
|
||||
</p>
|
||||
|
||||
## Supporting
|
||||
|
||||
If you like my work, please consider supporting me on GitHub Sponsors, Patreon or PayPal. Thanks a lot!
|
||||
|
||||
<p align="center">
|
||||
<a href="https://github.com/sponsors/WerWolv"><img src="https://werwolv.net/assets/github_banner.png" alt="GitHub donate button" /> </a>
|
||||
<a href="https://www.patreon.com/werwolv"><img src="https://c5.patreon.com/external/logo/become_a_patron_button.png" alt="Patreon donate button" /> </a>
|
||||
<a href="https://werwolv.net/donate"><img src="https://werwolv.net/assets/paypal_banner.png" alt="PayPal donate button" /> </a>
|
||||
</p>
|
||||
|
||||
## Features
|
||||
|
||||
- Featureful hex view
|
||||
- Byte patching
|
||||
- Patch management
|
||||
- Copy bytes as feature
|
||||
- Bytes
|
||||
- Hex string
|
||||
- C, C++, C#, Rust, Python, Java & JavaScript array
|
||||
- ASCII-Art hex view
|
||||
- HTML self contained div
|
||||
- String and hex search
|
||||
- Colorful highlighting
|
||||
- Goto from start, end and current cursor position
|
||||
- Custom C++-like pattern language for parsing highlighting a file's content
|
||||
- Automatic loading based on MIME type
|
||||
- arrays, pointers, structs, unions, enums, bitfields, using declarations, little and big endian support, conditionals and much more!
|
||||
- Useful error messages, syntax highlighting and error marking
|
||||
- Data importing
|
||||
- Base64 files
|
||||
- IPS and IPS32 patches
|
||||
- Data exporting
|
||||
- IPS and IPS32 patches
|
||||
- Data inspector allowing interpretation of data as many different types (little and big endian)
|
||||
- Huge file support with fast and efficient loading
|
||||
- String search
|
||||
- Copying of strings
|
||||
- Copying of demangled strings
|
||||
- File hashing support
|
||||
- CRC16 and CRC32 with custom initial values and polynomials
|
||||
- MD4, MD5
|
||||
- SHA-1, SHA-224, SHA-256, SHA-384, SHA-512
|
||||
- Disassembler supporting many different architectures
|
||||
- ARM32 (ARM, Thumb, Cortex-M, AArch32)
|
||||
- ARM64
|
||||
- MIPS (MIPS32, MIPS64, MIPS32R6, Micro)
|
||||
- x86 (16-bit, 32-bit, 64-bit)
|
||||
- PowerPC (32-bit, 64-bit)
|
||||
- SPARC
|
||||
- IBM SystemZ
|
||||
- xCORE
|
||||
- M68K
|
||||
- TMS320C64X
|
||||
- M680X
|
||||
- Ethereum
|
||||
- Bookmarks
|
||||
- Region highlighting
|
||||
- Comments
|
||||
- Data Analyzer
|
||||
- File magic-based file parser and MIME type database
|
||||
- Byte distribution graph
|
||||
- Entropy graph
|
||||
- Highest and avarage entropy
|
||||
- Encrypted / Compressed file detection
|
||||
- Helpful tools
|
||||
- Itanium and MSVC demangler
|
||||
- ASCII table
|
||||
- Regex replacer
|
||||
- Mathematical expression evaluator (Calculator)
|
||||
- Hexadecimal Color picker
|
||||
- Built-in cheat sheet for pattern language and Math evaluator
|
||||
- Doesn't burn out your retinas when used in late-night sessions
|
||||
|
||||
## Screenshots
|
||||
|
||||

|
||||

|
||||

|
||||
|
||||
## Pattern Language
|
||||
|
||||
The custom C-like Pattern Language developed and used by ImHex is easy to read, understand and learn. A guide with all features of the langauge can be found [in the wiki](https://github.com/WerWolv/ImHex/wiki/Pattern-Language-Guide) or a simpler version in ImHex under `Help -> Pattern Language Cheat Sheet`
|
||||
|
||||
## Additional Files
|
||||
|
||||
For format patterns, includable libraries and magic files, check out the [ImHex-Patterns](https://github.com/WerWolv/ImHex-Patterns) repository. Feel free to PR your own files there as well!
|
||||
|
||||
## Nightly builds
|
||||
|
||||
Nightlies are available via GitHub Actions [here](https://github.com/WerWolv/ImHex/actions?query=workflow%3ABuild).
|
||||
|
||||
- Windows • __x86_64__
|
||||
- [MSI Installer](https://nightly.link/WerWolv/ImHex/workflows/build/master/Windows%20Installer.zip)
|
||||
- [Portable ZIP](https://nightly.link/WerWolv/ImHex/workflows/build/master/Windows%20Portable%20ZIP.zip)
|
||||
- MacOS • __x86_64__
|
||||
- [DMG](https://nightly.link/WerWolv/ImHex/workflows/build/master/macOS%20DMG.zip)
|
||||
- Linux • __x86_64__
|
||||
- [ELF](https://nightly.link/WerWolv/ImHex/workflows/build/master/Linux%20ELF.zip)
|
||||
|
||||
## Compiling
|
||||
|
||||
You need a C++20 compatible compiler such as GCC 10.2.0 to compile ImHex. Moreover, the following dependencies are needed for compiling ImHex:
|
||||
|
||||
- GLFW3
|
||||
- libmagic, libgnurx, libtre, libintl, libiconv
|
||||
- libcrypto
|
||||
- capstone
|
||||
- nlohmann json
|
||||
- Python3
|
||||
- freetype2
|
||||
- Brew (macOS only)
|
||||
|
||||
### Windows and Linux
|
||||
|
||||
Find all-in-one dependency installation scripts for Arch Linux, Fedora, Debian/Ubuntu and/or MSYS2 in [dist](dist).
|
||||
|
||||
After all the dependencies are installed, run the following commands to build ImHex:
|
||||
|
||||
```sh
|
||||
mkdir build
|
||||
cd build
|
||||
cmake -DCMAKE_BUILD_TYPE=Release ..
|
||||
make -j
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
To create a standalone zipfile on Windows, get the Python standard library (e.g. from https://github.com/python/cpython/tree/master/Lib) and place the files and folders in `lib/python3.8` next to your built executable. Don't forget to also copy the `libpython3.8.dll` and `libwinpthread-1.dll` from your mingw setup next to the executable.
|
||||
|
||||
On both Windows and Linux:
|
||||
|
||||
- Copy the files from `python_libs` in the `lib` folder next to your built executable.
|
||||
- Place your magic databases in the `magic` folder next to your built executable
|
||||
- Place your patterns in the `pattern` folder next to your built executable
|
||||
- Place your include pattern files in the `include` folder next to your built executable
|
||||
|
||||
### macOS
|
||||
|
||||
To build ImHex on macOS, run the following commands:
|
||||
|
||||
```sh
|
||||
brew bundle --no-lock --file dist/Brewfile
|
||||
mkdir build
|
||||
cd build
|
||||
CC=$(brew --prefix llvm)/bin/clang CXX=$(brew --prefix llvm)/bin/clang++ PKG_CONFIG_PATH="$(brew --prefix openssl)/lib/pkgconfig":"$(brew --prefix)/lib/pkgconfig" cmake -DCMAKE_BUILD_TYPE=Release ..
|
||||
make -j
|
||||
```
|
||||
|
||||
## Credits
|
||||
|
||||
- Thanks a lot to ocornut for their amazing [Dear ImGui](https://github.com/ocornut/imgui) which is used for building the entire interface
|
||||
- Thanks to orconut as well for their hex editor view used as base for this project.
|
||||
- Thanks to BalazsJako for their incredible [ImGuiColorTextEdit](https://github.com/BalazsJako/ImGuiColorTextEdit) used for the pattern language syntax highlighting
|
||||
- Thanks to AirGuanZ for their amazing [imgui-filebrowser](https://github.com/AirGuanZ/imgui-filebrowser) used for loading and saving files
|
||||
- Thanks to nlohmann for their [json](https://github.com/nlohmann/json) library used for project files
|
||||
- Thanks to aquynh for [capstone](https://github.com/aquynh/capstone) which is the base of the disassembly window
|
||||
|
||||
270
cmake/build_helpers.cmake
Normal file
270
cmake/build_helpers.cmake
Normal file
@@ -0,0 +1,270 @@
|
||||
macro(addVersionDefines)
|
||||
if (IS_DIRECTORY "${CMAKE_SOURCE_DIR}/.git")
|
||||
# Get the current working branch
|
||||
execute_process(
|
||||
COMMAND git rev-parse --abbrev-ref HEAD
|
||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
||||
OUTPUT_VARIABLE GIT_BRANCH
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
)
|
||||
|
||||
# Get the latest abbreviated commit hash of the working branch
|
||||
execute_process(
|
||||
COMMAND git log -1 --format=%h
|
||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
||||
OUTPUT_VARIABLE GIT_COMMIT_HASH
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
)
|
||||
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DGIT_COMMIT_HASH=\"\\\"${GIT_COMMIT_HASH}\"\\\"")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DGIT_BRANCH=\"\\\"${GIT_BRANCH}\"\\\"")
|
||||
endif()
|
||||
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -DRELEASE -DIMHEX_VERSION=\"\\\"${PROJECT_VERSION}\"\\\"")
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DDEBUG -DIMHEX_VERSION=\"\\\"${PROJECT_VERSION}-Debug\"\\\"")
|
||||
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -DRELEASE -DIMHEX_VERSION=\"\\\"${PROJECT_VERSION}-ReleaseWithDebugInfo\"\\\"")
|
||||
set(CMAKE_CXX_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS_MINSIZEREL} -DRELEASE -DIMHEX_VERSION=\"\\\"${PROJECT_VERSION}-ReleaseMinimumSize\"\\\"")
|
||||
endmacro()
|
||||
|
||||
macro(findLibraries)
|
||||
set(CMAKE_FIND_PACKAGE_SORT_ORDER NATURAL)
|
||||
set(CMAKE_FIND_PACKAGE_SORT_DIRECTION DEC)
|
||||
|
||||
# Enforce that we use non system Python 3 on macOS.
|
||||
set(Python_FIND_FRAMEWORK NEVER)
|
||||
|
||||
# Find packages
|
||||
find_package(PkgConfig REQUIRED)
|
||||
|
||||
find_package(mbedTLS REQUIRED)
|
||||
|
||||
pkg_search_module(CAPSTONE REQUIRED capstone)
|
||||
|
||||
find_package(OpenGL REQUIRED)
|
||||
|
||||
find_package(Python COMPONENTS Development REQUIRED)
|
||||
if(Python_VERSION LESS 3)
|
||||
message(STATUS ${PYTHON_VERSION_MAJOR_MINOR})
|
||||
message(FATAL_ERROR "No valid version of Python 3 was found.")
|
||||
endif()
|
||||
|
||||
string(REPLACE "." ";" PYTHON_VERSION_MAJOR_MINOR ${Python_VERSION})
|
||||
|
||||
list(LENGTH PYTHON_VERSION_MAJOR_MINOR PYTHON_VERSION_COMPONENT_COUNT)
|
||||
|
||||
if (PYTHON_VERSION_COMPONENT_COUNT EQUAL 3)
|
||||
list(REMOVE_AT PYTHON_VERSION_MAJOR_MINOR 2)
|
||||
endif ()
|
||||
list(JOIN PYTHON_VERSION_MAJOR_MINOR "." PYTHON_VERSION_MAJOR_MINOR)
|
||||
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CMAKE_C_FLAGS} -DPYTHON_VERSION_MAJOR_MINOR=\"\\\"${PYTHON_VERSION_MAJOR_MINOR}\"\\\"")
|
||||
|
||||
pkg_search_module(MAGIC libmagic)
|
||||
if(NOT MAGIC_FOUND)
|
||||
find_library(MAGIC magic REQUIRED)
|
||||
else()
|
||||
set(MAGIC_INCLUDE_DIRS ${MAGIC_INCLUDEDIR})
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
# Detect current OS / System
|
||||
macro(detectOS)
|
||||
if (WIN32)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DOS_WINDOWS")
|
||||
elseif(APPLE)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DOS_MACOS")
|
||||
elseif(UNIX AND NOT APPLE)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DOS_LINUX")
|
||||
else()
|
||||
message(FATAL_ERROR "Unknown / unsupported system!")
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
# Detect 32 vs. 64 bit system
|
||||
macro(detectArch)
|
||||
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DARCH_64_BIT")
|
||||
elseif(CMAKE_SIZEOF_VOID_P EQUAL 4)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DARCH_32_BIT")
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
|
||||
macro(configurePackageCreation)
|
||||
option (CREATE_PACKAGE "Create a package with CPack" OFF)
|
||||
|
||||
if (APPLE)
|
||||
option (CREATE_BUNDLE "Create a bundle on macOS" OFF)
|
||||
endif()
|
||||
|
||||
if (WIN32)
|
||||
if (CMAKE_BUILD_TYPE EQUAL "DEBUG")
|
||||
set(application_type WIN32)
|
||||
else ()
|
||||
set(application_type)
|
||||
endif ()
|
||||
set(imhex_icon "${PROJECT_SOURCE_DIR}/res/resource.rc")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -static-libstdc++ -static-libgcc -Wl,--allow-multiple-definition -static -Wl,-Bstatic,--whole-archive -lwinpthread -Wl,--no-whole-archive")
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -Wl,-subsystem,windows")
|
||||
|
||||
if (CREATE_PACKAGE)
|
||||
set(CPACK_GENERATOR "WIX")
|
||||
set(CPACK_PACKAGE_NAME "ImHex")
|
||||
set(CPACK_WIX_UPGRADE_GUID "05000E99-9659-42FD-A1CF-05C554B39285")
|
||||
set(CPACK_WIX_PRODUCT_ICON "${PROJECT_SOURCE_DIR}/res/icon.ico")
|
||||
set(CPACK_PACKAGE_INSTALL_DIRECTORY "ImHex")
|
||||
set_property(INSTALL "$<TARGET_FILE_NAME:imhex>"
|
||||
PROPERTY CPACK_START_MENU_SHORTCUTS "ImHex"
|
||||
)
|
||||
set(CPACK_RESOURCE_FILE_LICENSE "${PROJECT_SOURCE_DIR}/res/LICENSE.rtf")
|
||||
endif()
|
||||
elseif (APPLE)
|
||||
set (imhex_icon "${PROJECT_SOURCE_DIR}/res/mac/AppIcon.icns")
|
||||
|
||||
if (CREATE_BUNDLE)
|
||||
set(application_type MACOSX_BUNDLE)
|
||||
set_source_files_properties(${imhex_icon} PROPERTIES MACOSX_PACKAGE_LOCATION Resources)
|
||||
set(MACOSX_BUNDLE_ICON_FILE "AppIcon.icns")
|
||||
set(MACOSX_BUNDLE_INFO_STRING "WerWolv")
|
||||
set(MACOSX_BUNDLE_BUNDLE_NAME "ImHex")
|
||||
set(MACOSX_BUNDLE_BUNDLE_VERSION "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}")
|
||||
set(MACOSX_BUNDLE_GUI_IDENTIFIER "WerWolv.ImHex")
|
||||
set(MACOSX_BUNDLE_LONG_VERSION_STRING "${PROJECT_VERSION}-${GIT_COMMIT_HASH}")
|
||||
set(MACOSX_BUNDLE_SHORT_VERSION_STRING "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}")
|
||||
set(MACOSX_BUNDLE_COPYRIGHT "Copyright © 2020 WerWolv and Thog. All rights reserved." )
|
||||
if ("${CMAKE_GENERATOR}" STREQUAL "Xcode")
|
||||
set ( bundle_path "${CMAKE_BINARY_DIR}/${CMAKE_BUILD_TYPE}/imhex.app" )
|
||||
else ()
|
||||
set ( bundle_path "${CMAKE_BINARY_DIR}/imhex.app" )
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
macro(createPackage)
|
||||
file(MAKE_DIRECTORY "plugins")
|
||||
foreach (plugin IN LISTS PLUGINS)
|
||||
add_subdirectory("plugins/${plugin}")
|
||||
set_target_properties(${plugin} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/plugins)
|
||||
add_dependencies(imhex ${plugin})
|
||||
endforeach()
|
||||
|
||||
set_target_properties(libimhex PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
|
||||
|
||||
if (WIN32)
|
||||
# Install binaries directly in the prefix, usually C:\Program Files\ImHex.
|
||||
set(CMAKE_INSTALL_BINDIR ".")
|
||||
|
||||
# Grab all dynamically linked dependencies.
|
||||
INSTALL(CODE "set(CMAKE_INSTALL_BINDIR \"${CMAKE_INSTALL_BINDIR}\")")
|
||||
INSTALL(CODE "get_filename_component(PY_PARENT ${Python_LIBRARIES} DIRECTORY)")
|
||||
INSTALL(CODE "LIST(APPEND DEP_FOLDERS \${PY_PARENT})")
|
||||
install(CODE [[
|
||||
file(GET_RUNTIME_DEPENDENCIES
|
||||
EXECUTABLES $<TARGET_FILE:imhex>
|
||||
RESOLVED_DEPENDENCIES_VAR _r_deps
|
||||
UNRESOLVED_DEPENDENCIES_VAR _u_deps
|
||||
CONFLICTING_DEPENDENCIES_PREFIX _c_deps
|
||||
DIRECTORIES ${DEP_FOLDERS}
|
||||
POST_EXCLUDE_REGEXES ".*system32/.*\\.dll"
|
||||
)
|
||||
|
||||
if(_u_deps)
|
||||
message(WARNING "There were unresolved dependencies for binary $<TARGET_FILE:imhex>: \"${_u_deps}\"!")
|
||||
endif()
|
||||
if(_c_deps_FILENAMES)
|
||||
message(WARNING "There were conflicting dependencies for library $<TARGET_FILE:imhex>: \"${_c_deps}\"!")
|
||||
endif()
|
||||
|
||||
foreach(_file ${_r_deps})
|
||||
file(INSTALL
|
||||
DESTINATION "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_BINDIR}"
|
||||
TYPE SHARED_LIBRARY
|
||||
FOLLOW_SYMLINK_CHAIN
|
||||
FILES "${_file}"
|
||||
)
|
||||
endforeach()
|
||||
]])
|
||||
endif()
|
||||
|
||||
if (UNIX AND NOT APPLE)
|
||||
install(TARGETS libimhex DESTINATION ${CMAKE_INSTALL_PREFIX})
|
||||
|
||||
string(REPLACE ":" ";" EXTRA_MAGICDBS "${EXTRA_MAGICDBS}")
|
||||
|
||||
endif ()
|
||||
|
||||
if (NOT EXTRA_MAGICDBS STREQUAL "")
|
||||
list(GET EXTRA_MAGICDBS -1 EXTRA_MAGICDBS)
|
||||
|
||||
if (NOT EXTRA_MAGICDBS STREQUAL "NOTFOUND")
|
||||
if (EXTRA_MAGICDBS MATCHES ".*\\.mgc")
|
||||
install(FILES "${EXTRA_MAGICDBS}" DESTINATION magic/)
|
||||
else ()
|
||||
install(FILES "${EXTRA_MAGICDBS}.mgc" DESTINATION magic/)
|
||||
endif ()
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
# Compile the imhex-specific magicdb
|
||||
add_custom_target(magic_dbs ALL
|
||||
SOURCES ${MAGICDBS}
|
||||
)
|
||||
add_custom_command(TARGET magic_dbs
|
||||
COMMAND file -C -m ${CMAKE_SOURCE_DIR}/magic_dbs
|
||||
)
|
||||
|
||||
foreach (plugin IN LISTS PLUGINS)
|
||||
install(FILES "$<TARGET_FILE:${plugin}>" DESTINATION plugins/)
|
||||
endforeach ()
|
||||
|
||||
# Install the magicdb files.
|
||||
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/magic_dbs.mgc DESTINATION magic/ RENAME imhex.mgc)
|
||||
|
||||
if (CREATE_BUNDLE)
|
||||
include(PostprocessBundle)
|
||||
|
||||
# Fix rpath
|
||||
add_custom_command(TARGET imhex POST_BUILD COMMAND ${CMAKE_INSTALL_NAME_TOOL} -add_rpath "@executable_path/../Frameworks/" $<TARGET_FILE:imhex>)
|
||||
|
||||
# FIXME: Remove this once we move/integrate the plugins directory.
|
||||
add_custom_target(build-time-make-plugins-directory ALL COMMAND ${CMAKE_COMMAND} -E make_directory "${bundle_path}/Contents/MacOS/plugins")
|
||||
|
||||
# Update library references to make the bundle portable
|
||||
postprocess_bundle(imhex)
|
||||
|
||||
# Enforce DragNDrop packaging.
|
||||
set(CPACK_GENERATOR "DragNDrop")
|
||||
|
||||
install(TARGETS imhex BUNDLE DESTINATION .)
|
||||
else()
|
||||
if (WIN32)
|
||||
install(TARGETS imhex RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
|
||||
else ()
|
||||
install(TARGETS imhex RUNTIME DESTINATION ${CMAKE_INSTALL_PREFIX})
|
||||
endif ()
|
||||
endif()
|
||||
|
||||
|
||||
if (CREATE_PACKAGE)
|
||||
include(apple)
|
||||
include(CPack)
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
function(JOIN OUTPUT GLUE)
|
||||
set(_TMP_RESULT "")
|
||||
set(_GLUE "") # effective glue is empty at the beginning
|
||||
foreach(arg ${ARGN})
|
||||
set(_TMP_RESULT "${_TMP_RESULT}${_GLUE}${arg}")
|
||||
set(_GLUE "${GLUE}")
|
||||
endforeach()
|
||||
set(${OUTPUT} "${_TMP_RESULT}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
macro(setDefaultBuiltTypeIfUnset)
|
||||
if (NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
|
||||
set(CMAKE_BUILD_TYPE "Release" CACHE STRING "Using Release build type as it was left unset" FORCE)
|
||||
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release")
|
||||
endif()
|
||||
endmacro()
|
||||
70
cmake/modules/FindmbedTLS.cmake
Normal file
70
cmake/modules/FindmbedTLS.cmake
Normal file
@@ -0,0 +1,70 @@
|
||||
# - Try to find mbedTLS
|
||||
# Once done this will define
|
||||
#
|
||||
# Read-Only variables
|
||||
# MBEDTLS_FOUND - system has mbedTLS
|
||||
# MBEDTLS_INCLUDE_DIR - the mbedTLS include directory
|
||||
# MBEDTLS_LIBRARY_DIR - the mbedTLS library directory
|
||||
# MBEDTLS_LIBRARIES - Link these to use mbedTLS
|
||||
# MBEDTLS_LIBRARY - path to mbedTLS library
|
||||
# MBEDX509_LIBRARY - path to mbedTLS X.509 library
|
||||
# MBEDCRYPTO_LIBRARY - path to mbedTLS Crypto library
|
||||
|
||||
# Copyright (c) 2004-2007 Sara Golemon <sarag@libssh2.org>
|
||||
# Copyright (c) 2005,2006 Mikhail Gusarov <dottedmag@dottedmag.net>
|
||||
# Copyright (c) 2006-2007 The Written Word, Inc.
|
||||
# Copyright (c) 2007 Eli Fant <elifantu@mail.ru>
|
||||
# Copyright (c) 2009-2019 Daniel Stenberg
|
||||
# Copyright (C) 2008, 2009 Simon Josefsson
|
||||
# All rights reserved.
|
||||
|
||||
|
||||
FIND_PATH(MBEDTLS_INCLUDE_DIR mbedtls/version.h)
|
||||
|
||||
SET(MBEDTLS_FIND_QUIETLY TRUE)
|
||||
|
||||
FIND_LIBRARY(MBEDTLS_LIBRARY NAMES mbedtls libmbedtls libmbedx509)
|
||||
FIND_LIBRARY(MBEDX509_LIBRARY NAMES mbedx509 libmbedx509)
|
||||
FIND_LIBRARY(MBEDCRYPTO_LIBRARY NAMES mbedcrypto libmbedcrypto)
|
||||
|
||||
IF(MBEDTLS_INCLUDE_DIR AND MBEDTLS_LIBRARY AND MBEDX509_LIBRARY AND MBEDCRYPTO_LIBRARY)
|
||||
SET(MBEDTLS_FOUND TRUE)
|
||||
ENDIF()
|
||||
|
||||
IF(MBEDTLS_FOUND)
|
||||
# split mbedTLS into -L and -l linker options, so we can set them for pkg-config
|
||||
GET_FILENAME_COMPONENT(MBEDTLS_LIBRARY_DIR ${MBEDTLS_LIBRARY} PATH)
|
||||
GET_FILENAME_COMPONENT(MBEDTLS_LIBRARY_FILE ${MBEDTLS_LIBRARY} NAME_WE)
|
||||
GET_FILENAME_COMPONENT(MBEDX509_LIBRARY_FILE ${MBEDX509_LIBRARY} NAME_WE)
|
||||
GET_FILENAME_COMPONENT(MBEDCRYPTO_LIBRARY_FILE ${MBEDCRYPTO_LIBRARY} NAME_WE)
|
||||
STRING(REGEX REPLACE "^lib" "" MBEDTLS_LIBRARY_FILE ${MBEDTLS_LIBRARY_FILE})
|
||||
STRING(REGEX REPLACE "^lib" "" MBEDX509_LIBRARY_FILE ${MBEDX509_LIBRARY_FILE})
|
||||
STRING(REGEX REPLACE "^lib" "" MBEDCRYPTO_LIBRARY_FILE ${MBEDCRYPTO_LIBRARY_FILE})
|
||||
SET(MBEDTLS_LIBRARIES "-L${MBEDTLS_LIBRARY_DIR} -l${MBEDTLS_LIBRARY_FILE} -l${MBEDX509_LIBRARY_FILE} -l${MBEDCRYPTO_LIBRARY_FILE}")
|
||||
|
||||
IF(NOT MBEDTLS_FIND_QUIETLY)
|
||||
MESSAGE(STATUS "Found mbedTLS:")
|
||||
FILE(READ ${MBEDTLS_INCLUDE_DIR}/mbedtls/version.h MBEDTLSCONTENT)
|
||||
STRING(REGEX MATCH "MBEDTLS_VERSION_STRING +\"[0-9|.]+\"" MBEDTLSMATCH ${MBEDTLSCONTENT})
|
||||
IF (MBEDTLSMATCH)
|
||||
STRING(REGEX REPLACE "MBEDTLS_VERSION_STRING +\"([0-9|.]+)\"" "\\1" MBEDTLS_VERSION ${MBEDTLSMATCH})
|
||||
MESSAGE(STATUS " version ${MBEDTLS_VERSION}")
|
||||
ENDIF(MBEDTLSMATCH)
|
||||
MESSAGE(STATUS " TLS: ${MBEDTLS_LIBRARY}")
|
||||
MESSAGE(STATUS " X509: ${MBEDX509_LIBRARY}")
|
||||
MESSAGE(STATUS " Crypto: ${MBEDCRYPTO_LIBRARY}")
|
||||
ENDIF(NOT MBEDTLS_FIND_QUIETLY)
|
||||
ELSE(MBEDTLS_FOUND)
|
||||
IF(MBEDTLS_FIND_REQUIRED)
|
||||
MESSAGE(FATAL_ERROR "Could not find mbedTLS")
|
||||
ENDIF(MBEDTLS_FIND_REQUIRED)
|
||||
ENDIF(MBEDTLS_FOUND)
|
||||
|
||||
MARK_AS_ADVANCED(
|
||||
MBEDTLS_INCLUDE_DIR
|
||||
MBEDTLS_LIBRARY_DIR
|
||||
MBEDTLS_LIBRARIES
|
||||
MBEDTLS_LIBRARY
|
||||
MBEDX509_LIBRARY
|
||||
MBEDCRYPTO_LIBRARY
|
||||
)
|
||||
59
cmake/modules/PostprocessBundle.cmake
Normal file
59
cmake/modules/PostprocessBundle.cmake
Normal file
@@ -0,0 +1,59 @@
|
||||
# Adapted from the Dolphin project: https://dolphin-emu.org/
|
||||
# This module can be used in two different ways.
|
||||
#
|
||||
# When invoked as `cmake -P PostprocessBundle.cmake`, it fixes up an
|
||||
# application folder to be standalone. It bundles all required libraries from
|
||||
# the system and fixes up library IDs. Any additional shared libraries, like
|
||||
# plugins, that are found under Contents/MacOS/ will be made standalone as well.
|
||||
#
|
||||
# When called with `include(PostprocessBundle)`, it defines a helper
|
||||
# function `postprocess_bundle` that sets up the command form of the
|
||||
# module as a post-build step.
|
||||
|
||||
if(CMAKE_GENERATOR)
|
||||
# Being called as include(PostprocessBundle), so define a helper function.
|
||||
set(_POSTPROCESS_BUNDLE_MODULE_LOCATION "${CMAKE_CURRENT_LIST_FILE}")
|
||||
function(postprocess_bundle target)
|
||||
add_custom_command(TARGET ${target} POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -DBUNDLE_PATH="$<TARGET_FILE_DIR:${target}>/../.." -DCODE_SIGN_CERTIFICATE_ID="${CODE_SIGN_CERTIFICATE_ID}"
|
||||
-P "${_POSTPROCESS_BUNDLE_MODULE_LOCATION}"
|
||||
)
|
||||
endfunction()
|
||||
return()
|
||||
endif()
|
||||
|
||||
get_filename_component(BUNDLE_PATH "${BUNDLE_PATH}" ABSOLUTE)
|
||||
message(STATUS "Fixing up application bundle: ${BUNDLE_PATH}")
|
||||
|
||||
|
||||
# Make sure to fix up any additional shared libraries (like plugins) that are
|
||||
# needed.
|
||||
file(GLOB_RECURSE extra_libs "${BUNDLE_PATH}/Contents/MacOS/*.dylib")
|
||||
|
||||
message(STATUS "Fixing up application bundle: ${extra_dirs}")
|
||||
|
||||
# BundleUtilities doesn't support DYLD_FALLBACK_LIBRARY_PATH behavior, which
|
||||
# makes it sometimes break on libraries that do weird things with @rpath. Specify
|
||||
# equivalent search directories until https://gitlab.kitware.com/cmake/cmake/issues/16625
|
||||
# is fixed and in our minimum CMake version.
|
||||
set(extra_dirs "/usr/local/lib" "/lib" "/usr/lib")
|
||||
|
||||
# BundleUtilities is overly verbose, so disable most of its messages
|
||||
function(message)
|
||||
if(NOT ARGV MATCHES "^STATUS;")
|
||||
_message(${ARGV})
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
include(BundleUtilities)
|
||||
set(BU_CHMOD_BUNDLE_ITEMS ON)
|
||||
fixup_bundle("${BUNDLE_PATH}" "${extra_libs}" "${extra_dirs}" IGNORE_ITEM "Python")
|
||||
|
||||
if (CODE_SIGN_CERTIFICATE_ID)
|
||||
# Hack around Apple Silicon signing bugs by copying the real app, signing it and moving it back.
|
||||
# IMPORTANT: DON'T USE ${CMAKE_COMMAND} -E copy_directory HERE (this follow symbolic links).
|
||||
execute_process(COMMAND cp -R "${BUNDLE_PATH}" "${BUNDLE_PATH}.temp")
|
||||
execute_process(COMMAND codesign --deep --force --sign "${CODE_SIGN_CERTIFICATE_ID}" "${BUNDLE_PATH}.temp")
|
||||
execute_process(COMMAND ${CMAKE_COMMAND} -E remove_directory "${BUNDLE_PATH}")
|
||||
execute_process(COMMAND ${CMAKE_COMMAND} -E rename "${BUNDLE_PATH}.temp" "${BUNDLE_PATH}")
|
||||
endif()
|
||||
3
cmake/modules/apple.cmake
Normal file
3
cmake/modules/apple.cmake
Normal file
@@ -0,0 +1,3 @@
|
||||
set (CPACK_BUNDLE_NAME "ImHex")
|
||||
set (CPACK_BUNDLE_ICON "${CMAKE_SOURCE_DIR}/res/mac/AppIcon.icns" )
|
||||
set (CPACK_BUNDLE_PLIST "${CMAKE_BINARY_DIR}/ImHex.app/Contents/Info.plist")
|
||||
12
dist/Brewfile
vendored
Normal file
12
dist/Brewfile
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
brew "glfw3"
|
||||
brew "mbedtls"
|
||||
brew "capstone"
|
||||
brew "nlohmann-json"
|
||||
brew "glm"
|
||||
brew "cmake"
|
||||
brew "python3"
|
||||
brew "freetype2"
|
||||
brew "libmagic"
|
||||
|
||||
# TODO: Remove this when XCode version of clang will support the same level as LLVM 10
|
||||
brew "llvm"
|
||||
34
dist/ImHex-9999.ebuild
vendored
Normal file
34
dist/ImHex-9999.ebuild
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
# app-editors/ImHex
|
||||
# Copyright 2020 Gentoo Authors
|
||||
# Distributed under the terms of the GNU General Public License v2
|
||||
|
||||
EAPI=7
|
||||
|
||||
DESCRIPTION="A hex editor for reverse engineers, programmers, and eyesight"
|
||||
HOMEPAGE="https://github.com/WerWolv/ImHex"
|
||||
SRC_URI=""
|
||||
EGIT_REPO_URI="https://github.com/WerWolv/ImHex.git"
|
||||
|
||||
PYTHON_COMPAT=( python3_{6,7,8,9} )
|
||||
|
||||
inherit git-r3 python-single-r1 cmake
|
||||
|
||||
LICENSE="GPL-2"
|
||||
SLOT="0"
|
||||
KEYWORDS="~amd64"
|
||||
IUSE=""
|
||||
|
||||
REQUIRED_USE="${PYTHON_REQUIRED_USE}"
|
||||
|
||||
DEPEND=""
|
||||
RDEPEND="${DEPEND}
|
||||
${PYTHON_DEPS}
|
||||
media-libs/glfw
|
||||
sys-apps/file
|
||||
dev-libs/mbedtls
|
||||
dev-libs/capstone
|
||||
sys-devel/llvm
|
||||
dev-cpp/nlohmann_json
|
||||
media-libs/glm
|
||||
"
|
||||
BDEPEND="${DEPEND}"
|
||||
12
dist/get_deps_archlinux.sh
vendored
Executable file
12
dist/get_deps_archlinux.sh
vendored
Executable file
@@ -0,0 +1,12 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
pacman -S --needed \
|
||||
cmake \
|
||||
gcc \
|
||||
glfw \
|
||||
file \
|
||||
mbedtls \
|
||||
capstone \
|
||||
glm \
|
||||
python3 \
|
||||
freetype2
|
||||
28
dist/get_deps_debian.sh
vendored
Executable file
28
dist/get_deps_debian.sh
vendored
Executable file
@@ -0,0 +1,28 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
echo "As of 2020-12, Debian stable does not include g++-10, needs debian testing or unstable."
|
||||
|
||||
# Tested on 2020-12-09 with Docker image bitnami/minideb:unstable
|
||||
|
||||
# Install pkgconf (adds minimum dependencies) only if the equivalent pkf-config is not already installed.
|
||||
if !which pkg-config
|
||||
then
|
||||
PKGCONF="pkgconf"
|
||||
fi
|
||||
|
||||
apt install \
|
||||
cmake \
|
||||
g++-10 \
|
||||
${PKGCONF:-} \
|
||||
libcapstone-dev \
|
||||
libmagic-dev \
|
||||
libglfw3-dev \
|
||||
libglm-dev \
|
||||
libjsoncpp-dev \
|
||||
libmbedtls-dev \
|
||||
libstdc++-10-dev \
|
||||
python3-dev \
|
||||
libfreetype-dev
|
||||
|
||||
echo "Please consider this before running cmake (useful on e.g. Ubuntu 20.04):"
|
||||
echo "export CXX=g++-10"
|
||||
13
dist/get_deps_fedora.sh
vendored
Executable file
13
dist/get_deps_fedora.sh
vendored
Executable file
@@ -0,0 +1,13 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
dnf install \
|
||||
cmake \
|
||||
gcc-c++ \
|
||||
capstone-devel \
|
||||
file-devel \
|
||||
glfw-devel \
|
||||
glm-devel \
|
||||
mesa-libGL-devel \
|
||||
mbedtls-devel \
|
||||
python-devel \
|
||||
freetype-devel
|
||||
15
dist/get_deps_msys2.sh
vendored
Executable file
15
dist/get_deps_msys2.sh
vendored
Executable file
@@ -0,0 +1,15 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
pacman -S --needed \
|
||||
mingw-w64-x86_64-gcc \
|
||||
mingw-w64-x86_64-cmake \
|
||||
mingw-w64-x86_64-make \
|
||||
mingw-w64-x86_64-capstone \
|
||||
mingw-w64-x86_64-glfw \
|
||||
mingw-w64-x86_64-glm \
|
||||
mingw-w64-x86_64-file \
|
||||
mingw-w64-x86_64-mbedtls \
|
||||
mingw-w64-x86_64-polly \
|
||||
mingw-w64-x86_64-python \
|
||||
mingw-w64-x86_64-freetype \
|
||||
mingw-w64-x86_64-dlfcn
|
||||
46
dist/msys2/PKGBUILD
vendored
Normal file
46
dist/msys2/PKGBUILD
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
_realname=ImHex
|
||||
pkgbase=mingw-w64-${_realname}
|
||||
pkgname="${MINGW_PACKAGE_PREFIX}-${_realname}"
|
||||
pkgver=ci
|
||||
pkgrel=1
|
||||
pkgdesc="${_realname}: a Hex Editor for Reverse Engineers, Programmers and people that value their eye sight when working at 3 AM (mingw-w64)"
|
||||
arch=('any')
|
||||
url="https://github.com/WerWolv/ImHex"
|
||||
license=('GPLv2')
|
||||
depends=("${MINGW_PACKAGE_PREFIX}-python")
|
||||
makedepends=("${MINGW_PACKAGE_PREFIX}-gcc"
|
||||
"${MINGW_PACKAGE_PREFIX}-cmake"
|
||||
"${MINGW_PACKAGE_PREFIX}-make"
|
||||
"${MINGW_PACKAGE_PREFIX}-dlsym"
|
||||
"${MINGW_PACKAGE_PREFIX}-capstone"
|
||||
"${MINGW_PACKAGE_PREFIX}-glfw"
|
||||
"${MINGW_PACKAGE_PREFIX}-glm"
|
||||
"${MINGW_PACKAGE_PREFIX}-file"
|
||||
"${MINGW_PACKAGE_PREFIX}-openssl"
|
||||
"${MINGW_PACKAGE_PREFIX}-polly"
|
||||
"${MINGW_PACKAGE_PREFIX}-python"
|
||||
"${MINGW_PACKAGE_PREFIX}-freetype")
|
||||
|
||||
source=()
|
||||
sha256sums=()
|
||||
|
||||
build() {
|
||||
cd "${srcdir}"/../..
|
||||
mkdir build
|
||||
cd build
|
||||
export BUILD_TYPE='Release'
|
||||
MSYS2_ARG_CONV_EXCL=- cmake \
|
||||
-G "MinGW Makefiles" \
|
||||
-DCMAKE_INSTALL_PREFIX="${MINGW_PREFIX}" \
|
||||
../../
|
||||
mingw32-make
|
||||
}
|
||||
|
||||
package() {
|
||||
cd "${srcdir}"/../../build
|
||||
mingw32-make DESTDIR="${pkgdir}" install
|
||||
|
||||
_licenses="${pkgdir}${MINGW_PREFIX}/share/licenses/${_realname}"
|
||||
mkdir -p "${_licenses}"
|
||||
install -m 644 ../LICENSE "${_licenses}"
|
||||
}
|
||||
40
external/ImGui/CMakeLists.txt
vendored
Normal file
40
external/ImGui/CMakeLists.txt
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
project(imgui)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
|
||||
find_package(PkgConfig REQUIRED)
|
||||
find_package(Freetype REQUIRED)
|
||||
pkg_search_module(GLM REQUIRED glm)
|
||||
pkg_search_module(GLFW REQUIRED glfw3)
|
||||
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC")
|
||||
|
||||
add_library(imgui
|
||||
source/imgui.cpp
|
||||
source/imgui_demo.cpp
|
||||
source/imgui_draw.cpp
|
||||
source/imgui_freetype.cpp
|
||||
source/imgui_impl_glfw.cpp
|
||||
source/imgui_impl_opengl3.cpp
|
||||
source/imgui_tables.cpp
|
||||
source/imgui_widgets.cpp
|
||||
source/ImGuiFileBrowser.cpp
|
||||
source/TextEditor.cpp
|
||||
source/imgui_imhex_extensions.cpp
|
||||
source/imnodes.cpp
|
||||
)
|
||||
|
||||
add_compile_definitions(IMGUI_IMPL_OPENGL_LOADER_GLAD)
|
||||
|
||||
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../glad ${CMAKE_CURRENT_BINARY_DIR}/external/glad)
|
||||
|
||||
target_include_directories(imgui PUBLIC include ${FREETYPE_INCLUDE_DIRS} ${GLFW_INCLUDE_DIRS})
|
||||
|
||||
target_link_directories(imgui PUBLIC ${GLM_INCLUDE_DIRS} ${GLFW_LIBRARY_DIRS})
|
||||
|
||||
if (WIN32)
|
||||
target_link_libraries(imgui libstdc++.a libgcc.a libharfbuzz.a libfreetype.a libharfbuzz.a libgraphite2.a libpng.a libbrotlidec-static.a libbrotlicommon-static.a libz.a libbz2.a librpcrt4.a glad libglfw3.a)
|
||||
elseif (UNIX)
|
||||
target_link_libraries(imgui Freetype::Freetype glad glfw)
|
||||
endif()
|
||||
1160
external/ImGui/include/Dirent/dirent.h
vendored
Normal file
1160
external/ImGui/include/Dirent/dirent.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
123
external/ImGui/include/ImGuiFileBrowser.h
vendored
Normal file
123
external/ImGui/include/ImGuiFileBrowser.h
vendored
Normal file
@@ -0,0 +1,123 @@
|
||||
#ifndef IMGUIFILEBROWSER_H
|
||||
#define IMGUIFILEBROWSER_H
|
||||
|
||||
#include <imgui.h>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace imgui_addons
|
||||
{
|
||||
class ImGuiFileBrowser
|
||||
{
|
||||
public:
|
||||
ImGuiFileBrowser();
|
||||
~ImGuiFileBrowser();
|
||||
|
||||
enum class DialogMode
|
||||
{
|
||||
SELECT, //Select Directory Mode
|
||||
OPEN, //Open File mode
|
||||
SAVE //Save File mode.
|
||||
};
|
||||
|
||||
/* Use this to show an open file dialog. The function takes label for the window,
|
||||
* the size, a DialogMode enum value defining in which mode the dialog should operate and optionally the extensions that are valid for opening.
|
||||
* Note that the select directory mode doesn't need any extensions.
|
||||
*/
|
||||
bool showFileDialog(const std::string& label, const DialogMode mode, const ImVec2& sz_xy = ImVec2(0,0), const std::string& valid_types = "*.*");
|
||||
|
||||
/* Store the opened/saved file name or dir name (incase of selectDirectoryDialog) and the absolute path to the selection
|
||||
* Should only be accessed when above functions return true else may contain garbage.
|
||||
*/
|
||||
std::string selected_fn;
|
||||
std::string selected_path;
|
||||
std::string ext; // Store the saved file extension
|
||||
|
||||
|
||||
private:
|
||||
struct Info
|
||||
{
|
||||
Info(std::string name, bool is_hidden) : name(name), is_hidden(is_hidden)
|
||||
{
|
||||
}
|
||||
std::string name;
|
||||
bool is_hidden;
|
||||
};
|
||||
|
||||
//Enum used as bit flags.
|
||||
enum FilterMode
|
||||
{
|
||||
FilterMode_Files = 0x01,
|
||||
FilterMode_Dirs = 0x02
|
||||
};
|
||||
|
||||
//Helper Functions
|
||||
static std::string wStringToString(const wchar_t* wchar_arr);
|
||||
static bool alphaSortComparator(const Info& a, const Info& b);
|
||||
ImVec2 getButtonSize(std::string button_text);
|
||||
|
||||
/* Helper Functions that render secondary modals
|
||||
* and help in validating file extensions and for filtering, parsing top navigation bar.
|
||||
*/
|
||||
void setValidExtTypes(const std::string& valid_types_string);
|
||||
bool validateFile();
|
||||
void showErrorModal();
|
||||
void showInvalidFileModal();
|
||||
bool showReplaceFileModal();
|
||||
void showHelpMarker(std::string desc);
|
||||
void parsePathTabs(std::string str);
|
||||
void filterFiles(int filter_mode);
|
||||
|
||||
/* Core Functions that render the 4 different regions making up
|
||||
* a simple file dialog
|
||||
*/
|
||||
bool renderNavAndSearchBarRegion();
|
||||
bool renderFileListRegion();
|
||||
bool renderInputTextAndExtRegion();
|
||||
bool renderButtonsAndCheckboxRegion();
|
||||
bool renderInputComboBox();
|
||||
void renderExtBox();
|
||||
|
||||
/* Core Functions that handle navigation and
|
||||
* reading directories/files
|
||||
*/
|
||||
bool readDIR(std::string path);
|
||||
bool onNavigationButtonClick(int idx);
|
||||
bool onDirClick(int idx);
|
||||
|
||||
// Functions that reset state and/or clear file list when reading new directory
|
||||
void clearFileList();
|
||||
void closeDialog();
|
||||
|
||||
#if defined (WIN32) || defined (_WIN32) || defined (__WIN32)
|
||||
bool loadWindowsDrives(); // Helper Function for Windows to load Drive Letters.
|
||||
#endif
|
||||
|
||||
#if defined(unix) || defined(__unix__) || defined(__unix) || defined(__APPLE__)
|
||||
void initCurrentPath(); // Helper function for UNIX based system to load Absolute path using realpath
|
||||
#endif
|
||||
|
||||
ImVec2 min_size, max_size, input_combobox_pos, input_combobox_sz;
|
||||
DialogMode dialog_mode;
|
||||
int filter_mode, col_items_limit, selected_idx, selected_ext_idx;
|
||||
float col_width, ext_box_width;
|
||||
bool show_hidden, show_inputbar_combobox, is_dir, is_appearing, filter_dirty, validate_file, path_input_enabled;
|
||||
char input_fn[256];
|
||||
char temp_dir_input[256];
|
||||
|
||||
std::vector<std::string> valid_exts;
|
||||
std::vector<std::string> current_dirlist;
|
||||
std::vector<Info> subdirs;
|
||||
std::vector<Info> subfiles;
|
||||
std::string current_path, error_msg, error_title, invfile_modal_id, repfile_modal_id;
|
||||
|
||||
ImGuiTextFilter filter;
|
||||
std::string valid_types;
|
||||
std::vector<const Info*> filtered_dirs; // Note: We don't need to call delete. It's just for storing filtered items from subdirs and subfiles so we don't use PassFilter every frame.
|
||||
std::vector<const Info*> filtered_files;
|
||||
std::vector< std::reference_wrapper<std::string> > inputcb_filter_files;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
#endif // IMGUIFILEBROWSER_H
|
||||
395
external/ImGui/include/TextEditor.h
vendored
Normal file
395
external/ImGui/include/TextEditor.h
vendored
Normal file
@@ -0,0 +1,395 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <array>
|
||||
#include <memory>
|
||||
#include <unordered_set>
|
||||
#include <unordered_map>
|
||||
#include <map>
|
||||
#include <regex>
|
||||
#include "imgui.h"
|
||||
|
||||
class TextEditor
|
||||
{
|
||||
public:
|
||||
enum class PaletteIndex
|
||||
{
|
||||
Default,
|
||||
Keyword,
|
||||
Number,
|
||||
String,
|
||||
CharLiteral,
|
||||
Punctuation,
|
||||
Preprocessor,
|
||||
Identifier,
|
||||
KnownIdentifier,
|
||||
PreprocIdentifier,
|
||||
Comment,
|
||||
MultiLineComment,
|
||||
Background,
|
||||
Cursor,
|
||||
Selection,
|
||||
ErrorMarker,
|
||||
Breakpoint,
|
||||
LineNumber,
|
||||
CurrentLineFill,
|
||||
CurrentLineFillInactive,
|
||||
CurrentLineEdge,
|
||||
Max
|
||||
};
|
||||
|
||||
enum class SelectionMode
|
||||
{
|
||||
Normal,
|
||||
Word,
|
||||
Line
|
||||
};
|
||||
|
||||
struct Breakpoint
|
||||
{
|
||||
int mLine;
|
||||
bool mEnabled;
|
||||
std::string mCondition;
|
||||
|
||||
Breakpoint()
|
||||
: mLine(-1)
|
||||
, mEnabled(false)
|
||||
{}
|
||||
};
|
||||
|
||||
// Represents a character coordinate from the user's point of view,
|
||||
// i. e. consider an uniform grid (assuming fixed-width font) on the
|
||||
// screen as it is rendered, and each cell has its own coordinate, starting from 0.
|
||||
// Tabs are counted as [1..mTabSize] count empty spaces, depending on
|
||||
// how many space is necessary to reach the next tab stop.
|
||||
// For example, coordinate (1, 5) represents the character 'B' in a line "\tABC", when mTabSize = 4,
|
||||
// because it is rendered as " ABC" on the screen.
|
||||
struct Coordinates
|
||||
{
|
||||
int mLine, mColumn;
|
||||
Coordinates() : mLine(0), mColumn(0) {}
|
||||
Coordinates(int aLine, int aColumn) : mLine(aLine), mColumn(aColumn)
|
||||
{
|
||||
assert(aLine >= 0);
|
||||
assert(aColumn >= 0);
|
||||
}
|
||||
static Coordinates Invalid() { static Coordinates invalid(-1, -1); return invalid; }
|
||||
|
||||
bool operator ==(const Coordinates& o) const
|
||||
{
|
||||
return
|
||||
mLine == o.mLine &&
|
||||
mColumn == o.mColumn;
|
||||
}
|
||||
|
||||
bool operator !=(const Coordinates& o) const
|
||||
{
|
||||
return
|
||||
mLine != o.mLine ||
|
||||
mColumn != o.mColumn;
|
||||
}
|
||||
|
||||
bool operator <(const Coordinates& o) const
|
||||
{
|
||||
if (mLine != o.mLine)
|
||||
return mLine < o.mLine;
|
||||
return mColumn < o.mColumn;
|
||||
}
|
||||
|
||||
bool operator >(const Coordinates& o) const
|
||||
{
|
||||
if (mLine != o.mLine)
|
||||
return mLine > o.mLine;
|
||||
return mColumn > o.mColumn;
|
||||
}
|
||||
|
||||
bool operator <=(const Coordinates& o) const
|
||||
{
|
||||
if (mLine != o.mLine)
|
||||
return mLine < o.mLine;
|
||||
return mColumn <= o.mColumn;
|
||||
}
|
||||
|
||||
bool operator >=(const Coordinates& o) const
|
||||
{
|
||||
if (mLine != o.mLine)
|
||||
return mLine > o.mLine;
|
||||
return mColumn >= o.mColumn;
|
||||
}
|
||||
};
|
||||
|
||||
struct Identifier
|
||||
{
|
||||
Coordinates mLocation;
|
||||
std::string mDeclaration;
|
||||
};
|
||||
|
||||
typedef std::string String;
|
||||
typedef std::unordered_map<std::string, Identifier> Identifiers;
|
||||
typedef std::unordered_set<std::string> Keywords;
|
||||
typedef std::map<int, std::string> ErrorMarkers;
|
||||
typedef std::unordered_set<int> Breakpoints;
|
||||
typedef std::array<ImU32, (unsigned)PaletteIndex::Max> Palette;
|
||||
typedef uint8_t Char;
|
||||
|
||||
struct Glyph
|
||||
{
|
||||
Char mChar;
|
||||
PaletteIndex mColorIndex = PaletteIndex::Default;
|
||||
bool mComment : 1;
|
||||
bool mMultiLineComment : 1;
|
||||
bool mPreprocessor : 1;
|
||||
|
||||
Glyph(Char aChar, PaletteIndex aColorIndex) : mChar(aChar), mColorIndex(aColorIndex),
|
||||
mComment(false), mMultiLineComment(false), mPreprocessor(false) {}
|
||||
};
|
||||
|
||||
typedef std::vector<Glyph> Line;
|
||||
typedef std::vector<Line> Lines;
|
||||
|
||||
struct LanguageDefinition
|
||||
{
|
||||
typedef std::pair<std::string, PaletteIndex> TokenRegexString;
|
||||
typedef std::vector<TokenRegexString> TokenRegexStrings;
|
||||
typedef bool(*TokenizeCallback)(const char * in_begin, const char * in_end, const char *& out_begin, const char *& out_end, PaletteIndex & paletteIndex);
|
||||
|
||||
std::string mName;
|
||||
Keywords mKeywords;
|
||||
Identifiers mIdentifiers;
|
||||
Identifiers mPreprocIdentifiers;
|
||||
std::string mCommentStart, mCommentEnd, mSingleLineComment;
|
||||
char mPreprocChar;
|
||||
bool mAutoIndentation;
|
||||
|
||||
TokenizeCallback mTokenize;
|
||||
|
||||
TokenRegexStrings mTokenRegexStrings;
|
||||
|
||||
bool mCaseSensitive;
|
||||
|
||||
LanguageDefinition()
|
||||
: mPreprocChar('#'), mAutoIndentation(true), mTokenize(nullptr), mCaseSensitive(true)
|
||||
{
|
||||
}
|
||||
|
||||
static const LanguageDefinition& CPlusPlus();
|
||||
static const LanguageDefinition& HLSL();
|
||||
static const LanguageDefinition& GLSL();
|
||||
static const LanguageDefinition& C();
|
||||
static const LanguageDefinition& SQL();
|
||||
static const LanguageDefinition& AngelScript();
|
||||
static const LanguageDefinition& Lua();
|
||||
};
|
||||
|
||||
TextEditor();
|
||||
~TextEditor();
|
||||
|
||||
void SetLanguageDefinition(const LanguageDefinition& aLanguageDef);
|
||||
const LanguageDefinition& GetLanguageDefinition() const { return mLanguageDefinition; }
|
||||
|
||||
const Palette& GetPalette() const { return mPaletteBase; }
|
||||
void SetPalette(const Palette& aValue);
|
||||
|
||||
void SetErrorMarkers(const ErrorMarkers& aMarkers) { mErrorMarkers = aMarkers; }
|
||||
void SetBreakpoints(const Breakpoints& aMarkers) { mBreakpoints = aMarkers; }
|
||||
|
||||
void Render(const char* aTitle, const ImVec2& aSize = ImVec2(), bool aBorder = false);
|
||||
void SetText(const std::string& aText);
|
||||
std::string GetText() const;
|
||||
|
||||
void SetTextLines(const std::vector<std::string>& aLines);
|
||||
std::vector<std::string> GetTextLines() const;
|
||||
|
||||
std::string GetSelectedText() const;
|
||||
std::string GetCurrentLineText()const;
|
||||
|
||||
int GetTotalLines() const { return (int)mLines.size(); }
|
||||
bool IsOverwrite() const { return mOverwrite; }
|
||||
|
||||
void SetReadOnly(bool aValue);
|
||||
bool IsReadOnly() const { return mReadOnly; }
|
||||
bool IsTextChanged() const { return mTextChanged; }
|
||||
bool IsCursorPositionChanged() const { return mCursorPositionChanged; }
|
||||
|
||||
bool IsColorizerEnabled() const { return mColorizerEnabled; }
|
||||
void SetColorizerEnable(bool aValue);
|
||||
|
||||
Coordinates GetCursorPosition() const { return GetActualCursorCoordinates(); }
|
||||
void SetCursorPosition(const Coordinates& aPosition);
|
||||
|
||||
inline void SetHandleMouseInputs (bool aValue){ mHandleMouseInputs = aValue;}
|
||||
inline bool IsHandleMouseInputsEnabled() const { return mHandleKeyboardInputs; }
|
||||
|
||||
inline void SetHandleKeyboardInputs (bool aValue){ mHandleKeyboardInputs = aValue;}
|
||||
inline bool IsHandleKeyboardInputsEnabled() const { return mHandleKeyboardInputs; }
|
||||
|
||||
inline void SetImGuiChildIgnored (bool aValue){ mIgnoreImGuiChild = aValue;}
|
||||
inline bool IsImGuiChildIgnored() const { return mIgnoreImGuiChild; }
|
||||
|
||||
inline void SetShowWhitespaces(bool aValue) { mShowWhitespaces = aValue; }
|
||||
inline bool IsShowingWhitespaces() const { return mShowWhitespaces; }
|
||||
|
||||
void SetTabSize(int aValue);
|
||||
inline int GetTabSize() const { return mTabSize; }
|
||||
|
||||
void InsertText(const std::string& aValue);
|
||||
void InsertText(const char* aValue);
|
||||
|
||||
void MoveUp(int aAmount = 1, bool aSelect = false);
|
||||
void MoveDown(int aAmount = 1, bool aSelect = false);
|
||||
void MoveLeft(int aAmount = 1, bool aSelect = false, bool aWordMode = false);
|
||||
void MoveRight(int aAmount = 1, bool aSelect = false, bool aWordMode = false);
|
||||
void MoveTop(bool aSelect = false);
|
||||
void MoveBottom(bool aSelect = false);
|
||||
void MoveHome(bool aSelect = false);
|
||||
void MoveEnd(bool aSelect = false);
|
||||
|
||||
void SetSelectionStart(const Coordinates& aPosition);
|
||||
void SetSelectionEnd(const Coordinates& aPosition);
|
||||
void SetSelection(const Coordinates& aStart, const Coordinates& aEnd, SelectionMode aMode = SelectionMode::Normal);
|
||||
void SelectWordUnderCursor();
|
||||
void SelectAll();
|
||||
bool HasSelection() const;
|
||||
|
||||
void Copy();
|
||||
void Cut();
|
||||
void Paste();
|
||||
void Delete();
|
||||
|
||||
bool CanUndo() const;
|
||||
bool CanRedo() const;
|
||||
void Undo(int aSteps = 1);
|
||||
void Redo(int aSteps = 1);
|
||||
|
||||
static const Palette& GetDarkPalette();
|
||||
static const Palette& GetLightPalette();
|
||||
static const Palette& GetRetroBluePalette();
|
||||
|
||||
private:
|
||||
typedef std::vector<std::pair<std::regex, PaletteIndex>> RegexList;
|
||||
|
||||
struct EditorState
|
||||
{
|
||||
Coordinates mSelectionStart;
|
||||
Coordinates mSelectionEnd;
|
||||
Coordinates mCursorPosition;
|
||||
};
|
||||
|
||||
class UndoRecord
|
||||
{
|
||||
public:
|
||||
UndoRecord() {}
|
||||
~UndoRecord() {}
|
||||
|
||||
UndoRecord(
|
||||
const std::string& aAdded,
|
||||
const TextEditor::Coordinates aAddedStart,
|
||||
const TextEditor::Coordinates aAddedEnd,
|
||||
|
||||
const std::string& aRemoved,
|
||||
const TextEditor::Coordinates aRemovedStart,
|
||||
const TextEditor::Coordinates aRemovedEnd,
|
||||
|
||||
TextEditor::EditorState& aBefore,
|
||||
TextEditor::EditorState& aAfter);
|
||||
|
||||
void Undo(TextEditor* aEditor);
|
||||
void Redo(TextEditor* aEditor);
|
||||
|
||||
std::string mAdded;
|
||||
Coordinates mAddedStart;
|
||||
Coordinates mAddedEnd;
|
||||
|
||||
std::string mRemoved;
|
||||
Coordinates mRemovedStart;
|
||||
Coordinates mRemovedEnd;
|
||||
|
||||
EditorState mBefore;
|
||||
EditorState mAfter;
|
||||
};
|
||||
|
||||
typedef std::vector<UndoRecord> UndoBuffer;
|
||||
|
||||
void ProcessInputs();
|
||||
void Colorize(int aFromLine = 0, int aCount = -1);
|
||||
void ColorizeRange(int aFromLine = 0, int aToLine = 0);
|
||||
void ColorizeInternal();
|
||||
float TextDistanceToLineStart(const Coordinates& aFrom) const;
|
||||
void EnsureCursorVisible();
|
||||
int GetPageSize() const;
|
||||
std::string GetText(const Coordinates& aStart, const Coordinates& aEnd) const;
|
||||
Coordinates GetActualCursorCoordinates() const;
|
||||
Coordinates SanitizeCoordinates(const Coordinates& aValue) const;
|
||||
void Advance(Coordinates& aCoordinates) const;
|
||||
void DeleteRange(const Coordinates& aStart, const Coordinates& aEnd);
|
||||
int InsertTextAt(Coordinates& aWhere, const char* aValue);
|
||||
void AddUndo(UndoRecord& aValue);
|
||||
Coordinates ScreenPosToCoordinates(const ImVec2& aPosition) const;
|
||||
Coordinates FindWordStart(const Coordinates& aFrom) const;
|
||||
Coordinates FindWordEnd(const Coordinates& aFrom) const;
|
||||
Coordinates FindNextWord(const Coordinates& aFrom) const;
|
||||
int GetCharacterIndex(const Coordinates& aCoordinates) const;
|
||||
int GetCharacterColumn(int aLine, int aIndex) const;
|
||||
int GetLineCharacterCount(int aLine) const;
|
||||
int GetLineMaxColumn(int aLine) const;
|
||||
bool IsOnWordBoundary(const Coordinates& aAt) const;
|
||||
void RemoveLine(int aStart, int aEnd);
|
||||
void RemoveLine(int aIndex);
|
||||
Line& InsertLine(int aIndex);
|
||||
void EnterCharacter(ImWchar aChar, bool aShift);
|
||||
void Backspace();
|
||||
void DeleteSelection();
|
||||
std::string GetWordUnderCursor() const;
|
||||
std::string GetWordAt(const Coordinates& aCoords) const;
|
||||
ImU32 GetGlyphColor(const Glyph& aGlyph) const;
|
||||
|
||||
void HandleKeyboardInputs();
|
||||
void HandleMouseInputs();
|
||||
void Render();
|
||||
|
||||
float mLineSpacing;
|
||||
Lines mLines;
|
||||
EditorState mState;
|
||||
UndoBuffer mUndoBuffer;
|
||||
int mUndoIndex;
|
||||
|
||||
int mTabSize;
|
||||
bool mOverwrite;
|
||||
bool mReadOnly;
|
||||
bool mWithinRender;
|
||||
bool mScrollToCursor;
|
||||
bool mScrollToTop;
|
||||
bool mTextChanged;
|
||||
bool mColorizerEnabled;
|
||||
float mTextStart; // position (in pixels) where a code line starts relative to the left of the TextEditor.
|
||||
int mLeftMargin;
|
||||
bool mCursorPositionChanged;
|
||||
int mColorRangeMin, mColorRangeMax;
|
||||
SelectionMode mSelectionMode;
|
||||
bool mHandleKeyboardInputs;
|
||||
bool mHandleMouseInputs;
|
||||
bool mIgnoreImGuiChild;
|
||||
bool mShowWhitespaces;
|
||||
|
||||
Palette mPaletteBase;
|
||||
Palette mPalette;
|
||||
LanguageDefinition mLanguageDefinition;
|
||||
RegexList mRegexList;
|
||||
|
||||
bool mCheckComments;
|
||||
Breakpoints mBreakpoints;
|
||||
ErrorMarkers mErrorMarkers;
|
||||
ImVec2 mCharAdvance;
|
||||
Coordinates mInteractiveStart, mInteractiveEnd;
|
||||
std::string mLineBuffer;
|
||||
uint64_t mStartTime;
|
||||
|
||||
float mLastClick;
|
||||
};
|
||||
|
||||
bool TokenizeCStyleString(const char * in_begin, const char * in_end, const char *& out_begin, const char *& out_end);
|
||||
bool TokenizeCStyleCharacterLiteral(const char * in_begin, const char * in_end, const char *& out_begin, const char *& out_end);
|
||||
bool TokenizeCStyleIdentifier(const char * in_begin, const char * in_end, const char *& out_begin, const char *& out_end);
|
||||
bool TokenizeCStyleNumber(const char * in_begin, const char * in_end, const char *& out_begin, const char *& out_end);
|
||||
bool TokenizeCStylePunctuation(const char * in_begin, const char * in_end, const char *& out_begin, const char *& out_end);
|
||||
@@ -31,7 +31,7 @@
|
||||
// It is very strongly recommended to NOT disable the demo windows during development. Please read comments in imgui_demo.cpp.
|
||||
//#define IMGUI_DISABLE // Disable everything: all headers and source files will be empty.
|
||||
//#define IMGUI_DISABLE_DEMO_WINDOWS // Disable demo windows: ShowDemoWindow()/ShowStyleEditor() will be empty. Not recommended.
|
||||
//#define IMGUI_DISABLE_METRICS_WINDOW // Disable debug/metrics window: ShowMetricsWindow() will be empty.
|
||||
//#define IMGUI_DISABLE_METRICS_WINDOW // Disable metrics/debugger window: ShowMetricsWindow() will be empty.
|
||||
|
||||
//---- Don't implement some functions to reduce linkage requirements.
|
||||
//#define IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCTIONS // [Win32] Don't implement default clipboard handler. Won't use and link with OpenClipboard/GetClipboardData/CloseClipboard etc.
|
||||
@@ -59,8 +59,8 @@
|
||||
//#define IMGUI_DISABLE_STB_TRUETYPE_IMPLEMENTATION
|
||||
//#define IMGUI_DISABLE_STB_RECT_PACK_IMPLEMENTATION
|
||||
|
||||
//---- Unless IMGUI_DISABLE_DEFAULT_FORMAT_FUNCTIONS is defined, use the much faster STB sprintf library implementation of vsnprintf instead of the one from the default C library.
|
||||
// Note that stb_sprintf.h is meant to be provided by the user and available in the include path at compile time. Also, the compatibility checks of the arguments and formats done by clang and GCC will be disabled in order to support the extra formats provided by STB sprintf.
|
||||
//---- Use stb_printf's faster implementation of vsnprintf instead of the one from libc (unless IMGUI_DISABLE_DEFAULT_FORMAT_FUNCTIONS is defined)
|
||||
// Requires 'stb_sprintf.h' to be available in the include path. Compatibility checks of arguments and formats done by clang and GCC will be disabled in order to support the extra formats provided by STB sprintf.
|
||||
// #define IMGUI_USE_STB_SPRINTF
|
||||
|
||||
//---- Define constructor and implicit cast operators to convert back<>forth between your math types and ImVec2/ImVec4.
|
||||
@@ -1,4 +1,4 @@
|
||||
// dear imgui, v1.80 WIP
|
||||
// dear imgui, v1.80
|
||||
// (headers)
|
||||
|
||||
// Help:
|
||||
@@ -19,26 +19,25 @@
|
||||
/*
|
||||
|
||||
Index of this file:
|
||||
// Header mess
|
||||
// Forward declarations and basic types
|
||||
// ImGui API (Dear ImGui end-user API)
|
||||
// Flags & Enumerations
|
||||
// Memory allocations macros
|
||||
// ImVector<>
|
||||
// ImGuiStyle
|
||||
// ImGuiIO
|
||||
// Misc data structures (ImGuiInputTextCallbackData, ImGuiSizeCallbackData, ImGuiWindowClass, ImGuiPayload)
|
||||
// Obsolete functions
|
||||
// Helpers (ImGuiOnceUponAFrame, ImGuiTextFilter, ImGuiTextBuffer, ImGuiStorage, ImGuiListClipper, ImColor)
|
||||
// Draw List API (ImDrawCallback, ImDrawCmd, ImDrawIdx, ImDrawVert, ImDrawChannel, ImDrawListSplitter, ImDrawListFlags, ImDrawList, ImDrawData)
|
||||
// Font API (ImFontConfig, ImFontGlyph, ImFontGlyphRangesBuilder, ImFontAtlasFlags, ImFontAtlas, ImFont)
|
||||
// Platform interface for multi-viewport support (ImGuiPlatformIO, ImGuiPlatformMonitor, ImGuiViewportFlags, ImGuiViewport)
|
||||
// [SECTION] Header mess
|
||||
// [SECTION] Forward declarations and basic types
|
||||
// [SECTION] Dear ImGui end-user API functions
|
||||
// [SECTION] Flags & Enumerations
|
||||
// [SECTION] Helpers: Memory allocations macros, ImVector<>
|
||||
// [SECTION] ImGuiStyle
|
||||
// [SECTION] ImGuiIO
|
||||
// [SECTION] Misc data structures (ImGuiInputTextCallbackData, ImGuiSizeCallbackData, ImGuiWindowClass, ImGuiPayload, ImGuiTableSortSpecs, ImGuiTableColumnSortSpecs)
|
||||
// [SECTION] Obsolete functions
|
||||
// [SECTION] Helpers (ImGuiOnceUponAFrame, ImGuiTextFilter, ImGuiTextBuffer, ImGuiStorage, ImGuiListClipper, ImColor)
|
||||
// [SECTION] Drawing API (ImDrawCallback, ImDrawCmd, ImDrawIdx, ImDrawVert, ImDrawChannel, ImDrawListSplitter, ImDrawListFlags, ImDrawList, ImDrawData)
|
||||
// [SECTION] Font API (ImFontConfig, ImFontGlyph, ImFontGlyphRangesBuilder, ImFontAtlasFlags, ImFontAtlas, ImFont)
|
||||
// [SECTION] Platform interface for multi-viewport support (ImGuiPlatformIO, ImGuiPlatformMonitor, ImGuiViewportFlags, ImGuiViewport)
|
||||
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
// Configuration file with compile-time options (edit imconfig.h or #define IMGUI_USER_CONFIG to your own filename)
|
||||
// Configuration file with compile-time options (edit imconfig.h or '#define IMGUI_USER_CONFIG "myfilename.h" from your build system')
|
||||
#ifdef IMGUI_USER_CONFIG
|
||||
#include IMGUI_USER_CONFIG
|
||||
#endif
|
||||
@@ -49,7 +48,7 @@ Index of this file:
|
||||
#ifndef IMGUI_DISABLE
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Header mess
|
||||
// [SECTION] Header mess
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// Includes
|
||||
@@ -60,11 +59,12 @@ Index of this file:
|
||||
|
||||
// Version
|
||||
// (Integer encoded as XYYZZ for use in #if preprocessor conditionals. Work in progress versions typically starts at XYY99 then bounce up to XYY00, XYY01 etc. when release tagging happens)
|
||||
#define IMGUI_VERSION "1.80 WIP"
|
||||
#define IMGUI_VERSION_NUM 17905
|
||||
#define IMGUI_VERSION "1.80"
|
||||
#define IMGUI_VERSION_NUM 18000
|
||||
#define IMGUI_CHECKVERSION() ImGui::DebugCheckVersionAndDataLayout(IMGUI_VERSION, sizeof(ImGuiIO), sizeof(ImGuiStyle), sizeof(ImVec2), sizeof(ImVec4), sizeof(ImDrawVert), sizeof(ImDrawIdx))
|
||||
#define IMGUI_HAS_VIEWPORT 1 // Viewport WIP branch
|
||||
#define IMGUI_HAS_DOCK 1 // Docking WIP branch
|
||||
#define IMGUI_HAS_TABLE
|
||||
#define IMGUI_HAS_VIEWPORT // Viewport WIP branch
|
||||
#define IMGUI_HAS_DOCK // Docking WIP branch
|
||||
|
||||
// Define attributes of all API symbols declarations (e.g. for DLL under Windows)
|
||||
// IMGUI_API is used for core imgui functions, IMGUI_IMPL_API is used for the default backends files (imgui_impl_xxx.h)
|
||||
@@ -81,21 +81,26 @@ Index of this file:
|
||||
#include <assert.h>
|
||||
#define IM_ASSERT(_EXPR) assert(_EXPR) // You can override the default assert handler by editing imconfig.h
|
||||
#endif
|
||||
#if !defined(IMGUI_USE_STB_SPRINTF) && (defined(__clang__) || defined(__GNUC__))
|
||||
#define IM_FMTARGS(FMT) __attribute__((format(printf, FMT, FMT+1))) // To apply printf-style warnings to our functions.
|
||||
#define IM_FMTLIST(FMT) __attribute__((format(printf, FMT, 0)))
|
||||
#else
|
||||
#define IM_FMTARGS(FMT)
|
||||
#define IM_FMTLIST(FMT)
|
||||
#endif
|
||||
#define IM_ARRAYSIZE(_ARR) ((int)(sizeof(_ARR) / sizeof(*(_ARR)))) // Size of a static C-style array. Don't use on pointers!
|
||||
#define IM_UNUSED(_VAR) ((void)(_VAR)) // Used to silence "unused variable warnings". Often useful as asserts may be stripped out from final builds.
|
||||
#if (__cplusplus >= 201100)
|
||||
#if (__cplusplus >= 201100) || (defined(_MSVC_LANG) && _MSVC_LANG >= 201100)
|
||||
#define IM_OFFSETOF(_TYPE,_MEMBER) offsetof(_TYPE, _MEMBER) // Offset of _MEMBER within _TYPE. Standardized as offsetof() in C++11
|
||||
#else
|
||||
#define IM_OFFSETOF(_TYPE,_MEMBER) ((size_t)&(((_TYPE*)0)->_MEMBER)) // Offset of _MEMBER within _TYPE. Old style macro.
|
||||
#endif
|
||||
|
||||
// Helper Macros - IM_FMTARGS, IM_FMTLIST: Apply printf-style warnings to our formatting functions.
|
||||
#if !defined(IMGUI_USE_STB_SPRINTF) && defined(__clang__)
|
||||
#define IM_FMTARGS(FMT) __attribute__((format(printf, FMT, FMT+1)))
|
||||
#define IM_FMTLIST(FMT) __attribute__((format(printf, FMT, 0)))
|
||||
#elif !defined(IMGUI_USE_STB_SPRINTF) && defined(__GNUC__) && defined(__MINGW32__)
|
||||
#define IM_FMTARGS(FMT) __attribute__((format(gnu_printf, FMT, FMT+1)))
|
||||
#define IM_FMTLIST(FMT) __attribute__((format(gnu_printf, FMT, 0)))
|
||||
#else
|
||||
#define IM_FMTARGS(FMT)
|
||||
#define IM_FMTLIST(FMT)
|
||||
#endif
|
||||
|
||||
// Warnings
|
||||
#if defined(__clang__)
|
||||
#pragma clang diagnostic push
|
||||
@@ -105,12 +110,12 @@ Index of this file:
|
||||
#endif
|
||||
#elif defined(__GNUC__)
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wpragmas" // warning: unknown option after '#pragma GCC diagnostic' kind
|
||||
#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 "-Wpragmas" // warning: unknown option after '#pragma GCC diagnostic' kind
|
||||
#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
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Forward declarations and basic types
|
||||
// [SECTION] Forward declarations and basic types
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// Forward declarations
|
||||
@@ -138,6 +143,8 @@ struct ImGuiPlatformMonitor; // Multi-viewport support: user-provided bou
|
||||
struct ImGuiSizeCallbackData; // Callback data when using SetNextWindowSizeConstraints() (rare/advanced use)
|
||||
struct ImGuiStorage; // Helper for key->value storage
|
||||
struct ImGuiStyle; // Runtime data for styling/colors
|
||||
struct ImGuiTableSortSpecs; // Sorting specifications for a table (often handling sort specs for a single column, occasionally more)
|
||||
struct ImGuiTableColumnSortSpecs; // Sorting specification for one column of a table
|
||||
struct ImGuiTextBuffer; // Helper to hold and append into a text buffer (~string builder)
|
||||
struct ImGuiTextFilter; // Helper to parse and apply text filters (e.g. "aaaaa[,bbbbb][,ccccc]")
|
||||
struct ImGuiViewport; // Viewport (generally ~1 per window to output to at the OS level. Need per-platform support to use multiple viewports)
|
||||
@@ -155,7 +162,9 @@ typedef int ImGuiKey; // -> enum ImGuiKey_ // Enum: A
|
||||
typedef int ImGuiNavInput; // -> enum ImGuiNavInput_ // Enum: An input identifier for navigation
|
||||
typedef int ImGuiMouseButton; // -> enum ImGuiMouseButton_ // Enum: A mouse button identifier (0=left, 1=right, 2=middle)
|
||||
typedef int ImGuiMouseCursor; // -> enum ImGuiMouseCursor_ // Enum: A mouse cursor identifier
|
||||
typedef int ImGuiSortDirection; // -> enum ImGuiSortDirection_ // Enum: A sorting direction (ascending or descending)
|
||||
typedef int ImGuiStyleVar; // -> enum ImGuiStyleVar_ // Enum: A variable identifier for styling
|
||||
typedef int ImGuiTableBgTarget; // -> enum ImGuiTableBgTarget_ // Enum: A color target for TableSetBgColor()
|
||||
typedef int ImDrawCornerFlags; // -> enum ImDrawCornerFlags_ // Flags: for ImDrawList::AddRect(), AddRectFilled() etc.
|
||||
typedef int ImDrawListFlags; // -> enum ImDrawListFlags_ // Flags: for ImDrawList
|
||||
typedef int ImFontAtlasFlags; // -> enum ImFontAtlasFlags_ // Flags: for ImFontAtlas build
|
||||
@@ -175,6 +184,9 @@ typedef int ImGuiSelectableFlags; // -> enum ImGuiSelectableFlags_ // Flags: f
|
||||
typedef int ImGuiSliderFlags; // -> enum ImGuiSliderFlags_ // Flags: for DragFloat(), DragInt(), SliderFloat(), SliderInt() etc.
|
||||
typedef int ImGuiTabBarFlags; // -> enum ImGuiTabBarFlags_ // Flags: for BeginTabBar()
|
||||
typedef int ImGuiTabItemFlags; // -> enum ImGuiTabItemFlags_ // Flags: for BeginTabItem()
|
||||
typedef int ImGuiTableFlags; // -> enum ImGuiTableFlags_ // Flags: For BeginTable()
|
||||
typedef int ImGuiTableColumnFlags; // -> enum ImGuiTableColumnFlags_// Flags: For TableSetupColumn()
|
||||
typedef int ImGuiTableRowFlags; // -> enum ImGuiTableRowFlags_ // Flags: For TableNextRow()
|
||||
typedef int ImGuiTreeNodeFlags; // -> enum ImGuiTreeNodeFlags_ // Flags: for TreeNode(), TreeNodeEx(), CollapsingHeader()
|
||||
typedef int ImGuiViewportFlags; // -> enum ImGuiViewportFlags_ // Flags: for ImGuiViewport
|
||||
typedef int ImGuiWindowFlags; // -> enum ImGuiWindowFlags_ // Flags: for Begin(), BeginChild()
|
||||
@@ -184,10 +196,10 @@ typedef int ImGuiWindowFlags; // -> enum ImGuiWindowFlags_ // Flags: f
|
||||
typedef void* ImTextureID; // User data for rendering backend to identify a texture. This is whatever to you want it to be! read the FAQ about ImTextureID for details.
|
||||
#endif
|
||||
typedef unsigned int ImGuiID; // A unique ID used by widgets, typically hashed from a stack of string.
|
||||
typedef int (*ImGuiInputTextCallback)(ImGuiInputTextCallbackData* data);
|
||||
typedef void (*ImGuiSizeCallback)(ImGuiSizeCallbackData* data);
|
||||
typedef int (*ImGuiInputTextCallback)(ImGuiInputTextCallbackData* data); // Callback function for ImGui::InputText()
|
||||
typedef void (*ImGuiSizeCallback)(ImGuiSizeCallbackData* data); // Callback function for ImGui::SetNextWindowSizeConstraints()
|
||||
|
||||
// Decoded character types
|
||||
// Character types
|
||||
// (we generally use UTF-8 encoded string in the API. This is storage specifically for a decoded character used for keyboard input and display)
|
||||
typedef unsigned short ImWchar16; // A single decoded U16 character/code point. We encode them as multi bytes UTF-8 when used in strings.
|
||||
typedef unsigned int ImWchar32; // A single decoded U32 character/code point. We encode them as multi bytes UTF-8 when used in strings.
|
||||
@@ -232,8 +244,8 @@ struct ImVec2
|
||||
// 4D vector (often used to store floating-point colors)
|
||||
struct ImVec4
|
||||
{
|
||||
float x, y, z, w;
|
||||
ImVec4() { x = y = z = w = 0.0f; }
|
||||
float x, y, z, w;
|
||||
ImVec4() { x = y = z = w = 0.0f; }
|
||||
ImVec4(float _x, float _y, float _z, float _w) { x = _x; y = _y; z = _z; w = _w; }
|
||||
#ifdef IM_VEC4_CLASS_EXTRA
|
||||
IM_VEC4_CLASS_EXTRA // Define additional constructors and implicit cast operators in imconfig.h to convert back and forth between your math types and ImVec4.
|
||||
@@ -241,8 +253,8 @@ struct ImVec4
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// ImGui: Dear ImGui end-user API
|
||||
// (This is a namespace. You can add extra ImGui:: functions in your own separate file. Please don't modify imgui source files!)
|
||||
// [SECTION] Dear ImGui end-user API functions
|
||||
// (Note that ImGui:: being a namespace, you can add extra ImGui:: functions in your own separate file. Please don't modify imgui source files!)
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
namespace ImGui
|
||||
@@ -264,19 +276,19 @@ namespace ImGui
|
||||
IMGUI_API ImDrawData* GetDrawData(); // valid after Render() and until the next call to NewFrame(). this is what you have to render.
|
||||
|
||||
// Demo, Debug, Information
|
||||
IMGUI_API void ShowDemoWindow(bool* p_open = NULL); // create Demo window (previously called ShowTestWindow). demonstrate most ImGui features. call this to learn about the library! try to make it always available in your application!
|
||||
IMGUI_API void ShowDemoWindow(bool* p_open = NULL); // create Demo window. demonstrate most ImGui features. call this to learn about the library! try to make it always available in your application!
|
||||
IMGUI_API void ShowMetricsWindow(bool* p_open = NULL); // create Metrics/Debugger window. display Dear ImGui internals: windows, draw commands, various internal state, etc.
|
||||
IMGUI_API void ShowAboutWindow(bool* p_open = NULL); // create About window. display Dear ImGui version, credits and build/system information.
|
||||
IMGUI_API void ShowMetricsWindow(bool* p_open = NULL); // create Debug/Metrics window. display Dear ImGui internals: draw commands (with individual draw calls and vertices), window list, basic internal state, etc.
|
||||
IMGUI_API void ShowStyleEditor(ImGuiStyle* ref = NULL); // add style editor block (not a window). you can pass in a reference ImGuiStyle structure to compare to, revert to and save to (else it uses the default style)
|
||||
IMGUI_API bool ShowStyleSelector(const char* label); // add style selector block (not a window), essentially a combo listing the default styles.
|
||||
IMGUI_API void ShowFontSelector(const char* label); // add font selector block (not a window), essentially a combo listing the loaded fonts.
|
||||
IMGUI_API void ShowUserGuide(); // add basic help/info block (not a window): how to manipulate ImGui as a end-user (mouse/keyboard controls).
|
||||
IMGUI_API const char* GetVersion(); // get the compiled version string e.g. "1.23" (essentially the compiled value for IMGUI_VERSION)
|
||||
IMGUI_API const char* GetVersion(); // get the compiled version string e.g. "1.80 WIP" (essentially the value for IMGUI_VERSION from the compiled version of imgui.cpp)
|
||||
|
||||
// Styles
|
||||
IMGUI_API void StyleColorsDark(ImGuiStyle* dst = NULL); // new, recommended style (default)
|
||||
IMGUI_API void StyleColorsClassic(ImGuiStyle* dst = NULL); // classic imgui style
|
||||
IMGUI_API void StyleColorsLight(ImGuiStyle* dst = NULL); // best used with borders and a custom, thicker font
|
||||
IMGUI_API void StyleColorsClassic(ImGuiStyle* dst = NULL); // classic imgui style
|
||||
|
||||
// Windows
|
||||
// - Begin() = push window to the stack and start appending to it. End() = pop window from the stack.
|
||||
@@ -297,7 +309,10 @@ namespace ImGui
|
||||
// - Use child windows to begin into a self-contained independent scrolling/clipping regions within a host window. Child windows can embed their own child.
|
||||
// - For each independent axis of 'size': ==0.0f: use remaining host window size / >0.0f: fixed size / <0.0f: use remaining window size minus abs(size) / Each axis can use a different mode, e.g. ImVec2(0,400).
|
||||
// - BeginChild() returns false to indicate the window is collapsed or fully clipped, so you may early out and omit submitting anything to the window.
|
||||
// Always call a matching EndChild() for each BeginChild() call, regardless of its return value [as with Begin: this is due to legacy reason and inconsistent with most BeginXXX functions apart from the regular Begin() which behaves like BeginChild().]
|
||||
// Always call a matching EndChild() for each BeginChild() call, regardless of its return value.
|
||||
// [Important: due to legacy reason, this is inconsistent with most other functions such as BeginMenu/EndMenu,
|
||||
// BeginPopup/EndPopup, etc. where the EndXXX call should only be called if the corresponding BeginXXX function
|
||||
// returned true. Begin and BeginChild are the only odd ones out. Will be fixed in a future update.]
|
||||
IMGUI_API bool BeginChild(const char* str_id, const ImVec2& size = ImVec2(0, 0), bool border = false, ImGuiWindowFlags flags = 0);
|
||||
IMGUI_API bool BeginChild(ImGuiID id, const ImVec2& size = ImVec2(0, 0), bool border = false, ImGuiWindowFlags flags = 0);
|
||||
IMGUI_API void EndChild();
|
||||
@@ -336,20 +351,21 @@ namespace ImGui
|
||||
IMGUI_API void SetWindowFocus(const char* name); // set named window to be focused / top-most. use NULL to remove focus.
|
||||
|
||||
// Content region
|
||||
// - Those functions are bound to be redesigned soon (they are confusing, incomplete and return values in local window coordinates which increases confusion)
|
||||
IMGUI_API ImVec2 GetContentRegionMax(); // current content boundaries (typically window boundaries including scrolling, or current column boundaries), in windows coordinates
|
||||
// - Retrieve available space from a given point. GetContentRegionAvail() is frequently useful.
|
||||
// - Those functions are bound to be redesigned (they are confusing, incomplete and the Min/Max return values are in local window coordinates which increases confusion)
|
||||
IMGUI_API ImVec2 GetContentRegionAvail(); // == GetContentRegionMax() - GetCursorPos()
|
||||
IMGUI_API ImVec2 GetContentRegionMax(); // current content boundaries (typically window boundaries including scrolling, or current column boundaries), in windows coordinates
|
||||
IMGUI_API ImVec2 GetWindowContentRegionMin(); // content boundaries min (roughly (0,0)-Scroll), in window coordinates
|
||||
IMGUI_API ImVec2 GetWindowContentRegionMax(); // content boundaries max (roughly (0,0)+Size-Scroll) where Size can be override with SetNextWindowContentSize(), in window coordinates
|
||||
IMGUI_API float GetWindowContentRegionWidth(); //
|
||||
|
||||
// Windows Scrolling
|
||||
IMGUI_API float GetScrollX(); // get scrolling amount [0..GetScrollMaxX()]
|
||||
IMGUI_API float GetScrollY(); // get scrolling amount [0..GetScrollMaxY()]
|
||||
IMGUI_API float GetScrollMaxX(); // get maximum scrolling amount ~~ ContentSize.x - WindowSize.x
|
||||
IMGUI_API float GetScrollMaxY(); // get maximum scrolling amount ~~ ContentSize.y - WindowSize.y
|
||||
IMGUI_API void SetScrollX(float scroll_x); // set scrolling amount [0..GetScrollMaxX()]
|
||||
IMGUI_API void SetScrollY(float scroll_y); // set scrolling amount [0..GetScrollMaxY()]
|
||||
IMGUI_API float GetScrollX(); // get scrolling amount [0 .. GetScrollMaxX()]
|
||||
IMGUI_API float GetScrollY(); // get scrolling amount [0 .. GetScrollMaxY()]
|
||||
IMGUI_API void SetScrollX(float scroll_x); // set scrolling amount [0 .. GetScrollMaxX()]
|
||||
IMGUI_API void SetScrollY(float scroll_y); // set scrolling amount [0 .. GetScrollMaxY()]
|
||||
IMGUI_API float GetScrollMaxX(); // get maximum scrolling amount ~~ ContentSize.x - WindowSize.x - DecorationsSize.x
|
||||
IMGUI_API float GetScrollMaxY(); // get maximum scrolling amount ~~ ContentSize.y - WindowSize.y - DecorationsSize.y
|
||||
IMGUI_API void SetScrollHereX(float center_x_ratio = 0.5f); // adjust scrolling amount to make current cursor position visible. center_x_ratio=0.0: left, 0.5: center, 1.0: right. When using to make a "default/current item" visible, consider using SetItemDefaultFocus() instead.
|
||||
IMGUI_API void SetScrollHereY(float center_y_ratio = 0.5f); // adjust scrolling amount to make current cursor position visible. center_y_ratio=0.0: top, 0.5: center, 1.0: bottom. When using to make a "default/current item" visible, consider using SetItemDefaultFocus() instead.
|
||||
IMGUI_API void SetScrollFromPosX(float local_x, float center_x_ratio = 0.5f); // adjust scrolling amount to make given position visible. Generally GetCursorStartPos() + offset to compute a valid position.
|
||||
@@ -358,32 +374,34 @@ namespace ImGui
|
||||
// Parameters stacks (shared)
|
||||
IMGUI_API void PushFont(ImFont* font); // use NULL as a shortcut to push default font
|
||||
IMGUI_API void PopFont();
|
||||
IMGUI_API void PushStyleColor(ImGuiCol idx, ImU32 col);
|
||||
IMGUI_API void PushStyleColor(ImGuiCol idx, ImU32 col); // modify a style color. always use this if you modify the style after NewFrame().
|
||||
IMGUI_API void PushStyleColor(ImGuiCol idx, const ImVec4& col);
|
||||
IMGUI_API void PopStyleColor(int count = 1);
|
||||
IMGUI_API void PushStyleVar(ImGuiStyleVar idx, float val);
|
||||
IMGUI_API void PushStyleVar(ImGuiStyleVar idx, const ImVec2& val);
|
||||
IMGUI_API void PushStyleVar(ImGuiStyleVar idx, float val); // modify a style float variable. always use this if you modify the style after NewFrame().
|
||||
IMGUI_API void PushStyleVar(ImGuiStyleVar idx, const ImVec2& val); // modify a style ImVec2 variable. always use this if you modify the style after NewFrame().
|
||||
IMGUI_API void PopStyleVar(int count = 1);
|
||||
IMGUI_API const ImVec4& GetStyleColorVec4(ImGuiCol idx); // retrieve style color as stored in ImGuiStyle structure. use to feed back into PushStyleColor(), otherwise use GetColorU32() to get style color with style alpha baked in.
|
||||
IMGUI_API ImFont* GetFont(); // get current font
|
||||
IMGUI_API float GetFontSize(); // get current font size (= height in pixels) of current font with current scale applied
|
||||
IMGUI_API ImVec2 GetFontTexUvWhitePixel(); // get UV coordinate for a while pixel, useful to draw custom shapes via the ImDrawList API
|
||||
IMGUI_API ImU32 GetColorU32(ImGuiCol idx, float alpha_mul = 1.0f); // retrieve given style color with style alpha applied and optional extra alpha multiplier
|
||||
IMGUI_API ImU32 GetColorU32(const ImVec4& col); // retrieve given color with style alpha applied
|
||||
IMGUI_API ImU32 GetColorU32(ImU32 col); // retrieve given color with style alpha applied
|
||||
|
||||
// Parameters stacks (current window)
|
||||
IMGUI_API void PushItemWidth(float item_width); // push width of items for common large "item+label" widgets. >0.0f: width in pixels, <0.0f align xx pixels to the right of window (so -1.0f always align width to the right side). 0.0f = default to ~2/3 of windows width,
|
||||
IMGUI_API void PopItemWidth();
|
||||
IMGUI_API void SetNextItemWidth(float item_width); // set width of the _next_ common large "item+label" widget. >0.0f: width in pixels, <0.0f align xx pixels to the right of window (so -1.0f always align width to the right side)
|
||||
IMGUI_API float CalcItemWidth(); // width of item given pushed settings and current cursor position. NOT necessarily the width of last item unlike most 'Item' functions.
|
||||
IMGUI_API void PushTextWrapPos(float wrap_local_pos_x = 0.0f); // push word-wrapping position for Text*() commands. < 0.0f: no wrapping; 0.0f: wrap to end of window (or column); > 0.0f: wrap at 'wrap_pos_x' position in window local space
|
||||
IMGUI_API void PopTextWrapPos();
|
||||
IMGUI_API void PushAllowKeyboardFocus(bool allow_keyboard_focus); // allow focusing using TAB/Shift-TAB, enabled by default but you can disable it for certain widgets
|
||||
IMGUI_API void PopAllowKeyboardFocus();
|
||||
IMGUI_API void PushButtonRepeat(bool repeat); // in 'repeat' mode, Button*() functions return repeated true in a typematic manner (using io.KeyRepeatDelay/io.KeyRepeatRate setting). Note that you can call IsItemActive() after any Button() to tell if the button is held in the current frame.
|
||||
IMGUI_API void PopButtonRepeat();
|
||||
|
||||
// Parameters stacks (current window)
|
||||
IMGUI_API void PushItemWidth(float item_width); // push width of items for common large "item+label" widgets. >0.0f: width in pixels, <0.0f align xx pixels to the right of window (so -FLT_MIN always align width to the right side). 0.0f = default to ~2/3 of windows width,
|
||||
IMGUI_API void PopItemWidth();
|
||||
IMGUI_API void SetNextItemWidth(float item_width); // set width of the _next_ common large "item+label" widget. >0.0f: width in pixels, <0.0f align xx pixels to the right of window (so -FLT_MIN always align width to the right side)
|
||||
IMGUI_API float CalcItemWidth(); // width of item given pushed settings and current cursor position. NOT necessarily the width of last item unlike most 'Item' functions.
|
||||
IMGUI_API void PushTextWrapPos(float wrap_local_pos_x = 0.0f); // push word-wrapping position for Text*() commands. < 0.0f: no wrapping; 0.0f: wrap to end of window (or column); > 0.0f: wrap at 'wrap_pos_x' position in window local space
|
||||
IMGUI_API void PopTextWrapPos();
|
||||
|
||||
// Style read access
|
||||
IMGUI_API ImFont* GetFont(); // get current font
|
||||
IMGUI_API float GetFontSize(); // get current font size (= height in pixels) of current font with current scale applied
|
||||
IMGUI_API ImVec2 GetFontTexUvWhitePixel(); // get UV coordinate for a while pixel, useful to draw custom shapes via the ImDrawList API
|
||||
IMGUI_API ImU32 GetColorU32(ImGuiCol idx, float alpha_mul = 1.0f); // retrieve given style color with style alpha applied and optional extra alpha multiplier, packed as a 32-bit value suitable for ImDrawList
|
||||
IMGUI_API ImU32 GetColorU32(const ImVec4& col); // retrieve given color with style alpha applied, packed as a 32-bit value suitable for ImDrawList
|
||||
IMGUI_API ImU32 GetColorU32(ImU32 col); // retrieve given color with style alpha applied, packed as a 32-bit value suitable for ImDrawList
|
||||
IMGUI_API const ImVec4& GetStyleColorVec4(ImGuiCol idx); // retrieve style color as stored in ImGuiStyle structure. use to feed back into PushStyleColor(), otherwise use GetColorU32() to get style color with style alpha baked in.
|
||||
|
||||
// Cursor / Layout
|
||||
// - By "cursor" we mean the current output position.
|
||||
// - The typical widget behavior is to output themselves at the current cursor position, then move the cursor one line down.
|
||||
@@ -396,8 +414,8 @@ namespace ImGui
|
||||
IMGUI_API void NewLine(); // undo a SameLine() or force a new line when in an horizontal-layout context.
|
||||
IMGUI_API void Spacing(); // add vertical spacing.
|
||||
IMGUI_API void Dummy(const ImVec2& size); // add a dummy item of given size. unlike InvisibleButton(), Dummy() won't take the mouse click or be navigable into.
|
||||
IMGUI_API void Indent(float indent_w = 0.0f); // move content position toward the right, by style.IndentSpacing or indent_w if != 0
|
||||
IMGUI_API void Unindent(float indent_w = 0.0f); // move content position back to the left, by style.IndentSpacing or indent_w if != 0
|
||||
IMGUI_API void Indent(float indent_w = 0.0f); // move content position toward the right, by indent_w, or style.IndentSpacing if indent_w <= 0
|
||||
IMGUI_API void Unindent(float indent_w = 0.0f); // move content position back to the left, by indent_w, or style.IndentSpacing if indent_w <= 0
|
||||
IMGUI_API void BeginGroup(); // lock horizontal starting position
|
||||
IMGUI_API void EndGroup(); // unlock horizontal starting position + capture the whole group bounding box into one "item" (so you can use IsItemHovered() or layout primitives such as SameLine() on whole group, etc.)
|
||||
IMGUI_API ImVec2 GetCursorPos(); // cursor position in window coordinates (relative to window position)
|
||||
@@ -456,10 +474,11 @@ namespace ImGui
|
||||
IMGUI_API void Image(ImTextureID user_texture_id, const ImVec2& size, const ImVec2& uv0 = ImVec2(0, 0), const ImVec2& uv1 = ImVec2(1,1), const ImVec4& tint_col = ImVec4(1,1,1,1), const ImVec4& border_col = ImVec4(0,0,0,0));
|
||||
IMGUI_API bool ImageButton(ImTextureID user_texture_id, const ImVec2& size, const ImVec2& uv0 = ImVec2(0, 0), const ImVec2& uv1 = ImVec2(1,1), int frame_padding = -1, const ImVec4& bg_col = ImVec4(0,0,0,0), const ImVec4& tint_col = ImVec4(1,1,1,1)); // <0 frame_padding uses default frame padding settings. 0 for no padding
|
||||
IMGUI_API bool Checkbox(const char* label, bool* v);
|
||||
IMGUI_API bool CheckboxFlags(const char* label, int* flags, int flags_value);
|
||||
IMGUI_API bool CheckboxFlags(const char* label, unsigned int* flags, unsigned int flags_value);
|
||||
IMGUI_API bool RadioButton(const char* label, bool active); // use with e.g. if (RadioButton("one", my_value==1)) { my_value = 1; }
|
||||
IMGUI_API bool RadioButton(const char* label, int* v, int v_button); // shortcut to handle the above pattern when value is an integer
|
||||
IMGUI_API void ProgressBar(float fraction, const ImVec2& size_arg = ImVec2(-1, 0), const char* overlay = NULL);
|
||||
IMGUI_API void ProgressBar(float fraction, const ImVec2& size_arg = ImVec2(-FLT_MIN, 0), const char* overlay = NULL);
|
||||
IMGUI_API void Bullet(); // draw a small circle + keep the cursor on the same line. advance cursor x position by GetTreeNodeToLabelSpacing(), same distance that TreeNode() uses
|
||||
|
||||
// Widgets: Combo Box
|
||||
@@ -561,7 +580,7 @@ namespace ImGui
|
||||
IMGUI_API void TreePop(); // ~ Unindent()+PopId()
|
||||
IMGUI_API float GetTreeNodeToLabelSpacing(); // horizontal distance preceding label when using TreeNode*() or Bullet() == (g.FontSize + style.FramePadding.x*2) for a regular unframed TreeNode
|
||||
IMGUI_API bool CollapsingHeader(const char* label, ImGuiTreeNodeFlags flags = 0); // if returning 'true' the header is open. doesn't indent nor push on ID stack. user doesn't have to call TreePop().
|
||||
IMGUI_API bool CollapsingHeader(const char* label, bool* p_open, ImGuiTreeNodeFlags flags = 0); // when 'p_open' isn't NULL, display an additional small close button on upper right of the header
|
||||
IMGUI_API bool CollapsingHeader(const char* label, bool* p_visible, ImGuiTreeNodeFlags flags = 0); // when 'p_visible != NULL': if '*p_visible==true' display an additional small close button on upper right of the header which will set the bool to false when clicked, if '*p_visible==false' don't display the header.
|
||||
IMGUI_API void SetNextItemOpen(bool is_open, ImGuiCond cond = 0); // set next TreeNode/CollapsingHeader open state.
|
||||
|
||||
// Widgets: Selectables
|
||||
@@ -605,7 +624,7 @@ namespace ImGui
|
||||
IMGUI_API bool MenuItem(const char* label, const char* shortcut, bool* p_selected, bool enabled = true); // return true when activated + toggle (*p_selected) if p_selected != NULL
|
||||
|
||||
// Tooltips
|
||||
// - Tooltip are windows following the mouse which do not take focus away.
|
||||
// - Tooltip are windows following the mouse. They do not take focus away.
|
||||
IMGUI_API void BeginTooltip(); // begin/append a tooltip window. to create full-featured tooltip (with any kind of items).
|
||||
IMGUI_API void EndTooltip();
|
||||
IMGUI_API void SetTooltip(const char* fmt, ...) IM_FMTARGS(1); // set a text-only tooltip, typically use with ImGui::IsItemHovered(). override any previous call to SetTooltip().
|
||||
@@ -648,11 +667,66 @@ namespace ImGui
|
||||
// - IsPopupOpen() with ImGuiPopupFlags_AnyPopupId + ImGuiPopupFlags_AnyPopupLevel: return true if any popup is open.
|
||||
IMGUI_API bool IsPopupOpen(const char* str_id, ImGuiPopupFlags flags = 0); // return true if the popup is open.
|
||||
|
||||
// Columns
|
||||
// Tables
|
||||
// [BETA API] API may evolve slightly! If you use this, please update to the next version when it comes out!
|
||||
// - Full-featured replacement for old Columns API.
|
||||
// - See Demo->Tables for demo code.
|
||||
// - See top of imgui_tables.cpp for general commentary.
|
||||
// - See ImGuiTableFlags_ and ImGuiTableColumnFlags_ enums for a description of available flags.
|
||||
// The typical call flow is:
|
||||
// - 1. Call BeginTable().
|
||||
// - 2. Optionally call TableSetupColumn() to submit column name/flags/defaults.
|
||||
// - 3. Optionally call TableSetupScrollFreeze() to request scroll freezing of columns/rows.
|
||||
// - 4. Optionally call TableHeadersRow() to submit a header row. Names are pulled from TableSetupColumn() data.
|
||||
// - 5. Populate contents:
|
||||
// - In most situations you can use TableNextRow() + TableSetColumnIndex(N) to start appending into a column.
|
||||
// - If you are using tables as a sort of grid, where every columns is holding the same type of contents,
|
||||
// you may prefer using TableNextColumn() instead of TableNextRow() + TableSetColumnIndex().
|
||||
// TableNextColumn() will automatically wrap-around into the next row if needed.
|
||||
// - IMPORTANT: Comparatively to the old Columns() API, we need to call TableNextColumn() for the first column!
|
||||
// - Summary of possible call flow:
|
||||
// --------------------------------------------------------------------------------------------------------
|
||||
// TableNextRow() -> TableSetColumnIndex(0) -> Text("Hello 0") -> TableSetColumnIndex(1) -> Text("Hello 1") // OK
|
||||
// TableNextRow() -> TableNextColumn() -> Text("Hello 0") -> TableNextColumn() -> Text("Hello 1") // OK
|
||||
// TableNextColumn() -> Text("Hello 0") -> TableNextColumn() -> Text("Hello 1") // OK: TableNextColumn() automatically gets to next row!
|
||||
// TableNextRow() -> Text("Hello 0") // Not OK! Missing TableSetColumnIndex() or TableNextColumn()! Text will not appear!
|
||||
// --------------------------------------------------------------------------------------------------------
|
||||
// - 5. Call EndTable()
|
||||
IMGUI_API bool BeginTable(const char* str_id, int column, ImGuiTableFlags flags = 0, const ImVec2& outer_size = ImVec2(0.0f, 0.0f), float inner_width = 0.0f);
|
||||
IMGUI_API void EndTable(); // only call EndTable() if BeginTable() returns true!
|
||||
IMGUI_API void TableNextRow(ImGuiTableRowFlags row_flags = 0, float min_row_height = 0.0f); // append into the first cell of a new row.
|
||||
IMGUI_API bool TableNextColumn(); // append into the next column (or first column of next row if currently in last column). Return true when column is visible.
|
||||
IMGUI_API bool TableSetColumnIndex(int column_n); // append into the specified column. Return true when column is visible.
|
||||
// Tables: Headers & Columns declaration
|
||||
// - Use TableSetupColumn() to specify label, resizing policy, default width/weight, id, various other flags etc.
|
||||
// - Use TableHeadersRow() to create a header row and automatically submit a TableHeader() for each column.
|
||||
// Headers are required to perform: reordering, sorting, and opening the context menu.
|
||||
// The context menu can also be made available in columns body using ImGuiTableFlags_ContextMenuInBody.
|
||||
// - You may manually submit headers using TableNextRow() + TableHeader() calls, but this is only useful in
|
||||
// some advanced use cases (e.g. adding custom widgets in header row).
|
||||
// - Use TableSetupScrollFreeze() to lock columns/rows so they stay visible when scrolled.
|
||||
IMGUI_API void TableSetupColumn(const char* label, ImGuiTableColumnFlags flags = 0, float init_width_or_weight = 0.0f, ImU32 user_id = 0);
|
||||
IMGUI_API void TableSetupScrollFreeze(int cols, int rows); // lock columns/rows so they stay visible when scrolled.
|
||||
IMGUI_API void TableHeadersRow(); // submit all headers cells based on data provided to TableSetupColumn() + submit context menu
|
||||
IMGUI_API void TableHeader(const char* label); // submit one header cell manually (rarely used)
|
||||
// Tables: Sorting
|
||||
// - Call TableGetSortSpecs() to retrieve latest sort specs for the table. NULL when not sorting.
|
||||
// - When 'SpecsDirty == true' you should sort your data. It will be true when sorting specs have changed
|
||||
// since last call, or the first time. Make sure to set 'SpecsDirty = false' after sorting, else you may
|
||||
// wastefully sort your data every frame!
|
||||
// - Lifetime: don't hold on this pointer over multiple frames or past any subsequent call to BeginTable().
|
||||
IMGUI_API ImGuiTableSortSpecs* TableGetSortSpecs(); // get latest sort specs for the table (NULL if not sorting).
|
||||
// Tables: Miscellaneous functions
|
||||
// - Functions args 'int column_n' treat the default value of -1 as the same as passing the current column index.
|
||||
IMGUI_API int TableGetColumnCount(); // return number of columns (value passed to BeginTable)
|
||||
IMGUI_API int TableGetColumnIndex(); // return current column index.
|
||||
IMGUI_API int TableGetRowIndex(); // return current row index.
|
||||
IMGUI_API const char* TableGetColumnName(int column_n = -1); // return "" if column didn't have a name declared by TableSetupColumn(). Pass -1 to use current column.
|
||||
IMGUI_API ImGuiTableColumnFlags TableGetColumnFlags(int column_n = -1); // return column flags so you can query their Enabled/Visible/Sorted/Hovered status flags. Pass -1 to use current column.
|
||||
IMGUI_API void TableSetBgColor(ImGuiTableBgTarget target, ImU32 color, int column_n = -1); // change the color of a cell, row, or column. See ImGuiTableBgTarget_ flags for details.
|
||||
|
||||
// Legacy Columns API (2020: prefer using Tables!)
|
||||
// - You can also use SameLine(pos_x) to mimic simplified columns.
|
||||
// - The columns API is work-in-progress and rather lacking (columns are arguably the worst part of dear imgui at the moment!)
|
||||
// - There is a maximum of 64 columns.
|
||||
// - Currently working on new 'Tables' api which will replace columns around Q2 2020 (see GitHub #2957).
|
||||
IMGUI_API void Columns(int count = 1, const char* id = NULL, bool border = true);
|
||||
IMGUI_API void NextColumn(); // next column, defaults to current row or next row if the current row is finished
|
||||
IMGUI_API int GetColumnIndex(); // get current column index
|
||||
@@ -696,7 +770,6 @@ namespace ImGui
|
||||
IMGUI_API void LogText(const char* fmt, ...) IM_FMTARGS(1); // pass text data straight to log (without being displayed)
|
||||
|
||||
// Drag and Drop
|
||||
// - [BETA API] API may evolve!
|
||||
// - If you stop calling BeginDragDropSource() the payload is preserved however it won't have a preview tooltip (we currently display a fallback "..." tooltip as replacement)
|
||||
IMGUI_API bool BeginDragDropSource(ImGuiDragDropFlags flags = 0); // call when the current item is active. If this return true, you can call SetDragDropPayload() + EndDragDropSource()
|
||||
IMGUI_API bool SetDragDropPayload(const char* type, const void* data, size_t sz, ImGuiCond cond = 0); // type is a user defined string of maximum 32 characters. Strings starting with '_' are reserved for dear imgui internal types. Data is copied and held by imgui.
|
||||
@@ -707,6 +780,7 @@ namespace ImGui
|
||||
IMGUI_API const ImGuiPayload* GetDragDropPayload(); // peek directly into the current payload from anywhere. may return NULL. use ImGuiPayload::IsDataType() to test for the payload type.
|
||||
|
||||
// Clipping
|
||||
// - Mouse hovering is affected by ImGui::PushClipRect() calls, unlike direct calls to ImDrawList::PushClipRect() which are render only.
|
||||
IMGUI_API void PushClipRect(const ImVec2& clip_rect_min, const ImVec2& clip_rect_max, bool intersect_with_current_clip_rect);
|
||||
IMGUI_API void PopClipRect();
|
||||
|
||||
@@ -829,7 +903,7 @@ namespace ImGui
|
||||
} // namespace ImGui
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Flags & Enumerations
|
||||
// [SECTION] Flags & Enumerations
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// Flags for ImGui::Begin()
|
||||
@@ -1004,6 +1078,149 @@ enum ImGuiTabItemFlags_
|
||||
ImGuiTabItemFlags_Trailing = 1 << 7 // Enforce the tab position to the right of the tab bar (before the scrolling buttons)
|
||||
};
|
||||
|
||||
// Flags for ImGui::BeginTable()
|
||||
// [BETA API] API may evolve slightly! If you use this, please update to the next version when it comes out!
|
||||
// - Important! Sizing policies have complex and subtle side effects, more so than you would expect.
|
||||
// Read comments/demos carefully + experiment with live demos to get acquainted with them.
|
||||
// - The DEFAULT sizing policies are:
|
||||
// - Default to ImGuiTableFlags_SizingFixedFit if ScrollX is on, or if host window has ImGuiWindowFlags_AlwaysAutoResize.
|
||||
// - Default to ImGuiTableFlags_SizingStretchSame if ScrollX is off.
|
||||
// - When ScrollX is off:
|
||||
// - Table defaults to ImGuiTableFlags_SizingStretchSame -> all Columns defaults to ImGuiTableColumnFlags_WidthStretch with same weight.
|
||||
// - Columns sizing policy allowed: Stretch (default), Fixed/Auto.
|
||||
// - Fixed Columns will generally obtain their requested width (unless the table cannot fit them all).
|
||||
// - Stretch Columns will share the remaining width.
|
||||
// - Mixed Fixed/Stretch columns is possible but has various side-effects on resizing behaviors.
|
||||
// The typical use of mixing sizing policies is: any number of LEADING Fixed columns, followed by one or two TRAILING Stretch columns.
|
||||
// (this is because the visible order of columns have subtle but necessary effects on how they react to manual resizing).
|
||||
// - When ScrollX is on:
|
||||
// - Table defaults to ImGuiTableFlags_SizingFixedFit -> all Columns defaults to ImGuiTableColumnFlags_WidthFixed
|
||||
// - Columns sizing policy allowed: Fixed/Auto mostly.
|
||||
// - Fixed Columns can be enlarged as needed. Table will show an horizontal scrollbar if needed.
|
||||
// - When using auto-resizing (non-resizable) fixed columns, querying the content width to use item right-alignment e.g. SetNextItemWidth(-FLT_MIN) doesn't make sense, would create a feedback loop.
|
||||
// - Using Stretch columns OFTEN DOES NOT MAKE SENSE if ScrollX is on, UNLESS you have specified a value for 'inner_width' in BeginTable().
|
||||
// If you specify a value for 'inner_width' then effectively the scrolling space is known and Stretch or mixed Fixed/Stretch columns become meaningful again.
|
||||
// - Read on documentation at the top of imgui_tables.cpp for details.
|
||||
enum ImGuiTableFlags_
|
||||
{
|
||||
// Features
|
||||
ImGuiTableFlags_None = 0,
|
||||
ImGuiTableFlags_Resizable = 1 << 0, // Enable resizing columns.
|
||||
ImGuiTableFlags_Reorderable = 1 << 1, // Enable reordering columns in header row (need calling TableSetupColumn() + TableHeadersRow() to display headers)
|
||||
ImGuiTableFlags_Hideable = 1 << 2, // Enable hiding/disabling columns in context menu.
|
||||
ImGuiTableFlags_Sortable = 1 << 3, // Enable sorting. Call TableGetSortSpecs() to obtain sort specs. Also see ImGuiTableFlags_SortMulti and ImGuiTableFlags_SortTristate.
|
||||
ImGuiTableFlags_NoSavedSettings = 1 << 4, // Disable persisting columns order, width and sort settings in the .ini file.
|
||||
ImGuiTableFlags_ContextMenuInBody = 1 << 5, // Right-click on columns body/contents will display table context menu. By default it is available in TableHeadersRow().
|
||||
// Decorations
|
||||
ImGuiTableFlags_RowBg = 1 << 6, // Set each RowBg color with ImGuiCol_TableRowBg or ImGuiCol_TableRowBgAlt (equivalent of calling TableSetBgColor with ImGuiTableBgFlags_RowBg0 on each row manually)
|
||||
ImGuiTableFlags_BordersInnerH = 1 << 7, // Draw horizontal borders between rows.
|
||||
ImGuiTableFlags_BordersOuterH = 1 << 8, // Draw horizontal borders at the top and bottom.
|
||||
ImGuiTableFlags_BordersInnerV = 1 << 9, // Draw vertical borders between columns.
|
||||
ImGuiTableFlags_BordersOuterV = 1 << 10, // Draw vertical borders on the left and right sides.
|
||||
ImGuiTableFlags_BordersH = ImGuiTableFlags_BordersInnerH | ImGuiTableFlags_BordersOuterH, // Draw horizontal borders.
|
||||
ImGuiTableFlags_BordersV = ImGuiTableFlags_BordersInnerV | ImGuiTableFlags_BordersOuterV, // Draw vertical borders.
|
||||
ImGuiTableFlags_BordersInner = ImGuiTableFlags_BordersInnerV | ImGuiTableFlags_BordersInnerH, // Draw inner borders.
|
||||
ImGuiTableFlags_BordersOuter = ImGuiTableFlags_BordersOuterV | ImGuiTableFlags_BordersOuterH, // Draw outer borders.
|
||||
ImGuiTableFlags_Borders = ImGuiTableFlags_BordersInner | ImGuiTableFlags_BordersOuter, // Draw all borders.
|
||||
ImGuiTableFlags_NoBordersInBody = 1 << 11, // [ALPHA] Disable vertical borders in columns Body (borders will always appears in Headers). -> May move to style
|
||||
ImGuiTableFlags_NoBordersInBodyUntilResize = 1 << 12, // [ALPHA] Disable vertical borders in columns Body until hovered for resize (borders will always appears in Headers). -> May move to style
|
||||
// Sizing Policy (read above for defaults)
|
||||
ImGuiTableFlags_SizingFixedFit = 1 << 13, // Columns default to _WidthFixed or _WidthAuto (if resizable or not resizable), matching contents width.
|
||||
ImGuiTableFlags_SizingFixedSame = 2 << 13, // Columns default to _WidthFixed or _WidthAuto (if resizable or not resizable), matching the maximum contents width of all columns. Implicitly enable ImGuiTableFlags_NoKeepColumnsVisible.
|
||||
ImGuiTableFlags_SizingStretchProp = 3 << 13, // Columns default to _WidthStretch with default weights proportional to each columns contents widths.
|
||||
ImGuiTableFlags_SizingStretchSame = 4 << 13, // Columns default to _WidthStretch with default weights all equal, unless overriden by TableSetupColumn().
|
||||
// Sizing Extra Options
|
||||
ImGuiTableFlags_NoHostExtendX = 1 << 16, // Make outer width auto-fit to columns, overriding outer_size.x value. Only available when ScrollX/ScrollY are disabled and Stretch columns are not used.
|
||||
ImGuiTableFlags_NoHostExtendY = 1 << 17, // Make outer height stop exactly at outer_size.y (prevent auto-extending table past the limit). Only available when ScrollX/ScrollY are disabled. Data below the limit will be clipped and not visible.
|
||||
ImGuiTableFlags_NoKeepColumnsVisible = 1 << 18, // Disable keeping column always minimally visible when ScrollX is off and table gets too small. Not recommended if columns are resizable.
|
||||
ImGuiTableFlags_PreciseWidths = 1 << 19, // Disable distributing remainder width to stretched columns (width allocation on a 100-wide table with 3 columns: Without this flag: 33,33,34. With this flag: 33,33,33). With larger number of columns, resizing will appear to be less smooth.
|
||||
// Clipping
|
||||
ImGuiTableFlags_NoClip = 1 << 20, // Disable clipping rectangle for every individual columns (reduce draw command count, items will be able to overflow into other columns). Generally incompatible with TableSetupScrollFreeze().
|
||||
// Padding
|
||||
ImGuiTableFlags_PadOuterX = 1 << 21, // Default if BordersOuterV is on. Enable outer-most padding. Generally desirable if you have headers.
|
||||
ImGuiTableFlags_NoPadOuterX = 1 << 22, // Default if BordersOuterV is off. Disable outer-most padding.
|
||||
ImGuiTableFlags_NoPadInnerX = 1 << 23, // Disable inner padding between columns (double inner padding if BordersOuterV is on, single inner padding if BordersOuterV is off).
|
||||
// Scrolling
|
||||
ImGuiTableFlags_ScrollX = 1 << 24, // Enable horizontal scrolling. Require 'outer_size' parameter of BeginTable() to specify the container size. Changes default sizing policy. Because this create a child window, ScrollY is currently generally recommended when using ScrollX.
|
||||
ImGuiTableFlags_ScrollY = 1 << 25, // Enable vertical scrolling. Require 'outer_size' parameter of BeginTable() to specify the container size.
|
||||
// Sorting
|
||||
ImGuiTableFlags_SortMulti = 1 << 26, // Hold shift when clicking headers to sort on multiple column. TableGetSortSpecs() may return specs where (SpecsCount > 1).
|
||||
ImGuiTableFlags_SortTristate = 1 << 27, // Allow no sorting, disable default sorting. TableGetSortSpecs() may return specs where (SpecsCount == 0).
|
||||
|
||||
// [Internal] Combinations and masks
|
||||
ImGuiTableFlags_SizingMask_ = ImGuiTableFlags_SizingFixedFit | ImGuiTableFlags_SizingFixedSame | ImGuiTableFlags_SizingStretchProp | ImGuiTableFlags_SizingStretchSame
|
||||
|
||||
// Obsolete names (will be removed soon)
|
||||
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
|
||||
//, ImGuiTableFlags_ColumnsWidthFixed = ImGuiTableFlags_SizingFixedFit, ImGuiTableFlags_ColumnsWidthStretch = ImGuiTableFlags_SizingStretchSame // WIP Tables 2020/12
|
||||
//, ImGuiTableFlags_SizingPolicyFixed = ImGuiTableFlags_SizingFixedFit, ImGuiTableFlags_SizingPolicyStretch = ImGuiTableFlags_SizingStretchSame // WIP Tables 2021/01
|
||||
#endif
|
||||
};
|
||||
|
||||
// Flags for ImGui::TableSetupColumn()
|
||||
enum ImGuiTableColumnFlags_
|
||||
{
|
||||
// Input configuration flags
|
||||
ImGuiTableColumnFlags_None = 0,
|
||||
ImGuiTableColumnFlags_DefaultHide = 1 << 0, // Default as a hidden/disabled column.
|
||||
ImGuiTableColumnFlags_DefaultSort = 1 << 1, // Default as a sorting column.
|
||||
ImGuiTableColumnFlags_WidthStretch = 1 << 2, // Column will stretch. Preferable with horizontal scrolling disabled (default if table sizing policy is _SizingStretchSame or _SizingStretchProp).
|
||||
ImGuiTableColumnFlags_WidthFixed = 1 << 3, // Column will not stretch. Preferable with horizontal scrolling enabled (default if table sizing policy is _SizingFixedFit and table is resizable).
|
||||
ImGuiTableColumnFlags_NoResize = 1 << 4, // Disable manual resizing.
|
||||
ImGuiTableColumnFlags_NoReorder = 1 << 5, // Disable manual reordering this column, this will also prevent other columns from crossing over this column.
|
||||
ImGuiTableColumnFlags_NoHide = 1 << 6, // Disable ability to hide/disable this column.
|
||||
ImGuiTableColumnFlags_NoClip = 1 << 7, // Disable clipping for this column (all NoClip columns will render in a same draw command).
|
||||
ImGuiTableColumnFlags_NoSort = 1 << 8, // Disable ability to sort on this field (even if ImGuiTableFlags_Sortable is set on the table).
|
||||
ImGuiTableColumnFlags_NoSortAscending = 1 << 9, // Disable ability to sort in the ascending direction.
|
||||
ImGuiTableColumnFlags_NoSortDescending = 1 << 10, // Disable ability to sort in the descending direction.
|
||||
ImGuiTableColumnFlags_NoHeaderWidth = 1 << 11, // Disable header text width contribution to automatic column width.
|
||||
ImGuiTableColumnFlags_PreferSortAscending = 1 << 12, // Make the initial sort direction Ascending when first sorting on this column (default).
|
||||
ImGuiTableColumnFlags_PreferSortDescending = 1 << 13, // Make the initial sort direction Descending when first sorting on this column.
|
||||
ImGuiTableColumnFlags_IndentEnable = 1 << 14, // Use current Indent value when entering cell (default for column 0).
|
||||
ImGuiTableColumnFlags_IndentDisable = 1 << 15, // Ignore current Indent value when entering cell (default for columns > 0). Indentation changes _within_ the cell will still be honored.
|
||||
|
||||
// Output status flags, read-only via TableGetColumnFlags()
|
||||
ImGuiTableColumnFlags_IsEnabled = 1 << 20, // Status: is enabled == not hidden by user/api (referred to as "Hide" in _DefaultHide and _NoHide) flags.
|
||||
ImGuiTableColumnFlags_IsVisible = 1 << 21, // Status: is visible == is enabled AND not clipped by scrolling.
|
||||
ImGuiTableColumnFlags_IsSorted = 1 << 22, // Status: is currently part of the sort specs
|
||||
ImGuiTableColumnFlags_IsHovered = 1 << 23, // Status: is hovered by mouse
|
||||
|
||||
// [Internal] Combinations and masks
|
||||
ImGuiTableColumnFlags_WidthMask_ = ImGuiTableColumnFlags_WidthStretch | ImGuiTableColumnFlags_WidthFixed,
|
||||
ImGuiTableColumnFlags_IndentMask_ = ImGuiTableColumnFlags_IndentEnable | ImGuiTableColumnFlags_IndentDisable,
|
||||
ImGuiTableColumnFlags_StatusMask_ = ImGuiTableColumnFlags_IsEnabled | ImGuiTableColumnFlags_IsVisible | ImGuiTableColumnFlags_IsSorted | ImGuiTableColumnFlags_IsHovered,
|
||||
ImGuiTableColumnFlags_NoDirectResize_ = 1 << 30 // [Internal] Disable user resizing this column directly (it may however we resized indirectly from its left edge)
|
||||
|
||||
// Obsolete names (will be removed soon)
|
||||
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
|
||||
//ImGuiTableColumnFlags_WidthAuto = ImGuiTableColumnFlags_WidthFixed | ImGuiTableColumnFlags_NoResize, // Column will not stretch and keep resizing based on submitted contents.
|
||||
#endif
|
||||
};
|
||||
|
||||
// Flags for ImGui::TableNextRow()
|
||||
enum ImGuiTableRowFlags_
|
||||
{
|
||||
ImGuiTableRowFlags_None = 0,
|
||||
ImGuiTableRowFlags_Headers = 1 << 0 // Identify header row (set default background color + width of its contents accounted different for auto column width)
|
||||
};
|
||||
|
||||
// Enum for ImGui::TableSetBgColor()
|
||||
// Background colors are rendering in 3 layers:
|
||||
// - Layer 0: draw with RowBg0 color if set, otherwise draw with ColumnBg0 if set.
|
||||
// - Layer 1: draw with RowBg1 color if set, otherwise draw with ColumnBg1 if set.
|
||||
// - Layer 2: draw with CellBg color if set.
|
||||
// The purpose of the two row/columns layers is to let you decide if a background color changes should override or blend with the existing color.
|
||||
// When using ImGuiTableFlags_RowBg on the table, each row has the RowBg0 color automatically set for odd/even rows.
|
||||
// If you set the color of RowBg0 target, your color will override the existing RowBg0 color.
|
||||
// If you set the color of RowBg1 or ColumnBg1 target, your color will blend over the RowBg0 color.
|
||||
enum ImGuiTableBgTarget_
|
||||
{
|
||||
ImGuiTableBgTarget_None = 0,
|
||||
ImGuiTableBgTarget_RowBg0 = 1, // Set row background color 0 (generally used for background, automatically set when ImGuiTableFlags_RowBg is used)
|
||||
ImGuiTableBgTarget_RowBg1 = 2, // Set row background color 1 (generally used for selection marking)
|
||||
ImGuiTableBgTarget_CellBg = 3 // Set cell background color (top-most color)
|
||||
};
|
||||
|
||||
// Flags for ImGui::IsWindowFocused()
|
||||
enum ImGuiFocusedFlags_
|
||||
{
|
||||
@@ -1096,6 +1313,14 @@ enum ImGuiDir_
|
||||
ImGuiDir_COUNT
|
||||
};
|
||||
|
||||
// A sorting direction
|
||||
enum ImGuiSortDirection_
|
||||
{
|
||||
ImGuiSortDirection_None = 0,
|
||||
ImGuiSortDirection_Ascending = 1, // Ascending = 0->9, A->Z etc.
|
||||
ImGuiSortDirection_Descending = 2 // Descending = 9->0, Z->A etc.
|
||||
};
|
||||
|
||||
// User fill ImGuiIO.KeyMap[] array with indices into the ImGuiIO.KeysDown[512] array
|
||||
enum ImGuiKey_
|
||||
{
|
||||
@@ -1137,7 +1362,7 @@ enum ImGuiKeyModFlags_
|
||||
// Gamepad/Keyboard navigation
|
||||
// Keyboard: Set io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard to enable. NewFrame() will automatically fill io.NavInputs[] based on your io.KeysDown[] + io.KeyMap[] arrays.
|
||||
// Gamepad: Set io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad to enable. Backend: set ImGuiBackendFlags_HasGamepad and fill the io.NavInputs[] fields before calling NewFrame(). Note that io.NavInputs[] is cleared by EndFrame().
|
||||
// Read instructions in imgui.cpp for more details. Download PNG/PSD at http://goo.gl/9LgVZW.
|
||||
// Read instructions in imgui.cpp for more details. Download PNG/PSD at http://dearimgui.org/controls_sheets.
|
||||
enum ImGuiNavInput_
|
||||
{
|
||||
// Gamepad Mapping
|
||||
@@ -1256,6 +1481,11 @@ enum ImGuiCol_
|
||||
ImGuiCol_PlotLinesHovered,
|
||||
ImGuiCol_PlotHistogram,
|
||||
ImGuiCol_PlotHistogramHovered,
|
||||
ImGuiCol_TableHeaderBg, // Table header background
|
||||
ImGuiCol_TableBorderStrong, // Table outer and header borders (prefer using Alpha=1.0 here)
|
||||
ImGuiCol_TableBorderLight, // Table inner borders (prefer using Alpha=1.0 here)
|
||||
ImGuiCol_TableRowBg, // Table row background (even rows)
|
||||
ImGuiCol_TableRowBgAlt, // Table row background (odd rows)
|
||||
ImGuiCol_TextSelectedBg,
|
||||
ImGuiCol_DragDropTarget,
|
||||
ImGuiCol_NavHighlight, // Gamepad/keyboard: current highlighted item
|
||||
@@ -1263,11 +1493,6 @@ enum ImGuiCol_
|
||||
ImGuiCol_NavWindowingDimBg, // Darken/colorize entire screen behind the CTRL+TAB window list, when active
|
||||
ImGuiCol_ModalWindowDimBg, // Darken/colorize entire screen behind a modal window, when one is active
|
||||
ImGuiCol_COUNT
|
||||
|
||||
// Obsolete names (will be removed)
|
||||
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
|
||||
, ImGuiCol_ModalWindowDarkening = ImGuiCol_ModalWindowDimBg // [renamed in 1.63]
|
||||
#endif
|
||||
};
|
||||
|
||||
// Enumeration for PushStyleVar() / PopStyleVar() to temporarily modify the ImGuiStyle structure.
|
||||
@@ -1296,6 +1521,7 @@ enum ImGuiStyleVar_
|
||||
ImGuiStyleVar_ItemSpacing, // ImVec2 ItemSpacing
|
||||
ImGuiStyleVar_ItemInnerSpacing, // ImVec2 ItemInnerSpacing
|
||||
ImGuiStyleVar_IndentSpacing, // float IndentSpacing
|
||||
ImGuiStyleVar_CellPadding, // ImVec2 CellPadding
|
||||
ImGuiStyleVar_ScrollbarSize, // float ScrollbarSize
|
||||
ImGuiStyleVar_ScrollbarRounding, // float ScrollbarRounding
|
||||
ImGuiStyleVar_GrabMinSize, // float GrabMinSize
|
||||
@@ -1422,7 +1648,10 @@ enum ImGuiCond_
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Helpers: Memory allocations macros
|
||||
// [SECTION] Helpers: Memory allocations macros, ImVector<>
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// IM_MALLOC(), IM_FREE(), IM_NEW(), IM_PLACEMENT_NEW(), IM_DELETE()
|
||||
// We call C++ constructor on own allocated memory via the placement "new(ptr) Type()" syntax.
|
||||
// Defining a custom placement new() with a custom parameter allows us to bypass including <new> which on some platforms complains when user has disabled exceptions.
|
||||
@@ -1438,7 +1667,7 @@ inline void operator delete(void*, ImNewWrapper, void*) {} // This is only re
|
||||
template<typename T> void IM_DELETE(T* p) { if (p) { p->~T(); ImGui::MemFree(p); } }
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Helper: ImVector<>
|
||||
// ImVector<>
|
||||
// Lightweight std::vector<>-like class to avoid dragging dependencies (also, some implementations of STL with debug enabled are absurdly slow, we bypass it so our code runs fast in debug).
|
||||
//-----------------------------------------------------------------------------
|
||||
// - You generally do NOT need to care or use this ever. But we need to make it available in imgui.h because some of our public structures are relying on it.
|
||||
@@ -1508,7 +1737,8 @@ struct ImVector
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// ImGuiStyle
|
||||
// [SECTION] ImGuiStyle
|
||||
//-----------------------------------------------------------------------------
|
||||
// You may modify the ImGui::GetStyle() main instance during initialization and before NewFrame().
|
||||
// During the frame, use ImGui::PushStyleVar(ImGuiStyleVar_XXXX)/PopStyleVar() to alter the main style values,
|
||||
// and ImGui::PushStyleColor(ImGuiCol_XXX)/PopStyleColor() for colors.
|
||||
@@ -1532,6 +1762,7 @@ struct ImGuiStyle
|
||||
float FrameBorderSize; // Thickness of border around frames. Generally set to 0.0f or 1.0f. (Other values are not well tested and more CPU/GPU costly).
|
||||
ImVec2 ItemSpacing; // Horizontal and vertical spacing between widgets/lines.
|
||||
ImVec2 ItemInnerSpacing; // Horizontal and vertical spacing between within elements of a composed widget (e.g. a slider and its label).
|
||||
ImVec2 CellPadding; // Padding within a table cell
|
||||
ImVec2 TouchExtraPadding; // Expand reactive bounding box for touch-based system where touch position is not accurate enough. Unfortunately we don't sort widgets so priority on overlap will always be given to the first widget. So don't grow this too much!
|
||||
float IndentSpacing; // Horizontal indentation when e.g. entering a tree node. Generally == (FontSize + FramePadding.x*2).
|
||||
float ColumnsMinSpacing; // Minimum horizontal spacing between two columns. Preferably > (FramePadding.x + 1).
|
||||
@@ -1561,7 +1792,8 @@ struct ImGuiStyle
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// ImGuiIO
|
||||
// [SECTION] ImGuiIO
|
||||
//-----------------------------------------------------------------------------
|
||||
// Communicate most settings and inputs/outputs to Dear ImGui using this structure.
|
||||
// Access via ImGui::GetIO(). Read 'Programmer guide' section in .cpp file for general usage.
|
||||
//-----------------------------------------------------------------------------
|
||||
@@ -1602,16 +1834,17 @@ struct ImGuiIO
|
||||
// Viewport options (when ImGuiConfigFlags_ViewportsEnable is set)
|
||||
bool ConfigViewportsNoAutoMerge; // = false; // Set to make all floating imgui windows always create their own viewport. Otherwise, they are merged into the main host viewports when overlapping it. May also set ImGuiViewportFlags_NoAutoMerge on individual viewport.
|
||||
bool ConfigViewportsNoTaskBarIcon; // = false // Disable default OS task bar icon flag for secondary viewports. When a viewport doesn't want a task bar icon, ImGuiViewportFlags_NoTaskBarIcon will be set on it.
|
||||
bool ConfigViewportsNoDecoration; // = true // [BETA] Disable default OS window decoration flag for secondary viewports. When a viewport doesn't want window decorations, ImGuiViewportFlags_NoDecoration will be set on it. Enabling decoration can create subsequent issues at OS levels (e.g. minimum window size).
|
||||
bool ConfigViewportsNoDecoration; // = true // Disable default OS window decoration flag for secondary viewports. When a viewport doesn't want window decorations, ImGuiViewportFlags_NoDecoration will be set on it. Enabling decoration can create subsequent issues at OS levels (e.g. minimum window size).
|
||||
bool ConfigViewportsNoDefaultParent; // = false // Disable default OS parenting to main viewport for secondary viewports. By default, viewports are marked with ParentViewportId = <main_viewport>, expecting the platform backend to setup a parent/child relationship between the OS windows (some backend may ignore this). Set to true if you want the default to be 0, then all viewports will be top-level OS windows.
|
||||
|
||||
// Miscellaneous options
|
||||
bool MouseDrawCursor; // = false // Request ImGui to draw a mouse cursor for you (if you are on a platform without a mouse cursor). Cannot be easily renamed to 'io.ConfigXXX' because this is frequently used by backend implementations.
|
||||
bool ConfigMacOSXBehaviors; // = defined(__APPLE__) // OS X style: Text editing cursor movement using Alt instead of Ctrl, Shortcuts using Cmd/Super instead of Ctrl, Line/Text Start and End using Cmd+Arrows instead of Home/End, Double click selects by word instead of selecting whole text, Multi-selection in lists uses Cmd/Super instead of Ctrl (was called io.OptMacOSXBehaviors prior to 1.63)
|
||||
bool ConfigInputTextCursorBlink; // = true // Set to false to disable blinking cursor, for users who consider it distracting. (was called: io.OptCursorBlink prior to 1.63)
|
||||
bool ConfigMacOSXBehaviors; // = defined(__APPLE__) // OS X style: Text editing cursor movement using Alt instead of Ctrl, Shortcuts using Cmd/Super instead of Ctrl, Line/Text Start and End using Cmd+Arrows instead of Home/End, Double click selects by word instead of selecting whole text, Multi-selection in lists uses Cmd/Super instead of Ctrl.
|
||||
bool ConfigInputTextCursorBlink; // = true // Enable blinking cursor (optional as some users consider it to be distracting).
|
||||
bool ConfigDragClickToInputText; // = false // [BETA] Enable turning DragXXX widgets into text input with a simple mouse click-release (without moving). Not desirable on devices without a keyboard.
|
||||
bool ConfigWindowsResizeFromEdges; // = true // Enable resizing of windows from their edges and from the lower-left corner. This requires (io.BackendFlags & ImGuiBackendFlags_HasMouseCursors) because it needs mouse cursor feedback. (This used to be a per-window ImGuiWindowFlags_ResizeFromAnySide flag)
|
||||
bool ConfigWindowsMoveFromTitleBarOnly; // = false // [BETA] Set to true to only allow moving windows when clicked+dragged from the title bar. Windows without a title bar are not affected.
|
||||
float ConfigWindowsMemoryCompactTimer;// = 60.0f // [BETA] Compact window memory usage when unused. Set to -1.0f to disable.
|
||||
bool ConfigWindowsMoveFromTitleBarOnly; // = false // Enable allowing to move windows only when clicking on their title bar. Does not apply to windows without a title bar.
|
||||
float ConfigMemoryCompactTimer; // = 60.0f // Timer (in seconds) to free transient windows/tables memory buffers when unused. Set to -1.0f to disable.
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// Platform Functions
|
||||
@@ -1703,7 +1936,7 @@ struct ImGuiIO
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Misc data structures
|
||||
// [SECTION] Misc data structures
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// Shared state of InputText(), passed as an argument to your callback when a ImGuiInputTextFlags_Callback* flag is used.
|
||||
@@ -1767,12 +2000,13 @@ struct ImGuiWindowClass
|
||||
ImGuiID ParentViewportId; // Hint for the platform backend. If non-zero, the platform backend can create a parent<>child relationship between the platform windows. Not conforming backends are free to e.g. parent every viewport to the main viewport or not.
|
||||
ImGuiViewportFlags ViewportFlagsOverrideSet; // Viewport flags to set when a window of this class owns a viewport. This allows you to enforce OS decoration or task bar icon, override the defaults on a per-window basis.
|
||||
ImGuiViewportFlags ViewportFlagsOverrideClear; // Viewport flags to clear when a window of this class owns a viewport. This allows you to enforce OS decoration or task bar icon, override the defaults on a per-window basis.
|
||||
ImGuiTabItemFlags TabItemFlagsOverrideSet; // [EXPERIMENTAL] TabItem flags to set when a window of this class gets submitted into a dock node tab bar. May use with ImGuiTabItemFlags_Leading or ImGuiTabItemFlags_Trailing.
|
||||
ImGuiDockNodeFlags DockNodeFlagsOverrideSet; // [EXPERIMENTAL] Dock node flags to set when a window of this class is hosted by a dock node (it doesn't have to be selected!)
|
||||
ImGuiDockNodeFlags DockNodeFlagsOverrideClear; // [EXPERIMENTAL]
|
||||
bool DockingAlwaysTabBar; // Set to true to enforce single floating windows of this class always having their own docking node (equivalent of setting the global io.ConfigDockingAlwaysTabBar)
|
||||
bool DockingAllowUnclassed; // Set to true to allow windows of this class to be docked/merged with an unclassed window. // FIXME-DOCK: Move to DockNodeFlags override?
|
||||
|
||||
ImGuiWindowClass() { ClassId = 0; ParentViewportId = 0; ViewportFlagsOverrideSet = ViewportFlagsOverrideClear = 0x00; DockNodeFlagsOverrideSet = DockNodeFlagsOverrideClear = 0x00; DockingAlwaysTabBar = false; DockingAllowUnclassed = true; }
|
||||
ImGuiWindowClass() { memset(this, 0, sizeof(*this)); DockingAllowUnclassed = true; }
|
||||
};
|
||||
|
||||
// Data payload for Drag and Drop operations: AcceptDragDropPayload(), GetDragDropPayload()
|
||||
@@ -1797,8 +2031,33 @@ struct ImGuiPayload
|
||||
bool IsDelivery() const { return Delivery; }
|
||||
};
|
||||
|
||||
// Sorting specification for one column of a table (sizeof == 12 bytes)
|
||||
struct ImGuiTableColumnSortSpecs
|
||||
{
|
||||
ImGuiID ColumnUserID; // User id of the column (if specified by a TableSetupColumn() call)
|
||||
ImS16 ColumnIndex; // Index of the column
|
||||
ImS16 SortOrder; // Index within parent ImGuiTableSortSpecs (always stored in order starting from 0, tables sorted on a single criteria will always have a 0 here)
|
||||
ImGuiSortDirection SortDirection : 8; // ImGuiSortDirection_Ascending or ImGuiSortDirection_Descending (you can use this or SortSign, whichever is more convenient for your sort function)
|
||||
|
||||
ImGuiTableColumnSortSpecs() { memset(this, 0, sizeof(*this)); }
|
||||
};
|
||||
|
||||
// Sorting specifications for a table (often handling sort specs for a single column, occasionally more)
|
||||
// Obtained by calling TableGetSortSpecs().
|
||||
// When 'SpecsDirty == true' you can sort your data. It will be true with sorting specs have changed since last call, or the first time.
|
||||
// Make sure to set 'SpecsDirty = false' after sorting, else you may wastefully sort your data every frame!
|
||||
struct ImGuiTableSortSpecs
|
||||
{
|
||||
const ImGuiTableColumnSortSpecs* Specs; // Pointer to sort spec array.
|
||||
int SpecsCount; // Sort spec count. Most often 1. May be > 1 when ImGuiTableFlags_SortMulti is enabled. May be == 0 when ImGuiTableFlags_SortTristate is enabled.
|
||||
bool SpecsDirty; // Set to true when specs have changed since last time! Use this to sort again, then clear the flag.
|
||||
|
||||
ImGuiTableSortSpecs() { memset(this, 0, sizeof(*this)); }
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Obsolete functions (Will be removed! Read 'API BREAKING CHANGES' section in imgui.cpp for details)
|
||||
// [SECTION] Obsolete functions
|
||||
// (Will be removed! Read 'API BREAKING CHANGES' section in imgui.cpp for details)
|
||||
// Please keep your copy of dear imgui up to date! Occasionally set '#define IMGUI_DISABLE_OBSOLETE_FUNCTIONS' in imconfig.h to stay ahead.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
@@ -1834,15 +2093,11 @@ namespace ImGui
|
||||
static inline ImDrawList* GetOverlayDrawList() { return GetForegroundDrawList(); }
|
||||
// OBSOLETED in 1.66 (from Sep 2018)
|
||||
static inline void SetScrollHere(float center_ratio=0.5f){ SetScrollHereY(center_ratio); }
|
||||
// OBSOLETED in 1.63 (between Aug 2018 and Sept 2018)
|
||||
static inline bool IsItemDeactivatedAfterChange() { return IsItemDeactivatedAfterEdit(); }
|
||||
}
|
||||
typedef ImGuiInputTextCallback ImGuiTextEditCallback; // OBSOLETED in 1.63 (from Aug 2018): made the names consistent
|
||||
typedef ImGuiInputTextCallbackData ImGuiTextEditCallbackData;
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Helpers
|
||||
// [SECTION] Helpers (ImGuiOnceUponAFrame, ImGuiTextFilter, ImGuiTextBuffer, ImGuiStorage, ImGuiListClipper, ImColor)
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// Helper: Unicode defines
|
||||
@@ -1985,6 +2240,7 @@ struct ImGuiListClipper
|
||||
// [Internal]
|
||||
int ItemsCount;
|
||||
int StepNo;
|
||||
int ItemsFrozen;
|
||||
float ItemsHeight;
|
||||
float StartPosY;
|
||||
|
||||
@@ -2043,7 +2299,7 @@ struct ImColor
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Draw List API (ImDrawCmd, ImDrawIdx, ImDrawVert, ImDrawChannel, ImDrawListSplitter, ImDrawListFlags, ImDrawList, ImDrawData)
|
||||
// [SECTION] Drawing API (ImDrawCmd, ImDrawIdx, ImDrawVert, ImDrawChannel, ImDrawListSplitter, ImDrawListFlags, ImDrawList, ImDrawData)
|
||||
// Hold a series of drawing commands. The user provides a renderer for ImDrawData which essentially contains an array of ImDrawList.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
@@ -2110,22 +2366,31 @@ struct ImDrawVert
|
||||
IMGUI_OVERRIDE_DRAWVERT_STRUCT_LAYOUT;
|
||||
#endif
|
||||
|
||||
// For use by ImDrawListSplitter.
|
||||
// [Internal] For use by ImDrawList
|
||||
struct ImDrawCmdHeader
|
||||
{
|
||||
ImVec4 ClipRect;
|
||||
ImTextureID TextureId;
|
||||
unsigned int VtxOffset;
|
||||
};
|
||||
|
||||
// [Internal] For use by ImDrawListSplitter
|
||||
struct ImDrawChannel
|
||||
{
|
||||
ImVector<ImDrawCmd> _CmdBuffer;
|
||||
ImVector<ImDrawIdx> _IdxBuffer;
|
||||
};
|
||||
|
||||
|
||||
// Split/Merge functions are used to split the draw list into different layers which can be drawn into out of order.
|
||||
// This is used by the Columns api, so items of each column can be batched together in a same draw call.
|
||||
// This is used by the Columns/Tables API, so items of each column can be batched together in a same draw call.
|
||||
struct ImDrawListSplitter
|
||||
{
|
||||
int _Current; // Current channel number (0)
|
||||
int _Count; // Number of active channels (1+)
|
||||
ImVector<ImDrawChannel> _Channels; // Draw channels (not resized down so _Count might be < Channels.Size)
|
||||
|
||||
inline ImDrawListSplitter() { Clear(); }
|
||||
inline ImDrawListSplitter() { memset(this, 0, sizeof(*this)); }
|
||||
inline ~ImDrawListSplitter() { ClearFreeMemory(); }
|
||||
inline void Clear() { _Current = 0; _Count = 1; } // Do not clear Channels[] so our allocations are reused next frame
|
||||
IMGUI_API void ClearFreeMemory();
|
||||
@@ -2176,19 +2441,20 @@ struct ImDrawList
|
||||
ImDrawListFlags Flags; // Flags, you may poke into these to adjust anti-aliasing settings per-primitive.
|
||||
|
||||
// [Internal, used while building lists]
|
||||
unsigned int _VtxCurrentIdx; // [Internal] generally == VtxBuffer.Size unless we are past 64K vertices, in which case this gets reset to 0.
|
||||
const ImDrawListSharedData* _Data; // Pointer to shared draw data (you can use ImGui::GetDrawListSharedData() to get the one from current ImGui context)
|
||||
const char* _OwnerName; // Pointer to owner window's name for debugging
|
||||
unsigned int _VtxCurrentIdx; // [Internal] Generally == VtxBuffer.Size unless we are past 64K vertices, in which case this gets reset to 0.
|
||||
ImDrawVert* _VtxWritePtr; // [Internal] point within VtxBuffer.Data after each add command (to avoid using the ImVector<> operators too much)
|
||||
ImDrawIdx* _IdxWritePtr; // [Internal] point within IdxBuffer.Data after each add command (to avoid using the ImVector<> operators too much)
|
||||
ImVector<ImVec4> _ClipRectStack; // [Internal]
|
||||
ImVector<ImTextureID> _TextureIdStack; // [Internal]
|
||||
ImVector<ImVec2> _Path; // [Internal] current path building
|
||||
ImDrawCmd _CmdHeader; // [Internal] Template of active commands. Fields should match those of CmdBuffer.back().
|
||||
ImDrawCmdHeader _CmdHeader; // [Internal] template of active commands. Fields should match those of CmdBuffer.back().
|
||||
ImDrawListSplitter _Splitter; // [Internal] for channels api (note: prefer using your own persistent instance of ImDrawListSplitter!)
|
||||
float _FringeScale; // [Internal] anti-alias fringe is scaled by this value, this helps to keep things sharp while zooming at vertex buffer content
|
||||
|
||||
// If you want to create ImDrawList instances, pass them ImGui::GetDrawListSharedData() or create and use your own ImDrawListSharedData (so you can use ImDrawList without ImGui)
|
||||
ImDrawList(const ImDrawListSharedData* shared_data) { _Data = shared_data; Flags = ImDrawListFlags_None; _VtxCurrentIdx = 0; _VtxWritePtr = NULL; _IdxWritePtr = NULL; _OwnerName = NULL; }
|
||||
ImDrawList(const ImDrawListSharedData* shared_data) { memset(this, 0, sizeof(*this)); _Data = shared_data; }
|
||||
|
||||
~ImDrawList() { _ClearFreeMemory(); }
|
||||
IMGUI_API void PushClipRect(ImVec2 clip_rect_min, ImVec2 clip_rect_max, bool intersect_with_current_clip_rect = false); // Render-level scissoring. This is passed down to your render function but not used for CPU-side coarse clipping. Prefer using higher-level ImGui::PushClipRect() to affect logic (hit-testing and widget culling)
|
||||
@@ -2221,7 +2487,8 @@ struct ImDrawList
|
||||
IMGUI_API void AddText(const ImFont* font, float font_size, const ImVec2& pos, ImU32 col, const char* text_begin, const char* text_end = NULL, float wrap_width = 0.0f, const ImVec4* cpu_fine_clip_rect = NULL);
|
||||
IMGUI_API void AddPolyline(const ImVec2* points, int num_points, ImU32 col, bool closed, float thickness);
|
||||
IMGUI_API void AddConvexPolyFilled(const ImVec2* points, int num_points, ImU32 col); // Note: Anti-aliased filling requires points to be in clockwise order.
|
||||
IMGUI_API void AddBezierCurve(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, ImU32 col, float thickness, int num_segments = 0);
|
||||
IMGUI_API void AddBezierCubic(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, ImU32 col, float thickness, int num_segments = 0); // Cubic Bezier (4 control points)
|
||||
IMGUI_API void AddBezierQuadratic(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, ImU32 col, float thickness, int num_segments = 0); // Quadratic Bezier (3 control points)
|
||||
|
||||
// Image primitives
|
||||
// - Read FAQ to understand what ImTextureID is.
|
||||
@@ -2238,8 +2505,9 @@ struct ImDrawList
|
||||
inline void PathFillConvex(ImU32 col) { AddConvexPolyFilled(_Path.Data, _Path.Size, col); _Path.Size = 0; } // Note: Anti-aliased filling requires points to be in clockwise order.
|
||||
inline void PathStroke(ImU32 col, bool closed, float thickness = 1.0f) { AddPolyline(_Path.Data, _Path.Size, col, closed, thickness); _Path.Size = 0; }
|
||||
IMGUI_API void PathArcTo(const ImVec2& center, float radius, float a_min, float a_max, int num_segments = 10);
|
||||
IMGUI_API void PathArcToFast(const ImVec2& center, float radius, int a_min_of_12, int a_max_of_12); // Use precomputed angles for a 12 steps circle
|
||||
IMGUI_API void PathBezierCurveTo(const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, int num_segments = 0);
|
||||
IMGUI_API void PathArcToFast(const ImVec2& center, float radius, int a_min_of_12, int a_max_of_12); // Use precomputed angles for a 12 steps circle
|
||||
IMGUI_API void PathBezierCubicCurveTo(const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, int num_segments = 0); // Cubic Bezier (4 control points)
|
||||
IMGUI_API void PathBezierQuadraticCurveTo(const ImVec2& p2, const ImVec2& p3, int num_segments = 0); // Quadratic Bezier (3 control points)
|
||||
IMGUI_API void PathRect(const ImVec2& rect_min, const ImVec2& rect_max, float rounding = 0.0f, ImDrawCornerFlags rounding_corners = ImDrawCornerFlags_All);
|
||||
|
||||
// Advanced
|
||||
@@ -2269,6 +2537,11 @@ struct ImDrawList
|
||||
inline void PrimWriteIdx(ImDrawIdx idx) { *_IdxWritePtr = idx; _IdxWritePtr++; }
|
||||
inline void PrimVtx(const ImVec2& pos, const ImVec2& uv, ImU32 col) { PrimWriteIdx((ImDrawIdx)_VtxCurrentIdx); PrimWriteVtx(pos, uv, col); } // Write vertex with unique index
|
||||
|
||||
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
|
||||
inline void AddBezierCurve(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, ImU32 col, float thickness, int num_segments = 0) { AddBezierCubic(p1, p2, p3, p4, col, thickness, num_segments); }
|
||||
inline void PathBezierCurveTo(const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, int num_segments = 0) { PathBezierCubicCurveTo(p2, p3, p4, num_segments); }
|
||||
#endif
|
||||
|
||||
// [Internal helpers]
|
||||
IMGUI_API void _ResetForNewFrame();
|
||||
IMGUI_API void _ClearFreeMemory();
|
||||
@@ -2302,7 +2575,7 @@ struct ImDrawData
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Font API (ImFontConfig, ImFontGlyph, ImFontAtlasFlags, ImFontAtlas, ImFontGlyphRangesBuilder, ImFont)
|
||||
// [SECTION] Font API (ImFontConfig, ImFontGlyph, ImFontAtlasFlags, ImFontAtlas, ImFontGlyphRangesBuilder, ImFont)
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
struct ImFontConfig
|
||||
@@ -2433,7 +2706,7 @@ struct ImFontAtlas
|
||||
// NB: Consider using ImFontGlyphRangesBuilder to build glyph ranges from textual data.
|
||||
IMGUI_API const ImWchar* GetGlyphRangesDefault(); // Basic Latin, Extended Latin
|
||||
IMGUI_API const ImWchar* GetGlyphRangesKorean(); // Default + Korean characters
|
||||
IMGUI_API const ImWchar* GetGlyphRangesJapanese(); // Default + Hiragana, Katakana, Half-Width, Selection of 1946 Ideographs
|
||||
IMGUI_API const ImWchar* GetGlyphRangesJapanese(); // Default + Hiragana, Katakana, Half-Width, Selection of 2999 Ideographs
|
||||
IMGUI_API const ImWchar* GetGlyphRangesChineseFull(); // Default + Half-Width + Japanese Hiragana/Katakana + full set of about 21000 CJK Unified Ideographs
|
||||
IMGUI_API const ImWchar* GetGlyphRangesChineseSimplifiedCommon();// Default + Half-Width + Japanese Hiragana/Katakana + set of 2500 CJK Unified Ideographs for common simplified Chinese
|
||||
IMGUI_API const ImWchar* GetGlyphRangesCyrillic(); // Default + about 400 Cyrillic characters
|
||||
@@ -2545,9 +2818,9 @@ struct ImFont
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// [BETA] Platform interface for multi-viewport support
|
||||
// [SECTION] Platform interface for multi-viewport support
|
||||
//-----------------------------------------------------------------------------
|
||||
// (Optional) This is completely optional, for advanced users!
|
||||
// [BETA] (Optional) This is completely optional, for advanced users!
|
||||
// If you are new to Dear ImGui and trying to integrate it into your engine, you can probably ignore this for now.
|
||||
//
|
||||
// This feature allows you to seamlessly drag Dear ImGui windows outside of your application viewport.
|
||||
36
external/ImGui/include/imgui_freetype.h
vendored
Normal file
36
external/ImGui/include/imgui_freetype.h
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
// dear imgui: wrapper to use FreeType (instead of stb_truetype)
|
||||
// Get latest version at https://github.com/ocornut/imgui/tree/master/misc/freetype
|
||||
// Original code by @Vuhdo (Aleksei Skriabin), maintained by @ocornut
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "imgui.h" // IMGUI_API, ImFontAtlas
|
||||
|
||||
namespace ImGuiFreeType
|
||||
{
|
||||
// Hinting greatly impacts visuals (and glyph sizes).
|
||||
// When disabled, FreeType generates blurrier glyphs, more or less matches the stb's output.
|
||||
// The Default hinting mode usually looks good, but may distort glyphs in an unusual way.
|
||||
// The Light hinting mode generates fuzzier glyphs but better matches Microsoft's rasterizer.
|
||||
|
||||
// You can set those flags on a per font basis in ImFontConfig::RasterizerFlags.
|
||||
// Use the 'extra_flags' parameter of BuildFontAtlas() to force a flag on all your fonts.
|
||||
enum RasterizerFlags
|
||||
{
|
||||
// By default, hinting is enabled and the font's native hinter is preferred over the auto-hinter.
|
||||
NoHinting = 1 << 0, // Disable hinting. This generally generates 'blurrier' bitmap glyphs when the glyph are rendered in any of the anti-aliased modes.
|
||||
NoAutoHint = 1 << 1, // Disable auto-hinter.
|
||||
ForceAutoHint = 1 << 2, // Indicates that the auto-hinter is preferred over the font's native hinter.
|
||||
LightHinting = 1 << 3, // A lighter hinting algorithm for gray-level modes. Many generated glyphs are fuzzier but better resemble their original shape. This is achieved by snapping glyphs to the pixel grid only vertically (Y-axis), as is done by Microsoft's ClearType and Adobe's proprietary font renderer. This preserves inter-glyph spacing in horizontal text.
|
||||
MonoHinting = 1 << 4, // Strong hinting algorithm that should only be used for monochrome output.
|
||||
Bold = 1 << 5, // Styling: Should we artificially embolden the font?
|
||||
Oblique = 1 << 6, // Styling: Should we slant the font, emulating italic style?
|
||||
Monochrome = 1 << 7 // Disable anti-aliasing. Combine this with MonoHinting for best results!
|
||||
};
|
||||
|
||||
IMGUI_API bool BuildFontAtlas(ImFontAtlas* atlas, unsigned int extra_flags = 0);
|
||||
|
||||
// By default ImGuiFreeType will use IM_ALLOC()/IM_FREE().
|
||||
// However, as FreeType does lots of allocations we provide a way for the user to redirect it to a separate memory heap if desired:
|
||||
IMGUI_API void SetAllocatorFunctions(void* (*alloc_func)(size_t sz, void* user_data), void (*free_func)(void* ptr, void* user_data), void* user_data = NULL);
|
||||
}
|
||||
15
external/ImGui/include/imgui_imhex_extensions.h
vendored
Normal file
15
external/ImGui/include/imgui_imhex_extensions.h
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
#pragma once
|
||||
|
||||
#include <functional>
|
||||
|
||||
#include <imgui.h>
|
||||
|
||||
namespace ImGui {
|
||||
|
||||
bool Hyperlink(const char* label, const ImVec2& size_arg = ImVec2(0, 0), ImGuiButtonFlags flags = 0);
|
||||
bool BulletHyperlink(const char* label, const ImVec2& size_arg = ImVec2(0, 0), ImGuiButtonFlags flags = 0);
|
||||
bool DescriptionButton(const char* label, const char* description, const ImVec2& size_arg = ImVec2(0, 0), ImGuiButtonFlags flags = 0);
|
||||
|
||||
void UnderlinedText(const char* label, ImColor color, const ImVec2& size_arg = ImVec2(0, 0));
|
||||
|
||||
}
|
||||
@@ -7,10 +7,6 @@
|
||||
// [X] Platform: Gamepad support. Enable with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'.
|
||||
// [x] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'. FIXME: 3 cursors types are missing from GLFW.
|
||||
// [X] Platform: Keyboard arrays indexed using GLFW_KEY_* codes, e.g. ImGui::IsKeyPressed(GLFW_KEY_SPACE).
|
||||
// [X] Platform: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
|
||||
|
||||
// Issues:
|
||||
// [ ] Platform: Multi-viewport support: ParentViewportID not honored, and so io.ConfigViewportsNoDefaultParent has no effect (minor).
|
||||
|
||||
// You can copy and use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp.
|
||||
@@ -24,7 +20,6 @@
|
||||
#include "imgui.h" // IMGUI_IMPL_API
|
||||
|
||||
struct GLFWwindow;
|
||||
struct GLFWmonitor;
|
||||
|
||||
IMGUI_IMPL_API bool ImGui_ImplGlfw_InitForOpenGL(GLFWwindow* window, bool install_callbacks);
|
||||
IMGUI_IMPL_API bool ImGui_ImplGlfw_InitForVulkan(GLFWwindow* window, bool install_callbacks);
|
||||
@@ -38,4 +33,3 @@ IMGUI_IMPL_API void ImGui_ImplGlfw_MouseButtonCallback(GLFWwindow* window, i
|
||||
IMGUI_IMPL_API void ImGui_ImplGlfw_ScrollCallback(GLFWwindow* window, double xoffset, double yoffset);
|
||||
IMGUI_IMPL_API void ImGui_ImplGlfw_KeyCallback(GLFWwindow* window, int key, int scancode, int action, int mods);
|
||||
IMGUI_IMPL_API void ImGui_ImplGlfw_CharCallback(GLFWwindow* window, unsigned int c);
|
||||
IMGUI_IMPL_API void ImGui_ImplGlfw_MonitorCallback(GLFWmonitor* monitor, int event);
|
||||
@@ -5,7 +5,6 @@
|
||||
|
||||
// Implemented features:
|
||||
// [X] Renderer: User texture binding. Use 'GLuint' OpenGL texture identifier as void*/ImTextureID. Read the FAQ about ImTextureID!
|
||||
// [X] Renderer: Multi-viewport support. Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
|
||||
// [x] Renderer: Desktop GL only: Support for large meshes (64k+ vertices) with 16-bit indices.
|
||||
|
||||
// You can copy and use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
File diff suppressed because it is too large
Load Diff
@@ -46,6 +46,11 @@
|
||||
|
||||
#include <stdio.h> // sprintf, scanf
|
||||
#include <stdint.h> // uint8_t, etc.
|
||||
#include <hex/helpers/utils.hpp>
|
||||
|
||||
#include <hex/views/view.hpp>
|
||||
|
||||
#include <string>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define _PRISizeT "I"
|
||||
@@ -60,6 +65,8 @@
|
||||
#pragma warning (disable: 4996) // warning C4996: 'sprintf': This function or variable may be unsafe.
|
||||
#endif
|
||||
|
||||
ImU32 ImAlphaBlendColors(ImU32 col_a, ImU32 col_b);
|
||||
|
||||
struct MemoryEditor
|
||||
{
|
||||
enum DataFormat
|
||||
@@ -70,14 +77,19 @@ struct MemoryEditor
|
||||
DataFormat_COUNT
|
||||
};
|
||||
|
||||
struct DecodeData {
|
||||
std::string data;
|
||||
size_t advance;
|
||||
ImColor color;
|
||||
};
|
||||
|
||||
// Settings
|
||||
bool Open; // = true // set to false when DrawWindow() was closed. ignore if not using DrawWindow().
|
||||
bool ReadOnly; // = false // disable any editing.
|
||||
int Cols; // = 16 // number of columns to display.
|
||||
bool OptShowOptions; // = true // display options button/context menu. when disabled, options will be locked unless you provide your own UI for them.
|
||||
bool OptShowDataPreview; // = false // display a footer previewing the decimal/binary/hex/float representation of the currently selected bytes.
|
||||
bool OptShowHexII; // = false // display values in HexII representation instead of regular hexadecimal: hide null/zero bytes, ascii values as ".X".
|
||||
bool OptShowAscii; // = true // display ASCII representation on the right side.
|
||||
bool OptShowAdvancedDecoding; // = true // display advanced decoding data on the right side.
|
||||
bool OptGreyOutZeroes; // = true // display null/zero bytes using the TextDisabled color.
|
||||
bool OptUpperCaseHex; // = true // display hexadecimal values as "FF" instead of "ff".
|
||||
int OptMidColsCount; // = 8 // set to 0 to disable extra spacing between every mid-cols.
|
||||
@@ -86,10 +98,15 @@ struct MemoryEditor
|
||||
ImU8 (*ReadFn)(const ImU8* data, size_t off); // = 0 // optional handler to read bytes.
|
||||
void (*WriteFn)(ImU8* data, size_t off, ImU8 d); // = 0 // optional handler to write bytes.
|
||||
bool (*HighlightFn)(const ImU8* data, size_t off, bool next);//= 0 // optional handler to return Highlight property (to support non-contiguous highlighting).
|
||||
void (*HoverFn)(const ImU8 *data, size_t off);
|
||||
DecodeData (*DecodeFn)(const ImU8 *data, size_t off);
|
||||
|
||||
// [Internal State]
|
||||
bool ContentsWidthChanged;
|
||||
size_t DataPreviewAddr;
|
||||
size_t DataPreviewAddrOld;
|
||||
size_t DataPreviewAddrEnd;
|
||||
size_t DataPreviewAddrEndOld;
|
||||
size_t DataEditingAddr;
|
||||
bool DataEditingTakeFocus;
|
||||
char DataInputBuf[32];
|
||||
@@ -102,13 +119,12 @@ struct MemoryEditor
|
||||
MemoryEditor()
|
||||
{
|
||||
// Settings
|
||||
Open = true;
|
||||
ReadOnly = false;
|
||||
Cols = 16;
|
||||
OptShowOptions = true;
|
||||
OptShowDataPreview = false;
|
||||
OptShowHexII = false;
|
||||
OptShowAscii = true;
|
||||
OptShowAdvancedDecoding = true;
|
||||
OptGreyOutZeroes = true;
|
||||
OptUpperCaseHex = true;
|
||||
OptMidColsCount = 8;
|
||||
@@ -117,10 +133,13 @@ struct MemoryEditor
|
||||
ReadFn = NULL;
|
||||
WriteFn = NULL;
|
||||
HighlightFn = NULL;
|
||||
HoverFn = NULL;
|
||||
DecodeFn = NULL;
|
||||
|
||||
// State/Internals
|
||||
ContentsWidthChanged = false;
|
||||
DataPreviewAddr = DataEditingAddr = (size_t)-1;
|
||||
DataPreviewAddr = DataEditingAddr = DataPreviewAddrEnd = (size_t)-1;
|
||||
DataPreviewAddrOld = DataPreviewAddrEndOld = (size_t)-1;
|
||||
DataEditingTakeFocus = false;
|
||||
memset(DataInputBuf, 0, sizeof(DataInputBuf));
|
||||
memset(AddrInputBuf, 0, sizeof(AddrInputBuf));
|
||||
@@ -148,6 +167,8 @@ struct MemoryEditor
|
||||
float PosHexEnd;
|
||||
float PosAsciiStart;
|
||||
float PosAsciiEnd;
|
||||
float PosDecodingStart;
|
||||
float PosDecodingEnd;
|
||||
float WindowWidth;
|
||||
|
||||
Sizes() { memset(this, 0, sizeof(*this)); }
|
||||
@@ -167,27 +188,47 @@ struct MemoryEditor
|
||||
s.PosHexStart = (s.AddrDigitsCount + 2) * s.GlyphWidth;
|
||||
s.PosHexEnd = s.PosHexStart + (s.HexCellWidth * Cols);
|
||||
s.PosAsciiStart = s.PosAsciiEnd = s.PosHexEnd;
|
||||
if (OptShowAscii)
|
||||
{
|
||||
|
||||
if (OptShowAscii && OptShowAdvancedDecoding) {
|
||||
s.PosAsciiStart = s.PosHexEnd + s.GlyphWidth * 1;
|
||||
if (OptMidColsCount > 0)
|
||||
s.PosAsciiStart += (float)((Cols + OptMidColsCount - 1) / OptMidColsCount) * s.SpacingBetweenMidCols;
|
||||
s.PosAsciiEnd = s.PosAsciiStart + Cols * s.GlyphWidth;
|
||||
|
||||
s.PosDecodingStart = s.PosAsciiEnd + s.GlyphWidth * 1;
|
||||
if (OptMidColsCount > 0)
|
||||
s.PosDecodingStart += (float)((Cols + OptMidColsCount - 1) / OptMidColsCount) * s.SpacingBetweenMidCols;
|
||||
s.PosDecodingEnd = s.PosDecodingStart + Cols * s.GlyphWidth;
|
||||
} else if (OptShowAscii) {
|
||||
s.PosAsciiStart = s.PosHexEnd + s.GlyphWidth * 1;
|
||||
if (OptMidColsCount > 0)
|
||||
s.PosAsciiStart += (float)((Cols + OptMidColsCount - 1) / OptMidColsCount) * s.SpacingBetweenMidCols;
|
||||
s.PosAsciiEnd = s.PosAsciiStart + Cols * s.GlyphWidth;
|
||||
} else if (OptShowAdvancedDecoding) {
|
||||
s.PosDecodingStart = s.PosHexEnd + s.GlyphWidth * 1;
|
||||
if (OptMidColsCount > 0)
|
||||
s.PosDecodingStart += (float)((Cols + OptMidColsCount - 1) / OptMidColsCount) * s.SpacingBetweenMidCols;
|
||||
s.PosDecodingEnd = s.PosDecodingStart + Cols * s.GlyphWidth;
|
||||
}
|
||||
s.WindowWidth = s.PosAsciiEnd + style.ScrollbarSize + style.WindowPadding.x * 2 + s.GlyphWidth;
|
||||
}
|
||||
|
||||
// Standalone Memory Editor window
|
||||
void DrawWindow(const char* title, void* mem_data, size_t mem_size, size_t base_display_addr = 0x0000)
|
||||
void DrawWindow(const char* title, bool *p_open, void* mem_data, size_t mem_size, size_t base_display_addr = 0x0000)
|
||||
{
|
||||
Sizes s;
|
||||
CalcSizes(s, mem_size, base_display_addr);
|
||||
ImGui::SetNextWindowSizeConstraints(ImVec2(0.0f, 0.0f), ImVec2(s.WindowWidth, FLT_MAX));
|
||||
|
||||
if (ImGui::Begin(title, &Open, ImGuiWindowFlags_NoScrollbar))
|
||||
if (ImGui::Begin(title, p_open, ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoNavInputs))
|
||||
{
|
||||
if (ImGui::IsWindowHovered(ImGuiHoveredFlags_RootAndChildWindows) && ImGui::IsMouseReleased(ImGuiMouseButton_Right))
|
||||
ImGui::OpenPopup("context");
|
||||
if (DataPreviewAddr != DataPreviewAddrOld || DataPreviewAddrEnd != DataPreviewAddrEndOld) {
|
||||
hex::Region selectionRegion = { std::min(DataPreviewAddr, DataPreviewAddrEnd), std::max(DataPreviewAddr, DataPreviewAddrEnd) - std::min(DataPreviewAddr, DataPreviewAddrEnd) };
|
||||
hex::View::postEvent(hex::Events::RegionSelected, selectionRegion);
|
||||
}
|
||||
|
||||
DataPreviewAddrOld = DataPreviewAddr;
|
||||
DataPreviewAddrEndOld = DataPreviewAddrEnd;
|
||||
|
||||
DrawContents(mem_data, mem_size, base_display_addr);
|
||||
if (ContentsWidthChanged)
|
||||
{
|
||||
@@ -209,16 +250,6 @@ struct MemoryEditor
|
||||
Sizes s;
|
||||
CalcSizes(s, mem_size, base_display_addr);
|
||||
ImGuiStyle& style = ImGui::GetStyle();
|
||||
ImDrawList* draw_list = ImGui::GetWindowDrawList();
|
||||
|
||||
if (mem_size == 0x00) {
|
||||
constexpr const char *noDataString = "No data loaded!";
|
||||
|
||||
auto pos = ImGui::GetCursorScreenPos();
|
||||
pos.x += (ImGui::GetWindowWidth() - (ImGui::CalcTextSize(noDataString).x)) / 2;
|
||||
draw_list->AddText(pos, 0xFFFFFFFF, noDataString);
|
||||
return;
|
||||
}
|
||||
|
||||
// We begin into our scrolling region with the 'ImGuiWindowFlags_NoMove' in order to prevent click from moving the window.
|
||||
// This is used as a facility since our main click detection code doesn't assign an ActiveId so the click would normally be caught as a window-move.
|
||||
@@ -226,8 +257,18 @@ struct MemoryEditor
|
||||
float footer_height = 0;
|
||||
if (OptShowOptions)
|
||||
footer_height += height_separator + ImGui::GetFrameHeightWithSpacing() * 1;
|
||||
if (OptShowDataPreview)
|
||||
footer_height += height_separator + ImGui::GetFrameHeightWithSpacing() * 1 + ImGui::GetTextLineHeightWithSpacing() * 3;
|
||||
|
||||
ImGui::BeginChild("offset", ImVec2(0, s.LineHeight), false, ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoNav);
|
||||
ImGui::Text("%*c ", s.AddrDigitsCount, ' ');
|
||||
for (int i = 0; i < Cols; i++) {
|
||||
float byte_pos_x = s.PosHexStart + s.HexCellWidth * i;
|
||||
if (OptMidColsCount > 0)
|
||||
byte_pos_x += (float)(i / OptMidColsCount) * s.SpacingBetweenMidCols;
|
||||
ImGui::SameLine(byte_pos_x);
|
||||
ImGui::Text("%02X", i);
|
||||
}
|
||||
ImGui::EndChild();
|
||||
|
||||
ImGui::BeginChild("##scrolling", ImVec2(0, -footer_height), false, ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoNav);
|
||||
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0, 0));
|
||||
@@ -236,31 +277,62 @@ struct MemoryEditor
|
||||
|
||||
|
||||
// We are not really using the clipper API correctly here, because we rely on visible_start_addr/visible_end_addr for our scrolling function.
|
||||
const int line_total_count = (int)((mem_size + Cols - 1) / Cols);
|
||||
ImGuiListClipper clipper;
|
||||
ImDrawList* draw_list = ImGui::GetWindowDrawList();
|
||||
|
||||
const int line_total_count = (int)((mem_size + Cols - 1) / Cols);
|
||||
clipper.Begin(line_total_count, s.LineHeight);
|
||||
clipper.Step();
|
||||
const size_t visible_start_addr = clipper.DisplayStart * Cols;
|
||||
const size_t visible_end_addr = clipper.DisplayEnd * Cols;
|
||||
const size_t visible_count = visible_end_addr - visible_start_addr;
|
||||
|
||||
bool data_next = false;
|
||||
|
||||
if (ReadOnly || DataEditingAddr >= mem_size)
|
||||
if (DataEditingAddr >= mem_size)
|
||||
DataEditingAddr = (size_t)-1;
|
||||
if (DataPreviewAddr >= mem_size)
|
||||
DataPreviewAddr = (size_t)-1;
|
||||
|
||||
size_t preview_data_type_size = OptShowDataPreview ? DataTypeGetSize(PreviewDataType) : 0;
|
||||
if (DataPreviewAddrEnd >= mem_size)
|
||||
DataPreviewAddrEnd = (size_t)-1;
|
||||
|
||||
size_t data_editing_addr_backup = DataEditingAddr;
|
||||
size_t data_preview_addr_backup = DataPreviewAddr;
|
||||
size_t data_editing_addr_next = (size_t)-1;
|
||||
if (DataEditingAddr != (size_t)-1)
|
||||
size_t data_preview_addr_next = (size_t)-1;
|
||||
|
||||
if (ImGui::IsWindowFocused()) {
|
||||
if (DataEditingAddr != (size_t)-1)
|
||||
{
|
||||
// Move cursor but only apply on next frame so scrolling with be synchronized (because currently we can't change the scrolling while the window is being rendered)
|
||||
if (ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_UpArrow)) && DataEditingAddr >= (size_t)Cols) { data_editing_addr_next = DataEditingAddr - Cols; DataEditingTakeFocus = true; }
|
||||
else if (ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_DownArrow)) && DataEditingAddr < mem_size - Cols) { data_editing_addr_next = DataEditingAddr + Cols; DataEditingTakeFocus = true; }
|
||||
else if (ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_LeftArrow)) && DataEditingAddr > 0) { data_editing_addr_next = DataEditingAddr - 1; DataEditingTakeFocus = true; }
|
||||
else if (ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_RightArrow)) && DataEditingAddr < mem_size - 1) { data_editing_addr_next = DataEditingAddr + 1; DataEditingTakeFocus = true; }
|
||||
else if (ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_PageUp)) && DataEditingAddr > 0) { data_editing_addr_next = std::max(s64(0), s64(DataEditingAddr) - s64(visible_count)); DataEditingTakeFocus = true; }
|
||||
else if (ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_PageDown)) && DataEditingAddr < mem_size - 1) { data_editing_addr_next = std::min(s64(mem_size - 1), s64(DataEditingAddr) + s64(visible_count)); DataEditingTakeFocus = true; }
|
||||
else if (ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_Home)) && DataEditingAddr > 0) { data_editing_addr_next = 0; DataEditingTakeFocus = true; }
|
||||
else if (ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_End)) && DataEditingAddr < mem_size - 1) { data_editing_addr_next = mem_size - 1; DataEditingTakeFocus = true; }
|
||||
} else if (DataPreviewAddr != -1) {
|
||||
// Move cursor but only apply on next frame so scrolling with be synchronized (because currently we can't change the scrolling while the window is being rendered)
|
||||
if (ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_UpArrow)) && DataPreviewAddr >= (size_t)Cols) { DataPreviewAddr = data_preview_addr_next = DataPreviewAddr - Cols; if (!ImGui::GetIO().KeyShift) DataPreviewAddrEnd = DataPreviewAddr; }
|
||||
else if (ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_DownArrow)) && DataPreviewAddr < mem_size - Cols) { DataPreviewAddr = data_preview_addr_next = DataPreviewAddr + Cols; if (!ImGui::GetIO().KeyShift) DataPreviewAddrEnd = DataPreviewAddr; }
|
||||
else if (ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_LeftArrow)) && DataPreviewAddr > 0) { DataPreviewAddr = data_preview_addr_next = DataPreviewAddr - 1; if (!ImGui::GetIO().KeyShift) DataPreviewAddrEnd = DataPreviewAddr; }
|
||||
else if (ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_RightArrow)) && DataPreviewAddr < mem_size - 1) { DataPreviewAddr = data_preview_addr_next = DataPreviewAddr + 1; if (!ImGui::GetIO().KeyShift) DataPreviewAddrEnd = DataPreviewAddr; }
|
||||
else if (ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_PageUp)) && DataPreviewAddr > 0) { DataPreviewAddr = data_preview_addr_next = std::max(s64(0), s64(DataPreviewAddr) - s64(visible_count)); if (!ImGui::GetIO().KeyShift) DataPreviewAddrEnd = DataPreviewAddr; }
|
||||
else if (ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_PageDown)) && DataPreviewAddr < mem_size - 1) { DataPreviewAddr = data_preview_addr_next = std::min(s64(mem_size - 1), s64(DataPreviewAddr) + s64(visible_count)); if (!ImGui::GetIO().KeyShift) DataPreviewAddrEnd = DataPreviewAddr; }
|
||||
else if (ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_Home)) && DataPreviewAddr > 0) { DataPreviewAddr = data_preview_addr_next = 0; if (!ImGui::GetIO().KeyShift) DataPreviewAddrEnd = DataPreviewAddr; }
|
||||
else if (ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_End)) && DataPreviewAddr < mem_size - 1) { DataPreviewAddr = data_preview_addr_next = mem_size - 1; if (!ImGui::GetIO().KeyShift) DataPreviewAddrEnd = DataPreviewAddr; }
|
||||
}
|
||||
}
|
||||
|
||||
if (data_preview_addr_next != (size_t)-1 && (data_preview_addr_next / Cols) != (data_preview_addr_backup / Cols))
|
||||
{
|
||||
// Move cursor but only apply on next frame so scrolling with be synchronized (because currently we can't change the scrolling while the window is being rendered)
|
||||
if (ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_UpArrow)) && DataEditingAddr >= (size_t)Cols) { data_editing_addr_next = DataEditingAddr - Cols; DataEditingTakeFocus = true; }
|
||||
else if (ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_DownArrow)) && DataEditingAddr < mem_size - Cols) { data_editing_addr_next = DataEditingAddr + Cols; DataEditingTakeFocus = true; }
|
||||
else if (ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_LeftArrow)) && DataEditingAddr > 0) { data_editing_addr_next = DataEditingAddr - 1; DataEditingTakeFocus = true; }
|
||||
else if (ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_RightArrow)) && DataEditingAddr < mem_size - 1) { data_editing_addr_next = DataEditingAddr + 1; DataEditingTakeFocus = true; }
|
||||
// Track cursor movements
|
||||
const int scroll_offset = ((int)(data_preview_addr_next / Cols) - (int)(data_preview_addr_backup / Cols));
|
||||
const bool scroll_desired = (scroll_offset < 0 && data_preview_addr_next < visible_start_addr + Cols * 2) || (scroll_offset > 0 && data_preview_addr_next > visible_end_addr - Cols * 2);
|
||||
if (scroll_desired)
|
||||
ImGui::SetScrollY(ImGui::GetScrollY() + scroll_offset * s.LineHeight);
|
||||
}
|
||||
if (data_editing_addr_next != (size_t)-1 && (data_editing_addr_next / Cols) != (data_editing_addr_backup / Cols))
|
||||
{
|
||||
@@ -275,6 +347,8 @@ struct MemoryEditor
|
||||
ImVec2 window_pos = ImGui::GetWindowPos();
|
||||
if (OptShowAscii)
|
||||
draw_list->AddLine(ImVec2(window_pos.x + s.PosAsciiStart - s.GlyphWidth, window_pos.y), ImVec2(window_pos.x + s.PosAsciiStart - s.GlyphWidth, window_pos.y + 9999), ImGui::GetColorU32(ImGuiCol_Border));
|
||||
if (OptShowAdvancedDecoding)
|
||||
draw_list->AddLine(ImVec2(window_pos.x + s.PosDecodingStart - s.GlyphWidth, window_pos.y), ImVec2(window_pos.x + s.PosDecodingStart - s.GlyphWidth, window_pos.y + 9999), ImGui::GetColorU32(ImGuiCol_Border));
|
||||
|
||||
const ImU32 color_text = ImGui::GetColorU32(ImGuiCol_Text);
|
||||
const ImU32 color_disabled = OptGreyOutZeroes ? ImGui::GetColorU32(ImGuiCol_TextDisabled) : color_text;
|
||||
@@ -284,6 +358,7 @@ struct MemoryEditor
|
||||
const char* format_byte = OptUpperCaseHex ? "%02X" : "%02x";
|
||||
const char* format_byte_space = OptUpperCaseHex ? "%02X " : "%02x ";
|
||||
|
||||
bool tooltipShown = false;
|
||||
for (int line_i = clipper.DisplayStart; line_i < clipper.DisplayEnd; line_i++) // display only visible lines
|
||||
{
|
||||
size_t addr = (size_t)(line_i * Cols);
|
||||
@@ -300,19 +375,27 @@ struct MemoryEditor
|
||||
// Draw highlight
|
||||
bool is_highlight_from_user_range = (addr >= HighlightMin && addr < HighlightMax);
|
||||
bool is_highlight_from_user_func = (HighlightFn && HighlightFn(mem_data, addr, false));
|
||||
bool is_highlight_from_preview = (addr >= DataPreviewAddr && addr < DataPreviewAddr + preview_data_type_size);
|
||||
bool is_highlight_from_preview = (addr >= DataPreviewAddr && addr <= DataPreviewAddrEnd) || (addr >= DataPreviewAddrEnd && addr <= DataPreviewAddr);
|
||||
if (is_highlight_from_user_range || is_highlight_from_user_func || is_highlight_from_preview)
|
||||
{
|
||||
ImVec2 pos = ImGui::GetCursorScreenPos();
|
||||
float highlight_width = s.GlyphWidth * 2;
|
||||
bool is_next_byte_highlighted = (addr + 1 < mem_size) && ((HighlightMax != (size_t)-1 && addr + 1 < HighlightMax) || (HighlightFn && HighlightFn(mem_data, addr + 1, true)));
|
||||
if (is_next_byte_highlighted || (n + 1 == Cols))
|
||||
bool is_next_byte_highlighted = (addr + 1 < mem_size) &&
|
||||
((HighlightMax != (size_t)-1 && addr + 1 < HighlightMax) ||
|
||||
(HighlightFn && HighlightFn(mem_data, addr + 1, true)) ||
|
||||
((addr + 1) >= DataPreviewAddr && (addr + 1) <= DataPreviewAddrEnd) || ((addr + 1) >= DataPreviewAddrEnd && (addr + 1) <= DataPreviewAddr));
|
||||
if (is_next_byte_highlighted)
|
||||
{
|
||||
highlight_width = s.HexCellWidth;
|
||||
if (OptMidColsCount > 0 && n > 0 && (n + 1) < Cols && ((n + 1) % OptMidColsCount) == 0)
|
||||
highlight_width += s.SpacingBetweenMidCols;
|
||||
}
|
||||
draw_list->AddRectFilled(pos, ImVec2(pos.x + highlight_width, pos.y + s.LineHeight), HighlightColor);
|
||||
|
||||
ImU32 color = HighlightColor;
|
||||
if ((is_highlight_from_user_range + is_highlight_from_user_func + is_highlight_from_preview) > 1)
|
||||
color = (ImAlphaBlendColors(HighlightColor, 0x60C08080) & 0x00FFFFFF) | 0x90000000;
|
||||
|
||||
draw_list->AddRectFilled(pos, ImVec2(pos.x + highlight_width, pos.y + s.LineHeight), color);
|
||||
}
|
||||
|
||||
if (DataEditingAddr == addr)
|
||||
@@ -397,10 +480,24 @@ struct MemoryEditor
|
||||
else
|
||||
ImGui::Text(format_byte_space, b);
|
||||
}
|
||||
if (!ReadOnly && ImGui::IsItemHovered() && ImGui::IsMouseClicked(0))
|
||||
if (ImGui::IsItemHovered() && ImGui::IsMouseClicked(0) && !ImGui::GetIO().KeyShift)
|
||||
{
|
||||
DataEditingTakeFocus = true;
|
||||
data_editing_addr_next = addr;
|
||||
if (!ReadOnly && ImGui::IsMouseDoubleClicked(0)) {
|
||||
DataEditingTakeFocus = true;
|
||||
data_editing_addr_next = addr;
|
||||
}
|
||||
|
||||
DataPreviewAddr = addr;
|
||||
DataPreviewAddrEnd = addr;
|
||||
}
|
||||
if (ImGui::IsItemHovered() && ((ImGui::IsMouseClicked(0) && ImGui::GetIO().KeyShift) || ImGui::IsMouseDragging(0))) {
|
||||
DataPreviewAddrEnd = addr;
|
||||
}
|
||||
if (ImGui::IsItemHovered() && !tooltipShown) {
|
||||
if (HoverFn) {
|
||||
HoverFn(mem_data, addr);
|
||||
tooltipShown = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -411,13 +508,13 @@ struct MemoryEditor
|
||||
ImGui::SameLine(s.PosAsciiStart);
|
||||
ImVec2 pos = ImGui::GetCursorScreenPos();
|
||||
addr = line_i * Cols;
|
||||
ImGui::PushID(line_i);
|
||||
if (ImGui::InvisibleButton("ascii", ImVec2(s.PosAsciiEnd - s.PosAsciiStart, s.LineHeight)))
|
||||
{
|
||||
DataEditingAddr = DataPreviewAddr = addr + (size_t)((ImGui::GetIO().MousePos.x - pos.x) / s.GlyphWidth);
|
||||
DataEditingTakeFocus = true;
|
||||
}
|
||||
|
||||
ImGui::PushID(-1);
|
||||
ImGui::SameLine();
|
||||
ImGui::Dummy(ImVec2(s.GlyphWidth, s.LineHeight));
|
||||
|
||||
ImGui::PopID();
|
||||
|
||||
for (int n = 0; n < Cols && addr < mem_size; n++, addr++)
|
||||
{
|
||||
if (addr == DataEditingAddr)
|
||||
@@ -428,8 +525,124 @@ struct MemoryEditor
|
||||
unsigned char c = ReadFn ? ReadFn(mem_data, addr) : mem_data[addr];
|
||||
char display_c = (c < 32 || c >= 128) ? '.' : c;
|
||||
draw_list->AddText(pos, (display_c == c) ? color_text : color_disabled, &display_c, &display_c + 1);
|
||||
|
||||
// Draw highlight
|
||||
bool is_highlight_from_user_range = (addr >= HighlightMin && addr < HighlightMax);
|
||||
bool is_highlight_from_user_func = (HighlightFn && HighlightFn(mem_data, addr, false));
|
||||
bool is_highlight_from_preview = (addr >= DataPreviewAddr && addr <= DataPreviewAddrEnd) || (addr >= DataPreviewAddrEnd && addr <= DataPreviewAddr);
|
||||
if (is_highlight_from_user_range || is_highlight_from_user_func || is_highlight_from_preview)
|
||||
{
|
||||
ImU32 color = HighlightColor;
|
||||
if ((is_highlight_from_user_range + is_highlight_from_user_func + is_highlight_from_preview) > 1)
|
||||
color = (ImAlphaBlendColors(HighlightColor, 0x60C08080) & 0x00FFFFFF) | 0x90000000;
|
||||
|
||||
draw_list->AddRectFilled(pos, ImVec2(pos.x + s.GlyphWidth, pos.y + s.LineHeight), color);
|
||||
}
|
||||
|
||||
|
||||
ImGui::PushID(line_i * Cols + n);
|
||||
ImGui::SameLine();
|
||||
ImGui::Dummy(ImVec2(s.GlyphWidth, s.LineHeight));
|
||||
|
||||
ImGui::PopID();
|
||||
|
||||
if (ImGui::IsItemHovered() && ImGui::IsMouseClicked(0) && !ImGui::GetIO().KeyShift)
|
||||
{
|
||||
if (!ReadOnly && ImGui::IsMouseDoubleClicked(0)) {
|
||||
DataEditingTakeFocus = true;
|
||||
data_editing_addr_next = addr;
|
||||
}
|
||||
|
||||
DataPreviewAddr = addr;
|
||||
DataPreviewAddrEnd = addr;
|
||||
|
||||
}
|
||||
if (ImGui::IsItemHovered() && ((ImGui::IsMouseClicked(0) && ImGui::GetIO().KeyShift) || ImGui::IsMouseDragging(0))) {
|
||||
DataPreviewAddrEnd = addr;
|
||||
}
|
||||
|
||||
pos.x += s.GlyphWidth;
|
||||
}
|
||||
|
||||
ImGui::PushID(-1);
|
||||
ImGui::SameLine();
|
||||
ImGui::Dummy(ImVec2(s.GlyphWidth, s.LineHeight));
|
||||
|
||||
ImGui::PopID();
|
||||
}
|
||||
|
||||
if (OptShowAdvancedDecoding && DecodeFn) {
|
||||
// Draw decoded bytes
|
||||
ImGui::SameLine(s.PosDecodingStart);
|
||||
ImVec2 pos = ImGui::GetCursorScreenPos();
|
||||
addr = line_i * Cols;
|
||||
|
||||
ImGui::PushID(-1);
|
||||
ImGui::SameLine();
|
||||
ImGui::Dummy(ImVec2(s.GlyphWidth, s.LineHeight));
|
||||
|
||||
ImGui::PopID();
|
||||
|
||||
for (int n = 0; n < Cols && addr < mem_size;)
|
||||
{
|
||||
auto decodedData = DecodeFn(mem_data, addr);
|
||||
|
||||
auto displayData = decodedData.data;
|
||||
auto glyphWidth = ImGui::CalcTextSize(displayData.c_str()).x + 1;
|
||||
|
||||
if (addr == DataEditingAddr)
|
||||
{
|
||||
draw_list->AddRectFilled(pos, ImVec2(pos.x + glyphWidth, pos.y + s.LineHeight), ImGui::GetColorU32(ImGuiCol_FrameBg));
|
||||
draw_list->AddRectFilled(pos, ImVec2(pos.x + glyphWidth, pos.y + s.LineHeight), ImGui::GetColorU32(ImGuiCol_TextSelectedBg));
|
||||
}
|
||||
|
||||
draw_list->AddText(pos, decodedData.color, displayData.c_str(), displayData.c_str() + displayData.length());
|
||||
|
||||
// Draw highlight
|
||||
bool is_highlight_from_user_range = (addr >= HighlightMin && addr < HighlightMax);
|
||||
bool is_highlight_from_user_func = (HighlightFn && HighlightFn(mem_data, addr, false));
|
||||
bool is_highlight_from_preview = (addr >= DataPreviewAddr && addr <= DataPreviewAddrEnd) || (addr >= DataPreviewAddrEnd && addr <= DataPreviewAddr);
|
||||
if (is_highlight_from_user_range || is_highlight_from_user_func || is_highlight_from_preview)
|
||||
{
|
||||
ImU32 color = HighlightColor;
|
||||
if ((is_highlight_from_user_range + is_highlight_from_user_func + is_highlight_from_preview) > 1)
|
||||
color = (ImAlphaBlendColors(HighlightColor, 0x60C08080) & 0x00FFFFFF) | 0x90000000;
|
||||
|
||||
draw_list->AddRectFilled(pos, ImVec2(pos.x + glyphWidth, pos.y + s.LineHeight), color);
|
||||
}
|
||||
|
||||
|
||||
ImGui::PushID(line_i * Cols + n);
|
||||
ImGui::SameLine();
|
||||
ImGui::Dummy(ImVec2(glyphWidth, s.LineHeight));
|
||||
|
||||
ImGui::PopID();
|
||||
|
||||
if (ImGui::IsItemHovered() && ImGui::IsMouseClicked(0) && !ImGui::GetIO().KeyShift)
|
||||
{
|
||||
if (!ReadOnly && ImGui::IsMouseDoubleClicked(0)) {
|
||||
DataEditingTakeFocus = true;
|
||||
data_editing_addr_next = addr;
|
||||
}
|
||||
|
||||
DataPreviewAddr = addr;
|
||||
DataPreviewAddrEnd = addr;
|
||||
|
||||
}
|
||||
if (ImGui::IsItemHovered() && ((ImGui::IsMouseClicked(0) && ImGui::GetIO().KeyShift) || ImGui::IsMouseDragging(0))) {
|
||||
DataPreviewAddrEnd = addr;
|
||||
}
|
||||
|
||||
pos.x += glyphWidth;
|
||||
|
||||
if (addr <= 1) {
|
||||
n++;
|
||||
addr++;
|
||||
} else {
|
||||
n += decodedData.advance;
|
||||
addr += decodedData.advance;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
IM_ASSERT(clipper.Step() == false);
|
||||
@@ -444,22 +657,15 @@ struct MemoryEditor
|
||||
}
|
||||
else if (data_editing_addr_next != (size_t)-1)
|
||||
{
|
||||
DataEditingAddr = DataPreviewAddr = data_editing_addr_next;
|
||||
DataEditingAddr = DataPreviewAddr = DataPreviewAddrEnd = data_editing_addr_next;
|
||||
}
|
||||
|
||||
const bool lock_show_data_preview = OptShowDataPreview;
|
||||
if (OptShowOptions)
|
||||
{
|
||||
ImGui::Separator();
|
||||
DrawOptionsLine(s, mem_data, mem_size, base_display_addr);
|
||||
}
|
||||
|
||||
if (lock_show_data_preview)
|
||||
{
|
||||
ImGui::Separator();
|
||||
DrawPreviewLine(s, mem_data, mem_size, base_display_addr);
|
||||
}
|
||||
|
||||
// Notify the main window of our ideal child content size (FIXME: we are missing an API to get the contents size from the child)
|
||||
ImGui::SetCursorPosX(s.WindowWidth);
|
||||
}
|
||||
@@ -469,18 +675,19 @@ struct MemoryEditor
|
||||
IM_UNUSED(mem_data);
|
||||
ImGuiStyle& style = ImGui::GetStyle();
|
||||
const char* format_range = OptUpperCaseHex ? "Range %0*" _PRISizeT "X..%0*" _PRISizeT "X" : "Range %0*" _PRISizeT "x..%0*" _PRISizeT "x";
|
||||
const char* format_selection = OptUpperCaseHex ? "Selection %0*" _PRISizeT "X..%0*" _PRISizeT "X (%ld %s)" : "Range %0*" _PRISizeT "x..%0*" _PRISizeT "x (%ld %s)";
|
||||
|
||||
// Options menu
|
||||
if (ImGui::Button("Options"))
|
||||
ImGui::OpenPopup("context");
|
||||
if (ImGui::BeginPopup("context"))
|
||||
{
|
||||
ImGui::PushItemWidth(56);
|
||||
ImGui::OpenPopup("options");
|
||||
|
||||
if (ImGui::BeginPopup("options")) {
|
||||
ImGui::PushItemWidth(ImGui::CalcTextSize("00 cols").x * 1.1f);
|
||||
if (ImGui::DragInt("##cols", &Cols, 0.2f, 4, 32, "%d cols")) { ContentsWidthChanged = true; if (Cols < 1) Cols = 1; }
|
||||
ImGui::PopItemWidth();
|
||||
ImGui::Checkbox("Show Data Preview", &OptShowDataPreview);
|
||||
ImGui::Checkbox("Show HexII", &OptShowHexII);
|
||||
if (ImGui::Checkbox("Show Ascii", &OptShowAscii)) { ContentsWidthChanged = true; }
|
||||
if (ImGui::Checkbox("Show Advanced Decoding", &OptShowAdvancedDecoding)) { ContentsWidthChanged = true; }
|
||||
ImGui::Checkbox("Grey out zeroes", &OptGreyOutZeroes);
|
||||
ImGui::Checkbox("Uppercase Hex", &OptUpperCaseHex);
|
||||
|
||||
@@ -489,18 +696,17 @@ struct MemoryEditor
|
||||
|
||||
ImGui::SameLine();
|
||||
ImGui::Text(format_range, s.AddrDigitsCount, base_display_addr, s.AddrDigitsCount, base_display_addr + mem_size - 1);
|
||||
ImGui::SameLine();
|
||||
ImGui::PushItemWidth((s.AddrDigitsCount + 1) * s.GlyphWidth + style.FramePadding.x * 2.0f);
|
||||
if (ImGui::InputText("##addr", AddrInputBuf, 32, ImGuiInputTextFlags_CharsHexadecimal | ImGuiInputTextFlags_EnterReturnsTrue))
|
||||
{
|
||||
size_t goto_addr;
|
||||
if (sscanf(AddrInputBuf, "%" _PRISizeT "X", &goto_addr) == 1)
|
||||
{
|
||||
GotoAddr = goto_addr - base_display_addr;
|
||||
HighlightMin = HighlightMax = (size_t)-1;
|
||||
}
|
||||
if (DataPreviewAddr != (size_t)-1 && DataPreviewAddrEnd != (size_t)-1) {
|
||||
ImGui::SameLine();
|
||||
ImGui::Spacing();
|
||||
ImGui::SameLine();
|
||||
|
||||
auto selectionStart = std::min(DataPreviewAddr, DataPreviewAddrEnd);
|
||||
auto selectionEnd = std::max(DataPreviewAddr, DataPreviewAddrEnd);
|
||||
|
||||
size_t regionSize = (selectionEnd - selectionStart) + 1;
|
||||
ImGui::Text(format_selection, s.AddrDigitsCount, base_display_addr + selectionStart, s.AddrDigitsCount, base_display_addr + selectionEnd, regionSize, regionSize == 1 ? "byte" : "bytes");
|
||||
}
|
||||
ImGui::PopItemWidth();
|
||||
|
||||
if (GotoAddr != (size_t)-1)
|
||||
{
|
||||
@@ -509,73 +715,14 @@ struct MemoryEditor
|
||||
ImGui::BeginChild("##scrolling");
|
||||
ImGui::SetScrollFromPosY(ImGui::GetCursorStartPos().y + (GotoAddr / Cols) * ImGui::GetTextLineHeight());
|
||||
ImGui::EndChild();
|
||||
DataEditingAddr = DataPreviewAddr = GotoAddr;
|
||||
DataEditingAddr = DataPreviewAddr = DataPreviewAddrEnd = GotoAddr;
|
||||
DataEditingTakeFocus = true;
|
||||
}
|
||||
GotoAddr = (size_t)-1;
|
||||
}
|
||||
}
|
||||
|
||||
void DrawPreviewLine(const Sizes& s, void* mem_data_void, size_t mem_size, size_t base_display_addr)
|
||||
{
|
||||
IM_UNUSED(base_display_addr);
|
||||
ImU8* mem_data = (ImU8*)mem_data_void;
|
||||
ImGuiStyle& style = ImGui::GetStyle();
|
||||
ImGui::AlignTextToFramePadding();
|
||||
ImGui::Text("Preview as:");
|
||||
ImGui::SameLine();
|
||||
ImGui::PushItemWidth((s.GlyphWidth * 10.0f) + style.FramePadding.x * 2.0f + style.ItemInnerSpacing.x);
|
||||
if (ImGui::BeginCombo("##combo_type", DataTypeGetDesc(PreviewDataType), ImGuiComboFlags_HeightLargest))
|
||||
{
|
||||
for (int n = 0; n < ImGuiDataType_COUNT; n++)
|
||||
if (ImGui::Selectable(DataTypeGetDesc((ImGuiDataType)n), PreviewDataType == n))
|
||||
PreviewDataType = (ImGuiDataType)n;
|
||||
ImGui::EndCombo();
|
||||
}
|
||||
ImGui::PopItemWidth();
|
||||
ImGui::SameLine();
|
||||
ImGui::PushItemWidth((s.GlyphWidth * 6.0f) + style.FramePadding.x * 2.0f + style.ItemInnerSpacing.x);
|
||||
ImGui::Combo("##combo_endianess", &PreviewEndianess, "LE\0BE\0\0");
|
||||
ImGui::PopItemWidth();
|
||||
|
||||
char buf[128] = "";
|
||||
float x = s.GlyphWidth * 6.0f;
|
||||
bool has_value = DataPreviewAddr != (size_t)-1;
|
||||
if (has_value)
|
||||
DrawPreviewData(DataPreviewAddr, mem_data, mem_size, PreviewDataType, DataFormat_Dec, buf, (size_t)IM_ARRAYSIZE(buf));
|
||||
ImGui::Text("Dec"); ImGui::SameLine(x); ImGui::TextUnformatted(has_value ? buf : "N/A");
|
||||
if (has_value)
|
||||
DrawPreviewData(DataPreviewAddr, mem_data, mem_size, PreviewDataType, DataFormat_Hex, buf, (size_t)IM_ARRAYSIZE(buf));
|
||||
ImGui::Text("Hex"); ImGui::SameLine(x); ImGui::TextUnformatted(has_value ? buf : "N/A");
|
||||
if (has_value)
|
||||
DrawPreviewData(DataPreviewAddr, mem_data, mem_size, PreviewDataType, DataFormat_Bin, buf, (size_t)IM_ARRAYSIZE(buf));
|
||||
buf[IM_ARRAYSIZE(buf) - 1] = 0;
|
||||
ImGui::Text("Bin"); ImGui::SameLine(x); ImGui::TextUnformatted(has_value ? buf : "N/A");
|
||||
}
|
||||
|
||||
// Utilities for Data Preview
|
||||
const char* DataTypeGetDesc(ImGuiDataType data_type) const
|
||||
{
|
||||
const char* descs[] = { "Int8", "Uint8", "Int16", "Uint16", "Int32", "Uint32", "Int64", "Uint64", "Float", "Double" };
|
||||
IM_ASSERT(data_type >= 0 && data_type < ImGuiDataType_COUNT);
|
||||
return descs[data_type];
|
||||
}
|
||||
|
||||
size_t DataTypeGetSize(ImGuiDataType data_type) const
|
||||
{
|
||||
const size_t sizes[] = { 1, 1, 2, 2, 4, 4, 8, 8, sizeof(float), sizeof(double) };
|
||||
IM_ASSERT(data_type >= 0 && data_type < ImGuiDataType_COUNT);
|
||||
return sizes[data_type];
|
||||
}
|
||||
|
||||
const char* DataFormatGetDesc(DataFormat data_format) const
|
||||
{
|
||||
const char* descs[] = { "Bin", "Dec", "Hex" };
|
||||
IM_ASSERT(data_format >= 0 && data_format < DataFormat_COUNT);
|
||||
return descs[data_format];
|
||||
}
|
||||
|
||||
bool IsBigEndian() const
|
||||
static bool IsBigEndian()
|
||||
{
|
||||
uint16_t x = 1;
|
||||
char c[2];
|
||||
@@ -622,132 +769,6 @@ struct MemoryEditor
|
||||
fp = IsBigEndian() ? EndianessCopyBigEndian : EndianessCopyLittleEndian;
|
||||
return fp(dst, src, size, PreviewEndianess);
|
||||
}
|
||||
|
||||
const char* FormatBinary(const uint8_t* buf, int width) const
|
||||
{
|
||||
IM_ASSERT(width <= 64);
|
||||
size_t out_n = 0;
|
||||
static char out_buf[64 + 8 + 1];
|
||||
int n = width / 8;
|
||||
for (int j = n - 1; j >= 0; --j)
|
||||
{
|
||||
for (int i = 0; i < 8; ++i)
|
||||
out_buf[out_n++] = (buf[j] & (1 << (7 - i))) ? '1' : '0';
|
||||
out_buf[out_n++] = ' ';
|
||||
}
|
||||
IM_ASSERT(out_n < IM_ARRAYSIZE(out_buf));
|
||||
out_buf[out_n] = 0;
|
||||
return out_buf;
|
||||
}
|
||||
|
||||
// [Internal]
|
||||
void DrawPreviewData(size_t addr, const ImU8* mem_data, size_t mem_size, ImGuiDataType data_type, DataFormat data_format, char* out_buf, size_t out_buf_size) const
|
||||
{
|
||||
uint8_t buf[8];
|
||||
size_t elem_size = DataTypeGetSize(data_type);
|
||||
size_t size = addr + elem_size > mem_size ? mem_size - addr : elem_size;
|
||||
if (ReadFn)
|
||||
for (int i = 0, n = (int)size; i < n; ++i)
|
||||
buf[i] = ReadFn(mem_data, addr + i);
|
||||
else
|
||||
memcpy(buf, mem_data + addr, size);
|
||||
|
||||
if (data_format == DataFormat_Bin)
|
||||
{
|
||||
uint8_t binbuf[8];
|
||||
EndianessCopy(binbuf, buf, size);
|
||||
ImSnprintf(out_buf, out_buf_size, "%s", FormatBinary(binbuf, (int)size * 8));
|
||||
return;
|
||||
}
|
||||
|
||||
out_buf[0] = 0;
|
||||
switch (data_type)
|
||||
{
|
||||
case ImGuiDataType_S8:
|
||||
{
|
||||
int8_t int8 = 0;
|
||||
EndianessCopy(&int8, buf, size);
|
||||
if (data_format == DataFormat_Dec) { ImSnprintf(out_buf, out_buf_size, "%hhd", int8); return; }
|
||||
if (data_format == DataFormat_Hex) { ImSnprintf(out_buf, out_buf_size, "0x%02x", int8 & 0xFF); return; }
|
||||
break;
|
||||
}
|
||||
case ImGuiDataType_U8:
|
||||
{
|
||||
uint8_t uint8 = 0;
|
||||
EndianessCopy(&uint8, buf, size);
|
||||
if (data_format == DataFormat_Dec) { ImSnprintf(out_buf, out_buf_size, "%hhu", uint8); return; }
|
||||
if (data_format == DataFormat_Hex) { ImSnprintf(out_buf, out_buf_size, "0x%02x", uint8 & 0XFF); return; }
|
||||
break;
|
||||
}
|
||||
case ImGuiDataType_S16:
|
||||
{
|
||||
int16_t int16 = 0;
|
||||
EndianessCopy(&int16, buf, size);
|
||||
if (data_format == DataFormat_Dec) { ImSnprintf(out_buf, out_buf_size, "%hd", int16); return; }
|
||||
if (data_format == DataFormat_Hex) { ImSnprintf(out_buf, out_buf_size, "0x%04x", int16 & 0xFFFF); return; }
|
||||
break;
|
||||
}
|
||||
case ImGuiDataType_U16:
|
||||
{
|
||||
uint16_t uint16 = 0;
|
||||
EndianessCopy(&uint16, buf, size);
|
||||
if (data_format == DataFormat_Dec) { ImSnprintf(out_buf, out_buf_size, "%hu", uint16); return; }
|
||||
if (data_format == DataFormat_Hex) { ImSnprintf(out_buf, out_buf_size, "0x%04x", uint16 & 0xFFFF); return; }
|
||||
break;
|
||||
}
|
||||
case ImGuiDataType_S32:
|
||||
{
|
||||
int32_t int32 = 0;
|
||||
EndianessCopy(&int32, buf, size);
|
||||
if (data_format == DataFormat_Dec) { ImSnprintf(out_buf, out_buf_size, "%d", int32); return; }
|
||||
if (data_format == DataFormat_Hex) { ImSnprintf(out_buf, out_buf_size, "0x%08x", int32); return; }
|
||||
break;
|
||||
}
|
||||
case ImGuiDataType_U32:
|
||||
{
|
||||
uint32_t uint32 = 0;
|
||||
EndianessCopy(&uint32, buf, size);
|
||||
if (data_format == DataFormat_Dec) { ImSnprintf(out_buf, out_buf_size, "%u", uint32); return; }
|
||||
if (data_format == DataFormat_Hex) { ImSnprintf(out_buf, out_buf_size, "0x%08x", uint32); return; }
|
||||
break;
|
||||
}
|
||||
case ImGuiDataType_S64:
|
||||
{
|
||||
int64_t int64 = 0;
|
||||
EndianessCopy(&int64, buf, size);
|
||||
if (data_format == DataFormat_Dec) { ImSnprintf(out_buf, out_buf_size, "%lld", (long long)int64); return; }
|
||||
if (data_format == DataFormat_Hex) { ImSnprintf(out_buf, out_buf_size, "0x%016llx", (long long)int64); return; }
|
||||
break;
|
||||
}
|
||||
case ImGuiDataType_U64:
|
||||
{
|
||||
uint64_t uint64 = 0;
|
||||
EndianessCopy(&uint64, buf, size);
|
||||
if (data_format == DataFormat_Dec) { ImSnprintf(out_buf, out_buf_size, "%llu", (long long)uint64); return; }
|
||||
if (data_format == DataFormat_Hex) { ImSnprintf(out_buf, out_buf_size, "0x%016llx", (long long)uint64); return; }
|
||||
break;
|
||||
}
|
||||
case ImGuiDataType_Float:
|
||||
{
|
||||
float float32 = 0.0f;
|
||||
EndianessCopy(&float32, buf, size);
|
||||
if (data_format == DataFormat_Dec) { ImSnprintf(out_buf, out_buf_size, "%f", float32); return; }
|
||||
if (data_format == DataFormat_Hex) { ImSnprintf(out_buf, out_buf_size, "%a", float32); return; }
|
||||
break;
|
||||
}
|
||||
case ImGuiDataType_Double:
|
||||
{
|
||||
double float64 = 0.0;
|
||||
EndianessCopy(&float64, buf, size);
|
||||
if (data_format == DataFormat_Dec) { ImSnprintf(out_buf, out_buf_size, "%f", float64); return; }
|
||||
if (data_format == DataFormat_Hex) { ImSnprintf(out_buf, out_buf_size, "%a", float64); return; }
|
||||
break;
|
||||
}
|
||||
case ImGuiDataType_COUNT:
|
||||
break;
|
||||
} // Switch
|
||||
IM_ASSERT(0); // Shouldn't reach
|
||||
}
|
||||
};
|
||||
|
||||
#undef _PRISizeT
|
||||
323
external/ImGui/include/imnodes.h
vendored
Normal file
323
external/ImGui/include/imnodes.h
vendored
Normal file
@@ -0,0 +1,323 @@
|
||||
#pragma once
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
struct ImVec2;
|
||||
|
||||
namespace imnodes
|
||||
{
|
||||
enum ColorStyle
|
||||
{
|
||||
ColorStyle_NodeBackground = 0,
|
||||
ColorStyle_NodeBackgroundHovered,
|
||||
ColorStyle_NodeBackgroundSelected,
|
||||
ColorStyle_NodeOutline,
|
||||
ColorStyle_TitleBar,
|
||||
ColorStyle_TitleBarHovered,
|
||||
ColorStyle_TitleBarSelected,
|
||||
ColorStyle_Link,
|
||||
ColorStyle_LinkHovered,
|
||||
ColorStyle_LinkSelected,
|
||||
ColorStyle_Pin,
|
||||
ColorStyle_PinHovered,
|
||||
ColorStyle_BoxSelector,
|
||||
ColorStyle_BoxSelectorOutline,
|
||||
ColorStyle_GridBackground,
|
||||
ColorStyle_GridLine,
|
||||
ColorStyle_Count
|
||||
};
|
||||
|
||||
enum StyleVar
|
||||
{
|
||||
StyleVar_GridSpacing = 0,
|
||||
StyleVar_NodeCornerRounding,
|
||||
StyleVar_NodePaddingHorizontal,
|
||||
StyleVar_NodePaddingVertical,
|
||||
StyleVar_NodeBorderThickness,
|
||||
StyleVar_LinkThickness,
|
||||
StyleVar_LinkLineSegmentsPerLength,
|
||||
StyleVar_LinkHoverDistance,
|
||||
StyleVar_PinCircleRadius,
|
||||
StyleVar_PinQuadSideLength,
|
||||
StyleVar_PinTriangleSideLength,
|
||||
StyleVar_PinLineThickness,
|
||||
StyleVar_PinHoverRadius,
|
||||
StyleVar_PinOffset
|
||||
};
|
||||
|
||||
enum StyleFlags
|
||||
{
|
||||
StyleFlags_None = 0,
|
||||
StyleFlags_NodeOutline = 1 << 0,
|
||||
StyleFlags_GridLines = 1 << 2
|
||||
};
|
||||
|
||||
// This enum controls the way attribute pins look.
|
||||
enum PinShape
|
||||
{
|
||||
PinShape_Circle,
|
||||
PinShape_CircleFilled,
|
||||
PinShape_Triangle,
|
||||
PinShape_TriangleFilled,
|
||||
PinShape_Quad,
|
||||
PinShape_QuadFilled
|
||||
};
|
||||
|
||||
// This enum controls the way the attribute pins behave.
|
||||
enum AttributeFlags
|
||||
{
|
||||
AttributeFlags_None = 0,
|
||||
// Allow detaching a link by left-clicking and dragging the link at a pin it is connected to.
|
||||
// NOTE: the user has to actually delete the link for this to work. A deleted link can be
|
||||
// detected by calling IsLinkDestroyed() after EndNodeEditor().
|
||||
AttributeFlags_EnableLinkDetachWithDragClick = 1 << 0,
|
||||
// Visual snapping of an in progress link will trigger IsLink Created/Destroyed events. Allows
|
||||
// for previewing the creation of a link while dragging it across attributes. See here for demo:
|
||||
// https://github.com/Nelarius/imnodes/issues/41#issuecomment-647132113 NOTE: the user has to
|
||||
// actually delete the link for this to work. A deleted link can be detected by calling
|
||||
// IsLinkDestroyed() after EndNodeEditor().
|
||||
AttributeFlags_EnableLinkCreationOnSnap = 1 << 1
|
||||
};
|
||||
|
||||
struct IO
|
||||
{
|
||||
struct EmulateThreeButtonMouse
|
||||
{
|
||||
EmulateThreeButtonMouse();
|
||||
|
||||
// Controls whether this feature is enabled or not.
|
||||
bool enabled;
|
||||
const bool* modifier; // The keyboard modifier to use with the mouse left click. Set to
|
||||
// &ImGuiIO::KeyAlt by default.
|
||||
} emulate_three_button_mouse;
|
||||
|
||||
struct LinkDetachWithModifierClick
|
||||
{
|
||||
LinkDetachWithModifierClick();
|
||||
|
||||
// Pointer to a boolean value indicating when the desired modifier is pressed. Set to NULL
|
||||
// by default (i.e. this feature is disabled). To enable the feature, set the link to point
|
||||
// to, for example, &ImGuiIO::KeyCtrl.
|
||||
//
|
||||
// Left-clicking a link with this modifier pressed will detach that link. NOTE: the user has
|
||||
// to actually delete the link for this to work. A deleted link can be detected by calling
|
||||
// IsLinkDestroyed() after EndNodeEditor().
|
||||
const bool* modifier;
|
||||
} link_detach_with_modifier_click;
|
||||
|
||||
IO();
|
||||
};
|
||||
|
||||
struct Style
|
||||
{
|
||||
float grid_spacing;
|
||||
|
||||
float node_corner_rounding;
|
||||
float node_padding_horizontal;
|
||||
float node_padding_vertical;
|
||||
float node_border_thickness;
|
||||
|
||||
float link_thickness;
|
||||
float link_line_segments_per_length;
|
||||
float link_hover_distance;
|
||||
|
||||
// The following variables control the look and behavior of the pins. The default size of each
|
||||
// pin shape is balanced to occupy approximately the same surface area on the screen.
|
||||
|
||||
// The circle radius used when the pin shape is either PinShape_Circle or PinShape_CircleFilled.
|
||||
float pin_circle_radius;
|
||||
// The quad side length used when the shape is either PinShape_Quad or PinShape_QuadFilled.
|
||||
float pin_quad_side_length;
|
||||
// The equilateral triangle side length used when the pin shape is either PinShape_Triangle or
|
||||
// PinShape_TriangleFilled.
|
||||
float pin_triangle_side_length;
|
||||
// The thickness of the line used when the pin shape is not filled.
|
||||
float pin_line_thickness;
|
||||
// The radius from the pin's center position inside of which it is detected as being hovered
|
||||
// over.
|
||||
float pin_hover_radius;
|
||||
// Offsets the pins' positions from the edge of the node to the outside of the node.
|
||||
float pin_offset;
|
||||
|
||||
// By default, StyleFlags_NodeOutline and StyleFlags_Gridlines are enabled.
|
||||
StyleFlags flags;
|
||||
// Set these mid-frame using Push/PopColorStyle. You can index this color array with with a
|
||||
// ColorStyle enum value.
|
||||
unsigned int colors[ColorStyle_Count];
|
||||
|
||||
Style();
|
||||
};
|
||||
|
||||
// An editor context corresponds to a set of nodes in a single workspace (created with a single
|
||||
// Begin/EndNodeEditor pair)
|
||||
//
|
||||
// By default, the library creates an editor context behind the scenes, so using any of the imnodes
|
||||
// functions doesn't require you to explicitly create a context.
|
||||
struct EditorContext;
|
||||
|
||||
EditorContext* EditorContextCreate();
|
||||
void EditorContextFree(EditorContext*);
|
||||
void EditorContextSet(EditorContext*);
|
||||
ImVec2 EditorContextGetPanning();
|
||||
void EditorContextResetPanning(const ImVec2& pos);
|
||||
void EditorContextMoveToNode(const int node_id);
|
||||
|
||||
// Initialize the node editor system.
|
||||
void Initialize();
|
||||
void Shutdown();
|
||||
|
||||
IO& GetIO();
|
||||
|
||||
// Returns the global style struct. See the struct declaration for default values.
|
||||
Style& GetStyle();
|
||||
// Style presets matching the dear imgui styles of the same name.
|
||||
void StyleColorsDark(); // on by default
|
||||
void StyleColorsClassic();
|
||||
void StyleColorsLight();
|
||||
|
||||
// The top-level function call. Call this before calling BeginNode/EndNode. Calling this function
|
||||
// will result the node editor grid workspace being rendered.
|
||||
void BeginNodeEditor();
|
||||
void EndNodeEditor();
|
||||
|
||||
// Use PushColorStyle and PopColorStyle to modify Style::colors mid-frame.
|
||||
void PushColorStyle(ColorStyle item, unsigned int color);
|
||||
void PopColorStyle();
|
||||
void PushStyleVar(StyleVar style_item, float value);
|
||||
void PopStyleVar();
|
||||
|
||||
// id can be any positive or negative integer, but INT_MIN is currently reserved for internal use.
|
||||
void BeginNode(int id);
|
||||
void EndNode();
|
||||
|
||||
ImVec2 GetNodeDimensions(int id);
|
||||
|
||||
// Place your node title bar content (such as the node title, using ImGui::Text) between the
|
||||
// following function calls. These functions have to be called before adding any attributes, or the
|
||||
// layout of the node will be incorrect.
|
||||
void BeginNodeTitleBar();
|
||||
void EndNodeTitleBar();
|
||||
|
||||
// Attributes are ImGui UI elements embedded within the node. Attributes can have pin shapes
|
||||
// rendered next to them. Links are created between pins.
|
||||
//
|
||||
// The activity status of an attribute can be checked via the IsAttributeActive() and
|
||||
// IsAnyAttributeActive() function calls. This is one easy way of checking for any changes made to
|
||||
// an attribute's drag float UI, for instance.
|
||||
//
|
||||
// Each attribute id must be unique.
|
||||
|
||||
// Create an input attribute block. The pin is rendered on left side.
|
||||
void BeginInputAttribute(int id, PinShape shape = PinShape_CircleFilled);
|
||||
void EndInputAttribute();
|
||||
// Create an output attribute block. The pin is rendered on the right side.
|
||||
void BeginOutputAttribute(int id, PinShape shape = PinShape_CircleFilled);
|
||||
void EndOutputAttribute();
|
||||
// Create a static attribute block. A static attribute has no pin, and therefore can't be linked to
|
||||
// anything. However, you can still use IsAttributeActive() and IsAnyAttributeActive() to check for
|
||||
// attribute activity.
|
||||
void BeginStaticAttribute(int id);
|
||||
void EndStaticAttribute();
|
||||
|
||||
// Push a single AttributeFlags value. By default, only AttributeFlags_None is set.
|
||||
void PushAttributeFlag(AttributeFlags flag);
|
||||
void PopAttributeFlag();
|
||||
|
||||
// Render a link between attributes.
|
||||
// The attributes ids used here must match the ids used in Begin(Input|Output)Attribute function
|
||||
// calls. The order of start_attr and end_attr doesn't make a difference for rendering the link.
|
||||
void Link(int id, int start_attribute_id, int end_attribute_id);
|
||||
|
||||
// Enable or disable the ability to click and drag a specific node.
|
||||
void SetNodeDraggable(int node_id, const bool draggable);
|
||||
|
||||
// The node's position can be expressed in three coordinate systems:
|
||||
// * screen space coordinates, -- the origin is the upper left corner of the window.
|
||||
// * editor space coordinates -- the origin is the upper left corner of the node editor window
|
||||
// * grid space coordinates, -- the origin is the upper left corner of the node editor window,
|
||||
// translated by the current editor panning vector (see EditorContextGetPanning() and
|
||||
// EditorContextResetPanning())
|
||||
|
||||
// Use the following functions to get and set the node's coordinates in these coordinate systems.
|
||||
|
||||
void SetNodeScreenSpacePos(int node_id, const ImVec2& screen_space_pos);
|
||||
void SetNodeEditorSpacePos(int node_id, const ImVec2& editor_space_pos);
|
||||
void SetNodeGridSpacePos(int node_id, const ImVec2& grid_pos);
|
||||
|
||||
ImVec2 GetNodeScreenSpacePos(const int node_id);
|
||||
ImVec2 GetNodeEditorSpacePos(const int node_id);
|
||||
ImVec2 GetNodeGridSpacePos(const int node_id);
|
||||
|
||||
// Returns true if the current node editor canvas is being hovered over by the mouse, and is not
|
||||
// blocked by any other windows.
|
||||
bool IsEditorHovered();
|
||||
// The following functions return true if a UI element is being hovered over by the mouse cursor.
|
||||
// Assigns the id of the UI element being hovered over to the function argument. Use these functions
|
||||
// after EndNodeEditor() has been called.
|
||||
bool IsNodeHovered(int* node_id);
|
||||
bool IsLinkHovered(int* link_id);
|
||||
bool IsPinHovered(int* attribute_id);
|
||||
|
||||
// Use The following two functions to query the number of selected nodes or links in the current
|
||||
// editor. Use after calling EndNodeEditor().
|
||||
int NumSelectedNodes();
|
||||
int NumSelectedLinks();
|
||||
// Get the selected node/link ids. The pointer argument should point to an integer array with at
|
||||
// least as many elements as the respective NumSelectedNodes/NumSelectedLinks function call
|
||||
// returned.
|
||||
void GetSelectedNodes(int* node_ids);
|
||||
void GetSelectedLinks(int* link_ids);
|
||||
|
||||
// Clears the list of selected nodes/links. Useful if you want to delete a selected node or link.
|
||||
void ClearNodeSelection();
|
||||
void ClearLinkSelection();
|
||||
|
||||
// Was the previous attribute active? This will continuously return true while the left mouse button
|
||||
// is being pressed over the UI content of the attribute.
|
||||
bool IsAttributeActive();
|
||||
// Was any attribute active? If so, sets the active attribute id to the output function argument.
|
||||
bool IsAnyAttributeActive(int* attribute_id = NULL);
|
||||
|
||||
// Use the following functions to query a change of state for an existing link, or new link. Call
|
||||
// these after EndNodeEditor().
|
||||
|
||||
// Did the user start dragging a new link from a pin?
|
||||
bool IsLinkStarted(int* started_at_attribute_id);
|
||||
// Did the user drop the dragged link before attaching it to a pin?
|
||||
// There are two different kinds of situations to consider when handling this event:
|
||||
// 1) a link which is created at a pin and then dropped
|
||||
// 2) an existing link which is detached from a pin and then dropped
|
||||
// Use the including_detached_links flag to control whether this function triggers when the user
|
||||
// detaches a link and drops it.
|
||||
bool IsLinkDropped(int* started_at_attribute_id = NULL, bool including_detached_links = true);
|
||||
// Did the user finish creating a new link?
|
||||
bool IsLinkCreated(
|
||||
int* started_at_attribute_id,
|
||||
int* ended_at_attribute_id,
|
||||
bool* created_from_snap = NULL);
|
||||
bool IsLinkCreated(
|
||||
int* started_at_node_id,
|
||||
int* started_at_attribute_id,
|
||||
int* ended_at_node_id,
|
||||
int* ended_at_attribute_id,
|
||||
bool* created_from_snap = NULL);
|
||||
|
||||
// Was an existing link detached from a pin by the user? The detached link's id is assigned to the
|
||||
// output argument link_id.
|
||||
bool IsLinkDestroyed(int* link_id);
|
||||
|
||||
// Use the following functions to write the editor context's state to a string, or directly to a
|
||||
// file. The editor context is serialized in the INI file format.
|
||||
|
||||
const char* SaveCurrentEditorStateToIniString(size_t* data_size = NULL);
|
||||
const char* SaveEditorStateToIniString(const EditorContext* editor, size_t* data_size = NULL);
|
||||
|
||||
void LoadCurrentEditorStateFromIniString(const char* data, size_t data_size);
|
||||
void LoadEditorStateFromIniString(EditorContext* editor, const char* data, size_t data_size);
|
||||
|
||||
void SaveCurrentEditorStateToIniFile(const char* file_name);
|
||||
void SaveEditorStateToIniFile(const EditorContext* editor, const char* file_name);
|
||||
|
||||
void LoadCurrentEditorStateFromIniFile(const char* file_name);
|
||||
void LoadEditorStateFromIniFile(EditorContext* editor, const char* file_name);
|
||||
} // namespace imnodes
|
||||
1214
external/ImGui/source/ImGuiFileBrowser.cpp
vendored
Normal file
1214
external/ImGui/source/ImGuiFileBrowser.cpp
vendored
Normal file
File diff suppressed because it is too large
Load Diff
3160
external/ImGui/source/TextEditor.cpp
vendored
Normal file
3160
external/ImGui/source/TextEditor.cpp
vendored
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,4 +1,4 @@
|
||||
// dear imgui, v1.80 WIP
|
||||
// dear imgui, v1.80
|
||||
// (drawing and font code)
|
||||
|
||||
/*
|
||||
@@ -60,6 +60,9 @@ Index of this file:
|
||||
#if __has_warning("-Wunknown-warning-option")
|
||||
#pragma clang diagnostic ignored "-Wunknown-warning-option" // warning: unknown warning group 'xxx' // not all warnings are known by all Clang versions and they tend to be rename-happy.. so ignoring warnings triggers new warnings on some configuration. Great!
|
||||
#endif
|
||||
#if __has_warning("-Walloca")
|
||||
#pragma clang diagnostic ignored "-Walloca" // warning: use of function '__builtin_alloca' is discouraged
|
||||
#endif
|
||||
#pragma clang diagnostic ignored "-Wunknown-pragmas" // warning: unknown warning group 'xxx'
|
||||
#pragma clang diagnostic ignored "-Wold-style-cast" // warning: use of old-style cast // yes, they are more terse.
|
||||
#pragma clang diagnostic ignored "-Wfloat-equal" // warning: comparing floating point with == or != is unsafe // storing and comparing against same constants ok.
|
||||
@@ -207,7 +210,7 @@ void ImGui::StyleColorsDark(ImGuiStyle* dst)
|
||||
colors[ImGuiCol_Separator] = colors[ImGuiCol_Border];
|
||||
colors[ImGuiCol_SeparatorHovered] = ImVec4(0.10f, 0.40f, 0.75f, 0.78f);
|
||||
colors[ImGuiCol_SeparatorActive] = ImVec4(0.10f, 0.40f, 0.75f, 1.00f);
|
||||
colors[ImGuiCol_ResizeGrip] = ImVec4(0.26f, 0.59f, 0.98f, 0.25f);
|
||||
colors[ImGuiCol_ResizeGrip] = ImVec4(0.26f, 0.59f, 0.98f, 0.20f);
|
||||
colors[ImGuiCol_ResizeGripHovered] = ImVec4(0.26f, 0.59f, 0.98f, 0.67f);
|
||||
colors[ImGuiCol_ResizeGripActive] = ImVec4(0.26f, 0.59f, 0.98f, 0.95f);
|
||||
colors[ImGuiCol_Tab] = ImLerp(colors[ImGuiCol_Header], colors[ImGuiCol_TitleBgActive], 0.80f);
|
||||
@@ -221,6 +224,11 @@ void ImGui::StyleColorsDark(ImGuiStyle* dst)
|
||||
colors[ImGuiCol_PlotLinesHovered] = ImVec4(1.00f, 0.43f, 0.35f, 1.00f);
|
||||
colors[ImGuiCol_PlotHistogram] = ImVec4(0.90f, 0.70f, 0.00f, 1.00f);
|
||||
colors[ImGuiCol_PlotHistogramHovered] = ImVec4(1.00f, 0.60f, 0.00f, 1.00f);
|
||||
colors[ImGuiCol_TableHeaderBg] = ImVec4(0.19f, 0.19f, 0.20f, 1.00f);
|
||||
colors[ImGuiCol_TableBorderStrong] = ImVec4(0.31f, 0.31f, 0.35f, 1.00f); // Prefer using Alpha=1.0 here
|
||||
colors[ImGuiCol_TableBorderLight] = ImVec4(0.23f, 0.23f, 0.25f, 1.00f); // Prefer using Alpha=1.0 here
|
||||
colors[ImGuiCol_TableRowBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f);
|
||||
colors[ImGuiCol_TableRowBgAlt] = ImVec4(1.00f, 1.00f, 1.00f, 0.06f);
|
||||
colors[ImGuiCol_TextSelectedBg] = ImVec4(0.26f, 0.59f, 0.98f, 0.35f);
|
||||
colors[ImGuiCol_DragDropTarget] = ImVec4(1.00f, 1.00f, 0.00f, 0.90f);
|
||||
colors[ImGuiCol_NavHighlight] = ImVec4(0.26f, 0.59f, 0.98f, 1.00f);
|
||||
@@ -236,7 +244,7 @@ void ImGui::StyleColorsClassic(ImGuiStyle* dst)
|
||||
|
||||
colors[ImGuiCol_Text] = ImVec4(0.90f, 0.90f, 0.90f, 1.00f);
|
||||
colors[ImGuiCol_TextDisabled] = ImVec4(0.60f, 0.60f, 0.60f, 1.00f);
|
||||
colors[ImGuiCol_WindowBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.70f);
|
||||
colors[ImGuiCol_WindowBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.85f);
|
||||
colors[ImGuiCol_ChildBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f);
|
||||
colors[ImGuiCol_PopupBg] = ImVec4(0.11f, 0.11f, 0.14f, 0.92f);
|
||||
colors[ImGuiCol_Border] = ImVec4(0.50f, 0.50f, 0.50f, 0.50f);
|
||||
@@ -264,7 +272,7 @@ void ImGui::StyleColorsClassic(ImGuiStyle* dst)
|
||||
colors[ImGuiCol_Separator] = ImVec4(0.50f, 0.50f, 0.50f, 0.60f);
|
||||
colors[ImGuiCol_SeparatorHovered] = ImVec4(0.60f, 0.60f, 0.70f, 1.00f);
|
||||
colors[ImGuiCol_SeparatorActive] = ImVec4(0.70f, 0.70f, 0.90f, 1.00f);
|
||||
colors[ImGuiCol_ResizeGrip] = ImVec4(1.00f, 1.00f, 1.00f, 0.16f);
|
||||
colors[ImGuiCol_ResizeGrip] = ImVec4(1.00f, 1.00f, 1.00f, 0.10f);
|
||||
colors[ImGuiCol_ResizeGripHovered] = ImVec4(0.78f, 0.82f, 1.00f, 0.60f);
|
||||
colors[ImGuiCol_ResizeGripActive] = ImVec4(0.78f, 0.82f, 1.00f, 0.90f);
|
||||
colors[ImGuiCol_Tab] = ImLerp(colors[ImGuiCol_Header], colors[ImGuiCol_TitleBgActive], 0.80f);
|
||||
@@ -278,6 +286,11 @@ void ImGui::StyleColorsClassic(ImGuiStyle* dst)
|
||||
colors[ImGuiCol_PlotLinesHovered] = ImVec4(0.90f, 0.70f, 0.00f, 1.00f);
|
||||
colors[ImGuiCol_PlotHistogram] = ImVec4(0.90f, 0.70f, 0.00f, 1.00f);
|
||||
colors[ImGuiCol_PlotHistogramHovered] = ImVec4(1.00f, 0.60f, 0.00f, 1.00f);
|
||||
colors[ImGuiCol_TableHeaderBg] = ImVec4(0.27f, 0.27f, 0.38f, 1.00f);
|
||||
colors[ImGuiCol_TableBorderStrong] = ImVec4(0.31f, 0.31f, 0.45f, 1.00f); // Prefer using Alpha=1.0 here
|
||||
colors[ImGuiCol_TableBorderLight] = ImVec4(0.26f, 0.26f, 0.28f, 1.00f); // Prefer using Alpha=1.0 here
|
||||
colors[ImGuiCol_TableRowBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f);
|
||||
colors[ImGuiCol_TableRowBgAlt] = ImVec4(1.00f, 1.00f, 1.00f, 0.07f);
|
||||
colors[ImGuiCol_TextSelectedBg] = ImVec4(0.00f, 0.00f, 1.00f, 0.35f);
|
||||
colors[ImGuiCol_DragDropTarget] = ImVec4(1.00f, 1.00f, 0.00f, 0.90f);
|
||||
colors[ImGuiCol_NavHighlight] = colors[ImGuiCol_HeaderHovered];
|
||||
@@ -322,7 +335,7 @@ void ImGui::StyleColorsLight(ImGuiStyle* dst)
|
||||
colors[ImGuiCol_Separator] = ImVec4(0.39f, 0.39f, 0.39f, 0.62f);
|
||||
colors[ImGuiCol_SeparatorHovered] = ImVec4(0.14f, 0.44f, 0.80f, 0.78f);
|
||||
colors[ImGuiCol_SeparatorActive] = ImVec4(0.14f, 0.44f, 0.80f, 1.00f);
|
||||
colors[ImGuiCol_ResizeGrip] = ImVec4(0.80f, 0.80f, 0.80f, 0.56f);
|
||||
colors[ImGuiCol_ResizeGrip] = ImVec4(0.35f, 0.35f, 0.35f, 0.17f);
|
||||
colors[ImGuiCol_ResizeGripHovered] = ImVec4(0.26f, 0.59f, 0.98f, 0.67f);
|
||||
colors[ImGuiCol_ResizeGripActive] = ImVec4(0.26f, 0.59f, 0.98f, 0.95f);
|
||||
colors[ImGuiCol_Tab] = ImLerp(colors[ImGuiCol_Header], colors[ImGuiCol_TitleBgActive], 0.90f);
|
||||
@@ -336,6 +349,11 @@ void ImGui::StyleColorsLight(ImGuiStyle* dst)
|
||||
colors[ImGuiCol_PlotLinesHovered] = ImVec4(1.00f, 0.43f, 0.35f, 1.00f);
|
||||
colors[ImGuiCol_PlotHistogram] = ImVec4(0.90f, 0.70f, 0.00f, 1.00f);
|
||||
colors[ImGuiCol_PlotHistogramHovered] = ImVec4(1.00f, 0.45f, 0.00f, 1.00f);
|
||||
colors[ImGuiCol_TableHeaderBg] = ImVec4(0.78f, 0.87f, 0.98f, 1.00f);
|
||||
colors[ImGuiCol_TableBorderStrong] = ImVec4(0.57f, 0.57f, 0.64f, 1.00f); // Prefer using Alpha=1.0 here
|
||||
colors[ImGuiCol_TableBorderLight] = ImVec4(0.68f, 0.68f, 0.74f, 1.00f); // Prefer using Alpha=1.0 here
|
||||
colors[ImGuiCol_TableRowBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f);
|
||||
colors[ImGuiCol_TableRowBgAlt] = ImVec4(0.30f, 0.30f, 0.30f, 0.09f);
|
||||
colors[ImGuiCol_TextSelectedBg] = ImVec4(0.26f, 0.59f, 0.98f, 0.35f);
|
||||
colors[ImGuiCol_DragDropTarget] = ImVec4(0.26f, 0.59f, 0.98f, 0.95f);
|
||||
colors[ImGuiCol_NavHighlight] = colors[ImGuiCol_HeaderHovered];
|
||||
@@ -350,21 +368,12 @@ void ImGui::StyleColorsLight(ImGuiStyle* dst)
|
||||
|
||||
ImDrawListSharedData::ImDrawListSharedData()
|
||||
{
|
||||
Font = NULL;
|
||||
FontSize = 0.0f;
|
||||
CurveTessellationTol = 0.0f;
|
||||
CircleSegmentMaxError = 0.0f;
|
||||
ClipRectFullscreen = ImVec4(-8192.0f, -8192.0f, +8192.0f, +8192.0f);
|
||||
InitialFlags = ImDrawListFlags_None;
|
||||
|
||||
// Lookup tables
|
||||
memset(this, 0, sizeof(*this));
|
||||
for (int i = 0; i < IM_ARRAYSIZE(ArcFastVtx); i++)
|
||||
{
|
||||
const float a = ((float)i * 2 * IM_PI) / (float)IM_ARRAYSIZE(ArcFastVtx);
|
||||
ArcFastVtx[i] = ImVec2(ImCos(a), ImSin(a));
|
||||
}
|
||||
memset(CircleSegmentCounts, 0, sizeof(CircleSegmentCounts)); // This will be set by SetCircleSegmentMaxError()
|
||||
TexUvLines = NULL;
|
||||
}
|
||||
|
||||
void ImDrawListSharedData::SetCircleSegmentMaxError(float max_error)
|
||||
@@ -402,6 +411,7 @@ void ImDrawList::_ResetForNewFrame()
|
||||
_Path.resize(0);
|
||||
_Splitter.Clear();
|
||||
CmdBuffer.push_back(ImDrawCmd());
|
||||
_FringeScale = 1.0f;
|
||||
}
|
||||
|
||||
void ImDrawList::_ClearFreeMemory()
|
||||
@@ -677,12 +687,12 @@ void ImDrawList::AddPolyline(const ImVec2* points, const int points_count, ImU32
|
||||
|
||||
const ImVec2 opaque_uv = _Data->TexUvWhitePixel;
|
||||
const int count = closed ? points_count : points_count - 1; // The number of line segments we need to draw
|
||||
const bool thick_line = (thickness > 1.0f);
|
||||
const bool thick_line = (thickness > _FringeScale);
|
||||
|
||||
if (Flags & ImDrawListFlags_AntiAliasedLines)
|
||||
{
|
||||
// Anti-aliased stroke
|
||||
const float AA_SIZE = 1.0f;
|
||||
const float AA_SIZE = _FringeScale;
|
||||
const ImU32 col_trans = col & ~IM_COL32_A_MASK;
|
||||
|
||||
// Thicknesses <1.0 should behave like thickness 1.0
|
||||
@@ -693,7 +703,7 @@ void ImDrawList::AddPolyline(const ImVec2* points, const int points_count, ImU32
|
||||
// Do we want to draw this line using a texture?
|
||||
// - For now, only draw integer-width lines using textures to avoid issues with the way scaling occurs, could be improved.
|
||||
// - If AA_SIZE is not 1.0f we cannot use the texture path.
|
||||
const bool use_texture = (Flags & ImDrawListFlags_AntiAliasedLinesUseTex) && (integer_thickness < IM_DRAWLIST_TEX_LINES_WIDTH_MAX) && (fractional_thickness <= 0.00001f);
|
||||
const bool use_texture = (Flags & ImDrawListFlags_AntiAliasedLinesUseTex) && (integer_thickness < IM_DRAWLIST_TEX_LINES_WIDTH_MAX) && (fractional_thickness <= 0.00001f) && (AA_SIZE == 1.0f);
|
||||
|
||||
// We should never hit this, because NewFrame() doesn't set ImDrawListFlags_AntiAliasedLinesUseTex unless ImFontAtlasFlags_NoBakedLines is off
|
||||
IM_ASSERT_PARANOID(!use_texture || !(_Data->Font->ContainerAtlas->Flags & ImFontAtlasFlags_NoBakedLines));
|
||||
@@ -790,14 +800,14 @@ void ImDrawList::AddPolyline(const ImVec2* points, const int points_count, ImU32
|
||||
{
|
||||
// If we're using textures we only need to emit the left/right edge vertices
|
||||
ImVec4 tex_uvs = _Data->TexUvLines[integer_thickness];
|
||||
if (fractional_thickness != 0.0f)
|
||||
/*if (fractional_thickness != 0.0f) // Currently always zero when use_texture==false!
|
||||
{
|
||||
const ImVec4 tex_uvs_1 = _Data->TexUvLines[integer_thickness + 1];
|
||||
tex_uvs.x = tex_uvs.x + (tex_uvs_1.x - tex_uvs.x) * fractional_thickness; // inlined ImLerp()
|
||||
tex_uvs.y = tex_uvs.y + (tex_uvs_1.y - tex_uvs.y) * fractional_thickness;
|
||||
tex_uvs.z = tex_uvs.z + (tex_uvs_1.z - tex_uvs.z) * fractional_thickness;
|
||||
tex_uvs.w = tex_uvs.w + (tex_uvs_1.w - tex_uvs.w) * fractional_thickness;
|
||||
}
|
||||
}*/
|
||||
ImVec2 tex_uv0(tex_uvs.x, tex_uvs.y);
|
||||
ImVec2 tex_uv1(tex_uvs.z, tex_uvs.w);
|
||||
for (int i = 0; i < points_count; i++)
|
||||
@@ -935,7 +945,7 @@ void ImDrawList::AddConvexPolyFilled(const ImVec2* points, const int points_coun
|
||||
if (Flags & ImDrawListFlags_AntiAliasedFill)
|
||||
{
|
||||
// Anti-aliased Fill
|
||||
const float AA_SIZE = 1.0f;
|
||||
const float AA_SIZE = _FringeScale;
|
||||
const ImU32 col_trans = col & ~IM_COL32_A_MASK;
|
||||
const int idx_count = (points_count - 2)*3 + points_count * 6;
|
||||
const int vtx_count = (points_count * 2);
|
||||
@@ -1047,23 +1057,32 @@ void ImDrawList::PathArcTo(const ImVec2& center, float radius, float a_min, floa
|
||||
}
|
||||
}
|
||||
|
||||
ImVec2 ImBezierCalc(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, float t)
|
||||
ImVec2 ImBezierCubicCalc(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, float t)
|
||||
{
|
||||
float u = 1.0f - t;
|
||||
float w1 = u*u*u;
|
||||
float w2 = 3*u*u*t;
|
||||
float w3 = 3*u*t*t;
|
||||
float w4 = t*t*t;
|
||||
return ImVec2(w1*p1.x + w2*p2.x + w3*p3.x + w4*p4.x, w1*p1.y + w2*p2.y + w3*p3.y + w4*p4.y);
|
||||
float w1 = u * u * u;
|
||||
float w2 = 3 * u * u * t;
|
||||
float w3 = 3 * u * t * t;
|
||||
float w4 = t * t * t;
|
||||
return ImVec2(w1 * p1.x + w2 * p2.x + w3 * p3.x + w4 * p4.x, w1 * p1.y + w2 * p2.y + w3 * p3.y + w4 * p4.y);
|
||||
}
|
||||
|
||||
// Closely mimics BezierClosestPointCasteljauStep() in imgui.cpp
|
||||
static void PathBezierToCasteljau(ImVector<ImVec2>* path, float x1, float y1, float x2, float y2, float x3, float y3, float x4, float y4, float tess_tol, int level)
|
||||
ImVec2 ImBezierQuadraticCalc(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, float t)
|
||||
{
|
||||
float u = 1.0f - t;
|
||||
float w1 = u * u;
|
||||
float w2 = 2 * u * t;
|
||||
float w3 = t * t;
|
||||
return ImVec2(w1 * p1.x + w2 * p2.x + w3 * p3.x, w1 * p1.y + w2 * p2.y + w3 * p3.y);
|
||||
}
|
||||
|
||||
// Closely mimics ImBezierCubicClosestPointCasteljau() in imgui.cpp
|
||||
static void PathBezierCubicCurveToCasteljau(ImVector<ImVec2>* path, float x1, float y1, float x2, float y2, float x3, float y3, float x4, float y4, float tess_tol, int level)
|
||||
{
|
||||
float dx = x4 - x1;
|
||||
float dy = y4 - y1;
|
||||
float d2 = ((x2 - x4) * dy - (y2 - y4) * dx);
|
||||
float d3 = ((x3 - x4) * dy - (y3 - y4) * dx);
|
||||
float d2 = (x2 - x4) * dy - (y2 - y4) * dx;
|
||||
float d3 = (x3 - x4) * dy - (y3 - y4) * dx;
|
||||
d2 = (d2 >= 0) ? d2 : -d2;
|
||||
d3 = (d3 >= 0) ? d3 : -d3;
|
||||
if ((d2 + d3) * (d2 + d3) < tess_tol * (dx * dx + dy * dy))
|
||||
@@ -1072,29 +1091,62 @@ static void PathBezierToCasteljau(ImVector<ImVec2>* path, float x1, float y1, fl
|
||||
}
|
||||
else if (level < 10)
|
||||
{
|
||||
float x12 = (x1 + x2)*0.5f, y12 = (y1 + y2)*0.5f;
|
||||
float x23 = (x2 + x3)*0.5f, y23 = (y2 + y3)*0.5f;
|
||||
float x34 = (x3 + x4)*0.5f, y34 = (y3 + y4)*0.5f;
|
||||
float x123 = (x12 + x23)*0.5f, y123 = (y12 + y23)*0.5f;
|
||||
float x234 = (x23 + x34)*0.5f, y234 = (y23 + y34)*0.5f;
|
||||
float x1234 = (x123 + x234)*0.5f, y1234 = (y123 + y234)*0.5f;
|
||||
PathBezierToCasteljau(path, x1, y1, x12, y12, x123, y123, x1234, y1234, tess_tol, level + 1);
|
||||
PathBezierToCasteljau(path, x1234, y1234, x234, y234, x34, y34, x4, y4, tess_tol, level + 1);
|
||||
float x12 = (x1 + x2) * 0.5f, y12 = (y1 + y2) * 0.5f;
|
||||
float x23 = (x2 + x3) * 0.5f, y23 = (y2 + y3) * 0.5f;
|
||||
float x34 = (x3 + x4) * 0.5f, y34 = (y3 + y4) * 0.5f;
|
||||
float x123 = (x12 + x23) * 0.5f, y123 = (y12 + y23) * 0.5f;
|
||||
float x234 = (x23 + x34) * 0.5f, y234 = (y23 + y34) * 0.5f;
|
||||
float x1234 = (x123 + x234) * 0.5f, y1234 = (y123 + y234) * 0.5f;
|
||||
PathBezierCubicCurveToCasteljau(path, x1, y1, x12, y12, x123, y123, x1234, y1234, tess_tol, level + 1);
|
||||
PathBezierCubicCurveToCasteljau(path, x1234, y1234, x234, y234, x34, y34, x4, y4, tess_tol, level + 1);
|
||||
}
|
||||
}
|
||||
|
||||
void ImDrawList::PathBezierCurveTo(const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, int num_segments)
|
||||
static void PathBezierQuadraticCurveToCasteljau(ImVector<ImVec2>* path, float x1, float y1, float x2, float y2, float x3, float y3, float tess_tol, int level)
|
||||
{
|
||||
float dx = x3 - x1, dy = y3 - y1;
|
||||
float det = (x2 - x3) * dy - (y2 - y3) * dx;
|
||||
if (det * det * 4.0f < tess_tol * (dx * dx + dy * dy))
|
||||
{
|
||||
path->push_back(ImVec2(x3, y3));
|
||||
}
|
||||
else if (level < 10)
|
||||
{
|
||||
float x12 = (x1 + x2) * 0.5f, y12 = (y1 + y2) * 0.5f;
|
||||
float x23 = (x2 + x3) * 0.5f, y23 = (y2 + y3) * 0.5f;
|
||||
float x123 = (x12 + x23) * 0.5f, y123 = (y12 + y23) * 0.5f;
|
||||
PathBezierQuadraticCurveToCasteljau(path, x1, y1, x12, y12, x123, y123, tess_tol, level + 1);
|
||||
PathBezierQuadraticCurveToCasteljau(path, x123, y123, x23, y23, x3, y3, tess_tol, level + 1);
|
||||
}
|
||||
}
|
||||
|
||||
void ImDrawList::PathBezierCubicCurveTo(const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, int num_segments)
|
||||
{
|
||||
ImVec2 p1 = _Path.back();
|
||||
if (num_segments == 0)
|
||||
{
|
||||
PathBezierToCasteljau(&_Path, p1.x, p1.y, p2.x, p2.y, p3.x, p3.y, p4.x, p4.y, _Data->CurveTessellationTol, 0); // Auto-tessellated
|
||||
PathBezierCubicCurveToCasteljau(&_Path, p1.x, p1.y, p2.x, p2.y, p3.x, p3.y, p4.x, p4.y, _Data->CurveTessellationTol, 0); // Auto-tessellated
|
||||
}
|
||||
else
|
||||
{
|
||||
float t_step = 1.0f / (float)num_segments;
|
||||
for (int i_step = 1; i_step <= num_segments; i_step++)
|
||||
_Path.push_back(ImBezierCalc(p1, p2, p3, p4, t_step * i_step));
|
||||
_Path.push_back(ImBezierCubicCalc(p1, p2, p3, p4, t_step * i_step));
|
||||
}
|
||||
}
|
||||
|
||||
void ImDrawList::PathBezierQuadraticCurveTo(const ImVec2& p2, const ImVec2& p3, int num_segments)
|
||||
{
|
||||
ImVec2 p1 = _Path.back();
|
||||
if (num_segments == 0)
|
||||
{
|
||||
PathBezierQuadraticCurveToCasteljau(&_Path, p1.x, p1.y, p2.x, p2.y, p3.x, p3.y, _Data->CurveTessellationTol, 0);// Auto-tessellated
|
||||
}
|
||||
else
|
||||
{
|
||||
float t_step = 1.0f / (float)num_segments;
|
||||
for (int i_step = 1; i_step <= num_segments; i_step++)
|
||||
_Path.push_back(ImBezierQuadraticCalc(p1, p2, p3, t_step * i_step));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1308,13 +1360,24 @@ void ImDrawList::AddNgonFilled(const ImVec2& center, float radius, ImU32 col, in
|
||||
}
|
||||
|
||||
// Cubic Bezier takes 4 controls points
|
||||
void ImDrawList::AddBezierCurve(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, ImU32 col, float thickness, int num_segments)
|
||||
void ImDrawList::AddBezierCubic(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, ImU32 col, float thickness, int num_segments)
|
||||
{
|
||||
if ((col & IM_COL32_A_MASK) == 0)
|
||||
return;
|
||||
|
||||
PathLineTo(p1);
|
||||
PathBezierCurveTo(p2, p3, p4, num_segments);
|
||||
PathBezierCubicCurveTo(p2, p3, p4, num_segments);
|
||||
PathStroke(col, false, thickness);
|
||||
}
|
||||
|
||||
// Quadratic Bezier takes 3 controls points
|
||||
void ImDrawList::AddBezierQuadratic(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, ImU32 col, float thickness, int num_segments)
|
||||
{
|
||||
if ((col & IM_COL32_A_MASK) == 0)
|
||||
return;
|
||||
|
||||
PathLineTo(p1);
|
||||
PathBezierQuadraticCurveTo(p2, p3, num_segments);
|
||||
PathStroke(col, false, thickness);
|
||||
}
|
||||
|
||||
@@ -1432,10 +1495,14 @@ void ImDrawListSplitter::ClearFreeMemory()
|
||||
|
||||
void ImDrawListSplitter::Split(ImDrawList* draw_list, int channels_count)
|
||||
{
|
||||
IM_UNUSED(draw_list);
|
||||
IM_ASSERT(_Current == 0 && _Count <= 1 && "Nested channel splitting is not supported. Please use separate instances of ImDrawListSplitter.");
|
||||
int old_channels_count = _Channels.Size;
|
||||
if (old_channels_count < channels_count)
|
||||
{
|
||||
_Channels.reserve(channels_count); // Avoid over reserving since this is likely to stay stable
|
||||
_Channels.resize(channels_count);
|
||||
}
|
||||
_Count = channels_count;
|
||||
|
||||
// Channels[] (24/32 bytes each) hold storage that we'll swap with draw_list->_CmdBuffer/_IdxBuffer
|
||||
@@ -1453,12 +1520,6 @@ void ImDrawListSplitter::Split(ImDrawList* draw_list, int channels_count)
|
||||
_Channels[i]._CmdBuffer.resize(0);
|
||||
_Channels[i]._IdxBuffer.resize(0);
|
||||
}
|
||||
if (_Channels[i]._CmdBuffer.Size == 0)
|
||||
{
|
||||
ImDrawCmd draw_cmd;
|
||||
ImDrawCmd_HeaderCopy(&draw_cmd, &draw_list->_CmdHeader); // Copy ClipRect, TextureId, VtxOffset
|
||||
_Channels[i]._CmdBuffer.push_back(draw_cmd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1548,8 +1609,10 @@ void ImDrawListSplitter::SetCurrentChannel(ImDrawList* draw_list, int idx)
|
||||
draw_list->_IdxWritePtr = draw_list->IdxBuffer.Data + draw_list->IdxBuffer.Size;
|
||||
|
||||
// If current command is used with different settings we need to add a new command
|
||||
ImDrawCmd* curr_cmd = &draw_list->CmdBuffer.Data[draw_list->CmdBuffer.Size - 1];
|
||||
if (curr_cmd->ElemCount == 0)
|
||||
ImDrawCmd* curr_cmd = (draw_list->CmdBuffer.Size == 0) ? NULL : &draw_list->CmdBuffer.Data[draw_list->CmdBuffer.Size - 1];
|
||||
if (curr_cmd == NULL)
|
||||
draw_list->AddDrawCmd();
|
||||
else if (curr_cmd->ElemCount == 0)
|
||||
ImDrawCmd_HeaderCopy(curr_cmd, &draw_list->_CmdHeader); // Copy ClipRect, TextureId, VtxOffset
|
||||
else if (ImDrawCmd_HeaderCompare(curr_cmd, &draw_list->_CmdHeader) != 0)
|
||||
draw_list->AddDrawCmd();
|
||||
@@ -2114,10 +2177,11 @@ bool ImFontAtlasBuildWithStbTruetype(ImFontAtlas* atlas)
|
||||
for (int output_i = 0; output_i < atlas->Fonts.Size && src_tmp.DstIndex == -1; output_i++)
|
||||
if (cfg.DstFont == atlas->Fonts[output_i])
|
||||
src_tmp.DstIndex = output_i;
|
||||
IM_ASSERT(src_tmp.DstIndex != -1); // cfg.DstFont not pointing within atlas->Fonts[] array?
|
||||
if (src_tmp.DstIndex == -1)
|
||||
{
|
||||
IM_ASSERT(src_tmp.DstIndex != -1); // cfg.DstFont not pointing within atlas->Fonts[] array?
|
||||
return false;
|
||||
|
||||
}
|
||||
// Initialize helper structure for font loading and verify that the TTF/OTF data is correct
|
||||
const int font_offset = stbtt_GetFontOffsetForIndex((unsigned char*)cfg.FontData, cfg.FontNo);
|
||||
IM_ASSERT(font_offset >= 0 && "FontData is incorrect, or FontNo cannot be found.");
|
||||
@@ -2628,45 +2692,76 @@ const ImWchar* ImFontAtlas::GetGlyphRangesChineseSimplifiedCommon()
|
||||
|
||||
const ImWchar* ImFontAtlas::GetGlyphRangesJapanese()
|
||||
{
|
||||
// 1946 common ideograms code points for Japanese
|
||||
// Sourced from http://theinstructionlimit.com/common-kanji-character-ranges-for-xna-spritefont-rendering
|
||||
// FIXME: Source a list of the revised 2136 Joyo Kanji list from 2010 and rebuild this.
|
||||
// 2999 ideograms code points for Japanese
|
||||
// - 2136 Joyo (meaning "for regular use" or "for common use") Kanji code points
|
||||
// - 863 Jinmeiyo (meaning "for personal name") Kanji code points
|
||||
// - Sourced from the character information database of the Information-technology Promotion Agency, Japan
|
||||
// - https://mojikiban.ipa.go.jp/mji/
|
||||
// - Available under the terms of the Creative Commons Attribution-ShareAlike 2.1 Japan (CC BY-SA 2.1 JP).
|
||||
// - https://creativecommons.org/licenses/by-sa/2.1/jp/deed.en
|
||||
// - https://creativecommons.org/licenses/by-sa/2.1/jp/legalcode
|
||||
// - You can generate this code by the script at:
|
||||
// - https://github.com/vaiorabbit/everyday_use_kanji
|
||||
// - References:
|
||||
// - List of Joyo Kanji
|
||||
// - (Official list by the Agency for Cultural Affairs) https://www.bunka.go.jp/kokugo_nihongo/sisaku/joho/joho/kakuki/14/tosin02/index.html
|
||||
// - (Wikipedia) https://en.wikipedia.org/wiki/List_of_j%C5%8Dy%C5%8D_kanji
|
||||
// - List of Jinmeiyo Kanji
|
||||
// - (Official list by the Ministry of Justice) http://www.moj.go.jp/MINJI/minji86.html
|
||||
// - (Wikipedia) https://en.wikipedia.org/wiki/Jinmeiy%C5%8D_kanji
|
||||
// - Missing 1 Joyo Kanji: U+20B9F (Kun'yomi: Shikaru, On'yomi: Shitsu,shichi), see https://github.com/ocornut/imgui/pull/3627 for details.
|
||||
// You can use ImFontGlyphRangesBuilder to create your own ranges derived from this, by merging existing ranges or adding new characters.
|
||||
// (Stored as accumulative offsets from the initial unicode codepoint 0x4E00. This encoding is designed to helps us compact the source code size.)
|
||||
static const short accumulative_offsets_from_0x4E00[] =
|
||||
{
|
||||
0,1,2,4,1,1,1,1,2,1,6,2,2,1,8,5,7,11,1,2,10,10,8,2,4,20,2,11,8,2,1,2,1,6,2,1,7,5,3,7,1,1,13,7,9,1,4,6,1,2,1,10,1,1,9,2,2,4,5,6,14,1,1,9,3,18,
|
||||
5,4,2,2,10,7,1,1,1,3,2,4,3,23,2,10,12,2,14,2,4,13,1,6,10,3,1,7,13,6,4,13,5,2,3,17,2,2,5,7,6,4,1,7,14,16,6,13,9,15,1,1,7,16,4,7,1,19,9,2,7,15,
|
||||
2,6,5,13,25,4,14,13,11,25,1,1,1,2,1,2,2,3,10,11,3,3,1,1,4,4,2,1,4,9,1,4,3,5,5,2,7,12,11,15,7,16,4,5,16,2,1,1,6,3,3,1,1,2,7,6,6,7,1,4,7,6,1,1,
|
||||
2,1,12,3,3,9,5,8,1,11,1,2,3,18,20,4,1,3,6,1,7,3,5,5,7,2,2,12,3,1,4,2,3,2,3,11,8,7,4,17,1,9,25,1,1,4,2,2,4,1,2,7,1,1,1,3,1,2,6,16,1,2,1,1,3,12,
|
||||
20,2,5,20,8,7,6,2,1,1,1,1,6,2,1,2,10,1,1,6,1,3,1,2,1,4,1,12,4,1,3,1,1,1,1,1,10,4,7,5,13,1,15,1,1,30,11,9,1,15,38,14,1,32,17,20,1,9,31,2,21,9,
|
||||
4,49,22,2,1,13,1,11,45,35,43,55,12,19,83,1,3,2,3,13,2,1,7,3,18,3,13,8,1,8,18,5,3,7,25,24,9,24,40,3,17,24,2,1,6,2,3,16,15,6,7,3,12,1,9,7,3,3,
|
||||
3,15,21,5,16,4,5,12,11,11,3,6,3,2,31,3,2,1,1,23,6,6,1,4,2,6,5,2,1,1,3,3,22,2,6,2,3,17,3,2,4,5,1,9,5,1,1,6,15,12,3,17,2,14,2,8,1,23,16,4,2,23,
|
||||
8,15,23,20,12,25,19,47,11,21,65,46,4,3,1,5,6,1,2,5,26,2,1,1,3,11,1,1,1,2,1,2,3,1,1,10,2,3,1,1,1,3,6,3,2,2,6,6,9,2,2,2,6,2,5,10,2,4,1,2,1,2,2,
|
||||
3,1,1,3,1,2,9,23,9,2,1,1,1,1,5,3,2,1,10,9,6,1,10,2,31,25,3,7,5,40,1,15,6,17,7,27,180,1,3,2,2,1,1,1,6,3,10,7,1,3,6,17,8,6,2,2,1,3,5,5,8,16,14,
|
||||
15,1,1,4,1,2,1,1,1,3,2,7,5,6,2,5,10,1,4,2,9,1,1,11,6,1,44,1,3,7,9,5,1,3,1,1,10,7,1,10,4,2,7,21,15,7,2,5,1,8,3,4,1,3,1,6,1,4,2,1,4,10,8,1,4,5,
|
||||
1,5,10,2,7,1,10,1,1,3,4,11,10,29,4,7,3,5,2,3,33,5,2,19,3,1,4,2,6,31,11,1,3,3,3,1,8,10,9,12,11,12,8,3,14,8,6,11,1,4,41,3,1,2,7,13,1,5,6,2,6,12,
|
||||
12,22,5,9,4,8,9,9,34,6,24,1,1,20,9,9,3,4,1,7,2,2,2,6,2,28,5,3,6,1,4,6,7,4,2,1,4,2,13,6,4,4,3,1,8,8,3,2,1,5,1,2,2,3,1,11,11,7,3,6,10,8,6,16,16,
|
||||
22,7,12,6,21,5,4,6,6,3,6,1,3,2,1,2,8,29,1,10,1,6,13,6,6,19,31,1,13,4,4,22,17,26,33,10,4,15,12,25,6,67,10,2,3,1,6,10,2,6,2,9,1,9,4,4,1,2,16,2,
|
||||
5,9,2,3,8,1,8,3,9,4,8,6,4,8,11,3,2,1,1,3,26,1,7,5,1,11,1,5,3,5,2,13,6,39,5,1,5,2,11,6,10,5,1,15,5,3,6,19,21,22,2,4,1,6,1,8,1,4,8,2,4,2,2,9,2,
|
||||
1,1,1,4,3,6,3,12,7,1,14,2,4,10,2,13,1,17,7,3,2,1,3,2,13,7,14,12,3,1,29,2,8,9,15,14,9,14,1,3,1,6,5,9,11,3,38,43,20,7,7,8,5,15,12,19,15,81,8,7,
|
||||
1,5,73,13,37,28,8,8,1,15,18,20,165,28,1,6,11,8,4,14,7,15,1,3,3,6,4,1,7,14,1,1,11,30,1,5,1,4,14,1,4,2,7,52,2,6,29,3,1,9,1,21,3,5,1,26,3,11,14,
|
||||
11,1,17,5,1,2,1,3,2,8,1,2,9,12,1,1,2,3,8,3,24,12,7,7,5,17,3,3,3,1,23,10,4,4,6,3,1,16,17,22,3,10,21,16,16,6,4,10,2,1,1,2,8,8,6,5,3,3,3,39,25,
|
||||
15,1,1,16,6,7,25,15,6,6,12,1,22,13,1,4,9,5,12,2,9,1,12,28,8,3,5,10,22,60,1,2,40,4,61,63,4,1,13,12,1,4,31,12,1,14,89,5,16,6,29,14,2,5,49,18,18,
|
||||
5,29,33,47,1,17,1,19,12,2,9,7,39,12,3,7,12,39,3,1,46,4,12,3,8,9,5,31,15,18,3,2,2,66,19,13,17,5,3,46,124,13,57,34,2,5,4,5,8,1,1,1,4,3,1,17,5,
|
||||
3,5,3,1,8,5,6,3,27,3,26,7,12,7,2,17,3,7,18,78,16,4,36,1,2,1,6,2,1,39,17,7,4,13,4,4,4,1,10,4,2,4,6,3,10,1,19,1,26,2,4,33,2,73,47,7,3,8,2,4,15,
|
||||
18,1,29,2,41,14,1,21,16,41,7,39,25,13,44,2,2,10,1,13,7,1,7,3,5,20,4,8,2,49,1,10,6,1,6,7,10,7,11,16,3,12,20,4,10,3,1,2,11,2,28,9,2,4,7,2,15,1,
|
||||
27,1,28,17,4,5,10,7,3,24,10,11,6,26,3,2,7,2,2,49,16,10,16,15,4,5,27,61,30,14,38,22,2,7,5,1,3,12,23,24,17,17,3,3,2,4,1,6,2,7,5,1,1,5,1,1,9,4,
|
||||
1,3,6,1,8,2,8,4,14,3,5,11,4,1,3,32,1,19,4,1,13,11,5,2,1,8,6,8,1,6,5,13,3,23,11,5,3,16,3,9,10,1,24,3,198,52,4,2,2,5,14,5,4,22,5,20,4,11,6,41,
|
||||
1,5,2,2,11,5,2,28,35,8,22,3,18,3,10,7,5,3,4,1,5,3,8,9,3,6,2,16,22,4,5,5,3,3,18,23,2,6,23,5,27,8,1,33,2,12,43,16,5,2,3,6,1,20,4,2,9,7,1,11,2,
|
||||
10,3,14,31,9,3,25,18,20,2,5,5,26,14,1,11,17,12,40,19,9,6,31,83,2,7,9,19,78,12,14,21,76,12,113,79,34,4,1,1,61,18,85,10,2,2,13,31,11,50,6,33,159,
|
||||
179,6,6,7,4,4,2,4,2,5,8,7,20,32,22,1,3,10,6,7,28,5,10,9,2,77,19,13,2,5,1,4,4,7,4,13,3,9,31,17,3,26,2,6,6,5,4,1,7,11,3,4,2,1,6,2,20,4,1,9,2,6,
|
||||
3,7,1,1,1,20,2,3,1,6,2,3,6,2,4,8,1,5,13,8,4,11,23,1,10,6,2,1,3,21,2,2,4,24,31,4,10,10,2,5,192,15,4,16,7,9,51,1,2,1,1,5,1,1,2,1,3,5,3,1,3,4,1,
|
||||
3,1,3,3,9,8,1,2,2,2,4,4,18,12,92,2,10,4,3,14,5,25,16,42,4,14,4,2,21,5,126,30,31,2,1,5,13,3,22,5,6,6,20,12,1,14,12,87,3,19,1,8,2,9,9,3,3,23,2,
|
||||
3,7,6,3,1,2,3,9,1,3,1,6,3,2,1,3,11,3,1,6,10,3,2,3,1,2,1,5,1,1,11,3,6,4,1,7,2,1,2,5,5,34,4,14,18,4,19,7,5,8,2,6,79,1,5,2,14,8,2,9,2,1,36,28,16,
|
||||
4,1,1,1,2,12,6,42,39,16,23,7,15,15,3,2,12,7,21,64,6,9,28,8,12,3,3,41,59,24,51,55,57,294,9,9,2,6,2,15,1,2,13,38,90,9,9,9,3,11,7,1,1,1,5,6,3,2,
|
||||
1,2,2,3,8,1,4,4,1,5,7,1,4,3,20,4,9,1,1,1,5,5,17,1,5,2,6,2,4,1,4,5,7,3,18,11,11,32,7,5,4,7,11,127,8,4,3,3,1,10,1,1,6,21,14,1,16,1,7,1,3,6,9,65,
|
||||
51,4,3,13,3,10,1,1,12,9,21,110,3,19,24,1,1,10,62,4,1,29,42,78,28,20,18,82,6,3,15,6,84,58,253,15,155,264,15,21,9,14,7,58,40,39,
|
||||
0,1,2,4,1,1,1,1,2,1,3,3,2,2,1,5,3,5,7,5,6,1,2,1,7,2,6,3,1,8,1,1,4,1,1,18,2,11,2,6,2,1,2,1,5,1,2,1,3,1,2,1,2,3,3,1,1,2,3,1,1,1,12,7,9,1,4,5,1,
|
||||
1,2,1,10,1,1,9,2,2,4,5,6,9,3,1,1,1,1,9,3,18,5,2,2,2,2,1,6,3,7,1,1,1,1,2,2,4,2,1,23,2,10,4,3,5,2,4,10,2,4,13,1,6,1,9,3,1,1,6,6,7,6,3,1,2,11,3,
|
||||
2,2,3,2,15,2,2,5,4,3,6,4,1,2,5,2,12,16,6,13,9,13,2,1,1,7,16,4,7,1,19,1,5,1,2,2,7,7,8,2,6,5,4,9,18,7,4,5,9,13,11,8,15,2,1,1,1,2,1,2,2,1,2,2,8,
|
||||
2,9,3,3,1,1,4,4,1,1,1,4,9,1,4,3,5,5,2,7,5,3,4,8,2,1,13,2,3,3,1,14,1,1,4,5,1,3,6,1,5,2,1,1,3,3,3,3,1,1,2,7,6,6,7,1,4,7,6,1,1,1,1,1,12,3,3,9,5,
|
||||
2,6,1,5,6,1,2,3,18,2,4,14,4,1,3,6,1,1,6,3,5,5,3,2,2,2,2,12,3,1,4,2,3,2,3,11,1,7,4,1,2,1,3,17,1,9,1,24,1,1,4,2,2,4,1,2,7,1,1,1,3,1,2,2,4,15,1,
|
||||
1,2,1,1,2,1,5,2,5,20,2,5,9,1,10,8,7,6,1,1,1,1,1,1,6,2,1,2,8,1,1,1,1,5,1,1,3,1,1,1,1,3,1,1,12,4,1,3,1,1,1,1,1,10,3,1,7,5,13,1,2,3,4,6,1,1,30,
|
||||
2,9,9,1,15,38,11,3,1,8,24,7,1,9,8,10,2,1,9,31,2,13,6,2,9,4,49,5,2,15,2,1,10,2,1,1,1,2,2,6,15,30,35,3,14,18,8,1,16,10,28,12,19,45,38,1,3,2,3,
|
||||
13,2,1,7,3,6,5,3,4,3,1,5,7,8,1,5,3,18,5,3,6,1,21,4,24,9,24,40,3,14,3,21,3,2,1,2,4,2,3,1,15,15,6,5,1,1,3,1,5,6,1,9,7,3,3,2,1,4,3,8,21,5,16,4,
|
||||
5,2,10,11,11,3,6,3,2,9,3,6,13,1,2,1,1,1,1,11,12,6,6,1,4,2,6,5,2,1,1,3,3,6,13,3,1,1,5,1,2,3,3,14,2,1,2,2,2,5,1,9,5,1,1,6,12,3,12,3,4,13,2,14,
|
||||
2,8,1,17,5,1,16,4,2,2,21,8,9,6,23,20,12,25,19,9,38,8,3,21,40,25,33,13,4,3,1,4,1,2,4,1,2,5,26,2,1,1,2,1,3,6,2,1,1,1,1,1,1,2,3,1,1,1,9,2,3,1,1,
|
||||
1,3,6,3,2,1,1,6,6,1,8,2,2,2,1,4,1,2,3,2,7,3,2,4,1,2,1,2,2,1,1,1,1,1,3,1,2,5,4,10,9,4,9,1,1,1,1,1,1,5,3,2,1,6,4,9,6,1,10,2,31,17,8,3,7,5,40,1,
|
||||
7,7,1,6,5,2,10,7,8,4,15,39,25,6,28,47,18,10,7,1,3,1,1,2,1,1,1,3,3,3,1,1,1,3,4,2,1,4,1,3,6,10,7,8,6,2,2,1,3,3,2,5,8,7,9,12,2,15,1,1,4,1,2,1,1,
|
||||
1,3,2,1,3,3,5,6,2,3,2,10,1,4,2,8,1,1,1,11,6,1,21,4,16,3,1,3,1,4,2,3,6,5,1,3,1,1,3,3,4,6,1,1,10,4,2,7,10,4,7,4,2,9,4,3,1,1,1,4,1,8,3,4,1,3,1,
|
||||
6,1,4,2,1,4,7,2,1,8,1,4,5,1,1,2,2,4,6,2,7,1,10,1,1,3,4,11,10,8,21,4,6,1,3,5,2,1,2,28,5,5,2,3,13,1,2,3,1,4,2,1,5,20,3,8,11,1,3,3,3,1,8,10,9,2,
|
||||
10,9,2,3,1,1,2,4,1,8,3,6,1,7,8,6,11,1,4,29,8,4,3,1,2,7,13,1,4,1,6,2,6,12,12,2,20,3,2,3,6,4,8,9,2,7,34,5,1,18,6,1,1,4,4,5,7,9,1,2,2,4,3,4,1,7,
|
||||
2,2,2,6,2,3,25,5,3,6,1,4,6,7,4,2,1,4,2,13,6,4,4,3,1,5,3,4,4,3,2,1,1,4,1,2,1,1,3,1,11,1,6,3,1,7,3,6,2,8,8,6,9,3,4,11,3,2,10,12,2,5,11,1,6,4,5,
|
||||
3,1,8,5,4,6,6,3,5,1,1,3,2,1,2,2,6,17,12,1,10,1,6,12,1,6,6,19,9,6,16,1,13,4,4,15,7,17,6,11,9,15,12,6,7,2,1,2,2,15,9,3,21,4,6,49,18,7,3,2,3,1,
|
||||
6,8,2,2,6,2,9,1,3,6,4,4,1,2,16,2,5,2,1,6,2,3,5,3,1,2,5,1,2,1,9,3,1,8,6,4,8,11,3,1,1,1,1,3,1,13,8,4,1,3,2,2,1,4,1,11,1,5,2,1,5,2,5,8,6,1,1,7,
|
||||
4,3,8,3,2,7,2,1,5,1,5,2,4,7,6,2,8,5,1,11,4,5,3,6,18,1,2,13,3,3,1,21,1,1,4,1,4,1,1,1,8,1,2,2,7,1,2,4,2,2,9,2,1,1,1,4,3,6,3,12,5,1,1,1,5,6,3,2,
|
||||
4,8,2,2,4,2,7,1,8,9,5,2,3,2,1,3,2,13,7,14,6,5,1,1,2,1,4,2,23,2,1,1,6,3,1,4,1,15,3,1,7,3,9,14,1,3,1,4,1,1,5,8,1,3,8,3,8,15,11,4,14,4,4,2,5,5,
|
||||
1,7,1,6,14,7,7,8,5,15,4,8,6,5,6,2,1,13,1,20,15,11,9,2,5,6,2,11,2,6,2,5,1,5,8,4,13,19,25,4,1,1,11,1,34,2,5,9,14,6,2,2,6,1,1,14,1,3,14,13,1,6,
|
||||
12,21,14,14,6,32,17,8,32,9,28,1,2,4,11,8,3,1,14,2,5,15,1,1,1,1,3,6,4,1,3,4,11,3,1,1,11,30,1,5,1,4,1,5,8,1,1,3,2,4,3,17,35,2,6,12,17,3,1,6,2,
|
||||
1,1,12,2,7,3,3,2,1,16,2,8,3,6,5,4,7,3,3,8,1,9,8,5,1,2,1,3,2,8,1,2,9,12,1,1,2,3,8,3,24,12,4,3,7,5,8,3,3,3,3,3,3,1,23,10,3,1,2,2,6,3,1,16,1,16,
|
||||
22,3,10,4,11,6,9,7,7,3,6,2,2,2,4,10,2,1,1,2,8,7,1,6,4,1,3,3,3,5,10,12,12,2,3,12,8,15,1,1,16,6,6,1,5,9,11,4,11,4,2,6,12,1,17,5,13,1,4,9,5,1,11,
|
||||
2,1,8,1,5,7,28,8,3,5,10,2,17,3,38,22,1,2,18,12,10,4,38,18,1,4,44,19,4,1,8,4,1,12,1,4,31,12,1,14,7,75,7,5,10,6,6,13,3,2,11,11,3,2,5,28,15,6,18,
|
||||
18,5,6,4,3,16,1,7,18,7,36,3,5,3,1,7,1,9,1,10,7,2,4,2,6,2,9,7,4,3,32,12,3,7,10,2,23,16,3,1,12,3,31,4,11,1,3,8,9,5,1,30,15,6,12,3,2,2,11,19,9,
|
||||
14,2,6,2,3,19,13,17,5,3,3,25,3,14,1,1,1,36,1,3,2,19,3,13,36,9,13,31,6,4,16,34,2,5,4,2,3,3,5,1,1,1,4,3,1,17,3,2,3,5,3,1,3,2,3,5,6,3,12,11,1,3,
|
||||
1,2,26,7,12,7,2,14,3,3,7,7,11,25,25,28,16,4,36,1,2,1,6,2,1,9,3,27,17,4,3,4,13,4,1,3,2,2,1,10,4,2,4,6,3,8,2,1,18,1,1,24,2,2,4,33,2,3,63,7,1,6,
|
||||
40,7,3,4,4,2,4,15,18,1,16,1,1,11,2,41,14,1,3,18,13,3,2,4,16,2,17,7,15,24,7,18,13,44,2,2,3,6,1,1,7,5,1,7,1,4,3,3,5,10,8,2,3,1,8,1,1,27,4,2,1,
|
||||
12,1,2,1,10,6,1,6,7,5,2,3,7,11,5,11,3,6,6,2,3,15,4,9,1,1,2,1,2,11,2,8,12,8,5,4,2,3,1,5,2,2,1,14,1,12,11,4,1,11,17,17,4,3,2,5,5,7,3,1,5,9,9,8,
|
||||
2,5,6,6,13,13,2,1,2,6,1,2,2,49,4,9,1,2,10,16,7,8,4,3,2,23,4,58,3,29,1,14,19,19,11,11,2,7,5,1,3,4,6,2,18,5,12,12,17,17,3,3,2,4,1,6,2,3,4,3,1,
|
||||
1,1,1,5,1,1,9,1,3,1,3,6,1,8,1,1,2,6,4,14,3,1,4,11,4,1,3,32,1,2,4,13,4,1,2,4,2,1,3,1,11,1,4,2,1,4,4,6,3,5,1,6,5,7,6,3,23,3,5,3,5,3,3,13,3,9,10,
|
||||
1,12,10,2,3,18,13,7,160,52,4,2,2,3,2,14,5,4,12,4,6,4,1,20,4,11,6,2,12,27,1,4,1,2,2,7,4,5,2,28,3,7,25,8,3,19,3,6,10,2,2,1,10,2,5,4,1,3,4,1,5,
|
||||
3,2,6,9,3,6,2,16,3,3,16,4,5,5,3,2,1,2,16,15,8,2,6,21,2,4,1,22,5,8,1,1,21,11,2,1,11,11,19,13,12,4,2,3,2,3,6,1,8,11,1,4,2,9,5,2,1,11,2,9,1,1,2,
|
||||
14,31,9,3,4,21,14,4,8,1,7,2,2,2,5,1,4,20,3,3,4,10,1,11,9,8,2,1,4,5,14,12,14,2,17,9,6,31,4,14,1,20,13,26,5,2,7,3,6,13,2,4,2,19,6,2,2,18,9,3,5,
|
||||
12,12,14,4,6,2,3,6,9,5,22,4,5,25,6,4,8,5,2,6,27,2,35,2,16,3,7,8,8,6,6,5,9,17,2,20,6,19,2,13,3,1,1,1,4,17,12,2,14,7,1,4,18,12,38,33,2,10,1,1,
|
||||
2,13,14,17,11,50,6,33,20,26,74,16,23,45,50,13,38,33,6,6,7,4,4,2,1,3,2,5,8,7,8,9,3,11,21,9,13,1,3,10,6,7,1,2,2,18,5,5,1,9,9,2,68,9,19,13,2,5,
|
||||
1,4,4,7,4,13,3,9,10,21,17,3,26,2,1,5,2,4,5,4,1,7,4,7,3,4,2,1,6,1,1,20,4,1,9,2,2,1,3,3,2,3,2,1,1,1,20,2,3,1,6,2,3,6,2,4,8,1,3,2,10,3,5,3,4,4,
|
||||
3,4,16,1,6,1,10,2,4,2,1,1,2,10,11,2,2,3,1,24,31,4,10,10,2,5,12,16,164,15,4,16,7,9,15,19,17,1,2,1,1,5,1,1,1,1,1,3,1,4,3,1,3,1,3,1,2,1,1,3,3,7,
|
||||
2,8,1,2,2,2,1,3,4,3,7,8,12,92,2,10,3,1,3,14,5,25,16,42,4,7,7,4,2,21,5,27,26,27,21,25,30,31,2,1,5,13,3,22,5,6,6,11,9,12,1,5,9,7,5,5,22,60,3,5,
|
||||
13,1,1,8,1,1,3,3,2,1,9,3,3,18,4,1,2,3,7,6,3,1,2,3,9,1,3,1,3,2,1,3,1,1,1,2,1,11,3,1,6,9,1,3,2,3,1,2,1,5,1,1,4,3,4,1,2,2,4,4,1,7,2,1,2,2,3,5,13,
|
||||
18,3,4,14,9,9,4,16,3,7,5,8,2,6,48,28,3,1,1,4,2,14,8,2,9,2,1,15,2,4,3,2,10,16,12,8,7,1,1,3,1,1,1,2,7,4,1,6,4,38,39,16,23,7,15,15,3,2,12,7,21,
|
||||
37,27,6,5,4,8,2,10,8,8,6,5,1,2,1,3,24,1,16,17,9,23,10,17,6,1,51,55,44,13,294,9,3,6,2,4,2,2,15,1,1,1,13,21,17,68,14,8,9,4,1,4,9,3,11,7,1,1,1,
|
||||
5,6,3,2,1,1,1,2,3,8,1,2,2,4,1,5,5,2,1,4,3,7,13,4,1,4,1,3,1,1,1,5,5,10,1,6,1,5,2,1,5,2,4,1,4,5,7,3,18,2,9,11,32,4,3,3,2,4,7,11,16,9,11,8,13,38,
|
||||
32,8,4,2,1,1,2,1,2,4,4,1,1,1,4,1,21,3,11,1,16,1,1,6,1,3,2,4,9,8,57,7,44,1,3,3,13,3,10,1,1,7,5,2,7,21,47,63,3,15,4,7,1,16,1,1,2,8,2,3,42,15,4,
|
||||
1,29,7,22,10,3,78,16,12,20,18,4,67,11,5,1,3,15,6,21,31,32,27,18,13,71,35,5,142,4,10,1,2,50,19,33,16,35,37,16,19,27,7,1,133,19,1,4,8,7,20,1,4,
|
||||
4,1,10,3,1,6,1,2,51,5,40,15,24,43,22928,11,1,13,154,70,3,1,1,7,4,10,1,2,1,1,2,1,2,1,2,2,1,1,2,1,1,1,1,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,2,1,1,1,
|
||||
3,2,1,1,1,1,2,1,1,
|
||||
};
|
||||
static ImWchar base_ranges[] = // not zero-terminated
|
||||
{
|
||||
680
external/ImGui/source/imgui_freetype.cpp
vendored
Normal file
680
external/ImGui/source/imgui_freetype.cpp
vendored
Normal file
@@ -0,0 +1,680 @@
|
||||
// dear imgui: wrapper to use FreeType (instead of stb_truetype)
|
||||
// Get latest version at https://github.com/ocornut/imgui/tree/master/misc/freetype
|
||||
// Original code by @vuhdo (Aleksei Skriabin). Improvements by @mikesart. Maintained and v0.60+ by @ocornut.
|
||||
|
||||
// Changelog:
|
||||
// - v0.50: (2017/08/16) imported from https://github.com/Vuhdo/imgui_freetype into http://www.github.com/ocornut/imgui_club, updated for latest changes in ImFontAtlas, minor tweaks.
|
||||
// - v0.51: (2017/08/26) cleanup, optimizations, support for ImFontConfig::RasterizerFlags, ImFontConfig::RasterizerMultiply.
|
||||
// - v0.52: (2017/09/26) fixes for imgui internal changes.
|
||||
// - v0.53: (2017/10/22) minor inconsequential change to match change in master (removed an unnecessary statement).
|
||||
// - v0.54: (2018/01/22) fix for addition of ImFontAtlas::TexUvscale member.
|
||||
// - v0.55: (2018/02/04) moved to main imgui repository (away from http://www.github.com/ocornut/imgui_club)
|
||||
// - v0.56: (2018/06/08) added support for ImFontConfig::GlyphMinAdvanceX, GlyphMaxAdvanceX.
|
||||
// - v0.60: (2019/01/10) re-factored to match big update in STB builder. fixed texture height waste. fixed redundant glyphs when merging. support for glyph padding.
|
||||
// - v0.61: (2019/01/15) added support for imgui allocators + added FreeType only override function SetAllocatorFunctions().
|
||||
// - v0.62: (2019/02/09) added RasterizerFlags::Monochrome flag to disable font anti-aliasing (combine with ::MonoHinting for best results!)
|
||||
// - v0.63: (2020/06/04) fix for rare case where FT_Get_Char_Index() succeed but FT_Load_Glyph() fails.
|
||||
|
||||
// Gamma Correct Blending:
|
||||
// FreeType assumes blending in linear space rather than gamma space.
|
||||
// See https://www.freetype.org/freetype2/docs/reference/ft2-base_interface.html#FT_Render_Glyph
|
||||
// For correct results you need to be using sRGB and convert to linear space in the pixel shader output.
|
||||
// The default imgui styles will be impacted by this change (alpha values will need tweaking).
|
||||
|
||||
// FIXME: cfg.OversampleH, OversampleV are not supported (but perhaps not so necessary with this rasterizer).
|
||||
|
||||
#include "imgui_freetype.h"
|
||||
#include "imgui_internal.h" // ImMin,ImMax,ImFontAtlasBuild*,
|
||||
#include <stdint.h>
|
||||
#include <ft2build.h>
|
||||
#include FT_FREETYPE_H // <freetype/freetype.h>
|
||||
#include FT_MODULE_H // <freetype/ftmodapi.h>
|
||||
#include FT_GLYPH_H // <freetype/ftglyph.h>
|
||||
#include FT_SYNTHESIS_H // <freetype/ftsynth.h>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning (disable: 4505) // unreferenced local function has been removed (stb stuff)
|
||||
#endif
|
||||
|
||||
#if 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
|
||||
#endif
|
||||
|
||||
namespace
|
||||
{
|
||||
// Glyph metrics:
|
||||
// --------------
|
||||
//
|
||||
// xmin xmax
|
||||
// | |
|
||||
// |<-------- width -------->|
|
||||
// | |
|
||||
// | +-------------------------+----------------- ymax
|
||||
// | | ggggggggg ggggg | ^ ^
|
||||
// | | g:::::::::ggg::::g | | |
|
||||
// | | g:::::::::::::::::g | | |
|
||||
// | | g::::::ggggg::::::gg | | |
|
||||
// | | g:::::g g:::::g | | |
|
||||
// offsetX -|-------->| g:::::g g:::::g | offsetY |
|
||||
// | | g:::::g g:::::g | | |
|
||||
// | | g::::::g g:::::g | | |
|
||||
// | | g:::::::ggggg:::::g | | |
|
||||
// | | g::::::::::::::::g | | height
|
||||
// | | gg::::::::::::::g | | |
|
||||
// baseline ---*---------|---- gggggggg::::::g-----*-------- |
|
||||
// / | | g:::::g | |
|
||||
// origin | | gggggg g:::::g | |
|
||||
// | | g:::::gg gg:::::g | |
|
||||
// | | g::::::ggg:::::::g | |
|
||||
// | | gg:::::::::::::g | |
|
||||
// | | ggg::::::ggg | |
|
||||
// | | gggggg | v
|
||||
// | +-------------------------+----------------- ymin
|
||||
// | |
|
||||
// |------------- advanceX ----------->|
|
||||
|
||||
/// A structure that describe a glyph.
|
||||
struct GlyphInfo
|
||||
{
|
||||
int Width; // Glyph's width in pixels.
|
||||
int Height; // Glyph's height in pixels.
|
||||
FT_Int OffsetX; // The distance from the origin ("pen position") to the left of the glyph.
|
||||
FT_Int OffsetY; // The distance from the origin to the top of the glyph. This is usually a value < 0.
|
||||
float AdvanceX; // The distance from the origin to the origin of the next glyph. This is usually a value > 0.
|
||||
};
|
||||
|
||||
// Font parameters and metrics.
|
||||
struct FontInfo
|
||||
{
|
||||
uint32_t PixelHeight; // Size this font was generated with.
|
||||
float Ascender; // The pixel extents above the baseline in pixels (typically positive).
|
||||
float Descender; // The extents below the baseline in pixels (typically negative).
|
||||
float LineSpacing; // The baseline-to-baseline distance. Note that it usually is larger than the sum of the ascender and descender taken as absolute values. There is also no guarantee that no glyphs extend above or below subsequent baselines when using this distance. Think of it as a value the designer of the font finds appropriate.
|
||||
float LineGap; // The spacing in pixels between one row's descent and the next row's ascent.
|
||||
float MaxAdvanceWidth; // This field gives the maximum horizontal cursor advance for all glyphs in the font.
|
||||
};
|
||||
|
||||
// FreeType glyph rasterizer.
|
||||
// NB: No ctor/dtor, explicitly call Init()/Shutdown()
|
||||
struct FreeTypeFont
|
||||
{
|
||||
bool InitFont(FT_Library ft_library, const ImFontConfig& cfg, unsigned int extra_user_flags); // Initialize from an external data buffer. Doesn't copy data, and you must ensure it stays valid up to this object lifetime.
|
||||
void CloseFont();
|
||||
void SetPixelHeight(int pixel_height); // Change font pixel size. All following calls to RasterizeGlyph() will use this size
|
||||
const FT_Glyph_Metrics* LoadGlyph(uint32_t in_codepoint);
|
||||
const FT_Bitmap* RenderGlyphAndGetInfo(GlyphInfo* out_glyph_info);
|
||||
void BlitGlyph(const FT_Bitmap* ft_bitmap, uint8_t* dst, uint32_t dst_pitch, unsigned char* multiply_table = NULL);
|
||||
~FreeTypeFont() { CloseFont(); }
|
||||
|
||||
// [Internals]
|
||||
FontInfo Info; // Font descriptor of the current font.
|
||||
FT_Face Face;
|
||||
unsigned int UserFlags; // = ImFontConfig::RasterizerFlags
|
||||
FT_Int32 LoadFlags;
|
||||
FT_Render_Mode RenderMode;
|
||||
};
|
||||
|
||||
// From SDL_ttf: Handy routines for converting from fixed point
|
||||
#define FT_CEIL(X) (((X + 63) & -64) / 64)
|
||||
|
||||
bool FreeTypeFont::InitFont(FT_Library ft_library, const ImFontConfig& cfg, unsigned int extra_user_flags)
|
||||
{
|
||||
FT_Error error = FT_New_Memory_Face(ft_library, (uint8_t*)cfg.FontData, (uint32_t)cfg.FontDataSize, (uint32_t)cfg.FontNo, &Face);
|
||||
if (error != 0)
|
||||
return false;
|
||||
error = FT_Select_Charmap(Face, FT_ENCODING_UNICODE);
|
||||
if (error != 0)
|
||||
return false;
|
||||
|
||||
memset(&Info, 0, sizeof(Info));
|
||||
SetPixelHeight((uint32_t)cfg.SizePixels);
|
||||
|
||||
// Convert to FreeType flags (NB: Bold and Oblique are processed separately)
|
||||
UserFlags = cfg.RasterizerFlags | extra_user_flags;
|
||||
LoadFlags = FT_LOAD_NO_BITMAP;
|
||||
if (UserFlags & ImGuiFreeType::NoHinting)
|
||||
LoadFlags |= FT_LOAD_NO_HINTING;
|
||||
if (UserFlags & ImGuiFreeType::NoAutoHint)
|
||||
LoadFlags |= FT_LOAD_NO_AUTOHINT;
|
||||
if (UserFlags & ImGuiFreeType::ForceAutoHint)
|
||||
LoadFlags |= FT_LOAD_FORCE_AUTOHINT;
|
||||
if (UserFlags & ImGuiFreeType::LightHinting)
|
||||
LoadFlags |= FT_LOAD_TARGET_LIGHT;
|
||||
else if (UserFlags & ImGuiFreeType::MonoHinting)
|
||||
LoadFlags |= FT_LOAD_TARGET_MONO;
|
||||
else
|
||||
LoadFlags |= FT_LOAD_TARGET_NORMAL;
|
||||
|
||||
if (UserFlags & ImGuiFreeType::Monochrome)
|
||||
RenderMode = FT_RENDER_MODE_MONO;
|
||||
else
|
||||
RenderMode = FT_RENDER_MODE_NORMAL;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void FreeTypeFont::CloseFont()
|
||||
{
|
||||
if (Face)
|
||||
{
|
||||
FT_Done_Face(Face);
|
||||
Face = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void FreeTypeFont::SetPixelHeight(int pixel_height)
|
||||
{
|
||||
// Vuhdo: I'm not sure how to deal with font sizes properly. As far as I understand, currently ImGui assumes that the 'pixel_height'
|
||||
// is a maximum height of an any given glyph, i.e. it's the sum of font's ascender and descender. Seems strange to me.
|
||||
// NB: FT_Set_Pixel_Sizes() doesn't seem to get us the same result.
|
||||
FT_Size_RequestRec req;
|
||||
req.type = FT_SIZE_REQUEST_TYPE_REAL_DIM;
|
||||
req.width = 0;
|
||||
req.height = (uint32_t)pixel_height * 64;
|
||||
req.horiResolution = 0;
|
||||
req.vertResolution = 0;
|
||||
FT_Request_Size(Face, &req);
|
||||
|
||||
// Update font info
|
||||
FT_Size_Metrics metrics = Face->size->metrics;
|
||||
Info.PixelHeight = (uint32_t)pixel_height;
|
||||
Info.Ascender = (float)FT_CEIL(metrics.ascender);
|
||||
Info.Descender = (float)FT_CEIL(metrics.descender);
|
||||
Info.LineSpacing = (float)FT_CEIL(metrics.height);
|
||||
Info.LineGap = (float)FT_CEIL(metrics.height - metrics.ascender + metrics.descender);
|
||||
Info.MaxAdvanceWidth = (float)FT_CEIL(metrics.max_advance);
|
||||
}
|
||||
|
||||
const FT_Glyph_Metrics* FreeTypeFont::LoadGlyph(uint32_t codepoint)
|
||||
{
|
||||
uint32_t glyph_index = FT_Get_Char_Index(Face, codepoint);
|
||||
if (glyph_index == 0)
|
||||
return NULL;
|
||||
FT_Error error = FT_Load_Glyph(Face, glyph_index, LoadFlags);
|
||||
if (error)
|
||||
return NULL;
|
||||
|
||||
// Need an outline for this to work
|
||||
FT_GlyphSlot slot = Face->glyph;
|
||||
IM_ASSERT(slot->format == FT_GLYPH_FORMAT_OUTLINE);
|
||||
|
||||
// Apply convenience transform (this is not picking from real "Bold"/"Italic" fonts! Merely applying FreeType helper transform. Oblique == Slanting)
|
||||
if (UserFlags & ImGuiFreeType::Bold)
|
||||
FT_GlyphSlot_Embolden(slot);
|
||||
if (UserFlags & ImGuiFreeType::Oblique)
|
||||
{
|
||||
FT_GlyphSlot_Oblique(slot);
|
||||
//FT_BBox bbox;
|
||||
//FT_Outline_Get_BBox(&slot->outline, &bbox);
|
||||
//slot->metrics.width = bbox.xMax - bbox.xMin;
|
||||
//slot->metrics.height = bbox.yMax - bbox.yMin;
|
||||
}
|
||||
|
||||
return &slot->metrics;
|
||||
}
|
||||
|
||||
const FT_Bitmap* FreeTypeFont::RenderGlyphAndGetInfo(GlyphInfo* out_glyph_info)
|
||||
{
|
||||
FT_GlyphSlot slot = Face->glyph;
|
||||
FT_Error error = FT_Render_Glyph(slot, RenderMode);
|
||||
if (error != 0)
|
||||
return NULL;
|
||||
|
||||
FT_Bitmap* ft_bitmap = &Face->glyph->bitmap;
|
||||
out_glyph_info->Width = (int)ft_bitmap->width;
|
||||
out_glyph_info->Height = (int)ft_bitmap->rows;
|
||||
out_glyph_info->OffsetX = Face->glyph->bitmap_left;
|
||||
out_glyph_info->OffsetY = -Face->glyph->bitmap_top;
|
||||
out_glyph_info->AdvanceX = (float)FT_CEIL(slot->advance.x);
|
||||
|
||||
return ft_bitmap;
|
||||
}
|
||||
|
||||
void FreeTypeFont::BlitGlyph(const FT_Bitmap* ft_bitmap, uint8_t* dst, uint32_t dst_pitch, unsigned char* multiply_table)
|
||||
{
|
||||
IM_ASSERT(ft_bitmap != NULL);
|
||||
const uint32_t w = ft_bitmap->width;
|
||||
const uint32_t h = ft_bitmap->rows;
|
||||
const uint8_t* src = ft_bitmap->buffer;
|
||||
const uint32_t src_pitch = ft_bitmap->pitch;
|
||||
|
||||
switch (ft_bitmap->pixel_mode)
|
||||
{
|
||||
case FT_PIXEL_MODE_GRAY: // Grayscale image, 1 byte per pixel.
|
||||
{
|
||||
if (multiply_table == NULL)
|
||||
{
|
||||
for (uint32_t y = 0; y < h; y++, src += src_pitch, dst += dst_pitch)
|
||||
memcpy(dst, src, w);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (uint32_t y = 0; y < h; y++, src += src_pitch, dst += dst_pitch)
|
||||
for (uint32_t x = 0; x < w; x++)
|
||||
dst[x] = multiply_table[src[x]];
|
||||
}
|
||||
break;
|
||||
}
|
||||
case FT_PIXEL_MODE_MONO: // Monochrome image, 1 bit per pixel. The bits in each byte are ordered from MSB to LSB.
|
||||
{
|
||||
uint8_t color0 = multiply_table ? multiply_table[0] : 0;
|
||||
uint8_t color1 = multiply_table ? multiply_table[255] : 255;
|
||||
for (uint32_t y = 0; y < h; y++, src += src_pitch, dst += dst_pitch)
|
||||
{
|
||||
uint8_t bits = 0;
|
||||
const uint8_t* bits_ptr = src;
|
||||
for (uint32_t x = 0; x < w; x++, bits <<= 1)
|
||||
{
|
||||
if ((x & 7) == 0)
|
||||
bits = *bits_ptr++;
|
||||
dst[x] = (bits & 0x80) ? color1 : color0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
IM_ASSERT(0 && "FreeTypeFont::BlitGlyph(): Unknown bitmap pixel mode!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef STB_RECT_PACK_IMPLEMENTATION // in case the user already have an implementation in the _same_ compilation unit (e.g. unity builds)
|
||||
#ifndef IMGUI_DISABLE_STB_RECT_PACK_IMPLEMENTATION
|
||||
#define STBRP_ASSERT(x) do { IM_ASSERT(x); } while (0)
|
||||
#define STBRP_STATIC
|
||||
#define STB_RECT_PACK_IMPLEMENTATION
|
||||
#endif
|
||||
#ifdef IMGUI_STB_RECT_PACK_FILENAME
|
||||
#include IMGUI_STB_RECT_PACK_FILENAME
|
||||
#else
|
||||
#include "imstb_rectpack.h"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
struct ImFontBuildSrcGlyphFT
|
||||
{
|
||||
GlyphInfo Info;
|
||||
uint32_t Codepoint;
|
||||
unsigned char* BitmapData; // Point within one of the dst_tmp_bitmap_buffers[] array
|
||||
};
|
||||
|
||||
struct ImFontBuildSrcDataFT
|
||||
{
|
||||
FreeTypeFont Font;
|
||||
stbrp_rect* Rects; // Rectangle to pack. We first fill in their size and the packer will give us their position.
|
||||
const ImWchar* SrcRanges; // Ranges as requested by user (user is allowed to request too much, e.g. 0x0020..0xFFFF)
|
||||
int DstIndex; // Index into atlas->Fonts[] and dst_tmp_array[]
|
||||
int GlyphsHighest; // Highest requested codepoint
|
||||
int GlyphsCount; // Glyph count (excluding missing glyphs and glyphs already set by an earlier source font)
|
||||
ImBitVector GlyphsSet; // Glyph bit map (random access, 1-bit per codepoint. This will be a maximum of 8KB)
|
||||
ImVector<ImFontBuildSrcGlyphFT> GlyphsList;
|
||||
};
|
||||
|
||||
// Temporary data for one destination ImFont* (multiple source fonts can be merged into one destination ImFont)
|
||||
struct ImFontBuildDstDataFT
|
||||
{
|
||||
int SrcCount; // Number of source fonts targeting this destination font.
|
||||
int GlyphsHighest;
|
||||
int GlyphsCount;
|
||||
ImBitVector GlyphsSet; // This is used to resolve collision when multiple sources are merged into a same destination font.
|
||||
};
|
||||
|
||||
bool ImFontAtlasBuildWithFreeType(FT_Library ft_library, ImFontAtlas* atlas, unsigned int extra_flags)
|
||||
{
|
||||
IM_ASSERT(atlas->ConfigData.Size > 0);
|
||||
|
||||
ImFontAtlasBuildInit(atlas);
|
||||
|
||||
// Clear atlas
|
||||
atlas->TexID = (ImTextureID)NULL;
|
||||
atlas->TexWidth = atlas->TexHeight = 0;
|
||||
atlas->TexUvScale = ImVec2(0.0f, 0.0f);
|
||||
atlas->TexUvWhitePixel = ImVec2(0.0f, 0.0f);
|
||||
atlas->ClearTexData();
|
||||
|
||||
// Temporary storage for building
|
||||
ImVector<ImFontBuildSrcDataFT> src_tmp_array;
|
||||
ImVector<ImFontBuildDstDataFT> dst_tmp_array;
|
||||
src_tmp_array.resize(atlas->ConfigData.Size);
|
||||
dst_tmp_array.resize(atlas->Fonts.Size);
|
||||
memset((void*)src_tmp_array.Data, 0, (size_t)src_tmp_array.size_in_bytes());
|
||||
memset((void*)dst_tmp_array.Data, 0, (size_t)dst_tmp_array.size_in_bytes());
|
||||
|
||||
// 1. Initialize font loading structure, check font data validity
|
||||
for (int src_i = 0; src_i < atlas->ConfigData.Size; src_i++)
|
||||
{
|
||||
ImFontBuildSrcDataFT& src_tmp = src_tmp_array[src_i];
|
||||
ImFontConfig& cfg = atlas->ConfigData[src_i];
|
||||
FreeTypeFont& font_face = src_tmp.Font;
|
||||
IM_ASSERT(cfg.DstFont && (!cfg.DstFont->IsLoaded() || cfg.DstFont->ContainerAtlas == atlas));
|
||||
|
||||
// Find index from cfg.DstFont (we allow the user to set cfg.DstFont. Also it makes casual debugging nicer than when storing indices)
|
||||
src_tmp.DstIndex = -1;
|
||||
for (int output_i = 0; output_i < atlas->Fonts.Size && src_tmp.DstIndex == -1; output_i++)
|
||||
if (cfg.DstFont == atlas->Fonts[output_i])
|
||||
src_tmp.DstIndex = output_i;
|
||||
IM_ASSERT(src_tmp.DstIndex != -1); // cfg.DstFont not pointing within atlas->Fonts[] array?
|
||||
if (src_tmp.DstIndex == -1)
|
||||
return false;
|
||||
|
||||
// Load font
|
||||
if (!font_face.InitFont(ft_library, cfg, extra_flags))
|
||||
return false;
|
||||
|
||||
// Measure highest codepoints
|
||||
ImFontBuildDstDataFT& dst_tmp = dst_tmp_array[src_tmp.DstIndex];
|
||||
src_tmp.SrcRanges = cfg.GlyphRanges ? cfg.GlyphRanges : atlas->GetGlyphRangesDefault();
|
||||
for (const ImWchar* src_range = src_tmp.SrcRanges; src_range[0] && src_range[1]; src_range += 2)
|
||||
src_tmp.GlyphsHighest = ImMax(src_tmp.GlyphsHighest, (int)src_range[1]);
|
||||
dst_tmp.SrcCount++;
|
||||
dst_tmp.GlyphsHighest = ImMax(dst_tmp.GlyphsHighest, src_tmp.GlyphsHighest);
|
||||
}
|
||||
|
||||
// 2. For every requested codepoint, check for their presence in the font data, and handle redundancy or overlaps between source fonts to avoid unused glyphs.
|
||||
int total_glyphs_count = 0;
|
||||
for (int src_i = 0; src_i < src_tmp_array.Size; src_i++)
|
||||
{
|
||||
ImFontBuildSrcDataFT& src_tmp = src_tmp_array[src_i];
|
||||
ImFontBuildDstDataFT& dst_tmp = dst_tmp_array[src_tmp.DstIndex];
|
||||
src_tmp.GlyphsSet.Create(src_tmp.GlyphsHighest + 1);
|
||||
if (dst_tmp.GlyphsSet.Storage.empty())
|
||||
dst_tmp.GlyphsSet.Create(dst_tmp.GlyphsHighest + 1);
|
||||
|
||||
for (const ImWchar* src_range = src_tmp.SrcRanges; src_range[0] && src_range[1]; src_range += 2)
|
||||
for (int codepoint = src_range[0]; codepoint <= (int)src_range[1]; codepoint++)
|
||||
{
|
||||
if (dst_tmp.GlyphsSet.TestBit(codepoint)) // Don't overwrite existing glyphs. We could make this an option (e.g. MergeOverwrite)
|
||||
continue;
|
||||
uint32_t glyph_index = FT_Get_Char_Index(src_tmp.Font.Face, codepoint); // It is actually in the font? (FIXME-OPT: We are not storing the glyph_index..)
|
||||
if (glyph_index == 0)
|
||||
continue;
|
||||
|
||||
// Add to avail set/counters
|
||||
src_tmp.GlyphsCount++;
|
||||
dst_tmp.GlyphsCount++;
|
||||
src_tmp.GlyphsSet.SetBit(codepoint);
|
||||
dst_tmp.GlyphsSet.SetBit(codepoint);
|
||||
total_glyphs_count++;
|
||||
}
|
||||
}
|
||||
|
||||
// 3. Unpack our bit map into a flat list (we now have all the Unicode points that we know are requested _and_ available _and_ not overlapping another)
|
||||
for (int src_i = 0; src_i < src_tmp_array.Size; src_i++)
|
||||
{
|
||||
ImFontBuildSrcDataFT& src_tmp = src_tmp_array[src_i];
|
||||
src_tmp.GlyphsList.reserve(src_tmp.GlyphsCount);
|
||||
|
||||
IM_ASSERT(sizeof(src_tmp.GlyphsSet.Storage.Data[0]) == sizeof(ImU32));
|
||||
const ImU32* it_begin = src_tmp.GlyphsSet.Storage.begin();
|
||||
const ImU32* it_end = src_tmp.GlyphsSet.Storage.end();
|
||||
for (const ImU32* it = it_begin; it < it_end; it++)
|
||||
if (ImU32 entries_32 = *it)
|
||||
for (ImU32 bit_n = 0; bit_n < 32; bit_n++)
|
||||
if (entries_32 & ((ImU32)1 << bit_n))
|
||||
{
|
||||
ImFontBuildSrcGlyphFT src_glyph;
|
||||
memset(&src_glyph, 0, sizeof(src_glyph));
|
||||
src_glyph.Codepoint = (ImWchar)(((it - it_begin) << 5) + bit_n);
|
||||
//src_glyph.GlyphIndex = 0; // FIXME-OPT: We had this info in the previous step and lost it..
|
||||
src_tmp.GlyphsList.push_back(src_glyph);
|
||||
}
|
||||
src_tmp.GlyphsSet.Clear();
|
||||
IM_ASSERT(src_tmp.GlyphsList.Size == src_tmp.GlyphsCount);
|
||||
}
|
||||
for (int dst_i = 0; dst_i < dst_tmp_array.Size; dst_i++)
|
||||
dst_tmp_array[dst_i].GlyphsSet.Clear();
|
||||
dst_tmp_array.clear();
|
||||
|
||||
// Allocate packing character data and flag packed characters buffer as non-packed (x0=y0=x1=y1=0)
|
||||
// (We technically don't need to zero-clear buf_rects, but let's do it for the sake of sanity)
|
||||
ImVector<stbrp_rect> buf_rects;
|
||||
buf_rects.resize(total_glyphs_count);
|
||||
memset(buf_rects.Data, 0, (size_t)buf_rects.size_in_bytes());
|
||||
|
||||
// Allocate temporary rasterization data buffers.
|
||||
// We could not find a way to retrieve accurate glyph size without rendering them.
|
||||
// (e.g. slot->metrics->width not always matching bitmap->width, especially considering the Oblique transform)
|
||||
// We allocate in chunks of 256 KB to not waste too much extra memory ahead. Hopefully users of FreeType won't find the temporary allocations.
|
||||
const int BITMAP_BUFFERS_CHUNK_SIZE = 256 * 1024;
|
||||
int buf_bitmap_current_used_bytes = 0;
|
||||
ImVector<unsigned char*> buf_bitmap_buffers;
|
||||
buf_bitmap_buffers.push_back((unsigned char*)IM_ALLOC(BITMAP_BUFFERS_CHUNK_SIZE));
|
||||
|
||||
// 4. Gather glyphs sizes so we can pack them in our virtual canvas.
|
||||
// 8. Render/rasterize font characters into the texture
|
||||
int total_surface = 0;
|
||||
int buf_rects_out_n = 0;
|
||||
for (int src_i = 0; src_i < src_tmp_array.Size; src_i++)
|
||||
{
|
||||
ImFontBuildSrcDataFT& src_tmp = src_tmp_array[src_i];
|
||||
ImFontConfig& cfg = atlas->ConfigData[src_i];
|
||||
if (src_tmp.GlyphsCount == 0)
|
||||
continue;
|
||||
|
||||
src_tmp.Rects = &buf_rects[buf_rects_out_n];
|
||||
buf_rects_out_n += src_tmp.GlyphsCount;
|
||||
|
||||
// Compute multiply table if requested
|
||||
const bool multiply_enabled = (cfg.RasterizerMultiply != 1.0f);
|
||||
unsigned char multiply_table[256];
|
||||
if (multiply_enabled)
|
||||
ImFontAtlasBuildMultiplyCalcLookupTable(multiply_table, cfg.RasterizerMultiply);
|
||||
|
||||
// Gather the sizes of all rectangles we will need to pack
|
||||
const int padding = atlas->TexGlyphPadding;
|
||||
for (int glyph_i = 0; glyph_i < src_tmp.GlyphsList.Size; glyph_i++)
|
||||
{
|
||||
ImFontBuildSrcGlyphFT& src_glyph = src_tmp.GlyphsList[glyph_i];
|
||||
|
||||
const FT_Glyph_Metrics* metrics = src_tmp.Font.LoadGlyph(src_glyph.Codepoint);
|
||||
if (metrics == NULL)
|
||||
continue;
|
||||
|
||||
// Render glyph into a bitmap (currently held by FreeType)
|
||||
const FT_Bitmap* ft_bitmap = src_tmp.Font.RenderGlyphAndGetInfo(&src_glyph.Info);
|
||||
IM_ASSERT(ft_bitmap);
|
||||
|
||||
// Allocate new temporary chunk if needed
|
||||
const int bitmap_size_in_bytes = src_glyph.Info.Width * src_glyph.Info.Height;
|
||||
if (buf_bitmap_current_used_bytes + bitmap_size_in_bytes > BITMAP_BUFFERS_CHUNK_SIZE)
|
||||
{
|
||||
buf_bitmap_current_used_bytes = 0;
|
||||
buf_bitmap_buffers.push_back((unsigned char*)IM_ALLOC(BITMAP_BUFFERS_CHUNK_SIZE));
|
||||
}
|
||||
|
||||
// Blit rasterized pixels to our temporary buffer and keep a pointer to it.
|
||||
src_glyph.BitmapData = buf_bitmap_buffers.back() + buf_bitmap_current_used_bytes;
|
||||
buf_bitmap_current_used_bytes += bitmap_size_in_bytes;
|
||||
src_tmp.Font.BlitGlyph(ft_bitmap, src_glyph.BitmapData, src_glyph.Info.Width * 1, multiply_enabled ? multiply_table : NULL);
|
||||
|
||||
src_tmp.Rects[glyph_i].w = (stbrp_coord)(src_glyph.Info.Width + padding);
|
||||
src_tmp.Rects[glyph_i].h = (stbrp_coord)(src_glyph.Info.Height + padding);
|
||||
total_surface += src_tmp.Rects[glyph_i].w * src_tmp.Rects[glyph_i].h;
|
||||
}
|
||||
}
|
||||
|
||||
// We need a width for the skyline algorithm, any width!
|
||||
// The exact width doesn't really matter much, but some API/GPU have texture size limitations and increasing width can decrease height.
|
||||
// User can override TexDesiredWidth and TexGlyphPadding if they wish, otherwise we use a simple heuristic to select the width based on expected surface.
|
||||
const int surface_sqrt = (int)ImSqrt((float)total_surface) + 1;
|
||||
atlas->TexHeight = 0;
|
||||
if (atlas->TexDesiredWidth > 0)
|
||||
atlas->TexWidth = atlas->TexDesiredWidth;
|
||||
else
|
||||
atlas->TexWidth = (surface_sqrt >= 4096 * 0.7f) ? 4096 : (surface_sqrt >= 2048 * 0.7f) ? 2048 : (surface_sqrt >= 1024 * 0.7f) ? 1024 : 512;
|
||||
|
||||
// 5. Start packing
|
||||
// Pack our extra data rectangles first, so it will be on the upper-left corner of our texture (UV will have small values).
|
||||
const int TEX_HEIGHT_MAX = 1024 * 32;
|
||||
const int num_nodes_for_packing_algorithm = atlas->TexWidth - atlas->TexGlyphPadding;
|
||||
ImVector<stbrp_node> pack_nodes;
|
||||
pack_nodes.resize(num_nodes_for_packing_algorithm);
|
||||
stbrp_context pack_context;
|
||||
stbrp_init_target(&pack_context, atlas->TexWidth, TEX_HEIGHT_MAX, pack_nodes.Data, pack_nodes.Size);
|
||||
ImFontAtlasBuildPackCustomRects(atlas, &pack_context);
|
||||
|
||||
// 6. Pack each source font. No rendering yet, we are working with rectangles in an infinitely tall texture at this point.
|
||||
for (int src_i = 0; src_i < src_tmp_array.Size; src_i++)
|
||||
{
|
||||
ImFontBuildSrcDataFT& src_tmp = src_tmp_array[src_i];
|
||||
if (src_tmp.GlyphsCount == 0)
|
||||
continue;
|
||||
|
||||
stbrp_pack_rects(&pack_context, src_tmp.Rects, src_tmp.GlyphsCount);
|
||||
|
||||
// Extend texture height and mark missing glyphs as non-packed so we won't render them.
|
||||
// FIXME: We are not handling packing failure here (would happen if we got off TEX_HEIGHT_MAX or if a single if larger than TexWidth?)
|
||||
for (int glyph_i = 0; glyph_i < src_tmp.GlyphsCount; glyph_i++)
|
||||
if (src_tmp.Rects[glyph_i].was_packed)
|
||||
atlas->TexHeight = ImMax(atlas->TexHeight, src_tmp.Rects[glyph_i].y + src_tmp.Rects[glyph_i].h);
|
||||
}
|
||||
|
||||
// 7. Allocate texture
|
||||
atlas->TexHeight = (atlas->Flags & ImFontAtlasFlags_NoPowerOfTwoHeight) ? (atlas->TexHeight + 1) : ImUpperPowerOfTwo(atlas->TexHeight);
|
||||
atlas->TexUvScale = ImVec2(1.0f / atlas->TexWidth, 1.0f / atlas->TexHeight);
|
||||
atlas->TexPixelsAlpha8 = (unsigned char*)IM_ALLOC(atlas->TexWidth * atlas->TexHeight);
|
||||
memset(atlas->TexPixelsAlpha8, 0, atlas->TexWidth * atlas->TexHeight);
|
||||
|
||||
// 8. Copy rasterized font characters back into the main texture
|
||||
// 9. Setup ImFont and glyphs for runtime
|
||||
for (int src_i = 0; src_i < src_tmp_array.Size; src_i++)
|
||||
{
|
||||
ImFontBuildSrcDataFT& src_tmp = src_tmp_array[src_i];
|
||||
if (src_tmp.GlyphsCount == 0)
|
||||
continue;
|
||||
|
||||
// When merging fonts with MergeMode=true:
|
||||
// - We can have multiple input fonts writing into a same destination font.
|
||||
// - dst_font->ConfigData is != from cfg which is our source configuration.
|
||||
ImFontConfig& cfg = atlas->ConfigData[src_i];
|
||||
ImFont* dst_font = cfg.DstFont;
|
||||
|
||||
const float ascent = src_tmp.Font.Info.Ascender;
|
||||
const float descent = src_tmp.Font.Info.Descender;
|
||||
ImFontAtlasBuildSetupFont(atlas, dst_font, &cfg, ascent, descent);
|
||||
const float font_off_x = cfg.GlyphOffset.x;
|
||||
const float font_off_y = cfg.GlyphOffset.y + IM_ROUND(dst_font->Ascent);
|
||||
|
||||
const int padding = atlas->TexGlyphPadding;
|
||||
for (int glyph_i = 0; glyph_i < src_tmp.GlyphsCount; glyph_i++)
|
||||
{
|
||||
ImFontBuildSrcGlyphFT& src_glyph = src_tmp.GlyphsList[glyph_i];
|
||||
stbrp_rect& pack_rect = src_tmp.Rects[glyph_i];
|
||||
IM_ASSERT(pack_rect.was_packed);
|
||||
if (pack_rect.w == 0 && pack_rect.h == 0)
|
||||
continue;
|
||||
|
||||
GlyphInfo& info = src_glyph.Info;
|
||||
IM_ASSERT(info.Width + padding <= pack_rect.w);
|
||||
IM_ASSERT(info.Height + padding <= pack_rect.h);
|
||||
const int tx = pack_rect.x + padding;
|
||||
const int ty = pack_rect.y + padding;
|
||||
|
||||
// Blit from temporary buffer to final texture
|
||||
size_t blit_src_stride = (size_t)src_glyph.Info.Width;
|
||||
size_t blit_dst_stride = (size_t)atlas->TexWidth;
|
||||
unsigned char* blit_src = src_glyph.BitmapData;
|
||||
unsigned char* blit_dst = atlas->TexPixelsAlpha8 + (ty * blit_dst_stride) + tx;
|
||||
for (int y = info.Height; y > 0; y--, blit_dst += blit_dst_stride, blit_src += blit_src_stride)
|
||||
memcpy(blit_dst, blit_src, blit_src_stride);
|
||||
|
||||
// Register glyph
|
||||
float x0 = info.OffsetX + font_off_x;
|
||||
float y0 = info.OffsetY + font_off_y;
|
||||
float x1 = x0 + info.Width;
|
||||
float y1 = y0 + info.Height;
|
||||
float u0 = (tx) / (float)atlas->TexWidth;
|
||||
float v0 = (ty) / (float)atlas->TexHeight;
|
||||
float u1 = (tx + info.Width) / (float)atlas->TexWidth;
|
||||
float v1 = (ty + info.Height) / (float)atlas->TexHeight;
|
||||
dst_font->AddGlyph(&cfg, (ImWchar)src_glyph.Codepoint, x0, y0, x1, y1, u0, v0, u1, v1, info.AdvanceX);
|
||||
}
|
||||
|
||||
src_tmp.Rects = NULL;
|
||||
}
|
||||
|
||||
// Cleanup
|
||||
for (int buf_i = 0; buf_i < buf_bitmap_buffers.Size; buf_i++)
|
||||
IM_FREE(buf_bitmap_buffers[buf_i]);
|
||||
for (int src_i = 0; src_i < src_tmp_array.Size; src_i++)
|
||||
src_tmp_array[src_i].~ImFontBuildSrcDataFT();
|
||||
|
||||
ImFontAtlasBuildFinish(atlas);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Default memory allocators
|
||||
static void* ImFreeTypeDefaultAllocFunc(size_t size, void* user_data) { IM_UNUSED(user_data); return IM_ALLOC(size); }
|
||||
static void ImFreeTypeDefaultFreeFunc(void* ptr, void* user_data) { IM_UNUSED(user_data); IM_FREE(ptr); }
|
||||
|
||||
// Current memory allocators
|
||||
static void* (*GImFreeTypeAllocFunc)(size_t size, void* user_data) = ImFreeTypeDefaultAllocFunc;
|
||||
static void (*GImFreeTypeFreeFunc)(void* ptr, void* user_data) = ImFreeTypeDefaultFreeFunc;
|
||||
static void* GImFreeTypeAllocatorUserData = NULL;
|
||||
|
||||
// FreeType memory allocation callbacks
|
||||
static void* FreeType_Alloc(FT_Memory /*memory*/, long size)
|
||||
{
|
||||
return GImFreeTypeAllocFunc((size_t)size, GImFreeTypeAllocatorUserData);
|
||||
}
|
||||
|
||||
static void FreeType_Free(FT_Memory /*memory*/, void* block)
|
||||
{
|
||||
GImFreeTypeFreeFunc(block, GImFreeTypeAllocatorUserData);
|
||||
}
|
||||
|
||||
static void* FreeType_Realloc(FT_Memory /*memory*/, long cur_size, long new_size, void* block)
|
||||
{
|
||||
// Implement realloc() as we don't ask user to provide it.
|
||||
if (block == NULL)
|
||||
return GImFreeTypeAllocFunc((size_t)new_size, GImFreeTypeAllocatorUserData);
|
||||
|
||||
if (new_size == 0)
|
||||
{
|
||||
GImFreeTypeFreeFunc(block, GImFreeTypeAllocatorUserData);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (new_size > cur_size)
|
||||
{
|
||||
void* new_block = GImFreeTypeAllocFunc((size_t)new_size, GImFreeTypeAllocatorUserData);
|
||||
memcpy(new_block, block, (size_t)cur_size);
|
||||
GImFreeTypeFreeFunc(block, GImFreeTypeAllocatorUserData);
|
||||
return new_block;
|
||||
}
|
||||
|
||||
return block;
|
||||
}
|
||||
|
||||
bool ImGuiFreeType::BuildFontAtlas(ImFontAtlas* atlas, unsigned int extra_flags)
|
||||
{
|
||||
// FreeType memory management: https://www.freetype.org/freetype2/docs/design/design-4.html
|
||||
FT_MemoryRec_ memory_rec = {};
|
||||
memory_rec.user = NULL;
|
||||
memory_rec.alloc = &FreeType_Alloc;
|
||||
memory_rec.free = &FreeType_Free;
|
||||
memory_rec.realloc = &FreeType_Realloc;
|
||||
|
||||
// https://www.freetype.org/freetype2/docs/reference/ft2-module_management.html#FT_New_Library
|
||||
FT_Library ft_library;
|
||||
FT_Error error = FT_New_Library(&memory_rec, &ft_library);
|
||||
if (error != 0)
|
||||
return false;
|
||||
|
||||
// If you don't call FT_Add_Default_Modules() the rest of code may work, but FreeType won't use our custom allocator.
|
||||
FT_Add_Default_Modules(ft_library);
|
||||
|
||||
bool ret = ImFontAtlasBuildWithFreeType(ft_library, atlas, extra_flags);
|
||||
FT_Done_Library(ft_library);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void ImGuiFreeType::SetAllocatorFunctions(void* (*alloc_func)(size_t sz, void* user_data), void (*free_func)(void* ptr, void* user_data), void* user_data)
|
||||
{
|
||||
GImFreeTypeAllocFunc = alloc_func;
|
||||
GImFreeTypeFreeFunc = free_func;
|
||||
GImFreeTypeAllocatorUserData = user_data;
|
||||
}
|
||||
144
external/ImGui/source/imgui_imhex_extensions.cpp
vendored
Normal file
144
external/ImGui/source/imgui_imhex_extensions.cpp
vendored
Normal file
@@ -0,0 +1,144 @@
|
||||
#include <imgui_imhex_extensions.h>
|
||||
|
||||
#include <imgui.h>
|
||||
#include <imgui_freetype.h>
|
||||
#define IMGUI_DEFINE_MATH_OPERATORS
|
||||
#include <imgui_internal.h>
|
||||
#undef IMGUI_DEFINE_MATH_OPERATORS
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace ImGui {
|
||||
|
||||
bool Hyperlink(const char* label, const ImVec2& size_arg, ImGuiButtonFlags flags) {
|
||||
ImGuiWindow* window = GetCurrentWindow();
|
||||
if (window->SkipItems)
|
||||
return false;
|
||||
|
||||
ImGuiContext& g = *GImGui;
|
||||
const ImGuiStyle& style = g.Style;
|
||||
const ImGuiID id = window->GetID(label);
|
||||
const ImVec2 label_size = CalcTextSize(label, NULL, true);
|
||||
|
||||
ImVec2 pos = window->DC.CursorPos;
|
||||
ImVec2 size = CalcItemSize(size_arg, label_size.x, label_size.y);
|
||||
|
||||
const ImRect bb(pos, pos + size);
|
||||
if (!ItemAdd(bb, id))
|
||||
return false;
|
||||
|
||||
if (window->DC.ItemFlags & ImGuiItemFlags_ButtonRepeat)
|
||||
flags |= ImGuiButtonFlags_Repeat;
|
||||
bool hovered, held;
|
||||
bool pressed = ButtonBehavior(bb, id, &hovered, &held, flags);
|
||||
|
||||
// Render
|
||||
const ImU32 col = hovered ? GetColorU32(ImGuiCol_ButtonHovered) : GetColorU32(ImGuiCol_ButtonActive);
|
||||
PushStyleColor(ImGuiCol_Text, ImU32(col));
|
||||
TextEx(label, NULL, ImGuiTextFlags_NoWidthForLargeClippedText); // Skip formatting
|
||||
GetWindowDrawList()->AddLine(ImVec2(pos.x, pos.y + size.y), pos + size, ImU32(col));
|
||||
PopStyleColor();
|
||||
|
||||
IMGUI_TEST_ENGINE_ITEM_INFO(id, label, window->DC.LastItemStatusFlags);
|
||||
return pressed;
|
||||
}
|
||||
|
||||
bool BulletHyperlink(const char* label, const ImVec2& size_arg, ImGuiButtonFlags flags) {
|
||||
ImGuiWindow* window = GetCurrentWindow();
|
||||
if (window->SkipItems)
|
||||
return false;
|
||||
|
||||
ImGuiContext& g = *GImGui;
|
||||
const ImGuiStyle& style = g.Style;
|
||||
const ImGuiID id = window->GetID(label);
|
||||
const ImVec2 label_size = CalcTextSize(label, NULL, true);
|
||||
|
||||
ImVec2 pos = window->DC.CursorPos;
|
||||
ImVec2 size = CalcItemSize(size_arg, label_size.x, label_size.y) + ImVec2(g.FontSize + style.FramePadding.x * 2, 0.0f);
|
||||
|
||||
const ImRect bb(pos, pos + size);
|
||||
if (!ItemAdd(bb, id))
|
||||
return false;
|
||||
|
||||
if (window->DC.ItemFlags & ImGuiItemFlags_ButtonRepeat)
|
||||
flags |= ImGuiButtonFlags_Repeat;
|
||||
bool hovered, held;
|
||||
bool pressed = ButtonBehavior(bb, id, &hovered, &held, flags);
|
||||
|
||||
// Render
|
||||
const ImU32 col = hovered ? GetColorU32(ImGuiCol_ButtonHovered) : GetColorU32(ImGuiCol_ButtonActive);
|
||||
PushStyleColor(ImGuiCol_Text, ImU32(col));
|
||||
RenderBullet(window->DrawList, bb.Min + ImVec2(style.FramePadding.x + g.FontSize * 0.5f, g.FontSize * 0.5f), col);
|
||||
RenderText(bb.Min + ImVec2(g.FontSize + style.FramePadding.x * 2, 0.0f), label, nullptr, false);
|
||||
GetWindowDrawList()->AddLine(bb.Min + ImVec2(style.FramePadding.x, size.y), pos + size, ImU32(col));
|
||||
ImGui::NewLine();
|
||||
PopStyleColor();
|
||||
|
||||
IMGUI_TEST_ENGINE_ITEM_INFO(id, label, window->DC.LastItemStatusFlags);
|
||||
return pressed;
|
||||
}
|
||||
|
||||
bool DescriptionButton(const char* label, const char* description, const ImVec2& size_arg, ImGuiButtonFlags flags) {
|
||||
ImGuiWindow* window = GetCurrentWindow();
|
||||
if (window->SkipItems)
|
||||
return false;
|
||||
|
||||
ImGuiContext& g = *GImGui;
|
||||
const ImGuiStyle& style = g.Style;
|
||||
const ImGuiID id = window->GetID(label);
|
||||
const ImVec2 text_size = CalcTextSize((std::string(label) + "\n " + std::string(description)).c_str(), NULL, true);
|
||||
const ImVec2 label_size = CalcTextSize(label, NULL, true);
|
||||
|
||||
ImVec2 pos = window->DC.CursorPos;
|
||||
if ((flags & ImGuiButtonFlags_AlignTextBaseLine) && style.FramePadding.y < window->DC.CurrLineTextBaseOffset) // Try to vertically align buttons that are smaller/have no padding so that text baseline matches (bit hacky, since it shouldn't be a flag)
|
||||
pos.y += window->DC.CurrLineTextBaseOffset - style.FramePadding.y;
|
||||
ImVec2 size = CalcItemSize(size_arg, text_size.x + style.FramePadding.x * 4.0f, text_size.y + style.FramePadding.y * 4.0f);
|
||||
|
||||
const ImRect bb(pos, pos + size);
|
||||
ItemSize(size, style.FramePadding.y);
|
||||
if (!ItemAdd(bb, id))
|
||||
return false;
|
||||
|
||||
if (window->DC.ItemFlags & ImGuiItemFlags_ButtonRepeat)
|
||||
flags |= ImGuiButtonFlags_Repeat;
|
||||
bool hovered, held;
|
||||
bool pressed = ButtonBehavior(bb, id, &hovered, &held, flags);
|
||||
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_ButtonTextAlign, ImVec2(0.0, 0.5));
|
||||
|
||||
// Render
|
||||
const ImU32 col = GetColorU32((held && hovered) ? ImGuiCol_TableHeaderBg : hovered ? ImGuiCol_TableBorderLight : ImGuiCol_TableBorderStrong);
|
||||
RenderNavHighlight(bb, id);
|
||||
RenderFrame(bb.Min, bb.Max, col, true, style.FrameRounding);
|
||||
PushStyleColor(ImGuiCol_Text, GetColorU32(ImGuiCol_ButtonActive));
|
||||
RenderTextClipped(bb.Min + style.FramePadding * 2, bb.Max - style.FramePadding * 2, label, NULL, &text_size, style.ButtonTextAlign, &bb);
|
||||
PopStyleColor();
|
||||
PushStyleColor(ImGuiCol_Text, GetColorU32(ImGuiCol_Text));
|
||||
RenderTextClipped(bb.Min + style.FramePadding * 2 + ImVec2(style.FramePadding.x * 2, label_size.y), bb.Max - style.FramePadding, description, NULL, &text_size, style.ButtonTextAlign, &bb);
|
||||
PopStyleColor();
|
||||
|
||||
ImGui::PopStyleVar();
|
||||
|
||||
// Automatically close popups
|
||||
//if (pressed && !(flags & ImGuiButtonFlags_DontClosePopups) && (window->Flags & ImGuiWindowFlags_Popup))
|
||||
// CloseCurrentPopup();
|
||||
|
||||
IMGUI_TEST_ENGINE_ITEM_INFO(id, label, window->DC.LastItemStatusFlags);
|
||||
return pressed;
|
||||
}
|
||||
|
||||
void UnderlinedText(const char* label, ImColor color, const ImVec2& size_arg) {
|
||||
ImGuiWindow* window = GetCurrentWindow();
|
||||
|
||||
const ImVec2 label_size = CalcTextSize(label, NULL, true);
|
||||
|
||||
ImVec2 pos = window->DC.CursorPos;
|
||||
ImVec2 size = CalcItemSize(size_arg, label_size.x, label_size.y);
|
||||
|
||||
PushStyleColor(ImGuiCol_Text, ImU32(color));
|
||||
TextEx(label, NULL, ImGuiTextFlags_NoWidthForLargeClippedText); // Skip formatting
|
||||
GetWindowDrawList()->AddLine(ImVec2(pos.x, pos.y + size.y), pos + size, ImU32(color));
|
||||
PopStyleColor();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -19,7 +19,7 @@
|
||||
|
||||
// CHANGELOG
|
||||
// (minor and older changes stripped away, please see git history for details)
|
||||
// 2020-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
|
||||
// 2021-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
|
||||
// 2020-01-17: Inputs: Disable error callback while assigning mouse cursors because some X11 setup don't have them and it generates errors.
|
||||
// 2019-12-05: Inputs: Added support for new mouse cursors added in GLFW 3.4+ (resizing cursors, not allowed cursor).
|
||||
// 2019-10-18: Misc: Previously installed user callbacks are now restored on shutdown.
|
||||
@@ -14,8 +14,9 @@
|
||||
|
||||
// CHANGELOG
|
||||
// (minor and older changes stripped away, please see git history for details)
|
||||
// 2020-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
|
||||
// 2020-10-23: OpenGL: Save and restore current GL_PRIMITIVE_RESTART state.
|
||||
// 2021-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
|
||||
// 2021-01-03: OpenGL: Backup, setup and restore GL_STENCIL_TEST state.
|
||||
// 2020-10-23: OpenGL: Backup, setup and restore GL_PRIMITIVE_RESTART state.
|
||||
// 2020-10-15: OpenGL: Use glGetString(GL_VERSION) instead of glGetIntegerv(GL_MAJOR_VERSION, ...) when the later returns zero (e.g. Desktop GL 2.x)
|
||||
// 2020-09-17: OpenGL: Fix to avoid compiling/calling glBindSampler() on ES or pre 3.3 context which have the defines set by a loader.
|
||||
// 2020-07-10: OpenGL: Added support for glad2 OpenGL loader.
|
||||
@@ -260,6 +261,7 @@ static void ImGui_ImplOpenGL3_SetupRenderState(ImDrawData* draw_data, int fb_wid
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glDisable(GL_CULL_FACE);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glDisable(GL_STENCIL_TEST);
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
#ifdef IMGUI_IMPL_OPENGL_MAY_HAVE_PRIMITIVE_RESTART
|
||||
if (g_GlVersion >= 310)
|
||||
@@ -270,8 +272,8 @@ static void ImGui_ImplOpenGL3_SetupRenderState(ImDrawData* draw_data, int fb_wid
|
||||
#endif
|
||||
|
||||
// Support for GL 4.5 rarely used glClipControl(GL_UPPER_LEFT)
|
||||
bool clip_origin_lower_left = true;
|
||||
#if defined(GL_CLIP_ORIGIN) && !defined(__APPLE__)
|
||||
bool clip_origin_lower_left = true;
|
||||
GLenum current_clip_origin = 0; glGetIntegerv(GL_CLIP_ORIGIN, (GLint*)¤t_clip_origin);
|
||||
if (current_clip_origin == GL_UPPER_LEFT)
|
||||
clip_origin_lower_left = false;
|
||||
@@ -284,23 +286,25 @@ static void ImGui_ImplOpenGL3_SetupRenderState(ImDrawData* draw_data, int fb_wid
|
||||
float R = draw_data->DisplayPos.x + draw_data->DisplaySize.x;
|
||||
float T = draw_data->DisplayPos.y;
|
||||
float B = draw_data->DisplayPos.y + draw_data->DisplaySize.y;
|
||||
#if defined(GL_CLIP_ORIGIN) && !defined(__APPLE__)
|
||||
if (!clip_origin_lower_left) { float tmp = T; T = B; B = tmp; } // Swap top and bottom if origin is upper left
|
||||
#endif
|
||||
const float ortho_projection[4][4] =
|
||||
{
|
||||
{ 2.0f/(R-L), 0.0f, 0.0f, 0.0f },
|
||||
{ 0.0f, 2.0f/(T-B), 0.0f, 0.0f },
|
||||
{ 0.0f, 0.0f, -1.0f, 0.0f },
|
||||
{ (R+L)/(L-R), (T+B)/(B-T), 0.0f, 1.0f },
|
||||
};
|
||||
{
|
||||
{ 2.0f/(R-L), 0.0f, 0.0f, 0.0f },
|
||||
{ 0.0f, 2.0f/(T-B), 0.0f, 0.0f },
|
||||
{ 0.0f, 0.0f, -1.0f, 0.0f },
|
||||
{ (R+L)/(L-R), (T+B)/(B-T), 0.0f, 1.0f },
|
||||
};
|
||||
glUseProgram(g_ShaderHandle);
|
||||
glUniform1i(g_AttribLocationTex, 0);
|
||||
glUniformMatrix4fv(g_AttribLocationProjMtx, 1, GL_FALSE, &ortho_projection[0][0]);
|
||||
|
||||
|
||||
#ifdef IMGUI_IMPL_OPENGL_MAY_HAVE_BIND_SAMPLER
|
||||
if (g_GlVersion >= 330)
|
||||
glBindSampler(0, 0); // We use combined texture/sampler state. Applications using GL 3.3 may set that otherwise.
|
||||
#endif
|
||||
|
||||
|
||||
(void)vertex_array_object;
|
||||
#ifndef IMGUI_IMPL_OPENGL_ES2
|
||||
glBindVertexArray(vertex_array_object);
|
||||
@@ -354,6 +358,7 @@ void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data)
|
||||
GLboolean last_enable_blend = glIsEnabled(GL_BLEND);
|
||||
GLboolean last_enable_cull_face = glIsEnabled(GL_CULL_FACE);
|
||||
GLboolean last_enable_depth_test = glIsEnabled(GL_DEPTH_TEST);
|
||||
GLboolean last_enable_stencil_test = glIsEnabled(GL_STENCIL_TEST);
|
||||
GLboolean last_enable_scissor_test = glIsEnabled(GL_SCISSOR_TEST);
|
||||
#ifdef IMGUI_IMPL_OPENGL_MAY_HAVE_PRIMITIVE_RESTART
|
||||
GLboolean last_enable_primitive_restart = (g_GlVersion >= 310) ? glIsEnabled(GL_PRIMITIVE_RESTART) : GL_FALSE;
|
||||
@@ -414,7 +419,7 @@ void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data)
|
||||
glDrawElementsBaseVertex(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, (void*)(intptr_t)(pcmd->IdxOffset * sizeof(ImDrawIdx)), (GLint)pcmd->VtxOffset);
|
||||
else
|
||||
#endif
|
||||
glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, (void*)(intptr_t)(pcmd->IdxOffset * sizeof(ImDrawIdx)));
|
||||
glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, (void*)(intptr_t)(pcmd->IdxOffset * sizeof(ImDrawIdx)));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -442,6 +447,7 @@ void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data)
|
||||
if (last_enable_blend) glEnable(GL_BLEND); else glDisable(GL_BLEND);
|
||||
if (last_enable_cull_face) glEnable(GL_CULL_FACE); else glDisable(GL_CULL_FACE);
|
||||
if (last_enable_depth_test) glEnable(GL_DEPTH_TEST); else glDisable(GL_DEPTH_TEST);
|
||||
if (last_enable_stencil_test) glEnable(GL_STENCIL_TEST); else glDisable(GL_STENCIL_TEST);
|
||||
if (last_enable_scissor_test) glEnable(GL_SCISSOR_TEST); else glDisable(GL_SCISSOR_TEST);
|
||||
#ifdef IMGUI_IMPL_OPENGL_MAY_HAVE_PRIMITIVE_RESTART
|
||||
if (g_GlVersion >= 310) { if (last_enable_primitive_restart) glEnable(GL_PRIMITIVE_RESTART); else glDisable(GL_PRIMITIVE_RESTART); }
|
||||
@@ -546,104 +552,104 @@ bool ImGui_ImplOpenGL3_CreateDeviceObjects()
|
||||
sscanf(g_GlslVersionString, "#version %d", &glsl_version);
|
||||
|
||||
const GLchar* vertex_shader_glsl_120 =
|
||||
"uniform mat4 ProjMtx;\n"
|
||||
"attribute vec2 Position;\n"
|
||||
"attribute vec2 UV;\n"
|
||||
"attribute vec4 Color;\n"
|
||||
"varying vec2 Frag_UV;\n"
|
||||
"varying vec4 Frag_Color;\n"
|
||||
"void main()\n"
|
||||
"{\n"
|
||||
" Frag_UV = UV;\n"
|
||||
" Frag_Color = Color;\n"
|
||||
" gl_Position = ProjMtx * vec4(Position.xy,0,1);\n"
|
||||
"}\n";
|
||||
"uniform mat4 ProjMtx;\n"
|
||||
"attribute vec2 Position;\n"
|
||||
"attribute vec2 UV;\n"
|
||||
"attribute vec4 Color;\n"
|
||||
"varying vec2 Frag_UV;\n"
|
||||
"varying vec4 Frag_Color;\n"
|
||||
"void main()\n"
|
||||
"{\n"
|
||||
" Frag_UV = UV;\n"
|
||||
" Frag_Color = Color;\n"
|
||||
" gl_Position = ProjMtx * vec4(Position.xy,0,1);\n"
|
||||
"}\n";
|
||||
|
||||
const GLchar* vertex_shader_glsl_130 =
|
||||
"uniform mat4 ProjMtx;\n"
|
||||
"in vec2 Position;\n"
|
||||
"in vec2 UV;\n"
|
||||
"in vec4 Color;\n"
|
||||
"out vec2 Frag_UV;\n"
|
||||
"out vec4 Frag_Color;\n"
|
||||
"void main()\n"
|
||||
"{\n"
|
||||
" Frag_UV = UV;\n"
|
||||
" Frag_Color = Color;\n"
|
||||
" gl_Position = ProjMtx * vec4(Position.xy,0,1);\n"
|
||||
"}\n";
|
||||
"uniform mat4 ProjMtx;\n"
|
||||
"in vec2 Position;\n"
|
||||
"in vec2 UV;\n"
|
||||
"in vec4 Color;\n"
|
||||
"out vec2 Frag_UV;\n"
|
||||
"out vec4 Frag_Color;\n"
|
||||
"void main()\n"
|
||||
"{\n"
|
||||
" Frag_UV = UV;\n"
|
||||
" Frag_Color = Color;\n"
|
||||
" gl_Position = ProjMtx * vec4(Position.xy,0,1);\n"
|
||||
"}\n";
|
||||
|
||||
const GLchar* vertex_shader_glsl_300_es =
|
||||
"precision mediump float;\n"
|
||||
"layout (location = 0) in vec2 Position;\n"
|
||||
"layout (location = 1) in vec2 UV;\n"
|
||||
"layout (location = 2) in vec4 Color;\n"
|
||||
"uniform mat4 ProjMtx;\n"
|
||||
"out vec2 Frag_UV;\n"
|
||||
"out vec4 Frag_Color;\n"
|
||||
"void main()\n"
|
||||
"{\n"
|
||||
" Frag_UV = UV;\n"
|
||||
" Frag_Color = Color;\n"
|
||||
" gl_Position = ProjMtx * vec4(Position.xy,0,1);\n"
|
||||
"}\n";
|
||||
"precision mediump float;\n"
|
||||
"layout (location = 0) in vec2 Position;\n"
|
||||
"layout (location = 1) in vec2 UV;\n"
|
||||
"layout (location = 2) in vec4 Color;\n"
|
||||
"uniform mat4 ProjMtx;\n"
|
||||
"out vec2 Frag_UV;\n"
|
||||
"out vec4 Frag_Color;\n"
|
||||
"void main()\n"
|
||||
"{\n"
|
||||
" Frag_UV = UV;\n"
|
||||
" Frag_Color = Color;\n"
|
||||
" gl_Position = ProjMtx * vec4(Position.xy,0,1);\n"
|
||||
"}\n";
|
||||
|
||||
const GLchar* vertex_shader_glsl_410_core =
|
||||
"layout (location = 0) in vec2 Position;\n"
|
||||
"layout (location = 1) in vec2 UV;\n"
|
||||
"layout (location = 2) in vec4 Color;\n"
|
||||
"uniform mat4 ProjMtx;\n"
|
||||
"out vec2 Frag_UV;\n"
|
||||
"out vec4 Frag_Color;\n"
|
||||
"void main()\n"
|
||||
"{\n"
|
||||
" Frag_UV = UV;\n"
|
||||
" Frag_Color = Color;\n"
|
||||
" gl_Position = ProjMtx * vec4(Position.xy,0,1);\n"
|
||||
"}\n";
|
||||
"layout (location = 0) in vec2 Position;\n"
|
||||
"layout (location = 1) in vec2 UV;\n"
|
||||
"layout (location = 2) in vec4 Color;\n"
|
||||
"uniform mat4 ProjMtx;\n"
|
||||
"out vec2 Frag_UV;\n"
|
||||
"out vec4 Frag_Color;\n"
|
||||
"void main()\n"
|
||||
"{\n"
|
||||
" Frag_UV = UV;\n"
|
||||
" Frag_Color = Color;\n"
|
||||
" gl_Position = ProjMtx * vec4(Position.xy,0,1);\n"
|
||||
"}\n";
|
||||
|
||||
const GLchar* fragment_shader_glsl_120 =
|
||||
"#ifdef GL_ES\n"
|
||||
" precision mediump float;\n"
|
||||
"#endif\n"
|
||||
"uniform sampler2D Texture;\n"
|
||||
"varying vec2 Frag_UV;\n"
|
||||
"varying vec4 Frag_Color;\n"
|
||||
"void main()\n"
|
||||
"{\n"
|
||||
" gl_FragColor = Frag_Color * texture2D(Texture, Frag_UV.st);\n"
|
||||
"}\n";
|
||||
"#ifdef GL_ES\n"
|
||||
" precision mediump float;\n"
|
||||
"#endif\n"
|
||||
"uniform sampler2D Texture;\n"
|
||||
"varying vec2 Frag_UV;\n"
|
||||
"varying vec4 Frag_Color;\n"
|
||||
"void main()\n"
|
||||
"{\n"
|
||||
" gl_FragColor = Frag_Color * texture2D(Texture, Frag_UV.st);\n"
|
||||
"}\n";
|
||||
|
||||
const GLchar* fragment_shader_glsl_130 =
|
||||
"uniform sampler2D Texture;\n"
|
||||
"in vec2 Frag_UV;\n"
|
||||
"in vec4 Frag_Color;\n"
|
||||
"out vec4 Out_Color;\n"
|
||||
"void main()\n"
|
||||
"{\n"
|
||||
" Out_Color = Frag_Color * texture(Texture, Frag_UV.st);\n"
|
||||
"}\n";
|
||||
"uniform sampler2D Texture;\n"
|
||||
"in vec2 Frag_UV;\n"
|
||||
"in vec4 Frag_Color;\n"
|
||||
"out vec4 Out_Color;\n"
|
||||
"void main()\n"
|
||||
"{\n"
|
||||
" Out_Color = Frag_Color * texture(Texture, Frag_UV.st);\n"
|
||||
"}\n";
|
||||
|
||||
const GLchar* fragment_shader_glsl_300_es =
|
||||
"precision mediump float;\n"
|
||||
"uniform sampler2D Texture;\n"
|
||||
"in vec2 Frag_UV;\n"
|
||||
"in vec4 Frag_Color;\n"
|
||||
"layout (location = 0) out vec4 Out_Color;\n"
|
||||
"void main()\n"
|
||||
"{\n"
|
||||
" Out_Color = Frag_Color * texture(Texture, Frag_UV.st);\n"
|
||||
"}\n";
|
||||
"precision mediump float;\n"
|
||||
"uniform sampler2D Texture;\n"
|
||||
"in vec2 Frag_UV;\n"
|
||||
"in vec4 Frag_Color;\n"
|
||||
"layout (location = 0) out vec4 Out_Color;\n"
|
||||
"void main()\n"
|
||||
"{\n"
|
||||
" Out_Color = Frag_Color * texture(Texture, Frag_UV.st);\n"
|
||||
"}\n";
|
||||
|
||||
const GLchar* fragment_shader_glsl_410_core =
|
||||
"in vec2 Frag_UV;\n"
|
||||
"in vec4 Frag_Color;\n"
|
||||
"uniform sampler2D Texture;\n"
|
||||
"layout (location = 0) out vec4 Out_Color;\n"
|
||||
"void main()\n"
|
||||
"{\n"
|
||||
" Out_Color = Frag_Color * texture(Texture, Frag_UV.st);\n"
|
||||
"}\n";
|
||||
"in vec2 Frag_UV;\n"
|
||||
"in vec4 Frag_Color;\n"
|
||||
"uniform sampler2D Texture;\n"
|
||||
"layout (location = 0) out vec4 Out_Color;\n"
|
||||
"void main()\n"
|
||||
"{\n"
|
||||
" Out_Color = Frag_Color * texture(Texture, Frag_UV.st);\n"
|
||||
"}\n";
|
||||
|
||||
// Select shaders matching our GLSL versions
|
||||
const GLchar* vertex_shader = NULL;
|
||||
@@ -749,4 +755,4 @@ static void ImGui_ImplOpenGL3_InitPlatformInterface()
|
||||
static void ImGui_ImplOpenGL3_ShutdownPlatformInterface()
|
||||
{
|
||||
ImGui::DestroyPlatformWindows();
|
||||
}
|
||||
}
|
||||
3923
external/ImGui/source/imgui_tables.cpp
vendored
Normal file
3923
external/ImGui/source/imgui_tables.cpp
vendored
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,4 +1,4 @@
|
||||
// dear imgui, v1.80 WIP
|
||||
// dear imgui, v1.80
|
||||
// (widgets code)
|
||||
|
||||
/*
|
||||
@@ -40,6 +40,7 @@ Index of this file:
|
||||
#endif
|
||||
#include "imgui_internal.h"
|
||||
|
||||
// System includes
|
||||
#include <ctype.h> // toupper
|
||||
#if defined(_MSC_VER) && _MSC_VER <= 1500 // MSVC 2008 or earlier
|
||||
#include <stddef.h> // intptr_t
|
||||
@@ -47,6 +48,10 @@ Index of this file:
|
||||
#include <stdint.h> // intptr_t
|
||||
#endif
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// Warnings
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
// Visual Studio warnings
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning (disable: 4127) // condition expression is constant
|
||||
@@ -72,15 +77,19 @@ Index of this file:
|
||||
#pragma clang diagnostic ignored "-Wdeprecated-enum-enum-conversion"// warning: bitwise operation between different enumeration types ('XXXFlags_' and 'XXXFlagsPrivate_') is deprecated
|
||||
#pragma clang diagnostic ignored "-Wimplicit-int-float-conversion" // warning: implicit conversion from 'xxx' to 'float' may lose precision
|
||||
#elif defined(__GNUC__)
|
||||
#pragma GCC diagnostic ignored "-Wpragmas" // warning: unknown option after '#pragma GCC diagnostic' kind
|
||||
#pragma GCC diagnostic ignored "-Wformat-nonliteral" // warning: format not a string literal, format string not checked
|
||||
#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 "-Wpragmas" // warning: unknown option after '#pragma GCC diagnostic' kind
|
||||
#pragma GCC diagnostic ignored "-Wformat-nonliteral" // warning: format not a string literal, format string not checked
|
||||
#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
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// Data
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
// Widgets
|
||||
static const float DRAGDROP_HOLD_TO_OPEN_TIMER = 0.70f; // Time for drag-hold to activate items accepting the ImGuiButtonFlags_PressedOnDragDropHold button behavior.
|
||||
static const float DRAG_MOUSE_THRESHOLD_FACTOR = 0.50f; // Multiplier for the default value of io.MouseDragThreshold to make DragFloat/DragInt react faster to mouse drags.
|
||||
|
||||
// Those MIN/MAX values are not define because we need to point to them
|
||||
static const signed char IM_S8_MIN = -128;
|
||||
static const signed char IM_S8_MAX = 127;
|
||||
@@ -408,6 +417,7 @@ void ImGui::BulletTextV(const char* fmt, va_list args)
|
||||
// - Image()
|
||||
// - ImageButton()
|
||||
// - Checkbox()
|
||||
// - CheckboxFlagsT() [Internal]
|
||||
// - CheckboxFlags()
|
||||
// - RadioButton()
|
||||
// - ProgressBar()
|
||||
@@ -510,10 +520,9 @@ bool ImGui::ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool
|
||||
if (g.DragDropActive && (flags & ImGuiButtonFlags_PressedOnDragDropHold) && !(g.DragDropSourceFlags & ImGuiDragDropFlags_SourceNoHoldToOpenOthers))
|
||||
if (IsItemHovered(ImGuiHoveredFlags_AllowWhenBlockedByActiveItem))
|
||||
{
|
||||
const float DRAG_DROP_HOLD_TIMER = 0.70f;
|
||||
hovered = true;
|
||||
SetHoveredID(id);
|
||||
if (CalcTypematicRepeatAmount(g.HoveredIdTimer + 0.0001f - g.IO.DeltaTime, g.HoveredIdTimer + 0.0001f, DRAG_DROP_HOLD_TIMER, 0.00f))
|
||||
if (CalcTypematicRepeatAmount(g.HoveredIdTimer + 0.0001f - g.IO.DeltaTime, g.HoveredIdTimer + 0.0001f, DRAGDROP_HOLD_TO_OPEN_TIMER, 0.00f))
|
||||
{
|
||||
pressed = true;
|
||||
g.DragDropHoldJustPressedId = id;
|
||||
@@ -1064,7 +1073,10 @@ bool ImGui::Checkbox(const char* label, bool* v)
|
||||
const ImRect total_bb(pos, pos + ImVec2(square_sz + (label_size.x > 0.0f ? style.ItemInnerSpacing.x + label_size.x : 0.0f), label_size.y + style.FramePadding.y * 2.0f));
|
||||
ItemSize(total_bb, style.FramePadding.y);
|
||||
if (!ItemAdd(total_bb, id))
|
||||
{
|
||||
IMGUI_TEST_ENGINE_ITEM_INFO(id, label, window->DC.ItemFlags | ImGuiItemStatusFlags_Checkable | (*v ? ImGuiItemStatusFlags_Checked : 0));
|
||||
return false;
|
||||
}
|
||||
|
||||
bool hovered, held;
|
||||
bool pressed = ButtonBehavior(total_bb, id, &hovered, &held);
|
||||
@@ -1082,6 +1094,7 @@ bool ImGui::Checkbox(const char* label, bool* v)
|
||||
if (mixed_value)
|
||||
{
|
||||
// Undocumented tristate/mixed/indeterminate checkbox (#2644)
|
||||
// This may seem awkwardly designed because the aim is to make ImGuiItemFlags_MixedValue supported by all widgets (not just checkbox)
|
||||
ImVec2 pad(ImMax(1.0f, IM_FLOOR(square_sz / 3.6f)), ImMax(1.0f, IM_FLOOR(square_sz / 3.6f)));
|
||||
window->DrawList->AddRectFilled(check_bb.Min + pad, check_bb.Max - pad, check_col, style.FrameRounding);
|
||||
}
|
||||
@@ -1100,35 +1113,55 @@ bool ImGui::Checkbox(const char* label, bool* v)
|
||||
return pressed;
|
||||
}
|
||||
|
||||
bool ImGui::CheckboxFlags(const char* label, unsigned int* flags, unsigned int flags_value)
|
||||
template<typename T>
|
||||
bool ImGui::CheckboxFlagsT(const char* label, T* flags, T flags_value)
|
||||
{
|
||||
bool v = ((*flags & flags_value) == flags_value);
|
||||
bool all_on = (*flags & flags_value) == flags_value;
|
||||
bool any_on = (*flags & flags_value) != 0;
|
||||
bool pressed;
|
||||
if (v == false && (*flags & flags_value) != 0)
|
||||
if (!all_on && any_on)
|
||||
{
|
||||
// Mixed value (FIXME: find a way to expose neatly to Checkbox?)
|
||||
ImGuiWindow* window = GetCurrentWindow();
|
||||
const ImGuiItemFlags backup_item_flags = window->DC.ItemFlags;
|
||||
ImGuiItemFlags backup_item_flags = window->DC.ItemFlags;
|
||||
window->DC.ItemFlags |= ImGuiItemFlags_MixedValue;
|
||||
pressed = Checkbox(label, &v);
|
||||
pressed = Checkbox(label, &all_on);
|
||||
window->DC.ItemFlags = backup_item_flags;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Regular checkbox
|
||||
pressed = Checkbox(label, &v);
|
||||
pressed = Checkbox(label, &all_on);
|
||||
|
||||
}
|
||||
if (pressed)
|
||||
{
|
||||
if (v)
|
||||
if (all_on)
|
||||
*flags |= flags_value;
|
||||
else
|
||||
*flags &= ~flags_value;
|
||||
}
|
||||
|
||||
return pressed;
|
||||
}
|
||||
|
||||
bool ImGui::CheckboxFlags(const char* label, int* flags, int flags_value)
|
||||
{
|
||||
return CheckboxFlagsT(label, flags, flags_value);
|
||||
}
|
||||
|
||||
bool ImGui::CheckboxFlags(const char* label, unsigned int* flags, unsigned int flags_value)
|
||||
{
|
||||
return CheckboxFlagsT(label, flags, flags_value);
|
||||
}
|
||||
|
||||
bool ImGui::CheckboxFlags(const char* label, ImS64* flags, ImS64 flags_value)
|
||||
{
|
||||
return CheckboxFlagsT(label, flags, flags_value);
|
||||
}
|
||||
|
||||
bool ImGui::CheckboxFlags(const char* label, ImU64* flags, ImU64 flags_value)
|
||||
{
|
||||
return CheckboxFlagsT(label, flags, flags_value);
|
||||
}
|
||||
|
||||
bool ImGui::RadioButton(const char* label, bool active)
|
||||
{
|
||||
ImGuiWindow* window = GetCurrentWindow();
|
||||
@@ -1341,10 +1374,12 @@ void ImGui::SeparatorEx(ImGuiSeparatorFlags flags)
|
||||
// Horizontal Separator
|
||||
float x1 = window->Pos.x;
|
||||
float x2 = window->Pos.x + window->Size.x;
|
||||
if (!window->DC.GroupStack.empty())
|
||||
|
||||
// FIXME-WORKRECT: old hack (#205) until we decide of consistent behavior with WorkRect/Indent and Separator
|
||||
if (g.GroupStack.Size > 0 && g.GroupStack.back().WindowID == window->ID)
|
||||
x1 += window->DC.Indent.x;
|
||||
|
||||
ImGuiColumns* columns = (flags & ImGuiSeparatorFlags_SpanAllColumns) ? window->DC.CurrentColumns : NULL;
|
||||
ImGuiOldColumns* columns = (flags & ImGuiSeparatorFlags_SpanAllColumns) ? window->DC.CurrentColumns : NULL;
|
||||
if (columns)
|
||||
PushColumnsBackground();
|
||||
|
||||
@@ -1583,13 +1618,17 @@ bool ImGui::BeginCombo(const char* label, const char* preview_value, ImGuiComboF
|
||||
char name[16];
|
||||
ImFormatString(name, IM_ARRAYSIZE(name), "##Combo_%02d", g.BeginPopupStack.Size); // Recycle windows based on depth
|
||||
|
||||
// Peak into expected window size so we can position it
|
||||
// Position the window given a custom constraint (peak into expected window size so we can position it)
|
||||
// This might be easier to express with an hypothetical SetNextWindowPosConstraints() function.
|
||||
if (ImGuiWindow* popup_window = FindWindowByName(name))
|
||||
if (popup_window->WasActive)
|
||||
{
|
||||
ImVec2 size_expected = CalcWindowExpectedSize(popup_window);
|
||||
// Always override 'AutoPosLastDirection' to not leave a chance for a past value to affect us.
|
||||
ImVec2 size_expected = CalcWindowNextAutoFitSize(popup_window);
|
||||
if (flags & ImGuiComboFlags_PopupAlignLeft)
|
||||
popup_window->AutoPosLastDirection = ImGuiDir_Left;
|
||||
popup_window->AutoPosLastDirection = ImGuiDir_Left; // "Below, Toward Left"
|
||||
else
|
||||
popup_window->AutoPosLastDirection = ImGuiDir_Down; // "Below, Toward Right (default)"
|
||||
ImRect r_outer = GetWindowAllowedExtentRect(popup_window);
|
||||
ImVec2 pos = FindBestWindowPosForPopupEx(frame_bb.GetBL(), size_expected, &popup_window->AutoPosLastDirection, r_outer, frame_bb, ImGuiPopupPositionPolicy_ComboBox);
|
||||
SetNextWindowPos(pos);
|
||||
@@ -1684,6 +1723,9 @@ bool ImGui::Combo(const char* label, int* current_item, bool (*items_getter)(voi
|
||||
}
|
||||
|
||||
EndCombo();
|
||||
if (value_changed)
|
||||
MarkItemEdited(g.CurrentWindow->DC.LastItemId);
|
||||
|
||||
return value_changed;
|
||||
}
|
||||
|
||||
@@ -2076,7 +2118,7 @@ bool ImGui::DragBehaviorT(ImGuiDataType data_type, TYPE* v, float v_speed, const
|
||||
|
||||
// Inputs accumulates into g.DragCurrentAccum, which is flushed into the current value as soon as it makes a difference with our precision settings
|
||||
float adjust_delta = 0.0f;
|
||||
if (g.ActiveIdSource == ImGuiInputSource_Mouse && IsMousePosValid() && g.IO.MouseDragMaxDistanceSqr[0] > 1.0f * 1.0f)
|
||||
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)
|
||||
@@ -2239,7 +2281,7 @@ bool ImGui::DragScalar(const char* label, ImGuiDataType data_type, void* p_data,
|
||||
else if (data_type == ImGuiDataType_S32 && strcmp(format, "%d") != 0) // (FIXME-LEGACY: Patch old "%.0f" format string to use "%d", read function more details.)
|
||||
format = PatchFormatStringFloatToInt(format);
|
||||
|
||||
// Tabbing or CTRL-clicking on Drag turns it into an input box
|
||||
// Tabbing or CTRL-clicking on Drag turns it into an InputText
|
||||
const bool hovered = ItemHoverable(frame_bb, id);
|
||||
const bool temp_input_allowed = (flags & ImGuiSliderFlags_NoInput) == 0;
|
||||
bool temp_input_is_active = temp_input_allowed && TempInputIsActive(id);
|
||||
@@ -2260,6 +2302,15 @@ bool ImGui::DragScalar(const char* label, ImGuiDataType data_type, void* p_data,
|
||||
FocusableItemUnregister(window);
|
||||
}
|
||||
}
|
||||
// Experimental: simple click (without moving) turns Drag into an InputText
|
||||
// FIXME: Currently polling ImGuiConfigFlags_IsTouchScreen, may either poll an hypothetical ImGuiBackendFlags_HasKeyboard and/or an explicit drag settings.
|
||||
if (g.IO.ConfigDragClickToInputText && temp_input_allowed && !temp_input_is_active)
|
||||
if (g.ActiveId == id && hovered && g.IO.MouseReleased[0] && !IsMouseDragPastThreshold(0, g.IO.MouseDragThreshold * DRAG_MOUSE_THRESHOLD_FACTOR))
|
||||
{
|
||||
g.NavInputId = id;
|
||||
temp_input_is_active = true;
|
||||
FocusableItemUnregister(window);
|
||||
}
|
||||
}
|
||||
|
||||
if (temp_input_is_active)
|
||||
@@ -3850,9 +3901,10 @@ 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_changed_specs = (state != NULL && state->Stb.single_line != !is_multiline);
|
||||
const bool init_make_active = (focus_requested || user_clicked || user_scroll_finish || user_nav_input_start);
|
||||
const bool init_state = (init_make_active || user_scroll_active);
|
||||
if (init_state && g.ActiveId != id)
|
||||
if ((init_state && g.ActiveId != id) || init_changed_specs)
|
||||
{
|
||||
// Access state even if we don't own it yet.
|
||||
state = &g.InputTextState;
|
||||
@@ -3874,7 +3926,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
||||
|
||||
// Preserve cursor position and undo/redo stack if we come back to same widget
|
||||
// FIXME: For non-readonly widgets we might be able to require that TextAIsValid && TextA == buf ? (untested) and discard undo stack if user buffer has changed.
|
||||
const bool recycle_state = (state->ID == id);
|
||||
const bool recycle_state = (state->ID == id && !init_changed_specs);
|
||||
if (recycle_state)
|
||||
{
|
||||
// Recycle existing cursor/selection/undo stack but clamp position
|
||||
@@ -4268,10 +4320,11 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
||||
IM_ASSERT(callback_data.Buf == state->TextA.Data); // Invalid to modify those fields
|
||||
IM_ASSERT(callback_data.BufSize == state->BufCapacityA);
|
||||
IM_ASSERT(callback_data.Flags == flags);
|
||||
if (callback_data.CursorPos != utf8_cursor_pos) { state->Stb.cursor = ImTextCountCharsFromUtf8(callback_data.Buf, callback_data.Buf + callback_data.CursorPos); state->CursorFollow = true; }
|
||||
if (callback_data.SelectionStart != utf8_selection_start) { state->Stb.select_start = ImTextCountCharsFromUtf8(callback_data.Buf, callback_data.Buf + callback_data.SelectionStart); }
|
||||
if (callback_data.SelectionEnd != utf8_selection_end) { state->Stb.select_end = ImTextCountCharsFromUtf8(callback_data.Buf, callback_data.Buf + callback_data.SelectionEnd); }
|
||||
if (callback_data.BufDirty)
|
||||
const bool buf_dirty = callback_data.BufDirty;
|
||||
if (callback_data.CursorPos != utf8_cursor_pos || buf_dirty) { state->Stb.cursor = ImTextCountCharsFromUtf8(callback_data.Buf, callback_data.Buf + callback_data.CursorPos); state->CursorFollow = true; }
|
||||
if (callback_data.SelectionStart != utf8_selection_start || buf_dirty) { state->Stb.select_start = (callback_data.SelectionStart == callback_data.CursorPos) ? state->Stb.cursor : ImTextCountCharsFromUtf8(callback_data.Buf, callback_data.Buf + callback_data.SelectionStart); }
|
||||
if (callback_data.SelectionEnd != utf8_selection_end || buf_dirty) { state->Stb.select_end = (callback_data.SelectionEnd == callback_data.SelectionStart) ? state->Stb.select_start : ImTextCountCharsFromUtf8(callback_data.Buf, callback_data.Buf + callback_data.SelectionEnd); }
|
||||
if (buf_dirty)
|
||||
{
|
||||
IM_ASSERT(callback_data.BufTextLen == (int)strlen(callback_data.Buf)); // You need to maintain BufTextLen if you change the text!
|
||||
if (callback_data.BufTextLen > backup_current_text_length && is_resizable)
|
||||
@@ -5444,7 +5497,7 @@ void ImGui::ColorPickerOptionsPopup(const float* ref_col, ImGuiColorEditFlags fl
|
||||
if (allow_opt_alpha_bar)
|
||||
{
|
||||
if (allow_opt_picker) Separator();
|
||||
CheckboxFlags("Alpha Bar", (unsigned int*)&g.ColorEditOptions, ImGuiColorEditFlags_AlphaBar);
|
||||
CheckboxFlags("Alpha Bar", &g.ColorEditOptions, ImGuiColorEditFlags_AlphaBar);
|
||||
}
|
||||
EndPopup();
|
||||
}
|
||||
@@ -5867,21 +5920,25 @@ bool ImGui::CollapsingHeader(const char* label, ImGuiTreeNodeFlags flags)
|
||||
return TreeNodeBehavior(window->GetID(label), flags | ImGuiTreeNodeFlags_CollapsingHeader, label);
|
||||
}
|
||||
|
||||
bool ImGui::CollapsingHeader(const char* label, bool* p_open, ImGuiTreeNodeFlags flags)
|
||||
// p_visible == NULL : regular collapsing header
|
||||
// p_visible != NULL && *p_visible == true : show a small close button on the corner of the header, clicking the button will set *p_visible = false
|
||||
// p_visible != NULL && *p_visible == false : do not show the header at all
|
||||
// Do not mistake this with the Open state of the header itself, which you can adjust with SetNextItemOpen() or ImGuiTreeNodeFlags_DefaultOpen.
|
||||
bool ImGui::CollapsingHeader(const char* label, bool* p_visible, ImGuiTreeNodeFlags flags)
|
||||
{
|
||||
ImGuiWindow* window = GetCurrentWindow();
|
||||
if (window->SkipItems)
|
||||
return false;
|
||||
|
||||
if (p_open && !*p_open)
|
||||
if (p_visible && !*p_visible)
|
||||
return false;
|
||||
|
||||
ImGuiID id = window->GetID(label);
|
||||
flags |= ImGuiTreeNodeFlags_CollapsingHeader;
|
||||
if (p_open)
|
||||
if (p_visible)
|
||||
flags |= ImGuiTreeNodeFlags_AllowItemOverlap | ImGuiTreeNodeFlags_ClipLabelForTrailingButton;
|
||||
bool is_open = TreeNodeBehavior(id, flags, label);
|
||||
if (p_open != NULL)
|
||||
if (p_visible != NULL)
|
||||
{
|
||||
// Create a small overlapping close button
|
||||
// FIXME: We can evolve this into user accessible helpers to add extra buttons on title bars, headers, etc.
|
||||
@@ -5893,7 +5950,7 @@ bool ImGui::CollapsingHeader(const char* label, bool* p_open, ImGuiTreeNodeFlags
|
||||
float button_y = window->DC.LastItemRect.Min.y;
|
||||
ImGuiID close_button_id = GetIDWithSeed("#CLOSE", NULL, id);
|
||||
if (CloseButton(close_button_id, ImVec2(button_x, button_y)))
|
||||
*p_open = false;
|
||||
*p_visible = false;
|
||||
last_item_backup.Restore();
|
||||
}
|
||||
|
||||
@@ -5919,10 +5976,6 @@ bool ImGui::Selectable(const char* label, bool selected, ImGuiSelectableFlags fl
|
||||
ImGuiContext& g = *GImGui;
|
||||
const ImGuiStyle& style = g.Style;
|
||||
|
||||
const bool span_all_columns = (flags & ImGuiSelectableFlags_SpanAllColumns) != 0;
|
||||
if (span_all_columns && window->DC.CurrentColumns) // FIXME-OPT: Avoid if vertically clipped.
|
||||
PushColumnsBackground();
|
||||
|
||||
// Submit label or explicit size to ItemSize(), whereas ItemAdd() will submit a larger/spanning rectangle.
|
||||
ImGuiID id = window->GetID(label);
|
||||
ImVec2 label_size = CalcTextSize(label, NULL, true);
|
||||
@@ -5933,6 +5986,7 @@ bool ImGui::Selectable(const char* label, bool selected, ImGuiSelectableFlags fl
|
||||
|
||||
// Fill horizontal space
|
||||
// We don't support (size < 0.0f) in Selectable() because the ItemSpacing extension would make explicitely right-aligned sizes not visibly match other widgets.
|
||||
const bool span_all_columns = (flags & ImGuiSelectableFlags_SpanAllColumns) != 0;
|
||||
const float min_x = span_all_columns ? window->ParentWorkRect.Min.x : pos.x;
|
||||
const float max_x = span_all_columns ? window->ParentWorkRect.Max.x : window->WorkRect.Max.x;
|
||||
if (size_arg.x == 0.0f || (flags & ImGuiSelectableFlags_SpanAvailWidth))
|
||||
@@ -5946,7 +6000,7 @@ bool ImGui::Selectable(const char* label, bool selected, ImGuiSelectableFlags fl
|
||||
ImRect bb(min_x, pos.y, text_max.x, text_max.y);
|
||||
if ((flags & ImGuiSelectableFlags_NoPadWithHalfSpacing) == 0)
|
||||
{
|
||||
const float spacing_x = style.ItemSpacing.x;
|
||||
const float spacing_x = span_all_columns ? 0.0f : style.ItemSpacing.x;
|
||||
const float spacing_y = style.ItemSpacing.y;
|
||||
const float spacing_L = IM_FLOOR(spacing_x * 0.50f);
|
||||
const float spacing_U = IM_FLOOR(spacing_y * 0.50f);
|
||||
@@ -5957,6 +6011,15 @@ bool ImGui::Selectable(const char* label, bool selected, ImGuiSelectableFlags fl
|
||||
}
|
||||
//if (g.IO.KeyCtrl) { GetForegroundDrawList()->AddRect(bb.Min, bb.Max, IM_COL32(0, 255, 0, 255)); }
|
||||
|
||||
// Modify ClipRect for the ItemAdd(), faster than doing a PushColumnsBackground/PushTableBackground for every Selectable..
|
||||
const float backup_clip_rect_min_x = window->ClipRect.Min.x;
|
||||
const float backup_clip_rect_max_x = window->ClipRect.Max.x;
|
||||
if (span_all_columns)
|
||||
{
|
||||
window->ClipRect.Min.x = window->ParentWorkRect.Min.x;
|
||||
window->ClipRect.Max.x = window->ParentWorkRect.Max.x;
|
||||
}
|
||||
|
||||
bool item_add;
|
||||
if (flags & ImGuiSelectableFlags_Disabled)
|
||||
{
|
||||
@@ -5969,13 +6032,23 @@ bool ImGui::Selectable(const char* label, bool selected, ImGuiSelectableFlags fl
|
||||
{
|
||||
item_add = ItemAdd(bb, id);
|
||||
}
|
||||
if (!item_add)
|
||||
|
||||
if (span_all_columns)
|
||||
{
|
||||
if (span_all_columns && window->DC.CurrentColumns)
|
||||
PopColumnsBackground();
|
||||
return false;
|
||||
window->ClipRect.Min.x = backup_clip_rect_min_x;
|
||||
window->ClipRect.Max.x = backup_clip_rect_max_x;
|
||||
}
|
||||
|
||||
if (!item_add)
|
||||
return false;
|
||||
|
||||
// FIXME: We can standardize the behavior of those two, we could also keep the fast path of override ClipRect + full push on render only,
|
||||
// which would be advantageous since most selectable are not selected.
|
||||
if (span_all_columns && window->DC.CurrentColumns)
|
||||
PushColumnsBackground();
|
||||
else if (span_all_columns && g.CurrentTable)
|
||||
TablePushBackgroundChannel();
|
||||
|
||||
// We use NoHoldingActiveID on menus so user can click and _hold_ on a menu then drag to browse child entries
|
||||
ImGuiButtonFlags button_flags = 0;
|
||||
if (flags & ImGuiSelectableFlags_NoHoldingActiveID) { button_flags |= ImGuiButtonFlags_NoHoldingActiveId; }
|
||||
@@ -6023,6 +6096,8 @@ bool ImGui::Selectable(const char* label, bool selected, ImGuiSelectableFlags fl
|
||||
|
||||
if (span_all_columns && window->DC.CurrentColumns)
|
||||
PopColumnsBackground();
|
||||
else if (span_all_columns && g.CurrentTable)
|
||||
TablePopBackgroundChannel();
|
||||
|
||||
if (flags & ImGuiSelectableFlags_Disabled) PushStyleColor(ImGuiCol_Text, style.Colors[ImGuiCol_TextDisabled]);
|
||||
RenderTextClipped(text_min, text_max, label, NULL, &label_size, style.SelectableTextAlign, &bb);
|
||||
@@ -6116,7 +6191,9 @@ bool ImGui::ListBoxHeader(const char* label, int items_count, int height_in_item
|
||||
// FIXME: In principle this function should be called EndListBox(). We should rename it after re-evaluating if we want to keep the same signature.
|
||||
void ImGui::ListBoxFooter()
|
||||
{
|
||||
ImGuiWindow* parent_window = GetCurrentWindow()->ParentWindow;
|
||||
ImGuiWindow * window = GetCurrentWindow();
|
||||
IM_ASSERT((window->Flags & ImGuiWindowFlags_ChildWindow) && "Mismatched ListBoxHeader/ListBoxFooter calls. Did you test the return value of ListBoxHeader()?");
|
||||
ImGuiWindow* parent_window = window->ParentWindow;
|
||||
const ImRect bb = parent_window->DC.LastItemRect;
|
||||
const ImGuiStyle& style = GetStyle();
|
||||
|
||||
@@ -6178,6 +6255,11 @@ bool ImGui::ListBox(const char* label, int* current_item, bool (*items_getter)(v
|
||||
// - PlotLines()
|
||||
// - PlotHistogram()
|
||||
//-------------------------------------------------------------------------
|
||||
// Plot/Graph widgets are not very good.
|
||||
// Consider writing your own, or using a third-party one, see:
|
||||
// - ImPlot https://github.com/epezent/implot
|
||||
// - others https://github.com/ocornut/imgui/wiki/Useful-Widgets
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
int ImGui::PlotEx(ImGuiPlotType plot_type, const char* label, float (*values_getter)(void* data, int idx), void* data, int values_count, int values_offset, const char* overlay_text, float scale_min, float scale_max, ImVec2 frame_size)
|
||||
{
|
||||
@@ -6384,13 +6466,6 @@ void ImGui::Value(const char* prefix, float v, const char* float_format)
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
// Helpers for internal use
|
||||
ImGuiMenuColumns::ImGuiMenuColumns()
|
||||
{
|
||||
Spacing = Width = NextWidth = 0.0f;
|
||||
memset(Pos, 0, sizeof(Pos));
|
||||
memset(NextWidths, 0, sizeof(NextWidths));
|
||||
}
|
||||
|
||||
void ImGuiMenuColumns::Update(int count, float spacing, bool clear)
|
||||
{
|
||||
IM_ASSERT(count == IM_ARRAYSIZE(Pos));
|
||||
@@ -6490,7 +6565,7 @@ void ImGui::EndMenuBar()
|
||||
PopClipRect();
|
||||
PopID();
|
||||
window->DC.MenuBarOffset.x = window->DC.CursorPos.x - window->MenuBarRect().Min.x; // Save horizontal position so next append can reuse it. This is kinda equivalent to a per-layer CursorPos.
|
||||
window->DC.GroupStack.back().EmitItem = false;
|
||||
g.GroupStack.back().EmitItem = false;
|
||||
EndGroup(); // Restore position on layer 0
|
||||
window->DC.LayoutType = ImGuiLayoutType_Vertical;
|
||||
window->DC.NavLayerCurrent = ImGuiNavLayer_Main;
|
||||
@@ -7221,7 +7296,8 @@ static void ImGui::TabBarLayout(ImGuiTabBar* tab_bar)
|
||||
// Actual layout in host window (we don't do it in BeginTabBar() so as not to waste an extra frame)
|
||||
ImGuiWindow* window = g.CurrentWindow;
|
||||
window->DC.CursorPos = tab_bar->BarRect.Min;
|
||||
ItemSize(ImVec2(tab_bar->WidthAllTabsIdeal, tab_bar->BarRect.GetHeight()), tab_bar->FramePadding.y);
|
||||
ItemSize(ImVec2(tab_bar->WidthAllTabs, tab_bar->BarRect.GetHeight()), tab_bar->FramePadding.y);
|
||||
window->DC.IdealMaxPos.x = ImMax(window->DC.IdealMaxPos.x, tab_bar->BarRect.Min.x + tab_bar->WidthAllTabsIdeal);
|
||||
}
|
||||
|
||||
// Dockable uses Name/ID in the global namespace. Non-dockable items use the ID stack.
|
||||
@@ -7444,7 +7520,7 @@ static ImGuiTabItem* ImGui::TabBarScrollingButtons(ImGuiTabBar* tab_bar)
|
||||
{
|
||||
target_order += select_dir;
|
||||
selected_order += select_dir;
|
||||
tab_to_scroll_to = (target_order <= 0 || target_order >= tab_bar->Tabs.Size) ? tab_to_scroll_to : NULL;
|
||||
tab_to_scroll_to = (target_order < 0 || target_order >= tab_bar->Tabs.Size) ? tab_to_scroll_to : NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7545,7 +7621,7 @@ void ImGui::EndTabItem()
|
||||
IM_ASSERT(tab_bar->LastTabItemIdx >= 0);
|
||||
ImGuiTabItem* tab = &tab_bar->Tabs[tab_bar->LastTabItemIdx];
|
||||
if (!(tab->Flags & ImGuiTabItemFlags_NoPushId))
|
||||
window->IDStack.pop_back();
|
||||
PopID();
|
||||
}
|
||||
|
||||
bool ImGui::TabItemButton(const char* label, ImGuiTabItemFlags flags)
|
||||
@@ -7720,7 +7796,7 @@ bool ImGui::TabItemEx(ImGuiTabBar* tab_bar, const char* label, bool* p_open,
|
||||
g.ActiveIdWindow = docked_window;
|
||||
|
||||
// Allow the close button to overlap unless we are dragging (in which case we don't want any overlapping tabs to be hovered)
|
||||
if (!held)
|
||||
if (g.ActiveId != id)
|
||||
SetItemAllowOverlap();
|
||||
|
||||
// Drag and drop a single floating window node moves it
|
||||
@@ -7787,7 +7863,7 @@ bool ImGui::TabItemEx(ImGuiTabBar* tab_bar, const char* label, bool* p_open,
|
||||
}
|
||||
|
||||
#if 0
|
||||
if (hovered && g.HoveredIdNotActiveTimer > 0.50f && bb.GetWidth() < tab->ContentWidth)
|
||||
if (hovered && g.HoveredIdNotActiveTimer > TOOLTIP_DELAY && bb.GetWidth() < tab->ContentWidth)
|
||||
{
|
||||
// Enlarge tab display when hovering
|
||||
bb.Max.x = bb.Min.x + IM_FLOOR(ImLerp(bb.GetWidth(), tab->ContentWidth, ImSaturate((g.HoveredIdNotActiveTimer - 0.40f) * 6.0f)));
|
||||
@@ -7829,7 +7905,7 @@ bool ImGui::TabItemEx(ImGuiTabBar* tab_bar, const char* label, bool* p_open,
|
||||
|
||||
// Tooltip (FIXME: Won't work over the close button because ItemOverlap systems messes up with HoveredIdTimer)
|
||||
// We test IsItemHovered() to discard e.g. when another item is active or drag and drop over the tab bar (which g.HoveredId ignores)
|
||||
if (text_clipped && g.HoveredId == id && !held && g.HoveredIdNotActiveTimer > 0.50f && IsItemHovered())
|
||||
if (text_clipped && g.HoveredId == id && !held && g.HoveredIdNotActiveTimer > g.TooltipSlowDelay && IsItemHovered())
|
||||
if (!(tab_bar->Flags & ImGuiTabBarFlags_NoTooltip) && !(tab->Flags & ImGuiTabItemFlags_NoTooltip))
|
||||
SetTooltip("%.*s", (int)(FindRenderedTextEnd(label) - label), label);
|
||||
|
||||
@@ -7985,446 +8061,4 @@ void ImGui::TabItemLabelAndCloseButton(ImDrawList* draw_list, const ImRect& bb,
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// [SECTION] Widgets: Columns, BeginColumns, EndColumns, etc.
|
||||
// In the current version, Columns are very weak. Needs to be replaced with a more full-featured system.
|
||||
//-------------------------------------------------------------------------
|
||||
// - SetWindowClipRectBeforeSetChannel() [Internal]
|
||||
// - GetColumnIndex()
|
||||
// - GetColumnCount()
|
||||
// - GetColumnOffset()
|
||||
// - GetColumnWidth()
|
||||
// - SetColumnOffset()
|
||||
// - SetColumnWidth()
|
||||
// - PushColumnClipRect() [Internal]
|
||||
// - PushColumnsBackground() [Internal]
|
||||
// - PopColumnsBackground() [Internal]
|
||||
// - FindOrCreateColumns() [Internal]
|
||||
// - GetColumnsID() [Internal]
|
||||
// - BeginColumns()
|
||||
// - NextColumn()
|
||||
// - EndColumns()
|
||||
// - Columns()
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
// [Internal] Small optimization to avoid calls to PopClipRect/SetCurrentChannel/PushClipRect in sequences,
|
||||
// they would meddle many times with the underlying ImDrawCmd.
|
||||
// Instead, we do a preemptive overwrite of clipping rectangle _without_ altering the command-buffer and let
|
||||
// the subsequent single call to SetCurrentChannel() does it things once.
|
||||
void ImGui::SetWindowClipRectBeforeSetChannel(ImGuiWindow* window, const ImRect& clip_rect)
|
||||
{
|
||||
ImVec4 clip_rect_vec4 = clip_rect.ToVec4();
|
||||
window->ClipRect = clip_rect;
|
||||
window->DrawList->_CmdHeader.ClipRect = clip_rect_vec4;
|
||||
window->DrawList->_ClipRectStack.Data[window->DrawList->_ClipRectStack.Size - 1] = clip_rect_vec4;
|
||||
}
|
||||
|
||||
int ImGui::GetColumnIndex()
|
||||
{
|
||||
ImGuiWindow* window = GetCurrentWindowRead();
|
||||
return window->DC.CurrentColumns ? window->DC.CurrentColumns->Current : 0;
|
||||
}
|
||||
|
||||
int ImGui::GetColumnsCount()
|
||||
{
|
||||
ImGuiWindow* window = GetCurrentWindowRead();
|
||||
return window->DC.CurrentColumns ? window->DC.CurrentColumns->Count : 1;
|
||||
}
|
||||
|
||||
float ImGui::GetColumnOffsetFromNorm(const ImGuiColumns* columns, float offset_norm)
|
||||
{
|
||||
return offset_norm * (columns->OffMaxX - columns->OffMinX);
|
||||
}
|
||||
|
||||
float ImGui::GetColumnNormFromOffset(const ImGuiColumns* columns, float offset)
|
||||
{
|
||||
return offset / (columns->OffMaxX - columns->OffMinX);
|
||||
}
|
||||
|
||||
static const float COLUMNS_HIT_RECT_HALF_WIDTH = 4.0f;
|
||||
|
||||
static float GetDraggedColumnOffset(ImGuiColumns* columns, int column_index)
|
||||
{
|
||||
// Active (dragged) column always follow mouse. The reason we need this is that dragging a column to the right edge of an auto-resizing
|
||||
// window creates a feedback loop because we store normalized positions. So while dragging we enforce absolute positioning.
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiWindow* window = g.CurrentWindow;
|
||||
IM_ASSERT(column_index > 0); // We are not supposed to drag column 0.
|
||||
IM_ASSERT(g.ActiveId == columns->ID + ImGuiID(column_index));
|
||||
|
||||
float x = g.IO.MousePos.x - g.ActiveIdClickOffset.x + COLUMNS_HIT_RECT_HALF_WIDTH - window->Pos.x;
|
||||
x = ImMax(x, ImGui::GetColumnOffset(column_index - 1) + g.Style.ColumnsMinSpacing);
|
||||
if ((columns->Flags & ImGuiColumnsFlags_NoPreserveWidths))
|
||||
x = ImMin(x, ImGui::GetColumnOffset(column_index + 1) - g.Style.ColumnsMinSpacing);
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
float ImGui::GetColumnOffset(int column_index)
|
||||
{
|
||||
ImGuiWindow* window = GetCurrentWindowRead();
|
||||
ImGuiColumns* columns = window->DC.CurrentColumns;
|
||||
if (columns == NULL)
|
||||
return 0.0f;
|
||||
|
||||
if (column_index < 0)
|
||||
column_index = columns->Current;
|
||||
IM_ASSERT(column_index < columns->Columns.Size);
|
||||
|
||||
const float t = columns->Columns[column_index].OffsetNorm;
|
||||
const float x_offset = ImLerp(columns->OffMinX, columns->OffMaxX, t);
|
||||
return x_offset;
|
||||
}
|
||||
|
||||
static float GetColumnWidthEx(ImGuiColumns* columns, int column_index, bool before_resize = false)
|
||||
{
|
||||
if (column_index < 0)
|
||||
column_index = columns->Current;
|
||||
|
||||
float offset_norm;
|
||||
if (before_resize)
|
||||
offset_norm = columns->Columns[column_index + 1].OffsetNormBeforeResize - columns->Columns[column_index].OffsetNormBeforeResize;
|
||||
else
|
||||
offset_norm = columns->Columns[column_index + 1].OffsetNorm - columns->Columns[column_index].OffsetNorm;
|
||||
return ImGui::GetColumnOffsetFromNorm(columns, offset_norm);
|
||||
}
|
||||
|
||||
float ImGui::GetColumnWidth(int column_index)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiWindow* window = g.CurrentWindow;
|
||||
ImGuiColumns* columns = window->DC.CurrentColumns;
|
||||
if (columns == NULL)
|
||||
return GetContentRegionAvail().x;
|
||||
|
||||
if (column_index < 0)
|
||||
column_index = columns->Current;
|
||||
return GetColumnOffsetFromNorm(columns, columns->Columns[column_index + 1].OffsetNorm - columns->Columns[column_index].OffsetNorm);
|
||||
}
|
||||
|
||||
void ImGui::SetColumnOffset(int column_index, float offset)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiWindow* window = g.CurrentWindow;
|
||||
ImGuiColumns* columns = window->DC.CurrentColumns;
|
||||
IM_ASSERT(columns != NULL);
|
||||
|
||||
if (column_index < 0)
|
||||
column_index = columns->Current;
|
||||
IM_ASSERT(column_index < columns->Columns.Size);
|
||||
|
||||
const bool preserve_width = !(columns->Flags & ImGuiColumnsFlags_NoPreserveWidths) && (column_index < columns->Count - 1);
|
||||
const float width = preserve_width ? GetColumnWidthEx(columns, column_index, columns->IsBeingResized) : 0.0f;
|
||||
|
||||
if (!(columns->Flags & ImGuiColumnsFlags_NoForceWithinWindow))
|
||||
offset = ImMin(offset, columns->OffMaxX - g.Style.ColumnsMinSpacing * (columns->Count - column_index));
|
||||
columns->Columns[column_index].OffsetNorm = GetColumnNormFromOffset(columns, offset - columns->OffMinX);
|
||||
|
||||
if (preserve_width)
|
||||
SetColumnOffset(column_index + 1, offset + ImMax(g.Style.ColumnsMinSpacing, width));
|
||||
}
|
||||
|
||||
void ImGui::SetColumnWidth(int column_index, float width)
|
||||
{
|
||||
ImGuiWindow* window = GetCurrentWindowRead();
|
||||
ImGuiColumns* columns = window->DC.CurrentColumns;
|
||||
IM_ASSERT(columns != NULL);
|
||||
|
||||
if (column_index < 0)
|
||||
column_index = columns->Current;
|
||||
SetColumnOffset(column_index + 1, GetColumnOffset(column_index) + width);
|
||||
}
|
||||
|
||||
void ImGui::PushColumnClipRect(int column_index)
|
||||
{
|
||||
ImGuiWindow* window = GetCurrentWindowRead();
|
||||
ImGuiColumns* columns = window->DC.CurrentColumns;
|
||||
if (column_index < 0)
|
||||
column_index = columns->Current;
|
||||
|
||||
ImGuiColumnData* column = &columns->Columns[column_index];
|
||||
PushClipRect(column->ClipRect.Min, column->ClipRect.Max, false);
|
||||
}
|
||||
|
||||
// Get into the columns background draw command (which is generally the same draw command as before we called BeginColumns)
|
||||
void ImGui::PushColumnsBackground()
|
||||
{
|
||||
ImGuiWindow* window = GetCurrentWindowRead();
|
||||
ImGuiColumns* columns = window->DC.CurrentColumns;
|
||||
if (columns->Count == 1)
|
||||
return;
|
||||
|
||||
// Optimization: avoid SetCurrentChannel() + PushClipRect()
|
||||
columns->HostBackupClipRect = window->ClipRect;
|
||||
SetWindowClipRectBeforeSetChannel(window, columns->HostInitialClipRect);
|
||||
columns->Splitter.SetCurrentChannel(window->DrawList, 0);
|
||||
}
|
||||
|
||||
void ImGui::PopColumnsBackground()
|
||||
{
|
||||
ImGuiWindow* window = GetCurrentWindowRead();
|
||||
ImGuiColumns* columns = window->DC.CurrentColumns;
|
||||
if (columns->Count == 1)
|
||||
return;
|
||||
|
||||
// Optimization: avoid PopClipRect() + SetCurrentChannel()
|
||||
SetWindowClipRectBeforeSetChannel(window, columns->HostBackupClipRect);
|
||||
columns->Splitter.SetCurrentChannel(window->DrawList, columns->Current + 1);
|
||||
}
|
||||
|
||||
ImGuiColumns* ImGui::FindOrCreateColumns(ImGuiWindow* window, ImGuiID id)
|
||||
{
|
||||
// We have few columns per window so for now we don't need bother much with turning this into a faster lookup.
|
||||
for (int n = 0; n < window->ColumnsStorage.Size; n++)
|
||||
if (window->ColumnsStorage[n].ID == id)
|
||||
return &window->ColumnsStorage[n];
|
||||
|
||||
window->ColumnsStorage.push_back(ImGuiColumns());
|
||||
ImGuiColumns* columns = &window->ColumnsStorage.back();
|
||||
columns->ID = id;
|
||||
return columns;
|
||||
}
|
||||
|
||||
ImGuiID ImGui::GetColumnsID(const char* str_id, int columns_count)
|
||||
{
|
||||
ImGuiWindow* window = GetCurrentWindow();
|
||||
|
||||
// Differentiate column ID with an arbitrary prefix for cases where users name their columns set the same as another widget.
|
||||
// In addition, when an identifier isn't explicitly provided we include the number of columns in the hash to make it uniquer.
|
||||
PushID(0x11223347 + (str_id ? 0 : columns_count));
|
||||
ImGuiID id = window->GetID(str_id ? str_id : "columns");
|
||||
PopID();
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
void ImGui::BeginColumns(const char* str_id, int columns_count, ImGuiColumnsFlags flags)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiWindow* window = GetCurrentWindow();
|
||||
|
||||
IM_ASSERT(columns_count >= 1);
|
||||
IM_ASSERT(window->DC.CurrentColumns == NULL); // Nested columns are currently not supported
|
||||
|
||||
// Acquire storage for the columns set
|
||||
ImGuiID id = GetColumnsID(str_id, columns_count);
|
||||
ImGuiColumns* columns = FindOrCreateColumns(window, id);
|
||||
IM_ASSERT(columns->ID == id);
|
||||
columns->Current = 0;
|
||||
columns->Count = columns_count;
|
||||
columns->Flags = flags;
|
||||
window->DC.CurrentColumns = columns;
|
||||
|
||||
columns->HostCursorPosY = window->DC.CursorPos.y;
|
||||
columns->HostCursorMaxPosX = window->DC.CursorMaxPos.x;
|
||||
columns->HostInitialClipRect = window->ClipRect;
|
||||
columns->HostBackupParentWorkRect = window->ParentWorkRect;
|
||||
window->ParentWorkRect = window->WorkRect;
|
||||
|
||||
// Set state for first column
|
||||
// We aim so that the right-most column will have the same clipping width as other after being clipped by parent ClipRect
|
||||
const float column_padding = g.Style.ItemSpacing.x;
|
||||
const float half_clip_extend_x = ImFloor(ImMax(window->WindowPadding.x * 0.5f, window->WindowBorderSize));
|
||||
const float max_1 = window->WorkRect.Max.x + column_padding - ImMax(column_padding - window->WindowPadding.x, 0.0f);
|
||||
const float max_2 = window->WorkRect.Max.x + half_clip_extend_x;
|
||||
columns->OffMinX = window->DC.Indent.x - column_padding + ImMax(column_padding - window->WindowPadding.x, 0.0f);
|
||||
columns->OffMaxX = ImMax(ImMin(max_1, max_2) - window->Pos.x, columns->OffMinX + 1.0f);
|
||||
columns->LineMinY = columns->LineMaxY = window->DC.CursorPos.y;
|
||||
|
||||
// Clear data if columns count changed
|
||||
if (columns->Columns.Size != 0 && columns->Columns.Size != columns_count + 1)
|
||||
columns->Columns.resize(0);
|
||||
|
||||
// Initialize default widths
|
||||
columns->IsFirstFrame = (columns->Columns.Size == 0);
|
||||
if (columns->Columns.Size == 0)
|
||||
{
|
||||
columns->Columns.reserve(columns_count + 1);
|
||||
for (int n = 0; n < columns_count + 1; n++)
|
||||
{
|
||||
ImGuiColumnData column;
|
||||
column.OffsetNorm = n / (float)columns_count;
|
||||
columns->Columns.push_back(column);
|
||||
}
|
||||
}
|
||||
|
||||
for (int n = 0; n < columns_count; n++)
|
||||
{
|
||||
// Compute clipping rectangle
|
||||
ImGuiColumnData* column = &columns->Columns[n];
|
||||
float clip_x1 = IM_ROUND(window->Pos.x + GetColumnOffset(n));
|
||||
float clip_x2 = IM_ROUND(window->Pos.x + GetColumnOffset(n + 1) - 1.0f);
|
||||
column->ClipRect = ImRect(clip_x1, -FLT_MAX, clip_x2, +FLT_MAX);
|
||||
column->ClipRect.ClipWithFull(window->ClipRect);
|
||||
}
|
||||
|
||||
if (columns->Count > 1)
|
||||
{
|
||||
columns->Splitter.Split(window->DrawList, 1 + columns->Count);
|
||||
columns->Splitter.SetCurrentChannel(window->DrawList, 1);
|
||||
PushColumnClipRect(0);
|
||||
}
|
||||
|
||||
// We don't generally store Indent.x inside ColumnsOffset because it may be manipulated by the user.
|
||||
float offset_0 = GetColumnOffset(columns->Current);
|
||||
float offset_1 = GetColumnOffset(columns->Current + 1);
|
||||
float width = offset_1 - offset_0;
|
||||
PushItemWidth(width * 0.65f);
|
||||
window->DC.ColumnsOffset.x = ImMax(column_padding - window->WindowPadding.x, 0.0f);
|
||||
window->DC.CursorPos.x = IM_FLOOR(window->Pos.x + window->DC.Indent.x + window->DC.ColumnsOffset.x);
|
||||
window->WorkRect.Max.x = window->Pos.x + offset_1 - column_padding;
|
||||
}
|
||||
|
||||
void ImGui::NextColumn()
|
||||
{
|
||||
ImGuiWindow* window = GetCurrentWindow();
|
||||
if (window->SkipItems || window->DC.CurrentColumns == NULL)
|
||||
return;
|
||||
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiColumns* columns = window->DC.CurrentColumns;
|
||||
|
||||
if (columns->Count == 1)
|
||||
{
|
||||
window->DC.CursorPos.x = IM_FLOOR(window->Pos.x + window->DC.Indent.x + window->DC.ColumnsOffset.x);
|
||||
IM_ASSERT(columns->Current == 0);
|
||||
return;
|
||||
}
|
||||
|
||||
// Next column
|
||||
if (++columns->Current == columns->Count)
|
||||
columns->Current = 0;
|
||||
|
||||
PopItemWidth();
|
||||
|
||||
// Optimization: avoid PopClipRect() + SetCurrentChannel() + PushClipRect()
|
||||
// (which would needlessly attempt to update commands in the wrong channel, then pop or overwrite them),
|
||||
ImGuiColumnData* column = &columns->Columns[columns->Current];
|
||||
SetWindowClipRectBeforeSetChannel(window, column->ClipRect);
|
||||
columns->Splitter.SetCurrentChannel(window->DrawList, columns->Current + 1);
|
||||
|
||||
const float column_padding = g.Style.ItemSpacing.x;
|
||||
columns->LineMaxY = ImMax(columns->LineMaxY, window->DC.CursorPos.y);
|
||||
if (columns->Current > 0)
|
||||
{
|
||||
// Columns 1+ ignore IndentX (by canceling it out)
|
||||
// FIXME-COLUMNS: Unnecessary, could be locked?
|
||||
window->DC.ColumnsOffset.x = GetColumnOffset(columns->Current) - window->DC.Indent.x + column_padding;
|
||||
}
|
||||
else
|
||||
{
|
||||
// New row/line: column 0 honor IndentX.
|
||||
window->DC.ColumnsOffset.x = ImMax(column_padding - window->WindowPadding.x, 0.0f);
|
||||
columns->LineMinY = columns->LineMaxY;
|
||||
}
|
||||
window->DC.CursorPos.x = IM_FLOOR(window->Pos.x + window->DC.Indent.x + window->DC.ColumnsOffset.x);
|
||||
window->DC.CursorPos.y = columns->LineMinY;
|
||||
window->DC.CurrLineSize = ImVec2(0.0f, 0.0f);
|
||||
window->DC.CurrLineTextBaseOffset = 0.0f;
|
||||
|
||||
// FIXME-COLUMNS: Share code with BeginColumns() - move code on columns setup.
|
||||
float offset_0 = GetColumnOffset(columns->Current);
|
||||
float offset_1 = GetColumnOffset(columns->Current + 1);
|
||||
float width = offset_1 - offset_0;
|
||||
PushItemWidth(width * 0.65f);
|
||||
window->WorkRect.Max.x = window->Pos.x + offset_1 - column_padding;
|
||||
}
|
||||
|
||||
void ImGui::EndColumns()
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiWindow* window = GetCurrentWindow();
|
||||
ImGuiColumns* columns = window->DC.CurrentColumns;
|
||||
IM_ASSERT(columns != NULL);
|
||||
|
||||
PopItemWidth();
|
||||
if (columns->Count > 1)
|
||||
{
|
||||
PopClipRect();
|
||||
columns->Splitter.Merge(window->DrawList);
|
||||
}
|
||||
|
||||
const ImGuiColumnsFlags flags = columns->Flags;
|
||||
columns->LineMaxY = ImMax(columns->LineMaxY, window->DC.CursorPos.y);
|
||||
window->DC.CursorPos.y = columns->LineMaxY;
|
||||
if (!(flags & ImGuiColumnsFlags_GrowParentContentsSize))
|
||||
window->DC.CursorMaxPos.x = columns->HostCursorMaxPosX; // Restore cursor max pos, as columns don't grow parent
|
||||
|
||||
// Draw columns borders and handle resize
|
||||
// The IsBeingResized flag ensure we preserve pre-resize columns width so back-and-forth are not lossy
|
||||
bool is_being_resized = false;
|
||||
if (!(flags & ImGuiColumnsFlags_NoBorder) && !window->SkipItems)
|
||||
{
|
||||
// We clip Y boundaries CPU side because very long triangles are mishandled by some GPU drivers.
|
||||
const float y1 = ImMax(columns->HostCursorPosY, window->ClipRect.Min.y);
|
||||
const float y2 = ImMin(window->DC.CursorPos.y, window->ClipRect.Max.y);
|
||||
int dragging_column = -1;
|
||||
for (int n = 1; n < columns->Count; n++)
|
||||
{
|
||||
ImGuiColumnData* column = &columns->Columns[n];
|
||||
float x = window->Pos.x + GetColumnOffset(n);
|
||||
const ImGuiID column_id = columns->ID + ImGuiID(n);
|
||||
const float column_hit_hw = COLUMNS_HIT_RECT_HALF_WIDTH;
|
||||
const ImRect column_hit_rect(ImVec2(x - column_hit_hw, y1), ImVec2(x + column_hit_hw, y2));
|
||||
KeepAliveID(column_id);
|
||||
if (IsClippedEx(column_hit_rect, column_id, false))
|
||||
continue;
|
||||
|
||||
bool hovered = false, held = false;
|
||||
if (!(flags & ImGuiColumnsFlags_NoResize))
|
||||
{
|
||||
ButtonBehavior(column_hit_rect, column_id, &hovered, &held);
|
||||
if (hovered || held)
|
||||
g.MouseCursor = ImGuiMouseCursor_ResizeEW;
|
||||
if (held && !(column->Flags & ImGuiColumnsFlags_NoResize))
|
||||
dragging_column = n;
|
||||
}
|
||||
|
||||
// Draw column
|
||||
const ImU32 col = GetColorU32(held ? ImGuiCol_SeparatorActive : hovered ? ImGuiCol_SeparatorHovered : ImGuiCol_Separator);
|
||||
const float xi = IM_FLOOR(x);
|
||||
window->DrawList->AddLine(ImVec2(xi, y1 + 1.0f), ImVec2(xi, y2), col);
|
||||
}
|
||||
|
||||
// Apply dragging after drawing the column lines, so our rendered lines are in sync with how items were displayed during the frame.
|
||||
if (dragging_column != -1)
|
||||
{
|
||||
if (!columns->IsBeingResized)
|
||||
for (int n = 0; n < columns->Count + 1; n++)
|
||||
columns->Columns[n].OffsetNormBeforeResize = columns->Columns[n].OffsetNorm;
|
||||
columns->IsBeingResized = is_being_resized = true;
|
||||
float x = GetDraggedColumnOffset(columns, dragging_column);
|
||||
SetColumnOffset(dragging_column, x);
|
||||
}
|
||||
}
|
||||
columns->IsBeingResized = is_being_resized;
|
||||
|
||||
window->WorkRect = window->ParentWorkRect;
|
||||
window->ParentWorkRect = columns->HostBackupParentWorkRect;
|
||||
window->DC.CurrentColumns = NULL;
|
||||
window->DC.ColumnsOffset.x = 0.0f;
|
||||
window->DC.CursorPos.x = IM_FLOOR(window->Pos.x + window->DC.Indent.x + window->DC.ColumnsOffset.x);
|
||||
}
|
||||
|
||||
// [2018-03: This is currently the only public API, while we are working on making BeginColumns/EndColumns user-facing]
|
||||
void ImGui::Columns(int columns_count, const char* id, bool border)
|
||||
{
|
||||
ImGuiWindow* window = GetCurrentWindow();
|
||||
IM_ASSERT(columns_count >= 1);
|
||||
|
||||
ImGuiColumnsFlags flags = (border ? 0 : ImGuiColumnsFlags_NoBorder);
|
||||
//flags |= ImGuiColumnsFlags_NoPreserveWidths; // NB: Legacy behavior
|
||||
ImGuiColumns* columns = window->DC.CurrentColumns;
|
||||
if (columns != NULL && columns->Count == columns_count && columns->Flags == flags)
|
||||
return;
|
||||
|
||||
if (columns != NULL)
|
||||
EndColumns();
|
||||
|
||||
if (columns_count != 1)
|
||||
BeginColumns(id, columns_count, flags);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
#endif // #ifndef IMGUI_DISABLE
|
||||
2944
external/ImGui/source/imnodes.cpp
vendored
Normal file
2944
external/ImGui/source/imnodes.cpp
vendored
Normal file
File diff suppressed because it is too large
Load Diff
22
external/glad/CMakeLists.txt
vendored
Normal file
22
external/glad/CMakeLists.txt
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
project(glad)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
|
||||
if (WIN32)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -static-libstdc++ -static-libgcc")
|
||||
endif()
|
||||
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC")
|
||||
|
||||
add_library(glad
|
||||
source/glad.c
|
||||
)
|
||||
|
||||
target_include_directories(glad PUBLIC include)
|
||||
|
||||
if (WIN32)
|
||||
target_link_libraries(glad PRIVATE libdl.a)
|
||||
else()
|
||||
target_link_libraries(glad PRIVATE dl)
|
||||
endif()
|
||||
19
external/llvm/CMakeLists.txt
vendored
Normal file
19
external/llvm/CMakeLists.txt
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
project(LLVMDemangle)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
|
||||
if (WIN32)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -static-libstdc++ -static-libgcc")
|
||||
endif()
|
||||
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC")
|
||||
|
||||
add_library(LLVMDemangle
|
||||
Demangle/Demangle.cpp
|
||||
Demangle/ItaniumDemangle.cpp
|
||||
Demangle/MicrosoftDemangle.cpp
|
||||
Demangle/MicrosoftDemangleNodes.cpp
|
||||
)
|
||||
|
||||
target_include_directories(LLVMDemangle PUBLIC include)
|
||||
36
external/llvm/Demangle/Demangle.cpp
vendored
Normal file
36
external/llvm/Demangle/Demangle.cpp
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
//===-- Demangle.cpp - Common demangling functions ------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
///
|
||||
/// \file This file contains definitions of common demangling functions.
|
||||
///
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "llvm/Demangle/Demangle.h"
|
||||
#include <cstdlib>
|
||||
|
||||
static bool isItaniumEncoding(const std::string &MangledName) {
|
||||
size_t Pos = MangledName.find_first_not_of('_');
|
||||
// A valid Itanium encoding requires 1-4 leading underscores, followed by 'Z'.
|
||||
return Pos > 0 && Pos <= 4 && MangledName[Pos] == 'Z';
|
||||
}
|
||||
|
||||
std::string llvm::demangle(const std::string &MangledName) {
|
||||
char *Demangled;
|
||||
if (isItaniumEncoding(MangledName))
|
||||
Demangled = itaniumDemangle(MangledName.c_str(), nullptr, nullptr, nullptr);
|
||||
else
|
||||
Demangled = microsoftDemangle(MangledName.c_str(), nullptr, nullptr,
|
||||
nullptr, nullptr);
|
||||
|
||||
if (!Demangled)
|
||||
return MangledName;
|
||||
|
||||
std::string Ret = Demangled;
|
||||
free(Demangled);
|
||||
return Ret;
|
||||
}
|
||||
577
external/llvm/Demangle/ItaniumDemangle.cpp
vendored
Normal file
577
external/llvm/Demangle/ItaniumDemangle.cpp
vendored
Normal file
@@ -0,0 +1,577 @@
|
||||
//===------------------------- ItaniumDemangle.cpp ------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// FIXME: (possibly) incomplete list of features that clang mangles that this
|
||||
// file does not yet support:
|
||||
// - C++ modules TS
|
||||
|
||||
#include "llvm/Demangle/Demangle.h"
|
||||
#include "llvm/Demangle/ItaniumDemangle.h"
|
||||
|
||||
#include <cassert>
|
||||
#include <cctype>
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <functional>
|
||||
#include <numeric>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
using namespace llvm;
|
||||
using namespace llvm::itanium_demangle;
|
||||
|
||||
constexpr const char *itanium_demangle::FloatData<float>::spec;
|
||||
constexpr const char *itanium_demangle::FloatData<double>::spec;
|
||||
constexpr const char *itanium_demangle::FloatData<long double>::spec;
|
||||
|
||||
// <discriminator> := _ <non-negative number> # when number < 10
|
||||
// := __ <non-negative number> _ # when number >= 10
|
||||
// extension := decimal-digit+ # at the end of string
|
||||
const char *itanium_demangle::parse_discriminator(const char *first,
|
||||
const char *last) {
|
||||
// parse but ignore discriminator
|
||||
if (first != last) {
|
||||
if (*first == '_') {
|
||||
const char *t1 = first + 1;
|
||||
if (t1 != last) {
|
||||
if (std::isdigit(*t1))
|
||||
first = t1 + 1;
|
||||
else if (*t1 == '_') {
|
||||
for (++t1; t1 != last && std::isdigit(*t1); ++t1)
|
||||
;
|
||||
if (t1 != last && *t1 == '_')
|
||||
first = t1 + 1;
|
||||
}
|
||||
}
|
||||
} else if (std::isdigit(*first)) {
|
||||
const char *t1 = first + 1;
|
||||
for (; t1 != last && std::isdigit(*t1); ++t1)
|
||||
;
|
||||
if (t1 == last)
|
||||
first = last;
|
||||
}
|
||||
}
|
||||
return first;
|
||||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
namespace {
|
||||
struct DumpVisitor {
|
||||
unsigned Depth = 0;
|
||||
bool PendingNewline = false;
|
||||
|
||||
template<typename NodeT> static constexpr bool wantsNewline(const NodeT *) {
|
||||
return true;
|
||||
}
|
||||
static bool wantsNewline(NodeArray A) { return !A.empty(); }
|
||||
static constexpr bool wantsNewline(...) { return false; }
|
||||
|
||||
template<typename ...Ts> static bool anyWantNewline(Ts ...Vs) {
|
||||
for (bool B : {wantsNewline(Vs)...})
|
||||
if (B)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
void printStr(const char *S) { fprintf(stderr, "%s", S); }
|
||||
void print(StringView SV) {
|
||||
fprintf(stderr, "\"%.*s\"", (int)SV.size(), SV.begin());
|
||||
}
|
||||
void print(const Node *N) {
|
||||
if (N)
|
||||
N->visit(std::ref(*this));
|
||||
else
|
||||
printStr("<null>");
|
||||
}
|
||||
void print(NodeArray A) {
|
||||
++Depth;
|
||||
printStr("{");
|
||||
bool First = true;
|
||||
for (const Node *N : A) {
|
||||
if (First)
|
||||
print(N);
|
||||
else
|
||||
printWithComma(N);
|
||||
First = false;
|
||||
}
|
||||
printStr("}");
|
||||
--Depth;
|
||||
}
|
||||
|
||||
// Overload used when T is exactly 'bool', not merely convertible to 'bool'.
|
||||
void print(bool B) { printStr(B ? "true" : "false"); }
|
||||
|
||||
template <class T> std::enable_if_t<std::is_unsigned<T>::value> print(T N) {
|
||||
fprintf(stderr, "%llu", (unsigned long long)N);
|
||||
}
|
||||
|
||||
template <class T> std::enable_if_t<std::is_signed<T>::value> print(T N) {
|
||||
fprintf(stderr, "%lld", (long long)N);
|
||||
}
|
||||
|
||||
void print(ReferenceKind RK) {
|
||||
switch (RK) {
|
||||
case ReferenceKind::LValue:
|
||||
return printStr("ReferenceKind::LValue");
|
||||
case ReferenceKind::RValue:
|
||||
return printStr("ReferenceKind::RValue");
|
||||
}
|
||||
}
|
||||
void print(FunctionRefQual RQ) {
|
||||
switch (RQ) {
|
||||
case FunctionRefQual::FrefQualNone:
|
||||
return printStr("FunctionRefQual::FrefQualNone");
|
||||
case FunctionRefQual::FrefQualLValue:
|
||||
return printStr("FunctionRefQual::FrefQualLValue");
|
||||
case FunctionRefQual::FrefQualRValue:
|
||||
return printStr("FunctionRefQual::FrefQualRValue");
|
||||
}
|
||||
}
|
||||
void print(Qualifiers Qs) {
|
||||
if (!Qs) return printStr("QualNone");
|
||||
struct QualName { Qualifiers Q; const char *Name; } Names[] = {
|
||||
{QualConst, "QualConst"},
|
||||
{QualVolatile, "QualVolatile"},
|
||||
{QualRestrict, "QualRestrict"},
|
||||
};
|
||||
for (QualName Name : Names) {
|
||||
if (Qs & Name.Q) {
|
||||
printStr(Name.Name);
|
||||
Qs = Qualifiers(Qs & ~Name.Q);
|
||||
if (Qs) printStr(" | ");
|
||||
}
|
||||
}
|
||||
}
|
||||
void print(SpecialSubKind SSK) {
|
||||
switch (SSK) {
|
||||
case SpecialSubKind::allocator:
|
||||
return printStr("SpecialSubKind::allocator");
|
||||
case SpecialSubKind::basic_string:
|
||||
return printStr("SpecialSubKind::basic_string");
|
||||
case SpecialSubKind::string:
|
||||
return printStr("SpecialSubKind::string");
|
||||
case SpecialSubKind::istream:
|
||||
return printStr("SpecialSubKind::istream");
|
||||
case SpecialSubKind::ostream:
|
||||
return printStr("SpecialSubKind::ostream");
|
||||
case SpecialSubKind::iostream:
|
||||
return printStr("SpecialSubKind::iostream");
|
||||
}
|
||||
}
|
||||
void print(TemplateParamKind TPK) {
|
||||
switch (TPK) {
|
||||
case TemplateParamKind::Type:
|
||||
return printStr("TemplateParamKind::Type");
|
||||
case TemplateParamKind::NonType:
|
||||
return printStr("TemplateParamKind::NonType");
|
||||
case TemplateParamKind::Template:
|
||||
return printStr("TemplateParamKind::Template");
|
||||
}
|
||||
}
|
||||
|
||||
void newLine() {
|
||||
printStr("\n");
|
||||
for (unsigned I = 0; I != Depth; ++I)
|
||||
printStr(" ");
|
||||
PendingNewline = false;
|
||||
}
|
||||
|
||||
template<typename T> void printWithPendingNewline(T V) {
|
||||
print(V);
|
||||
if (wantsNewline(V))
|
||||
PendingNewline = true;
|
||||
}
|
||||
|
||||
template<typename T> void printWithComma(T V) {
|
||||
if (PendingNewline || wantsNewline(V)) {
|
||||
printStr(",");
|
||||
newLine();
|
||||
} else {
|
||||
printStr(", ");
|
||||
}
|
||||
|
||||
printWithPendingNewline(V);
|
||||
}
|
||||
|
||||
struct CtorArgPrinter {
|
||||
DumpVisitor &Visitor;
|
||||
|
||||
template<typename T, typename ...Rest> void operator()(T V, Rest ...Vs) {
|
||||
if (Visitor.anyWantNewline(V, Vs...))
|
||||
Visitor.newLine();
|
||||
Visitor.printWithPendingNewline(V);
|
||||
int PrintInOrder[] = { (Visitor.printWithComma(Vs), 0)..., 0 };
|
||||
(void)PrintInOrder;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename NodeT> void operator()(const NodeT *Node) {
|
||||
Depth += 2;
|
||||
fprintf(stderr, "%s(", itanium_demangle::NodeKind<NodeT>::name());
|
||||
Node->match(CtorArgPrinter{*this});
|
||||
fprintf(stderr, ")");
|
||||
Depth -= 2;
|
||||
}
|
||||
|
||||
void operator()(const ForwardTemplateReference *Node) {
|
||||
Depth += 2;
|
||||
fprintf(stderr, "ForwardTemplateReference(");
|
||||
if (Node->Ref && !Node->Printing) {
|
||||
Node->Printing = true;
|
||||
CtorArgPrinter{*this}(Node->Ref);
|
||||
Node->Printing = false;
|
||||
} else {
|
||||
CtorArgPrinter{*this}(Node->Index);
|
||||
}
|
||||
fprintf(stderr, ")");
|
||||
Depth -= 2;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
void itanium_demangle::Node::dump() const {
|
||||
DumpVisitor V;
|
||||
visit(std::ref(V));
|
||||
V.newLine();
|
||||
}
|
||||
#endif
|
||||
|
||||
namespace {
|
||||
class BumpPointerAllocator {
|
||||
struct BlockMeta {
|
||||
BlockMeta* Next;
|
||||
size_t Current;
|
||||
};
|
||||
|
||||
static constexpr size_t AllocSize = 4096;
|
||||
static constexpr size_t UsableAllocSize = AllocSize - sizeof(BlockMeta);
|
||||
|
||||
alignas(long double) char InitialBuffer[AllocSize];
|
||||
BlockMeta* BlockList = nullptr;
|
||||
|
||||
void grow() {
|
||||
char* NewMeta = static_cast<char *>(std::malloc(AllocSize));
|
||||
if (NewMeta == nullptr)
|
||||
std::terminate();
|
||||
BlockList = new (NewMeta) BlockMeta{BlockList, 0};
|
||||
}
|
||||
|
||||
void* allocateMassive(size_t NBytes) {
|
||||
NBytes += sizeof(BlockMeta);
|
||||
BlockMeta* NewMeta = reinterpret_cast<BlockMeta*>(std::malloc(NBytes));
|
||||
if (NewMeta == nullptr)
|
||||
std::terminate();
|
||||
BlockList->Next = new (NewMeta) BlockMeta{BlockList->Next, 0};
|
||||
return static_cast<void*>(NewMeta + 1);
|
||||
}
|
||||
|
||||
public:
|
||||
BumpPointerAllocator()
|
||||
: BlockList(new (InitialBuffer) BlockMeta{nullptr, 0}) {}
|
||||
|
||||
void* allocate(size_t N) {
|
||||
N = (N + 15u) & ~15u;
|
||||
if (N + BlockList->Current >= UsableAllocSize) {
|
||||
if (N > UsableAllocSize)
|
||||
return allocateMassive(N);
|
||||
grow();
|
||||
}
|
||||
BlockList->Current += N;
|
||||
return static_cast<void*>(reinterpret_cast<char*>(BlockList + 1) +
|
||||
BlockList->Current - N);
|
||||
}
|
||||
|
||||
void reset() {
|
||||
while (BlockList) {
|
||||
BlockMeta* Tmp = BlockList;
|
||||
BlockList = BlockList->Next;
|
||||
if (reinterpret_cast<char*>(Tmp) != InitialBuffer)
|
||||
std::free(Tmp);
|
||||
}
|
||||
BlockList = new (InitialBuffer) BlockMeta{nullptr, 0};
|
||||
}
|
||||
|
||||
~BumpPointerAllocator() { reset(); }
|
||||
};
|
||||
|
||||
class DefaultAllocator {
|
||||
BumpPointerAllocator Alloc;
|
||||
|
||||
public:
|
||||
void reset() { Alloc.reset(); }
|
||||
|
||||
template<typename T, typename ...Args> T *makeNode(Args &&...args) {
|
||||
return new (Alloc.allocate(sizeof(T)))
|
||||
T(std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
void *allocateNodeArray(size_t sz) {
|
||||
return Alloc.allocate(sizeof(Node *) * sz);
|
||||
}
|
||||
};
|
||||
} // unnamed namespace
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Code beyond this point should not be synchronized with libc++abi.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
using Demangler = itanium_demangle::ManglingParser<DefaultAllocator>;
|
||||
|
||||
char *llvm::itaniumDemangle(const char *MangledName, char *Buf,
|
||||
size_t *N, int *Status) {
|
||||
if (MangledName == nullptr || (Buf != nullptr && N == nullptr)) {
|
||||
if (Status)
|
||||
*Status = demangle_invalid_args;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
int InternalStatus = demangle_success;
|
||||
Demangler Parser(MangledName, MangledName + std::strlen(MangledName));
|
||||
OutputStream S;
|
||||
|
||||
Node *AST = Parser.parse();
|
||||
|
||||
if (AST == nullptr)
|
||||
InternalStatus = demangle_invalid_mangled_name;
|
||||
else if (!initializeOutputStream(Buf, N, S, 1024))
|
||||
InternalStatus = demangle_memory_alloc_failure;
|
||||
else {
|
||||
assert(Parser.ForwardTemplateRefs.empty());
|
||||
AST->print(S);
|
||||
S += '\0';
|
||||
if (N != nullptr)
|
||||
*N = S.getCurrentPosition();
|
||||
Buf = S.getBuffer();
|
||||
}
|
||||
|
||||
if (Status)
|
||||
*Status = InternalStatus;
|
||||
return InternalStatus == demangle_success ? Buf : nullptr;
|
||||
}
|
||||
|
||||
ItaniumPartialDemangler::ItaniumPartialDemangler()
|
||||
: RootNode(nullptr), Context(new Demangler{nullptr, nullptr}) {}
|
||||
|
||||
ItaniumPartialDemangler::~ItaniumPartialDemangler() {
|
||||
delete static_cast<Demangler *>(Context);
|
||||
}
|
||||
|
||||
ItaniumPartialDemangler::ItaniumPartialDemangler(
|
||||
ItaniumPartialDemangler &&Other)
|
||||
: RootNode(Other.RootNode), Context(Other.Context) {
|
||||
Other.Context = Other.RootNode = nullptr;
|
||||
}
|
||||
|
||||
ItaniumPartialDemangler &ItaniumPartialDemangler::
|
||||
operator=(ItaniumPartialDemangler &&Other) {
|
||||
std::swap(RootNode, Other.RootNode);
|
||||
std::swap(Context, Other.Context);
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Demangle MangledName into an AST, storing it into this->RootNode.
|
||||
bool ItaniumPartialDemangler::partialDemangle(const char *MangledName) {
|
||||
Demangler *Parser = static_cast<Demangler *>(Context);
|
||||
size_t Len = std::strlen(MangledName);
|
||||
Parser->reset(MangledName, MangledName + Len);
|
||||
RootNode = Parser->parse();
|
||||
return RootNode == nullptr;
|
||||
}
|
||||
|
||||
static char *printNode(const Node *RootNode, char *Buf, size_t *N) {
|
||||
OutputStream S;
|
||||
if (!initializeOutputStream(Buf, N, S, 128))
|
||||
return nullptr;
|
||||
RootNode->print(S);
|
||||
S += '\0';
|
||||
if (N != nullptr)
|
||||
*N = S.getCurrentPosition();
|
||||
return S.getBuffer();
|
||||
}
|
||||
|
||||
char *ItaniumPartialDemangler::getFunctionBaseName(char *Buf, size_t *N) const {
|
||||
if (!isFunction())
|
||||
return nullptr;
|
||||
|
||||
const Node *Name = static_cast<const FunctionEncoding *>(RootNode)->getName();
|
||||
|
||||
while (true) {
|
||||
switch (Name->getKind()) {
|
||||
case Node::KAbiTagAttr:
|
||||
Name = static_cast<const AbiTagAttr *>(Name)->Base;
|
||||
continue;
|
||||
case Node::KStdQualifiedName:
|
||||
Name = static_cast<const StdQualifiedName *>(Name)->Child;
|
||||
continue;
|
||||
case Node::KNestedName:
|
||||
Name = static_cast<const NestedName *>(Name)->Name;
|
||||
continue;
|
||||
case Node::KLocalName:
|
||||
Name = static_cast<const LocalName *>(Name)->Entity;
|
||||
continue;
|
||||
case Node::KNameWithTemplateArgs:
|
||||
Name = static_cast<const NameWithTemplateArgs *>(Name)->Name;
|
||||
continue;
|
||||
default:
|
||||
return printNode(Name, Buf, N);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
char *ItaniumPartialDemangler::getFunctionDeclContextName(char *Buf,
|
||||
size_t *N) const {
|
||||
if (!isFunction())
|
||||
return nullptr;
|
||||
const Node *Name = static_cast<const FunctionEncoding *>(RootNode)->getName();
|
||||
|
||||
OutputStream S;
|
||||
if (!initializeOutputStream(Buf, N, S, 128))
|
||||
return nullptr;
|
||||
|
||||
KeepGoingLocalFunction:
|
||||
while (true) {
|
||||
if (Name->getKind() == Node::KAbiTagAttr) {
|
||||
Name = static_cast<const AbiTagAttr *>(Name)->Base;
|
||||
continue;
|
||||
}
|
||||
if (Name->getKind() == Node::KNameWithTemplateArgs) {
|
||||
Name = static_cast<const NameWithTemplateArgs *>(Name)->Name;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
switch (Name->getKind()) {
|
||||
case Node::KStdQualifiedName:
|
||||
S += "std";
|
||||
break;
|
||||
case Node::KNestedName:
|
||||
static_cast<const NestedName *>(Name)->Qual->print(S);
|
||||
break;
|
||||
case Node::KLocalName: {
|
||||
auto *LN = static_cast<const LocalName *>(Name);
|
||||
LN->Encoding->print(S);
|
||||
S += "::";
|
||||
Name = LN->Entity;
|
||||
goto KeepGoingLocalFunction;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
S += '\0';
|
||||
if (N != nullptr)
|
||||
*N = S.getCurrentPosition();
|
||||
return S.getBuffer();
|
||||
}
|
||||
|
||||
char *ItaniumPartialDemangler::getFunctionName(char *Buf, size_t *N) const {
|
||||
if (!isFunction())
|
||||
return nullptr;
|
||||
auto *Name = static_cast<FunctionEncoding *>(RootNode)->getName();
|
||||
return printNode(Name, Buf, N);
|
||||
}
|
||||
|
||||
char *ItaniumPartialDemangler::getFunctionParameters(char *Buf,
|
||||
size_t *N) const {
|
||||
if (!isFunction())
|
||||
return nullptr;
|
||||
NodeArray Params = static_cast<FunctionEncoding *>(RootNode)->getParams();
|
||||
|
||||
OutputStream S;
|
||||
if (!initializeOutputStream(Buf, N, S, 128))
|
||||
return nullptr;
|
||||
|
||||
S += '(';
|
||||
Params.printWithComma(S);
|
||||
S += ')';
|
||||
S += '\0';
|
||||
if (N != nullptr)
|
||||
*N = S.getCurrentPosition();
|
||||
return S.getBuffer();
|
||||
}
|
||||
|
||||
char *ItaniumPartialDemangler::getFunctionReturnType(
|
||||
char *Buf, size_t *N) const {
|
||||
if (!isFunction())
|
||||
return nullptr;
|
||||
|
||||
OutputStream S;
|
||||
if (!initializeOutputStream(Buf, N, S, 128))
|
||||
return nullptr;
|
||||
|
||||
if (const Node *Ret =
|
||||
static_cast<const FunctionEncoding *>(RootNode)->getReturnType())
|
||||
Ret->print(S);
|
||||
|
||||
S += '\0';
|
||||
if (N != nullptr)
|
||||
*N = S.getCurrentPosition();
|
||||
return S.getBuffer();
|
||||
}
|
||||
|
||||
char *ItaniumPartialDemangler::finishDemangle(char *Buf, size_t *N) const {
|
||||
assert(RootNode != nullptr && "must call partialDemangle()");
|
||||
return printNode(static_cast<Node *>(RootNode), Buf, N);
|
||||
}
|
||||
|
||||
bool ItaniumPartialDemangler::hasFunctionQualifiers() const {
|
||||
assert(RootNode != nullptr && "must call partialDemangle()");
|
||||
if (!isFunction())
|
||||
return false;
|
||||
auto *E = static_cast<const FunctionEncoding *>(RootNode);
|
||||
return E->getCVQuals() != QualNone || E->getRefQual() != FrefQualNone;
|
||||
}
|
||||
|
||||
bool ItaniumPartialDemangler::isCtorOrDtor() const {
|
||||
const Node *N = static_cast<const Node *>(RootNode);
|
||||
while (N) {
|
||||
switch (N->getKind()) {
|
||||
default:
|
||||
return false;
|
||||
case Node::KCtorDtorName:
|
||||
return true;
|
||||
|
||||
case Node::KAbiTagAttr:
|
||||
N = static_cast<const AbiTagAttr *>(N)->Base;
|
||||
break;
|
||||
case Node::KFunctionEncoding:
|
||||
N = static_cast<const FunctionEncoding *>(N)->getName();
|
||||
break;
|
||||
case Node::KLocalName:
|
||||
N = static_cast<const LocalName *>(N)->Entity;
|
||||
break;
|
||||
case Node::KNameWithTemplateArgs:
|
||||
N = static_cast<const NameWithTemplateArgs *>(N)->Name;
|
||||
break;
|
||||
case Node::KNestedName:
|
||||
N = static_cast<const NestedName *>(N)->Name;
|
||||
break;
|
||||
case Node::KStdQualifiedName:
|
||||
N = static_cast<const StdQualifiedName *>(N)->Child;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ItaniumPartialDemangler::isFunction() const {
|
||||
assert(RootNode != nullptr && "must call partialDemangle()");
|
||||
return static_cast<const Node *>(RootNode)->getKind() ==
|
||||
Node::KFunctionEncoding;
|
||||
}
|
||||
|
||||
bool ItaniumPartialDemangler::isSpecialName() const {
|
||||
assert(RootNode != nullptr && "must call partialDemangle()");
|
||||
auto K = static_cast<const Node *>(RootNode)->getKind();
|
||||
return K == Node::KSpecialName || K == Node::KCtorVtableSpecialName;
|
||||
}
|
||||
|
||||
bool ItaniumPartialDemangler::isData() const {
|
||||
return !isFunction() && !isSpecialName();
|
||||
}
|
||||
2377
external/llvm/Demangle/MicrosoftDemangle.cpp
vendored
Normal file
2377
external/llvm/Demangle/MicrosoftDemangle.cpp
vendored
Normal file
File diff suppressed because it is too large
Load Diff
653
external/llvm/Demangle/MicrosoftDemangleNodes.cpp
vendored
Normal file
653
external/llvm/Demangle/MicrosoftDemangleNodes.cpp
vendored
Normal file
@@ -0,0 +1,653 @@
|
||||
//===- MicrosoftDemangle.cpp ----------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file defines a demangler for MSVC-style mangled symbols.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "llvm/Demangle/MicrosoftDemangleNodes.h"
|
||||
#include "llvm/Demangle/DemangleConfig.h"
|
||||
#include "llvm/Demangle/Utility.h"
|
||||
#include <cctype>
|
||||
#include <string>
|
||||
|
||||
using namespace llvm;
|
||||
using namespace ms_demangle;
|
||||
|
||||
#define OUTPUT_ENUM_CLASS_VALUE(Enum, Value, Desc) \
|
||||
case Enum::Value: \
|
||||
OS << Desc; \
|
||||
break;
|
||||
|
||||
// Writes a space if the last token does not end with a punctuation.
|
||||
static void outputSpaceIfNecessary(OutputStream &OS) {
|
||||
if (OS.empty())
|
||||
return;
|
||||
|
||||
char C = OS.back();
|
||||
if (std::isalnum(C) || C == '>')
|
||||
OS << " ";
|
||||
}
|
||||
|
||||
static void outputSingleQualifier(OutputStream &OS, Qualifiers Q) {
|
||||
switch (Q) {
|
||||
case Q_Const:
|
||||
OS << "const";
|
||||
break;
|
||||
case Q_Volatile:
|
||||
OS << "volatile";
|
||||
break;
|
||||
case Q_Restrict:
|
||||
OS << "__restrict";
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static bool outputQualifierIfPresent(OutputStream &OS, Qualifiers Q,
|
||||
Qualifiers Mask, bool NeedSpace) {
|
||||
if (!(Q & Mask))
|
||||
return NeedSpace;
|
||||
|
||||
if (NeedSpace)
|
||||
OS << " ";
|
||||
|
||||
outputSingleQualifier(OS, Mask);
|
||||
return true;
|
||||
}
|
||||
|
||||
static void outputQualifiers(OutputStream &OS, Qualifiers Q, bool SpaceBefore,
|
||||
bool SpaceAfter) {
|
||||
if (Q == Q_None)
|
||||
return;
|
||||
|
||||
size_t Pos1 = OS.getCurrentPosition();
|
||||
SpaceBefore = outputQualifierIfPresent(OS, Q, Q_Const, SpaceBefore);
|
||||
SpaceBefore = outputQualifierIfPresent(OS, Q, Q_Volatile, SpaceBefore);
|
||||
SpaceBefore = outputQualifierIfPresent(OS, Q, Q_Restrict, SpaceBefore);
|
||||
size_t Pos2 = OS.getCurrentPosition();
|
||||
if (SpaceAfter && Pos2 > Pos1)
|
||||
OS << " ";
|
||||
}
|
||||
|
||||
static void outputCallingConvention(OutputStream &OS, CallingConv CC) {
|
||||
outputSpaceIfNecessary(OS);
|
||||
|
||||
switch (CC) {
|
||||
case CallingConv::Cdecl:
|
||||
OS << "__cdecl";
|
||||
break;
|
||||
case CallingConv::Fastcall:
|
||||
OS << "__fastcall";
|
||||
break;
|
||||
case CallingConv::Pascal:
|
||||
OS << "__pascal";
|
||||
break;
|
||||
case CallingConv::Regcall:
|
||||
OS << "__regcall";
|
||||
break;
|
||||
case CallingConv::Stdcall:
|
||||
OS << "__stdcall";
|
||||
break;
|
||||
case CallingConv::Thiscall:
|
||||
OS << "__thiscall";
|
||||
break;
|
||||
case CallingConv::Eabi:
|
||||
OS << "__eabi";
|
||||
break;
|
||||
case CallingConv::Vectorcall:
|
||||
OS << "__vectorcall";
|
||||
break;
|
||||
case CallingConv::Clrcall:
|
||||
OS << "__clrcall";
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
std::string Node::toString(OutputFlags Flags) const {
|
||||
OutputStream OS;
|
||||
initializeOutputStream(nullptr, nullptr, OS, 1024);
|
||||
this->output(OS, Flags);
|
||||
OS << '\0';
|
||||
return {OS.getBuffer()};
|
||||
}
|
||||
|
||||
void PrimitiveTypeNode::outputPre(OutputStream &OS, OutputFlags Flags) const {
|
||||
switch (PrimKind) {
|
||||
OUTPUT_ENUM_CLASS_VALUE(PrimitiveKind, Void, "void");
|
||||
OUTPUT_ENUM_CLASS_VALUE(PrimitiveKind, Bool, "bool");
|
||||
OUTPUT_ENUM_CLASS_VALUE(PrimitiveKind, Char, "char");
|
||||
OUTPUT_ENUM_CLASS_VALUE(PrimitiveKind, Schar, "signed char");
|
||||
OUTPUT_ENUM_CLASS_VALUE(PrimitiveKind, Uchar, "unsigned char");
|
||||
OUTPUT_ENUM_CLASS_VALUE(PrimitiveKind, Char8, "char8_t");
|
||||
OUTPUT_ENUM_CLASS_VALUE(PrimitiveKind, Char16, "char16_t");
|
||||
OUTPUT_ENUM_CLASS_VALUE(PrimitiveKind, Char32, "char32_t");
|
||||
OUTPUT_ENUM_CLASS_VALUE(PrimitiveKind, Short, "short");
|
||||
OUTPUT_ENUM_CLASS_VALUE(PrimitiveKind, Ushort, "unsigned short");
|
||||
OUTPUT_ENUM_CLASS_VALUE(PrimitiveKind, Int, "int");
|
||||
OUTPUT_ENUM_CLASS_VALUE(PrimitiveKind, Uint, "unsigned int");
|
||||
OUTPUT_ENUM_CLASS_VALUE(PrimitiveKind, Long, "long");
|
||||
OUTPUT_ENUM_CLASS_VALUE(PrimitiveKind, Ulong, "unsigned long");
|
||||
OUTPUT_ENUM_CLASS_VALUE(PrimitiveKind, Int64, "__int64");
|
||||
OUTPUT_ENUM_CLASS_VALUE(PrimitiveKind, Uint64, "unsigned __int64");
|
||||
OUTPUT_ENUM_CLASS_VALUE(PrimitiveKind, Wchar, "wchar_t");
|
||||
OUTPUT_ENUM_CLASS_VALUE(PrimitiveKind, Float, "float");
|
||||
OUTPUT_ENUM_CLASS_VALUE(PrimitiveKind, Double, "double");
|
||||
OUTPUT_ENUM_CLASS_VALUE(PrimitiveKind, Ldouble, "long double");
|
||||
OUTPUT_ENUM_CLASS_VALUE(PrimitiveKind, Nullptr, "std::nullptr_t");
|
||||
}
|
||||
outputQualifiers(OS, Quals, true, false);
|
||||
}
|
||||
|
||||
void NodeArrayNode::output(OutputStream &OS, OutputFlags Flags) const {
|
||||
output(OS, Flags, ", ");
|
||||
}
|
||||
|
||||
void NodeArrayNode::output(OutputStream &OS, OutputFlags Flags,
|
||||
StringView Separator) const {
|
||||
if (Count == 0)
|
||||
return;
|
||||
if (Nodes[0])
|
||||
Nodes[0]->output(OS, Flags);
|
||||
for (size_t I = 1; I < Count; ++I) {
|
||||
OS << Separator;
|
||||
Nodes[I]->output(OS, Flags);
|
||||
}
|
||||
}
|
||||
|
||||
void EncodedStringLiteralNode::output(OutputStream &OS,
|
||||
OutputFlags Flags) const {
|
||||
switch (Char) {
|
||||
case CharKind::Wchar:
|
||||
OS << "L\"";
|
||||
break;
|
||||
case CharKind::Char:
|
||||
OS << "\"";
|
||||
break;
|
||||
case CharKind::Char16:
|
||||
OS << "u\"";
|
||||
break;
|
||||
case CharKind::Char32:
|
||||
OS << "U\"";
|
||||
break;
|
||||
}
|
||||
OS << DecodedString << "\"";
|
||||
if (IsTruncated)
|
||||
OS << "...";
|
||||
}
|
||||
|
||||
void IntegerLiteralNode::output(OutputStream &OS, OutputFlags Flags) const {
|
||||
if (IsNegative)
|
||||
OS << '-';
|
||||
OS << Value;
|
||||
}
|
||||
|
||||
void TemplateParameterReferenceNode::output(OutputStream &OS,
|
||||
OutputFlags Flags) const {
|
||||
if (ThunkOffsetCount > 0)
|
||||
OS << "{";
|
||||
else if (Affinity == PointerAffinity::Pointer)
|
||||
OS << "&";
|
||||
|
||||
if (Symbol) {
|
||||
Symbol->output(OS, Flags);
|
||||
if (ThunkOffsetCount > 0)
|
||||
OS << ", ";
|
||||
}
|
||||
|
||||
if (ThunkOffsetCount > 0)
|
||||
OS << ThunkOffsets[0];
|
||||
for (int I = 1; I < ThunkOffsetCount; ++I) {
|
||||
OS << ", " << ThunkOffsets[I];
|
||||
}
|
||||
if (ThunkOffsetCount > 0)
|
||||
OS << "}";
|
||||
}
|
||||
|
||||
void IdentifierNode::outputTemplateParameters(OutputStream &OS,
|
||||
OutputFlags Flags) const {
|
||||
if (!TemplateParams)
|
||||
return;
|
||||
OS << "<";
|
||||
TemplateParams->output(OS, Flags);
|
||||
OS << ">";
|
||||
}
|
||||
|
||||
void DynamicStructorIdentifierNode::output(OutputStream &OS,
|
||||
OutputFlags Flags) const {
|
||||
if (IsDestructor)
|
||||
OS << "`dynamic atexit destructor for ";
|
||||
else
|
||||
OS << "`dynamic initializer for ";
|
||||
|
||||
if (Variable) {
|
||||
OS << "`";
|
||||
Variable->output(OS, Flags);
|
||||
OS << "''";
|
||||
} else {
|
||||
OS << "'";
|
||||
Name->output(OS, Flags);
|
||||
OS << "''";
|
||||
}
|
||||
}
|
||||
|
||||
void NamedIdentifierNode::output(OutputStream &OS, OutputFlags Flags) const {
|
||||
OS << Name;
|
||||
outputTemplateParameters(OS, Flags);
|
||||
}
|
||||
|
||||
void IntrinsicFunctionIdentifierNode::output(OutputStream &OS,
|
||||
OutputFlags Flags) const {
|
||||
switch (Operator) {
|
||||
OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, New, "operator new");
|
||||
OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, Delete, "operator delete");
|
||||
OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, Assign, "operator=");
|
||||
OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, RightShift, "operator>>");
|
||||
OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, LeftShift, "operator<<");
|
||||
OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, LogicalNot, "operator!");
|
||||
OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, Equals, "operator==");
|
||||
OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, NotEquals, "operator!=");
|
||||
OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, ArraySubscript,
|
||||
"operator[]");
|
||||
OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, Pointer, "operator->");
|
||||
OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, Increment, "operator++");
|
||||
OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, Decrement, "operator--");
|
||||
OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, Minus, "operator-");
|
||||
OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, Plus, "operator+");
|
||||
OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, Dereference, "operator*");
|
||||
OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, BitwiseAnd, "operator&");
|
||||
OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, MemberPointer,
|
||||
"operator->*");
|
||||
OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, Divide, "operator/");
|
||||
OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, Modulus, "operator%");
|
||||
OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, LessThan, "operator<");
|
||||
OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, LessThanEqual, "operator<=");
|
||||
OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, GreaterThan, "operator>");
|
||||
OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, GreaterThanEqual,
|
||||
"operator>=");
|
||||
OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, Comma, "operator,");
|
||||
OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, Parens, "operator()");
|
||||
OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, BitwiseNot, "operator~");
|
||||
OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, BitwiseXor, "operator^");
|
||||
OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, BitwiseOr, "operator|");
|
||||
OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, LogicalAnd, "operator&&");
|
||||
OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, LogicalOr, "operator||");
|
||||
OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, TimesEqual, "operator*=");
|
||||
OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, PlusEqual, "operator+=");
|
||||
OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, MinusEqual, "operator-=");
|
||||
OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, DivEqual, "operator/=");
|
||||
OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, ModEqual, "operator%=");
|
||||
OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, RshEqual, "operator>>=");
|
||||
OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, LshEqual, "operator<<=");
|
||||
OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, BitwiseAndEqual,
|
||||
"operator&=");
|
||||
OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, BitwiseOrEqual,
|
||||
"operator|=");
|
||||
OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, BitwiseXorEqual,
|
||||
"operator^=");
|
||||
OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, VbaseDtor, "`vbase dtor'");
|
||||
OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, VecDelDtor,
|
||||
"`vector deleting dtor'");
|
||||
OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, DefaultCtorClosure,
|
||||
"`default ctor closure'");
|
||||
OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, ScalarDelDtor,
|
||||
"`scalar deleting dtor'");
|
||||
OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, VecCtorIter,
|
||||
"`vector ctor iterator'");
|
||||
OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, VecDtorIter,
|
||||
"`vector dtor iterator'");
|
||||
OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, VecVbaseCtorIter,
|
||||
"`vector vbase ctor iterator'");
|
||||
OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, VdispMap,
|
||||
"`virtual displacement map'");
|
||||
OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, EHVecCtorIter,
|
||||
"`eh vector ctor iterator'");
|
||||
OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, EHVecDtorIter,
|
||||
"`eh vector dtor iterator'");
|
||||
OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, EHVecVbaseCtorIter,
|
||||
"`eh vector vbase ctor iterator'");
|
||||
OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, CopyCtorClosure,
|
||||
"`copy ctor closure'");
|
||||
OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, LocalVftableCtorClosure,
|
||||
"`local vftable ctor closure'");
|
||||
OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, ArrayNew, "operator new[]");
|
||||
OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, ArrayDelete,
|
||||
"operator delete[]");
|
||||
OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, ManVectorCtorIter,
|
||||
"`managed vector ctor iterator'");
|
||||
OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, ManVectorDtorIter,
|
||||
"`managed vector dtor iterator'");
|
||||
OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, EHVectorCopyCtorIter,
|
||||
"`EH vector copy ctor iterator'");
|
||||
OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, EHVectorVbaseCopyCtorIter,
|
||||
"`EH vector vbase copy ctor iterator'");
|
||||
OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, VectorCopyCtorIter,
|
||||
"`vector copy ctor iterator'");
|
||||
OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, VectorVbaseCopyCtorIter,
|
||||
"`vector vbase copy constructor iterator'");
|
||||
OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, ManVectorVbaseCopyCtorIter,
|
||||
"`managed vector vbase copy constructor iterator'");
|
||||
OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, CoAwait,
|
||||
"operator co_await");
|
||||
OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, Spaceship, "operator<=>");
|
||||
case IntrinsicFunctionKind::MaxIntrinsic:
|
||||
case IntrinsicFunctionKind::None:
|
||||
break;
|
||||
}
|
||||
outputTemplateParameters(OS, Flags);
|
||||
}
|
||||
|
||||
void LocalStaticGuardIdentifierNode::output(OutputStream &OS,
|
||||
OutputFlags Flags) const {
|
||||
if (IsThread)
|
||||
OS << "`local static thread guard'";
|
||||
else
|
||||
OS << "`local static guard'";
|
||||
if (ScopeIndex > 0)
|
||||
OS << "{" << ScopeIndex << "}";
|
||||
}
|
||||
|
||||
void ConversionOperatorIdentifierNode::output(OutputStream &OS,
|
||||
OutputFlags Flags) const {
|
||||
OS << "operator";
|
||||
outputTemplateParameters(OS, Flags);
|
||||
OS << " ";
|
||||
TargetType->output(OS, Flags);
|
||||
}
|
||||
|
||||
void StructorIdentifierNode::output(OutputStream &OS, OutputFlags Flags) const {
|
||||
if (IsDestructor)
|
||||
OS << "~";
|
||||
Class->output(OS, Flags);
|
||||
outputTemplateParameters(OS, Flags);
|
||||
}
|
||||
|
||||
void LiteralOperatorIdentifierNode::output(OutputStream &OS,
|
||||
OutputFlags Flags) const {
|
||||
OS << "operator \"\"" << Name;
|
||||
outputTemplateParameters(OS, Flags);
|
||||
}
|
||||
|
||||
void FunctionSignatureNode::outputPre(OutputStream &OS,
|
||||
OutputFlags Flags) const {
|
||||
if (!(Flags & OF_NoAccessSpecifier)) {
|
||||
if (FunctionClass & FC_Public)
|
||||
OS << "public: ";
|
||||
if (FunctionClass & FC_Protected)
|
||||
OS << "protected: ";
|
||||
if (FunctionClass & FC_Private)
|
||||
OS << "private: ";
|
||||
}
|
||||
|
||||
if (!(Flags & OF_NoMemberType)) {
|
||||
if (!(FunctionClass & FC_Global)) {
|
||||
if (FunctionClass & FC_Static)
|
||||
OS << "static ";
|
||||
}
|
||||
if (FunctionClass & FC_Virtual)
|
||||
OS << "virtual ";
|
||||
|
||||
if (FunctionClass & FC_ExternC)
|
||||
OS << "extern \"C\" ";
|
||||
}
|
||||
|
||||
if (!(Flags & OF_NoReturnType) && ReturnType) {
|
||||
ReturnType->outputPre(OS, Flags);
|
||||
OS << " ";
|
||||
}
|
||||
|
||||
if (!(Flags & OF_NoCallingConvention))
|
||||
outputCallingConvention(OS, CallConvention);
|
||||
}
|
||||
|
||||
void FunctionSignatureNode::outputPost(OutputStream &OS,
|
||||
OutputFlags Flags) const {
|
||||
if (!(FunctionClass & FC_NoParameterList)) {
|
||||
OS << "(";
|
||||
if (Params)
|
||||
Params->output(OS, Flags);
|
||||
else
|
||||
OS << "void";
|
||||
|
||||
if (IsVariadic) {
|
||||
if (OS.back() != '(')
|
||||
OS << ", ";
|
||||
OS << "...";
|
||||
}
|
||||
OS << ")";
|
||||
}
|
||||
|
||||
if (Quals & Q_Const)
|
||||
OS << " const";
|
||||
if (Quals & Q_Volatile)
|
||||
OS << " volatile";
|
||||
if (Quals & Q_Restrict)
|
||||
OS << " __restrict";
|
||||
if (Quals & Q_Unaligned)
|
||||
OS << " __unaligned";
|
||||
|
||||
if (IsNoexcept)
|
||||
OS << " noexcept";
|
||||
|
||||
if (RefQualifier == FunctionRefQualifier::Reference)
|
||||
OS << " &";
|
||||
else if (RefQualifier == FunctionRefQualifier::RValueReference)
|
||||
OS << " &&";
|
||||
|
||||
if (!(Flags & OF_NoReturnType) && ReturnType)
|
||||
ReturnType->outputPost(OS, Flags);
|
||||
}
|
||||
|
||||
void ThunkSignatureNode::outputPre(OutputStream &OS, OutputFlags Flags) const {
|
||||
OS << "[thunk]: ";
|
||||
|
||||
FunctionSignatureNode::outputPre(OS, Flags);
|
||||
}
|
||||
|
||||
void ThunkSignatureNode::outputPost(OutputStream &OS, OutputFlags Flags) const {
|
||||
if (FunctionClass & FC_StaticThisAdjust) {
|
||||
OS << "`adjustor{" << ThisAdjust.StaticOffset << "}'";
|
||||
} else if (FunctionClass & FC_VirtualThisAdjust) {
|
||||
if (FunctionClass & FC_VirtualThisAdjustEx) {
|
||||
OS << "`vtordispex{" << ThisAdjust.VBPtrOffset << ", "
|
||||
<< ThisAdjust.VBOffsetOffset << ", " << ThisAdjust.VtordispOffset
|
||||
<< ", " << ThisAdjust.StaticOffset << "}'";
|
||||
} else {
|
||||
OS << "`vtordisp{" << ThisAdjust.VtordispOffset << ", "
|
||||
<< ThisAdjust.StaticOffset << "}'";
|
||||
}
|
||||
}
|
||||
|
||||
FunctionSignatureNode::outputPost(OS, Flags);
|
||||
}
|
||||
|
||||
void PointerTypeNode::outputPre(OutputStream &OS, OutputFlags Flags) const {
|
||||
if (Pointee->kind() == NodeKind::FunctionSignature) {
|
||||
// If this is a pointer to a function, don't output the calling convention.
|
||||
// It needs to go inside the parentheses.
|
||||
const FunctionSignatureNode *Sig =
|
||||
static_cast<const FunctionSignatureNode *>(Pointee);
|
||||
Sig->outputPre(OS, OF_NoCallingConvention);
|
||||
} else
|
||||
Pointee->outputPre(OS, Flags);
|
||||
|
||||
outputSpaceIfNecessary(OS);
|
||||
|
||||
if (Quals & Q_Unaligned)
|
||||
OS << "__unaligned ";
|
||||
|
||||
if (Pointee->kind() == NodeKind::ArrayType) {
|
||||
OS << "(";
|
||||
} else if (Pointee->kind() == NodeKind::FunctionSignature) {
|
||||
OS << "(";
|
||||
const FunctionSignatureNode *Sig =
|
||||
static_cast<const FunctionSignatureNode *>(Pointee);
|
||||
outputCallingConvention(OS, Sig->CallConvention);
|
||||
OS << " ";
|
||||
}
|
||||
|
||||
if (ClassParent) {
|
||||
ClassParent->output(OS, Flags);
|
||||
OS << "::";
|
||||
}
|
||||
|
||||
switch (Affinity) {
|
||||
case PointerAffinity::Pointer:
|
||||
OS << "*";
|
||||
break;
|
||||
case PointerAffinity::Reference:
|
||||
OS << "&";
|
||||
break;
|
||||
case PointerAffinity::RValueReference:
|
||||
OS << "&&";
|
||||
break;
|
||||
default:
|
||||
assert(false);
|
||||
}
|
||||
outputQualifiers(OS, Quals, false, false);
|
||||
}
|
||||
|
||||
void PointerTypeNode::outputPost(OutputStream &OS, OutputFlags Flags) const {
|
||||
if (Pointee->kind() == NodeKind::ArrayType ||
|
||||
Pointee->kind() == NodeKind::FunctionSignature)
|
||||
OS << ")";
|
||||
|
||||
Pointee->outputPost(OS, Flags);
|
||||
}
|
||||
|
||||
void TagTypeNode::outputPre(OutputStream &OS, OutputFlags Flags) const {
|
||||
if (!(Flags & OF_NoTagSpecifier)) {
|
||||
switch (Tag) {
|
||||
OUTPUT_ENUM_CLASS_VALUE(TagKind, Class, "class");
|
||||
OUTPUT_ENUM_CLASS_VALUE(TagKind, Struct, "struct");
|
||||
OUTPUT_ENUM_CLASS_VALUE(TagKind, Union, "union");
|
||||
OUTPUT_ENUM_CLASS_VALUE(TagKind, Enum, "enum");
|
||||
}
|
||||
OS << " ";
|
||||
}
|
||||
QualifiedName->output(OS, Flags);
|
||||
outputQualifiers(OS, Quals, true, false);
|
||||
}
|
||||
|
||||
void TagTypeNode::outputPost(OutputStream &OS, OutputFlags Flags) const {}
|
||||
|
||||
void ArrayTypeNode::outputPre(OutputStream &OS, OutputFlags Flags) const {
|
||||
ElementType->outputPre(OS, Flags);
|
||||
outputQualifiers(OS, Quals, true, false);
|
||||
}
|
||||
|
||||
void ArrayTypeNode::outputOneDimension(OutputStream &OS, OutputFlags Flags,
|
||||
Node *N) const {
|
||||
assert(N->kind() == NodeKind::IntegerLiteral);
|
||||
IntegerLiteralNode *ILN = static_cast<IntegerLiteralNode *>(N);
|
||||
if (ILN->Value != 0)
|
||||
ILN->output(OS, Flags);
|
||||
}
|
||||
|
||||
void ArrayTypeNode::outputDimensionsImpl(OutputStream &OS,
|
||||
OutputFlags Flags) const {
|
||||
if (Dimensions->Count == 0)
|
||||
return;
|
||||
|
||||
outputOneDimension(OS, Flags, Dimensions->Nodes[0]);
|
||||
for (size_t I = 1; I < Dimensions->Count; ++I) {
|
||||
OS << "][";
|
||||
outputOneDimension(OS, Flags, Dimensions->Nodes[I]);
|
||||
}
|
||||
}
|
||||
|
||||
void ArrayTypeNode::outputPost(OutputStream &OS, OutputFlags Flags) const {
|
||||
OS << "[";
|
||||
outputDimensionsImpl(OS, Flags);
|
||||
OS << "]";
|
||||
|
||||
ElementType->outputPost(OS, Flags);
|
||||
}
|
||||
|
||||
void SymbolNode::output(OutputStream &OS, OutputFlags Flags) const {
|
||||
Name->output(OS, Flags);
|
||||
}
|
||||
|
||||
void FunctionSymbolNode::output(OutputStream &OS, OutputFlags Flags) const {
|
||||
Signature->outputPre(OS, Flags);
|
||||
outputSpaceIfNecessary(OS);
|
||||
Name->output(OS, Flags);
|
||||
Signature->outputPost(OS, Flags);
|
||||
}
|
||||
|
||||
void VariableSymbolNode::output(OutputStream &OS, OutputFlags Flags) const {
|
||||
const char *AccessSpec = nullptr;
|
||||
bool IsStatic = true;
|
||||
switch (SC) {
|
||||
case StorageClass::PrivateStatic:
|
||||
AccessSpec = "private";
|
||||
break;
|
||||
case StorageClass::PublicStatic:
|
||||
AccessSpec = "public";
|
||||
break;
|
||||
case StorageClass::ProtectedStatic:
|
||||
AccessSpec = "protected";
|
||||
break;
|
||||
default:
|
||||
IsStatic = false;
|
||||
break;
|
||||
}
|
||||
if (!(Flags & OF_NoAccessSpecifier) && AccessSpec)
|
||||
OS << AccessSpec << ": ";
|
||||
if (!(Flags & OF_NoMemberType) && IsStatic)
|
||||
OS << "static ";
|
||||
|
||||
if (Type) {
|
||||
Type->outputPre(OS, Flags);
|
||||
outputSpaceIfNecessary(OS);
|
||||
}
|
||||
Name->output(OS, Flags);
|
||||
if (Type)
|
||||
Type->outputPost(OS, Flags);
|
||||
}
|
||||
|
||||
void CustomTypeNode::outputPre(OutputStream &OS, OutputFlags Flags) const {
|
||||
Identifier->output(OS, Flags);
|
||||
}
|
||||
void CustomTypeNode::outputPost(OutputStream &OS, OutputFlags Flags) const {}
|
||||
|
||||
void QualifiedNameNode::output(OutputStream &OS, OutputFlags Flags) const {
|
||||
Components->output(OS, Flags, "::");
|
||||
}
|
||||
|
||||
void RttiBaseClassDescriptorNode::output(OutputStream &OS,
|
||||
OutputFlags Flags) const {
|
||||
OS << "`RTTI Base Class Descriptor at (";
|
||||
OS << NVOffset << ", " << VBPtrOffset << ", " << VBTableOffset << ", "
|
||||
<< this->Flags;
|
||||
OS << ")'";
|
||||
}
|
||||
|
||||
void LocalStaticGuardVariableNode::output(OutputStream &OS,
|
||||
OutputFlags Flags) const {
|
||||
Name->output(OS, Flags);
|
||||
}
|
||||
|
||||
void VcallThunkIdentifierNode::output(OutputStream &OS,
|
||||
OutputFlags Flags) const {
|
||||
OS << "`vcall'{" << OffsetInVTable << ", {flat}}";
|
||||
}
|
||||
|
||||
void SpecialTableSymbolNode::output(OutputStream &OS, OutputFlags Flags) const {
|
||||
outputQualifiers(OS, Quals, false, true);
|
||||
Name->output(OS, Flags);
|
||||
if (TargetName) {
|
||||
OS << "{for `";
|
||||
TargetName->output(OS, Flags);
|
||||
OS << "'}";
|
||||
}
|
||||
return;
|
||||
}
|
||||
124
external/llvm/include/llvm/Demangle/Demangle.h
vendored
Normal file
124
external/llvm/include/llvm/Demangle/Demangle.h
vendored
Normal file
@@ -0,0 +1,124 @@
|
||||
//===--- Demangle.h ---------------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_DEMANGLE_DEMANGLE_H
|
||||
#define LLVM_DEMANGLE_DEMANGLE_H
|
||||
|
||||
#include <cstddef>
|
||||
#include <string>
|
||||
|
||||
namespace llvm {
|
||||
/// This is a llvm local version of __cxa_demangle. Other than the name and
|
||||
/// being in the llvm namespace it is identical.
|
||||
///
|
||||
/// The mangled_name is demangled into buf and returned. If the buffer is not
|
||||
/// large enough, realloc is used to expand it.
|
||||
///
|
||||
/// The *status will be set to a value from the following enumeration
|
||||
enum : int {
|
||||
demangle_unknown_error = -4,
|
||||
demangle_invalid_args = -3,
|
||||
demangle_invalid_mangled_name = -2,
|
||||
demangle_memory_alloc_failure = -1,
|
||||
demangle_success = 0,
|
||||
};
|
||||
|
||||
char *itaniumDemangle(const char *mangled_name, char *buf, size_t *n,
|
||||
int *status);
|
||||
|
||||
|
||||
enum MSDemangleFlags {
|
||||
MSDF_None = 0,
|
||||
MSDF_DumpBackrefs = 1 << 0,
|
||||
MSDF_NoAccessSpecifier = 1 << 1,
|
||||
MSDF_NoCallingConvention = 1 << 2,
|
||||
MSDF_NoReturnType = 1 << 3,
|
||||
MSDF_NoMemberType = 1 << 4,
|
||||
};
|
||||
|
||||
/// Demangles the Microsoft symbol pointed at by mangled_name and returns it.
|
||||
/// Returns a pointer to the start of a null-terminated demangled string on
|
||||
/// success, or nullptr on error.
|
||||
/// If n_read is non-null and demangling was successful, it receives how many
|
||||
/// bytes of the input string were consumed.
|
||||
/// buf can point to a *n_buf bytes large buffer where the demangled name is
|
||||
/// stored. If the buffer is too small, it is grown with realloc(). If buf is
|
||||
/// nullptr, then this malloc()s memory for the result.
|
||||
/// *n_buf stores the size of buf on input if buf is non-nullptr, and it
|
||||
/// receives the size of the demangled string on output if n_buf is not nullptr.
|
||||
/// status receives one of the demangle_ enum entries above if it's not nullptr.
|
||||
/// Flags controls various details of the demangled representation.
|
||||
char *microsoftDemangle(const char *mangled_name, size_t *n_read,
|
||||
char *buf, size_t *n_buf,
|
||||
int *status, MSDemangleFlags Flags = MSDF_None);
|
||||
|
||||
/// Attempt to demangle a string using different demangling schemes.
|
||||
/// The function uses heuristics to determine which demangling scheme to use.
|
||||
/// \param MangledName - reference to string to demangle.
|
||||
/// \returns - the demangled string, or a copy of the input string if no
|
||||
/// demangling occurred.
|
||||
std::string demangle(const std::string &MangledName);
|
||||
|
||||
/// "Partial" demangler. This supports demangling a string into an AST
|
||||
/// (typically an intermediate stage in itaniumDemangle) and querying certain
|
||||
/// properties or partially printing the demangled name.
|
||||
struct ItaniumPartialDemangler {
|
||||
ItaniumPartialDemangler();
|
||||
|
||||
ItaniumPartialDemangler(ItaniumPartialDemangler &&Other);
|
||||
ItaniumPartialDemangler &operator=(ItaniumPartialDemangler &&Other);
|
||||
|
||||
/// Demangle into an AST. Subsequent calls to the rest of the member functions
|
||||
/// implicitly operate on the AST this produces.
|
||||
/// \return true on error, false otherwise
|
||||
bool partialDemangle(const char *MangledName);
|
||||
|
||||
/// Just print the entire mangled name into Buf. Buf and N behave like the
|
||||
/// second and third parameters to itaniumDemangle.
|
||||
char *finishDemangle(char *Buf, size_t *N) const;
|
||||
|
||||
/// Get the base name of a function. This doesn't include trailing template
|
||||
/// arguments, ie for "a::b<int>" this function returns "b".
|
||||
char *getFunctionBaseName(char *Buf, size_t *N) const;
|
||||
|
||||
/// Get the context name for a function. For "a::b::c", this function returns
|
||||
/// "a::b".
|
||||
char *getFunctionDeclContextName(char *Buf, size_t *N) const;
|
||||
|
||||
/// Get the entire name of this function.
|
||||
char *getFunctionName(char *Buf, size_t *N) const;
|
||||
|
||||
/// Get the parameters for this function.
|
||||
char *getFunctionParameters(char *Buf, size_t *N) const;
|
||||
char *getFunctionReturnType(char *Buf, size_t *N) const;
|
||||
|
||||
/// If this function has any any cv or reference qualifiers. These imply that
|
||||
/// the function is a non-static member function.
|
||||
bool hasFunctionQualifiers() const;
|
||||
|
||||
/// If this symbol describes a constructor or destructor.
|
||||
bool isCtorOrDtor() const;
|
||||
|
||||
/// If this symbol describes a function.
|
||||
bool isFunction() const;
|
||||
|
||||
/// If this symbol describes a variable.
|
||||
bool isData() const;
|
||||
|
||||
/// If this symbol is a <special-name>. These are generally implicitly
|
||||
/// generated by the implementation, such as vtables and typeinfo names.
|
||||
bool isSpecialName() const;
|
||||
|
||||
~ItaniumPartialDemangler();
|
||||
private:
|
||||
void *RootNode;
|
||||
void *Context;
|
||||
};
|
||||
} // namespace llvm
|
||||
|
||||
#endif
|
||||
92
external/llvm/include/llvm/Demangle/DemangleConfig.h
vendored
Normal file
92
external/llvm/include/llvm/Demangle/DemangleConfig.h
vendored
Normal file
@@ -0,0 +1,92 @@
|
||||
//===--- DemangleConfig.h ---------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file contains a variety of feature test macros copied from
|
||||
// include/llvm/Support/Compiler.h so that LLVMDemangle does not need to take
|
||||
// a dependency on LLVMSupport.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_DEMANGLE_COMPILER_H
|
||||
#define LLVM_DEMANGLE_COMPILER_H
|
||||
|
||||
#ifndef __has_feature
|
||||
#define __has_feature(x) 0
|
||||
#endif
|
||||
|
||||
#ifndef __has_cpp_attribute
|
||||
#define __has_cpp_attribute(x) 0
|
||||
#endif
|
||||
|
||||
#ifndef __has_attribute
|
||||
#define __has_attribute(x) 0
|
||||
#endif
|
||||
|
||||
#ifndef __has_builtin
|
||||
#define __has_builtin(x) 0
|
||||
#endif
|
||||
|
||||
#ifndef DEMANGLE_GNUC_PREREQ
|
||||
#if defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__GNUC_PATCHLEVEL__)
|
||||
#define DEMANGLE_GNUC_PREREQ(maj, min, patch) \
|
||||
((__GNUC__ << 20) + (__GNUC_MINOR__ << 10) + __GNUC_PATCHLEVEL__ >= \
|
||||
((maj) << 20) + ((min) << 10) + (patch))
|
||||
#elif defined(__GNUC__) && defined(__GNUC_MINOR__)
|
||||
#define DEMANGLE_GNUC_PREREQ(maj, min, patch) \
|
||||
((__GNUC__ << 20) + (__GNUC_MINOR__ << 10) >= ((maj) << 20) + ((min) << 10))
|
||||
#else
|
||||
#define DEMANGLE_GNUC_PREREQ(maj, min, patch) 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if __has_attribute(used) || DEMANGLE_GNUC_PREREQ(3, 1, 0)
|
||||
#define DEMANGLE_ATTRIBUTE_USED __attribute__((__used__))
|
||||
#else
|
||||
#define DEMANGLE_ATTRIBUTE_USED
|
||||
#endif
|
||||
|
||||
#if __has_builtin(__builtin_unreachable) || DEMANGLE_GNUC_PREREQ(4, 5, 0)
|
||||
#define DEMANGLE_UNREACHABLE __builtin_unreachable()
|
||||
#elif defined(_MSC_VER)
|
||||
#define DEMANGLE_UNREACHABLE __assume(false)
|
||||
#else
|
||||
#define DEMANGLE_UNREACHABLE
|
||||
#endif
|
||||
|
||||
#if __has_attribute(noinline) || DEMANGLE_GNUC_PREREQ(3, 4, 0)
|
||||
#define DEMANGLE_ATTRIBUTE_NOINLINE __attribute__((noinline))
|
||||
#elif defined(_MSC_VER)
|
||||
#define DEMANGLE_ATTRIBUTE_NOINLINE __declspec(noinline)
|
||||
#else
|
||||
#define DEMANGLE_ATTRIBUTE_NOINLINE
|
||||
#endif
|
||||
|
||||
#if !defined(NDEBUG)
|
||||
#define DEMANGLE_DUMP_METHOD DEMANGLE_ATTRIBUTE_NOINLINE DEMANGLE_ATTRIBUTE_USED
|
||||
#else
|
||||
#define DEMANGLE_DUMP_METHOD DEMANGLE_ATTRIBUTE_NOINLINE
|
||||
#endif
|
||||
|
||||
#if __cplusplus > 201402L && __has_cpp_attribute(fallthrough)
|
||||
#define DEMANGLE_FALLTHROUGH [[fallthrough]]
|
||||
#elif __has_cpp_attribute(gnu::fallthrough)
|
||||
#define DEMANGLE_FALLTHROUGH [[gnu::fallthrough]]
|
||||
#elif !__cplusplus
|
||||
// Workaround for llvm.org/PR23435, since clang 3.6 and below emit a spurious
|
||||
// error when __has_cpp_attribute is given a scoped attribute in C mode.
|
||||
#define DEMANGLE_FALLTHROUGH
|
||||
#elif __has_cpp_attribute(clang::fallthrough)
|
||||
#define DEMANGLE_FALLTHROUGH [[clang::fallthrough]]
|
||||
#else
|
||||
#define DEMANGLE_FALLTHROUGH
|
||||
#endif
|
||||
|
||||
#define DEMANGLE_NAMESPACE_BEGIN namespace llvm { namespace itanium_demangle {
|
||||
#define DEMANGLE_NAMESPACE_END } }
|
||||
|
||||
#endif
|
||||
5574
external/llvm/include/llvm/Demangle/ItaniumDemangle.h
vendored
Normal file
5574
external/llvm/include/llvm/Demangle/ItaniumDemangle.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
278
external/llvm/include/llvm/Demangle/MicrosoftDemangle.h
vendored
Normal file
278
external/llvm/include/llvm/Demangle/MicrosoftDemangle.h
vendored
Normal file
@@ -0,0 +1,278 @@
|
||||
//===------------------------- MicrosoftDemangle.h --------------*- C++ -*-===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_DEMANGLE_MICROSOFT_DEMANGLE_H
|
||||
#define LLVM_DEMANGLE_MICROSOFT_DEMANGLE_H
|
||||
|
||||
#include "llvm/Demangle/DemangleConfig.h"
|
||||
#include "llvm/Demangle/MicrosoftDemangleNodes.h"
|
||||
#include "llvm/Demangle/StringView.h"
|
||||
#include "llvm/Demangle/Utility.h"
|
||||
|
||||
#include <utility>
|
||||
|
||||
namespace llvm {
|
||||
namespace ms_demangle {
|
||||
// This memory allocator is extremely fast, but it doesn't call dtors
|
||||
// for allocated objects. That means you can't use STL containers
|
||||
// (such as std::vector) with this allocator. But it pays off --
|
||||
// the demangler is 3x faster with this allocator compared to one with
|
||||
// STL containers.
|
||||
constexpr size_t AllocUnit = 4096;
|
||||
|
||||
class ArenaAllocator {
|
||||
struct AllocatorNode {
|
||||
uint8_t *Buf = nullptr;
|
||||
size_t Used = 0;
|
||||
size_t Capacity = 0;
|
||||
AllocatorNode *Next = nullptr;
|
||||
};
|
||||
|
||||
void addNode(size_t Capacity) {
|
||||
AllocatorNode *NewHead = new AllocatorNode;
|
||||
NewHead->Buf = new uint8_t[Capacity];
|
||||
NewHead->Next = Head;
|
||||
NewHead->Capacity = Capacity;
|
||||
Head = NewHead;
|
||||
NewHead->Used = 0;
|
||||
}
|
||||
|
||||
public:
|
||||
ArenaAllocator() { addNode(AllocUnit); }
|
||||
|
||||
~ArenaAllocator() {
|
||||
while (Head) {
|
||||
assert(Head->Buf);
|
||||
delete[] Head->Buf;
|
||||
AllocatorNode *Next = Head->Next;
|
||||
delete Head;
|
||||
Head = Next;
|
||||
}
|
||||
}
|
||||
|
||||
char *allocUnalignedBuffer(size_t Size) {
|
||||
assert(Head && Head->Buf);
|
||||
|
||||
uint8_t *P = Head->Buf + Head->Used;
|
||||
|
||||
Head->Used += Size;
|
||||
if (Head->Used <= Head->Capacity)
|
||||
return reinterpret_cast<char *>(P);
|
||||
|
||||
addNode(std::max(AllocUnit, Size));
|
||||
Head->Used = Size;
|
||||
return reinterpret_cast<char *>(Head->Buf);
|
||||
}
|
||||
|
||||
template <typename T, typename... Args> T *allocArray(size_t Count) {
|
||||
size_t Size = Count * sizeof(T);
|
||||
assert(Head && Head->Buf);
|
||||
|
||||
size_t P = (size_t)Head->Buf + Head->Used;
|
||||
uintptr_t AlignedP =
|
||||
(((size_t)P + alignof(T) - 1) & ~(size_t)(alignof(T) - 1));
|
||||
uint8_t *PP = (uint8_t *)AlignedP;
|
||||
size_t Adjustment = AlignedP - P;
|
||||
|
||||
Head->Used += Size + Adjustment;
|
||||
if (Head->Used <= Head->Capacity)
|
||||
return new (PP) T[Count]();
|
||||
|
||||
addNode(std::max(AllocUnit, Size));
|
||||
Head->Used = Size;
|
||||
return new (Head->Buf) T[Count]();
|
||||
}
|
||||
|
||||
template <typename T, typename... Args> T *alloc(Args &&... ConstructorArgs) {
|
||||
constexpr size_t Size = sizeof(T);
|
||||
assert(Head && Head->Buf);
|
||||
|
||||
size_t P = (size_t)Head->Buf + Head->Used;
|
||||
uintptr_t AlignedP =
|
||||
(((size_t)P + alignof(T) - 1) & ~(size_t)(alignof(T) - 1));
|
||||
uint8_t *PP = (uint8_t *)AlignedP;
|
||||
size_t Adjustment = AlignedP - P;
|
||||
|
||||
Head->Used += Size + Adjustment;
|
||||
if (Head->Used <= Head->Capacity)
|
||||
return new (PP) T(std::forward<Args>(ConstructorArgs)...);
|
||||
|
||||
static_assert(Size < AllocUnit, "");
|
||||
addNode(AllocUnit);
|
||||
Head->Used = Size;
|
||||
return new (Head->Buf) T(std::forward<Args>(ConstructorArgs)...);
|
||||
}
|
||||
|
||||
private:
|
||||
AllocatorNode *Head = nullptr;
|
||||
};
|
||||
|
||||
struct BackrefContext {
|
||||
static constexpr size_t Max = 10;
|
||||
|
||||
TypeNode *FunctionParams[Max];
|
||||
size_t FunctionParamCount = 0;
|
||||
|
||||
// The first 10 BackReferences in a mangled name can be back-referenced by
|
||||
// special name @[0-9]. This is a storage for the first 10 BackReferences.
|
||||
NamedIdentifierNode *Names[Max];
|
||||
size_t NamesCount = 0;
|
||||
};
|
||||
|
||||
enum class QualifierMangleMode { Drop, Mangle, Result };
|
||||
|
||||
enum NameBackrefBehavior : uint8_t {
|
||||
NBB_None = 0, // don't save any names as backrefs.
|
||||
NBB_Template = 1 << 0, // save template instanations.
|
||||
NBB_Simple = 1 << 1, // save simple names.
|
||||
};
|
||||
|
||||
enum class FunctionIdentifierCodeGroup { Basic, Under, DoubleUnder };
|
||||
|
||||
// Demangler class takes the main role in demangling symbols.
|
||||
// It has a set of functions to parse mangled symbols into Type instances.
|
||||
// It also has a set of functions to convert Type instances to strings.
|
||||
class Demangler {
|
||||
public:
|
||||
Demangler() = default;
|
||||
virtual ~Demangler() = default;
|
||||
|
||||
// You are supposed to call parse() first and then check if error is true. If
|
||||
// it is false, call output() to write the formatted name to the given stream.
|
||||
SymbolNode *parse(StringView &MangledName);
|
||||
|
||||
TagTypeNode *parseTagUniqueName(StringView &MangledName);
|
||||
|
||||
// True if an error occurred.
|
||||
bool Error = false;
|
||||
|
||||
void dumpBackReferences();
|
||||
|
||||
private:
|
||||
SymbolNode *demangleEncodedSymbol(StringView &MangledName,
|
||||
QualifiedNameNode *QN);
|
||||
SymbolNode *demangleDeclarator(StringView &MangledName);
|
||||
SymbolNode *demangleMD5Name(StringView &MangledName);
|
||||
SymbolNode *demangleTypeinfoName(StringView &MangledName);
|
||||
|
||||
VariableSymbolNode *demangleVariableEncoding(StringView &MangledName,
|
||||
StorageClass SC);
|
||||
FunctionSymbolNode *demangleFunctionEncoding(StringView &MangledName);
|
||||
|
||||
Qualifiers demanglePointerExtQualifiers(StringView &MangledName);
|
||||
|
||||
// Parser functions. This is a recursive-descent parser.
|
||||
TypeNode *demangleType(StringView &MangledName, QualifierMangleMode QMM);
|
||||
PrimitiveTypeNode *demanglePrimitiveType(StringView &MangledName);
|
||||
CustomTypeNode *demangleCustomType(StringView &MangledName);
|
||||
TagTypeNode *demangleClassType(StringView &MangledName);
|
||||
PointerTypeNode *demanglePointerType(StringView &MangledName);
|
||||
PointerTypeNode *demangleMemberPointerType(StringView &MangledName);
|
||||
FunctionSignatureNode *demangleFunctionType(StringView &MangledName,
|
||||
bool HasThisQuals);
|
||||
|
||||
ArrayTypeNode *demangleArrayType(StringView &MangledName);
|
||||
|
||||
NodeArrayNode *demangleFunctionParameterList(StringView &MangledName,
|
||||
bool &IsVariadic);
|
||||
NodeArrayNode *demangleTemplateParameterList(StringView &MangledName);
|
||||
|
||||
std::pair<uint64_t, bool> demangleNumber(StringView &MangledName);
|
||||
uint64_t demangleUnsigned(StringView &MangledName);
|
||||
int64_t demangleSigned(StringView &MangledName);
|
||||
|
||||
void memorizeString(StringView s);
|
||||
void memorizeIdentifier(IdentifierNode *Identifier);
|
||||
|
||||
/// Allocate a copy of \p Borrowed into memory that we own.
|
||||
StringView copyString(StringView Borrowed);
|
||||
|
||||
QualifiedNameNode *demangleFullyQualifiedTypeName(StringView &MangledName);
|
||||
QualifiedNameNode *demangleFullyQualifiedSymbolName(StringView &MangledName);
|
||||
|
||||
IdentifierNode *demangleUnqualifiedTypeName(StringView &MangledName,
|
||||
bool Memorize);
|
||||
IdentifierNode *demangleUnqualifiedSymbolName(StringView &MangledName,
|
||||
NameBackrefBehavior NBB);
|
||||
|
||||
QualifiedNameNode *demangleNameScopeChain(StringView &MangledName,
|
||||
IdentifierNode *UnqualifiedName);
|
||||
IdentifierNode *demangleNameScopePiece(StringView &MangledName);
|
||||
|
||||
NamedIdentifierNode *demangleBackRefName(StringView &MangledName);
|
||||
IdentifierNode *demangleTemplateInstantiationName(StringView &MangledName,
|
||||
NameBackrefBehavior NBB);
|
||||
IntrinsicFunctionKind
|
||||
translateIntrinsicFunctionCode(char CH, FunctionIdentifierCodeGroup Group);
|
||||
IdentifierNode *demangleFunctionIdentifierCode(StringView &MangledName);
|
||||
IdentifierNode *
|
||||
demangleFunctionIdentifierCode(StringView &MangledName,
|
||||
FunctionIdentifierCodeGroup Group);
|
||||
StructorIdentifierNode *demangleStructorIdentifier(StringView &MangledName,
|
||||
bool IsDestructor);
|
||||
ConversionOperatorIdentifierNode *
|
||||
demangleConversionOperatorIdentifier(StringView &MangledName);
|
||||
LiteralOperatorIdentifierNode *
|
||||
demangleLiteralOperatorIdentifier(StringView &MangledName);
|
||||
|
||||
SymbolNode *demangleSpecialIntrinsic(StringView &MangledName);
|
||||
SpecialTableSymbolNode *
|
||||
demangleSpecialTableSymbolNode(StringView &MangledName,
|
||||
SpecialIntrinsicKind SIK);
|
||||
LocalStaticGuardVariableNode *
|
||||
demangleLocalStaticGuard(StringView &MangledName, bool IsThread);
|
||||
VariableSymbolNode *demangleUntypedVariable(ArenaAllocator &Arena,
|
||||
StringView &MangledName,
|
||||
StringView VariableName);
|
||||
VariableSymbolNode *
|
||||
demangleRttiBaseClassDescriptorNode(ArenaAllocator &Arena,
|
||||
StringView &MangledName);
|
||||
FunctionSymbolNode *demangleInitFiniStub(StringView &MangledName,
|
||||
bool IsDestructor);
|
||||
|
||||
NamedIdentifierNode *demangleSimpleName(StringView &MangledName,
|
||||
bool Memorize);
|
||||
NamedIdentifierNode *demangleAnonymousNamespaceName(StringView &MangledName);
|
||||
NamedIdentifierNode *demangleLocallyScopedNamePiece(StringView &MangledName);
|
||||
EncodedStringLiteralNode *demangleStringLiteral(StringView &MangledName);
|
||||
FunctionSymbolNode *demangleVcallThunkNode(StringView &MangledName);
|
||||
|
||||
StringView demangleSimpleString(StringView &MangledName, bool Memorize);
|
||||
|
||||
FuncClass demangleFunctionClass(StringView &MangledName);
|
||||
CallingConv demangleCallingConvention(StringView &MangledName);
|
||||
StorageClass demangleVariableStorageClass(StringView &MangledName);
|
||||
bool demangleThrowSpecification(StringView &MangledName);
|
||||
wchar_t demangleWcharLiteral(StringView &MangledName);
|
||||
uint8_t demangleCharLiteral(StringView &MangledName);
|
||||
|
||||
std::pair<Qualifiers, bool> demangleQualifiers(StringView &MangledName);
|
||||
|
||||
// Memory allocator.
|
||||
ArenaAllocator Arena;
|
||||
|
||||
// A single type uses one global back-ref table for all function params.
|
||||
// This means back-refs can even go "into" other types. Examples:
|
||||
//
|
||||
// // Second int* is a back-ref to first.
|
||||
// void foo(int *, int*);
|
||||
//
|
||||
// // Second int* is not a back-ref to first (first is not a function param).
|
||||
// int* foo(int*);
|
||||
//
|
||||
// // Second int* is a back-ref to first (ALL function types share the same
|
||||
// // back-ref map.
|
||||
// using F = void(*)(int*);
|
||||
// F G(int *);
|
||||
BackrefContext Backrefs;
|
||||
};
|
||||
|
||||
} // namespace ms_demangle
|
||||
} // namespace llvm
|
||||
|
||||
#endif // LLVM_DEMANGLE_MICROSOFT_DEMANGLE_H
|
||||
629
external/llvm/include/llvm/Demangle/MicrosoftDemangleNodes.h
vendored
Normal file
629
external/llvm/include/llvm/Demangle/MicrosoftDemangleNodes.h
vendored
Normal file
@@ -0,0 +1,629 @@
|
||||
//===- MicrosoftDemangleNodes.h ---------------------------------*- C++ -*-===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file defines the AST nodes used in the MSVC demangler.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_SUPPORT_MICROSOFTDEMANGLENODES_H
|
||||
#define LLVM_SUPPORT_MICROSOFTDEMANGLENODES_H
|
||||
|
||||
#include "llvm/Demangle/DemangleConfig.h"
|
||||
#include "llvm/Demangle/StringView.h"
|
||||
#include <array>
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
|
||||
namespace llvm {
|
||||
namespace itanium_demangle {
|
||||
class OutputStream;
|
||||
}
|
||||
}
|
||||
|
||||
using llvm::itanium_demangle::OutputStream;
|
||||
using llvm::itanium_demangle::StringView;
|
||||
|
||||
namespace llvm {
|
||||
namespace ms_demangle {
|
||||
|
||||
// Storage classes
|
||||
enum Qualifiers : uint8_t {
|
||||
Q_None = 0,
|
||||
Q_Const = 1 << 0,
|
||||
Q_Volatile = 1 << 1,
|
||||
Q_Far = 1 << 2,
|
||||
Q_Huge = 1 << 3,
|
||||
Q_Unaligned = 1 << 4,
|
||||
Q_Restrict = 1 << 5,
|
||||
Q_Pointer64 = 1 << 6
|
||||
};
|
||||
|
||||
enum class StorageClass : uint8_t {
|
||||
None,
|
||||
PrivateStatic,
|
||||
ProtectedStatic,
|
||||
PublicStatic,
|
||||
Global,
|
||||
FunctionLocalStatic,
|
||||
};
|
||||
|
||||
enum class PointerAffinity { None, Pointer, Reference, RValueReference };
|
||||
enum class FunctionRefQualifier { None, Reference, RValueReference };
|
||||
|
||||
// Calling conventions
|
||||
enum class CallingConv : uint8_t {
|
||||
None,
|
||||
Cdecl,
|
||||
Pascal,
|
||||
Thiscall,
|
||||
Stdcall,
|
||||
Fastcall,
|
||||
Clrcall,
|
||||
Eabi,
|
||||
Vectorcall,
|
||||
Regcall,
|
||||
};
|
||||
|
||||
enum class ReferenceKind : uint8_t { None, LValueRef, RValueRef };
|
||||
|
||||
enum OutputFlags {
|
||||
OF_Default = 0,
|
||||
OF_NoCallingConvention = 1,
|
||||
OF_NoTagSpecifier = 2,
|
||||
OF_NoAccessSpecifier = 4,
|
||||
OF_NoMemberType = 8,
|
||||
OF_NoReturnType = 16,
|
||||
};
|
||||
|
||||
// Types
|
||||
enum class PrimitiveKind {
|
||||
Void,
|
||||
Bool,
|
||||
Char,
|
||||
Schar,
|
||||
Uchar,
|
||||
Char8,
|
||||
Char16,
|
||||
Char32,
|
||||
Short,
|
||||
Ushort,
|
||||
Int,
|
||||
Uint,
|
||||
Long,
|
||||
Ulong,
|
||||
Int64,
|
||||
Uint64,
|
||||
Wchar,
|
||||
Float,
|
||||
Double,
|
||||
Ldouble,
|
||||
Nullptr,
|
||||
};
|
||||
|
||||
enum class CharKind {
|
||||
Char,
|
||||
Char16,
|
||||
Char32,
|
||||
Wchar,
|
||||
};
|
||||
|
||||
enum class IntrinsicFunctionKind : uint8_t {
|
||||
None,
|
||||
New, // ?2 # operator new
|
||||
Delete, // ?3 # operator delete
|
||||
Assign, // ?4 # operator=
|
||||
RightShift, // ?5 # operator>>
|
||||
LeftShift, // ?6 # operator<<
|
||||
LogicalNot, // ?7 # operator!
|
||||
Equals, // ?8 # operator==
|
||||
NotEquals, // ?9 # operator!=
|
||||
ArraySubscript, // ?A # operator[]
|
||||
Pointer, // ?C # operator->
|
||||
Dereference, // ?D # operator*
|
||||
Increment, // ?E # operator++
|
||||
Decrement, // ?F # operator--
|
||||
Minus, // ?G # operator-
|
||||
Plus, // ?H # operator+
|
||||
BitwiseAnd, // ?I # operator&
|
||||
MemberPointer, // ?J # operator->*
|
||||
Divide, // ?K # operator/
|
||||
Modulus, // ?L # operator%
|
||||
LessThan, // ?M operator<
|
||||
LessThanEqual, // ?N operator<=
|
||||
GreaterThan, // ?O operator>
|
||||
GreaterThanEqual, // ?P operator>=
|
||||
Comma, // ?Q operator,
|
||||
Parens, // ?R operator()
|
||||
BitwiseNot, // ?S operator~
|
||||
BitwiseXor, // ?T operator^
|
||||
BitwiseOr, // ?U operator|
|
||||
LogicalAnd, // ?V operator&&
|
||||
LogicalOr, // ?W operator||
|
||||
TimesEqual, // ?X operator*=
|
||||
PlusEqual, // ?Y operator+=
|
||||
MinusEqual, // ?Z operator-=
|
||||
DivEqual, // ?_0 operator/=
|
||||
ModEqual, // ?_1 operator%=
|
||||
RshEqual, // ?_2 operator>>=
|
||||
LshEqual, // ?_3 operator<<=
|
||||
BitwiseAndEqual, // ?_4 operator&=
|
||||
BitwiseOrEqual, // ?_5 operator|=
|
||||
BitwiseXorEqual, // ?_6 operator^=
|
||||
VbaseDtor, // ?_D # vbase destructor
|
||||
VecDelDtor, // ?_E # vector deleting destructor
|
||||
DefaultCtorClosure, // ?_F # default constructor closure
|
||||
ScalarDelDtor, // ?_G # scalar deleting destructor
|
||||
VecCtorIter, // ?_H # vector constructor iterator
|
||||
VecDtorIter, // ?_I # vector destructor iterator
|
||||
VecVbaseCtorIter, // ?_J # vector vbase constructor iterator
|
||||
VdispMap, // ?_K # virtual displacement map
|
||||
EHVecCtorIter, // ?_L # eh vector constructor iterator
|
||||
EHVecDtorIter, // ?_M # eh vector destructor iterator
|
||||
EHVecVbaseCtorIter, // ?_N # eh vector vbase constructor iterator
|
||||
CopyCtorClosure, // ?_O # copy constructor closure
|
||||
LocalVftableCtorClosure, // ?_T # local vftable constructor closure
|
||||
ArrayNew, // ?_U operator new[]
|
||||
ArrayDelete, // ?_V operator delete[]
|
||||
ManVectorCtorIter, // ?__A managed vector ctor iterator
|
||||
ManVectorDtorIter, // ?__B managed vector dtor iterator
|
||||
EHVectorCopyCtorIter, // ?__C EH vector copy ctor iterator
|
||||
EHVectorVbaseCopyCtorIter, // ?__D EH vector vbase copy ctor iterator
|
||||
VectorCopyCtorIter, // ?__G vector copy constructor iterator
|
||||
VectorVbaseCopyCtorIter, // ?__H vector vbase copy constructor iterator
|
||||
ManVectorVbaseCopyCtorIter, // ?__I managed vector vbase copy constructor
|
||||
CoAwait, // ?__L operator co_await
|
||||
Spaceship, // ?__M operator<=>
|
||||
MaxIntrinsic
|
||||
};
|
||||
|
||||
enum class SpecialIntrinsicKind {
|
||||
None,
|
||||
Vftable,
|
||||
Vbtable,
|
||||
Typeof,
|
||||
VcallThunk,
|
||||
LocalStaticGuard,
|
||||
StringLiteralSymbol,
|
||||
UdtReturning,
|
||||
Unknown,
|
||||
DynamicInitializer,
|
||||
DynamicAtexitDestructor,
|
||||
RttiTypeDescriptor,
|
||||
RttiBaseClassDescriptor,
|
||||
RttiBaseClassArray,
|
||||
RttiClassHierarchyDescriptor,
|
||||
RttiCompleteObjLocator,
|
||||
LocalVftable,
|
||||
LocalStaticThreadGuard,
|
||||
};
|
||||
|
||||
// Function classes
|
||||
enum FuncClass : uint16_t {
|
||||
FC_None = 0,
|
||||
FC_Public = 1 << 0,
|
||||
FC_Protected = 1 << 1,
|
||||
FC_Private = 1 << 2,
|
||||
FC_Global = 1 << 3,
|
||||
FC_Static = 1 << 4,
|
||||
FC_Virtual = 1 << 5,
|
||||
FC_Far = 1 << 6,
|
||||
FC_ExternC = 1 << 7,
|
||||
FC_NoParameterList = 1 << 8,
|
||||
FC_VirtualThisAdjust = 1 << 9,
|
||||
FC_VirtualThisAdjustEx = 1 << 10,
|
||||
FC_StaticThisAdjust = 1 << 11,
|
||||
};
|
||||
|
||||
enum class TagKind { Class, Struct, Union, Enum };
|
||||
|
||||
enum class NodeKind {
|
||||
Unknown,
|
||||
Md5Symbol,
|
||||
PrimitiveType,
|
||||
FunctionSignature,
|
||||
Identifier,
|
||||
NamedIdentifier,
|
||||
VcallThunkIdentifier,
|
||||
LocalStaticGuardIdentifier,
|
||||
IntrinsicFunctionIdentifier,
|
||||
ConversionOperatorIdentifier,
|
||||
DynamicStructorIdentifier,
|
||||
StructorIdentifier,
|
||||
LiteralOperatorIdentifier,
|
||||
ThunkSignature,
|
||||
PointerType,
|
||||
TagType,
|
||||
ArrayType,
|
||||
Custom,
|
||||
IntrinsicType,
|
||||
NodeArray,
|
||||
QualifiedName,
|
||||
TemplateParameterReference,
|
||||
EncodedStringLiteral,
|
||||
IntegerLiteral,
|
||||
RttiBaseClassDescriptor,
|
||||
LocalStaticGuardVariable,
|
||||
FunctionSymbol,
|
||||
VariableSymbol,
|
||||
SpecialTableSymbol
|
||||
};
|
||||
|
||||
struct Node {
|
||||
explicit Node(NodeKind K) : Kind(K) {}
|
||||
virtual ~Node() = default;
|
||||
|
||||
NodeKind kind() const { return Kind; }
|
||||
|
||||
virtual void output(OutputStream &OS, OutputFlags Flags) const = 0;
|
||||
|
||||
std::string toString(OutputFlags Flags = OF_Default) const;
|
||||
|
||||
private:
|
||||
NodeKind Kind;
|
||||
};
|
||||
|
||||
struct TypeNode;
|
||||
struct PrimitiveTypeNode;
|
||||
struct FunctionSignatureNode;
|
||||
struct IdentifierNode;
|
||||
struct NamedIdentifierNode;
|
||||
struct VcallThunkIdentifierNode;
|
||||
struct IntrinsicFunctionIdentifierNode;
|
||||
struct LiteralOperatorIdentifierNode;
|
||||
struct ConversionOperatorIdentifierNode;
|
||||
struct StructorIdentifierNode;
|
||||
struct ThunkSignatureNode;
|
||||
struct PointerTypeNode;
|
||||
struct ArrayTypeNode;
|
||||
struct CustomNode;
|
||||
struct TagTypeNode;
|
||||
struct IntrinsicTypeNode;
|
||||
struct NodeArrayNode;
|
||||
struct QualifiedNameNode;
|
||||
struct TemplateParameterReferenceNode;
|
||||
struct EncodedStringLiteralNode;
|
||||
struct IntegerLiteralNode;
|
||||
struct RttiBaseClassDescriptorNode;
|
||||
struct LocalStaticGuardVariableNode;
|
||||
struct SymbolNode;
|
||||
struct FunctionSymbolNode;
|
||||
struct VariableSymbolNode;
|
||||
struct SpecialTableSymbolNode;
|
||||
|
||||
struct TypeNode : public Node {
|
||||
explicit TypeNode(NodeKind K) : Node(K) {}
|
||||
|
||||
virtual void outputPre(OutputStream &OS, OutputFlags Flags) const = 0;
|
||||
virtual void outputPost(OutputStream &OS, OutputFlags Flags) const = 0;
|
||||
|
||||
void output(OutputStream &OS, OutputFlags Flags) const override {
|
||||
outputPre(OS, Flags);
|
||||
outputPost(OS, Flags);
|
||||
}
|
||||
|
||||
Qualifiers Quals = Q_None;
|
||||
};
|
||||
|
||||
struct PrimitiveTypeNode : public TypeNode {
|
||||
explicit PrimitiveTypeNode(PrimitiveKind K)
|
||||
: TypeNode(NodeKind::PrimitiveType), PrimKind(K) {}
|
||||
|
||||
void outputPre(OutputStream &OS, OutputFlags Flags) const override;
|
||||
void outputPost(OutputStream &OS, OutputFlags Flags) const override {}
|
||||
|
||||
PrimitiveKind PrimKind;
|
||||
};
|
||||
|
||||
struct FunctionSignatureNode : public TypeNode {
|
||||
explicit FunctionSignatureNode(NodeKind K) : TypeNode(K) {}
|
||||
FunctionSignatureNode() : TypeNode(NodeKind::FunctionSignature) {}
|
||||
|
||||
void outputPre(OutputStream &OS, OutputFlags Flags) const override;
|
||||
void outputPost(OutputStream &OS, OutputFlags Flags) const override;
|
||||
|
||||
// Valid if this FunctionTypeNode is the Pointee of a PointerType or
|
||||
// MemberPointerType.
|
||||
PointerAffinity Affinity = PointerAffinity::None;
|
||||
|
||||
// The function's calling convention.
|
||||
CallingConv CallConvention = CallingConv::None;
|
||||
|
||||
// Function flags (gloabl, public, etc)
|
||||
FuncClass FunctionClass = FC_Global;
|
||||
|
||||
FunctionRefQualifier RefQualifier = FunctionRefQualifier::None;
|
||||
|
||||
// The return type of the function.
|
||||
TypeNode *ReturnType = nullptr;
|
||||
|
||||
// True if this is a C-style ... varargs function.
|
||||
bool IsVariadic = false;
|
||||
|
||||
// Function parameters
|
||||
NodeArrayNode *Params = nullptr;
|
||||
|
||||
// True if the function type is noexcept.
|
||||
bool IsNoexcept = false;
|
||||
};
|
||||
|
||||
struct IdentifierNode : public Node {
|
||||
explicit IdentifierNode(NodeKind K) : Node(K) {}
|
||||
|
||||
NodeArrayNode *TemplateParams = nullptr;
|
||||
|
||||
protected:
|
||||
void outputTemplateParameters(OutputStream &OS, OutputFlags Flags) const;
|
||||
};
|
||||
|
||||
struct VcallThunkIdentifierNode : public IdentifierNode {
|
||||
VcallThunkIdentifierNode() : IdentifierNode(NodeKind::VcallThunkIdentifier) {}
|
||||
|
||||
void output(OutputStream &OS, OutputFlags Flags) const override;
|
||||
|
||||
uint64_t OffsetInVTable = 0;
|
||||
};
|
||||
|
||||
struct DynamicStructorIdentifierNode : public IdentifierNode {
|
||||
DynamicStructorIdentifierNode()
|
||||
: IdentifierNode(NodeKind::DynamicStructorIdentifier) {}
|
||||
|
||||
void output(OutputStream &OS, OutputFlags Flags) const override;
|
||||
|
||||
VariableSymbolNode *Variable = nullptr;
|
||||
QualifiedNameNode *Name = nullptr;
|
||||
bool IsDestructor = false;
|
||||
};
|
||||
|
||||
struct NamedIdentifierNode : public IdentifierNode {
|
||||
NamedIdentifierNode() : IdentifierNode(NodeKind::NamedIdentifier) {}
|
||||
|
||||
void output(OutputStream &OS, OutputFlags Flags) const override;
|
||||
|
||||
StringView Name;
|
||||
};
|
||||
|
||||
struct IntrinsicFunctionIdentifierNode : public IdentifierNode {
|
||||
explicit IntrinsicFunctionIdentifierNode(IntrinsicFunctionKind Operator)
|
||||
: IdentifierNode(NodeKind::IntrinsicFunctionIdentifier),
|
||||
Operator(Operator) {}
|
||||
|
||||
void output(OutputStream &OS, OutputFlags Flags) const override;
|
||||
|
||||
IntrinsicFunctionKind Operator;
|
||||
};
|
||||
|
||||
struct LiteralOperatorIdentifierNode : public IdentifierNode {
|
||||
LiteralOperatorIdentifierNode()
|
||||
: IdentifierNode(NodeKind::LiteralOperatorIdentifier) {}
|
||||
|
||||
void output(OutputStream &OS, OutputFlags Flags) const override;
|
||||
|
||||
StringView Name;
|
||||
};
|
||||
|
||||
struct LocalStaticGuardIdentifierNode : public IdentifierNode {
|
||||
LocalStaticGuardIdentifierNode()
|
||||
: IdentifierNode(NodeKind::LocalStaticGuardIdentifier) {}
|
||||
|
||||
void output(OutputStream &OS, OutputFlags Flags) const override;
|
||||
|
||||
bool IsThread = false;
|
||||
uint32_t ScopeIndex = 0;
|
||||
};
|
||||
|
||||
struct ConversionOperatorIdentifierNode : public IdentifierNode {
|
||||
ConversionOperatorIdentifierNode()
|
||||
: IdentifierNode(NodeKind::ConversionOperatorIdentifier) {}
|
||||
|
||||
void output(OutputStream &OS, OutputFlags Flags) const override;
|
||||
|
||||
// The type that this operator converts too.
|
||||
TypeNode *TargetType = nullptr;
|
||||
};
|
||||
|
||||
struct StructorIdentifierNode : public IdentifierNode {
|
||||
StructorIdentifierNode() : IdentifierNode(NodeKind::StructorIdentifier) {}
|
||||
explicit StructorIdentifierNode(bool IsDestructor)
|
||||
: IdentifierNode(NodeKind::StructorIdentifier),
|
||||
IsDestructor(IsDestructor) {}
|
||||
|
||||
void output(OutputStream &OS, OutputFlags Flags) const override;
|
||||
|
||||
// The name of the class that this is a structor of.
|
||||
IdentifierNode *Class = nullptr;
|
||||
bool IsDestructor = false;
|
||||
};
|
||||
|
||||
struct ThunkSignatureNode : public FunctionSignatureNode {
|
||||
ThunkSignatureNode() : FunctionSignatureNode(NodeKind::ThunkSignature) {}
|
||||
|
||||
void outputPre(OutputStream &OS, OutputFlags Flags) const override;
|
||||
void outputPost(OutputStream &OS, OutputFlags Flags) const override;
|
||||
|
||||
struct ThisAdjustor {
|
||||
uint32_t StaticOffset = 0;
|
||||
int32_t VBPtrOffset = 0;
|
||||
int32_t VBOffsetOffset = 0;
|
||||
int32_t VtordispOffset = 0;
|
||||
};
|
||||
|
||||
ThisAdjustor ThisAdjust;
|
||||
};
|
||||
|
||||
struct PointerTypeNode : public TypeNode {
|
||||
PointerTypeNode() : TypeNode(NodeKind::PointerType) {}
|
||||
void outputPre(OutputStream &OS, OutputFlags Flags) const override;
|
||||
void outputPost(OutputStream &OS, OutputFlags Flags) const override;
|
||||
|
||||
// Is this a pointer, reference, or rvalue-reference?
|
||||
PointerAffinity Affinity = PointerAffinity::None;
|
||||
|
||||
// If this is a member pointer, this is the class that the member is in.
|
||||
QualifiedNameNode *ClassParent = nullptr;
|
||||
|
||||
// Represents a type X in "a pointer to X", "a reference to X", or
|
||||
// "rvalue-reference to X"
|
||||
TypeNode *Pointee = nullptr;
|
||||
};
|
||||
|
||||
struct TagTypeNode : public TypeNode {
|
||||
explicit TagTypeNode(TagKind Tag) : TypeNode(NodeKind::TagType), Tag(Tag) {}
|
||||
|
||||
void outputPre(OutputStream &OS, OutputFlags Flags) const override;
|
||||
void outputPost(OutputStream &OS, OutputFlags Flags) const override;
|
||||
|
||||
QualifiedNameNode *QualifiedName = nullptr;
|
||||
TagKind Tag;
|
||||
};
|
||||
|
||||
struct ArrayTypeNode : public TypeNode {
|
||||
ArrayTypeNode() : TypeNode(NodeKind::ArrayType) {}
|
||||
|
||||
void outputPre(OutputStream &OS, OutputFlags Flags) const override;
|
||||
void outputPost(OutputStream &OS, OutputFlags Flags) const override;
|
||||
|
||||
void outputDimensionsImpl(OutputStream &OS, OutputFlags Flags) const;
|
||||
void outputOneDimension(OutputStream &OS, OutputFlags Flags, Node *N) const;
|
||||
|
||||
// A list of array dimensions. e.g. [3,4,5] in `int Foo[3][4][5]`
|
||||
NodeArrayNode *Dimensions = nullptr;
|
||||
|
||||
// The type of array element.
|
||||
TypeNode *ElementType = nullptr;
|
||||
};
|
||||
|
||||
struct IntrinsicNode : public TypeNode {
|
||||
IntrinsicNode() : TypeNode(NodeKind::IntrinsicType) {}
|
||||
void output(OutputStream &OS, OutputFlags Flags) const override {}
|
||||
};
|
||||
|
||||
struct CustomTypeNode : public TypeNode {
|
||||
CustomTypeNode() : TypeNode(NodeKind::Custom) {}
|
||||
|
||||
void outputPre(OutputStream &OS, OutputFlags Flags) const override;
|
||||
void outputPost(OutputStream &OS, OutputFlags Flags) const override;
|
||||
|
||||
IdentifierNode *Identifier = nullptr;
|
||||
};
|
||||
|
||||
struct NodeArrayNode : public Node {
|
||||
NodeArrayNode() : Node(NodeKind::NodeArray) {}
|
||||
|
||||
void output(OutputStream &OS, OutputFlags Flags) const override;
|
||||
|
||||
void output(OutputStream &OS, OutputFlags Flags, StringView Separator) const;
|
||||
|
||||
Node **Nodes = nullptr;
|
||||
size_t Count = 0;
|
||||
};
|
||||
|
||||
struct QualifiedNameNode : public Node {
|
||||
QualifiedNameNode() : Node(NodeKind::QualifiedName) {}
|
||||
|
||||
void output(OutputStream &OS, OutputFlags Flags) const override;
|
||||
|
||||
NodeArrayNode *Components = nullptr;
|
||||
|
||||
IdentifierNode *getUnqualifiedIdentifier() {
|
||||
Node *LastComponent = Components->Nodes[Components->Count - 1];
|
||||
return static_cast<IdentifierNode *>(LastComponent);
|
||||
}
|
||||
};
|
||||
|
||||
struct TemplateParameterReferenceNode : public Node {
|
||||
TemplateParameterReferenceNode()
|
||||
: Node(NodeKind::TemplateParameterReference) {}
|
||||
|
||||
void output(OutputStream &OS, OutputFlags Flags) const override;
|
||||
|
||||
SymbolNode *Symbol = nullptr;
|
||||
|
||||
int ThunkOffsetCount = 0;
|
||||
std::array<int64_t, 3> ThunkOffsets;
|
||||
PointerAffinity Affinity = PointerAffinity::None;
|
||||
bool IsMemberPointer = false;
|
||||
};
|
||||
|
||||
struct IntegerLiteralNode : public Node {
|
||||
IntegerLiteralNode() : Node(NodeKind::IntegerLiteral) {}
|
||||
IntegerLiteralNode(uint64_t Value, bool IsNegative)
|
||||
: Node(NodeKind::IntegerLiteral), Value(Value), IsNegative(IsNegative) {}
|
||||
|
||||
void output(OutputStream &OS, OutputFlags Flags) const override;
|
||||
|
||||
uint64_t Value = 0;
|
||||
bool IsNegative = false;
|
||||
};
|
||||
|
||||
struct RttiBaseClassDescriptorNode : public IdentifierNode {
|
||||
RttiBaseClassDescriptorNode()
|
||||
: IdentifierNode(NodeKind::RttiBaseClassDescriptor) {}
|
||||
|
||||
void output(OutputStream &OS, OutputFlags Flags) const override;
|
||||
|
||||
uint32_t NVOffset = 0;
|
||||
int32_t VBPtrOffset = 0;
|
||||
uint32_t VBTableOffset = 0;
|
||||
uint32_t Flags = 0;
|
||||
};
|
||||
|
||||
struct SymbolNode : public Node {
|
||||
explicit SymbolNode(NodeKind K) : Node(K) {}
|
||||
void output(OutputStream &OS, OutputFlags Flags) const override;
|
||||
QualifiedNameNode *Name = nullptr;
|
||||
};
|
||||
|
||||
struct SpecialTableSymbolNode : public SymbolNode {
|
||||
explicit SpecialTableSymbolNode()
|
||||
: SymbolNode(NodeKind::SpecialTableSymbol) {}
|
||||
|
||||
void output(OutputStream &OS, OutputFlags Flags) const override;
|
||||
QualifiedNameNode *TargetName = nullptr;
|
||||
Qualifiers Quals = Qualifiers::Q_None;
|
||||
};
|
||||
|
||||
struct LocalStaticGuardVariableNode : public SymbolNode {
|
||||
LocalStaticGuardVariableNode()
|
||||
: SymbolNode(NodeKind::LocalStaticGuardVariable) {}
|
||||
|
||||
void output(OutputStream &OS, OutputFlags Flags) const override;
|
||||
|
||||
bool IsVisible = false;
|
||||
};
|
||||
|
||||
struct EncodedStringLiteralNode : public SymbolNode {
|
||||
EncodedStringLiteralNode() : SymbolNode(NodeKind::EncodedStringLiteral) {}
|
||||
|
||||
void output(OutputStream &OS, OutputFlags Flags) const override;
|
||||
|
||||
StringView DecodedString;
|
||||
bool IsTruncated = false;
|
||||
CharKind Char = CharKind::Char;
|
||||
};
|
||||
|
||||
struct VariableSymbolNode : public SymbolNode {
|
||||
VariableSymbolNode() : SymbolNode(NodeKind::VariableSymbol) {}
|
||||
|
||||
void output(OutputStream &OS, OutputFlags Flags) const override;
|
||||
|
||||
StorageClass SC = StorageClass::None;
|
||||
TypeNode *Type = nullptr;
|
||||
};
|
||||
|
||||
struct FunctionSymbolNode : public SymbolNode {
|
||||
FunctionSymbolNode() : SymbolNode(NodeKind::FunctionSymbol) {}
|
||||
|
||||
void output(OutputStream &OS, OutputFlags Flags) const override;
|
||||
|
||||
FunctionSignatureNode *Signature = nullptr;
|
||||
};
|
||||
|
||||
} // namespace ms_demangle
|
||||
} // namespace llvm
|
||||
|
||||
#endif
|
||||
126
external/llvm/include/llvm/Demangle/StringView.h
vendored
Normal file
126
external/llvm/include/llvm/Demangle/StringView.h
vendored
Normal file
@@ -0,0 +1,126 @@
|
||||
//===--- StringView.h -------------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// FIXME: Use std::string_view instead when we support C++17.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef DEMANGLE_STRINGVIEW_H
|
||||
#define DEMANGLE_STRINGVIEW_H
|
||||
|
||||
#include "DemangleConfig.h"
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <cstring>
|
||||
|
||||
DEMANGLE_NAMESPACE_BEGIN
|
||||
|
||||
class StringView {
|
||||
const char *First;
|
||||
const char *Last;
|
||||
|
||||
public:
|
||||
static const size_t npos = ~size_t(0);
|
||||
|
||||
template <size_t N>
|
||||
StringView(const char (&Str)[N]) : First(Str), Last(Str + N - 1) {}
|
||||
StringView(const char *First_, const char *Last_)
|
||||
: First(First_), Last(Last_) {}
|
||||
StringView(const char *First_, size_t Len)
|
||||
: First(First_), Last(First_ + Len) {}
|
||||
StringView(const char *Str) : First(Str), Last(Str + std::strlen(Str)) {}
|
||||
StringView() : First(nullptr), Last(nullptr) {}
|
||||
|
||||
StringView substr(size_t From) const {
|
||||
return StringView(begin() + From, size() - From);
|
||||
}
|
||||
|
||||
size_t find(char C, size_t From = 0) const {
|
||||
size_t FindBegin = std::min(From, size());
|
||||
// Avoid calling memchr with nullptr.
|
||||
if (FindBegin < size()) {
|
||||
// Just forward to memchr, which is faster than a hand-rolled loop.
|
||||
if (const void *P = ::memchr(First + FindBegin, C, size() - FindBegin))
|
||||
return size_t(static_cast<const char *>(P) - First);
|
||||
}
|
||||
return npos;
|
||||
}
|
||||
|
||||
StringView substr(size_t From, size_t To) const {
|
||||
if (To >= size())
|
||||
To = size() - 1;
|
||||
if (From >= size())
|
||||
From = size() - 1;
|
||||
return StringView(First + From, First + To);
|
||||
}
|
||||
|
||||
StringView dropFront(size_t N = 1) const {
|
||||
if (N >= size())
|
||||
N = size();
|
||||
return StringView(First + N, Last);
|
||||
}
|
||||
|
||||
StringView dropBack(size_t N = 1) const {
|
||||
if (N >= size())
|
||||
N = size();
|
||||
return StringView(First, Last - N);
|
||||
}
|
||||
|
||||
char front() const {
|
||||
assert(!empty());
|
||||
return *begin();
|
||||
}
|
||||
|
||||
char back() const {
|
||||
assert(!empty());
|
||||
return *(end() - 1);
|
||||
}
|
||||
|
||||
char popFront() {
|
||||
assert(!empty());
|
||||
return *First++;
|
||||
}
|
||||
|
||||
bool consumeFront(char C) {
|
||||
if (!startsWith(C))
|
||||
return false;
|
||||
*this = dropFront(1);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool consumeFront(StringView S) {
|
||||
if (!startsWith(S))
|
||||
return false;
|
||||
*this = dropFront(S.size());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool startsWith(char C) const { return !empty() && *begin() == C; }
|
||||
|
||||
bool startsWith(StringView Str) const {
|
||||
if (Str.size() > size())
|
||||
return false;
|
||||
return std::equal(Str.begin(), Str.end(), begin());
|
||||
}
|
||||
|
||||
const char &operator[](size_t Idx) const { return *(begin() + Idx); }
|
||||
|
||||
const char *begin() const { return First; }
|
||||
const char *end() const { return Last; }
|
||||
size_t size() const { return static_cast<size_t>(Last - First); }
|
||||
bool empty() const { return First == Last; }
|
||||
};
|
||||
|
||||
inline bool operator==(const StringView &LHS, const StringView &RHS) {
|
||||
return LHS.size() == RHS.size() &&
|
||||
std::equal(LHS.begin(), LHS.end(), RHS.begin());
|
||||
}
|
||||
|
||||
DEMANGLE_NAMESPACE_END
|
||||
|
||||
#endif
|
||||
191
external/llvm/include/llvm/Demangle/Utility.h
vendored
Normal file
191
external/llvm/include/llvm/Demangle/Utility.h
vendored
Normal file
@@ -0,0 +1,191 @@
|
||||
//===--- Utility.h ----------------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Provide some utility classes for use in the demangler(s).
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef DEMANGLE_UTILITY_H
|
||||
#define DEMANGLE_UTILITY_H
|
||||
|
||||
#include "StringView.h"
|
||||
#include <cstdint>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <iterator>
|
||||
#include <limits>
|
||||
|
||||
DEMANGLE_NAMESPACE_BEGIN
|
||||
|
||||
// Stream that AST nodes write their string representation into after the AST
|
||||
// has been parsed.
|
||||
class OutputStream {
|
||||
char *Buffer = nullptr;
|
||||
size_t CurrentPosition = 0;
|
||||
size_t BufferCapacity = 0;
|
||||
|
||||
// Ensure there is at least n more positions in buffer.
|
||||
void grow(size_t N) {
|
||||
if (N + CurrentPosition >= BufferCapacity) {
|
||||
BufferCapacity *= 2;
|
||||
if (BufferCapacity < N + CurrentPosition)
|
||||
BufferCapacity = N + CurrentPosition;
|
||||
Buffer = static_cast<char *>(std::realloc(Buffer, BufferCapacity));
|
||||
if (Buffer == nullptr)
|
||||
std::terminate();
|
||||
}
|
||||
}
|
||||
|
||||
void writeUnsigned(uint64_t N, bool isNeg = false) {
|
||||
// Handle special case...
|
||||
if (N == 0) {
|
||||
*this << '0';
|
||||
return;
|
||||
}
|
||||
|
||||
char Temp[21];
|
||||
char *TempPtr = std::end(Temp);
|
||||
|
||||
while (N) {
|
||||
*--TempPtr = '0' + char(N % 10);
|
||||
N /= 10;
|
||||
}
|
||||
|
||||
// Add negative sign...
|
||||
if (isNeg)
|
||||
*--TempPtr = '-';
|
||||
this->operator<<(StringView(TempPtr, std::end(Temp)));
|
||||
}
|
||||
|
||||
public:
|
||||
OutputStream(char *StartBuf, size_t Size)
|
||||
: Buffer(StartBuf), CurrentPosition(0), BufferCapacity(Size) {}
|
||||
OutputStream() = default;
|
||||
void reset(char *Buffer_, size_t BufferCapacity_) {
|
||||
CurrentPosition = 0;
|
||||
Buffer = Buffer_;
|
||||
BufferCapacity = BufferCapacity_;
|
||||
}
|
||||
|
||||
/// If a ParameterPackExpansion (or similar type) is encountered, the offset
|
||||
/// into the pack that we're currently printing.
|
||||
unsigned CurrentPackIndex = std::numeric_limits<unsigned>::max();
|
||||
unsigned CurrentPackMax = std::numeric_limits<unsigned>::max();
|
||||
|
||||
OutputStream &operator+=(StringView R) {
|
||||
size_t Size = R.size();
|
||||
if (Size == 0)
|
||||
return *this;
|
||||
grow(Size);
|
||||
std::memmove(Buffer + CurrentPosition, R.begin(), Size);
|
||||
CurrentPosition += Size;
|
||||
return *this;
|
||||
}
|
||||
|
||||
OutputStream &operator+=(char C) {
|
||||
grow(1);
|
||||
Buffer[CurrentPosition++] = C;
|
||||
return *this;
|
||||
}
|
||||
|
||||
OutputStream &operator<<(StringView R) { return (*this += R); }
|
||||
|
||||
OutputStream &operator<<(char C) { return (*this += C); }
|
||||
|
||||
OutputStream &operator<<(long long N) {
|
||||
if (N < 0)
|
||||
writeUnsigned(static_cast<unsigned long long>(-N), true);
|
||||
else
|
||||
writeUnsigned(static_cast<unsigned long long>(N));
|
||||
return *this;
|
||||
}
|
||||
|
||||
OutputStream &operator<<(unsigned long long N) {
|
||||
writeUnsigned(N, false);
|
||||
return *this;
|
||||
}
|
||||
|
||||
OutputStream &operator<<(long N) {
|
||||
return this->operator<<(static_cast<long long>(N));
|
||||
}
|
||||
|
||||
OutputStream &operator<<(unsigned long N) {
|
||||
return this->operator<<(static_cast<unsigned long long>(N));
|
||||
}
|
||||
|
||||
OutputStream &operator<<(int N) {
|
||||
return this->operator<<(static_cast<long long>(N));
|
||||
}
|
||||
|
||||
OutputStream &operator<<(unsigned int N) {
|
||||
return this->operator<<(static_cast<unsigned long long>(N));
|
||||
}
|
||||
|
||||
size_t getCurrentPosition() const { return CurrentPosition; }
|
||||
void setCurrentPosition(size_t NewPos) { CurrentPosition = NewPos; }
|
||||
|
||||
char back() const {
|
||||
return CurrentPosition ? Buffer[CurrentPosition - 1] : '\0';
|
||||
}
|
||||
|
||||
bool empty() const { return CurrentPosition == 0; }
|
||||
|
||||
char *getBuffer() { return Buffer; }
|
||||
char *getBufferEnd() { return Buffer + CurrentPosition - 1; }
|
||||
size_t getBufferCapacity() const { return BufferCapacity; }
|
||||
};
|
||||
|
||||
template <class T> class SwapAndRestore {
|
||||
T &Restore;
|
||||
T OriginalValue;
|
||||
bool ShouldRestore = true;
|
||||
|
||||
public:
|
||||
SwapAndRestore(T &Restore_) : SwapAndRestore(Restore_, Restore_) {}
|
||||
|
||||
SwapAndRestore(T &Restore_, T NewVal)
|
||||
: Restore(Restore_), OriginalValue(Restore) {
|
||||
Restore = std::move(NewVal);
|
||||
}
|
||||
~SwapAndRestore() {
|
||||
if (ShouldRestore)
|
||||
Restore = std::move(OriginalValue);
|
||||
}
|
||||
|
||||
void shouldRestore(bool ShouldRestore_) { ShouldRestore = ShouldRestore_; }
|
||||
|
||||
void restoreNow(bool Force) {
|
||||
if (!Force && !ShouldRestore)
|
||||
return;
|
||||
|
||||
Restore = std::move(OriginalValue);
|
||||
ShouldRestore = false;
|
||||
}
|
||||
|
||||
SwapAndRestore(const SwapAndRestore &) = delete;
|
||||
SwapAndRestore &operator=(const SwapAndRestore &) = delete;
|
||||
};
|
||||
|
||||
inline bool initializeOutputStream(char *Buf, size_t *N, OutputStream &S,
|
||||
size_t InitSize) {
|
||||
size_t BufferSize;
|
||||
if (Buf == nullptr) {
|
||||
Buf = static_cast<char *>(std::malloc(InitSize));
|
||||
if (Buf == nullptr)
|
||||
return false;
|
||||
BufferSize = InitSize;
|
||||
} else
|
||||
BufferSize = *N;
|
||||
|
||||
S.reset(Buf, BufferSize);
|
||||
return true;
|
||||
}
|
||||
|
||||
DEMANGLE_NAMESPACE_END
|
||||
|
||||
#endif
|
||||
8
external/nlohmann_json/CMakeLists.txt
vendored
Normal file
8
external/nlohmann_json/CMakeLists.txt
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
project(nlohmann_json)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
|
||||
add_library(nlohmann_json INTERFACE)
|
||||
|
||||
target_include_directories(nlohmann_json INTERFACE include)
|
||||
25447
external/nlohmann_json/include/nlohmann/json.hpp
vendored
Normal file
25447
external/nlohmann_json/include/nlohmann/json.hpp
vendored
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,24 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <hex.hpp>
|
||||
|
||||
#include <array>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
|
||||
namespace hex {
|
||||
|
||||
namespace prv { class Provider; }
|
||||
|
||||
u16 crc16(prv::Provider* &data, u64 offset, size_t size, u16 polynomial, u16 init);
|
||||
u32 crc32(prv::Provider* &data, u64 offset, size_t size, u32 polynomial, u32 init);
|
||||
|
||||
std::array<u32, 4> md4(prv::Provider* &data, u64 offset, size_t size);
|
||||
std::array<u32, 4> md5(prv::Provider* &data, u64 offset, size_t size);
|
||||
std::array<u32, 5> sha1(prv::Provider* &data, u64 offset, size_t size);
|
||||
std::array<u32, 7> sha224(prv::Provider* &data, u64 offset, size_t size);
|
||||
std::array<u32, 8> sha256(prv::Provider* &data, u64 offset, size_t size);
|
||||
std::array<u32, 12> sha384(prv::Provider* &data, u64 offset, size_t size);
|
||||
std::array<u32, 16> sha512(prv::Provider* &data, u64 offset, size_t size);
|
||||
|
||||
}
|
||||
@@ -1,45 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include <functional>
|
||||
|
||||
namespace hex {
|
||||
|
||||
enum class Events {
|
||||
DataChanged
|
||||
};
|
||||
|
||||
struct EventHandler {
|
||||
void *sender;
|
||||
Events eventType;
|
||||
std::function<void(void*)> callback;
|
||||
};
|
||||
|
||||
class EventManager {
|
||||
public:
|
||||
|
||||
void post(Events eventType, void *userData) {
|
||||
for (auto &handler : this->m_eventHandlers)
|
||||
if (eventType == handler.eventType)
|
||||
handler.callback(userData);
|
||||
}
|
||||
|
||||
void subscribe(Events eventType, void *sender, std::function<void(void*)> callback) {
|
||||
for (auto &handler : this->m_eventHandlers)
|
||||
if (eventType == handler.eventType && sender == handler.sender)
|
||||
return;
|
||||
|
||||
this->m_eventHandlers.push_back(EventHandler { sender, eventType, callback });
|
||||
}
|
||||
|
||||
void unsubscribe(Events eventType, void *sender) {
|
||||
std::erase_if(this->m_eventHandlers, [&eventType, &sender](EventHandler handler) {
|
||||
return eventType == handler.eventType && sender == handler.sender;
|
||||
});
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<EventHandler> m_eventHandlers;
|
||||
};
|
||||
|
||||
}
|
||||
58
include/helpers/disassembler.hpp
Normal file
58
include/helpers/disassembler.hpp
Normal file
@@ -0,0 +1,58 @@
|
||||
#pragma once
|
||||
|
||||
#if __has_include(<capstone/capstone.h>)
|
||||
#include <capstone/capstone.h>
|
||||
#else
|
||||
#include <capstone.h>
|
||||
#endif
|
||||
#include <hex.hpp>
|
||||
|
||||
namespace hex {
|
||||
|
||||
enum class Architecture : s32 {
|
||||
ARM,
|
||||
ARM64,
|
||||
MIPS,
|
||||
X86,
|
||||
PPC,
|
||||
SPARC,
|
||||
SYSZ,
|
||||
XCORE,
|
||||
M68K,
|
||||
TMS320C64X,
|
||||
M680X,
|
||||
EVM,
|
||||
|
||||
MAX,
|
||||
MIN = ARM
|
||||
};
|
||||
|
||||
class Disassembler {
|
||||
public:
|
||||
static constexpr cs_arch toCapstoneArchictecture(Architecture architecture) {
|
||||
return static_cast<cs_arch>(architecture);
|
||||
}
|
||||
|
||||
static inline bool isSupported(Architecture architecture) {
|
||||
return cs_support(toCapstoneArchictecture(architecture));
|
||||
}
|
||||
|
||||
constexpr static const char * const ArchitectureNames[] = { "ARM32", "ARM64", "MIPS", "x86", "PowerPC", "Sparc", "SystemZ", "XCore", "68K", "TMS320C64x", "680X", "Ethereum" };
|
||||
|
||||
static inline s32 getArchitectureSupportedCount() {
|
||||
static s32 supportedCount = -1;
|
||||
|
||||
if (supportedCount != -1) {
|
||||
return supportedCount;
|
||||
}
|
||||
|
||||
for (supportedCount = static_cast<s32>(Architecture::MIN); supportedCount < static_cast<s32>(Architecture::MAX); supportedCount++) {
|
||||
if (!cs_support(supportedCount)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return supportedCount;
|
||||
}
|
||||
};
|
||||
}
|
||||
37
include/helpers/encoding_file.hpp
Normal file
37
include/helpers/encoding_file.hpp
Normal file
@@ -0,0 +1,37 @@
|
||||
#pragma once
|
||||
|
||||
#include <hex.hpp>
|
||||
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
namespace hex {
|
||||
|
||||
template<typename T>
|
||||
struct SizeSorter {
|
||||
bool operator() (const T& lhs, const T& rhs) const {
|
||||
return lhs.size() < rhs.size();
|
||||
}
|
||||
};
|
||||
|
||||
class EncodingFile {
|
||||
public:
|
||||
enum class Type {
|
||||
Thingy,
|
||||
CSV
|
||||
};
|
||||
|
||||
EncodingFile() = default;
|
||||
EncodingFile(Type type, std::string_view path);
|
||||
|
||||
std::pair<std::string_view, size_t> getEncodingFor(const std::vector<u8> &buffer) const;
|
||||
size_t getLongestSequence() const { return this->m_longestSequence; }
|
||||
|
||||
private:
|
||||
void parseThingyFile(std::ifstream &content);
|
||||
|
||||
std::map<u32, std::map<std::vector<u8>, std::string>> m_mapping;
|
||||
size_t m_longestSequence = 0;
|
||||
};
|
||||
|
||||
}
|
||||
33
include/helpers/loader_script_handler.hpp
Normal file
33
include/helpers/loader_script_handler.hpp
Normal file
@@ -0,0 +1,33 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
|
||||
struct _object;
|
||||
typedef struct _object PyObject;
|
||||
|
||||
namespace hex {
|
||||
|
||||
namespace prv { class Provider; }
|
||||
|
||||
class LoaderScript {
|
||||
public:
|
||||
LoaderScript() = delete;
|
||||
|
||||
static bool processFile(std::string_view scriptPath);
|
||||
|
||||
static void setFilePath(std::string_view filePath) { LoaderScript::s_filePath = filePath; }
|
||||
static void setDataProvider(prv::Provider* provider) { LoaderScript::s_dataProvider = provider; }
|
||||
private:
|
||||
static inline std::string s_filePath;
|
||||
static inline prv::Provider* s_dataProvider;
|
||||
|
||||
static PyObject* Py_getFilePath(PyObject *self, PyObject *args);
|
||||
static PyObject* Py_addPatch(PyObject *self, PyObject *args);
|
||||
static PyObject* Py_addBookmark(PyObject *self, PyObject *args);
|
||||
|
||||
static PyObject* Py_addStruct(PyObject *self, PyObject *args);
|
||||
static PyObject* Py_addUnion(PyObject *self, PyObject *args);
|
||||
};
|
||||
|
||||
}
|
||||
17
include/helpers/patches.hpp
Normal file
17
include/helpers/patches.hpp
Normal file
@@ -0,0 +1,17 @@
|
||||
#pragma once
|
||||
|
||||
#include <hex.hpp>
|
||||
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
namespace hex {
|
||||
|
||||
using Patches = std::map<u64, u8>;
|
||||
|
||||
std::vector<u8> generateIPSPatch(const Patches &patches);
|
||||
std::vector<u8> generateIPS32Patch(const Patches &patches);
|
||||
|
||||
Patches loadIPSPatch(const std::vector<u8> &ipsPatch);
|
||||
Patches loadIPS32Patch(const std::vector<u8> &ipsPatch);
|
||||
}
|
||||
46
include/helpers/plugin_handler.hpp
Normal file
46
include/helpers/plugin_handler.hpp
Normal file
@@ -0,0 +1,46 @@
|
||||
#pragma once
|
||||
|
||||
#include <hex.hpp>
|
||||
|
||||
#include <hex/views/view.hpp>
|
||||
#include <hex/providers/provider.hpp>
|
||||
|
||||
#include <string_view>
|
||||
|
||||
namespace hex {
|
||||
|
||||
class Plugin {
|
||||
public:
|
||||
Plugin(std::string_view path);
|
||||
Plugin(const Plugin&) = delete;
|
||||
Plugin(Plugin &&other);
|
||||
~Plugin();
|
||||
|
||||
void initializePlugin() const;
|
||||
|
||||
private:
|
||||
using InitializePluginFunc = void(*)();
|
||||
|
||||
void *m_handle = nullptr;
|
||||
|
||||
InitializePluginFunc m_initializePluginFunction = nullptr;
|
||||
};
|
||||
|
||||
class PluginHandler {
|
||||
public:
|
||||
PluginHandler() = delete;
|
||||
|
||||
static void load(std::string_view pluginFolder);
|
||||
static void unload();
|
||||
static void reload();
|
||||
|
||||
static const auto& getPlugins() {
|
||||
return PluginHandler::s_plugins;
|
||||
}
|
||||
|
||||
private:
|
||||
static inline std::string s_pluginFolder;
|
||||
static inline std::vector<Plugin> s_plugins;
|
||||
};
|
||||
|
||||
}
|
||||
46
include/helpers/project_file_handler.hpp
Normal file
46
include/helpers/project_file_handler.hpp
Normal file
@@ -0,0 +1,46 @@
|
||||
#pragma once
|
||||
|
||||
#include <list>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
|
||||
#include "patches.hpp"
|
||||
#include <hex/api/imhex_api.hpp>
|
||||
|
||||
namespace hex {
|
||||
|
||||
class ProjectFile {
|
||||
public:
|
||||
ProjectFile() = delete;
|
||||
|
||||
static bool load(std::string_view filePath);
|
||||
static bool store(std::string_view filePath = "");
|
||||
|
||||
[[nodiscard]] static bool hasUnsavedChanges() { return ProjectFile::s_hasUnsavedChanged; }
|
||||
static void markDirty() { if (!ProjectFile::s_currProjectFilePath.empty()) ProjectFile::s_hasUnsavedChanged = true; }
|
||||
|
||||
[[nodiscard]] static std::string getProjectFilePath() { return ProjectFile::s_currProjectFilePath; }
|
||||
|
||||
[[nodiscard]] static std::string getFilePath() { return ProjectFile::s_filePath; }
|
||||
static void setFilePath(std::string_view filePath) { ProjectFile::s_hasUnsavedChanged = true; ProjectFile::s_filePath = filePath; }
|
||||
|
||||
[[nodiscard]] static std::string getPattern() { return ProjectFile::s_pattern; }
|
||||
static void setPattern(std::string_view pattern) { ProjectFile::s_hasUnsavedChanged = true; ProjectFile::s_pattern = pattern; }
|
||||
|
||||
[[nodiscard]] static const Patches& getPatches() { return ProjectFile::s_patches; }
|
||||
static void setPatches(const Patches &patches) { ProjectFile::s_hasUnsavedChanged = true; ProjectFile::s_patches = patches; }
|
||||
|
||||
[[nodiscard]] static const std::list<ImHexApi::Bookmarks::Entry>& getBookmarks() { return ProjectFile::s_bookmarks; }
|
||||
static void setBookmarks(const std::list<ImHexApi::Bookmarks::Entry> &bookmarks) { ProjectFile::s_hasUnsavedChanged = true; ProjectFile::s_bookmarks = bookmarks; }
|
||||
|
||||
private:
|
||||
static inline std::string s_currProjectFilePath;
|
||||
static inline bool s_hasUnsavedChanged = false;
|
||||
|
||||
static inline std::string s_filePath;
|
||||
static inline std::string s_pattern;
|
||||
static inline Patches s_patches;
|
||||
static inline std::list<ImHexApi::Bookmarks::Entry> s_bookmarks;
|
||||
};
|
||||
|
||||
}
|
||||
@@ -1,81 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "token.hpp"
|
||||
|
||||
#include <optional>
|
||||
#include <vector>
|
||||
|
||||
namespace hex::lang {
|
||||
|
||||
class ASTNode {
|
||||
public:
|
||||
enum class Type {
|
||||
VariableDecl,
|
||||
TypeDecl,
|
||||
Struct,
|
||||
Scope,
|
||||
};
|
||||
|
||||
explicit ASTNode(Type type) : m_type(type) {}
|
||||
virtual ~ASTNode() = default;
|
||||
|
||||
Type getType() { return this->m_type; }
|
||||
|
||||
private:
|
||||
Type m_type;
|
||||
};
|
||||
|
||||
class ASTNodeVariableDecl : public ASTNode {
|
||||
public:
|
||||
explicit ASTNodeVariableDecl(const Token::TypeToken::Type &type, const std::string &name, const std::string& customTypeName = "", std::optional<u64> offset = { }, size_t arraySize = 1)
|
||||
: ASTNode(Type::VariableDecl), m_type(type), m_name(name), m_customTypeName(customTypeName), m_offset(offset), m_arraySize(arraySize) { }
|
||||
|
||||
const Token::TypeToken::Type& getVariableType() const { return this->m_type; }
|
||||
const std::string& getCustomVariableTypeName() const { return this->m_customTypeName; }
|
||||
const std::string& getVariableName() const { return this->m_name; };
|
||||
std::optional<u64> getOffset() const { return this->m_offset; }
|
||||
size_t getArraySize() const { return this->m_arraySize; }
|
||||
|
||||
private:
|
||||
Token::TypeToken::Type m_type;
|
||||
std::string m_name, m_customTypeName;
|
||||
std::optional<u64> m_offset;
|
||||
size_t m_arraySize;
|
||||
};
|
||||
|
||||
class ASTNodeScope : public ASTNode {
|
||||
public:
|
||||
explicit ASTNodeScope(std::vector<ASTNode*> nodes) : ASTNode(Type::Scope), m_nodes(nodes) { }
|
||||
|
||||
std::vector<ASTNode*> &getNodes() { return this->m_nodes; }
|
||||
private:
|
||||
std::vector<ASTNode*> m_nodes;
|
||||
};
|
||||
|
||||
class ASTNodeStruct : public ASTNode {
|
||||
public:
|
||||
explicit ASTNodeStruct(std::string name, std::vector<ASTNode*> nodes)
|
||||
: ASTNode(Type::Struct), m_name(name), m_nodes(nodes) { }
|
||||
|
||||
const std::string& getName() const { return this->m_name; }
|
||||
std::vector<ASTNode*> &getNodes() { return this->m_nodes; }
|
||||
private:
|
||||
std::string m_name;
|
||||
std::vector<ASTNode*> m_nodes;
|
||||
};
|
||||
|
||||
class ASTNodeTypeDecl : public ASTNode {
|
||||
public:
|
||||
explicit ASTNodeTypeDecl(const Token::TypeToken::Type &type, const std::string &name, const std::string& customTypeName = "")
|
||||
: ASTNode(Type::TypeDecl), m_type(type), m_name(name), m_customTypeName(customTypeName) { }
|
||||
|
||||
const std::string& getTypeName() const { return this->m_name; };
|
||||
|
||||
const Token::TypeToken::Type& getAssignedType() const { return this->m_type; }
|
||||
const std::string& getAssignedCustomTypeName() const { return this->m_customTypeName; }
|
||||
private:
|
||||
Token::TypeToken::Type m_type;
|
||||
std::string m_name, m_customTypeName;
|
||||
};
|
||||
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <hex.hpp>
|
||||
|
||||
#include "token.hpp"
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace hex::lang {
|
||||
|
||||
class Lexer {
|
||||
public:
|
||||
Lexer();
|
||||
|
||||
std::pair<Result, std::vector<Token>> lex(const std::string& code);
|
||||
};
|
||||
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <hex.hpp>
|
||||
#include "token.hpp"
|
||||
#include "ast_node.hpp"
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace hex::lang {
|
||||
|
||||
class Parser {
|
||||
public:
|
||||
Parser();
|
||||
|
||||
std::pair<Result, std::vector<ASTNode*>> parse(const std::vector<Token> &tokens);
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace hex::lang {
|
||||
|
||||
class Result {
|
||||
public:
|
||||
constexpr Result(const std::uint8_t module, const std::uint32_t desc) noexcept : m_result((module << 24) | (desc & 0x00FFFFFF)) { }
|
||||
|
||||
constexpr std::uint32_t getResult() const noexcept { return this->m_result; }
|
||||
constexpr std::uint8_t getModule() const noexcept { return this->m_result >> 24; }
|
||||
constexpr std::uint32_t getDescription() const noexcept { return this->m_result & 0x00FFFFFF; }
|
||||
|
||||
constexpr bool succeeded() const noexcept { return this->m_result == 0; }
|
||||
constexpr bool failed() const noexcept { return !succeeded(); }
|
||||
private:
|
||||
const std::uint32_t m_result;
|
||||
};
|
||||
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "result.hpp"
|
||||
|
||||
namespace hex::lang {
|
||||
|
||||
constexpr Result ResultSuccess(0, 0);
|
||||
|
||||
constexpr Result ResultLexicalError(1, 1);
|
||||
constexpr Result ResultParseError(2, 1);
|
||||
|
||||
}
|
||||
@@ -1,61 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <hex.hpp>
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace hex::lang {
|
||||
|
||||
struct Token {
|
||||
enum class Type : u64 {
|
||||
Keyword,
|
||||
Type,
|
||||
Operator,
|
||||
Integer,
|
||||
Identifier,
|
||||
EndOfExpression,
|
||||
ScopeOpen,
|
||||
ScopeClose,
|
||||
ArrayOpen,
|
||||
ArrayClose,
|
||||
Separator,
|
||||
EndOfProgram
|
||||
} type;
|
||||
|
||||
struct KeywordToken {
|
||||
enum class Keyword {
|
||||
Struct,
|
||||
Using
|
||||
} keyword;
|
||||
} keywordToken;
|
||||
struct IdentifierToken {
|
||||
std::string identifier;
|
||||
} identifierToken;
|
||||
struct OperatorToken {
|
||||
enum class Operator {
|
||||
AtDeclaration,
|
||||
Assignment
|
||||
} op;
|
||||
} operatorToken;
|
||||
struct IntegerToken {
|
||||
s128 integer;
|
||||
} integerToken;
|
||||
struct TypeToken {
|
||||
enum class Type {
|
||||
Unsigned8Bit = 0x10,
|
||||
Signed8Bit = 0x11,
|
||||
Unsigned16Bit = 0x20,
|
||||
Signed16Bit = 0x21,
|
||||
Unsigned32Bit = 0x40,
|
||||
Signed32Bit = 0x41,
|
||||
Unsigned64Bit = 0x80,
|
||||
Signed64Bit = 0x81,
|
||||
Unsigned128Bit = 0x100,
|
||||
Signed128Bit = 0x101,
|
||||
Float = 0x42,
|
||||
Double = 0x82,
|
||||
CustomType = 0x00
|
||||
} type;
|
||||
} typeToken;
|
||||
};
|
||||
}
|
||||
@@ -1,9 +1,19 @@
|
||||
#pragma once
|
||||
|
||||
#include "providers/provider.hpp"
|
||||
#include <hex/providers/provider.hpp>
|
||||
|
||||
#include <string_view>
|
||||
|
||||
#include <sys/stat.h>
|
||||
|
||||
#if defined(OS_WINDOWS)
|
||||
#include <windows.h>
|
||||
#else
|
||||
#include <sys/mman.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/fcntl.h>
|
||||
#endif
|
||||
|
||||
namespace hex::prv {
|
||||
|
||||
class FileProvider : public Provider {
|
||||
@@ -16,11 +26,27 @@ namespace hex::prv {
|
||||
bool isWritable() override;
|
||||
|
||||
void read(u64 offset, void *buffer, size_t size) override;
|
||||
void write(u64 offset, void *buffer, size_t size) override;
|
||||
size_t getSize() override;
|
||||
void write(u64 offset, const void *buffer, size_t size) override;
|
||||
|
||||
void readRaw(u64 offset, void *buffer, size_t size) override;
|
||||
void writeRaw(u64 offset, const void *buffer, size_t size) override;
|
||||
size_t getActualSize() override;
|
||||
|
||||
std::vector<std::pair<std::string, std::string>> getDataInformation() override;
|
||||
|
||||
private:
|
||||
FILE *m_file;
|
||||
#if defined(OS_WINDOWS)
|
||||
HANDLE m_file;
|
||||
HANDLE m_mapping;
|
||||
#else
|
||||
int m_file;
|
||||
#endif
|
||||
std::string m_path;
|
||||
void *m_mappedFile;
|
||||
size_t m_fileSize;
|
||||
|
||||
bool m_fileStatsValid = false;
|
||||
struct stat m_fileStats = { 0 };
|
||||
|
||||
bool m_readable, m_writable;
|
||||
};
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <hex.hpp>
|
||||
|
||||
namespace hex::prv {
|
||||
|
||||
class Provider {
|
||||
public:
|
||||
Provider() = default;
|
||||
virtual ~Provider() = default;
|
||||
|
||||
virtual bool isAvailable() = 0;
|
||||
virtual bool isReadable() = 0;
|
||||
virtual bool isWritable() = 0;
|
||||
|
||||
virtual void read(u64 offset, void *buffer, size_t size) = 0;
|
||||
virtual void write(u64 offset, void *buffer, size_t size) = 0;
|
||||
virtual size_t getSize() = 0;
|
||||
};
|
||||
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <hex.hpp>
|
||||
|
||||
#include <array>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
|
||||
namespace hex {
|
||||
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <hex.hpp>
|
||||
#include <string>
|
||||
|
||||
namespace hex {
|
||||
|
||||
struct Highlight {
|
||||
Highlight(u64 offset, size_t size, u32 color, std::string name)
|
||||
: offset(offset), size(size), color(color), name(name) {
|
||||
|
||||
}
|
||||
|
||||
u64 offset;
|
||||
size_t size;
|
||||
u32 color;
|
||||
std::string name;
|
||||
};
|
||||
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <hex.hpp>
|
||||
|
||||
#include "imgui.h"
|
||||
|
||||
#include "event.hpp"
|
||||
|
||||
namespace hex {
|
||||
|
||||
class View {
|
||||
public:
|
||||
View() { }
|
||||
virtual ~View() { }
|
||||
|
||||
virtual void createView() = 0;
|
||||
virtual void createMenu() { }
|
||||
virtual bool handleShortcut(int key, int mods) { return false; }
|
||||
|
||||
protected:
|
||||
void subscribeEvent(Events eventType, std::function<void(void*)> callback) {
|
||||
View::s_eventManager.subscribe(eventType, this, callback);
|
||||
}
|
||||
|
||||
void unsubscribeEvent(Events eventType) {
|
||||
View::s_eventManager.unsubscribe(eventType, this);
|
||||
}
|
||||
|
||||
void postEvent(Events eventType, void *userData = nullptr) {
|
||||
View::s_eventManager.post(eventType, userData);
|
||||
}
|
||||
|
||||
private:
|
||||
static inline EventManager s_eventManager;
|
||||
};
|
||||
|
||||
}
|
||||
23
include/views/view_bookmarks.hpp
Normal file
23
include/views/view_bookmarks.hpp
Normal file
@@ -0,0 +1,23 @@
|
||||
#pragma once
|
||||
|
||||
#include <hex/views/view.hpp>
|
||||
|
||||
#include <vector>
|
||||
#include <list>
|
||||
|
||||
#include <hex/helpers/utils.hpp>
|
||||
|
||||
namespace hex {
|
||||
|
||||
namespace prv { class Provider; }
|
||||
|
||||
class ViewBookmarks : public View {
|
||||
public:
|
||||
ViewBookmarks();
|
||||
~ViewBookmarks() override;
|
||||
|
||||
void drawContent() override;
|
||||
void drawMenu() override;
|
||||
};
|
||||
|
||||
}
|
||||
62
include/views/view_command_palette.hpp
Normal file
62
include/views/view_command_palette.hpp
Normal file
@@ -0,0 +1,62 @@
|
||||
#pragma once
|
||||
|
||||
#include <hex.hpp>
|
||||
#include <hex/views/view.hpp>
|
||||
|
||||
#include <imgui.h>
|
||||
#include <hex/lang/pattern_data.hpp>
|
||||
|
||||
#include <vector>
|
||||
#include <tuple>
|
||||
#include <cstdio>
|
||||
|
||||
namespace hex {
|
||||
|
||||
namespace prv { class Provider; }
|
||||
|
||||
class ViewCommandPalette : public View {
|
||||
public:
|
||||
ViewCommandPalette();
|
||||
~ViewCommandPalette() override;
|
||||
|
||||
void drawContent() override;
|
||||
void drawMenu() override;
|
||||
bool isAvailable() override { return true; }
|
||||
bool shouldProcess() override { return true; }
|
||||
|
||||
bool handleShortcut(int key, int mods) override;
|
||||
|
||||
bool hasViewMenuItemEntry() override { return false; }
|
||||
ImVec2 getMinSize() override { return ImVec2(400, 100); }
|
||||
ImVec2 getMaxSize() override { return ImVec2(400, 100); }
|
||||
|
||||
private:
|
||||
enum class MatchType {
|
||||
NoMatch,
|
||||
InfoMatch,
|
||||
PartialMatch,
|
||||
PerfectMatch
|
||||
};
|
||||
|
||||
struct CommandResult {
|
||||
std::string displayResult;
|
||||
std::string matchedCommand;
|
||||
std::function<void(std::string)> executeCallback;
|
||||
};
|
||||
|
||||
bool m_commandPaletteOpen = false;
|
||||
bool m_justOpened = false;
|
||||
bool m_focusInputTextBox = false;
|
||||
|
||||
std::vector<char> m_commandBuffer;
|
||||
std::vector<CommandResult> m_lastResults;
|
||||
std::string m_exactResult;
|
||||
|
||||
void focusInputTextBox() {
|
||||
this->m_focusInputTextBox = true;
|
||||
}
|
||||
|
||||
std::vector<CommandResult> getCommandResults(std::string_view command);
|
||||
};
|
||||
|
||||
}
|
||||
34
include/views/view_data_inspector.hpp
Normal file
34
include/views/view_data_inspector.hpp
Normal file
@@ -0,0 +1,34 @@
|
||||
#pragma once
|
||||
|
||||
#include <hex/views/view.hpp>
|
||||
|
||||
#include <hex/api/content_registry.hpp>
|
||||
|
||||
#include <bit>
|
||||
#include <cstdio>
|
||||
#include <string>
|
||||
|
||||
namespace hex {
|
||||
|
||||
namespace prv { class Provider; }
|
||||
|
||||
class ViewDataInspector : public View {
|
||||
public:
|
||||
explicit ViewDataInspector();
|
||||
~ViewDataInspector() override;
|
||||
|
||||
void drawContent() override;
|
||||
void drawMenu() override;
|
||||
|
||||
private:
|
||||
bool m_shouldInvalidate = true;
|
||||
|
||||
std::endian m_endian = std::endian::native;
|
||||
ContentRegistry::DataInspector::NumberDisplayStyle m_numberDisplayStyle =ContentRegistry::DataInspector::NumberDisplayStyle::Decimal;
|
||||
|
||||
u64 m_startAddress = 0;
|
||||
size_t m_validBytes = 0;
|
||||
std::vector<std::pair<std::string, ContentRegistry::DataInspector::DisplayFunction>> m_cachedData;
|
||||
};
|
||||
|
||||
}
|
||||
42
include/views/view_data_processor.hpp
Normal file
42
include/views/view_data_processor.hpp
Normal file
@@ -0,0 +1,42 @@
|
||||
#pragma once
|
||||
|
||||
#include <hex.hpp>
|
||||
|
||||
#include <imgui.h>
|
||||
#include <hex/views/view.hpp>
|
||||
#include <hex/data_processor/node.hpp>
|
||||
#include <hex/data_processor/link.hpp>
|
||||
|
||||
#include <array>
|
||||
#include <string>
|
||||
|
||||
namespace hex {
|
||||
|
||||
namespace prv { class Provider; }
|
||||
|
||||
class ViewDataProcessor : public View {
|
||||
public:
|
||||
ViewDataProcessor();
|
||||
~ViewDataProcessor() override;
|
||||
|
||||
void drawContent() override;
|
||||
void drawMenu() override;
|
||||
|
||||
private:
|
||||
std::list<dp::Node*> m_endNodes;
|
||||
std::list<dp::Node*> m_nodes;
|
||||
std::list<dp::Link> m_links;
|
||||
|
||||
std::vector<prv::Overlay*> m_dataOverlays;
|
||||
|
||||
int m_rightClickedId = -1;
|
||||
ImVec2 m_rightClickedCoords;
|
||||
|
||||
std::optional<dp::Node::NodeError> m_currNodeError;
|
||||
|
||||
void eraseLink(u32 id);
|
||||
void eraseNodes(const std::vector<int> &ids);
|
||||
void processNodes();
|
||||
};
|
||||
|
||||
}
|
||||
48
include/views/view_disassembler.hpp
Normal file
48
include/views/view_disassembler.hpp
Normal file
@@ -0,0 +1,48 @@
|
||||
#pragma once
|
||||
|
||||
#include <hex/views/view.hpp>
|
||||
|
||||
#include "helpers/disassembler.hpp"
|
||||
|
||||
#include <cstdio>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace hex {
|
||||
|
||||
namespace prv { class Provider; }
|
||||
|
||||
struct Disassembly {
|
||||
u64 address;
|
||||
u64 offset;
|
||||
size_t size;
|
||||
std::string bytes;
|
||||
std::string mnemonic;
|
||||
std::string operators;
|
||||
};
|
||||
|
||||
class ViewDisassembler : public View {
|
||||
public:
|
||||
explicit ViewDisassembler();
|
||||
~ViewDisassembler() override;
|
||||
|
||||
void drawContent() override;
|
||||
void drawMenu() override;
|
||||
|
||||
private:
|
||||
bool m_shouldInvalidate = false;
|
||||
|
||||
u64 m_baseAddress = 0;
|
||||
u64 m_codeRegion[2] = { 0 };
|
||||
bool m_shouldMatchSelection = false;
|
||||
|
||||
Architecture m_architecture = Architecture::ARM;
|
||||
cs_mode m_modeBasicARM = cs_mode(0), m_modeExtraARM = cs_mode(0), m_modeBasicMIPS = cs_mode(0), m_modeBasicPPC = cs_mode(0), m_modeBasicX86 = cs_mode(0);
|
||||
bool m_littleEndianMode = true, m_micoMode = false, m_sparcV9Mode = false;
|
||||
|
||||
std::vector<Disassembly> m_disassembly;
|
||||
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include "views/view.hpp"
|
||||
#include <hex/views/view.hpp>
|
||||
|
||||
#include <cstdio>
|
||||
|
||||
@@ -10,20 +10,19 @@ namespace hex {
|
||||
|
||||
class ViewHashes : public View {
|
||||
public:
|
||||
explicit ViewHashes(prv::Provider* &dataProvider);
|
||||
explicit ViewHashes();
|
||||
~ViewHashes() override;
|
||||
|
||||
void createView() override;
|
||||
void createMenu() override;
|
||||
void drawContent() override;
|
||||
void drawMenu() override;
|
||||
|
||||
private:
|
||||
prv::Provider* &m_dataProvider;
|
||||
bool m_windowOpen = true;
|
||||
|
||||
bool m_shouldInvalidate = true;
|
||||
int m_currHashFunction = 0;
|
||||
int m_hashStart = 0, m_hashEnd = 0;
|
||||
static constexpr const char* HashFunctionNames[] = { "CRC16", "CRC32", "MD4", "MD5", "SHA-1", "SHA-224", "SHA-256", "SHA-384", "SHA-512" };
|
||||
u64 m_hashRegion[2] = { 0 };
|
||||
bool m_shouldMatchSelection = false;
|
||||
|
||||
static constexpr const char* HashFunctionNames[] = { "CRC16", "CRC32", "MD5", "SHA-1", "SHA-224", "SHA-256", "SHA-384", "SHA-512" };
|
||||
};
|
||||
|
||||
}
|
||||
42
include/views/view_help.hpp
Normal file
42
include/views/view_help.hpp
Normal file
@@ -0,0 +1,42 @@
|
||||
#pragma once
|
||||
|
||||
#include <hex.hpp>
|
||||
|
||||
#include <imgui.h>
|
||||
#include <hex/views/view.hpp>
|
||||
#include <hex/lang/pattern_data.hpp>
|
||||
|
||||
#include <vector>
|
||||
#include <tuple>
|
||||
#include <cstdio>
|
||||
|
||||
namespace hex {
|
||||
|
||||
namespace prv { class Provider; }
|
||||
|
||||
class ViewHelp : public View {
|
||||
public:
|
||||
ViewHelp();
|
||||
~ViewHelp() override;
|
||||
|
||||
void drawContent() override;
|
||||
void drawMenu() override;
|
||||
bool isAvailable() override { return true; }
|
||||
|
||||
bool hasViewMenuItemEntry() override { return false; }
|
||||
|
||||
ImVec2 getMinSize() override {
|
||||
return ImVec2(400, 300);
|
||||
}
|
||||
|
||||
private:
|
||||
bool m_aboutWindowOpen = false;
|
||||
bool m_patternHelpWindowOpen = false;
|
||||
bool m_mathHelpWindowOpen = false;
|
||||
|
||||
void drawAboutPopup();
|
||||
void drawPatternHelpPopup();
|
||||
void drawMathEvaluatorHelp();
|
||||
};
|
||||
|
||||
}
|
||||
@@ -1,47 +1,77 @@
|
||||
#pragma once
|
||||
|
||||
#include "utils.hpp"
|
||||
#include "views/view.hpp"
|
||||
#include <hex/helpers/utils.hpp>
|
||||
#include <hex/views/view.hpp>
|
||||
#include "helpers/encoding_file.hpp"
|
||||
|
||||
#include "imgui_memory_editor.h"
|
||||
#include "imfilebrowser.h"
|
||||
#include <imgui_memory_editor.h>
|
||||
#include <ImGuiFileBrowser.h>
|
||||
|
||||
#include <list>
|
||||
#include <tuple>
|
||||
#include <random>
|
||||
#include <vector>
|
||||
|
||||
#include "views/highlight.hpp"
|
||||
#include <hex/lang/pattern_data.hpp>
|
||||
|
||||
namespace hex {
|
||||
|
||||
namespace prv { class Provider; }
|
||||
|
||||
using SearchFunction = std::vector<std::pair<u64, u64>> (*)(prv::Provider* &provider, std::string string);
|
||||
|
||||
class ViewHexEditor : public View {
|
||||
public:
|
||||
ViewHexEditor(prv::Provider* &dataProvider, std::vector<Highlight> &highlights);
|
||||
ViewHexEditor(std::vector<lang::PatternData*> &patternData);
|
||||
~ViewHexEditor() override;
|
||||
|
||||
void createView() override;
|
||||
void createMenu() override;
|
||||
void drawContent() override;
|
||||
void drawAlwaysVisible() override;
|
||||
void drawMenu() override;
|
||||
bool handleShortcut(int key, int mods) override;
|
||||
|
||||
private:
|
||||
MemoryEditor m_memoryEditor;
|
||||
|
||||
ImGui::FileBrowser m_fileBrowser;
|
||||
std::vector<lang::PatternData*> &m_patternData;
|
||||
|
||||
std::map<u64, u32> m_highlightedBytes;
|
||||
|
||||
prv::Provider* &m_dataProvider;
|
||||
std::vector<Highlight> &m_highlights;
|
||||
std::vector<char> m_searchStringBuffer;
|
||||
std::vector<char> m_searchHexBuffer;
|
||||
SearchFunction m_searchFunction = nullptr;
|
||||
std::vector<std::pair<u64, u64>> *m_lastSearchBuffer;
|
||||
|
||||
char m_searchBuffer[0xFFFF] = { 0 };
|
||||
s64 m_lastSearchIndex = 0;
|
||||
std::vector<std::pair<u64, u64>> m_lastSearch;
|
||||
u64 m_gotoAddress = 0;
|
||||
std::vector<std::pair<u64, u64>> m_lastStringSearch;
|
||||
std::vector<std::pair<u64, u64>> m_lastHexSearch;
|
||||
|
||||
s64 m_gotoAddress = 0;
|
||||
|
||||
char m_baseAddressBuffer[0x20] = { 0 };
|
||||
|
||||
std::vector<u8> m_dataToSave;
|
||||
|
||||
std::string m_loaderScriptScriptPath;
|
||||
std::string m_loaderScriptFilePath;
|
||||
|
||||
hex::EncodingFile m_currEncodingFile;
|
||||
|
||||
void drawSearchPopup();
|
||||
void drawGotoPopup();
|
||||
void drawEditPopup();
|
||||
|
||||
void openFile(std::string path);
|
||||
bool saveToFile(std::string path, const std::vector<u8>& data);
|
||||
bool loadFromFile(std::string path, std::vector<u8>& data);
|
||||
|
||||
enum class Language { C, Cpp, CSharp, Rust, Python, Java, JavaScript };
|
||||
void copyBytes();
|
||||
void copyString();
|
||||
void copyLanguageArray(Language language);
|
||||
void copyHexView();
|
||||
void copyHexViewHTML();
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include "views/view.hpp"
|
||||
#include <hex/views/view.hpp>
|
||||
|
||||
#include <array>
|
||||
#include <cstdio>
|
||||
@@ -13,22 +13,23 @@ namespace hex {
|
||||
|
||||
class ViewInformation : public View {
|
||||
public:
|
||||
explicit ViewInformation(prv::Provider* &dataProvider);
|
||||
explicit ViewInformation();
|
||||
~ViewInformation() override;
|
||||
|
||||
void createView() override;
|
||||
void createMenu() override;
|
||||
void drawContent() override;
|
||||
void drawMenu() override;
|
||||
|
||||
private:
|
||||
prv::Provider* &m_dataProvider;
|
||||
bool m_windowOpen = true;
|
||||
|
||||
bool m_dataValid = false;
|
||||
u32 m_blockSize = 0;
|
||||
float m_averageEntropy = 0;
|
||||
float m_highestBlockEntropy = 0;
|
||||
std::vector<float> m_blockEntropy;
|
||||
|
||||
std::array<float, 256> m_valueCounts = { 0 };
|
||||
bool m_shouldInvalidate = true;
|
||||
bool m_shouldInvalidate = false;
|
||||
|
||||
std::pair<u64, u64> m_analyzedRegion = { 0, 0 };
|
||||
|
||||
std::string m_fileDescription;
|
||||
std::string m_mimeType;
|
||||
|
||||
26
include/views/view_patches.hpp
Normal file
26
include/views/view_patches.hpp
Normal file
@@ -0,0 +1,26 @@
|
||||
#pragma once
|
||||
|
||||
#include <hex.hpp>
|
||||
|
||||
#include <imgui.h>
|
||||
#include <hex/views/view.hpp>
|
||||
|
||||
#include <optional>
|
||||
|
||||
namespace hex {
|
||||
|
||||
namespace prv { class Provider; }
|
||||
|
||||
class ViewPatches : public View {
|
||||
public:
|
||||
explicit ViewPatches();
|
||||
~ViewPatches() override;
|
||||
|
||||
void drawContent() override;
|
||||
void drawMenu() override;
|
||||
|
||||
private:
|
||||
u64 m_selectedPatch;
|
||||
};
|
||||
|
||||
}
|
||||
@@ -1,41 +1,43 @@
|
||||
#pragma once
|
||||
|
||||
#include "parser/ast_node.hpp"
|
||||
#include "parser/parser.hpp"
|
||||
#include "parser/lexer.hpp"
|
||||
#include "views/view.hpp"
|
||||
#include <hex/views/view.hpp>
|
||||
#include <hex/lang/evaluator.hpp>
|
||||
#include <hex/lang/pattern_language.hpp>
|
||||
|
||||
#include <hex/providers/provider.hpp>
|
||||
|
||||
#include <concepts>
|
||||
#include <cstring>
|
||||
#include <filesystem>
|
||||
#include <string_view>
|
||||
#include <thread>
|
||||
#include <vector>
|
||||
|
||||
#include "views/highlight.hpp"
|
||||
|
||||
#include "imfilebrowser.h"
|
||||
#include <ImGuiFileBrowser.h>
|
||||
#include <TextEditor.h>
|
||||
|
||||
namespace hex {
|
||||
|
||||
class ViewPattern : public View {
|
||||
public:
|
||||
explicit ViewPattern(std::vector<Highlight> &highlights);
|
||||
explicit ViewPattern(std::vector<lang::PatternData*> &patternData);
|
||||
~ViewPattern() override;
|
||||
|
||||
void createMenu() override;
|
||||
void createView() override;
|
||||
void drawMenu() override;
|
||||
void drawAlwaysVisible() override;
|
||||
void drawContent() override;
|
||||
|
||||
private:
|
||||
char *m_buffer;
|
||||
lang::PatternLanguage *m_patternLanguageRuntime;
|
||||
std::vector<lang::PatternData*> &m_patternData;
|
||||
std::vector<std::string> m_possiblePatternFiles;
|
||||
int m_selectedPatternFile = 0;
|
||||
|
||||
std::vector<Highlight> &m_highlights;
|
||||
bool m_windowOpen = true;
|
||||
TextEditor m_textEditor;
|
||||
std::vector<std::pair<lang::LogConsole::Level, std::string>> m_console;
|
||||
|
||||
ImGui::FileBrowser m_fileBrowser;
|
||||
|
||||
|
||||
void setHighlight(u64 offset, size_t size, std::string name, u32 color = 0);
|
||||
void loadPatternFile(std::string_view path);
|
||||
void clearPatternData();
|
||||
void parsePattern(char *buffer);
|
||||
|
||||
s32 highlightUsingDecls(std::vector<lang::ASTNode*> &ast, lang::ASTNodeTypeDecl* currTypeDeclNode, lang::ASTNodeVariableDecl* currVarDec, u64 offset);
|
||||
s32 highlightStruct(std::vector<lang::ASTNode*> &ast, lang::ASTNodeStruct* currStructNode, u64 offset);
|
||||
};
|
||||
|
||||
}
|
||||
@@ -2,9 +2,9 @@
|
||||
|
||||
#include <hex.hpp>
|
||||
|
||||
#include "imgui.h"
|
||||
#include "views/view.hpp"
|
||||
#include "views/highlight.hpp"
|
||||
#include <imgui.h>
|
||||
#include <hex/views/view.hpp>
|
||||
#include <hex/lang/pattern_data.hpp>
|
||||
|
||||
#include <vector>
|
||||
#include <tuple>
|
||||
@@ -16,16 +16,16 @@ namespace hex {
|
||||
|
||||
class ViewPatternData : public View {
|
||||
public:
|
||||
ViewPatternData(prv::Provider* &dataProvider, std::vector<Highlight> &highlights);
|
||||
ViewPatternData(std::vector<lang::PatternData*> &patternData);
|
||||
~ViewPatternData() override;
|
||||
|
||||
void createView() override;
|
||||
void createMenu() override;
|
||||
void drawContent() override;
|
||||
void drawMenu() override;
|
||||
|
||||
private:
|
||||
prv::Provider* &m_dataProvider;
|
||||
std::vector<Highlight> &m_highlights;
|
||||
bool m_windowOpen = true;
|
||||
|
||||
std::vector<lang::PatternData*> &m_patternData;
|
||||
std::vector<lang::PatternData*> m_sortedPatternData;
|
||||
};
|
||||
|
||||
}
|
||||
22
include/views/view_settings.hpp
Normal file
22
include/views/view_settings.hpp
Normal file
@@ -0,0 +1,22 @@
|
||||
#pragma once
|
||||
|
||||
#include <hex/views/view.hpp>
|
||||
|
||||
#include <cstdio>
|
||||
#include <string>
|
||||
|
||||
namespace hex {
|
||||
|
||||
class ViewSettings : public View {
|
||||
public:
|
||||
explicit ViewSettings();
|
||||
~ViewSettings() override;
|
||||
|
||||
void drawContent() override;
|
||||
void drawMenu() override;
|
||||
bool isAvailable() override { return true; }
|
||||
|
||||
bool hasViewMenuItemEntry() override { return false; }
|
||||
};
|
||||
|
||||
}
|
||||
39
include/views/view_strings.hpp
Normal file
39
include/views/view_strings.hpp
Normal file
@@ -0,0 +1,39 @@
|
||||
#pragma once
|
||||
|
||||
#include <hex/views/view.hpp>
|
||||
|
||||
#include <cstdio>
|
||||
#include <string>
|
||||
|
||||
namespace hex {
|
||||
|
||||
namespace prv { class Provider; }
|
||||
|
||||
struct FoundString {
|
||||
std::string string;
|
||||
u64 offset;
|
||||
size_t size;
|
||||
};
|
||||
|
||||
class ViewStrings : public View {
|
||||
public:
|
||||
explicit ViewStrings();
|
||||
~ViewStrings() override;
|
||||
|
||||
void drawContent() override;
|
||||
void drawMenu() override;
|
||||
|
||||
private:
|
||||
bool m_shouldInvalidate = false;
|
||||
|
||||
std::vector<FoundString> m_foundStrings;
|
||||
int m_minimumLength = 5;
|
||||
std::vector<char> m_filter;
|
||||
|
||||
std::string m_selectedString;
|
||||
std::string m_demangledName;
|
||||
|
||||
void createStringContextMenu(const FoundString &foundString);
|
||||
};
|
||||
|
||||
}
|
||||
25
include/views/view_tools.hpp
Normal file
25
include/views/view_tools.hpp
Normal file
@@ -0,0 +1,25 @@
|
||||
#pragma once
|
||||
|
||||
#include <hex.hpp>
|
||||
|
||||
#include <imgui.h>
|
||||
#include <hex/views/view.hpp>
|
||||
|
||||
#include <array>
|
||||
#include <string>
|
||||
|
||||
namespace hex {
|
||||
|
||||
namespace prv { class Provider; }
|
||||
|
||||
class ViewTools : public View {
|
||||
public:
|
||||
ViewTools();
|
||||
~ViewTools() override;
|
||||
|
||||
void drawContent() override;
|
||||
void drawMenu() override;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user