Compare commits

...

497 Commits

Author SHA1 Message Date
WerWolv
0717d4a1b4 build: Bump version to 1.8.1 2021-05-24 19:09:53 +02:00
WerWolv
2fde4c7c98 build: Fix publisher name of windows installer 2021-05-24 19:09:32 +02:00
WerWolv
21525a7261 ui: Added ImHex directories table to about page 2021-05-23 23:35:04 +02:00
WerWolv
c760ccb5bb ui: Fixed broken header text in about popup 2021-05-23 23:07:49 +02:00
WerWolv
7cca646e3f ui/ux: Put capstone into SKIPDATA mode to always disassemble everything
If invalid data is reached, instead of stopping it will now insert a `.byte 0x00, 0x00, 0x00, 0x00` "instruction"
2021-05-23 23:04:20 +02:00
WerWolv
1aa21b8a2d ui: Display correct offsets in hex editor header when base address is not aligned 2021-05-23 22:52:09 +02:00
WerWolv
143cdbd44b ux: Update region setting after ticking "Match Selection" checkbox 2021-05-23 22:46:33 +02:00
Matthias Mailänder
e688d34587 build: Fix yara system lib detection and add support for fmt and curl (#241)
* find yara with pkgconfig

* Use system fmt and curl.

* Flip/unify system library conditional
2021-05-23 14:16:38 +02:00
Matthias Mailänder
db5402dc09 build: Use system libraries if so desired. (#210)
Co-authored-by: WerWolv <werwolv98@gmail.com>
2021-05-23 12:16:14 +02:00
WerWolv
fe977f4ba9 ui: Improve confusing "Quit application" popup text
This fixes #234
2021-05-21 23:59:28 +02:00
WerWolv
4ccd963037 ui: Properly display git info in help menu in release builds again
This fixes #233
2021-05-21 23:53:16 +02:00
WerWolv
b1c597e662 fix: ImHex crashing when default folders couldn't get created
This fixes #238
2021-05-21 23:46:36 +02:00
WerWolv
16a0fe4281 build: Bump version to 1.8.0 2021-05-18 21:25:59 +02:00
WerWolv
fee176dc72 nodes: Added data size node 2021-05-18 21:24:33 +02:00
WerWolv
b6f76ad8ed ux: Fixed MIME-based pattern loading popup not working properly
Fixed issues addressed in #225
2021-05-18 18:27:36 +02:00
WerWolv
0d11f4460f nodes: Allow data processor content to be stored in project files 2021-05-18 18:06:47 +02:00
WerWolv
ee2b412a10 nodes: Added primitive saving and loading mechanism
Not fully integrated yet. Also doesn't yet save any node settings, just nodes and links
2021-05-17 23:17:58 +02:00
WerWolv
cf67adfa42 patterns: Added $ to keyword highlight list 2021-05-17 23:17:00 +02:00
WerWolv
4029c333ed patterns: Added UTF-16 character type and string parsing 2021-05-02 20:13:37 +02:00
WerWolv
0c6bd73996 fix: After a init task failure, future tasks didn't run at all 2021-04-22 00:20:16 +02:00
WerWolv
d91abb5eba build: No more liblibyara 2021-04-21 23:38:37 +02:00
WerWolv
d177d69724 fix: ImHex no longer behaves weirdly or crashes when no plugins are loaded 2021-04-21 23:31:51 +02:00
WerWolv
64e35886b7 fix: Possibly fix crashes on macos 2021-04-21 20:06:48 +02:00
WerWolv
7f75f814e3 ui: Added some more icons in various places 2021-04-21 19:27:05 +02:00
WerWolv
6527c942c2 ui: Fixed FPS display not being visible 2021-04-21 19:26:50 +02:00
WerWolv
ea71389982 fix: Invalid type in integer literal ast node on mac 2021-04-21 10:37:14 +02:00
WerWolv
32d47456de patterns: Added array index syntax to rvalues and turned addressof/sizeof into operators 2021-04-21 10:17:42 +02:00
WerWolv
407c13fcce build: Updated MacOS icon 2021-04-20 22:39:52 +02:00
WerWolv
39b935affe build: Fix tons of useless build artifacts to be included on install 2021-04-20 22:11:50 +02:00
WerWolv
1f2fe6b93d sys: Merge splash screen and ImHex into one application
This fixes so many issues the previous implementation had, especially on Unix
2021-04-20 21:46:48 +02:00
WerWolv
d7811e2c55 sys: Inverted logic in imhex args checking 2021-04-18 20:27:16 +02:00
WerWolv
5b692067d8 patterns/fix: Accessing variables in global scope no longer crashes 2021-04-18 20:26:23 +02:00
WerWolv
ebbbcafe5c sys: Implement more functionality into splash screen (#223)
* build: Add libcurl

* build: Stop the whole static linking on Windows mess. There's no use anymore

* sys: Added update detector and moved some startup tasks to splash screen

* sys: Updated ImHex icon

* fix: Settings button on welcome page once again works

* build: Fix build on Linux

* sys: Fixed splash window not searching all paths for resources
2021-04-18 20:24:42 +02:00
WerWolv
6fb6de6b64 sys: Updated libfmt, yara and nativefiledialogs 2021-04-17 16:35:57 +02:00
WerWolv
24c7f1d5b7 ui: Added really fancy splash screen (updater in the future) 2021-04-17 15:46:26 +02:00
WerWolv
93e1c4c4e8 sys: Drastically revamp the relative vs absolute address mess 2021-04-16 21:50:15 +02:00
WerWolv
72eac9f149 ux: Fixed goto to work with base addresses and added absolute goto 2021-04-16 19:44:52 +02:00
WerWolv
fddb790c70 fix: Pasting values properly works now 2021-04-16 19:44:22 +02:00
WerWolv
771bb22962 sys: Improve shortcut api 2021-04-16 19:43:54 +02:00
WerWolv
59dd372ec8 ux: Added support for pasting bytes 2021-04-16 17:01:01 +02:00
WerWolv
a3b3eeb56a ui: Improve how pointers are displayed in pattern data view 2021-04-16 15:59:13 +02:00
WerWolv
7795872be1 ux: Fix jumping to addresses when base address is not 0x00 2021-04-16 13:24:34 +02:00
WerWolv
c3e41710c7 patterns: Properly apply base addresses to pointers 2021-04-16 10:11:10 +02:00
WerWolv
386ae7d8c3 fix: Using pointers no longer crashes ImHex 2021-04-15 15:56:39 +02:00
WerWolv
2e338ebc01 fix: Properly localize Undo and Redo 2021-04-14 09:03:41 +02:00
WerWolv
8314b147d5 patterns: Fix sign extension for signed types.
Fixes #216
2021-04-13 22:30:57 +02:00
WerWolv
cab3410d23 patterns: Fix members getting added multiple times 2021-04-13 22:08:02 +02:00
WerWolv
45b00c8b5f patterns: Make placements respect set base addresses and discard out of bounds variables 2021-04-13 21:50:24 +02:00
WerWolv
183b8770bb patterns: Added base_address pragma 2021-04-13 21:49:31 +02:00
WerWolv
950598911c patterns: Allow usage of types within itself and used out-of-order 2021-04-13 20:40:21 +02:00
WerWolv
8a485575f5 ui: Added recent files to File menu 2021-04-13 08:41:59 +02:00
WerWolv
1e6b493b41 ux: Add slider to entropy plot 2021-04-12 22:20:05 +02:00
WerWolv
959988a670 fix: Stop all views from opening automatically on launch 2021-04-12 21:08:36 +02:00
WerWolv
907f25c231 patterns: Added parent keyword to access members of the parent struct 2021-04-12 20:49:37 +02:00
WerWolv
2d7dd36b0d build: Improve linking and fix resource strings on windows 2021-04-12 20:36:16 +02:00
ThisALV
0168a3b741 Fix: ignore non-existent magic directories (#215) 2021-04-03 17:08:16 +02:00
WerWolv
2f19ff768d sys: Improved ScopeGuard syntax a lot 2021-03-31 22:54:43 +02:00
WerWolv
a2c80e3fd6 patterns: Fixed enum constant literals not being interpreted as correct type 2021-03-31 22:10:06 +02:00
WerWolv
356273d71e bug: Fix binary value in base converter being shifted by one
Fixes #212
2021-03-30 18:38:28 +02:00
WerWolv
6223b26888 ui: Added hex editor highlight opacity setting 2021-03-29 23:07:18 +02:00
WerWolv
147aefc7e5 ux: Add close file button to file menu 2021-03-29 22:44:35 +02:00
WerWolv
0cc7004d0d ux: Show currently loaded file name in window name 2021-03-29 22:44:23 +02:00
WerWolv
f263685e44 bug: Fix loading of bookmark name and comment from project file
Fixes #211
2021-03-27 22:54:26 +01:00
WerWolv
a17bc43d80 lang: Improved Italian translation 2021-03-27 19:13:46 +01:00
WerWolv
d805d976a6 sys: Replace the terrible event manager with a much better one 2021-03-27 11:36:36 +01:00
WerWolv
688ca01b1b ux: Added undo and redo option 2021-03-26 21:43:24 +01:00
WerWolv
42461c467f ux: Properly use current key layout for shortcuts 2021-03-26 21:40:35 +01:00
WerWolv
2c3a6d38ab nodes: Properly reset data overlays when errors occurred 2021-03-21 14:52:21 +01:00
WerWolv
ce22028781 imgui: Fix floating windows creating their own task bar items 2021-03-21 14:51:21 +01:00
WerWolv
2a7b698a3d prv: Make data overlays work everywhere, not just in the hex editor view 2021-03-21 14:50:47 +01:00
WerWolv
ef747cc4c0 sys: Explicitly delete views so destructors get called properly 2021-03-16 22:44:37 +01:00
WerWolv
b7dd936dae patterns: Fixed ternaries not being proper numeric expressions 2021-03-16 21:29:14 +01:00
WerWolv
f34b946ea9 patterns: Fixed eval_depth default and preprocessor errors 2021-03-15 08:11:19 +01:00
WerWolv
2326e090af sys: Properly delete data provider on exit 2021-03-09 19:32:04 +01:00
Robin Lambertz
f2f6dd2219 docs: Fix path to plugins in readme. (#199)
Typing is hard.
2021-03-08 16:09:33 +01:00
WerWolv
ee10322603 nodes: Added buffer combine, slice and repeat nodes 2021-03-07 13:44:22 +01:00
WerWolv
af444999bf ui: Added used memory footer item on Windows 2021-03-07 13:20:55 +01:00
WerWolv
8423f78586 nodes/patterns: Fixed crashes when recursion occurred 2021-03-07 13:20:33 +01:00
WerWolv
d4265f16eb node: Added arithmetic nodes (add, sub, mul, div, mod) 2021-03-06 14:46:47 +01:00
WerWolv
cadd4e5c2b sys: Lower down FPS to 5 when ImHex loses focus
#189
2021-03-06 13:36:20 +01:00
WerWolv
6cba868e20 sys: Added FPS limit, some power saving
#189
2021-03-06 13:09:20 +01:00
Robin Lambertz
4f98149fa7 api: Fix various crashes on bad settings data. (#186)
getSetting now returns a straight nlohmann::json instead of an optional.
If the data isn't present, it will return a json null.

All accesses to the settings will first check that the data has the
expected type.
2021-03-06 12:40:29 +01:00
tomGER
32cfaac1e2 lang: Small corrections to de_DE (#193)
* Small corrections to German translation

* Change wording of match_selection
2021-03-04 16:22:18 +01:00
Crusty ★
d954d9280f lang: Added Italian translation (#196)
* Added Italian (IT) translation

* Address fixes

* fix missing file in CMakeList
2021-03-04 13:52:35 +01:00
WerWolv
0ad0a91fa4 build: Use libfmt as header-only library instead 2021-03-03 23:33:44 +01:00
WerWolv
c18cb9f61e build: Compile libfmt with -fPIC 2021-03-03 22:51:09 +01:00
WerWolv
4a908a314f lang: Added German translation, improved language handling 2021-03-03 22:26:17 +01:00
WerWolv
188723e888 sys: Replace printf formatting with libfmt 2021-03-03 19:58:22 +01:00
WerWolv
4e86d874a7 sys: Fixed one missed api call update on non-windows 2021-03-02 23:15:15 +01:00
WerWolv
8646fb4487 patterns: Prevent division by zero 2021-03-02 22:55:23 +01:00
WerWolv
a91afdb6ae ux: Allow copying value from data inspector 2021-03-02 22:09:38 +01:00
Henry Wang
6e71d5aa31 docs: Update deps in README (#191)
This change is to reflect the commit made in 785ecb8a78, which changes openssl libcrypto to libmbedtls, making changes everywhere except in the README documentation.
2021-03-02 21:36:54 +01:00
WerWolv
b5912c59cc sys: Last one 2021-03-02 16:45:39 +01:00
WerWolv
a9635bb78a sys: Missed one 2021-03-02 14:36:29 +01:00
WerWolv
9481c70ecd sys: ImU64 is not 64 bit everywhere... 2021-03-02 14:32:18 +01:00
WerWolv
b6939654b3 lang: Fix color attribute not being applied to array entries 2021-03-02 14:23:06 +01:00
WerWolv
c84ac0bc10 sys: Fix compile on Unix 2021-03-02 14:22:47 +01:00
WerWolv
3a7a3a6e9c lang: Add dataSize function to get size of loaded data 2021-03-02 13:55:43 +01:00
WerWolv
de327cf3a4 ui: Make use of ImPlot to drastically improve information view 2021-03-02 13:49:45 +01:00
WerWolv
2e4eaf8d33 ux: Fixed region selection only selecting one byte 2021-03-02 13:49:23 +01:00
WerWolv
f0b392575f ui: Added ImPlot library 2021-03-02 13:48:23 +01:00
WerWolv
f1c03f8b1d sys: Place config files in AppData/Local/imhex folder on Windows
Fixes #182
2021-03-02 10:20:29 +01:00
WerWolv
8760fb39cb build: Fixed libs not being built in correct directory 2021-03-02 10:19:37 +01:00
Mary
1e17aa7431 Add missing pkg-config in Brewfile 2021-03-01 23:18:17 +01:00
Robin Lambertz
293fc17aa6 events: Fix passing path through argv (#187) 2021-03-01 20:45:13 +01:00
Robin Lambertz
2eb83b0035 docs: Fix new linux file locations in README (#185) 2021-03-01 10:40:05 +01:00
WerWolv
7a2b3397a3 repo: Cleanup 2021-03-01 09:03:13 +01:00
WerWolv
7838d420d8 ui/ux: Updated dependencies list, make them hyperlinks 2021-03-01 08:59:29 +01:00
WerWolv
3e6865ffa9 sys/build: Properly support per-system metadata file paths (#181)
* sys: Move away from metadata paths next to executable in the application

Build system doesn't properly install / pack stuff yet

* build: Updated README to contain better install instructions

* sys: Search for imhex resource files in ~/Application Support

* sys: MAX_PATH -> PATH_MAX

* sys: Seach for imhex resource files in Application Support using NSFileManager (#180)

* sys: Allow for multiple file search paths

Also use install prefix instead of just /usr on Linux

* build: Fixed IMHEX_INSTALL_PREFIX macro definition

* build: Fix duplicate switch entry on Linux

* docs: Updated readme to properly reflect new paths and dependencies

* sys: Install files in their proper paths on linux (#183)

* Install files in their proper paths on linux

* Only create user directories

* Follow the XDG specification on linux

XDG specification specifies how to find config and data directories on
linux systems. Specifically, it says this:

- Data should be written to $XDG_DATA_HOME
- Config should be written to $XDG_CONFIG_HOME
- Data should be read from $XDG_DATA_HOME:$XDG_DATA_DIRS
- Config should be read from $XDG_CONFIG_HOME:$XDG_CONFIG_DIRS

The default values are this:

- XDG_DATA_HOME: $HOME/.local/share
- XDG_CONFIG_HOME: $HOME/.config
- XDG_DATA_DIRS: /usr/share:/usr/local/share
- XDG_CONFIG_DIRS: /etc/xdg

Platforms with non-standard filesystems (like NixOS) will correctly set
up those environment variables, allowing softwares to work unmodified.

In order to make integration as simple as possible, we use a simple
header-only dependency called XDGPP which does all the hard work for us
to find the default directories.

* Look for plugins in all Plugin Paths

If the plugin folder was missing from one of the PluginPaths, we would
immediately stop loading plugins. We now keep looking even if one of the
path is missing.

Co-authored-by: Nichole Mattera <me@nicholemattera.com>
Co-authored-by: Robin Lambertz <unfiltered@roblab.la>
2021-03-01 08:56:49 +01:00
WerWolv
c26bea06d6 github: Split msys2 install and dependency install 2021-02-28 16:05:05 +01:00
WerWolv
f2cd60e7b2 github: Properly run msys2 deps script 2021-02-28 15:34:44 +01:00
WerWolv
903a4a9222 github: Fixed CI script syntax 2021-02-28 15:26:37 +01:00
WerWolv
06e0bb19a3 github: Use dependency install scripts in CI 2021-02-28 15:24:02 +01:00
WerWolv
e6dc731921 build: Fixed libyara building on MacOS 2021-02-26 17:29:57 +01:00
luzpaz
61cf13edf8 Fix typos in README (#176) 2021-02-26 13:35:48 +01:00
WerWolv
31e5ec7bc3 Add Yara rule matching interface (#178)
* build: Added YARA as submodule

* ui: Added basic yara rules matching interface

* build: Make libyara link libpthread on Unix

* ui: Add jump-to feature to yara matches list

* yara: Add more modules and patch yara to support mbedtls crypto

* yara: Started to fix scanning of bigger data

* yara: Fixed implementation

* ui: Improved yara matcher interface and added localization

* build: Ignore changed files in yara submodule

* yara: Fixed rules matching agianst entire file

* yara: Properly handle compiler errors
2021-02-26 13:35:19 +01:00
@xAndy
372981920e Don't dlclose nullptrs in plugins (#179)
* dont dlclose nullptrs in plugins

this fixes a segmentation fault at startup when dlclose is called with a nullptr

* Style fixes

Co-authored-by: WerWolv <werwolv98@gmail.com>
2021-02-26 12:49:33 +01:00
WerWolv
4c9459def3 ui: Various ui improvements 2021-02-25 21:51:12 +01:00
WerWolv
26b881e4c9 imgui: Fixed fontawesome 2021-02-25 21:50:57 +01:00
WerWolv
93802f5872 patterns: Always interpret color attribute value as hexadecimal 2021-02-25 12:08:46 +01:00
WerWolv
205d88cd23 ui: Added custom theme colors, improved look of description button 2021-02-25 00:17:41 +01:00
WerWolv
02a63639da ui: Add font awesome icons font 2021-02-24 22:42:26 +01:00
WerWolv
4a1de5d1cb bookmarks: Added ability to lock bookmarks 2021-02-24 21:42:18 +01:00
WerWolv
209d33ca57 ui: Fixed bookmark name and comment not accepting changes 2021-02-24 21:24:43 +01:00
WerWolv
e854e42bd7 github: Checkout all submodules 2021-02-24 21:04:00 +01:00
WerWolv
b25cc17ac9 build: Add libgtk+ to build dependencies 2021-02-24 20:59:22 +01:00
WerWolv
0af8b8155f ui/ux: Give up on custom ImGui file browsers and just use the system one 2021-02-22 23:36:13 +01:00
WerWolv
7f97416e6e ui/ux: Improve data analyzer interface, make it run asynchronously 2021-02-22 13:08:06 +01:00
WerWolv
3cbbfb1782 lang: Localize provider data information strings 2021-02-22 13:07:25 +01:00
WerWolv
ced9706c5b ui: Turned spinner into ImGui widget 2021-02-22 13:06:53 +01:00
WerWolv
7f21cdffa2 build: Fix linking on Unix platforms 2021-02-22 12:29:16 +01:00
WerWolv
0e2add204b ux: Disassemble asynchronously 2021-02-22 11:56:33 +01:00
WerWolv
490c7e8fec ux: Search for strings asynchronously 2021-02-22 10:16:58 +01:00
WerWolv
a4b4360df6 patterns: Fixed more memory leaks 2021-02-22 10:01:58 +01:00
WerWolv
0a29f25330 ui: Open all views and create default layout on first launch 2021-02-21 13:49:03 +01:00
WerWolv
5532a0673f ui: Localized new strings 2021-02-20 22:41:17 +01:00
WerWolv
9b9c040d2d ui: Run pattern language runtime asynchronously, added compile button 2021-02-20 22:38:31 +01:00
WerWolv
305b4d0ac0 build: Don't build and include example plugin by default 2021-02-19 17:37:02 +01:00
WerWolv
615a96f9d8 api: Improved documentation 2021-02-19 17:36:10 +01:00
WerWolv
0da508594b ui/api: Added loaded plugin information to welcome screen 2021-02-19 13:22:12 +01:00
WerWolv
89643d1538 lang: Added some strings that went missing 2021-02-19 11:16:09 +01:00
WerWolv
9900a51757 patterns: Fixed multiple severe memory leaks
#163 - probably not all yet
2021-02-19 10:51:30 +01:00
WerWolv
e6a08b9c18 Bump version to 1.7.0 2021-02-18 17:11:50 +01:00
WerWolv
e8027293bf Disabled multi viewports support on Linux as it didn't work well
Also cleanup and fixing a typo
2021-02-18 17:10:56 +01:00
WerWolv
0e00555703 Added Footer and API for it and the welcome screen 2021-02-18 12:09:19 +01:00
WerWolv
a251c7325a Fixed copy-paste error in pattern language evaluator 2021-02-17 21:04:59 +01:00
WerWolv
e5d664bc07 Fixed bookmark creation in huge files 2021-02-17 14:57:32 +01:00
WerWolv
460d5a9386 Various fixes and improvements 2021-02-17 14:47:25 +01:00
WerWolv
df06dd49c5 Added better settings API that handles errors better
This fixes #161
2021-02-16 23:42:35 +01:00
WerWolv
096bdef25a Fix cmake trying to remove patch version of python even if there was none
This fixes #159
2021-02-15 12:44:38 +01:00
WerWolv
5286a2d9ae Added some safety checks to thingy file parser 2021-02-14 12:32:48 +01:00
WerWolv
714b62049c Improved thingy file parsing 2021-02-14 12:05:58 +01:00
WerWolv
1eb6f781b3 Added support for displaying non-ASCII characters in decoder view
This requires the user to provide a font that supports these characters as well (for example unifont). The default ImGui font does not have them.
2021-02-14 11:51:05 +01:00
WerWolv
b4c2f7d371 Implemented crude support for custom encodings via thingy files
Relevant issue: #26
2021-02-14 01:11:55 +01:00
WerWolv
424bba71f7 Fixed localization issues when using the content registry 2021-02-13 15:15:32 +01:00
WerWolv
36a4930b35 Implement localization all throughout ImHex
English only for now, additional languages will come in the future
2021-02-11 23:09:45 +01:00
WerWolv
9227fba474 Revamped language system right away again to allow plugins to use it 2021-02-11 00:35:30 +01:00
WerWolv
4a8e59a95b Fixed multiple definitions of _lang user defined literal 2021-02-10 23:38:51 +01:00
WerWolv
bd5da4a36e Added Language setting and localization wrapper 2021-02-10 18:17:09 +01:00
WerWolv
a926b7b912 Added buffer constant node 2021-02-08 23:17:30 +01:00
WerWolv
179e222919 Fixed command palette and added /web command 2021-02-08 19:56:04 +01:00
WerWolv
1b98afe37d Fix mbedtls finding on macos (#156) 2021-02-07 22:57:34 +01:00
WerWolv
cfb4b5bd51 I wish I was good at C++ (Properly fix plugin system) 2021-02-07 14:57:13 +01:00
WerWolv
8e7bfb7f1a Fixed some popups not appearing when no views are open 2021-02-07 14:29:13 +01:00
WerWolv
15bcf71aaf Removed debug prints 2021-02-07 14:28:53 +01:00
WerWolv
5b38c43b7e Fixed plugin loading and closing issues mainly on Windows
This fixes #87
2021-02-07 13:40:47 +01:00
WerWolv
4d7d449cea Added base converter to tools window 2021-02-05 00:17:56 +01:00
WerWolv
ac100936c7 Added comments node 2021-02-04 12:46:38 +01:00
WerWolv
5eb289f1fe Added proper error messages to data processor 2021-02-04 01:14:05 +01:00
WerWolv
fe7ae9450b Clear node and link selection in data processor when right clicking 2021-02-04 00:22:14 +01:00
WerWolv
91d05c5de6 Added AES decryption node 2021-02-04 00:21:53 +01:00
WerWolv
ac019a7d7e Fixed build on Unix, move crypto wrapper to libimhex 2021-02-03 11:54:41 +01:00
WerWolv
8c306a5d3d Make views get auto deleted 2021-02-03 00:56:33 +01:00
WerWolv
785ecb8a78 Switch from openssl/libcrypto to mbedtls 2021-02-02 23:11:23 +01:00
WerWolv
fa352b6917 Fixed linker warnings on plugins 2021-02-02 00:39:47 +01:00
WerWolv
29f50bb70b Fixed search selection and hex editor shortcuts 2021-02-02 00:39:35 +01:00
WerWolv
83bbde8d29 Fixed multiple memory leaks 2021-02-01 20:07:57 +01:00
WerWolv
d69eee55dd Added recent files selection to Welcome screen 2021-02-01 19:03:45 +01:00
WerWolv
d9ec628333 Allow reading and writing settings through code 2021-02-01 19:03:28 +01:00
WerWolv
16a1ae3010 Properly pack all dependencies into nightlies on all platforms (#153)
* Properly bundle all files in linux install step

* Run make install on linux build

* Use correct default magic database

* Set default magic db permissions correctly

* Fixed magic file detection issues

* Don't install default magic file if none was found

* Try fix windows packing issues
2021-02-01 17:26:05 +01:00
WerWolv
8603ec1c99 Fixed 64 bit value display in data inspector once again 2021-02-01 01:12:23 +01:00
WerWolv
0a3cfe001d Properly added back console window on Windows debug builds 2021-01-31 22:05:06 +01:00
WerWolv
ee8e1996d9 Allow reading of empty buffers passed to a node as input 2021-01-31 21:49:13 +01:00
WerWolv
0ab565ab02 Properly set the build directory of all plugins and libimhex 2021-01-31 21:48:36 +01:00
WerWolv
744b9f574c Fixed node links not connecting properly anymore 2021-01-31 18:59:47 +01:00
WerWolv
f259e347aa Greatly improved Nodes API 2021-01-31 16:11:25 +01:00
WerWolv
b330829f09 Allow detaching of links by dragging 2021-01-31 11:00:35 +01:00
WerWolv
5a59bc2abc Added casting and control flow nodes to data processor 2021-01-31 01:42:29 +01:00
WerWolv
8dd76a6cc8 Added error messages for file opening issues 2021-01-31 00:05:07 +01:00
WerWolv
b4cbfa02cf Added latest release link to welcome screen 2021-01-31 00:04:33 +01:00
WerWolv
073eee8fab Further improved UI/UX of welcome screen 2021-01-30 23:02:03 +01:00
WerWolv
5c7a529fa1 Added Data Processor using Nodes (#152)
* Added imnodes

* Added basic data processor view. Still needs to be cleaned up

* Make sure all attached links get properly removed when a Node is deleted

* Cleanup and API exposing

* Added data provider overlays and integrate them with the data processor

* Optimized data processing

* Node UI enhancements

* Added support for all themes to the nodes editor

* Improved data processor context menus

* Fixed data processor context menu showing up everywhere

* Make hex editor context menu behave the same as data processor one

* Add different node pin types and prevent incompatible ones from being connected

* Don't require explicitly marking node as end node

* Fixed plugin copying

* Added some more nodes
2021-01-30 22:39:06 +01:00
WerWolv
3bd01c0d98 Updated OpenGL3 imgui backend to once again support multi-viewports 2021-01-30 18:01:23 +01:00
WerWolv
a3d71b1dca Added support for Home, End, PageUp and PageDown in hex view
Resolves #148
2021-01-28 13:23:50 +01:00
WerWolv
319068eef5 Implemented Open File and Preferences button in Welcome screen 2021-01-27 14:26:24 +01:00
WerWolv
bc6d33e4fb Fleshed out welcome screen 2021-01-27 12:04:42 +01:00
WerWolv
004d99fc3a Get rid of leftovers 2021-01-27 08:50:50 +01:00
WerWolv
49b5deb9f4 Added back missing semicolons... 2021-01-27 01:11:14 +01:00
WerWolv
47ca69b80e Added very basic Welcome screen 2021-01-27 01:10:13 +01:00
WerWolv
8990fad85a Make File Dialogs less hacky 2021-01-27 00:44:10 +01:00
WerWolv
ab2458bdf4 Make links in About page actual hyperlinks 2021-01-27 00:00:20 +01:00
WerWolv
97f15c04b4 Merge branch 'ci_fixing' 2021-01-25 15:49:52 +01:00
WerWolv
a1b937b1fb Included direct link to nightlies in readme and removed old macOS note 2021-01-25 15:49:20 +01:00
WerWolv
896c13a612 Fixed magic include dirs not defined on mac 2021-01-25 15:27:33 +01:00
WerWolv
27e5f8eeb6 Fixed capstone build issue on mac
On mac, capstone's include path is `include/capstone` instead of just `include`...
2021-01-25 15:19:56 +01:00
WerWolv
362f8acb15 Reenabled mac CI and trying to debug the capstone issue 2021-01-25 15:09:30 +01:00
WerWolv
b58bc685e1 Extra formatting check in hex::format 2021-01-25 13:36:29 +01:00
WerWolv
9ff92aeb40 Add hacky way to get console output back on windows 2021-01-25 13:36:29 +01:00
WerWolv
0b52092eda Properly compile magicdbs again 2021-01-25 13:36:29 +01:00
James Wah
0300d77fdb Add a Gentoo ebuild for app-editors/ImHex (#82) 2021-01-24 14:33:12 +01:00
WerWolv
4839558429 Properly define IMHEX_VERSION when using RelWithDebInfo and MinSizeRel build type 2021-01-23 18:24:06 +01:00
WerWolv
b8e383368d Make pattern popup when loading a file list all available patterns 2021-01-23 14:01:23 +01:00
WerWolv
51d9d37d1a Fixed pattern language being basically completely broken 2021-01-23 14:00:09 +01:00
WerWolv
8e46751e98 Improved about page 2021-01-23 00:46:50 +01:00
WerWolv
b0b9ce0cf8 Added back module path definition 2021-01-22 23:33:13 +01:00
WerWolv
09d3ecde2a Massively cleaned up cmake script 2021-01-22 23:27:01 +01:00
WerWolv
8ed03051c3 Properly statically link libwinpthread and cleanup plugins cmake files 2021-01-22 22:44:45 +01:00
WerWolv
104000fbc4 Huge refactoring of builtin features into an external plugin 2021-01-22 18:01:42 +01:00
WerWolv
9bc569bf9a Temporarily disable mac CI until it's fixed
I'm sick of getting an email on every single commit
2021-01-22 08:25:43 +01:00
WerWolv
7f4cc6e5c0 Updated ImGui to 1.80
It works. It just works. Updating anything else usually takes hours and ImGui took literally 2 minutes. ocornut is amazing
2021-01-21 23:09:43 +01:00
WerWolv
0aacf1d07f Fixed 128 bit byte swapping 2021-01-21 22:55:04 +01:00
WerWolv
b6e2bbc434 Added comments attribute 2021-01-21 20:55:10 +01:00
WerWolv
9a97c6c328 Use big endian rgb8 color for color attribute 2021-01-21 18:01:52 +01:00
WerWolv
e04511269a Fixed one compile issue on macos 2021-01-21 17:49:46 +01:00
WerWolv
ff566aa51f Added attributes syntax to pattern language
This comes with two experimental attributes for variables called `name` and `color`
2021-01-21 17:49:30 +01:00
WerWolv
3e3a5273c0 Don't allow navigation when the pattern editor is focused 2021-01-21 17:48:24 +01:00
WerWolv
367356f7f5 Fixed compiling with PKGBUILD 2021-01-21 15:31:40 +01:00
WerWolv
f4dd79ab43 Fixed link errors in libimhex 2021-01-21 15:12:53 +01:00
Cam Sinclair
f9fa58a6ea Enable ImGui keyboard navigation (#138) 2021-01-21 15:02:49 +01:00
WerWolv
9c055ea1fd Allow printing of 128 bit values 2021-01-21 14:53:44 +01:00
WerWolv
046a5866bf Added alignTo builtin function
Resolves #143
2021-01-21 12:10:49 +01:00
WerWolv
22d75ed856 Improved logging and aborting from pattern language builtin functions 2021-01-21 11:36:58 +01:00
WerWolv
a641f27b7e Improved events API 2021-01-21 10:53:12 +01:00
WerWolv
f0ab13ebc3 Added "dollar operator" to get the current offset 2021-01-20 22:56:31 +01:00
WerWolv
31426a289c Added modulus operator 2021-01-20 22:55:57 +01:00
WerWolv
78a87baa94 Added addressof, sizeof and nextAfter builtin functions.
Resolves #144
2021-01-20 22:54:46 +01:00
WerWolv
b2648afc7b Improve bookmark API 2021-01-20 20:16:24 +01:00
WerWolv
be738eb5e7 Improved byte highlighting 2021-01-20 18:10:40 +01:00
WerWolv
740619529c Allow most modal popups to be closed with escape 2021-01-14 17:01:44 +01:00
WerWolv
441f4a9fc7 Removed more static inline variables in headers to avoid duplication 2021-01-13 23:08:41 +01:00
WerWolv
cd200b978b Properly set the initial bookmark name 2021-01-13 22:53:33 +01:00
WerWolv
0a8368d639 Close base address popup when clicking Set 2021-01-13 22:53:21 +01:00
WerWolv
9ade281a92 Use hex::derived_from for compatibility with macos 2021-01-13 17:41:16 +01:00
WerWolv
eb066b3539 Refactored libimhex to and includes to better represent it as library 2021-01-13 17:28:27 +01:00
WerWolv
00648c9673 Move msys2 folder to dist folder 2021-01-13 16:57:44 +01:00
WerWolv
c7d179d68e Use the ID stack the way it was meant to be used 2021-01-13 16:55:42 +01:00
WerWolv
c1ad816211 Added hover tooltip for bookmarks in hex editor 2021-01-13 16:45:31 +01:00
WerWolv
4328a335ec Added color picker for Bookmarks and highlighting in the hex view 2021-01-13 14:11:23 +01:00
WerWolv
d3e47245d6 Improved memory region highlighting through selection 2021-01-13 14:11:02 +01:00
WerWolv
0e32dd667d Made tools registry more in-line with the other APIs 2021-01-13 13:18:03 +01:00
WerWolv
95437b2afe Trying to get mac to build again 2021-01-13 12:24:29 +01:00
WerWolv
d15307a237 Added data inspector to content registry 2021-01-13 01:24:27 +01:00
WerWolv
ac76e47b94 No more liblib 2021-01-12 23:49:51 +01:00
WerWolv
df50f1934e Fixed display of most signed integers in the data inspector 2021-01-12 23:39:31 +01:00
WerWolv
dc85616549 Hopefully fixed the whole plugin mess I started 2021-01-12 23:28:41 +01:00
WerWolv
8ae15abb85 Fixed plugin unloading segfault 2021-01-12 16:56:14 +01:00
WerWolv
84a6fff034 Refactored plugin system 2021-01-12 16:50:15 +01:00
WerWolv
c09a8bca7f Language refactoring, added builtin function registry 2021-01-11 23:54:12 +01:00
WerWolv
90e0aa83d8 Added registry for command palette commands 2021-01-11 23:02:55 +01:00
WerWolv
81652e3650 libimhex needs nlohmann json too 2021-01-11 21:51:52 +01:00
WerWolv
bdd2f51497 Use same folder structure for nlohmann json as previously 2021-01-11 21:45:19 +01:00
WerWolv
688e921034 Added nlohmann json to imhex directly
Once again Ubuntu is fucking outdated by over a year for literally no reason. Fuck this
2021-01-11 21:42:21 +01:00
WerWolv
e27993aff2 Added custom event registry 2021-01-11 21:11:03 +01:00
WerWolv
46388f4707 Added experimental support for Light and Classic theme
MY EYES
2021-01-11 20:32:12 +01:00
WerWolv
d68b931013 Added settings registry and settings menu 2021-01-11 20:31:40 +01:00
WerWolv
8807d6c6f3 Moved resource.rc to res folder 2021-01-11 16:03:10 +01:00
WerWolv
14adcc0e51 Added set base address function to hex editor
This resolves #19
2021-01-11 13:50:04 +01:00
WerWolv
a09aec032f Bump version to 1.6.1 2021-01-11 09:56:09 +01:00
WerWolv
7784fca0d4 Always display Pattern Data table header 2021-01-11 09:53:20 +01:00
WerWolv
68bd5569ce Don't show Plugin Views menu if there are no views 2021-01-11 09:50:51 +01:00
WerWolv
60e1c23a6b Fixed pattern format strings 2021-01-11 09:14:32 +01:00
WerWolv
77fbb54ebc Added dlsym to msys2 PKGBUILD 2021-01-11 08:54:23 +01:00
WerWolv
9b7b782020 Fixed cmake error when build type was left unset 2021-01-11 08:46:51 +01:00
WerWolv
bb3e0c126f CI steps naming consistency 2021-01-11 00:44:20 +01:00
WerWolv
3aeb9f31b0 Mark toEngineeringString inline to prevent linker errors 2021-01-11 00:36:24 +01:00
WerWolv
8b19f0c3c0 Improved UTF-8 display in data inspector 2021-01-11 00:34:50 +01:00
WerWolv
73e259d6e7 Added engineering display mode to calculator 2021-01-11 00:27:00 +01:00
WerWolv
f9039f4b34 Added hex editor view right click context menu 2021-01-10 23:59:36 +01:00
George Hopkins
5fb046ad1f Show commit on about page only if available (#132) 2021-01-10 22:57:57 +01:00
WerWolv
7b089a1f2f Fixed unions not advancing offset 2021-01-10 22:57:04 +01:00
WerWolv
867faef496 Fixed invalid applying of define replacements 2021-01-10 22:52:58 +01:00
WerWolv
557313ae1e Fixed boolean OR never being parsed 2021-01-10 22:52:28 +01:00
WerWolv
e4c2049975 Fixed off-by-one error for array bound check 2021-01-10 22:52:12 +01:00
WerWolv
b4ef19dac7 Fixed empty struct and union offset display 2021-01-10 19:43:21 +01:00
WerWolv
dc6c1fa622 Fixed issues with struct and union members when using conditionals 2021-01-10 19:40:44 +01:00
Nobutaka Mantani
d9db8401e2 Fix build on FreeBSD (#126)
* Fix build on FreeBSD

* Use more generic way to search libcrypto

* Integrate macro for FreeBSD
2021-01-10 18:52:00 +01:00
WerWolv
9fe8a0f491 Fixed enums not counting towards size of structs / enums 2021-01-10 18:24:58 +01:00
WerWolv
43d6b48cab Fixed rvalue endianess 2021-01-10 17:18:14 +01:00
WerWolv
ad40c53eb2 Fixed enum parse/evaluate error and crash 2021-01-10 17:14:38 +01:00
Robin Lambertz
c71c610eba Windows MSI Installer (#121)
* Create ImHex WIX Installer

* Build Windows Installer in github actions

* Have a single windows step handling MSI and ZIP.

* Properly copy dependencies to portable zip

* Add magicdb to zip/msi

* Use arial font and smaller text in license
2021-01-10 14:22:34 +01:00
WerWolv
cf1fe04431 Fixed invalid type name in bitfields 2021-01-10 13:50:34 +01:00
WerWolv
8f16a733b9 Fixed bitfields behaving like they have no size. Fixes #127 2021-01-10 13:40:07 +01:00
WerWolv
bc4991f915 Improved type consistency throughout the language 2021-01-10 00:40:57 +01:00
WerWolv
7a8e923b41 Added print & warnAssert functions and a colored console 2021-01-09 23:48:42 +01:00
WerWolv
e54dbcf574 Added assert function. Resolves #123 2021-01-09 21:47:52 +01:00
WerWolv
c5d023822d Added functions with string literals as parameter 2021-01-09 21:47:52 +01:00
WerWolv
e28d6e7451 Added string literals and improved character parsing 2021-01-09 21:47:52 +01:00
WerWolv
9f275cc84f Show evaluator errors in a console window instead of the first line 2021-01-09 21:47:52 +01:00
Philipp Kovalev
575903f921 fix(lang): fixes occurrence index in findSequnce built-in fucntion (#120) 2021-01-09 18:48:34 +01:00
WerWolv
02b3b94804 Increased ImHex to version 1.6.0 2021-01-08 22:09:08 +01:00
WerWolv
17ecdbf8ec Allow accessing of pointer values in mathematical expressions 2021-01-08 20:12:16 +01:00
WerWolv
80e0782fdb Various UI/UX improvements 2021-01-08 19:34:29 +01:00
WerWolv
c505b5b9cb Fixed non-native endian on floats 2021-01-08 17:46:31 +01:00
WerWolv
99f37504de Force reload the current pattern when loading a new file 2021-01-08 17:38:43 +01:00
WerWolv
69f4c6e5e9 Allow global variables to be accessed and used in expressions 2021-01-08 17:37:05 +01:00
WerWolv
fd98db1b70 Fixed error line number mismatch when including files or using comments 2021-01-08 17:14:35 +01:00
WerWolv
205f3a327e Fixed endian specifier not applying 2021-01-08 16:56:39 +01:00
WerWolv
750f7463cc Nightly support for Windows and Linux (#119) 2021-01-08 16:25:12 +01:00
WerWolv
f84b661af7 Fixed pointers to built-in types and endian handling 2021-01-08 15:03:53 +01:00
WerWolv
56330686be Fixed crash when creating an enum 2021-01-08 11:58:07 +01:00
WerWolv
a41e91a731 Fixed floating point pattern displaying 2021-01-08 11:57:28 +01:00
WerWolv
e758b16ba3 Added Pattern Language Guide to the Readme 2021-01-08 01:36:17 +01:00
WerWolv
e48c61cf27 Hopefully fixed macos compile finally 2021-01-07 21:52:03 +01:00
WerWolv
08c802f733 Added unbounded char arrays for null-terminated strings 2021-01-07 21:16:34 +01:00
WerWolv
7e4babaca8 Use custom versions of concepts for macos support 2021-01-07 20:06:28 +01:00
WerWolv
f65c792191 Include unordered_map instead of map 2021-01-07 18:12:02 +01:00
WerWolv
e572c5776d Only define is_integral and is_signed for 128 bit types on non-apple
Clang on macos already defines is_integral and is_signed for 128 bit types
2021-01-07 18:07:56 +01:00
WerWolv
5d1e53f469 Added boolean patterns 2021-01-07 17:34:50 +01:00
WerWolv
bef20f7808 Added function calling as well as a few builtin functions 2021-01-07 15:37:37 +01:00
WerWolv
b47736b595 Properly include headers for memcpy 2021-01-07 01:58:56 +01:00
WerWolv
2dbfbe70af Fixed rvalue value evaluation 2021-01-07 01:56:15 +01:00
WerWolv
3f1d9ed366 Added ternary condition operator 2021-01-07 01:19:54 +01:00
WerWolv
b30bb21646 Added unary operators +, -, ~ and ! 2021-01-07 00:41:06 +01:00
WerWolv
acfd5aa02f Added if, else and else if to pattern language 2021-01-07 00:02:51 +01:00
WerWolv
d8b16766f5 Force Release build type if none was specified 2021-01-07 00:02:33 +01:00
WerWolv
b902cc6531 Go back to static linking on WIndows
Everything except python is once again statically linked
2021-01-06 19:19:01 +01:00
WerWolv
2248cd96b1 Fixed opening of files with non-ASCII characters in path
Fixes #116
2021-01-06 17:22:12 +01:00
WerWolv
01b7059582 Dynamically link everything on Windows as well 2021-01-06 16:30:30 +01:00
WerWolv
7fd0d87d56 Allow enum entries to be accessed via the scope resolution operator 2021-01-06 16:30:30 +01:00
Nicolas Noble
be515d4c40 Proper permission on get_deps_debian.sh script. (#100) 2021-01-06 14:14:47 +01:00
WerWolv
ceee311efa Added support for more literal types and scope resolution operator parsing 2021-01-05 14:42:08 +01:00
WerWolv
f137d759c8 Allow zero-sized arrays again 2021-01-04 16:25:03 +01:00
WerWolv
f5250d6bcf Fixed rvalues not evaluating correctly in nested structs 2021-01-04 16:13:03 +01:00
WerWolv
af42d2ff66 Properly convert rvalue to mathematical expression 2021-01-04 14:10:59 +01:00
WerWolv
f1339f8b4a Fixed crash on load when no plugin folder was present 2021-01-04 13:52:49 +01:00
WerWolv
eed7ef1ac3 Make sure important data is synchronized between ImHex and plugins 2021-01-04 00:19:56 +01:00
WerWolv
c7c654d310 Improved data inspector displaying, added additional number formats 2021-01-03 17:12:20 +01:00
WerWolv
94a7d3116a Fix mac build with missing concepts header 2021-01-03 16:20:28 +01:00
WerWolv
e770fcd197 Fixed includes on unix 2021-01-03 15:09:12 +01:00
WerWolv
5a0f965125 Use file mapping instead of of normal file IO
This drastically reduces disk reads and improves performance
2021-01-03 15:00:16 +01:00
WerWolv
206be8b110 Greatly improved hex editor byte highlighting performance 2021-01-03 02:37:37 +01:00
WerWolv
4189700a3b Use hex::integral instead of std::integral concept 2021-01-02 22:24:52 +01:00
WerWolv
9a968674d6 Fixed compile on macos 2021-01-02 20:49:55 +01:00
WerWolv
18c9340950 Removed duplicated code from hex.hpp 2021-01-02 20:46:44 +01:00
WerWolv
78ef07cf0f Pattern Language rewrite (#111)
* Initial parser rewrite effort

Lexer and Token cleanup, Parser started over

* Greatly improved parser syntax

* Reimplemented using declarations and variable placement parsing

* Added back unions and structs

* Added enums as well as mathematical expressions (+, -, *, /, <<, >>, &, |, ^)

* Code style improvement

* Implemented arrays and fixed memory issues

* Fixed more memory issues in parser, reimplemented validator, evaluator and patterns

* Fixed builtin types, arrays and reimplemented strings

* Improved error messages

* Made character a distinct type, used for chars and strings

* Implemented padding, fixed arrays

* Added bitfields

* Added rvalue parsing, no evaluating yet

* Added .idea folder to gitignore

* Fixed build on MacOS

* Added custom implementation of integral concept if not available

* Rebased onto master

* Fixed array variable decl crash

* Added rvalues and dot syntax

* Lower case all pattern language error messages

* Fixed typo in variable name

* Fixed bug where preprocessor would not ignore commented out directives

* Reimplemented pointers

* Fixed rebase issues
2021-01-02 20:27:11 +01:00
Mary
d510f8c7cf Github Actions: Enforce a cache miss on Windows job
Workaround discuted in msys2/setup-msys2#99.
2020-12-30 19:08:40 +01:00
Mary
2180a8faef Github Actions: upload resulting DMG on macOS
Add infos about nightly builds.
2020-12-30 18:56:25 +01:00
Mary
2340ab0518 cmake: Handle code sign and packaging for macOS bundle 2020-12-29 22:50:11 +01:00
Mary
de5c6a4084 cmake Readd CREATE_BUNDLE infos on macOS 2020-12-29 21:00:41 +01:00
Mary
ce06d9bdfb Fix version and vendor in macOS bundle 2020-12-29 20:41:43 +01:00
Mary
33c11baca9 clean up after previous commit 2020-12-29 02:07:26 +01:00
Mary
8fbdcd54aa Make macOS bundle works!
TODO: codesign
2020-12-29 01:59:28 +01:00
Mary
20d3a84fc0 Fix creation of macOS bundle
Still need to find a way to handle the deps madness
2020-12-28 23:37:51 +01:00
Mary
58a65b0004 cmake: Do not ship resource.rc on non WIN32 systems
Also add some very early macOS bundle definitions.
2020-12-28 20:03:50 +01:00
Mary
bbd00a6020 Ignore .DS_Store in gitignore 2020-12-28 18:52:42 +01:00
Mary
63f544918d Fix build instruction to add CMAKE_BUILD_TYPE 2020-12-28 18:52:22 +01:00
WerWolv
93938d6090 external: glfw3 -> glfw 2020-12-27 15:57:59 +01:00
WerWolv
144e30775f Fixed duplicated utils.hpp 2020-12-27 15:54:12 +01:00
WerWolv
f74eff8934 Add support for custom providers via plugins 2020-12-27 15:39:06 +01:00
WerWolv
8ba96904a6 More plugin support work 2020-12-27 14:12:53 +01:00
WerWolv
dbbc525174 Added Plugin support (#102)
* Build refactoring and initial plugin support

* Possibly fixed linux / mac build

* Added libdl to libglad build script

* Add glfw to imgui dependencies

* Refactored common functionality into "libimhex" for plugins

* Added plugin loading and example plugin

* Added proper API for creating a custom view and a custom tools entry with plugins
2020-12-22 18:10:01 +01:00
WerWolv
b9324f44e6 Added selected addresses to hex editor footer
This (and the two previous commits) fixes #99
2020-12-21 15:20:57 +01:00
WerWolv
d6c5e3dc3e Fixed render order of ASCII display in hex editor
Fixes #98
2020-12-21 14:44:01 +01:00
WerWolv
7c350dde90 Added current commit hash and branch to about page 2020-12-21 12:38:50 +01:00
WerWolv
2c1759ce0a Unified OS and arch checking defines 2020-12-21 12:38:30 +01:00
WerWolv
7f5a32a83b Improved hex::format 2020-12-21 12:36:43 +01:00
WerWolv
379f77af48 Cleaned up github actions 2020-12-21 11:54:33 +01:00
WerWolv
4b59d57f89 Added version info to about page 2020-12-21 11:24:27 +01:00
WerWolv
15b3860f83 Fixed data inspector not updating properly in all cases 2020-12-21 11:23:57 +01:00
WerWolv
b71a9b7d14 More centering 2020-12-19 15:15:24 +01:00
WerWolv
85352868ec Cleaned up readme and added link to discord server 2020-12-19 15:14:45 +01:00
Mary
310059f274 Support macOS
This allows building and running under macOS.
There is still some issues with dpi but the application compiles and run now.
2020-12-18 21:44:13 +01:00
Mary
b5cc3b6f1b Make target link and include more generic
This fixes issues with library link and unify support for linking on Linux/macOS/BSD.
2020-12-18 20:04:55 +01:00
Mary
de9421e68f Fix missing dependencies in README and ArchLinux get_deps script 2020-12-18 18:46:20 +01:00
Mary
413443aa95 Build LLVM demangler directly with our sources
This remove dep on LLVM library by building the demangler as part of the
project.

This should help with building on macOS.
2020-12-18 17:56:41 +01:00
Sam Umbach
82d7c54a3d Fix minor typos (#95) 2020-12-17 08:55:40 +01:00
WerWolv
9123b21e18 Added basic command palette (similar to the one in vscode) 2020-12-16 22:43:07 +01:00
averne
56cca88fbd Proper DPI scaling and basic custom font (#85)
* add glm to arch deps

After running got `None of the required 'glm' found`. This fixes that

* dist/fedora: Include file magic headers

Due to differences in package names between Deb based systems, Arch
Linux, and RPM based systems the package containing the development
headers for file were missing from the Fedora dependencies script.

This includes the package `file-devel`, which is the package which
resolves the issue.

In Fedora, one can identify the package providing a specific file using
the verb "whatprovides" with the command dnf, e.g.:

    [~]$ dnf whatprovides /usr/include/magic.h
    Last metadata expiration check: 4 days, 0:23:05 ago on Fri 04 Dec 2020 09:06:53 AM PST.
    file-devel-5.39-3.fc33.i686 : Libraries and header files for file development
    Repo        : fedora
    Matched from:
    Filename    : /usr/include/magic.h

    file-devel-5.39-3.fc33.x86_64 : Libraries and header files for file development
    Repo        : @System
    Matched from:
    Filename    : /usr/include/magic.h

    file-devel-5.39-3.fc33.x86_64 : Libraries and header files for file development
    Repo        : fedora
    Matched from:
    Filename    : /usr/include/magic.h

If one is unsure of the specific path, globbing may be used (but must be
quoted):

    dnf whatprovides "*/magic.h"

Resolves #48

* dist: Prevent already installed packages in ArchLinux and MSYS2.

Use --needed option with pacman to prevent it.

* Add script to install dependencies on Debian/Ubuntu.

Tested with Xubuntu 20.04 and Debian testing
(in today's Docker image bitnami/minideb).

Update README.md.

* ci: rework (#31)

* Support non standard LLVM library names (#86)

This fix openSUSE and Gentoo issue mentioned in https://github.com/WerWolv/ImHex/issues/37#issuecomment-739503138.

(tested on openSUSE tumbleweed via Docker)

I also took the liberty of renaming llvm_lib to llvm_demangle_lib to be more specific in the ``CMakeLists.txt``.

* Implement proper DPI handling

* Implement basic custom font support

* Fix building on windows

* Hopefully fix fonts on Windows

* Fix several scaling issues

* Replace font renderer with freetype

* Updated CI and dependency scripts

* Rebuild default font atlas

* Correct platform detection macro for mingw

* Fixed PKGBUILD

Co-authored-by: brockelmore <31553173+brockelmore@users.noreply.github.com>
Co-authored-by: Brian 'Redbeard' Harrington <redbeard@dead-city.org>
Co-authored-by: Biswapriyo Nath <nathbappai@gmail.com>
Co-authored-by: Stéphane Gourichon <stephane.gourichon@fidergo.fr>
Co-authored-by: umarcor <38422348+umarcor@users.noreply.github.com>
Co-authored-by: Mary <me@thog.eu>
Co-authored-by: WerWolv <werwolv98@gmail.com>
2020-12-11 14:24:42 +01:00
Mary
9b853350f1 Support non standard LLVM library names (#86)
This fix openSUSE and Gentoo issue mentioned in https://github.com/WerWolv/ImHex/issues/37#issuecomment-739503138.

(tested on openSUSE tumbleweed via Docker)

I also took the liberty of renaming llvm_lib to llvm_demangle_lib to be more specific in the ``CMakeLists.txt``.
2020-12-10 22:28:49 +01:00
umarcor
e3b5a55eba ci: rework (#31) 2020-12-09 19:49:56 +01:00
WerWolv
366dc80dc0 Merge pull request #79 from fidergo-stephane-gourichon/dependency_install_script_debian_ubuntu
Add script to install dependencies on Debian/Ubuntu.
2020-12-09 18:51:26 +01:00
Stéphane Gourichon
ba2ee6d6e5 Add script to install dependencies on Debian/Ubuntu.
Tested with Xubuntu 20.04 and Debian testing
(in today's Docker image bitnami/minideb).

Update README.md.
2020-12-09 15:18:18 +01:00
WerWolv
6afcf1a26f Merge pull request #76 from Biswa96/master
dist: Prevent already installed packages in ArchLinux and MSYS2.
2020-12-09 10:33:48 +01:00
Biswapriyo Nath
ee831fbcb6 dist: Prevent already installed packages in ArchLinux and MSYS2.
Use --needed option with pacman to prevent it.
2020-12-09 14:21:36 +05:30
WerWolv
4d87eefbe9 Merge pull request #69 from brianredbeard/issue-48-fix-fedora-error
dist/fedora: Include file magic headers
2020-12-08 18:45:44 +01:00
Brian 'Redbeard' Harrington
ec04fea9be dist/fedora: Include file magic headers
Due to differences in package names between Deb based systems, Arch
Linux, and RPM based systems the package containing the development
headers for file were missing from the Fedora dependencies script.

This includes the package `file-devel`, which is the package which
resolves the issue.

In Fedora, one can identify the package providing a specific file using
the verb "whatprovides" with the command dnf, e.g.:

    [~]$ dnf whatprovides /usr/include/magic.h
    Last metadata expiration check: 4 days, 0:23:05 ago on Fri 04 Dec 2020 09:06:53 AM PST.
    file-devel-5.39-3.fc33.i686 : Libraries and header files for file development
    Repo        : fedora
    Matched from:
    Filename    : /usr/include/magic.h

    file-devel-5.39-3.fc33.x86_64 : Libraries and header files for file development
    Repo        : @System
    Matched from:
    Filename    : /usr/include/magic.h

    file-devel-5.39-3.fc33.x86_64 : Libraries and header files for file development
    Repo        : fedora
    Matched from:
    Filename    : /usr/include/magic.h

If one is unsure of the specific path, globbing may be used (but must be
quoted):

    dnf whatprovides "*/magic.h"

Resolves #48
2020-12-08 09:31:17 -08:00
Mary
1586aee2d2 Merge pull request #59 from brockelmore/patch-1
add glm to arch deps
2020-12-08 13:33:42 +01:00
WerWolv
226169bbbe Merge remote-tracking branch 'origin/master' 2020-12-07 23:49:28 +01:00
WerWolv
e1e73077a1 Improved language parsing and validation. This fixes #58 2020-12-07 23:49:19 +01:00
brockelmore
7b5cfcb817 add glm to arch deps
After running got `None of the required 'glm' found`. This fixes that
2020-12-07 16:51:08 -05:00
WerWolv
b3645ec945 Merge pull request #53 from umarcor/deps
create subdir 'dist', update compiling guidelines
2020-12-07 18:46:25 +01:00
umarcor
7d06460e54 create subdir 'dist', update compiling guidelines 2020-12-07 04:17:17 +01:00
WerWolv
485761f45c Fixed ImHex refusing to be closed in some circumstances 2020-12-07 00:42:52 +01:00
WerWolv
f3d788de16 Fixed bytes not being selectable when a read-only file was loaded
This most likely fixes #49
2020-12-06 23:21:31 +01:00
WerWolv
b06f5630c7 Fixed additional issues with padding and zero sized arrays 2020-12-06 23:15:51 +01:00
WerWolv
5c96a28fb6 Actually fix crash when creating zero sized arrays
If size is zero, the array will be treated as non-existent. This fixes #50
2020-12-06 22:52:15 +01:00
WerWolv
9425569784 Merge pull request #47 from Calinou/readme-add-fedora-package-list
Add a list of packages to install for building on Fedora 33
2020-12-06 22:24:19 +01:00
Hugo Locurcio
8b982b977b Add a list of packages to install for building on Fedora 33
Tested in a fresh Fedora 33 Docker container.
2020-12-06 22:19:52 +01:00
WerWolv
7a9d7b59e8 Added overriding of endianess for individual variables 2020-12-06 21:40:57 +01:00
WerWolv
4720cf9fbe Added possible support for MacOS. Completely untested.
Relevant: #32
2020-12-06 13:48:56 +01:00
WerWolv
68f93c5e3d Fixed possible crash when loading files, relax pattern detection requirements
This fixes #20
2020-12-05 22:30:09 +01:00
WerWolv
7b8330f8f8 Added command line support / dropping files onto executable
Closes #36
2020-12-05 22:10:03 +01:00
WerWolv
63696b9f5f Merge pull request #38 from Thog/feature/linux-ci
CI: Add a GitHub Action to build on Ubuntu 20.04 LTS
2020-12-05 20:32:45 +01:00
Mary
727b3c6b10 CI: Add a GitHub Action to build on Ubuntu 20.04 LTS
Also clean up MSYS2 action.
2020-12-05 20:03:22 +01:00
WerWolv
05cb3831a2 Merge pull request #35 from Thog/fix/llvm-custom-lib-dir
Make sure to add LLVM_LIBRARY_DIR to link directories
2020-12-05 18:55:28 +01:00
Mary
5b51375404 Make sure to add LLVM_LIBRARY_DIR to link directories
This fix build on Debian and Ubuntu systems.

Close #28
Close #8
2020-12-05 18:13:47 +01:00
WerWolv
398e845e8d Merge pull request #33 from Thog/fix/capstone-401-support
Abstract capstone architectures
2020-12-05 17:43:18 +01:00
Mary
45c29888b4 Abstract capstone architectures
This allows to support older version of Capstone (example 4.0.1).

Should help with ubuntu building issues.
2020-12-05 17:32:30 +01:00
WerWolv
82c5bd528c Added more compile information 2020-12-05 15:39:28 +01:00
WerWolv
45d0b614c2 Added sponsoring links to Readme. Thank you <3 2020-12-05 15:10:57 +01:00
WerWolv
4725ff6d5f Don't open a console window in release build
This fixes #21
2020-12-05 14:09:32 +01:00
WerWolv
7158d4d4ad Always allow cursor movement with arrow keys
Implements #22
2020-12-05 12:55:37 +01:00
WerWolv
502d90b117 Merge remote-tracking branch 'origin/master' 2020-12-05 12:54:42 +01:00
WerWolv
f0c95b3f29 Merge pull request #29 from Thog/feature/python3-detect
Detect python version at build time
2020-12-05 12:54:30 +01:00
Mary
d3dccace37 Detect python version at build time
This remove the hardcoded version in CMakeLists.txt and
loader_script_handler.cpp.

Fixing building on Arch Linux and probably other systems.
2020-12-05 12:46:50 +01:00
WerWolv
a30453616b Turned cheat sheet popups into actual windows 2020-12-05 11:34:49 +01:00
WerWolv
168ba2ff9f Denote invalid GUIDs in data inspector
Addresses #24
2020-12-05 11:00:56 +01:00
WerWolv
2ca9a8fc79 Fixed data inspector displaying zero at the end of data
Fixes #25
2020-12-05 10:42:42 +01:00
WerWolv
6456a68805 Fixed crash when array size variable has a value of zero 2020-12-05 10:36:30 +01:00
WerWolv
e82b607fa1 Merge pull request #16 from Thog/feature/github-actions
CI: Add a GitHub Action to build on Windows
2020-12-04 13:40:36 +01:00
Mary
7168c9ed59 Limit make to 4 threads and move build.yml to build_win.yml 2020-12-04 13:17:54 +01:00
WerWolv
d7af6934b6 Added ImHex-Patterns repository to the readme 2020-12-04 09:26:19 +01:00
Mary
b4a5a936a0 CI: Add a GitHub Action to build on Windows
This build in any commits and pull requests.
2020-12-04 01:28:26 +01:00
WerWolv
6129e0d696 Added libwinpthread dll to copy instructions
Because smh not everybody has qemu installed
2020-12-03 23:18:41 +01:00
WerWolv
a0c8424800 Create FUNDING.yml 2020-12-03 21:10:38 +01:00
WerWolv
dc839e1ad1 Fixed typos, love you @foone :P 2020-12-03 20:56:02 +01:00
WerWolv
59155256a9 Create LICENSE 2020-12-03 15:34:58 +01:00
WerWolv
29b7995e7f Formatting 2020-12-03 09:18:55 +01:00
WerWolv
ae9ec8851c Credit where it's due 2020-12-03 09:17:55 +01:00
WerWolv
7c2df736df Improved readme 2020-12-01 20:47:57 +01:00
WerWolv
192e7d5060 Added Python API function to create structs and unions 2020-12-01 18:21:29 +01:00
WerWolv
6aed140ecf Use custom "argc" and "argv" exposing. Fixes #6 2020-12-01 18:19:49 +01:00
WerWolv
76d56c9ed4 Added python version requirement to cmake. Fixes #5 2020-12-01 18:18:15 +01:00
WerWolv
17096055f8 Added create_struct and create_union function to Python API 2020-12-01 16:41:38 +01:00
WerWolv
c6134bc038 Added basic python-based load scripts 2020-12-01 02:21:40 +01:00
WerWolv
16f885f469 Added read/write command to math evaluator 2020-11-30 21:45:48 +01:00
WerWolv
00072d0216 Improved pattern language cheat sheet, added math evaluator cheat sheet 2020-11-30 21:44:40 +01:00
WerWolv
4878f70e58 Added project files 2020-11-30 00:03:12 +01:00
WerWolv
9e8523470d Added applying of IPS and IPS32 patches 2020-11-29 15:09:36 +01:00
WerWolv
7316be0bc2 Added patches display window 2020-11-29 02:06:41 +01:00
WerWolv
8a4b663890 Prevent shortcuts from applying to closed windows 2020-11-29 01:18:12 +01:00
WerWolv
3276ad9979 Open file dialog to not pop up if hex view wasn't open 2020-11-29 01:17:54 +01:00
WerWolv
0890043bf4 Make Help view no longer appear in View menu 2020-11-28 22:01:50 +01:00
WerWolv
c90ef343c1 Added math evaluator / calculator to tools window 2020-11-28 21:55:52 +01:00
WerWolv
0f6e276113 Updated screenshots 2020-11-28 17:21:34 +01:00
WerWolv
1395c95831 Same treatment for the disassembly window 2020-11-28 16:15:12 +01:00
WerWolv
33b70a550f Improved look and feel of hash window. Added "Match selection" feature 2020-11-28 15:53:11 +01:00
WerWolv
985e924e9d Added simple bookmarks / comments feature. No saving yet though 2020-11-28 00:33:26 +01:00
WerWolv
3827919a32 Added error messages and error display to pattern language editor 2020-11-27 21:20:23 +01:00
WerWolv
d55bea7c46 Added character literals to pattern language 2020-11-27 14:18:28 +01:00
WerWolv
2efe326fdb Added Save, Save As and implemented error message for Base64 importing 2020-11-27 13:45:56 +01:00
WerWolv
d43bd23e1a Added default error message window 2020-11-27 13:45:27 +01:00
WerWolv
015ec12215 Improved byte write speed by a lot 2020-11-27 13:44:52 +01:00
WerWolv
fde9dc7961 Various small fixes 2020-11-27 09:09:59 +01:00
WerWolv
ed572ececf Added patching system and IPS/IPS32 patch exporting 2020-11-27 09:09:48 +01:00
WerWolv
fd2b79bea9 Removed cxxabi.h include 2020-11-24 18:12:48 +01:00
WerWolv
acc10930c2 Added MSVC symbol demangling, switched to LLVM libs for demangling 2020-11-24 18:12:08 +01:00
WerWolv
f17d6c2359 Added copy string and copy demangled string to strings window 2020-11-24 02:59:49 +01:00
WerWolv
e21211f3f6 Added back default debug/release specific flags 2020-11-24 02:00:48 +01:00
WerWolv
58deaa6b29 Added importing from base64 encoded file 2020-11-24 02:00:22 +01:00
WerWolv
fcd88b4b3b Shrink the color picker to a bit more reasonable size 2020-11-24 00:01:44 +01:00
WerWolv
3bd987ff2c Streamline view creation, save all view states when quitting 2020-11-23 23:57:19 +01:00
WerWolv
45bcdc8c46 Added toggle for ImGui demo window in Debug mode 2020-11-23 22:23:06 +01:00
WerWolv
0d0b2d6962 Indent variable name instead of color in pattern data view 2020-11-23 22:14:11 +01:00
WerWolv
fd6a41d219 Make selecting memory by clicking on a table item update the inspector 2020-11-23 16:26:01 +01:00
WerWolv
b052429a73 Improved ASCII and Wide char display in data inspector 2020-11-23 16:19:58 +01:00
WerWolv
1996f401e0 Fixed last block searched for strings to yield invalid results 2020-11-23 16:19:31 +01:00
WerWolv
3b3f2226f1 Remove collapse button from all windows 2020-11-23 15:51:58 +01:00
WerWolv
5c0f6a1e50 Enabled ImGui's viewports support 2020-11-23 15:51:40 +01:00
WerWolv
b7438f6ab8 Massively improved look and feel of pattern data, string and disassembly tables 2020-11-23 15:22:26 +01:00
WerWolv
84f80b3e06 Select region when clicking on string, disassembly or pattern data item 2020-11-23 13:10:14 +01:00
WerWolv
c281372b8d Improved table coloring 2020-11-23 13:08:24 +01:00
WerWolv
788a3cfc5e Merge pull request #3 from misson20000/bugfixes
a few bugfixes
2020-11-23 08:25:15 +01:00
misson20000
01eeb53af0 Fix out-of-bounds vector write on copy hex string 2020-11-22 18:00:46 -08:00
misson20000
7cf69128ea Actually fix time_t decoding crash on Linux 2020-11-22 18:00:17 -08:00
WerWolv
c977baecc4 Fixed crash when snprintf failed in formatter 2020-11-23 00:35:26 +01:00
WerWolv
2ab2f5e675 Improved block size text 2020-11-23 00:34:53 +01:00
WerWolv
6a38f1e9f3 Truncate file size to 2 digits after comma 2020-11-23 00:22:51 +01:00
WerWolv
f0eba69c4a Fixed time_t decoding crash on Linux 2020-11-23 00:20:29 +01:00
WerWolv
cea366e135 Fixed crash when scrolling disassembler options child off screen 2020-11-23 00:12:53 +01:00
WerWolv
d752c7434f Fixed crash when no patterns folder exists 2020-11-23 00:12:33 +01:00
WerWolv
4402120ffc Added the capstone disassembler and a disassembler window 2020-11-22 23:07:50 +01:00
WerWolv
b3fffdf530 Fixed automatic pattern loading 2020-11-22 23:06:17 +01:00
WerWolv
8d6d959e17 No need to manually set table colors 2020-11-22 20:41:54 +01:00
WerWolv
43f5cc622e Allow loading of huge files efficiently 2020-11-22 19:43:35 +01:00
WerWolv
5f025bcbcc Fixed UTF-8 decoding to not work 2020-11-22 16:22:23 +01:00
WerWolv
8297e22f10 Added global big and little endian support to the pattern parser 2020-11-22 16:22:02 +01:00
WerWolv
989eade5d7 Added big and little endian support to inspector 2020-11-22 15:32:37 +01:00
WerWolv
cd4de2ff96 Fixed data inspector to only show unsigned values 2020-11-22 12:50:49 +01:00
WerWolv
73d66365e9 Updated cheat sheet page 2020-11-22 11:20:01 +01:00
WerWolv
fbd4e593d2 Make array and pointer pattern data display more consistent with other types 2020-11-22 02:25:25 +01:00
WerWolv
033ef3889a Fixed enums failing to validate 2020-11-22 02:25:03 +01:00
WerWolv
0ce1b5d40b Added simple pointer type inside structs 2020-11-21 23:00:09 +01:00
WerWolv
ed4ed6b433 Added array sizes based on other local variables 2020-11-21 20:19:33 +01:00
WerWolv
4cd18b8358 Added auto loading patterns based on MIME types 2020-11-21 14:39:16 +01:00
WerWolv
fb85f272a1 Added pragmas to pattern language 2020-11-21 14:39:01 +01:00
WerWolv
28bb28b79c Also rename data inspector window 2020-11-21 14:37:09 +01:00
232 changed files with 90805 additions and 10895 deletions

5
.github/FUNDING.yml vendored Normal file
View File

@@ -0,0 +1,5 @@
# Sponsor links
patreon: werwolv
custom: https://werwolv.net/donate
github: WerWolv

140
.github/workflows/build.yml vendored Normal file
View File

@@ -0,0 +1,140 @@
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
submodules: recursive
- name: ⬇️ Install dependencies
run: |
sudo apt-get update
sudo bash dist/get_deps_debian.sh
- 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
name: 🟦 Windows MINGW64
defaults:
run:
shell: msys2 {0}
steps:
- name: 🧰 Checkout
uses: actions/checkout@v2
with:
fetch-depth: 0
submodules: recursive
- name: 🟦 Install msys2
uses: msys2/setup-msys2@v2
- name: ⬇️ Install dependencies
run: |
bash dist/get_deps_msys2.sh
- 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
submodules: recursive
- 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

3
.gitignore vendored
View File

@@ -1,3 +1,5 @@
.vscode/
.idea/
cmake-build-debug/
@@ -8,3 +10,4 @@ build/
*.mgc
imgui.ini
.DS_Store

16
.gitmodules vendored Normal file
View File

@@ -0,0 +1,16 @@
[submodule "external/nativefiledialog"]
path = external/nativefiledialog
url = https://github.com/btzy/nativefiledialog-extended
[submodule "external/yara/yara"]
path = external/yara/yara
url = https://github.com/VirusTotal/yara
ignore = dirty
[submodule "external/xdgpp"]
path = external/xdgpp
url = https://git.sr.ht/~danyspin97/xdgpp
[submodule "external/fmt"]
path = external/fmt
url = https://github.com/fmtlib/fmt
[submodule "external/curl"]
path = external/curl
url = https://github.com/curl/curl

1
.idea/.name generated Normal file
View File

@@ -0,0 +1 @@
imhex

2
.idea/imhex.iml generated Normal file
View 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
View File

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

5
.idea/vcs.xml generated
View File

@@ -2,5 +2,10 @@
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
<mapping directory="$PROJECT_DIR$/external/curl" vcs="Git" />
<mapping directory="$PROJECT_DIR$/external/fmt" vcs="Git" />
<mapping directory="$PROJECT_DIR$/external/nativefiledialog" vcs="Git" />
<mapping directory="$PROJECT_DIR$/external/xdgpp" vcs="Git" />
<mapping directory="$PROJECT_DIR$/external/yara/yara" vcs="Git" />
</component>
</project>

View File

@@ -1,32 +1,71 @@
cmake_minimum_required(VERSION 3.16)
project(HexEditor)
# Updating the version here will update it throughout ImHex as well
set(IMHEX_VERSION "1.8.1")
project(imhex VERSION ${IMHEX_VERSION})
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
builtin
# example
)
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
)
if (WIN32)
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -static-libstdc++ -static-libgcc -static")
endif (WIN32)
findLibraries()
add_executable(ImHex
detectOS()
detectArch()
if (NOT USE_SYSTEM_LLVM)
add_subdirectory(external/llvm)
else()
find_package(LLVM REQUIRED Demangle)
endif()
if (NOT USE_SYSTEM_YARA)
add_subdirectory(external/yara)
else()
find_package(PkgConfig REQUIRED)
pkg_check_modules(YARA REQUIRED IMPORTED_TARGET yara)
endif()
# Add bundled dependencies
add_subdirectory(plugins/libimhex)
# Add include directories
include_directories(include ${MBEDTLS_INCLUDE_DIRS} ${CAPSTONE_INCLUDE_DIRS} ${MAGIC_INCLUDE_DIRS} ${Python_INCLUDE_DIRS})
if (USE_SYSTEM_LLVM)
include_directories(include ${LLVM_INCLUDE_DIRS})
endif()
if (USE_SYSTEM_YARA)
include_directories(include ${YARA_INCLUDE_DIRS})
endif()
addVersionDefines()
configurePackageCreation()
add_executable(imhex ${application_type}
source/main.cpp
source/window.cpp
source/utils.cpp
source/crypto.cpp
source/lang/preprocessor.cpp
source/lang/lexer.cpp
source/lang/parser.cpp
source/lang/validator.cpp
source/lang/evaluator.cpp
source/init/splash_window.cpp
source/init/tasks.cpp
source/provider/file_provider.cpp
source/helpers/patches.cpp
source/helpers/project_file_handler.cpp
source/helpers/loader_script_handler.cpp
source/helpers/plugin_manager.cpp
source/helpers/encoding_file.cpp
source/providers/file_provider.cpp
source/views/view_hexeditor.cpp
source/views/view_pattern.cpp
@@ -37,25 +76,24 @@ add_executable(ImHex
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
source/views/view_yara.cpp
libs/glad/source/glad.c
libs/ImGui/source/imgui.cpp
libs/ImGui/source/imgui_draw.cpp
libs/ImGui/source/imgui_widgets.cpp
libs/ImGui/source/imgui_demo.cpp
libs/ImGui/source/imgui_impl_glfw.cpp
libs/ImGui/source/imgui_impl_opengl3.cpp
libs/ImGui/source/ImGuiFileBrowser.cpp
libs/ImGui/source/TextEditor.cpp
resource.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 ws2_32.lib libcrypto.a libwinpthread.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 magic ${CMAKE_DL_LIBS} capstone LLVMDemangle libimhex ${Python_LIBRARIES} wsock32 ws2_32 libyara)
else ()
target_link_libraries(imhex magic ${CMAKE_DL_LIBS} capstone LLVMDemangle libimhex ${Python_LIBRARIES} dl pthread libyara)
endif ()
createPackage()

339
LICENSE Normal file
View 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.

206
README.md
View File

@@ -1,7 +1,207 @@
# 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 average 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
![](https://i.imgur.com/ClEsNwL.png)
![](https://i.imgur.com/xH7xJ4g.png)
![](https://i.imgur.com/fhVJYEa.png)
## 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 language 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
- libmbedtls
- capstone
- Python3
- freetype2
- Brew (macOS only)
- Xcode (macOS only)
### Windows
On Windows, ImHex is built through msys2 / mingw. To install all dependencies, open a mys2 window and run the PKGCONFIG script in the (dist/msys2)[dist/msys2] folder.
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.
- 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
```
Install the ImHex executable as well as libimhex.dylib to wherever ImHex should be installed.
All other files belong in `~/Library/Application Support/imhex`:
```
Patterns: ~/Library/Application Support/imhex/patterns
Pattern Includes: ~/Library/Application Support/imhex/includes
Magic files: ~/Library/Application Support/imhex/magic
Python: ~/Library/Application Support/imhex/lib/pythonX.X
Plugins: ~/Library/Application Support/imhex/plugins
Configuration: ~/Library/Application Support/imhex/config
Resources: ~/Library/Application Support/imhex/resources
```
### Linux
Dependency installation scripts are available for many common Linux distributions in the (/dist)[dist] folder.
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
```
---
Put the ImHex executable into the `/usr/bin` folder.
Put libimhex.so into the `/usr/lib` folder.
Configuration files go to `/etc/xdg/imhex` or `~/.config/imhex`.
All other files belong in `/usr/share/imhex` or `~/.local/share/imhex`:
```
Patterns: /usr/share/imhex/patterns
Pattern Includes: /usr/share/imhex/includes
Magic files: /usr/share/imhex/magic
Python: /usr/share/imhex/lib/pythonX.X
Plugins: /usr/share/imhex/plugins
Configuration: /etc/xdg/imhex/config
Resources: /usr/share/imhex/resources
```
All paths follow the XDG Base Directories standard, and can thus be modified
with the environment variables `XDG_CONFIG_HOME`, `XDG_CONFIG_DIRS`,
`XDG_DATA_HOME` and `XDG_DATA_DIRS`.
## 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

283
cmake/build_helpers.cmake Normal file
View File

@@ -0,0 +1,283 @@
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_RC_FLAGS "${CMAKE_RC_FLAGS} -DPROJECT_VERSION_MAJOR=${PROJECT_VERSION_MAJOR} -DPROJECT_VERSION_MINOR=${PROJECT_VERSION_MINOR} -DPROJECT_VERSION_PATCH=${PROJECT_VERSION_PATCH} ")
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")
set(CMAKE_INSTALL_BINDIR ".")
set(CMAKE_INSTALL_LIBDIR ".")
set(PLUGINS_INSTALL_LOCATION "plugins")
set(MAGIC_INSTALL_LOCATION "magic")
set(RESOURCES_INSTALL_LOCATION "resources")
elseif(APPLE)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DOS_MACOS")
set(CMAKE_INSTALL_BINDIR ".")
set(CMAKE_INSTALL_LIBDIR ".")
set(PLUGINS_INSTALL_LOCATION "plugins")
set(MAGIC_INSTALL_LOCATION "magic")
set(RESOURCES_INSTALL_LOCATION "resources")
elseif(UNIX AND NOT APPLE)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DOS_LINUX")
set(CMAKE_INSTALL_BINDIR "bin")
set(CMAKE_INSTALL_LIBDIR "lib")
set(PLUGINS_INSTALL_LOCATION "share/imhex/plugins")
set(MAGIC_INSTALL_LOCATION "share/imhex/magic")
set(RESOURCES_INSTALL_LOCATION "share/imhex/resources")
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 "${CMAKE_SOURCE_DIR}/res/resource.rc")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wl,--allow-multiple-definition")
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_PACKAGE_VENDOR "WerWolv")
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 "${CMAKE_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)
install(TARGETS ${plugin} RUNTIME DESTINATION ${PLUGINS_INSTALL_LOCATION})
add_dependencies(imhex ${plugin})
endforeach()
set_target_properties(libimhex PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
install(TARGETS libimhex RUNTIME DESTINATION ${CMAKE_INSTALL_LIBDIR})
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)
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_INSTALL_LOCATION})
else ()
install(FILES "${EXTRA_MAGICDBS}.mgc" DESTINATION ${MAGIC_INSTALL_LOCATION})
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
)
# Install the magicdb files.
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/magic_dbs.mgc DESTINATION ${MAGIC_INSTALL_LOCATION} RENAME imhex.mgc)
# Install resources
install(DIRECTORY ${CMAKE_SOURCE_DIR}/res/resources/ DESTINATION ${RESOURCES_INSTALL_LOCATION})
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()
install(TARGETS imhex RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
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()

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

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

View 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")

13
dist/Brewfile vendored Normal file
View File

@@ -0,0 +1,13 @@
brew "glfw3"
brew "mbedtls"
brew "capstone"
brew "nlohmann-json"
brew "glm"
brew "cmake"
brew "python3"
brew "freetype2"
brew "libmagic"
brew "pkg-config"
# 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
View 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
dev-cpp/nlohmann_json
media-libs/glm
x11-libs/gtk+
"
BDEPEND="${DEPEND}"

13
dist/get_deps_archlinux.sh vendored Executable file
View File

@@ -0,0 +1,13 @@
#!/usr/bin/env sh
pacman -S --needed \
cmake \
gcc \
glfw \
file \
mbedtls \
capstone \
glm \
python3 \
freetype2 \
gtk3

30
dist/get_deps_debian.sh vendored Executable file
View File

@@ -0,0 +1,30 @@
#!/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 -y \
build-essential \
gcc-10 \
g++-10 \
${PKGCONF:-} \
cmake \
make \
libglfw3-dev \
libglm-dev \
libmagic-dev \
libmbedtls-dev \
libcapstone-dev \
python3-dev \
libfreetype-dev \
libgtk-3-dev \
echo "Please consider this before running cmake (useful on e.g. Ubuntu 20.04):"
echo "export CXX=g++-10"

14
dist/get_deps_fedora.sh vendored Executable file
View File

@@ -0,0 +1,14 @@
#!/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 \
gtk3

14
dist/get_deps_msys2.sh vendored Executable file
View File

@@ -0,0 +1,14 @@
#!/usr/bin/env sh
pacman -S --needed --noconfirm \
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-python \
mingw-w64-x86_64-freetype \
mingw-w64-x86_64-dlfcn

46
dist/msys2/PKGBUILD vendored Normal file
View 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}-dlfcn"
"${MINGW_PACKAGE_PREFIX}-capstone"
"${MINGW_PACKAGE_PREFIX}-glfw"
"${MINGW_PACKAGE_PREFIX}-glm"
"${MINGW_PACKAGE_PREFIX}-file"
"${MINGW_PACKAGE_PREFIX}-mbedtls"
"${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}"
}

48
external/ImGui/CMakeLists.txt vendored Normal file
View File

@@ -0,0 +1,48 @@
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 STATIC
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/TextEditor.cpp
source/imgui_imhex_extensions.cpp
source/imnodes.cpp
source/implot.cpp
source/implot_items.cpp
source/implot_demo.cpp
fonts/fontawesome_font.c
)
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 fonts ${FREETYPE_INCLUDE_DIRS} ${GLFW_INCLUDE_DIRS})
target_link_directories(imgui PUBLIC ${GLM_INCLUDE_DIRS} ${GLFW_LIBRARY_DIRS})
if (WIN32)
target_link_libraries(imgui Freetype::Freetype glad glfw3)
elseif (UNIX)
target_link_libraries(imgui Freetype::Freetype glad glfw)
endif()

3025
external/ImGui/fonts/fontawesome_font.c vendored Normal file

File diff suppressed because it is too large Load Diff

1015
external/ImGui/fonts/fontawesome_font.h vendored Normal file

File diff suppressed because it is too large Load Diff

View File

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

View File

@@ -1,4 +1,4 @@
// dear imgui, v1.80 WIP
// dear imgui, v1.80
// (headers)
// Help:
@@ -19,28 +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)
// FIXME-TABLE: Add ImGuiTableSortSpecsColumn and ImGuiTableSortSpecs in "Misc data structures" section above (we don't do it right now to facilitate merging various branches)
// [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
@@ -51,7 +48,7 @@ Index of this file:
#ifndef IMGUI_DISABLE
//-----------------------------------------------------------------------------
// Header mess
// [SECTION] Header mess
//-----------------------------------------------------------------------------
// Includes
@@ -62,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 17906
#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)
@@ -85,16 +83,18 @@ Index of this file:
#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))) // Apply printf-style warnings to our formatting functions.
#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))) // Apply printf-style warnings to our formatting functions.
#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)
@@ -110,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
@@ -144,7 +144,7 @@ struct ImGuiSizeCallbackData; // Callback data when using SetNextWindowSiz
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 ImGuiTableSortSpecsColumn; // Sorting specification for one column of a table
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)
@@ -196,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.
@@ -244,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.
@@ -253,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
@@ -276,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 ShowAboutWindow(bool* p_open = NULL); // create About window. display Dear ImGui version, credits and build/system information.
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 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.
@@ -351,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.
@@ -373,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 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();
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 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 -1.0f always align width to the right side)
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.
@@ -475,7 +478,7 @@ namespace ImGui
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
@@ -577,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
@@ -621,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().
@@ -665,62 +668,62 @@ namespace ImGui
IMGUI_API bool IsPopupOpen(const char* str_id, ImGuiPopupFlags flags = 0); // return true if the popup is open.
// Tables
// [ALPHA API] API may evolve!
// [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 details.
// - 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 will be pulled from data submitted to TableSetupColumns)
// - 5. Populate contents
// - In most situations you can use TableNextRow() + TableSetColumnIndex(xx) to start appending into a column.
// - 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!
// - Both TableSetColumnIndex() and TableNextColumn() return false when the column is not visible, so you can
// skip submitting the contents of a cell but only if you know the contents is not going to alter row height.
// - 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!
// ----------------------------------------------------------------------------------------------------------
// --------------------------------------------------------------------------------------------------------
// 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()
#define IMGUI_HAS_TABLE 1
IMGUI_API bool BeginTable(const char* str_id, int columns_count, ImGuiTableFlags flags = 0, const ImVec2& outer_size = ImVec2(0, 0), float inner_width = 0.0f);
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 false when column is not visible.
IMGUI_API bool TableSetColumnIndex(int column_n); // append into the specified column. Return false when column is not visible.
IMGUI_API int TableGetColumnIndex(); // return current column index.
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.
// Important: this will not display anything! The name passed to TableSetupColumn() is used by TableHeadersRow() and context-menus.
// - Use TableHeadersRow() to create a row and automatically submit a TableHeader() for each column.
// Headers are required to perform: reordering, sorting, and opening the context menu (but context menu can also be available in columns body using ImGuiTableFlags_ContextMenuInBody).
// - You may manually submit headers using TableNextRow() + TableHeader() calls, but this is only useful in some advanced cases (e.g. adding custom widgets in header row).
// - Use TableSetupScrollFreeze() to lock columns (from the right) or rows (from the top) so they stay visible when scrolled.
IMGUI_API void TableSetupColumn(const char* label, ImGuiTableColumnFlags flags = 0, float init_width_or_weight = -1.0f, ImU32 user_id = 0);
// - 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
// - Most functions taking 'int column_n' treat the default value of -1 as the same as passing the current column index
// - Sorting: call TableGetSortSpecs() to retrieve latest sort specs for the table. Return value will be NULL if no 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 int TableGetColumnCount(); // return number of columns (value passed to BeginTable)
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 bool TableGetColumnIsVisible(int column_n = -1); // return true if column is visible. Same value is also returned by TableNextColumn() and TableSetColumnIndex(). Pass -1 to use current column.
IMGUI_API bool TableGetColumnIsSorted(int column_n = -1); // return true if column is included in the sort specs. Rarely used, can be useful to tell if a data change should trigger resort. Equivalent to test ImGuiTableSortSpecs's ->ColumnsMask & (1 << column_n). Pass -1 to use current column.
IMGUI_API int TableGetHoveredColumn(); // return hovered column. return -1 when table is not hovered. return columns_count if the unused space at the right of visible columns is hovered.
IMGUI_API ImGuiTableSortSpecs* TableGetSortSpecs(); // get latest sort specs for the table (NULL if not sorting).
IMGUI_API void TableSetBgColor(ImGuiTableBgTarget bg_target, ImU32 color, int column_n = -1); // change the color of a cell, row, or column. See ImGuiTableBgTarget_ flags for details.
// - 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.
@@ -767,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.
@@ -778,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();
@@ -900,7 +903,7 @@ namespace ImGui
} // namespace ImGui
//-----------------------------------------------------------------------------
// Flags & Enumerations
// [SECTION] Flags & Enumerations
//-----------------------------------------------------------------------------
// Flags for ImGui::Begin()
@@ -1076,93 +1079,122 @@ enum ImGuiTabItemFlags_
};
// Flags for ImGui::BeginTable()
// - Important! Sizing policies have particularly complex and subtle side effects, more so than you would expect.
// [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 policy for columns depends on whether the ScrollX flag is set on the table:
// When ScrollX is off:
// - Table defaults to ImGuiTableFlags_SizingPolicyStretchX -> all Columns defaults to ImGuiTableColumnFlags_WidthStretch.
// - Columns sizing policy allowed: Fixed/Auto or Stretch.
// - Stretch Columns will share the width available in table.
// - Fixed Columns will generally obtain their requested width unless the Table cannot fit them all.
// When ScrollX is on:
// - Table defaults to ImGuiTableFlags_SizingPolicyFixedX -> all Columns defaults to ImGuiTableColumnFlags_WidthFixed.
// - Columns sizing policy allowed: Fixed/Auto mostly! Using Stretch columns OFTEN DOES NOT MAKE SENSE if ScrollX is on, UNLESS you have specified a value for 'inner_width' in BeginTable().
// - 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.
// - Stretch Columns, if any, will calculate their width using inner_width, assuming no scrolling (it really doesn't make sense to do otherwise).
// - Mixing up columns with different sizing policy is possible BUT can be tricky and has some side-effects and restrictions.
// (their visible order and the scrolling state have subtle but necessary effects on how they can be manually resized).
// The typical use of mixing sizing policies is to have ScrollX disabled, one or two Stretch Column and many Fixed Columns.
// - 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, // Allow resizing columns.
ImGuiTableFlags_Reorderable = 1 << 1, // Allow reordering columns in header row (need calling TableSetupColumn() + TableHeadersRow() to display headers)
ImGuiTableFlags_Hideable = 1 << 2, // Allow hiding columns in context menu.
ImGuiTableFlags_Sortable = 1 << 3, // Allow sorting on one column (sort_specs_count will always be == 1). Call TableGetSortSpecs() to obtain sort specs.
ImGuiTableFlags_MultiSortable = 1 << 4, // Allow sorting on multiple columns by holding Shift (sort_specs_count may be > 1). Call TableGetSortSpecs() to obtain sort specs.
ImGuiTableFlags_NoSavedSettings = 1 << 5, // Disable persisting columns order, width and sort settings in the .ini file.
ImGuiTableFlags_ContextMenuInBody = 1 << 6, // Right-click on columns body/contents will display table context menu. By default it is available in TableHeadersRow().
// Decoration
ImGuiTableFlags_RowBg = 1 << 7, // Set each RowBg color with ImGuiCol_TableRowBg or ImGuiCol_TableRowBgAlt (equivalent to calling TableSetBgColor with ImGuiTableBgFlags_RowBg0 on each row manually)
ImGuiTableFlags_BordersInnerH = 1 << 8, // Draw horizontal borders between rows.
ImGuiTableFlags_BordersOuterH = 1 << 9, // Draw horizontal borders at the top and bottom.
ImGuiTableFlags_BordersInnerV = 1 << 10, // Draw vertical borders between columns.
ImGuiTableFlags_BordersOuterV = 1 << 11, // 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 << 12, // Disable vertical borders in columns Body (borders will always appears in Headers).
ImGuiTableFlags_NoBordersInBodyUntilResize = 1 << 13, // Disable vertical borders in columns Body until hovered for resize (borders will always appears in Headers).
// Sizing
ImGuiTableFlags_SizingPolicyFixedX = 1 << 14, // Default if ScrollX is on. Columns will default to use _WidthFixed or _WidthAlwaysAutoResize policy. Read description above for more details.
ImGuiTableFlags_SizingPolicyStretchX = 1 << 15, // Default if ScrollX is off. Columns will default to use _WidthStretch policy. Read description above for more details.
ImGuiTableFlags_NoHeadersWidth = 1 << 16, // Disable header width contribution to automatic width calculation.
ImGuiTableFlags_NoHostExtendY = 1 << 17, // (FIXME-TABLE: Reword as SizingPolicy?) Disable extending past the limit set by outer_size.y, only meaningful when neither of ScrollX|ScrollY are set (data below the limit will be clipped and not visible)
ImGuiTableFlags_NoKeepColumnsVisible = 1 << 18, // Disable keeping column always minimally visible when table width gets too small and ScrllX is off.
ImGuiTableFlags_PreciseStretchWidths = 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.
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().
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.
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).
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.
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_SizingPolicyMaskX_ = ImGuiTableFlags_SizingPolicyStretchX | ImGuiTableFlags_SizingPolicyFixedX
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()
// FIXME-TABLE: Rename to ImGuiColumns_*, stick old columns api flags in there under an obsolete api block
enum ImGuiTableColumnFlags_
{
ImGuiTableColumnFlags_None = 0,
ImGuiTableColumnFlags_DefaultHide = 1 << 0, // Default as a hidden column.
ImGuiTableColumnFlags_DefaultSort = 1 << 1, // Default as a sorting column.
ImGuiTableColumnFlags_WidthFixed = 1 << 2, // Column will keep a fixed size, preferable with horizontal scrolling enabled (default if table sizing policy is SizingPolicyFixedX and table is resizable).
ImGuiTableColumnFlags_WidthStretch = 1 << 3, // Column will stretch, preferable with horizontal scrolling disabled (default if table sizing policy is SizingPolicyStretchX).
ImGuiTableColumnFlags_WidthAlwaysAutoResize = 1 << 4, // Column will keep resizing based on submitted contents (with a one frame delay) == Fixed with auto resize (default if table sizing policy is SizingPolicyFixedX and table is not resizable).
ImGuiTableColumnFlags_NoResize = 1 << 5, // Disable manual resizing.
ImGuiTableColumnFlags_NoClipX = 1 << 6, // Disable clipping for this column (all NoClipX columns will render in a same draw command).
ImGuiTableColumnFlags_NoSort = 1 << 7, // Disable ability to sort on this field (even if ImGuiTableFlags_Sortable is set on the table).
ImGuiTableColumnFlags_NoSortAscending = 1 << 8, // Disable ability to sort in the ascending direction.
ImGuiTableColumnFlags_NoSortDescending = 1 << 9, // Disable ability to sort in the descending direction.
ImGuiTableColumnFlags_NoHide = 1 << 10, // Disable hiding this column.
ImGuiTableColumnFlags_NoHeaderWidth = 1 << 11, // Header width don't contribute 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 1st column).
ImGuiTableColumnFlags_IndentDisable = 1 << 15, // Ignore current Indent value when entering cell (default for columns after the 1st one). Indentation changes _within_ the cell will still be honored.
ImGuiTableColumnFlags_NoReorder = 1 << 16, // Disable reordering this column, this will also prevent other columns from crossing over this column.
// 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_WidthFixed | ImGuiTableColumnFlags_WidthStretch | ImGuiTableColumnFlags_WidthAlwaysAutoResize,
ImGuiTableColumnFlags_IndentMask_ = ImGuiTableColumnFlags_IndentEnable | ImGuiTableColumnFlags_IndentDisable,
ImGuiTableColumnFlags_NoDirectResize_ = 1 << 20 // [Internal] Disable user resizing this column directly (it may however we resized indirectly from its left edge)
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()
@@ -1184,11 +1216,9 @@ enum ImGuiTableRowFlags_
enum ImGuiTableBgTarget_
{
ImGuiTableBgTarget_None = 0,
//ImGuiTableBgTarget_ColumnBg0 = 1, // FIXME-TABLE: Todo. Set column background color 0 (generally used for background
//ImGuiTableBgTarget_ColumnBg1 = 2, // FIXME-TABLE: Todo. Set column background color 1 (generally used for selection marking)
ImGuiTableBgTarget_RowBg0 = 3, // Set row background color 0 (generally used for background, automatically set when ImGuiTableFlags_RowBg is used)
ImGuiTableBgTarget_RowBg1 = 4, // Set row background color 1 (generally used for selection marking)
ImGuiTableBgTarget_CellBg = 5 // Set cell background color (top-most color)
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()
@@ -1332,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
@@ -1463,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.
@@ -1623,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.
@@ -1639,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.
@@ -1709,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.
@@ -1763,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.
//-----------------------------------------------------------------------------
@@ -1804,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 ConfigMemoryCompactTimer; // = 60.0f // [BETA] Free transient windows/tables memory buffers when unused for given amount of time. 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
@@ -1905,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.
@@ -1969,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()
@@ -1999,15 +2031,15 @@ struct ImGuiPayload
bool IsDelivery() const { return Delivery; }
};
// Sorting specification for one column of a table (sizeof == 8 bytes)
struct ImGuiTableSortSpecsColumn
// 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)
ImU8 ColumnIndex; // Index of the column
ImU8 SortOrder; // Index within parent ImGuiTableSortSpecs (always stored in order starting from 0, tables sorted on a single criteria will always have a 0 here)
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)
ImGuiTableSortSpecsColumn() { ColumnUserID = 0; ColumnIndex = 0; SortOrder = 0; SortDirection = ImGuiSortDirection_Ascending; }
ImGuiTableColumnSortSpecs() { memset(this, 0, sizeof(*this)); }
};
// Sorting specifications for a table (often handling sort specs for a single column, occasionally more)
@@ -2016,16 +2048,16 @@ struct ImGuiTableSortSpecsColumn
// Make sure to set 'SpecsDirty = false' after sorting, else you may wastefully sort your data every frame!
struct ImGuiTableSortSpecs
{
const ImGuiTableSortSpecsColumn* Specs; // Pointer to sort spec array.
int SpecsCount; // Sort spec count. Most often 1 unless e.g. ImGuiTableFlags_MultiSortable is enabled.
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.
ImU64 ColumnsMask; // Set to the mask of column indexes included in the Specs array. e.g. (1 << N) when column N is sorted.
ImGuiTableSortSpecs() { Specs = NULL; SpecsCount = 0; SpecsDirty = false; ColumnsMask = 0x00; }
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.
//-----------------------------------------------------------------------------
@@ -2061,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
@@ -2271,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.
//-----------------------------------------------------------------------------
@@ -2423,6 +2451,7 @@ struct ImDrawList
ImVector<ImVec2> _Path; // [Internal] current path building
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) { memset(this, 0, sizeof(*this)); _Data = shared_data; }
@@ -2458,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.
@@ -2475,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
@@ -2506,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();
@@ -2539,7 +2575,7 @@ struct ImDrawData
};
//-----------------------------------------------------------------------------
// Font API (ImFontConfig, ImFontGlyph, ImFontAtlasFlags, ImFontAtlas, ImFontGlyphRangesBuilder, ImFont)
// [SECTION] Font API (ImFontConfig, ImFontGlyph, ImFontAtlasFlags, ImFontAtlas, ImFontGlyphRangesBuilder, ImFont)
//-----------------------------------------------------------------------------
struct ImFontConfig
@@ -2670,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
@@ -2782,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
View 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);
}

View File

@@ -0,0 +1,39 @@
#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));
void Disabled(const std::function<void()> &widgets, bool disabled);
void TextSpinner(const char* label);
void Header(const char *label, bool firstEntry = false);
std::tuple<ImTextureID, int, int> LoadImageFromPath(const char *path);
void UnloadImage(ImTextureID texture);
enum ImGuiCustomCol {
ImGuiCustomCol_DescButton,
ImGuiCustomCol_DescButtonHovered,
ImGuiCustomCol_DescButtonActive,
ImGuiCustomCol_COUNT
};
struct ImHexCustomData {
ImVec4 Colors[ImGuiCustomCol_COUNT];
};
ImU32 GetCustomColorU32(ImGuiCustomCol idx, float alpha_mul = 1.0F);
void StyleCustomColorsDark();
void StyleCustomColorsLight();
void StyleCustomColorsClassic();
}

View File

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

View File

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

View File

@@ -1,4 +1,4 @@
// dear imgui, v1.80 WIP
// dear imgui, v1.80
// (internal structures/api)
// You may use this file to debug, understand or extend ImGui features but we don't provide any guarantee of forward compatibility!
@@ -92,8 +92,6 @@ struct ImRect; // An axis-aligned rectangle (2 points)
struct ImDrawDataBuilder; // Helper to build a ImDrawData instance
struct ImDrawListSharedData; // Data shared between all ImDrawList instances
struct ImGuiColorMod; // Stacked color modifier, backup of modified data so we can restore it
struct ImGuiColumnData; // Storage data for a single column
struct ImGuiColumns; // Storage data for a columns set
struct ImGuiContext; // Main Dear ImGui context
struct ImGuiContextHook; // Hook for extensions like ImGuiTestEngine
struct ImGuiDataTypeInfo; // Type information associated to a ImGuiDataType enum
@@ -109,6 +107,8 @@ struct ImGuiNavMoveResult; // Result of a gamepad/keyboard directional
struct ImGuiMetricsConfig; // Storage for ShowMetricsWindow() and DebugNodeXXX() functions
struct ImGuiNextWindowData; // Storage for SetNextWindow** functions
struct ImGuiNextItemData; // Storage for SetNextItem** functions
struct ImGuiOldColumnData; // Storage data for a single column for legacy Columns() api
struct ImGuiOldColumns; // Storage data for a columns set for legacy Columns() api
struct ImGuiPopupData; // Storage for current popup stack
struct ImGuiSettingsHandler; // Storage for one type registered in the .ini file
struct ImGuiStackSizes; // Storage of stack sizes for debugging/asserting
@@ -126,10 +126,9 @@ struct ImGuiWindowSettings; // Storage for a window .ini settings (we ke
// Use your programming IDE "Go to definition" facility on the names of the center columns to find the actual flags/enum lists.
typedef int ImGuiDataAuthority; // -> enum ImGuiDataAuthority_ // Enum: for storing the source authority (dock node vs window) of a field
typedef int ImGuiLayoutType; // -> enum ImGuiLayoutType_ // Enum: Horizontal or vertical
typedef int ImGuiButtonFlags; // -> enum ImGuiButtonFlags_ // Flags: for ButtonEx(), ButtonBehavior()
typedef int ImGuiColumnsFlags; // -> enum ImGuiColumnsFlags_ // Flags: BeginColumns()
typedef int ImGuiItemFlags; // -> enum ImGuiItemFlags_ // Flags: for PushItemFlag()
typedef int ImGuiItemStatusFlags; // -> enum ImGuiItemStatusFlags_ // Flags: for DC.LastItemStatusFlags
typedef int ImGuiOldColumnFlags; // -> enum ImGuiOldColumnFlags_ // Flags: for BeginColumns()
typedef int ImGuiNavHighlightFlags; // -> enum ImGuiNavHighlightFlags_ // Flags: for RenderNavHighlight()
typedef int ImGuiNavDirSourceFlags; // -> enum ImGuiNavDirSourceFlags_ // Flags: for GetNavInputAmount2d()
typedef int ImGuiNavMoveFlags; // -> enum ImGuiNavMoveFlags_ // Flags: for navigation requests
@@ -139,6 +138,8 @@ typedef int ImGuiSeparatorFlags; // -> enum ImGuiSeparatorFlags_ // F
typedef int ImGuiTextFlags; // -> enum ImGuiTextFlags_ // Flags: for TextEx()
typedef int ImGuiTooltipFlags; // -> enum ImGuiTooltipFlags_ // Flags: for BeginTooltipEx()
typedef void (*ImGuiErrorLogCallback)(void* user_data, const char* fmt, ...);
//-----------------------------------------------------------------------------
// [SECTION] Context pointer
// See implementation of this variable in imgui.cpp for comments and details.
@@ -189,7 +190,7 @@ namespace ImStb
#define IMGUI_DEBUG_LOG_DOCKING(...) ((void)0) // Disable log
// Static Asserts
#if (__cplusplus >= 201100)
#if (__cplusplus >= 201100) || (defined(_MSVC_LANG) && _MSVC_LANG >= 201100)
#define IM_STATIC_ASSERT(_COND) static_assert(_COND, "")
#else
#define IM_STATIC_ASSERT(_COND) typedef char static_assertion_##__line__[(_COND)?1:-1]
@@ -266,10 +267,10 @@ namespace ImStb
//-----------------------------------------------------------------------------
// Helpers: Hashing
IMGUI_API ImU32 ImHashData(const void* data, size_t data_size, ImU32 seed = 0);
IMGUI_API ImU32 ImHashStr(const char* data, size_t data_size = 0, ImU32 seed = 0);
IMGUI_API ImGuiID ImHashData(const void* data, size_t data_size, ImU32 seed = 0);
IMGUI_API ImGuiID ImHashStr(const char* data, size_t data_size = 0, ImU32 seed = 0);
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
static inline ImU32 ImHash(const void* data, int size, ImU32 seed = 0) { return size ? ImHashData(data, (size_t)size, seed) : ImHashStr((const char*)data, 0, seed); } // [moved to ImHashStr/ImHashData in 1.68]
static inline ImGuiID ImHash(const void* data, int size, ImU32 seed = 0) { return size ? ImHashData(data, (size_t)size, seed) : ImHashStr((const char*)data, 0, seed); } // [moved to ImHashStr/ImHashData in 1.68]
#endif
// Helpers: Sorting
@@ -407,9 +408,10 @@ static inline float ImLinearSweep(float current, float target, float speed)
static inline ImVec2 ImMul(const ImVec2& lhs, const ImVec2& rhs) { return ImVec2(lhs.x * rhs.x, lhs.y * rhs.y); }
// Helpers: Geometry
IMGUI_API ImVec2 ImBezierCalc(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, float t); // Cubic Bezier
IMGUI_API ImVec2 ImBezierClosestPoint(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, const ImVec2& p, int num_segments); // For curves with explicit number of segments
IMGUI_API ImVec2 ImBezierClosestPointCasteljau(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, const ImVec2& p, float tess_tol);// For auto-tessellated curves you can use tess_tol = style.CurveTessellationTol
IMGUI_API ImVec2 ImBezierCubicCalc(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, float t);
IMGUI_API ImVec2 ImBezierCubicClosestPoint(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, const ImVec2& p, int num_segments); // For curves with explicit number of segments
IMGUI_API ImVec2 ImBezierCubicClosestPointCasteljau(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, const ImVec2& p, float tess_tol);// For auto-tessellated curves you can use tess_tol = style.CurveTessellationTol
IMGUI_API ImVec2 ImBezierQuadraticCalc(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, float t);
IMGUI_API ImVec2 ImLineClosestPoint(const ImVec2& a, const ImVec2& b, const ImVec2& p);
IMGUI_API bool ImTriangleContainsPoint(const ImVec2& a, const ImVec2& b, const ImVec2& c, const ImVec2& p);
IMGUI_API ImVec2 ImTriangleClosestPoint(const ImVec2& a, const ImVec2& b, const ImVec2& c, const ImVec2& p);
@@ -476,8 +478,9 @@ struct IMGUI_API ImRect
inline bool ImBitArrayTestBit(const ImU32* arr, int n) { ImU32 mask = (ImU32)1 << (n & 31); return (arr[n >> 5] & mask) != 0; }
inline void ImBitArrayClearBit(ImU32* arr, int n) { ImU32 mask = (ImU32)1 << (n & 31); arr[n >> 5] &= ~mask; }
inline void ImBitArraySetBit(ImU32* arr, int n) { ImU32 mask = (ImU32)1 << (n & 31); arr[n >> 5] |= mask; }
inline void ImBitArraySetBitRange(ImU32* arr, int n, int n2)
inline void ImBitArraySetBitRange(ImU32* arr, int n, int n2) // Works on range [n..n2)
{
n2--;
while (n <= n2)
{
int a_mod = (n & 31);
@@ -495,11 +498,12 @@ struct IMGUI_API ImBitArray
{
ImU32 Storage[(BITCOUNT + 31) >> 5];
ImBitArray() { }
void ClearBits() { memset(Storage, 0, sizeof(Storage)); }
void ClearAllBits() { memset(Storage, 0, sizeof(Storage)); }
void SetAllBits() { memset(Storage, 255, sizeof(Storage)); }
bool TestBit(int n) const { IM_ASSERT(n < BITCOUNT); return ImBitArrayTestBit(Storage, n); }
void SetBit(int n) { IM_ASSERT(n < BITCOUNT); ImBitArraySetBit(Storage, n); }
void ClearBit(int n) { IM_ASSERT(n < BITCOUNT); ImBitArrayClearBit(Storage, n); }
void SetBitRange(int n1, int n2) { ImBitArraySetBitRange(Storage, n1, n2); }
void SetBitRange(int n, int n2) { ImBitArraySetBitRange(Storage, n, n2); } // Works on range [n..n2)
};
// Helper: ImBitVector
@@ -530,6 +534,7 @@ struct ImSpan
inline void set(T* data, int size) { Data = data; DataEnd = data + size; }
inline void set(T* data, T* data_end) { Data = data; DataEnd = data_end; }
inline int size() const { return (int)(ptrdiff_t)(DataEnd - Data); }
inline int size_in_bytes() const { return (int)(ptrdiff_t)(DataEnd - Data) * (int)sizeof(T); }
inline T& operator[](int i) { T* p = Data + i; IM_ASSERT(p >= Data && p < DataEnd); return *p; }
inline const T& operator[](int i) const { const T* p = Data + i; IM_ASSERT(p >= Data && p < DataEnd); return *p; }
@@ -1081,31 +1086,41 @@ struct ImGuiPtrOrIndex
// [SECTION] Columns support
//-----------------------------------------------------------------------------
enum ImGuiColumnsFlags_
// Flags for internal's BeginColumns(). Prefix using BeginTable() nowadays!
enum ImGuiOldColumnFlags_
{
// Default: 0
ImGuiColumnsFlags_None = 0,
ImGuiColumnsFlags_NoBorder = 1 << 0, // Disable column dividers
ImGuiColumnsFlags_NoResize = 1 << 1, // Disable resizing columns when clicking on the dividers
ImGuiColumnsFlags_NoPreserveWidths = 1 << 2, // Disable column width preservation when adjusting columns
ImGuiColumnsFlags_NoForceWithinWindow = 1 << 3, // Disable forcing columns to fit within window
ImGuiColumnsFlags_GrowParentContentsSize= 1 << 4 // (WIP) Restore pre-1.51 behavior of extending the parent window contents size but _without affecting the columns width at all_. Will eventually remove.
ImGuiOldColumnFlags_None = 0,
ImGuiOldColumnFlags_NoBorder = 1 << 0, // Disable column dividers
ImGuiOldColumnFlags_NoResize = 1 << 1, // Disable resizing columns when clicking on the dividers
ImGuiOldColumnFlags_NoPreserveWidths = 1 << 2, // Disable column width preservation when adjusting columns
ImGuiOldColumnFlags_NoForceWithinWindow = 1 << 3, // Disable forcing columns to fit within window
ImGuiOldColumnFlags_GrowParentContentsSize = 1 << 4 // (WIP) Restore pre-1.51 behavior of extending the parent window contents size but _without affecting the columns width at all_. Will eventually remove.
// Obsolete names (will be removed)
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
, ImGuiColumnsFlags_None = ImGuiOldColumnFlags_None,
ImGuiColumnsFlags_NoBorder = ImGuiOldColumnFlags_NoBorder,
ImGuiColumnsFlags_NoResize = ImGuiOldColumnFlags_NoResize,
ImGuiColumnsFlags_NoPreserveWidths = ImGuiOldColumnFlags_NoPreserveWidths,
ImGuiColumnsFlags_NoForceWithinWindow = ImGuiOldColumnFlags_NoForceWithinWindow,
ImGuiColumnsFlags_GrowParentContentsSize = ImGuiOldColumnFlags_GrowParentContentsSize
#endif
};
struct ImGuiColumnData
struct ImGuiOldColumnData
{
float OffsetNorm; // Column start offset, normalized 0.0 (far left) -> 1.0 (far right)
float OffsetNormBeforeResize;
ImGuiColumnsFlags Flags; // Not exposed
ImGuiOldColumnFlags Flags; // Not exposed
ImRect ClipRect;
ImGuiColumnData() { memset(this, 0, sizeof(*this)); }
ImGuiOldColumnData() { memset(this, 0, sizeof(*this)); }
};
struct ImGuiColumns
struct ImGuiOldColumns
{
ImGuiID ID;
ImGuiColumnsFlags Flags;
ImGuiOldColumnFlags Flags;
bool IsFirstFrame;
bool IsBeingResized;
int Current;
@@ -1117,10 +1132,10 @@ struct ImGuiColumns
ImRect HostInitialClipRect; // Backup of ClipRect at the time of BeginColumns()
ImRect HostBackupClipRect; // Backup of ClipRect during PushColumnsBackground()/PopColumnsBackground()
ImRect HostBackupParentWorkRect;//Backup of WorkRect at the time of BeginColumns()
ImVector<ImGuiColumnData> Columns;
ImVector<ImGuiOldColumnData> Columns;
ImDrawListSplitter Splitter;
ImGuiColumns() { memset(this, 0, sizeof(*this)); }
ImGuiOldColumns() { memset(this, 0, sizeof(*this)); }
};
//-----------------------------------------------------------------------------
@@ -1234,13 +1249,33 @@ struct ImGuiDockNode
ImRect Rect() const { return ImRect(Pos.x, Pos.y, Pos.x + Size.x, Pos.y + Size.y); }
};
// List of colors that are stored at the time of Begin() into Docked Windows.
// We currently store the packed colors in a simple array window->DockStyle.Colors[].
// A better solution may involve appending into a log of colors in ImGuiContext + store offsets into those arrays in ImGuiWindow,
// but it would be more complex as we'd need to double-buffer both as e.g. drop target may refer to window from last frame.
enum ImGuiWindowDockStyleCol
{
ImGuiWindowDockStyleCol_Text,
ImGuiWindowDockStyleCol_Tab,
ImGuiWindowDockStyleCol_TabHovered,
ImGuiWindowDockStyleCol_TabActive,
ImGuiWindowDockStyleCol_TabUnfocused,
ImGuiWindowDockStyleCol_TabUnfocusedActive,
ImGuiWindowDockStyleCol_COUNT
};
struct ImGuiWindowDockStyle
{
ImU32 Colors[ImGuiWindowDockStyleCol_COUNT];
};
struct ImGuiDockContext
{
ImGuiStorage Nodes; // Map ID -> ImGuiDockNode*: Active nodes
ImVector<ImGuiDockRequest> Requests;
ImVector<ImGuiDockNodeSettings> NodesSettings;
bool WantFullRebuild;
ImGuiDockContext() { WantFullRebuild = false; }
ImGuiDockContext() { memset(this, 0, sizeof(*this)); }
};
#endif // #ifdef IMGUI_HAS_DOCK
@@ -1362,8 +1397,8 @@ struct IMGUI_API ImGuiStackSizes
short SizeOfBeginPopupStack;
ImGuiStackSizes() { memset(this, 0, sizeof(*this)); }
IMGUI_API void SetToCurrentState();
IMGUI_API void CompareWithCurrentState();
void SetToCurrentState();
void CompareWithCurrentState();
};
//-----------------------------------------------------------------------------
@@ -1431,9 +1466,11 @@ struct ImGuiContext
float WheelingWindowTimer;
// Item/widgets state and tracking information
ImGuiID HoveredId; // Hovered widget
ImGuiID HoveredId; // Hovered widget, filled during the frame
ImGuiID HoveredIdPreviousFrame;
bool HoveredIdAllowOverlap;
bool HoveredIdUsingMouseWheel; // Hovered widget will use mouse wheel. Blocks scrolling the underlying window.
bool HoveredIdPreviousFrameUsingMouseWheel;
bool HoveredIdDisabled; // At least one widget passed the rect test, but has been discarded by disabled flag or popup inhibit. May be true even if HoveredId == 0.
float HoveredIdTimer; // Measure contiguous hovering time
float HoveredIdNotActiveTimer; // Measure contiguous hovering time where the item has not been active
@@ -1446,6 +1483,7 @@ struct ImGuiContext
bool ActiveIdHasBeenPressedBefore; // Track whether the active id led to a press (this is to allow changing between PressOnClick and PressOnRelease without pressing twice). Used by range_select branch.
bool ActiveIdHasBeenEditedBefore; // Was the value associated to the widget Edited over the course of the Active state.
bool ActiveIdHasBeenEditedThisFrame;
bool ActiveIdUsingMouseWheel; // Active widget will want to read mouse wheel. Blocks scrolling the underlying window.
ImU32 ActiveIdUsingNavDirMask; // Active widget will want to read those nav move requests (e.g. can activate a button and move away from it)
ImU32 ActiveIdUsingNavInputMask; // Active widget will want to read those nav inputs.
ImU64 ActiveIdUsingKeyInputMask; // Active widget will want to read those key inputs. When we grow the ImGuiKey enum we'll need to either to order the enum to make useful keys come first, either redesign this into e.g. a small array.
@@ -1591,6 +1629,7 @@ struct ImGuiContext
float DragSpeedDefaultRatio; // If speed == 0.0f, uses (max-min) * DragSpeedDefaultRatio
float ScrollbarClickDeltaToGrabCenter; // Distance between mouse and center of grab box, normalized in parent space. Use storage?
int TooltipOverrideCount;
float TooltipSlowDelay; // Time before slow tooltips appears (FIXME: This is temporary until we merge in tooltip timer+priority work)
ImVector<char> ClipboardHandlerData; // If no custom clipboard handler is defined
ImVector<ImGuiID> MenusIdSubmittedThisFrame; // A list of menu IDs that were rendered at least once
@@ -1667,6 +1706,7 @@ struct ImGuiContext
HoveredId = HoveredIdPreviousFrame = 0;
HoveredIdAllowOverlap = false;
HoveredIdUsingMouseWheel = HoveredIdPreviousFrameUsingMouseWheel = false;
HoveredIdDisabled = false;
HoveredIdTimer = HoveredIdNotActiveTimer = 0.0f;
ActiveId = 0;
@@ -1678,6 +1718,7 @@ struct ImGuiContext
ActiveIdHasBeenPressedBefore = false;
ActiveIdHasBeenEditedBefore = false;
ActiveIdHasBeenEditedThisFrame = false;
ActiveIdUsingMouseWheel = false;
ActiveIdUsingNavDirMask = 0x00;
ActiveIdUsingNavInputMask = 0x00;
ActiveIdUsingKeyInputMask = 0x00;
@@ -1761,6 +1802,7 @@ struct ImGuiContext
DragSpeedDefaultRatio = 1.0f / 100.0f;
ScrollbarClickDeltaToGrabCenter = 0.0f;
TooltipOverrideCount = 0;
TooltipSlowDelay = 0.50f;
PlatformImePos = PlatformImeLastPos = ImVec2(FLT_MAX, FLT_MAX);
PlatformImePosViewport = 0;
@@ -1801,7 +1843,8 @@ struct IMGUI_API ImGuiWindowTempData
ImVec2 CursorPos; // Current emitting position, in absolute coordinates.
ImVec2 CursorPosPrevLine;
ImVec2 CursorStartPos; // Initial position after Begin(), generally ~ window position + WindowPadding.
ImVec2 CursorMaxPos; // Used to implicitly calculate the size of our contents, always growing during the frame. Used to calculate window->ContentSize at the beginning of next frame
ImVec2 CursorMaxPos; // Used to implicitly calculate ContentSize at the beginning of next frame, for scrolling range and auto-resize. Always growing during the frame.
ImVec2 IdealMaxPos; // Used to implicitly calculate ContentSizeIdeal at the beginning of next frame, for auto-resize only. Always growing during the frame.
ImVec2 CurrLineSize;
ImVec2 PrevLineSize;
float CurrLineTextBaseOffset; // Baseline offset (0.0f by default on a new line, generally == style.FramePadding.y when a framed item has been added).
@@ -1832,7 +1875,7 @@ struct IMGUI_API ImGuiWindowTempData
ImU32 TreeJumpToParentOnPopMask; // Store a copy of !g.NavIdIsAlive for TreeDepth 0..31.. Could be turned into a ImU64 if necessary.
ImVector<ImGuiWindow*> ChildWindows;
ImGuiStorage* StateStorage; // Current persistent per-window storage (store e.g. tree node open/close state)
ImGuiColumns* CurrentColumns; // Current columns set
ImGuiOldColumns* CurrentColumns; // Current columns set
int CurrentTableIdx; // Current table index (into g.Tables)
ImGuiLayoutType LayoutType;
ImGuiLayoutType ParentLayoutType; // Layout type of parent window at the time of Begin()
@@ -1864,6 +1907,7 @@ struct IMGUI_API ImGuiWindow
ImVec2 Size; // Current size (==SizeFull or collapsed title bar size)
ImVec2 SizeFull; // Size when non collapsed
ImVec2 ContentSize; // Size of contents/scrollable client area (calculated from the extents reach of the cursor) from previous frame. Does not include window decoration or window padding.
ImVec2 ContentSizeIdeal;
ImVec2 ContentSizeExplicit; // Size of contents/scrollable client area explicitly request by the user via SetNextWindowContentSize().
ImVec2 WindowPadding; // Window padding at the time of Begin().
float WindowRounding; // Window rounding at the time of Begin(). May be clamped lower to avoid rendering artifacts with title bar, menu bar etc.
@@ -1898,12 +1942,13 @@ struct IMGUI_API ImGuiWindow
ImS8 AutoFitChildAxises;
bool AutoFitOnlyGrows;
ImGuiDir AutoPosLastDirection;
int HiddenFramesCanSkipItems; // Hide the window for N frames
int HiddenFramesCannotSkipItems; // Hide the window for N frames while allowing items to be submitted so we can measure their size
ImGuiCond SetWindowPosAllowFlags; // store acceptable condition flags for SetNextWindowPos() use.
ImGuiCond SetWindowSizeAllowFlags; // store acceptable condition flags for SetNextWindowSize() use.
ImGuiCond SetWindowCollapsedAllowFlags; // store acceptable condition flags for SetNextWindowCollapsed() use.
ImGuiCond SetWindowDockAllowFlags; // store acceptable condition flags for SetNextWindowDock() use.
ImS8 HiddenFramesCanSkipItems; // Hide the window for N frames
ImS8 HiddenFramesCannotSkipItems; // Hide the window for N frames while allowing items to be submitted so we can measure their size
ImS8 HiddenFramesForRenderOnly; // Hide the window until frame N at Render() time only
ImGuiCond SetWindowPosAllowFlags : 8; // store acceptable condition flags for SetNextWindowPos() use.
ImGuiCond SetWindowSizeAllowFlags : 8; // store acceptable condition flags for SetNextWindowSize() use.
ImGuiCond SetWindowCollapsedAllowFlags : 8; // store acceptable condition flags for SetNextWindowCollapsed() use.
ImGuiCond SetWindowDockAllowFlags : 8; // store acceptable condition flags for SetNextWindowDock() use.
ImVec2 SetWindowPosVal; // store window position when using a non-zero Pivot (position set needs to be processed when we know the window size)
ImVec2 SetWindowPosPivot; // store window pivot for positioning. ImVec2(0, 0) when positioning from top-left corner; ImVec2(0.5f, 0.5f) for centering; ImVec2(1, 1) for bottom right.
@@ -1927,7 +1972,7 @@ struct IMGUI_API ImGuiWindow
float LastTimeActive; // Last timestamp the window was Active (using float as we don't need high precision there)
float ItemWidthDefault;
ImGuiStorage StateStorage;
ImVector<ImGuiColumns> ColumnsStorage;
ImVector<ImGuiOldColumns> ColumnsStorage;
float FontWindowScale; // User scale multiplier per-window, via SetWindowFontScale()
float FontDpiScale;
int SettingsOffset; // Offset into SettingsWindows[] (offsets are always valid as we only grow the array from the back)
@@ -1949,15 +1994,16 @@ struct IMGUI_API ImGuiWindow
bool MemoryCompacted; // Set when window extraneous data have been garbage collected
// Docking
bool DockIsActive :1; // When docking artifacts are actually visible. When this is set, DockNode is guaranteed to be != NULL. ~~ (DockNode != NULL) && (DockNode->Windows.Size > 1).
bool DockTabIsVisible :1; // Is our window visible this frame? ~~ is the corresponding tab selected?
bool DockTabWantClose :1;
short DockOrder; // Order of the last time the window was visible within its DockNode. This is used to reorder windows that are reappearing on the same frame. Same value between windows that were active and windows that were none are possible.
ImGuiWindowDockStyle DockStyle;
ImGuiDockNode* DockNode; // Which node are we docked into. Important: Prefer testing DockIsActive in many cases as this will still be set when the dock node is hidden.
ImGuiDockNode* DockNodeAsHost; // Which node are we owning (for parent windows)
ImGuiID DockId; // Backup of last valid DockNode->ID, so single window remember their dock node id even when they are not bound any more
ImGuiItemStatusFlags DockTabItemStatusFlags;
ImRect DockTabItemRect;
short DockOrder; // Order of the last time the window was visible within its DockNode. This is used to reorder windows that are reappearing on the same frame. Same value between windows that were active and windows that were none are possible.
bool DockIsActive :1; // When docking artifacts are actually visible. When this is set, DockNode is guaranteed to be != NULL. ~~ (DockNode != NULL) && (DockNode->Windows.Size > 1).
bool DockTabIsVisible :1; // Is our window visible this frame? ~~ is the corresponding tab selected?
bool DockTabWantClose :1;
public:
ImGuiWindow(ImGuiContext* context, const char* name);
@@ -2087,58 +2133,68 @@ struct ImGuiTabBar
#define IM_COL32_DISABLE IM_COL32(0,0,0,1) // Special sentinel code which cannot be used as a regular color.
#define IMGUI_TABLE_MAX_COLUMNS 64 // sizeof(ImU64) * 8. This is solely because we frequently encode columns set in a ImU64.
#define IMGUI_TABLE_MAX_DRAW_CHANNELS (4 + 64 * 2) // See TableUpdateDrawChannels()
#define IMGUI_TABLE_MAX_DRAW_CHANNELS (4 + 64 * 2) // See TableSetupDrawChannels()
// [Internal] sizeof() ~ 100
// We use the terminology "Visible" to refer to a column that is not Hidden by user or settings. However it may still be out of view and clipped (see IsClipped).
// Our current column maximum is 64 but we may raise that in the future.
typedef ImS8 ImGuiTableColumnIdx;
typedef ImU8 ImGuiTableDrawChannelIdx;
// [Internal] sizeof() ~ 104
// We use the terminology "Enabled" to refer to a column that is not Hidden by user/api.
// We use the terminology "Clipped" to refer to a column that is out of sight because of scrolling/clipping.
// This is in contrast with some user-facing api such as IsItemVisible() / IsRectVisible() which use "Visible" to mean "not clipped".
struct ImGuiTableColumn
{
ImRect ClipRect; // Clipping rectangle for the column
ImGuiID UserID; // Optional, value passed to TableSetupColumn()
ImGuiTableColumnFlags FlagsIn; // Flags as they were provided by user. See ImGuiTableColumnFlags_
ImGuiTableColumnFlags Flags; // Effective flags. See ImGuiTableColumnFlags_
ImGuiTableColumnFlags Flags; // Flags after some patching (not directly same as provided by user). See ImGuiTableColumnFlags_
float WidthGiven; // Final/actual width visible == (MaxX - MinX), locked in TableUpdateLayout(). May be > WidthRequest to honor minimum width, may be < WidthRequest to honor shrinking columns down in tight space.
float MinX; // Absolute positions
float MaxX;
float InitStretchWeightOrWidth; // Value passed to TableSetupColumn(). For Width it is a content width (_without padding_).
float StretchWeight; // Master width weight when (Flags & _WidthStretch). Often around ~1.0f initially.
float WidthAuto; // Automatic width
float WidthRequest; // Master width absolute value when !(Flags & _WidthStretch). When Stretch this is derived every frame from StretchWeight in TableUpdateLayout()
float WidthGiven; // Final/actual width visible == (MaxX - MinX), locked in TableUpdateLayout(). May be > WidthRequest to honor minimum width, may be < WidthRequest to honor shrinking columns down in tight space.
float WorkMinX; // Start position for the frame, currently ~(MinX + CellPaddingX)
float WorkMaxX;
float WidthAuto; // Automatic width
float StretchWeight; // Master width weight when (Flags & _WidthStretch). Often around ~1.0f initially.
float InitStretchWeightOrWidth; // Value passed to TableSetupColumn(). For Width it is a content width (_without padding_).
ImRect ClipRect; // Clipping rectangle for the column
ImGuiID UserID; // Optional, value passed to TableSetupColumn()
float WorkMinX; // Contents region min ~(MinX + CellPaddingX + CellSpacingX1) == cursor start position when entering column
float WorkMaxX; // Contents region max ~(MaxX - CellPaddingX - CellSpacingX2)
float ItemWidth; // Current item width for the column, preserved across rows
float ContentMaxXFrozen; // Contents maximum position for frozen rows (apart from headers), from which we can infer content width.
float ContentMaxXUnfrozen;
float ContentMaxXHeadersUsed; // Contents maximum position for headers rows (regardless of freezing). TableHeader() automatically softclip itself + report ideal desired size, to avoid creating extraneous draw calls
float ContentMaxXHeadersIdeal;
ImS16 NameOffset; // Offset into parent ColumnsNames[]
bool IsVisible; // Is the column not marked Hidden by the user? (even if off view, e.g. clipped by scrolling).
bool IsVisibleNextFrame;
bool IsClipped; // Is not actually in view (e.g. not overlapping the host window clipping rectangle).
bool IsSkipItems; // Do we want item submissions to this column to be ignored early on.
ImGuiTableColumnIdx DisplayOrder; // Index within Table's IndexToDisplayOrder[] (column may be reordered by users)
ImGuiTableColumnIdx IndexWithinEnabledSet; // Index within enabled/visible set (<= IndexToDisplayOrder)
ImGuiTableColumnIdx PrevEnabledColumn; // Index of prev enabled/visible column within Columns[], -1 if first enabled/visible column
ImGuiTableColumnIdx NextEnabledColumn; // Index of next enabled/visible column within Columns[], -1 if last enabled/visible column
ImGuiTableColumnIdx SortOrder; // Index of this column within sort specs, -1 if not sorting on this column, 0 for single-sort, may be >0 on multi-sort
ImGuiTableDrawChannelIdx DrawChannelCurrent; // Index within DrawSplitter.Channels[]
ImGuiTableDrawChannelIdx DrawChannelFrozen;
ImGuiTableDrawChannelIdx DrawChannelUnfrozen;
bool IsEnabled; // Is the column not marked Hidden by the user? (even if off view, e.g. clipped by scrolling).
bool IsEnabledNextFrame;
bool IsVisibleX; // Is actually in view (e.g. overlapping the host window clipping rectangle, not scrolled).
bool IsVisibleY;
bool IsRequestOutput; // Return value for TableSetColumnIndex() / TableNextColumn(): whether we request user to output contents or not.
bool IsSkipItems; // Do we want item submissions to this column to be completely ignored (no layout will happen).
bool IsPreserveWidthAuto;
ImS8 NavLayerCurrent; // ImGuiNavLayer in 1 byte
ImS8 DisplayOrder; // Index within Table's IndexToDisplayOrder[] (column may be reordered by users)
ImS8 IndexWithinVisibleSet; // Index within visible set (<= IndexToDisplayOrder)
ImS8 PrevVisibleColumn; // Index of prev visible column within Columns[], -1 if first visible column
ImS8 NextVisibleColumn; // Index of next visible column within Columns[], -1 if last visible column
ImS8 SortOrder; // Index of this column within sort specs, -1 if not sorting on this column, 0 for single-sort, may be >0 on multi-sort
ImS8 SortDirection; // ImGuiSortDirection_Ascending or ImGuiSortDirection_Descending
ImU8 AutoFitQueue; // Queue of 8 values for the next 8 frames to request auto-fit
ImU8 CannotSkipItemsQueue; // Queue of 8 values for the next 8 frames to disable Clipped/SkipItem
ImU8 DrawChannelCurrent; // Index within DrawSplitter.Channels[]
ImU8 DrawChannelFrozen;
ImU8 DrawChannelUnfrozen;
ImU8 SortDirection : 2; // ImGuiSortDirection_Ascending or ImGuiSortDirection_Descending
ImU8 SortDirectionsAvailCount : 2; // Number of available sort directions (0 to 3)
ImU8 SortDirectionsAvailMask : 4; // Mask of available sort directions (1-bit each)
ImU8 SortDirectionsAvailList; // Ordered of available sort directions (2-bits each)
ImGuiTableColumn()
{
memset(this, 0, sizeof(*this));
StretchWeight = WidthRequest = -1.0f;
NameOffset = -1;
IsVisible = IsVisibleNextFrame = true;
DisplayOrder = IndexWithinVisibleSet = -1;
PrevVisibleColumn = NextVisibleColumn = -1;
DisplayOrder = IndexWithinEnabledSet = -1;
PrevEnabledColumn = NextEnabledColumn = -1;
SortOrder = -1;
SortDirection = ImGuiSortDirection_None;
AutoFitQueue = CannotSkipItemsQueue = (1 << 3) - 1; // Skip for three frames
DrawChannelCurrent = DrawChannelFrozen = DrawChannelUnfrozen = (ImU8)-1;
}
};
@@ -2147,26 +2203,27 @@ struct ImGuiTableColumn
// sizeof() ~ 6
struct ImGuiTableCellData
{
ImU32 BgColor; // Actual color
ImS8 Column; // Column number
ImU32 BgColor; // Actual color
ImGuiTableColumnIdx Column; // Column number
};
// FIXME-TABLE: transient data could be stored in a per-stacked table structure: DrawSplitter, SortSpecs, incoming RowData
struct ImGuiTable
{
ImGuiID ID;
ImGuiTableFlags Flags;
void* RawData; // Single allocation to hold Columns[], DisplayOrderToIndex[] and RowCellData[]
ImSpan<ImGuiTableColumn> Columns; // Point within RawData[]
ImSpan<ImS8> DisplayOrderToIndex; // Point within RawData[]. Store display order of columns (when not reordered, the values are 0...Count-1)
ImSpan<ImGuiTableColumnIdx> DisplayOrderToIndex; // Point within RawData[]. Store display order of columns (when not reordered, the values are 0...Count-1)
ImSpan<ImGuiTableCellData> RowCellData; // Point within RawData[]. Store cells background requests for current row.
ImU64 VisibleMaskByIndex; // Column Index -> IsVisible map (== not hidden by user/api) in a format adequate for iterating column without touching cold data
ImU64 VisibleMaskByDisplayOrder; // Column DisplayOrder -> IsVisible map
ImU64 VisibleUnclippedMaskByIndex;// Visible and not Clipped, aka "actually visible" "not hidden by some scrolling"
ImU64 EnabledMaskByDisplayOrder; // Column DisplayOrder -> IsEnabled map
ImU64 EnabledMaskByIndex; // Column Index -> IsEnabled map (== not hidden by user/api) in a format adequate for iterating column without touching cold data
ImU64 VisibleMaskByIndex; // Column Index -> IsVisibleX|IsVisibleY map (== not hidden by user/api && not hidden by scrolling/cliprect)
ImU64 RequestOutputMaskByIndex; // Column Index -> IsVisible || AutoFit (== expect user to submit items)
ImGuiTableFlags SettingsLoadedFlags; // Which data were loaded from the .ini file (e.g. when order is not altered we won't save order)
int SettingsOffset; // Offset in g.SettingsTables
int LastFrameActive;
int ColumnsCount; // Number of columns declared in BeginTable()
int ColumnsVisibleCount; // Number of non-hidden columns (<= ColumnsCount)
int CurrentRow;
int CurrentColumn;
ImS16 InstanceCurrent; // Count of BeginTable() calls with same ID in the same frame (generally 0). This is a little bit similar to BeginCount for a window, but multiple table with same ID look are multiple tables, they are just synched.
@@ -2185,6 +2242,7 @@ struct ImGuiTable
float BorderX1;
float BorderX2;
float HostIndentX;
float MinColumnWidth;
float OuterPaddingX;
float CellPaddingX; // Padding from each borders
float CellPaddingY;
@@ -2193,47 +2251,60 @@ struct ImGuiTable
float LastOuterHeight; // Outer height from last frame
float LastFirstRowHeight; // Height of first row from last frame
float InnerWidth; // User value passed to BeginTable(), see comments at the top of BeginTable() for details.
float ColumnsTotalWidth; // Sum of current column width
float ColumnsGivenWidth; // Sum of current column width
float ColumnsAutoFitWidth; // Sum of ideal column width in order nothing to be clipped, used for auto-fitting and content width submission in outer window
float ResizedColumnNextWidth;
float ResizeLockMinContentsX2; // Lock minimum contents width while resizing down in order to not create feedback loops. But we allow growing the table.
float RefScale; // Reference scale to be able to rescale columns on font/dpi changes.
ImRect OuterRect; // Note: OuterRect.Max.y is often FLT_MAX until EndTable(), unless a height has been specified in BeginTable().
ImRect OuterRect; // Note: for non-scrolling table, OuterRect.Max.y is often FLT_MAX until EndTable(), unless a height has been specified in BeginTable().
ImRect InnerRect; // InnerRect but without decoration. As with OuterRect, for non-scrolling tables, InnerRect.Max.y is
ImRect WorkRect;
ImRect InnerClipRect;
ImRect BgClipRect; // We use this to cpu-clip cell background color fill
ImRect BgClipRectForDrawCmd;
ImRect Bg0ClipRectForDrawCmd; // Actual ImDrawCmd clip rect for BG0/1 channel. This tends to be == OuterWindow->ClipRect at BeginTable() because output in BG0/BG1 is cpu-clipped
ImRect Bg2ClipRectForDrawCmd; // Actual ImDrawCmd clip rect for BG2 channel. This tends to be a correct, tight-fit, because output to BG2 are done by widgets relying on regular ClipRect.
ImRect HostClipRect; // This is used to check if we can eventually merge our columns draw calls into the current draw call of the current window.
ImRect HostBackupWorkRect; // Backup of InnerWindow->WorkRect at the end of BeginTable()
ImRect HostBackupParentWorkRect; // Backup of InnerWindow->ParentWorkRect at the end of BeginTable()
ImRect HostBackupClipRect; // Backup of InnerWindow->ClipRect during PushTableBackground()/PopTableBackground()
ImRect HostBackupInnerClipRect; // Backup of InnerWindow->ClipRect during PushTableBackground()/PopTableBackground()
ImVec2 HostBackupPrevLineSize; // Backup of InnerWindow->DC.PrevLineSize at the end of BeginTable()
ImVec2 HostBackupCurrLineSize; // Backup of InnerWindow->DC.CurrLineSize at the end of BeginTable()
ImVec2 HostBackupCursorMaxPos; // Backup of InnerWindow->DC.CursorMaxPos at the end of BeginTable()
ImVec1 HostBackupColumnsOffset; // Backup of OuterWindow->ColumnsOffset at the end of BeginTable()
ImVec2 UserOuterSize; // outer_size.x passed to BeginTable()
ImVec1 HostBackupColumnsOffset; // Backup of OuterWindow->DC.ColumnsOffset at the end of BeginTable()
float HostBackupItemWidth; // Backup of OuterWindow->DC.ItemWidth at the end of BeginTable()
int HostBackupItemWidthStackSize;// Backup of OuterWindow->DC.ItemWidthStack.Size at the end of BeginTable()
ImGuiWindow* OuterWindow; // Parent window for the table
ImGuiWindow* InnerWindow; // Window holding the table data (== OuterWindow or a child window)
ImGuiTextBuffer ColumnsNames; // Contiguous buffer holding columns names
ImDrawListSplitter DrawSplitter; // We carry our own ImDrawList splitter to allow recursion (FIXME: could be stored outside, worst case we need 1 splitter per recursing table)
ImVector<ImGuiTableSortSpecsColumn> SortSpecsData; // FIXME-OPT: Fixed-size array / small-vector pattern, optimize for single sort spec
ImGuiTableColumnSortSpecs SortSpecsSingle;
ImVector<ImGuiTableColumnSortSpecs> SortSpecsMulti; // FIXME-OPT: Using a small-vector pattern would work be good.
ImGuiTableSortSpecs SortSpecs; // Public facing sorts specs, this is what we return in TableGetSortSpecs()
ImS8 SortSpecsCount;
ImS8 DeclColumnsCount; // Count calls to TableSetupColumn()
ImS8 HoveredColumnBody; // Index of column whose visible region is being hovered. Important: == ColumnsCount when hovering empty region after the right-most column!
ImS8 HoveredColumnBorder; // Index of column whose right-border is being hovered (for resizing).
ImS8 ResizedColumn; // Index of column being resized. Reset when InstanceCurrent==0.
ImS8 LastResizedColumn; // Index of column being resized from previous frame.
ImS8 HeldHeaderColumn; // Index of column header being held.
ImS8 ReorderColumn; // Index of column being reordered. (not cleared)
ImS8 ReorderColumnDir; // -1 or +1
ImS8 RightMostVisibleColumn; // Index of right-most non-hidden column.
ImS8 LeftMostStretchedColumnDisplayOrder; // Display order of left-most stretched column.
ImS8 ContextPopupColumn; // Column right-clicked on, of -1 if opening context menu from a neutral/empty spot
ImS8 FreezeRowsRequest; // Requested frozen rows count
ImS8 FreezeRowsCount; // Actual frozen row count (== FreezeRowsRequest, or == 0 when no scrolling offset)
ImS8 FreezeColumnsRequest; // Requested frozen columns count
ImS8 FreezeColumnsCount; // Actual frozen columns count (== FreezeColumnsRequest, or == 0 when no scrolling offset)
ImS8 RowCellDataCurrent; // Index of current RowCellData[] entry in current row
ImU8 DummyDrawChannel; // Redirect non-visible columns here.
ImU8 Bg1DrawChannelCurrent; // For Selectable() and other widgets drawing accross columns after the freezing line. Index within DrawSplitter.Channels[]
ImU8 Bg1DrawChannelUnfrozen;
ImGuiTableColumnIdx SortSpecsCount;
ImGuiTableColumnIdx ColumnsEnabledCount; // Number of enabled columns (<= ColumnsCount)
ImGuiTableColumnIdx ColumnsEnabledFixedCount; // Number of enabled columns (<= ColumnsCount)
ImGuiTableColumnIdx DeclColumnsCount; // Count calls to TableSetupColumn()
ImGuiTableColumnIdx HoveredColumnBody; // Index of column whose visible region is being hovered. Important: == ColumnsCount when hovering empty region after the right-most column!
ImGuiTableColumnIdx HoveredColumnBorder; // Index of column whose right-border is being hovered (for resizing).
ImGuiTableColumnIdx AutoFitSingleColumn; // Index of single column requesting auto-fit.
ImGuiTableColumnIdx ResizedColumn; // Index of column being resized. Reset when InstanceCurrent==0.
ImGuiTableColumnIdx LastResizedColumn; // Index of column being resized from previous frame.
ImGuiTableColumnIdx HeldHeaderColumn; // Index of column header being held.
ImGuiTableColumnIdx ReorderColumn; // Index of column being reordered. (not cleared)
ImGuiTableColumnIdx ReorderColumnDir; // -1 or +1
ImGuiTableColumnIdx LeftMostStretchedColumn; // Index of left-most stretched column.
ImGuiTableColumnIdx RightMostStretchedColumn; // Index of right-most stretched column.
ImGuiTableColumnIdx RightMostEnabledColumn; // Index of right-most non-hidden column.
ImGuiTableColumnIdx ContextPopupColumn; // Column right-clicked on, of -1 if opening context menu from a neutral/empty spot
ImGuiTableColumnIdx FreezeRowsRequest; // Requested frozen rows count
ImGuiTableColumnIdx FreezeRowsCount; // Actual frozen row count (== FreezeRowsRequest, or == 0 when no scrolling offset)
ImGuiTableColumnIdx FreezeColumnsRequest; // Requested frozen columns count
ImGuiTableColumnIdx FreezeColumnsCount; // Actual frozen columns count (== FreezeColumnsRequest, or == 0 when no scrolling offset)
ImGuiTableColumnIdx RowCellDataCurrent; // Index of current RowCellData[] entry in current row
ImGuiTableDrawChannelIdx DummyDrawChannel; // Redirect non-visible columns here.
ImGuiTableDrawChannelIdx Bg2DrawChannelCurrent; // For Selectable() and other widgets drawing accross columns after the freezing line. Index within DrawSplitter.Channels[]
ImGuiTableDrawChannelIdx Bg2DrawChannelUnfrozen;
bool IsLayoutLocked; // Set by TableUpdateLayout() which is called when beginning the first row.
bool IsInsideRow; // Set when inside TableBeginRow()/TableEndRow().
bool IsInitializing;
@@ -2243,26 +2314,28 @@ struct ImGuiTable
bool IsSettingsRequestLoad;
bool IsSettingsDirty; // Set when table settings have changed and needs to be reported into ImGuiTableSetttings data.
bool IsDefaultDisplayOrder; // Set when display order is unchanged from default (DisplayOrder contains 0...Count-1)
bool IsResetAllRequest;
bool IsResetDisplayOrderRequest;
bool IsUnfrozen; // Set when we got past the frozen row.
bool IsUnfrozenRows; // Set when we got past the frozen row.
bool IsDefaultSizingPolicy; // Set if user didn't explicitely set a sizing policy in BeginTable()
bool MemoryCompacted;
bool HostSkipItems; // Backup of InnerWindow->SkipItem at the end of BeginTable(), because we will overwrite InnerWindow->SkipItem on a per-column basis
IMGUI_API ImGuiTable();
IMGUI_API ~ImGuiTable();
IMGUI_API ImGuiTable() { memset(this, 0, sizeof(*this)); LastFrameActive = -1; }
IMGUI_API ~ImGuiTable() { IM_FREE(RawData); }
};
// sizeof() ~ 12
struct ImGuiTableColumnSettings
{
float WidthOrWeight;
ImGuiID UserID;
ImS8 Index;
ImS8 DisplayOrder;
ImS8 SortOrder;
ImU8 SortDirection : 2;
ImU8 IsVisible : 1;
ImU8 IsStretch : 1;
float WidthOrWeight;
ImGuiID UserID;
ImGuiTableColumnIdx Index;
ImGuiTableColumnIdx DisplayOrder;
ImGuiTableColumnIdx SortOrder;
ImU8 SortDirection : 2;
ImU8 IsEnabled : 1; // "Visible" in ini file
ImU8 IsStretch : 1;
ImGuiTableColumnSettings()
{
@@ -2271,7 +2344,7 @@ struct ImGuiTableColumnSettings
Index = -1;
DisplayOrder = SortOrder = -1;
SortDirection = ImGuiSortDirection_None;
IsVisible = 1;
IsEnabled = 1;
IsStretch = 0;
}
};
@@ -2282,8 +2355,8 @@ struct ImGuiTableSettings
ImGuiID ID; // Set to 0 to invalidate/delete the setting
ImGuiTableFlags SaveFlags; // Indicate data we want to save using the Resizable/Reorderable/Sortable/Hideable flags (could be using its own flags..)
float RefScale; // Reference scale to be able to rescale columns on font/dpi changes.
ImS8 ColumnsCount;
ImS8 ColumnsCountMax; // Maximum number of columns this settings instance can store, we can recycle a settings instance with lower number of columns but not higher
ImGuiTableColumnIdx ColumnsCount;
ImGuiTableColumnIdx ColumnsCountMax; // Maximum number of columns this settings instance can store, we can recycle a settings instance with lower number of columns but not higher
bool WantApply; // Set when loaded from .ini data (to enable merging/loading .ini data into an already running context)
ImGuiTableSettings() { memset(this, 0, sizeof(*this)); }
@@ -2309,8 +2382,9 @@ namespace ImGui
IMGUI_API ImGuiWindow* FindWindowByID(ImGuiID id);
IMGUI_API ImGuiWindow* FindWindowByName(const char* name);
IMGUI_API void UpdateWindowParentAndRootLinks(ImGuiWindow* window, ImGuiWindowFlags flags, ImGuiWindow* parent_window);
IMGUI_API ImVec2 CalcWindowExpectedSize(ImGuiWindow* window);
IMGUI_API ImVec2 CalcWindowNextAutoFitSize(ImGuiWindow* window);
IMGUI_API bool IsWindowChildOf(ImGuiWindow* window, ImGuiWindow* potential_parent);
IMGUI_API bool IsWindowAbove(ImGuiWindow* potential_above, ImGuiWindow* potential_below);
IMGUI_API bool IsWindowNavFocusable(ImGuiWindow* window);
IMGUI_API ImRect GetWindowAllowedExtentRect(ImGuiWindow* window);
IMGUI_API void SetWindowPos(ImGuiWindow* window, const ImVec2& pos, ImGuiCond cond = 0);
@@ -2440,6 +2514,7 @@ namespace ImGui
// Inputs
// FIXME: Eventually we should aim to move e.g. IsActiveIdUsingKey() into IsKeyXXX functions.
IMGUI_API void SetItemUsingMouseWheel();
inline bool IsActiveIdUsingNavDir(ImGuiDir dir) { ImGuiContext& g = *GImGui; return (g.ActiveIdUsingNavDirMask & (1 << dir)) != 0; }
inline bool IsActiveIdUsingNavInput(ImGuiNavInput input) { ImGuiContext& g = *GImGui; return (g.ActiveIdUsingNavInputMask & (1 << input)) != 0; }
inline bool IsActiveIdUsingKey(ImGuiKey key) { ImGuiContext& g = *GImGui; IM_ASSERT(key < 64); return (g.ActiveIdUsingKeyInputMask & ((ImU64)1 << key)) != 0; }
@@ -2455,8 +2530,8 @@ namespace ImGui
IMGUI_API void DockContextShutdown(ImGuiContext* ctx);
IMGUI_API void DockContextClearNodes(ImGuiContext* ctx, ImGuiID root_id, bool clear_settings_refs); // Use root_id==0 to clear all
IMGUI_API void DockContextRebuildNodes(ImGuiContext* ctx);
IMGUI_API void DockContextUpdateUndocking(ImGuiContext* ctx);
IMGUI_API void DockContextUpdateDocking(ImGuiContext* ctx);
IMGUI_API void DockContextNewFrameUpdateUndocking(ImGuiContext* ctx);
IMGUI_API void DockContextNewFrameUpdateDocking(ImGuiContext* ctx);
IMGUI_API ImGuiID DockContextGenNodeID(ImGuiContext* ctx);
IMGUI_API void DockContextQueueDock(ImGuiContext* ctx, ImGuiWindow* target, ImGuiDockNode* target_node, ImGuiWindow* payload, ImGuiDir split_dir, float split_ratio, bool split_outer);
IMGUI_API void DockContextQueueUndockWindow(ImGuiContext* ctx, ImGuiWindow* window);
@@ -2504,32 +2579,42 @@ namespace ImGui
// Internal Columns API (this is not exposed because we will encourage transitioning to the Tables API)
IMGUI_API void SetWindowClipRectBeforeSetChannel(ImGuiWindow* window, const ImRect& clip_rect);
IMGUI_API void BeginColumns(const char* str_id, int count, ImGuiColumnsFlags flags = 0); // setup number of columns. use an identifier to distinguish multiple column sets. close with EndColumns().
IMGUI_API void EndColumns(); // close columns
IMGUI_API void BeginColumns(const char* str_id, int count, ImGuiOldColumnFlags flags = 0); // setup number of columns. use an identifier to distinguish multiple column sets. close with EndColumns().
IMGUI_API void EndColumns(); // close columns
IMGUI_API void PushColumnClipRect(int column_index);
IMGUI_API void PushColumnsBackground();
IMGUI_API void PopColumnsBackground();
IMGUI_API ImGuiID GetColumnsID(const char* str_id, int count);
IMGUI_API ImGuiColumns* FindOrCreateColumns(ImGuiWindow* window, ImGuiID id);
IMGUI_API float GetColumnOffsetFromNorm(const ImGuiColumns* columns, float offset_norm);
IMGUI_API float GetColumnNormFromOffset(const ImGuiColumns* columns, float offset);
IMGUI_API ImGuiOldColumns* FindOrCreateColumns(ImGuiWindow* window, ImGuiID id);
IMGUI_API float GetColumnOffsetFromNorm(const ImGuiOldColumns* columns, float offset_norm);
IMGUI_API float GetColumnNormFromOffset(const ImGuiOldColumns* columns, float offset);
// Tables
// Tables: Candidates for public API
IMGUI_API void TableOpenContextMenu(int column_n = -1);
IMGUI_API void TableSetColumnWidth(int column_n, float width);
IMGUI_API void TableSetColumnSortDirection(int column_n, ImGuiSortDirection sort_direction, bool append_to_sort_specs);
IMGUI_API int TableGetHoveredColumn(); // May use (TableGetColumnFlags() & ImGuiTableColumnFlags_IsHovered) instead. Return hovered column. return -1 when table is not hovered. return columns_count if the unused space at the right of visible columns is hovered.
IMGUI_API float TableGetHeaderRowHeight();
IMGUI_API void TablePushBackgroundChannel();
IMGUI_API void TablePopBackgroundChannel();
// Tables: Internals
IMGUI_API ImGuiTable* TableFindByID(ImGuiID id);
IMGUI_API bool BeginTableEx(const char* name, ImGuiID id, int columns_count, ImGuiTableFlags flags = 0, const ImVec2& outer_size = ImVec2(0, 0), float inner_width = 0.0f);
IMGUI_API void TableBeginUpdateColumns(ImGuiTable* table);
IMGUI_API void TableUpdateDrawChannels(ImGuiTable* table);
IMGUI_API void TableBeginInitMemory(ImGuiTable* table, int columns_count);
IMGUI_API void TableBeginApplyRequests(ImGuiTable* table);
IMGUI_API void TableSetupDrawChannels(ImGuiTable* table);
IMGUI_API void TableUpdateLayout(ImGuiTable* table);
IMGUI_API void TableUpdateBorders(ImGuiTable* table);
IMGUI_API void TableSetColumnWidth(int column_n, float width);
IMGUI_API void TableSetColumnVisible(int column_n, bool visible);
IMGUI_API void TableUpdateColumnsWeightFromWidth(ImGuiTable* table);
IMGUI_API void TableDrawBorders(ImGuiTable* table);
IMGUI_API void TableDrawContextMenu(ImGuiTable* table);
IMGUI_API void TableOpenContextMenu(int column_n = -1);
IMGUI_API void TableReorderDrawChannelsForMerge(ImGuiTable* table);
IMGUI_API void TableSetColumnSortDirection(int column_n, ImGuiSortDirection sort_direction, bool append_to_sort_specs);
IMGUI_API void TableMergeDrawChannels(ImGuiTable* table);
IMGUI_API void TableSortSpecsSanitize(ImGuiTable* table);
IMGUI_API void TableSortSpecsBuild(ImGuiTable* table);
IMGUI_API ImGuiSortDirection TableGetColumnNextSortDirection(ImGuiTableColumn* column);
IMGUI_API void TableFixColumnSortDirection(ImGuiTable* table, ImGuiTableColumn* column);
IMGUI_API float TableGetColumnWidthAuto(ImGuiTable* table, ImGuiTableColumn* column);
IMGUI_API void TableBeginRow(ImGuiTable* table);
IMGUI_API void TableEndRow(ImGuiTable* table);
IMGUI_API void TableBeginCell(ImGuiTable* table, int column_n);
@@ -2537,9 +2622,9 @@ namespace ImGui
IMGUI_API ImRect TableGetCellBgRect(const ImGuiTable* table, int column_n);
IMGUI_API const char* TableGetColumnName(const ImGuiTable* table, int column_n);
IMGUI_API ImGuiID TableGetColumnResizeID(const ImGuiTable* table, int column_n, int instance_no = 0);
IMGUI_API void TableSetColumnAutofit(ImGuiTable* table, int column_n);
IMGUI_API void PushTableBackground();
IMGUI_API void PopTableBackground();
IMGUI_API float TableGetMaxColumnWidth(const ImGuiTable* table, int column_n);
IMGUI_API void TableSetColumnWidthAutoSingle(ImGuiTable* table, int column_n);
IMGUI_API void TableSetColumnWidthAutoAll(ImGuiTable* table);
IMGUI_API void TableRemove(ImGuiTable* table);
IMGUI_API void TableGcCompactTransientBuffers(ImGuiTable* table);
IMGUI_API void TableGcCompactSettings();
@@ -2547,11 +2632,11 @@ namespace ImGui
// Tables: Settings
IMGUI_API void TableLoadSettings(ImGuiTable* table);
IMGUI_API void TableSaveSettings(ImGuiTable* table);
IMGUI_API void TableResetSettings(ImGuiTable* table);
IMGUI_API ImGuiTableSettings* TableGetBoundSettings(ImGuiTable* table);
IMGUI_API void TableSettingsInstallHandler(ImGuiContext* context);
IMGUI_API ImGuiTableSettings* TableSettingsCreate(ImGuiID id, int columns_count);
IMGUI_API ImGuiTableSettings* TableSettingsFindByID(ImGuiID id);
IMGUI_API void TableSettingsClearByID(ImGuiID id);
// Tab Bars
IMGUI_API bool BeginTabBarEx(ImGuiTabBar* tab_bar, const ImRect& bb, ImGuiTabBarFlags flags, ImGuiDockNode* dock_node);
@@ -2611,6 +2696,8 @@ namespace ImGui
IMGUI_API ImGuiID GetWindowScrollbarID(ImGuiWindow* window, ImGuiAxis axis);
IMGUI_API ImGuiID GetWindowResizeID(ImGuiWindow* window, int n); // 0..3: corners, 4..7: borders
IMGUI_API void SeparatorEx(ImGuiSeparatorFlags flags);
IMGUI_API bool CheckboxFlags(const char* label, ImS64* flags, ImS64 flags_value);
IMGUI_API bool CheckboxFlags(const char* label, ImU64* flags, ImU64 flags_value);
// Widgets low-level behaviors
IMGUI_API bool ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool* out_held, ImGuiButtonFlags flags = 0);
@@ -2664,10 +2751,11 @@ namespace ImGui
IMGUI_API void GcAwakeTransientWindowBuffers(ImGuiWindow* window);
// Debug Tools
IMGUI_API void ErrorCheckEndFrameRecover(ImGuiErrorLogCallback log_callback, void* user_data = NULL);
inline void DebugDrawItemRect(ImU32 col = IM_COL32(255,0,0,255)) { ImGuiContext& g = *GImGui; ImGuiWindow* window = g.CurrentWindow; GetForegroundDrawList(window)->AddRect(window->DC.LastItemRect.Min, window->DC.LastItemRect.Max, col); }
inline void DebugStartItemPicker() { ImGuiContext& g = *GImGui; g.DebugItemPickerActive = true; }
IMGUI_API void DebugNodeColumns(ImGuiColumns* columns);
IMGUI_API void DebugNodeColumns(ImGuiOldColumns* columns);
IMGUI_API void DebugNodeDockNode(ImGuiDockNode* node, const char* label);
IMGUI_API void DebugNodeDrawList(ImGuiWindow* window, ImGuiViewportP* viewport, const ImDrawList* draw_list, const char* label);
IMGUI_API void DebugNodeDrawCmdShowMeshAndBoundingBox(ImDrawList* out_draw_list, const ImDrawList* draw_list, const ImDrawCmd* draw_cmd, bool show_mesh, bool show_aabb);

View File

@@ -46,8 +46,11 @@
#include <stdio.h> // sprintf, scanf
#include <stdint.h> // uint8_t, etc.
#include <hex/helpers/utils.hpp>
#include "views/view.hpp"
#include <hex/api/event.hpp>
#include <string>
#ifdef _MSC_VER
#define _PRISizeT "I"
@@ -74,13 +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 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.
@@ -89,12 +98,16 @@ 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 DataEditingAddr;
size_t DataPreviewAddrOld;
size_t DataPreviewAddrEnd;
size_t DataPreviewAddrEndOld;
size_t DataEditingAddr;
bool DataEditingTakeFocus;
char DataInputBuf[32];
char AddrInputBuf[32];
@@ -106,12 +119,12 @@ struct MemoryEditor
MemoryEditor()
{
// Settings
Open = true;
ReadOnly = false;
Cols = 16;
OptShowOptions = true;
OptShowHexII = false;
OptShowAscii = true;
OptShowAdvancedDecoding = true;
OptGreyOutZeroes = true;
OptUpperCaseHex = true;
OptMidColsCount = 8;
@@ -120,10 +133,13 @@ struct MemoryEditor
ReadFn = NULL;
WriteFn = NULL;
HighlightFn = NULL;
HoverFn = NULL;
DecodeFn = NULL;
// State/Internals
ContentsWidthChanged = false;
DataPreviewAddr = DataEditingAddr = DataPreviewAddrEnd = (size_t)-1;
DataPreviewAddrOld = DataPreviewAddrEndOld = (size_t)-1;
DataEditingTakeFocus = false;
memset(DataInputBuf, 0, sizeof(DataInputBuf));
memset(AddrInputBuf, 0, sizeof(AddrInputBuf));
@@ -140,6 +156,13 @@ struct MemoryEditor
HighlightMax = addr_max;
}
void GotoAddrAndSelect(size_t addr_min, size_t addr_max)
{
GotoAddr = addr_min;
DataPreviewAddr = addr_min;
DataPreviewAddrEnd = addr_max;
}
struct Sizes
{
int AddrDigitsCount;
@@ -151,6 +174,8 @@ struct MemoryEditor
float PosHexEnd;
float PosAsciiStart;
float PosAsciiEnd;
float PosDecodingStart;
float PosDecodingEnd;
float WindowWidth;
Sizes() { memset(this, 0, sizeof(*this)); }
@@ -170,25 +195,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 (DataPreviewAddr != DataPreviewAddrOld || DataPreviewAddrEnd != DataPreviewAddrEndOld) {
hex::Region selectionRegion = { std::min(DataPreviewAddr, DataPreviewAddrEnd) + base_display_addr, std::max(DataPreviewAddr, DataPreviewAddrEnd) - std::min(DataPreviewAddr, DataPreviewAddrEnd) };
hex::EventManager::post<hex::EventRegionSelected>(selectionRegion);
}
DataPreviewAddrOld = DataPreviewAddr;
DataPreviewAddrEndOld = DataPreviewAddrEnd;
DrawContents(mem_data, mem_size, base_display_addr);
if (ContentsWidthChanged)
{
@@ -210,16 +257,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.
@@ -229,13 +266,13 @@ struct MemoryEditor
footer_height += height_separator + ImGui::GetFrameHeightWithSpacing() * 1;
ImGui::BeginChild("offset", ImVec2(0, s.LineHeight), false, ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoNav);
ImGui::Text("% *c ", s.AddrDigitsCount, ' ');
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::Text("%02llX", i + (base_display_addr % Cols));
}
ImGui::EndChild();
@@ -247,16 +284,19 @@ 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;
@@ -264,14 +304,42 @@ struct MemoryEditor
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))
{
@@ -286,6 +354,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;
@@ -295,6 +365,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);
@@ -316,7 +387,10 @@ struct MemoryEditor
{
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)));
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;
@@ -413,24 +487,24 @@ struct MemoryEditor
else
ImGui::Text(format_byte_space, b);
}
if (!ReadOnly && ImGui::IsItemHovered() && ImGui::IsMouseClicked(0) && !ImGui::GetIO().KeyShift)
if (ImGui::IsItemHovered() && ImGui::IsMouseClicked(0) && !ImGui::GetIO().KeyShift)
{
if (ImGui::IsMouseDoubleClicked(0)) {
if (!ReadOnly && ImGui::IsMouseDoubleClicked(0)) {
DataEditingTakeFocus = true;
data_editing_addr_next = addr;
}
DataPreviewAddr = addr;
DataPreviewAddrEnd = addr;
hex::View::postEvent(hex::Events::ByteSelected, &DataPreviewAddr);
}
if (!ReadOnly && ImGui::IsItemHovered() && ((ImGui::IsMouseClicked(0) && ImGui::GetIO().KeyShift) || ImGui::IsMouseDragging(0))) {
if (ImGui::IsItemHovered() && ((ImGui::IsMouseClicked(0) && ImGui::GetIO().KeyShift) || ImGui::IsMouseDragging(0))) {
DataPreviewAddrEnd = addr;
size_t dataPreviewStart = std::min(DataPreviewAddr, DataPreviewAddrEnd);
hex::View::postEvent(hex::Events::ByteSelected, &dataPreviewStart);
}
if (ImGui::IsItemHovered() && !tooltipShown) {
if (HoverFn) {
HoverFn(mem_data, addr);
tooltipShown = true;
}
}
}
}
@@ -479,9 +553,9 @@ struct MemoryEditor
ImGui::PopID();
if (!ReadOnly && ImGui::IsItemHovered() && ImGui::IsMouseClicked(0) && !ImGui::GetIO().KeyShift)
if (ImGui::IsItemHovered() && ImGui::IsMouseClicked(0) && !ImGui::GetIO().KeyShift)
{
if (ImGui::IsMouseDoubleClicked(0)) {
if (!ReadOnly && ImGui::IsMouseDoubleClicked(0)) {
DataEditingTakeFocus = true;
data_editing_addr_next = addr;
}
@@ -490,12 +564,92 @@ struct MemoryEditor
DataPreviewAddrEnd = addr;
}
if (!ReadOnly && ImGui::IsItemHovered() && ((ImGui::IsMouseClicked(0) && ImGui::GetIO().KeyShift) || ImGui::IsMouseDragging(0))) {
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);
@@ -510,7 +664,7 @@ struct MemoryEditor
}
else if (data_editing_addr_next != (size_t)-1)
{
DataEditingAddr = DataPreviewAddr = data_editing_addr_next;
DataEditingAddr = DataPreviewAddr = DataPreviewAddrEnd = data_editing_addr_next;
}
if (OptShowOptions)
@@ -528,17 +682,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("options");
if (ImGui::BeginPopup("options")) {
ImGui::PushItemWidth(56);
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 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);
@@ -547,18 +703,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)
{
@@ -567,8 +722,8 @@ struct MemoryEditor
ImGui::BeginChild("##scrolling");
ImGui::SetScrollFromPosY(ImGui::GetCursorStartPos().y + (GotoAddr / Cols) * ImGui::GetTextLineHeight());
ImGui::EndChild();
DataEditingAddr = DataPreviewAddr = GotoAddr;
DataEditingTakeFocus = true;
DataEditingAddr = DataPreviewAddr = HighlightMin;
DataPreviewAddrEnd = HighlightMax;
}
GotoAddr = (size_t)-1;
}

323
external/ImGui/include/imnodes.h vendored Normal file
View 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

688
external/ImGui/include/implot.h vendored Normal file
View File

@@ -0,0 +1,688 @@
// MIT License
// Copyright (c) 2020 Evan Pezent
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
// ImPlot v0.8 WIP
#pragma once
#include "imgui.h"
//-----------------------------------------------------------------------------
// Macros and Defines
//-----------------------------------------------------------------------------
// Define attributes of all API symbols declarations (e.g. for DLL under Windows)
// Using ImPlot via a shared library is not recommended, because we don't guarantee
// backward nor forward ABI compatibility and also function call overhead. If you
// do use ImPlot as a DLL, be sure to call SetImGuiContext (details below).
#ifndef IMPLOT_API
#define IMPLOT_API
#endif
// ImPlot version string
#define IMPLOT_VERSION "0.8 WIP"
// Indicates variable should deduced automatically.
#define IMPLOT_AUTO -1
// Special color used to indicate that a color should be deduced automatically.
#define IMPLOT_AUTO_COL ImVec4(0,0,0,-1)
//-----------------------------------------------------------------------------
// Forward Declarations and Basic Types
//-----------------------------------------------------------------------------
// Forward declarations
struct ImPlotContext; // ImPlot context (opaque struct, see implot_internal.h)
// Enums/Flags
typedef int ImPlotFlags; // -> enum ImPlotFlags_
typedef int ImPlotAxisFlags; // -> enum ImPlotAxisFlags_
typedef int ImPlotCol; // -> enum ImPlotCol_
typedef int ImPlotStyleVar; // -> enum ImPlotStyleVar_
typedef int ImPlotMarker; // -> enum ImPlotMarker_
typedef int ImPlotColormap; // -> enum ImPlotColormap_
typedef int ImPlotLocation; // -> enum ImPlotLocation_
typedef int ImPlotOrientation; // -> enum ImPlotOrientation_
typedef int ImPlotYAxis; // -> enum ImPlotYAxis_;
// Options for plots.
enum ImPlotFlags_ {
ImPlotFlags_None = 0, // default
ImPlotFlags_NoLegend = 1 << 0, // the top-left legend will not be displayed
ImPlotFlags_NoMenus = 1 << 1, // the user will not be able to open context menus with double-right click
ImPlotFlags_NoBoxSelect = 1 << 2, // the user will not be able to box-select with right-mouse
ImPlotFlags_NoMousePos = 1 << 3, // the mouse position, in plot coordinates, will not be displayed inside of the plot
ImPlotFlags_NoHighlight = 1 << 4, // plot items will not be highlighted when their legend entry is hovered
ImPlotFlags_NoChild = 1 << 5, // a child window region will not be used to capture mouse scroll (can boost performance for single ImGui window applications)
ImPlotFlags_YAxis2 = 1 << 6, // enable a 2nd y-axis on the right side
ImPlotFlags_YAxis3 = 1 << 7, // enable a 3rd y-axis on the right side
ImPlotFlags_Query = 1 << 8, // the user will be able to draw query rects with middle-mouse
ImPlotFlags_Crosshairs = 1 << 9, // the default mouse cursor will be replaced with a crosshair when hovered
ImPlotFlags_AntiAliased = 1 << 10, // plot lines will be software anti-aliased (not recommended for density plots, prefer MSAA)
ImPlotFlags_CanvasOnly = ImPlotFlags_NoLegend | ImPlotFlags_NoMenus | ImPlotFlags_NoBoxSelect | ImPlotFlags_NoMousePos
};
// Options for plot axes (X and Y).
enum ImPlotAxisFlags_ {
ImPlotAxisFlags_None = 0, // default
ImPlotAxisFlags_NoGridLines = 1 << 0, // no grid lines will be displayed
ImPlotAxisFlags_NoTickMarks = 1 << 1, // no tick marks will be displayed
ImPlotAxisFlags_NoTickLabels = 1 << 2, // no text labels will be displayed
ImPlotAxisFlags_LogScale = 1 << 3, // a logartithmic (base 10) axis scale will be used (mutually exclusive with ImPlotAxisFlags_Time)
ImPlotAxisFlags_Time = 1 << 4, // axis will display date/time formatted labels (mutually exclusive with ImPlotAxisFlags_LogScale)
ImPlotAxisFlags_Invert = 1 << 5, // the axis will be inverted
ImPlotAxisFlags_LockMin = 1 << 6, // the axis minimum value will be locked when panning/zooming
ImPlotAxisFlags_LockMax = 1 << 7, // the axis maximum value will be locked when panning/zooming
ImPlotAxisFlags_Lock = ImPlotAxisFlags_LockMin | ImPlotAxisFlags_LockMax,
ImPlotAxisFlags_NoDecorations = ImPlotAxisFlags_NoGridLines | ImPlotAxisFlags_NoTickMarks | ImPlotAxisFlags_NoTickLabels
};
// Plot styling colors.
enum ImPlotCol_ {
// item styling colors
ImPlotCol_Line, // plot line/outline color (defaults to next unused color in current colormap)
ImPlotCol_Fill, // plot fill color for bars (defaults to the current line color)
ImPlotCol_MarkerOutline, // marker outline color (defaults to the current line color)
ImPlotCol_MarkerFill, // marker fill color (defaults to the current line color)
ImPlotCol_ErrorBar, // error bar color (defaults to ImGuiCol_Text)
// plot styling colors
ImPlotCol_FrameBg, // plot frame background color (defaults to ImGuiCol_FrameBg)
ImPlotCol_PlotBg, // plot area background color (defaults to ImGuiCol_WindowBg)
ImPlotCol_PlotBorder, // plot area border color (defaults to ImGuiCol_Border)
ImPlotCol_LegendBg, // legend background color (defaults to ImGuiCol_PopupBg)
ImPlotCol_LegendBorder, // legend border color (defaults to ImPlotCol_PlotBorder)
ImPlotCol_LegendText, // legend text color (defaults to ImPlotCol_InlayText)
ImPlotCol_TitleText, // plot title text color (defaults to ImGuiCol_Text)
ImPlotCol_InlayText, // color of text appearing inside of plots (defaults to ImGuiCol_Text)
ImPlotCol_XAxis, // x-axis label and tick lables color (defaults to ImGuiCol_Text)
ImPlotCol_XAxisGrid, // x-axis grid color (defaults to 25% ImPlotCol_XAxis)
ImPlotCol_YAxis, // y-axis label and tick labels color (defaults to ImGuiCol_Text)
ImPlotCol_YAxisGrid, // y-axis grid color (defaults to 25% ImPlotCol_YAxis)
ImPlotCol_YAxis2, // 2nd y-axis label and tick labels color (defaults to ImGuiCol_Text)
ImPlotCol_YAxisGrid2, // 2nd y-axis grid/label color (defaults to 25% ImPlotCol_YAxis2)
ImPlotCol_YAxis3, // 3rd y-axis label and tick labels color (defaults to ImGuiCol_Text)
ImPlotCol_YAxisGrid3, // 3rd y-axis grid/label color (defaults to 25% ImPlotCol_YAxis3)
ImPlotCol_Selection, // box-selection color (defaults to yellow)
ImPlotCol_Query, // box-query color (defaults to green)
ImPlotCol_Crosshairs, // crosshairs color (defaults to ImPlotCol_PlotBorder)
ImPlotCol_COUNT
};
// Plot styling variables.
enum ImPlotStyleVar_ {
// item styling variables
ImPlotStyleVar_LineWeight, // float, plot item line weight in pixels
ImPlotStyleVar_Marker, // int, marker specification
ImPlotStyleVar_MarkerSize, // float, marker size in pixels (roughly the marker's "radius")
ImPlotStyleVar_MarkerWeight, // float, plot outline weight of markers in pixels
ImPlotStyleVar_FillAlpha, // float, alpha modifier applied to all plot item fills
ImPlotStyleVar_ErrorBarSize, // float, error bar whisker width in pixels
ImPlotStyleVar_ErrorBarWeight, // float, error bar whisker weight in pixels
ImPlotStyleVar_DigitalBitHeight, // float, digital channels bit height (at 1) in pixels
ImPlotStyleVar_DigitalBitGap, // float, digital channels bit padding gap in pixels
// plot styling variables
ImPlotStyleVar_PlotBorderSize, // float, thickness of border around plot area
ImPlotStyleVar_MinorAlpha, // float, alpha multiplier applied to minor axis grid lines
ImPlotStyleVar_MajorTickLen, // ImVec2, major tick lengths for X and Y axes
ImPlotStyleVar_MinorTickLen, // ImVec2, minor tick lengths for X and Y axes
ImPlotStyleVar_MajorTickSize, // ImVec2, line thickness of major ticks
ImPlotStyleVar_MinorTickSize, // ImVec2, line thickness of minor ticks
ImPlotStyleVar_MajorGridSize, // ImVec2, line thickness of major grid lines
ImPlotStyleVar_MinorGridSize, // ImVec2, line thickness of minor grid lines
ImPlotStyleVar_PlotPadding, // ImVec2, padding between widget frame and plot area, labels, or outside legends (i.e. main padding)
ImPlotStyleVar_LabelPadding, // ImVec2, padding between axes labels, tick labels, and plot edge
ImPlotStyleVar_LegendPadding, // ImVec2, legend padding from plot edges
ImPlotStyleVar_LegendInnerPadding, // ImVec2, legend inner padding from legend edges
ImPlotStyleVar_LegendSpacing, // ImVec2, spacing between legend entries
ImPlotStyleVar_MousePosPadding, // ImVec2, padding between plot edge and interior info text
ImPlotStyleVar_AnnotationPadding, // ImVec2, text padding around annotation labels
ImPlotStyleVar_PlotDefaultSize, // ImVec2, default size used when ImVec2(0,0) is passed to BeginPlot
ImPlotStyleVar_PlotMinSize, // ImVec2, minimum size plot frame can be when shrunk
ImPlotStyleVar_COUNT
};
// Marker specifications.
enum ImPlotMarker_ {
ImPlotMarker_None = -1, // no marker
ImPlotMarker_Circle, // a circle marker
ImPlotMarker_Square, // a square maker
ImPlotMarker_Diamond, // a diamond marker
ImPlotMarker_Up, // an upward-pointing triangle marker
ImPlotMarker_Down, // an downward-pointing triangle marker
ImPlotMarker_Left, // an leftward-pointing triangle marker
ImPlotMarker_Right, // an rightward-pointing triangle marker
ImPlotMarker_Cross, // a cross marker (not fillable)
ImPlotMarker_Plus, // a plus marker (not fillable)
ImPlotMarker_Asterisk, // a asterisk marker (not fillable)
ImPlotMarker_COUNT
};
// Built-in colormaps
enum ImPlotColormap_ {
ImPlotColormap_Default = 0, // ImPlot default colormap (n=10)
ImPlotColormap_Deep = 1, // a.k.a. seaborn deep (n=10)
ImPlotColormap_Dark = 2, // a.k.a. matplotlib "Set1" (n=9)
ImPlotColormap_Pastel = 3, // a.k.a. matplotlib "Pastel1" (n=9)
ImPlotColormap_Paired = 4, // a.k.a. matplotlib "Paired" (n=12)
ImPlotColormap_Viridis = 5, // a.k.a. matplotlib "viridis" (n=11)
ImPlotColormap_Plasma = 6, // a.k.a. matplotlib "plasma" (n=11)
ImPlotColormap_Hot = 7, // a.k.a. matplotlib/MATLAB "hot" (n=11)
ImPlotColormap_Cool = 8, // a.k.a. matplotlib/MATLAB "cool" (n=11)
ImPlotColormap_Pink = 9, // a.k.a. matplotlib/MATLAB "pink" (n=11)
ImPlotColormap_Jet = 10, // a.k.a. MATLAB "jet" (n=11)
ImPlotColormap_COUNT
};
// Used to position items on a plot (e.g. legends, labels, etc.)
enum ImPlotLocation_ {
ImPlotLocation_Center = 0, // center-center
ImPlotLocation_North = 1 << 0, // top-center
ImPlotLocation_South = 1 << 1, // bottom-center
ImPlotLocation_West = 1 << 2, // center-left
ImPlotLocation_East = 1 << 3, // center-right
ImPlotLocation_NorthWest = ImPlotLocation_North | ImPlotLocation_West, // top-left
ImPlotLocation_NorthEast = ImPlotLocation_North | ImPlotLocation_East, // top-right
ImPlotLocation_SouthWest = ImPlotLocation_South | ImPlotLocation_West, // bottom-left
ImPlotLocation_SouthEast = ImPlotLocation_South | ImPlotLocation_East // bottom-right
};
// Used to orient items on a plot (e.g. legends, labels, etc.)
enum ImPlotOrientation_ {
ImPlotOrientation_Horizontal, // left/right
ImPlotOrientation_Vertical // up/down
};
// Enums for different y-axes.
enum ImPlotYAxis_ {
ImPlotYAxis_1 = 0, // left (default)
ImPlotYAxis_2 = 1, // first on right side
ImPlotYAxis_3 = 2 // second on right side
};
// Double precision version of ImVec2 used by ImPlot. Extensible by end users.
struct ImPlotPoint {
double x, y;
ImPlotPoint() { x = y = 0.0; }
ImPlotPoint(double _x, double _y) { x = _x; y = _y; }
ImPlotPoint(const ImVec2& p) { x = p.x; y = p.y; }
double operator[] (size_t idx) const { return (&x)[idx]; }
double& operator[] (size_t idx) { return (&x)[idx]; }
#ifdef IMPLOT_POINT_CLASS_EXTRA
IMPLOT_POINT_CLASS_EXTRA // Define additional constructors and implicit cast operators in imconfig.h
// to convert back and forth between your math types and ImPlotPoint.
#endif
};
// A range defined by a min/max value. Used for plot axes ranges.
struct ImPlotRange {
double Min, Max;
ImPlotRange() { Min = 0; Max = 0; }
ImPlotRange(double _min, double _max) { Min = _min; Max = _max; }
bool Contains(double value) const { return value >= Min && value <= Max; };
double Size() const { return Max - Min; };
};
// Combination of two ranges for X and Y axes.
struct ImPlotLimits {
ImPlotRange X, Y;
bool Contains(const ImPlotPoint& p) const { return Contains(p.x, p.y); }
bool Contains(double x, double y) const { return X.Contains(x) && Y.Contains(y); }
};
// Plot style structure
struct ImPlotStyle {
// item styling variables
float LineWeight; // = 1, item line weight in pixels
int Marker; // = ImPlotMarker_None, marker specification
float MarkerSize; // = 4, marker size in pixels (roughly the marker's "radius")
float MarkerWeight; // = 1, outline weight of markers in pixels
float FillAlpha; // = 1, alpha modifier applied to plot fills
float ErrorBarSize; // = 5, error bar whisker width in pixels
float ErrorBarWeight; // = 1.5, error bar whisker weight in pixels
float DigitalBitHeight; // = 8, digital channels bit height (at y = 1.0f) in pixels
float DigitalBitGap; // = 4, digital channels bit padding gap in pixels
// plot styling variables
float PlotBorderSize; // = 1, line thickness of border around plot area
float MinorAlpha; // = 0.25 alpha multiplier applied to minor axis grid lines
ImVec2 MajorTickLen; // = 10,10 major tick lengths for X and Y axes
ImVec2 MinorTickLen; // = 5,5 minor tick lengths for X and Y axes
ImVec2 MajorTickSize; // = 1,1 line thickness of major ticks
ImVec2 MinorTickSize; // = 1,1 line thickness of minor ticks
ImVec2 MajorGridSize; // = 1,1 line thickness of major grid lines
ImVec2 MinorGridSize; // = 1,1 line thickness of minor grid lines
ImVec2 PlotPadding; // = 10,10 padding between widget frame and plot area, labels, or outside legends (i.e. main padding)
ImVec2 LabelPadding; // = 5,5 padding between axes labels, tick labels, and plot edge
ImVec2 LegendPadding; // = 10,10 legend padding from plot edges
ImVec2 LegendInnerPadding; // = 5,5 legend inner padding from legend edges
ImVec2 LegendSpacing; // = 0,0 spacing between legend entries
ImVec2 MousePosPadding; // = 10,10 padding between plot edge and interior mouse location text
ImVec2 AnnotationPadding; // = 2,2 text padding around annotation labels
ImVec2 PlotDefaultSize; // = 400,300 default size used when ImVec2(0,0) is passed to BeginPlot
ImVec2 PlotMinSize; // = 300,225 minimum size plot frame can be when shrunk
// colors
ImVec4 Colors[ImPlotCol_COUNT]; // array of plot specific colors
// settings/flags
bool AntiAliasedLines; // = false, enable global anti-aliasing on plot lines (overrides ImPlotFlags_AntiAliased)
bool UseLocalTime; // = false, axis labels will be formatted for your timezone when ImPlotAxisFlag_Time is enabled
bool UseISO8601; // = false, dates will be formatted according to ISO 8601 where applicable (e.g. YYYY-MM-DD, YYYY-MM, --MM-DD, etc.)
bool Use24HourClock; // = false, times will be formatted using a 24 hour clock
IMPLOT_API ImPlotStyle();
};
// Input mapping structure, default values listed in the comments.
struct ImPlotInputMap {
ImGuiMouseButton PanButton; // LMB enables panning when held
ImGuiKeyModFlags PanMod; // none optional modifier that must be held for panning
ImGuiMouseButton FitButton; // LMB fits visible data when double clicked
ImGuiMouseButton ContextMenuButton; // RMB opens plot context menu (if enabled) when double clicked
ImGuiMouseButton BoxSelectButton; // RMB begins box selection when pressed and confirms selection when released
ImGuiKeyModFlags BoxSelectMod; // none optional modifier that must be held for box selection
ImGuiMouseButton BoxSelectCancelButton; // LMB cancels active box selection when pressed
ImGuiMouseButton QueryButton; // MMB begins query selection when pressed and end query selection when released
ImGuiKeyModFlags QueryMod; // none optional modifier that must be held for query selection
ImGuiKeyModFlags QueryToggleMod; // Ctrl when held, active box selections turn into queries
ImGuiKeyModFlags HorizontalMod; // Alt expands active box selection/query horizontally to plot edge when held
ImGuiKeyModFlags VerticalMod; // Shift expands active box selection/query vertically to plot edge when held
IMPLOT_API ImPlotInputMap();
};
//-----------------------------------------------------------------------------
// ImPlot End-User API
//-----------------------------------------------------------------------------
namespace ImPlot {
//-----------------------------------------------------------------------------
// ImPlot Context
//-----------------------------------------------------------------------------
// Creates a new ImPlot context. Call this after ImGui::CreateContext.
IMPLOT_API ImPlotContext* CreateContext();
// Destroys an ImPlot context. Call this before ImGui::DestroyContext. NULL = destroy current context
IMPLOT_API void DestroyContext(ImPlotContext* ctx = NULL);
// Returns the current ImPlot context. NULL if no context has ben set.
IMPLOT_API ImPlotContext* GetCurrentContext();
// Sets the current ImPlot context.
IMPLOT_API void SetCurrentContext(ImPlotContext* ctx);
//-----------------------------------------------------------------------------
// Begin/End Plot
//-----------------------------------------------------------------------------
// Starts a 2D plotting context. If this function returns true, EndPlot() must
// be called, e.g. "if (BeginPlot(...)) { ... EndPlot(); }". #title_id must
// be unique. If you need to avoid ID collisions or don't want to display a
// title in the plot, use double hashes (e.g. "MyPlot##Hidden" or "##NoTitle").
// If #x_label and/or #y_label are provided, axes labels will be displayed.
IMPLOT_API bool BeginPlot(const char* title_id,
const char* x_label = NULL,
const char* y_label = NULL,
const ImVec2& size = ImVec2(-1,0),
ImPlotFlags flags = ImPlotFlags_None,
ImPlotAxisFlags x_flags = ImPlotAxisFlags_None,
ImPlotAxisFlags y_flags = ImPlotAxisFlags_None,
ImPlotAxisFlags y2_flags = ImPlotAxisFlags_NoGridLines,
ImPlotAxisFlags y3_flags = ImPlotAxisFlags_NoGridLines);
// Only call EndPlot() if BeginPlot() returns true! Typically called at the end
// of an if statement conditioned on BeginPlot().
IMPLOT_API void EndPlot();
//-----------------------------------------------------------------------------
// Plot Items
//-----------------------------------------------------------------------------
// The template functions below are explicitly instantiated in implot_items.cpp.
// They are not intended to be used generically with custom types. You will get
// a linker error if you try! All functions support the following scalar types:
//
// float, double, ImS8, ImU8, ImS16, ImU16, ImS32, ImU32, ImS64, ImU64
//
//
// If you need to plot custom or non-homogenous data you have a few options:
//
// 1. If your data is a simple struct/class (e.g. Vector2f), you can use striding.
// This is the most performant option if applicable.
//
// struct Vector2f { float X, Y; };
// ...
// Vector2f data[42];
// ImPlot::PlotLine("line", &data[0].x, &data[0].y, 42, 0, sizeof(Vector2f)); // or sizeof(float)*2
//
// 2. Write a custom getter function or C++ lambda and pass it and your data to
// an ImPlot function post-fixed with a G (e.g. PlotScatterG). This has a
// slight performance cost, but probably not enough to worry about.
//
// ImPlotPoint MyDataGetter(void* data, int idx) {
// MyData* my_data = (MyData*)data;
// ImPlotPoint p;
// p.x = my_data->GetTime(idx);
// p.y = my_data->GetValue(idx);
// return p
// }
// ...
// MyData my_data;
// ImPlot::PlotScatterG("scatter", MyDataGetter, &my_data, my_data.Size());
//
// NB: All types are converted to double before plotting. You may loose information
// if you try plotting extremely large 64-bit integral types. Proceed with caution!
// Plots a standard 2D line plot.
template <typename T> IMPLOT_API void PlotLine(const char* label_id, const T* values, int count, double xscale=1, double x0=0, int offset=0, int stride=sizeof(T));
template <typename T> IMPLOT_API void PlotLine(const char* label_id, const T* xs, const T* ys, int count, int offset=0, int stride=sizeof(T));
IMPLOT_API void PlotLineG(const char* label_id, ImPlotPoint (*getter)(void* data, int idx), void* data, int count, int offset=0);
// Plots a standard 2D scatter plot. Default marker is ImPlotMarker_Circle.
template <typename T> IMPLOT_API void PlotScatter(const char* label_id, const T* values, int count, double xscale=1, double x0=0, int offset=0, int stride=sizeof(T));
template <typename T> IMPLOT_API void PlotScatter(const char* label_id, const T* xs, const T* ys, int count, int offset=0, int stride=sizeof(T));
IMPLOT_API void PlotScatterG(const char* label_id, ImPlotPoint (*getter)(void* data, int idx), void* data, int count, int offset=0);
// Plots a a stairstep graph. The y value is continued constantly from every x position, i.e. the interval [x[i], x[i+1]) has the value y[i].
template <typename T> IMPLOT_API void PlotStairs(const char* label_id, const T* values, int count, double xscale=1, double x0=0, int offset=0, int stride=sizeof(T));
template <typename T> IMPLOT_API void PlotStairs(const char* label_id, const T* xs, const T* ys, int count, int offset=0, int stride=sizeof(T));
IMPLOT_API void PlotStairsG(const char* label_id, ImPlotPoint (*getter)(void* data, int idx), void* data, int count, int offset=0);
// Plots a shaded (filled) region between two lines, or a line and a horizontal reference.
template <typename T> IMPLOT_API void PlotShaded(const char* label_id, const T* values, int count, double y_ref=0, double xscale=1, double x0=0, int offset=0, int stride=sizeof(T));
template <typename T> IMPLOT_API void PlotShaded(const char* label_id, const T* xs, const T* ys, int count, double y_ref=0, int offset=0, int stride=sizeof(T));
template <typename T> IMPLOT_API void PlotShaded(const char* label_id, const T* xs, const T* ys1, const T* ys2, int count, int offset=0, int stride=sizeof(T));
IMPLOT_API void PlotShadedG(const char* label_id, ImPlotPoint (*getter1)(void* data, int idx), void* data1, ImPlotPoint (*getter2)(void* data, int idx), void* data2, int count, int offset=0);
// Plots a vertical bar graph. #width and #shift are in X units.
template <typename T> IMPLOT_API void PlotBars(const char* label_id, const T* values, int count, double width=0.67, double shift=0, int offset=0, int stride=sizeof(T));
template <typename T> IMPLOT_API void PlotBars(const char* label_id, const T* xs, const T* ys, int count, double width, int offset=0, int stride=sizeof(T));
IMPLOT_API void PlotBarsG(const char* label_id, ImPlotPoint (*getter)(void* data, int idx), void* data, int count, double width, int offset=0);
// Plots a horizontal bar graph. #height and #shift are in Y units.
template <typename T> IMPLOT_API void PlotBarsH(const char* label_id, const T* values, int count, double height=0.67, double shift=0, int offset=0, int stride=sizeof(T));
template <typename T> IMPLOT_API void PlotBarsH(const char* label_id, const T* xs, const T* ys, int count, double height, int offset=0, int stride=sizeof(T));
IMPLOT_API void PlotBarsHG(const char* label_id, ImPlotPoint (*getter)(void* data, int idx), void* data, int count, double height, int offset=0);
// Plots vertical error bar. The label_id should be the same as the label_id of the associated line or bar plot.
template <typename T> IMPLOT_API void PlotErrorBars(const char* label_id, const T* xs, const T* ys, const T* err, int count, int offset=0, int stride=sizeof(T));
template <typename T> IMPLOT_API void PlotErrorBars(const char* label_id, const T* xs, const T* ys, const T* neg, const T* pos, int count, int offset=0, int stride=sizeof(T));
// Plots horizontal error bars. The label_id should be the same as the label_id of the associated line or bar plot.
template <typename T> IMPLOT_API void PlotErrorBarsH(const char* label_id, const T* xs, const T* ys, const T* err, int count, int offset=0, int stride=sizeof(T));
template <typename T> IMPLOT_API void PlotErrorBarsH(const char* label_id, const T* xs, const T* ys, const T* neg, const T* pos, int count, int offset=0, int stride=sizeof(T));
/// Plots vertical stems.
template <typename T> IMPLOT_API void PlotStems(const char* label_id, const T* values, int count, double y_ref=0, double xscale=1, double x0=0, int offset=0, int stride=sizeof(T));
template <typename T> IMPLOT_API void PlotStems(const char* label_id, const T* xs, const T* ys, int count, double y_ref=0, int offset=0, int stride=sizeof(T));
// Plots a pie chart. If the sum of values > 1 or normalize is true, each value will be normalized. Center and radius are in plot units. #label_fmt can be set to NULL for no labels.
template <typename T> IMPLOT_API void PlotPieChart(const char* const label_ids[], const T* values, int count, double x, double y, double radius, bool normalize=false, const char* label_fmt="%.1f", double angle0=90);
// Plots a 2D heatmap chart. Values are expected to be in row-major order. #label_fmt can be set to NULL for no labels.
template <typename T> IMPLOT_API void PlotHeatmap(const char* label_id, const T* values, int rows, int cols, double scale_min, double scale_max, const char* label_fmt="%.1f", const ImPlotPoint& bounds_min=ImPlotPoint(0,0), const ImPlotPoint& bounds_max=ImPlotPoint(1,1));
// Plots digital data. Digital plots do not respond to y drag or zoom, and are always referenced to the bottom of the plot.
template <typename T> IMPLOT_API void PlotDigital(const char* label_id, const T* xs, const T* ys, int count, int offset=0, int stride=sizeof(T));
IMPLOT_API void PlotDigitalG(const char* label_id, ImPlotPoint (*getter)(void* data, int idx), void* data, int count, int offset=0);
// Plots an axis-aligned image. #bounds_min/bounds_max are in plot coordinatse (y-up) and #uv0/uv1 are in texture coordinates (y-down).
IMPLOT_API void PlotImage(const char* label_id, ImTextureID user_texture_id, const ImPlotPoint& bounds_min, const ImPlotPoint& bounds_max, const ImVec2& uv0=ImVec2(0,0), const ImVec2& uv1=ImVec2(1,1), const ImVec4& tint_col=ImVec4(1,1,1,1));
// Plots a centered text label at point x,y with optional pixel offset. Text color can be changed with ImPlot::PushStyleColor(ImPlotCol_InlayText, ...).
IMPLOT_API void PlotText(const char* text, double x, double y, bool vertical=false, const ImVec2& pix_offset=ImVec2(0,0));
// Plots an dummy item (i.e. adds a legend entry colored by ImPlotCol_Line)
IMPLOT_API void PlotDummy(const char* label_id);
//-----------------------------------------------------------------------------
// Plot Utils
//-----------------------------------------------------------------------------
// The following functions MUST be called before BeginPlot!
// Set the axes range limits of the next plot. Call right before BeginPlot(). If ImGuiCond_Always is used, the axes limits will be locked.
IMPLOT_API void SetNextPlotLimits(double xmin, double xmax, double ymin, double ymax, ImGuiCond cond = ImGuiCond_Once);
// Set the X axis range limits of the next plot. Call right before BeginPlot(). If ImGuiCond_Always is used, the X axis limits will be locked.
IMPLOT_API void SetNextPlotLimitsX(double xmin, double xmax, ImGuiCond cond = ImGuiCond_Once);
// Set the Y axis range limits of the next plot. Call right before BeginPlot(). If ImGuiCond_Always is used, the Y axis limits will be locked.
IMPLOT_API void SetNextPlotLimitsY(double ymin, double ymax, ImGuiCond cond = ImGuiCond_Once, ImPlotYAxis y_axis = 0);
// Links the next plot limits to external values. Set to NULL for no linkage. The pointer data must remain valid until the matching call EndPlot.
IMPLOT_API void LinkNextPlotLimits(double* xmin, double* xmax, double* ymin, double* ymax, double* ymin2 = NULL, double* ymax2 = NULL, double* ymin3 = NULL, double* ymax3 = NULL);
// Fits the next plot axes to all plotted data if they are unlocked (equivalent to double-clicks).
IMPLOT_API void FitNextPlotAxes(bool x = true, bool y = true, bool y2 = true, bool y3 = true);
// Set the X axis ticks and optionally the labels for the next plot.
IMPLOT_API void SetNextPlotTicksX(const double* values, int n_ticks, const char* const labels[] = NULL, bool show_default = false);
IMPLOT_API void SetNextPlotTicksX(double x_min, double x_max, int n_ticks, const char* const labels[] = NULL, bool show_default = false);
// Set the Y axis ticks and optionally the labels for the next plot.
IMPLOT_API void SetNextPlotTicksY(const double* values, int n_ticks, const char* const labels[] = NULL, bool show_default = false, ImPlotYAxis y_axis = 0);
IMPLOT_API void SetNextPlotTicksY(double y_min, double y_max, int n_ticks, const char* const labels[] = NULL, bool show_default = false, ImPlotYAxis y_axis = 0);
// The following functions MUST be called between Begin/EndPlot!
// Select which Y axis will be used for subsequent plot elements. The default is ImPlotYAxis_1, or the first (left) Y axis. Enable 2nd and 3rd axes with ImPlotFlags_YAxisX.
IMPLOT_API void SetPlotYAxis(ImPlotYAxis y_axis);
// Hides or shows the next plot item (i.e. as if it were toggled from the legend). Use ImGuiCond_Always if you need to forcefully set this every frame.
IMPLOT_API void HideNextItem(bool hidden = true, ImGuiCond cond = ImGuiCond_Once);
// Convert pixels to a position in the current plot's coordinate system. A negative y_axis uses the current value of SetPlotYAxis (ImPlotYAxis_1 initially).
IMPLOT_API ImPlotPoint PixelsToPlot(const ImVec2& pix, ImPlotYAxis y_axis = IMPLOT_AUTO);
IMPLOT_API ImPlotPoint PixelsToPlot(float x, float y, ImPlotYAxis y_axis = IMPLOT_AUTO);
// Convert a position in the current plot's coordinate system to pixels. A negative y_axis uses the current value of SetPlotYAxis (ImPlotYAxis_1 initially).
IMPLOT_API ImVec2 PlotToPixels(const ImPlotPoint& plt, ImPlotYAxis y_axis = IMPLOT_AUTO);
IMPLOT_API ImVec2 PlotToPixels(double x, double y, ImPlotYAxis y_axis = IMPLOT_AUTO);
// Get the current Plot position (top-left) in pixels.
IMPLOT_API ImVec2 GetPlotPos();
// Get the curent Plot size in pixels.
IMPLOT_API ImVec2 GetPlotSize();
// Returns true if the plot area in the current plot is hovered.
IMPLOT_API bool IsPlotHovered();
// Returns true if the XAxis plot area in the current plot is hovered.
IMPLOT_API bool IsPlotXAxisHovered();
// Returns true if the YAxis[n] plot area in the current plot is hovered.
IMPLOT_API bool IsPlotYAxisHovered(ImPlotYAxis y_axis = 0);
// Returns the mouse position in x,y coordinates of the current plot. A negative y_axis uses the current value of SetPlotYAxis (ImPlotYAxis_1 initially).
IMPLOT_API ImPlotPoint GetPlotMousePos(ImPlotYAxis y_axis = IMPLOT_AUTO);
// Returns the current plot axis range. A negative y_axis uses the current value of SetPlotYAxis (ImPlotYAxis_1 initially).
IMPLOT_API ImPlotLimits GetPlotLimits(ImPlotYAxis y_axis = IMPLOT_AUTO);
// Returns true if the current plot is being queried. Query must be enabled with ImPlotFlags_Query.
IMPLOT_API bool IsPlotQueried();
// Returns the current plot query bounds. Query must be enabled with ImPlotFlags_Query.
IMPLOT_API ImPlotLimits GetPlotQuery(ImPlotYAxis y_axis = IMPLOT_AUTO);
//-----------------------------------------------------------------------------
// Plot Tools
//-----------------------------------------------------------------------------
// The following functions MUST be called between Begin/EndPlot!
// Shows an annotation callout at a chosen point.
IMPLOT_API void Annotate(double x, double y, const ImVec2& pix_offset, const char* fmt, ...) IM_FMTARGS(4);
IMPLOT_API void Annotate(double x, double y, const ImVec2& pix_offset, const ImVec4& color, const char* fmt, ...) IM_FMTARGS(5);
IMPLOT_API void AnnotateV(double x, double y, const ImVec2& pix_offset, const char* fmt, va_list args) IM_FMTLIST(4);
IMPLOT_API void AnnotateV(double x, double y, const ImVec2& pix_offset, const ImVec4& color, const char* fmt, va_list args) IM_FMTLIST(5);
// Same as above, but the annotation will always be clamped to stay inside the plot area.
IMPLOT_API void AnnotateClamped(double x, double y, const ImVec2& pix_offset, const char* fmt, ...) IM_FMTARGS(4);
IMPLOT_API void AnnotateClamped(double x, double y, const ImVec2& pix_offset, const ImVec4& color, const char* fmt, ...) IM_FMTARGS(5);
IMPLOT_API void AnnotateClampedV(double x, double y, const ImVec2& pix_offset, const char* fmt, va_list args) IM_FMTLIST(4);
IMPLOT_API void AnnotateClampedV(double x, double y, const ImVec2& pix_offset, const ImVec4& color, const char* fmt, va_list args) IM_FMTLIST(5);
// Shows a draggable vertical guide line at an x-value. #col defaults to ImGuiCol_Text.
IMPLOT_API bool DragLineX(const char* id, double* x_value, bool show_label = true, const ImVec4& col = IMPLOT_AUTO_COL, float thickness = 1);
// Shows a draggable horizontal guide line at a y-value. #col defaults to ImGuiCol_Text.
IMPLOT_API bool DragLineY(const char* id, double* y_value, bool show_label = true, const ImVec4& col = IMPLOT_AUTO_COL, float thickness = 1);
// Shows a draggable point at x,y. #col defaults to ImGuiCol_Text.
IMPLOT_API bool DragPoint(const char* id, double* x, double* y, bool show_label = true, const ImVec4& col = IMPLOT_AUTO_COL, float radius = 4);
//-----------------------------------------------------------------------------
// Legend Utils and Tools
//-----------------------------------------------------------------------------
// The following functions MUST be called between Begin/EndPlot!
// Set the location of the current plot's legend.
IMPLOT_API void SetLegendLocation(ImPlotLocation location, ImPlotOrientation orientation = ImPlotOrientation_Vertical, bool outside = false);
// Set the location of the current plot's mouse position text (default = South|East).
IMPLOT_API void SetMousePosLocation(ImPlotLocation location);
// Returns true if a plot item legend entry is hovered.
IMPLOT_API bool IsLegendEntryHovered(const char* label_id);
// Begin a drag and drop source from a legend entry. The only supported flag is SourceNoPreviewTooltip
IMPLOT_API bool BeginLegendDragDropSource(const char* label_id, ImGuiDragDropFlags flags = 0);
// End legend drag and drop source.
IMPLOT_API void EndLegendDragDropSource();
// Begin a popup for a legend entry.
IMPLOT_API bool BeginLegendPopup(const char* label_id, ImGuiMouseButton mouse_button = 1);
// End a popup for a legend entry.
IMPLOT_API void EndLegendPopup();
//-----------------------------------------------------------------------------
// Plot and Item Styling
//-----------------------------------------------------------------------------
// Provides access to plot style structure for permanant modifications to colors, sizes, etc.
IMPLOT_API ImPlotStyle& GetStyle();
// Style colors for current ImGui style (default).
IMPLOT_API void StyleColorsAuto(ImPlotStyle* dst = NULL);
// Style colors for ImGui "Classic".
IMPLOT_API void StyleColorsClassic(ImPlotStyle* dst = NULL);
// Style colors for ImGui "Dark".
IMPLOT_API void StyleColorsDark(ImPlotStyle* dst = NULL);
// Style colors for ImGui "Light".
IMPLOT_API void StyleColorsLight(ImPlotStyle* dst = NULL);
// Use PushStyleX to temporarily modify your ImPlotStyle. The modification
// will last until the matching call to PopStyleX. You MUST call a pop for
// every push, otherwise you will leak memory! This behaves just like ImGui.
// Temporarily modify a plot color. Don't forget to call PopStyleColor!
IMPLOT_API void PushStyleColor(ImPlotCol idx, ImU32 col);
IMPLOT_API void PushStyleColor(ImPlotCol idx, const ImVec4& col);
// Undo temporary color modification. Undo multiple pushes at once by increasing count.
IMPLOT_API void PopStyleColor(int count = 1);
// Temporarily modify a style variable of float type. Don't forget to call PopStyleVar!
IMPLOT_API void PushStyleVar(ImPlotStyleVar idx, float val);
// Temporarily modify a style variable of int type. Don't forget to call PopStyleVar!
IMPLOT_API void PushStyleVar(ImPlotStyleVar idx, int val);
// Temporarily modify a style variable of ImVec2 type. Don't forget to call PopStyleVar!
IMPLOT_API void PushStyleVar(ImPlotStyleVar idx, const ImVec2& val);
// Undo temporary style modification. Undo multiple pushes at once by increasing count.
IMPLOT_API void PopStyleVar(int count = 1);
// The following can be used to modify the style of the next plot item ONLY. They do
// NOT require calls to PopStyleX. Leave style attributes you don't want modified to
// IMPLOT_AUTO or IMPLOT_AUTO_COL. Automatic styles will be deduced from the current
// values in your ImPlotStyle or from Colormap data.
// Set the line color and weight for the next item only.
IMPLOT_API void SetNextLineStyle(const ImVec4& col = IMPLOT_AUTO_COL, float weight = IMPLOT_AUTO);
// Set the fill color for the next item only.
IMPLOT_API void SetNextFillStyle(const ImVec4& col = IMPLOT_AUTO_COL, float alpha_mod = IMPLOT_AUTO);
// Set the marker style for the next item only.
IMPLOT_API void SetNextMarkerStyle(ImPlotMarker marker = IMPLOT_AUTO, float size = IMPLOT_AUTO, const ImVec4& fill = IMPLOT_AUTO_COL, float weight = IMPLOT_AUTO, const ImVec4& outline = IMPLOT_AUTO_COL);
// Set the error bar style for the next item only.
IMPLOT_API void SetNextErrorBarStyle(const ImVec4& col = IMPLOT_AUTO_COL, float size = IMPLOT_AUTO, float weight = IMPLOT_AUTO);
// Gets the last item primary color (i.e. its legend icon color)
IMPLOT_API ImVec4 GetLastItemColor();
// Returns the null terminated string name for an ImPlotCol.
IMPLOT_API const char* GetStyleColorName(ImPlotCol idx);
// Returns the null terminated string name for an ImPlotMarker.
IMPLOT_API const char* GetMarkerName(ImPlotMarker idx);
//-----------------------------------------------------------------------------
// Colormaps
//-----------------------------------------------------------------------------
// Item styling is based on Colormaps when the relevant ImPlotCol is set to
// IMPLOT_AUTO_COL (default). Several built in colormaps are available and can be
// toggled in the demo. You can push/pop or set your own colormaps as well.
// The Colormap data will be ignored and a custom color will be used if you have either:
// 1) Modified an item style color in your ImPlotStyle to anything but IMPLOT_AUTO_COL.
// 2) Pushed an item style color using PushStyleColor().
// 3) Set the next item style with a SetNextXStyle function.
// Temporarily switch to one of the built-in colormaps.
IMPLOT_API void PushColormap(ImPlotColormap colormap);
// Temporarily switch to your custom colormap. The pointer data must persist until the matching call to PopColormap!
IMPLOT_API void PushColormap(const ImVec4* colormap, int size);
// Undo temporary colormap modification.
IMPLOT_API void PopColormap(int count = 1);
// Permanently sets a custom colormap. The colors will be copied to internal memory. Prefer PushColormap instead of calling this each frame.
IMPLOT_API void SetColormap(const ImVec4* colormap, int size);
// Permanently switch to one of the built-in colormaps. If samples is greater than 1, the map will be linearly resampled. Don't call this each frame.
IMPLOT_API void SetColormap(ImPlotColormap colormap, int samples = 0);
// Returns the size of the current colormap.
IMPLOT_API int GetColormapSize();
// Returns a color from the Color map given an index >= 0 (modulo will be performed).
IMPLOT_API ImVec4 GetColormapColor(int index);
// Linearly interpolates a color from the current colormap given t between 0 and 1.
IMPLOT_API ImVec4 LerpColormap(float t);
// Returns the next unused colormap color and advances the colormap. Can be used to skip colors if desired.
IMPLOT_API ImVec4 NextColormapColor();
// Renders a vertical color scale using the current color map. Call this outside of Begin/EndPlot.
IMPLOT_API void ShowColormapScale(double scale_min, double scale_max, float height);
// Returns a null terminated string name for a built-in colormap.
IMPLOT_API const char* GetColormapName(ImPlotColormap colormap);
//-----------------------------------------------------------------------------
// Miscellaneous
//-----------------------------------------------------------------------------
// Allows changing how keyboard/mouse interaction works.
IMPLOT_API ImPlotInputMap& GetInputMap();
// Get the plot draw list for rendering to the current plot area.
IMPLOT_API ImDrawList* GetPlotDrawList();
// Push clip rect for rendering to current plot area.
IMPLOT_API void PushPlotClipRect();
// Pop plot clip rect.
IMPLOT_API void PopPlotClipRect();
// Shows ImPlot style selector dropdown menu.
IMPLOT_API bool ShowStyleSelector(const char* label);
// Shows ImPlot colormap selector dropdown menu.
IMPLOT_API bool ShowColormapSelector(const char* label);
// Shows ImPlot style editor block (not a window).
IMPLOT_API void ShowStyleEditor(ImPlotStyle* ref = NULL);
// Add basic help/info block (not a window): how to manipulate ImPlot as an end-user.
IMPLOT_API void ShowUserGuide();
// Shows ImPlot metrics/debug information.
IMPLOT_API void ShowMetricsWindow(bool* p_popen = NULL);
// Sets the current _ImGui_ context. This is ONLY necessary if you are compiling
// ImPlot as a DLL (not recommended) separate from your ImGui compilation. It
// sets the global variable GImGui, which is not shared across DLL boundaries.
// See GImGui documentation in imgui.cpp for more details.
IMPLOT_API void SetImGuiContext(ImGuiContext* ctx);
//-----------------------------------------------------------------------------
// Demo (add implot_demo.cpp to your sources!)
//-----------------------------------------------------------------------------
// Shows the ImPlot demo. Pass the current ImGui context if ImPlot is a DLL.
IMPLOT_API void ShowDemoWindow(bool* p_open = NULL);
} // namespace ImPlot

981
external/ImGui/include/implot_internal.h vendored Normal file
View File

@@ -0,0 +1,981 @@
// MIT License
// Copyright (c) 2020 Evan Pezent
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
// ImPlot v0.8 WIP
// You may use this file to debug, understand or extend ImPlot features but we
// don't provide any guarantee of forward compatibility!
//-----------------------------------------------------------------------------
// [SECTION] Header Mess
//-----------------------------------------------------------------------------
#pragma once
#ifndef IMGUI_DEFINE_MATH_OPERATORS
#define IMGUI_DEFINE_MATH_OPERATORS
#endif
#include <time.h>
#include "imgui_internal.h"
#ifndef IMPLOT_VERSION
#error Must include implot.h before implot_internal.h
#endif
//-----------------------------------------------------------------------------
// [SECTION] Forward Declarations
//-----------------------------------------------------------------------------
struct ImPlotTick;
struct ImPlotAxis;
struct ImPlotAxisState;
struct ImPlotAxisColor;
struct ImPlotItem;
struct ImPlotLegendData;
struct ImPlotPlot;
struct ImPlotNextPlotData;
//-----------------------------------------------------------------------------
// [SECTION] Context Pointer
//-----------------------------------------------------------------------------
extern IMPLOT_API ImPlotContext* GImPlot; // Current implicit context pointer
//-----------------------------------------------------------------------------
// [SECTION] Macros and Constants
//-----------------------------------------------------------------------------
// Constants can be changed unless stated otherwise. We may move some of these
// to ImPlotStyleVar_ over time.
// The maximum number of supported y-axes (DO NOT CHANGE THIS)
#define IMPLOT_Y_AXES 3
// The number of times to subdivided grid divisions (best if a multiple of 1, 2, and 5)
#define IMPLOT_SUB_DIV 10
// Zoom rate for scroll (e.g. 0.1f = 10% plot range every scroll click)
#define IMPLOT_ZOOM_RATE 0.1f
// Mimimum allowable timestamp value 01/01/1970 @ 12:00am (UTC) (DO NOT DECREASE THIS)
#define IMPLOT_MIN_TIME 0
// Maximum allowable timestamp value 01/01/3000 @ 12:00am (UTC) (DO NOT INCREASE THIS)
#define IMPLOT_MAX_TIME 32503680000
//-----------------------------------------------------------------------------
// [SECTION] Generic Helpers
//-----------------------------------------------------------------------------
// Computes the common (base-10) logarithm
static inline float ImLog10(float x) { return log10f(x); }
static inline double ImLog10(double x) { return log10(x); }
// Returns true if a flag is set
template <typename TSet, typename TFlag>
inline bool ImHasFlag(TSet set, TFlag flag) { return (set & flag) == flag; }
// Flips a flag in a flagset
template <typename TSet, typename TFlag>
inline void ImFlipFlag(TSet& set, TFlag flag) { ImHasFlag(set, flag) ? set &= ~flag : set |= flag; }
// Linearly remaps x from [x0 x1] to [y0 y1].
template <typename T>
inline T ImRemap(T x, T x0, T x1, T y0, T y1) { return y0 + (x - x0) * (y1 - y0) / (x1 - x0); }
// Returns always positive modulo (assumes r != 0)
inline int ImPosMod(int l, int r) { return (l % r + r) % r; }
// Returns true if val is NAN or INFINITY
inline bool ImNanOrInf(double val) { return val == HUGE_VAL || val == -HUGE_VAL || isnan(val); }
// Turns NANs to 0s
inline double ImConstrainNan(double val) { return isnan(val) ? 0 : val; }
// Turns infinity to floating point maximums
inline double ImConstrainInf(double val) { return val == HUGE_VAL ? DBL_MAX : val == -HUGE_VAL ? - DBL_MAX : val; }
// Turns numbers less than or equal to 0 to 0.001 (sort of arbitrary, is there a better way?)
inline double ImConstrainLog(double val) { return val <= 0 ? 0.001f : val; }
// Turns numbers less than 0 to zero
inline double ImConstrainTime(double val) { return val < IMPLOT_MIN_TIME ? IMPLOT_MIN_TIME : (val > IMPLOT_MAX_TIME ? IMPLOT_MAX_TIME : val); }
// Offset calculator helper
template <int Count>
struct ImOffsetCalculator {
ImOffsetCalculator(const int* sizes) {
Offsets[0] = 0;
for (int i = 1; i < Count; ++i)
Offsets[i] = Offsets[i-1] + sizes[i-1];
}
int Offsets[Count];
};
// Character buffer writer helper
struct ImBufferWriter
{
char* Buffer;
int Size;
int Pos;
ImBufferWriter(char* buffer, int size) {
Buffer = buffer;
Size = size;
Pos = 0;
}
void Write(const char* fmt, ...) {
va_list argp;
va_start(argp, fmt);
const int written = ::vsnprintf(&Buffer[Pos], Size - Pos - 1, fmt, argp);
if (written > 0)
Pos += ImMin(written, Size-Pos-1);
va_end(argp);
}
};
// Fixed size point array
template <int N>
struct ImPlotPointArray {
inline ImPlotPoint& operator[](int i) { return Data[i]; }
inline const ImPlotPoint& operator[](int i) const { return Data[i]; }
inline int Size() { return N; }
ImPlotPoint Data[N];
};
//-----------------------------------------------------------------------------
// [SECTION] ImPlot Enums
//-----------------------------------------------------------------------------
typedef int ImPlotScale; // -> enum ImPlotScale_
typedef int ImPlotTimeUnit; // -> enum ImPlotTimeUnit_
typedef int ImPlotDateFmt; // -> enum ImPlotDateFmt_
typedef int ImPlotTimeFmt; // -> enum ImPlotTimeFmt_
// XY axes scaling combinations
enum ImPlotScale_ {
ImPlotScale_LinLin, // linear x, linear y
ImPlotScale_LogLin, // log x, linear y
ImPlotScale_LinLog, // linear x, log y
ImPlotScale_LogLog // log x, log y
};
enum ImPlotTimeUnit_ {
ImPlotTimeUnit_Us, // microsecond
ImPlotTimeUnit_Ms, // millisecond
ImPlotTimeUnit_S, // second
ImPlotTimeUnit_Min, // minute
ImPlotTimeUnit_Hr, // hour
ImPlotTimeUnit_Day, // day
ImPlotTimeUnit_Mo, // month
ImPlotTimeUnit_Yr, // year
ImPlotTimeUnit_COUNT
};
enum ImPlotDateFmt_ { // default [ ISO 8601 ]
ImPlotDateFmt_None = 0,
ImPlotDateFmt_DayMo, // 10/3 [ --10-03 ]
ImPlotDateFmt_DayMoYr, // 10/3/91 [ 1991-10-03 ]
ImPlotDateFmt_MoYr, // Oct 1991 [ 1991-10 ]
ImPlotDateFmt_Mo, // Oct [ --10 ]
ImPlotDateFmt_Yr // 1991 [ 1991 ]
};
enum ImPlotTimeFmt_ { // default [ 24 Hour Clock ]
ImPlotTimeFmt_None = 0,
ImPlotTimeFmt_Us, // .428 552 [ .428 552 ]
ImPlotTimeFmt_SUs, // :29.428 552 [ :29.428 552 ]
ImPlotTimeFmt_SMs, // :29.428 [ :29.428 ]
ImPlotTimeFmt_S, // :29 [ :29 ]
ImPlotTimeFmt_HrMinSMs, // 7:21:29.428pm [ 19:21:29.428 ]
ImPlotTimeFmt_HrMinS, // 7:21:29pm [ 19:21:29 ]
ImPlotTimeFmt_HrMin, // 7:21pm [ 19:21 ]
ImPlotTimeFmt_Hr // 7pm [ 19:00 ]
};
//-----------------------------------------------------------------------------
// [SECTION] ImPlot Structs
//-----------------------------------------------------------------------------
// Combined data/time format spec
struct ImPlotDateTimeFmt {
ImPlotDateTimeFmt(ImPlotDateFmt date_fmt, ImPlotTimeFmt time_fmt, bool use_24_hr_clk = false, bool use_iso_8601 = false) {
Date = date_fmt;
Time = time_fmt;
UseISO8601 = use_iso_8601;
Use24HourClock = use_24_hr_clk;
}
ImPlotDateFmt Date;
ImPlotTimeFmt Time;
bool UseISO8601;
bool Use24HourClock;
};
// Two part timestamp struct.
struct ImPlotTime {
time_t S; // second part
int Us; // microsecond part
ImPlotTime() { S = 0; Us = 0; }
ImPlotTime(time_t s, int us = 0) { S = s + us / 1000000; Us = us % 1000000; }
void RollOver() { S = S + Us / 1000000; Us = Us % 1000000; }
double ToDouble() const { return (double)S + (double)Us / 1000000.0; }
static ImPlotTime FromDouble(double t) { return ImPlotTime((time_t)t, (int)(t * 1000000 - floor(t) * 1000000)); }
};
static inline ImPlotTime operator+(const ImPlotTime& lhs, const ImPlotTime& rhs)
{ return ImPlotTime(lhs.S + rhs.S, lhs.Us + rhs.Us); }
static inline ImPlotTime operator-(const ImPlotTime& lhs, const ImPlotTime& rhs)
{ return ImPlotTime(lhs.S - rhs.S, lhs.Us - rhs.Us); }
static inline bool operator==(const ImPlotTime& lhs, const ImPlotTime& rhs)
{ return lhs.S == rhs.S && lhs.Us == rhs.Us; }
static inline bool operator<(const ImPlotTime& lhs, const ImPlotTime& rhs)
{ return lhs.S == rhs.S ? lhs.Us < rhs.Us : lhs.S < rhs.S; }
static inline bool operator>(const ImPlotTime& lhs, const ImPlotTime& rhs)
{ return rhs < lhs; }
static inline bool operator<=(const ImPlotTime& lhs, const ImPlotTime& rhs)
{ return lhs < rhs || lhs == rhs; }
static inline bool operator>=(const ImPlotTime& lhs, const ImPlotTime& rhs)
{ return lhs > rhs || lhs == rhs; }
// Storage for colormap modifiers
struct ImPlotColormapMod {
ImPlotColormapMod(const ImVec4* colormap, int colormap_size) {
Colormap = colormap;
ColormapSize = colormap_size;
}
const ImVec4* Colormap;
int ColormapSize;
};
// ImPlotPoint with positive/negative error values
struct ImPlotPointError
{
double X, Y, Neg, Pos;
ImPlotPointError(double x, double y, double neg, double pos) {
X = x; Y = y; Neg = neg; Pos = pos;
}
};
// Interior plot label/annotation
struct ImPlotAnnotation {
ImVec2 Pos;
ImVec2 Offset;
ImU32 ColorBg;
ImU32 ColorFg;
int TextOffset;
bool Clamp;
};
// Collection of plot labels
struct ImPlotAnnotationCollection {
ImVector<ImPlotAnnotation> Annotations;
ImGuiTextBuffer TextBuffer;
int Size;
ImPlotAnnotationCollection() { Reset(); }
void AppendV(const ImVec2& pos, const ImVec2& off, ImU32 bg, ImU32 fg, bool clamp, const char* fmt, va_list args) IM_FMTLIST(7) {
ImPlotAnnotation an;
an.Pos = pos; an.Offset = off;
an.ColorBg = bg; an.ColorFg = fg;
an.TextOffset = TextBuffer.size();
an.Clamp = clamp;
Annotations.push_back(an);
TextBuffer.appendfv(fmt, args);
const char nul[] = "";
TextBuffer.append(nul,nul+1);
Size++;
}
void Append(const ImVec2& pos, const ImVec2& off, ImU32 bg, ImU32 fg, bool clamp, const char* fmt, ...) IM_FMTARGS(7) {
va_list args;
va_start(args, fmt);
AppendV(pos, off, bg, fg, clamp, fmt, args);
va_end(args);
}
const char* GetText(int idx) {
return TextBuffer.Buf.Data + Annotations[idx].TextOffset;
}
void Reset() {
Annotations.shrink(0);
TextBuffer.Buf.shrink(0);
Size = 0;
}
};
// Tick mark info
struct ImPlotTick
{
double PlotPos;
float PixelPos;
ImVec2 LabelSize;
int TextOffset;
bool Major;
bool ShowLabel;
int Level;
ImPlotTick(double value, bool major, bool show_label) {
PlotPos = value;
Major = major;
ShowLabel = show_label;
TextOffset = -1;
Level = 0;
}
};
// Collection of ticks
struct ImPlotTickCollection {
ImVector<ImPlotTick> Ticks;
ImGuiTextBuffer TextBuffer;
float TotalWidth;
float TotalHeight;
float MaxWidth;
float MaxHeight;
int Size;
ImPlotTickCollection() { Reset(); }
void Append(const ImPlotTick& tick) {
if (tick.ShowLabel) {
TotalWidth += tick.ShowLabel ? tick.LabelSize.x : 0;
TotalHeight += tick.ShowLabel ? tick.LabelSize.y : 0;
MaxWidth = tick.LabelSize.x > MaxWidth ? tick.LabelSize.x : MaxWidth;
MaxHeight = tick.LabelSize.y > MaxHeight ? tick.LabelSize.y : MaxHeight;
}
Ticks.push_back(tick);
Size++;
}
void Append(double value, bool major, bool show_label, void (*labeler)(ImPlotTick& tick, ImGuiTextBuffer& buf)) {
ImPlotTick tick(value, major, show_label);
if (labeler)
labeler(tick, TextBuffer);
Append(tick);
}
const char* GetText(int idx) {
return TextBuffer.Buf.Data + Ticks[idx].TextOffset;
}
void Reset() {
Ticks.shrink(0);
TextBuffer.Buf.shrink(0);
TotalWidth = TotalHeight = MaxWidth = MaxHeight = 0;
Size = 0;
}
};
// Axis state information that must persist after EndPlot
struct ImPlotAxis
{
ImPlotAxisFlags Flags;
ImPlotAxisFlags PreviousFlags;
ImPlotRange Range;
ImPlotOrientation Direction;
bool Dragging;
bool HoveredExt;
bool HoveredTot;
double* LinkedMin;
double* LinkedMax;
ImPlotTime PickerTimeMin, PickerTimeMax;
int PickerLevel;
ImPlotAxis() {
Flags = PreviousFlags = ImPlotAxisFlags_None;
Range.Min = 0;
Range.Max = 1;
Dragging = false;
HoveredExt = false;
HoveredTot = false;
LinkedMin = LinkedMax = NULL;
PickerLevel = 0;
}
bool SetMin(double _min) {
_min = ImConstrainNan(ImConstrainInf(_min));
if (ImHasFlag(Flags, ImPlotAxisFlags_LogScale))
_min = ImConstrainLog(_min);
if (ImHasFlag(Flags, ImPlotAxisFlags_Time))
_min = ImConstrainTime(_min);
if (_min >= Range.Max)
return false;
Range.Min = _min;
PickerTimeMin = ImPlotTime::FromDouble(Range.Min);
return true;
};
bool SetMax(double _max) {
_max = ImConstrainNan(ImConstrainInf(_max));
if (ImHasFlag(Flags, ImPlotAxisFlags_LogScale))
_max = ImConstrainLog(_max);
if (ImHasFlag(Flags, ImPlotAxisFlags_Time))
_max = ImConstrainTime(_max);
if (_max <= Range.Min)
return false;
Range.Max = _max;
PickerTimeMax = ImPlotTime::FromDouble(Range.Max);
return true;
};
void SetRange(double _min, double _max) {
Range.Min = _min;
Range.Max = _max;
Constrain();
PickerTimeMin = ImPlotTime::FromDouble(Range.Min);
PickerTimeMax = ImPlotTime::FromDouble(Range.Max);
}
void SetRange(const ImPlotRange& range) {
SetRange(range.Min, range.Max);
}
void Constrain() {
Range.Min = ImConstrainNan(ImConstrainInf(Range.Min));
Range.Max = ImConstrainNan(ImConstrainInf(Range.Max));
if (ImHasFlag(Flags, ImPlotAxisFlags_LogScale)) {
Range.Min = ImConstrainLog(Range.Min);
Range.Max = ImConstrainLog(Range.Max);
}
if (ImHasFlag(Flags, ImPlotAxisFlags_Time)) {
Range.Min = ImConstrainTime(Range.Min);
Range.Max = ImConstrainTime(Range.Max);
}
if (Range.Max <= Range.Min)
Range.Max = Range.Min + DBL_EPSILON;
}
};
// Axis state information only needed between BeginPlot/EndPlot
struct ImPlotAxisState
{
ImPlotAxis* Axis;
ImGuiCond RangeCond;
bool HasRange;
bool Present;
bool HasLabels;
bool Invert;
bool LockMin;
bool LockMax;
bool Lock;
bool IsTime;
ImPlotAxisState(ImPlotAxis* axis, bool has_range, ImGuiCond range_cond, bool present) {
Axis = axis;
HasRange = has_range;
RangeCond = range_cond;
Present = present;
HasLabels = !ImHasFlag(Axis->Flags, ImPlotAxisFlags_NoTickLabels);
Invert = ImHasFlag(Axis->Flags, ImPlotAxisFlags_Invert);
LockMin = ImHasFlag(Axis->Flags, ImPlotAxisFlags_LockMin) || (HasRange && RangeCond == ImGuiCond_Always);
LockMax = ImHasFlag(Axis->Flags, ImPlotAxisFlags_LockMax) || (HasRange && RangeCond == ImGuiCond_Always);
Lock = !Present || ((LockMin && LockMax) || (HasRange && RangeCond == ImGuiCond_Always));
IsTime = ImHasFlag(Axis->Flags, ImPlotAxisFlags_Time);
}
ImPlotAxisState() { }
};
struct ImPlotAxisColor
{
ImU32 Major, Minor, MajTxt, MinTxt;
ImPlotAxisColor() { Major = Minor = MajTxt = MinTxt = 0; }
};
// State information for Plot items
struct ImPlotItem
{
ImGuiID ID;
ImVec4 Color;
int NameOffset;
bool Show;
bool LegendHovered;
bool SeenThisFrame;
ImPlotItem() {
ID = 0;
Color = ImPlot::NextColormapColor();
NameOffset = -1;
Show = true;
SeenThisFrame = false;
LegendHovered = false;
}
~ImPlotItem() { ID = 0; }
};
// Holds Legend state labels and item references
struct ImPlotLegendData
{
ImVector<int> Indices;
ImGuiTextBuffer Labels;
void Reset() { Indices.shrink(0); Labels.Buf.shrink(0); }
};
// Holds Plot state information that must persist after EndPlot
struct ImPlotPlot
{
ImGuiID ID;
ImPlotFlags Flags;
ImPlotFlags PreviousFlags;
ImPlotAxis XAxis;
ImPlotAxis YAxis[IMPLOT_Y_AXES];
ImPlotLegendData LegendData;
ImPool<ImPlotItem> Items;
ImVec2 SelectStart;
ImVec2 QueryStart;
ImRect QueryRect;
bool Selecting;
bool Querying;
bool Queried;
bool DraggingQuery;
bool LegendHovered;
bool LegendOutside;
bool LegendFlipSide;
int ColormapIdx;
int CurrentYAxis;
ImPlotLocation MousePosLocation;
ImPlotLocation LegendLocation;
ImPlotOrientation LegendOrientation;
ImPlotPlot() {
Flags = PreviousFlags = ImPlotFlags_None;
XAxis.Direction = ImPlotOrientation_Horizontal;
for (int i = 0; i < IMPLOT_Y_AXES; ++i)
YAxis[i].Direction = ImPlotOrientation_Vertical;
SelectStart = QueryStart = ImVec2(0,0);
Selecting = Querying = Queried = DraggingQuery = LegendHovered = LegendOutside = LegendFlipSide = false;
ColormapIdx = CurrentYAxis = 0;
LegendLocation = ImPlotLocation_North | ImPlotLocation_West;
LegendOrientation = ImPlotOrientation_Vertical;
MousePosLocation = ImPlotLocation_South | ImPlotLocation_East;
}
int GetLegendCount() const { return LegendData.Indices.size(); }
ImPlotItem* GetLegendItem(int i);
const char* GetLegendLabel(int i);
};
// Temporary data storage for upcoming plot
struct ImPlotNextPlotData
{
ImGuiCond XRangeCond;
ImGuiCond YRangeCond[IMPLOT_Y_AXES];
ImPlotRange X;
ImPlotRange Y[IMPLOT_Y_AXES];
bool HasXRange;
bool HasYRange[IMPLOT_Y_AXES];
bool ShowDefaultTicksX;
bool ShowDefaultTicksY[IMPLOT_Y_AXES];
bool FitX;
bool FitY[IMPLOT_Y_AXES];
double* LinkedXmin;
double* LinkedXmax;
double* LinkedYmin[IMPLOT_Y_AXES];
double* LinkedYmax[IMPLOT_Y_AXES];
ImPlotNextPlotData() {
HasXRange = false;
ShowDefaultTicksX = true;
FitX = false;
LinkedXmin = LinkedXmax = NULL;
for (int i = 0; i < IMPLOT_Y_AXES; ++i) {
HasYRange[i] = false;
ShowDefaultTicksY[i] = true;
FitY[i] = false;
LinkedYmin[i] = LinkedYmax[i] = NULL;
}
}
};
// Temporary data storage for upcoming item
struct ImPlotNextItemData {
ImVec4 Colors[5]; // ImPlotCol_Line, ImPlotCol_Fill, ImPlotCol_MarkerOutline, ImPlotCol_MarkerFill, ImPlotCol_ErrorBar
float LineWeight;
ImPlotMarker Marker;
float MarkerSize;
float MarkerWeight;
float FillAlpha;
float ErrorBarSize;
float ErrorBarWeight;
float DigitalBitHeight;
float DigitalBitGap;
bool RenderLine;
bool RenderFill;
bool RenderMarkerLine;
bool RenderMarkerFill;
bool HasHidden;
bool Hidden;
ImGuiCond HiddenCond;
ImPlotNextItemData() {
for (int i = 0; i < 5; ++i)
Colors[i] = IMPLOT_AUTO_COL;
LineWeight = MarkerSize = MarkerWeight = FillAlpha = ErrorBarSize = ErrorBarWeight = DigitalBitHeight = DigitalBitGap = IMPLOT_AUTO;
Marker = IMPLOT_AUTO;
HasHidden = Hidden = false;
}
};
// Holds state information that must persist between calls to BeginPlot()/EndPlot()
struct ImPlotContext {
// Plot States
ImPool<ImPlotPlot> Plots;
ImPlotPlot* CurrentPlot;
ImPlotItem* CurrentItem;
ImPlotItem* PreviousItem;
// Bounding Boxes
ImRect BB_Frame;
ImRect BB_Canvas;
ImRect BB_Plot;
ImRect BB_Axes;
ImRect BB_X;
ImRect BB_Y[IMPLOT_Y_AXES];
// Axis States
ImPlotAxisColor Col_X;
ImPlotAxisColor Col_Y[IMPLOT_Y_AXES];
ImPlotAxisState X;
ImPlotAxisState Y[IMPLOT_Y_AXES];
// Tick Marks and Labels
ImPlotTickCollection XTicks;
ImPlotTickCollection YTicks[IMPLOT_Y_AXES];
float YAxisReference[IMPLOT_Y_AXES];
// Annotation and User Labels
ImPlotAnnotationCollection Annotations;
// Transformations and Data Extents
ImPlotScale Scales[IMPLOT_Y_AXES];
ImRect PixelRange[IMPLOT_Y_AXES];
double Mx;
double My[IMPLOT_Y_AXES];
double LogDenX;
double LogDenY[IMPLOT_Y_AXES];
ImPlotRange ExtentsX;
ImPlotRange ExtentsY[IMPLOT_Y_AXES];
// Data Fitting Flags
bool FitThisFrame;
bool FitX;
bool FitY[IMPLOT_Y_AXES];
// Hover states
bool Hov_Frame;
bool Hov_Plot;
// Axis Rendering Flags
bool RenderX;
bool RenderY[IMPLOT_Y_AXES];
// Axis Locking Flags
bool LockPlot;
bool ChildWindowMade;
// Style and Colormaps
ImPlotStyle Style;
ImVector<ImGuiColorMod> ColorModifiers;
ImVector<ImGuiStyleMod> StyleModifiers;
const ImVec4* Colormap;
int ColormapSize;
ImVector<ImPlotColormapMod> ColormapModifiers;
// Time
tm Tm;
// Misc
int VisibleItemCount;
int DigitalPlotItemCnt;
int DigitalPlotOffset;
ImPlotNextPlotData NextPlotData;
ImPlotNextItemData NextItemData;
ImPlotInputMap InputMap;
ImPlotPoint MousePos[IMPLOT_Y_AXES];
};
struct ImPlotAxisScale
{
ImPlotPoint Min, Max;
ImPlotAxisScale(int y_axis, float tx, float ty, float zoom_rate) {
ImPlotContext& gp = *GImPlot;
Min = ImPlot::PixelsToPlot(gp.BB_Plot.Min - gp.BB_Plot.GetSize() * ImVec2(tx * zoom_rate, ty * zoom_rate), y_axis);
Max = ImPlot::PixelsToPlot(gp.BB_Plot.Max + gp.BB_Plot.GetSize() * ImVec2((1 - tx) * zoom_rate, (1 - ty) * zoom_rate), y_axis);
}
};
//-----------------------------------------------------------------------------
// [SECTION] Internal API
// No guarantee of forward compatibility here!
//-----------------------------------------------------------------------------
namespace ImPlot {
//-----------------------------------------------------------------------------
// [SECTION] Context Utils
//-----------------------------------------------------------------------------
// Initializes an ImPlotContext
IMPLOT_API void Initialize(ImPlotContext* ctx);
// Resets an ImPlot context for the next call to BeginPlot
IMPLOT_API void Reset(ImPlotContext* ctx);
//-----------------------------------------------------------------------------
// [SECTION] Plot Utils
//-----------------------------------------------------------------------------
// Gets a plot from the current ImPlotContext
IMPLOT_API ImPlotPlot* GetPlot(const char* title);
// Gets the current plot from the current ImPlotContext
IMPLOT_API ImPlotPlot* GetCurrentPlot();
// Busts the cache for every plot in the current context
IMPLOT_API void BustPlotCache();
// Shows a plot's context menu.
IMPLOT_API void ShowPlotContextMenu(ImPlotPlot& plot);
//-----------------------------------------------------------------------------
// [SECTION] Item Utils
//-----------------------------------------------------------------------------
// Begins a new item. Returns false if the item should not be plotted. Pushes PlotClipRect.
IMPLOT_API bool BeginItem(const char* label_id, ImPlotCol recolor_from = -1);
// Ends an item (call only if BeginItem returns true). Pops PlotClipRect.
IMPLOT_API void EndItem();
// Register or get an existing item from the current plot.
IMPLOT_API ImPlotItem* RegisterOrGetItem(const char* label_id, bool* just_created = NULL);
// Get a plot item from the current plot.
IMPLOT_API ImPlotItem* GetItem(const char* label_id);
// Gets the current item.
IMPLOT_API ImPlotItem* GetCurrentItem();
// Busts the cache for every item for every plot in the current context.
IMPLOT_API void BustItemCache();
//-----------------------------------------------------------------------------
// [SECTION] Axis Utils
//-----------------------------------------------------------------------------
// Gets the current y-axis for the current plot
inline int GetCurrentYAxis() { return GImPlot->CurrentPlot->CurrentYAxis; }
// Updates axis ticks, lins, and label colors
IMPLOT_API void UpdateAxisColors(int axis_flag, ImPlotAxisColor* col);
// Updates plot-to-pixel space transformation variables for the current plot.
IMPLOT_API void UpdateTransformCache();
// Gets the XY scale for the current plot and y-axis
inline ImPlotScale GetCurrentScale() { return GImPlot->Scales[GetCurrentYAxis()]; }
// Returns true if the user has requested data to be fit.
inline bool FitThisFrame() { return GImPlot->FitThisFrame; }
// Extends the current plots axes so that it encompasses point p
IMPLOT_API void FitPoint(const ImPlotPoint& p);
// Returns true if two ranges overlap
inline bool RangesOverlap(const ImPlotRange& r1, const ImPlotRange& r2)
{ return r1.Min <= r2.Max && r2.Min <= r1.Max; }
// Updates pointers for linked axes from axis internal range.
IMPLOT_API void PushLinkedAxis(ImPlotAxis& axis);
// Updates axis internal range from points for linked axes.
IMPLOT_API void PullLinkedAxis(ImPlotAxis& axis);
// Shows an axis's context menu.
IMPLOT_API void ShowAxisContextMenu(ImPlotAxisState& state, bool time_allowed = false);
//-----------------------------------------------------------------------------
// [SECTION] Legend Utils
//-----------------------------------------------------------------------------
// Gets the position of an inner rect that is located inside of an outer rect according to an ImPlotLocation and padding amount.
IMPLOT_API ImVec2 GetLocationPos(const ImRect& outer_rect, const ImVec2& inner_size, ImPlotLocation location, const ImVec2& pad = ImVec2(0,0));
// Calculates the bounding box size of a legend
IMPLOT_API ImVec2 CalcLegendSize(ImPlotPlot& plot, const ImVec2& pad, const ImVec2& spacing, ImPlotOrientation orientation);
// Renders legend entries into a bounding box
IMPLOT_API void ShowLegendEntries(ImPlotPlot& plot, const ImRect& legend_bb, bool interactable, const ImVec2& pad, const ImVec2& spacing, ImPlotOrientation orientation, ImDrawList& DrawList);
// Shows an alternate legend for the plot identified by #title_id, outside of the plot frame (can be called before or after of Begin/EndPlot but must occur in the same ImGui window!).
IMPLOT_API void ShowAltLegend(const char* title_id, ImPlotOrientation orientation = ImPlotOrientation_Vertical, const ImVec2 size = ImVec2(0,0), bool interactable = true);
//-----------------------------------------------------------------------------
// [SECTION] Tick Utils
//-----------------------------------------------------------------------------
// Label a tick with default formatting.
IMPLOT_API void LabelTickDefault(ImPlotTick& tick, ImGuiTextBuffer& buffer);
// Label a tick with scientific formating.
IMPLOT_API void LabelTickScientific(ImPlotTick& tick, ImGuiTextBuffer& buffer);
// Label a tick with time formatting.
IMPLOT_API void LabelTickTime(ImPlotTick& tick, ImGuiTextBuffer& buffer, const ImPlotTime& t, ImPlotDateTimeFmt fmt);
// Populates a list of ImPlotTicks with normal spaced and formatted ticks
IMPLOT_API void AddTicksDefault(const ImPlotRange& range, int nMajor, int nMinor, ImPlotTickCollection& ticks);
// Populates a list of ImPlotTicks with logarithmic space and formatted ticks
IMPLOT_API void AddTicksLogarithmic(const ImPlotRange& range, int nMajor, ImPlotTickCollection& ticks);
// Populates a list of ImPlotTicks with time formatted ticks.
IMPLOT_API void AddTicksTime(const ImPlotRange& range, int nMajor, ImPlotTickCollection& ticks);
// Populates a list of ImPlotTicks with custom spaced and labeled ticks
IMPLOT_API void AddTicksCustom(const double* values, const char* const labels[], int n, ImPlotTickCollection& ticks);
// Create a a string label for a an axis value
IMPLOT_API int LabelAxisValue(const ImPlotAxis& axis, const ImPlotTickCollection& ticks, double value, char* buff, int size);
//-----------------------------------------------------------------------------
// [SECTION] Styling Utils
//-----------------------------------------------------------------------------
// Get styling data for next item (call between Begin/EndItem)
inline const ImPlotNextItemData& GetItemData() { return GImPlot->NextItemData; }
// Returns true if a color is set to be automatically determined
inline bool IsColorAuto(const ImVec4& col) { return col.w == -1; }
// Returns true if a style color is set to be automaticaly determined
inline bool IsColorAuto(ImPlotCol idx) { return IsColorAuto(GImPlot->Style.Colors[idx]); }
// Returns the automatically deduced style color
IMPLOT_API ImVec4 GetAutoColor(ImPlotCol idx);
// Returns the style color whether it is automatic or custom set
inline ImVec4 GetStyleColorVec4(ImPlotCol idx) { return IsColorAuto(idx) ? GetAutoColor(idx) : GImPlot->Style.Colors[idx]; }
inline ImU32 GetStyleColorU32(ImPlotCol idx) { return ImGui::ColorConvertFloat4ToU32(GetStyleColorVec4(idx)); }
// Get built-in colormap data and size
IMPLOT_API const ImVec4* GetColormap(ImPlotColormap colormap, int* size_out);
// Linearly interpolates a color from the current colormap given t between 0 and 1.
IMPLOT_API ImVec4 LerpColormap(const ImVec4* colormap, int size, float t);
// Resamples a colormap. #size_out must be greater than 1.
IMPLOT_API void ResampleColormap(const ImVec4* colormap_in, int size_in, ImVec4* colormap_out, int size_out);
// Draws vertical text. The position is the bottom left of the text rect.
IMPLOT_API void AddTextVertical(ImDrawList *DrawList, ImVec2 pos, ImU32 col, const char* text_begin, const char* text_end = NULL);
// Calculates the size of vertical text
inline ImVec2 CalcTextSizeVertical(const char *text) { ImVec2 sz = ImGui::CalcTextSize(text); return ImVec2(sz.y, sz.x); }
// Returns white or black text given background color
inline ImU32 CalcTextColor(const ImVec4& bg) { return (bg.x * 0.299 + bg.y * 0.587 + bg.z * 0.114) > 0.5 ? IM_COL32_BLACK : IM_COL32_WHITE; }
// Clamps a label position so that it fits a rect defined by Min/Max
inline ImVec2 ClampLabelPos(ImVec2 pos, const ImVec2& size, const ImVec2& Min, const ImVec2& Max) {
if (pos.x < Min.x) pos.x = Min.x;
if (pos.y < Min.y) pos.y = Min.y;
if ((pos.x + size.x) > Max.x) pos.x = Max.x - size.x;
if ((pos.y + size.y) > Max.y) pos.y = Max.y - size.y;
return pos;
}
//-----------------------------------------------------------------------------
// [SECTION] Math and Misc Utils
//-----------------------------------------------------------------------------
// Rounds x to powers of 2,5 and 10 for generating axis labels (from Graphics Gems 1 Chapter 11.2)
IMPLOT_API double NiceNum(double x, bool round);
// Computes order of magnitude of double.
inline int OrderOfMagnitude(double val) { return val == 0 ? 0 : (int)(floor(log10(fabs(val)))); }
// Returns the precision required for a order of magnitude.
inline int OrderToPrecision(int order) { return order > 0 ? 0 : 1 - order; }
// Returns a floating point precision to use given a value
inline int Precision(double val) { return OrderToPrecision(OrderOfMagnitude(val)); }
// Returns the intersection point of two lines A and B (assumes they are not parallel!)
inline ImVec2 Intersection(const ImVec2& a1, const ImVec2& a2, const ImVec2& b1, const ImVec2& b2) {
float v1 = (a1.x * a2.y - a1.y * a2.x); float v2 = (b1.x * b2.y - b1.y * b2.x);
float v3 = ((a1.x - a2.x) * (b1.y - b2.y) - (a1.y - a2.y) * (b1.x - b2.x));
return ImVec2((v1 * (b1.x - b2.x) - v2 * (a1.x - a2.x)) / v3, (v1 * (b1.y - b2.y) - v2 * (a1.y - a2.y)) / v3);
}
// Fills a buffer with n samples linear interpolated from vmin to vmax
template <typename T>
void FillRange(ImVector<T>& buffer, int n, T vmin, T vmax) {
buffer.resize(n);
T step = (vmax - vmin) / (n - 1);
for (int i = 0; i < n; ++i) {
buffer[i] = vmin + i * step;
}
}
// Offsets and strides a data buffer
template <typename T>
inline T OffsetAndStride(const T* data, int idx, int count, int offset, int stride) {
idx = ImPosMod(offset + idx, count);
return *(const T*)(const void*)((const unsigned char*)data + (size_t)idx * stride);
}
//-----------------------------------------------------------------------------
// Time Utils
//-----------------------------------------------------------------------------
// Returns true if year is leap year (366 days long)
inline bool IsLeapYear(int year) {
return year % 4 == 0 && (year % 100 != 0 || year % 400 == 0);
}
// Returns the number of days in a month, accounting for Feb. leap years. #month is zero indexed.
inline int GetDaysInMonth(int year, int month) {
static const int days[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
return days[month] + (int)(month == 1 && IsLeapYear(year));
}
// Make a UNIX timestamp from a tm struct expressed in UTC time (i.e. GMT timezone).
IMPLOT_API ImPlotTime MkGmtTime(struct tm *ptm);
// Make a tm struct expressed in UTC time (i.e. GMT timezone) from a UNIX timestamp.
IMPLOT_API tm* GetGmtTime(const ImPlotTime& t, tm* ptm);
// Make a UNIX timestamp from a tm struct expressed in local time.
IMPLOT_API ImPlotTime MkLocTime(struct tm *ptm);
// Make a tm struct expressed in local time from a UNIX timestamp.
IMPLOT_API tm* GetLocTime(const ImPlotTime& t, tm* ptm);
// NB: The following functions only work if there is a current ImPlotContext because the
// internal tm struct is owned by the context! They are aware of ImPlotStyle.UseLocalTime.
// Make a timestamp from time components.
// year[1970-3000], month[0-11], day[1-31], hour[0-23], min[0-59], sec[0-59], us[0,999999]
IMPLOT_API ImPlotTime MakeTime(int year, int month = 0, int day = 1, int hour = 0, int min = 0, int sec = 0, int us = 0);
// Get year component from timestamp [1970-3000]
IMPLOT_API int GetYear(const ImPlotTime& t);
// Adds or subtracts time from a timestamp. #count > 0 to add, < 0 to subtract.
IMPLOT_API ImPlotTime AddTime(const ImPlotTime& t, ImPlotTimeUnit unit, int count);
// Rounds a timestamp down to nearest unit.
IMPLOT_API ImPlotTime FloorTime(const ImPlotTime& t, ImPlotTimeUnit unit);
// Rounds a timestamp up to the nearest unit.
IMPLOT_API ImPlotTime CeilTime(const ImPlotTime& t, ImPlotTimeUnit unit);
// Rounds a timestamp up or down to the nearest unit.
IMPLOT_API ImPlotTime RoundTime(const ImPlotTime& t, ImPlotTimeUnit unit);
// Combines the date of one timestamp with the time-of-day of another timestamp.
IMPLOT_API ImPlotTime CombineDateTime(const ImPlotTime& date_part, const ImPlotTime& time_part);
// Formats the time part of timestamp t into a buffer according to #fmt
IMPLOT_API int FormatTime(const ImPlotTime& t, char* buffer, int size, ImPlotTimeFmt fmt, bool use_24_hr_clk);
// Formats the date part of timestamp t into a buffer according to #fmt
IMPLOT_API int FormatDate(const ImPlotTime& t, char* buffer, int size, ImPlotDateFmt fmt, bool use_iso_8601);
// Formats the time and/or date parts of a timestamp t into a buffer according to #fmt
IMPLOT_API int FormatDateTime(const ImPlotTime& t, char* buffer, int size, ImPlotDateTimeFmt fmt);
// Shows a date picker widget block (year/month/day).
// #level = 0 for day, 1 for month, 2 for year. Modified by user interaction.
// #t will be set when a day is clicked and the function will return true.
// #t1 and #t2 are optional dates to highlight.
IMPLOT_API bool ShowDatePicker(const char* id, int* level, ImPlotTime* t, const ImPlotTime* t1 = NULL, const ImPlotTime* t2 = NULL);
// Shows a time picker widget block (hour/min/sec).
// #t will be set when a new hour, minute, or sec is selected or am/pm is toggled, and the function will return true.
IMPLOT_API bool ShowTimePicker(const char* id, ImPlotTime* t);
//-----------------------------------------------------------------------------
// [SECTION] Internal / Experimental Plotters
// No guarantee of forward compatibility here!
//-----------------------------------------------------------------------------
// Plots axis-aligned, filled rectangles. Every two consecutive points defines opposite corners of a single rectangle.
IMPLOT_API void PlotRects(const char* label_id, const float* xs, const float* ys, int count, int offset = 0, int stride = sizeof(float));
IMPLOT_API void PlotRects(const char* label_id, const double* xs, const double* ys, int count, int offset = 0, int stride = sizeof(double));
IMPLOT_API void PlotRects(const char* label_id, ImPlotPoint (*getter)(void* data, int idx), void* data, int count, int offset = 0);
} // namespace ImPlot

7762
external/ImGui/include/stb_image.h vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1127,7 +1127,7 @@ void TextEditor::Render(const char* aTitle, const ImVec2& aSize, bool aBorder)
ImGui::PushStyleColor(ImGuiCol_ChildBg, ImGui::ColorConvertU32ToFloat4(mPalette[(int)PaletteIndex::Background]));
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0.0f, 0.0f));
if (!mIgnoreImGuiChild)
ImGui::BeginChild(aTitle, aSize, aBorder, ImGuiWindowFlags_HorizontalScrollbar | ImGuiWindowFlags_AlwaysHorizontalScrollbar | ImGuiWindowFlags_NoMove);
ImGui::BeginChild(aTitle, aSize, aBorder, ImGuiWindowFlags_HorizontalScrollbar | ImGuiWindowFlags_NoMove);
if (mHandleKeyboardInputs)
{

View File

@@ -1,4 +1,4 @@
// dear imgui, v1.80 WIP
// dear imgui, v1.80
// (main code and documentation)
// Help:
@@ -126,7 +126,7 @@ CODE
- You can apply arithmetic operators +,*,/ on numerical values. Use +- to subtract (because - would set a negative value!)
- Controls are automatically adjusted for OSX to match standard OSX text editing operations.
- General Keyboard controls: enable with ImGuiConfigFlags_NavEnableKeyboard.
- General Gamepad controls: enable with ImGuiConfigFlags_NavEnableGamepad. See suggested mappings in imgui.h ImGuiNavInput_ + download PNG/PSD at http://goo.gl/9LgVZW
- General Gamepad controls: enable with ImGuiConfigFlags_NavEnableGamepad. See suggested mappings in imgui.h ImGuiNavInput_ + download PNG/PSD at http://dearimgui.org/controls_sheets
PROGRAMMER GUIDE
@@ -158,18 +158,20 @@ CODE
HOW TO UPDATE TO A NEWER VERSION OF DEAR IMGUI
----------------------------------------------
- Overwrite all the sources files except for imconfig.h (if you have made modification to your copy of imconfig.h)
- Or maintain your own branch where you have imconfig.h modified.
- Or maintain your own branch where you have imconfig.h modified as a top-most commit which you can regularly rebase over master.
- You can also use '#define IMGUI_USER_CONFIG "my_config_file.h" to redirect configuration to your own file.
- Read the "API BREAKING CHANGES" section (below). This is where we list occasional API breaking changes.
If a function/type has been renamed / or marked obsolete, try to fix the name in your code before it is permanently removed
from the public API. If you have a problem with a missing function/symbols, search for its name in the code, there will
likely be a comment about it. Please report any issue to the GitHub page!
- Try to keep your copy of dear imgui reasonably up to date.
- To find out usage of old API, you can add '#define IMGUI_DISABLE_OBSOLETE_FUNCTIONS' in your configuration file.
- Try to keep your copy of Dear ImGui reasonably up to date.
GETTING STARTED WITH INTEGRATING DEAR IMGUI IN YOUR CODE/ENGINE
---------------------------------------------------------------
- Run and study the examples and demo in imgui_demo.cpp to get acquainted with the library.
- In the majority of cases you should be able to use unmodified backends files available in the examples/ folder.
- In the majority of cases you should be able to use unmodified backends files available in the backends/ folder.
- Add the Dear ImGui source files + selected backend source files to your projects or using your preferred build system.
It is recommended you build and statically link the .cpp files as part of your project and NOT as shared library (DLL).
- You can later customize the imconfig.h file to tweak some compile-time behavior, such as integrating Dear ImGui types with your own maths types.
@@ -350,7 +352,7 @@ CODE
0.0f= not held. 1.0f= fully held. Pass intermediate 0.0f..1.0f values for analog triggers/sticks.
- We uses a simple >0.0f test for activation testing, and won't attempt to test for a dead-zone.
Your code will probably need to transform your raw inputs (such as e.g. remapping your 0.2..0.9 raw input range to 0.0..1.0 imgui range, etc.).
- You can download PNG/PSD files depicting the gamepad controls for common controllers at: http://goo.gl/9LgVZW.
- You can download PNG/PSD files depicting the gamepad controls for common controllers at: http://dearimgui.org/controls_sheets
- If you need to share inputs between your game and the imgui parts, the easiest approach is to go all-or-nothing, with a buttons combo
to toggle the target. Please reach out if you think the game vs navigation input sharing could be improved.
- Mouse:
@@ -382,6 +384,14 @@ CODE
- 2020/XX/XX (1.XX) - Moved IME support functions from io.ImeSetInputScreenPosFn, io.ImeWindowHandle to the PlatformIO api.
- 2020/12/21 (1.80) - removed redirecting functions/enums that were marked obsolete in 1.63 (August 2018):
- ImGui::IsItemDeactivatedAfterChange() -> use ImGui::IsItemDeactivatedAfterEdit().
- ImGuiCol_ModalWindowDarkening -> use ImGuiCol_ModalWindowDimBg
- ImGuiInputTextCallback -> use ImGuiTextEditCallback
- ImGuiInputTextCallbackData -> use ImGuiTextEditCallbackData
- 2020/12/21 (1.80) - renamed ImDrawList::AddBezierCurve() to AddBezierCubic(), and PathBezierCurveTo() to PathBezierCubicCurveTo(). Kept inline redirection function (will obsolete).
- 2020/12/04 (1.80) - added imgui_tables.cpp file! Manually constructed project files will need the new file added!
- 2020/11/18 (1.80) - renamed undocumented/internals ImGuiColumnsFlags_* to ImGuiOldColumnFlags_* in prevision of incoming Tables API.
- 2020/11/03 (1.80) - renamed io.ConfigWindowsMemoryCompactTimer to io.ConfigMemoryCompactTimer as the feature will apply to other data structures
- 2020/10/14 (1.80) - backends: moved all backends files (imgui_impl_XXXX.cpp, imgui_impl_XXXX.h) from examples/ to backends/.
- 2020/10/12 (1.80) - removed redirecting functions/enums that were marked obsolete in 1.60 (April 2018):
@@ -958,7 +968,7 @@ ImGuiStyle::ImGuiStyle()
{
Alpha = 1.0f; // Global alpha applies to everything in ImGui
WindowPadding = ImVec2(8,8); // Padding within a window
WindowRounding = 7.0f; // Radius of window corners rounding. Set to 0.0f to have rectangular windows. Large values tend to lead to variety of artifacts and are not recommended.
WindowRounding = 0.0f; // Radius of window corners rounding. Set to 0.0f to have rectangular windows. Large values tend to lead to variety of artifacts and are not recommended.
WindowBorderSize = 1.0f; // Thickness of border around windows. Generally set to 0.0f or 1.0f. Other values not well tested.
WindowMinSize = ImVec2(32,32); // Minimum window size
WindowTitleAlign = ImVec2(0.0f,0.5f);// Alignment for title bar text
@@ -1155,7 +1165,7 @@ void ImGuiIO::ClearInputCharacters()
// [SECTION] MISC HELPERS/UTILITIES (Geometry functions)
//-----------------------------------------------------------------------------
ImVec2 ImBezierClosestPoint(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, const ImVec2& p, int num_segments)
ImVec2 ImBezierCubicClosestPoint(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, const ImVec2& p, int num_segments)
{
IM_ASSERT(num_segments > 0); // Use ImBezierClosestPointCasteljau()
ImVec2 p_last = p1;
@@ -1164,7 +1174,7 @@ ImVec2 ImBezierClosestPoint(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3
float t_step = 1.0f / (float)num_segments;
for (int i_step = 1; i_step <= num_segments; i_step++)
{
ImVec2 p_current = ImBezierCalc(p1, p2, p3, p4, t_step * i_step);
ImVec2 p_current = ImBezierCubicCalc(p1, p2, p3, p4, t_step * i_step);
ImVec2 p_line = ImLineClosestPoint(p_last, p_current, p);
float dist2 = ImLengthSqr(p - p_line);
if (dist2 < p_closest_dist2)
@@ -1178,7 +1188,7 @@ ImVec2 ImBezierClosestPoint(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3
}
// Closely mimics PathBezierToCasteljau() in imgui_draw.cpp
static void BezierClosestPointCasteljauStep(const ImVec2& p, ImVec2& p_closest, ImVec2& p_last, float& p_closest_dist2, float x1, float y1, float x2, float y2, float x3, float y3, float x4, float y4, float tess_tol, int level)
static void ImBezierCubicClosestPointCasteljauStep(const ImVec2& p, ImVec2& p_closest, ImVec2& p_last, float& p_closest_dist2, 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;
@@ -1206,20 +1216,20 @@ static void BezierClosestPointCasteljauStep(const ImVec2& p, ImVec2& p_closest,
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;
BezierClosestPointCasteljauStep(p, p_closest, p_last, p_closest_dist2, x1, y1, x12, y12, x123, y123, x1234, y1234, tess_tol, level + 1);
BezierClosestPointCasteljauStep(p, p_closest, p_last, p_closest_dist2, x1234, y1234, x234, y234, x34, y34, x4, y4, tess_tol, level + 1);
ImBezierCubicClosestPointCasteljauStep(p, p_closest, p_last, p_closest_dist2, x1, y1, x12, y12, x123, y123, x1234, y1234, tess_tol, level + 1);
ImBezierCubicClosestPointCasteljauStep(p, p_closest, p_last, p_closest_dist2, x1234, y1234, x234, y234, x34, y34, x4, y4, tess_tol, level + 1);
}
}
// tess_tol is generally the same value you would find in ImGui::GetStyle().CurveTessellationTol
// Because those ImXXX functions are lower-level than ImGui:: we cannot access this value automatically.
ImVec2 ImBezierClosestPointCasteljau(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, const ImVec2& p, float tess_tol)
ImVec2 ImBezierCubicClosestPointCasteljau(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, const ImVec2& p, float tess_tol)
{
IM_ASSERT(tess_tol > 0.0f);
ImVec2 p_last = p1;
ImVec2 p_closest;
float p_closest_dist2 = FLT_MAX;
BezierClosestPointCasteljauStep(p, p_closest, p_last, p_closest_dist2, p1.x, p1.y, p2.x, p2.y, p3.x, p3.y, p4.x, p4.y, tess_tol, 0);
ImBezierCubicClosestPointCasteljauStep(p, p_closest, p_last, p_closest_dist2, p1.x, p1.y, p2.x, p2.y, p3.x, p3.y, p4.x, p4.y, tess_tol, 0);
return p_closest;
}
@@ -1471,7 +1481,7 @@ static const ImU32 GCrc32LookupTable[256] =
// Known size hash
// It is ok to call ImHashData on a string with known length but the ### operator won't be supported.
// FIXME-OPT: Replace with e.g. FNV1a hash? CRC32 pretty much randomly access 1KB. Need to do proper measurements.
ImU32 ImHashData(const void* data_p, size_t data_size, ImU32 seed)
ImGuiID ImHashData(const void* data_p, size_t data_size, ImU32 seed)
{
ImU32 crc = ~seed;
const unsigned char* data = (const unsigned char*)data_p;
@@ -1487,7 +1497,7 @@ ImU32 ImHashData(const void* data_p, size_t data_size, ImU32 seed)
// - If we reach ### in the string we discard the hash so far and reset to the seed.
// - We don't do 'current += 2; continue;' after handling ### to keep the code smaller/faster (measured ~10% diff in Debug build)
// FIXME-OPT: Replace with e.g. FNV1a hash? CRC32 pretty much randomly access 1KB. Need to do proper measurements.
ImU32 ImHashStr(const char* data_p, size_t data_size, ImU32 seed)
ImGuiID ImHashStr(const char* data_p, size_t data_size, ImU32 seed)
{
seed = ~seed;
ImU32 crc = seed;
@@ -2235,14 +2245,16 @@ static void SetCursorPosYAndSetupForPrevLine(float pos_y, float line_height)
window->DC.CursorMaxPos.y = ImMax(window->DC.CursorMaxPos.y, pos_y);
window->DC.CursorPosPrevLine.y = window->DC.CursorPos.y - line_height; // Setting those fields so that SetScrollHereY() can properly function after the end of our clipper usage.
window->DC.PrevLineSize.y = (line_height - g.Style.ItemSpacing.y); // If we end up needing more accurate data (to e.g. use SameLine) we may as well make the clipper have a fourth step to let user process and display the last item in their list.
if (ImGuiColumns* columns = window->DC.CurrentColumns)
if (ImGuiOldColumns* columns = window->DC.CurrentColumns)
columns->LineMinY = window->DC.CursorPos.y; // Setting this so that cell Y position are set properly
if (ImGuiTable* table = g.CurrentTable)
{
if (table->IsInsideRow)
ImGui::TableEndRow(table);
table->RowPosY2 = window->DC.CursorPos.y;
table->RowBgColorCounter += (int)((off_y / line_height) + 0.5f);
const int row_increase = (int)((off_y / line_height) + 0.5f);
//table->CurrentRow += row_increase; // Can't do without fixing TableEndRow()
table->RowBgColorCounter += row_increase;
}
}
@@ -2299,8 +2311,8 @@ bool ImGuiListClipper::Step()
if (table && table->IsInsideRow)
ImGui::TableEndRow(table);
// Reached end of list
if (DisplayEnd >= ItemsCount || GetSkipItemForListClipping())
// No items
if (ItemsCount == 0 || GetSkipItemForListClipping())
{
End();
return false;
@@ -2311,7 +2323,7 @@ bool ImGuiListClipper::Step()
{
// While we are in frozen row state, keep displaying items one by one, unclipped
// FIXME: Could be stored as a table-agnostic state.
if (table != NULL && !table->IsUnfrozen)
if (table != NULL && !table->IsUnfrozenRows)
{
DisplayStart = ItemsFrozen;
DisplayEnd = ItemsFrozen + 1;
@@ -2353,6 +2365,13 @@ bool ImGuiListClipper::Step()
StepNo = 2;
}
// Reached end of list
if (DisplayEnd >= ItemsCount)
{
End();
return false;
}
// Step 2: calculate the actual range of elements to display, and position the cursor before the first element
if (StepNo == 2)
{
@@ -2469,6 +2488,11 @@ struct ImGuiStyleVarInfo
void* GetVarPtr(ImGuiStyle* style) const { return (void*)((unsigned char*)style + Offset); }
};
static const ImGuiCol GWindowDockStyleColors[ImGuiWindowDockStyleCol_COUNT] =
{
ImGuiCol_Text, ImGuiCol_Tab, ImGuiCol_TabHovered, ImGuiCol_TabActive, ImGuiCol_TabUnfocused, ImGuiCol_TabUnfocusedActive
};
static const ImGuiStyleVarInfo GStyleVarInfo[] =
{
{ ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImGuiStyle, Alpha) }, // ImGuiStyleVar_Alpha
@@ -2897,7 +2921,7 @@ ImGuiWindow::~ImGuiWindow()
IM_ASSERT(DrawList == &DrawListInst);
IM_DELETE(Name);
for (int i = 0; i != ColumnsStorage.Size; i++)
ColumnsStorage[i].~ImGuiColumns();
ColumnsStorage[i].~ImGuiOldColumns();
}
ImGuiID ImGuiWindow::GetID(const char* str, const char* str_end)
@@ -3050,6 +3074,7 @@ void ImGui::SetActiveID(ImGuiID id, ImGuiWindow* window)
// Clear declaration of inputs claimed by the widget
// (Please note that this is WIP and not all keys/inputs are thoroughly declared by all widgets yet)
g.ActiveIdUsingMouseWheel = false;
g.ActiveIdUsingNavDirMask = 0x00;
g.ActiveIdUsingNavInputMask = 0x00;
g.ActiveIdUsingKeyInputMask = 0x00;
@@ -3065,6 +3090,7 @@ void ImGui::SetHoveredID(ImGuiID id)
ImGuiContext& g = *GImGui;
g.HoveredId = id;
g.HoveredIdAllowOverlap = false;
g.HoveredIdUsingMouseWheel = false;
if (id != 0 && g.HoveredIdPreviousFrame != id)
g.HoveredIdTimer = g.HoveredIdNotActiveTimer = 0.0f;
}
@@ -3599,7 +3625,7 @@ void ImGui::UpdateMouseMovingWindowEndFrame()
if (root_window != NULL && !is_closed_popup)
{
StartMouseMovingWindow(g.HoveredWindow);
StartMouseMovingWindow(g.HoveredWindow); //-V595
// Cancel moving if clicked outside of title bar
if (g.IO.ConfigWindowsMoveFromTitleBarOnly)
@@ -3626,17 +3652,7 @@ void ImGui::UpdateMouseMovingWindowEndFrame()
// Find the top-most window between HoveredWindow and the top-most Modal Window.
// This is where we can trim the popup stack.
ImGuiWindow* modal = GetTopMostPopupModal();
bool hovered_window_above_modal = false;
if (modal == NULL)
hovered_window_above_modal = true;
for (int i = g.Windows.Size - 1; i >= 0 && hovered_window_above_modal == false; i--)
{
ImGuiWindow* window = g.Windows[i];
if (window == modal)
break;
if (window == g.HoveredWindow)
hovered_window_above_modal = true;
}
bool hovered_window_above_modal = g.HoveredWindow && IsWindowAbove(g.HoveredWindow, modal);
ClosePopupsOverWindow(hovered_window_above_modal ? g.HoveredWindow : modal, true);
}
}
@@ -3755,6 +3771,9 @@ void ImGui::UpdateMouseWheel()
if (g.IO.MouseWheel == 0.0f && g.IO.MouseWheelH == 0.0f)
return;
if ((g.ActiveId != 0 && g.ActiveIdUsingMouseWheel) || (g.HoveredIdPreviousFrame != 0 && g.HoveredIdPreviousFrameUsingMouseWheel))
return;
ImGuiWindow* window = g.WheelingWindow ? g.WheelingWindow : g.HoveredWindow;
if (!window || window->Collapsed)
return;
@@ -3994,8 +4013,10 @@ void ImGui::NewFrame()
if (g.HoveredId && g.ActiveId != g.HoveredId)
g.HoveredIdNotActiveTimer += g.IO.DeltaTime;
g.HoveredIdPreviousFrame = g.HoveredId;
g.HoveredIdPreviousFrameUsingMouseWheel = g.HoveredIdUsingMouseWheel;
g.HoveredId = 0;
g.HoveredIdAllowOverlap = false;
g.HoveredIdUsingMouseWheel = false;
g.HoveredIdDisabled = false;
// Update ActiveId data (clear reference to active widget if the widget isn't alive anymore)
@@ -4043,7 +4064,7 @@ void ImGui::NewFrame()
// Undocking
// (needs to be before UpdateMouseMovingWindowNewFrame so the window is already offset and following the mouse on the detaching frame)
DockContextUpdateUndocking(&g);
DockContextNewFrameUpdateUndocking(&g);
// Find hovered window
// (needs to be before UpdateMouseMovingWindowNewFrame so we fill g.HoveredWindowUnderMovingWindow on the mouse release frame)
@@ -4107,7 +4128,7 @@ void ImGui::NewFrame()
ClosePopupsOverWindow(g.NavWindow, false);
// Docking
DockContextUpdateDocking(&g);
DockContextNewFrameUpdateDocking(&g);
// [DEBUG] Item picker tool - start with DebugStartItemPicker() - useful to visually select an item and break into its call-stack.
UpdateDebugToolItemPicker();
@@ -4451,6 +4472,8 @@ static void ImGui::EndFrameDrawDimmedBackgrounds()
continue;
if (g.NavWindowingTargetAnim && viewport == g.NavWindowingTargetAnim->Viewport)
continue;
if (viewport->Window && modal_window && IsWindowAbove(viewport->Window, modal_window))
continue;
ImDrawList* draw_list = GetForegroundDrawList(viewport);
const ImU32 dim_bg_col = GetColorU32(dim_bg_for_modal ? ImGuiCol_ModalWindowDimBg : ImGuiCol_NavWindowingDimBg, g.DimBgRatio);
draw_list->AddRectFilled(viewport->Pos, viewport->Pos + viewport->Size, dim_bg_col);
@@ -5066,15 +5089,27 @@ bool ImGui::IsItemEdited()
}
// Allow last item to be overlapped by a subsequent item. Both may be activated during the same frame before the later one takes priority.
// FIXME: Although this is exposed, its interaction and ideal idiom with using ImGuiButtonFlags_AllowItemOverlap flag are extremely confusing, need rework.
void ImGui::SetItemAllowOverlap()
{
ImGuiContext& g = *GImGui;
if (g.HoveredId == g.CurrentWindow->DC.LastItemId)
ImGuiID id = g.CurrentWindow->DC.LastItemId;
if (g.HoveredId == id)
g.HoveredIdAllowOverlap = true;
if (g.ActiveId == g.CurrentWindow->DC.LastItemId)
if (g.ActiveId == id)
g.ActiveIdAllowOverlap = true;
}
void ImGui::SetItemUsingMouseWheel()
{
ImGuiContext& g = *GImGui;
ImGuiID id = g.CurrentWindow->DC.LastItemId;
if (g.HoveredId == id)
g.HoveredIdUsingMouseWheel = true;
if (g.ActiveId == id)
g.ActiveIdUsingMouseWheel = true;
}
ImVec2 ImGui::GetItemRectMin()
{
ImGuiWindow* window = GetCurrentWindowRead();
@@ -5112,16 +5147,15 @@ bool ImGui::BeginChildEx(const char* name, ImGuiID id, const ImVec2& size_arg, b
SetNextWindowSize(size);
// Build up name. If you need to append to a same child from multiple location in the ID stack, use BeginChild(ImGuiID id) with a stable value.
char title[256];
if (name)
ImFormatString(title, IM_ARRAYSIZE(title), "%s/%s_%08X", parent_window->Name, name, id);
ImFormatString(g.TempBuffer, IM_ARRAYSIZE(g.TempBuffer), "%s/%s_%08X", parent_window->Name, name, id);
else
ImFormatString(title, IM_ARRAYSIZE(title), "%s/%08X", parent_window->Name, id);
ImFormatString(g.TempBuffer, IM_ARRAYSIZE(g.TempBuffer), "%s/%08X", parent_window->Name, id);
const float backup_border_size = g.Style.ChildBorderSize;
if (!border)
g.Style.ChildBorderSize = 0.0f;
bool ret = Begin(title, NULL, flags);
bool ret = Begin(g.TempBuffer, NULL, flags);
g.Style.ChildBorderSize = backup_border_size;
ImGuiWindow* child_window = g.CurrentWindow;
@@ -5347,18 +5381,24 @@ static ImVec2 CalcWindowSizeAfterConstraint(ImGuiWindow* window, ImVec2 new_size
return new_size;
}
static ImVec2 CalcWindowContentSize(ImGuiWindow* window)
static void CalcWindowContentSizes(ImGuiWindow* window, ImVec2* content_size_current, ImVec2* content_size_ideal)
{
if (window->Collapsed)
if (window->AutoFitFramesX <= 0 && window->AutoFitFramesY <= 0)
return window->ContentSize;
if (window->Hidden && window->HiddenFramesCannotSkipItems == 0 && window->HiddenFramesCanSkipItems > 0)
return window->ContentSize;
bool preserve_old_content_sizes = false;
if (window->Collapsed && window->AutoFitFramesX <= 0 && window->AutoFitFramesY <= 0)
preserve_old_content_sizes = true;
else if (window->Hidden && window->HiddenFramesCannotSkipItems == 0 && window->HiddenFramesCanSkipItems > 0)
preserve_old_content_sizes = true;
if (preserve_old_content_sizes)
{
*content_size_current = window->ContentSize;
*content_size_ideal = window->ContentSizeIdeal;
return;
}
ImVec2 sz;
sz.x = IM_FLOOR((window->ContentSizeExplicit.x != 0.0f) ? window->ContentSizeExplicit.x : window->DC.CursorMaxPos.x - window->DC.CursorStartPos.x);
sz.y = IM_FLOOR((window->ContentSizeExplicit.y != 0.0f) ? window->ContentSizeExplicit.y : window->DC.CursorMaxPos.y - window->DC.CursorStartPos.y);
return sz;
content_size_current->x = (window->ContentSizeExplicit.x != 0.0f) ? window->ContentSizeExplicit.x : IM_FLOOR(window->DC.CursorMaxPos.x - window->DC.CursorStartPos.x);
content_size_current->y = (window->ContentSizeExplicit.y != 0.0f) ? window->ContentSizeExplicit.y : IM_FLOOR(window->DC.CursorMaxPos.y - window->DC.CursorStartPos.y);
content_size_ideal->x = (window->ContentSizeExplicit.x != 0.0f) ? window->ContentSizeExplicit.x : IM_FLOOR(ImMax(window->DC.CursorMaxPos.x, window->DC.IdealMaxPos.x) - window->DC.CursorStartPos.x);
content_size_ideal->y = (window->ContentSizeExplicit.y != 0.0f) ? window->ContentSizeExplicit.y : IM_FLOOR(ImMax(window->DC.CursorMaxPos.y, window->DC.IdealMaxPos.y) - window->DC.CursorStartPos.y);
}
static ImVec2 CalcWindowAutoFitSize(ImGuiWindow* window, const ImVec2& size_contents)
@@ -5404,10 +5444,12 @@ static ImVec2 CalcWindowAutoFitSize(ImGuiWindow* window, const ImVec2& size_cont
}
}
ImVec2 ImGui::CalcWindowExpectedSize(ImGuiWindow* window)
ImVec2 ImGui::CalcWindowNextAutoFitSize(ImGuiWindow* window)
{
ImVec2 size_contents = CalcWindowContentSize(window);
ImVec2 size_auto_fit = CalcWindowAutoFitSize(window, size_contents);
ImVec2 size_contents_current;
ImVec2 size_contents_ideal;
CalcWindowContentSizes(window, &size_contents_current, &size_contents_ideal);
ImVec2 size_auto_fit = CalcWindowAutoFitSize(window, size_contents_ideal);
ImVec2 size_final = CalcWindowSizeAfterConstraint(window, size_auto_fit);
return size_final;
}
@@ -6088,11 +6130,13 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
// UPDATE CONTENTS SIZE, UPDATE HIDDEN STATUS
// Update contents size from last frame for auto-fitting (or use explicit size)
window->ContentSize = CalcWindowContentSize(window);
CalcWindowContentSizes(window, &window->ContentSize, &window->ContentSizeIdeal);
if (window->HiddenFramesCanSkipItems > 0)
window->HiddenFramesCanSkipItems--;
if (window->HiddenFramesCannotSkipItems > 0)
window->HiddenFramesCannotSkipItems--;
if (window->HiddenFramesForRenderOnly > 0)
window->HiddenFramesForRenderOnly--;
// Hide new windows for one frame until they calculate their size
if (window_just_created && (!window_size_x_set_by_api || !window_size_y_set_by_api))
@@ -6109,7 +6153,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
window->Size.x = window->SizeFull.x = 0.f;
if (!window_size_y_set_by_api)
window->Size.y = window->SizeFull.y = 0.f;
window->ContentSize = ImVec2(0.f, 0.f);
window->ContentSize = window->ContentSizeIdeal = ImVec2(0.f, 0.f);
}
}
@@ -6162,7 +6206,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
// SIZE
// Calculate auto-fit size, handle automatic resize
const ImVec2 size_auto_fit = CalcWindowAutoFitSize(window, window->ContentSize);
const ImVec2 size_auto_fit = CalcWindowAutoFitSize(window, window->ContentSizeIdeal);
bool use_current_size_for_scrollbar_x = window_just_created;
bool use_current_size_for_scrollbar_y = window_just_created;
if ((flags & ImGuiWindowFlags_AlwaysAutoResize) && !window->Collapsed)
@@ -6284,19 +6328,26 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
// Update common viewport flags
const ImGuiViewportFlags viewport_flags_to_clear = ImGuiViewportFlags_TopMost | ImGuiViewportFlags_NoTaskBarIcon | ImGuiViewportFlags_NoDecoration | ImGuiViewportFlags_NoRendererClear;
ImGuiViewportFlags viewport_flags = window->Viewport->Flags & ~viewport_flags_to_clear;
const bool is_modal = (flags & ImGuiWindowFlags_Modal) != 0;
const bool is_short_lived_floating_window = (flags & (ImGuiWindowFlags_ChildMenu | ImGuiWindowFlags_Tooltip | ImGuiWindowFlags_Popup)) != 0;
if (flags & ImGuiWindowFlags_Tooltip)
viewport_flags |= ImGuiViewportFlags_TopMost;
if (g.IO.ConfigViewportsNoTaskBarIcon || is_short_lived_floating_window)
if ((g.IO.ConfigViewportsNoTaskBarIcon || is_short_lived_floating_window) && !is_modal)
viewport_flags |= ImGuiViewportFlags_NoTaskBarIcon;
if (g.IO.ConfigViewportsNoDecoration || is_short_lived_floating_window)
viewport_flags |= ImGuiViewportFlags_NoDecoration;
// Not correct to set modal as topmost because:
// - Because other popups can be stacked above a modal (e.g. combo box in a modal)
// - ImGuiViewportFlags_TopMost is currently handled different in backends: in Win32 it is "appear top most" whereas in GLFW and SDL it is "stay topmost"
//if (flags & ImGuiWindowFlags_Modal)
// viewport_flags |= ImGuiViewportFlags_TopMost;
// For popups and menus that may be protruding out of their parent viewport, we enable _NoFocusOnClick so that clicking on them
// won't steal the OS focus away from their parent window (which may be reflected in OS the title bar decoration).
// Setting _NoFocusOnClick would technically prevent us from bringing back to front in case they are being covered by an OS window from a different app,
// but it shouldn't be much of a problem considering those are already popups that are closed when clicking elsewhere.
if (is_short_lived_floating_window && (flags & ImGuiWindowFlags_Modal) == 0)
if (is_short_lived_floating_window && !is_modal)
viewport_flags |= ImGuiViewportFlags_NoFocusOnAppearing | ImGuiViewportFlags_NoFocusOnClick;
// We can overwrite viewport flags using ImGuiWindowClass (advanced users)
@@ -6381,7 +6432,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
int border_held = -1;
ImU32 resize_grip_col[4] = {};
const int resize_grip_count = g.IO.ConfigWindowsResizeFromEdges ? 2 : 1; // Allow resize from lower-left if we have the mouse cursor feedback for it.
const float resize_grip_draw_size = IM_FLOOR(ImMax(g.FontSize * 1.35f, window->WindowRounding + 1.0f + g.FontSize * 0.2f));
const float resize_grip_draw_size = IM_FLOOR(ImMax(g.FontSize * 1.10f, window->WindowRounding + 1.0f + g.FontSize * 0.2f));
if (handle_borders_and_resize_grips && !window->Collapsed)
if (UpdateWindowManualResize(window, size_auto_fit, &border_held, resize_grip_count, &resize_grip_col[0], visibility_rect))
use_current_size_for_scrollbar_x = use_current_size_for_scrollbar_y = true;
@@ -6579,6 +6630,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
window->DC.CursorPos = window->DC.CursorStartPos;
window->DC.CursorPosPrevLine = window->DC.CursorPos;
window->DC.CursorMaxPos = window->DC.CursorStartPos;
window->DC.IdealMaxPos = window->DC.CursorStartPos;
window->DC.CurrLineSize = window->DC.PrevLineSize = ImVec2(0.0f, 0.0f);
window->DC.CurrLineTextBaseOffset = window->DC.PrevLineTextBaseOffset = 0.0f;
@@ -6639,7 +6691,8 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
// This works but 1. doesn't handle multiple Begin/End pairs, 2. recursing into another Begin/End pair - so we need to work that out and add better logging scope.
// Maybe we can support CTRL+C on every element?
/*
if (g.ActiveId == move_id)
//if (g.NavWindow == window && g.ActiveId == 0)
if (g.ActiveId == window->MoveId)
if (g.IO.KeyCtrl && IsKeyPressedMap(ImGuiKey_C))
LogToClipboard();
*/
@@ -6709,10 +6762,11 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
{
// Child window can be out of sight and have "negative" clip windows.
// Mark them as collapsed so commands are skipped earlier (we can't manually collapse them because they have no title bar).
IM_ASSERT((flags & ImGuiWindowFlags_NoTitleBar) != 0 || (window->DockIsActive));
if (!(flags & ImGuiWindowFlags_AlwaysAutoResize) && window->AutoFitFramesX <= 0 && window->AutoFitFramesY <= 0)
if (window->OuterRectClipped.Min.x >= window->OuterRectClipped.Max.x || window->OuterRectClipped.Min.y >= window->OuterRectClipped.Max.y)
window->HiddenFramesCanSkipItems = 1;
IM_ASSERT((flags& ImGuiWindowFlags_NoTitleBar) != 0 || (window->DockIsActive));
if (!(flags & ImGuiWindowFlags_AlwaysAutoResize) && window->AutoFitFramesX <= 0 && window->AutoFitFramesY <= 0) // FIXME: Doesn't make sense for ChildWindow??
if (!g.LogEnabled)
if (window->OuterRectClipped.Min.x >= window->OuterRectClipped.Max.x || window->OuterRectClipped.Min.y >= window->OuterRectClipped.Max.y)
window->HiddenFramesCanSkipItems = 1;
// Hide along with parent or if parent is collapsed
if (parent_window && (parent_window->Collapsed || parent_window->HiddenFramesCanSkipItems > 0))
@@ -6726,7 +6780,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
window->HiddenFramesCanSkipItems = 1;
// Update the Hidden flag
window->Hidden = (window->HiddenFramesCanSkipItems > 0) || (window->HiddenFramesCannotSkipItems > 0);
window->Hidden = (window->HiddenFramesCanSkipItems > 0) || (window->HiddenFramesCannotSkipItems > 0) || (window->HiddenFramesForRenderOnly > 0);
// Update the SkipItems flag, used to early out of all items functions (no layout required)
bool skip_items = false;
@@ -7010,6 +7064,20 @@ bool ImGui::IsWindowChildOf(ImGuiWindow* window, ImGuiWindow* potential_parent)
return false;
}
bool ImGui::IsWindowAbove(ImGuiWindow* potential_above, ImGuiWindow* potential_below)
{
ImGuiContext& g = *GImGui;
for (int i = g.Windows.Size - 1; i >= 0; i--)
{
ImGuiWindow* candidate_window = g.Windows[i];
if (candidate_window == potential_above)
return true;
if (candidate_window == potential_below)
return false;
}
return false;
}
bool ImGui::IsWindowHovered(ImGuiHoveredFlags flags)
{
IM_ASSERT((flags & ImGuiHoveredFlags_AllowWhenOverlapped) == 0); // Flags not supported by this function
@@ -7089,7 +7157,7 @@ bool ImGui::IsWindowDocked()
// If you want a window to never be focused, you may use the e.g. NoInputs flag.
bool ImGui::IsWindowNavFocusable(ImGuiWindow* window)
{
return window->Active && window == window->RootWindowDockStop && !(window->Flags & ImGuiWindowFlags_NoNavFocus);
return window->WasActive && window == window->RootWindowDockStop && !(window->Flags & ImGuiWindowFlags_NoNavFocus);
}
float ImGui::GetWindowWidth()
@@ -7285,7 +7353,7 @@ void ImGui::SetNextWindowContentSize(const ImVec2& size)
{
ImGuiContext& g = *GImGui;
g.NextWindowData.Flags |= ImGuiNextWindowDataFlags_HasContentSize;
g.NextWindowData.ContentSizeVal = size;
g.NextWindowData.ContentSizeVal = ImFloor(size);
}
void ImGui::SetNextWindowScroll(const ImVec2& scroll)
@@ -7567,8 +7635,8 @@ static void ImGui::ErrorCheckNewFrameSanityChecks()
// (IF YOU GET A WARNING OR COMPILE ERROR HERE: it means you assert macro is incorrectly defined!
// If your macro uses multiple statements, it NEEDS to be surrounded by a 'do { ... } while (0)' block.
// This is a common C/C++ idiom to allow multiple statements macros to be used in control flow blocks.)
// #define IM_ASSERT(EXPR) SomeCode(EXPR); SomeMoreCode(); // Wrong!
// #define IM_ASSERT(EXPR) do { SomeCode(EXPR); SomeMoreCode(); } while (0) // Correct!
// #define IM_ASSERT(EXPR) if (SomeCode(EXPR)) SomeMoreCode(); // Wrong!
// #define IM_ASSERT(EXPR) do { if (SomeCode(EXPR)) SomeMoreCode(); } while (0) // Correct!
if (true) IM_ASSERT(1); else IM_ASSERT(0);
// Check user data
@@ -7577,21 +7645,21 @@ static void ImGui::ErrorCheckNewFrameSanityChecks()
IM_ASSERT((g.IO.DeltaTime > 0.0f || g.FrameCount == 0) && "Need a positive DeltaTime!");
IM_ASSERT((g.FrameCount == 0 || g.FrameCountEnded == g.FrameCount) && "Forgot to call Render() or EndFrame() at the end of the previous frame?");
IM_ASSERT(g.IO.DisplaySize.x >= 0.0f && g.IO.DisplaySize.y >= 0.0f && "Invalid DisplaySize value!");
IM_ASSERT(g.IO.Fonts->Fonts.Size > 0 && "Font Atlas not built. Did you call io.Fonts->GetTexDataAsRGBA32() / GetTexDataAsAlpha8() ?");
IM_ASSERT(g.IO.Fonts->Fonts[0]->IsLoaded() && "Font Atlas not built. Did you call io.Fonts->GetTexDataAsRGBA32() / GetTexDataAsAlpha8() ?");
IM_ASSERT(g.IO.Fonts->Fonts.Size > 0 && "Font Atlas not built. Did you call io.Fonts->GetTexDataAsRGBA32() / GetTexDataAsAlpha8()?");
IM_ASSERT(g.IO.Fonts->Fonts[0]->IsLoaded() && "Font Atlas not built. Did you call io.Fonts->GetTexDataAsRGBA32() / GetTexDataAsAlpha8()?");
IM_ASSERT(g.Style.CurveTessellationTol > 0.0f && "Invalid style setting!");
IM_ASSERT(g.Style.CircleSegmentMaxError > 0.0f && "Invalid style setting!");
IM_ASSERT(g.Style.Alpha >= 0.0f && g.Style.Alpha <= 1.0f && "Invalid style setting. Alpha cannot be negative (allows us to avoid a few clamps in color computations)!");
IM_ASSERT(g.Style.Alpha >= 0.0f && g.Style.Alpha <= 1.0f && "Invalid style setting!"); // Allows us to avoid a few clamps in color computations
IM_ASSERT(g.Style.WindowMinSize.x >= 1.0f && g.Style.WindowMinSize.y >= 1.0f && "Invalid style setting.");
IM_ASSERT(g.Style.WindowMenuButtonPosition == ImGuiDir_None || g.Style.WindowMenuButtonPosition == ImGuiDir_Left || g.Style.WindowMenuButtonPosition == ImGuiDir_Right);
for (int n = 0; n < ImGuiKey_COUNT; n++)
IM_ASSERT(g.IO.KeyMap[n] >= -1 && g.IO.KeyMap[n] < IM_ARRAYSIZE(g.IO.KeysDown) && "io.KeyMap[] contains an out of bound value (need to be 0..512, or -1 for unmapped key)");
// Perform simple check: required key mapping (we intentionally do NOT check all keys to not pressure user into setting up everything, but Space is required and was only recently added in 1.60 WIP)
// Check: required key mapping (we intentionally do NOT check all keys to not pressure user into setting up everything, but Space is required and was only added in 1.60 WIP)
if (g.IO.ConfigFlags & ImGuiConfigFlags_NavEnableKeyboard)
IM_ASSERT(g.IO.KeyMap[ImGuiKey_Space] != -1 && "ImGuiKey_Space is not mapped, required for keyboard navigation.");
// Perform simple check: the beta io.ConfigWindowsResizeFromEdges option requires backend to honor mouse cursor changes and set the ImGuiBackendFlags_HasMouseCursors flag accordingly.
// Check: the io.ConfigWindowsResizeFromEdges option requires backend to honor mouse cursor changes and set the ImGuiBackendFlags_HasMouseCursors flag accordingly.
if (g.IO.ConfigWindowsResizeFromEdges && !(g.IO.BackendFlags & ImGuiBackendFlags_HasMouseCursors))
g.IO.ConfigWindowsResizeFromEdges = false;
@@ -7649,6 +7717,9 @@ static void ImGui::ErrorCheckEndFrameSanityChecks()
IM_ASSERT((key_mod_flags == 0 || g.IO.KeyMods == key_mod_flags) && "Mismatching io.KeyCtrl/io.KeyShift/io.KeyAlt/io.KeySuper vs io.KeyMods");
IM_UNUSED(key_mod_flags);
// Recover from errors
//ErrorCheckEndFrameRecover();
// Report when there is a mismatch of Begin/BeginChild vs End/EndChild calls. Important: Remember that the Begin/BeginChild API requires you
// to always call End/EndChild even if Begin/BeginChild returns false! (this is unfortunately inconsistent with most other Begin* API).
if (g.CurrentWindowStack.Size != 1)
@@ -7668,6 +7739,80 @@ static void ImGui::ErrorCheckEndFrameSanityChecks()
IM_ASSERT_USER_ERROR(g.GroupStack.Size == 0, "Missing EndGroup call!");
}
// Experimental recovery from incorrect usage of BeginXXX/EndXXX/PushXXX/PopXXX calls.
// Must be called during or before EndFrame().
// This is generally flawed as we are not necessarily End/Popping things in the right order.
// FIXME: Can't recover from inside BeginTabItem/EndTabItem yet.
// FIXME: Can't recover from interleaved BeginTabBar/Begin
void ImGui::ErrorCheckEndFrameRecover(ImGuiErrorLogCallback log_callback, void* user_data)
{
// PVS-Studio V1044 is "Loop break conditions do not depend on the number of iterations"
ImGuiContext& g = *GImGui;
while (g.CurrentWindowStack.Size > 0)
{
#ifdef IMGUI_HAS_TABLE
while (g.CurrentTable && (g.CurrentTable->OuterWindow == g.CurrentWindow || g.CurrentTable->InnerWindow == g.CurrentWindow))
{
if (log_callback) log_callback(user_data, "Recovered from missing EndTable() in '%s'", g.CurrentTable->OuterWindow->Name);
EndTable();
}
#endif
ImGuiWindow* window = g.CurrentWindow;
IM_ASSERT(window != NULL);
while (g.CurrentTabBar != NULL) //-V1044
{
if (log_callback) log_callback(user_data, "Recovered from missing EndTabBar() in '%s'", window->Name);
EndTabBar();
}
while (window->DC.TreeDepth > 0)
{
if (log_callback) log_callback(user_data, "Recovered from missing TreePop() in '%s'", window->Name);
TreePop();
}
while (g.GroupStack.Size > window->DC.StackSizesOnBegin.SizeOfGroupStack)
{
if (log_callback) log_callback(user_data, "Recovered from missing EndGroup() in '%s'", window->Name);
EndGroup();
}
while (window->IDStack.Size > 1)
{
if (log_callback) log_callback(user_data, "Recovered from missing PopID() in '%s'", window->Name);
PopID();
}
while (g.ColorStack.Size > window->DC.StackSizesOnBegin.SizeOfColorStack)
{
if (log_callback) log_callback(user_data, "Recovered from missing PopStyleColor() in '%s' for ImGuiCol_%s", window->Name, GetStyleColorName(g.ColorStack.back().Col));
PopStyleColor();
}
while (g.StyleVarStack.Size > window->DC.StackSizesOnBegin.SizeOfStyleVarStack)
{
if (log_callback) log_callback(user_data, "Recovered from missing PopStyleVar() in '%s'", window->Name);
PopStyleVar();
}
while (g.FocusScopeStack.Size > window->DC.StackSizesOnBegin.SizeOfFocusScopeStack)
{
if (log_callback) log_callback(user_data, "Recovered from missing PopFocusScope() in '%s'", window->Name);
PopFocusScope();
}
if (g.CurrentWindowStack.Size == 1)
{
IM_ASSERT(g.CurrentWindow->IsFallbackWindow);
break;
}
IM_ASSERT(window == g.CurrentWindow);
if (window->Flags & ImGuiWindowFlags_ChildWindow)
{
if (log_callback) log_callback(user_data, "Recovered from missing EndChild() for '%s'", window->Name);
EndChild();
}
else
{
if (log_callback) log_callback(user_data, "Recovered from missing End() for '%s'", window->Name);
End();
}
}
}
// Save current stack sizes for later compare
void ImGuiStackSizes::SetToCurrentState()
{
@@ -7687,6 +7832,7 @@ void ImGuiStackSizes::CompareWithCurrentState()
{
ImGuiContext& g = *GImGui;
ImGuiWindow* window = g.CurrentWindow;
IM_UNUSED(window);
// Window stacks
// NOT checking: DC.ItemWidth, DC.TextWrapPos (per window) to allow user to conveniently push once and not pop (they are cleared on Begin)
@@ -8409,7 +8555,7 @@ void ImGui::BeginTooltipEx(ImGuiWindowFlags extra_flags, ImGuiTooltipFlags toolt
{
// Hide previous tooltip from being displayed. We can't easily "reset" the content of a window so we create a new one.
window->Hidden = true;
window->HiddenFramesCanSkipItems = 1;
window->HiddenFramesCanSkipItems = 1; // FIXME: This may not be necessary?
ImFormatString(window_name, IM_ARRAYSIZE(window_name), "##Tooltip_%02d", ++g.TooltipOverrideCount);
}
ImGuiWindowFlags flags = ImGuiWindowFlags_Tooltip | ImGuiWindowFlags_NoInputs | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoDocking;
@@ -11483,10 +11629,11 @@ static void ImGui::UpdateSelectWindowViewport(ImGuiWindow* window)
UpdateTryMergeWindowIntoHostViewports(window);
}
// Fallback to default viewport
// Fallback: merge in default viewport if z-order matches, otherwise create a new viewport
if (window->Viewport == NULL)
window->Viewport = main_viewport;
if (!UpdateTryMergeWindowIntoHostViewport(window, main_viewport))
window->Viewport = AddUpdateViewport(window, window->ID, window->Pos, window->Size, ImGuiViewportFlags_None);
// Mark window as allowed to protrude outside of its viewport and into the current monitor
if (!lock_viewport)
{
@@ -11796,6 +11943,50 @@ void ImGui::DestroyPlatformWindows()
// Docking: Settings
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// Typical Docking call flow: (root level is generally public API):
//-----------------------------------------------------------------------------
// - NewFrame() new dear imgui frame
// | DockContextNewFrameUpdateUndocking() - process queued undocking requests
// | - DockContextProcessUndockWindow() - process one window undocking request
// | - DockContextProcessUndockNode() - process one whole node undocking request
// | DockContextNewFrameUpdateUndocking() - process queue docking requests, create floating dock nodes
// | - update g.HoveredDockNode - [debug] update node hovered by mouse
// | - DockContextProcessDock() - process one docking request
// | - DockNodeUpdate()
// | - DockNodeUpdateForRootNode()
// | - DockNodeUpdateVisibleFlagAndInactiveChilds()
// | - DockNodeFindInfo()
// | - destroy unused node or tab bar
// | - create dock node host window
// | - Begin() etc.
// | - DockNodeStartMouseMovingWindow()
// | - DockNodeTreeUpdatePosSize()
// | - DockNodeTreeUpdateSplitter()
// | - draw node background
// | - DockNodeUpdateTabBar() - create/update tab bar for a docking node
// | - DockNodeAddTabBar()
// | - DockNodeUpdateWindowMenu()
// | - DockNodeCalcTabBarLayout()
// | - BeginTabBarEx()
// | - TabItemEx() calls
// | - EndTabBar()
// | - BeginDockableDragDropTarget()
// | - DockNodeUpdate() - recurse into child nodes...
//-----------------------------------------------------------------------------
// - DockSpace() user submit a dockspace into a window
// | Begin(Child) - create a child window
// | DockNodeUpdate() - call main dock node update function
// | End(Child)
// | ItemSize()
//-----------------------------------------------------------------------------
// - Begin()
// | BeginDocked()
// | BeginDockableDragDropSource()
// | BeginDockableDragDropTarget()
// | - DockNodePreviewDockRender()
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// Docking: Internal Types
//-----------------------------------------------------------------------------
@@ -11946,8 +12137,8 @@ namespace ImGui
// - DockContextShutdown()
// - DockContextClearNodes()
// - DockContextRebuildNodes()
// - DockContextUpdateUndocking()
// - DockContextUpdateDocking()
// - DockContextNewFrameUpdateUndocking()
// - DockContextNewFrameUpdateDocking()
// - DockContextFindNodeByID()
// - DockContextBindNodeToWindow()
// - DockContextGenNodeID()
@@ -12006,7 +12197,7 @@ void ImGui::DockContextRebuildNodes(ImGuiContext* ctx)
}
// Docking context update function, called by NewFrame()
void ImGui::DockContextUpdateUndocking(ImGuiContext* ctx)
void ImGui::DockContextNewFrameUpdateUndocking(ImGuiContext* ctx)
{
ImGuiContext& g = *ctx;
ImGuiDockContext* dc = &ctx->DockContext;
@@ -12050,14 +12241,16 @@ void ImGui::DockContextUpdateUndocking(ImGuiContext* ctx)
}
// Docking context update function, called by NewFrame()
void ImGui::DockContextUpdateDocking(ImGuiContext* ctx)
void ImGui::DockContextNewFrameUpdateDocking(ImGuiContext* ctx)
{
ImGuiContext& g = *ctx;
ImGuiDockContext* dc = &ctx->DockContext;
if (!(g.IO.ConfigFlags & ImGuiConfigFlags_DockingEnable))
return;
// Store hovered dock node. We could in theory use DockNodeTreeFindVisibleNodeByPos() on the root host dock node, but using ->DockNode is a good shortcut.
// [DEBUG] Store hovered dock node.
// We could in theory use DockNodeTreeFindVisibleNodeByPos() on the root host dock node, but using ->DockNode is a good shortcut.
// Note this is mostly a debug thing and isn't actually used for docking target, because docking involve more detailed filtering.
g.HoveredDockNode = NULL;
if (ImGuiWindow* hovered_window = g.HoveredWindowUnderMovingWindow)
{
@@ -13141,8 +13334,8 @@ static void ImGui::DockNodeUpdate(ImGuiDockNode* node)
if (g.NavWindow && g.NavWindow->RootWindowDockStop->DockNode && g.NavWindow->RootWindowDockStop->ParentWindow == host_window)
node->LastFocusedNodeId = g.NavWindow->RootWindowDockStop->DockNode->ID;
// We need to draw a background at the root level if requested by ImGuiDockNodeFlags_PassthruCentralNode, but we will only know the correct pos/size after
// processing the resizing splitters. So we are using the DrawList channel splitting facility to submit drawing primitives out of order!
// We need to draw a background at the root level if requested by ImGuiDockNodeFlags_PassthruCentralNode, but we will only know the correct pos/size
// _after_ processing the resizing splitters. So we are using the DrawList channel splitting facility to submit drawing primitives out of order!
const bool render_dockspace_bg = node->IsRootNode() && host_window && (node_flags & ImGuiDockNodeFlags_PassthruCentralNode) != 0;
if (render_dockspace_bg)
{
@@ -13381,6 +13574,17 @@ static void ImGui::DockNodeUpdateTabBar(ImGuiDockNode* node, ImGuiWindow* host_w
ImVec2 window_menu_button_pos;
DockNodeCalcTabBarLayout(node, &title_bar_rect, &tab_bar_rect, &window_menu_button_pos);
// Submit new tabs and apply NavWindow focus back to the tab bar. They will be added as Unsorted and sorted below based on relative DockOrder value.
const int tabs_count_old = tab_bar->Tabs.Size;
for (int window_n = 0; window_n < node->Windows.Size; window_n++)
{
ImGuiWindow* window = node->Windows[window_n];
if (g.NavWindow && g.NavWindow->RootWindowDockStop == window)
tab_bar->SelectedTabId = window->ID;
if (TabBarFindTabByID(tab_bar, window->ID) == NULL)
TabBarAddTab(tab_bar, ImGuiTabItemFlags_Unsorted, window);
}
// Title bar
if (is_focused)
node->LastFrameFocused = g.FrameCount;
@@ -13396,17 +13600,6 @@ static void ImGui::DockNodeUpdateTabBar(ImGuiDockNode* node, ImGuiWindow* host_w
focus_tab_id = tab_bar->SelectedTabId;
}
// Submit new tabs and apply NavWindow focus back to the tab bar. They will be added as Unsorted and sorted below based on relative DockOrder value.
const int tabs_count_old = tab_bar->Tabs.Size;
for (int window_n = 0; window_n < node->Windows.Size; window_n++)
{
ImGuiWindow* window = node->Windows[window_n];
if (g.NavWindow && g.NavWindow->RootWindowDockStop == window)
tab_bar->SelectedTabId = window->ID;
if (TabBarFindTabByID(tab_bar, window->ID) == NULL)
TabBarAddTab(tab_bar, ImGuiTabItemFlags_Unsorted, window);
}
// If multiple tabs are appearing on the same frame, sort them based on their persistent DockOrder value
int tabs_unsorted_start = tab_bar->Tabs.Size;
for (int tab_n = tab_bar->Tabs.Size - 1; tab_n >= 0 && (tab_bar->Tabs[tab_n].Flags & ImGuiTabItemFlags_Unsorted); tab_n--)
@@ -13438,6 +13631,11 @@ static void ImGui::DockNodeUpdateTabBar(ImGuiDockNode* node, ImGuiWindow* host_w
BeginTabBarEx(tab_bar, tab_bar_rect, tab_bar_flags, node);
//host_window->DrawList->AddRect(tab_bar_rect.Min, tab_bar_rect.Max, IM_COL32(255,0,255,255));
// Backup style colors
ImVec4 backup_style_cols[ImGuiWindowDockStyleCol_COUNT];
for (int color_n = 0; color_n < ImGuiWindowDockStyleCol_COUNT; color_n++)
backup_style_cols[color_n] = g.Style.Colors[GWindowDockStyleColors[color_n]];
// Submit actual tabs
node->VisibleWindow = NULL;
for (int window_n = 0; window_n < node->Windows.Size; window_n++)
@@ -13448,11 +13646,16 @@ static void ImGui::DockNodeUpdateTabBar(ImGuiDockNode* node, ImGuiWindow* host_w
if (window->LastFrameActive + 1 >= g.FrameCount || !node_was_active)
{
ImGuiTabItemFlags tab_item_flags = 0;
tab_item_flags |= window->WindowClass.TabItemFlagsOverrideSet;
if (window->Flags & ImGuiWindowFlags_UnsavedDocument)
tab_item_flags |= ImGuiTabItemFlags_UnsavedDocument;
if (tab_bar->Flags & ImGuiTabBarFlags_NoCloseWithMiddleMouseButton)
tab_item_flags |= ImGuiTabItemFlags_NoCloseWithMiddleMouseButton;
// Apply stored style overrides for the window
for (int color_n = 0; color_n < ImGuiWindowDockStyleCol_COUNT; color_n++)
g.Style.Colors[GWindowDockStyleColors[color_n]] = ColorConvertU32ToFloat4(window->DockStyle.Colors[color_n]);
bool tab_open = true;
TabItemEx(tab_bar, window->Name, window->HasCloseButton ? &tab_open : NULL, tab_item_flags, window);
if (!tab_open)
@@ -13470,6 +13673,10 @@ static void ImGui::DockNodeUpdateTabBar(ImGuiDockNode* node, ImGuiWindow* host_w
}
}
// Restore style colors
for (int color_n = 0; color_n < ImGuiWindowDockStyleCol_COUNT; color_n++)
g.Style.Colors[GWindowDockStyleColors[color_n]] = backup_style_cols[color_n];
// Notify root of visible window (used to display title in OS task bar)
if (node->VisibleWindow)
if (is_focused || root_node->VisibleWindow == NULL)
@@ -13818,7 +14025,6 @@ static void ImGui::DockNodePreviewDockRender(ImGuiWindow* host_window, ImGuiDock
overlay_draw_lists[overlay_draw_lists_count++] = GetForegroundDrawList(root_payload->Viewport);
// Draw main preview rectangle
const ImU32 overlay_col_tabs = GetColorU32(ImGuiCol_TabActive);
const ImU32 overlay_col_main = GetColorU32(ImGuiCol_DockingPreview, is_transparent_payload ? 0.60f : 0.40f);
const ImU32 overlay_col_drop = GetColorU32(ImGuiCol_DockingPreview, is_transparent_payload ? 0.90f : 0.70f);
const ImU32 overlay_col_drop_hovered = GetColorU32(ImGuiCol_DockingPreview, is_transparent_payload ? 1.20f : 1.00f);
@@ -13873,6 +14079,9 @@ static void ImGui::DockNodePreviewDockRender(ImGuiWindow* host_window, ImGuiDock
ImVec2 tab_size = TabItemCalcSize(payload_window->Name, payload_window->HasCloseButton);
ImRect tab_bb(tab_pos.x, tab_pos.y, tab_pos.x + tab_size.x, tab_pos.y + tab_size.y);
tab_pos.x += tab_size.x + g.Style.ItemInnerSpacing.x;
const ImU32 overlay_col_text = GetColorU32(payload_window->DockStyle.Colors[ImGuiWindowDockStyleCol_Text]);
const ImU32 overlay_col_tabs = GetColorU32(payload_window->DockStyle.Colors[ImGuiWindowDockStyleCol_TabActive]);
PushStyleColor(ImGuiCol_Text, overlay_col_text);
for (int overlay_n = 0; overlay_n < overlay_draw_lists_count; overlay_n++)
{
ImGuiTabItemFlags tab_flags = ImGuiTabItemFlags_Preview | ((payload_window->Flags & ImGuiWindowFlags_UnsavedDocument) ? ImGuiTabItemFlags_UnsavedDocument : 0);
@@ -13883,6 +14092,7 @@ static void ImGui::DockNodePreviewDockRender(ImGuiWindow* host_window, ImGuiDock
if (!tab_bar_rect.Contains(tab_bb))
overlay_draw_lists[overlay_n]->PopClipRect();
}
PopStyleColor();
}
}
@@ -14961,7 +15171,7 @@ void ImGui::BeginDocked(ImGuiWindow* window, bool* p_open)
// Note how we are testing for LastFrameAlive and NOT LastFrameActive. A DockSpace node can be maintained alive while being inactive with ImGuiDockNodeFlags_KeepAliveOnly.
if (node->LastFrameAlive < g.FrameCount)
{
// If the window has been orphaned, transition the docknode to an implicit node processed in DockContextUpdateDocking()
// If the window has been orphaned, transition the docknode to an implicit node processed in DockContextNewFrameUpdateDocking()
ImGuiDockNode* root_node = DockNodeGetRootNode(node);
if (root_node->LastFrameAlive < g.FrameCount)
{
@@ -14975,6 +15185,10 @@ void ImGui::BeginDocked(ImGuiWindow* window, bool* p_open)
return;
}
// Store style overrides
for (int color_n = 0; color_n < ImGuiWindowDockStyleCol_COUNT; color_n++)
window->DockStyle.Colors[color_n] = ColorConvertFloat4ToU32(g.Style.Colors[GWindowDockStyleColors[color_n]]);
// Fast path return. It is common for windows to hold on a persistent DockId but be the only visible window,
// and never create neither a host window neither a tab bar.
// FIXME-DOCK: replace ->HostWindow NULL compare with something more explicit (~was initially intended as a first frame test)
@@ -15046,6 +15260,10 @@ void ImGui::BeginDockableDragDropSource(ImGuiWindow* window)
{
SetDragDropPayload(IMGUI_PAYLOAD_TYPE_WINDOW, &window, sizeof(window));
EndDragDropSource();
// Store style overrides
for (int color_n = 0; color_n < ImGuiWindowDockStyleCol_COUNT; color_n++)
window->DockStyle.Colors[color_n] = ColorConvertFloat4ToU32(g.Style.Colors[GWindowDockStyleColors[color_n]]);
}
}
@@ -15603,10 +15821,10 @@ void ImGui::ShowMetricsWindow(bool* p_open)
Separator();
// Debugging enums
enum { WRT_OuterRect, WRT_OuterRectClipped, WRT_InnerRect, WRT_InnerClipRect, WRT_WorkRect, WRT_Content, WRT_ContentRegionRect, WRT_Count }; // Windows Rect Type
const char* wrt_rects_names[WRT_Count] = { "OuterRect", "OuterRectClipped", "InnerRect", "InnerClipRect", "WorkRect", "Content", "ContentRegionRect" };
enum { TRT_OuterRect, TRT_WorkRect, TRT_HostClipRect, TRT_InnerClipRect, TRT_BackgroundClipRect, TRT_ColumnsRect, TRT_ColumnsClipRect, TRT_ColumnsContentHeadersUsed, TRT_ColumnsContentHeadersIdeal, TRT_ColumnsContentFrozen, TRT_ColumnsContentUnfrozen, TRT_Count }; // Tables Rect Type
const char* trt_rects_names[TRT_Count] = { "OuterRect", "WorkRect", "HostClipRect", "InnerClipRect", "BackgroundClipRect", "ColumnsRect", "ColumnsClipRect", "ColumnsContentHeadersUsed", "ColumnsContentHeadersIdeal", "ColumnsContentFrozen", "ColumnsContentUnfrozen" };
enum { WRT_OuterRect, WRT_OuterRectClipped, WRT_InnerRect, WRT_InnerClipRect, WRT_WorkRect, WRT_Content, WRT_ContentIdeal, WRT_ContentRegionRect, WRT_Count }; // Windows Rect Type
const char* wrt_rects_names[WRT_Count] = { "OuterRect", "OuterRectClipped", "InnerRect", "InnerClipRect", "WorkRect", "Content", "ContentIdeal", "ContentRegionRect" };
enum { TRT_OuterRect, TRT_InnerRect, TRT_WorkRect, TRT_HostClipRect, TRT_InnerClipRect, TRT_BackgroundClipRect, TRT_ColumnsRect, TRT_ColumnsWorkRect, TRT_ColumnsClipRect, TRT_ColumnsContentHeadersUsed, TRT_ColumnsContentHeadersIdeal, TRT_ColumnsContentFrozen, TRT_ColumnsContentUnfrozen, TRT_Count }; // Tables Rect Type
const char* trt_rects_names[TRT_Count] = { "OuterRect", "InnerRect", "WorkRect", "HostClipRect", "InnerClipRect", "BackgroundClipRect", "ColumnsRect", "ColumnsWorkRect", "ColumnsClipRect", "ColumnsContentHeadersUsed", "ColumnsContentHeadersIdeal", "ColumnsContentFrozen", "ColumnsContentUnfrozen" };
if (cfg->ShowWindowsRectsType < 0)
cfg->ShowWindowsRectsType = WRT_WorkRect;
if (cfg->ShowTablesRectsType < 0)
@@ -15617,11 +15835,13 @@ void ImGui::ShowMetricsWindow(bool* p_open)
static ImRect GetTableRect(ImGuiTable* table, int rect_type, int n)
{
if (rect_type == TRT_OuterRect) { return table->OuterRect; }
else if (rect_type == TRT_InnerRect) { return table->InnerRect; }
else if (rect_type == TRT_WorkRect) { return table->WorkRect; }
else if (rect_type == TRT_HostClipRect) { return table->HostClipRect; }
else if (rect_type == TRT_InnerClipRect) { return table->InnerClipRect; }
else if (rect_type == TRT_BackgroundClipRect) { return table->BgClipRect; }
else if (rect_type == TRT_ColumnsRect) { ImGuiTableColumn* c = &table->Columns[n]; return ImRect(c->MinX, table->InnerClipRect.Min.y, c->MaxX, table->InnerClipRect.Min.y + table->LastOuterHeight); }
else if (rect_type == TRT_ColumnsWorkRect) { ImGuiTableColumn* c = &table->Columns[n]; return ImRect(c->WorkMinX, table->WorkRect.Min.y, c->WorkMaxX, table->WorkRect.Max.y); }
else if (rect_type == TRT_ColumnsClipRect) { ImGuiTableColumn* c = &table->Columns[n]; return c->ClipRect; }
else if (rect_type == TRT_ColumnsContentHeadersUsed){ ImGuiTableColumn* c = &table->Columns[n]; return ImRect(c->WorkMinX, table->InnerClipRect.Min.y, c->ContentMaxXHeadersUsed, table->InnerClipRect.Min.y + table->LastFirstRowHeight); } // Note: y1/y2 not always accurate
else if (rect_type == TRT_ColumnsContentHeadersIdeal){ImGuiTableColumn* c = &table->Columns[n]; return ImRect(c->WorkMinX, table->InnerClipRect.Min.y, c->ContentMaxXHeadersIdeal, table->InnerClipRect.Min.y + table->LastFirstRowHeight); }
@@ -15638,7 +15858,8 @@ void ImGui::ShowMetricsWindow(bool* p_open)
else if (rect_type == WRT_InnerRect) { return window->InnerRect; }
else if (rect_type == WRT_InnerClipRect) { return window->InnerClipRect; }
else if (rect_type == WRT_WorkRect) { return window->WorkRect; }
else if (rect_type == WRT_Content) { ImVec2 min = window->InnerRect.Min - window->Scroll + window->WindowPadding; return ImRect(min, min + window->ContentSize); }
else if (rect_type == WRT_Content) { ImVec2 min = window->InnerRect.Min - window->Scroll + window->WindowPadding; return ImRect(min, min + window->ContentSize); }
else if (rect_type == WRT_ContentIdeal) { ImVec2 min = window->InnerRect.Min - window->Scroll + window->WindowPadding; return ImRect(min, min + window->ContentSizeIdeal); }
else if (rect_type == WRT_ContentRegionRect) { return window->ContentRegionRect; }
IM_ASSERT(0);
return ImRect();
@@ -15986,7 +16207,7 @@ void ImGui::ShowMetricsWindow(bool* p_open)
}
// [DEBUG] Display contents of Columns
void ImGui::DebugNodeColumns(ImGuiColumns* columns)
void ImGui::DebugNodeColumns(ImGuiOldColumns* columns)
{
if (!TreeNode((void*)(uintptr_t)columns->ID, "Columns Id: 0x%08X, Count: %d, Flags: 0x%04X", columns->ID, columns->Count, columns->Flags))
return;
@@ -16278,7 +16499,7 @@ void ImGui::DebugNodeWindow(ImGuiWindow* window, const char* label)
ImGuiWindowFlags flags = window->Flags;
DebugNodeDrawList(window, window->Viewport, window->DrawList, "DrawList");
BulletText("Pos: (%.1f,%.1f), Size: (%.1f,%.1f), ContentSize (%.1f,%.1f)", window->Pos.x, window->Pos.y, window->Size.x, window->Size.y, window->ContentSize.x, window->ContentSize.y);
BulletText("Pos: (%.1f,%.1f), Size: (%.1f,%.1f), ContentSize (%.1f,%.1f) Ideal (%.1f,%.1f)", window->Pos.x, window->Pos.y, window->Size.x, window->Size.y, window->ContentSize.x, window->ContentSize.y, window->ContentSizeIdeal.x, window->ContentSizeIdeal.y);
BulletText("Flags: 0x%08X (%s%s%s%s%s%s%s%s%s..)", flags,
(flags & ImGuiWindowFlags_ChildWindow) ? "Child " : "", (flags & ImGuiWindowFlags_Tooltip) ? "Tooltip " : "", (flags & ImGuiWindowFlags_Popup) ? "Popup " : "",
(flags & ImGuiWindowFlags_Modal) ? "Modal " : "", (flags & ImGuiWindowFlags_ChildMenu) ? "ChildMenu " : "", (flags & ImGuiWindowFlags_NoSavedSettings) ? "NoSavedSettings " : "",
@@ -16335,13 +16556,11 @@ void ImGui::DebugNodeWindowsList(ImVector<ImGuiWindow*>* windows, const char* la
#else
void ImGui::ShowMetricsWindow(bool*) {}
void ImGui::DebugNodeColumns(ImGuiColumns*) {}
void ImGui::DebugNodeColumns(ImGuiOldColumns*) {}
void ImGui::DebugNodeDrawList(ImGuiWindow*, ImGuiViewportP*, const ImDrawList*, const char*) {}
void ImGui::DebugNodeDrawCmdShowMeshAndBoundingBox(ImDrawList*, const ImDrawList*, const ImDrawCmd*, bool, bool) {}
void ImGui::DebugNodeStorage(ImGuiStorage*, const char*) {}
void ImGui::DebugNodeTabBar(ImGuiTabBar*, const char*) {}
void ImGui::DebugNodeTable(ImGuiTable*) {}
void ImGui::DebugNodeTableSettings(ImGuiTableSettings*) {}
void ImGui::DebugNodeWindow(ImGuiWindow*, const char*) {}
void ImGui::DebugNodeWindowSettings(ImGuiWindowSettings*) {}
void ImGui::DebugNodeWindowsList(ImVector<ImGuiWindow*>*, const char*) {}

File diff suppressed because it is too large Load Diff

View File

@@ -1,4 +1,4 @@
// dear imgui, v1.80 WIP
// dear imgui, v1.80
// (drawing and font code)
/*
@@ -69,7 +69,6 @@ Index of this file:
#pragma clang diagnostic ignored "-Wglobal-constructors" // warning: declaration requires a global destructor // similar to above, not sure what the exact difference is.
#pragma clang diagnostic ignored "-Wsign-conversion" // warning: implicit conversion changes signedness
#pragma clang diagnostic ignored "-Wzero-as-null-pointer-constant" // warning: zero as null pointer constant // some standard header variations use #define NULL 0
#pragma clang diagnostic ignored "-Walloca" // warning: use of function '__builtin_alloca' is discouraged
#pragma clang diagnostic ignored "-Wcomma" // warning: possible misuse of comma operator here
#pragma clang diagnostic ignored "-Wreserved-id-macro" // warning: macro name is a reserved identifier
#pragma clang diagnostic ignored "-Wdouble-promotion" // warning: implicit conversion from 'float' to 'double' when passing argument to function // using printf() is a misery with this as C++ va_arg ellipsis changes float to double.
@@ -211,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);
@@ -229,7 +228,7 @@ void ImGui::StyleColorsDark(ImGuiStyle* dst)
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.07f);
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);
@@ -245,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);
@@ -273,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);
@@ -336,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);
@@ -354,7 +353,7 @@ void ImGui::StyleColorsLight(ImGuiStyle* dst)
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.07f);
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];
@@ -412,6 +411,7 @@ void ImDrawList::_ResetForNewFrame()
_Path.resize(0);
_Splitter.Clear();
CmdBuffer.push_back(ImDrawCmd());
_FringeScale = 1.0f;
}
void ImDrawList::_ClearFreeMemory()
@@ -687,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
@@ -703,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));
@@ -800,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++)
@@ -945,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);
@@ -1057,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))
@@ -1082,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));
}
}
@@ -1318,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);
}
@@ -2124,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.");
@@ -2638,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
View 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;
}

View File

@@ -0,0 +1,234 @@
#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
#define STB_IMAGE_IMPLEMENTATION
#include <stb_image.h>
#include <string>
#include <glad/glad.h>
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 = GetCustomColorU32((held && hovered) ? ImGuiCustomCol_DescButtonActive : hovered ? ImGuiCustomCol_DescButtonHovered : ImGuiCustomCol_DescButton);
RenderNavHighlight(bb, id);
RenderFrame(bb.Min, bb.Max, col, true, style.FrameRounding);
PushStyleColor(ImGuiCol_Text, GetColorU32(ImGuiCol_ButtonActive));
RenderTextWrapped(bb.Min + style.FramePadding * 2, label, nullptr, CalcWrapWidthForPos(window->DC.CursorPos, window->DC.TextWrapPos));
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();
}
void Disabled(const std::function<void()> &widgets, bool disabled) {
if (disabled) {
ImGui::PushItemFlag(ImGuiItemFlags_Disabled, true);
ImGui::PushStyleVar(ImGuiStyleVar_Alpha, ImGui::GetStyle().Alpha * 0.5F);
widgets();
ImGui::PopStyleVar();
ImGui::PopItemFlag();
} else {
widgets();
}
}
void TextSpinner(const char* label) {
ImGui::Text("[%c] %s", "|/-\\"[ImU32(ImGui::GetTime() * 20) % 4], label);
}
void Header(const char *label, bool firstEntry) {
if (!firstEntry)
ImGui::NewLine();
ImGui::TextUnformatted(label);
ImGui::Separator();
}
ImU32 GetCustomColorU32(ImGuiCustomCol idx, float alpha_mul) {
auto& customData = *static_cast<ImHexCustomData*>(GImGui->IO.UserData);
ImVec4 c = customData.Colors[idx];
c.w *= GImGui->Style.Alpha * alpha_mul;
return ColorConvertFloat4ToU32(c);
}
void StyleCustomColorsDark() {
auto &colors = static_cast<ImHexCustomData*>(GImGui->IO.UserData)->Colors;
colors[ImGuiCustomCol_DescButton] = ImColor(20, 20, 20);
colors[ImGuiCustomCol_DescButtonHovered] = ImColor(40, 40, 40);
colors[ImGuiCustomCol_DescButtonActive] = ImColor(60, 60, 60);
}
void StyleCustomColorsLight() {
auto &colors = static_cast<ImHexCustomData*>(GImGui->IO.UserData)->Colors;
colors[ImGuiCustomCol_DescButton] = ImColor(230, 230, 230);
colors[ImGuiCustomCol_DescButtonHovered] = ImColor(210, 210, 210);
colors[ImGuiCustomCol_DescButtonActive] = ImColor(190, 190, 190);
}
void StyleCustomColorsClassic() {
auto &colors = static_cast<ImHexCustomData*>(GImGui->IO.UserData)->Colors;
colors[ImGuiCustomCol_DescButton] = ImColor(40, 40, 80);
colors[ImGuiCustomCol_DescButtonHovered] = ImColor(60, 60, 100);
colors[ImGuiCustomCol_DescButtonActive] = ImColor(80, 80, 120);
}
std::tuple<ImTextureID, int, int> LoadImageFromPath(const char *path) {
int imageWidth = 0;
int imageHeight = 0;
unsigned char* imageData = stbi_load(path, &imageWidth, &imageHeight, nullptr, 4);
if (imageData == nullptr)
return { nullptr, -1, -1 };
GLuint texture;
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
#if defined(GL_UNPACK_ROW_LENGTH)
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
#endif
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, imageWidth, imageHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, imageData);
stbi_image_free(imageData);
return { reinterpret_cast<ImTextureID>(static_cast<intptr_t>(texture)), imageWidth, imageHeight };
}
void UnloadImage(ImTextureID texture) {
auto glTextureId = static_cast<GLuint>(reinterpret_cast<intptr_t>(texture));
glDeleteTextures(1, &glTextureId);
}
}

View File

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

View File

@@ -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*)&current_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

File diff suppressed because it is too large Load Diff

2944
external/ImGui/source/imnodes.cpp vendored Normal file

File diff suppressed because it is too large Load Diff

4109
external/ImGui/source/implot.cpp vendored Normal file

File diff suppressed because it is too large Load Diff

1691
external/ImGui/source/implot_demo.cpp vendored Normal file

File diff suppressed because it is too large Load Diff

1915
external/ImGui/source/implot_items.cpp vendored Normal file

File diff suppressed because it is too large Load Diff

1
external/curl vendored Submodule

Submodule external/curl added at 566b74a0e1

1
external/fmt vendored Submodule

Submodule external/fmt added at 6271406233

14
external/glad/CMakeLists.txt vendored Normal file
View File

@@ -0,0 +1,14 @@
cmake_minimum_required(VERSION 3.16)
project(glad)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC")
add_library(glad STATIC
source/glad.c
)
target_include_directories(glad PUBLIC include)
target_link_libraries(glad PRIVATE dl)

15
external/llvm/CMakeLists.txt vendored Normal file
View File

@@ -0,0 +1,15 @@
cmake_minimum_required(VERSION 3.16)
project(LLVMDemangle)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC")
add_library(LLVMDemangle STATIC
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
View 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;
}

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

File diff suppressed because it is too large Load Diff

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

View 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

View 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

File diff suppressed because it is too large Load Diff

View 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

View 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

View 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

View 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

1
external/nativefiledialog vendored Submodule

8
external/nlohmann_json/CMakeLists.txt vendored Normal file
View 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)

File diff suppressed because it is too large Load Diff

1
external/xdgpp vendored Submodule

Submodule external/xdgpp added at f01f810714

128
external/yara/CMakeLists.txt vendored Normal file
View File

@@ -0,0 +1,128 @@
cmake_minimum_required(VERSION 3.16)
set(LIBYARA_SOURCE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/yara/libyara")
set(LIBYARA_INCLUDES
${LIBYARA_SOURCE_PATH}/include/yara/ahocorasick.h
${LIBYARA_SOURCE_PATH}/include/yara/arena.h
${LIBYARA_SOURCE_PATH}/include/yara/atoms.h
${LIBYARA_SOURCE_PATH}/include/yara/bitmask.h
${LIBYARA_SOURCE_PATH}/include/yara/compiler.h
${LIBYARA_SOURCE_PATH}/include/yara/error.h
${LIBYARA_SOURCE_PATH}/include/yara/exec.h
${LIBYARA_SOURCE_PATH}/include/yara/exefiles.h
${LIBYARA_SOURCE_PATH}/include/yara/filemap.h
${LIBYARA_SOURCE_PATH}/include/yara/hash.h
${LIBYARA_SOURCE_PATH}/include/yara/integers.h
${LIBYARA_SOURCE_PATH}/include/yara/libyara.h
${LIBYARA_SOURCE_PATH}/include/yara/limits.h
${LIBYARA_SOURCE_PATH}/include/yara/mem.h
${LIBYARA_SOURCE_PATH}/include/yara/modules.h
${LIBYARA_SOURCE_PATH}/include/yara/object.h
${LIBYARA_SOURCE_PATH}/include/yara/parser.h
${LIBYARA_SOURCE_PATH}/include/yara/proc.h
${LIBYARA_SOURCE_PATH}/include/yara/re.h
${LIBYARA_SOURCE_PATH}/include/yara/rules.h
${LIBYARA_SOURCE_PATH}/include/yara/scan.h
${LIBYARA_SOURCE_PATH}/include/yara/scanner.h
${LIBYARA_SOURCE_PATH}/include/yara/sizedstr.h
${LIBYARA_SOURCE_PATH}/include/yara/stack.h
${LIBYARA_SOURCE_PATH}/include/yara/stopwatch.h
${LIBYARA_SOURCE_PATH}/include/yara/stream.h
${LIBYARA_SOURCE_PATH}/include/yara/strutils.h
${LIBYARA_SOURCE_PATH}/include/yara/threading.h
${LIBYARA_SOURCE_PATH}/include/yara/types.h
${LIBYARA_SOURCE_PATH}/include/yara/utils.h
${LIBYARA_SOURCE_PATH}/crypto.h
)
set(LIBYARA_SOURCE
${LIBYARA_SOURCE_PATH}/grammar.y
${LIBYARA_SOURCE_PATH}/ahocorasick.c
${LIBYARA_SOURCE_PATH}/arena.c
${LIBYARA_SOURCE_PATH}/atoms.c
${LIBYARA_SOURCE_PATH}/base64.c
${LIBYARA_SOURCE_PATH}/bitmask.c
${LIBYARA_SOURCE_PATH}/compiler.c
${LIBYARA_SOURCE_PATH}/endian.c
${LIBYARA_SOURCE_PATH}/exec.c
${LIBYARA_SOURCE_PATH}/exefiles.c
${LIBYARA_SOURCE_PATH}/filemap.c
${LIBYARA_SOURCE_PATH}/hash.c
${LIBYARA_SOURCE_PATH}/hex_grammar.y
${LIBYARA_SOURCE_PATH}/hex_lexer.l
${LIBYARA_SOURCE_PATH}/lexer.l
${LIBYARA_SOURCE_PATH}/libyara.c
${LIBYARA_SOURCE_PATH}/mem.c
${LIBYARA_SOURCE_PATH}/modules.c
${LIBYARA_SOURCE_PATH}/notebook.c
${LIBYARA_SOURCE_PATH}/object.c
${LIBYARA_SOURCE_PATH}/parser.c
${LIBYARA_SOURCE_PATH}/proc.c
${LIBYARA_SOURCE_PATH}/re.c
${LIBYARA_SOURCE_PATH}/re_grammar.y
${LIBYARA_SOURCE_PATH}/re_lexer.l
${LIBYARA_SOURCE_PATH}/rules.c
${LIBYARA_SOURCE_PATH}/scan.c
${LIBYARA_SOURCE_PATH}/scanner.c
${LIBYARA_SOURCE_PATH}/sizedstr.c
${LIBYARA_SOURCE_PATH}/stack.c
${LIBYARA_SOURCE_PATH}/stopwatch.c
${LIBYARA_SOURCE_PATH}/strutils.c
${LIBYARA_SOURCE_PATH}/stream.c
${LIBYARA_SOURCE_PATH}/threading.c
${LIBYARA_SOURCE_PATH}/lexer.c
${LIBYARA_SOURCE_PATH}/hex_lexer.c
${LIBYARA_SOURCE_PATH}/grammar.c
${LIBYARA_SOURCE_PATH}/re_lexer.c
${LIBYARA_SOURCE_PATH}/hex_grammar.c
${LIBYARA_SOURCE_PATH}/re_grammar.c
${LIBYARA_SOURCE_PATH}/proc/none.c
)
set(LIBYARA_MODULES
${LIBYARA_SOURCE_PATH}/modules/tests/tests.c
${LIBYARA_SOURCE_PATH}/modules/pe/pe.c
${LIBYARA_SOURCE_PATH}/modules/pe/pe_utils.c
${LIBYARA_SOURCE_PATH}/modules/elf/elf.c
${LIBYARA_SOURCE_PATH}/modules/math/math.c
${LIBYARA_SOURCE_PATH}/modules/time/time.c
${LIBYARA_SOURCE_PATH}/modules/macho/macho.c
${LIBYARA_SOURCE_PATH}/modules/hash/hash.c
${LIBYARA_SOURCE_PATH}/modules/dex/dex.c
${LIBYARA_SOURCE_PATH}/modules/dotnet/dotnet.c
${LIBYARA_SOURCE_PATH}/modules/magic/magic.c)
# Add mbedtls crypto wrappers
file(READ crypto_mbedtls.h MBEDTLS_CRYPTO_H)
file(WRITE ${LIBYARA_SOURCE_PATH}/crypto.h "${MBEDTLS_CRYPTO_H}")
add_compile_definitions("HAVE_MBEDTLS")
add_compile_definitions("USE_NO_PROC")
add_compile_definitions("HASH_MODULE")
add_compile_definitions("DOTNET_MODULE")
add_compile_definitions("MAGIC_MODULE")
add_compile_definitions("MACHO_MODULE")
add_compile_definitions("DEX_MODULE")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-shift-count-overflow")
add_library(libyara STATIC ${LIBYARA_SOURCE} ${LIBYARA_INCLUDES} ${LIBYARA_MODULES})
target_include_directories(
libyara
PUBLIC $<BUILD_INTERFACE:${LIBYARA_SOURCE_PATH}/include> $<INSTALL_INTERFACE:include>
PRIVATE ${LIBYARA_SOURCE_PATH} ${MBEDTLS_INCLUDE_DIR}
)
if (UNIX)
target_link_libraries(libyara magic pthread)
else ()
target_link_libraries(libyara magic)
endif ()
include(GNUInstallDirs)
configure_file(${LIBYARA_SOURCE_PATH}/yara.pc.in
${LIBYARA_SOURCE_PATH}/yara.pc @ONLY)
set(CMAKE_STATIC_LIBRARY_PREFIX "")

143
external/yara/crypto_mbedtls.h vendored Normal file
View File

@@ -0,0 +1,143 @@
/*
Copyright (c) 2017. The YARA Authors. All Rights Reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its contributors
may be used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef YR_CRYPTO_H
#define YR_CRYPTO_H
#define YR_MD5_LEN 16
#define YR_SHA1_LEN 20
#define YR_SHA256_LEN 32
#if defined(HAVE_LIBCRYPTO)
#include <openssl/crypto.h>
#include <openssl/md5.h>
#include <openssl/sha.h>
typedef MD5_CTX yr_md5_ctx;
typedef SHA_CTX yr_sha1_ctx;
typedef SHA256_CTX yr_sha256_ctx;
#define yr_md5_init(ctx) MD5_Init(ctx)
#define yr_md5_update(ctx, data, len) MD5_Update(ctx, data, len)
#define yr_md5_final(digest, ctx) MD5_Final(digest, ctx)
#define yr_sha1_init(ctx) SHA1_Init(ctx)
#define yr_sha1_update(ctx, data, len) SHA1_Update(ctx, data, len)
#define yr_sha1_final(digest, ctx) SHA1_Final(digest, ctx)
#define yr_sha256_init(ctx) SHA256_Init(ctx)
#define yr_sha256_update(ctx, data, len) SHA256_Update(ctx, data, len)
#define yr_sha256_final(digest, ctx) SHA256_Final(digest, ctx)
#elif defined(HAVE_WINCRYPT_H)
#include <windows.h>
#include <wincrypt.h>
extern HCRYPTPROV yr_cryptprov;
typedef HCRYPTHASH yr_md5_ctx;
typedef HCRYPTHASH yr_sha1_ctx;
typedef HCRYPTHASH yr_sha256_ctx;
#define yr_md5_init(ctx) CryptCreateHash(yr_cryptprov, CALG_MD5, 0, 0, ctx)
#define yr_md5_update(ctx, data, len) \
CryptHashData(*ctx, (const BYTE*) data, len, 0)
#define yr_md5_final(digest, ctx) \
{ \
DWORD len = YR_MD5_LEN; \
CryptGetHashParam(*ctx, HP_HASHVAL, digest, &len, 0); \
CryptDestroyHash(*ctx); \
}
#define yr_sha1_init(ctx) CryptCreateHash(yr_cryptprov, CALG_SHA1, 0, 0, ctx)
#define yr_sha1_update(ctx, data, len) \
CryptHashData(*ctx, (const BYTE*) data, len, 0)
#define yr_sha1_final(digest, ctx) \
{ \
DWORD len = YR_SHA1_LEN; \
CryptGetHashParam(*ctx, HP_HASHVAL, digest, &len, 0); \
CryptDestroyHash(*ctx); \
}
#define yr_sha256_init(ctx) \
CryptCreateHash(yr_cryptprov, CALG_SHA_256, 0, 0, ctx)
#define yr_sha256_update(ctx, data, len) \
CryptHashData(*ctx, (const BYTE*) data, len, 0)
#define yr_sha256_final(digest, ctx) \
{ \
DWORD len = YR_SHA256_LEN; \
CryptGetHashParam(*ctx, HP_HASHVAL, digest, &len, 0); \
CryptDestroyHash(*ctx); \
}
#elif defined(HAVE_COMMONCRYPTO_COMMONCRYPTO_H)
#include <CommonCrypto/CommonDigest.h>
typedef CC_MD5_CTX yr_md5_ctx;
typedef CC_SHA1_CTX yr_sha1_ctx;
typedef CC_SHA256_CTX yr_sha256_ctx;
#define yr_md5_init(ctx) CC_MD5_Init(ctx)
#define yr_md5_update(ctx, data, len) CC_MD5_Update(ctx, data, len)
#define yr_md5_final(digest, ctx) CC_MD5_Final(digest, ctx)
#define yr_sha1_init(ctx) CC_SHA1_Init(ctx)
#define yr_sha1_update(ctx, data, len) CC_SHA1_Update(ctx, data, len)
#define yr_sha1_final(digest, ctx) CC_SHA1_Final(digest, ctx)
#define yr_sha256_init(ctx) CC_SHA256_Init(ctx)
#define yr_sha256_update(ctx, data, len) CC_SHA256_Update(ctx, data, len)
#define yr_sha256_final(digest, ctx) CC_SHA256_Final(digest, ctx)
#elif defined(HAVE_MBEDTLS)
#include <mbedtls/md5.h>
#include <mbedtls/sha1.h>
#include <mbedtls/sha256.h>
typedef mbedtls_md5_context yr_md5_ctx;
typedef mbedtls_sha1_context yr_sha1_ctx;
typedef mbedtls_sha256_context yr_sha256_ctx;
#define yr_md5_init(ctx) { mbedtls_md5_init(ctx); mbedtls_md5_starts_ret(ctx); }
#define yr_md5_update(ctx, data, len) mbedtls_md5_update_ret(ctx, data, len)
#define yr_md5_final(digest, ctx) { mbedtls_md5_finish_ret(ctx, digest); mbedtls_md5_free(ctx); }
#define yr_sha1_init(ctx) { mbedtls_sha1_init(ctx); mbedtls_sha1_starts_ret(ctx); }
#define yr_sha1_update(ctx, data, len) mbedtls_sha1_update_ret(ctx, data, len)
#define yr_sha1_final(digest, ctx) { mbedtls_sha1_finish_ret(ctx, digest); mbedtls_sha1_free(ctx); }
#define yr_sha256_init(ctx) { mbedtls_sha256_init(ctx); mbedtls_sha256_starts_ret(ctx, false); }
#define yr_sha256_update(ctx, data, len) mbedtls_sha256_update_ret(ctx, data, len)
#define yr_sha256_final(digest, ctx) { mbedtls_sha256_finish_ret(ctx, digest); mbedtls_sha256_free(ctx); }
#define HAVE_COMMONCRYPTO_COMMONCRYPTO_H
#endif
#endif

1
external/yara/yara vendored Submodule

Submodule external/yara/yara added at 1842271119

BIN
icon.ico

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

View File

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

View File

@@ -1,48 +0,0 @@
#pragma once
#include <vector>
#include <functional>
namespace hex {
enum class Events {
DataChanged,
PatternChanged,
FileDropped,
ByteSelected
};
struct EventHandler {
void *sender;
Events eventType;
std::function<void(const void*)> callback;
};
class EventManager {
public:
void post(Events eventType, const void *userData) {
for (auto &handler : this->m_eventHandlers)
if (eventType == handler.eventType)
handler.callback(userData);
}
void subscribe(Events eventType, void *sender, std::function<void(const 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;
};
}

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

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

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

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

View File

@@ -0,0 +1,64 @@
#pragma once
#include <hex.hpp>
#include <hex/views/view.hpp>
#include <hex/providers/provider.hpp>
#include <hex/helpers/utils.hpp>
#include <string_view>
#include <dlfcn.h>
namespace hex {
class Plugin {
public:
Plugin(std::string_view path);
Plugin(const Plugin&) = delete;
Plugin(Plugin &&other) noexcept;
~Plugin();
void initializePlugin() const;
std::string getPluginName() const;
std::string getPluginAuthor() const;
std::string getPluginDescription() const;
private:
using InitializePluginFunc = void(*)();
using GetPluginNameFunc = const char*(*)();
using GetPluginAuthorFunc = const char*(*)();
using GetPluginDescriptionFunc = const char*(*)();
void *m_handle = nullptr;
InitializePluginFunc m_initializePluginFunction = nullptr;
GetPluginNameFunc m_getPluginNameFunction = nullptr;
GetPluginAuthorFunc m_getPluginAuthorFunction = nullptr;
GetPluginDescriptionFunc m_getPluginDescriptionFunction = nullptr;
template<typename T>
auto getPluginFunction(std::string_view pluginName, std::string_view symbol) {
auto symbolName = hex::format(symbol.data(), pluginName.length(), pluginName.data());
return reinterpret_cast<T>(dlsym(this->m_handle, symbolName.c_str()));
};
};
class PluginManager {
public:
PluginManager() = delete;
static bool load(std::string_view pluginFolder);
static void unload();
static void reload();
static const auto& getPlugins() {
return PluginManager::s_plugins;
}
private:
static inline std::string s_pluginFolder;
static inline std::vector<Plugin> s_plugins;
};
}

View File

@@ -0,0 +1,50 @@
#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; }
[[nodiscard]] static const std::string_view getDataProcessorContent() { return ProjectFile::s_dataProcessorContent; }
static void setDataProcessorContent(std::string_view json) { ProjectFile::s_dataProcessorContent = json; }
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;
static inline std::string s_dataProcessorContent;
};
}

View File

@@ -0,0 +1,41 @@
#pragma once
#include <functional>
#include <future>
#include <vector>
#include <mutex>
struct GLFWwindow;
namespace hex::init {
class WindowSplash {
public:
WindowSplash(int &argc, char **&argv);
~WindowSplash();
bool loop();
void addStartupTask(std::string_view taskName, const std::function<bool()> &task) {
this->m_tasks.emplace_back(taskName, task);
}
private:
GLFWwindow *m_window;
std::mutex m_progressMutex;
float m_progress = 0;
std::string m_currTaskName;
void initGLFW();
void initImGui();
void deinitGLFW();
void deinitImGui();
std::future<bool> processTasksAsync();
std::vector<std::pair<std::string, std::function<bool()>>> m_tasks;
};
}

22
include/init/tasks.hpp Normal file
View File

@@ -0,0 +1,22 @@
#pragma once
#include <functional>
#include <string>
#include <vector>
namespace hex::init {
struct Task {
std::string name;
std::function<bool()> function;
};
struct Argument {
std::string name, value;
};
std::vector<Task> getInitTasks();
std::vector<Task> getExitTasks();
std::vector<Argument>& getInitArguments();
}

View File

@@ -1,124 +0,0 @@
#pragma once
#include "token.hpp"
#include <optional>
#include <unordered_map>
#include <vector>
namespace hex::lang {
class ASTNode {
public:
enum class Type {
VariableDecl,
TypeDecl,
Struct,
Union,
Enum,
Bitfield,
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 ASTNodeUnion : public ASTNode {
public:
explicit ASTNodeUnion(std::string name, std::vector<ASTNode*> nodes)
: ASTNode(Type::Union), 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 ASTNodeBitField : public ASTNode {
public:
explicit ASTNodeBitField(std::string name, std::vector<std::pair<std::string, size_t>> fields)
: ASTNode(Type::Bitfield), m_name(name), m_fields(fields) { }
const std::string& getName() const { return this->m_name; }
std::vector<std::pair<std::string, size_t>> &getFields() { return this->m_fields; }
private:
std::string m_name;
std::vector<std::pair<std::string, size_t>> m_fields;
};
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;
};
class ASTNodeEnum : public ASTNode {
public:
explicit ASTNodeEnum(const Token::TypeToken::Type &type, const std::string &name)
: ASTNode(Type::Enum), m_type(type), m_name(name) { }
const std::string& getName() const { return this->m_name; };
const Token::TypeToken::Type& getUnderlyingType() const { return this->m_type; }
std::vector<std::pair<u64, std::string>>& getValues() { return this->m_values; }
private:
Token::TypeToken::Type m_type;
std::string m_name;
std::vector<std::pair<u64, std::string>> m_values;
};
}

View File

@@ -1,34 +0,0 @@
#pragma once
#include <hex.hpp>
#include "lang/pattern_data.hpp"
#include "ast_node.hpp"
#include <string>
#include <unordered_map>
#include <vector>
namespace hex::lang {
class Evaluator {
public:
Evaluator();
std::pair<Result, std::vector<PatternData*>> evaluate(const std::vector<ASTNode*>& ast);
private:
std::unordered_map<std::string, ASTNode*> m_types;
std::pair<PatternData*, size_t> createStructPattern(ASTNodeVariableDecl *varDeclNode, u64 offset);
std::pair<PatternData*, size_t> createUnionPattern(ASTNodeVariableDecl *varDeclNode, u64 offset);
std::pair<PatternData*, size_t> createEnumPattern(ASTNodeVariableDecl *varDeclNode, u64 offset);
std::pair<PatternData*, size_t> createBitfieldPattern(ASTNodeVariableDecl *varDeclNode, u64 offset);
std::pair<PatternData*, size_t> createArrayPattern(ASTNodeVariableDecl *varDeclNode, u64 offset);
std::pair<PatternData*, size_t> createStringPattern(ASTNodeVariableDecl *varDeclNode, u64 offset);
std::pair<PatternData*, size_t> createCustomTypePattern(ASTNodeVariableDecl *varDeclNode, u64 offset);
std::pair<PatternData*, size_t> createBuiltInTypePattern(ASTNodeVariableDecl *varDeclNode, u64 offset);
};
}

View File

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

View File

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

View File

@@ -1,527 +0,0 @@
#pragma once
#include <hex.hpp>
#include <string>
#include "imgui.h"
#include "imgui_memory_editor.h"
#include "providers/provider.hpp"
#include "utils.hpp"
#include <random>
namespace hex::lang {
namespace {
std::string makeDisplayable(u8 *data, size_t size) {
std::string result;
for (u8* c = data; c < (data + size); c++) {
if (iscntrl(*c) || *c > 0x7F)
result += " ";
else
result += *c;
}
return result;
}
}
class PatternData {
public:
enum class Type { Padding, Unsigned, Signed, Float, Character, String, Struct, Union, Array, Enum };
PatternData(Type type, u64 offset, size_t size, const std::string &name, u32 color = 0)
: m_type(type), m_offset(offset), m_size(size), m_color(color), m_name(name) {
constexpr u32 Palette[] = { 0x50b4771f, 0x500e7fff, 0x502ca02c, 0x502827d6, 0x50bd6794, 0x504b568c, 0x50c277e3, 0x507f7f7f, 0x5022bdbc, 0x50cfbe17 };
if (color != 0)
return;
this->m_color = Palette[PatternData::s_paletteOffset++];
if (PatternData::s_paletteOffset >= (sizeof(Palette) / sizeof(u32)))
PatternData::s_paletteOffset = 0;
}
virtual ~PatternData() = default;
[[nodiscard]] Type getPatternType() const { return this->m_type; }
[[nodiscard]] u64 getOffset() const { return this->m_offset; }
[[nodiscard]] size_t getSize() const { return this->m_size; }
[[nodiscard]] u32 getColor() const { return this->m_color; }
[[nodiscard]] const std::string& getName() const { return this->m_name; }
virtual void createEntry(prv::Provider* &provider) = 0;
virtual std::string getTypeName() = 0;
virtual std::optional<u32> highlightBytes(size_t offset) {
if (offset >= this->getOffset() && offset < (this->getOffset() + this->getSize()))
return this->getColor();
else
return { };
}
virtual void sort(ImGuiTableSortSpecs *sortSpecs, prv::Provider *provider) { }
static bool sortPatternDataTable(ImGuiTableSortSpecs *sortSpecs, prv::Provider *provider, lang::PatternData* left, lang::PatternData* right) {
if (sortSpecs->Specs->ColumnUserID == ImGui::GetID("name")) {
if (sortSpecs->Specs->SortDirection == ImGuiSortDirection_Ascending)
return left->getName() > right->getName();
else
return left->getName() < right->getName();
}
else if (sortSpecs->Specs->ColumnUserID == ImGui::GetID("offset")) {
if (sortSpecs->Specs->SortDirection == ImGuiSortDirection_Ascending)
return left->getOffset() > right->getOffset();
else
return left->getOffset() < right->getOffset();
}
else if (sortSpecs->Specs->ColumnUserID == ImGui::GetID("size")) {
if (sortSpecs->Specs->SortDirection == ImGuiSortDirection_Ascending)
return left->getSize() > right->getSize();
else
return left->getSize() < right->getSize();
}
else if (sortSpecs->Specs->ColumnUserID == ImGui::GetID("value")) {
size_t biggerSize = std::max(left->getSize(), right->getSize());
std::vector<u8> leftBuffer(biggerSize, 0x00), rightBuffer(biggerSize, 0x00);
provider->read(left->getOffset(), leftBuffer.data(), left->getSize());
provider->read(right->getOffset(), rightBuffer.data(), right->getSize());
if (sortSpecs->Specs->SortDirection == ImGuiSortDirection_Ascending)
return leftBuffer > rightBuffer;
else
return leftBuffer < rightBuffer;
}
else if (sortSpecs->Specs->ColumnUserID == ImGui::GetID("type")) {
if (sortSpecs->Specs->SortDirection == ImGuiSortDirection_Ascending)
return left->getTypeName() > right->getTypeName();
else
return left->getTypeName() < right->getTypeName();
}
else if (sortSpecs->Specs->ColumnUserID == ImGui::GetID("color")) {
if (sortSpecs->Specs->SortDirection == ImGuiSortDirection_Ascending)
return left->getColor() > right->getColor();
else
return left->getColor() < right->getColor();
}
return false;
}
static void resetPalette() { PatternData::s_paletteOffset = 0; }
protected:
void createDefaultEntry(std::string value) {
ImGui::TableNextRow();
ImGui::TreeNodeEx(this->getName().c_str(), ImGuiTreeNodeFlags_Leaf | ImGuiTreeNodeFlags_NoTreePushOnOpen | ImGuiTreeNodeFlags_SpanFullWidth);
ImGui::TableNextColumn();
ImGui::ColorButton("color", ImColor(this->getColor()), ImGuiColorEditFlags_NoTooltip);
ImGui::TableNextColumn();
ImGui::Text("%s", this->getName().c_str());
ImGui::TableNextColumn();
ImGui::Text("0x%08lx : 0x%08lx", this->getOffset(), this->getOffset() + this->getSize() - 1);
ImGui::TableNextColumn();
ImGui::Text("0x%04lx", this->getSize());
ImGui::TableNextColumn();
ImGui::Text("%s", this->getTypeName().c_str());
ImGui::TableNextColumn();
ImGui::Text("%s", value.c_str());
}
private:
Type m_type;
u64 m_offset;
size_t m_size;
u32 m_color;
std::string m_name;
static inline u8 s_paletteOffset = 0;
};
class PatternDataPadding : public PatternData {
public:
PatternDataPadding(u64 offset, size_t size) : PatternData(Type::Padding, offset, size, "", 0x00FFFFFF) { }
void createEntry(prv::Provider* &provider) override {
}
std::string getTypeName() override {
return "";
}
};
class PatternDataUnsigned : public PatternData {
public:
PatternDataUnsigned(u64 offset, size_t size, const std::string &name, u32 color = 0) : PatternData(Type::Unsigned, offset, size, name, color) { }
void createEntry(prv::Provider* &provider) override {
u64 data = 0;
provider->read(this->getOffset(), &data, this->getSize());
this->createDefaultEntry(hex::format("%lu (0x%0*lx)", data, this->getSize() * 2, data));
}
std::string getTypeName() override {
switch (this->getSize()) {
case 1: return "u8";
case 2: return "u16";
case 4: return "u32";
case 8: return "u64";
case 16: return "u128";
default: return "Unsigned data";
}
}
};
class PatternDataSigned : public PatternData {
public:
PatternDataSigned(u64 offset, size_t size, const std::string &name, u32 color = 0) : PatternData(Type::Signed, offset, size, name, color) { }
void createEntry(prv::Provider* &provider) override {
u64 data = 0;
provider->read(this->getOffset(), &data, this->getSize());
s64 signedData = signedData = hex::signExtend(data, this->getSize(), 64);
this->createDefaultEntry(hex::format("%ld (0x%0*lx)", signedData, this->getSize() * 2, data));
}
std::string getTypeName() override {
switch (this->getSize()) {
case 1: return "s8";
case 2: return "s16";
case 4: return "s32";
case 8: return "s64";
case 16: return "s128";
default: return "Signed data";
}
}
};
class PatternDataFloat : public PatternData {
public:
PatternDataFloat(u64 offset, size_t size, const std::string &name, u32 color = 0) : PatternData(Type::Float, offset, size, name, color) { }
void createEntry(prv::Provider* &provider) override {
double formatData = 0;
if (this->getSize() == 4) {
float data = 0;
provider->read(this->getOffset(), &data, 4);
formatData = data;
} else if (this->getSize() == 8) {
double data = 0;
provider->read(this->getOffset(), &data, 8);
formatData = data;
}
this->createDefaultEntry(hex::format("%f (0x%0*lx)", formatData, this->getSize() * 2, formatData));
}
std::string getTypeName() override {
switch (this->getSize()) {
case 4: return "float";
case 8: return "double";
default: return "Floating point data";
}
}
};
class PatternDataCharacter : public PatternData {
public:
PatternDataCharacter(u64 offset, size_t size, const std::string &name, u32 color = 0) : PatternData(Type::Character, offset, size, name, color) { }
void createEntry(prv::Provider* &provider) override {
char character;
provider->read(this->getOffset(), &character, 1);
this->createDefaultEntry(hex::format("'%c'", character));
}
std::string getTypeName() override {
return "Character";
}
};
class PatternDataString : public PatternData {
public:
PatternDataString(u64 offset, size_t size, const std::string &name, u32 color = 0) : PatternData(Type::String, offset, size, name, color) { }
void createEntry(prv::Provider* &provider) override {
std::vector<u8> buffer(this->getSize() + 1, 0x00);
provider->read(this->getOffset(), buffer.data(), this->getSize());
buffer[this->getSize()] = '\0';
this->createDefaultEntry(hex::format("\"%s\"", makeDisplayable(buffer.data(), this->getSize()).c_str()));
}
std::string getTypeName() override {
return "String";
}
};
class PatternDataArray : public PatternData {
public:
PatternDataArray(u64 offset, size_t size, const std::string &name, const std::vector<PatternData*> & entries, u32 color = 0)
: PatternData(Type::Array, offset, size, name, color), m_entries(entries) { }
void createEntry(prv::Provider* &provider) override {
ImGui::TableNextRow(ImGuiTableRowFlags_Headers);
ImGui::TableNextColumn();
ImGui::ColorButton("color", ImColor(this->getColor()), ImGuiColorEditFlags_NoTooltip);
ImGui::TableNextColumn();
bool open = ImGui::TreeNodeEx(this->getName().c_str(), ImGuiTreeNodeFlags_SpanFullWidth);
ImGui::TableNextColumn();
ImGui::Text("0x%08lx : 0x%08lx", this->getOffset(), this->getOffset() + this->getSize() - 1);
ImGui::TableNextColumn();
ImGui::Text("0x%04lx", this->getSize());
ImGui::TableNextColumn();
ImGui::Text("%s", this->getTypeName().c_str());
ImGui::TableNextColumn();
ImGui::Text("%s", "{ ... }");
if (open) {
for (auto &member : this->m_entries)
member->createEntry(provider);
ImGui::TreePop();
}
}
std::optional<u32> highlightBytes(size_t offset) override{
for (auto &entry : this->m_entries) {
if (auto color = entry->highlightBytes(offset); color.has_value())
return color.value();
}
return { };
}
std::string getTypeName() override {
return this->m_entries[0]->getTypeName() + "[" + std::to_string(this->m_entries.size()) + "]";
}
private:
std::vector<PatternData*> m_entries;
};
class PatternDataStruct : public PatternData {
public:
PatternDataStruct(u64 offset, size_t size, const std::string &name, const std::string &structName, const std::vector<PatternData*> & members, u32 color = 0)
: PatternData(Type::Struct, offset, size, name, color), m_structName(structName), m_members(members), m_sortedMembers(members) { }
void createEntry(prv::Provider* &provider) override {
ImGui::TableNextRow(ImGuiTableRowFlags_Headers);
ImGui::TableNextColumn();
ImGui::ColorButton("color", ImColor(this->getColor()), ImGuiColorEditFlags_NoTooltip | ImGuiColorEditFlags_AlphaPreview);
ImGui::TableNextColumn();
bool open = ImGui::TreeNodeEx(this->getName().c_str(), ImGuiTreeNodeFlags_SpanFullWidth);
ImGui::TableNextColumn();
ImGui::Text("0x%08lx : 0x%08lx", this->getOffset(), this->getOffset() + this->getSize() - 1);
ImGui::TableNextColumn();
ImGui::Text("0x%04lx", this->getSize());
ImGui::TableNextColumn();
ImGui::Text("%s", this->getTypeName().c_str());
ImGui::TableNextColumn();
ImGui::Text("%s", "{ ... }");
if (open) {
for (auto &member : this->m_sortedMembers)
member->createEntry(provider);
ImGui::TreePop();
}
}
std::optional<u32> highlightBytes(size_t offset) override{
for (auto &member : this->m_members) {
if (auto color = member->highlightBytes(offset); color.has_value())
return color.value();
}
return { };
}
void sort(ImGuiTableSortSpecs *sortSpecs, prv::Provider *provider) override {
this->m_sortedMembers = this->m_members;
std::sort(this->m_sortedMembers.begin(), this->m_sortedMembers.end(), [&sortSpecs, &provider](PatternData *left, PatternData *right) {
return PatternData::sortPatternDataTable(sortSpecs, provider, left, right);
});
for (auto &member : this->m_members)
member->sort(sortSpecs, provider);
}
std::string getTypeName() override {
return "struct " + this->m_structName;
}
private:
std::string m_structName;
std::vector<PatternData*> m_members;
std::vector<PatternData*> m_sortedMembers;
};
class PatternDataUnion : public PatternData {
public:
PatternDataUnion(u64 offset, size_t size, const std::string &name, const std::string &unionName, const std::vector<PatternData*> & members, u32 color = 0)
: PatternData(Type::Union, offset, size, name, color), m_unionName(unionName), m_members(members), m_sortedMembers(members) { }
void createEntry(prv::Provider* &provider) override {
ImGui::TableNextRow(ImGuiTableRowFlags_Headers);
ImGui::TableNextColumn();
ImGui::ColorButton("color", ImColor(this->getColor()), ImGuiColorEditFlags_NoTooltip | ImGuiColorEditFlags_AlphaPreview);
ImGui::TableNextColumn();
bool open = ImGui::TreeNodeEx(this->getName().c_str(), ImGuiTreeNodeFlags_SpanFullWidth);
ImGui::TableNextColumn();
ImGui::Text("0x%08lx : 0x%08lx", this->getOffset(), this->getOffset() + this->getSize() - 1);
ImGui::TableNextColumn();
ImGui::Text("0x%04lx", this->getSize());
ImGui::TableNextColumn();
ImGui::Text("%s", this->getTypeName().c_str());
ImGui::TableNextColumn();
ImGui::Text("%s", "{ ... }");
if (open) {
for (auto &member : this->m_sortedMembers)
member->createEntry(provider);
ImGui::TreePop();
}
}
std::optional<u32> highlightBytes(size_t offset) override{
for (auto &member : this->m_members) {
if (auto color = member->highlightBytes(offset); color.has_value())
return color.value();
}
return { };
}
void sort(ImGuiTableSortSpecs *sortSpecs, prv::Provider *provider) override {
this->m_sortedMembers = this->m_members;
std::sort(this->m_sortedMembers.begin(), this->m_sortedMembers.end(), [&sortSpecs, &provider](PatternData *left, PatternData *right) {
return PatternData::sortPatternDataTable(sortSpecs, provider, left, right);
});
for (auto &member : this->m_members)
member->sort(sortSpecs, provider);
}
std::string getTypeName() override {
return "union " + this->m_unionName;
}
private:
std::string m_unionName;
std::vector<PatternData*> m_members;
std::vector<PatternData*> m_sortedMembers;
};
class PatternDataEnum : public PatternData {
public:
PatternDataEnum(u64 offset, size_t size, const std::string &name, const std::string &enumName, std::vector<std::pair<u64, std::string>> enumValues, u32 color = 0)
: PatternData(Type::Enum, offset, size, name, color), m_enumName(enumName), m_enumValues(enumValues) { }
void createEntry(prv::Provider* &provider) override {
u64 value = 0;
provider->read(this->getOffset(), &value, this->getSize());
std::string valueString = this->m_enumName + "::";
bool foundValue = false;
for (auto &[entryValue, entryName] : this->m_enumValues) {
if (value == entryValue) {
valueString += entryName;
foundValue = true;
break;
}
}
if (!foundValue)
valueString += "???";
this->createDefaultEntry(hex::format("%s (0x0*lx)", valueString.c_str(), this->getSize() * 2, value));
}
std::string getTypeName() override {
return "enum " + this->m_enumName;
}
private:
std::string m_enumName;
std::vector<std::pair<u64, std::string>> m_enumValues;
};
class PatternDataBitfield : public PatternData {
public:
PatternDataBitfield(u64 offset, size_t size, const std::string &name, const std::string &bitfieldName, std::vector<std::pair<std::string, size_t>> fields, u32 color = 0)
: PatternData(Type::Enum, offset, size, name, color), m_bitfieldName(bitfieldName), m_fields(fields) { }
void createEntry(prv::Provider* &provider) override {
u64 value = 0;
provider->read(this->getOffset(), &value, this->getSize());
ImGui::TableNextRow(ImGuiTableRowFlags_Headers);
ImGui::TableNextColumn();
ImGui::ColorButton("color", ImColor(0x00FFFFFF), ImGuiColorEditFlags_NoTooltip | ImGuiColorEditFlags_AlphaPreview);
ImGui::TableNextColumn();
bool open = ImGui::TreeNodeEx(this->getName().c_str(), ImGuiTreeNodeFlags_SpanFullWidth);
ImGui::TableNextColumn();
ImGui::Text("0x%08lx : 0x%08lx", this->getOffset(), this->getOffset() + this->getSize() - 1);
ImGui::TableNextColumn();
ImGui::Text("0x%04lx", this->getSize());
ImGui::TableNextColumn();
ImGui::Text("%s", this->getTypeName().c_str());
ImGui::TableNextColumn();
ImGui::Text("{ %llx }", value);
if (open) {
u16 bitOffset = 0;
for (auto &[entryName, entrySize] : this->m_fields) {
ImGui::TableNextRow();
ImGui::TreeNodeEx(this->getName().c_str(), ImGuiTreeNodeFlags_Leaf | ImGuiTreeNodeFlags_NoTreePushOnOpen | ImGuiTreeNodeFlags_SpanFullWidth);
ImGui::TableNextColumn();
ImGui::ColorButton("color", ImColor(this->getColor()), ImGuiColorEditFlags_NoTooltip);
ImGui::TableNextColumn();
ImGui::Text("%s", entryName.c_str());
ImGui::TableNextColumn();
ImGui::Text("0x%08lx : 0x%08lx", this->getOffset() + (bitOffset >> 3), this->getOffset() + ((bitOffset + entrySize) >> 3) - 1);
ImGui::TableNextColumn();
if (entrySize == 1)
ImGui::Text("%llu bit", entrySize);
else
ImGui::Text("%llu bits", entrySize);
ImGui::TableNextColumn();
ImGui::Text("%s", entryName.c_str());
ImGui::TableNextColumn();
ImGui::Text("%llx", hex::extract((bitOffset + entrySize) - 1, bitOffset, value));
bitOffset += entrySize;
}
ImGui::TreePop();
}
}
std::string getTypeName() override {
return "bitfield " + this->m_bitfieldName;
}
private:
std::string m_bitfieldName;
std::vector<std::pair<std::string, size_t>> m_fields;
};
}

View File

@@ -1,23 +0,0 @@
#pragma once
#include <hex.hpp>
#include "token.hpp"
#include <string>
#include <utility>
#include <set>
namespace hex::lang {
class Preprocessor {
public:
Preprocessor();
std::pair<Result, std::string> preprocess(const std::string& code, bool applyDefines = true);
private:
std::set<std::pair<std::string, std::string>> m_defines;
};
}

View File

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

View File

@@ -1,14 +0,0 @@
#pragma once
#include "result.hpp"
namespace hex::lang {
constexpr Result ResultSuccess(0, 0);
constexpr Result ResultPreprocessingError(1, 1);
constexpr Result ResultLexicalError(2, 1);
constexpr Result ResultParseError(3, 1);
constexpr Result ResultEvaluatorError(4, 1);
}

View File

@@ -1,66 +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,
Union,
Using,
Enum,
Bitfield
} keyword;
} keywordToken;
struct IdentifierToken {
std::string identifier;
} identifierToken;
struct OperatorToken {
enum class Operator {
AtDeclaration,
Assignment,
Inherit
} 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,
Padding = 0x1F
} type;
} typeToken;
};
}

Some files were not shown because too many files have changed in this diff Show More