Merge branch 'master' of https://github.com/tildearrow/furnace into command-palette

This commit is contained in:
YohananDiamond 2023-09-04 19:32:24 -03:00
commit 5a5090f711
168 changed files with 5101 additions and 1926 deletions

3
.gitmodules vendored
View file

@ -12,3 +12,6 @@
[submodule "extern/adpcm"]
path = extern/adpcm
url = https://github.com/superctr/adpcm
[submodule "extern/portaudio"]
path = extern/portaudio
url = https://github.com/PortAudio/portaudio.git

View file

@ -27,6 +27,7 @@ include(TestBigEndian)
if (ANDROID)
set(USE_RTMIDI_DEFAULT OFF)
set(WITH_PORTAUDIO_DEFAULT OFF)
set(USE_BACKWARD_DEFAULT OFF)
find_library(TERMUX rt)
if (TERMUX)
@ -34,6 +35,7 @@ if (ANDROID)
endif()
else()
set(USE_RTMIDI_DEFAULT ON)
set(WITH_PORTAUDIO_DEFAULT ON)
if (WIN32 OR APPLE)
set(USE_BACKWARD_DEFAULT ON)
else()
@ -78,6 +80,7 @@ option(USE_SDL2 "Build with SDL2. Required to build with GUI." ${USE_SDL2_DEFAUL
option(USE_SNDFILE "Build with libsndfile. Required in order to work with audio files." ${USE_SNDFILE_DEFAULT})
option(USE_BACKWARD "Use backward-cpp to print a backtrace on crash/abort." ${USE_BACKWARD_DEFAULT})
option(WITH_JACK "Whether to build with JACK support. Auto-detects if JACK is available" ${WITH_JACK_DEFAULT})
option(WITH_PORTAUDIO "Whether to build with PortAudio for audio output." ${WITH_PORTAUDIO_DEFAULT})
option(WITH_RENDER_SDL "Whether to build with the SDL_Renderer render backend." ${WITH_RENDER_SDL_DEFAULT})
option(WITH_RENDER_OPENGL "Whether to build with the OpenGL render backend." ${WITH_RENDER_OPENGL_DEFAULT})
option(WITH_RENDER_DX11 "Whether to build with the DirectX 11 render backend." ${WITH_RENDER_DX11_DEFAULT})
@ -85,6 +88,7 @@ option(USE_GLES "Use OpenGL ES for the OpenGL render backend." ${USE_GLES_DEFAUL
option(SYSTEM_FFTW "Use a system-installed version of FFTW instead of the vendored one" OFF)
option(SYSTEM_FMT "Use a system-installed version of fmt instead of the vendored one" OFF)
option(SYSTEM_LIBSNDFILE "Use a system-installed version of libsndfile instead of the vendored one" OFF)
option(SYSTEM_PORTAUDIO "Use a system-installed version of PortAudio instead of the vendored one" OFF)
option(SYSTEM_RTMIDI "Use a system-installed version of RtMidi instead of the vendored one" OFF)
option(SYSTEM_ZLIB "Use a system-installed version of zlib instead of the vendored one" OFF)
option(SYSTEM_SDL2 "Use a system-installed version of SDL2 instead of the vendored one" ${SYSTEM_SDL2_DEFAULT})
@ -204,6 +208,27 @@ else()
message(STATUS "Not using libsndfile")
endif()
if (WITH_PORTAUDIO)
if (SYSTEM_PORTAUDIO)
find_package(PkgConfig REQUIRED)
pkg_check_modules(PORTAUDIO REQUIRED portaudio)
list(APPEND DEPENDENCIES_INCLUDE_DIRS ${PORTAUDIO_INCLUDE_DIRS})
list(APPEND DEPENDENCIES_COMPILE_OPTIONS ${PORTAUDIO_CFLAGS_OTHER})
list(APPEND DEPENDENCIES_LIBRARIES ${PORTAUDIO_LIBRARIES})
list(APPEND DEPENDENCIES_LIBRARY_DIRS ${PORTAUDIO_LIBRARY_DIRS})
list(APPEND DEPENDENCIES_LINK_OPTIONS ${PORTAUDIO_LDFLAGS_OTHER})
list(APPEND DEPENDENCIES_LEGACY_LDFLAGS ${PORTAUDIO_LDFLAGS})
message(STATUS "Using system-installed PortAudio")
else()
set(PA_BUILD_SHARED_LIBS OFF CACHE BOOL "Build dynamic library" FORCE)
# don't - Furnace has its own implementation
set(PA_USE_JACK OFF CACHE BOOL "Enable support for JACK Audio Connection Kit" FORCE)
add_subdirectory(extern/portaudio EXCLUDE_FROM_ALL)
list(APPEND DEPENDENCIES_LIBRARIES PortAudio)
message(STATUS "Using vendored PortAudio")
endif()
endif()
if (USE_RTMIDI)
if (SYSTEM_RTMIDI)
find_package(PkgConfig REQUIRED)
@ -345,6 +370,14 @@ else()
message(STATUS "Building without JACK support")
endif()
if (WITH_PORTAUDIO)
list(APPEND AUDIO_SOURCES src/audio/pa.cpp)
message(STATUS "Building with PortAudio")
list(APPEND DEPENDENCIES_DEFINES HAVE_PA)
else()
message(STATUS "Building without PortAudio")
endif()
if (USE_RTMIDI)
list(APPEND AUDIO_SOURCES src/audio/rtmidi.cpp)
message(STATUS "Building with RtMidi")
@ -507,7 +540,7 @@ src/engine/platform/sound/d65modified.c
src/engine/platform/sound/ted-sound.c
src/engine/platform/sound/c140.c
src/engine/platform/sound/c140_c219.c
src/engine/platform/oplAInterface.cpp
src/engine/platform/ym2608Interface.cpp

View file

@ -252,6 +252,7 @@ Available options:
| `USE_SNDFILE` | `ON` | Build with libsndfile (required in order to work with audio files) |
| `USE_BACKWARD` | `ON` | Use backward-cpp to print a backtrace on crash/abort |
| `WITH_JACK` | `ON` if system-installed JACK detected, otherwise `OFF` | Whether to build with JACK support. Auto-detects if JACK is available |
| `WITH_PORTAUDIO` | `ON` | Whether to build with PortAudio. |
| `SYSTEM_FFTW` | `OFF` | Use a system-installed version of FFTW instead of the vendored one |
| `SYSTEM_FMT` | `OFF` | Use a system-installed version of fmt instead of the vendored one |
| `SYSTEM_LIBSNDFILE` | `OFF` | Use a system-installed version of libsndfile instead of the vendored one |

View file

@ -15,22 +15,22 @@ The **[pattern view](../3-pattern/README.md)** is like a spreadsheet that displa
## structure
The **order list** is a smaller spreadsheet showing the overall song structure.
- A song is made up of a list of **orders**.
- An **order** is a set of numbered **patterns** used for each channel.
- A song is made up of a list of orders.
- An **order** is a set of numbered patterns used for each channel.
- Each channel has its own unique list of patterns.
- Each pattern contains note and effect data for that channel only.
- Each **pattern** contains note and effect data for that channel only.
- Patterns may be used multiple times in the order list. Changing a pattern's data in one order will affect the same pattern used in other orders.
## time
- Each pattern is made of the same number of **rows** as seen in the tracker view.
- During playback, Each row lasts a number of **ticks** determined by its **speed** value.
- A tick is the smallest measure of time to which all note, effect, and macro times are quantized.
- Each pattern is made of the same number of rows as seen in the tracker view.
- During playback, each **row** lasts a number of ticks determined by its **speed** value.
- A **tick** is the smallest measure of time to which all note, effect, and macro times are quantized.
## sound
Different chips have different capabilities. Even within the same chip, each channel may have its own ways of making sound.
- Some channels use one or more waveform **generators** (sine, square, noise...) to build up a sound.
- Of special note are **[FM (frequency modulation)](../4-instrument/fm.md)** channels, which use a number of generators called **operators** that can interact to make very complex sounds.
- Some channels use **[samples](../6-sample/README.md)** - recordings of sounds, often with defined loop points to allow a note to sustain.
- Some channels use **[samples](../6-sample/README.md)** which are recordings of sounds, often with defined loop points to allow a note to sustain.
- Some channels use **[wavetables](../5-wave/README.md)**, which are like very short samples of fixed length that automatically loop.

View file

@ -3,10 +3,20 @@
![instruments window](instruments.png)
Buttons from left to right:
- **Add**: Creates a new, default instrument.
- **Add**: pops up a menu to select which type of instrument to add. if only one instrument type is available, the menu is skipped.
- If the "Display instrument type menu when adding instrument" setting is disabled, this skips the menu and creates an instrument according to the chip under the cursor.
- Right-clicking always brings up the menu.
- **Duplicate**: Duplicates the currently selected instrument.
- **Open**: Brings up a file dialog to load a file as a new instrument at the end of the list.
- **Save**: Brings up a file dialog to save the currently selected instrument.
- **Save**: Brings up a file dialog to save the currently selected asset.
- Instruments are saved as Furnace instrument (.fui) files.
- Wavetables are saved as Furnace wavetable (.fuw) files.
- Samples are saved as standard wave (.wav) files.
- Right-clicking brings up a menu with the applicable items from this list:
- **save instrument as .dmp...**: saves the selected instrument in DefleMask format.
- **save wavetable as .dmw...**: saves the selected wavetable in DefleMask format.
- **save raw wavetable...**: saves the selected wavetable as raw data.
- **save raw sample...**: saves the selected sample as raw data.
- **Toggle folders/standard view**: Enables (and disables) folder view, explained below.
- **Move up**: Moves the currently selected instrument up in the list. Pattern data will automatically be adjusted to match.
- **Move down**: Same, but downward.
@ -33,6 +43,6 @@ Everything from the instrument list applies here also, with one major difference
![samples window](samples.png)
Everything from the wavetables list applies here also, with the addition of two buttons before the Delete button:
Everything from the wavetables list applies here also, with the addition of one button before the Delete button:
- **Preview**: Plays the selected sample at its default note.
- **Stop preview**: Stops the sample playback.
- Right-clicking stops the sample playback.

View file

@ -1,15 +1,256 @@
# global keyboard shortcuts
# keyboard
this is a list of available shortcuts that may be used at any time, regardless of currently focused window.
everything on this list can be configured in the "Keyboard" tab of the Settings dialog:
- click on a keybind then enter a key or key combination to change it.
- right-click to clear the keybind.
key | action
-----------|-----------------------
Ctrl-O | open file
Ctrl-S | save file
Enter | play/stop song
F5/F6 | "
Shift-Enter| play from cursor position
F7 | "
Ctrl-Enter | play one row
NumPad `/` | decrease octave
NumPad `*` | increase octave
the keys in the "Global hotkeys" section can be used in any window, though not within text boxes.
| action | default keybind |
|--------------------------------------------------------|------------------|
| **Global hotkeys** | |
| New | `Ctrl-N` |
| Clear song data | — |
| Open file | `Ctrl-O` |
| Restore backup | — |
| Save file | `Ctrl-S` |
| Save as | `Ctrl-Shift-S` |
| Undo | `Ctrl-Z` |
| Redo | `Ctrl-Y` |
| Play/Stop (toggle) | `Return` |
| Play | — |
| Stop | — |
| Play (from beginning) | `F5` |
| Play (repeat pattern) | — |
| Play from cursor | `Shift-Return` |
| Step row | `Ctrl-Return` |
| Octave up | `Keypad *` |
| Octave down | `Keypad /` |
| Previous instrument | `Shift-Keypad /` |
| Next instrument | `Shift-Keypad *` |
| Increase edit step | `Ctrl-Keypad *` |
| Decrease edit step | `Ctrl-Keypad /` |
| Toggle edit mode | `Space` |
| Metronome | `Ctrl-M` |
| Toggle repeat pattern | — |
| Follow orders | — |
| Follow pattern | — |
| Toggle full-screen | `F11` |
| Request voice from TX81Z | — |
| Panic | `F12` |
| | |
| **Window activation** | |
| Find/Replace | Ctrl-F |
| Settings | — |
| Song Information | — |
| Subsongs | — |
| Speed | — |
| Instrument List | — |
| Wavetable List | — |
| Sample List | — |
| Orders | — |
| Pattern | — |
| Mixer | — |
| Grooves | — |
| Channels | — |
| Pattern Manager | — |
| Chip Manager | — |
| Compatibility Flags | — |
| Song Comments | — |
| Instrument Editor | — |
| Wavetable Editor | — |
| Sample Editor | — |
| Edit Controls | — |
| Piano | — |
| Oscilloscope (master) | — |
| Oscilloscope (per-channel) | — |
| Volume Meter | — |
| Clock | — |
| Register View | — |
| Log Viewer | — |
| Statistics | — |
| Effect List | — |
| Debug Menu | `Ctrl-Shift-D` |
| About | — |
| Collapse/expand current window | — |
| Close current window | `Shift-Escape` |
| | |
| **Note input** | |
| _see "note input" section after table_ | |
| | |
| **Pattern** | |
| Transpose (+1) | `Ctrl-F2` |
| Transpose (-1) | `Ctrl-F1` |
| Transpose (+1 octave) | `Ctrl-F4` |
| Transpose (-1 octave) | `Ctrl-F3` |
| Increase values (+1) | `Ctrl-Shift-F2` |
| Increase values (-1) | `Ctrl-Shift-F1` |
| Increase values (+16) | `Ctrl-Shift-F4` |
| Increase values (-16) | `Ctrl-Shift-F3` |
| Select all | `Ctrl-A` |
| Cut | `Ctrl-X` |
| Copy | `Ctrl-C` |
| Paste | `Ctrl-V` |
| Paste Mix (foreground) | `Ctrl-Shift-V` |
| Paste Mix (background) | — |
| Paste Flood | — |
| Paste Overflow | — |
| Move cursor up | `Up` |
| Move cursor down | `Down` |
| Move cursor left | `Left` |
| Move cursor right | `Right` |
| Move cursor up by one (override Edit Step) | `Shift-Home` |
| Move cursor down by one (override Edit Step) | `Shift-End` |
| Move cursor to previous channel | — |
| Move cursor to next channel | — |
| Move cursor to next channel (overflow) | — |
| Move cursor to previous channel (overflow) | — |
| Move cursor to beginning of pattern | `Home` |
| Move cursor to end of pattern | `End` |
| Move cursor up (coarse) | `PageUp` |
| Move cursor down (coarse) | `PageDown` |
| Expand selection upwards | `Shift-Up` |
| Expand selection downwards | `Shift-Down` |
| Expand selection to the left | `Shift-Left` |
| Expand selection to the right | `Shift-Right` |
| Expand selection upwards by one (override Edit Step) | — |
| Expand selection downwards by one (override Edit Step) | — |
| Expand selection to beginning of pattern | — |
| Expand selection to end of pattern | — |
| Expand selection upwards (coarse) | `Shift-PageUp` |
| Expand selection downwards (coarse) | `Shift-PageDown` |
| Delete | `Delete` |
| Pull delete | `Backspace` |
| Insert | `Insert` |
| Mute channel at cursor | `Alt-F9` |
| Solo channel at cursor | `Alt-F10` |
| Unmute all channels | `Alt-Shift-F9` |
| Go to next order | — |
| Go to previous order | — |
| Collapse channel at cursor | — |
| Increase effect columns | — |
| Decrease effect columns | — |
| Interpolate | — |
| Fade | — |
| Invert values | — |
| Flip selection | — |
| Collapse rows | — |
| Expand rows | — |
| Collapse pattern | — |
| Expand pattern | — |
| Collapse song | — |
| Expand song | — |
| Set note input latch | — |
| Clear note input latch | — |
| | |
| **Instrument list** | |
| Add | `Insert` |
| Duplicate | `Ctrl-D` |
| Open | — |
| Open (replace current) | — |
| Save | — |
| Save (.dmp) | — |
| Move up | `Shift-Up` |
| Move down | `Shift-Down` |
| Delete | — |
| Edit | `Shift-Return` |
| Cursor up | `Up` |
| Cursor down | `Down` |
| Toggle folders/standard view | `Ctrl-V` |
| | |
| **Wavetable list** | |
| Add | `Insert` |
| Duplicate | `Ctrl-D` |
| Open | — |
| Open (replace current) | — |
| Save | — |
| Save (.dmw) | — |
| Save (raw) | — |
| Move up | `Shift-Up` |
| Move down | `Shift-Down` |
| Delete | — |
| Edit | `Shift-Return` |
| Cursor up | `Up` |
| Cursor down | `Down` |
| Toggle folders/standard view | `Ctrl-V` |
| | |
| **Sample list** | |
| Add | `Insert` |
| Duplicate | `Ctrl-D` |
| Create wavetable from selection | `Ctrl-W` |
| Open | — |
| Open (replace current) | — |
| Import raw data | — |
| Import raw data (replace current) | — |
| Save | — |
| Save (raw) | — |
| Move up | `Shift-Up` |
| Move down | `Shift-Down` |
| Delete | — |
| Edit | `Shift-Return` |
| Cursor up | `Up` |
| Cursor down | `Down` |
| Preview | — |
| Stop preview | — |
| Toggle folders/standard view | `Ctrl-V` |
| | |
| **Orders** | |
| Previous order | `Up` |
| Next order | `Down` |
| Cursor left | `Left` |
| Cursor right | `Right` |
| Increase value | — |
| Decrease value | — |
| Switch edit mode | — |
| Toggle alter entire row | `Ctrl-L` |
| Add | `Insert` |
| Duplicate | `Ctrl-D` |
| Deep clone | `Ctrl-Shift-D` |
| Duplicate to end of song | `Ctrl-E` |
| Deep clone to end of song | `Ctrl-Shift-E` |
| Remove | `Delete` |
| Move up | `Shift-Up` |
| Move down | `Shift-Down` |
| Replay | — |
| | |
| **Sample editor** | |
| Edit mode: Select | `Shift-I` |
| Edit mode: Draw | `Shift-D` |
| Cut | `Ctrl-X` |
| Copy | `Ctrl-C` |
| Paste | `Ctrl-V` |
| Paste replace | `Ctrl-Shift-V` |
| Paste mix | `Ctrl-Alt-V` |
| Select all | `Ctrl-A` |
| Resize | `Ctrl-R` |
| Resample | `Ctrl-E` |
| Amplify | `Ctrl-B` |
| Normalize | `Ctrl-N` |
| Fade in | `Ctrl-I` |
| Fade out | `Ctrl-O` |
| Insert silence | `Insert` |
| Apply silence | `Shift-Delete` |
| Delete | `Delete` |
| Trim | `Ctrl-Delete` |
| Reverse | `Ctrl-T` |
| Invert | `Ctrl-Shift-T` |
| Signed/unsigned exchange | `Ctrl-U` |
| Apply filter | `Ctrl-F` |
| Preview sample | — |
| Stop sample preview | — |
| Zoom in | `Ctrl-=` |
| Zoom out | `Ctrl--` |
| Toggle auto-zoom | `Ctrl-0` |
| Create instrument from sample | — |
| Set loop to selection | `Ctrl-l` |
## note input
the settings for note input keybinds operate differently. each entry in the list of keybinds is made of the following:
- **Key**: key assignment.
- **Type**: type of note input. left-click cycles through "Note", "Note off", "Note release", and "Macro release".
- _note:_ the list is sorted by type. on changing a key's type, it will instantly move to its new sorting position!
- **Value**: number of semitones above C at the current octave. only appears for note type binds.
- **Remove**: removes the keybind from the list.
below all the binds, select a key from the dropdown list to add it. it will appear at or near the top of the list as a note with value 0.

View file

@ -6,10 +6,10 @@ items in _italics_ don't appear in basic mode and are only available in advanced
# file
- **new...**: create a new song.
- **new...**: creates a new song.
- **open...**: opens the file picker, allowing you to select a song to open.
- **open recent**: contains a list of the songs you've opened before.
- **clear history**: this option erases the file history.
- **clear history**: erases the file history.
- **save**: saves the current song.
- opens the file picker if this is a new song, or a backup.
@ -33,22 +33,16 @@ items in _italics_ don't appear in basic mode and are only available in advanced
- Neo Geo CD (DefleMask 1.0+)
- only use this option if you really need it. there are features which DefleMask does not support, like some effects and FM macros, so these will be lost.
- **export audio...**: export your song to a .wav file. see next section for more details.
- **export VGM...**: export your song to a .vgm file. see next section for more details.
- **export ZSM...**: export your song to a .zsm file. see next section for more details.
- **export audio...**: opens the file picker, allowing you to export your song to a .wav file. see next section for more details.
- **export VGM...**: opens the file picker, allowing you to export your song to a .vgm file. see next section for more details.
- **export ZSM...**: opens the file picker, allowing you to export your song to a .zsm file. see next section for more details.
- only available when there's a YM2151 and/or VERA.
- **export command stream...**: export song data to a command stream file. see next section for more details.
- this option is for developers.
- _**add chip...**:_ add a chip to the current song.
- _**configure chip...**:_ set a chip's parameters.
- for a list of parameters, see [7-systems](../7-systems/README.md).
- _**change chip...**:_ change a chip to another.
- **Preserve channel positions**: enable this option to make sure Furnace does not auto-arrange/delete channels to compensate for differing channel counts. this can be useful for doing ports, e.g. from Genesis to PC-98.
- _**remove chip...**_: remove a chip.
- **Preserve channel positions**: same thing as above.
- **manage chips**: opens the [Chip Manager](../8-advanced/chip-manager.md) dialog.
- **restore backup**: restore a previously saved backup.
- **restore backup**: restores a previously saved backup.
- Furnace keeps up to 5 backups of a song.
- the backup directory is located in:
- Windows: `%USERPROFILE%\AppData\Roaming\furnace\backups`
@ -87,8 +81,8 @@ the following settings exist:
- other versions may not support all chips.
- use this option if you need to export for a quirky player or parser.
- for example, RYMCast is picky with format versions. if you're going to use this player, select 1.60.
- **loop**: writes loop. if disabled, the resulting file won't loop.
- **loop trail**: this option allows you to set how much of the song is written after it loops.
- **loop**: includes loop information. if disabled, the resulting file won't loop.
- **loop trail**: sets how much of the song is written after it loops.
- the reason this exists is to work around a VGM format limitation in where post-loop state isn't recorded at all.
- this may change the song length as it appears on a player.
- **auto-detect**: detect how much to write automatically.
@ -137,6 +131,8 @@ it's not really useful, unless you're a developer and want to use a command stre
# edit
- **...**: does nothing except prevent accidental clicks on later menu items if the menu is too tall to fit on the program window.
- **undo**: reverts the last action.
- **redo**: repeats what you undid previously.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 72 KiB

After

Width:  |  Height:  |  Size: 80 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 44 KiB

After

Width:  |  Height:  |  Size: 42 KiB

View file

@ -66,17 +66,31 @@ settings are saved when clicking the **OK** or **Apply** buttons at the bottom o
### Output
- **Backend**: selects SDL or JACK for audio output.
- only appears on Linux, or MacOS compiled with JACK support
- **Driver**: select a different SDL audio driver if you're having problems with the default one.
- **Backend**: selects a different backend for audio output.
- SDL: the default one.
- JACK: the JACK Audio Connection Kit (low-latency audio server). only appears on Linux, or MacOS compiled with JACK support.
- PortAudio: this may or may not perform better than the SDL backend.
- **Driver**: select a different audio driver if you're having problems with the default one.
- only appears when Backend is SDL.
- **Device**: audio device for playback.
- **Sample rate**
- if using PortAudio backend, devices will be prefixed with the audio API that PortAudio is going to use:
- Windows WASAPI: a modern audio API available on Windows Vista and later, featuring an (optional) Exclusive Mode. be noted that your buffer size setting may be ignored.
- Windows WDM-KS: low-latency, direct to hardware output mechanism. may not work all the time and prevents your audio device from being used for anything else!
- Windows DirectSound: this is the worst choice. best to move on.
- MME: an old audio API. doesn't have Exclusive Mode.
- Core Audio: the only choice in macOS.
- ALSA: low-level audio output on Linux. may prevent other applications from using your audio device.
- **Sample rate**: audio output rate.
- a lower rate decreases quality and isn't really beneficial.
- if using PortAudio backend, be careful about this value.
- **Outputs**: number of audio outputs created, up to 16.
- only appears when Backend is JACK.
- **Channels**: number of output channels to use.
- **Channels**: mono, stereo or something.
- **Buffer size**: size of buffer in both samples and milliseconds.
- setting this to a low value may cause stuttering/glitches in playback (known as "underruns" or "xruns").
- setting this to a high value increases latency.
- **Exclusive mode**: enables Exclusive Mode, which may offer latency improvements.
- only available on WASAPI devices in the PortAudio backend!
- **Low-latency mode (experimental!)**: reduces latency by running the engine faster than the tick rate. useful for live playback/jam mode.
- only enable if your buffer size is small (10ms or less).
- **Force mono audio**: use if you're unable to hear stereo audio (e.g. single speaker or hearing loss in one ear).
@ -88,6 +102,7 @@ settings are saved when clicking the **OK** or **Apply** buttons at the bottom o
- **Quality**: selects quality of resampling. low quality reduces CPU load by a small amount.
- **Software clipping**: clips output to nominal range (-1.0 to 1.0) before passing it to the audio device.
- this avoids activating Windows' built-in limiter.
- this option shall be enabled when using PortAudio backend with a DirectSound device.
### Metronome
@ -193,7 +208,7 @@ settings are saved when clicking the **OK** or **Apply** buttons at the bottom o
- **Import**
- **Export**
- **Reset defaults**
- several categories of keybinds...
- [grouped list of keybinds...](keyboard.md)
- click on a keybind then enter a key or key combination to change it
- right-click to clear the keybind
@ -327,6 +342,7 @@ settings are saved when clicking the **OK** or **Apply** buttons at the bottom o
- **Cursor details or file path**
- **Nothing**
- **Capitalize menu bar**
- **Display add/configure/change/remove chip menus in File menu**: if enabled, the "manage chips" item in the file menu is split into the four listed items for quick access.
### Orders

View file

@ -50,8 +50,9 @@ The very first numeric entry sets the visible width of the bars in sequence-type
Each macro has two buttons on the left.
- Macro type (explained below).
- Timing editor, which pops up a small dialog:
- Step Length (ticks): Determines how many ticks pass before each change of value.
- Delay: Delays the start of the macro until this many ticks have passed.
- Step Length (ticks): Determines how many ticks pass before each change of value. Default is 1.
- Delay: Delays the start of the macro until this many ticks have passed. Default is 0.
- The button is highlighted if either of these is set differently from default.
## macro types
@ -113,7 +114,7 @@ This tab appears for PC Engine, FDS, Namco WSG, and other wavetable-based instru
![wavetable tab](wavetable.png)
When **Enable synthesizer** is off, the only option is to select a wavetable entry with the text entry box beneath the **Wave 1** preview.
When **Enable synthesizer** is off, the wavetable used for the instrument may be selected by creating a Waveform macro with a single value.
To use the wavetable synthesizer, refer to the bottom part of [the wavetable documentation](../5-wave/README.md).

View file

@ -15,14 +15,17 @@ The OPLL synthesizer is two-operator, meaning it takes two oscillators to produc
These apply to the instrument as a whole:
- **Feedback (FB)**: Determines how many times operator 1 returns its output to itself. (0-7 range)
- **Sustain (SUS)**: enables the sustain flag (sets the release rate to 5)
- algorithm: shows the connection of operators (though they are always connected the same way).
- Right-click to switch to a preview display of the waveform generated on a new note:
- Left-click restarts the preview.
- Middle-click pauses and unpauses the preview.
- Right-click returns to algorithm view.
- **DC (half-sine carrier)**: Sets the waveform produced by carrier operator to half-sine
- **DM (half-sine modulator)**: Sets the waveform produced by modulator operator to half-sine
To the right, there is a drop down menu for OPLL preset instrument selection.
- preset dropdown: selects OPLL preset instrument.
These apply to each operator:
- The crossed-arrows button can be dragged to rearrange operators.
- The **OP1**, **OP2** buttons enable or disable those operators.
- **Amplitude Modulation (AM)**: Makes the operator affected by LFO tremolo.
- **Envelope generator sustain flag (EGS)**: When enabled, value of Sustain Level is in effect.
- **Attack Rate (AR)**: determines the rising time for the sound. The bigger the value, the faster the attack. (0-15 range)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 31 KiB

View file

@ -19,7 +19,15 @@ these tabs are unique to the editor for SNES instruments.
- **Effective (exponential decrease)**: after release, volume decays exponentially. see [gain chart](../7-systems/snes.md).
- **Delayed (write R on release)**: after release, waits until A and D have completed before starting exponential decrease.
if envelope is off, select gain mode as described below.
if envelope is off:
- **Gain Mode**: selects gain mode.
- **Direct**: direct gain from 0 to 127
- **Decrease (linear)**: linear gain from -0 to -31
- **Decrease (logarithmic)**: exponential gain from -0 to -31
- **Increase (linear)**: linear gain from +0 to +31
- **Increase (bent line)**: exponential gain from +0 to +31
- _note:_ using decrease modes will not produce any sound unless a Gain macro is set. The first tick must be the initial gain, and the second tick must be the decrease gain value. gain values are as described in the Macros section below.
- **Gain**: value of gain.

View file

@ -27,8 +27,11 @@ Amiga | ≤256 | 256 |
controls across the top line:
- waveform number. the `-` and `+` buttons step through the list.
- open.
- save.
- open. opens a file selector to choose the file to open.
- save. opens a file selector to choose the file to save to.
- right-clicking brings up a menu:
- **save as .dmw...**: saves the selected wavetable in DefleMask format.
- **save raw...**: saves the selected wavetable as raw data.
- **Steps**: view waveform as discrete blocks.
- **Lines**: view waveform as a continuous line.
- **Width**: length of the waveform data. maximum is 256.
@ -84,6 +87,7 @@ these are useful editing tools to fine-tune the waveform:
- **Amplify**. changes the volume of the waveform. it will clip at the top and bottom.
- **Normalize**: stretches waveform to maximum within the wavetable height.
- **Invert**: flips waveform vertically.
- **Reverse**: flips waveform horizontally.
- **Half**: halves the waveform's frequency by stretching its first half to fill the waveform length.
- **Double**: doubles the waveform's frequency by squashing it to half length then repeating it.
- **Convert Signed/Unsigned**. worth trying if an imported wave sounds corrupted.
@ -107,6 +111,7 @@ input waveforms should match the size of the wavetable or unexpected results may
- synthesizer type: selects the synthesis algorithm.
- waveform displays.
- **Wave 1**: selects input waveform.
- this will turn yellow to indicate that a Waveform macro is set.
- **Wave 2**: selects second input waveform. only appears when a dual-waveform synthesizer is selected.
- **Pause preview**: toggles live waveform preview.
- **Restart preview**: restarts preview from initial state.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 96 KiB

After

Width:  |  Height:  |  Size: 94 KiB

View file

@ -46,7 +46,7 @@ if you need to use more samples, you may change the sample bank using effect `EB
due to limitations in some of those sound chips, some restrictions exist:
- Amiga: maximum frequency is 31,469Hz, but anything over 28,867 will sound glitchy on hardware. sample lengths and loop will be set to an even number, and your sample can't be longer than 131070.
- Amiga: maximum frequency is 31469Hz, but anything over 28867 will sound glitchy on hardware. sample lengths and loop will be set to an even number, and your sample can't be longer than 131070.
- NES: if on DPCM mode, only a limited selection of frequencies is available, and loop position isn't supported (only entire sample).
- SegaPCM: your sample can't be longer than 65535, and the maximum frequency is 31.25KHz.
- QSound: your sample can't be longer than 65535, and the loop length shall not be greater than 32767.
@ -75,11 +75,16 @@ in there, you can modify certain data pertaining to your sample, such as the:
- top-left drop-down box: sample slot.
- **Open**: replaces current sample.
- Right-clicking brings up a menu:
- **import raw...**: brings up a file selector, then presents a dialog to choose the format of the selected file.
- **Save**: saves current sample to disk.
- Right-clicking brings up a menu:
- **save raw...**: brings up a file selector, then saves the sample as raw data.
- **Name**: name in sample list.
- button to left of **Info**: collapses and expands the info bar.
- **Type**: sample format. only 8-bit and 16-bit PCM samples are editable. selecting a format converts the sample data.
- **BRR emphasis**: boosts higher frequencies to compensate for the SNES low-pass filter. should not be enabled for BRR-type samples.
- **BRR emphasis**: boosts higher frequencies to compensate for the SNES low-pass filter. should not be enabled for BRR-type samples. only appears when applicable.
- **8-bit dither**: applies dithering to samples meant to play back at 8-bit resolution. only appears when applicable.
- **Rate**: switches to normal rate values.
- **Compat Rate**: switches to DefleMask-compatible rate values for sample mapping.

View file

@ -184,7 +184,7 @@ this chip uses the [TIA](../4-instrument/tia.md) instrument editor.
| 30 | 32.7 | C-1 | 0.0 | 32.5 | C-1 | -11
| 31 | 31.7 | B-0 | +44 | 31.5 | B-0 | +33
## shapes 8
## shape 8
| pitch | NTSC | note | cent | PAL | note | cent
|------:|--------:|:----:|-----:|--------:|:----:|-----:

View file

@ -2,7 +2,7 @@
![comments dialog](comments.png)
Comments, credits, or any arbitrary text may be entered here.
Comments, credits, or any arbitrary text may be entered here.\
It has no effect on the song.
There is no word wrap; long lines must be broken manually with the Enter key.

View file

@ -29,10 +29,5 @@ Key layout:
- **Standard**: Black keys are 2/3 length.
- **Continuous**: Black keys are full length.
Value input pad: (document this)
- **Disabled**
- **Replace piano**
- **Split (automatic)**
- **Split (always visible)**
**Share play/edit offset/range**: (document this)
**Share play/edit offset/range**: If disabled, the piano will keep different octave and range values for playback and non-playback states.
**Read-only (can't input notes): Prevents note entry.

View file

@ -720,6 +720,7 @@ namespace IGFD
auto arr = IGFD::Utils::SplitStringToVector(fs, ',', false);
for (auto a : arr)
{
infos.firstFilter=a;
infos.collectionfilters.emplace(a);
}
}
@ -1048,7 +1049,7 @@ namespace IGFD
// check if current file extention is covered by current filter
// we do that here, for avoid doing that during filelist display
// for better fps
if (prSelectedFilter.exist(vTag) || prSelectedFilter.filter == ".*")
if (prSelectedFilter.exist(vTag) || prSelectedFilter.firstFilter == ".*")
{
return true;
}

View file

@ -745,6 +745,7 @@ namespace IGFD
{
public:
std::string filter;
std::string firstFilter;
std::set<std::string> collectionfilters;
public:

View file

@ -1,5 +1,10 @@
# modified version
this is a modified version of Dear ImGui to fix UI scaling on macOS, which works in a really weird (but logical) way.
this is a modified version of Dear ImGui (docking branch) to suit Furnace.
the following changes have been made:
further modifications may be made to suit Furnace.
- fix UI scaling on macOS, Wayland and any other platform where HiDPI is implemented through logical pixels
- gradients on frames
- improved touch support (inertial scrolling in particular)
- disable text input undo/redo by default
- add ability to lock dockspace

View file

@ -47,10 +47,11 @@
// 2018-02-06: Misc: Removed call to ImGui::Shutdown() which is not available from 1.60 WIP, user needs to call CreateContext/DestroyContext themselves.
// 2018-02-06: Inputs: Added mapping for ImGuiKey_Space.
#include "imgui.h"
#ifndef IMGUI_DISABLE
#include "imgui_impl_allegro5.h"
#include <stdint.h> // uint64_t
#include <cstring> // memcpy
#include "imgui.h"
#include "imgui_impl_allegro5.h"
// Allegro
#include <allegro5/allegro.h>
@ -603,3 +604,7 @@ void ImGui_ImplAllegro5_NewFrame()
// Setup mouse cursor shape
ImGui_ImplAllegro5_UpdateMouseCursor();
}
//-----------------------------------------------------------------------------
#endif // #ifndef IMGUI_DISABLE

View file

@ -17,6 +17,7 @@
#pragma once
#include "imgui.h" // IMGUI_IMPL_API
#ifndef IMGUI_DISABLE
struct ALLEGRO_DISPLAY;
union ALLEGRO_EVENT;
@ -30,3 +31,5 @@ IMGUI_IMPL_API bool ImGui_ImplAllegro5_ProcessEvent(ALLEGRO_EVENT* event);
// Use if you want to reset your rendering device without losing Dear ImGui state.
IMGUI_IMPL_API bool ImGui_ImplAllegro5_CreateDeviceObjects();
IMGUI_IMPL_API void ImGui_ImplAllegro5_InvalidateDeviceObjects();
#endif // #ifndef IMGUI_DISABLE

View file

@ -27,6 +27,7 @@
// 2021-03-04: Initial version.
#include "imgui.h"
#ifndef IMGUI_DISABLE
#include "imgui_impl_android.h"
#include <time.h>
#include <android/native_window.h>
@ -294,3 +295,7 @@ void ImGui_ImplAndroid_NewFrame()
io.DeltaTime = g_Time > 0.0 ? (float)(current_time - g_Time) : (float)(1.0f / 60.0f);
g_Time = current_time;
}
//-----------------------------------------------------------------------------
#endif // #ifndef IMGUI_DISABLE

View file

@ -19,6 +19,8 @@
// Read online: https://github.com/ocornut/imgui/tree/master/docs
#pragma once
#include "imgui.h" // IMGUI_IMPL_API
#ifndef IMGUI_DISABLE
struct ANativeWindow;
struct AInputEvent;
@ -27,3 +29,5 @@ IMGUI_IMPL_API bool ImGui_ImplAndroid_Init(ANativeWindow* window);
IMGUI_IMPL_API int32_t ImGui_ImplAndroid_HandleInputEvent(AInputEvent* input_event);
IMGUI_IMPL_API void ImGui_ImplAndroid_Shutdown();
IMGUI_IMPL_API void ImGui_ImplAndroid_NewFrame();
#endif // #ifndef IMGUI_DISABLE

View file

@ -32,6 +32,7 @@
// 2016-05-07: DirectX10: Disabling depth-write.
#include "imgui.h"
#ifndef IMGUI_DISABLE
#include "imgui_impl_dx10.h"
// DirectX
@ -713,3 +714,6 @@ void ImGui_ImplDX10_ShutdownPlatformInterface()
ImGui::DestroyPlatformWindows();
}
//-----------------------------------------------------------------------------
#endif // #ifndef IMGUI_DISABLE

View file

@ -13,6 +13,7 @@
#pragma once
#include "imgui.h" // IMGUI_IMPL_API
#ifndef IMGUI_DISABLE
struct ID3D10Device;
@ -24,3 +25,5 @@ IMGUI_IMPL_API void ImGui_ImplDX10_RenderDrawData(ImDrawData* draw_data);
// Use if you want to reset your rendering device without losing Dear ImGui state.
IMGUI_IMPL_API void ImGui_ImplDX10_InvalidateDeviceObjects();
IMGUI_IMPL_API bool ImGui_ImplDX10_CreateDeviceObjects();
#endif // #ifndef IMGUI_DISABLE

View file

@ -35,6 +35,7 @@
// DISCLAIMER: modified with d3dcompiler patch (see https://github.com/ocornut/imgui/pull/638).
#include "imgui.h"
#ifndef IMGUI_DISABLE
#include "imgui_impl_dx11.h"
// DirectX
@ -747,3 +748,7 @@ static void ImGui_ImplDX11_ShutdownPlatformInterface()
{
ImGui::DestroyPlatformWindows();
}
//-----------------------------------------------------------------------------
#endif // #ifndef IMGUI_DISABLE

View file

@ -13,6 +13,7 @@
#pragma once
#include "imgui.h" // IMGUI_IMPL_API
#ifndef IMGUI_DISABLE
struct ID3D11Device;
struct ID3D11DeviceContext;
@ -25,3 +26,5 @@ IMGUI_IMPL_API void ImGui_ImplDX11_RenderDrawData(ImDrawData* draw_data);
// Use if you want to reset your rendering device without losing Dear ImGui state.
IMGUI_IMPL_API void ImGui_ImplDX11_InvalidateDeviceObjects();
IMGUI_IMPL_API bool ImGui_ImplDX11_CreateDeviceObjects();
#endif // #ifndef IMGUI_DISABLE

View file

@ -42,6 +42,7 @@
// 2018-02-22: Merged into master with all Win32 code synchronized to other examples.
#include "imgui.h"
#ifndef IMGUI_DISABLE
#include "imgui_impl_dx12.h"
// DirectX
@ -1074,3 +1075,7 @@ void ImGui_ImplDX12_ShutdownPlatformInterface()
{
ImGui::DestroyPlatformWindows();
}
//-----------------------------------------------------------------------------
#endif // #ifndef IMGUI_DISABLE

View file

@ -16,6 +16,7 @@
#pragma once
#include "imgui.h" // IMGUI_IMPL_API
#ifndef IMGUI_DISABLE
#include <dxgiformat.h> // DXGI_FORMAT
struct ID3D12Device;
@ -37,3 +38,5 @@ IMGUI_IMPL_API void ImGui_ImplDX12_RenderDrawData(ImDrawData* draw_data, ID3
// Use if you want to reset your rendering device without losing Dear ImGui state.
IMGUI_IMPL_API void ImGui_ImplDX12_InvalidateDeviceObjects();
IMGUI_IMPL_API bool ImGui_ImplDX12_CreateDeviceObjects();
#endif // #ifndef IMGUI_DISABLE

View file

@ -34,6 +34,7 @@
// 2018-02-06: Misc: Removed call to ImGui::Shutdown() which is not available from 1.60 WIP, user needs to call CreateContext/DestroyContext themselves.
#include "imgui.h"
#ifndef IMGUI_DISABLE
#include "imgui_impl_dx9.h"
// DirectX
@ -540,3 +541,7 @@ static void ImGui_ImplDX9_InvalidateDeviceObjectsForPlatformWindows()
if (platform_io.Viewports[i]->RendererUserData)
ImGui_ImplDX9_DestroyWindow(platform_io.Viewports[i]);
}
//-----------------------------------------------------------------------------
#endif // #ifndef IMGUI_DISABLE

View file

@ -13,6 +13,7 @@
#pragma once
#include "imgui.h" // IMGUI_IMPL_API
#ifndef IMGUI_DISABLE
struct IDirect3DDevice9;
@ -24,3 +25,5 @@ IMGUI_IMPL_API void ImGui_ImplDX9_RenderDrawData(ImDrawData* draw_data);
// Use if you want to reset your rendering device without losing Dear ImGui state.
IMGUI_IMPL_API bool ImGui_ImplDX9_CreateDeviceObjects();
IMGUI_IMPL_API void ImGui_ImplDX9_InvalidateDeviceObjects();
#endif // #ifndef IMGUI_DISABLE

View file

@ -22,6 +22,8 @@
// CHANGELOG
// (minor and older changes stripped away, please see git history for details)
// 2023-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
// 2023-07-18: Inputs: Revert ignoring mouse data on GLFW_CURSOR_DISABLED as it can be used differently. User may set ImGuiConfigFLags_NoMouse if desired. (#5625, #6609)
// 2023-06-12: Accept glfwGetTime() not returning a monotonically increasing value. This seems to happens on some Windows setup when peripherals disconnect, and is likely to also happen on browser + Emscripten. (#6491)
// 2023-04-04: Inputs: Added support for io.AddMouseSourceEvent() to discriminate ImGuiMouseSource_Mouse/ImGuiMouseSource_TouchScreen/ImGuiMouseSource_Pen on Windows ONLY, using a custom WndProc hook. (#2702)
// 2023-03-16: Inputs: Fixed key modifiers handling on secondary viewports (docking branch). Broken on 2023/01/04. (#6248, #6034)
// 2023-03-14: Emscripten: Avoid using glfwGetError() and glfwGetGamepadState() which are not correctly implemented in Emscripten emulation. (#6240)
@ -32,7 +34,7 @@
// 2022-10-18: Perform a dummy glfwGetError() read to cancel missing mouse cursors errors. Using GLFW_VERSION_COMBINED directly. (#5785)
// 2022-10-11: Using 'nullptr' instead of 'NULL' as per our switch to C++11.
// 2022-09-26: Inputs: Renamed ImGuiKey_ModXXX introduced in 1.87 to ImGuiMod_XXX (old names still supported).
// 2022-09-01: Inputs: Honor GLFW_CURSOR_DISABLED by not setting mouse position.
// 2022-09-01: Inputs: Honor GLFW_CURSOR_DISABLED by not setting mouse position *EDIT* Reverted 2023-07-18.
// 2022-04-30: Inputs: Fixed ImGui_ImplGlfw_TranslateUntranslatedKey() for lower case letters on OSX.
// 2022-03-23: Inputs: Fixed a regression in 1.87 which resulted in keyboard modifiers events being reported incorrectly on Linux/X11.
// 2022-02-07: Added ImGui_ImplGlfw_InstallCallbacks()/ImGui_ImplGlfw_RestoreCallbacks() helpers to facilitate user installing callbacks after initializing backend.
@ -69,6 +71,7 @@
// 2016-10-15: Misc: Added a void* user_data parameter to Clipboard function handlers.
#include "imgui.h"
#ifndef IMGUI_DISABLE
#include "imgui_impl_glfw.h"
// Clang warnings with -Weverything
@ -418,8 +421,6 @@ void ImGui_ImplGlfw_CursorPosCallback(GLFWwindow* window, double x, double y)
ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData();
if (bd->PrevUserCallbackCursorPos != nullptr && ImGui_ImplGlfw_ShouldChainCallback(window))
bd->PrevUserCallbackCursorPos(window, x, y);
if (glfwGetInputMode(window, GLFW_CURSOR) == GLFW_CURSOR_DISABLED)
return;
ImGuiIO& io = ImGui::GetIO();
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
@ -440,8 +441,6 @@ void ImGui_ImplGlfw_CursorEnterCallback(GLFWwindow* window, int entered)
ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData();
if (bd->PrevUserCallbackCursorEnter != nullptr && ImGui_ImplGlfw_ShouldChainCallback(window))
bd->PrevUserCallbackCursorEnter(window, entered);
if (glfwGetInputMode(window, GLFW_CURSOR) == GLFW_CURSOR_DISABLED)
return;
ImGuiIO& io = ImGui::GetIO();
if (entered)
@ -727,11 +726,6 @@ static void ImGui_ImplGlfw_UpdateMouseData()
ImGuiIO& io = ImGui::GetIO();
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
if (glfwGetInputMode(bd->Window, GLFW_CURSOR) == GLFW_CURSOR_DISABLED)
{
io.AddMousePosEvent(-FLT_MAX, -FLT_MAX);
return;
}
ImGuiID mouse_viewport_id = 0;
const ImVec2 mouse_pos_prev = io.MousePos;
@ -937,7 +931,10 @@ void ImGui_ImplGlfw_NewFrame()
ImGui_ImplGlfw_UpdateMonitors();
// Setup time step
// (Accept glfwGetTime() not returning a monotonically increasing value. Seems to happens on disconnecting peripherals and probably on VMs and Emscripten, see #6491, #6189, #6114, #3644)
double current_time = glfwGetTime();
if (current_time <= bd->Time)
current_time = bd->Time + 0.00001f;
io.DeltaTime = bd->Time > 0.0 ? (float)(current_time - bd->Time) : (float)(1.0f / 60.0f);
bd->Time = current_time;
@ -1285,6 +1282,10 @@ static void ImGui_ImplGlfw_ShutdownPlatformInterface()
ImGui::DestroyPlatformWindows();
}
//-----------------------------------------------------------------------------
#if defined(__clang__)
#pragma clang diagnostic pop
#endif
#endif // #ifndef IMGUI_DISABLE

View file

@ -21,6 +21,7 @@
#pragma once
#include "imgui.h" // IMGUI_IMPL_API
#ifndef IMGUI_DISABLE
struct GLFWwindow;
struct GLFWmonitor;
@ -50,3 +51,5 @@ IMGUI_IMPL_API void ImGui_ImplGlfw_ScrollCallback(GLFWwindow* window, double
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);
#endif // #ifndef IMGUI_DISABLE

View file

@ -32,6 +32,7 @@
// 2018-03-22: Added GLUT Platform binding.
#include "imgui.h"
#ifndef IMGUI_DISABLE
#include "imgui_impl_glut.h"
#define GL_SILENCE_DEPRECATION
#ifdef __APPLE__
@ -298,3 +299,7 @@ void ImGui_ImplGLUT_MotionFunc(int x, int y)
ImGuiIO& io = ImGui::GetIO();
io.AddMousePosEvent((float)x, (float)y);
}
//-----------------------------------------------------------------------------
#endif // #ifndef IMGUI_DISABLE

View file

@ -20,6 +20,7 @@
// Read online: https://github.com/ocornut/imgui/tree/master/docs
#pragma once
#ifndef IMGUI_DISABLE
#include "imgui.h" // IMGUI_IMPL_API
IMGUI_IMPL_API bool ImGui_ImplGLUT_Init();
@ -29,7 +30,7 @@ IMGUI_IMPL_API void ImGui_ImplGLUT_NewFrame();
// You can call ImGui_ImplGLUT_InstallFuncs() to get all those functions installed automatically,
// or call them yourself from your own GLUT handlers. We are using the same weird names as GLUT for consistency..
//---------------------------------------- GLUT name --------------------------------------------- Decent Name ---------
//------------------------------------ GLUT name ---------------------------------------------- Decent Name ---------
IMGUI_IMPL_API void ImGui_ImplGLUT_ReshapeFunc(int w, int h); // ~ ResizeFunc
IMGUI_IMPL_API void ImGui_ImplGLUT_MotionFunc(int x, int y); // ~ MouseMoveFunc
IMGUI_IMPL_API void ImGui_ImplGLUT_MouseFunc(int button, int state, int x, int y); // ~ MouseButtonFunc
@ -38,3 +39,5 @@ IMGUI_IMPL_API void ImGui_ImplGLUT_KeyboardFunc(unsigned char c, int x, int
IMGUI_IMPL_API void ImGui_ImplGLUT_KeyboardUpFunc(unsigned char c, int x, int y); // ~ CharReleasedFunc
IMGUI_IMPL_API void ImGui_ImplGLUT_SpecialFunc(int key, int x, int y); // ~ KeyPressedFunc
IMGUI_IMPL_API void ImGui_ImplGLUT_SpecialUpFunc(int key, int x, int y); // ~ KeyReleasedFunc
#endif // #ifndef IMGUI_DISABLE

View file

@ -12,6 +12,7 @@
// Read online: https://github.com/ocornut/imgui/tree/master/docs
#include "imgui.h" // IMGUI_IMPL_API
#ifndef IMGUI_DISABLE
//-----------------------------------------------------------------------------
// ObjC API
@ -63,3 +64,7 @@ IMGUI_IMPL_API void ImGui_ImplMetal_DestroyDeviceObjects();
#endif
#endif
//-----------------------------------------------------------------------------
#endif // #ifndef IMGUI_DISABLE

View file

@ -32,6 +32,7 @@
// 2018-07-05: Metal: Added new Metal backend implementation.
#include "imgui.h"
#ifndef IMGUI_DISABLE
#include "imgui_impl_metal.h"
#import <time.h>
#import <Metal/Metal.h>
@ -740,3 +741,7 @@ static void ImGui_ImplMetal_InvalidateDeviceObjectsForPlatformWindows()
}
@end
//-----------------------------------------------------------------------------
#endif // #ifndef IMGUI_DISABLE

View file

@ -39,12 +39,9 @@
// 2016-09-05: OpenGL: Fixed save and restore of current scissor rectangle.
#include "imgui.h"
#ifndef IMGUI_DISABLE
#include "imgui_impl_opengl2.h"
#if defined(_MSC_VER) && _MSC_VER <= 1500 // MSVC 2008 or earlier
#include <stddef.h> // intptr_t
#else
#include <stdint.h> // intptr_t
#endif
// Clang/GCC warnings with -Weverything
#if defined(__clang__)
@ -305,6 +302,7 @@ void ImGui_ImplOpenGL2_DestroyDeviceObjects()
ImGui_ImplOpenGL2_DestroyFontsTexture();
}
//--------------------------------------------------------------------------------------------------------
// MULTI-VIEWPORT / PLATFORM INTERFACE SUPPORT
// This is an _advanced_ and _optional_ feature, allowing the backend to create and handle multiple viewports simultaneously.
@ -333,6 +331,10 @@ static void ImGui_ImplOpenGL2_ShutdownPlatformInterface()
ImGui::DestroyPlatformWindows();
}
//-----------------------------------------------------------------------------
#if defined(__clang__)
#pragma clang diagnostic pop
#endif
#endif // #ifndef IMGUI_DISABLE

View file

@ -20,6 +20,7 @@
#pragma once
#include "imgui.h" // IMGUI_IMPL_API
#ifndef IMGUI_DISABLE
IMGUI_IMPL_API bool ImGui_ImplOpenGL2_Init();
IMGUI_IMPL_API void ImGui_ImplOpenGL2_Shutdown();
@ -31,3 +32,5 @@ IMGUI_IMPL_API bool ImGui_ImplOpenGL2_CreateFontsTexture();
IMGUI_IMPL_API void ImGui_ImplOpenGL2_DestroyFontsTexture();
IMGUI_IMPL_API bool ImGui_ImplOpenGL2_CreateDeviceObjects();
IMGUI_IMPL_API void ImGui_ImplOpenGL2_DestroyDeviceObjects();
#endif // #ifndef IMGUI_DISABLE

View file

@ -21,6 +21,7 @@
// CHANGELOG
// (minor and older changes stripped away, please see git history for details)
// 2023-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
// 2023-06-20: OpenGL: Fixed erroneous use glGetIntegerv(GL_CONTEXT_PROFILE_MASK) on contexts lower than 3.2. (#6539, #6333)
// 2023-05-09: OpenGL: Support for glBindSampler() backup/restore on ES3. (#6375)
// 2023-04-18: OpenGL: Restore front and back polygon mode separately when supported by context. (#6333)
// 2023-03-23: OpenGL: Properly restoring "no shader program bound" if it was the case prior to running the rendering function. (#6267, #6220, #6224)
@ -105,13 +106,10 @@
#endif
#include "imgui.h"
#ifndef IMGUI_DISABLE
#include "imgui_impl_opengl3.h"
#include <stdio.h>
#if defined(_MSC_VER) && _MSC_VER <= 1500 // MSVC 2008 or earlier
#include <stddef.h> // intptr_t
#else
#include <stdint.h> // intptr_t
#endif
#if defined(__APPLE__)
#include <TargetConditionals.h>
#endif
@ -292,7 +290,12 @@ bool ImGui_ImplOpenGL3_Init(const char* glsl_version)
io.BackendRendererName = "imgui_impl_opengl3";
// Query for GL version (e.g. 320 for GL 3.2)
#if !defined(IMGUI_IMPL_OPENGL_ES2)
#if defined(IMGUI_IMPL_OPENGL_ES2)
// GLES 2
bd->GlVersion = 200;
bd->GlProfileIsES2 = true;
#else
// Desktop or GLES 3
GLint major = 0;
GLint minor = 0;
glGetIntegerv(GL_MAJOR_VERSION, &major);
@ -305,10 +308,15 @@ bool ImGui_ImplOpenGL3_Init(const char* glsl_version)
}
bd->GlVersion = (GLuint)(major * 100 + minor * 10);
#if defined(GL_CONTEXT_PROFILE_MASK)
if (bd->GlVersion >= 320)
glGetIntegerv(GL_CONTEXT_PROFILE_MASK, &bd->GlProfileMask);
bd->GlProfileIsCompat = (bd->GlProfileMask & GL_CONTEXT_COMPATIBILITY_PROFILE_BIT) != 0;
#endif
#if defined(IMGUI_IMPL_OPENGL_ES3)
bd->GlProfileIsES3 = true;
#endif
bd->UseBufferSubData = false;
/*
// Query vendor to enable glBufferSubData kludge
@ -318,16 +326,10 @@ bool ImGui_ImplOpenGL3_Init(const char* glsl_version)
bd->UseBufferSubData = true;
#endif
*/
#elif defined(IMGUI_IMPL_OPENGL_ES2)
bd->GlVersion = 200; // GLES 2
bd->GlProfileIsES2 = true;
#elif defined(IMGUI_IMPL_OPENGL_ES3)
bd->GlVersion = 200; // Don't raise version as it is intended as a desktop version check for now.
bd->GlProfileIsES3 = true;
#endif
#ifdef IMGUI_IMPL_OPENGL_DEBUG
logD("\nGL_VENDOR = '%s'\nGL_RENDERER = '%s'\n", (const char*)glGetString(GL_VENDOR), (const char*)glGetString(GL_RENDERER)); // [DEBUG]
printf("GlVersion = %d\nGlProfileIsCompat = %d\nGlProfileMask = 0x%X\nGlProfileIsES2 = %d, GlProfileIsES3 = %d\nGL_VENDOR = '%s'\nGL_RENDERER = '%s'\n", bd->GlVersion, bd->GlProfileIsCompat, bd->GlProfileMask, bd->GlProfileIsES2, bd->GlProfileIsES3, (const char*)glGetString(GL_VENDOR), (const char*)glGetString(GL_RENDERER)); // [DEBUG]
#endif
#ifdef IMGUI_IMPL_OPENGL_MAY_HAVE_VTX_OFFSET
@ -979,9 +981,13 @@ static void ImGui_ImplOpenGL3_ShutdownPlatformInterface()
ImGui::DestroyPlatformWindows();
}
//-----------------------------------------------------------------------------
#if defined(__GNUC__)
#pragma GCC diagnostic pop
#endif
#if defined(__clang__)
#pragma clang diagnostic pop
#endif
#endif // #ifndef IMGUI_DISABLE

View file

@ -25,6 +25,7 @@
#pragma once
#include "imgui.h" // IMGUI_IMPL_API
#ifndef IMGUI_DISABLE
// Backend API
IMGUI_IMPL_API bool ImGui_ImplOpenGL3_Init(const char* glsl_version = nullptr);
@ -59,3 +60,5 @@ IMGUI_IMPL_API void ImGui_ImplOpenGL3_DestroyDeviceObjects();
#endif
#endif
#endif // #ifndef IMGUI_DISABLE

View file

@ -18,6 +18,7 @@
// Read online: https://github.com/ocornut/imgui/tree/master/docs
#include "imgui.h" // IMGUI_IMPL_API
#ifndef IMGUI_DISABLE
#ifdef __OBJC__
@ -44,3 +45,5 @@ IMGUI_IMPL_API void ImGui_ImplOSX_NewFrame(void* _Nullable view);
#endif
#endif
#endif // #ifndef IMGUI_DISABLE

View file

@ -18,6 +18,7 @@
// Read online: https://github.com/ocornut/imgui/tree/master/docs
#import "imgui.h"
#ifndef IMGUI_DISABLE
#import "imgui_impl_osx.h"
#import <Cocoa/Cocoa.h>
#import <Carbon/Carbon.h>
@ -1109,3 +1110,7 @@ static void ImGui_ImplOSX_ShutdownPlatformInterface()
main_viewport->PlatformUserData = nullptr;
ImGui::DestroyPlatformWindows();
}
//-----------------------------------------------------------------------------
#endif // #ifndef IMGUI_DISABLE

View file

@ -77,6 +77,7 @@
// 2016-10-15: Misc: Added a void* user_data parameter to Clipboard function handlers.
#include "imgui.h"
#ifndef IMGUI_DISABLE
#include "imgui_impl_sdl2.h"
#include <stdio.h>
#include <cmath>
@ -321,14 +322,8 @@ bool ImGui_ImplSDL2_ProcessEvent(const SDL_Event* event)
mouse_pos.y += window_y;
}
// Fix for high DPI mac/idevice/wayland
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
if (!platform_io.Monitors.empty() && platform_io.Monitors[0].DpiScale > 1.0f)
{
// The Framebuffer is scaled by an integer ceiling of the actual ratio, so 2.0 not 1.685 on Mac!
//printf("multiply by %f\n",platform_io.Monitors[0].DpiScale);
mouse_pos.x *= std::ceil(platform_io.Monitors[0].DpiScale);
mouse_pos.y *= std::ceil(platform_io.Monitors[0].DpiScale);
}
mouse_pos.x *= io.InputScale;
mouse_pos.y *= io.InputScale;
io.AddMouseSourceEvent(event->motion.which == SDL_TOUCH_MOUSEID ? ImGuiMouseSource_TouchScreen : ImGuiMouseSource_Mouse);
io.AddMousePosEvent(mouse_pos.x, mouse_pos.y);
return true;
@ -626,13 +621,8 @@ static void ImGui_ImplSDL2_UpdateMouseData()
mouse_y -= window_y;
}
// Fix for high DPI mac/idevice/wayland
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
if (!platform_io.Monitors.empty() && platform_io.Monitors[0].DpiScale > 1.0f)
{
// The Framebuffer is scaled by an integer ceiling of the actual ratio, so 2.0 not 1.685 on Mac!
mouse_x *= std::ceil(platform_io.Monitors[0].DpiScale);
mouse_y *= std::ceil(platform_io.Monitors[0].DpiScale);
}
mouse_x *= io.InputScale;
mouse_y *= io.InputScale;
io.AddMousePosEvent((float)mouse_x, (float)mouse_y);
}
}
@ -792,7 +782,7 @@ void ImGui_ImplSDL2_NewFrame()
io.DisplayFramebufferScale = ImVec2(1.0f, 1.0f);
io.DisplaySize = ImVec2((float)display_w, (float)display_h);
//printf("write %d/%d to DpiScale\n",display_w,w);
platform_io.Monitors[0].DpiScale=(float)display_w/(float)w;
io.InputScale=(float)display_w/(float)w;
}
// Setup time step (we don't use SDL_GetTicks() because it is using millisecond resolution)
@ -1072,6 +1062,10 @@ static void ImGui_ImplSDL2_ShutdownPlatformInterface()
ImGui::DestroyPlatformWindows();
}
//-----------------------------------------------------------------------------
#if defined(__clang__)
#pragma clang diagnostic pop
#endif
#endif // #ifndef IMGUI_DISABLE

View file

@ -20,6 +20,7 @@
#pragma once
#include "imgui.h" // IMGUI_IMPL_API
#ifndef IMGUI_DISABLE
struct SDL_Window;
struct SDL_Renderer;
@ -37,3 +38,5 @@ IMGUI_IMPL_API bool ImGui_ImplSDL2_ProcessEvent(const SDL_Event* event);
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
static inline void ImGui_ImplSDL2_NewFrame(SDL_Window*) { ImGui_ImplSDL2_NewFrame(); } // 1.84: removed unnecessary parameter
#endif
#endif // #ifndef IMGUI_DISABLE

View file

@ -29,6 +29,7 @@
// 2023-02-07: Forked "imgui_impl_sdl2" into "imgui_impl_sdl3". Removed version checks for old feature. Refer to imgui_impl_sdl2.cpp for older changelog.
#include "imgui.h"
#ifndef IMGUI_DISABLE
#include "imgui_impl_sdl3.h"
// Clang warnings with -Weverything
@ -752,7 +753,7 @@ static void ImGui_ImplSDL3_CreateWindow(ImGuiViewport* viewport)
sdl_flags |= (viewport->Flags & ImGuiViewportFlags_NoDecoration) ? 0 : SDL_WINDOW_RESIZABLE;
#if !defined(_WIN32)
// See SDL hack in ImGui_ImplSDL3_ShowWindow().
sdl_flags |= (viewport->Flags & ImGuiViewportFlags_NoTaskBarIcon) ? SDL_WINDOW_SKIP_TASKBAR : 0;
sdl_flags |= (viewport->Flags & ImGuiViewportFlags_NoTaskBarIcon) ? SDL_WINDOW_UTILITY : 0;
#endif
sdl_flags |= (viewport->Flags & ImGuiViewportFlags_TopMost) ? SDL_WINDOW_ALWAYS_ON_TOP : 0;
vd->Window = SDL_CreateWindow("No Title Yet", (int)viewport->Size.x, (int)viewport->Size.y, sdl_flags);
@ -801,7 +802,7 @@ static void ImGui_ImplSDL3_ShowWindow(ImGuiViewport* viewport)
HWND hwnd = (HWND)viewport->PlatformHandleRaw;
// SDL hack: Hide icon from task bar
// Note: SDL 2.0.6+ has a SDL_WINDOW_SKIP_TASKBAR flag which is supported under Windows but the way it create the window breaks our seamless transition.
// Note: SDL 3.0.0+ has a SDL_WINDOW_UTILITY flag which is supported under Windows but the way it create the window breaks our seamless transition.
if (viewport->Flags & ImGuiViewportFlags_NoTaskBarIcon)
{
LONG ex_style = ::GetWindowLong(hwnd, GWL_EXSTYLE);
@ -944,6 +945,10 @@ static void ImGui_ImplSDL3_ShutdownPlatformInterface()
ImGui::DestroyPlatformWindows();
}
//-----------------------------------------------------------------------------
#if defined(__clang__)
#pragma clang diagnostic pop
#endif
#endif // #ifndef IMGUI_DISABLE

View file

@ -21,6 +21,7 @@
#pragma once
#include "imgui.h" // IMGUI_IMPL_API
#ifndef IMGUI_DISABLE
struct SDL_Window;
struct SDL_Renderer;
@ -34,3 +35,5 @@ IMGUI_IMPL_API bool ImGui_ImplSDL3_InitForSDLRenderer(SDL_Window* window, SD
IMGUI_IMPL_API void ImGui_ImplSDL3_Shutdown();
IMGUI_IMPL_API void ImGui_ImplSDL3_NewFrame();
IMGUI_IMPL_API bool ImGui_ImplSDL3_ProcessEvent(const SDL_Event* event);
#endif // #ifndef IMGUI_DISABLE

View file

@ -26,12 +26,9 @@
// 2021-09-21: Initial version.
#include "imgui.h"
#ifndef IMGUI_DISABLE
#include "imgui_impl_sdlrenderer2.h"
#if defined(_MSC_VER) && _MSC_VER <= 1500 // MSVC 2008 or earlier
#include <stddef.h> // intptr_t
#else
#include <stdint.h> // intptr_t
#endif
// Clang warnings with -Weverything
#if defined(__clang__)
@ -260,6 +257,10 @@ void ImGui_ImplSDLRenderer2_DestroyDeviceObjects()
ImGui_ImplSDLRenderer2_DestroyFontsTexture();
}
//-----------------------------------------------------------------------------
#if defined(__clang__)
#pragma clang diagnostic pop
#endif
#endif // #ifndef IMGUI_DISABLE

View file

@ -14,6 +14,7 @@
// [ ] Renderer: Multi-viewport support (multiple windows).
#pragma once
#ifndef IMGUI_DISABLE
#include "imgui.h" // IMGUI_IMPL_API
struct SDL_Renderer;
@ -28,3 +29,5 @@ IMGUI_IMPL_API bool ImGui_ImplSDLRenderer2_CreateFontsTexture();
IMGUI_IMPL_API void ImGui_ImplSDLRenderer2_DestroyFontsTexture();
IMGUI_IMPL_API bool ImGui_ImplSDLRenderer2_CreateDeviceObjects();
IMGUI_IMPL_API void ImGui_ImplSDLRenderer2_DestroyDeviceObjects();
#endif // #ifndef IMGUI_DISABLE

View file

@ -21,12 +21,9 @@
// 2023-05-30: Initial version.
#include "imgui.h"
#ifndef IMGUI_DISABLE
#include "imgui_impl_sdlrenderer3.h"
#if defined(_MSC_VER) && _MSC_VER <= 1500 // MSVC 2008 or earlier
#include <stddef.h> // intptr_t
#else
#include <stdint.h> // intptr_t
#endif
// Clang warnings with -Weverything
#if defined(__clang__)
@ -253,6 +250,10 @@ void ImGui_ImplSDLRenderer3_DestroyDeviceObjects()
ImGui_ImplSDLRenderer3_DestroyFontsTexture();
}
//-----------------------------------------------------------------------------
#if defined(__clang__)
#pragma clang diagnostic pop
#endif
#endif // #ifndef IMGUI_DISABLE

View file

@ -15,6 +15,7 @@
#pragma once
#include "imgui.h" // IMGUI_IMPL_API
#ifndef IMGUI_DISABLE
struct SDL_Renderer;
@ -28,3 +29,5 @@ IMGUI_IMPL_API bool ImGui_ImplSDLRenderer3_CreateFontsTexture();
IMGUI_IMPL_API void ImGui_ImplSDLRenderer3_DestroyFontsTexture();
IMGUI_IMPL_API bool ImGui_ImplSDLRenderer3_CreateDeviceObjects();
IMGUI_IMPL_API void ImGui_ImplSDLRenderer3_DestroyDeviceObjects();
#endif // #ifndef IMGUI_DISABLE

View file

@ -32,6 +32,7 @@
// CHANGELOG
// (minor and older changes stripped away, please see git history for details)
// 2023-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
// 2023-07-04: Vulkan: Added optional support for VK_KHR_dynamic_rendering. User needs to set init_info->UseDynamicRendering = true and init_info->ColorAttachmentFormat.
// 2023-01-02: Vulkan: Fixed sampler passed to ImGui_ImplVulkan_AddTexture() not being honored + removed a bunch of duplicate code.
// 2022-10-11: Using 'nullptr' instead of 'NULL' as per our switch to C++11.
// 2022-10-04: Vulkan: Added experimental ImGui_ImplVulkan_RemoveTexture() for api symetry. (#914, #5738).
@ -67,6 +68,8 @@
// 2016-10-18: Vulkan: Add location decorators & change to use structs as in/out in glsl, update embedded spv (produced with glslangValidator -x). Null the released resources.
// 2016-08-27: Vulkan: Fix Vulkan example for use when a depth buffer is active.
#include "imgui.h"
#ifndef IMGUI_DISABLE
#include "imgui_impl_vulkan.h"
#include <stdio.h>
@ -238,6 +241,12 @@ IMGUI_VULKAN_FUNC_MAP(IMGUI_VULKAN_FUNC_DEF)
#undef IMGUI_VULKAN_FUNC_DEF
#endif // VK_NO_PROTOTYPES
#if defined(VK_VERSION_1_3) || defined(VK_KHR_dynamic_rendering)
#define IMGUI_IMPL_VULKAN_HAS_DYNAMIC_RENDERING
static PFN_vkCmdBeginRenderingKHR ImGuiImplVulkanFuncs_vkCmdBeginRenderingKHR;
static PFN_vkCmdEndRenderingKHR ImGuiImplVulkanFuncs_vkCmdEndRenderingKHR;
#endif
//-----------------------------------------------------------------------------
// SHADERS
//-----------------------------------------------------------------------------
@ -872,6 +881,19 @@ static void ImGui_ImplVulkan_CreatePipeline(VkDevice device, const VkAllocationC
info.layout = bd->PipelineLayout;
info.renderPass = renderPass;
info.subpass = subpass;
#ifdef IMGUI_IMPL_VULKAN_HAS_DYNAMIC_RENDERING
VkPipelineRenderingCreateInfoKHR pipelineRenderingCreateInfo = {};
pipelineRenderingCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO_KHR;
pipelineRenderingCreateInfo.colorAttachmentCount = 1;
pipelineRenderingCreateInfo.pColorAttachmentFormats = &bd->VulkanInitInfo.ColorAttachmentFormat;
if (bd->VulkanInitInfo.UseDynamicRendering)
{
info.pNext = &pipelineRenderingCreateInfo;
info.renderPass = VK_NULL_HANDLE; // Just make sure it's actually nullptr.
}
#endif
VkResult err = vkCreateGraphicsPipelines(device, pipelineCache, 1, &info, allocator, pipeline);
check_vk_result(err);
}
@ -984,10 +1006,17 @@ bool ImGui_ImplVulkan_LoadFunctions(PFN_vkVoidFunction(*loader_func)(const ch
return false;
IMGUI_VULKAN_FUNC_MAP(IMGUI_VULKAN_FUNC_LOAD)
#undef IMGUI_VULKAN_FUNC_LOAD
#ifdef IMGUI_IMPL_VULKAN_HAS_DYNAMIC_RENDERING
// Manually load those two (see #5446)
ImGuiImplVulkanFuncs_vkCmdBeginRenderingKHR = reinterpret_cast<PFN_vkCmdBeginRenderingKHR>(loader_func("vkCmdBeginRenderingKHR", user_data));
ImGuiImplVulkanFuncs_vkCmdEndRenderingKHR = reinterpret_cast<PFN_vkCmdEndRenderingKHR>(loader_func("vkCmdEndRenderingKHR", user_data));
#endif
#else
IM_UNUSED(loader_func);
IM_UNUSED(user_data);
#endif
g_FunctionsLoaded = true;
return true;
}
@ -996,6 +1025,20 @@ bool ImGui_ImplVulkan_Init(ImGui_ImplVulkan_InitInfo* info, VkRenderPass rend
{
IM_ASSERT(g_FunctionsLoaded && "Need to call ImGui_ImplVulkan_LoadFunctions() if IMGUI_IMPL_VULKAN_NO_PROTOTYPES or VK_NO_PROTOTYPES are set!");
if (info->UseDynamicRendering)
{
#ifdef IMGUI_IMPL_VULKAN_HAS_DYNAMIC_RENDERING
#ifndef VK_NO_PROTOTYPES
ImGuiImplVulkanFuncs_vkCmdBeginRenderingKHR = reinterpret_cast<PFN_vkCmdBeginRenderingKHR>(vkGetInstanceProcAddr(info->Instance, "vkCmdBeginRenderingKHR"));
ImGuiImplVulkanFuncs_vkCmdEndRenderingKHR = reinterpret_cast<PFN_vkCmdEndRenderingKHR>(vkGetInstanceProcAddr(info->Instance, "vkCmdEndRenderingKHR"));
#endif
IM_ASSERT(ImGuiImplVulkanFuncs_vkCmdBeginRenderingKHR != nullptr);
IM_ASSERT(ImGuiImplVulkanFuncs_vkCmdEndRenderingKHR != nullptr);
#else
IM_ASSERT(0 && "Can't use dynamic rendering when neither VK_VERSION_1_3 or VK_KHR_dynamic_rendering is defined.");
#endif
}
ImGuiIO& io = ImGui::GetIO();
IM_ASSERT(io.BackendRendererUserData == nullptr && "Already initialized a renderer backend!");
@ -1013,6 +1056,7 @@ bool ImGui_ImplVulkan_Init(ImGui_ImplVulkan_InitInfo* info, VkRenderPass rend
IM_ASSERT(info->DescriptorPool != VK_NULL_HANDLE);
IM_ASSERT(info->MinImageCount >= 2);
IM_ASSERT(info->ImageCount >= info->MinImageCount);
if (info->UseDynamicRendering == false)
IM_ASSERT(render_pass != VK_NULL_HANDLE);
bd->VulkanInitInfo = *info;
@ -1350,6 +1394,7 @@ void ImGui_ImplVulkanH_CreateWindowSwapChain(VkPhysicalDevice physical_device, V
vkDestroySwapchainKHR(device, old_swapchain, allocator);
// Create the Render Pass
if (wd->UseDynamicRendering == false)
{
VkAttachmentDescription attachment = {};
attachment.format = wd->SurfaceFormat.format;
@ -1412,6 +1457,7 @@ void ImGui_ImplVulkanH_CreateWindowSwapChain(VkPhysicalDevice physical_device, V
}
// Create Framebuffer
if (wd->UseDynamicRendering == false)
{
VkImageView attachment[1];
VkFramebufferCreateInfo info = {};
@ -1553,6 +1599,7 @@ static void ImGui_ImplVulkan_CreateWindow(ImGuiViewport* viewport)
// Create SwapChain, RenderPass, Framebuffer, etc.
wd->ClearEnable = (viewport->Flags & ImGuiViewportFlags_NoRendererClear) ? false : true;
wd->UseDynamicRendering = v->UseDynamicRendering;
ImGui_ImplVulkanH_CreateOrResizeWindow(v->Instance, v->PhysicalDevice, v->Device, wd, v->QueueFamily, v->Allocator, (int)viewport->Size.x, (int)viewport->Size.y, v->MinImageCount);
vd->WindowOwned = true;
}
@ -1618,7 +1665,45 @@ static void ImGui_ImplVulkan_RenderWindow(ImGuiViewport* viewport, void*)
{
ImVec4 clear_color = ImVec4(0.0f, 0.0f, 0.0f, 1.0f);
memcpy(&wd->ClearValue.color.float32[0], &clear_color, 4 * sizeof(float));
}
#ifdef IMGUI_IMPL_VULKAN_HAS_DYNAMIC_RENDERING
if (v->UseDynamicRendering)
{
// Transition swapchain image to a layout suitable for drawing.
VkImageMemoryBarrier barrier = {};
barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
barrier.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
barrier.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED;
barrier.newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
barrier.image = fd->Backbuffer;
barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
barrier.subresourceRange.levelCount = 1;
barrier.subresourceRange.layerCount = 1;
vkCmdPipelineBarrier(fd->CommandBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 0, 0, nullptr, 0, nullptr, 1, &barrier);
VkRenderingAttachmentInfo attachmentInfo = {};
attachmentInfo.sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO_KHR;
attachmentInfo.imageView = fd->BackbufferView;
attachmentInfo.imageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
attachmentInfo.resolveMode = VK_RESOLVE_MODE_NONE;
attachmentInfo.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
attachmentInfo.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
attachmentInfo.clearValue = wd->ClearValue;
VkRenderingInfo renderingInfo = {};
renderingInfo.sType = VK_STRUCTURE_TYPE_RENDERING_INFO_KHR;
renderingInfo.renderArea.extent.width = wd->Width;
renderingInfo.renderArea.extent.height = wd->Height;
renderingInfo.layerCount = 1;
renderingInfo.viewMask = 0;
renderingInfo.colorAttachmentCount = 1;
renderingInfo.pColorAttachments = &attachmentInfo;
ImGuiImplVulkanFuncs_vkCmdBeginRenderingKHR(fd->CommandBuffer, &renderingInfo);
}
else
#endif
{
VkRenderPassBeginInfo info = {};
info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
info.renderPass = wd->RenderPass;
@ -1633,8 +1718,29 @@ static void ImGui_ImplVulkan_RenderWindow(ImGuiViewport* viewport, void*)
ImGui_ImplVulkan_RenderDrawData(viewport->DrawData, fd->CommandBuffer, wd->Pipeline);
{
#ifdef IMGUI_IMPL_VULKAN_HAS_DYNAMIC_RENDERING
if (v->UseDynamicRendering)
{
ImGuiImplVulkanFuncs_vkCmdEndRenderingKHR(fd->CommandBuffer);
// Transition image to a layout suitable for presentation
VkImageMemoryBarrier barrier = {};
barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
barrier.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
barrier.oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
barrier.newLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
barrier.image = fd->Backbuffer;
barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
barrier.subresourceRange.levelCount = 1;
barrier.subresourceRange.layerCount = 1;
vkCmdPipelineBarrier(fd->CommandBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, 0, 0, nullptr, 0, nullptr, 1, &barrier);
}
else
#endif
{
vkCmdEndRenderPass(fd->CommandBuffer);
}
{
VkPipelineStageFlags wait_stage = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
VkSubmitInfo info = {};
@ -1701,3 +1807,7 @@ void ImGui_ImplVulkan_ShutdownPlatformInterface()
{
ImGui::DestroyPlatformWindows();
}
//-----------------------------------------------------------------------------
#endif // #ifndef IMGUI_DISABLE

View file

@ -25,6 +25,7 @@
// Read comments in imgui_impl_vulkan.h.
#pragma once
#ifndef IMGUI_DISABLE
#include "imgui.h" // IMGUI_IMPL_API
// [Configuration] in order to use a custom Vulkan function loader:
@ -60,6 +61,12 @@ struct ImGui_ImplVulkan_InitInfo
uint32_t MinImageCount; // >= 2
uint32_t ImageCount; // >= MinImageCount
VkSampleCountFlagBits MSAASamples; // >= VK_SAMPLE_COUNT_1_BIT (0 -> default to VK_SAMPLE_COUNT_1_BIT)
// Dynamic Rendering (Optional)
bool UseDynamicRendering; // Need to explicitly enable VK_KHR_dynamic_rendering extension to use this, even for Vulkan 1.3.
VkFormat ColorAttachmentFormat; // Required for dynamic rendering
// Allocation, Debugging
const VkAllocationCallbacks* Allocator;
void (*CheckVkResultFn)(VkResult err);
};
@ -140,6 +147,7 @@ struct ImGui_ImplVulkanH_Window
VkPresentModeKHR PresentMode;
VkRenderPass RenderPass;
VkPipeline Pipeline; // The window pipeline may uses a different VkRenderPass than the one passed in ImGui_ImplVulkan_InitInfo
bool UseDynamicRendering;
bool ClearEnable;
VkClearValue ClearValue;
uint32_t FrameIndex; // Current frame being rendered to (0 <= FrameIndex < FrameInFlightCount)
@ -156,3 +164,4 @@ struct ImGui_ImplVulkanH_Window
}
};
#endif // #ifndef IMGUI_DISABLE

View file

@ -13,6 +13,7 @@
// CHANGELOG
// (minor and older changes stripped away, please see git history for details)
// 2023-07-13: Use WGPUShaderModuleWGSLDescriptor's code instead of source. use WGPUMipmapFilterMode_Linear instead of WGPUFilterMode_Linear. (#6602)
// 2023-04-11: Align buffer sizes. Use WGSL shaders instead of precompiled SPIR-V.
// 2023-04-11: Reorganized backend to pull data from a single structure to facilitate usage with multiple-contexts (all g_XXXX access changed to bd->XXXX).
// 2023-01-25: Revert automatic pipeline layout generation (see https://github.com/gpuweb/gpuweb/issues/2470)
@ -28,6 +29,7 @@
// 2021-01-28: Initial version.
#include "imgui.h"
#ifndef IMGUI_DISABLE
#include "imgui_impl_wgpu.h"
#include <limits.h>
#include <webgpu/webgpu.h>
@ -230,7 +232,7 @@ static WGPUProgrammableStageDescriptor ImGui_ImplWGPU_CreateShaderModule(const c
WGPUShaderModuleWGSLDescriptor wgsl_desc = {};
wgsl_desc.chain.sType = WGPUSType_ShaderModuleWGSLDescriptor;
wgsl_desc.source = wgsl_source;
wgsl_desc.code = wgsl_source;
WGPUShaderModuleDescriptor desc = {};
desc.nextInChain = reinterpret_cast<WGPUChainedStruct*>(&wgsl_desc);
@ -511,7 +513,7 @@ static void ImGui_ImplWGPU_CreateFontsTexture()
WGPUSamplerDescriptor sampler_desc = {};
sampler_desc.minFilter = WGPUFilterMode_Linear;
sampler_desc.magFilter = WGPUFilterMode_Linear;
sampler_desc.mipmapFilter = WGPUFilterMode_Linear;
sampler_desc.mipmapFilter = WGPUMipmapFilterMode_Linear;
sampler_desc.addressModeU = WGPUAddressMode_Repeat;
sampler_desc.addressModeV = WGPUAddressMode_Repeat;
sampler_desc.addressModeW = WGPUAddressMode_Repeat;
@ -761,3 +763,7 @@ void ImGui_ImplWGPU_NewFrame()
if (!bd->pipelineState)
ImGui_ImplWGPU_CreateDeviceObjects();
}
//-----------------------------------------------------------------------------
#endif // #ifndef IMGUI_DISABLE

View file

@ -13,6 +13,8 @@
#pragma once
#include "imgui.h" // IMGUI_IMPL_API
#ifndef IMGUI_DISABLE
#include <webgpu/webgpu.h>
IMGUI_IMPL_API bool ImGui_ImplWGPU_Init(WGPUDevice device, int num_frames_in_flight, WGPUTextureFormat rt_format, WGPUTextureFormat depth_format = WGPUTextureFormat_Undefined);
@ -23,3 +25,5 @@ IMGUI_IMPL_API void ImGui_ImplWGPU_RenderDrawData(ImDrawData* draw_data, WGPURen
// Use if you want to reset your rendering device without losing Dear ImGui state.
IMGUI_IMPL_API void ImGui_ImplWGPU_InvalidateDeviceObjects();
IMGUI_IMPL_API bool ImGui_ImplWGPU_CreateDeviceObjects();
#endif // #ifndef IMGUI_DISABLE

View file

@ -15,6 +15,7 @@
// Read online: https://github.com/ocornut/imgui/tree/master/docs
#include "imgui.h"
#ifndef IMGUI_DISABLE
#include "imgui_impl_win32.h"
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
@ -950,11 +951,12 @@ void ImGui_ImplWin32_EnableAlphaCompositing(void* hwnd)
struct ImGui_ImplWin32_ViewportData
{
HWND Hwnd;
HWND HwndParent;
bool HwndOwned;
DWORD DwStyle;
DWORD DwExStyle;
ImGui_ImplWin32_ViewportData() { Hwnd = nullptr; HwndOwned = false; DwStyle = DwExStyle = 0; }
ImGui_ImplWin32_ViewportData() { Hwnd = HwndParent = nullptr; HwndOwned = false; DwStyle = DwExStyle = 0; }
~ImGui_ImplWin32_ViewportData() { IM_ASSERT(Hwnd == nullptr); }
};
@ -974,6 +976,14 @@ static void ImGui_ImplWin32_GetWin32StyleFromViewportFlags(ImGuiViewportFlags fl
*out_ex_style |= WS_EX_TOPMOST;
}
static HWND ImGui_ImplWin32_GetHwndFromViewportID(ImGuiID viewport_id)
{
if (viewport_id != 0)
if (ImGuiViewport* viewport = ImGui::FindViewportByID(viewport_id))
return (HWND)viewport->PlatformHandle;
return nullptr;
}
static void ImGui_ImplWin32_CreateWindow(ImGuiViewport* viewport)
{
ImGui_ImplWin32_ViewportData* vd = IM_NEW(ImGui_ImplWin32_ViewportData)();
@ -981,10 +991,7 @@ static void ImGui_ImplWin32_CreateWindow(ImGuiViewport* viewport)
// Select style and parent window
ImGui_ImplWin32_GetWin32StyleFromViewportFlags(viewport->Flags, &vd->DwStyle, &vd->DwExStyle);
HWND parent_window = nullptr;
if (viewport->ParentViewportId != 0)
if (ImGuiViewport* parent_viewport = ImGui::FindViewportByID(viewport->ParentViewportId))
parent_window = (HWND)parent_viewport->PlatformHandle;
vd->HwndParent = ImGui_ImplWin32_GetHwndFromViewportID(viewport->ParentViewportId);
// Create window
RECT rect = { (LONG)viewport->Pos.x, (LONG)viewport->Pos.y, (LONG)(viewport->Pos.x + viewport->Size.x), (LONG)(viewport->Pos.y + viewport->Size.y) };
@ -992,7 +999,7 @@ static void ImGui_ImplWin32_CreateWindow(ImGuiViewport* viewport)
vd->Hwnd = ::CreateWindowEx(
vd->DwExStyle, _T("ImGui Platform"), _T("Untitled"), vd->DwStyle, // Style, class name, window name
rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, // Window area
parent_window, nullptr, ::GetModuleHandle(nullptr), nullptr); // Parent window, Menu, Instance, Param
vd->HwndParent, nullptr, ::GetModuleHandle(nullptr), nullptr); // Owner window, Menu, Instance, Param
vd->HwndOwned = true;
viewport->PlatformRequestResize = false;
viewport->PlatformHandle = viewport->PlatformHandleRaw = vd->Hwnd;
@ -1029,10 +1036,26 @@ static void ImGui_ImplWin32_ShowWindow(ImGuiViewport* viewport)
static void ImGui_ImplWin32_UpdateWindow(ImGuiViewport* viewport)
{
// (Optional) Update Win32 style if it changed _after_ creation.
// Generally they won't change unless configuration flags are changed, but advanced uses (such as manually rewriting viewport flags) make this useful.
ImGui_ImplWin32_ViewportData* vd = (ImGui_ImplWin32_ViewportData*)viewport->PlatformUserData;
IM_ASSERT(vd->Hwnd != 0);
// Update Win32 parent if it changed _after_ creation
// Unlike style settings derived from configuration flags, this is more likely to change for advanced apps that are manipulating ParentViewportID manually.
HWND new_parent = ImGui_ImplWin32_GetHwndFromViewportID(viewport->ParentViewportId);
if (new_parent != vd->HwndParent)
{
// Win32 windows can either have a "Parent" (for WS_CHILD window) or an "Owner" (which among other thing keeps window above its owner).
// Our Dear Imgui-side concept of parenting only mostly care about what Win32 call "Owner".
// The parent parameter of CreateWindowEx() sets up Parent OR Owner depending on WS_CHILD flag. In our case an Owner as we never use WS_CHILD.
// Calling ::SetParent() here would be incorrect: it will create a full child relation, alter coordinate system and clipping.
// Calling ::SetWindowLongPtr() with GWLP_HWNDPARENT seems correct although poorly documented.
// https://devblogs.microsoft.com/oldnewthing/20100315-00/?p=14613
vd->HwndParent = new_parent;
::SetWindowLongPtr(vd->Hwnd, GWLP_HWNDPARENT, (LONG_PTR)vd->HwndParent);
}
// (Optional) Update Win32 style if it changed _after_ creation.
// Generally they won't change unless configuration flags are changed, but advanced uses (such as manually rewriting viewport flags) make this useful.
DWORD new_style;
DWORD new_ex_style;
ImGui_ImplWin32_GetWin32StyleFromViewportFlags(viewport->Flags, &new_style, &new_ex_style);
@ -1261,3 +1284,5 @@ static void ImGui_ImplWin32_ShutdownPlatformInterface()
}
//---------------------------------------------------------------------------------------------------------
#endif // #ifndef IMGUI_DISABLE

View file

@ -16,6 +16,7 @@
#pragma once
#include "imgui.h" // IMGUI_IMPL_API
#ifndef IMGUI_DISABLE
IMGUI_IMPL_API bool ImGui_ImplWin32_Init(void* hwnd);
IMGUI_IMPL_API bool ImGui_ImplWin32_InitForOpenGL(void* hwnd);
@ -45,3 +46,5 @@ IMGUI_IMPL_API float ImGui_ImplWin32_GetDpiScaleForMonitor(void* monitor); //
// - Use to enable alpha compositing transparency with the desktop.
// - Use together with e.g. clearing your framebuffer with zero-alpha.
IMGUI_IMPL_API void ImGui_ImplWin32_EnableAlphaCompositing(void* hwnd); // HWND hwnd
#endif // #ifndef IMGUI_DISABLE

View file

@ -5,25 +5,30 @@ This document holds the user-facing changelog that we also use in release notes.
We generally fold multiple commits pertaining to the same topic as a single entry.
Changes to backends are also included within the individual .cpp files of each backend.
RELEASE NOTES: https://github.com/ocornut/imgui/releases
REPORT ISSUES: https://github.com/ocornut/imgui/issues
DISCUSS, ASK QUESTIONS: https://github.com/ocornut/imgui/discussions
WIKI https://github.com/ocornut/imgui/wiki
FAQ https://www.dearimgui.com/faq/
RELEASE NOTES: https://github.com/ocornut/imgui/releases
WIKI https://github.com/ocornut/imgui/wiki
GETTING STARTED https://github.com/ocornut/imgui/wiki/Getting-Started
GLOSSARY https://github.com/ocornut/imgui/wiki/Glossary
ISSUES & SUPPORT https://github.com/ocornut/imgui/issues
WHEN TO UPDATE?
- Keeping your copy of Dear ImGui updated regularly is recommended.
- It is generally safe to sync to the latest commit in master or docking branches
The library is fairly stable and regressions tends to be fixed fast when reported.
- It is generally safe and recommended to sync to the latest commit in 'master' or 'docking'
branches. The library is fairly stable and regressions tends to be fixed fast when reported.
HOW TO UPDATE?
- Overwrite every file except imconfig.h (if you have modified it).
- You may also locally branch to modify imconfig.h and merge latest into your branch.
- Update submodule or copy/overwrite every file.
- About imconfig.h:
- You may modify your copy of imconfig.h, in this case don't overwrite it.
- or you may locally branch to modify imconfig.h and merge/rebase latest.
- or you may '#define IMGUI_USER_CONFIG "my_config_file.h"' globally from your build system to
specify a custom path for your imconfig.h file and instead not have to modify the default one.
- Read the `Breaking Changes` section (in imgui.cpp or here in the Changelog).
- 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.
- If you are dropping this repository in your codebase, please leave the demo and text files in there, they will be useful.
- If you are copying this repository in your codebase, please leave the demo and documentations files in there, they will be useful.
- You may diff your previous Changelog with the one you just copied and read that diff.
- You may enable `IMGUI_DISABLE_OBSOLETE_FUNCTIONS` in imconfig.h to forcefully disable legacy names and symbols.
Doing it every once in a while is a good way to make sure you are not using obsolete symbols. Dear ImGui is in active development,
@ -32,70 +37,193 @@ HOW TO UPDATE?
-----------------------------------------------------------------------
DOCKING+MULTI-VIEWPORT BRANCH (In Progress)
VERSION 1.89.8 (Released 2023-08-01)
-----------------------------------------------------------------------
DOCKING FEATURES
(see https://github.com/ocornut/imgui/wiki/Docking for quick intro)
Decorated log and release notes: https://github.com/ocornut/imgui/releases/tag/v1.89.8
- Added Docking system: [BETA] (#2109, #351)
- Added ImGuiConfigFlags_DockingEnable flag to enable Docking.
Set with `io.ConfigFlags |= ImGuiConfigFlags_DockingEnable;`.
- Added DockSpace(), DockSpaceOverViewport() API.
- Added ImGuiDockNodeFlags flags for DockSpace().
- Added SetNextWindowDockID(), SetNextWindowClass() API.
- Added GetWindowDockID(), IsWindowDocked() API.
- Added ImGuiWindowFlags_NoDocking window flag to disable the possibility for a window to be docked.
Popup, Menu and Child windows always have the ImGuiWindowFlags_NoDocking flag set.
- Added ImGuiWindowClass to specify advanced docking/viewport related flags via SetNextWindowClass().
- Added io.ConfigDockingNoSplit option.
- Added io.ConfigDockingWithShift option.
- Added io.ConfigDockingAlwaysTabBar option.
- Added io.ConfigDockingTransparentPayload option.
- Style: Added ImGuiCol_DockingPreview, ImGuiCol_DockingEmptyBg colors.
- Demo: Added "DockSpace" example app showcasing use of explicit dockspace nodes.
Breaking changes:
MULTI-VIEWPORT FEATURES
(see https://github.com/ocornut/imgui/wiki/Multi-Viewports for quick intro)
Breaking Changes:
- IMPORTANT: When multi-viewports are enabled (with io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable),
all coordinates/positions will be in your natural OS coordinates space. It means that:
- Reference to hard-coded positions such as in SetNextWindowPos(ImVec2(0,0)) are _probably_ not what you want anymore.
Use GetMainViewport()->Pos to offset hard-coded positions, e.g. SetNextWindowPos(GetMainViewport()->Pos).
- Likewise io.MousePos and GetMousePos() will use OS coordinates.
If you query mouse positions to interact with non-imgui coordinates you will need to offset them.
e.g. subtract GetWindowViewport()->Pos.
- IO: Removed io.DisplayVisibleMin, io.DisplayVisibleMax settings (they were marked obsoleted, used to clip within the (0,0)..(DisplaySize) range).
- IO: Obsoleted io.ClearInputCharacters() (added in 1.47) as it now ambiguous
and often incorrect/misleading considering the existence of a higher-level
input queue. This is automatically cleared by io.ClearInputsKeys(). (#4921)
- ImDrawData: CmdLists[] array is now owned, changed from 'ImDrawList**' to
'ImVector<ImDrawList*>'. Majority of users shouldn't be affected, but you
cannot compare to NULL nor reassign manually anymore.
Instead use AddDrawList(). Allocation count are identical. (#6406, #4879, #1878)
Other changes:
(FIXME: This need a fuller explanation!)
- Added ImGuiPlatformIO structure and GetPlatformIO().
- Similarly to ImGuiIO and GetIO(), this structure is the main point of communication for backends supporting multi-viewports.
- Backend sets functions in ImGuiPlatformIO to manipulate platform windows.
- ImGuiPlatformIO::Monitors is a list of platform monitors (input from backend)
- ImGuiPlatformIO::Viewports is a list of viewports (output from dear imgui)
- Added ImGuiPlatformMonitor to feed OS monitor information in the ImGuiPlatformIO::Monitors.
- Added GetWindowViewport(), SetNextWindowViewport().
- Added GetWindowDpiScale().
- Added GetOverlayDrawList(ImGuiViewport* viewport).
The no-parameter version of GetOverlayDrawList() return the overlay for the current window's viewport.
- Added UpdatePlatformWindows(), RenderPlatformWindowsDefault(), DestroyPlatformWindows() for usage in application setup.
- Added FindViewportByID(), FindViewportByPlatformHandle() for usage by backends.
- Added ImGuiConfigFlags_ViewportsEnable configuration flag and other viewport options.
- Added io.ConfigViewportsNoAutoMerge option.
- Added io.ConfigViewportsNoTaskBarIcon option.
- Added io.ConfigViewportsNoDecoration option.
- Added io.ConfigViewportsNoDefaultParent option.
- Added ImGuiBackendFlags_PlatformHasViewports, ImGuiBackendFlags_RendererHasViewports, ImGuiBackendFlags_HasMouseHoveredViewport backend flags.
- Added io.AddMouseViewportEvent() (optional _even_ for multi-viewport support, tied to ImGuiBackendFlags_HasMouseHoveredViewport flag).
- Expanded ImGuiViewport structure, ImGuiViewportFlags flags.
- Added ImGuiWindowClass and SetNextWindowClass() for passing viewport related hints to the OS/platform back-end.
- Examples: Renderer: OpenGL2, OpenGL3, DirectX9, DirectX10, DirectX11, DirectX12, Vulkan: Added support for multi-viewports.
- Examples: Platforms: Win32, GLFW, SDL2: Added support for multi-viewports.
Note that Linux/Mac still have inconsistent support for multi-viewports. If you want to help see https://github.com/ocornut/imgui/issues/2117.
- Fonts: ImFontConfig::OversampleH now defaults to 2 instead of 3, since the
quality increase is largely minimal.
- Fonts, imgui_freetype: Added support to render OpenType SVG fonts using lunasvg.
Requires enabling IMGUI_ENABLE_FREETYPE_LUNASVG along with IMGUI_ENABLE_FREETYPE,
and providing headers/libraries for lunasvg. (#6591, #6607) [@sakiodre]
- ImDrawData: CmdLists[] array is now an ImVector<> owned by ImDrawData rather
than a pointer to internal state.
- This makes it easier for user to create their own or append to an existing draw data.
Added a ImDrawData::AddDrawList() helper function to do that. (#6406, #4879, #1878)
- This makes it easier to perform a deep-swap instead of a deep-copy, as array
ownership is now clear. (#6597, #6475, #6167, #5776, #5109, #4763, #3515, #1860)
- Syntax and allocation count are otherwise identical.
- Fixed CTRL+Tab dimming background assert when target window has a callback
in the last ImDrawCmd. (#4857, #5937)
- IsItemHovered: Fixed ImGuiHoveredFlags_ForTooltip for Keyboard/Gamepad navigation,
got broken prior to 1.89.7 due to an unrelated change making flags conflict. (#6622, #1485)
- InputText: Fixed a case where deactivation frame would write to underlying
buffer or call CallbackResize although unnecessary, in a frame where the
return value was false.
- Tables: fixed GetContentRegionAvail().y report not taking account of lower cell
padding or of using ImGuiTableFlags_NoHostExtendY. Not taking it into account
would make the idiom of creating vertically bottom-aligned content (e.g. a child
window) inside a table make the parent window erroneously have a scrollbar. (#6619)
- Tables: fixed calculation of multi-instance shared decoration/scrollbar width of
scrolling tables, to avoid flickering width variation when resizing down a table
hosting a child window. (#5920, #6619)
- Scrollbar: layout needs to take account of window border size, so a border size
will slightly reduce scrollbar size. Generally we tried to make it that window
border size has no incidence on layout but this can't work with thick borders. (#2522)
- IO: Added io.ClearEventsQueue() to clear incoming inputs events. (#4921)
May be useful in conjunction with io.ClearInputsKeys() if you need to clear
both current inputs state and queued events (e.g. when using blocking native
dialogs such as Windows's ::MessageBox() or ::GetOpenFileName()).
- IO: Changed io.ClearInputsKeys() specs to also clear current frame character buffer
(what now obsoleted io.ClearInputCharacters() did), as this is effectively the
desirable behavior.
- Misc: Added IMGUI_DISABLE_STB_SPRINTF_IMPLEMENTATION config macro to disable
stb_sprintf implementation when using IMGUI_USE_STB_SPRINTF. (#6626) [@septag]
- Misc: Avoid stb_textedit.h reincluding string.h while in a namespace, which
messes up with building with Clang Modules. (#6653, #4791) [@JohelEGP]
- Demo: Better showcase use of SetNextItemAllowOverlap(). (#6574, #6512, #3909, #517)
- Demo: Showcase a few more InputText() flags.
- Backends: Made all backends sources files support global IMGUI_DISABLE. (#6601)
- Backends: GLFW: Revert ignoring mouse data on GLFW_CURSOR_DISABLED as it can be used
differently. User may set ImGuiConfigFlags_NoMouse if desired. (#5625, #6609) [@scorpion-26]
- Backends: WebGPU: Update for changes in Dawn. (#6602, #6188) [@williamhCode]
- Examples: Vulkan: Creating minimal descriptor pools to fit only what is needed by
example. (#6642) [@SaschaWillem]
Docking+Viewports Branch:
- Docking, Style: resizing separators use same colors as window borders (ImGuiCol_Border)
for consistency. With default styles it doesn't make a big difference. (#2522) [@rmitton]
In the future if we promote using thick value for inner/outer docking padding we may
need to introduce new colors for it.
- Docking: added style.DockingSeparatorSize, ImGuiStyleVar_DockingSeparatorSize. Now
also scaled by style.ScaleAllSizes(). (#3481, #4721, #2522) [@PossiblyAShrub, @wobbier]
- Docking: fixed rendering of docked-window scrollbar above outer border. (#2522)
-----------------------------------------------------------------------
VERSION 1.89.7 (Released 2023-07-04)
-----------------------------------------------------------------------
Decorated log and release notes: https://github.com/ocornut/imgui/releases/tag/v1.89.7
Breaking changes:
- Moved io.HoverDelayShort/io.HoverDelayNormal to style.HoverDelayShort/style.HoverDelayNormal.
As the fields were added in 1.89 and expected to be left unchanged by most users, or only
tweaked once during app initialisation, we are exceptionally accepting the breakage.
Majority of users should not even notice.
- Overlapping items: (#6512, #3909, #517)
- Added 'SetNextItemAllowOverlap()' (called before an item) as a replacement for using
'SetItemAllowOverlap()' (called after an item). This is roughly equivalent to using the
legacy 'SetItemAllowOverlap()' call (public API) + ImGuiButtonFlags_AllowOverlap (internal).
- Obsoleted 'SetItemAllowOverlap()': it didn't and couldn't work reliably since 1.89 (2022-11-15),
and relied on ambiguously defined design. Use 'SetNextItemAllowOverlap()' before item instead.
- Selectable, TreeNode: When using ImGuiSelectableFlags_AllowOverlap/ImGuiTreeNodeFlags_AllowOverlap
and holding item held, overlapping widgets won't appear as hovered. (#6512, #3909)
While this fixes a common small visual issue, it also means that calling IsItemHovered()
after a non-reactive elements - e.g. Text() - overlapping an active one may fail if you don't
use IsItemHovered(ImGuiHoveredFlags_AllowWhenBlockedByActiveItem). (#6610)
- Renamed 'ImGuiTreeNodeFlags_AllowItemOverlap' to 'ImGuiTreeNodeFlags_AllowOverlap'.
- Renamed 'ImGuiSelectableFlags_AllowItemOverlap' to 'ImGuiSelectableFlags_AllowOverlap'
- Kept redirecting enums (will obsolete).
Other changes:
- Tooltips/IsItemHovered() related changes:
- Tooltips: Added SetItemTooltip() and BeginItemTooltip() functions.
They are shortcuts for the common idiom of using IsItemHovered().
- SetItemTooltip("Hello") == if (IsItemHovered(ImGuiHoveredFlags_Tooltip)) { SetTooltip("Hello"); }
- BeginItemTooltip() == IsItemHovered(ImGuiHoveredFlags_Tooltip) && BeginTooltip()
The newly added ImGuiHoveredFlags_Tooltip is meant to facilitate standardizing
mouse hovering delays and rules for a given application.
The previously common idiom of using 'if (IsItemHovered()) { SetTooltip(...); }'
won't use delay or stationary test.
- IsItemHovered: Added ImGuiHoveredFlags_Stationary to require mouse being
stationary when hovering a new item. Added style.HoverStationaryDelay (~0.15 sec).
Once the mouse has been stationary once the state is preserved for same item. (#1485)
- IsItemHovered: Added ImGuiHoveredFlags_ForTooltip as a shortcut for pulling flags
from style.HoverFlagsForTooltipMouse or style.HoverFlagsForTooltipNav depending
on active inputs (#1485)
- style.HoverFlagsForTooltipMouse defaults to 'ImGuiHoveredFlags_Stationary | ImGuiHoveredFlags_DelayShort'
- style.HoverFlagsForTooltipNav defaults to 'ImGuiHoveredFlags_NoSharedDelay | ImGuiHoveredFlags_DelayNormal'.
- Tooltips: Tweak default offset for non-drag and drop tooltips so underlying items
isn't covered as much. (Match offset for drag and drop tooltips)
- IsItemHovered: Tweaked default value of style.HoverDelayNormal from 0.30 to 0.40,
Tweaked default value of style.HoverDelayShort from 0.10 to 0.15. (#1485)
- IsItemHovered: Added ImGuiHoveredFlags_AllowWhenOverlappedByWindow to ignore window-overlap only.
Option ImGuiHoveredFlags_AllowWhenOverlapped now expand into a combination of both
_AllowWhenOverlappedByWindow + _AllowWhenOverlappedByItem, matching old behavior.
- Overlapping items: (#6512, #3909, #517)
- Most item types should now work with SetNextItemAllowOverlap(). (#6512, #3909, #517)
- Fixed first frame of an overlap highlighting underlying item if previous frame didn't hover anything.
- IsItemHovered: Changed to return false when querying an item using AllowOverlap mode which
is being overlapped. Added ImGuiHoveredFlags_AllowWhenOverlappedByItem to opt-out. (#6512, #3909, #517)
- IsWindowHovered: Added support for ImGuiHoveredFlags_Stationary.
- IsWindowHovered, IsItemHovered: Assert when passed any unsupported flags.
- Tables: Fixed a regression in 1.89.6 leading to the first column of tables with either
ScrollX or ScrollY flags from being impossible to resize. (#6503)
- CollapsingHeader/TreeNode: Fixed text padding when using _Framed+_Leaf flags. (#6549) [@BobbyAnguelov]
- InputText: Fixed not returning true when buffer is cleared while using the
ImGuiInputTextFlags_EscapeClearsAll flag. (#5688, #2620)
- InputText: Fixed a crash on deactivating a ReadOnly buffer. (#6570, #6292, #4714)
- InputText: ImGuiInputTextCallbackData::InsertChars() accept (NULL,NULL) range, in order to conform
to common idioms (e.g. passing .data(), .data() + .size() from a null string). (#6565, #6566, #3615)
- Combo: Made simple/legacy Combo() function not returns true when picking already selected item.
This is consistent with other widgets. If you need something else, you can use BeginCombo(). (#1182)
- Clipper: Rework inner logic to allow functioning with a zero-clear constructor.
This is order to facilitate usage for language bindings (e.g cimgui or dear_binding)
where user may not be calling a constructor manually. (#5856)
- Drag and Drop: Apply default behavior of drag source not reporting itself as hovered
at lower-level, so DragXXX, SliderXXX, InputXXX, Plot widgets are fulfilling it.
(Behavior doesn't apply when ImGuiDragDropFlags_SourceNoDisableHover is set).
- Modals: In the case of nested modal, made sure that focused or appearing windows are
moved below the lowest blocking modal (rather than the highest one). (#4317)
- GetKeyName(): Fixed assert with ImGuiMod_XXX values when IMGUI_DISABLE_OBSOLETE_KEYIO is set.
- Debug Tools: Added 'io.ConfigDebugIniSettings' option to save .ini data with extra
comments. Currently mainly for inspecting Docking .ini data, but makes saving slower.
- Demo: Added more developed "Widgets->Tooltips" section. (#1485)
- Backends: OpenGL3: Fixed support for glBindSampler() backup/restore on ES3. (#6375, #6508) [@jsm174]
- Backends: OpenGL3: Fixed erroneous use glGetIntegerv(GL_CONTEXT_PROFILE_MASK) on contexts
lower than 3.2. (#6539, #6333) [@krumelmonster]
- Backends: Vulkan: Added optional support for VK_KHR_dynamic_rendering (Vulkan 1.3+) in the
backend for applications using it. User needs to set 'init_info->UseDynamicRendering = true'
and 'init_info->ColorAttachmentFormat'. RenderPass becomes unused. (#5446, #5037) [@spnda, @cmarcelo]
- Backends: GLFW: Accept glfwGetTime() not returning a monotonically increasing value.
This seems to happens on some Windows setup when peripherals disconnect, and is likely
to also happen on browser+Emscripten. Matches similar 1.89.4 fix in SDL backend. (#6491)
- Examples: Win32+OpenGL3: Changed DefWindowProc() to DefWindowProcW() to match other examples
and support the example app being compiled without UNICODE. (#6516, #5725, #5961, #5975) [@yenixing]
Docking+Viewports Branch:
- Viewports+Docking: Fixed extraneous viewport+platform-window recreation in various
combination of showing or hiding windows, docking with/without split, undocking.
While with some backends and without OS decorations, some extraneous window recreation
were visibly not noticeable, they would typically become noticeable when enabling
OS decorations on those windows (e.g. Windows title bar fade-in/animation).
- Viewports: Closing a viewport via OS/platform means (e.g. OS close button or task-bar menu),
mark all windows in this viewport as closed.
- Docking: Fixed one-frame flickering on reappearing windows binding to a dock node
where a later-submitted window was already bound.
- Docking: Fixed dragging from title-bar empty space (regression from 1.88 related to
keeping ID alive when calling low-level ButtonBehavior() directly). (#5181, #2645)
- Docking: [Internal] DockBuilderDockWindow() API calls don't clear docking order
if the target node is same as existing one.
- Backends: Win32: Added support for changing ParentViewportID after viewport creation.
-----------------------------------------------------------------------
@ -643,7 +771,7 @@ Other Changes:
- ColorEdit3: fixed id collision leading to an assertion. (#5707)
- IsItemHovered: Added ImGuiHoveredFlags_DelayNormal and ImGuiHoveredFlags_DelayShort flags,
allowing to introduce a shared delay for tooltip idioms. The delays are respectively
io.HoverDelayNormal (default to 0.30f) and io.HoverDelayFast (default to 0.10f). (#1485)
io.HoverDelayNormal (default to 0.30f) and io.HoverDelayShort (default to 0.10f). (#1485)
- IsItemHovered: Added ImGuiHoveredFlags_NoSharedDelay to disable sharing delays between items,
so moving from one item to a nearby one will requires delay to elapse again. (#1485)
- Tables: activating an ID (e.g. clicking button inside) column doesn't prevent columns

View file

@ -11,7 +11,7 @@
## Getting Started & General Advice
- Article: [How To Ask Good Questions](https://bit.ly/3nwRnx1).
- Please browse the [Wiki](https://github.com/ocornut/imgui/wiki) to find code snippets, links and other resources (e.g. [Useful extensions](https://github.com/ocornut/imgui/wiki/Useful-Extensions)).
- Please browse the [Wiki](https://github.com/ocornut/imgui/wiki) to find code snippets, links and other resources (e.g. [Getting Started](https://github.com/ocornut/imgui/wiki/Getting-Started), [Useful extensions](https://github.com/ocornut/imgui/wiki/Useful-Extensions)).
- Please read [docs/FAQ.md](https://github.com/ocornut/imgui/blob/master/docs/FAQ.md).
- Please read [docs/FONTS.md](https://github.com/ocornut/imgui/blob/master/docs/FONTS.md) if your question relates to fonts or text.
- Please read one of the [examples/](https://github.com/ocornut/imgui/tree/master/examples) application if your question relates to setting up Dear ImGui.

View file

@ -50,7 +50,8 @@ or view this file with any Markdown viewer.
**This library is poorly documented at the moment and expects the user to be acquainted with C/C++.**
- The [Wiki](https://github.com/ocornut/imgui/wiki) is a hub to many resources and links.
- Dozens of standalone example applications using e.g. OpenGL/DirectX are provided in the [examples/](https://github.com/ocornut/imgui/blob/master/examples/) folder to explain how to integrate Dear ImGui with your own engine/application. You can run those applications and explore them.
- Handy [Getting Started](https://github.com/ocornut/imgui/wiki/Getting-Started) guide to integrate Dear ImGui in an existing application.
- 20+ standalone example applications using e.g. OpenGL/DirectX are provided in the [examples/](https://github.com/ocornut/imgui/blob/master/examples/) folder to explain how to integrate Dear ImGui with your own engine/application. You can run those applications and explore them.
- See demo code in [imgui_demo.cpp](https://github.com/ocornut/imgui/blob/master/imgui_demo.cpp) and particularly the `ImGui::ShowDemoWindow()` function. The demo covers most features of Dear ImGui, so you can read the code and see its output.
- See documentation: [Backends](https://github.com/ocornut/imgui/blob/master/docs/BACKENDS.md), [Examples](https://github.com/ocornut/imgui/blob/master/docs/EXAMPLES.md), [Fonts](https://github.com/ocornut/imgui/blob/master/docs/FONTS.md).
- See documentation and comments at the top of [imgui.cpp](https://github.com/ocornut/imgui/blob/master/imgui.cpp) + general API comments in [imgui.h](https://github.com/ocornut/imgui/blob/master/imgui.h).
@ -90,6 +91,7 @@ Many projects are using this branch and it is kept in sync with master regularly
### Q: How to get started?
Read [Getting Started](https://github.com/ocornut/imgui/wiki/Getting-Started). <BR>
Read [EXAMPLES.md](https://github.com/ocornut/imgui/blob/master/docs/EXAMPLES.md). <BR>
Read [BACKENDS.md](https://github.com/ocornut/imgui/blob/master/docs/BACKENDS.md). <BR>
Read `PROGRAMMER GUIDE` section of [imgui.cpp](https://github.com/ocornut/imgui/blob/master/imgui.cpp). <BR>
@ -163,8 +165,8 @@ Console SDK also sometimes provide equivalent tooling or wrapper for Synergy-lik
---
### Q: I integrated Dear ImGui in my engine and little squares are showing instead of text...
Your renderer is not using the font texture correctly or it hasn't been uploaded to the GPU.
- If this happens using the standard backends: A) have you modified the font atlas after `ImGui_ImplXXX_NewFrame()`? B) maybe the texture failed to upload, which could happens if for some reason your texture is too big. Also see [docs/FONTS.md](https://github.com/ocornut/imgui/blob/master/docs/FONTS.md).
Your renderer backend is not using the font texture correctly or it hasn't been uploaded to the GPU.
- If this happens using the standard backends: A) have you modified the font atlas after `ImGui_ImplXXX_NewFrame()`? B) maybe the texture failed to upload, which **can if your texture atlas is too big**. Also see [docs/FONTS.md](https://github.com/ocornut/imgui/blob/master/docs/FONTS.md).
- If this happens with a custom backend: make sure you have uploaded the font texture to the GPU, that all shaders are rendering states are setup properly (e.g. texture is bound). Compare your code to existing backends and use a graphics debugger such as [RenderDoc](https://renderdoc.org) to debug your rendering states.
##### [Return to Index](#index)
@ -568,44 +570,15 @@ io.Fonts->AddFontFromFileTTF("MyFolder/MyFont.ttf", size); // ALSO CORRECT
### Q: How can I easily use icons in my application?
The most convenient and practical way is to merge an icon font such as FontAwesome inside your
main font. Then you can refer to icons within your strings.
You may want to see `ImFontConfig::GlyphMinAdvanceX` to make your icon look monospace to facilitate alignment.
(Read the [docs/FONTS.md](https://github.com/ocornut/imgui/blob/master/docs/FONTS.md) file for more details about icons font loading.)
With some extra effort, you may use colorful icons by registering custom rectangle space inside the font atlas,
and copying your own graphics data into it. See docs/FONTS.md about using the AddCustomRectFontGlyph API.
Read the [docs/FONTS.md](https://github.com/ocornut/imgui/blob/master/docs/FONTS.md) file for more details about icons font loading.
##### [Return to Index](#index)
---
### Q: How can I load multiple fonts?
Use the font atlas to pack them into a single texture:
(Read the [docs/FONTS.md](https://github.com/ocornut/imgui/blob/master/docs/FONTS.md) file and the code in ImFontAtlas for more details.)
```cpp
ImGuiIO& io = ImGui::GetIO();
ImFont* font0 = io.Fonts->AddFontDefault();
ImFont* font1 = io.Fonts->AddFontFromFileTTF("myfontfile.ttf", size_in_pixels);
ImFont* font2 = io.Fonts->AddFontFromFileTTF("myfontfile2.ttf", size_in_pixels);
io.Fonts->GetTexDataAsRGBA32() or GetTexDataAsAlpha8()
// the first loaded font gets used by default
// use ImGui::PushFont()/ImGui::PopFont() to change the font at runtime
// Options
ImFontConfig config;
config.OversampleH = 2;
config.OversampleV = 1;
config.GlyphOffset.y -= 1.0f; // Move everything by 1 pixel up
config.GlyphExtraSpacing.x = 1.0f; // Increase spacing between characters
io.Fonts->AddFontFromFileTTF("myfontfile.ttf", size_pixels, &config);
// Combine multiple fonts into one (e.g. for icon fonts)
static ImWchar ranges[] = { 0xf000, 0xf3ff, 0 };
ImFontConfig config;
config.MergeMode = true;
io.Fonts->AddFontDefault();
io.Fonts->AddFontFromFileTTF("fontawesome-webfont.ttf", 16.0f, &config, ranges); // Merge icon font
io.Fonts->AddFontFromFileTTF("myfontfile.ttf", size_pixels, nullptr, &config, io.Fonts->GetGlyphRangesJapanese()); // Merge japanese glyphs
```
Use the font atlas to pack them into a single texture. Read [docs/FONTS.md](https://github.com/ocornut/imgui/blob/master/docs/FONTS.md) for more details.
##### [Return to Index](#index)

View file

@ -11,10 +11,7 @@ In the [misc/fonts/](https://github.com/ocornut/imgui/tree/master/misc/fonts) fo
**Also read the FAQ:** https://www.dearimgui.com/faq (there is a Fonts section!)
## Index
- [Readme First](#readme-first)
- [About Filenames](#about-filenames)
- [About UTF-8 Encoding](#about-utf-8-encoding)
- [Debug Tools](#debug-tools)
- [Troubleshooting](#troubleshooting)
- [How should I handle DPI in my application?](#how-should-i-handle-dpi-in-my-application)
- [Fonts Loading Instructions](#fonts-loading-instructions)
- [Using Icon Fonts](#using-icon-fonts)
@ -23,103 +20,44 @@ In the [misc/fonts/](https://github.com/ocornut/imgui/tree/master/misc/fonts) fo
- [Using Custom Glyph Ranges](#using-custom-glyph-ranges)
- [Using Custom Colorful Icons](#using-custom-colorful-icons)
- [Using Font Data Embedded In Source Code](#using-font-data-embedded-in-source-code)
- [About Filenames](#about-filenames)
- [About UTF-8 Encoding](#about-utf-8-encoding)
- [Debug Tools](#debug-tools)
- [Credits/Licenses For Fonts Included In Repository](#creditslicenses-for-fonts-included-in-repository)
- [Font Links](#font-links)
---------------------------------------
## Readme First
## Troubleshooting
**A vast majority of font and text related issues encountered comes from 3 things:**
- Invalid filename due to use of `\` or unexpected working directory. See [About Filenames](#about-filenames). AddFontXXX functions should assert if the filename is incorrect.
- Invalid UTF-8 encoding of your non-ASCII strings. See [About UTF-8 Encoding](#about-utf-8-encoding). Use the encoding viewer to confirm yours is correct.
- You need to load a font with explicit glyph ranges if you want to use non-ASCII characters. See [Fonts Loading Instructions](#fonts-loading-instructions). Use Metrics/Debugger->Fonts to confirm loaded fonts and loaded glyph ranges.
**A vast majority of font and text related issues encountered comes from 4 things:**
The third point is a current constraint of Dear ImGui (which we will lift in the future): when loading a font you need to specify which characters glyphs to load.
All loaded fonts glyphs are rendered into a single texture atlas ahead of time. Calling either of `io.Fonts->GetTexDataAsAlpha8()`, `io.Fonts->GetTexDataAsRGBA32()` or `io.Fonts->Build()` will build the atlas. This is generally called by the Renderer backend, e.g. `ImGui_ImplDX11_NewFrame()` calls it.
### (1) Invalid filename due to use of `\` or unexpected working directory.
**If you use custom glyphs ranges, make sure the array is persistent** and available during the calls to `GetTexDataAsAlpha8()/GetTexDataAsRGBA32()/Build()`.
See [About Filenames](#about-filenames). AddFontXXX functions should assert if the filename is incorrect.
##### [Return to Index](#index)
### (2) Invalid UTF-8 encoding of your non-ASCII strings.
## About Filenames
See [About UTF-8 Encoding](#about-utf-8-encoding). Use the encoding viewer to confirm encoding of string literal in your source code is correct.
**Please note that many new C/C++ users have issues loading their files _because the filename they provide is wrong_ due to incorrect assumption of what is the current directory.**
### (3) Missing glyph ranges.
Two things to watch for:
You need to load a font with explicit glyph ranges if you want to use non-ASCII characters. See [Fonts Loading Instructions](#fonts-loading-instructions). Use [Debug Tools](#debug-tools) confirm loaded fonts and loaded glyph ranges.
(1) In C/C++ and most programming languages if you want to use a backslash `\` within a string literal, you need to write it double backslash `\\`. At it happens, Windows uses backslashes as a path separator, so be mindful.
```cpp
io.Fonts->AddFontFromFileTTF("MyFiles\MyImage01.jpg", ...); // This is INCORRECT!!
io.Fonts->AddFontFromFileTTF("MyFiles\\MyImage01.jpg", ...); // This is CORRECT
```
In some situations, you may also use `/` path separator under Windows.
This is a current constraint of Dear ImGui (which we will lift in the future): when loading a font you need to specify which characters glyphs to load.
All loaded fonts glyphs are rendered into a single texture atlas ahead of time. Calling either of `io.Fonts->GetTexDataAsAlpha8()`, `io.Fonts->GetTexDataAsRGBA32()` or `io.Fonts->Build()` will build the atlas. This is generally called by the Renderer backend, e.g. `ImGui_ImplDX11_NewFrame()` calls it. **If you use custom glyphs ranges, make sure the array is persistent** and available during the calls to `GetTexDataAsAlpha8()/GetTexDataAsRGBA32()/Build()`.
(2) Make sure your IDE/debugger settings starts your executable from the right working (current) directory. In Visual Studio you can change your working directory in project `Properties > General > Debugging > Working Directory`. People assume that their execution will start from the root folder of the project, where by default it often starts from the folder where object or executable files are stored.
```cpp
io.Fonts->AddFontFromFileTTF("MyImage01.jpg", ...); // Relative filename depends on your Working Directory when running your program!
io.Fonts->AddFontFromFileTTF("../MyImage01.jpg", ...); // Load from the parent folder of your Working Directory
```
##### [Return to Index](#index)
### (4) Font atlas texture fails to upload to GPU.
This is often of byproduct of point 3. If you have large number of glyphs or multiple fonts, the texture may become too big for your graphics API. **The typical result of failing to upload a texture is if every glyph or everything appears as empty black or white rectangle.** Mind the fact that some graphics drivers have texture size limitation. If you are building a PC application, mind the fact that your users may use hardware with lower limitations than yours.
## About UTF-8 Encoding
**For non-ASCII characters display, a common user issue is not passing correctly UTF-8 encoded strings.**
(1) We provide a function `ImGui::DebugTextEncoding(const char* text)` which you can call to verify the content of your UTF-8 strings.
This is a convenient way to confirm that your encoding is correct.
```cpp
ImGui::SeparatorText("CORRECT");
ImGui::DebugTextEncoding(u8"こんにちは");
ImGui::SeparatorText("INCORRECT");
ImGui::DebugTextEncoding("こんにちは");
```
![UTF-8 Encoding viewer](https://github.com/ocornut/imgui/assets/8225057/61c1696a-9a94-46c5-9627-cf91211111f0)
You can also find this tool under `Metrics/Debuggers->Tools->UTF-8 Encoding viewer` if you want to paste from clipboard, but this won't validate the UTF-8 encoding done by your compiler.
(2) To encode in UTF-8:
There are also compiler-specific ways to enforce UTF-8 encoding by default:
- Visual Studio compiler: `/utf-8` command-line flag.
- Visual Studio compiler: `#pragma execution_character_set("utf-8")` inside your code.
- Since May 2023 we have changed the Visual Studio projects of all our examples to use `/utf-8` ([see commit](https://github.com/ocornut/imgui/commit/513af1efc9080857bbd10000d98f98f2a0c96803)).
Or, since C++11, you can use the `u8"my text"` syntax to encode literal strings as UTF-8. e.g.:
```cpp
ImGui::Text(u8"hello");
ImGui::Text(u8"こんにちは"); // this will always be encoded as UTF-8
ImGui::Text("こんにちは"); // the encoding of this is depending on compiler settings/flags and may be incorrect.
```
Since C++20, because the C++ committee hate its users, they decided to change the `u8""` syntax to not return `const char*` but a new type `const char_t*` which doesn't cast to `const char*`.
Because of type usage of `u8""` in C++20 is a little more tedious:
```cpp
ImGui::Text((const char*)u8"こんにちは");
```
We suggest using a macro in your codebase:
```cpp
#define U8(_S) (const char*)u8##_S
ImGui::Text(U8("こんにちは"));
```
##### [Return to Index](#index)
## Debug Tools
#### Metrics/Debugger->Fonts
You can use the `Metrics/Debugger` window (available in `Demo>Tools`) to browse your fonts and understand what's going on if you have an issue. You can also reach it in `Demo->Tools->Style Editor->Fonts`. The same information are also available in the Style Editor under Fonts.
![Fonts debugging](https://user-images.githubusercontent.com/8225057/135429892-0e41ef8d-33c5-4991-bcf6-f997a0bcfd6b.png)
#### UTF-8 Encoding Viewer**
You can use the `UTF-8 Encoding viewer` in `Metrics/Debugger` to verify the content of your UTF-8 strings. From C/C++ code, you can call `ImGui::DebugTextEncoding("my string");` function to verify that your UTF-8 encoding is correct.
![UTF-8 Encoding viewer](https://user-images.githubusercontent.com/8225057/166505963-8a0d7899-8ee8-4558-abb2-1ae523dc02f9.png)
Some solutions:
- You may reduce oversampling, e.g. `font_config.OversampleH = 1`, this will half your texture size for a quality looss.
Note that while OversampleH = 2 looks visibly very close to 3 in most situations, with OversampleH = 1 the quality drop will be noticeable. Read about oversampling [here](https://github.com/nothings/stb/blob/master/tests/oversample).
- Reduce glyphs ranges by calculating them from source localization data.
You can use the `ImFontGlyphRangesBuilder` for this purpose and rebuilding your atlas between frames when new characters are needed. This will be the biggest win!
- Set `io.Fonts.Flags |= ImFontAtlasFlags_NoPowerOfTwoHeight;` to disable rounding the texture height to the next power of two.
- Set `io.Fonts.TexDesiredWidth` to specify a texture width to reduce maximum texture height (see comment in `ImFontAtlas::Build()` function).
##### [Return to Index](#index)
@ -144,7 +82,7 @@ io.Fonts->AddFontDefault();
ImGuiIO& io = ImGui::GetIO();
io.Fonts->AddFontFromFileTTF("font.ttf", size_pixels);
```
If you get an assert stating "Could not load font file!", your font filename is likely incorrect. Read "[About filenames](#about-filenames)" carefully.
If you get an assert stating "Could not load font file!", your font filename is likely incorrect. Read [About filenames](#about-filenames) carefully.
**Load multiple fonts:**
```cpp
@ -153,8 +91,9 @@ ImGuiIO& io = ImGui::GetIO();
ImFont* font1 = io.Fonts->AddFontFromFileTTF("font.ttf", size_pixels);
ImFont* font2 = io.Fonts->AddFontFromFileTTF("anotherfont.otf", size_pixels);
```
In your application loop, select which font to use:
```cpp
// In application loop: select font at runtime
ImGui::Text("Hello"); // use the default font (which is the first loaded font)
ImGui::PushFont(font2);
ImGui::Text("Hello with another font");
@ -220,22 +159,6 @@ ImGui::SliderFloat("float", &f, 0.0f, 1.0f);
![sample code output](https://raw.githubusercontent.com/wiki/ocornut/imgui/web/v160/code_sample_02_jp.png)
<br>_(settings: Dark style (left), Light style (right) / Font: NotoSansCJKjp-Medium, 20px / Rounding: 5)_
**Font Atlas too large?**
- If you have very large number of glyphs or multiple fonts, the texture may become too big for your graphics API. The typical result of failing to upload a texture is if every glyph appears as a white rectangle.
- Mind the fact that some graphics drivers have texture size limitation. If you are building a PC application, mind the fact that your users may use hardware with lower limitations than yours.
Some solutions:
1. Reduce glyphs ranges by calculating them from source localization data.
You can use the `ImFontGlyphRangesBuilder` for this purpose and rebuilding your atlas between frames when new characters are needed. This will be the biggest win!
2. You may reduce oversampling, e.g. `font_config.OversampleH = 2`, this will largely reduce your texture size.
Note that while OversampleH = 2 looks visibly very close to 3 in most situations, with OversampleH = 1 the quality drop will be noticeable.
3. Set `io.Fonts.TexDesiredWidth` to specify a texture width to minimize texture height (see comment in `ImFontAtlas::Build()` function).
4. Set `io.Fonts.Flags |= ImFontAtlasFlags_NoPowerOfTwoHeight;` to disable rounding the texture height to the next power of two.
5. Read about oversampling [here](https://github.com/nothings/stb/blob/master/tests/oversample).
6. To support the extended range of unicode beyond 0xFFFF (e.g. emoticons, dingbats, symbols, shapes, ancient languages, etc...) add `#define IMGUI_USE_WCHAR32`in your `imconfig.h`.
##### [Return to Index](#index)
## Using Icon Fonts
@ -270,6 +193,12 @@ ImGui::Button(ICON_FA_SEARCH " Search");
```
See Links below for other icons fonts and related tools.
**Monospace Icons?**
To make your icon look more monospace and facilitate alignment, you may want to set the ImFontConfig::GlyphMinAdvanceX value when loading an icon font.
**Screenshot**
Here's an application using icons ("Avoyd", https://www.avoyd.com):
![avoyd](https://user-images.githubusercontent.com/8225057/81696852-c15d9e80-9464-11ea-9cab-2a4d4fc84396.jpg)
@ -287,7 +216,7 @@ Here's an application using icons ("Avoyd", https://www.avoyd.com):
## Using Colorful Glyphs/Emojis
- Rendering of colored emojis is only supported by imgui_freetype with FreeType 2.10+.
- Rendering of colored emojis is supported by imgui_freetype with FreeType 2.10+.
- You will need to load fonts with the `ImGuiFreeTypeBuilderFlags_LoadColor` flag.
- Emojis are frequently encoded in upper Unicode layers (character codes >0x10000) and will need dear imgui compiled with `IMGUI_USE_WCHAR32`.
- Not all types of color fonts are supported by FreeType at the moment.
@ -384,6 +313,93 @@ ImFont* font = io.Fonts->AddFontFromMemoryCompressedBase85TTF(compressed_data_ba
##### [Return to Index](#index)
--
## About Filenames
**Please note that many new C/C++ users have issues loading their files _because the filename they provide is wrong_ due to incorrect assumption of what is the current directory.**
Two things to watch for:
(1) In C/C++ and most programming languages if you want to use a backslash `\` within a string literal, you need to write it double backslash `\\`. At it happens, Windows uses backslashes as a path separator, so be mindful.
```cpp
io.Fonts->AddFontFromFileTTF("MyFiles\MyImage01.jpg", ...); // This is INCORRECT!!
io.Fonts->AddFontFromFileTTF("MyFiles\\MyImage01.jpg", ...); // This is CORRECT
```
In some situations, you may also use `/` path separator under Windows.
(2) Make sure your IDE/debugger settings starts your executable from the right working (current) directory. In Visual Studio you can change your working directory in project `Properties > General > Debugging > Working Directory`. People assume that their execution will start from the root folder of the project, where by default it often starts from the folder where object or executable files are stored.
```cpp
io.Fonts->AddFontFromFileTTF("MyImage01.jpg", ...); // Relative filename depends on your Working Directory when running your program!
io.Fonts->AddFontFromFileTTF("../MyImage01.jpg", ...); // Load from the parent folder of your Working Directory
```
##### [Return to Index](#index)
--
## About UTF-8 Encoding
**For non-ASCII characters display, a common user issue is not passing correctly UTF-8 encoded strings.**
(1) We provide a function `ImGui::DebugTextEncoding(const char* text)` which you can call to verify the content of your UTF-8 strings.
This is a convenient way to confirm that your encoding is correct.
```cpp
ImGui::SeparatorText("CORRECT");
ImGui::DebugTextEncoding(u8"こんにちは");
ImGui::SeparatorText("INCORRECT");
ImGui::DebugTextEncoding("こんにちは");
```
![UTF-8 Encoding viewer](https://github.com/ocornut/imgui/assets/8225057/61c1696a-9a94-46c5-9627-cf91211111f0)
You can also find this tool under `Metrics/Debuggers->Tools->UTF-8 Encoding viewer` if you want to paste from clipboard, but this won't validate the UTF-8 encoding done by your compiler.
(2) To encode in UTF-8:
There are also compiler-specific ways to enforce UTF-8 encoding by default:
- Visual Studio compiler: `/utf-8` command-line flag.
- Visual Studio compiler: `#pragma execution_character_set("utf-8")` inside your code.
- Since May 2023 we have changed the Visual Studio projects of all our examples to use `/utf-8` ([see commit](https://github.com/ocornut/imgui/commit/513af1efc9080857bbd10000d98f98f2a0c96803)).
Or, since C++11, you can use the `u8"my text"` syntax to encode literal strings as UTF-8. e.g.:
```cpp
ImGui::Text(u8"hello");
ImGui::Text(u8"こんにちは"); // this will always be encoded as UTF-8
ImGui::Text("こんにちは"); // the encoding of this is depending on compiler settings/flags and may be incorrect.
```
Since C++20, because the C++ committee hate its users, they decided to change the `u8""` syntax to not return `const char*` but a new type `const char_t*` which doesn't cast to `const char*`.
Because of type usage of `u8""` in C++20 is a little more tedious:
```cpp
ImGui::Text((const char*)u8"こんにちは");
```
We suggest using a macro in your codebase:
```cpp
#define U8(_S) (const char*)u8##_S
ImGui::Text(U8("こんにちは"));
```
##### [Return to Index](#index)
--
## Debug Tools
#### Metrics/Debugger->Fonts
You can use the `Metrics/Debugger` window (available in `Demo>Tools`) to browse your fonts and understand what's going on if you have an issue. You can also reach it in `Demo->Tools->Style Editor->Fonts`. The same information are also available in the Style Editor under Fonts.
![Fonts debugging](https://user-images.githubusercontent.com/8225057/135429892-0e41ef8d-33c5-4991-bcf6-f997a0bcfd6b.png)
#### UTF-8 Encoding Viewer**
You can use the `UTF-8 Encoding viewer` in `Metrics/Debugger` to verify the content of your UTF-8 strings. From C/C++ code, you can call `ImGui::DebugTextEncoding("my string");` function to verify that your UTF-8 encoding is correct.
![UTF-8 Encoding viewer](https://user-images.githubusercontent.com/8225057/166505963-8a0d7899-8ee8-4558-abb2-1ae523dc02f9.png)
##### [Return to Index](#index)
--
## Credits/Licenses For Fonts Included In Repository
Some fonts files are available in the `misc/fonts/` folder:

View file

@ -39,7 +39,7 @@ Dear ImGui is particularly suited to integration in game engines (for tooling),
### Usage
**The core of Dear ImGui is self-contained within a few platform-agnostic files** which you can easily compile in your application/engine. They are all the files in the root folder of the repository (imgui*.cpp, imgui*.h). **No specific build process is required**. You can add the .cpp files into your existing project.
**The core of Dear ImGui is self-contained within a few platform-agnostic files** which you can easily compile in your application/engine. They are all the files in the root folder of the repository (imgui*.cpp, imgui*.h). **No specific build process is required**. You can add the .cpp files into your existing project. See [Getting Started](https://github.com/ocornut/imgui/wiki/Getting-Started).
**Backends for a variety of graphics API and rendering platforms** are provided in the [backends/](https://github.com/ocornut/imgui/tree/master/backends) folder, along with example applications in the [examples/](https://github.com/ocornut/imgui/tree/master/examples) folder. See the [Integration](#integration) section of this document for details. You may also create your own backend. Anywhere where you can render textured triangles, you can render Dear ImGui.
@ -92,7 +92,7 @@ Dear ImGui allows you to **create elaborate tools** as well as very short-lived
### How it works
Check out the Wiki's [About the IMGUI paradigm](https://github.com/ocornut/imgui/wiki#about-the-imgui-paradigm) section if you want to understand the core principles behind the IMGUI paradigm. An IMGUI tries to minimize superfluous state duplication, state synchronization, and state retention from the user's point of view. It is less error-prone (less code and fewer bugs) than traditional retained-mode interfaces, and lends itself to creating dynamic user interfaces.
The IMGUI paradigm through its API tries to minimize superfluous state duplication, state synchronization, and state retention from the user's point of view. It is less error-prone (less code and fewer bugs) than traditional retained-mode interfaces, and lends itself to creating dynamic user interfaces. Check out the Wiki's [About the IMGUI paradigm](https://github.com/ocornut/imgui/wiki#about-the-imgui-paradigm) section for more details.
Dear ImGui outputs vertex buffers and command lists that you can easily render in your application. The number of draw calls and state changes required to render them is fairly small. Because Dear ImGui doesn't know or touch graphics state directly, you can call its functions anywhere in your code (e.g. in the middle of a running algorithm, or in the middle of your own rendering process). Refer to the sample applications in the examples/ folder for instructions on how to integrate Dear ImGui with your existing codebase.
@ -108,7 +108,7 @@ Reading the changelogs is a good way to keep up to date with the things Dear ImG
Calling the `ImGui::ShowDemoWindow()` function will create a demo window showcasing a variety of features and examples. The code is always available for reference in `imgui_demo.cpp`. [Here's how the demo looks](https://raw.githubusercontent.com/wiki/ocornut/imgui/web/v167/v167-misc.png).
You should be able to build the examples from sources. If you don't, let us know! If you want to have a quick look at some Dear ImGui features, you can download Windows binaries of the demo app here:
- [imgui-demo-binaries-20220504.zip](https://www.dearimgui.com/binaries/imgui-demo-binaries-20220504.zip) (Windows, 1.88 WIP, built 2022/05/04, master) or [older binaries](https://www.dearimgui.com/binaries).
- [imgui-demo-binaries-20230704.zip](https://www.dearimgui.com/binaries/imgui-demo-binaries-20230704.zip) (Windows, 1.89.7, built 2023/07/04, master) or [older binaries](https://www.dearimgui.com/binaries).
The demo applications are not DPI aware so expect some blurriness on a 4K screen. For DPI awareness in your application, you can load/reload your font at a different scale and scale your style with `style.ScaleAllSizes()` (see [FAQ](https://www.dearimgui.com/faq)).
@ -116,7 +116,7 @@ The demo applications are not DPI aware so expect some blurriness on a 4K screen
On most platforms and when using C++, **you should be able to use a combination of the [imgui_impl_xxxx](https://github.com/ocornut/imgui/tree/master/backends) backends without modification** (e.g. `imgui_impl_win32.cpp` + `imgui_impl_dx11.cpp`). If your engine supports multiple platforms, consider using more imgui_impl_xxxx files instead of rewriting them: this will be less work for you, and you can get Dear ImGui running immediately. You can _later_ decide to rewrite a custom backend using your custom engine functions if you wish so.
Integrating Dear ImGui within your custom engine is a matter of 1) wiring mouse/keyboard/gamepad inputs 2) uploading a texture to your GPU/render engine 3) providing a render function that can bind textures and render textured triangles. The [examples/](https://github.com/ocornut/imgui/tree/master/examples) folder is populated with applications doing just that. If you are an experienced programmer at ease with those concepts, it should take you less than two hours to integrate Dear ImGui into your custom engine. **Make sure to spend time reading the [FAQ](https://www.dearimgui.com/faq), comments, and the examples applications!**
See [Getting Started](https://github.com/ocornut/imgui/wiki/Getting-Started). Integrating Dear ImGui within your custom engine is a matter of 1) wiring mouse/keyboard/gamepad inputs 2) uploading a texture to your GPU/render engine 3) providing a render function that can bind textures and render textured triangles, which is essentially what Backends are doing. The [examples/](https://github.com/ocornut/imgui/tree/master/examples) folder is populated with applications doing just that: setting up a window and using backends. If you follow [Getting Started](https://github.com/ocornut/imgui/wiki/Getting-Started) it should in theory takes you less than an hour to integrate Dear ImGui. **Make sure to spend time reading the [FAQ](https://www.dearimgui.com/faq), comments, and the examples applications!**
Officially maintained backends/bindings (in repository):
- Renderers: DirectX9, DirectX10, DirectX11, DirectX12, Metal, OpenGL/ES/ES2, SDL_Renderer, Vulkan, WebGPU.
@ -148,7 +148,7 @@ For a list of third-party widgets and extensions, check out the [Useful Extensio
See: [Frequently Asked Questions (FAQ)](https://github.com/ocornut/imgui/blob/master/docs/FAQ.md) where common questions are answered.
See: [Wiki](https://github.com/ocornut/imgui/wiki) for many links, references, articles.
See: [Getting Started](https://github.com/ocornut/imgui/wiki/Getting-Started) and [Wiki](https://github.com/ocornut/imgui/wiki) for many links, references, articles.
See: [Articles about the IMGUI paradigm](https://github.com/ocornut/imgui/wiki#about-the-imgui-paradigm) to read/learn about the Immediate Mode GUI paradigm.
@ -162,7 +162,7 @@ Private support is available for paying business customers (E-mail: _contact @ d
**Which version should I get?**
We occasionally tag [Releases](https://github.com/ocornut/imgui/releases) (with nice releases notes) but it is generally safe and recommended to sync to master/latest. The library is fairly stable and regressions tend to be fixed fast when reported. Advanced users may want to use the `docking` branch with [Multi-Viewport](https://github.com/ocornut/imgui/issues/1542) and [Docking](https://github.com/ocornut/imgui/issues/2109) features. This branch is kept in sync with master regularly.
We occasionally tag [Releases](https://github.com/ocornut/imgui/releases) (with nice releases notes) but it is generally safe and recommended to sync to latest `master` or `docking` branch. The library is fairly stable and regressions tend to be fixed fast when reported. Advanced users may want to use the `docking` branch with [Multi-Viewport](https://github.com/ocornut/imgui/issues/1542) and [Docking](https://github.com/ocornut/imgui/issues/2109) features. This branch is kept in sync with master regularly.
**Who uses Dear ImGui?**

View file

@ -2,12 +2,12 @@ dear imgui
ISSUES & TODO LIST
Issue numbers (#) refer to GitHub issues listed at https://github.com/ocornut/imgui/issues/XXXX
This list is not well maintained, most of the work happens on GitHub nowadays.
THIS LIST IS NOT WELL MAINTAINED. MOST OF THE WORK HAPPENS ON GITHUB NOWADAYS.
The list below consist mostly of ideas noted down before they are requested/discussed by users (at which point they usually exist on the github issue tracker).
It's mostly a bunch of personal notes, probably incomplete. Feel free to query if you have any questions.
- doc/test: add a proper documentation+regression testing system (#435)
- doc/test: checklist app to verify backends/integration of imgui (test inputs, rendering, callback, etc.).
- doc: add a proper documentation system (maybe relying on automation? #435)
- doc: checklist app to verify backends/integration of imgui (test inputs, rendering, callback, etc.).
- doc/tips: tips of the day: website? applet in imgui_club?
- doc/wiki: work on the wiki https://github.com/ocornut/imgui/wiki
@ -18,7 +18,7 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i
- window: begin with *p_open == false could return false.
- window: get size/pos helpers given names (see discussion in #249)
- window: when window is very small, prioritize resize button over close button.
- window: double-clicking on title bar to minimize isn't consistent, perhaps move to single-click on left-most collapse icon?
- window: double-clicking on title bar to minimize isn't consistent interaction, perhaps move to single-click on left-most collapse icon?
- window: expose contents size. (#1045)
- window: using SetWindowPos() inside Begin() and moving the window with the mouse reacts a very ugly glitch. We should just defer the SetWindowPos() call.
- window: GetWindowSize() returns (0,0) when not calculated? (#1045)
@ -31,29 +31,26 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i
- window/child: allow resizing of child windows (possibly given min/max for each axis?.)
- window/child: allow SetNextWindowContentSize() to work on child windows.
- window/clipping: some form of clipping when DisplaySize (or corresponding viewport) is zero.
- window/tabbing: add a way to signify that a window or docked window requires attention (e.g. blinking title bar).
- window/id_stack: add e.g. window->GetIDFromPath() with support for leading / and ../ (#1390, #331)
- window/tabbing: add a way to signify that a window or docked window requires attention (e.g. blinking title bar, trying to click behind a modal).
- window/id_stack: add e.g. window->GetIDFromPath() with support for leading / and ../ (#1390, #331) -> model from test engine.
! scrolling: exposing horizontal scrolling with Shift+Wheel even when scrollbar is disabled expose lots of issues (#2424, #1463)
- scrolling: while holding down a scrollbar, try to keep the same contents visible (at least while not moving mouse)
- scrolling: allow immediately effective change of scroll after Begin() if we haven't appended items yet.
- scrolling: forward mouse wheel scrolling to parent window when at the edge of scrolling limits? (useful for listbox,tables?)
- scrolling/clipping: separator on the initial position of a window is not visible (cursorpos.y <= clippos.y). (2017-08-20: can't repro)
- scrolling/style: shadows on scrollable areas to denote that there is more contents (see e.g. DaVinci Resolve ui)
- drawdata: make it easy to deep-copy (or swap?) a full ImDrawData so user can easily save that data if they use threaded rendering. (e.g. #2646)
! drawlist: add CalcTextSize() func to facilitate consistent code from user pov (currently need to use ImGui or ImFont alternatives!)
- drawlist: maintaining bounding box per command would allow to merge draw command when clipping isn't relied on (typical non-scrolling window or non-overflowing column would merge with previous command). (WIP branch)
- drawlist: primitives/helpers to manipulate vertices post submission, so e.g. a quad/rect can be resized to fit later submitted content, _without_ using the ChannelSplit api
- drawlist: make it easier to toggle AA per primitive, so we can use e.g. non-AA fill + AA borders more naturally
- drawlist: non-AA strokes have gaps between points (#593, #288), glitch especially on RenderCheckmark() and ColorPicker4().
- drawlist: rendering: provide a way for imgui to output to a single/global vertex buffer, re-order indices only at the end of the frame (ref: https://gist.github.com/floooh/10388a0afbe08fce9e617d8aefa7d302)
- drawlist: callback: add an extra void* in ImDrawCallback to allow passing render-local data to the callback (would break API).
- drawlist: AddRect vs AddLine position confusing (#2441)
- drawlist/opt: store rounded corners in texture to use 1 quad per corner (filled and wireframe) to lower the cost of rounding. (#1962)
- drawlist/opt: AddRect() axis aligned pixel aligned (no-aa) could use 8 triangles instead of 16 and no normal calculation.
- drawlist/opt: thick AA line could be doable in same number of triangles as 1.0 AA line by storing gradient+full color in atlas.
- main: IsItemHovered() info stored in a stack? so that 'if TreeNode() { Text; TreePop; } if IsHovered' return the hover state of the TreeNode?
- items: IsItemHovered() info stored in a stack? so that 'if TreeNode() { Text; TreePop; } if IsHovered' return the hover state of the TreeNode?
- widgets: display mode: widget-label, label-widget (aligned on column or using fixed size), label-newline-tab-widget etc. (#395)
- widgets: clean up widgets internal toward exposing everything and stabilizing imgui_internals.h.
@ -61,8 +58,7 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i
- widgets: start exposing PushItemFlag() and ImGuiItemFlags
- widgets: alignment options in style (e.g. center Selectable, Right-Align within Button, etc.) #1260
- widgets: activate by identifier (trigger button, focus given id)
- widgets: a way to represent "mixed" values, so e.g. all values replaced with *, including check-boxes, colors, etc. with support for multi-components widgets (e.g. SliderFloat3, make only "Y" mixed) (#2644)
- widgets: checkbox: checkbox with custom glyph inside frame.
- widgets: custom glyph/shapes replacements for stock sapes. (also #6090 #2431 #2235 #6517)
- widgets: coloredit: keep reporting as active when picker is on?
- widgets: group/scalarn functions: expose more per-component information. e.g. store NextItemData.ComponentIdx set by scalarn function, groups can expose them back somehow.
- selectable: using (size.x == 0.0f) and (SelectableTextAlign.x > 0.0f) followed by SameLine() is currently not supported.
@ -81,7 +77,6 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i
- input text: option to Tab after an Enter validation.
- input text: add ImGuiInputTextFlags_EnterToApply? (off #218)
- input text: easier ways to update buffer (from source char*) while owned. preserve some sort of cursor position for multi-line text.
- input text: add flag (e.g. ImGuiInputTextFlags_EscapeClearsBuffer) to clear instead of revert. what to do with focus? (also see #2890)
- input text: add discard flag (e.g. ImGuiInputTextFlags_DiscardActiveBuffer) or make it easier to clear active focus for text replacement during edition (#725)
- input text: display bug when clicking a drag/slider after an input text in a different window has all-selected text (order dependent). actually a very old bug but no one appears to have noticed it.
- input text: allow centering/positioning text so that ctrl+clicking Drag or Slider keeps the textual value at the same pixel position.
@ -116,20 +111,14 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i
- tables: see https://github.com/ocornut/imgui/issues/2957#issuecomment-569726095
- group: BeginGroup() needs a border option. (~#1496)
- group: IsHovered() after EndGroup() covers whole AABB rather than the intersection of individual items. Is that desirable?
- group: IsItemHovered() after EndGroup() covers whole AABB rather than the intersection of individual items. Is that desirable?
- group: merge deactivation/activation within same group (fwd WasEdited flag). (#2550)
!- color: the color conversion helpers/types are a mess and needs sorting out.
- color: (api breaking) ImGui::ColorConvertXXX functions should be loose ImColorConvertXX to match imgui_internals.h
- plot: full featured plot/graph api w/ scrolling, zooming etc. all bell & whistle. why not!
- plot: PlotLines() should use the polygon-stroke facilities, less vertices (currently issues with averaging normals)
- plot: make it easier for user to draw extra stuff into the graph (e.g: draw basis, highlight certain points, 2d plots, multiple plots)
- plot: "smooth" automatic scale over time, user give an input 0.0(full user scale) 1.0(full derived from value)
- plot: option/feature: draw the zero line
- plot: option/feature: draw grid, vertical markers
- plot: option/feature: draw unit
- plot: add a helper e.g. Plot(char* label, float value, float time_span=2.0f) that stores values and Plot them for you - probably another function name. and/or automatically allow to plot ANY displayed value (more reliance on stable ID)
- plot: full featured plot/graph api w/ scrolling, zooming etc. --> ImPlot
- (plot: deleted all other todo lines on 2023-06-28)
- clipper: ability to disable the clipping through a simple flag/bool.
- clipper: ability to run without knowing full count in advance.
@ -140,7 +129,6 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i
- separator: width, thickness, centering (#1643)
- splitter: formalize the splitter idiom into an official api (we want to handle n-way split) (#319)
- docking: merge docking branch (#2109)
- docking: B: ordering currently held in tab bar should be implicitly held by windows themselves (also see #2304)
- docking: B- tab bar: the order/focus restoring code could be part of TabBar and not DockNode? (#8)
- docking: B~ rework code to be able to lazily create tab bar instance in a single place. The _Unsorted tab flag could be replacing a trailing-counter in DockNode?
@ -174,16 +162,11 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i
- tabs: "there is currently a problem because TabItem() will try to submit their own tooltip after 0.50 second, and this will have the effect of making your tooltip flicker once." -> tooltip priority work (WIP branch)
- tabs: make EndTabBar fail if users doesn't respect BeginTabBar return value, for consistency/future-proofing.
- tabs: persistent order/focus in BeginTabBar() api (#261, #351)
- tabs: TabItem could honor SetNextItemWidth()?
- tabs: explicit api (even if internal) to cleanly manipulate tab order.
- tabs: Mouse wheel over tab bar could scroll? (with shift?) (#2702)
- image/image button: misalignment on padded/bordered button?
- image/image button: parameters are confusing, image() has tint_col,border_col whereas imagebutton() has bg_col/tint_col. Even thou they are different parameters ordering could be more consistent. can we fix that?
- image button: not taking an explicit id can be problematic. (#2464, #1390)
- slider/drag: ctrl+click when format doesn't include a % character.. disable? display underlying value in default format? (see TempInputTextScalar)
- slider: allow using the [-]/[+] buttons used by InputFloat()/InputInt()
- slider: initial absolute click is imprecise. change to relative movement slider (same as scrollbar). (#1946)
- slider: add dragging-based widgets to edit values with mouse (on 2 axises), saving screen real-estate.
- slider: tint background based on value (e.g. v_min -> v_max, or use 0.0f either side of the sign)
- slider: relative dragging? + precision dragging
@ -196,7 +179,6 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i
- drag float: added leeway on edge (e.g. a few invisible steps past the clamp limits)
- combo: use clipper.
- combo: flag for BeginCombo to not return true when unchanged (#1182)
- combo: a way/helper to customize the combo preview (#1658) -> experimental BeginComboPreview()
- combo/listbox: keyboard control. need InputText-like non-active focus + key handling. considering keyboard for custom listbox (pr #203)
- listbox: multiple selection (WIP range-select branch)
@ -218,7 +200,6 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i
- tooltip: drag and drop with tooltip near monitor edges lose/changes its last direction instead of locking one. The drag and drop tooltip should always follow without changing direction.
- tooltip: allow to set the width of a tooltip to allow TextWrapped() etc. while keeping the height automatic.
- tooltip: tooltips with delay timers? or general timer policy? (instantaneous vs timed): IsItemHovered() with timer + implicit aabb-id for items with no ID. (#1485) (WIP branch)
- tooltip: drag tooltip hovering over source widget with IsItemHovered/SetTooltip flickers (WIP branch)
- status-bar: add a per-window status bar helper similar to what menu-bar does. generalize concept of layer0 rect in window (can make _MenuBar window flag obsolete too).
@ -227,7 +208,6 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i
- shortcuts: programmatically access shortcuts "Focus("&Save"))
- menus: menu-bar: main menu-bar could affect clamping of windows position (~ akin to modifying DisplayMin)
- menus: hovering from menu to menu on a menu-bar has 1 frame without any menu, which is a little annoying. ideally either 0 either longer.
- menus: could merge draw call in most cases (how about storing an optional aabb in ImDrawCmd to move the burden of merging in a single spot).
- menus: would be nice if the Selectable() supported horizontal alignment (must be given the equivalent of WorkRect.Max.x matching the position of the shortcut column)
- tree node: add treenode/treepush int variants? not there because (void*) cast from int warns on some platforms/settings?
@ -273,7 +253,6 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i
- drag and drop: drag source on a group object (would need e.g. an invisible button covering group in EndGroup) https://twitter.com/paniq/status/1121446364909535233
- drag and drop: have some way to know when a drag begin from BeginDragDropSource() pov. (see 2018/01/11 post in #143)
- drag and drop: allow preview tooltip to be submitted from a different place than the drag source. (#1725)
- drag and drop: allow using with other mouse buttons (where activeid won't be set). (#1637)
- drag and drop: make it easier and provide a demo to have tooltip both are source and target site, with a more detailed one on target site (tooltip ordering problem)
- drag and drop: demo with reordering nodes (in a list, or a tree node). (#143)
- drag and drop: test integrating with os drag and drop (make it easy to do a naive WM_DROPFILE integration)
@ -325,10 +304,10 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i
- font/opt: Considering storing standalone AdvanceX table as 16-bit fixed point integer?
- font/opt: Glyph currently 40 bytes (2+9*4). Consider storing UV as 16-bits integer? (->32 bytes). X0/Y0/X1/Y1 as 16 fixed-point integers? Or X0/Y0 as float and X1/Y1 as fixed8_8?
- nav: visual feedback on button press.
- nav: some features such as PageUp/Down/Home/End should probably work without ImGuiConfigFlags_NavEnableKeyboard? (where do we draw the line? how about CTRL+Tab)
! nav: never clear NavId on some setup (e.g. gamepad centric)
- nav: there's currently no way to completely clear focus with the keyboard. depending on patterns used by the application to dispatch inputs, it may be desirable.
- nav: code to focus child-window on restoring NavId appears to have issue: e.g. when focus change is implicit because of window closure.
- nav: Home/End behavior when navigable item is not fully visible at the edge of scrolling? should be backtrack to keep item into view?
- nav: NavScrollToBringItemIntoView() with item bigger than view should focus top-right? Repro: using Nav in "About Window"
- nav: wrap around logic to allow e.g. grid based layout (pressing NavRight on the right-most element would go to the next row, etc.). see internal's NavMoveRequestTryWrapping().
@ -349,7 +328,6 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i
- nav/menus: when using the main menu bar, even though we restore focus after, the underlying window loses its title bar highlight during menu manipulation. could we prevent it?
- nav/menus: main menu bar currently cannot restore a nullptr focus. Could save NavWindow at the time of being focused, similarly to what popup do?
- nav/menus: Alt,Up could open the first menu (e.g. "File") currently it tends to nav into the window/collapse menu. Do do that we would need custom transition?
- nav/windowing: configure fade-in/fade-out delay on Ctrl+Tab?
- nav/windowing: when CTRL+Tab/windowing is active, the HoveredWindow detection doesn't take account of the window display re-ordering.
- nav/windowing: Resizing window will currently fail with certain types of resizing constraints/callback applied
- focus: preserve ActiveId/focus stack state, e.g. when opening a menu and close it, previously selected InputText() focus gets restored (#622)
@ -368,7 +346,6 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i
- platform: sdl: no refresh of monitor/display (SDL doesn't seem to have an event for it).
- platform: sdl: multi-viewport + minimized window seems to break mouse wheel events (at least under Win32).
- inputs: we need an explicit flag about whether the platform window is focused, to be able to distinguish focused key releases vs alt-tabbing all release behaviors.
- inputs: support track pad style scrolling & slider edit.
- inputs/io: backspace and arrows in the context of a text input could use system repeat rate.
- inputs/io: clarify/standardize/expose repeat rate and repeat delays (#1808)
@ -394,7 +371,6 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i
- examples: provide a zero frame-rate/idle example.
- examples: dx11/dx12: try to use new swapchain blit models (#2970)
- backends: report it better when not able to create texture?
- backends: apple: example_apple should be using modern GL3.
- backends: glfw: could go idle when minimized? if (glfwGetWindowAttrib(window, GLFW_ICONIFIED)) { glfwWaitEvents(); continue; } // issue: DeltaTime will be super high on resume, perhaps provide a way to let impl know (#440)
- backends: opengl: rename imgui_impl_opengl2 to impl_opengl_legacy and imgui_impl_opengl3 to imgui_impl_opengl? (#1900)
- backends: opengl: could use a single vertex buffer and glBufferSubData for uploads?

View file

@ -1,5 +1,5 @@
//-----------------------------------------------------------------------------
// COMPILE-TIME OPTIONS FOR DEAR IMGUI
// DEAR IMGUI COMPILE-TIME OPTIONS
// Runtime options (clipboard callbacks, enabling various features, etc.) can generally be set via the ImGuiIO structure.
// You can use ImGui::SetAllocatorFunctions() before calling ImGui::CreateContext() to rewire memory allocation functions.
//-----------------------------------------------------------------------------
@ -9,7 +9,7 @@
// You need to make sure that configuration settings are defined consistently _everywhere_ Dear ImGui is used, which include the imgui*.cpp
// files but also _any_ of your code that uses Dear ImGui. This is because some compile-time options have an affect on data structures.
// Defining those options in imconfig.h will ensure every compilation unit gets to see the same data structure layouts.
// Call IMGUI_CHECKVERSION() from your .cpp files to verify that the data structures your files are using are matching the ones imgui.cpp is using.
// Call IMGUI_CHECKVERSION() from your .cpp file to verify that the data structures your files are using are matching the ones imgui.cpp is using.
//-----------------------------------------------------------------------------
#pragma once
@ -26,7 +26,7 @@
//#define IMGUI_API __declspec( dllexport )
//#define IMGUI_API __declspec( dllimport )
//---- Don't define obsolete functions/enums/behaviors. Consider enabling from time to time after updating to avoid using soon-to-be obsolete function/names.
//---- Don't define obsolete functions/enums/behaviors. Consider enabling from time to time after updating to clean your code of obsolete function/names.
//#define IMGUI_DISABLE_OBSOLETE_FUNCTIONS
//#define IMGUI_DISABLE_OBSOLETE_KEYIO // 1.87: disable legacy io.KeyMap[]+io.KeysDown[] in favor io.AddKeyEvent(). This will be folded into IMGUI_DISABLE_OBSOLETE_FUNCTIONS in a few versions.
@ -40,7 +40,7 @@
//#define IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCTIONS // [Win32] Don't implement default clipboard handler. Won't use and link with OpenClipboard/GetClipboardData/CloseClipboard etc. (user32.lib/.a, kernel32.lib/.a)
//#define IMGUI_ENABLE_WIN32_DEFAULT_IME_FUNCTIONS // [Win32] [Default with Visual Studio] Implement default IME handler (require imm32.lib/.a, auto-link for Visual Studio, -limm32 on command-line for MinGW)
//#define IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCTIONS // [Win32] [Default with non-Visual Studio compilers] Don't implement default IME handler (won't require imm32.lib/.a)
//#define IMGUI_DISABLE_WIN32_FUNCTIONS // [Win32] Won't use and link with any Win32 function (clipboard, ime).
//#define IMGUI_DISABLE_WIN32_FUNCTIONS // [Win32] Won't use and link with any Win32 function (clipboard, IME).
//#define IMGUI_ENABLE_OSX_DEFAULT_CLIPBOARD_FUNCTIONS // [OSX] Implement default OSX clipboard handler (need to link with '-framework ApplicationServices', this is why this is not the default).
//#define IMGUI_DISABLE_DEFAULT_FORMAT_FUNCTIONS // Don't implement ImFormatString/ImFormatStringV so you can implement them yourself (e.g. if you don't want to link with vsnprintf)
//#define IMGUI_DISABLE_DEFAULT_MATH_FUNCTIONS // Don't implement ImFabs/ImSqrt/ImPow/ImFmod/ImCos/ImSin/ImAcos/ImAtan2 so you can implement them yourself.
@ -62,9 +62,10 @@
// By default the embedded implementations are declared static and not available outside of Dear ImGui sources files.
//#define IMGUI_STB_TRUETYPE_FILENAME "my_folder/stb_truetype.h"
//#define IMGUI_STB_RECT_PACK_FILENAME "my_folder/stb_rect_pack.h"
//#define IMGUI_STB_SPRINTF_FILENAME "my_folder/stb_sprintf.h" // only used if enabled
//#define IMGUI_STB_SPRINTF_FILENAME "my_folder/stb_sprintf.h" // only used if IMGUI_USE_STB_SPRINTF is defined.
//#define IMGUI_DISABLE_STB_TRUETYPE_IMPLEMENTATION
//#define IMGUI_DISABLE_STB_RECT_PACK_IMPLEMENTATION
//#define IMGUI_DISABLE_STB_SPRINTF_IMPLEMENTATION // only disabled if IMGUI_USE_STB_SPRINTF is defined.
//---- Use stb_sprintf.h for a faster implementation of vsnprintf instead of the one from libc (unless IMGUI_DISABLE_DEFAULT_FORMAT_FUNCTIONS is defined)
// 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.h.
@ -75,6 +76,12 @@
// On Windows you may use vcpkg with 'vcpkg install freetype --triplet=x64-windows' + 'vcpkg integrate install'.
//#define IMGUI_ENABLE_FREETYPE
//---- Use FreeType+lunasvg library to render OpenType SVG fonts (SVGinOT)
// Requires lunasvg headers to be available in the include path + program to be linked with the lunasvg library (not provided).
// Only works in combination with IMGUI_ENABLE_FREETYPE.
// (implementation is based on Freetype's rsvg-port.c which is licensed under CeCILL-C Free Software License Agreement)
//#define IMGUI_ENABLE_FREETYPE_LUNASVG
//---- Use stb_truetype to build and rasterize the font atlas (default)
// The only purpose of this define is if you want force compilation of the stb_truetype backend ALONG with the FreeType backend.
//#define IMGUI_ENABLE_STB_TRUETYPE
@ -107,7 +114,7 @@
//typedef void (*MyImDrawCallback)(const ImDrawList* draw_list, const ImDrawCmd* cmd, void* my_renderer_user_data);
//#define ImDrawCallback MyImDrawCallback
//---- Debug Tools: Macro to break in Debugger
//---- Debug Tools: Macro to break in Debugger (we provide a default implementation of this in the codebase)
// (use 'Metrics->Tools->Item Picker' to pick widgets with the mouse and break into them for easy debugging.)
//#define IM_DEBUG_BREAK IM_ASSERT(0)
//#define IM_DEBUG_BREAK __debugbreak()
@ -115,10 +122,10 @@
//---- Debug Tools: Enable slower asserts
//#define IMGUI_DEBUG_PARANOID
//---- Tip: You can add extra functions within the ImGui:: namespace, here or in your own headers files.
//---- Tip: You can add extra functions within the ImGui:: namespace from anywhere (e.g. your own sources/header files)
/*
namespace ImGui
{
void MyFunction(const char* name, const MyMatrix44& v);
void MyFunction(const char* name, MyMatrix44* mtx);
}
*/

File diff suppressed because it is too large Load diff

View file

@ -1,4 +1,4 @@
// dear imgui, v1.89.6
// dear imgui, v1.89.8
// (headers)
// Help:
@ -9,21 +9,24 @@
// Resources:
// - FAQ http://dearimgui.com/faq
// - Homepage & latest https://github.com/ocornut/imgui
// - Homepage https://github.com/ocornut/imgui
// - Releases & changelog https://github.com/ocornut/imgui/releases
// - Gallery https://github.com/ocornut/imgui/issues/6478 (please post your screenshots/video there!)
// - Wiki https://github.com/ocornut/imgui/wiki (lots of good stuff there)
// - Getting Started https://github.com/ocornut/imgui/wiki/Getting-Started
// - Glossary https://github.com/ocornut/imgui/wiki/Glossary
// - Issues & support https://github.com/ocornut/imgui/issues
// - Tests & Automation https://github.com/ocornut/imgui_test_engine
// Getting Started?
// - For first-time users having issues compiling/linking/running or issues loading fonts:
// - Read https://github.com/ocornut/imgui/wiki/Getting-Started
// - For first-time users having issues compiling/linking/running/loading fonts:
// please post in https://github.com/ocornut/imgui/discussions if you cannot find a solution in resources above.
// Library Version
// (Integer encoded as XYYZZ for use in #if preprocessor conditionals, e.g. '#if IMGUI_VERSION_NUM >= 12345')
#define IMGUI_VERSION "1.89.6"
#define IMGUI_VERSION_NUM 18960
#define IMGUI_VERSION "1.89.8"
#define IMGUI_VERSION_NUM 18980
#define IMGUI_HAS_TABLE
#define IMGUI_HAS_VIEWPORT // Viewport WIP branch
#define IMGUI_HAS_DOCK // Docking WIP branch
@ -115,10 +118,13 @@ Index of this file:
#endif
#if defined(__clang__)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wold-style-cast"
#if __has_warning("-Wzero-as-null-pointer-constant")
#pragma clang diagnostic ignored "-Wzero-as-null-pointer-constant"
#if __has_warning("-Wunknown-warning-option")
#pragma clang diagnostic ignored "-Wunknown-warning-option" // warning: unknown warning group 'xxx'
#endif
#pragma clang diagnostic ignored "-Wunknown-pragmas" // warning: unknown warning group 'xxx'
#pragma clang diagnostic ignored "-Wold-style-cast"
#pragma clang diagnostic ignored "-Wzero-as-null-pointer-constant"
#pragma clang diagnostic ignored "-Wreserved-identifier" // warning: identifier '_Xxx' is reserved because it starts with '_' followed by a capital letter
#elif defined(__GNUC__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wpragmas" // warning: unknown option after '#pragma GCC diagnostic' kind
@ -672,12 +678,21 @@ 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. They do not take focus away.
IMGUI_API bool BeginTooltip(); // begin/append a tooltip window. to create full-featured tooltip (with any kind of items).
IMGUI_API void EndTooltip(); // only call EndTooltip() if BeginTooltip() returns true!
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().
// - Tooltips are windows following the mouse. They do not take focus away.
// - A tooltip window can contain items of any types. SetTooltip() is a shortcut for the 'if (BeginTooltip()) { Text(...); EndTooltip(); }' idiom.
IMGUI_API bool BeginTooltip(); // begin/append a tooltip window.
IMGUI_API void EndTooltip(); // only call EndTooltip() if BeginTooltip()/BeginItemTooltip() returns true!
IMGUI_API void SetTooltip(const char* fmt, ...) IM_FMTARGS(1); // set a text-only tooltip. Often used after a ImGui::IsItemHovered() check. Override any previous call to SetTooltip().
IMGUI_API void SetTooltipV(const char* fmt, va_list args) IM_FMTLIST(1);
// Tooltips: helpers for showing a tooltip when hovering an item
// - BeginItemTooltip() is a shortcut for the 'if (IsItemHovered(ImGuiHoveredFlags_Tooltip) && BeginTooltip())' idiom.
// - SetItemTooltip() is a shortcut for the 'if (IsItemHovered(ImGuiHoveredFlags_Tooltip)) { SetTooltip(...); }' idiom.
// - Where 'ImGuiHoveredFlags_Tooltip' itself is a shortcut to use 'style.HoverFlagsForTooltipMouse' or 'style.HoverFlagsForTooltipNav' depending on active input type. For mouse it defaults to 'ImGuiHoveredFlags_Stationary | ImGuiHoveredFlags_DelayShort'.
IMGUI_API bool BeginItemTooltip(); // begin/append a tooltip window if preceding item was hovered.
IMGUI_API void SetItemTooltip(const char* fmt, ...) IM_FMTARGS(1); // set a text-only tooltip if preceeding item was hovered. override any previous call to SetTooltip().
IMGUI_API void SetItemTooltipV(const char* fmt, va_list args) IM_FMTLIST(1);
// Popups, Modals
// - They block normal mouse hovering detection (and therefore most mouse interactions) behind them.
// - If not modal: they can be closed by clicking anywhere outside them, or by pressing ESCAPE.
@ -806,9 +821,9 @@ namespace ImGui
// - Drag from window menu button (upper-left button) to undock an entire node (all windows).
// - When io.ConfigDockingWithShift == true, you instead need to hold SHIFT to _enable_ docking/undocking.
// About dockspaces:
// - Use DockSpace() to create an explicit dock node _within_ an existing window. See Docking demo for details.
// - Use DockSpaceOverViewport() to create an explicit dock node covering the screen or a specific viewport.
// This is often used with ImGuiDockNodeFlags_PassthruCentralNode.
// This is often used with ImGuiDockNodeFlags_PassthruCentralNode to make it transparent.
// - Use DockSpace() to create an explicit dock node _within_ an existing window. See Docking demo for details.
// - Important: Dockspaces need to be submitted _before_ any window they can host. Submit it early in your frame!
// - Important: Dockspaces need to be kept alive if hidden, otherwise windows docked into it will be undocked.
// e.g. if you have multiple tabs with a dockspace inside each tab: submit the non-visible dockspaces with ImGuiDockNodeFlags_KeepAliveOnly.
@ -864,6 +879,9 @@ namespace ImGui
IMGUI_API void SetItemDefaultFocus(); // make last item the default focused item of a window.
IMGUI_API void SetKeyboardFocusHere(int offset = 0); // focus keyboard on the next widget. Use positive 'offset' to access sub components of a multiple component widget. Use -1 to access previous widget.
// Overlapping mode
IMGUI_API void SetNextItemAllowOverlap(); // allow next item to be overlapped by a subsequent item. Useful with invisible buttons, selectable, treenode covering an area where subsequent items may need to be added. Note that both Selectable() and TreeNode() have dedicated flags doing this.
// Item/Widgets Utilities and Query Functions
// - Most of the functions are referring to the previous Item that has been submitted.
// - See Demo Window under "Widgets->Querying Status" for an interactive visualization of most of those functions.
@ -884,7 +902,6 @@ namespace ImGui
IMGUI_API ImVec2 GetItemRectMin(); // get upper-left bounding rectangle of the last item (screen space)
IMGUI_API ImVec2 GetItemRectMax(); // get lower-right bounding rectangle of the last item (screen space)
IMGUI_API ImVec2 GetItemRectSize(); // get size of last item
IMGUI_API void SetItemAllowOverlap(); // allow last item to be overlapped by a subsequent item. sometimes useful with invisible buttons, selectables, etc. to catch unused area.
// Viewports
// - Currently represents the Platform Window created by the application which is hosting our Dear ImGui windows.
@ -1073,7 +1090,7 @@ enum ImGuiTreeNodeFlags_
ImGuiTreeNodeFlags_None = 0,
ImGuiTreeNodeFlags_Selected = 1 << 0, // Draw as selected
ImGuiTreeNodeFlags_Framed = 1 << 1, // Draw frame with background (e.g. for CollapsingHeader)
ImGuiTreeNodeFlags_AllowItemOverlap = 1 << 2, // Hit testing to allow subsequent widgets to overlap this one
ImGuiTreeNodeFlags_AllowOverlap = 1 << 2, // Hit testing to allow subsequent widgets to overlap this one
ImGuiTreeNodeFlags_NoTreePushOnOpen = 1 << 3, // Don't do a TreePush() when open (e.g. for CollapsingHeader) = no extra indent nor pushing on ID stack
ImGuiTreeNodeFlags_NoAutoOpenOnLog = 1 << 4, // Don't automatically and temporarily open node when Logging is active (by default logging will automatically open tree nodes)
ImGuiTreeNodeFlags_DefaultOpen = 1 << 5, // Default node to be open
@ -1087,6 +1104,10 @@ enum ImGuiTreeNodeFlags_
ImGuiTreeNodeFlags_NavLeftJumpsBackHere = 1 << 13, // (WIP) Nav: left direction may move to this TreeNode() from any of its child (items submitted between TreeNode and TreePop)
//ImGuiTreeNodeFlags_NoScrollOnOpen = 1 << 14, // FIXME: TODO: Disable automatic scroll on TreePop() if node got just open and contents is not visible
ImGuiTreeNodeFlags_CollapsingHeader = ImGuiTreeNodeFlags_Framed | ImGuiTreeNodeFlags_NoTreePushOnOpen | ImGuiTreeNodeFlags_NoAutoOpenOnLog,
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
ImGuiTreeNodeFlags_AllowItemOverlap = ImGuiTreeNodeFlags_AllowOverlap, // Renamed in 1.89.7
#endif
};
// Flags for OpenPopup*(), BeginPopupContext*(), IsPopupOpen() functions.
@ -1120,7 +1141,11 @@ enum ImGuiSelectableFlags_
ImGuiSelectableFlags_SpanAllColumns = 1 << 1, // Selectable frame can span all columns (text will still fit in current column)
ImGuiSelectableFlags_AllowDoubleClick = 1 << 2, // Generate press events on double clicks too
ImGuiSelectableFlags_Disabled = 1 << 3, // Cannot be selected, display grayed out text
ImGuiSelectableFlags_AllowItemOverlap = 1 << 4, // (WIP) Hit testing to allow subsequent widgets to overlap this one
ImGuiSelectableFlags_AllowOverlap = 1 << 4, // (WIP) Hit testing to allow subsequent widgets to overlap this one
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
ImGuiSelectableFlags_AllowItemOverlap = ImGuiSelectableFlags_AllowOverlap, // Renamed in 1.89.7
#endif
};
// Flags for ImGui::BeginCombo()
@ -1329,16 +1354,30 @@ enum ImGuiHoveredFlags_
ImGuiHoveredFlags_AllowWhenBlockedByPopup = 1 << 5, // Return true even if a popup window is normally blocking access to this item/window
//ImGuiHoveredFlags_AllowWhenBlockedByModal = 1 << 6, // Return true even if a modal popup window is normally blocking access to this item/window. FIXME-TODO: Unavailable yet.
ImGuiHoveredFlags_AllowWhenBlockedByActiveItem = 1 << 7, // Return true even if an active item is blocking access to this item/window. Useful for Drag and Drop patterns.
ImGuiHoveredFlags_AllowWhenOverlapped = 1 << 8, // IsItemHovered() only: Return true even if the position is obstructed or overlapped by another window
ImGuiHoveredFlags_AllowWhenDisabled = 1 << 9, // IsItemHovered() only: Return true even if the item is disabled
ImGuiHoveredFlags_NoNavOverride = 1 << 10, // Disable using gamepad/keyboard navigation state when active, always query mouse.
ImGuiHoveredFlags_AllowWhenOverlappedByItem = 1 << 8, // IsItemHovered() only: Return true even if the item uses AllowOverlap mode and is overlapped by another hoverable item.
ImGuiHoveredFlags_AllowWhenOverlappedByWindow = 1 << 9, // IsItemHovered() only: Return true even if the position is obstructed or overlapped by another window.
ImGuiHoveredFlags_AllowWhenDisabled = 1 << 10, // IsItemHovered() only: Return true even if the item is disabled
ImGuiHoveredFlags_NoNavOverride = 1 << 11, // IsItemHovered() only: Disable using gamepad/keyboard navigation state when active, always query mouse
ImGuiHoveredFlags_AllowWhenOverlapped = ImGuiHoveredFlags_AllowWhenOverlappedByItem | ImGuiHoveredFlags_AllowWhenOverlappedByWindow,
ImGuiHoveredFlags_RectOnly = ImGuiHoveredFlags_AllowWhenBlockedByPopup | ImGuiHoveredFlags_AllowWhenBlockedByActiveItem | ImGuiHoveredFlags_AllowWhenOverlapped,
ImGuiHoveredFlags_RootAndChildWindows = ImGuiHoveredFlags_RootWindow | ImGuiHoveredFlags_ChildWindows,
// Hovering delays (for tooltips)
ImGuiHoveredFlags_DelayNormal = 1 << 11, // Return true after io.HoverDelayNormal elapsed (~0.30 sec)
ImGuiHoveredFlags_DelayShort = 1 << 12, // Return true after io.HoverDelayShort elapsed (~0.10 sec)
ImGuiHoveredFlags_NoSharedDelay = 1 << 13, // Disable shared delay system where moving from one item to the next keeps the previous timer for a short time (standard for tooltips with long delays)
// Tooltips mode
// - typically used in IsItemHovered() + SetTooltip() sequence.
// - this is a shortcut to pull flags from 'style.HoverFlagsForTooltipMouse' or 'style.HoverFlagsForTooltipNav' where you can reconfigure desired behavior.
// e.g. 'TooltipHoveredFlagsForMouse' defaults to 'ImGuiHoveredFlags_Stationary | ImGuiHoveredFlags_DelayShort'.
// - for frequently actioned or hovered items providing a tooltip, you want may to use ImGuiHoveredFlags_ForTooltip (stationary + delay) so the tooltip doesn't show too often.
// - for items which main purpose is to be hovered, or items with low affordance, or in less consistent apps, prefer no delay or shorter delay.
ImGuiHoveredFlags_ForTooltip = 1 << 12, // Shortcut for standard flags when using IsItemHovered() + SetTooltip() sequence.
// (Advanced) Mouse Hovering delays.
// - generally you can use ImGuiHoveredFlags_ForTooltip to use application-standardized flags.
// - use those if you need specific overrides.
ImGuiHoveredFlags_Stationary = 1 << 13, // Require mouse to be stationary for style.HoverStationaryDelay (~0.15 sec) _at least one time_. After this, can move on same item/window. Using the stationary test tends to reduces the need for a long delay.
ImGuiHoveredFlags_DelayNone = 1 << 14, // IsItemHovered() only: Return true immediately (default). As this is the default you generally ignore this.
ImGuiHoveredFlags_DelayShort = 1 << 15, // IsItemHovered() only: Return true after style.HoverDelayShort elapsed (~0.15 sec) (shared between items) + requires mouse to be stationary for style.HoverStationaryDelay (once per item).
ImGuiHoveredFlags_DelayNormal = 1 << 16, // IsItemHovered() only: Return true after style.HoverDelayNormal elapsed (~0.40 sec) (shared between items) + requires mouse to be stationary for style.HoverStationaryDelay (once per item).
ImGuiHoveredFlags_NoSharedDelay = 1 << 17, // IsItemHovered() only: Disable shared delay system where moving from one item to the next keeps the previous timer for a short time (standard for tooltips with long delays)
};
// Flags for ImGui::DockSpace(), shared/inherited by child nodes.
@ -1700,6 +1739,7 @@ enum ImGuiStyleVar_
ImGuiStyleVar_SeparatorTextBorderSize,// float SeparatorTextBorderSize
ImGuiStyleVar_SeparatorTextAlign, // ImVec2 SeparatorTextAlign
ImGuiStyleVar_SeparatorTextPadding,// ImVec2 SeparatorTextPadding
ImGuiStyleVar_DockingSeparatorSize,// float DockingSeparatorSize
ImGuiStyleVar_COUNT
};
@ -1971,6 +2011,7 @@ struct ImGuiStyle
ImVec2 SeparatorTextPadding; // Horizontal offset of text from each edge of the separator + spacing on other axis. Generally small values. .y is recommended to be == FramePadding.y.
ImVec2 DisplayWindowPadding; // Window position are clamped to be visible within the display area or monitors by at least this amount. Only applies to regular windows.
ImVec2 DisplaySafeAreaPadding; // If you cannot see the edges of your screen (e.g. on a TV) increase the safe area padding. Apply to popups/tooltips as well regular windows. NB: Prefer configuring your TV sets correctly!
float DockingSeparatorSize; // Thickness of resizing border between docked windows
float MouseCursorScale; // Scale software rendered mouse cursor (when io.MouseDrawCursor is enabled). We apply per-monitor DPI scaling over this scale. May be removed later.
bool AntiAliasedLines; // Enable anti-aliased lines/borders. Disable if you are really tight on CPU/GPU. Latched at the beginning of the frame (copied to ImDrawList).
bool AntiAliasedLinesUseTex; // Enable anti-aliased lines/borders using textures where possible. Require backend to render with bilinear filtering (NOT point/nearest filtering). Latched at the beginning of the frame (copied to ImDrawList).
@ -1979,6 +2020,14 @@ struct ImGuiStyle
float CircleTessellationMaxError; // Maximum error (in pixels) allowed when using AddCircle()/AddCircleFilled() or drawing rounded corner rectangles with no explicit segment count specified. Decrease for higher quality but more geometry.
ImVec4 Colors[ImGuiCol_COUNT];
// Behaviors
// (It is possible to modify those fields mid-frame if specific behavior need it, unlike e.g. configuration fields in ImGuiIO)
float HoverStationaryDelay; // Delay for IsItemHovered(ImGuiHoveredFlags_Stationary). Time required to consider mouse stationary.
float HoverDelayShort; // Delay for IsItemHovered(ImGuiHoveredFlags_DelayShort). Usually used along with HoverStationaryDelay.
float HoverDelayNormal; // Delay for IsItemHovered(ImGuiHoveredFlags_DelayNormal). "
ImGuiHoveredFlags HoverFlagsForTooltipMouse;// Default flags when using IsItemHovered(ImGuiHoveredFlags_ForTooltip) or BeginItemTooltip()/SetItemTooltip() while using mouse.
ImGuiHoveredFlags HoverFlagsForTooltipNav; // Default flags when using IsItemHovered(ImGuiHoveredFlags_ForTooltip) or BeginItemTooltip()/SetItemTooltip() while using keyboard/gamepad.
IMGUI_API ImGuiStyle();
IMGUI_API void ScaleAllSizes(float scale_factor);
};
@ -2011,15 +2060,9 @@ struct ImGuiIO
ImVec2 DisplaySize; // <unset> // Main display size, in pixels (generally == GetMainViewport()->Size). May change every frame.
float DeltaTime; // = 1.0f/60.0f // Time elapsed since last frame, in seconds. May change every frame.
float IniSavingRate; // = 5.0f // Minimum time between saving positions/sizes to .ini file, in seconds.
float InputScale; // = 1.0f // Used by backend in system managed scale situations.
const char* IniFilename; // = "imgui.ini" // Path to .ini file (important: default "imgui.ini" is relative to current working dir!). Set NULL to disable automatic .ini loading/saving or if you want to manually call LoadIniSettingsXXX() / SaveIniSettingsXXX() functions.
const char* LogFilename; // = "imgui_log.txt"// Path to .log file (default parameter to ImGui::LogToFile when no file is specified).
float MouseDoubleClickTime; // = 0.30f // Time for a double-click, in seconds.
float MouseDoubleClickMaxDist; // = 6.0f // Distance threshold to stay in to validate a double-click, in pixels.
float MouseDragThreshold; // = 6.0f // Distance threshold before considering we are dragging.
float KeyRepeatDelay; // = 0.275f // When holding a key/button, time before it starts repeating, in seconds (for buttons in Repeat mode, etc.).
float KeyRepeatRate; // = 0.050f // When holding a key/button, rate at which it repeats, in seconds.
float HoverDelayNormal; // = 0.30 sec // Delay on hovering before IsItemHovered(ImGuiHoveredFlags_DelayNormal) returns true.
float HoverDelayShort; // = 0.10 sec // Delay on hovering before IsItemHovered(ImGuiHoveredFlags_DelayShort) returns true.
void* UserData; // = NULL // Store your own data.
ImFontAtlas*Fonts; // <auto> // Font atlas: load, rasterize and pack one or more fonts into a single texture.
@ -2054,18 +2097,33 @@ struct ImGuiIO
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.
// Inputs Behaviors
// (other variables, ones which are expected to be tweaked within UI code, are exposed in ImGuiStyle)
float MouseDoubleClickTime; // = 0.30f // Time for a double-click, in seconds.
float MouseDoubleClickMaxDist; // = 6.0f // Distance threshold to stay in to validate a double-click, in pixels.
float MouseDragThreshold; // = 6.0f // Distance threshold before considering we are dragging.
float KeyRepeatDelay; // = 0.275f // When holding a key/button, time before it starts repeating, in seconds (for buttons in Repeat mode, etc.).
float KeyRepeatRate; // = 0.050f // When holding a key/button, rate at which it repeats, in seconds.
//------------------------------------------------------------------
// Debug options
// - tools to test correct Begin/End and BeginChild/EndChild behaviors.
// - presently Begin()/End() and BeginChild()/EndChild() needs to ALWAYS be called in tandem, regardless of return value of BeginXXX()
// this is inconsistent with other BeginXXX functions and create confusion for many users.
// - we expect to update the API eventually. In the meanwhile we provide tools to facilitate checking user-code behavior.
//------------------------------------------------------------------
// Tools to test correct Begin/End and BeginChild/EndChild behaviors.
// Presently Begin()/End() and BeginChild()/EndChild() needs to ALWAYS be called in tandem, regardless of return value of BeginXXX()
// This is inconsistent with other BeginXXX functions and create confusion for many users.
// We expect to update the API eventually. In the meanwhile we provide tools to facilitate checking user-code behavior.
bool ConfigDebugBeginReturnValueOnce;// = false // First-time calls to Begin()/BeginChild() will return false. NEEDS TO BE SET AT APPLICATION BOOT TIME if you don't want to miss windows.
bool ConfigDebugBeginReturnValueLoop;// = false // Some calls to Begin()/BeginChild() will return false. Will cycle through window depths then repeat. Suggested use: add "io.ConfigDebugBeginReturnValue = io.KeyShift" in your main loop then occasionally press SHIFT. Windows should be flickering while running.
// - option to deactivate io.AddFocusEvent(false) handling. May facilitate interactions with a debugger when focus loss leads to clearing inputs data.
// - backends may have other side-effects on focus loss, so this will reduce side-effects but not necessary remove all of them.
// - consider using e.g. Win32's IsDebuggerPresent() as an additional filter (or see ImOsIsDebuggerPresent() in imgui_test_engine/imgui_te_utils.cpp for a Unix compatible version).
// Option to deactivate io.AddFocusEvent(false) handling. May facilitate interactions with a debugger when focus loss leads to clearing inputs data.
// Backends may have other side-effects on focus loss, so this will reduce side-effects but not necessary remove all of them.
// Consider using e.g. Win32's IsDebuggerPresent() as an additional filter (or see ImOsIsDebuggerPresent() in imgui_test_engine/imgui_te_utils.cpp for a Unix compatible version).
bool ConfigDebugIgnoreFocusLoss; // = false // Ignore io.AddFocusEvent(false), consequently not calling io.ClearInputKeys() in input processing.
// Option to audit .ini data
bool ConfigDebugIniSettings; // = false // Save .ini data with extra comments (particularly helpful for Docking, but makes saving slower)
//------------------------------------------------------------------
// Platform Functions
// (the imgui_impl_xxxx backend files are setting those up for you)
@ -2112,8 +2170,11 @@ struct ImGuiIO
IMGUI_API void SetKeyEventNativeData(ImGuiKey key, int native_keycode, int native_scancode, int native_legacy_index = -1); // [Optional] Specify index for legacy <1.87 IsKeyXXX() functions with native indices + specify native keycode, scancode.
IMGUI_API void SetAppAcceptingEvents(bool accepting_events); // Set master flag for accepting key/mouse/text events (default to true). Useful if you have native dialog boxes that are interrupting your application loop/refresh, and you want to disable events being queued while your app is frozen.
IMGUI_API void ClearInputCharacters(); // [Internal] Clear the text input buffer manually
IMGUI_API void ClearInputKeys(); // [Internal] Release all keys
IMGUI_API void ClearEventsQueue(); // Clear all incoming events.
IMGUI_API void ClearInputKeys(); // Clear current keyboard/mouse/gamepad state + current frame text input buffer. Equivalent to releasing all keys/buttons.
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
IMGUI_API void ClearInputCharacters(); // [Obsolete] Clear the current frame text input buffer. Now included within ClearInputKeys().
#endif
//------------------------------------------------------------------
// Output - Updated by NewFrame() or EndFrame()/Render()
@ -2544,8 +2605,8 @@ struct ImColor
constexpr ImColor() { }
constexpr ImColor(float r, float g, float b, float a = 1.0f) : Value(r, g, b, a) { }
constexpr ImColor(const ImVec4& col) : Value(col) {}
ImColor(int r, int g, int b, int a = 255) { float sc = 1.0f / 255.0f; Value.x = (float)r * sc; Value.y = (float)g * sc; Value.z = (float)b * sc; Value.w = (float)a * sc; }
ImColor(ImU32 rgba) { float sc = 1.0f / 255.0f; Value.x = (float)((rgba >> IM_COL32_R_SHIFT) & 0xFF) * sc; Value.y = (float)((rgba >> IM_COL32_G_SHIFT) & 0xFF) * sc; Value.z = (float)((rgba >> IM_COL32_B_SHIFT) & 0xFF) * sc; Value.w = (float)((rgba >> IM_COL32_A_SHIFT) & 0xFF) * sc; }
constexpr ImColor(int r, int g, int b, int a = 255) : Value((float)r * (1.0f / 255.0f), (float)g * (1.0f / 255.0f), (float)b * (1.0f / 255.0f), (float)a* (1.0f / 255.0f)) {}
constexpr ImColor(ImU32 rgba) : Value((float)((rgba >> IM_COL32_R_SHIFT) & 0xFF) * (1.0f / 255.0f), (float)((rgba >> IM_COL32_G_SHIFT) & 0xFF) * (1.0f / 255.0f), (float)((rgba >> IM_COL32_B_SHIFT) & 0xFF) * (1.0f / 255.0f), (float)((rgba >> IM_COL32_A_SHIFT) & 0xFF) * (1.0f / 255.0f)) {}
inline operator ImU32() const { return ImGui::ColorConvertFloat4ToU32(Value); }
inline operator ImVec4() const { return Value; }
@ -2824,7 +2885,7 @@ struct ImDrawData
int CmdListsCount; // Number of ImDrawList* to render
int TotalIdxCount; // For convenience, sum of all ImDrawList's IdxBuffer.Size
int TotalVtxCount; // For convenience, sum of all ImDrawList's VtxBuffer.Size
ImDrawList** CmdLists; // Array of ImDrawList* to render. The ImDrawList are owned by ImGuiContext and only pointed to from here.
ImVector<ImDrawList*> CmdLists; // Array of ImDrawList* to render. The ImDrawLists are owned by ImGuiContext and only pointed to from here.
ImVec2 DisplayPos; // Top-left position of the viewport to render (== top-left of the orthogonal projection matrix to use) (== GetMainViewport()->Pos for the main viewport, == (0.0) in most single-viewport applications)
ImVec2 DisplaySize; // Size of the viewport to render (== GetMainViewport()->Size for the main viewport, == io.DisplaySize in most single-viewport applications)
ImVec2 FramebufferScale; // Amount of pixels for each unit of DisplaySize. Based on io.DisplayFramebufferScale. Generally (1,1) on normal display, (2,2) on OSX with Retina display.
@ -2832,7 +2893,8 @@ struct ImDrawData
// Functions
ImDrawData() { Clear(); }
void Clear() { memset(this, 0, sizeof(*this)); } // The ImDrawList are owned by ImGuiContext!
IMGUI_API void Clear();
IMGUI_API void AddDrawList(ImDrawList* draw_list); // Helper to add an external draw list into an existing ImDrawData.
IMGUI_API void DeIndexAllBuffers(); // Helper to convert all buffers from indexed to non-indexed, in case you cannot render indexed. Note: this is slow and most likely a waste of resources. Always prefer indexed rendering!
IMGUI_API void ScaleClipRects(const ImVec2& fb_scale); // Helper to scale the ClipRect field of each ImDrawCmd. Use if your final output buffer is at a different scale than Dear ImGui expects, or if there is a difference between your window resolution and framebuffer resolution.
};
@ -2848,7 +2910,7 @@ struct ImFontConfig
bool FontDataOwnedByAtlas; // true // TTF/OTF data ownership taken by the container ImFontAtlas (will delete memory itself).
int FontNo; // 0 // Index of font within TTF/OTF file
float SizePixels; // // Size in pixels for rasterizer (more or less maps to the resulting font height).
int OversampleH; // 3 // Rasterize at higher quality for sub-pixel positioning. Note the difference between 2 and 3 is minimal so you can reduce this to 2 to save memory. Read https://github.com/nothings/stb/blob/master/tests/oversample/README.md for details.
int OversampleH; // 2 // Rasterize at higher quality for sub-pixel positioning. Note the difference between 2 and 3 is minimal. You can reduce this to 1 for large glyphs save memory. Read https://github.com/nothings/stb/blob/master/tests/oversample/README.md for details.
int OversampleV; // 1 // Rasterize at higher quality for sub-pixel positioning. This is not really useful as we don't use sub-pixel positions on the Y axis.
bool PixelSnapH; // false // Align every glyph to pixel boundary. Useful e.g. if you are merging a non-pixel aligned font with the default font. If enabled, you can set OversampleH/V to 1.
ImVec2 GlyphExtraSpacing; // 0, 0 // Extra spacing (in pixels) between glyphs. Only X axis is supported for now.
@ -3309,6 +3371,8 @@ namespace ImGui
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
namespace ImGui
{
// OBSOLETED in 1.89.7 (from June 2023)
IMGUI_API void SetItemAllowOverlap(); // Use SetNextItemAllowOverlap() before item.
// OBSOLETED in 1.89.4 (from March 2023)
static inline void PushAllowKeyboardFocus(bool tab_stop) { PushTabStop(tab_stop); }
static inline void PopAllowKeyboardFocus() { PopTabStop(); }

View file

@ -1,10 +1,12 @@
// dear imgui, v1.89.6
// dear imgui, v1.89.8
// (demo code)
// Help:
// - Read FAQ at http://dearimgui.com/faq
// - Newcomers, read 'Programmer guide' in imgui.cpp for notes on how to setup Dear ImGui in your codebase.
// - Call and read ImGui::ShowDemoWindow() in imgui_demo.cpp. All applications in examples/ are doing that.
// - Need help integrating Dear ImGui in your codebase?
// - Read Getting Started https://github.com/ocornut/imgui/wiki/Getting-Started
// - Read 'Programmer guide' in imgui.cpp for notes on how to setup Dear ImGui in your codebase.
// Read imgui.cpp for more details, documentation and comments.
// Get the latest version at https://github.com/ocornut/imgui
@ -92,11 +94,7 @@ Index of this file:
#include <math.h> // sqrtf, powf, cosf, sinf, floorf, ceilf
#include <stdio.h> // vsnprintf, sscanf, printf
#include <stdlib.h> // NULL, malloc, free, atoi
#if defined(_MSC_VER) && _MSC_VER <= 1500 // MSVC 2008 or earlier
#include <stddef.h> // intptr_t
#else
#include <stdint.h> // intptr_t
#endif
// Visual Studio warnings
#ifdef _MSC_VER
@ -213,7 +211,7 @@ static void ShowDemoWindowInputs();
static void HelpMarker(const char* desc)
{
ImGui::TextDisabled("(?)");
if (ImGui::IsItemHovered(ImGuiHoveredFlags_DelayShort) && ImGui::BeginTooltip())
if (ImGui::BeginItemTooltip())
{
ImGui::PushTextWrapPos(ImGui::GetFontSize() * 35.0f);
ImGui::TextUnformatted(desc);
@ -525,6 +523,8 @@ void ImGui::ShowDemoWindow(bool* p_open)
ImGui::SameLine(); HelpMarker("Some calls to Begin()/BeginChild() will return false.\n\nWill cycle through window depths then repeat. Windows should be flickering while running.");
ImGui::Checkbox("io.ConfigDebugIgnoreFocusLoss", &io.ConfigDebugIgnoreFocusLoss);
ImGui::SameLine(); HelpMarker("Option to deactivate io.AddFocusEvent(false) handling. May facilitate interactions with a debugger when focus loss leads to clearing inputs data.");
ImGui::Checkbox("io.ConfigDebugIniSettings", &io.ConfigDebugIniSettings);
ImGui::SameLine(); HelpMarker("Option to save .ini data with extra comments (particularly helpful for Docking, but makes saving slower).");
ImGui::TreePop();
ImGui::Spacing();
@ -683,37 +683,8 @@ static void ShowDemoWindowWidgets()
ImGui::SameLine();
ImGui::Text("%d", counter);
{
// Tooltips
IMGUI_DEMO_MARKER("Widgets/Basic/Tooltips");
//ImGui::AlignTextToFramePadding();
ImGui::Text("Tooltips:");
ImGui::SameLine();
ImGui::SmallButton("Basic");
if (ImGui::IsItemHovered())
ImGui::SetTooltip("I am a tooltip");
ImGui::SameLine();
ImGui::SmallButton("Fancy");
if (ImGui::IsItemHovered() && ImGui::BeginTooltip())
{
ImGui::Text("I am a fancy tooltip");
static float arr[] = { 0.6f, 0.1f, 1.0f, 0.5f, 0.92f, 0.1f, 0.2f };
ImGui::PlotLines("Curve", arr, IM_ARRAYSIZE(arr));
ImGui::Text("Sin(time) = %f", sinf((float)ImGui::GetTime()));
ImGui::EndTooltip();
}
ImGui::SameLine();
ImGui::SmallButton("Delayed");
if (ImGui::IsItemHovered(ImGuiHoveredFlags_DelayNormal)) // With a delay
ImGui::SetTooltip("I am a tooltip with a delay.");
ImGui::SameLine();
HelpMarker(
"Tooltip are created by using the IsItemHovered() function over any kind of item.");
}
ImGui::Button("Tooltip");
ImGui::SetItemTooltip("I am a tooltip");
ImGui::LabelText("label", "Value");
@ -848,6 +819,85 @@ static void ShowDemoWindowWidgets()
ImGui::TreePop();
}
IMGUI_DEMO_MARKER("Widgets/Tooltips");
if (ImGui::TreeNode("Tooltips"))
{
// Tooltips are windows following the mouse. They do not take focus away.
ImGui::SeparatorText("General");
// Typical use cases:
// - Short-form (text only): SetItemTooltip("Hello");
// - Short-form (any contents): if (BeginItemTooltip()) { Text("Hello"); EndTooltip(); }
// - Full-form (text only): if (IsItemHovered(...)) { SetTooltip("Hello"); }
// - Full-form (any contents): if (IsItemHovered(...) && BeginTooltip()) { Text("Hello"); EndTooltip(); }
HelpMarker(
"Tooltip are typically created by using a IsItemHovered() + SetTooltip() sequence.\n\n"
"We provide a helper SetItemTooltip() function to perform the two with standards flags.");
ImVec2 sz = ImVec2(-FLT_MIN, 0.0f);
ImGui::Button("Basic", sz);
ImGui::SetItemTooltip("I am a tooltip");
ImGui::Button("Fancy", sz);
if (ImGui::BeginItemTooltip())
{
ImGui::Text("I am a fancy tooltip");
static float arr[] = { 0.6f, 0.1f, 1.0f, 0.5f, 0.92f, 0.1f, 0.2f };
ImGui::PlotLines("Curve", arr, IM_ARRAYSIZE(arr));
ImGui::Text("Sin(time) = %f", sinf((float)ImGui::GetTime()));
ImGui::EndTooltip();
}
ImGui::SeparatorText("Always On");
// Showcase NOT relying on a IsItemHovered() to emit a tooltip.
// Here the tooltip is always emitted when 'always_on == true'.
static int always_on = 0;
ImGui::RadioButton("Off", &always_on, 0);
ImGui::SameLine();
ImGui::RadioButton("Always On (Simple)", &always_on, 1);
ImGui::SameLine();
ImGui::RadioButton("Always On (Advanced)", &always_on, 2);
if (always_on == 1)
ImGui::SetTooltip("I am following you around.");
else if (always_on == 2 && ImGui::BeginTooltip())
{
ImGui::ProgressBar(sinf((float)ImGui::GetTime()) * 0.5f + 0.5f, ImVec2(ImGui::GetFontSize() * 25, 0.0f));
ImGui::EndTooltip();
}
ImGui::SeparatorText("Custom");
// The following examples are passed for documentation purpose but may not be useful to most users.
// Passing ImGuiHoveredFlags_Tooltip to IsItemHovered() will pull ImGuiHoveredFlags flags values from
// 'style.HoverFlagsForTooltipMouse' or 'style.HoverFlagsForTooltipNav' depending on whether mouse or gamepad/keyboard is being used.
// With default settings, ImGuiHoveredFlags_Tooltip is equivalent to ImGuiHoveredFlags_DelayShort + ImGuiHoveredFlags_Stationary.
ImGui::Button("Manual", sz);
if (ImGui::IsItemHovered(ImGuiHoveredFlags_ForTooltip))
ImGui::SetTooltip("I am a manually emitted tooltip");
ImGui::Button("DelayNone", sz);
if (ImGui::IsItemHovered(ImGuiHoveredFlags_DelayNone))
ImGui::SetTooltip("I am a tooltip with no delay.");
ImGui::Button("DelayShort", sz);
if (ImGui::IsItemHovered(ImGuiHoveredFlags_DelayShort | ImGuiHoveredFlags_NoSharedDelay))
ImGui::SetTooltip("I am a tooltip with a short delay (%0.2f sec).", ImGui::GetStyle().HoverDelayShort);
ImGui::Button("DelayLong", sz);
if (ImGui::IsItemHovered(ImGuiHoveredFlags_DelayNormal | ImGuiHoveredFlags_NoSharedDelay))
ImGui::SetTooltip("I am a tooltip with a long delay (%0.2f sec)", ImGui::GetStyle().HoverDelayNormal);
ImGui::Button("Stationary", sz);
if (ImGui::IsItemHovered(ImGuiHoveredFlags_Stationary))
ImGui::SetTooltip("I am a tooltip requiring mouse to be stationary before activating.");
ImGui::TreePop();
}
// Testing ImGuiOnceUponAFrame helper.
//static ImGuiOnceUponAFrame once;
//for (int i = 0; i < 5; i++)
@ -1113,7 +1163,7 @@ static void ShowDemoWindowWidgets()
ImVec4 tint_col = use_text_color_for_tint ? ImGui::GetStyleColorVec4(ImGuiCol_Text) : ImVec4(1.0f, 1.0f, 1.0f, 1.0f); // No tint
ImVec4 border_col = ImGui::GetStyleColorVec4(ImGuiCol_Border);
ImGui::Image(my_tex_id, ImVec2(my_tex_w, my_tex_h), uv_min, uv_max, tint_col, border_col);
if (ImGui::IsItemHovered() && ImGui::BeginTooltip())
if (ImGui::BeginItemTooltip())
{
float region_sz = 32.0f;
float region_x = io.MousePos.x - pos.x - region_sz * 0.5f;
@ -1267,16 +1317,16 @@ static void ShowDemoWindowWidgets()
IMGUI_DEMO_MARKER("Widgets/Selectables/Basic");
if (ImGui::TreeNode("Basic"))
{
static bool selection[5] = { false, true, false, false, false };
static bool selection[5] = { false, true, false, false };
ImGui::Selectable("1. I am selectable", &selection[0]);
ImGui::Selectable("2. I am selectable", &selection[1]);
ImGui::Text("(I am not selectable)");
ImGui::Selectable("4. I am selectable", &selection[3]);
if (ImGui::Selectable("5. I am double clickable", selection[4], ImGuiSelectableFlags_AllowDoubleClick))
ImGui::Selectable("3. I am selectable", &selection[2]);
if (ImGui::Selectable("4. I am double clickable", selection[3], ImGuiSelectableFlags_AllowDoubleClick))
if (ImGui::IsMouseDoubleClicked(0))
selection[4] = !selection[4];
selection[3] = !selection[3];
ImGui::TreePop();
}
IMGUI_DEMO_MARKER("Widgets/Selectables/Single Selection");
if (ImGui::TreeNode("Selection State: Single Selection"))
{
@ -1308,17 +1358,18 @@ static void ShowDemoWindowWidgets()
}
ImGui::TreePop();
}
IMGUI_DEMO_MARKER("Widgets/Selectables/Rendering more text into the same line");
if (ImGui::TreeNode("Rendering more text into the same line"))
IMGUI_DEMO_MARKER("Widgets/Selectables/Rendering more items on the same line");
if (ImGui::TreeNode("Rendering more items on the same line"))
{
// Using the Selectable() override that takes "bool* p_selected" parameter,
// this function toggle your bool value automatically.
// (1) Using SetNextItemAllowOverlap()
// (2) Using the Selectable() override that takes "bool* p_selected" parameter, the bool value is toggled automatically.
static bool selected[3] = { false, false, false };
ImGui::Selectable("main.c", &selected[0]); ImGui::SameLine(300); ImGui::Text(" 2,345 bytes");
ImGui::Selectable("Hello.cpp", &selected[1]); ImGui::SameLine(300); ImGui::Text("12,345 bytes");
ImGui::Selectable("Hello.h", &selected[2]); ImGui::SameLine(300); ImGui::Text(" 2,345 bytes");
ImGui::SetNextItemAllowOverlap(); ImGui::Selectable("main.c", &selected[0]); ImGui::SameLine(); ImGui::SmallButton("Link 1");
ImGui::SetNextItemAllowOverlap(); ImGui::Selectable("Hello.cpp", &selected[1]); ImGui::SameLine(); ImGui::SmallButton("Link 2");
ImGui::SetNextItemAllowOverlap(); ImGui::Selectable("Hello.h", &selected[2]); ImGui::SameLine(); ImGui::SmallButton("Link 3");
ImGui::TreePop();
}
IMGUI_DEMO_MARKER("Widgets/Selectables/In columns");
if (ImGui::TreeNode("In columns"))
{
@ -1354,6 +1405,7 @@ static void ShowDemoWindowWidgets()
}
ImGui::TreePop();
}
IMGUI_DEMO_MARKER("Widgets/Selectables/Grid");
if (ImGui::TreeNode("Grid"))
{
@ -1452,8 +1504,8 @@ static void ShowDemoWindowWidgets()
// Modify character input by altering 'data->Eventchar' (ImGuiInputTextFlags_CallbackCharFilter callback)
static int FilterCasingSwap(ImGuiInputTextCallbackData* data)
{
if (data->EventChar >= 'a' && data->EventChar <= 'z') { data->EventChar = data->EventChar - 'A' - 'a'; } // Lowercase becomes uppercase
else if (data->EventChar >= 'A' && data->EventChar <= 'Z') { data->EventChar = data->EventChar + 'a' - 'A'; } // Uppercase becomes lowercase
if (data->EventChar >= 'a' && data->EventChar <= 'z') { data->EventChar -= 'a' - 'A'; } // Lowercase becomes uppercase
else if (data->EventChar >= 'A' && data->EventChar <= 'Z') { data->EventChar += 'a' - 'A'; } // Uppercase becomes lowercase
return 0;
}
@ -1487,6 +1539,7 @@ static void ShowDemoWindowWidgets()
ImGui::TreePop();
}
IMGUI_DEMO_MARKER("Widgets/Text Input/Completion, History, Edit Callbacks");
if (ImGui::TreeNode("Completion, History, Edit Callbacks"))
{
struct Funcs
@ -1586,6 +1639,18 @@ static void ShowDemoWindowWidgets()
ImGui::TreePop();
}
IMGUI_DEMO_MARKER("Widgets/Text Input/Miscellaneous");
if (ImGui::TreeNode("Miscellaneous"))
{
static char buf1[16];
static ImGuiInputTextFlags flags = ImGuiInputTextFlags_EscapeClearsAll;
ImGui::CheckboxFlags("ImGuiInputTextFlags_EscapeClearsAll", &flags, ImGuiInputTextFlags_EscapeClearsAll);
ImGui::CheckboxFlags("ImGuiInputTextFlags_ReadOnly", &flags, ImGuiInputTextFlags_ReadOnly);
ImGui::CheckboxFlags("ImGuiInputTextFlags_NoUndoRedo", &flags, ImGuiInputTextFlags_NoUndoRedo);
ImGui::InputText("Hello", buf1, IM_ARRAYSIZE(buf1), flags);
ImGui::TreePop();
}
ImGui::TreePop();
}
@ -2434,8 +2499,10 @@ static void ShowDemoWindowWidgets()
if (item_type == 15){ const char* items[] = { "Apple", "Banana", "Cherry", "Kiwi" }; static int current = 1; ret = ImGui::ListBox("ITEM: ListBox", &current, items, IM_ARRAYSIZE(items), IM_ARRAYSIZE(items)); }
bool hovered_delay_none = ImGui::IsItemHovered();
bool hovered_delay_stationary = ImGui::IsItemHovered(ImGuiHoveredFlags_Stationary);
bool hovered_delay_short = ImGui::IsItemHovered(ImGuiHoveredFlags_DelayShort);
bool hovered_delay_normal = ImGui::IsItemHovered(ImGuiHoveredFlags_DelayNormal);
bool hovered_delay_tooltip = ImGui::IsItemHovered(ImGuiHoveredFlags_ForTooltip); // = Normal + Stationary
// Display the values of IsItemHovered() and other common item state functions.
// Note that the ImGuiHoveredFlags_XXX flags can be combined.
@ -2447,7 +2514,8 @@ static void ShowDemoWindowWidgets()
"IsItemHovered() = %d\n"
"IsItemHovered(_AllowWhenBlockedByPopup) = %d\n"
"IsItemHovered(_AllowWhenBlockedByActiveItem) = %d\n"
"IsItemHovered(_AllowWhenOverlapped) = %d\n"
"IsItemHovered(_AllowWhenOverlappedByItem) = %d\n"
"IsItemHovered(_AllowWhenOverlappedByWindow) = %d\n"
"IsItemHovered(_AllowWhenDisabled) = %d\n"
"IsItemHovered(_RectOnly) = %d\n"
"IsItemActive() = %d\n"
@ -2466,7 +2534,8 @@ static void ShowDemoWindowWidgets()
ImGui::IsItemHovered(),
ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenBlockedByPopup),
ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenBlockedByActiveItem),
ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenOverlapped),
ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenOverlappedByItem),
ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenOverlappedByWindow),
ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled),
ImGui::IsItemHovered(ImGuiHoveredFlags_RectOnly),
ImGui::IsItemActive(),
@ -2482,7 +2551,13 @@ static void ShowDemoWindowWidgets()
ImGui::GetItemRectSize().x, ImGui::GetItemRectSize().y
);
ImGui::BulletText(
"w/ Hovering Delay: None = %d, Fast %d, Normal = %d", hovered_delay_none, hovered_delay_short, hovered_delay_normal);
"with Hovering Delay or Stationary test:\n"
"IsItemHovered() = = %d\n"
"IsItemHovered(_Stationary) = %d\n"
"IsItemHovered(_DelayShort) = %d\n"
"IsItemHovered(_DelayNormal) = %d\n"
"IsItemHovered(_Tooltip) = %d",
hovered_delay_none, hovered_delay_stationary, hovered_delay_short, hovered_delay_normal, hovered_delay_tooltip);
if (item_disabled)
ImGui::EndDisabled();
@ -2543,7 +2618,8 @@ static void ShowDemoWindowWidgets()
"IsWindowHovered(_RootWindow|_NoPopupHierarchy) = %d\n"
"IsWindowHovered(_RootWindow|_DockHierarchy) = %d\n"
"IsWindowHovered(_ChildWindows|_AllowWhenBlockedByPopup) = %d\n"
"IsWindowHovered(_AnyWindow) = %d\n",
"IsWindowHovered(_AnyWindow) = %d\n"
"IsWindowHovered(_Stationary) = %d\n",
ImGui::IsWindowHovered(),
ImGui::IsWindowHovered(ImGuiHoveredFlags_AllowWhenBlockedByPopup),
ImGui::IsWindowHovered(ImGuiHoveredFlags_AllowWhenBlockedByActiveItem),
@ -2557,7 +2633,8 @@ static void ShowDemoWindowWidgets()
ImGui::IsWindowHovered(ImGuiHoveredFlags_RootWindow | ImGuiHoveredFlags_NoPopupHierarchy),
ImGui::IsWindowHovered(ImGuiHoveredFlags_RootWindow | ImGuiHoveredFlags_DockHierarchy),
ImGui::IsWindowHovered(ImGuiHoveredFlags_ChildWindows | ImGuiHoveredFlags_AllowWhenBlockedByPopup),
ImGui::IsWindowHovered(ImGuiHoveredFlags_AnyWindow));
ImGui::IsWindowHovered(ImGuiHoveredFlags_AnyWindow),
ImGui::IsWindowHovered(ImGuiHoveredFlags_Stationary));
ImGui::BeginChild("child", ImVec2(0, 50), true);
ImGui::Text("This is another child window for testing the _ChildWindows flag.");
@ -2858,7 +2935,7 @@ static void ShowDemoWindowLayout()
ImGui::PushID(i);
ImGui::ListBox("", &selection[i], items, IM_ARRAYSIZE(items));
ImGui::PopID();
//if (ImGui::IsItemHovered()) ImGui::SetTooltip("ListBox %d hovered", i);
//ImGui::SetItemTooltip("ListBox %d hovered", i);
}
ImGui::PopItemWidth();
@ -2911,8 +2988,7 @@ static void ShowDemoWindowLayout()
ImGui::SameLine();
ImGui::Button("EEE");
ImGui::EndGroup();
if (ImGui::IsItemHovered())
ImGui::SetTooltip("First group hovered");
ImGui::SetItemTooltip("First group hovered");
}
// Capture the group size and create widgets using the same size
ImVec2 size = ImGui::GetItemRectSize();
@ -3406,6 +3482,36 @@ static void ShowDemoWindowLayout()
ImGui::TreePop();
}
IMGUI_DEMO_MARKER("Layout/Overlap Mode");
if (ImGui::TreeNode("Overlap Mode"))
{
static bool enable_allow_overlap = true;
HelpMarker(
"Hit-testing is by default performed in item submission order, which generally is perceived as 'back-to-front'.\n\n"
"By using SetNextItemAllowOverlap() you can notify that an item may be overlapped by another. Doing so alters the hovering logic: items using AllowOverlap mode requires an extra frame to accept hovered state.");
ImGui::Checkbox("Enable AllowOverlap", &enable_allow_overlap);
ImVec2 button1_pos = ImGui::GetCursorScreenPos();
ImVec2 button2_pos = ImVec2(button1_pos.x + 50.0f, button1_pos.y + 50.0f);
if (enable_allow_overlap)
ImGui::SetNextItemAllowOverlap();
ImGui::Button("Button 1", ImVec2(80, 80));
ImGui::SetCursorScreenPos(button2_pos);
ImGui::Button("Button 2", ImVec2(80, 80));
// This is typically used with width-spanning items.
// (note that Selectable() has a dedicated flag ImGuiSelectableFlags_AllowOverlap, which is a shortcut
// for using SetNextItemAllowOverlap(). For demo purpose we use SetNextItemAllowOverlap() here.)
if (enable_allow_overlap)
ImGui::SetNextItemAllowOverlap();
ImGui::Selectable("Some Selectable", false);
ImGui::SameLine();
ImGui::SmallButton("++");
ImGui::TreePop();
}
}
static void ShowDemoWindowPopups()
@ -3473,8 +3579,7 @@ static void ShowDemoWindowPopups()
ImGui::Separator();
ImGui::Text("Tooltip here");
if (ImGui::IsItemHovered())
ImGui::SetTooltip("I am a tooltip over a popup");
ImGui::SetItemTooltip("I am a tooltip over a popup");
if (ImGui::Button("Stacked Popup"))
ImGui::OpenPopup("another popup");
@ -3558,8 +3663,7 @@ static void ShowDemoWindowPopups()
ImGui::CloseCurrentPopup();
ImGui::EndPopup();
}
if (ImGui::IsItemHovered())
ImGui::SetTooltip("Right-click to open popup");
ImGui::SetItemTooltip("Right-click to open popup");
}
}
@ -3811,7 +3915,7 @@ static void EditTableSizingFlags(ImGuiTableFlags* p_flags)
}
ImGui::SameLine();
ImGui::TextDisabled("(?)");
if (ImGui::IsItemHovered() && ImGui::BeginTooltip())
if (ImGui::BeginItemTooltip())
{
ImGui::PushTextWrapPos(ImGui::GetFontSize() * 50.0f);
for (int m = 0; m < IM_ARRAYSIZE(policies); m++)
@ -5509,7 +5613,7 @@ static void ShowDemoWindowTables()
ImGui::Button(label, ImVec2(-FLT_MIN, 0.0f));
else if (contents_type == CT_Selectable || contents_type == CT_SelectableSpanRow)
{
ImGuiSelectableFlags selectable_flags = (contents_type == CT_SelectableSpanRow) ? ImGuiSelectableFlags_SpanAllColumns | ImGuiSelectableFlags_AllowItemOverlap : ImGuiSelectableFlags_None;
ImGuiSelectableFlags selectable_flags = (contents_type == CT_SelectableSpanRow) ? ImGuiSelectableFlags_SpanAllColumns | ImGuiSelectableFlags_AllowOverlap : ImGuiSelectableFlags_None;
if (ImGui::Selectable(label, item_is_selected, selectable_flags, ImVec2(0, row_min_height)))
{
if (ImGui::GetIO().KeyCtrl)
@ -6012,10 +6116,11 @@ void ImGui::ShowAboutWindow(bool* p_open)
return;
}
IMGUI_DEMO_MARKER("Tools/About Dear ImGui");
ImGui::Text("Dear ImGui %s", ImGui::GetVersion());
ImGui::Text("Dear ImGui %s (%d)", IMGUI_VERSION, IMGUI_VERSION_NUM);
ImGui::Separator();
ImGui::Text("By Omar Cornut and all Dear ImGui contributors.");
ImGui::Text("Dear ImGui is licensed under the MIT License, see LICENSE for more information.");
ImGui::Text("If your company uses this, please consider sponsoring the project!");
static bool show_config_info = false;
ImGui::Checkbox("Config/Build Information", &show_config_info);
@ -6311,11 +6416,28 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref)
ImGui::SameLine(); HelpMarker("Alignment applies when a selectable is larger than its text content.");
ImGui::SliderFloat("SeparatorTextBorderSize", &style.SeparatorTextBorderSize, 0.0f, 10.0f, "%.0f");
ImGui::SliderFloat2("SeparatorTextAlign", (float*)&style.SeparatorTextAlign, 0.0f, 1.0f, "%.2f");
ImGui::SliderFloat2("SeparatorTextPadding", (float*)&style.SeparatorTextPadding, 0.0f, 40.0f, "%0.f");
ImGui::SliderFloat2("SeparatorTextPadding", (float*)&style.SeparatorTextPadding, 0.0f, 40.0f, "%.0f");
ImGui::SliderFloat("LogSliderDeadzone", &style.LogSliderDeadzone, 0.0f, 12.0f, "%.0f");
ImGui::SeparatorText("Docking");
ImGui::SliderFloat("DockingSplitterSize", &style.DockingSeparatorSize, 0.0f, 12.0f, "%.0f");
ImGui::SeparatorText("Tooltips");
for (int n = 0; n < 2; n++)
if (ImGui::TreeNodeEx(n == 0 ? "HoverFlagsForTooltipMouse" : "HoverFlagsForTooltipNav"))
{
ImGuiHoveredFlags* p = (n == 0) ? &style.HoverFlagsForTooltipMouse : &style.HoverFlagsForTooltipNav;
ImGui::CheckboxFlags("ImGuiHoveredFlags_DelayNone", p, ImGuiHoveredFlags_DelayNone);
ImGui::CheckboxFlags("ImGuiHoveredFlags_DelayShort", p, ImGuiHoveredFlags_DelayShort);
ImGui::CheckboxFlags("ImGuiHoveredFlags_DelayNormal", p, ImGuiHoveredFlags_DelayNormal);
ImGui::CheckboxFlags("ImGuiHoveredFlags_Stationary", p, ImGuiHoveredFlags_Stationary);
ImGui::CheckboxFlags("ImGuiHoveredFlags_NoSharedDelay", p, ImGuiHoveredFlags_NoSharedDelay);
ImGui::TreePop();
}
ImGui::SeparatorText("Misc");
ImGui::SliderFloat2("DisplaySafeAreaPadding", (float*)&style.DisplaySafeAreaPadding, 0.0f, 30.0f, "%.0f"); ImGui::SameLine(); HelpMarker("Adjust if you cannot see the edges of your screen (e.g. on a TV where scaling has not been configured).");
ImGui::EndTabItem();
}
@ -7872,18 +7994,20 @@ static void ShowExampleAppCustomRendering(bool* p_open)
// your own implicit "Debug##2" window after calling DockSpace() and leave it in the window stack for anyone to use.
void ShowExampleAppDockSpace(bool* p_open)
{
// If you strip some features of, this demo is pretty much equivalent to calling DockSpaceOverViewport()!
// In most cases you should be able to just call DockSpaceOverViewport() and ignore all the code below!
// In this specific demo, we are not using DockSpaceOverViewport() because:
// - we allow the host window to be floating/moveable instead of filling the viewport (when opt_fullscreen == false)
// - we allow the host window to have padding (when opt_padding == true)
// - we have a local menu bar in the host window (vs. you could use BeginMainMenuBar() + DockSpaceOverViewport() in your code!)
// TL;DR; this demo is more complicated than what you would normally use.
// If we removed all the options we are showcasing, this demo would become:
// READ THIS !!!
// TL;DR; this demo is more complicated than what most users you would normally use.
// If we remove all options we are showcasing, this demo would become:
// void ShowExampleAppDockSpace()
// {
// ImGui::DockSpaceOverViewport(ImGui::GetMainViewport());
// }
// In most cases you should be able to just call DockSpaceOverViewport() and ignore all the code below!
// In this specific demo, we are not using DockSpaceOverViewport() because:
// - (1) we allow the host window to be floating/moveable instead of filling the viewport (when opt_fullscreen == false)
// - (2) we allow the host window to have padding (when opt_padding == true)
// - (3) we expose many flags and need a way to have them visible.
// - (4) we have a local menu bar in the host window (vs. you could use BeginMainMenuBar() + DockSpaceOverViewport()
// in your code, but we don't here because we allow the window to be floating)
static bool opt_fullscreen = true;
static bool opt_padding = false;
@ -8293,8 +8417,8 @@ void ShowExampleAppDocuments(bool* p_open)
for (int n = 0; n < close_queue.Size; n++)
if (close_queue[n]->Dirty)
ImGui::Text("%s", close_queue[n]->Name);
ImGui::EndChildFrame();
}
ImGui::EndChildFrame();
ImVec2 button_size(ImGui::GetFontSize() * 7.0f, 0.0f);
if (ImGui::Button("Yes", button_size))

View file

@ -1,4 +1,4 @@
// dear imgui, v1.89.6
// dear imgui, v1.89.8
// (drawing and font code)
/*
@ -63,6 +63,7 @@ Index of this file:
#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.
#pragma clang diagnostic ignored "-Wimplicit-int-float-conversion" // warning: implicit conversion from 'xxx' to 'float' may lose precision
#pragma clang diagnostic ignored "-Wreserved-identifier" // warning: identifier '_Xxx' is reserved because it starts with '_' followed by a capital letter
#elif defined(__GNUC__)
#pragma GCC diagnostic ignored "-Wpragmas" // warning: unknown option after '#pragma GCC diagnostic' kind
#pragma GCC diagnostic ignored "-Wunused-function" // warning: 'xxxx' defined but not used
@ -1861,6 +1862,63 @@ void ImDrawListSplitter::SetCurrentChannel(ImDrawList* draw_list, int idx)
// [SECTION] ImDrawData
//-----------------------------------------------------------------------------
void ImDrawData::Clear()
{
Valid = false;
CmdListsCount = TotalIdxCount = TotalVtxCount = 0;
CmdLists.resize(0); // The ImDrawList are NOT owned by ImDrawData but e.g. by ImGuiContext, so we don't clear them.
DisplayPos = DisplaySize = FramebufferScale = ImVec2(0.0f, 0.0f);
OwnerViewport = NULL;
}
// Important: 'out_list' is generally going to be draw_data->CmdLists, but may be another temporary list
// as long at it is expected that the result will be later merged into draw_data->CmdLists[].
void ImGui::AddDrawListToDrawDataEx(ImDrawData* draw_data, ImVector<ImDrawList*>* out_list, ImDrawList* draw_list)
{
if (draw_list->CmdBuffer.Size == 0)
return;
if (draw_list->CmdBuffer.Size == 1 && draw_list->CmdBuffer[0].ElemCount == 0 && draw_list->CmdBuffer[0].UserCallback == NULL)
return;
// Draw list sanity check. Detect mismatch between PrimReserve() calls and incrementing _VtxCurrentIdx, _VtxWritePtr etc.
// May trigger for you if you are using PrimXXX functions incorrectly.
IM_ASSERT(draw_list->VtxBuffer.Size == 0 || draw_list->_VtxWritePtr == draw_list->VtxBuffer.Data + draw_list->VtxBuffer.Size);
IM_ASSERT(draw_list->IdxBuffer.Size == 0 || draw_list->_IdxWritePtr == draw_list->IdxBuffer.Data + draw_list->IdxBuffer.Size);
if (!(draw_list->Flags & ImDrawListFlags_AllowVtxOffset))
IM_ASSERT((int)draw_list->_VtxCurrentIdx == draw_list->VtxBuffer.Size);
// Check that draw_list doesn't use more vertices than indexable (default ImDrawIdx = unsigned short = 2 bytes = 64K vertices per ImDrawList = per window)
// If this assert triggers because you are drawing lots of stuff manually:
// - First, make sure you are coarse clipping yourself and not trying to draw many things outside visible bounds.
// Be mindful that the lower-level ImDrawList API doesn't filter vertices. Use the Metrics/Debugger window to inspect draw list contents.
// - If you want large meshes with more than 64K vertices, you can either:
// (A) Handle the ImDrawCmd::VtxOffset value in your renderer backend, and set 'io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset'.
// Most example backends already support this from 1.71. Pre-1.71 backends won't.
// Some graphics API such as GL ES 1/2 don't have a way to offset the starting vertex so it is not supported for them.
// (B) Or handle 32-bit indices in your renderer backend, and uncomment '#define ImDrawIdx unsigned int' line in imconfig.h.
// Most example backends already support this. For example, the OpenGL example code detect index size at compile-time:
// glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, idx_buffer_offset);
// Your own engine or render API may use different parameters or function calls to specify index sizes.
// 2 and 4 bytes indices are generally supported by most graphics API.
// - If for some reason neither of those solutions works for you, a workaround is to call BeginChild()/EndChild() before reaching
// the 64K limit to split your draw commands in multiple draw lists.
if (sizeof(ImDrawIdx) == 2)
IM_ASSERT(draw_list->_VtxCurrentIdx < (1 << 16) && "Too many vertices in ImDrawList using 16-bit indices. Read comment above");
// Add to output list + records state in ImDrawData
out_list->push_back(draw_list);
draw_data->CmdListsCount++;
draw_data->TotalVtxCount += draw_list->VtxBuffer.Size;
draw_data->TotalIdxCount += draw_list->IdxBuffer.Size;
}
void ImDrawData::AddDrawList(ImDrawList* draw_list)
{
IM_ASSERT(CmdLists.Size == CmdListsCount);
draw_list->_PopUnusedDrawCmd();
ImGui::AddDrawListToDrawDataEx(this, &CmdLists, draw_list);
}
// For backward compatibility: convert all buffers from indexed to de-indexed, in case you cannot render indexed. Note: this is slow and most likely a waste of resources. Always prefer indexed rendering!
void ImDrawData::DeIndexAllBuffers()
{
@ -1957,7 +2015,7 @@ ImFontConfig::ImFontConfig()
{
memset(this, 0, sizeof(*this));
FontDataOwnedByAtlas = true;
OversampleH = 3; // FIXME: 2 may be a better default?
OversampleH = 2;
OversampleV = 1;
GlyphMaxAdvanceX = FLT_MAX;
RasterizerMultiply = 1.0f;
@ -2228,7 +2286,7 @@ ImFont* ImFontAtlas::AddFontFromMemoryCompressedTTF(const void* compressed_ttf_d
#ifdef TA_BIG_ENDIAN
unsigned char* beData=(unsigned char*)IM_ALLOC(compressed_ttf_size);
for (int i=0; i<compressed_ttf_size; i++) {
beData[i]=compressed_ttf_data[i^3];
beData[i]=((unsigned char*)compressed_ttf_data)[i^3];
}
compressed_ttf_data=beData;
#endif

View file

@ -1,4 +1,4 @@
// dear imgui, v1.89.6
// dear imgui, v1.89.8
// (internal structures/api)
// You may use this file to debug, understand or extend Dear ImGui features but we don't provide any guarantee of forward compatibility.
@ -278,6 +278,8 @@ namespace ImStb
#define IM_F32_TO_INT8_SAT(_VAL) ((int)(ImSaturate(_VAL) * 255.0f + 0.5f)) // Saturated, always output 0..255
#define IM_FLOOR(_VAL) ((float)(int)(_VAL)) // ImFloor() is not inlined in MSVC debug builds
#define IM_ROUND(_VAL) ((float)(int)((_VAL) + 0.5f)) //
#define IM_STRINGIFY_HELPER(_X) #_X
#define IM_STRINGIFY(_X) IM_STRINGIFY_HELPER(_X) // Preprocessor idiom to stringify e.g. an integer.
// Enforce cdecl calling convention for functions called by the standard library, in case compilation settings changed the default to e.g. __vectorcall
#ifdef _MSC_VER
@ -780,12 +782,10 @@ struct IMGUI_API ImDrawListSharedData
struct ImDrawDataBuilder
{
ImVector<ImDrawList*> Layers[2]; // Global layers for: regular, tooltip
ImVector<ImDrawList*>* Layers[2]; // Pointers to global layers for: regular, tooltip. LayersP[0] is owned by DrawData.
ImVector<ImDrawList*> LayerData1;
void Clear() { for (int n = 0; n < IM_ARRAYSIZE(Layers); n++) Layers[n].resize(0); }
void ClearFreeMemory() { for (int n = 0; n < IM_ARRAYSIZE(Layers); n++) Layers[n].clear(); }
int GetDrawListCount() const { int count = 0; for (int n = 0; n < IM_ARRAYSIZE(Layers); n++) count += Layers[n].Size; return count; }
IMGUI_API void FlattenIntoSingleLayer();
ImDrawDataBuilder() { memset(this, 0, sizeof(*this)); }
};
//-----------------------------------------------------------------------------
@ -810,6 +810,7 @@ enum ImGuiItemFlags_
ImGuiItemFlags_MixedValue = 1 << 6, // false // [BETA] Represent a mixed/indeterminate value, generally multi-selection where values differ. Currently only supported by Checkbox() (later should support all sorts of widgets)
ImGuiItemFlags_ReadOnly = 1 << 7, // false // [ALPHA] Allow hovering interactions but underlying value is not changed.
ImGuiItemFlags_NoWindowHoverableCheck = 1 << 8, // false // Disable hoverable check in ItemHoverable()
ImGuiItemflags_AllowOverlap = 1 << 9, // false // Allow being overlapped by another widget. Not-hovered to Hovered transition deferred by a frame.
// Controlled by widget code
ImGuiItemFlags_Inputable = 1 << 10, // false // [WIP] Auto-activate input mode when tab focused. Currently only used and supported by a few items before it becomes a generic feature.
@ -842,6 +843,14 @@ enum ImGuiItemStatusFlags_
#endif
};
// Extend ImGuiHoveredFlags_
enum ImGuiHoveredFlagsPrivate_
{
ImGuiHoveredFlags_DelayMask_ = ImGuiHoveredFlags_DelayNone | ImGuiHoveredFlags_DelayShort | ImGuiHoveredFlags_DelayNormal | ImGuiHoveredFlags_NoSharedDelay,
ImGuiHoveredFlags_AllowedMaskForIsWindowHovered = ImGuiHoveredFlags_ChildWindows | ImGuiHoveredFlags_RootWindow | ImGuiHoveredFlags_AnyWindow | ImGuiHoveredFlags_NoPopupHierarchy | ImGuiHoveredFlags_DockHierarchy | ImGuiHoveredFlags_AllowWhenBlockedByPopup | ImGuiHoveredFlags_AllowWhenBlockedByActiveItem | ImGuiHoveredFlags_ForTooltip | ImGuiHoveredFlags_Stationary,
ImGuiHoveredFlags_AllowedMaskForIsItemHovered = ImGuiHoveredFlags_AllowWhenBlockedByPopup | ImGuiHoveredFlags_AllowWhenBlockedByActiveItem | ImGuiHoveredFlags_AllowWhenOverlapped | ImGuiHoveredFlags_AllowWhenDisabled | ImGuiHoveredFlags_NoNavOverride | ImGuiHoveredFlags_ForTooltip | ImGuiHoveredFlags_Stationary | ImGuiHoveredFlags_DelayMask_,
};
// Extend ImGuiInputTextFlags_
enum ImGuiInputTextFlagsPrivate_
{
@ -862,7 +871,7 @@ enum ImGuiButtonFlagsPrivate_
ImGuiButtonFlags_PressedOnDragDropHold = 1 << 9, // return true when held into while we are drag and dropping another item (used by e.g. tree nodes, collapsing headers)
ImGuiButtonFlags_Repeat = 1 << 10, // hold to repeat
ImGuiButtonFlags_FlattenChildren = 1 << 11, // allow interactions even if a child window is overlapping
ImGuiButtonFlags_AllowItemOverlap = 1 << 12, // require previous frame HoveredId to either match id or be null before being usable, use along with SetItemAllowOverlap()
ImGuiButtonFlags_AllowOverlap = 1 << 12, // require previous frame HoveredId to either match id or be null before being usable.
ImGuiButtonFlags_DontClosePopups = 1 << 13, // disable automatically closing parent popup on press // [UNUSED]
//ImGuiButtonFlags_Disabled = 1 << 14, // disable interactions -> use BeginDisabled() or ImGuiItemFlags_Disabled
ImGuiButtonFlags_AlignTextBaseLine = 1 << 15, // vertically align button to match text baseline - ButtonEx() only // FIXME: Should be removed and handled by SmallButton(), not possible currently because of DC.CursorPosPrevLine
@ -907,6 +916,7 @@ enum ImGuiSelectableFlagsPrivate_
enum ImGuiTreeNodeFlagsPrivate_
{
ImGuiTreeNodeFlags_ClipLabelForTrailingButton = 1 << 20,
ImGuiTreeNodeFlags_UpsideDownArrow = 1 << 21,// (FIXME-WIP) Turn Down arrow into an Up arrow, but reversed trees (#6517)
};
enum ImGuiSeparatorFlags_
@ -936,7 +946,7 @@ enum ImGuiTextFlags_
enum ImGuiTooltipFlags_
{
ImGuiTooltipFlags_None = 0,
ImGuiTooltipFlags_OverridePreviousTooltip = 1 << 0, // Override will clear/ignore previously submitted tooltip (defaults to append)
ImGuiTooltipFlags_OverridePrevious = 1 << 1, // Clear/ignore previously submitted tooltip (defaults to append)
};
// FIXME: this is in development, not exposed/functional as a generic feature yet.
@ -1187,13 +1197,14 @@ enum ImGuiNextItemDataFlags_
struct ImGuiNextItemData
{
ImGuiNextItemDataFlags Flags;
ImGuiItemFlags ItemFlags; // Currently only tested/used for ImGuiItemflags_AllowOverlap.
float Width; // Set by SetNextItemWidth()
ImGuiID FocusScopeId; // Set by SetNextItemMultiSelectData() (!= 0 signify value has been set, so it's an alternate version of HasSelectionData, we don't use Flags for this because they are cleared too early. This is mostly used for debugging)
ImGuiCond OpenCond;
bool OpenVal; // Set by SetNextItemOpen()
ImGuiNextItemData() { memset(this, 0, sizeof(*this)); }
inline void ClearFlags() { Flags = ImGuiNextItemDataFlags_None; } // Also cleared manually by ItemAdd()!
inline void ClearFlags() { Flags = ImGuiNextItemDataFlags_None; ItemFlags = ImGuiItemFlags_None; } // Also cleared manually by ItemAdd()!
};
// Status storage for the last submitted item
@ -1501,10 +1512,12 @@ enum ImGuiNavMoveFlags_
ImGuiNavMoveFlags_ScrollToEdgeY = 1 << 6, // Force scrolling to min/max (used by Home/End) // FIXME-NAV: Aim to remove or reword, probably unnecessary
ImGuiNavMoveFlags_Forwarded = 1 << 7,
ImGuiNavMoveFlags_DebugNoResult = 1 << 8, // Dummy scoring for debug purpose, don't apply result
ImGuiNavMoveFlags_FocusApi = 1 << 9,
ImGuiNavMoveFlags_Tabbing = 1 << 10, // == Focus + Activate if item is Inputable + DontChangeNavHighlight
ImGuiNavMoveFlags_Activate = 1 << 11,
ImGuiNavMoveFlags_DontSetNavHighlight = 1 << 12, // Do not alter the visible state of keyboard vs mouse nav highlight
ImGuiNavMoveFlags_FocusApi = 1 << 9, // Requests from focus API can land/focus/activate items even if they are marked with _NoTabStop (see NavProcessItemForTabbingRequest() for details)
ImGuiNavMoveFlags_IsTabbing = 1 << 10, // == Focus + Activate if item is Inputable + DontChangeNavHighlight
ImGuiNavMoveFlags_IsPageMove = 1 << 11, // Identify a PageDown/PageUp request.
ImGuiNavMoveFlags_Activate = 1 << 12, // Activate/select target item.
ImGuiNavMoveFlags_NoSelect = 1 << 13, // Don't trigger selection by not setting g.NavJustMovedTo
ImGuiNavMoveFlags_NoSetNavHighlight = 1 << 14, // Do not alter the visible state of keyboard vs mouse nav highlight
};
enum ImGuiNavLayer
@ -1674,6 +1687,7 @@ struct IMGUI_API ImGuiDockNode
ImGuiID LastFocusedNodeId; // [Root node only] Which of our child docking node (any ancestor in the hierarchy) was last focused.
ImGuiID SelectedTabId; // [Leaf node only] Which of our tab/window is selected.
ImGuiID WantCloseTabId; // [Leaf node only] Set when closing a specific tab/window.
ImGuiID RefViewportId; // Reference viewport ID from visible window when HostWindow == NULL.
ImGuiDataAuthority AuthorityForPos :3;
ImGuiDataAuthority AuthorityForSize :3;
ImGuiDataAuthority AuthorityForViewport :3;
@ -1758,7 +1772,7 @@ struct ImGuiViewportP : public ImGuiViewport
int DrawListsLastFrame[2]; // Last frame number the background (0) and foreground (1) draw lists were used
ImDrawList* DrawLists[2]; // Convenience background (0) and foreground (1) draw lists. We use them to draw software mouser cursor when io.MouseDrawCursor is set and to draw most debug overlays.
ImDrawData DrawDataP;
ImDrawDataBuilder DrawDataBuilder;
ImDrawDataBuilder DrawDataBuilder; // Temporary data while building final ImDrawData
ImVec2 LastPlatformPos;
ImVec2 LastPlatformSize;
ImVec2 LastRendererSize;
@ -1829,6 +1843,7 @@ struct ImGuiSettingsHandler
// This is experimental and not officially supported, it'll probably fall short of features, if/when it does we may backtrack.
enum ImGuiLocKey : int
{
ImGuiLocKey_VersionStr,
ImGuiLocKey_TableSizeOne,
ImGuiLocKey_TableSizeAllFit,
ImGuiLocKey_TableSizeAllDefault,
@ -2046,6 +2061,8 @@ struct ImGuiContext
ImGuiViewportP* MouseLastHoveredViewport; // Last known viewport that was hovered by mouse (even if we are not hovering any viewport any more) + honoring the _NoInputs flag.
ImGuiID PlatformLastFocusedViewportId;
ImGuiPlatformMonitor FallbackMonitor; // Virtual monitor used as fallback if backend doesn't provide monitor information.
int ViewportCreatedCount; // Unique sequential creation counter (mostly for testing/debugging)
int PlatformWindowsCreatedCount; // Unique sequential creation counter (mostly for testing/debugging)
int ViewportFocusedStampCount; // Every time the front-most window changes, we stamp its viewport with an incrementing counter
// Gamepad/keyboard Navigation
@ -2111,7 +2128,6 @@ struct ImGuiContext
// Render
float DimBgRatio; // 0.0..1.0 animation when fading in a dimming background (for modal window and CTRL+TAB list)
ImGuiMouseCursor MouseCursor;
// Drag and Drop
bool DragDropActive;
@ -2151,13 +2167,19 @@ struct ImGuiContext
ImVector<ImGuiShrinkWidthItem> ShrinkWidthBuffer;
// Hover Delay system
ImGuiID HoverDelayId;
ImGuiID HoverDelayIdPreviousFrame;
float HoverDelayTimer; // Currently used IsItemHovered(), generally inferred from g.HoveredIdTimer but kept uncleared until clear timer elapse.
float HoverDelayClearTimer; // Currently used IsItemHovered(): grace time before g.TooltipHoverTimer gets cleared.
ImGuiID HoverItemDelayId;
ImGuiID HoverItemDelayIdPreviousFrame;
float HoverItemDelayTimer; // Currently used by IsItemHovered()
float HoverItemDelayClearTimer; // Currently used by IsItemHovered(): grace time before g.TooltipHoverTimer gets cleared.
ImGuiID HoverItemUnlockedStationaryId; // Mouse has once been stationary on this item. Only reset after departing the item.
ImGuiID HoverWindowUnlockedStationaryId; // Mouse has once been stationary on this window. Only reset after departing the window.
// Mouse state
ImGuiMouseCursor MouseCursor;
float MouseStationaryTimer; // Time the mouse has been stationary (with some loose heuristic)
ImVec2 MouseLastValidPos;
// Widget state
ImVec2 MouseLastValidPos;
ImGuiInputTextState InputTextState;
ImGuiInputTextDeactivatedState InputTextDeactivatedState;
ImFont InputTextPasswordFont;
@ -2314,6 +2336,7 @@ struct ImGuiContext
CurrentViewport = NULL;
MouseViewport = MouseLastHoveredViewport = NULL;
PlatformLastFocusedViewportId = 0;
ViewportCreatedCount = PlatformWindowsCreatedCount = 0;
ViewportFocusedStampCount = 0;
NavWindow = NULL;
@ -2350,7 +2373,6 @@ struct ImGuiContext
InertialScrollInhibited = false;
DimBgRatio = 0.0f;
MouseCursor = ImGuiMouseCursor_Arrow;
DragDropActive = DragDropWithinSource = DragDropWithinTarget = false;
DragDropSourceFlags = ImGuiDragDropFlags_None;
@ -2370,8 +2392,11 @@ struct ImGuiContext
TablesTempDataStacked = 0;
CurrentTabBar = NULL;
HoverDelayId = HoverDelayIdPreviousFrame = 0;
HoverDelayTimer = HoverDelayClearTimer = 0.0f;
HoverItemDelayId = HoverItemDelayIdPreviousFrame = HoverItemUnlockedStationaryId = HoverWindowUnlockedStationaryId = 0;
HoverItemDelayTimer = HoverItemDelayClearTimer = 0.0f;
MouseCursor = ImGuiMouseCursor_Arrow;
MouseStationaryTimer = 0.0f;
TempInputId = 0;
ColorEditOptions = ImGuiColorEditFlags_DefaultOptions_;
@ -2797,8 +2822,10 @@ struct ImGuiTableInstanceData
float LastOuterHeight; // Outer height from last frame
float LastFirstRowHeight; // Height of first row from last frame (FIXME: this is used as "header height" and may be reworked)
float LastFrozenHeight; // Height of frozen section from last frame
int HoveredRowLast; // Index of row which was hovered last frame.
int HoveredRowNext; // Index of row hovered this frame, set after encountering it.
ImGuiTableInstanceData() { TableInstanceID = 0; LastOuterHeight = LastFirstRowHeight = LastFrozenHeight = 0.0f; }
ImGuiTableInstanceData() { TableInstanceID = 0; LastOuterHeight = LastFirstRowHeight = LastFrozenHeight = 0.0f; HoveredRowLast = HoveredRowNext = -1; }
};
// FIXME-TABLE: more transient data could be stored in a stacked ImGuiTableTempData: e.g. SortSpecs, incoming RowData
@ -3022,6 +3049,7 @@ namespace ImGui
IMGUI_API void SetCurrentFont(ImFont* font);
inline ImFont* GetDefaultFont() { ImGuiContext& g = *GImGui; return g.IO.FontDefault ? g.IO.FontDefault : g.IO.Fonts->Fonts[0]; }
inline ImDrawList* GetForegroundDrawList(ImGuiWindow* window) { return GetForegroundDrawList(window->Viewport); }
IMGUI_API void AddDrawListToDrawDataEx(ImDrawData* draw_data, ImVector<ImDrawList*>* out_list, ImDrawList* draw_list);
// Init
IMGUI_API void Initialize();
@ -3101,7 +3129,7 @@ namespace ImGui
IMGUI_API void ItemSize(const ImVec2& size, float text_baseline_y = -1.0f);
inline void ItemSize(const ImRect& bb, float text_baseline_y = -1.0f) { ItemSize(bb.GetSize(), text_baseline_y); } // FIXME: This is a misleading API since we expect CursorPos to be bb.Min.
IMGUI_API bool ItemAdd(const ImRect& bb, ImGuiID id, const ImRect* nav_bb = NULL, ImGuiItemFlags extra_flags = 0);
IMGUI_API bool ItemHoverable(const ImRect& bb, ImGuiID id);
IMGUI_API bool ItemHoverable(const ImRect& bb, ImGuiID id, ImGuiItemFlags item_flags);
IMGUI_API bool IsWindowContentHoverable(ImGuiWindow* window, ImGuiHoveredFlags flags = 0);
IMGUI_API bool IsClippedEx(const ImRect& bb, ImGuiID id);
IMGUI_API void SetLastItemData(ImGuiID item_id, ImGuiItemFlags in_flags, ImGuiItemStatusFlags status_flags, const ImRect& item_rect);
@ -3161,10 +3189,15 @@ namespace ImGui
IMGUI_API void NavMoveRequestTryWrapping(ImGuiWindow* window, ImGuiNavMoveFlags move_flags);
IMGUI_API void NavClearPreferredPosForAxis(ImGuiAxis axis);
IMGUI_API void NavUpdateCurrentWindowIsScrollPushableX();
IMGUI_API void ActivateItem(ImGuiID id); // Remotely activate a button, checkbox, tree node etc. given its unique ID. activation is queued and processed on the next frame when the item is encountered again.
IMGUI_API void SetNavWindow(ImGuiWindow* window);
IMGUI_API void SetNavID(ImGuiID id, ImGuiNavLayer nav_layer, ImGuiID focus_scope_id, const ImRect& rect_rel);
// Focus/Activation
// This should be part of a larger set of API: FocusItem(offset = -1), FocusItemByID(id), ActivateItem(offset = -1), ActivateItemByID(id) etc. which are
// much harder to design and implement than expected. I have a couple of private branches on this matter but it's not simple. For now implementing the easy ones.
IMGUI_API void FocusItem(); // Focus last item (no selection/activation).
IMGUI_API void ActivateItemByID(ImGuiID id); // Activate an item by ID (button, checkbox, tree node etc.). Activation is queued and processed on the next frame when the item is encountered again.
// Inputs
// FIXME: Eventually we should aim to move e.g. IsActiveIdUsingKey() into IsKeyXXX functions.
inline bool IsNamedKey(ImGuiKey key) { return key >= ImGuiKey_NamedKey_BEGIN && key < ImGuiKey_NamedKey_END; }
@ -3335,6 +3368,7 @@ namespace ImGui
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 int TableGetHoveredRow(); // Retrieve *PREVIOUS FRAME* hovered row. This difference with TableGetHoveredColumn() is the reason why this is not public yet.
IMGUI_API float TableGetHeaderRowHeight();
IMGUI_API void TablePushBackgroundChannel();
IMGUI_API void TablePopBackgroundChannel();

View file

@ -1,4 +1,4 @@
// dear imgui, v1.89.6
// dear imgui, v1.89.8
// (tables and columns code)
/*
@ -198,11 +198,7 @@ Index of this file:
#include "imgui_internal.h"
// System includes
#if defined(_MSC_VER) && _MSC_VER <= 1500 // MSVC 2008 or earlier
#include <stddef.h> // intptr_t
#else
#include <stdint.h> // intptr_t
#endif
// Visual Studio warnings
#ifdef _MSC_VER
@ -417,7 +413,7 @@ bool ImGui::BeginTableEx(const char* name, ImGuiID id, int columns_count, ImG
table->HasScrollbarYPrev = table->HasScrollbarYCurr;
table->HasScrollbarYCurr = false;
}
table->HasScrollbarYCurr |= (table->InnerWindow->ScrollMax.y > 0.0f);
table->HasScrollbarYCurr |= table->InnerWindow->ScrollbarY;
}
else
{
@ -974,12 +970,14 @@ void ImGui::TableUpdateLayout(ImGuiTable* table)
// clear ActiveId, which is equivalent to the change provided by _AllowWhenBLockedByActiveItem).
// - This allows columns to be marked as hovered when e.g. clicking a button inside the column, or using drag and drop.
ImGuiTableInstanceData* table_instance = TableGetInstanceData(table, table->InstanceCurrent);
table_instance->HoveredRowLast = table_instance->HoveredRowNext;
table_instance->HoveredRowNext = -1;
table->HoveredColumnBody = -1;
table->HoveredColumnBorder = -1;
const ImRect mouse_hit_rect(table->OuterRect.Min.x, table->OuterRect.Min.y, table->OuterRect.Max.x, ImMax(table->OuterRect.Max.y, table->OuterRect.Min.y + table_instance->LastOuterHeight));
const ImGuiID backup_active_id = g.ActiveId;
g.ActiveId = 0;
const bool is_hovering_table = ItemHoverable(mouse_hit_rect, 0);
const bool is_hovering_table = ItemHoverable(mouse_hit_rect, 0, ImGuiItemFlags_None);
g.ActiveId = backup_active_id;
// [Part 6] Setup final position, offset, skip/clip states and clipping rectangles, detect hovered column
@ -1131,6 +1129,14 @@ void ImGui::TableUpdateLayout(ImGuiTable* table)
table->BorderX1 = table->InnerClipRect.Min.x;// +((table->Flags & ImGuiTableFlags_BordersOuter) ? 0.0f : -1.0f);
table->BorderX2 = table->InnerClipRect.Max.x;// +((table->Flags & ImGuiTableFlags_BordersOuter) ? 0.0f : +1.0f);
// Setup window's WorkRect.Max.y for GetContentRegionAvail(). Other values will be updated in each TableBeginCell() call.
float window_content_max_y;
if (table->Flags & ImGuiTableFlags_NoHostExtendY)
window_content_max_y = table->OuterRect.Max.y;
else
window_content_max_y = ImMax(table->InnerWindow->ContentRegionRect.Max.y, (table->Flags & ImGuiTableFlags_ScrollY) ? 0.0f : table->OuterRect.Max.y);
table->InnerWindow->WorkRect.Max.y = ImClamp(window_content_max_y - g.Style.CellPadding.y, table->InnerWindow->WorkRect.Min.y, table->InnerWindow->WorkRect.Max.y);
// [Part 9] Allocate draw channels and setup background cliprect
TableSetupDrawChannels(table);
@ -1170,8 +1176,6 @@ void ImGui::TableUpdateLayout(ImGuiTable* table)
// Process hit-testing on resizing borders. Actual size change will be applied in EndTable()
// - Set table->HoveredColumnBorder with a short delay/timer to reduce visual feedback noise.
// - Submit ahead of table contents and header, use ImGuiButtonFlags_AllowItemOverlap to prioritize
// widgets overlapping the same area.
void ImGui::TableUpdateBorders(ImGuiTable* table)
{
ImGuiContext& g = *GImGui;
@ -1211,7 +1215,7 @@ void ImGui::TableUpdateBorders(ImGuiTable* table)
//GetForegroundDrawList()->AddRect(hit_rect.Min, hit_rect.Max, IM_COL32(255, 0, 0, 100));
bool hovered = false, held = false;
bool pressed = ButtonBehavior(hit_rect, column_id, &hovered, &held, ImGuiButtonFlags_FlattenChildren | ImGuiButtonFlags_AllowItemOverlap | ImGuiButtonFlags_PressedOnClick | ImGuiButtonFlags_PressedOnDoubleClick | ImGuiButtonFlags_NoNavFocus);
bool pressed = ButtonBehavior(hit_rect, column_id, &hovered, &held, ImGuiButtonFlags_FlattenChildren | ImGuiButtonFlags_PressedOnClick | ImGuiButtonFlags_PressedOnDoubleClick | ImGuiButtonFlags_NoNavFocus);
if (pressed && IsMouseDoubleClicked(0))
{
TableSetColumnWidthAutoSingle(table, column_n);
@ -1552,6 +1556,7 @@ void ImGui::TableSetupScrollFreeze(int columns, int rows)
// - TableGetCellBgRect() [Internal]
// - TableGetColumnResizeID() [Internal]
// - TableGetHoveredColumn() [Internal]
// - TableGetHoveredRow() [Internal]
// - TableSetBgColor()
//-----------------------------------------------------------------------------
@ -1656,6 +1661,19 @@ int ImGui::TableGetHoveredColumn()
return (int)table->HoveredColumnBody;
}
// Return -1 when table is not hovered. Return maxrow+1 if in table but below last submitted row.
// *IMPORTANT* Unlike TableGetHoveredColumn(), this has a one frame latency in updating the value.
// This difference with is the reason why this is not public yet.
int ImGui::TableGetHoveredRow()
{
ImGuiContext& g = *GImGui;
ImGuiTable* table = g.CurrentTable;
if (!table)
return -1;
ImGuiTableInstanceData* table_instance = TableGetInstanceData(table, table->InstanceCurrent);
return (int)table_instance->HoveredRowLast;
}
void ImGui::TableSetBgColor(ImGuiTableBgTarget target, ImU32 color, int column_n)
{
ImGuiContext& g = *GImGui;
@ -1807,6 +1825,10 @@ void ImGui::TableEndRow(ImGuiTable* table)
const bool is_visible = (bg_y2 >= table->InnerClipRect.Min.y && bg_y1 <= table->InnerClipRect.Max.y);
if (is_visible)
{
// Update data for TableGetHoveredRow()
if (table->HoveredColumnBody != -1 && g.IO.MousePos.y >= bg_y1 && g.IO.MousePos.y < bg_y2)
TableGetInstanceData(table, table->InstanceCurrent)->HoveredRowNext = table->CurrentRow;
// Decide of background color for the row
ImU32 bg_col0 = 0;
ImU32 bg_col1 = 0;
@ -2000,6 +2022,7 @@ void ImGui::TableBeginCell(ImGuiTable* table, int column_n)
window->DC.CurrLineTextBaseOffset = table->RowTextBaseline;
window->DC.NavLayerCurrent = (ImGuiNavLayer)column->NavLayerCurrent;
// Note how WorkRect.Max.y is only set once during layout
window->WorkRect.Min.y = window->DC.CursorPos.y;
window->WorkRect.Min.x = column->WorkMinX;
window->WorkRect.Max.x = column->WorkMaxX;
@ -2964,11 +2987,9 @@ void ImGui::TableHeader(const char* label)
//GetForegroundDrawList()->AddRect(cell_r.Min, cell_r.Max, IM_COL32(255, 0, 0, 255)); // [DEBUG]
//GetForegroundDrawList()->AddRect(bb.Min, bb.Max, IM_COL32(255, 0, 0, 255)); // [DEBUG]
// Using AllowItemOverlap mode because we cover the whole cell, and we want user to be able to submit subsequent items.
// Using AllowOverlap mode because we cover the whole cell, and we want user to be able to submit subsequent items.
bool hovered, held;
bool pressed = ButtonBehavior(bb, id, &hovered, &held, ImGuiButtonFlags_AllowItemOverlap);
if (g.ActiveId != id)
SetItemAllowOverlap();
bool pressed = ButtonBehavior(bb, id, &hovered, &held, ImGuiButtonFlags_AllowOverlap);
if (held || hovered || selected)
{
const ImU32 col = GetColorU32(held ? ImGuiCol_HeaderActive : hovered ? ImGuiCol_HeaderHovered : ImGuiCol_Header);
@ -3039,8 +3060,8 @@ void ImGui::TableHeader(const char* label)
RenderTextEllipsis(window->DrawList, label_pos, ImVec2(ellipsis_max, label_pos.y + label_height + g.Style.FramePadding.y), ellipsis_max, ellipsis_max, label, label_end, &label_size);
const bool text_clipped = label_size.x > (ellipsis_max - label_pos.x);
if (text_clipped && hovered && g.ActiveId == 0 && IsItemHovered(ImGuiHoveredFlags_DelayNormal))
SetTooltip("%.*s", (int)(label_end - label), label);
if (text_clipped && hovered && g.ActiveId == 0)
SetItemTooltip("%.*s", (int)(label_end - label), label);
// We don't use BeginPopupContextItem() because we want the popup to stay up even after the column is hidden
if (IsMouseReleased(1) && IsItemHovered())
@ -3602,6 +3623,11 @@ void ImGui::DebugNodeTable(ImGuiTable* table)
BulletText("CellPaddingX: %.1f, CellSpacingX: %.1f/%.1f, OuterPaddingX: %.1f", table->CellPaddingX, table->CellSpacingX1, table->CellSpacingX2, table->OuterPaddingX);
BulletText("HoveredColumnBody: %d, HoveredColumnBorder: %d", table->HoveredColumnBody, table->HoveredColumnBorder);
BulletText("ResizedColumn: %d, ReorderColumn: %d, HeldHeaderColumn: %d", table->ResizedColumn, table->ReorderColumn, table->HeldHeaderColumn);
for (int n = 0; n < table->InstanceCurrent + 1; n++)
{
ImGuiTableInstanceData* table_instance = TableGetInstanceData(table, n);
BulletText("Instance %d: HoveredRow: %d, LastOuterHeight: %.2f", n, table_instance->HoveredRowLast, table_instance->LastOuterHeight);
}
//BulletText("BgDrawChannels: %d/%d", 0, table->BgDrawChannelUnfrozen);
float sum_weights = 0.0f;
for (int n = 0; n < table->ColumnsCount; n++)
@ -3960,6 +3986,7 @@ void ImGui::BeginColumns(const char* str_id, int columns_count, ImGuiOldColumnFl
window->DC.ColumnsOffset.x = ImMax(column_padding - window->WindowPadding.x, 0.0f);
window->DC.CursorPos.x = IM_FLOOR(window->Pos.x + window->DC.Indent.x + window->DC.ColumnsOffset.x);
window->WorkRect.Max.x = window->Pos.x + offset_1 - column_padding;
window->WorkRect.Max.y = window->ContentRegionRect.Max.y;
}
void ImGui::NextColumn()

View file

@ -1,4 +1,4 @@
// dear imgui, v1.89.6
// dear imgui, v1.89.8
// (widgets code)
/*
@ -41,11 +41,7 @@ Index of this file:
#include "imgui_internal.h"
// System includes
#if defined(_MSC_VER) && _MSC_VER <= 1500 // MSVC 2008 or earlier
#include <stddef.h> // intptr_t
#else
#include <stdint.h> // intptr_t
#endif
//-------------------------------------------------------------------------
// Warnings
@ -492,6 +488,14 @@ bool ImGui::ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool
if ((flags & ImGuiButtonFlags_PressedOnMask_) == 0)
flags |= ImGuiButtonFlags_PressedOnDefault_;
// Default behavior inherited from item flags
// Note that _both_ ButtonFlags and ItemFlags are valid sources, so copy one into the item_flags and only check that.
ImGuiItemFlags item_flags = (g.LastItemData.ID == id ? g.LastItemData.InFlags : g.CurrentItemFlags);
if (flags & ImGuiButtonFlags_AllowOverlap)
item_flags |= ImGuiItemflags_AllowOverlap;
if (flags & ImGuiButtonFlags_Repeat)
item_flags |= ImGuiItemFlags_ButtonRepeat;
ImGuiWindow* backup_hovered_window = g.HoveredWindow;
const bool flatten_hovered_children = (flags & ImGuiButtonFlags_FlattenChildren) && g.HoveredWindow && g.HoveredWindow->RootWindowDockTree == window->RootWindowDockTree;
if (flatten_hovered_children)
@ -504,11 +508,7 @@ bool ImGui::ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool
#endif
bool pressed = false;
bool hovered = ItemHoverable(bb, id);
// Drag source doesn't report as hovered
if (hovered && g.DragDropActive && g.DragDropPayload.SourceId == id && !(g.DragDropSourceFlags & ImGuiDragDropFlags_SourceNoDisableHover))
hovered = false;
bool hovered = ItemHoverable(bb, id, item_flags);
// Special mode for Drag and Drop where holding button pressed for a long time while dragging another item triggers the button
if (g.DragDropActive && (flags & ImGuiButtonFlags_PressedOnDragDropHold) && !(g.DragDropSourceFlags & ImGuiDragDropFlags_SourceNoHoldToOpenOthers))
@ -527,10 +527,6 @@ bool ImGui::ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool
if (flatten_hovered_children)
g.HoveredWindow = backup_hovered_window;
// AllowOverlap mode (rarely used) requires previous frame HoveredId to be null or to match. This allows using patterns where a later submitted widget overlaps a previous one.
if (hovered && (flags & ImGuiButtonFlags_AllowItemOverlap) && (g.HoveredIdPreviousFrame != id && g.HoveredIdPreviousFrame != 0))
hovered = false;
// Mouse handling
const ImGuiID test_owner_id = (flags & ImGuiButtonFlags_NoTestKeyOwner) ? ImGuiKeyOwner_Any : id;
if (hovered)
@ -579,7 +575,7 @@ bool ImGui::ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool
{
if (mouse_button_released != -1)
{
const bool has_repeated_at_least_once = (flags & ImGuiButtonFlags_Repeat) && g.IO.MouseDownDurationPrev[mouse_button_released] >= g.IO.KeyRepeatDelay; // Repeat mode trumps on release behavior
const bool has_repeated_at_least_once = (item_flags & ImGuiItemFlags_ButtonRepeat) && g.IO.MouseDownDurationPrev[mouse_button_released] >= g.IO.KeyRepeatDelay; // Repeat mode trumps on release behavior
if (!has_repeated_at_least_once)
pressed = true;
if (!(flags & ImGuiButtonFlags_NoNavFocus))
@ -590,7 +586,7 @@ bool ImGui::ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool
// 'Repeat' mode acts when held regardless of _PressedOn flags (see table above).
// Relies on repeat logic of IsMouseClicked() but we may as well do it ourselves if we end up exposing finer RepeatDelay/RepeatRate settings.
if (g.ActiveId == id && (flags & ImGuiButtonFlags_Repeat))
if (g.ActiveId == id && (item_flags & ImGuiItemFlags_ButtonRepeat))
if (g.IO.MouseDownDuration[g.ActiveIdMouseButton] > 0.0f && IsMouseClicked(g.ActiveIdMouseButton, test_owner_id, ImGuiInputFlags_Repeat))
pressed = true;
}
@ -608,7 +604,7 @@ bool ImGui::ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool
{
bool nav_activated_by_code = (g.NavActivateId == id);
bool nav_activated_by_inputs = (g.NavActivatePressedId == id);
if (!nav_activated_by_inputs && (flags & ImGuiButtonFlags_Repeat))
if (!nav_activated_by_inputs && (item_flags & ImGuiItemFlags_ButtonRepeat))
{
// Avoid pressing multiple keys from triggering excessive amount of repeat events
const ImGuiKeyData* key1 = GetKeyData(ImGuiKey_Space);
@ -655,7 +651,7 @@ bool ImGui::ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool
{
// Report as pressed when releasing the mouse (this is the most common path)
bool is_double_click_release = (flags & ImGuiButtonFlags_PressedOnDoubleClick) && g.IO.MouseReleased[mouse_button] && g.IO.MouseClickedLastCount[mouse_button] == 2;
bool is_repeating_already = (flags & ImGuiButtonFlags_Repeat) && g.IO.MouseDownDurationPrev[mouse_button] >= g.IO.KeyRepeatDelay; // Repeat mode trumps <on release>
bool is_repeating_already = (item_flags & ImGuiItemFlags_ButtonRepeat) && g.IO.MouseDownDurationPrev[mouse_button] >= g.IO.KeyRepeatDelay; // Repeat mode trumps <on release>
bool is_button_avail_or_owned = TestKeyOwner(MouseButtonToKey(mouse_button), test_owner_id);
if (!is_double_click_release && !is_repeating_already && is_button_avail_or_owned)
pressed = true;
@ -702,9 +698,6 @@ bool ImGui::ButtonEx(const char* label, const ImVec2& size_arg, ImGuiButtonFlags
if (!ItemAdd(bb, id))
return false;
if (g.LastItemData.InFlags & ImGuiItemFlags_ButtonRepeat)
flags |= ImGuiButtonFlags_Repeat;
bool hovered, held;
bool pressed = ButtonBehavior(bb, id, &hovered, &held, flags);
@ -781,9 +774,6 @@ bool ImGui::ArrowButtonEx(const char* str_id, ImGuiDir dir, ImVec2 size, ImGuiBu
if (!ItemAdd(bb, id))
return false;
if (g.LastItemData.InFlags & ImGuiItemFlags_ButtonRepeat)
flags |= ImGuiButtonFlags_Repeat;
bool hovered, held;
bool pressed = ButtonBehavior(bb, id, &hovered, &held, flags);
@ -887,9 +877,9 @@ ImRect ImGui::GetWindowScrollbarRect(ImGuiWindow* window, ImGuiAxis axis)
const float scrollbar_size = window->ScrollbarSizes[axis ^ 1]; // (ScrollbarSizes.x = width of Y scrollbar; ScrollbarSizes.y = height of X scrollbar)
IM_ASSERT(scrollbar_size > 0.0f);
if (axis == ImGuiAxis_X)
return ImRect(inner_rect.Min.x, ImMax(outer_rect.Min.y, outer_rect.Max.y - border_size - scrollbar_size), inner_rect.Max.x, outer_rect.Max.y);
return ImRect(inner_rect.Min.x, ImMax(outer_rect.Min.y, outer_rect.Max.y - border_size - scrollbar_size), inner_rect.Max.x - border_size, outer_rect.Max.y - border_size);
else
return ImRect(ImMax(outer_rect.Min.x, outer_rect.Max.x - border_size - scrollbar_size), inner_rect.Min.y, outer_rect.Max.x, inner_rect.Max.y);
return ImRect(ImMax(outer_rect.Min.x, outer_rect.Max.x - border_size - scrollbar_size), inner_rect.Min.y, outer_rect.Max.x - border_size, inner_rect.Max.y - border_size);
}
void ImGui::Scrollbar(ImGuiAxis axis)
@ -1174,10 +1164,8 @@ bool ImGui::CheckboxFlagsT(const char* label, T* flags, T flags_value)
if (!all_on && any_on)
{
ImGuiContext& g = *GImGui;
ImGuiItemFlags backup_item_flags = g.CurrentItemFlags;
g.CurrentItemFlags |= ImGuiItemFlags_MixedValue;
g.NextItemData.ItemFlags |= ImGuiItemFlags_MixedValue;
pressed = Checkbox(label, &all_on);
g.CurrentItemFlags = backup_item_flags;
}
else
{
@ -1559,14 +1547,20 @@ bool ImGui::SplitterBehavior(const ImRect& bb, ImGuiID id, ImGuiAxis axis, float
if (!ItemAdd(bb, id, NULL, ImGuiItemFlags_NoNav))
return false;
// FIXME: AFAIK the only leftover reason for passing ImGuiButtonFlags_AllowOverlap here is
// to allow caller of SplitterBehavior() to call SetItemAllowOverlap() after the item.
// Nowadays we would instead want to use SetNextItemAllowOverlap() before the item.
ImGuiButtonFlags button_flags = ImGuiButtonFlags_FlattenChildren;
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
button_flags |= ImGuiButtonFlags_AllowOverlap;
#endif
bool hovered, held;
ImRect bb_interact = bb;
bb_interact.Expand(axis == ImGuiAxis_Y ? ImVec2(0.0f, hover_extend) : ImVec2(hover_extend, 0.0f));
ButtonBehavior(bb_interact, id, &hovered, &held, ImGuiButtonFlags_FlattenChildren | ImGuiButtonFlags_AllowItemOverlap);
ButtonBehavior(bb_interact, id, &hovered, &held, button_flags);
if (hovered)
g.LastItemData.StatusFlags |= ImGuiItemStatusFlags_HoveredRect; // for IsItemHovered(), because bb_interact is larger than bb
if (g.ActiveId != id)
SetItemAllowOverlap();
if (held || (hovered && g.HoveredIdPreviousFrame == id && g.HoveredIdTimer >= hover_visibility_delay))
SetMouseCursor(axis == ImGuiAxis_Y ? ImGuiMouseCursor_ResizeNS : ImGuiMouseCursor_ResizeEW);
@ -1835,7 +1829,7 @@ bool ImGui::BeginComboPreview()
if (window->SkipItems || !(g.LastItemData.StatusFlags & ImGuiItemStatusFlags_Visible))
return false;
IM_ASSERT(g.LastItemData.Rect.Min.x == preview_data->PreviewRect.Min.x && g.LastItemData.Rect.Min.y == preview_data->PreviewRect.Min.y); // Didn't call after BeginCombo/EndCombo block or forgot to pass ImGuiComboFlags_CustomPreview flag?
if (!window->ClipRect.Contains(preview_data->PreviewRect)) // Narrower test (optional)
if (!window->ClipRect.Overlaps(preview_data->PreviewRect)) // Narrower test (optional)
return false;
// FIXME: This could be contained in a PushWorkRect() api
@ -1934,7 +1928,7 @@ bool ImGui::Combo(const char* label, int* current_item, bool (*items_getter)(voi
const char* item_text;
if (!items_getter(data, i, &item_text))
item_text = "*Unknown item*";
if (Selectable(item_text, item_selected))
if (Selectable(item_text, item_selected) && *current_item != i)
{
value_changed = true;
*current_item = i;
@ -2421,7 +2415,7 @@ bool ImGui::DragScalar(const char* label, ImGuiDataType data_type, void* p_data,
if (format == NULL)
format = DataTypeGetInfo(data_type)->PrintFmt;
const bool hovered = ItemHoverable(frame_bb, id);
const bool hovered = ItemHoverable(frame_bb, id, g.LastItemData.InFlags);
bool temp_input_is_active = temp_input_allowed && TempInputIsActive(id);
if (!temp_input_is_active)
{
@ -3014,7 +3008,7 @@ bool ImGui::SliderScalar(const char* label, ImGuiDataType data_type, void* p_dat
if (format == NULL)
format = DataTypeGetInfo(data_type)->PrintFmt;
const bool hovered = ItemHoverable(frame_bb, id);
const bool hovered = ItemHoverable(frame_bb, id, g.LastItemData.InFlags);
bool temp_input_is_active = temp_input_allowed && TempInputIsActive(id);
if (!temp_input_is_active)
{
@ -3182,7 +3176,7 @@ bool ImGui::VSliderScalar(const char* label, const ImVec2& size, ImGuiDataType d
if (format == NULL)
format = DataTypeGetInfo(data_type)->PrintFmt;
const bool hovered = ItemHoverable(frame_bb, id);
const bool hovered = ItemHoverable(frame_bb, id, g.LastItemData.InFlags);
bool temp_input_is_active = temp_input_allowed && TempInputIsActive(id);
if (!temp_input_is_active)
{
@ -3849,6 +3843,7 @@ static bool STB_TEXTEDIT_INSERTCHARS(ImGuiInputTextState* obj, int pos, const Im
#define STB_TEXTEDIT_K_SHIFT 0x400000
#define STB_TEXTEDIT_IMPLEMENTATION
#define STB_TEXTEDIT_memmove memmove
#include "imstb_textedit.h"
// stb_textedit internally allows for a single undo record to do addition and deletion, but somehow, calling
@ -3909,6 +3904,10 @@ void ImGuiInputTextCallbackData::DeleteChars(int pos, int bytes_count)
void ImGuiInputTextCallbackData::InsertChars(int pos, const char* new_text, const char* new_text_end)
{
// Accept null ranges
if (new_text == new_text_end)
return;
const bool is_resizable = (Flags & ImGuiInputTextFlags_CallbackResize) != 0;
const int new_text_len = new_text_end ? (int)(new_text_end - new_text) : (int)strlen(new_text);
if (new_text_len + BufTextLen >= BufSize)
@ -4084,8 +4083,16 @@ void ImGui::InputTextDeactivateHook(ImGuiID id)
if (id == 0 || state->ID != id)
return;
g.InputTextDeactivatedState.ID = state->ID;
if (state->Flags & ImGuiInputTextFlags_ReadOnly)
{
g.InputTextDeactivatedState.TextA.resize(0); // In theory this data won't be used, but clear to be neat.
}
else
{
IM_ASSERT(state->TextA.Data != 0);
g.InputTextDeactivatedState.TextA.resize(state->CurLenA + 1);
memcpy(g.InputTextDeactivatedState.TextA.Data, state->TextA.Data ? state->TextA.Data : "", state->CurLenA + 1);
memcpy(g.InputTextDeactivatedState.TextA.Data, state->TextA.Data, state->CurLenA + 1);
}
}
// Edit a string of text
@ -4175,7 +4182,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
return false;
item_status_flags = g.LastItemData.StatusFlags;
}
const bool hovered = ItemHoverable(frame_bb, id);
const bool hovered = ItemHoverable(frame_bb, id, g.LastItemData.InFlags);
if (hovered)
g.MouseCursor = ImGuiMouseCursor_TextInput;
@ -4517,7 +4524,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
{
if (flags & ImGuiInputTextFlags_EscapeClearsAll)
{
if (state->CurLenA > 0)
if (buf[0] != 0)
{
revert_edit = true;
}
@ -4605,8 +4612,10 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
if (flags & ImGuiInputTextFlags_EscapeClearsAll)
{
// Clear input
IM_ASSERT(buf[0] != 0);
apply_new_text = "";
apply_new_text_length = 0;
value_changed = true;
STB_TEXTEDIT_CHARTYPE empty_string;
stb_textedit_replace(state, &state->Stb, &empty_string, 0);
}
@ -4635,9 +4644,12 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
ImTextStrToUtf8(state->TextA.Data, state->TextA.Size, state->TextW.Data, NULL);
}
// When using 'ImGuiInputTextFlags_EnterReturnsTrue' as a special case we reapply the live buffer back to the input buffer before clearing ActiveId, even though strictly speaking it wasn't modified on this frame.
// When using 'ImGuiInputTextFlags_EnterReturnsTrue' as a special case we reapply the live buffer back to the input buffer
// before clearing ActiveId, even though strictly speaking it wasn't modified on this frame.
// If we didn't do that, code like InputInt() with ImGuiInputTextFlags_EnterReturnsTrue would fail.
// This also allows the user to use InputText() with ImGuiInputTextFlags_EnterReturnsTrue without maintaining any user-side storage (please note that if you use this property along ImGuiInputTextFlags_CallbackResize you can end up with your temporary string object unnecessarily allocating once a frame, either store your string data, either if you don't then don't use ImGuiInputTextFlags_CallbackResize).
// This also allows the user to use InputText() with ImGuiInputTextFlags_EnterReturnsTrue without maintaining any user-side storage
// (please note that if you use this property along ImGuiInputTextFlags_CallbackResize you can end up with your temporary string object
// unnecessarily allocating once a frame, either store your string data, either if you don't then don't use ImGuiInputTextFlags_CallbackResize).
const bool apply_edit_back_to_user_buffer = !revert_edit || (validated && (flags & ImGuiInputTextFlags_EnterReturnsTrue) != 0);
if (apply_edit_back_to_user_buffer)
{
@ -4738,11 +4750,11 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
// Handle reapplying final data on deactivation (see InputTextDeactivateHook() for details)
if (g.InputTextDeactivatedState.ID == id)
{
if (g.ActiveId != id && IsItemDeactivatedAfterEdit() && !is_readonly)
if (g.ActiveId != id && IsItemDeactivatedAfterEdit() && !is_readonly && strcmp(g.InputTextDeactivatedState.TextA.Data, buf) != 0)
{
apply_new_text = g.InputTextDeactivatedState.TextA.Data;
apply_new_text_length = g.InputTextDeactivatedState.TextA.Size - 1;
value_changed |= (strcmp(g.InputTextDeactivatedState.TextA.Data, buf) != 0);
value_changed = true;
//IMGUI_DEBUG_LOG("InputText(): apply Deactivated data for 0x%08X: \"%.*s\".\n", id, apply_new_text_length, apply_new_text);
}
g.InputTextDeactivatedState.ID = 0;
@ -5023,11 +5035,9 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
{
// For focus requests to work on our multiline we need to ensure our child ItemAdd() call specifies the ImGuiItemFlags_Inputable (ref issue #4761)...
Dummy(ImVec2(text_size.x, text_size.y + style.FramePadding.y));
ImGuiItemFlags backup_item_flags = g.CurrentItemFlags;
g.CurrentItemFlags |= ImGuiItemFlags_Inputable | ImGuiItemFlags_NoTabStop;
g.NextItemData.ItemFlags |= ImGuiItemFlags_Inputable | ImGuiItemFlags_NoTabStop;
EndChild();
item_data_backup.StatusFlags |= (g.LastItemData.StatusFlags & ImGuiItemStatusFlags_HoveredWindow);
g.CurrentItemFlags = backup_item_flags;
// ...and then we need to undo the group overriding last item data, which gets a bit messy as EndGroup() tries to forward scrollbar being active...
// FIXME: This quite messy/tricky, should attempt to get rid of the child window.
@ -5861,7 +5871,7 @@ bool ImGui::ColorButton(const char* desc_id, const ImVec4& col, ImGuiColorEditFl
}
// Tooltip
if (!(flags & ImGuiColorEditFlags_NoTooltip) && hovered)
if (!(flags & ImGuiColorEditFlags_NoTooltip) && hovered && IsItemHovered(ImGuiHoveredFlags_ForTooltip))
ColorTooltip(desc_id, &col.x, flags & (ImGuiColorEditFlags_InputMask_ | ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_AlphaPreview | ImGuiColorEditFlags_AlphaPreviewHalf));
return pressed;
@ -5891,7 +5901,7 @@ void ImGui::ColorTooltip(const char* text, const float* col, ImGuiColorEditFlags
{
ImGuiContext& g = *GImGui;
if (!BeginTooltipEx(ImGuiTooltipFlags_OverridePreviousTooltip, ImGuiWindowFlags_None))
if (!BeginTooltipEx(ImGuiTooltipFlags_OverridePrevious, ImGuiWindowFlags_None))
return;
const char* text_end = text ? FindRenderedTextEnd(text, NULL) : text;
if (text_end > text)
@ -6226,8 +6236,8 @@ bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* l
}
ImGuiButtonFlags button_flags = ImGuiTreeNodeFlags_None;
if (flags & ImGuiTreeNodeFlags_AllowItemOverlap)
button_flags |= ImGuiButtonFlags_AllowItemOverlap;
if ((flags & ImGuiTreeNodeFlags_AllowOverlap) || (g.LastItemData.InFlags & ImGuiItemflags_AllowOverlap))
button_flags |= ImGuiButtonFlags_AllowOverlap;
if (!is_leaf)
button_flags |= ImGuiButtonFlags_PressedOnDragDropHold;
@ -6300,8 +6310,6 @@ bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* l
g.LastItemData.StatusFlags |= ImGuiItemStatusFlags_ToggledOpen;
}
}
if (flags & ImGuiTreeNodeFlags_AllowItemOverlap)
SetItemAllowOverlap();
// In this branch, TreeNodeBehavior() cannot toggle the selection so this will never trigger.
if (selected != was_selected) //-V547
@ -6319,9 +6327,9 @@ bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* l
if (flags & ImGuiTreeNodeFlags_Bullet)
RenderBullet(window->DrawList, ImVec2(text_pos.x - text_offset_x * 0.60f, text_pos.y + g.FontSize * 0.5f), text_col);
else if (!is_leaf)
RenderArrow(window->DrawList, ImVec2(text_pos.x - text_offset_x + padding.x, text_pos.y), text_col, is_open ? ImGuiDir_Down : ImGuiDir_Right, 1.0f);
RenderArrow(window->DrawList, ImVec2(text_pos.x - text_offset_x + padding.x, text_pos.y), text_col, is_open ? ((flags & ImGuiTreeNodeFlags_UpsideDownArrow) ? ImGuiDir_Up : ImGuiDir_Down) : ImGuiDir_Right, 1.0f);
else // Leaf without bullet, left-adjusted text
text_pos.x -= text_offset_x;
text_pos.x -= text_offset_x -padding.x;
if (flags & ImGuiTreeNodeFlags_ClipLabelForTrailingButton)
frame_bb.Max.x -= g.FontSize + style.FramePadding.x;
@ -6341,7 +6349,7 @@ bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* l
if (flags & ImGuiTreeNodeFlags_Bullet)
RenderBullet(window->DrawList, ImVec2(text_pos.x - text_offset_x * 0.5f, text_pos.y + g.FontSize * 0.5f), text_col);
else if (!is_leaf)
RenderArrow(window->DrawList, ImVec2(text_pos.x - text_offset_x + padding.x, text_pos.y + g.FontSize * 0.15f), text_col, is_open ? ImGuiDir_Down : ImGuiDir_Right, 0.70f);
RenderArrow(window->DrawList, ImVec2(text_pos.x - text_offset_x + padding.x, text_pos.y + g.FontSize * 0.15f), text_col, is_open ? ((flags & ImGuiTreeNodeFlags_UpsideDownArrow) ? ImGuiDir_Up : ImGuiDir_Down) : ImGuiDir_Right, 0.70f);
if (g.LogEnabled)
LogSetNextTextDecoration(">", NULL);
RenderText(text_pos, label, label_end, false);
@ -6445,7 +6453,7 @@ bool ImGui::CollapsingHeader(const char* label, bool* p_visible, ImGuiTreeNodeFl
ImGuiID id = window->GetID(label);
flags |= ImGuiTreeNodeFlags_CollapsingHeader;
if (p_visible)
flags |= ImGuiTreeNodeFlags_AllowItemOverlap | ImGuiTreeNodeFlags_ClipLabelForTrailingButton;
flags |= ImGuiTreeNodeFlags_AllowOverlap | ImGuiTreeNodeFlags_ClipLabelForTrailingButton;
bool is_open = TreeNodeBehavior(id, flags, label);
if (p_visible != NULL)
{
@ -6474,7 +6482,7 @@ bool ImGui::CollapsingHeader(const char* label, bool* p_visible, ImGuiTreeNodeFl
// Tip: pass a non-visible label (e.g. "##hello") then you can use the space to draw other text or image.
// But you need to make sure the ID is unique, e.g. enclose calls in PushID/PopID or use ##unique_id.
// With this scheme, ImGuiSelectableFlags_SpanAllColumns and ImGuiSelectableFlags_AllowItemOverlap are also frequently used flags.
// With this scheme, ImGuiSelectableFlags_SpanAllColumns and ImGuiSelectableFlags_AllowOverlap are also frequently used flags.
// FIXME: Selectable() with (size.x == 0.0f) and (SelectableTextAlign.x > 0.0f) followed by SameLine() is currently not supported.
bool ImGui::Selectable(const char* label, bool selected, ImGuiSelectableFlags flags, const ImVec2& size_arg)
{
@ -6558,7 +6566,7 @@ bool ImGui::Selectable(const char* label, bool selected, ImGuiSelectableFlags fl
if (flags & ImGuiSelectableFlags_SelectOnClick) { button_flags |= ImGuiButtonFlags_PressedOnClick; }
if (flags & ImGuiSelectableFlags_SelectOnRelease) { button_flags |= ImGuiButtonFlags_PressedOnRelease; }
if (flags & ImGuiSelectableFlags_AllowDoubleClick) { button_flags |= ImGuiButtonFlags_PressedOnClickRelease | ImGuiButtonFlags_PressedOnDoubleClick; }
if (flags & ImGuiSelectableFlags_AllowItemOverlap) { button_flags |= ImGuiButtonFlags_AllowItemOverlap; }
if ((flags & ImGuiSelectableFlags_AllowOverlap) || (g.LastItemData.InFlags & ImGuiItemflags_AllowOverlap)) { button_flags |= ImGuiButtonFlags_AllowOverlap; }
const bool was_selected = selected;
bool hovered, held;
@ -6587,9 +6595,6 @@ bool ImGui::Selectable(const char* label, bool selected, ImGuiSelectableFlags fl
if (pressed)
MarkItemEdited(id);
if (flags & ImGuiSelectableFlags_AllowItemOverlap)
SetItemAllowOverlap();
// In this branch, Selectable() cannot toggle the selection so this will never trigger.
if (selected != was_selected) //-V547
g.LastItemData.StatusFlags |= ImGuiItemStatusFlags_ToggledSelection;
@ -6774,7 +6779,7 @@ int ImGui::PlotEx(ImGuiPlotType plot_type, const char* label, float (*values_get
ItemSize(total_bb, style.FramePadding.y);
if (!ItemAdd(total_bb, 0, &frame_bb))
return -1;
const bool hovered = ItemHoverable(frame_bb, id);
const bool hovered = ItemHoverable(frame_bb, id, g.LastItemData.InFlags);
// Determine scale from values if not specified
if (scale_min == FLT_MAX || scale_max == FLT_MAX)
@ -8516,7 +8521,7 @@ bool ImGui::TabItemEx(ImGuiTabBar* tab_bar, const char* label, bool* p_open,
}
// Click to Select a tab
ImGuiButtonFlags button_flags = ((is_tab_button ? ImGuiButtonFlags_PressedOnClickRelease : ImGuiButtonFlags_PressedOnClick) | ImGuiButtonFlags_AllowItemOverlap);
ImGuiButtonFlags button_flags = ((is_tab_button ? ImGuiButtonFlags_PressedOnClickRelease : ImGuiButtonFlags_PressedOnClick) | ImGuiButtonFlags_AllowOverlap);
if (g.DragDropActive && !g.DragDropPayload.IsDataType(IMGUI_PAYLOAD_TYPE_WINDOW)) // FIXME: May be an opt-in property of the payload to disable this
button_flags |= ImGuiButtonFlags_PressedOnDragDropHold;
bool hovered, held;
@ -8529,10 +8534,6 @@ bool ImGui::TabItemEx(ImGuiTabBar* tab_bar, const char* label, bool* p_open,
if (held && docked_window && g.ActiveId == id && g.ActiveIdIsJustActivated)
g.ActiveIdWindow = docked_window;
// Allow the close button to overlap unless we are dragging (in which case we don't want any overlapping tabs to be hovered)
if (g.ActiveId != id)
SetItemAllowOverlap();
// Drag and drop a single floating window node moves it
ImGuiDockNode* node = docked_window ? docked_window->DockNode : NULL;
const bool single_floating_window_node = node && node->IsFloatingNode() && (node->Windows.Size == 1);
@ -8653,8 +8654,7 @@ bool ImGui::TabItemEx(ImGuiTabBar* tab_bar, const char* label, bool* p_open,
// FIXME: We may want disabled tab to still display the tooltip?
if (text_clipped && g.HoveredId == id && !held)
if (!(tab_bar->Flags & ImGuiTabBarFlags_NoTooltip) && !(tab->Flags & ImGuiTabItemFlags_NoTooltip))
if (IsItemHovered(ImGuiHoveredFlags_DelayNormal))
SetTooltip("%.*s", (int)(FindRenderedTextEnd(label) - label), label);
SetItemTooltip("%.*s", (int)(FindRenderedTextEnd(label) - label), label);
IM_ASSERT(!is_tab_button || !(tab_bar->SelectedTabId == tab->ID && is_tab_button)); // TabItemButton should not be selected
if (is_tab_button)

View file

@ -10,6 +10,12 @@
#include "imgui.h"
#include "imgui_stdlib.h"
// Clang warnings with -Weverything
#if defined(__clang__)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wsign-conversion" // warning: implicit conversion changes signedness
#endif
struct InputTextCallback_UserData
{
std::string* Str;
@ -73,3 +79,7 @@ bool ImGui::InputTextWithHint(const char* label, const char* hint, std::string*
cb_user_data.ChainCallbackUserData = user_data;
return InputTextWithHint(label, hint, (char*)str->c_str(), str->capacity() + 1, flags, InputTextCallback, &cb_user_data);
}
#if defined(__clang__)
#pragma clang diagnostic pop
#endif

View file

@ -12,7 +12,7 @@ Build font atlases using FreeType instead of stb_truetype (which is the default
### About Gamma Correct Blending
FreeType assumes blending in linear space rather than gamma space.
See FreeType note for [FT_Render_Glyph](https://www.freetype.org/freetype2/docs/reference/ft2-base_interface.html#FT_Render_Glyph).
See FreeType note for [FT_Render_Glyph](https://freetype.org/freetype2/docs/reference/ft2-glyph_retrieval.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 Dear ImGui styles will be impacted by this change (alpha values will need tweaking).
@ -22,7 +22,7 @@ See https://gist.github.com/ocornut/b3a9ecf13502fd818799a452969649ad
### Known issues
- Oversampling settins are ignored but also not so much necessary with the higher quality rendering.
- Oversampling settings are ignored but also not so much necessary with the higher quality rendering.
### Comparison
@ -35,3 +35,10 @@ You can use the `ImGuiFreeTypeBuilderFlags_LoadColor` flag to load certain color
["Using Colorful Glyphs/Emojis"](https://github.com/ocornut/imgui/blob/master/docs/FONTS.md#using-colorful-glyphsemojis) section of FONTS.md.
![colored glyphs](https://user-images.githubusercontent.com/8225057/106171241-9dc4ba80-6191-11eb-8a69-ca1467b206d1.png)
### Using OpenType SVG fonts (SVGinOT)
- *SVG in Open Type* is a standard by Adobe and Mozilla for color OpenType and Open Font Format fonts. It allows font creators to embed complete SVG files within a font enabling full color and even animations.
- Popular fonts such as [twemoji](https://github.com/13rac1/twemoji-color-font) and fonts made with [scfbuild](https://github.com/13rac1/scfbuild) is SVGinOT
- Requires: [lunasvg](https://github.com/sammycage/lunasvg) v2.3.2 and above
1. Add `#define IMGUI_ENABLE_FREETYPE_LUNASVG` in your `imconfig.h`.
2. Get latest lunasvg binaries or build yourself. Under Windows you may use vcpkg with: `vcpkg install lunasvg --triplet=x64-windows`.

View file

@ -6,13 +6,13 @@
// CHANGELOG
// (minor and older changes stripped away, please see git history for details)
// 2023/08/01: added support for SVG fonts, enable by using '#define IMGUI_ENABLE_FREETYPE_LUNASVG' (#6591)
// 2023/01/04: fixed a packing issue which in some occurrences would prevent large amount of glyphs from being packed correctly.
// 2021/08/23: fixed crash when FT_Render_Glyph() fails to render a glyph and returns NULL.
// 2021/03/05: added ImGuiFreeTypeBuilderFlags_Bitmap to load bitmap glyphs.
// 2021/03/02: set 'atlas->TexPixelsUseColors = true' to help some backends with deciding of a prefered texture format.
// 2021/01/28: added support for color-layered glyphs via ImGuiFreeTypeBuilderFlags_LoadColor (require Freetype 2.10+).
// 2021/01/26: simplified integration by using '#define IMGUI_ENABLE_FREETYPE'.
// renamed ImGuiFreeType::XXX flags to ImGuiFreeTypeBuilderFlags_XXX for consistency with other API. removed ImGuiFreeType::BuildFontAtlas().
// 2021/01/26: simplified integration by using '#define IMGUI_ENABLE_FREETYPE'. renamed ImGuiFreeType::XXX flags to ImGuiFreeTypeBuilderFlags_XXX for consistency with other API. removed ImGuiFreeType::BuildFontAtlas().
// 2020/06/04: fix for rare case where FT_Get_Char_Index() succeed but FT_Load_Glyph() fails.
// 2019/02/09: added RasterizerFlags::Monochrome flag to disable font anti-aliasing (combine with ::MonoHinting for best results!)
// 2019/01/15: added support for imgui allocators + added FreeType only override function SetAllocatorFunctions().
@ -33,6 +33,8 @@
// FIXME: cfg.OversampleH, OversampleV are not supported (but perhaps not so necessary with this rasterizer).
#include "imgui.h"
#ifndef IMGUI_DISABLE
#include "imgui_freetype.h"
#include "imgui_internal.h" // ImMin,ImMax,ImFontAtlasBuild*,
#include <stdint.h>
@ -42,6 +44,15 @@
#include FT_GLYPH_H // <freetype/ftglyph.h>
#include FT_SYNTHESIS_H // <freetype/ftsynth.h>
#ifdef IMGUI_ENABLE_FREETYPE_LUNASVG
#include FT_OTSVG_H // <freetype/otsvg.h>
#include FT_BBOX_H // <freetype/ftbbox.h>
#include <lunasvg.h>
#if !((FREETYPE_MAJOR >= 2) && (FREETYPE_MINOR >= 12))
#error IMGUI_ENABLE_FREETYPE_LUNASVG requires FreeType version >= 2.12
#endif
#endif
#ifdef _MSC_VER
#pragma warning (push)
#pragma warning (disable: 4505) // unreferenced local function has been removed (stb stuff)
@ -68,6 +79,14 @@ static void* (*GImGuiFreeTypeAllocFunc)(size_t size, void* user_data) = ImGuiFre
static void (*GImGuiFreeTypeFreeFunc)(void* ptr, void* user_data) = ImGuiFreeTypeDefaultFreeFunc;
static void* GImGuiFreeTypeAllocatorUserData = nullptr;
// Lunasvg support
#ifdef IMGUI_ENABLE_FREETYPE_LUNASVG
static FT_Error ImGuiLunasvgPortInit(FT_Pointer* state);
static void ImGuiLunasvgPortFree(FT_Pointer* state);
static FT_Error ImGuiLunasvgPortRender(FT_GlyphSlot slot, FT_Pointer* _state);
static FT_Error ImGuiLunasvgPortPresetSlot(FT_GlyphSlot slot, FT_Bool cache, FT_Pointer* _state);
#endif
//-------------------------------------------------------------------------
// Code
//-------------------------------------------------------------------------
@ -242,7 +261,14 @@ namespace
// Need an outline for this to work
FT_GlyphSlot slot = Face->glyph;
#ifdef IMGUI_ENABLE_FREETYPE_LUNASVG
IM_ASSERT(slot->format == FT_GLYPH_FORMAT_OUTLINE || slot->format == FT_GLYPH_FORMAT_BITMAP || slot->format == FT_GLYPH_FORMAT_SVG);
#else
#if ((FREETYPE_MAJOR >= 2) && (FREETYPE_MINOR >= 12))
IM_ASSERT(slot->format != FT_GLYPH_FORMAT_SVG && "The font contains SVG glyphs, you'll need to enable IMGUI_ENABLE_FREETYPE_LUNASVG in imconfig.h and install required libraries in order to use this font");
#endif
IM_ASSERT(slot->format == FT_GLYPH_FORMAT_OUTLINE || slot->format == FT_GLYPH_FORMAT_BITMAP);
#endif // IMGUI_ENABLE_FREETYPE_LUNASVG
// Apply convenience transform (this is not picking from real "Bold"/"Italic" fonts! Merely applying FreeType helper transform. Oblique == Slanting)
if (UserFlags & ImGuiFreeTypeBuilderFlags_Bold)
@ -768,6 +794,14 @@ static bool ImFontAtlasBuildWithFreeType(ImFontAtlas* atlas)
// 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);
#ifdef IMGUI_ENABLE_FREETYPE_LUNASVG
// Install svg hooks for FreeType
// https://freetype.org/freetype2/docs/reference/ft2-properties.html#svg-hooks
// https://freetype.org/freetype2/docs/reference/ft2-svg_fonts.html#svg_fonts
SVG_RendererHooks hooks = { ImGuiLunasvgPortInit, ImGuiLunasvgPortFree, ImGuiLunasvgPortRender, ImGuiLunasvgPortPresetSlot };
FT_Property_Set(ft_library, "ot-svg", "svg-hooks", &hooks);
#endif // IMGUI_ENABLE_FREETYPE_LUNASVG
bool ret = ImFontAtlasBuildWithFreeTypeEx(ft_library, atlas, atlas->FontBuilderFlags);
FT_Done_Library(ft_library);
@ -788,6 +822,115 @@ void ImGuiFreeType::SetAllocatorFunctions(void* (*alloc_func)(size_t sz, void* u
GImGuiFreeTypeAllocatorUserData = user_data;
}
#ifdef IMGUI_ENABLE_FREETYPE_LUNASVG
// For more details, see https://gitlab.freedesktop.org/freetype/freetype-demos/-/blob/master/src/rsvg-port.c
// The original code from the demo is licensed under CeCILL-C Free Software License Agreement (https://gitlab.freedesktop.org/freetype/freetype/-/blob/master/LICENSE.TXT)
struct LunasvgPortState
{
FT_Error err = FT_Err_Ok;
lunasvg::Matrix matrix;
std::unique_ptr<lunasvg::Document> svg = nullptr;
};
static FT_Error ImGuiLunasvgPortInit(FT_Pointer* _state)
{
*_state = IM_NEW(LunasvgPortState)();
return FT_Err_Ok;
}
static void ImGuiLunasvgPortFree(FT_Pointer* _state)
{
IM_DELETE(*_state);
}
static FT_Error ImGuiLunasvgPortRender(FT_GlyphSlot slot, FT_Pointer* _state)
{
LunasvgPortState* state = *(LunasvgPortState**)_state;
// If there was an error while loading the svg in ImGuiLunasvgPortPresetSlot(), the renderer hook still get called, so just returns the error.
if (state->err != FT_Err_Ok)
return state->err;
// rows is height, pitch (or stride) equals to width * sizeof(int32)
lunasvg::Bitmap bitmap((uint8_t*)slot->bitmap.buffer, slot->bitmap.width, slot->bitmap.rows, slot->bitmap.pitch);
state->svg->setMatrix(state->svg->matrix().identity()); // Reset the svg matrix to the default value
state->svg->render(bitmap, state->matrix); // state->matrix is already scaled and translated
state->err = FT_Err_Ok;
return state->err;
}
static FT_Error ImGuiLunasvgPortPresetSlot(FT_GlyphSlot slot, FT_Bool cache, FT_Pointer* _state)
{
FT_SVG_Document document = (FT_SVG_Document)slot->other;
LunasvgPortState* state = *(LunasvgPortState**)_state;
FT_Size_Metrics& metrics = document->metrics;
// This function is called twice, once in the FT_Load_Glyph() and another right before ImGuiLunasvgPortRender().
// If it's the latter, don't do anything because it's // already done in the former.
if (cache)
return state->err;
state->svg = lunasvg::Document::loadFromData((const char*)document->svg_document, document->svg_document_length);
if (state->svg == nullptr)
{
state->err = FT_Err_Invalid_SVG_Document;
return state->err;
}
lunasvg::Box box = state->svg->box();
double scale = std::min(metrics.x_ppem / box.w, metrics.y_ppem / box.h);
double xx = (double)document->transform.xx / (1 << 16);
double xy = -(double)document->transform.xy / (1 << 16);
double yx = -(double)document->transform.yx / (1 << 16);
double yy = (double)document->transform.yy / (1 << 16);
double x0 = (double)document->delta.x / 64 * box.w / metrics.x_ppem;
double y0 = -(double)document->delta.y / 64 * box.h / metrics.y_ppem;
// Scale and transform, we don't translate the svg yet
state->matrix.identity();
state->matrix.scale(scale, scale);
state->matrix.transform(xx, xy, yx, yy, x0, y0);
state->svg->setMatrix(state->matrix);
// Pre-translate the matrix for the rendering step
state->matrix.translate(-box.x, -box.y);
// Get the box again after the transformation
box = state->svg->box();
// Calculate the bitmap size
slot->bitmap_left = FT_Int(box.x);
slot->bitmap_top = FT_Int(-box.y);
slot->bitmap.rows = (unsigned int)(ImCeil((float)box.h));
slot->bitmap.width = (unsigned int)(ImCeil((float)box.w));
slot->bitmap.pitch = slot->bitmap.width * 4;
slot->bitmap.pixel_mode = FT_PIXEL_MODE_BGRA;
// Compute all the bearings and set them correctly. The outline is scaled already, we just need to use the bounding box.
double metrics_width = box.w;
double metrics_height = box.h;
double horiBearingX = box.x;
double horiBearingY = -box.y;
double vertBearingX = slot->metrics.horiBearingX / 64.0 - slot->metrics.horiAdvance / 64.0 / 2.0;
double vertBearingY = (slot->metrics.vertAdvance / 64.0 - slot->metrics.height / 64.0) / 2.0;
slot->metrics.width = FT_Pos(IM_ROUND(metrics_width * 64.0)); // Using IM_ROUND() assume width and height are positive
slot->metrics.height = FT_Pos(IM_ROUND(metrics_height * 64.0));
slot->metrics.horiBearingX = FT_Pos(horiBearingX * 64);
slot->metrics.horiBearingY = FT_Pos(horiBearingY * 64);
slot->metrics.vertBearingX = FT_Pos(vertBearingX * 64);
slot->metrics.vertBearingY = FT_Pos(vertBearingY * 64);
if (slot->metrics.vertAdvance == 0)
slot->metrics.vertAdvance = FT_Pos(metrics_height * 1.2 * 64.0);
state->err = FT_Err_Ok;
return state->err;
}
#endif // #ifdef IMGUI_ENABLE_FREETYPE_LUNASVG
//-----------------------------------------------------------------------------
#ifdef __GNUC__
#pragma GCC diagnostic pop
#endif
@ -795,3 +938,5 @@ void ImGuiFreeType::SetAllocatorFunctions(void* (*alloc_func)(size_t sz, void* u
#ifdef _MSC_VER
#pragma warning (pop)
#endif
#endif // #ifndef IMGUI_DISABLE

View file

@ -2,8 +2,8 @@
// (headers)
#pragma once
#include "imgui.h" // IMGUI_API
#ifndef IMGUI_DISABLE
// Forward declarations
struct ImFontAtlas;
@ -48,3 +48,5 @@ namespace ImGuiFreeType
static inline bool BuildFontAtlas(ImFontAtlas* atlas, unsigned int flags = 0) { atlas->FontBuilderIO = GetBuilderForFreeType(); atlas->FontBuilderFlags = flags; return atlas->Build(); }
#endif
}
#endif // #ifndef IMGUI_DISABLE

1
extern/portaudio vendored Submodule

@ -0,0 +1 @@
Subproject commit 6ee9836a08d201c118b4715d4d70242816584000

View file

@ -66,6 +66,14 @@ namespace vgsound_emu
return T(T(in) << len) >> len;
}
// get sign extended value, sign_ext<type>(input, len)
template<typename T>
static inline T sign_ext_nomax(T in, u8 len)
{
len = (8 * sizeof(T)) - len;
return T(T(in) << len) >> len;
}
// convert attenuation decibel value to gain
static inline f32 dB_to_gain(f32 attenuation) { return std::pow(10.0f, attenuation / 20.0f); }

View file

@ -145,7 +145,7 @@ void es5504_core::voice_t::tick(u8 voice)
if (m_alu.busy())
{
// Send to output
m_out = ((sign_ext<s32>(m_filter.o4_1(), 16) >> 3) * m_volume) >>
m_out = ((sign_ext_nomax<s32>(m_filter.o4_1(), 16) >> 3) * m_volume) >>
12; // Analog multiplied in real chip, 13/12 bit ladder DAC
// ALU execute
@ -386,22 +386,22 @@ void es5504_core::regs_w(u8 page, u8 address, u16 data, bool cpu_access)
switch (address)
{
case 1: // O4(n-1) (Filter 4 Temp Register)
v.filter().set_o4_1(sign_ext<s32>(data, 16));
v.filter().set_o4_1(sign_ext_nomax<s32>(data, 16));
break;
case 2: // O3(n-2) (Filter 3 Temp Register #2)
v.filter().set_o3_2(sign_ext<s32>(data, 16));
v.filter().set_o3_2(sign_ext_nomax<s32>(data, 16));
break;
case 3: // O3(n-1) (Filter 3 Temp Register #1)
v.filter().set_o3_1(sign_ext<s32>(data, 16));
v.filter().set_o3_1(sign_ext_nomax<s32>(data, 16));
break;
case 4: // O2(n-2) (Filter 2 Temp Register #2)
v.filter().set_o2_2(sign_ext<s32>(data, 16));
v.filter().set_o2_2(sign_ext_nomax<s32>(data, 16));
break;
case 5: // O2(n-1) (Filter 2 Temp Register #1)
v.filter().set_o2_1(sign_ext<s32>(data, 16));
v.filter().set_o2_1(sign_ext_nomax<s32>(data, 16));
break;
case 6: // O1(n-1) (Filter 1 Temp Register)
v.filter().set_o1_1(sign_ext<s32>(data, 16));
v.filter().set_o1_1(sign_ext_nomax<s32>(data, 16));
break;
}
}

View file

@ -231,8 +231,8 @@ void es5505_core::voice_t::tick(u8 voice)
if (m_alu.busy())
{
// Send to output
m_output[0] = volume_calc(m_lvol, sign_ext<s32>(m_filter.o4_1(), 16));
m_output[1] = volume_calc(m_rvol, sign_ext<s32>(m_filter.o4_1(), 16));
m_output[0] = volume_calc(m_lvol, sign_ext_nomax<s32>(m_filter.o4_1(), 16));
m_output[1] = volume_calc(m_rvol, sign_ext_nomax<s32>(m_filter.o4_1(), 16));
m_ch.set_left(m_output[0]);
m_ch.set_right(m_output[1]);
@ -583,22 +583,22 @@ void es5505_core::regs_w(u8 page, u8 address, u16 data)
switch (address)
{
case 1: // O4(n-1) (Filter 4 Temp Register)
v.filter().set_o4_1(sign_ext<s32>(data, 16));
v.filter().set_o4_1(sign_ext_nomax<s32>(data, 16));
break;
case 2: // O3(n-2) (Filter 3 Temp Register #2)
v.filter().set_o3_2(sign_ext<s32>(data, 16));
v.filter().set_o3_2(sign_ext_nomax<s32>(data, 16));
break;
case 3: // O3(n-1) (Filter 3 Temp Register #1)
v.filter().set_o3_1(sign_ext<s32>(data, 16));
v.filter().set_o3_1(sign_ext_nomax<s32>(data, 16));
break;
case 4: // O2(n-2) (Filter 2 Temp Register #2)
v.filter().set_o2_2(sign_ext<s32>(data, 16));
v.filter().set_o2_2(sign_ext_nomax<s32>(data, 16));
break;
case 5: // O2(n-1) (Filter 2 Temp Register #1)
v.filter().set_o2_1(sign_ext<s32>(data, 16));
v.filter().set_o2_1(sign_ext_nomax<s32>(data, 16));
break;
case 6: // O1(n-1) (Filter 1 Temp Register)
v.filter().set_o1_1(sign_ext<s32>(data, 16));
v.filter().set_o1_1(sign_ext_nomax<s32>(data, 16));
break;
}
}

View file

@ -123,11 +123,11 @@ void es5506_core::voice_t::tick(u8 voice)
// Left and Right volume
if (bitfield(m_lvramp, 0, 8) != 0)
{
m_lvol = VGS_CLAMP(m_lvol + sign_ext<s32>(bitfield(m_lvramp, 0, 8), 8), 0, 0xffff);
m_lvol = VGS_CLAMP(m_lvol + sign_ext_nomax<s32>(bitfield(m_lvramp, 0, 8), 8), 0, 0xffff);
}
if (bitfield(m_rvramp, 0, 8) != 0)
{
m_rvol = VGS_CLAMP(m_rvol + sign_ext<s32>(bitfield(m_rvramp, 0, 8), 8), 0, 0xffff);
m_rvol = VGS_CLAMP(m_rvol + sign_ext_nomax<s32>(bitfield(m_rvramp, 0, 8), 8), 0, 0xffff);
}
// Filter coeffcient
@ -135,13 +135,13 @@ void es5506_core::voice_t::tick(u8 voice)
((m_k1ramp.slow() == 0) || (bitfield(m_filtcount, 0, 3) == 0)))
{
m_filter.set_k1(
VGS_CLAMP(m_filter.k1() + sign_ext<s32>(m_k1ramp.ramp(), 8), 0, 0xffff));
VGS_CLAMP(m_filter.k1() + sign_ext_nomax<s32>(m_k1ramp.ramp(), 8), 0, 0xffff));
}
if ((m_k2ramp.ramp() != 0) &&
((m_k2ramp.slow() == 0) || (bitfield(m_filtcount, 0, 3) == 0)))
{
m_filter.set_k2(
VGS_CLAMP(m_filter.k2() + sign_ext<s32>(m_k2ramp.ramp(), 8), 0, 0xffff));
VGS_CLAMP(m_filter.k2() + sign_ext_nomax<s32>(m_k2ramp.ramp(), 8), 0, 0xffff));
}
m_ecount--;
@ -531,7 +531,7 @@ void es5506_core::regs_w(u8 page, u8 address, u32 data)
case 8: // CH4L (Channel 4 Left)
case 10: // CH5L (Channel 5 Left)
m_ch[bitfield(address, 1, 3)].set_left(
sign_ext<s32>(bitfield(data, 0, 23), 23));
sign_ext_nomax<s32>(bitfield(data, 0, 23), 23));
break;
case 1: // CH0R (Channel 0 Right)
case 3: // CH1R (Channel 1 Right)
@ -540,7 +540,7 @@ void es5506_core::regs_w(u8 page, u8 address, u32 data)
case 9: // CH4R (Channel 4 Right)
case 11: // CH5R (Channel 5 Right)
m_ch[bitfield(address, 1, 3)].set_right(
sign_ext<s32>(bitfield(data, 0, 23), 23));
sign_ext_nomax<s32>(bitfield(data, 0, 23), 23));
break;
}
}
@ -574,22 +574,22 @@ void es5506_core::regs_w(u8 page, u8 address, u32 data)
v.alu().set_accum(data);
break;
case 4: // O4(n-1) (Filter 4 Temp Register)
v.filter().set_o4_1(sign_ext<s32>(bitfield(data, 0, 18), 18));
v.filter().set_o4_1(sign_ext_nomax<s32>(bitfield(data, 0, 18), 18));
break;
case 5: // O3(n-2) (Filter 3 Temp Register #2)
v.filter().set_o3_2(sign_ext<s32>(bitfield(data, 0, 18), 18));
v.filter().set_o3_2(sign_ext_nomax<s32>(bitfield(data, 0, 18), 18));
break;
case 6: // O3(n-1) (Filter 3 Temp Register #1)
v.filter().set_o3_1(sign_ext<s32>(bitfield(data, 0, 18), 18));
v.filter().set_o3_1(sign_ext_nomax<s32>(bitfield(data, 0, 18), 18));
break;
case 7: // O2(n-2) (Filter 2 Temp Register #2)
v.filter().set_o2_2(sign_ext<s32>(bitfield(data, 0, 18), 18));
v.filter().set_o2_2(sign_ext_nomax<s32>(bitfield(data, 0, 18), 18));
break;
case 8: // O2(n-1) (Filter 2 Temp Register #1)
v.filter().set_o2_1(sign_ext<s32>(bitfield(data, 0, 18), 18));
v.filter().set_o2_1(sign_ext_nomax<s32>(bitfield(data, 0, 18), 18));
break;
case 9: // O1(n-1) (Filter 1 Temp Register)
v.filter().set_o1_1(sign_ext<s32>(bitfield(data, 0, 18), 18));
v.filter().set_o1_1(sign_ext_nomax<s32>(bitfield(data, 0, 18), 18));
break;
case 10: // W_ST (Word Clock Start Register)
m_w_st = bitfield(data, 0, 7);

View file

@ -83,7 +83,7 @@ void k053260_core::voice_t::tick(u32 cycle)
}
// calculate output
s32 output = (m_adpcm ? m_output : sign_ext<s32>(m_data, 8)) * s32(m_volume);
s32 output = (m_adpcm ? m_output : sign_ext_nomax<s32>(m_data, 8)) * s32(m_volume);
// use math for now; actually fomula unknown
m_out[0] = (output * m_host.pan_lut(m_pan, 0)) >> 7;
m_out[1] = (output * m_host.pan_lut(m_pan, 1)) >> 7;

View file

@ -222,7 +222,7 @@ size | description
| - 0xcc: K053260 - 4 channels
| - 0xcd: TED - 2 channels
| - 0xce: Namco C140 - 24 channels
| - 0xcf: Namco C219 - 16 channels (UNAVAILABLE)
| - 0xcf: Namco C219 - 16 channels
| - 0xd0: Namco C352 - 32 channels (UNAVAILABLE)
| - 0xde: YM2610B extended - 19 channels
| - 0xe0: QSound - 19 channels

View file

@ -120,6 +120,7 @@ the following instrument types are available:
- 50: K053260
- 52: TED
- 53: C140
- 54: C219
the following feature codes are recognized:

View file

@ -21,7 +21,7 @@ OS2Version: 0
OS2_WeightWidthSlopeOnly: 0
OS2_UseTypoMetrics: 0
CreationTime: 1691897631
ModificationTime: 1692347465
ModificationTime: 1693208149
PfmFamily: 81
TTFWeight: 400
TTFWidth: 5
@ -53,7 +53,7 @@ FitToEm: 0
WinInfo: 57568 16 10
BeginPrivate: 0
EndPrivate
BeginChars: 65536 72
BeginChars: 65536 73
StartChar: space
Encoding: 32 32 0
@ -5812,7 +5812,7 @@ EndChar
StartChar: uniE141
Encoding: 57665 57665 71
Width: 1792
Flags: HWO
Flags: HW
LayerCount: 2
Fore
SplineSet
@ -5823,5 +5823,147 @@ SplineSet
92 677 l 25
EndSplineSet
EndChar
StartChar: uniE142
Encoding: 57666 57666 72
Width: 1792
Flags: H
LayerCount: 2
UndoRedoHistory
Layer: 1
Undoes
UndoOperation
Index: 0
Type: 1
WasModified: 0
WasOrder2: 0
Layer: 2
Width: 1792
VWidth: 1792
LBearingChange: 0
UnicodeEnc: 0
InstructionsLength: 0
EndUndoOperation
UndoOperation
Index: 1
Type: 3
WasModified: 0
WasOrder2: 0
Layer: 2
EndUndoOperation
EndUndoes
Redoes
EndRedoes
EndUndoRedoHistory
Fore
SplineSet
412.09375 -247.51953125 m 1
412.09375 -157.28515625 l 1
600.296875 -157.28515625 l 1
600.296875 343.80859375 l 1
592.5625 343.80859375 l 1
540.739257812 288.469726562 488.916992188 233.131835938 437.09375 177.791992188 c 1
415.010742188 197.609375 392.926757812 217.427734375 370.84375 237.245117188 c 1
427.796875 299.015625 484.75 360.787109375 541.702148438 422.557617188 c 1
706.858398438 422.557617188 l 1
706.858398438 -157.286132812 l 1
870.061523438 -157.286132812 l 1
870.061523438 -247.520507812 l 1
412.092773438 -247.520507812 l 1
412.09375 -247.51953125 l 1
1409.91015625 172.950195312 m 1
1409.91015625 124.356445312 1402.48828125 78.5751953125 1387.80078125 35.68359375 c 0
1373.11328125 -7.20703125 1354.20703125 -46.58203125 1331.16015625 -82.36328125 c 0
1308.11328125 -118.22265625 1282.33203125 -150.25390625 1253.89453125 -178.37890625 c 0
1225.37890625 -206.58203125 1197.41015625 -229.62890625 1169.91015625 -247.51953125 c 1
1025.84765625 -247.51953125 l 1
1063.66015625 -220.01953125 1097.56640625 -193.45703125 1127.64453125 -167.83203125 c 0
1157.72363281 -142.20703125 1183.97265625 -116.03515625 1206.39453125 -89.08203125 c 0
1228.73925781 -62.20703125 1247.48925781 -33.76953125 1262.48925781 -3.69140625 c 0
1277.56738281 26.38671875 1289.20800781 59.35546875 1297.56738281 95.21484375 c 0
1295.328125 95.83984375 1293.08789062 96.46484375 1290.84863281 97.08984375 c 0
1283.81738281 83.65234375 1275.61328125 71.07421875 1266.39550781 59.19921875 c 0
1257.09863281 47.32421875 1246.23925781 36.93359375 1233.73925781 28.02734375 c 0
1221.23925781 19.04296875 1207.02050781 12.01171875 1191.00488281 6.85546875 c 0
1174.98925781 1.77734375 1156.47363281 -0.80078125 1135.30175781 -0.80078125 c 0
1107.17675781 -0.80078125 1081.08300781 3.96484375 1057.09863281 13.57421875 c 0
1033.11425781 23.18359375 1012.25488281 37.08984375 994.676757812 55.37109375 c 0
977.098632812 73.57421875 963.348632812 95.37109375 953.426757812 120.60546875 c 0
943.504882812 145.91796875 938.504882812 174.58984375 938.504882812 206.54296875 c 0
938.504882812 239.82421875 944.129882812 270.52734375 955.301757812 298.73046875 c 0
966.551757812 326.85546875 982.333007812 350.91796875 1002.87988281 370.68359375 c 0
1023.34863281 390.52734375 1047.95800781 406.07421875 1076.78613281 417.24609375 c 0
1105.53613281 428.49609375 1137.87988281 434.04296875 1173.73828125 434.04296875 c 0
1210.84863281 434.04296875 1243.97363281 428.02734375 1273.11328125 415.83984375 c 0
1302.17578125 403.65234375 1326.86328125 386.23046875 1347.01953125 363.49609375 c 0
1367.17578125 340.76171875 1382.72265625 313.41796875 1393.58203125 281.46484375 c 0
1404.44140625 249.43359375 1409.91015625 213.26171875 1409.91015625 172.94921875 c 1
1409.91015625 172.950195312 l 1
1173.73046875 86.5498046875 m 0
1212.79296875 86.5498046875 1243.18261719 96.9404296875 1264.90234375 117.799804688 c 0
1286.69921875 138.581054688 1297.55761719 169.127929688 1297.55761719 209.440429688 c 2
1297.55761719 222.877929688 l 2
1297.55761719 263.190429688 1286.69824219 293.737304688 1264.90234375 314.596679688 c 0
1243.18261719 335.377929688 1212.79296875 345.768554688 1173.73046875 345.768554688 c 0
1134.66796875 345.768554688 1104.27734375 335.377929688 1082.48046875 314.596679688 c 0
1060.76074219 293.737304688 1049.90234375 263.190429688 1049.90234375 222.877929688 c 2
1049.90234375 209.440429688 l 2
1049.90234375 169.127929688 1060.76171875 138.581054688 1082.48046875 117.799804688 c 0
1104.27734375 96.9404296875 1134.66796875 86.5498046875 1173.73046875 86.5498046875 c 0
623.96875 607.015625 m 1
536.3125 607.015625 467.485351562 636.546875 417.563476562 695.765625 c 0
367.640625 754.984375 342.71875 840.921875 342.71875 953.578125 c 0
342.71875 1009.828125 349.125 1059.43652344 361.938476562 1102.328125 c 0
374.672851562 1145.21875 393.265625 1181.390625 417.563476562 1210.84375 c 0
441.938476562 1240.296875 471.46875 1262.484375 506.390625 1277.5625 c 0
541.235351562 1292.5625 580.453125 1300.0625 623.96875 1300.0625 c 0
682.25 1300.0625 731 1287.328125 770.375 1261.703125 c 0
809.75 1236.078125 840.609375 1198.34375 863.03125 1148.42285156 c 1
771.859375 1098.50097656 l 1
760.296875 1130.53125 742.5625 1155.92285156 718.578125 1174.828125 c 0
694.515625 1193.734375 663.03125 1203.109375 623.96875 1203.109375 c 0
572.171875 1203.109375 531.46875 1185.53125 502.09375 1150.375 c 0
472.640625 1115.140625 457.875 1066.46875 457.875 1004.4375 c 2
457.875 902.640625 l 2
457.875 840.609375 472.640625 791.9375 502.09375 756.702148438 c 0
531.46875 721.545898438 572.171875 703.967773438 623.96875 703.967773438 c 0
664.28125 703.967773438 697.09375 714.358398438 722.40625 735.139648438 c 0
747.640625 755.920898438 766.390625 782.639648438 778.578125 815.295898438 c 1
807.692382812 797.69140625 836.807617188 780.087890625 865.921875 762.483398438 c 1
843.5 713.889648438 812.171875 675.764648438 771.859375 648.264648438 c 0
731.46875 620.764648438 682.25 607.014648438 623.96875 607.014648438 c 1
623.96875 607.015625 l 1
1449.28027344 618.5 m 1
994.202148438 618.5 l 1
994.202148438 722.171875 l 1
1065.58203125 785.84375 1136.96289062 849.515625 1208.34277344 913.188476562 c 0
1242.24902344 943.96875 1268.34277344 973.188476562 1286.54589844 1001.078125 c 0
1304.74902344 1028.890625 1313.88964844 1058.18847656 1313.88964844 1088.890625 c 2
1313.88964844 1101.390625 l 2
1313.88964844 1134.046875 1304.12402344 1159.59375 1284.59277344 1178.18847656 c 0
1265.13964844 1196.703125 1238.73339844 1206.00097656 1205.45214844 1206.00097656 c 0
1186.85839844 1206.00097656 1170.68652344 1203.26660156 1156.93652344 1197.87597656 c 0
1143.18652344 1192.40722656 1131.15527344 1184.90625 1120.92089844 1175.29785156 c 0
1110.68652344 1165.68847656 1102.24902344 1154.51660156 1095.53027344 1141.703125 c 0
1088.81152344 1128.890625 1083.49902344 1115.140625 1079.67089844 1100.453125 c 1
1047.97851562 1112.61425781 1016.28515625 1124.77636719 984.592773438 1136.93847656 c 1
991.702148438 1158.03222656 1001.23339844 1178.34375 1013.42089844 1197.87597656 c 0
1025.60839844 1217.40722656 1040.92089844 1234.828125 1059.51464844 1250.21972656 c 0
1078.03027344 1265.53222656 1099.98339844 1277.71972656 1125.29589844 1286.62597656 c 0
1150.53027344 1295.61035156 1180.13964844 1300.06347656 1214.04589844 1300.06347656 c 0
1247.95214844 1300.06347656 1278.42089844 1295.14160156 1305.29589844 1285.21875 c 0
1332.17089844 1275.296875 1354.67089844 1261.546875 1372.95214844 1243.96875 c 0
1391.15527344 1226.31347656 1405.13964844 1205.375 1414.67089844 1181.078125 c 0
1424.28027344 1156.703125 1429.12402344 1130.21875 1429.12402344 1101.390625 c 0
1429.12402344 1074.515625 1424.98339844 1049.515625 1416.62402344 1026.46875 c 0
1408.34277344 1003.421875 1396.78027344 981.703125 1382.09277344 961.234375 c 0
1367.32714844 940.765625 1350.21777344 921.234375 1330.68652344 902.640625 c 0
1311.15527344 884.125 1290.53027344 865.21875 1268.81152344 846 c 0
1216.31152344 800.895507812 1163.81152344 755.791992188 1111.31152344 710.688476562 c 1
1449.28125 710.688476562 l 1
1449.28125 618.500976562 l 1
1449.28027344 618.5 l 1
EndSplineSet
EndChar
EndChars
EndSplineFont

Binary file not shown.

View file

@ -15,7 +15,7 @@ fi
cd win32build
# TODO: potential Arch-ism?
i686-w64-mingw32-cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_C_FLAGS="-O2 -march=i686" -DCMAKE_CXX_FLAGS="-O2 -Wall -Wextra -Wno-unused-parameter -Wno-cast-function-type -march=i686" -DBUILD_SHARED_LIBS=OFF -DSUPPORT_XP=OFF -DWITH_RENDER_DX11=ON .. || exit 1
i686-w64-mingw32-cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_C_FLAGS="-O2 -march=i586" -DCMAKE_CXX_FLAGS="-O2 -Wall -Wextra -Wno-unused-parameter -Wno-cast-function-type -march=i586" -DBUILD_SHARED_LIBS=OFF -DSUPPORT_XP=OFF -DWITH_RENDER_DX11=ON -DUSE_BACKWARD=OFF -DSDL_SSE2=OFF -DSDL_SSE3=OFF -DENABLE_SSE=OFF -DENABLE_SSE2=OFF -DENABLE_AVX=OFF -DENABLE_AVX2=OFF .. || exit 1
make -j8 || exit 1
cd ..

View file

@ -15,7 +15,7 @@ fi
cd xpbuild
# TODO: potential Arch-ism?
i686-w64-mingw32-cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_C_FLAGS="-O2" -DCMAKE_CXX_FLAGS="-O2 -Wall -Wextra -Wno-unused-parameter -Wno-cast-function-type" -DBUILD_SHARED_LIBS=OFF -DSUPPORT_XP=ON -DWITH_RENDER_DX11=OFF .. || exit 1
i686-w64-mingw32-cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_C_FLAGS="-O2" -DCMAKE_CXX_FLAGS="-O2 -Wall -Wextra -Wno-unused-parameter -Wno-cast-function-type" -DBUILD_SHARED_LIBS=OFF -DSUPPORT_XP=ON -DWITH_RENDER_DX11=OFF -DSDL_SSE2=OFF -DSDL_SSE3=OFF -DENABLE_SSE=OFF -DENABLE_SSE2=OFF -DENABLE_AVX=OFF -DENABLE_AVX2=OFF .. || exit 1
make -j8 || exit 1
cd ..

275
src/audio/pa.cpp Normal file
View file

@ -0,0 +1,275 @@
/**
* Furnace Tracker - multi-system chiptune tracker
* Copyright (C) 2021-2023 tildearrow and contributors
*
* 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.
*/
#include <string.h>
#include <vector>
#include "../ta-log.h"
#include "pa.h"
#ifdef _WIN32
#include <pa_win_wasapi.h>
#endif
int taPAProcess(const void* in, void* out, unsigned long nframes, const PaStreamCallbackTimeInfo* timeInfo, PaStreamCallbackFlags flags, void* inst) {
TAAudioPA* instance=(TAAudioPA*)inst;
return instance->onProcess(in,out,nframes,timeInfo,flags);
}
int TAAudioPA::onProcess(const void* in, void* out, unsigned long nframes, const PaStreamCallbackTimeInfo* timeInfo, PaStreamCallbackFlags flags) {
for (int i=0; i<desc.inChans; i++) {
if (nframes>desc.bufsize) {
delete[] inBufs[i];
inBufs[i]=new float[nframes];
}
}
for (int i=0; i<desc.outChans; i++) {
if (nframes>desc.bufsize) {
delete[] outBufs[i];
outBufs[i]=new float[nframes];
}
}
if (nframes!=desc.bufsize) {
desc.bufsize=nframes;
}
if (audioProcCallback!=NULL) {
if (midiIn!=NULL) midiIn->gather();
audioProcCallback(audioProcCallbackUser,inBufs,outBufs,desc.inChans,desc.outChans,desc.bufsize);
}
float* fbuf=(float*)out;
for (size_t j=0; j<desc.bufsize; j++) {
for (size_t i=0; i<desc.outChans; i++) {
fbuf[j*desc.outChans+i]=outBufs[i][j];
}
}
return 0;
}
void* TAAudioPA::getContext() {
return (void*)&ac;
}
bool TAAudioPA::quit() {
if (!initialized) return false;
Pa_CloseStream(ac);
if (running) {
running=false;
}
for (int i=0; i<desc.outChans; i++) {
delete[] outBufs[i];
}
delete[] outBufs;
initialized=false;
return true;
}
bool TAAudioPA::setRun(bool run) {
if (!initialized) return false;
if (running==run) return running;
PaError status;
if (run) {
status=Pa_StartStream(ac);
} else {
status=Pa_StopStream(ac);
}
if (status!=paNoError) {
logW("error while setting run status: %s",Pa_GetErrorText(status));
return running;
}
running=run;
return running;
}
std::vector<String> TAAudioPA::listAudioDevices() {
std::vector<String> ret;
if (!audioSysStarted) {
PaError status=Pa_Initialize();
if (status!=paNoError) {
logE("could not initialize PortAudio to list audio devices");
return ret;
} else {
audioSysStarted=true;
}
}
int count=Pa_GetDeviceCount();
if (count<0) return ret;
for (int i=0; i<count; i++) {
const PaDeviceInfo* devInfo=Pa_GetDeviceInfo(i);
if (devInfo==NULL) continue;
if (devInfo->maxOutputChannels<1) continue;
String devName;
const PaHostApiInfo* driverInfo=Pa_GetHostApiInfo(devInfo->hostApi);
if (driverInfo==NULL) {
devName+="[???] ";
} else {
devName+=fmt::sprintf("[%s] ",driverInfo->name);
}
if (devInfo->name!=NULL) {
devName+=devInfo->name;
ret.push_back(devName);
}
}
return ret;
}
bool TAAudioPA::init(TAAudioDesc& request, TAAudioDesc& response) {
if (initialized) {
logE("audio already initialized");
return false;
}
PaError status;
if (!audioSysStarted) {
status=Pa_Initialize();
if (status!=paNoError) {
logE("could not initialize PortAudio");
return false;
} else {
audioSysStarted=true;
}
}
desc=request;
desc.outFormat=TA_AUDIO_FORMAT_F32;
const PaDeviceInfo* devInfo=NULL;
const PaHostApiInfo* driverInfo=NULL;
int outDeviceID=0;
if (desc.deviceName.empty()) {
outDeviceID=Pa_GetDefaultOutputDevice();
devInfo=Pa_GetDeviceInfo(outDeviceID);
if (devInfo!=NULL) {
driverInfo=Pa_GetHostApiInfo(devInfo->hostApi);
}
} else {
int count=Pa_GetDeviceCount();
bool found=false;
if (count<0) {
logE("audio device not found");
return false;
}
for (int i=0; i<count; i++) {
devInfo=Pa_GetDeviceInfo(i);
if (devInfo==NULL) continue;
if (devInfo->maxOutputChannels<1) continue;
String devName;
driverInfo=Pa_GetHostApiInfo(devInfo->hostApi);
if (driverInfo==NULL) {
devName+="[???] ";
} else {
devName+=fmt::sprintf("[%s] ",driverInfo->name);
}
if (devInfo->name!=NULL) {
devName+=devInfo->name;
} else {
continue;
}
if (devName==desc.deviceName) {
outDeviceID=i;
found=true;
break;
}
}
if (!found) {
logE("audio device not found");
return false;
}
}
// check output channels and sample rate
if (devInfo!=NULL) {
if (desc.outChans>devInfo->maxOutputChannels) desc.outChans=devInfo->maxOutputChannels;
}
PaStreamParameters outParams;
outParams.device=outDeviceID;
outParams.channelCount=desc.outChans;
outParams.sampleFormat=paFloat32;
outParams.suggestedLatency=(double)(desc.bufsize*desc.fragments)/desc.rate;
outParams.hostApiSpecificStreamInfo=NULL;
if (driverInfo!=NULL) {
#ifdef _WIN32
if (driverInfo->type==paWASAPI) {
logV("setting WASAPI-specific flags");
PaWasapiStreamInfo* wasapiInfo=new PaWasapiStreamInfo;
memset(wasapiInfo,0,sizeof(PaWasapiStreamInfo));
wasapiInfo->size=sizeof(PaWasapiStreamInfo);
wasapiInfo->hostApiType=paWASAPI;
wasapiInfo->version=1;
wasapiInfo->flags=paWinWasapiThreadPriority;
wasapiInfo->threadPriority=eThreadPriorityProAudio;
wasapiInfo->streamCategory=eAudioCategoryMedia;
wasapiInfo->streamOption=eStreamOptionRaw;
if (desc.wasapiEx) {
wasapiInfo->flags|=paWinWasapiExclusive;
}
outParams.hostApiSpecificStreamInfo=wasapiInfo;
}
#endif
}
logV("opening audio device...");
status=Pa_OpenStream(
&ac,
NULL,
&outParams,
desc.rate,
0,
paClipOff|paDitherOff,
taPAProcess,
this
);
if (status!=paNoError) {
logE("could not open audio device: %s",Pa_GetErrorText(status));
return false;
}
desc.deviceName=devInfo->name;
desc.inChans=0;
if (desc.outChans>0) {
outBufs=new float*[desc.outChans];
for (int i=0; i<desc.outChans; i++) {
outBufs[i]=new float[desc.bufsize];
}
}
response=desc;
initialized=true;
return true;
}

38
src/audio/pa.h Normal file
View file

@ -0,0 +1,38 @@
/**
* Furnace Tracker - multi-system chiptune tracker
* Copyright (C) 2021-2023 tildearrow and contributors
*
* 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.
*/
#include "taAudio.h"
#include <portaudio.h>
class TAAudioPA: public TAAudio {
PaStream* ac;
bool audioSysStarted;
public:
int onProcess(const void* in, void* out, unsigned long nframes, const PaStreamCallbackTimeInfo* timeInfo, PaStreamCallbackFlags flags);
void* getContext();
bool quit();
bool setRun(bool run);
std::vector<String> listAudioDevices();
bool init(TAAudioDesc& request, TAAudioDesc& response);
TAAudioPA():
ac(NULL),
audioSysStarted(false) {}
};

View file

@ -58,13 +58,16 @@ struct TAAudioDesc {
unsigned char inChans, outChans;
TAAudioFormat outFormat;
bool wasapiEx;
TAAudioDesc():
rate(0.0),
bufsize(0),
fragments(0),
inChans(0),
outChans(0),
outFormat(TA_AUDIO_FORMAT_F32) {}
outFormat(TA_AUDIO_FORMAT_F32),
wasapiEx(false) {}
};

61
src/engine/bsr.h Normal file
View file

@ -0,0 +1,61 @@
/**
* Furnace Tracker - multi-system chiptune tracker
* Copyright (C) 2021-2023 tildearrow and contributors
*
* 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.
*/
#if defined( _MSC_VER )
#include <intrin.h>
static inline int bsr(unsigned short v) {
unsigned long idx;
if (_BitScanReverse(&idx,(unsigned long)v)) {
return idx;
}
else {
return -1;
}
}
#elif defined( __GNUC__ )
static inline int bsr(unsigned short v)
{
if (v) {
return 32 - __builtin_clz(v);
}
else{
return -1;
}
}
#else
static inline int bsr(unsigned short v)
{
unsigned short mask = 0x8000;
for (int i = 15; i >= 0; --i) {
if (v&mask)
return (int)i;
mask>>=1;
}
return -1;
}
#endif

View file

@ -587,6 +587,11 @@ void DivDispatchContainer::init(DivSystem sys, DivEngine* eng, int chanCount, do
break;
case DIV_SYSTEM_C140:
dispatch=new DivPlatformC140;
((DivPlatformC140*)dispatch)->set219(false);
break;
case DIV_SYSTEM_C219:
dispatch=new DivPlatformC140;
((DivPlatformC140*)dispatch)->set219(true);
break;
case DIV_SYSTEM_PCM_DAC:
dispatch=new DivPlatformPCMDAC;

View file

@ -32,6 +32,9 @@
#ifdef HAVE_JACK
#include "../audio/jack.h"
#endif
#ifdef HAVE_PA
#include "../audio/pa.h"
#endif
#include <math.h>
#include <float.h>
#include <fmt/printf.h>
@ -3279,6 +3282,8 @@ bool DivEngine::initAudioBackend() {
if (audioEngine==DIV_AUDIO_NULL) {
if (getConfString("audioEngine","SDL")=="JACK") {
audioEngine=DIV_AUDIO_JACK;
} else if (getConfString("audioEngine","SDL")=="PortAudio") {
audioEngine=DIV_AUDIO_PORTAUDIO;
} else {
audioEngine=DIV_AUDIO_SDL;
}
@ -3322,6 +3327,21 @@ bool DivEngine::initAudioBackend() {
#endif
#else
output=new TAAudioJACK;
#endif
break;
case DIV_AUDIO_PORTAUDIO:
#ifndef HAVE_PA
logE("Furnace was not compiled with PortAudio!");
setConf("audioEngine","SDL");
saveConf();
#ifdef HAVE_SDL2
output=new TAAudioSDL;
#else
logE("Furnace was not compiled with SDL support either!");
output=new TAAudio;
#endif
#else
output=new TAAudioPA;
#endif
break;
case DIV_AUDIO_SDL:
@ -3350,6 +3370,7 @@ bool DivEngine::initAudioBackend() {
want.inChans=0;
want.outChans=getConfInt("audioChans",2);
want.outFormat=TA_AUDIO_FORMAT_F32;
want.wasapiEx=getConfInt("wasapiEx",0);
want.name="Furnace";
if (want.outChans<1) want.outChans=1;

View file

@ -54,10 +54,10 @@
#define EXTERN_BUSY_BEGIN_SOFT e->softLocked=true; e->isBusy.lock();
#define EXTERN_BUSY_END e->isBusy.unlock(); e->softLocked=false;
//#define DIV_UNSTABLE
#define DIV_UNSTABLE
#define DIV_VERSION "0.6pre9"
#define DIV_ENGINE_VERSION 169
#define DIV_VERSION "dev170"
#define DIV_ENGINE_VERSION 170
// for imports
#define DIV_VERSION_MOD 0xff01
#define DIV_VERSION_FC 0xff02
@ -73,6 +73,7 @@ enum DivStatusView {
enum DivAudioEngines {
DIV_AUDIO_JACK=0,
DIV_AUDIO_SDL=1,
DIV_AUDIO_PORTAUDIO=2,
DIV_AUDIO_NULL=126,
DIV_AUDIO_DUMMY=127
@ -283,6 +284,7 @@ struct DivSysDef {
DivInstrumentType chanInsType[DIV_MAX_CHANS][2];
const EffectHandlerMap effectHandlers;
const EffectHandlerMap postEffectHandlers;
const EffectHandlerMap preEffectHandlers;
DivSysDef(
const char* sysName, const char* sysNameJ, unsigned char fileID, unsigned char fileID_DMF, int chans,
bool isFMChip, bool isSTDChip, unsigned int vgmVer, bool compound, unsigned int formatMask, const char* desc,
@ -292,7 +294,8 @@ struct DivSysDef {
std::initializer_list<DivInstrumentType> chInsType1,
std::initializer_list<DivInstrumentType> chInsType2={},
const EffectHandlerMap fxHandlers_={},
const EffectHandlerMap postFxHandlers_={}):
const EffectHandlerMap postFxHandlers_={},
const EffectHandlerMap preFxHandlers_={}):
name(sysName),
nameJ(sysNameJ),
description(desc),
@ -305,7 +308,8 @@ struct DivSysDef {
vgmVersion(vgmVer),
sampleFormatMask(formatMask),
effectHandlers(fxHandlers_),
postEffectHandlers(postFxHandlers_) {
postEffectHandlers(postFxHandlers_),
preEffectHandlers(preFxHandlers_) {
memset(chanNames,0,DIV_MAX_CHANS*sizeof(void*));
memset(chanShortNames,0,DIV_MAX_CHANS*sizeof(void*));
memset(chanTypes,0,DIV_MAX_CHANS*sizeof(int));
@ -484,6 +488,7 @@ class DivEngine {
// MIDI stuff
std::function<int(const TAMidiMessage&)> midiCallback=[](const TAMidiMessage&) -> int {return -2;};
void processRowPre(int i);
void processRow(int i, bool afterDelay);
void nextOrder();
void nextRow();
@ -492,6 +497,7 @@ class DivEngine {
bool nextTick(bool noAccum=false, bool inhibitLowLat=false);
bool perSystemEffect(int ch, unsigned char effect, unsigned char effectVal);
bool perSystemPostEffect(int ch, unsigned char effect, unsigned char effectVal);
bool perSystemPreEffect(int ch, unsigned char effect, unsigned char effectVal);
void recalcChans();
void reset();
void playSub(bool preserveDrift, int goalRow=0);

View file

@ -390,11 +390,13 @@ DivSample* DivEngine::sampleFromFileRaw(const char* path, DivSampleDepth depth,
case DIV_SAMPLE_DEPTH_QSOUND_ADPCM:
case DIV_SAMPLE_DEPTH_ADPCM_A:
case DIV_SAMPLE_DEPTH_ADPCM_B:
case DIV_SAMPLE_DEPTH_ADPCM_K:
case DIV_SAMPLE_DEPTH_VOX:
samples=lenDivided*2;
break;
case DIV_SAMPLE_DEPTH_8BIT:
case DIV_SAMPLE_DEPTH_MULAW:
case DIV_SAMPLE_DEPTH_C219:
samples=lenDivided;
break;
case DIV_SAMPLE_DEPTH_BRR:
@ -487,6 +489,7 @@ DivSample* DivEngine::sampleFromFileRaw(const char* path, DivSampleDepth depth,
case DIV_SAMPLE_DEPTH_QSOUND_ADPCM:
case DIV_SAMPLE_DEPTH_ADPCM_A:
case DIV_SAMPLE_DEPTH_ADPCM_B:
case DIV_SAMPLE_DEPTH_ADPCM_K:
case DIV_SAMPLE_DEPTH_VOX:
// swap nibbles
for (unsigned int i=0; i<sample->getCurBufLen(); i++) {

View file

@ -967,6 +967,10 @@ void DivInstrument::putInsData2(SafeWriter* w, bool fui, const DivSong* song) {
featureSM=true;
featureSL=true;
break;
case DIV_INS_C219:
featureSM=true;
featureSL=true;
break;
case DIV_INS_MAX:
break;

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