mirror of
https://github.com/Drezil/imgui.git
synced 2025-07-13 16:29:54 +02:00
Compare commits
70 Commits
Author | SHA1 | Date | |
---|---|---|---|
95c99aaa4b | |||
c6b01e8e1d | |||
14539b3ed2 | |||
d3fcc37e9e | |||
3c65b650e8 | |||
f32663b33c | |||
7f8f0096d8 | |||
fb0f2ebd41 | |||
fa279a6aa0 | |||
f75b29e7be | |||
8018623c5b | |||
170d02bd99 | |||
7607aea018 | |||
43c099f31e | |||
152dae9e2a | |||
9f98b4e7f2 | |||
a252a287bf | |||
46d75202b8 | |||
0e5b1ea297 | |||
214dd68ec1 | |||
a4dd4d60b4 | |||
8241cd6284 | |||
009276b6cb | |||
209a6a751c | |||
89ac87cd91 | |||
90b152f265 | |||
ede8825fb2 | |||
b15b25bccd | |||
8074b49148 | |||
fc61018b1c | |||
473a01adb0 | |||
a24578ec09 | |||
db886f3953 | |||
963839373c | |||
55041ac3be | |||
912c45ab23 | |||
4929a8e4a5 | |||
a876ad877d | |||
5d87941451 | |||
76ddacd2a1 | |||
218ff3a2a5 | |||
c7f5876f8a | |||
bbd061538c | |||
b8c22bdb28 | |||
fdc526e8f8 | |||
b335225caa | |||
e223bd8177 | |||
4be8155002 | |||
825f2ae455 | |||
eefae08261 | |||
550f110354 | |||
fb7f6cab8c | |||
06f7854b16 | |||
89685b346c | |||
66336528c8 | |||
3a6c9907cd | |||
b5bae9781d | |||
78d6bdf080 | |||
a07c8b6999 | |||
21d9e8e1f4 | |||
403bf45245 | |||
222b7ddbfa | |||
741ab74b55 | |||
1d3c3070d8 | |||
8e4046e13b | |||
0d03e1fafa | |||
a1d2c6fad9 | |||
ab4ef822f0 | |||
0738611559 | |||
dca7c3c629 |
45
.github/workflows/build.yml
vendored
45
.github/workflows/build.yml
vendored
@ -180,7 +180,7 @@ jobs:
|
||||
run: '"%MSBUILD_PATH%\MSBuild.exe" examples/example_win32_directx12/example_win32_directx12.vcxproj /p:Platform=x64 /p:Configuration=Release'
|
||||
|
||||
Linux:
|
||||
runs-on: ubuntu-18.04
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
with:
|
||||
@ -389,45 +389,12 @@ jobs:
|
||||
wget -q https://github.com/emscripten-core/emsdk/archive/master.tar.gz
|
||||
tar -xvf master.tar.gz
|
||||
emsdk-master/emsdk update
|
||||
emsdk-master/emsdk install latest-fastcomp
|
||||
emsdk-master/emsdk activate latest-fastcomp
|
||||
emsdk-master/emsdk install latest
|
||||
emsdk-master/emsdk activate latest
|
||||
|
||||
- name: Build example_emscripten
|
||||
run: |
|
||||
source emsdk-master/emsdk_env.sh
|
||||
pushd emsdk-master
|
||||
source ./emsdk_env.sh
|
||||
popd
|
||||
make -C examples/example_emscripten
|
||||
|
||||
Static-Analysis:
|
||||
runs-on: ubuntu-18.04
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
with:
|
||||
fetch-depth: 1
|
||||
|
||||
- name: Install Dependencies
|
||||
env:
|
||||
PVS_STUDIO_LICENSE: ${{ secrets.PVS_STUDIO_LICENSE }}
|
||||
run: |
|
||||
if [[ "$PVS_STUDIO_LICENSE" != "" ]];
|
||||
then
|
||||
echo "$PVS_STUDIO_LICENSE" > pvs-studio.lic
|
||||
wget -q https://files.viva64.com/etc/pubkey.txt
|
||||
sudo apt-key add pubkey.txt
|
||||
sudo wget -O /etc/apt/sources.list.d/viva64.list https://files.viva64.com/etc/viva64.list
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y pvs-studio
|
||||
fi
|
||||
|
||||
- name: PVS-Studio static analysis
|
||||
run: |
|
||||
if [[ ! -f pvs-studio.lic ]];
|
||||
then
|
||||
echo "PVS Studio license is missing. No analysis will be performed."
|
||||
echo "If you have a PVS Studio license please create a project secret named PVS_STUDIO_LICENSE with your license."
|
||||
echo "You may use a free license. More information at https://www.viva64.com/en/b/0457/"
|
||||
exit 0
|
||||
fi
|
||||
cd examples/example_null
|
||||
pvs-studio-analyzer trace -- make WITH_EXTRA_WARNINGS=1
|
||||
pvs-studio-analyzer analyze -e ../../imstb_rectpack.h -e ../../imstb_textedit.h -e ../../imstb_truetype.h -l ../../pvs-studio.lic -o pvs-studio.log
|
||||
plog-converter -a 'GA:1,2;OP:1' -t errorfile -w pvs-studio.log
|
||||
|
43
.github/workflows/static-analysis.yml
vendored
Normal file
43
.github/workflows/static-analysis.yml
vendored
Normal file
@ -0,0 +1,43 @@
|
||||
name: static-analysis
|
||||
|
||||
on:
|
||||
push: {}
|
||||
pull_request: {}
|
||||
schedule:
|
||||
- cron: '0 9 * * *'
|
||||
|
||||
jobs:
|
||||
PVS-Studio:
|
||||
runs-on: ubuntu-18.04
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
with:
|
||||
fetch-depth: 1
|
||||
|
||||
- name: Install Dependencies
|
||||
env:
|
||||
PVS_STUDIO_LICENSE: ${{ secrets.PVS_STUDIO_LICENSE }}
|
||||
run: |
|
||||
if [[ "$PVS_STUDIO_LICENSE" != "" ]];
|
||||
then
|
||||
echo "$PVS_STUDIO_LICENSE" > pvs-studio.lic
|
||||
wget -q https://files.viva64.com/etc/pubkey.txt
|
||||
sudo apt-key add pubkey.txt
|
||||
sudo wget -O /etc/apt/sources.list.d/viva64.list https://files.viva64.com/etc/viva64.list
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y pvs-studio
|
||||
fi
|
||||
|
||||
- name: PVS-Studio static analysis
|
||||
run: |
|
||||
if [[ ! -f pvs-studio.lic ]];
|
||||
then
|
||||
echo "PVS Studio license is missing. No analysis will be performed."
|
||||
echo "If you have a PVS Studio license please create a project secret named PVS_STUDIO_LICENSE with your license."
|
||||
echo "You may use a free license. More information at https://www.viva64.com/en/b/0457/"
|
||||
exit 0
|
||||
fi
|
||||
cd examples/example_null
|
||||
pvs-studio-analyzer trace -- make WITH_EXTRA_WARNINGS=1
|
||||
pvs-studio-analyzer analyze -e ../../imstb_rectpack.h -e ../../imstb_textedit.h -e ../../imstb_truetype.h -l ../../pvs-studio.lic -o pvs-studio.log
|
||||
plog-converter -a 'GA:1,2;OP:1' -t errorfile -w pvs-studio.log
|
@ -31,6 +31,103 @@ HOW TO UPDATE?
|
||||
- Please report any issue!
|
||||
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
VERSION 1.78 (Released 2020-08-18)
|
||||
-----------------------------------------------------------------------
|
||||
|
||||
Breaking Changes:
|
||||
|
||||
- Obsoleted use of the trailing 'float power=1.0f' parameter for those functions: [@Shironekoben, @ocornut]
|
||||
- DragFloat(), DragFloat2(), DragFloat3(), DragFloat4(), DragFloatRange2(), DragScalar(), DragScalarN()
|
||||
- SliderFloat(), SliderFloat2(), SliderFloat3(), SliderFloat4(), SliderScalar(), SliderScalarN()
|
||||
- VSliderFloat(), VSliderScalar()
|
||||
Replaced the final 'float power=1.0f' argument with ImGuiSliderFlags defaulting to 0 (as with all our flags).
|
||||
Worked out a backward-compatibility scheme so hopefully most C++ codebase should not be affected.
|
||||
In short, when calling those functions:
|
||||
- If you omitted the 'power' parameter (likely!), you are not affected.
|
||||
- If you set the 'power' parameter to 1.0f (same as previous default value):
|
||||
- Your compiler may warn on float>int conversion.
|
||||
- Everything else will work (but will assert if IMGUI_DISABLE_OBSOLETE_FUNCTIONS is defined).
|
||||
- You can replace the 1.0f value with 0 to fix the warning, and be technically correct.
|
||||
- If you set the 'power' parameter to >1.0f (to enable non-linear editing):
|
||||
- Your compiler may warn on float>int conversion.
|
||||
- Code will assert at runtime for IM_ASSERT(power == 1.0f) with the following assert description:
|
||||
"Call Drag function with ImGuiSliderFlags_Logarithmic instead of using the old 'float power' function!".
|
||||
- In case asserts are disabled, the code will not crash and enable the _Logarithmic flag.
|
||||
- You can replace the >1.0f value with ImGuiSliderFlags_Logarithmic to fix the warning/assert
|
||||
and get a _similar_ effect as previous uses of power >1.0f.
|
||||
See https://github.com/ocornut/imgui/issues/3361 for all details.
|
||||
Kept inline redirection functions (will obsolete) apart for: DragFloatRange2(), VSliderFloat(), VSliderScalar().
|
||||
For those three the 'float power=1.0f' version was removed directly as they were most unlikely ever used.
|
||||
- DragInt, DragFloat, DragScalar: Obsoleted use of v_min > v_max to lock edits (introduced in 1.73, this was not
|
||||
demoed nor documented much, will be replaced a more generic ReadOnly feature).
|
||||
|
||||
Other Changes:
|
||||
|
||||
- Nav: Fixed clicking on void (behind any windows) from not clearing the focused window.
|
||||
This would be problematic e.g. in situation where the application relies on io.WantCaptureKeyboard
|
||||
flag being cleared accordingly. (bug introduced in 1.77 WIP on 2020/06/16) (#3344, #2880)
|
||||
- Window: Fixed clicking over an item which hovering has been disabled (e.g inhibited by a popup)
|
||||
from marking the window as moved.
|
||||
- Drag, Slider: Added ImGuiSliderFlags parameters.
|
||||
- For float functions they replace the old trailing 'float power=1.0' parameter.
|
||||
(See #3361 and the "Breaking Changes" block above for all details).
|
||||
- Added ImGuiSliderFlags_Logarithmic flag to enable logarithmic editing
|
||||
(generally more precision around zero), as a replacement to the old 'float power' parameter
|
||||
which was obsoleted. (#1823, #1316, #642) [@Shironekoben, @AndrewBelt]
|
||||
- Added ImGuiSliderFlags_ClampOnInput flag to force clamping value when using
|
||||
CTRL+Click to type in a value manually. (#1829, #3209, #946, #413).
|
||||
- Added ImGuiSliderFlags_NoRoundToFormat flag to disable rounding underlying
|
||||
value to match precision of the display format string. (#642)
|
||||
- Added ImGuiSliderFlags_NoInput flag to disable turning widget into a text input
|
||||
with CTRL+Click or Nav Enter.
|
||||
- Nav, Slider: Fix using keyboard/gamepad controls with certain logarithmic sliders where
|
||||
pushing a direction near zero values would be cancelled out. [@Shironekoben]
|
||||
- DragFloatRange2, DragIntRange2: Fixed an issue allowing to drag out of bounds when both
|
||||
min and max value are on the same value. (#1441)
|
||||
- InputText, ImDrawList: Fixed assert triggering when drawing single line of text with more
|
||||
than ~16 KB characters. (Note that current code is going to show corrupted display if after
|
||||
clipping, more than 16 KB characters are visible in the same low-level ImDrawList::RenderText()
|
||||
call. ImGui-level functions such as TextUnformatted() are not affected. This is quite rare
|
||||
but it will be addressed later). (#3349)
|
||||
- Selectable: Fixed highlight/hit extent when used with horizontal scrolling (in or outside columns).
|
||||
Also fixed related text clipping when used in a column after the first one. (#3187, #3386)
|
||||
- Scrolling: Avoid SetScroll, SetScrollFromPos functions from snapping on the edge of scroll
|
||||
limits when close-enough by (WindowPadding - ItemPadding), which was a tweak with too many
|
||||
side-effects. The behavior is still present in SetScrollHere functions as they are more explicitly
|
||||
aiming at making widgets visible. May later be moved to a flag.
|
||||
- Tab Bar: Allow calling SetTabItemClosed() after a tab has been submitted (will process next frame).
|
||||
- InvisibleButton: Made public a small selection of ImGuiButtonFlags (previously in imgui_internal.h)
|
||||
and allowed to pass them to InvisibleButton(): ImGuiButtonFlags_MouseButtonLeft/Right/Middle.
|
||||
This is a small but rather important change because lots of multi-button behaviors could previously
|
||||
only be achieved using lower-level/internal API. Now also available via high-level InvisibleButton()
|
||||
with is a de-facto versatile building block to creating custom widgets with the public API.
|
||||
- Fonts: Fixed ImFontConfig::GlyphExtraSpacing and ImFontConfig::PixelSnapH settings being pulled
|
||||
from the merged/target font settings when merging fonts, instead of being pulled from the source
|
||||
font settings.
|
||||
- ImDrawList: Thick anti-aliased strokes (> 1.0f) with integer thickness now use a texture-based
|
||||
path, reducing the amount of vertices/indices and CPU/GPU usage. (#3245) [@Shironekoben]
|
||||
- This change will facilitate the wider use of thick borders in future style changes.
|
||||
- Requires an extra bit of texture space (~64x64 by default), relies on GPU bilinear filtering.
|
||||
- Set `io.AntiAliasedLinesUseTex = false` to disable rendering using this method.
|
||||
- Clear `ImFontAtlasFlags_NoBakedLines` in ImFontAtlas::Flags to disable baking data in texture.
|
||||
- ImDrawList: changed AddCircle(), AddCircleFilled() default num_segments from 12 to 0, effectively
|
||||
enabling auto-tessellation by default. Tweak tessellation in Style Editor->Rendering section, or
|
||||
by modifying the 'style.CircleSegmentMaxError' value. [@ShironekoBen]
|
||||
- ImDrawList: Fixed minor bug introduced in 1.75 where AddCircle() with 12 segments would generate
|
||||
an extra vertex. (This bug was mistakenly marked as fixed in earlier 1.77 release). [@ShironekoBen]
|
||||
- Demo: Improved "Custom Rendering"->"Canvas" demo with a grid, scrolling and context menu.
|
||||
Also showcase using InvisibleButton() with multiple mouse buttons flags.
|
||||
- Demo: Improved "Layout & Scrolling" -> "Clipping" section.
|
||||
- Demo: Improved "Layout & Scrolling" -> "Child Windows" section.
|
||||
- Style Editor: Added preview of circle auto-tessellation when editing the corresponding value.
|
||||
- Backends: OpenGL3: Added support for glad2 loader. (#3330) [@moritz-h]
|
||||
- Backends: Allegro 5: Fixed horizontal scrolling direction with mouse wheel / touch pads (it seems
|
||||
like Allegro 5 reports it differently from GLFW and SDL). (#3394, #2424, #1463) [@nobody-special666]
|
||||
- Examples: Vulkan: Fixed GLFW+Vulkan and SDL+Vulkan clear color not being set. (#3390) [@RoryO]
|
||||
- CI: Emscripten has stopped their support for their fastcomp backend, switching to latest sdk [@Xipiryon]
|
||||
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
VERSION 1.77 (Released 2020-06-29)
|
||||
-----------------------------------------------------------------------
|
||||
@ -40,7 +137,7 @@ Decorated log: https://github.com/ocornut/imgui/releases/tag/v1.77
|
||||
Breaking Changes:
|
||||
|
||||
- Removed unnecessary ID (first arg) of ImFontAtlas::AddCustomRectRegular() function. Please
|
||||
note that this is a Beta api and will likely be reworked in order to support multi-DPI accross
|
||||
note that this is a Beta api and will likely be reworked in order to support multi-DPI across
|
||||
multiple monitors.
|
||||
- Renamed OpenPopupOnItemClick() to OpenPopupContextItem(). Kept inline redirection function (will obsolete).
|
||||
- Removed BeginPopupContextWindow(const char*, int mouse_button, bool also_over_items) in favor
|
||||
@ -98,14 +195,12 @@ Other Changes:
|
||||
VtxOffset was not zero would lead to draw commands with wrong VtxOffset. (#2591)
|
||||
- ImDrawList, ImDrawListSplitter, Columns: Fixed an issue where starting a split right after
|
||||
a callback draw command would incorrectly override the callback draw command.
|
||||
- ImDrawList: Fixed minor bug introduced in 1.75 where AddCircle() with 12 segments would
|
||||
generate an extra unrequired vertex. [@ShironekoBen]
|
||||
- Misc, Freetype: Fix for rare case where FT_Get_Char_Index() succeeds but FT_Load_Glyph() fails.
|
||||
- Docs: Improved and moved font documentation to docs/FONTS.md so it can be readable on the web.
|
||||
Updated various links/wiki accordingly. Added FAQ entry about DPI. (#2861) [@ButternCream, @ocornut]
|
||||
- CI: Added CI test to verify we're never accidentally dragging libstdc++ (on some compiler setups,
|
||||
static constructors for non-pod data seems to drag in libstdc++ due to thread-safety concerns).
|
||||
Fixed a static constructor which led to this dependency on some compiler setups.
|
||||
Fixed a static constructor which led to this dependency on some compiler setups. [@rokups]
|
||||
- Backends: Win32: Support for #define NOGDI, won't try to call GetDeviceCaps(). (#3137, #2327)
|
||||
- Backends: Win32: Fix _WIN32_WINNT < 0x0600 (MinGW defaults to 0x502 == Windows 2003). (#3183)
|
||||
- Backends: SDL: Report a zero display-size when window is minimized, consistent with other backends,
|
||||
@ -531,7 +626,7 @@ Other Changes:
|
||||
because it needs application to be linked with '-framework ApplicationServices'. It can be explicitly
|
||||
enabled back by using '#define IMGUI_ENABLE_OSX_DEFAULT_CLIPBOARD_FUNCTIONS' in imconfig.h. Re-added
|
||||
equivalent using NSPasteboard api in the imgui_impl_osx.mm experimental back-end. (#2546)
|
||||
- Backends: SDL2: Added dummy ImGui_ImplSDL2_InitForD3D() function to make D3D support more visible.
|
||||
- Backends: SDL2: Added ImGui_ImplSDL2_InitForD3D() function to make D3D support more visible.
|
||||
(#2482, #2632) [@josiahmanson]
|
||||
- Examples: Added SDL2+DirectX11 example application. (#2632, #2612, #2482) [@vincenthamm]
|
||||
|
||||
@ -691,7 +786,7 @@ Other Changes:
|
||||
- Misc: Made IMGUI_CHECKVERSION() macro also check for matching size of ImDrawIdx.
|
||||
- Metrics: Added "Show windows rectangles" tool to visualize the different rectangles.
|
||||
- Demo: Improved trees in columns demo.
|
||||
- Examples: OpenGL: Added a dummy GL call + comments in ImGui_ImplOpenGL3_Init() to detect uninitialized
|
||||
- Examples: OpenGL: Added a test GL call + comments in ImGui_ImplOpenGL3_Init() to detect uninitialized
|
||||
GL function loaders early, and help users understand what they are missing. (#2421)
|
||||
- Examples: SDL: Added support for SDL_GameController gamepads (enable with ImGuiConfigFlags_NavEnableGamepad). (#2509) [@DJLink]
|
||||
- Examples: Emscripten: Added Emscripten+SDL+GLES2 example. (#2494, #2492, #2351, #336) [@nicolasnoble, @redblobgames]
|
||||
@ -799,7 +894,7 @@ Breaking Changes:
|
||||
|
||||
- Removed io.DisplayVisibleMin/DisplayVisibleMax (which were marked obsolete and removed from viewport/docking branch already).
|
||||
- Made it illegal/assert when io.DisplayTime == 0.0f (with an exception for the first frame).
|
||||
If for some reason your time step calculation gives you a zero value, replace it with a dummy small value!
|
||||
If for some reason your time step calculation gives you a zero value, replace it with a arbitrary small value!
|
||||
|
||||
Other Changes:
|
||||
|
||||
@ -1290,7 +1385,7 @@ Other Changes:
|
||||
- ColorEdit: Fixed not being able to pass the ImGuiColorEditFlags_NoAlpha or ImGuiColorEditFlags_HDR flags to SetColorEditOptions().
|
||||
- Nav: Fixed hovering a Selectable() with the mouse so that it update the navigation cursor (as it happened in the pre-1.60 navigation branch). (#787)
|
||||
- Style: Changed default style.DisplaySafeAreaPadding values from (4,4) to (3,3) so it is smaller than FramePadding and has no effect on main menu bar on a computer. (#1439)
|
||||
- Fonts: When building font atlas, glyphs that are missing in the fonts are not using the glyph slot to render a dummy/default glyph. Saves space and allow merging fonts with
|
||||
- Fonts: When building font atlas, glyphs that are missing in the fonts are not using the glyph slot to render the default glyph. Saves space and allow merging fonts with
|
||||
overlapping font ranges such as FontAwesome5 which split out the Brands separately from the Solid fonts. (#1703, #1671)
|
||||
- Misc: Added IMGUI_CHECKVERSION() macro to compare version string and data structure sizes in order to catch issues with mismatching compilation unit settings. (#1695, #1769)
|
||||
- Misc: Added IMGUI_DISABLE_MATH_FUNCTIONS in imconfig.h to make it easier to redefine wrappers for std/crt math functions.
|
||||
|
@ -453,7 +453,7 @@ ImGui::End();
|
||||
- To generate colors: you can use the macro `IM_COL32(255,255,255,255)` to generate them at compile time, or use `ImGui::GetColorU32(IM_COL32(255,255,255,255))` or `ImGui::GetColorU32(ImVec4(1.0f,1.0f,1.0f,1.0f))` to generate a color that is multiplied by the current value of `style.Alpha`.
|
||||
- Math operators: if you have setup `IM_VEC2_CLASS_EXTRA` in `imconfig.h` to bind your own math types, you can use your own math types and their natural operators instead of ImVec2. ImVec2 by default doesn't export any math operators in the public API. You may use `#define IMGUI_DEFINE_MATH_OPERATORS` `#include "imgui_internal.h"` to use the internally defined math operators, but instead prefer using your own math library and set it up in `imconfig.h`.
|
||||
- You can use `ImGui::GetBackgroundDrawList()` or `ImGui::GetForegroundDrawList()` to access draw lists which will be displayed behind and over every other dear imgui windows (one bg/fg drawlist per viewport). This is very convenient if you need to quickly display something on the screen that is not associated to a dear imgui window.
|
||||
- You can also create your own dummy window and draw inside it. Call Begin() with the NoBackground | NoDecoration | NoSavedSettings | NoInputs flags (The `ImGuiWindowFlags_NoDecoration` flag itself is a shortcut for NoTitleBar | NoResize | NoScrollbar | NoCollapse). Then you can retrieve the ImDrawList* via GetWindowDrawList() and draw to it in any way you like.
|
||||
- You can also create your own empty window and draw inside it. Call Begin() with the NoBackground | NoDecoration | NoSavedSettings | NoInputs flags (The `ImGuiWindowFlags_NoDecoration` flag itself is a shortcut for NoTitleBar | NoResize | NoScrollbar | NoCollapse). Then you can retrieve the ImDrawList* via GetWindowDrawList() and draw to it in any way you like.
|
||||
- You can create your own ImDrawList instance. You'll need to initialize them with `ImGui::GetDrawListSharedData()`, or create your own instancing ImDrawListSharedData, and then call your renderer function with your own ImDrawList or ImDrawData data.
|
||||
|
||||
##### [Return to Index](#index)
|
||||
|
@ -1,6 +1,7 @@
|
||||
Dear ImGui
|
||||
=====
|
||||
[](https://github.com/ocornut/imgui/actions?workflow=build)
|
||||
[](https://github.com/ocornut/imgui/actions?workflow=build) [](https://github.com/ocornut/imgui/actions?workflow=static-analysis)
|
||||
|
||||
|
||||
<sub>(This library is available under a free and permissive license, but needs financial support to sustain its continued improvements. In addition to maintenance and stability there are many desirable features yet to be added. If your company is using Dear ImGui, please consider reaching out.)</sub>
|
||||
|
||||
@ -97,7 +98,7 @@ Calling the `ImGui::ShowDemoWindow()` function will create a demo window showcas
|
||||

|
||||
|
||||
You should be able to build the examples from sources (tested on Windows/Mac/Linux). 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-20190715.zip](http://www.dearimgui.org/binaries/imgui-demo-binaries-20200412.zip) (Windows binaries, 1.76, built 2020/04/12, master branch) or [older demo binaries](http://www.dearimgui.org/binaries).
|
||||
- [imgui-demo-binaries-20200412.zip](http://www.dearimgui.org/binaries/imgui-demo-binaries-20200412.zip) (Windows, 1.76, built 2020/04/12, master branch) or [older demo binaries](http://www.dearimgui.org/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 different scale, and scale your style with `style.ScaleAllSizes()` (see [FAQ](https://www.dearimgui.org/faq)).
|
||||
|
||||
@ -113,8 +114,8 @@ Officially maintained bindings (in repository):
|
||||
- Frameworks: Emscripten, Allegro5, Marmalade.
|
||||
|
||||
Third-party bindings (see [Bindings](https://github.com/ocornut/imgui/wiki/Bindings/) page):
|
||||
- Languages: C, C#/.Net, ChaiScript, D, Go, Haskell, Haxe/hxcpp, Java, JavaScript, Julia, Kotlin, Lua, Odin, Pascal, PureBasic, Python, Ruby, Rust, Swift...
|
||||
- Frameworks: AGS/Adventure Game Studio, Amethyst, bsf, Cinder, Cocos2d-x, Diligent Engine, Flexium, GML/Game Maker Studio2, GTK3+OpenGL3, Irrlicht Engine, LÖVE+LUA, Magnum, NanoRT, Nim Game Lib, Ogre, openFrameworks, OSG/OpenSceneGraph, Orx, Photoshop, px_render, Qt/QtDirect3D, SFML, Sokol, Unity, Unreal Engine 4, vtk, Win32 GDI, WxWidgets.
|
||||
- Languages: C, C# and: Beef, ChaiScript, D, Go, Haskell, Haxe/hxcpp, Java, JavaScript, Julia, Kotlin, Lua, Odin, Pascal, PureBasic, Python, Ruby, Rust, Swift...
|
||||
- Frameworks: AGS/Adventure Game Studio, Amethyst, bsf, Cinder, Cocos2d-x, Diligent Engine, Flexium, GML/Game Maker Studio2, Godot, GTK3+OpenGL3, Irrlicht Engine, LÖVE+LUA, Magnum, NanoRT, Nim Game Lib, Ogre, openFrameworks, OSG/OpenSceneGraph, Orx, Photoshop, px_render, Qt/QtDirect3D, SFML, Sokol, Unity, Unreal Engine 4, vtk, Win32 GDI, WxWidgets.
|
||||
- Note that C bindings ([cimgui](https://github.com/cimgui/cimgui)) are auto-generated, you can use its json/lua output to generate bindings for other languages.
|
||||
|
||||
Also see [Wiki](https://github.com/ocornut/imgui/wiki) for more links and ideas.
|
||||
@ -125,7 +126,7 @@ Some of the goals for 2020 are:
|
||||
- Work on docking. (see [#2109](https://github.com/ocornut/imgui/issues/2109), in public [docking](https://github.com/ocornut/imgui/tree/docking) branch)
|
||||
- Work on multiple viewports / multiple OS windows. (see [#1542](https://github.com/ocornut/imgui/issues/1542), in public [docking](https://github.com/ocornut/imgui/tree/docking) branch looking for feedback)
|
||||
- Work on gamepad/keyboard controls. (see [#787](https://github.com/ocornut/imgui/issues/787))
|
||||
- Work on new Tables API (to replace Columns). (see [#2957](https://github.com/ocornut/imgui/issues/2957))
|
||||
- Work on new Tables API (to replace Columns). (see [#2957](https://github.com/ocornut/imgui/issues/2957), in public [tables](https://github.com/ocornut/imgui/tree/tables) branch looking for feedback)
|
||||
- Work on automation and testing system, both to test the library and end-user apps. (see [#435](https://github.com/ocornut/imgui/issues/435))
|
||||
- Make the examples look better, improve styles, improve font support, make the examples hi-DPI and multi-DPI aware.
|
||||
|
||||
@ -144,7 +145,7 @@ Custom engine
|
||||
|
||||
### Support, Frequently Asked Questions (FAQ)
|
||||
|
||||
Most common questions will be answered by the [Frequently Asked Questions (FAQ)](https://github.com/ocornut/imgui/blob/master/docs/FAQ.md) page.
|
||||
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.
|
||||
|
||||
@ -160,7 +161,7 @@ Private support is available for paying business customers (E-mail: _contact @ d
|
||||
|
||||
We occasionally tag [Releases](https://github.com/ocornut/imgui/releases) 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.
|
||||
|
||||
You may also peak at the [Multi-Viewport](https://github.com/ocornut/imgui/issues/1542) and [Docking](https://github.com/ocornut/imgui/issues/2109) features in the `docking` branch. Many projects are using this branch and it is kept in sync with master regularly.
|
||||
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?**
|
||||
|
||||
@ -219,7 +220,7 @@ Embeds [ProggyClean.ttf](http://upperbounds.net) font by Tristan Grimmer (MIT li
|
||||
|
||||
Embeds [stb_textedit.h, stb_truetype.h, stb_rect_pack.h](https://github.com/nothings/stb/) by Sean Barrett (public domain).
|
||||
|
||||
Inspiration, feedback, and testing for early versions: Casey Muratori, Atman Binstock, Mikko Mononen, Emmanuel Briney, Stefan Kamoda, Anton Mikhailov, Matt Willis. And everybody posting feedback, questions and patches on the GitHub.
|
||||
Inspiration, feedback, and testing for early versions: Casey Muratori, Atman Binstock, Mikko Mononen, Emmanuel Briney, Stefan Kamoda, Anton Mikhailov, Matt Willis. Also thank you to everyone posting feedback, questions and patches on GitHub.
|
||||
|
||||
License
|
||||
-------
|
||||
|
@ -161,6 +161,7 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i
|
||||
- dock: merge docking branch (#2109)
|
||||
- dock: dock out from a collapsing header? would work nicely but need emitting window to keep submitting the code.
|
||||
|
||||
- tabs: while dragging/reordering a tab, close button decoration shouldn't appear on other tabs
|
||||
- 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()?
|
||||
@ -180,7 +181,7 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i
|
||||
- slider: step option (#1183)
|
||||
- slider style: fill % of the bar instead of positioning a drag.
|
||||
- knob: rotating knob widget (#942)
|
||||
- drag float: power/logarithmic slider and drags are weird. (#1316)
|
||||
- drag float: support for reversed drags (min > max) (removed is_locked, also see fdc526e)
|
||||
- drag float: up/down axis
|
||||
- drag float: power != 0.0f with current value being outside the range keeps the value stuck.
|
||||
- drag float: added leeway on edge (e.g. a few invisible steps past the clamp limits)
|
||||
@ -207,6 +208,7 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i
|
||||
- popups: clicking outside (to close popup) and holding shouldn't drag window below.
|
||||
- popups: add variant using global identifier similar to Begin/End (#402)
|
||||
- popups: border options. richer api like BeginChild() perhaps? (#197)
|
||||
- popups: flags could be reworked to allow both mouse buttons as index (0..5 and as flags using higher-bit) allowing to or them.
|
||||
- popups/modals: although it is sometimes convenient that popups/modals lifetime is owned by imgui, we could also a bool-owned-by-user api as long as Begin() return value testing is enforced.
|
||||
|
||||
- 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.
|
||||
@ -308,7 +310,8 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i
|
||||
- font/atlas: dynamic font atlas to avoid baking huge ranges into bitmap and make scaling easier.
|
||||
- font/draw: vertical and/or rotated text renderer (#705) - vertical is easier clipping wise
|
||||
- font/draw: need to be able to specify wrap start position.
|
||||
- font/draw: better reserve policy for large horizontal block of text (shouldn't reserve for all clipped lines)
|
||||
- font/draw: better reserve policy for large horizontal block of text (shouldn't reserve for all clipped lines). also see #3349.
|
||||
- font/draw: fix for drawing 16k+ visible characters in same call.
|
||||
- font/draw: underline, squiggle line rendering helpers.
|
||||
- font: optimization: for monospace font (like the default one) we can trim IndexXAdvance as long as trailing value is == FallbackXAdvance (need to make sure TAB is still correct), would save on cache line.
|
||||
- font: add support for kerning, probably optional. A) perhaps default to (32..128)^2 matrix ~ 9K entries = 36KB, then hash for non-ascii?. B) or sparse lookup into per-char list?
|
||||
@ -363,7 +366,6 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i
|
||||
- misc: idle: if cursor blink if the _only_ visible animation, could even expose a dirty rectangle that optionally can be leverage by some app to render in a smaller viewport, getting rid of much pixel shading cost.
|
||||
- misc: no way to run a root-most GetID() with ImGui:: api since there's always a Debug window in the stack. (mentioned in #2960)
|
||||
- misc: make the ImGuiCond values linear (non-power-of-two). internal storage for ImGuiWindow can use integers to combine into flags (Why?)
|
||||
- misc: provide a way to compile out the entire implementation while providing a dummy API (e.g. #define IMGUI_DUMMY_IMPL)
|
||||
- misc: PushItemFlag(): add a flag to disable keyboard capture when used with mouse? (#1682)
|
||||
- misc: use more size_t in public api?
|
||||
- misc: possible compile-time support for string view/range instead of char* would e.g. facilitate usage with Rust (#683)
|
||||
@ -392,6 +394,8 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i
|
||||
- backends: bgfx: https://gist.github.com/RichardGale/6e2b74bc42b3005e08397236e4be0fd0
|
||||
- backends: mscriptem: with refactored examples, we could provide a direct imgui_impl_emscripten platform layer (see eg. https://github.com/floooh/sokol-samples/blob/master/html5/imgui-emsc.cc#L42)
|
||||
|
||||
- bindings: ways to use clang ast dump to generate bindings or helpers for bindings? (e.g. clang++ -Xclang -ast-dump=json imgui.h)
|
||||
|
||||
- optimization: replace vsnprintf with stb_printf? using IMGUI_USE_STB_SPRINTF.(#1038)
|
||||
- optimization: add clipping for multi-component widgets (SliderFloatX, ColorEditX, etc.). one problem is that nav branch can't easily clip parent group when there is a move request.
|
||||
- optimization: add a flag to disable most of rendering, for the case where the user expect to skip it (#335)
|
||||
|
@ -1,5 +1,5 @@
|
||||
-----------------------------------------------------------------------
|
||||
dear imgui, v1.77
|
||||
dear imgui, v1.78
|
||||
-----------------------------------------------------------------------
|
||||
examples/README.txt
|
||||
(This is the README file for the examples/ folder. See docs/ for more documentation)
|
||||
@ -204,7 +204,7 @@ example_glfw_opengl2/
|
||||
GLFW + OpenGL2 example (legacy, fixed pipeline).
|
||||
= main.cpp + imgui_impl_glfw.cpp + imgui_impl_opengl2.cpp
|
||||
**DO NOT USE OPENGL2 CODE IF YOUR CODE/ENGINE IS USING MODERN OPENGL (SHADERS, VBO, VAO, etc.)**
|
||||
**Prefer using OPENGL3 code (with gl3w/glew/glad/glbinding, you can replace the OpenGL function loader)**
|
||||
**Prefer using OPENGL3 code (with gl3w/glew/glad/glad2/glbinding, you can replace the OpenGL function loader)**
|
||||
This code is mostly provided as a reference to learn about Dear ImGui integration, because it is shorter.
|
||||
If your code is using GL3+ context or any semi modern OpenGL calls, using this renderer is likely to
|
||||
make things more complicated, will require your code to reset many OpenGL attributes to their initial
|
||||
@ -253,7 +253,7 @@ example_sdl_opengl2/
|
||||
SDL2 (Win32, Mac, Linux etc.) + OpenGL example (legacy, fixed pipeline).
|
||||
= main.cpp + imgui_impl_sdl.cpp + imgui_impl_opengl2.cpp
|
||||
**DO NOT USE OPENGL2 CODE IF YOUR CODE/ENGINE IS USING MODERN OPENGL (SHADERS, VBO, VAO, etc.)**
|
||||
**Prefer using OPENGL3 code (with gl3w/glew/glad/glbinding, you can replace the OpenGL function loader)**
|
||||
**Prefer using OPENGL3 code (with gl3w/glew/glad/glad2/glbinding, you can replace the OpenGL function loader)**
|
||||
This code is mostly provided as a reference to learn about Dear ImGui integration, because it is shorter.
|
||||
If your code is using GL3+ context or any semi modern OpenGL calls, using this renderer is likely to
|
||||
make things more complicated, will require your code to reset many OpenGL attributes to their initial
|
||||
|
@ -19,7 +19,7 @@
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{2AE17FDE-F7F3-4CAC-ADAB-0710EDA4F741}</ProjectGuid>
|
||||
<ProjectGuid>{73F235B5-7D31-4FC6-8682-DDC5A097B9C1}</ProjectGuid>
|
||||
<RootNamespace>example_allegro5</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
|
@ -1,12 +1,20 @@
|
||||
|
||||
# How to Build
|
||||
## How to Build
|
||||
|
||||
- You need to install Emscripten from https://emscripten.org/docs/getting_started/downloads.html, and have the environment variables set, as described in https://emscripten.org/docs/getting_started/downloads.html#installation-instructions
|
||||
|
||||
- You may also refer to our [Continuous Integration setup](https://github.com/ocornut/imgui/tree/master/.github/workflows) for Emscripten setup.
|
||||
- Depending on your configuration, in Windows you may need to run `emsdk/emsdk_env.bat` in your console to access the Emscripten command-line tools.
|
||||
|
||||
- Then build using `make` while in the `example_emscripten/` directory.
|
||||
|
||||
- Note that Emscripten 1.39.0 (October 2019) obsoleted the `BINARYEN_TRAP_MODE=clamp` compilation flag which was required with version older than 1.39.0 to avoid rendering artefacts. See [#2877](https://github.com/ocornut/imgui/issues/2877) for details. If you use an older version, uncomment this line in the Makefile:
|
||||
## How to Run
|
||||
|
||||
`#EMS += -s BINARYEN_TRAP_MODE=clamp`
|
||||
To run on a local machine:
|
||||
- Generally you may need a local webserver. Quoting [https://emscripten.org/docs/getting_started](https://emscripten.org/docs/getting_started/Tutorial.html#generating-html):<br>
|
||||
_"Unfortunately several browsers (including Chrome, Safari, and Internet Explorer) do not support file:// [XHR](https://emscripten.org/docs/site/glossary.html#term-xhr) requests, and can’t load extra files needed by the HTML (like a .wasm file, or packaged file data as mentioned lower down). For these browsers you’ll need to serve the files using a [local webserver](https://emscripten.org/docs/getting_started/FAQ.html#faq-local-webserver) and then open http://localhost:8000/hello.html."_
|
||||
- Emscripten SDK has a handy `emrun` command: `emrun example_emscripten.html` which will spawn a temporary local webserver. See https://emscripten.org/docs/compiling/Running-html-files-with-emrun.html for details.
|
||||
- Otherwise you may use Python builtin webserver: `python -m http.server` in Python 3 or `python -m SimpleHTTPServer` in Python 2. After doing that, you can visit http://localhost:8000/.
|
||||
|
||||
## Obsolete features:
|
||||
|
||||
- Emscripten 2.0 (August 2020) obsoleted the fastcomp back-end, only llvm is supported.
|
||||
- Emscripten 1.39.0 (October 2019) obsoleted the `BINARYEN_TRAP_MODE=clamp` compilation flag which was required with version older than 1.39.0 to avoid rendering artefacts. See [#2877](https://github.com/ocornut/imgui/issues/2877) for details. If you use an older version, uncomment this line in the Makefile: `#EMS += -s BINARYEN_TRAP_MODE=clamp`
|
||||
|
@ -42,6 +42,10 @@ CXXFLAGS += -I../libs/gl3w -DIMGUI_IMPL_OPENGL_LOADER_GL3W
|
||||
# SOURCES += ../libs/glad/src/glad.c
|
||||
# CXXFLAGS += -I../libs/glad/include -DIMGUI_IMPL_OPENGL_LOADER_GLAD
|
||||
|
||||
## Using OpenGL loader: glad2
|
||||
# SOURCES += ../libs/glad/src/gl.c
|
||||
# CXXFLAGS += -I../libs/glad/include -DIMGUI_IMPL_OPENGL_LOADER_GLAD2
|
||||
|
||||
## Using OpenGL loader: glbinding
|
||||
## This assumes a system-wide installation
|
||||
## of either version 3.0.0 (or newer)
|
||||
|
@ -17,6 +17,8 @@
|
||||
#include <GL/glew.h> // Initialize with glewInit()
|
||||
#elif defined(IMGUI_IMPL_OPENGL_LOADER_GLAD)
|
||||
#include <glad/glad.h> // Initialize with gladLoadGL()
|
||||
#elif defined(IMGUI_IMPL_OPENGL_LOADER_GLAD2)
|
||||
#include <glad/gl.h> // Initialize with gladLoadGL(...) or gladLoaderLoadGL()
|
||||
#elif defined(IMGUI_IMPL_OPENGL_LOADER_GLBINDING2)
|
||||
#define GLFW_INCLUDE_NONE // GLFW including OpenGL headers causes ambiguity or multiple definition errors.
|
||||
#include <glbinding/Binding.h> // Initialize with glbinding::Binding::initialize()
|
||||
@ -84,6 +86,8 @@ int main(int, char**)
|
||||
bool err = glewInit() != GLEW_OK;
|
||||
#elif defined(IMGUI_IMPL_OPENGL_LOADER_GLAD)
|
||||
bool err = gladLoadGL() == 0;
|
||||
#elif defined(IMGUI_IMPL_OPENGL_LOADER_GLAD2)
|
||||
bool err = gladLoadGL(glfwGetProcAddress) == 0; // glad2 recommend using the windowing library loader instead of the (optionally) bundled one.
|
||||
#elif defined(IMGUI_IMPL_OPENGL_LOADER_GLBINDING2)
|
||||
bool err = false;
|
||||
glbinding::Binding::initialize();
|
||||
|
@ -513,6 +513,7 @@ int main(int, char**)
|
||||
const bool is_minimized = (draw_data->DisplaySize.x <= 0.0f || draw_data->DisplaySize.y <= 0.0f);
|
||||
if (!is_minimized)
|
||||
{
|
||||
memcpy(&wd->ClearValue.color.float32[0], &clear_color, 4 * sizeof(float));
|
||||
FrameRender(wd, draw_data);
|
||||
FramePresent(wd);
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
// dear imgui: null/dummy example application
|
||||
// dear imgui: "null" example application
|
||||
// (compile and link imgui, create context, run headless with NO INPUTS, NO GRAPHICS OUTPUT)
|
||||
// This is useful to test building, but you cannot interact with anything here!
|
||||
#include "imgui.h"
|
||||
|
@ -42,6 +42,10 @@ CXXFLAGS += -I../libs/gl3w -DIMGUI_IMPL_OPENGL_LOADER_GL3W
|
||||
# SOURCES += ../libs/glad/src/glad.c
|
||||
# CXXFLAGS += -I../libs/glad/include -DIMGUI_IMPL_OPENGL_LOADER_GLAD
|
||||
|
||||
## Using OpenGL loader: glad2
|
||||
# SOURCES += ../libs/glad/src/gl.c
|
||||
# CXXFLAGS += -I../libs/glad/include -DIMGUI_IMPL_OPENGL_LOADER_GLAD2
|
||||
|
||||
## Using OpenGL loader: glbinding
|
||||
## This assumes a system-wide installation
|
||||
## of either version 3.0.0 (or newer)
|
||||
|
@ -19,6 +19,8 @@
|
||||
#include <GL/glew.h> // Initialize with glewInit()
|
||||
#elif defined(IMGUI_IMPL_OPENGL_LOADER_GLAD)
|
||||
#include <glad/glad.h> // Initialize with gladLoadGL()
|
||||
#elif defined(IMGUI_IMPL_OPENGL_LOADER_GLAD2)
|
||||
#include <glad/gl.h> // Initialize with gladLoadGL(...) or gladLoaderLoadGL()
|
||||
#elif defined(IMGUI_IMPL_OPENGL_LOADER_GLBINDING2)
|
||||
#define GLFW_INCLUDE_NONE // GLFW including OpenGL headers causes ambiguity or multiple definition errors.
|
||||
#include <glbinding/Binding.h> // Initialize with glbinding::Binding::initialize()
|
||||
@ -79,6 +81,8 @@ int main(int, char**)
|
||||
bool err = glewInit() != GLEW_OK;
|
||||
#elif defined(IMGUI_IMPL_OPENGL_LOADER_GLAD)
|
||||
bool err = gladLoadGL() == 0;
|
||||
#elif defined(IMGUI_IMPL_OPENGL_LOADER_GLAD2)
|
||||
bool err = gladLoadGL((GLADloadfunc)SDL_GL_GetProcAddress) == 0; // glad2 recommend using the windowing library loader instead of the (optionally) bundled one.
|
||||
#elif defined(IMGUI_IMPL_OPENGL_LOADER_GLBINDING2)
|
||||
bool err = false;
|
||||
glbinding::Binding::initialize();
|
||||
|
@ -513,6 +513,7 @@ int main(int, char**)
|
||||
const bool is_minimized = (draw_data->DisplaySize.x <= 0.0f || draw_data->DisplaySize.y <= 0.0f);
|
||||
if (!is_minimized)
|
||||
{
|
||||
memcpy(&wd->ClearValue.color.float32[0], &clear_color, 4 * sizeof(float));
|
||||
FrameRender(wd, draw_data);
|
||||
FramePresent(wd);
|
||||
}
|
||||
|
@ -26,6 +26,7 @@ LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
|
||||
int main(int, char**)
|
||||
{
|
||||
// Create application window
|
||||
//ImGui_ImplWin32_EnableDpiAwareness();
|
||||
WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, WndProc, 0L, 0L, GetModuleHandle(NULL), NULL, NULL, NULL, NULL, _T("ImGui Example"), NULL };
|
||||
::RegisterClassEx(&wc);
|
||||
HWND hwnd = ::CreateWindow(wc.lpszClassName, _T("Dear ImGui DirectX10 Example"), WS_OVERLAPPEDWINDOW, 100, 100, 1280, 800, NULL, NULL, wc.hInstance, NULL);
|
||||
|
@ -26,6 +26,7 @@ LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
|
||||
int main(int, char**)
|
||||
{
|
||||
// Create application window
|
||||
//ImGui_ImplWin32_EnableDpiAwareness();
|
||||
WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, WndProc, 0L, 0L, GetModuleHandle(NULL), NULL, NULL, NULL, NULL, _T("ImGui Example"), NULL };
|
||||
::RegisterClassEx(&wc);
|
||||
HWND hwnd = ::CreateWindow(wc.lpszClassName, _T("Dear ImGui DirectX11 Example"), WS_OVERLAPPEDWINDOW, 100, 100, 1280, 800, NULL, NULL, wc.hInstance, NULL);
|
||||
|
@ -57,6 +57,7 @@ LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
|
||||
int main(int, char**)
|
||||
{
|
||||
// Create application window
|
||||
//ImGui_ImplWin32_EnableDpiAwareness();
|
||||
WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, WndProc, 0L, 0L, GetModuleHandle(NULL), NULL, NULL, NULL, NULL, _T("ImGui Example"), NULL };
|
||||
::RegisterClassEx(&wc);
|
||||
HWND hwnd = ::CreateWindow(wc.lpszClassName, _T("Dear ImGui DirectX12 Example"), WS_OVERLAPPEDWINDOW, 100, 100, 1280, 800, NULL, NULL, wc.hInstance, NULL);
|
||||
|
@ -24,6 +24,7 @@ LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
|
||||
int main(int, char**)
|
||||
{
|
||||
// Create application window
|
||||
//ImGui_ImplWin32_EnableDpiAwareness();
|
||||
WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, WndProc, 0L, 0L, GetModuleHandle(NULL), NULL, NULL, NULL, NULL, _T("ImGui Example"), NULL };
|
||||
::RegisterClassEx(&wc);
|
||||
HWND hwnd = ::CreateWindow(wc.lpszClassName, _T("Dear ImGui DirectX9 Example"), WS_OVERLAPPEDWINDOW, 100, 100, 1280, 800, NULL, NULL, wc.hInstance, NULL);
|
||||
|
@ -15,6 +15,7 @@
|
||||
|
||||
// CHANGELOG
|
||||
// (minor and older changes stripped away, please see git history for details)
|
||||
// 2020-08-10: Inputs: Fixed horizontal mouse wheel direction.
|
||||
// 2019-12-05: Inputs: Added support for ImGuiMouseCursor_NotAllowed mouse cursor.
|
||||
// 2019-07-21: Inputs: Added mapping for ImGuiKey_KeyPadEnter.
|
||||
// 2019-05-11: Inputs: Don't filter character value from ALLEGRO_EVENT_KEY_CHAR before calling AddInputCharacter().
|
||||
@ -332,7 +333,7 @@ bool ImGui_ImplAllegro5_ProcessEvent(ALLEGRO_EVENT *ev)
|
||||
if (ev->mouse.display == g_Display)
|
||||
{
|
||||
io.MouseWheel += ev->mouse.dz;
|
||||
io.MouseWheelH += ev->mouse.dw;
|
||||
io.MouseWheelH -= ev->mouse.dw;
|
||||
io.MousePos = ImVec2(ev->mouse.x, ev->mouse.y);
|
||||
}
|
||||
return true;
|
||||
|
@ -509,7 +509,8 @@ bool ImGui_ImplDX12_CreateDeviceObjects()
|
||||
psoDesc.VS = { vertexShaderBlob->GetBufferPointer(), vertexShaderBlob->GetBufferSize() };
|
||||
|
||||
// Create the input layout
|
||||
static D3D12_INPUT_ELEMENT_DESC local_layout[] = {
|
||||
static D3D12_INPUT_ELEMENT_DESC local_layout[] =
|
||||
{
|
||||
{ "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, (UINT)IM_OFFSETOF(ImDrawVert, pos), D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 },
|
||||
{ "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, (UINT)IM_OFFSETOF(ImDrawVert, uv), D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 },
|
||||
{ "COLOR", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, (UINT)IM_OFFSETOF(ImDrawVert, col), D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 },
|
||||
|
@ -13,6 +13,7 @@
|
||||
|
||||
// CHANGELOG
|
||||
// (minor and older changes stripped away, please see git history for details)
|
||||
// 2020-07-10: OpenGL: Added support for glad2 OpenGL loader.
|
||||
// 2020-05-08: OpenGL: Made default GLSL version 150 (instead of 130) on OSX.
|
||||
// 2020-04-21: OpenGL: Fixed handling of glClipControl(GL_UPPER_LEFT) by inverting projection matrix.
|
||||
// 2020-04-12: OpenGL: Fixed context version check mistakenly testing for 4.0+ instead of 3.2+ to enable ImGuiBackendFlags_RendererHasVtxOffset.
|
||||
@ -24,7 +25,7 @@
|
||||
// 2019-05-29: OpenGL: Desktop GL only: Added support for large mesh (64K+ vertices), enable ImGuiBackendFlags_RendererHasVtxOffset flag.
|
||||
// 2019-04-30: OpenGL: Added support for special ImDrawCallback_ResetRenderState callback to reset render state.
|
||||
// 2019-03-29: OpenGL: Not calling glBindBuffer more than necessary in the render loop.
|
||||
// 2019-03-15: OpenGL: Added a dummy GL call + comments in ImGui_ImplOpenGL3_Init() to detect uninitialized GL function loaders early.
|
||||
// 2019-03-15: OpenGL: Added a GL call + comments in ImGui_ImplOpenGL3_Init() to detect uninitialized GL function loaders early.
|
||||
// 2019-03-03: OpenGL: Fix support for ES 2.0 (WebGL 1.0).
|
||||
// 2019-02-20: OpenGL: Fix for OSX not supporting OpenGL 4.5, we don't try to read GL_CLIP_ORIGIN even if defined by the headers/loader.
|
||||
// 2019-02-11: OpenGL: Projecting clipping rectangles correctly using draw_data->FramebufferScale to allow multi-viewports for retina display.
|
||||
@ -101,6 +102,8 @@
|
||||
#include <GL/glew.h> // Needs to be initialized with glewInit() in user's code.
|
||||
#elif defined(IMGUI_IMPL_OPENGL_LOADER_GLAD)
|
||||
#include <glad/glad.h> // Needs to be initialized with gladLoadGL() in user's code.
|
||||
#elif defined(IMGUI_IMPL_OPENGL_LOADER_GLAD2)
|
||||
#include <glad/gl.h> // Needs to be initialized with gladLoadGL(...) or gladLoaderLoadGL() in user's code.
|
||||
#elif defined(IMGUI_IMPL_OPENGL_LOADER_GLBINDING2)
|
||||
#ifndef GLFW_INCLUDE_NONE
|
||||
#define GLFW_INCLUDE_NONE // GLFW including OpenGL headers causes ambiguity or multiple definition errors.
|
||||
@ -176,7 +179,7 @@ bool ImGui_ImplOpenGL3_Init(const char* glsl_version)
|
||||
strcpy(g_GlslVersionString, glsl_version);
|
||||
strcat(g_GlslVersionString, "\n");
|
||||
|
||||
// Dummy construct to make it easily visible in the IDE and debugger which GL loader has been selected.
|
||||
// Debugging construct to make it easily visible in the IDE and debugger which GL loader has been selected.
|
||||
// The code actually never uses the 'gl_loader' variable! It is only here so you can read it!
|
||||
// If auto-detection fails or doesn't select the same GL loader file as used by your application,
|
||||
// you are likely to get a crash below.
|
||||
@ -189,6 +192,8 @@ bool ImGui_ImplOpenGL3_Init(const char* glsl_version)
|
||||
gl_loader = "GLEW";
|
||||
#elif defined(IMGUI_IMPL_OPENGL_LOADER_GLAD)
|
||||
gl_loader = "GLAD";
|
||||
#elif defined(IMGUI_IMPL_OPENGL_LOADER_GLAD2)
|
||||
gl_loader = "GLAD2";
|
||||
#elif defined(IMGUI_IMPL_OPENGL_LOADER_GLBINDING2)
|
||||
gl_loader = "glbinding2";
|
||||
#elif defined(IMGUI_IMPL_OPENGL_LOADER_GLBINDING3)
|
||||
@ -199,7 +204,7 @@ bool ImGui_ImplOpenGL3_Init(const char* glsl_version)
|
||||
gl_loader = "none";
|
||||
#endif
|
||||
|
||||
// Make a dummy GL call (we don't actually need the result)
|
||||
// Make an arbitrary GL call (we don't actually need the result)
|
||||
// IF YOU GET A CRASH HERE: it probably means that you haven't initialized the OpenGL function loader used by this code.
|
||||
// Desktop OpenGL 3/4 need a function loader. See the IMGUI_IMPL_OPENGL_LOADER_xxx explanation above.
|
||||
GLint current_texture;
|
||||
|
@ -49,6 +49,7 @@ IMGUI_IMPL_API void ImGui_ImplOpenGL3_DestroyDeviceObjects();
|
||||
&& !defined(IMGUI_IMPL_OPENGL_LOADER_GL3W) \
|
||||
&& !defined(IMGUI_IMPL_OPENGL_LOADER_GLEW) \
|
||||
&& !defined(IMGUI_IMPL_OPENGL_LOADER_GLAD) \
|
||||
&& !defined(IMGUI_IMPL_OPENGL_LOADER_GLAD2) \
|
||||
&& !defined(IMGUI_IMPL_OPENGL_LOADER_GLBINDING2) \
|
||||
&& !defined(IMGUI_IMPL_OPENGL_LOADER_GLBINDING3) \
|
||||
&& !defined(IMGUI_IMPL_OPENGL_LOADER_CUSTOM)
|
||||
@ -68,6 +69,8 @@ IMGUI_IMPL_API void ImGui_ImplOpenGL3_DestroyDeviceObjects();
|
||||
#define IMGUI_IMPL_OPENGL_LOADER_GLEW
|
||||
#elif __has_include(<glad/glad.h>)
|
||||
#define IMGUI_IMPL_OPENGL_LOADER_GLAD
|
||||
#elif __has_include(<glad/gl.h>)
|
||||
#define IMGUI_IMPL_OPENGL_LOADER_GLAD2
|
||||
#elif __has_include(<GL/gl3w.h>)
|
||||
#define IMGUI_IMPL_OPENGL_LOADER_GL3W
|
||||
#elif __has_include(<glbinding/glbinding.h>)
|
||||
|
268
imgui.cpp
268
imgui.cpp
@ -1,4 +1,4 @@
|
||||
// dear imgui, v1.77
|
||||
// dear imgui, v1.78
|
||||
// (main code and documentation)
|
||||
|
||||
// Help:
|
||||
@ -372,6 +372,15 @@ CODE
|
||||
When you are not sure about a old symbol or function name, try using the Search/Find function of your IDE to look for comments or references in all imgui files.
|
||||
You can read releases logs https://github.com/ocornut/imgui/releases for more details.
|
||||
|
||||
- 2020/08/17 (1.78) - obsoleted use of the trailing 'float power=1.0f' parameter for DragFloat(), DragFloat2(), DragFloat3(), DragFloat4(), DragFloatRange2(), DragScalar(), DragScalarN(), SliderFloat(), SliderFloat2(), SliderFloat3(), SliderFloat4(), SliderScalar(), SliderScalarN(), VSliderFloat() and VSliderScalar().
|
||||
replaced the 'float power=1.0f' argument with integer-based flags defaulting to 0 (as with all our flags).
|
||||
worked out a backward-compatibility scheme so hopefully most C++ codebase should not be affected. in short, when calling those functions:
|
||||
- if you omitted the 'power' parameter (likely!), you are not affected.
|
||||
- if you set the 'power' parameter to 1.0f (same as previous default value): 1/ your compiler may warn on float>int conversion, 2/ everything else will work. 3/ you can replace the 1.0f value with 0 to fix the warning, and be technically correct.
|
||||
- if you set the 'power' parameter to >1.0f (to enable non-linear editing): 1/ your compiler may warn on float>int conversion, 2/ code will assert at runtime, 3/ in case asserts are disabled, the code will not crash and enable the _Logarithmic flag. 4/ you can replace the >1.0f value with ImGuiSliderFlags_Logarithmic to fix the warning/assert and get a _similar_ effect as previous uses of power >1.0f.
|
||||
see https://github.com/ocornut/imgui/issues/3361 for all details.
|
||||
kept inline redirection functions (will obsolete) apart for: DragFloatRange2(), VSliderFloat(), VSliderScalar(). For those three the 'float power=1.0f' version were removed directly as they were most unlikely ever used.
|
||||
- obsoleted use of v_min > v_max in DragInt, DragFloat, DragScalar to lock edits (introduced in 1.73, was not demoed nor documented very), will be replaced by a more generic ReadOnly feature. You may use the ImGuiSliderFlags_ReadOnly internal flag in the meantime.
|
||||
- 2020/06/23 (1.77) - removed BeginPopupContextWindow(const char*, int mouse_button, bool also_over_items) in favor of BeginPopupContextWindow(const char*, ImGuiPopupFlags flags) with ImGuiPopupFlags_NoOverItems.
|
||||
- 2020/06/15 (1.77) - renamed OpenPopupOnItemClick() to OpenPopupContextItem(). Kept inline redirection function (will obsolete).
|
||||
- 2020/06/15 (1.77) - removed CalcItemRectClosestPoint() entry point which was made obsolete and asserting in December 2017.
|
||||
@ -417,7 +426,7 @@ CODE
|
||||
- 2019/04/29 (1.70) - removed GetContentRegionAvailWidth(), use GetContentRegionAvail().x instead. Kept inline redirection function (will obsolete).
|
||||
- 2019/03/04 (1.69) - renamed GetOverlayDrawList() to GetForegroundDrawList(). Kept redirection function (will obsolete).
|
||||
- 2019/02/26 (1.69) - renamed ImGuiColorEditFlags_RGB/ImGuiColorEditFlags_HSV/ImGuiColorEditFlags_HEX to ImGuiColorEditFlags_DisplayRGB/ImGuiColorEditFlags_DisplayHSV/ImGuiColorEditFlags_DisplayHex. Kept redirection enums (will obsolete).
|
||||
- 2019/02/14 (1.68) - made it illegal/assert when io.DisplayTime == 0.0f (with an exception for the first frame). If for some reason your time step calculation gives you a zero value, replace it with a dummy small value!
|
||||
- 2019/02/14 (1.68) - made it illegal/assert when io.DisplayTime == 0.0f (with an exception for the first frame). If for some reason your time step calculation gives you a zero value, replace it with an arbitrary small value!
|
||||
- 2019/02/01 (1.68) - removed io.DisplayVisibleMin/DisplayVisibleMax (which were marked obsolete and removed from viewport/docking branch already).
|
||||
- 2019/01/06 (1.67) - renamed io.InputCharacters[], marked internal as was always intended. Please don't access directly, and use AddInputCharacter() instead!
|
||||
- 2019/01/06 (1.67) - renamed ImFontAtlas::GlyphRangesBuilder to ImFontGlyphRangesBuilder. Kept redirection typedef (will obsolete).
|
||||
@ -805,7 +814,7 @@ static const float WINDOWS_MOUSE_WHEEL_SCROLL_LOCK_TIMER = 2.00f; // Lock
|
||||
static void SetCurrentWindow(ImGuiWindow* window);
|
||||
static void FindHoveredWindow();
|
||||
static ImGuiWindow* CreateNewWindow(const char* name, ImGuiWindowFlags flags);
|
||||
static ImVec2 CalcNextScrollFromScrollTargetAndClamp(ImGuiWindow* window, bool snap_on_edges);
|
||||
static ImVec2 CalcNextScrollFromScrollTargetAndClamp(ImGuiWindow* window);
|
||||
|
||||
static void AddDrawListToDrawData(ImVector<ImDrawList*>* out_list, ImDrawList* draw_list);
|
||||
static void AddWindowToSortBuffer(ImVector<ImGuiWindow*>* out_sorted_windows, ImGuiWindow* window);
|
||||
@ -925,6 +934,7 @@ ImGuiStyle::ImGuiStyle()
|
||||
ScrollbarRounding = 9.0f; // Radius of grab corners rounding for scrollbar
|
||||
GrabMinSize = 10.0f; // Minimum width/height of a grab box for slider/scrollbar
|
||||
GrabRounding = 0.0f; // Radius of grabs corners rounding. Set to 0.0f to have rectangular slider grabs.
|
||||
LogSliderDeadzone = 4.0f; // The size in pixels of the dead-zone around zero on logarithmic sliders that cross zero.
|
||||
TabRounding = 4.0f; // Radius of upper corners of a tab. Set to 0.0f to have rectangular tabs.
|
||||
TabBorderSize = 0.0f; // Thickness of border around tabs.
|
||||
TabMinWidthForUnselectedCloseButton = 0.0f; // Minimum width for close button to appears on an unselected tab when hovered. Set to 0.0f to always show when hovering, set to FLT_MAX to never show close button unless selected.
|
||||
@ -934,8 +944,9 @@ ImGuiStyle::ImGuiStyle()
|
||||
DisplayWindowPadding = ImVec2(19,19); // Window position are clamped to be visible within the display area or monitors by at least this amount. Only applies to regular windows.
|
||||
DisplaySafeAreaPadding = ImVec2(3,3); // If you cannot see the edge of your screen (e.g. on a TV) increase the safe area padding. Covers popups/tooltips as well regular windows.
|
||||
MouseCursorScale = 1.0f; // Scale software rendered mouse cursor (when io.MouseDrawCursor is enabled). May be removed later.
|
||||
AntiAliasedLines = true; // Enable anti-aliasing on lines/borders. Disable if you are really short on CPU/GPU.
|
||||
AntiAliasedFill = true; // Enable anti-aliasing on filled shapes (rounded rectangles, circles, etc.)
|
||||
AntiAliasedLines = true; // Enable anti-aliased lines/borders. Disable if you are really tight on CPU/GPU.
|
||||
AntiAliasedLinesUseTex = true; // Enable anti-aliased lines/borders using textures where possible. Require back-end to render with bilinear filtering.
|
||||
AntiAliasedFill = true; // Enable anti-aliased filled shapes (rounded rectangles, circles, etc.).
|
||||
CurveTessellationTol = 1.25f; // Tessellation tolerance when using PathBezierCurveTo() without a specific number of segments. Decrease for highly tessellated curves (higher quality, more polygons), increase to reduce quality.
|
||||
CircleSegmentMaxError = 1.60f; // 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.
|
||||
|
||||
@ -963,6 +974,7 @@ void ImGuiStyle::ScaleAllSizes(float scale_factor)
|
||||
ScrollbarRounding = ImFloor(ScrollbarRounding * scale_factor);
|
||||
GrabMinSize = ImFloor(GrabMinSize * scale_factor);
|
||||
GrabRounding = ImFloor(GrabRounding * scale_factor);
|
||||
LogSliderDeadzone = ImFloor(LogSliderDeadzone * scale_factor);
|
||||
TabRounding = ImFloor(TabRounding * scale_factor);
|
||||
if (TabMinWidthForUnselectedCloseButton != FLT_MAX)
|
||||
TabMinWidthForUnselectedCloseButton = ImFloor(TabMinWidthForUnselectedCloseButton * scale_factor);
|
||||
@ -1662,8 +1674,8 @@ static inline int ImTextCharToUtf8(char* buf, int buf_size, unsigned int c)
|
||||
// Not optimal but we very rarely use this function.
|
||||
int ImTextCountUtf8BytesFromChar(const char* in_text, const char* in_text_end)
|
||||
{
|
||||
unsigned int dummy = 0;
|
||||
return ImTextCharFromUtf8(&dummy, in_text, in_text_end);
|
||||
unsigned int unused = 0;
|
||||
return ImTextCharFromUtf8(&unused, in_text, in_text_end);
|
||||
}
|
||||
|
||||
static inline int ImTextCountUtf8BytesFromChar(unsigned int c)
|
||||
@ -2159,7 +2171,7 @@ void ImGui::CalcListClipping(int items_count, float items_height, int* out_items
|
||||
*out_items_display_end = end;
|
||||
}
|
||||
|
||||
static void SetCursorPosYAndSetupDummyPrevLine(float pos_y, float line_height)
|
||||
static void SetCursorPosYAndSetupForPrevLine(float pos_y, float line_height)
|
||||
{
|
||||
// Set cursor position and a few other things so that SetScrollHereY() and Columns() can work when seeking cursor.
|
||||
// FIXME: It is problematic that we have to do that here, because custom/equivalent end-user code would stumble on the same issue.
|
||||
@ -2191,7 +2203,7 @@ void ImGuiListClipper::Begin(int count, float items_height)
|
||||
{
|
||||
ImGui::CalcListClipping(ItemsCount, ItemsHeight, &DisplayStart, &DisplayEnd); // calculate how many to clip/display
|
||||
if (DisplayStart > 0)
|
||||
SetCursorPosYAndSetupDummyPrevLine(StartPosY + DisplayStart * ItemsHeight, ItemsHeight); // advance cursor
|
||||
SetCursorPosYAndSetupForPrevLine(StartPosY + DisplayStart * ItemsHeight, ItemsHeight); // advance cursor
|
||||
StepNo = 2;
|
||||
}
|
||||
}
|
||||
@ -2202,7 +2214,7 @@ void ImGuiListClipper::End()
|
||||
return;
|
||||
// In theory here we should assert that ImGui::GetCursorPosY() == StartPosY + DisplayEnd * ItemsHeight, but it feels saner to just seek at the end and not assert/crash the user.
|
||||
if (ItemsCount < INT_MAX)
|
||||
SetCursorPosYAndSetupDummyPrevLine(StartPosY + ItemsCount * ItemsHeight, ItemsHeight); // advance cursor
|
||||
SetCursorPosYAndSetupForPrevLine(StartPosY + ItemsCount * ItemsHeight, ItemsHeight); // advance cursor
|
||||
ItemsCount = -1;
|
||||
StepNo = 3;
|
||||
}
|
||||
@ -2236,7 +2248,7 @@ bool ImGuiListClipper::Step()
|
||||
StepNo = 3;
|
||||
return true;
|
||||
}
|
||||
if (StepNo == 2) // Step 2: dummy step only required if an explicit items_height was passed to constructor or Begin() and user still call Step(). Does nothing and switch to Step 3.
|
||||
if (StepNo == 2) // Step 2: empty step only required if an explicit items_height was passed to constructor or Begin() and user still call Step(). Does nothing and switch to Step 3.
|
||||
{
|
||||
IM_ASSERT(DisplayStart >= 0 && DisplayEnd >= 0);
|
||||
StepNo = 3;
|
||||
@ -2466,6 +2478,7 @@ const char* ImGui::GetStyleColorName(ImGuiCol idx)
|
||||
return "Unknown";
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// [SECTION] RENDER HELPERS
|
||||
// Some of those (internal) functions are currently quite a legacy mess - their signature and behavior will change,
|
||||
@ -2925,6 +2938,7 @@ void ImGui::SetActiveID(ImGuiID id, ImGuiWindow* window)
|
||||
}
|
||||
g.ActiveId = id;
|
||||
g.ActiveIdAllowOverlap = false;
|
||||
g.ActiveIdNoClearOnFocusLoss = false;
|
||||
g.ActiveIdWindow = window;
|
||||
g.ActiveIdHasBeenEditedThisFrame = false;
|
||||
if (id)
|
||||
@ -2942,7 +2956,7 @@ void ImGui::SetActiveID(ImGuiID id, ImGuiWindow* window)
|
||||
|
||||
void ImGui::ClearActiveID()
|
||||
{
|
||||
SetActiveID(0, NULL);
|
||||
SetActiveID(0, NULL); // g.ActiveId = 0;
|
||||
}
|
||||
|
||||
void ImGui::SetHoveredID(ImGuiID id)
|
||||
@ -3038,7 +3052,7 @@ bool ImGui::IsItemHovered(ImGuiHoveredFlags flags)
|
||||
if ((window->DC.ItemFlags & ImGuiItemFlags_Disabled) && !(flags & ImGuiHoveredFlags_AllowWhenDisabled))
|
||||
return false;
|
||||
|
||||
// Special handling for the dummy item after Begin() which represent the title bar or tab.
|
||||
// Special handling for calling after Begin() which represent the title bar or tab.
|
||||
// When the window is collapsed (SkipItems==true) that last item will never be overwritten so we need to detect the case.
|
||||
if (window->DC.LastItemId == window->MoveId && window->WriteAccessed)
|
||||
return false;
|
||||
@ -3059,10 +3073,13 @@ bool ImGui::ItemHoverable(const ImRect& bb, ImGuiID id)
|
||||
return false;
|
||||
if (!IsMouseHoveringRect(bb.Min, bb.Max))
|
||||
return false;
|
||||
if (g.NavDisableMouseHover || !IsWindowContentHoverable(window, ImGuiHoveredFlags_None))
|
||||
if (g.NavDisableMouseHover)
|
||||
return false;
|
||||
if (window->DC.ItemFlags & ImGuiItemFlags_Disabled)
|
||||
if (!IsWindowContentHoverable(window, ImGuiHoveredFlags_None) || (window->DC.ItemFlags & ImGuiItemFlags_Disabled))
|
||||
{
|
||||
g.HoveredIdDisabled = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
// We exceptionally allow this function to be called with id==0 to allow using it for easy high-level
|
||||
// hover test in widgets code. We could also decide to split this function is two.
|
||||
@ -3095,6 +3112,15 @@ bool ImGui::IsClippedEx(const ImRect& bb, ImGuiID id, bool clip_even_when_logged
|
||||
return false;
|
||||
}
|
||||
|
||||
// This is also inlined in ItemAdd()
|
||||
// Note: if ImGuiItemStatusFlags_HasDisplayRect is set, user needs to set window->DC.LastItemDisplayRect!
|
||||
void ImGui::SetLastItemData(ImGuiWindow* window, ImGuiID item_id, ImGuiItemStatusFlags item_flags, const ImRect& item_rect)
|
||||
{
|
||||
window->DC.LastItemId = item_id;
|
||||
window->DC.LastItemStatusFlags = item_flags;
|
||||
window->DC.LastItemRect = item_rect;
|
||||
}
|
||||
|
||||
// Process TAB/Shift+TAB. Be mindful that this function may _clear_ the ActiveID when tabbing out.
|
||||
bool ImGui::FocusableItemRegister(ImGuiWindow* window, ImGuiID id)
|
||||
{
|
||||
@ -3287,6 +3313,7 @@ void ImGui::StartMouseMovingWindow(ImGuiWindow* window)
|
||||
FocusWindow(window);
|
||||
SetActiveID(window->MoveId, window);
|
||||
g.NavDisableHighlight = true;
|
||||
g.ActiveIdNoClearOnFocusLoss = true;
|
||||
g.ActiveIdClickOffset = g.IO.MousePos - window->RootWindow->Pos;
|
||||
|
||||
bool can_move_window = true;
|
||||
@ -3362,11 +3389,17 @@ void ImGui::UpdateMouseMovingWindowEndFrame()
|
||||
if (root_window != NULL && !is_closed_popup)
|
||||
{
|
||||
StartMouseMovingWindow(g.HoveredWindow);
|
||||
|
||||
// Cancel moving if clicked outside of title bar
|
||||
if (g.IO.ConfigWindowsMoveFromTitleBarOnly && !(root_window->Flags & ImGuiWindowFlags_NoTitleBar))
|
||||
if (!root_window->TitleBarRect().Contains(g.IO.MouseClickedPos[0]))
|
||||
g.MovingWindow = NULL;
|
||||
|
||||
// Cancel moving if clicked over an item which was disabled or inhibited by popups (note that we know HoveredId == 0 already)
|
||||
if (g.HoveredIdDisabled)
|
||||
g.MovingWindow = NULL;
|
||||
}
|
||||
else if (root_window != NULL && g.NavWindow != NULL && GetTopMostPopupModal() == NULL)
|
||||
else if (root_window == NULL && g.NavWindow != NULL && GetTopMostPopupModal() == NULL)
|
||||
{
|
||||
// Clicking on void disable focus
|
||||
FocusWindow(NULL);
|
||||
@ -3591,15 +3624,14 @@ void ImGui::UpdateHoveredWindowAndCaptureFlags()
|
||||
// - We also support the moved window toggling the NoInputs flag after moving has started in order to be able to detect windows below it, which is useful for e.g. docking mechanisms.
|
||||
FindHoveredWindow();
|
||||
|
||||
// Modal windows prevents cursor from hovering behind them.
|
||||
// Modal windows prevents mouse from hovering behind them.
|
||||
ImGuiWindow* modal_window = GetTopMostPopupModal();
|
||||
if (modal_window)
|
||||
if (g.HoveredRootWindow && !IsWindowChildOf(g.HoveredRootWindow, modal_window))
|
||||
g.HoveredRootWindow = g.HoveredWindow = NULL;
|
||||
if (modal_window && g.HoveredRootWindow && !IsWindowChildOf(g.HoveredRootWindow, modal_window))
|
||||
g.HoveredWindow = g.HoveredRootWindow = g.HoveredWindowUnderMovingWindow = NULL;
|
||||
|
||||
// Disabled mouse?
|
||||
if (g.IO.ConfigFlags & ImGuiConfigFlags_NoMouse)
|
||||
g.HoveredWindow = g.HoveredRootWindow = NULL;
|
||||
g.HoveredWindow = g.HoveredRootWindow = g.HoveredWindowUnderMovingWindow = NULL;
|
||||
|
||||
// We track click ownership. When clicked outside of a window the click is owned by the application and won't report hovering nor request capture even while dragging over our windows afterward.
|
||||
int mouse_earliest_button_down = -1;
|
||||
@ -3619,7 +3651,7 @@ void ImGui::UpdateHoveredWindowAndCaptureFlags()
|
||||
// FIXME: For patterns of drag and drop across OS windows, we may need to rework/remove this test (first committed 311c0ca9 on 2015/02)
|
||||
const bool mouse_dragging_extern_payload = g.DragDropActive && (g.DragDropSourceFlags & ImGuiDragDropFlags_SourceExtern) != 0;
|
||||
if (!mouse_avail_to_imgui && !mouse_dragging_extern_payload)
|
||||
g.HoveredWindow = g.HoveredRootWindow = NULL;
|
||||
g.HoveredWindow = g.HoveredRootWindow = g.HoveredWindowUnderMovingWindow = NULL;
|
||||
|
||||
// Update io.WantCaptureMouse for the user application (true = dispatch mouse info to imgui, false = dispatch mouse info to Dear ImGui + app)
|
||||
if (g.WantCaptureMouseNextFrame != -1)
|
||||
@ -3688,6 +3720,8 @@ void ImGui::NewFrame()
|
||||
g.DrawListSharedData.InitialFlags = ImDrawListFlags_None;
|
||||
if (g.Style.AntiAliasedLines)
|
||||
g.DrawListSharedData.InitialFlags |= ImDrawListFlags_AntiAliasedLines;
|
||||
if (g.Style.AntiAliasedLinesUseTex && !(g.Font->ContainerAtlas->Flags & ImFontAtlasFlags_NoBakedLines))
|
||||
g.DrawListSharedData.InitialFlags |= ImDrawListFlags_AntiAliasedLinesUseTex;
|
||||
if (g.Style.AntiAliasedFill)
|
||||
g.DrawListSharedData.InitialFlags |= ImDrawListFlags_AntiAliasedFill;
|
||||
if (g.IO.BackendFlags & ImGuiBackendFlags_RendererHasVtxOffset)
|
||||
@ -3720,6 +3754,7 @@ void ImGui::NewFrame()
|
||||
g.HoveredIdPreviousFrame = g.HoveredId;
|
||||
g.HoveredId = 0;
|
||||
g.HoveredIdAllowOverlap = false;
|
||||
g.HoveredIdDisabled = false;
|
||||
|
||||
// Update ActiveId data (clear reference to active widget if the widget isn't alive anymore)
|
||||
if (g.ActiveIdIsAlive != g.ActiveId && g.ActiveIdPreviousFrame == g.ActiveId && g.ActiveId != 0)
|
||||
@ -3916,6 +3951,11 @@ void ImGui::Shutdown(ImGuiContext* context)
|
||||
SetCurrentContext(backup_context);
|
||||
}
|
||||
|
||||
// Notify hooked test engine, if any
|
||||
#ifdef IMGUI_ENABLE_TEST_ENGINE
|
||||
ImGuiTestEngineHook_Shutdown(context);
|
||||
#endif
|
||||
|
||||
// Clear everything else
|
||||
for (int i = 0; i < g.Windows.Size; i++)
|
||||
IM_DELETE(g.Windows[i]);
|
||||
@ -3926,7 +3966,7 @@ void ImGui::Shutdown(ImGuiContext* context)
|
||||
g.CurrentWindowStack.clear();
|
||||
g.WindowsById.Clear();
|
||||
g.NavWindow = NULL;
|
||||
g.HoveredWindow = g.HoveredRootWindow = NULL;
|
||||
g.HoveredWindow = g.HoveredRootWindow = g.HoveredWindowUnderMovingWindow = NULL;
|
||||
g.ActiveIdWindow = g.ActiveIdPreviousFrameWindow = NULL;
|
||||
g.MovingWindow = NULL;
|
||||
g.ColorModifiers.clear();
|
||||
@ -4265,6 +4305,7 @@ static void FindHoveredWindow()
|
||||
ImGuiContext& g = *GImGui;
|
||||
|
||||
ImGuiWindow* hovered_window = NULL;
|
||||
ImGuiWindow* hovered_window_ignoring_moving_window = NULL;
|
||||
if (g.MovingWindow && !(g.MovingWindow->Flags & ImGuiWindowFlags_NoMouseInputs))
|
||||
hovered_window = g.MovingWindow;
|
||||
|
||||
@ -4287,16 +4328,27 @@ static void FindHoveredWindow()
|
||||
if (!bb.Contains(g.IO.MousePos))
|
||||
continue;
|
||||
|
||||
// Those seemingly unnecessary extra tests are because the code here is a little different in viewport/docking branches.
|
||||
// Support for one rectangular hole in any given window
|
||||
// FIXME: Consider generalizing hit-testing override (with more generic data, callback, etc.) (#1512)
|
||||
if (window->HitTestHoleSize.x != 0)
|
||||
{
|
||||
ImVec2 hole_pos(window->Pos.x + (float)window->HitTestHoleOffset.x, window->Pos.y + (float)window->HitTestHoleOffset.y);
|
||||
ImVec2 hole_size((float)window->HitTestHoleSize.x, (float)window->HitTestHoleSize.y);
|
||||
if (ImRect(hole_pos, hole_pos + hole_size).Contains(g.IO.MousePos))
|
||||
continue;
|
||||
}
|
||||
|
||||
if (hovered_window == NULL)
|
||||
hovered_window = window;
|
||||
if (hovered_window)
|
||||
if (hovered_window_ignoring_moving_window == NULL && (!g.MovingWindow || window->RootWindow != g.MovingWindow->RootWindow))
|
||||
hovered_window_ignoring_moving_window = window;
|
||||
if (hovered_window && hovered_window_ignoring_moving_window)
|
||||
break;
|
||||
}
|
||||
|
||||
g.HoveredWindow = hovered_window;
|
||||
g.HoveredRootWindow = g.HoveredWindow ? g.HoveredWindow->RootWindow : NULL;
|
||||
|
||||
g.HoveredWindowUnderMovingWindow = hovered_window_ignoring_moving_window;
|
||||
}
|
||||
|
||||
// Test if mouse cursor is hovering given rectangle
|
||||
@ -4425,6 +4477,7 @@ bool ImGui::IsMouseDoubleClicked(ImGuiMouseButton button)
|
||||
return g.IO.MouseDoubleClicked[button];
|
||||
}
|
||||
|
||||
// Return if a mouse click/drag went past the given threshold. Valid to call during the MouseReleased frame.
|
||||
// [Internal] This doesn't test if the button is pressed
|
||||
bool ImGui::IsMouseDragPastThreshold(ImGuiMouseButton button, float lock_threshold)
|
||||
{
|
||||
@ -4697,7 +4750,7 @@ bool ImGui::BeginChildEx(const char* name, ImGuiID id, const ImVec2& size_arg, b
|
||||
{
|
||||
FocusWindow(child_window);
|
||||
NavInitWindow(child_window, false);
|
||||
SetActiveID(id+1, child_window); // Steal ActiveId with a dummy id so that key-press won't activate child item
|
||||
SetActiveID(id + 1, child_window); // Steal ActiveId with another arbitrary id so that key-press won't activate child item
|
||||
g.ActiveIdSource = ImGuiInputSource_Nav;
|
||||
}
|
||||
return ret;
|
||||
@ -5572,6 +5625,10 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
|
||||
if ((flags & ImGuiWindowFlags_ChildWindow) && !(flags & (ImGuiWindowFlags_AlwaysUseWindowPadding | ImGuiWindowFlags_Popup)) && window->WindowBorderSize == 0.0f)
|
||||
window->WindowPadding = ImVec2(0.0f, (flags & ImGuiWindowFlags_MenuBar) ? style.WindowPadding.y : 0.0f);
|
||||
|
||||
// Lock menu offset so size calculation can use it as menu-bar windows need a minimum size.
|
||||
window->DC.MenuBarOffset.x = ImMax(ImMax(window->WindowPadding.x, style.ItemSpacing.x), g.NextWindowData.MenuBarOffsetMinVal.x);
|
||||
window->DC.MenuBarOffset.y = g.NextWindowData.MenuBarOffsetMinVal.y;
|
||||
|
||||
// Collapse window by double-clicking on title bar
|
||||
// At this point we don't have a clipping rectangle setup yet, so we can use the title bar area for hit detection and drawing
|
||||
if (!(flags & ImGuiWindowFlags_NoTitleBar) && !(flags & ImGuiWindowFlags_NoCollapse))
|
||||
@ -5784,7 +5841,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
|
||||
window->ScrollMax.y = ImMax(0.0f, window->ContentSize.y + window->WindowPadding.y * 2.0f - window->InnerRect.GetHeight());
|
||||
|
||||
// Apply scrolling
|
||||
window->Scroll = CalcNextScrollFromScrollTargetAndClamp(window, true);
|
||||
window->Scroll = CalcNextScrollFromScrollTargetAndClamp(window);
|
||||
window->ScrollTarget = ImVec2(FLT_MAX, FLT_MAX);
|
||||
|
||||
// DRAWING
|
||||
@ -5863,6 +5920,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
|
||||
window->WorkRect.Min.y = ImFloor(window->InnerRect.Min.y - window->Scroll.y + ImMax(window->WindowPadding.y, window->WindowBorderSize));
|
||||
window->WorkRect.Max.x = window->WorkRect.Min.x + work_rect_size_x;
|
||||
window->WorkRect.Max.y = window->WorkRect.Min.y + work_rect_size_y;
|
||||
window->ParentWorkRect = window->WorkRect;
|
||||
|
||||
// [LEGACY] Content Region
|
||||
// FIXME-OBSOLETE: window->ContentRegionRect.Max is currently very misleading / partly faulty, but some BeginChild() patterns relies on it.
|
||||
@ -5894,8 +5952,6 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
|
||||
window->DC.NavHasScroll = (window->ScrollMax.y > 0.0f);
|
||||
|
||||
window->DC.MenuBarAppending = false;
|
||||
window->DC.MenuBarOffset.x = ImMax(ImMax(window->WindowPadding.x, style.ItemSpacing.x), g.NextWindowData.MenuBarOffsetMinVal.x);
|
||||
window->DC.MenuBarOffset.y = g.NextWindowData.MenuBarOffsetMinVal.y;
|
||||
window->DC.MenuColumns.Update(3, style.ItemSpacing.x, window_just_activated_by_user);
|
||||
window->DC.TreeDepth = 0;
|
||||
window->DC.TreeJumpToParentOnPopMask = 0x00;
|
||||
@ -5932,6 +5988,9 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
|
||||
if (!(flags & ImGuiWindowFlags_NoTitleBar))
|
||||
RenderWindowTitleBarContents(window, title_bar_rect, name, p_open);
|
||||
|
||||
// Clear hit test shape every frame
|
||||
window->HitTestHoleSize.x = window->HitTestHoleSize.y = 0;
|
||||
|
||||
// Pressing CTRL+C while holding on a window copy its content to the clipboard
|
||||
// This works but 1. doesn't handle multiple Begin/End pairs, 2. recursing into another Begin/End pair - so we need to work that out and add better logging scope.
|
||||
// Maybe we can support CTRL+C on every element?
|
||||
@ -5943,9 +6002,8 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
|
||||
|
||||
// We fill last item data based on Title Bar/Tab, in order for IsItemHovered() and IsItemActive() to be usable after Begin().
|
||||
// This is useful to allow creating context menus on title bar only, etc.
|
||||
window->DC.LastItemId = window->MoveId;
|
||||
window->DC.LastItemStatusFlags = IsMouseHoveringRect(title_bar_rect.Min, title_bar_rect.Max, false) ? ImGuiItemStatusFlags_HoveredRect : 0;
|
||||
window->DC.LastItemRect = title_bar_rect;
|
||||
SetLastItemData(window, window->MoveId, IsMouseHoveringRect(title_bar_rect.Min, title_bar_rect.Max, false) ? ImGuiItemStatusFlags_HoveredRect : 0, title_bar_rect);
|
||||
|
||||
#ifdef IMGUI_ENABLE_TEST_ENGINE
|
||||
if (!(window->Flags & ImGuiWindowFlags_NoTitleBar))
|
||||
IMGUI_TEST_ENGINE_ITEM_ADD(window->DC.LastItemRect, window->DC.LastItemId);
|
||||
@ -6051,7 +6109,7 @@ void ImGui::BringWindowToDisplayFront(ImGuiWindow* window)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiWindow* current_front_window = g.Windows.back();
|
||||
if (current_front_window == window || current_front_window->RootWindow == window)
|
||||
if (current_front_window == window || current_front_window->RootWindow == window) // Cheap early out (could be better)
|
||||
return;
|
||||
for (int i = g.Windows.Size - 2; i >= 0; i--) // We can ignore the top-most window
|
||||
if (g.Windows[i] == window)
|
||||
@ -6102,8 +6160,11 @@ void ImGui::FocusWindow(ImGuiWindow* window)
|
||||
ImGuiWindow* focus_front_window = window ? window->RootWindow : NULL; // NB: In docking branch this is window->RootWindowDockStop
|
||||
ImGuiWindow* display_front_window = window ? window->RootWindow : NULL;
|
||||
|
||||
// Steal focus on active widgets
|
||||
// Steal active widgets. Some of the cases it triggers includes:
|
||||
// - Focus a window while an InputText in another window is active, if focus happens before the old InputText can run.
|
||||
// - When using Nav to activate menu items (due to timing of activating on press->new window appears->losing ActiveId)
|
||||
if (g.ActiveId != 0 && g.ActiveIdWindow && g.ActiveIdWindow->RootWindow != focus_front_window)
|
||||
if (!g.ActiveIdNoClearOnFocusLoss)
|
||||
ClearActiveID();
|
||||
|
||||
// Passing NULL allow to disable keyboard focus
|
||||
@ -6153,6 +6214,7 @@ void ImGui::SetCurrentFont(ImFont* font)
|
||||
|
||||
ImFontAtlas* atlas = g.Font->ContainerAtlas;
|
||||
g.DrawListSharedData.TexUvWhitePixel = atlas->TexUvWhitePixel;
|
||||
g.DrawListSharedData.TexUvLines = atlas->TexUvLines;
|
||||
g.DrawListSharedData.Font = g.Font;
|
||||
g.DrawListSharedData.FontSize = g.FontSize;
|
||||
}
|
||||
@ -6420,6 +6482,13 @@ void ImGui::SetWindowCollapsed(ImGuiWindow* window, bool collapsed, ImGuiCond co
|
||||
window->Collapsed = collapsed;
|
||||
}
|
||||
|
||||
void ImGui::SetWindowHitTestHole(ImGuiWindow* window, const ImVec2& pos, const ImVec2& size)
|
||||
{
|
||||
IM_ASSERT(window->HitTestHoleSize.x == 0); // We don't support multiple holes/hit test filters
|
||||
window->HitTestHoleSize = ImVec2ih(size);
|
||||
window->HitTestHoleOffset = ImVec2ih(pos - window->Pos);
|
||||
}
|
||||
|
||||
void ImGui::SetWindowCollapsed(bool collapsed, ImGuiCond cond)
|
||||
{
|
||||
SetWindowCollapsed(GImGui->CurrentWindow, collapsed, cond);
|
||||
@ -6914,6 +6983,7 @@ bool ImGui::ItemAdd(const ImRect& bb, ImGuiID id, const ImRect* nav_bb_arg)
|
||||
#endif
|
||||
}
|
||||
|
||||
// Equivalent to calling SetLastItemData()
|
||||
window->DC.LastItemId = id;
|
||||
window->DC.LastItemRect = bb;
|
||||
window->DC.LastItemStatusFlags = ImGuiItemStatusFlags_None;
|
||||
@ -7281,30 +7351,20 @@ void ImGui::EndGroup()
|
||||
// [SECTION] SCROLLING
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
static ImVec2 CalcNextScrollFromScrollTargetAndClamp(ImGuiWindow* window, bool snap_on_edges)
|
||||
static ImVec2 CalcNextScrollFromScrollTargetAndClamp(ImGuiWindow* window)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImVec2 scroll = window->Scroll;
|
||||
if (window->ScrollTarget.x < FLT_MAX)
|
||||
{
|
||||
float cr_x = window->ScrollTargetCenterRatio.x;
|
||||
float target_x = window->ScrollTarget.x;
|
||||
if (snap_on_edges && cr_x <= 0.0f && target_x <= window->WindowPadding.x)
|
||||
target_x = 0.0f;
|
||||
else if (snap_on_edges && cr_x >= 1.0f && target_x >= window->ContentSize.x + window->WindowPadding.x + g.Style.ItemSpacing.x)
|
||||
target_x = window->ContentSize.x + window->WindowPadding.x * 2.0f;
|
||||
scroll.x = target_x - cr_x * (window->SizeFull.x - window->ScrollbarSizes.x);
|
||||
}
|
||||
if (window->ScrollTarget.y < FLT_MAX)
|
||||
{
|
||||
// 'snap_on_edges' allows for a discontinuity at the edge of scrolling limits to take account of WindowPadding so that scrolling to make the last item visible scroll far enough to see the padding.
|
||||
float decoration_up_height = window->TitleBarHeight() + window->MenuBarHeight();
|
||||
float cr_y = window->ScrollTargetCenterRatio.y;
|
||||
float target_y = window->ScrollTarget.y;
|
||||
if (snap_on_edges && cr_y <= 0.0f && target_y <= window->WindowPadding.y)
|
||||
target_y = 0.0f;
|
||||
if (snap_on_edges && cr_y >= 1.0f && target_y >= window->ContentSize.y + window->WindowPadding.y + g.Style.ItemSpacing.y)
|
||||
target_y = window->ContentSize.y + window->WindowPadding.y * 2.0f;
|
||||
scroll.y = target_y - cr_y * (window->SizeFull.y - window->ScrollbarSizes.y - decoration_up_height);
|
||||
}
|
||||
scroll.x = IM_FLOOR(ImMax(scroll.x, 0.0f));
|
||||
@ -7336,7 +7396,7 @@ ImVec2 ImGui::ScrollToBringRectIntoView(ImGuiWindow* window, const ImRect& item_
|
||||
else if (item_rect.Max.y >= window_rect.Max.y)
|
||||
SetScrollFromPosY(window, item_rect.Max.y - window->Pos.y + g.Style.ItemSpacing.y, 1.0f);
|
||||
|
||||
ImVec2 next_scroll = CalcNextScrollFromScrollTargetAndClamp(window, false);
|
||||
ImVec2 next_scroll = CalcNextScrollFromScrollTargetAndClamp(window);
|
||||
delta_scroll = next_scroll - window->Scroll;
|
||||
}
|
||||
|
||||
@ -7397,10 +7457,10 @@ void ImGui::SetScrollY(ImGuiWindow* window, float new_scroll_y)
|
||||
window->ScrollTargetCenterRatio.y = 0.0f;
|
||||
}
|
||||
|
||||
|
||||
// Note that a local position will vary depending on initial scroll value
|
||||
// We store a target position so centering can occur on the next frame when we are guaranteed to have a known window size
|
||||
void ImGui::SetScrollFromPosX(ImGuiWindow* window, float local_x, float center_x_ratio)
|
||||
{
|
||||
// We store a target position so centering can occur on the next frame when we are guaranteed to have a known window size
|
||||
IM_ASSERT(center_x_ratio >= 0.0f && center_x_ratio <= 1.0f);
|
||||
window->ScrollTarget.x = IM_FLOOR(local_x + window->Scroll.x);
|
||||
window->ScrollTargetCenterRatio.x = center_x_ratio;
|
||||
@ -7408,10 +7468,8 @@ void ImGui::SetScrollFromPosX(ImGuiWindow* window, float local_x, float center_x
|
||||
|
||||
void ImGui::SetScrollFromPosY(ImGuiWindow* window, float local_y, float center_y_ratio)
|
||||
{
|
||||
// We store a target position so centering can occur on the next frame when we are guaranteed to have a known window size
|
||||
IM_ASSERT(center_y_ratio >= 0.0f && center_y_ratio <= 1.0f);
|
||||
const float decoration_up_height = window->TitleBarHeight() + window->MenuBarHeight();
|
||||
local_y -= decoration_up_height;
|
||||
local_y -= window->TitleBarHeight() + window->MenuBarHeight(); // FIXME: Would be nice to have a more standardized access to our scrollable/client rect
|
||||
window->ScrollTarget.y = IM_FLOOR(local_y + window->Scroll.y);
|
||||
window->ScrollTargetCenterRatio.y = center_y_ratio;
|
||||
}
|
||||
@ -7428,15 +7486,34 @@ void ImGui::SetScrollFromPosY(float local_y, float center_y_ratio)
|
||||
SetScrollFromPosY(g.CurrentWindow, local_y, center_y_ratio);
|
||||
}
|
||||
|
||||
// Tweak: snap on edges when aiming at an item very close to the edge,
|
||||
// So the difference between WindowPadding and ItemSpacing will be in the visible area after scrolling.
|
||||
// When we refactor the scrolling API this may be configurable with a flag?
|
||||
// Note that the effect for this won't be visible on X axis with default Style settings as WindowPadding.x == ItemSpacing.x by default.
|
||||
static float CalcScrollSnap(float target, float snap_min, float snap_max, float snap_threshold, float center_ratio)
|
||||
{
|
||||
if (target <= snap_min + snap_threshold)
|
||||
return ImLerp(snap_min, target, center_ratio);
|
||||
if (target >= snap_max - snap_threshold)
|
||||
return ImLerp(target, snap_max, center_ratio);
|
||||
return target;
|
||||
}
|
||||
|
||||
// center_x_ratio: 0.0f left of last item, 0.5f horizontal center of last item, 1.0f right of last item.
|
||||
void ImGui::SetScrollHereX(float center_x_ratio)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiWindow* window = g.CurrentWindow;
|
||||
float target_x = window->DC.LastItemRect.Min.x - window->Pos.x; // Left of last item, in window space
|
||||
float last_item_width = window->DC.LastItemRect.GetWidth();
|
||||
target_x += (last_item_width * center_x_ratio) + (g.Style.ItemSpacing.x * (center_x_ratio - 0.5f) * 2.0f); // Precisely aim before, in the middle or after the last item.
|
||||
SetScrollFromPosX(target_x, center_x_ratio);
|
||||
float spacing_x = g.Style.ItemSpacing.x;
|
||||
float target_x = ImLerp(window->DC.LastItemRect.Min.x - spacing_x, window->DC.LastItemRect.Max.x + spacing_x, center_x_ratio);
|
||||
|
||||
// Tweak: snap on edges when aiming at an item very close to the edge
|
||||
const float snap_x_threshold = ImMax(0.0f, window->WindowPadding.x - spacing_x);
|
||||
const float snap_x_min = window->DC.CursorStartPos.x - window->WindowPadding.x;
|
||||
const float snap_x_max = window->DC.CursorStartPos.x + window->ContentSize.x + window->WindowPadding.x;
|
||||
target_x = CalcScrollSnap(target_x, snap_x_min, snap_x_max, snap_x_threshold, center_x_ratio);
|
||||
|
||||
SetScrollFromPosX(window, target_x - window->Pos.x, center_x_ratio);
|
||||
}
|
||||
|
||||
// center_y_ratio: 0.0f top of last item, 0.5f vertical center of last item, 1.0f bottom of last item.
|
||||
@ -7444,9 +7521,16 @@ void ImGui::SetScrollHereY(float center_y_ratio)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiWindow* window = g.CurrentWindow;
|
||||
float target_y = window->DC.CursorPosPrevLine.y - window->Pos.y; // Top of last item, in window space
|
||||
target_y += (window->DC.PrevLineSize.y * center_y_ratio) + (g.Style.ItemSpacing.y * (center_y_ratio - 0.5f) * 2.0f); // Precisely aim above, in the middle or below the last line.
|
||||
SetScrollFromPosY(target_y, center_y_ratio);
|
||||
float spacing_y = g.Style.ItemSpacing.y;
|
||||
float target_y = ImLerp(window->DC.CursorPosPrevLine.y - spacing_y, window->DC.CursorPosPrevLine.y + window->DC.PrevLineSize.y + spacing_y, center_y_ratio);
|
||||
|
||||
// Tweak: snap on edges when aiming at an item very close to the edge
|
||||
const float snap_y_threshold = ImMax(0.0f, window->WindowPadding.y - spacing_y);
|
||||
const float snap_y_min = window->DC.CursorStartPos.y - window->WindowPadding.y;
|
||||
const float snap_y_max = window->DC.CursorStartPos.y + window->ContentSize.y + window->WindowPadding.y;
|
||||
target_y = CalcScrollSnap(target_y, snap_y_min, snap_y_max, snap_y_threshold, center_y_ratio);
|
||||
|
||||
SetScrollFromPosY(window, target_y - window->Pos.y, center_y_ratio);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -7595,7 +7679,7 @@ void ImGui::OpenPopupEx(ImGuiID id, ImGuiPopupFlags popup_flags)
|
||||
popup_ref.OpenPopupPos = NavCalcPreferredRefPos();
|
||||
popup_ref.OpenMousePos = IsMousePosValid(&g.IO.MousePos) ? g.IO.MousePos : popup_ref.OpenPopupPos;
|
||||
|
||||
//IMGUI_DEBUG_LOG("OpenPopupEx(0x%08X)\n", g.FrameCount, id);
|
||||
IMGUI_DEBUG_LOG_POPUP("OpenPopupEx(0x%08X)\n", id);
|
||||
if (g.OpenPopupStack.Size < current_stack_size + 1)
|
||||
{
|
||||
g.OpenPopupStack.push_back(popup_ref);
|
||||
@ -7623,13 +7707,14 @@ void ImGui::OpenPopupEx(ImGuiID id, ImGuiPopupFlags popup_flags)
|
||||
}
|
||||
}
|
||||
|
||||
// When popups are stacked, clicking on a lower level popups puts focus back to it and close popups above it.
|
||||
// This function closes any popups that are over 'ref_window'.
|
||||
void ImGui::ClosePopupsOverWindow(ImGuiWindow* ref_window, bool restore_focus_to_window_under_popup)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
if (g.OpenPopupStack.Size == 0)
|
||||
return;
|
||||
|
||||
// When popups are stacked, clicking on a lower level popups puts focus back to it and close popups above it.
|
||||
// Don't close our own child popup windows.
|
||||
int popup_count_to_keep = 0;
|
||||
if (ref_window)
|
||||
@ -7644,19 +7729,26 @@ void ImGui::ClosePopupsOverWindow(ImGuiWindow* ref_window, bool restore_focus_to
|
||||
if (popup.Window->Flags & ImGuiWindowFlags_ChildWindow)
|
||||
continue;
|
||||
|
||||
// Trim the stack when popups are not direct descendant of the reference window (the reference window is often the NavWindow)
|
||||
bool popup_or_descendent_is_ref_window = false;
|
||||
for (int m = popup_count_to_keep; m < g.OpenPopupStack.Size && !popup_or_descendent_is_ref_window; m++)
|
||||
if (ImGuiWindow* popup_window = g.OpenPopupStack[m].Window)
|
||||
// Trim the stack unless the popup is a direct parent of the reference window (the reference window is often the NavWindow)
|
||||
// - With this stack of window, clicking/focusing Popup1 will close Popup2 and Popup3:
|
||||
// Window -> Popup1 -> Popup2 -> Popup3
|
||||
// - Each popups may contain child windows, which is why we compare ->RootWindow!
|
||||
// Window -> Popup1 -> Popup1_Child -> Popup2 -> Popup2_Child
|
||||
bool ref_window_is_descendent_of_popup = false;
|
||||
for (int n = popup_count_to_keep; n < g.OpenPopupStack.Size; n++)
|
||||
if (ImGuiWindow* popup_window = g.OpenPopupStack[n].Window)
|
||||
if (popup_window->RootWindow == ref_window->RootWindow)
|
||||
popup_or_descendent_is_ref_window = true;
|
||||
if (!popup_or_descendent_is_ref_window)
|
||||
{
|
||||
ref_window_is_descendent_of_popup = true;
|
||||
break;
|
||||
}
|
||||
if (!ref_window_is_descendent_of_popup)
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (popup_count_to_keep < g.OpenPopupStack.Size) // This test is not required but it allows to set a convenient breakpoint on the statement below
|
||||
{
|
||||
//IMGUI_DEBUG_LOG("ClosePopupsOverWindow(%s) -> ClosePopupToLevel(%d)\n", ref_window->Name, popup_count_to_keep);
|
||||
IMGUI_DEBUG_LOG_POPUP("ClosePopupsOverWindow(\"%s\") -> ClosePopupToLevel(%d)\n", ref_window->Name, popup_count_to_keep);
|
||||
ClosePopupToLevel(popup_count_to_keep, restore_focus_to_window_under_popup);
|
||||
}
|
||||
}
|
||||
@ -7664,6 +7756,7 @@ void ImGui::ClosePopupsOverWindow(ImGuiWindow* ref_window, bool restore_focus_to
|
||||
void ImGui::ClosePopupToLevel(int remaining, bool restore_focus_to_window_under_popup)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
IMGUI_DEBUG_LOG_POPUP("ClosePopupToLevel(%d), restore_focus_to_window_under_popup=%d\n", remaining, restore_focus_to_window_under_popup);
|
||||
IM_ASSERT(remaining >= 0 && remaining < g.OpenPopupStack.Size);
|
||||
|
||||
// Trim open popup stack
|
||||
@ -7708,7 +7801,7 @@ void ImGui::CloseCurrentPopup()
|
||||
break;
|
||||
popup_idx--;
|
||||
}
|
||||
//IMGUI_DEBUG_LOG("CloseCurrentPopup %d -> %d\n", g.BeginPopupStack.Size - 1, popup_idx);
|
||||
IMGUI_DEBUG_LOG_POPUP("CloseCurrentPopup %d -> %d\n", g.BeginPopupStack.Size - 1, popup_idx);
|
||||
ClosePopupToLevel(popup_idx, true);
|
||||
|
||||
// A common pattern is to close a popup when selecting a menu item/selectable that will open another window.
|
||||
@ -7804,6 +7897,7 @@ void ImGui::EndPopup()
|
||||
g.WithinEndChild = false;
|
||||
}
|
||||
|
||||
// Open a popup if mouse button is released over the item
|
||||
bool ImGui::OpenPopupContextItem(const char* str_id, ImGuiPopupFlags popup_flags)
|
||||
{
|
||||
ImGuiWindow* window = GImGui->CurrentWindow;
|
||||
@ -8293,18 +8387,20 @@ void ImGui::NavMoveRequestTryWrapping(ImGuiWindow* window, ImGuiNavMoveFlags mov
|
||||
// This way we could find the last focused window among our children. It would be much less confusing this way?
|
||||
static void ImGui::NavSaveLastChildNavWindowIntoParent(ImGuiWindow* nav_window)
|
||||
{
|
||||
ImGuiWindow* parent_window = nav_window;
|
||||
while (parent_window && (parent_window->Flags & ImGuiWindowFlags_ChildWindow) != 0 && (parent_window->Flags & (ImGuiWindowFlags_Popup | ImGuiWindowFlags_ChildMenu)) == 0)
|
||||
parent_window = parent_window->ParentWindow;
|
||||
if (parent_window && parent_window != nav_window)
|
||||
parent_window->NavLastChildNavWindow = nav_window;
|
||||
ImGuiWindow* parent = nav_window;
|
||||
while (parent && (parent->Flags & ImGuiWindowFlags_ChildWindow) != 0 && (parent->Flags & (ImGuiWindowFlags_Popup | ImGuiWindowFlags_ChildMenu)) == 0)
|
||||
parent = parent->ParentWindow;
|
||||
if (parent && parent != nav_window)
|
||||
parent->NavLastChildNavWindow = nav_window;
|
||||
}
|
||||
|
||||
// Restore the last focused child.
|
||||
// Call when we are expected to land on the Main Layer (0) after FocusWindow()
|
||||
static ImGuiWindow* ImGui::NavRestoreLastChildNavWindow(ImGuiWindow* window)
|
||||
{
|
||||
return window->NavLastChildNavWindow ? window->NavLastChildNavWindow : window;
|
||||
if (window->NavLastChildNavWindow && window->NavLastChildNavWindow->WasActive)
|
||||
return window->NavLastChildNavWindow;
|
||||
return window;
|
||||
}
|
||||
|
||||
static void NavRestoreLayer(ImGuiNavLayer layer)
|
||||
@ -9110,6 +9206,7 @@ void ImGui::NavUpdateWindowingOverlay()
|
||||
PopStyleVar();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// [SECTION] DRAG AND DROP
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -9299,7 +9396,8 @@ bool ImGui::BeginDragDropTargetCustom(const ImRect& bb, ImGuiID id)
|
||||
return false;
|
||||
|
||||
ImGuiWindow* window = g.CurrentWindow;
|
||||
if (g.HoveredWindow == NULL || window->RootWindow != g.HoveredWindow->RootWindow)
|
||||
ImGuiWindow* hovered_window = g.HoveredWindowUnderMovingWindow;
|
||||
if (hovered_window == NULL || window->RootWindow != hovered_window->RootWindow)
|
||||
return false;
|
||||
IM_ASSERT(id != 0);
|
||||
if (!IsMouseHoveringRect(bb.Min, bb.Max) || (id == g.DragDropPayload.SourceId))
|
||||
@ -9327,7 +9425,8 @@ bool ImGui::BeginDragDropTarget()
|
||||
ImGuiWindow* window = g.CurrentWindow;
|
||||
if (!(window->DC.LastItemStatusFlags & ImGuiItemStatusFlags_HoveredRect))
|
||||
return false;
|
||||
if (g.HoveredWindow == NULL || window->RootWindow != g.HoveredWindow->RootWindow)
|
||||
ImGuiWindow* hovered_window = g.HoveredWindowUnderMovingWindow;
|
||||
if (hovered_window == NULL || window->RootWindow != hovered_window->RootWindow)
|
||||
return false;
|
||||
|
||||
const ImRect& display_rect = (window->DC.LastItemStatusFlags & ImGuiItemStatusFlags_HasDisplayRect) ? window->DC.LastItemDisplayRect : window->DC.LastItemRect;
|
||||
@ -9622,6 +9721,7 @@ void ImGui::LogButtons()
|
||||
LogToClipboard();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// [SECTION] SETTINGS
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -9876,9 +9976,9 @@ static void WindowSettingsHandler_ReadLine(ImGuiContext*, ImGuiSettingsHandler*,
|
||||
ImGuiWindowSettings* settings = (ImGuiWindowSettings*)entry;
|
||||
int x, y;
|
||||
int i;
|
||||
if (sscanf(line, "Pos=%i,%i", &x, &y) == 2) settings->Pos = ImVec2ih((short)x, (short)y);
|
||||
else if (sscanf(line, "Size=%i,%i", &x, &y) == 2) settings->Size = ImVec2ih((short)x, (short)y);
|
||||
else if (sscanf(line, "Collapsed=%d", &i) == 1) settings->Collapsed = (i != 0);
|
||||
if (sscanf(line, "Pos=%i,%i", &x, &y) == 2) { settings->Pos = ImVec2ih((short)x, (short)y); }
|
||||
else if (sscanf(line, "Size=%i,%i", &x, &y) == 2) { settings->Size = ImVec2ih((short)x, (short)y); }
|
||||
else if (sscanf(line, "Collapsed=%d", &i) == 1) { settings->Collapsed = (i != 0); }
|
||||
}
|
||||
|
||||
// Apply to existing windows (if any)
|
||||
@ -10485,7 +10585,7 @@ void ImGui::ShowMetricsWindow(bool* p_open)
|
||||
|
||||
// Details for Docking
|
||||
#ifdef IMGUI_HAS_DOCK
|
||||
if (ImGui::TreeNode("Docking"))
|
||||
if (ImGui::TreeNode("Dock nodes"))
|
||||
{
|
||||
ImGui::TreePop();
|
||||
}
|
||||
@ -10497,6 +10597,9 @@ void ImGui::ShowMetricsWindow(bool* p_open)
|
||||
if (ImGui::SmallButton("Clear"))
|
||||
ImGui::ClearIniSettings();
|
||||
ImGui::SameLine();
|
||||
if (ImGui::SmallButton("Save to memory"))
|
||||
ImGui::SaveIniSettingsToMemory();
|
||||
ImGui::SameLine();
|
||||
if (ImGui::SmallButton("Save to disk"))
|
||||
ImGui::SaveIniSettingsToDisk(g.IO.IniFilename);
|
||||
ImGui::SameLine();
|
||||
@ -10508,7 +10611,7 @@ void ImGui::ShowMetricsWindow(bool* p_open)
|
||||
if (ImGui::TreeNode("SettingsHandlers", "Settings handlers: (%d)", g.SettingsHandlers.Size))
|
||||
{
|
||||
for (int n = 0; n < g.SettingsHandlers.Size; n++)
|
||||
ImGui::TextUnformatted(g.SettingsHandlers[n].TypeName);
|
||||
ImGui::BulletText("%s", g.SettingsHandlers[n].TypeName);
|
||||
ImGui::TreePop();
|
||||
}
|
||||
if (ImGui::TreeNode("SettingsWindows", "Settings packed data: Windows: %d bytes", g.SettingsWindows.size()))
|
||||
@ -10545,6 +10648,7 @@ void ImGui::ShowMetricsWindow(bool* p_open)
|
||||
const char* input_source_names[] = { "None", "Mouse", "Nav", "NavKeyboard", "NavGamepad" }; IM_ASSERT(IM_ARRAYSIZE(input_source_names) == ImGuiInputSource_COUNT);
|
||||
ImGui::Text("HoveredWindow: '%s'", g.HoveredWindow ? g.HoveredWindow->Name : "NULL");
|
||||
ImGui::Text("HoveredRootWindow: '%s'", g.HoveredRootWindow ? g.HoveredRootWindow->Name : "NULL");
|
||||
ImGui::Text("HoveredWindowUnderMovingWindow: '%s'", g.HoveredWindowUnderMovingWindow ? g.HoveredWindowUnderMovingWindow->Name : "NULL");
|
||||
ImGui::Text("HoveredId: 0x%08X/0x%08X (%.2f sec), AllowOverlap: %d", g.HoveredId, g.HoveredIdPreviousFrame, g.HoveredIdTimer, g.HoveredIdAllowOverlap); // Data is "in-flight" so depending on when the Metrics window is called we may see current frame information or not
|
||||
ImGui::Text("ActiveId: 0x%08X/0x%08X (%.2f sec), AllowOverlap: %d, Source: %s", g.ActiveId, g.ActiveIdPreviousFrame, g.ActiveIdTimer, g.ActiveIdAllowOverlap, input_source_names[g.ActiveIdSource]);
|
||||
ImGui::Text("ActiveIdWindow: '%s'", g.ActiveIdWindow ? g.ActiveIdWindow->Name : "NULL");
|
||||
|
183
imgui.h
183
imgui.h
@ -1,4 +1,4 @@
|
||||
// dear imgui, v1.77
|
||||
// dear imgui, v1.78
|
||||
// (headers)
|
||||
|
||||
// Help:
|
||||
@ -59,8 +59,8 @@ Index of this file:
|
||||
|
||||
// Version
|
||||
// (Integer encoded as XYYZZ for use in #if preprocessor conditionals. Work in progress versions typically starts at XYY99 then bounce up to XYY00, XYY01 etc. when release tagging happens)
|
||||
#define IMGUI_VERSION "1.77"
|
||||
#define IMGUI_VERSION_NUM 17700
|
||||
#define IMGUI_VERSION "1.78"
|
||||
#define IMGUI_VERSION_NUM 17800
|
||||
#define IMGUI_CHECKVERSION() ImGui::DebugCheckVersionAndDataLayout(IMGUI_VERSION, sizeof(ImGuiIO), sizeof(ImGuiStyle), sizeof(ImVec2), sizeof(ImVec4), sizeof(ImDrawVert), sizeof(ImDrawIdx))
|
||||
|
||||
// Define attributes of all API symbols declarations (e.g. for DLL under Windows)
|
||||
@ -151,8 +151,9 @@ typedef int ImGuiMouseCursor; // -> enum ImGuiMouseCursor_ // Enum: A
|
||||
typedef int ImGuiStyleVar; // -> enum ImGuiStyleVar_ // Enum: A variable identifier for styling
|
||||
typedef int ImDrawCornerFlags; // -> enum ImDrawCornerFlags_ // Flags: for ImDrawList::AddRect(), AddRectFilled() etc.
|
||||
typedef int ImDrawListFlags; // -> enum ImDrawListFlags_ // Flags: for ImDrawList
|
||||
typedef int ImFontAtlasFlags; // -> enum ImFontAtlasFlags_ // Flags: for ImFontAtlas
|
||||
typedef int ImFontAtlasFlags; // -> enum ImFontAtlasFlags_ // Flags: for ImFontAtlas build
|
||||
typedef int ImGuiBackendFlags; // -> enum ImGuiBackendFlags_ // Flags: for io.BackendFlags
|
||||
typedef int ImGuiButtonFlags; // -> enum ImGuiButtonFlags_ // Flags: for InvisibleButton()
|
||||
typedef int ImGuiColorEditFlags; // -> enum ImGuiColorEditFlags_ // Flags: for ColorEdit4(), ColorPicker4() etc.
|
||||
typedef int ImGuiConfigFlags; // -> enum ImGuiConfigFlags_ // Flags: for io.ConfigFlags
|
||||
typedef int ImGuiComboFlags; // -> enum ImGuiComboFlags_ // Flags: for BeginCombo()
|
||||
@ -163,6 +164,7 @@ typedef int ImGuiInputTextFlags; // -> enum ImGuiInputTextFlags_ // Flags: f
|
||||
typedef int ImGuiKeyModFlags; // -> enum ImGuiKeyModFlags_ // Flags: for io.KeyMods (Ctrl/Shift/Alt/Super)
|
||||
typedef int ImGuiPopupFlags; // -> enum ImGuiPopupFlags_ // Flags: for OpenPopup*(), BeginPopupContext*(), IsPopupOpen()
|
||||
typedef int ImGuiSelectableFlags; // -> enum ImGuiSelectableFlags_ // Flags: for Selectable()
|
||||
typedef int ImGuiSliderFlags; // -> enum ImGuiSliderFlags_ // Flags: for DragFloat(), DragInt(), SliderFloat(), SliderInt() etc.
|
||||
typedef int ImGuiTabBarFlags; // -> enum ImGuiTabBarFlags_ // Flags: for BeginTabBar()
|
||||
typedef int ImGuiTabItemFlags; // -> enum ImGuiTabItemFlags_ // Flags: for BeginTabItem()
|
||||
typedef int ImGuiTreeNodeFlags; // -> enum ImGuiTreeNodeFlags_ // Flags: for TreeNode(), TreeNodeEx(), CollapsingHeader()
|
||||
@ -332,8 +334,8 @@ namespace ImGui
|
||||
// Windows Scrolling
|
||||
IMGUI_API float GetScrollX(); // get scrolling amount [0..GetScrollMaxX()]
|
||||
IMGUI_API float GetScrollY(); // get scrolling amount [0..GetScrollMaxY()]
|
||||
IMGUI_API float GetScrollMaxX(); // get maximum scrolling amount ~~ ContentSize.X - WindowSize.X
|
||||
IMGUI_API float GetScrollMaxY(); // get maximum scrolling amount ~~ ContentSize.Y - WindowSize.Y
|
||||
IMGUI_API float GetScrollMaxX(); // get maximum scrolling amount ~~ ContentSize.x - WindowSize.x
|
||||
IMGUI_API float GetScrollMaxY(); // get maximum scrolling amount ~~ ContentSize.y - WindowSize.y
|
||||
IMGUI_API void SetScrollX(float scroll_x); // set scrolling amount [0..GetScrollMaxX()]
|
||||
IMGUI_API void SetScrollY(float scroll_y); // set scrolling amount [0..GetScrollMaxY()]
|
||||
IMGUI_API void SetScrollHereX(float center_x_ratio = 0.5f); // adjust scrolling amount to make current cursor position visible. center_x_ratio=0.0: left, 0.5: center, 1.0: right. When using to make a "default/current item" visible, consider using SetItemDefaultFocus() instead.
|
||||
@ -437,7 +439,7 @@ namespace ImGui
|
||||
// - You may also use one of the many IsItemXXX functions (e.g. IsItemActive, IsItemHovered, etc.) to query widget state.
|
||||
IMGUI_API bool Button(const char* label, const ImVec2& size = ImVec2(0, 0)); // button
|
||||
IMGUI_API bool SmallButton(const char* label); // button with FramePadding=(0,0) to easily embed within text
|
||||
IMGUI_API bool InvisibleButton(const char* str_id, const ImVec2& size); // button behavior without the visuals, frequently useful to build custom behaviors using the public api (along with IsItemActive, IsItemHovered, etc.)
|
||||
IMGUI_API bool InvisibleButton(const char* str_id, const ImVec2& size, ImGuiButtonFlags flags = 0); // flexible button behavior without the visuals, frequently useful to build custom behaviors using the public api (along with IsItemActive, IsItemHovered, etc.)
|
||||
IMGUI_API bool ArrowButton(const char* str_id, ImGuiDir dir); // square button with an arrow shape
|
||||
IMGUI_API void Image(ImTextureID user_texture_id, const ImVec2& size, const ImVec2& uv0 = ImVec2(0, 0), const ImVec2& uv1 = ImVec2(1,1), const ImVec4& tint_col = ImVec4(1,1,1,1), const ImVec4& border_col = ImVec4(0,0,0,0));
|
||||
IMGUI_API bool ImageButton(ImTextureID user_texture_id, const ImVec2& size, const ImVec2& uv0 = ImVec2(0, 0), const ImVec2& uv1 = ImVec2(1,1), int frame_padding = -1, const ImVec4& bg_col = ImVec4(0,0,0,0), const ImVec4& tint_col = ImVec4(1,1,1,1)); // <0 frame_padding uses default frame padding settings. 0 for no padding
|
||||
@ -446,7 +448,7 @@ namespace ImGui
|
||||
IMGUI_API bool RadioButton(const char* label, bool active); // use with e.g. if (RadioButton("one", my_value==1)) { my_value = 1; }
|
||||
IMGUI_API bool RadioButton(const char* label, int* v, int v_button); // shortcut to handle the above pattern when value is an integer
|
||||
IMGUI_API void ProgressBar(float fraction, const ImVec2& size_arg = ImVec2(-1, 0), const char* overlay = NULL);
|
||||
IMGUI_API void Bullet(); // draw a small circle and keep the cursor on the same line. advance cursor x position by GetTreeNodeToLabelSpacing(), same distance that TreeNode() uses
|
||||
IMGUI_API void Bullet(); // draw a small circle + keep the cursor on the same line. advance cursor x position by GetTreeNodeToLabelSpacing(), same distance that TreeNode() uses
|
||||
|
||||
// Widgets: Combo Box
|
||||
// - The BeginCombo()/EndCombo() api allows you to manage your contents and selection state however you want it, by creating e.g. Selectable() items.
|
||||
@ -457,44 +459,50 @@ namespace ImGui
|
||||
IMGUI_API bool Combo(const char* label, int* current_item, const char* items_separated_by_zeros, int popup_max_height_in_items = -1); // Separate items with \0 within a string, end item-list with \0\0. e.g. "One\0Two\0Three\0"
|
||||
IMGUI_API bool Combo(const char* label, int* current_item, bool(*items_getter)(void* data, int idx, const char** out_text), void* data, int items_count, int popup_max_height_in_items = -1);
|
||||
|
||||
// Widgets: Drags
|
||||
// Widgets: Drag Sliders
|
||||
// - CTRL+Click on any drag box to turn them into an input box. Manually input values aren't clamped and can go off-bounds.
|
||||
// - For all the Float2/Float3/Float4/Int2/Int3/Int4 versions of every functions, note that a 'float v[X]' function argument is the same as 'float* v', the array syntax is just a way to document the number of elements that are expected to be accessible. You can pass address of your first element out of a contiguous set, e.g. &myvector.x
|
||||
// - Adjust format string to decorate the value with a prefix, a suffix, or adapt the editing and display precision e.g. "%.3f" -> 1.234; "%5.2f secs" -> 01.23 secs; "Biscuit: %.0f" -> Biscuit: 1; etc.
|
||||
// - Format string may also be set to NULL or use the default format ("%f" or "%d").
|
||||
// - Speed are per-pixel of mouse movement (v_speed=0.2f: mouse needs to move by 5 pixels to increase value by 1). For gamepad/keyboard navigation, minimum speed is Max(v_speed, minimum_step_at_given_precision).
|
||||
// - Use v_min < v_max to clamp edits to given limits. Note that CTRL+Click manual input can override those limits.
|
||||
// - Use v_max = FLT_MAX / INT_MAX etc to avoid clamping to a maximum, same with v_min = -FLT_MAX / INT_MIN to avoid clamping to a minimum.
|
||||
// - Use v_min > v_max to lock edits.
|
||||
IMGUI_API bool DragFloat(const char* label, float* v, float v_speed = 1.0f, float v_min = 0.0f, float v_max = 0.0f, const char* format = "%.3f", float power = 1.0f); // If v_min >= v_max we have no bound
|
||||
IMGUI_API bool DragFloat2(const char* label, float v[2], float v_speed = 1.0f, float v_min = 0.0f, float v_max = 0.0f, const char* format = "%.3f", float power = 1.0f);
|
||||
IMGUI_API bool DragFloat3(const char* label, float v[3], float v_speed = 1.0f, float v_min = 0.0f, float v_max = 0.0f, const char* format = "%.3f", float power = 1.0f);
|
||||
IMGUI_API bool DragFloat4(const char* label, float v[4], float v_speed = 1.0f, float v_min = 0.0f, float v_max = 0.0f, const char* format = "%.3f", float power = 1.0f);
|
||||
IMGUI_API bool DragFloatRange2(const char* label, float* v_current_min, float* v_current_max, float v_speed = 1.0f, float v_min = 0.0f, float v_max = 0.0f, const char* format = "%.3f", const char* format_max = NULL, float power = 1.0f);
|
||||
IMGUI_API bool DragInt(const char* label, int* v, float v_speed = 1.0f, int v_min = 0, int v_max = 0, const char* format = "%d"); // If v_min >= v_max we have no bound
|
||||
IMGUI_API bool DragInt2(const char* label, int v[2], float v_speed = 1.0f, int v_min = 0, int v_max = 0, const char* format = "%d");
|
||||
IMGUI_API bool DragInt3(const char* label, int v[3], float v_speed = 1.0f, int v_min = 0, int v_max = 0, const char* format = "%d");
|
||||
IMGUI_API bool DragInt4(const char* label, int v[4], float v_speed = 1.0f, int v_min = 0, int v_max = 0, const char* format = "%d");
|
||||
IMGUI_API bool DragIntRange2(const char* label, int* v_current_min, int* v_current_max, float v_speed = 1.0f, int v_min = 0, int v_max = 0, const char* format = "%d", const char* format_max = NULL);
|
||||
IMGUI_API bool DragScalar(const char* label, ImGuiDataType data_type, void* p_data, float v_speed, const void* p_min = NULL, const void* p_max = NULL, const char* format = NULL, float power = 1.0f);
|
||||
IMGUI_API bool DragScalarN(const char* label, ImGuiDataType data_type, void* p_data, int components, float v_speed, const void* p_min = NULL, const void* p_max = NULL, const char* format = NULL, float power = 1.0f);
|
||||
// - We use the same sets of flags for DragXXX() and SliderXXX() functions as the features are the same and it makes it easier to swap them.
|
||||
// - Legacy: Pre-1.78 there are DragXXX() function signatures that takes a final `float power=1.0f' argument instead of the `ImGuiSliderFlags flags=0' argument.
|
||||
// If you get a warning converting a float to ImGuiSliderFlags, read https://github.com/ocornut/imgui/issues/3361
|
||||
IMGUI_API bool DragFloat(const char* label, float* v, float v_speed = 1.0f, float v_min = 0.0f, float v_max = 0.0f, const char* format = "%.3f", ImGuiSliderFlags flags = 0); // If v_min >= v_max we have no bound
|
||||
IMGUI_API bool DragFloat2(const char* label, float v[2], float v_speed = 1.0f, float v_min = 0.0f, float v_max = 0.0f, const char* format = "%.3f", ImGuiSliderFlags flags = 0);
|
||||
IMGUI_API bool DragFloat3(const char* label, float v[3], float v_speed = 1.0f, float v_min = 0.0f, float v_max = 0.0f, const char* format = "%.3f", ImGuiSliderFlags flags = 0);
|
||||
IMGUI_API bool DragFloat4(const char* label, float v[4], float v_speed = 1.0f, float v_min = 0.0f, float v_max = 0.0f, const char* format = "%.3f", ImGuiSliderFlags flags = 0);
|
||||
IMGUI_API bool DragFloatRange2(const char* label, float* v_current_min, float* v_current_max, float v_speed = 1.0f, float v_min = 0.0f, float v_max = 0.0f, const char* format = "%.3f", const char* format_max = NULL, ImGuiSliderFlags flags = 0);
|
||||
IMGUI_API bool DragInt(const char* label, int* v, float v_speed = 1.0f, int v_min = 0, int v_max = 0, const char* format = "%d", ImGuiSliderFlags flags = 0); // If v_min >= v_max we have no bound
|
||||
IMGUI_API bool DragInt2(const char* label, int v[2], float v_speed = 1.0f, int v_min = 0, int v_max = 0, const char* format = "%d", ImGuiSliderFlags flags = 0);
|
||||
IMGUI_API bool DragInt3(const char* label, int v[3], float v_speed = 1.0f, int v_min = 0, int v_max = 0, const char* format = "%d", ImGuiSliderFlags flags = 0);
|
||||
IMGUI_API bool DragInt4(const char* label, int v[4], float v_speed = 1.0f, int v_min = 0, int v_max = 0, const char* format = "%d", ImGuiSliderFlags flags = 0);
|
||||
IMGUI_API bool DragIntRange2(const char* label, int* v_current_min, int* v_current_max, float v_speed = 1.0f, int v_min = 0, int v_max = 0, const char* format = "%d", const char* format_max = NULL, ImGuiSliderFlags flags = 0);
|
||||
IMGUI_API bool DragScalar(const char* label, ImGuiDataType data_type, void* p_data, float v_speed, const void* p_min = NULL, const void* p_max = NULL, const char* format = NULL, ImGuiSliderFlags flags = 0);
|
||||
IMGUI_API bool DragScalarN(const char* label, ImGuiDataType data_type, void* p_data, int components, float v_speed, const void* p_min = NULL, const void* p_max = NULL, const char* format = NULL, ImGuiSliderFlags flags = 0);
|
||||
|
||||
// Widgets: Sliders
|
||||
// Widgets: Regular Sliders
|
||||
// - CTRL+Click on any slider to turn them into an input box. Manually input values aren't clamped and can go off-bounds.
|
||||
// - Adjust format string to decorate the value with a prefix, a suffix, or adapt the editing and display precision e.g. "%.3f" -> 1.234; "%5.2f secs" -> 01.23 secs; "Biscuit: %.0f" -> Biscuit: 1; etc.
|
||||
IMGUI_API bool SliderFloat(const char* label, float* v, float v_min, float v_max, const char* format = "%.3f", float power = 1.0f); // adjust format to decorate the value with a prefix or a suffix for in-slider labels or unit display. Use power!=1.0 for power curve sliders
|
||||
IMGUI_API bool SliderFloat2(const char* label, float v[2], float v_min, float v_max, const char* format = "%.3f", float power = 1.0f);
|
||||
IMGUI_API bool SliderFloat3(const char* label, float v[3], float v_min, float v_max, const char* format = "%.3f", float power = 1.0f);
|
||||
IMGUI_API bool SliderFloat4(const char* label, float v[4], float v_min, float v_max, const char* format = "%.3f", float power = 1.0f);
|
||||
IMGUI_API bool SliderAngle(const char* label, float* v_rad, float v_degrees_min = -360.0f, float v_degrees_max = +360.0f, const char* format = "%.0f deg");
|
||||
IMGUI_API bool SliderInt(const char* label, int* v, int v_min, int v_max, const char* format = "%d");
|
||||
IMGUI_API bool SliderInt2(const char* label, int v[2], int v_min, int v_max, const char* format = "%d");
|
||||
IMGUI_API bool SliderInt3(const char* label, int v[3], int v_min, int v_max, const char* format = "%d");
|
||||
IMGUI_API bool SliderInt4(const char* label, int v[4], int v_min, int v_max, const char* format = "%d");
|
||||
IMGUI_API bool SliderScalar(const char* label, ImGuiDataType data_type, void* p_data, const void* p_min, const void* p_max, const char* format = NULL, float power = 1.0f);
|
||||
IMGUI_API bool SliderScalarN(const char* label, ImGuiDataType data_type, void* p_data, int components, const void* p_min, const void* p_max, const char* format = NULL, float power = 1.0f);
|
||||
IMGUI_API bool VSliderFloat(const char* label, const ImVec2& size, float* v, float v_min, float v_max, const char* format = "%.3f", float power = 1.0f);
|
||||
IMGUI_API bool VSliderInt(const char* label, const ImVec2& size, int* v, int v_min, int v_max, const char* format = "%d");
|
||||
IMGUI_API bool VSliderScalar(const char* label, const ImVec2& size, ImGuiDataType data_type, void* p_data, const void* p_min, const void* p_max, const char* format = NULL, float power = 1.0f);
|
||||
// - Format string may also be set to NULL or use the default format ("%f" or "%d").
|
||||
// - Legacy: Pre-1.78 there are SliderXXX() function signatures that takes a final `float power=1.0f' argument instead of the `ImGuiSliderFlags flags=0' argument.
|
||||
// If you get a warning converting a float to ImGuiSliderFlags, read https://github.com/ocornut/imgui/issues/3361
|
||||
IMGUI_API bool SliderFloat(const char* label, float* v, float v_min, float v_max, const char* format = "%.3f", ImGuiSliderFlags flags = 0); // adjust format to decorate the value with a prefix or a suffix for in-slider labels or unit display.
|
||||
IMGUI_API bool SliderFloat2(const char* label, float v[2], float v_min, float v_max, const char* format = "%.3f", ImGuiSliderFlags flags = 0);
|
||||
IMGUI_API bool SliderFloat3(const char* label, float v[3], float v_min, float v_max, const char* format = "%.3f", ImGuiSliderFlags flags = 0);
|
||||
IMGUI_API bool SliderFloat4(const char* label, float v[4], float v_min, float v_max, const char* format = "%.3f", ImGuiSliderFlags flags = 0);
|
||||
IMGUI_API bool SliderAngle(const char* label, float* v_rad, float v_degrees_min = -360.0f, float v_degrees_max = +360.0f, const char* format = "%.0f deg", ImGuiSliderFlags flags = 0);
|
||||
IMGUI_API bool SliderInt(const char* label, int* v, int v_min, int v_max, const char* format = "%d", ImGuiSliderFlags flags = 0);
|
||||
IMGUI_API bool SliderInt2(const char* label, int v[2], int v_min, int v_max, const char* format = "%d", ImGuiSliderFlags flags = 0);
|
||||
IMGUI_API bool SliderInt3(const char* label, int v[3], int v_min, int v_max, const char* format = "%d", ImGuiSliderFlags flags = 0);
|
||||
IMGUI_API bool SliderInt4(const char* label, int v[4], int v_min, int v_max, const char* format = "%d", ImGuiSliderFlags flags = 0);
|
||||
IMGUI_API bool SliderScalar(const char* label, ImGuiDataType data_type, void* p_data, const void* p_min, const void* p_max, const char* format = NULL, ImGuiSliderFlags flags = 0);
|
||||
IMGUI_API bool SliderScalarN(const char* label, ImGuiDataType data_type, void* p_data, int components, const void* p_min, const void* p_max, const char* format = NULL, ImGuiSliderFlags flags = 0);
|
||||
IMGUI_API bool VSliderFloat(const char* label, const ImVec2& size, float* v, float v_min, float v_max, const char* format = "%.3f", ImGuiSliderFlags flags = 0);
|
||||
IMGUI_API bool VSliderInt(const char* label, const ImVec2& size, int* v, int v_min, int v_max, const char* format = "%d", ImGuiSliderFlags flags = 0);
|
||||
IMGUI_API bool VSliderScalar(const char* label, const ImVec2& size, ImGuiDataType data_type, void* p_data, const void* p_min, const void* p_max, const char* format = NULL, ImGuiSliderFlags flags = 0);
|
||||
|
||||
// Widgets: Input with Keyboard
|
||||
// - If you want to use InputText() with std::string or any custom dynamic string type, see misc/cpp/imgui_stdlib.h and comments in imgui_demo.cpp.
|
||||
@ -724,7 +732,7 @@ namespace ImGui
|
||||
IMGUI_API void ColorConvertHSVtoRGB(float h, float s, float v, float& out_r, float& out_g, float& out_b);
|
||||
|
||||
// Inputs Utilities: Keyboard
|
||||
// - For 'int user_key_index' you can use your own indices/enums according to how your backend/engine stored them in io.KeysDown[].
|
||||
// - For 'int user_key_index' you can use your own indices/enums according to how your back-end/engine stored them in io.KeysDown[].
|
||||
// - We don't know the meaning of those value. You can use GetKeyIndex() to map a ImGuiKey_ value into the user index.
|
||||
IMGUI_API int GetKeyIndex(ImGuiKey imgui_key); // map ImGuiKey_* values into user's key index. == io.KeyMap[key]
|
||||
IMGUI_API bool IsKeyDown(int user_key_index); // is key being held. == io.KeysDown[user_key_index].
|
||||
@ -740,7 +748,7 @@ namespace ImGui
|
||||
IMGUI_API bool IsMouseDown(ImGuiMouseButton button); // is mouse button held?
|
||||
IMGUI_API bool IsMouseClicked(ImGuiMouseButton button, bool repeat = false); // did mouse button clicked? (went from !Down to Down)
|
||||
IMGUI_API bool IsMouseReleased(ImGuiMouseButton button); // did mouse button released? (went from Down to !Down)
|
||||
IMGUI_API bool IsMouseDoubleClicked(ImGuiMouseButton button); // did mouse button double-clicked? a double-click returns false in IsMouseClicked(). uses io.MouseDoubleClickTime.
|
||||
IMGUI_API bool IsMouseDoubleClicked(ImGuiMouseButton button); // did mouse button double-clicked? (note that a double-click will also report IsMouseClicked() == true)
|
||||
IMGUI_API bool IsMouseHoveringRect(const ImVec2& r_min, const ImVec2& r_max, bool clip = true);// is mouse hovering given bounding rect (in screen space). clipped by current clipping settings, but disregarding of other consideration of focus/window ordering/popup-block.
|
||||
IMGUI_API bool IsMousePosValid(const ImVec2* mouse_pos = NULL); // by convention we use (-FLT_MAX,-FLT_MAX) to denote that there is no mouse available
|
||||
IMGUI_API bool IsAnyMouseDown(); // is any mouse button held?
|
||||
@ -878,6 +886,7 @@ enum ImGuiTreeNodeFlags_
|
||||
// small flags values as a mouse button index, so we encode the mouse button in the first few bits of the flags.
|
||||
// It is therefore guaranteed to be legal to pass a mouse button index in ImGuiPopupFlags.
|
||||
// - For the same reason, we exceptionally default the ImGuiPopupFlags argument of BeginPopupContextXXX functions to 1 instead of 0.
|
||||
// - Multiple buttons currently cannot be combined/or-ed in those functions (we could allow it later).
|
||||
enum ImGuiPopupFlags_
|
||||
{
|
||||
ImGuiPopupFlags_None = 0,
|
||||
@ -1222,6 +1231,19 @@ enum ImGuiStyleVar_
|
||||
#endif
|
||||
};
|
||||
|
||||
// Flags for InvisibleButton() [extended in imgui_internal.h]
|
||||
enum ImGuiButtonFlags_
|
||||
{
|
||||
ImGuiButtonFlags_None = 0,
|
||||
ImGuiButtonFlags_MouseButtonLeft = 1 << 0, // React on left mouse button (default)
|
||||
ImGuiButtonFlags_MouseButtonRight = 1 << 1, // React on right mouse button
|
||||
ImGuiButtonFlags_MouseButtonMiddle = 1 << 2, // React on center mouse button
|
||||
|
||||
// [Internal]
|
||||
ImGuiButtonFlags_MouseButtonMask_ = ImGuiButtonFlags_MouseButtonLeft | ImGuiButtonFlags_MouseButtonRight | ImGuiButtonFlags_MouseButtonMiddle,
|
||||
ImGuiButtonFlags_MouseButtonDefault_ = ImGuiButtonFlags_MouseButtonLeft
|
||||
};
|
||||
|
||||
// Flags for ColorEdit3() / ColorEdit4() / ColorPicker3() / ColorPicker4() / ColorButton()
|
||||
enum ImGuiColorEditFlags_
|
||||
{
|
||||
@ -1268,6 +1290,18 @@ enum ImGuiColorEditFlags_
|
||||
#endif
|
||||
};
|
||||
|
||||
// Flags for DragFloat(), DragInt(), SliderFloat(), SliderInt() etc.
|
||||
// We use the same sets of flags for DragXXX() and SliderXXX() functions as the features are the same and it makes it easier to swap them.
|
||||
enum ImGuiSliderFlags_
|
||||
{
|
||||
ImGuiSliderFlags_None = 0,
|
||||
ImGuiSliderFlags_ClampOnInput = 1 << 4, // Clamp value to min/max bounds when input manually with CTRL+Click. By default CTRL+Click allows going out of bounds.
|
||||
ImGuiSliderFlags_Logarithmic = 1 << 5, // Make the widget logarithmic (linear otherwise). Consider using ImGuiSliderFlags_NoRoundToFormat with this if using a format-string with small amount of digits.
|
||||
ImGuiSliderFlags_NoRoundToFormat = 1 << 6, // Disable rounding underlying value to match precision of the display format string (e.g. %.3f values are rounded to those 3 digits)
|
||||
ImGuiSliderFlags_NoInput = 1 << 7, // Disable CTRL+Click or Enter key allowing to input text directly into the widget
|
||||
ImGuiSliderFlags_InvalidMask_ = 0x7000000F // [Internal] We treat using those bits as being potentially a 'float power' argument from the previous API that has got miscast to this enum, and will trigger an assert if needed.
|
||||
};
|
||||
|
||||
// Identify a mouse button.
|
||||
// Those values are guaranteed to be stable and we frequently use 0/1 directly. Named enums provided for convenience.
|
||||
enum ImGuiMouseButton_
|
||||
@ -1316,16 +1350,16 @@ enum ImGuiCond_
|
||||
// Helpers: Memory allocations macros
|
||||
// IM_MALLOC(), IM_FREE(), IM_NEW(), IM_PLACEMENT_NEW(), IM_DELETE()
|
||||
// We call C++ constructor on own allocated memory via the placement "new(ptr) Type()" syntax.
|
||||
// Defining a custom placement new() with a dummy parameter allows us to bypass including <new> which on some platforms complains when user has disabled exceptions.
|
||||
// Defining a custom placement new() with a custom parameter allows us to bypass including <new> which on some platforms complains when user has disabled exceptions.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
struct ImNewDummy {};
|
||||
inline void* operator new(size_t, ImNewDummy, void* ptr) { return ptr; }
|
||||
inline void operator delete(void*, ImNewDummy, void*) {} // This is only required so we can use the symmetrical new()
|
||||
struct ImNewWrapper {};
|
||||
inline void* operator new(size_t, ImNewWrapper, void* ptr) { return ptr; }
|
||||
inline void operator delete(void*, ImNewWrapper, void*) {} // This is only required so we can use the symmetrical new()
|
||||
#define IM_ALLOC(_SIZE) ImGui::MemAlloc(_SIZE)
|
||||
#define IM_FREE(_PTR) ImGui::MemFree(_PTR)
|
||||
#define IM_PLACEMENT_NEW(_PTR) new(ImNewDummy(), _PTR)
|
||||
#define IM_NEW(_TYPE) new(ImNewDummy(), ImGui::MemAlloc(sizeof(_TYPE))) _TYPE
|
||||
#define IM_PLACEMENT_NEW(_PTR) new(ImNewWrapper(), _PTR)
|
||||
#define IM_NEW(_TYPE) new(ImNewWrapper(), ImGui::MemAlloc(sizeof(_TYPE))) _TYPE
|
||||
template<typename T> void IM_DELETE(T* p) { if (p) { p->~T(); ImGui::MemFree(p); } }
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -1429,17 +1463,19 @@ struct ImGuiStyle
|
||||
float ScrollbarRounding; // Radius of grab corners for scrollbar.
|
||||
float GrabMinSize; // Minimum width/height of a grab box for slider/scrollbar.
|
||||
float GrabRounding; // Radius of grabs corners rounding. Set to 0.0f to have rectangular slider grabs.
|
||||
float LogSliderDeadzone; // The size in pixels of the dead-zone around zero on logarithmic sliders that cross zero.
|
||||
float TabRounding; // Radius of upper corners of a tab. Set to 0.0f to have rectangular tabs.
|
||||
float TabBorderSize; // Thickness of border around tabs.
|
||||
float TabMinWidthForUnselectedCloseButton; // Minimum width for close button to appears on an unselected tab when hovered. Set to 0.0f to always show when hovering, set to FLT_MAX to never show close button unless selected.
|
||||
ImGuiDir ColorButtonPosition; // Side of the color button in the ColorEdit4 widget (left/right). Defaults to ImGuiDir_Right.
|
||||
ImVec2 ButtonTextAlign; // Alignment of button text when button is larger than text. Defaults to (0.5f, 0.5f) (centered).
|
||||
ImVec2 SelectableTextAlign; // Alignment of selectable text. Defaults to (0.0f, 0.0f) (top-left aligned). It's generally important to keep this left-aligned if you want to lay multiple items on a same line.
|
||||
ImVec2 DisplayWindowPadding; // Window position are clamped to be visible within the display area by at least this amount. Only applies to regular windows.
|
||||
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 MouseCursorScale; // Scale software rendered mouse cursor (when io.MouseDrawCursor is enabled). May be removed later.
|
||||
bool AntiAliasedLines; // Enable anti-aliasing on lines/borders. Disable if you are really tight on CPU/GPU.
|
||||
bool AntiAliasedFill; // Enable anti-aliasing on filled shapes (rounded rectangles, circles, etc.)
|
||||
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 back-end to render with bilinear filtering. Latched at the beginning of the frame (copied to ImDrawList).
|
||||
bool AntiAliasedFill; // Enable anti-aliased edges around filled shapes (rounded rectangles, circles, etc.). Disable if you are really tight on CPU/GPU. Latched at the beginning of the frame (copied to ImDrawList).
|
||||
float CurveTessellationTol; // Tessellation tolerance when using PathBezierCurveTo() without a specific number of segments. Decrease for highly tessellated curves (higher quality, more polygons), increase to reduce quality.
|
||||
float CircleSegmentMaxError; // 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];
|
||||
@ -1670,6 +1706,20 @@ struct ImGuiPayload
|
||||
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
|
||||
namespace ImGui
|
||||
{
|
||||
// OBSOLETED in 1.78 (from August 2020)
|
||||
// Old drag/sliders functions that took a 'float power = 1.0' argument instead of flags
|
||||
IMGUI_API bool DragScalar(const char* label, ImGuiDataType data_type, void* p_data, float v_speed, const void* p_min, const void* p_max, const char* format, float power);
|
||||
IMGUI_API bool DragScalarN(const char* label, ImGuiDataType data_type, void* p_data, int components, float v_speed, const void* p_min, const void* p_max, const char* format, float power);
|
||||
static inline bool DragFloat(const char* label, float* v, float v_speed, float v_min, float v_max, const char* format, float power) { return DragScalar(label, ImGuiDataType_Float, v, v_speed, &v_min, &v_max, format, power); }
|
||||
static inline bool DragFloat2(const char* label, float v[2], float v_speed, float v_min, float v_max, const char* format, float power) { return DragScalarN(label, ImGuiDataType_Float, v, 2, v_speed, &v_min, &v_max, format, power); }
|
||||
static inline bool DragFloat3(const char* label, float v[3], float v_speed, float v_min, float v_max, const char* format, float power) { return DragScalarN(label, ImGuiDataType_Float, v, 3, v_speed, &v_min, &v_max, format, power); }
|
||||
static inline bool DragFloat4(const char* label, float v[4], float v_speed, float v_min, float v_max, const char* format, float power) { return DragScalarN(label, ImGuiDataType_Float, v, 4, v_speed, &v_min, &v_max, format, power); }
|
||||
IMGUI_API bool SliderScalar(const char* label, ImGuiDataType data_type, void* p_data, const void* p_min, const void* p_max, const char* format, float power);
|
||||
IMGUI_API bool SliderScalarN(const char* label, ImGuiDataType data_type, void* p_data, int components, const void* p_min, const void* p_max, const char* format, float power);
|
||||
static inline bool SliderFloat(const char* label, float* v, float v_min, float v_max, const char* format, float power) { return SliderScalar(label, ImGuiDataType_Float, v, &v_min, &v_max, format, power); }
|
||||
static inline bool SliderFloat2(const char* label, float v[2], float v_min, float v_max, const char* format, float power) { return SliderScalarN(label, ImGuiDataType_Float, v, 2, &v_min, &v_max, format, power); }
|
||||
static inline bool SliderFloat3(const char* label, float v[3], float v_min, float v_max, const char* format, float power) { return SliderScalarN(label, ImGuiDataType_Float, v, 3, &v_min, &v_max, format, power); }
|
||||
static inline bool SliderFloat4(const char* label, float v[4], float v_min, float v_max, const char* format, float power) { return SliderScalarN(label, ImGuiDataType_Float, v, 4, &v_min, &v_max, format, power); }
|
||||
// OBSOLETED in 1.77 (from June 2020)
|
||||
static inline bool OpenPopupOnItemClick(const char* str_id = NULL, ImGuiMouseButton mb = 1) { return OpenPopupContextItem(str_id, mb); } // Passing a mouse button to ImGuiPopupFlags is legal
|
||||
static inline bool BeginPopupContextWindow(const char* str_id, ImGuiMouseButton mb, bool over_items) { return BeginPopupContextWindow(str_id, mb | (over_items ? 0 : ImGuiPopupFlags_NoOpenOverItems)); }
|
||||
@ -1828,7 +1878,7 @@ struct ImGuiStorage
|
||||
// ImGui::Text("line number %d", i);
|
||||
// - Step 0: the clipper let you process the first element, regardless of it being visible or not, so we can measure the element height (step skipped if we passed a known height as second arg to constructor).
|
||||
// - Step 1: the clipper infer height from first element, calculate the actual range of elements to display, and position the cursor before the first element.
|
||||
// - (Step 2: dummy step only required if an explicit items_height was passed to constructor or Begin() and user call Step(). Does nothing and switch to Step 3.)
|
||||
// - (Step 2: empty step only required if an explicit items_height was passed to constructor or Begin() and user call Step(). Does nothing and switch to Step 3.)
|
||||
// - Step 3: the clipper validate that we have reached the expected Y position (corresponding to element DisplayEnd), advance the cursor to the end of the list and then returns 'false' to end the loop.
|
||||
struct ImGuiListClipper
|
||||
{
|
||||
@ -1896,6 +1946,11 @@ struct ImColor
|
||||
// Hold a series of drawing commands. The user provides a renderer for ImDrawData which essentially contains an array of ImDrawList.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// The maximum line width to bake anti-aliased textures for. Build atlas with ImFontAtlasFlags_NoBakedLines to disable baking.
|
||||
#ifndef IM_DRAWLIST_TEX_LINES_WIDTH_MAX
|
||||
#define IM_DRAWLIST_TEX_LINES_WIDTH_MAX (63)
|
||||
#endif
|
||||
|
||||
// ImDrawCallback: Draw callbacks for advanced uses [configurable type: override in imconfig.h]
|
||||
// NB: You most likely do NOT need to use draw callbacks just to create your own widget or customized UI rendering,
|
||||
// you can poke into the draw list for that! Draw callback may be useful for example to:
|
||||
@ -1992,12 +2047,15 @@ enum ImDrawCornerFlags_
|
||||
ImDrawCornerFlags_All = 0xF // In your function calls you may use ~0 (= all bits sets) instead of ImDrawCornerFlags_All, as a convenience
|
||||
};
|
||||
|
||||
// Flags for ImDrawList. Those are set automatically by ImGui:: functions from ImGuiIO settings, and generally not manipulated directly.
|
||||
// It is however possible to temporarily alter flags between calls to ImDrawList:: functions.
|
||||
enum ImDrawListFlags_
|
||||
{
|
||||
ImDrawListFlags_None = 0,
|
||||
ImDrawListFlags_AntiAliasedLines = 1 << 0, // Lines are anti-aliased (*2 the number of triangles for 1.0f wide line, otherwise *3 the number of triangles)
|
||||
ImDrawListFlags_AntiAliasedFill = 1 << 1, // Filled shapes have anti-aliased edges (*2 the number of vertices)
|
||||
ImDrawListFlags_AllowVtxOffset = 1 << 2 // Can emit 'VtxOffset > 0' to allow large meshes. Set when 'ImGuiBackendFlags_RendererHasVtxOffset' is enabled.
|
||||
ImDrawListFlags_AntiAliasedLines = 1 << 0, // Enable anti-aliased lines/borders (*2 the number of triangles for 1.0f wide line or lines thin enough to be drawn using textures, otherwise *3 the number of triangles)
|
||||
ImDrawListFlags_AntiAliasedLinesUseTex = 1 << 1, // Enable anti-aliased lines/borders using textures when possible. Require back-end to render with bilinear filtering.
|
||||
ImDrawListFlags_AntiAliasedFill = 1 << 2, // Enable anti-aliased edge around filled shapes (rounded rectangles, circles).
|
||||
ImDrawListFlags_AllowVtxOffset = 1 << 3 // Can emit 'VtxOffset > 0' to allow large meshes. Set when 'ImGuiBackendFlags_RendererHasVtxOffset' is enabled.
|
||||
};
|
||||
|
||||
// Draw command list
|
||||
@ -2043,6 +2101,7 @@ struct ImDrawList
|
||||
// Primitives
|
||||
// - For rectangular primitives, "p_min" and "p_max" represent the upper-left and lower-right corners.
|
||||
// - For circle primitives, use "num_segments == 0" to automatically calculate tessellation (preferred).
|
||||
// In older versions (until Dear ImGui 1.77) the AddCircle functions defaulted to num_segments == 12.
|
||||
// In future versions we will use textures to provide cheaper and higher-quality circles.
|
||||
// Use AddNgon() and AddNgonFilled() functions if you need to guaranteed a specific number of sides.
|
||||
IMGUI_API void AddLine(const ImVec2& p1, const ImVec2& p2, ImU32 col, float thickness = 1.0f);
|
||||
@ -2053,8 +2112,8 @@ struct ImDrawList
|
||||
IMGUI_API void AddQuadFilled(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, ImU32 col);
|
||||
IMGUI_API void AddTriangle(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, ImU32 col, float thickness = 1.0f);
|
||||
IMGUI_API void AddTriangleFilled(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, ImU32 col);
|
||||
IMGUI_API void AddCircle(const ImVec2& center, float radius, ImU32 col, int num_segments = 12, float thickness = 1.0f);
|
||||
IMGUI_API void AddCircleFilled(const ImVec2& center, float radius, ImU32 col, int num_segments = 12);
|
||||
IMGUI_API void AddCircle(const ImVec2& center, float radius, ImU32 col, int num_segments = 0, float thickness = 1.0f);
|
||||
IMGUI_API void AddCircleFilled(const ImVec2& center, float radius, ImU32 col, int num_segments = 0);
|
||||
IMGUI_API void AddNgon(const ImVec2& center, float radius, ImU32 col, int num_segments, float thickness = 1.0f);
|
||||
IMGUI_API void AddNgonFilled(const ImVec2& center, float radius, ImU32 col, int num_segments);
|
||||
IMGUI_API void AddText(const ImVec2& pos, ImU32 col, const char* text_begin, const char* text_end = NULL);
|
||||
@ -2211,11 +2270,13 @@ struct ImFontAtlasCustomRect
|
||||
bool IsPacked() const { return X != 0xFFFF; }
|
||||
};
|
||||
|
||||
// Flags for ImFontAtlas build
|
||||
enum ImFontAtlasFlags_
|
||||
{
|
||||
ImFontAtlasFlags_None = 0,
|
||||
ImFontAtlasFlags_NoPowerOfTwoHeight = 1 << 0, // Don't round the height to next power of two
|
||||
ImFontAtlasFlags_NoMouseCursors = 1 << 1 // Don't build software mouse cursors into the atlas
|
||||
ImFontAtlasFlags_NoMouseCursors = 1 << 1, // Don't build software mouse cursors into the atlas (save a little texture memory)
|
||||
ImFontAtlasFlags_NoBakedLines = 1 << 2 // Don't build thick line textures into the atlas (save a little texture memory). The AntiAliasedLinesUseTex features uses them, otherwise they will be rendered using polygons (more expensive for CPU/GPU).
|
||||
};
|
||||
|
||||
// Load and rasterize multiple TTF/OTF fonts into a same texture. The font atlas will build a single texture holding:
|
||||
@ -2289,7 +2350,7 @@ struct ImFontAtlas
|
||||
// Note: this API may be redesigned later in order to support multi-monitor varying DPI settings.
|
||||
IMGUI_API int AddCustomRectRegular(int width, int height);
|
||||
IMGUI_API int AddCustomRectFontGlyph(ImFont* font, ImWchar id, int width, int height, float advance_x, const ImVec2& offset = ImVec2(0, 0));
|
||||
const ImFontAtlasCustomRect*GetCustomRectByIndex(int index) const { if (index < 0) return NULL; return &CustomRects[index]; }
|
||||
ImFontAtlasCustomRect* GetCustomRectByIndex(int index) { IM_ASSERT(index >= 0); return &CustomRects[index]; }
|
||||
|
||||
// [Internal]
|
||||
IMGUI_API void CalcCustomRectUV(const ImFontAtlasCustomRect* rect, ImVec2* out_uv_min, ImVec2* out_uv_max) const;
|
||||
@ -2315,8 +2376,12 @@ struct ImFontAtlas
|
||||
ImVec2 TexUvWhitePixel; // Texture coordinates to a white pixel
|
||||
ImVector<ImFont*> Fonts; // Hold all the fonts returned by AddFont*. Fonts[0] is the default font upon calling ImGui::NewFrame(), use ImGui::PushFont()/PopFont() to change the current font.
|
||||
ImVector<ImFontAtlasCustomRect> CustomRects; // Rectangles for packing custom texture data into the atlas.
|
||||
ImVector<ImFontConfig> ConfigData; // Internal data
|
||||
int CustomRectIds[1]; // Identifiers of custom texture rectangle used by ImFontAtlas/ImDrawList
|
||||
ImVector<ImFontConfig> ConfigData; // Configuration data
|
||||
ImVec4 TexUvLines[IM_DRAWLIST_TEX_LINES_WIDTH_MAX + 1]; // UVs for baked anti-aliased lines
|
||||
|
||||
// [Internal] Packing data
|
||||
int PackIdMouseCursors; // Custom texture rectangle ID for white pixel and mouse cursors
|
||||
int PackIdLines; // Custom texture rectangle ID for baked anti-aliased lines
|
||||
|
||||
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
|
||||
typedef ImFontAtlasCustomRect CustomRect; // OBSOLETED in 1.72+
|
||||
@ -2371,7 +2436,7 @@ struct ImFont
|
||||
IMGUI_API void BuildLookupTable();
|
||||
IMGUI_API void ClearOutputData();
|
||||
IMGUI_API void GrowIndex(int new_size);
|
||||
IMGUI_API void AddGlyph(ImWchar c, float x0, float y0, float x1, float y1, float u0, float v0, float u1, float v1, float advance_x);
|
||||
IMGUI_API void AddGlyph(ImFontConfig* src_cfg, ImWchar c, float x0, float y0, float x1, float y1, float u0, float v0, float u1, float v1, float advance_x);
|
||||
IMGUI_API void AddRemapChar(ImWchar dst, ImWchar src, bool overwrite_dst = true); // Makes 'dst' character/glyph points to 'src' character/glyph. Currently needs to be called AFTER fonts have been built.
|
||||
IMGUI_API void SetGlyphVisible(ImWchar c, bool visible);
|
||||
IMGUI_API void SetFallbackChar(ImWchar c);
|
||||
|
377
imgui_demo.cpp
377
imgui_demo.cpp
@ -1,4 +1,4 @@
|
||||
// dear imgui, v1.77
|
||||
// dear imgui, v1.78
|
||||
// (demo code)
|
||||
|
||||
// Help:
|
||||
@ -228,8 +228,8 @@ void ImGui::ShowDemoWindow(bool* p_open)
|
||||
IM_ASSERT(ImGui::GetCurrentContext() != NULL && "Missing dear imgui context. Refer to examples app!");
|
||||
|
||||
// Examples Apps (accessible from the "Examples" menu)
|
||||
static bool show_app_documents = false;
|
||||
static bool show_app_main_menu_bar = false;
|
||||
static bool show_app_documents = false;
|
||||
static bool show_app_console = false;
|
||||
static bool show_app_log = false;
|
||||
static bool show_app_layout = false;
|
||||
@ -241,8 +241,9 @@ void ImGui::ShowDemoWindow(bool* p_open)
|
||||
static bool show_app_window_titles = false;
|
||||
static bool show_app_custom_rendering = false;
|
||||
|
||||
if (show_app_documents) ShowExampleAppDocuments(&show_app_documents);
|
||||
if (show_app_main_menu_bar) ShowExampleAppMainMenuBar();
|
||||
if (show_app_documents) ShowExampleAppDocuments(&show_app_documents);
|
||||
|
||||
if (show_app_console) ShowExampleAppConsole(&show_app_console);
|
||||
if (show_app_log) ShowExampleAppLog(&show_app_log);
|
||||
if (show_app_layout) ShowExampleAppLayout(&show_app_layout);
|
||||
@ -405,6 +406,7 @@ void ImGui::ShowDemoWindow(bool* p_open)
|
||||
ImGui::Checkbox("io.ConfigWindowsMoveFromTitleBarOnly", &io.ConfigWindowsMoveFromTitleBarOnly);
|
||||
ImGui::Checkbox("io.MouseDrawCursor", &io.MouseDrawCursor);
|
||||
ImGui::SameLine(); HelpMarker("Instruct Dear ImGui to render a mouse cursor itself. Note that a mouse cursor rendered via your application GPU rendering path will feel more laggy than hardware cursor, but will be more in sync with your other visuals.\n\nSome desktop applications may use both kinds of cursors (e.g. enable software cursor only when resizing/dragging something).");
|
||||
ImGui::Text("Also see Style->Rendering for rendering options.");
|
||||
ImGui::TreePop();
|
||||
ImGui::Separator();
|
||||
}
|
||||
@ -627,7 +629,7 @@ static void ShowDemoWindowWidgets()
|
||||
|
||||
static float f1 = 0.123f, f2 = 0.0f;
|
||||
ImGui::SliderFloat("slider float", &f1, 0.0f, 1.0f, "ratio = %.3f");
|
||||
ImGui::SliderFloat("slider float (curve)", &f2, -10.0f, 10.0f, "%.4f", 2.0f);
|
||||
ImGui::SliderFloat("slider float (log)", &f2, -10.0f, 10.0f, "%.4f", ImGuiSliderFlags_Logarithmic);
|
||||
|
||||
static float angle = 0.0f;
|
||||
ImGui::SliderAngle("slider angle", &angle);
|
||||
@ -1241,7 +1243,7 @@ static void ShowDemoWindowWidgets()
|
||||
static float arr[] = { 0.6f, 0.1f, 1.0f, 0.5f, 0.92f, 0.1f, 0.2f };
|
||||
ImGui::PlotLines("Frame Times", arr, IM_ARRAYSIZE(arr));
|
||||
|
||||
// Create a dummy array of contiguous float values to plot
|
||||
// Fill an array of contiguous float values to plot
|
||||
// Tip: If your float aren't contiguous but part of a structure, you can pass a pointer to your first float
|
||||
// and the sizeof() of your structure in the "stride" parameter.
|
||||
static float values[90] = {};
|
||||
@ -1249,7 +1251,7 @@ static void ShowDemoWindowWidgets()
|
||||
static double refresh_time = 0.0;
|
||||
if (!animate || refresh_time == 0.0)
|
||||
refresh_time = ImGui::GetTime();
|
||||
while (refresh_time < ImGui::GetTime()) // Create dummy data at fixed 60 Hz rate for the demo
|
||||
while (refresh_time < ImGui::GetTime()) // Create data at fixed 60 Hz rate for the demo
|
||||
{
|
||||
static float phase = 0.0f;
|
||||
values[values_offset] = cosf(phase);
|
||||
@ -1349,7 +1351,7 @@ static void ShowDemoWindowWidgets()
|
||||
|
||||
ImGui::Text("Color button with Custom Picker Popup:");
|
||||
|
||||
// Generate a dummy default palette. The palette will persist and can be edited.
|
||||
// Generate a default palette. The palette will persist and can be edited.
|
||||
static bool saved_palette_init = true;
|
||||
static ImVec4 saved_palette[32] = {};
|
||||
if (saved_palette_init)
|
||||
@ -1486,11 +1488,45 @@ static void ShowDemoWindowWidgets()
|
||||
ImGui::TreePop();
|
||||
}
|
||||
|
||||
if (ImGui::TreeNode("Drag/Slider Flags"))
|
||||
{
|
||||
// Demonstrate using advanced flags for DragXXX and SliderXXX functions. Note that the flags are the same!
|
||||
static ImGuiSliderFlags flags = ImGuiSliderFlags_None;
|
||||
ImGui::CheckboxFlags("ImGuiSliderFlags_ClampOnInput", (unsigned int*)&flags, ImGuiSliderFlags_ClampOnInput);
|
||||
ImGui::SameLine(); HelpMarker("Always clamp value to min/max bounds (if any) when input manually with CTRL+Click.");
|
||||
ImGui::CheckboxFlags("ImGuiSliderFlags_Logarithmic", (unsigned int*)&flags, ImGuiSliderFlags_Logarithmic);
|
||||
ImGui::SameLine(); HelpMarker("Enable logarithmic editing (more precision for small values).");
|
||||
ImGui::CheckboxFlags("ImGuiSliderFlags_NoRoundToFormat", (unsigned int*)&flags, ImGuiSliderFlags_NoRoundToFormat);
|
||||
ImGui::SameLine(); HelpMarker("Disable rounding underlying value to match precision of the format string (e.g. %.3f values are rounded to those 3 digits).");
|
||||
ImGui::CheckboxFlags("ImGuiSliderFlags_NoInput", (unsigned int*)&flags, ImGuiSliderFlags_NoInput);
|
||||
ImGui::SameLine(); HelpMarker("Disable CTRL+Click or Enter key allowing to input text directly into the widget.");
|
||||
|
||||
// Drags
|
||||
static float drag_f = 0.5f;
|
||||
static int drag_i = 50;
|
||||
ImGui::Text("Underlying float value: %f", drag_f);
|
||||
ImGui::DragFloat("DragFloat (0 -> 1)", &drag_f, 0.005f, 0.0f, 1.0f, "%.3f", flags);
|
||||
ImGui::DragFloat("DragFloat (0 -> +inf)", &drag_f, 0.005f, 0.0f, FLT_MAX, "%.3f", flags);
|
||||
ImGui::DragFloat("DragFloat (-inf -> 1)", &drag_f, 0.005f, -FLT_MAX, 1.0f, "%.3f", flags);
|
||||
ImGui::DragFloat("DragFloat (-inf -> +inf)", &drag_f, 0.005f, -FLT_MAX, +FLT_MAX, "%.3f", flags);
|
||||
ImGui::DragInt("DragInt (0 -> 100)", &drag_i, 0.5f, 0, 100, "%d", flags);
|
||||
|
||||
// Sliders
|
||||
static float slider_f = 0.5f;
|
||||
static int slider_i = 50;
|
||||
ImGui::Text("Underlying float value: %f", slider_f);
|
||||
ImGui::SliderFloat("SliderFloat (0 -> 1)", &slider_f, 0.0f, 1.0f, "%.3f", flags);
|
||||
ImGui::SliderInt("SliderInt (0 -> 100)", &slider_i, 0, 100, "%.3f", flags);
|
||||
|
||||
ImGui::TreePop();
|
||||
}
|
||||
|
||||
if (ImGui::TreeNode("Range Widgets"))
|
||||
{
|
||||
static float begin = 10, end = 90;
|
||||
static int begin_i = 100, end_i = 1000;
|
||||
ImGui::DragFloatRange2("range", &begin, &end, 0.25f, 0.0f, 100.0f, "Min: %.1f %%", "Max: %.1f %%");
|
||||
ImGui::DragFloatRange2("range float", &begin, &end, 0.25f, 0.0f, 100.0f, "Min: %.1f %%", "Max: %.1f %%", ImGuiSliderFlags_ClampOnInput);
|
||||
ImGui::DragIntRange2("range int", &begin_i, &end_i, 5, 0, 1000, "Min: %d units", "Max: %d units");
|
||||
ImGui::DragIntRange2("range int (no bounds)", &begin_i, &end_i, 5, 0, 0, "Min: %d units", "Max: %d units");
|
||||
ImGui::TreePop();
|
||||
}
|
||||
@ -1554,10 +1590,10 @@ static void ShowDemoWindowWidgets()
|
||||
ImGui::DragScalar("drag u32", ImGuiDataType_U32, &u32_v, drag_speed, drag_clamp ? &u32_zero : NULL, drag_clamp ? &u32_fifty : NULL, "%u ms");
|
||||
ImGui::DragScalar("drag s64", ImGuiDataType_S64, &s64_v, drag_speed, drag_clamp ? &s64_zero : NULL, drag_clamp ? &s64_fifty : NULL);
|
||||
ImGui::DragScalar("drag u64", ImGuiDataType_U64, &u64_v, drag_speed, drag_clamp ? &u64_zero : NULL, drag_clamp ? &u64_fifty : NULL);
|
||||
ImGui::DragScalar("drag float", ImGuiDataType_Float, &f32_v, 0.005f, &f32_zero, &f32_one, "%f", 1.0f);
|
||||
ImGui::DragScalar("drag float ^2", ImGuiDataType_Float, &f32_v, 0.005f, &f32_zero, &f32_one, "%f", 2.0f); ImGui::SameLine(); HelpMarker("You can use the 'power' parameter to increase tweaking precision on one side of the range.");
|
||||
ImGui::DragScalar("drag double", ImGuiDataType_Double, &f64_v, 0.0005f, &f64_zero, NULL, "%.10f grams", 1.0f);
|
||||
ImGui::DragScalar("drag double ^2", ImGuiDataType_Double, &f64_v, 0.0005f, &f64_zero, &f64_one, "0 < %.10f < 1", 2.0f);
|
||||
ImGui::DragScalar("drag float", ImGuiDataType_Float, &f32_v, 0.005f, &f32_zero, &f32_one, "%f");
|
||||
ImGui::DragScalar("drag float log", ImGuiDataType_Float, &f32_v, 0.005f, &f32_zero, &f32_one, "%f", ImGuiSliderFlags_Logarithmic);
|
||||
ImGui::DragScalar("drag double", ImGuiDataType_Double, &f64_v, 0.0005f, &f64_zero, NULL, "%.10f grams");
|
||||
ImGui::DragScalar("drag double log",ImGuiDataType_Double, &f64_v, 0.0005f, &f64_zero, &f64_one, "0 < %.10f < 1", ImGuiSliderFlags_Logarithmic);
|
||||
|
||||
ImGui::Text("Sliders");
|
||||
ImGui::SliderScalar("slider s8 full", ImGuiDataType_S8, &s8_v, &s8_min, &s8_max, "%d");
|
||||
@ -1577,11 +1613,11 @@ static void ShowDemoWindowWidgets()
|
||||
ImGui::SliderScalar("slider u64 high", ImGuiDataType_U64, &u64_v, &u64_hi_a, &u64_hi_b, "%I64u ms");
|
||||
ImGui::SliderScalar("slider u64 full", ImGuiDataType_U64, &u64_v, &u64_min, &u64_max, "%I64u ms");
|
||||
ImGui::SliderScalar("slider float low", ImGuiDataType_Float, &f32_v, &f32_zero, &f32_one);
|
||||
ImGui::SliderScalar("slider float low^2", ImGuiDataType_Float, &f32_v, &f32_zero, &f32_one, "%.10f", 2.0f);
|
||||
ImGui::SliderScalar("slider float low log", ImGuiDataType_Float, &f32_v, &f32_zero, &f32_one, "%.10f", ImGuiSliderFlags_Logarithmic);
|
||||
ImGui::SliderScalar("slider float high", ImGuiDataType_Float, &f32_v, &f32_lo_a, &f32_hi_a, "%e");
|
||||
ImGui::SliderScalar("slider double low", ImGuiDataType_Double, &f64_v, &f64_zero, &f64_one, "%.10f grams", 1.0f);
|
||||
ImGui::SliderScalar("slider double low^2",ImGuiDataType_Double, &f64_v, &f64_zero, &f64_one, "%.10f", 2.0f);
|
||||
ImGui::SliderScalar("slider double high", ImGuiDataType_Double, &f64_v, &f64_lo_a, &f64_hi_a, "%e grams", 1.0f);
|
||||
ImGui::SliderScalar("slider double low", ImGuiDataType_Double, &f64_v, &f64_zero, &f64_one, "%.10f grams");
|
||||
ImGui::SliderScalar("slider double low log",ImGuiDataType_Double, &f64_v, &f64_zero, &f64_one, "%.10f", ImGuiSliderFlags_Logarithmic);
|
||||
ImGui::SliderScalar("slider double high", ImGuiDataType_Double, &f64_v, &f64_lo_a, &f64_hi_a, "%e grams");
|
||||
|
||||
static bool inputs_step = true;
|
||||
ImGui::Text("Inputs");
|
||||
@ -1929,8 +1965,8 @@ static void ShowDemoWindowWidgets()
|
||||
if (embed_all_inside_a_child_window)
|
||||
ImGui::EndChild();
|
||||
|
||||
static char dummy_str[] = "This is a dummy field to be able to tab-out of the widgets above.";
|
||||
ImGui::InputText("dummy", dummy_str, IM_ARRAYSIZE(dummy_str), ImGuiInputTextFlags_ReadOnly);
|
||||
static char unused_str[] = "This widget is only here to be able to tab-out of the widgets above.";
|
||||
ImGui::InputText("unused", unused_str, IM_ARRAYSIZE(unused_str), ImGuiInputTextFlags_ReadOnly);
|
||||
|
||||
// Calling IsItemHovered() after begin returns the hovered status of the title bar.
|
||||
// This is useful in particular if you want to create a context menu associated to the title bar of a window.
|
||||
@ -1957,7 +1993,7 @@ static void ShowDemoWindowWidgets()
|
||||
|
||||
static void ShowDemoWindowLayout()
|
||||
{
|
||||
if (!ImGui::CollapsingHeader("Layout"))
|
||||
if (!ImGui::CollapsingHeader("Layout & Scrolling"))
|
||||
return;
|
||||
|
||||
if (ImGui::TreeNode("Child windows"))
|
||||
@ -1968,12 +2004,6 @@ static void ShowDemoWindowLayout()
|
||||
ImGui::Checkbox("Disable Mouse Wheel", &disable_mouse_wheel);
|
||||
ImGui::Checkbox("Disable Menu", &disable_menu);
|
||||
|
||||
static int line = 50;
|
||||
bool goto_line = ImGui::Button("Goto");
|
||||
ImGui::SameLine();
|
||||
ImGui::SetNextItemWidth(100);
|
||||
goto_line |= ImGui::InputInt("##Line", &line, 0, 0, ImGuiInputTextFlags_EnterReturnsTrue);
|
||||
|
||||
// Child 1: no border, enable horizontal scrollbar
|
||||
{
|
||||
ImGuiWindowFlags window_flags = ImGuiWindowFlags_HorizontalScrollbar;
|
||||
@ -1981,13 +2011,7 @@ static void ShowDemoWindowLayout()
|
||||
window_flags |= ImGuiWindowFlags_NoScrollWithMouse;
|
||||
ImGui::BeginChild("ChildL", ImVec2(ImGui::GetWindowContentRegionWidth() * 0.5f, 260), false, window_flags);
|
||||
for (int i = 0; i < 100; i++)
|
||||
{
|
||||
ImGui::Text("%04d: scrollable region", i);
|
||||
if (goto_line && line == i)
|
||||
ImGui::SetScrollHereY();
|
||||
}
|
||||
if (goto_line && line >= 100)
|
||||
ImGui::SetScrollHereY();
|
||||
ImGui::EndChild();
|
||||
}
|
||||
|
||||
@ -2033,15 +2057,21 @@ static void ShowDemoWindowLayout()
|
||||
// - Using ImGui::GetItemRectMin/Max() to query the "item" state (because the child window is an item from
|
||||
// the POV of the parent window). See 'Demo->Querying Status (Active/Focused/Hovered etc.)' for details.
|
||||
{
|
||||
ImGui::SetCursorPosX(ImGui::GetCursorPosX() + 10);
|
||||
static int offset_x = 0;
|
||||
ImGui::SetNextItemWidth(100);
|
||||
ImGui::DragInt("Offset X", &offset_x, 1.0f, -1000, 1000);
|
||||
|
||||
ImGui::SetCursorPosX(ImGui::GetCursorPosX() + (float)offset_x);
|
||||
ImGui::PushStyleColor(ImGuiCol_ChildBg, IM_COL32(255, 0, 0, 100));
|
||||
ImGui::BeginChild("Red", ImVec2(200, 100), true, ImGuiWindowFlags_None);
|
||||
for (int n = 0; n < 50; n++)
|
||||
ImGui::Text("Some test %d", n);
|
||||
ImGui::EndChild();
|
||||
bool child_is_hovered = ImGui::IsItemHovered();
|
||||
ImVec2 child_rect_min = ImGui::GetItemRectMin();
|
||||
ImVec2 child_rect_max = ImGui::GetItemRectMax();
|
||||
ImGui::PopStyleColor();
|
||||
ImGui::Text("Hovered: %d", child_is_hovered);
|
||||
ImGui::Text("Rect of child window is: (%.0f,%.0f) (%.0f,%.0f)", child_rect_min.x, child_rect_min.y, child_rect_max.x, child_rect_max.y);
|
||||
}
|
||||
|
||||
@ -2379,7 +2409,7 @@ static void ShowDemoWindowLayout()
|
||||
ImGui::SameLine(0.0f, spacing);
|
||||
if (ImGui::TreeNode("Node##1"))
|
||||
{
|
||||
// Dummy tree data
|
||||
// Placeholder tree data
|
||||
for (int i = 0; i < 6; i++)
|
||||
ImGui::BulletText("Item %d..", i);
|
||||
ImGui::TreePop();
|
||||
@ -2395,7 +2425,7 @@ static void ShowDemoWindowLayout()
|
||||
ImGui::SameLine(0.0f, spacing); ImGui::Button("Button##2");
|
||||
if (node_open)
|
||||
{
|
||||
// Dummy tree data
|
||||
// Placeholder tree data
|
||||
for (int i = 0; i < 6; i++)
|
||||
ImGui::BulletText("Item %d..", i);
|
||||
ImGui::TreePop();
|
||||
@ -2427,8 +2457,6 @@ static void ShowDemoWindowLayout()
|
||||
static float scroll_to_pos_px = 200.0f;
|
||||
|
||||
ImGui::Checkbox("Decoration", &enable_extra_decorations);
|
||||
ImGui::SameLine();
|
||||
HelpMarker("We expose this for testing because scrolling sometimes had issues with window decoration such as menu-bars.");
|
||||
|
||||
ImGui::Checkbox("Track", &enable_track);
|
||||
ImGui::PushItemWidth(100);
|
||||
@ -2495,11 +2523,9 @@ static void ShowDemoWindowLayout()
|
||||
ImGui::Spacing();
|
||||
HelpMarker(
|
||||
"Use SetScrollHereX() or SetScrollFromPosX() to scroll to a given horizontal position.\n\n"
|
||||
"Using the \"Scroll To Pos\" button above will make the discontinuity at edges visible: "
|
||||
"scrolling to the top/bottom/left/right-most item will add an additional WindowPadding to reflect "
|
||||
"on reaching the edge of the list.\n\nBecause the clipping rectangle of most window hides half "
|
||||
"worth of WindowPadding on the left/right, using SetScrollFromPosX(+1) will usually result in "
|
||||
"clipped text whereas the equivalent SetScrollFromPosY(+1) wouldn't.");
|
||||
"Because the clipping rectangle of most window hides half worth of WindowPadding on the "
|
||||
"left/right, using SetScrollFromPosX(+1) will usually result in clipped text whereas the "
|
||||
"equivalent SetScrollFromPosY(+1) wouldn't.");
|
||||
ImGui::PushID("##HorizontalScrolling");
|
||||
for (int i = 0; i < 5; i++)
|
||||
{
|
||||
@ -2689,23 +2715,66 @@ static void ShowDemoWindowLayout()
|
||||
|
||||
if (ImGui::TreeNode("Clipping"))
|
||||
{
|
||||
static ImVec2 size(100, 100), offset(50, 20);
|
||||
ImGui::TextWrapped(
|
||||
"On a per-widget basis we are occasionally clipping text CPU-side if it won't fit in its frame. "
|
||||
"Otherwise we are doing coarser clipping + passing a scissor rectangle to the renderer. "
|
||||
"The system is designed to try minimizing both execution and CPU/GPU rendering cost.");
|
||||
static ImVec2 size(100.0f, 100.0f);
|
||||
static ImVec2 offset(30.0f, 30.0f);
|
||||
ImGui::DragFloat2("size", (float*)&size, 0.5f, 1.0f, 200.0f, "%.0f");
|
||||
ImGui::TextWrapped("(Click and drag)");
|
||||
ImVec2 pos = ImGui::GetCursorScreenPos();
|
||||
ImVec4 clip_rect(pos.x, pos.y, pos.x + size.x, pos.y + size.y);
|
||||
ImGui::InvisibleButton("##dummy", size);
|
||||
if (ImGui::IsItemActive() && ImGui::IsMouseDragging(0))
|
||||
ImGui::TextWrapped("(Click and drag to scroll)");
|
||||
|
||||
for (int n = 0; n < 3; n++)
|
||||
{
|
||||
if (n > 0)
|
||||
ImGui::SameLine();
|
||||
ImGui::PushID(n);
|
||||
ImGui::BeginGroup(); // Lock X position
|
||||
|
||||
ImGui::InvisibleButton("##empty", size);
|
||||
if (ImGui::IsItemActive() && ImGui::IsMouseDragging(ImGuiMouseButton_Left))
|
||||
{
|
||||
offset.x += ImGui::GetIO().MouseDelta.x;
|
||||
offset.y += ImGui::GetIO().MouseDelta.y;
|
||||
}
|
||||
ImGui::GetWindowDrawList()->AddRectFilled(pos, ImVec2(pos.x + size.x, pos.y + size.y), IM_COL32(90, 90, 120, 255));
|
||||
ImGui::GetWindowDrawList()->AddText(ImGui::GetFont(), ImGui::GetFontSize()*2.0f, ImVec2(pos.x + offset.x, pos.y + offset.y), IM_COL32_WHITE, "Line 1 hello\nLine 2 clip me!", NULL, 0.0f, &clip_rect);
|
||||
const ImVec2 p0 = ImGui::GetItemRectMin();
|
||||
const ImVec2 p1 = ImGui::GetItemRectMax();
|
||||
const char* text_str = "Line 1 hello\nLine 2 clip me!";
|
||||
const ImVec2 text_pos = ImVec2(p0.x + offset.x, p0.y + offset.y);
|
||||
ImDrawList* draw_list = ImGui::GetWindowDrawList();
|
||||
|
||||
switch (n)
|
||||
{
|
||||
case 0:
|
||||
HelpMarker(
|
||||
"Using ImGui::PushClipRect():\n"
|
||||
"Will alter ImGui hit-testing logic + ImDrawList rendering.\n"
|
||||
"(use this if you want your clipping rectangle to affect interactions)");
|
||||
ImGui::PushClipRect(p0, p1, true);
|
||||
draw_list->AddRectFilled(p0, p1, IM_COL32(90, 90, 120, 255));
|
||||
draw_list->AddText(text_pos, IM_COL32_WHITE, text_str);
|
||||
ImGui::PopClipRect();
|
||||
break;
|
||||
case 1:
|
||||
HelpMarker(
|
||||
"Using ImDrawList::PushClipRect():\n"
|
||||
"Will alter ImDrawList rendering only.\n"
|
||||
"(use this as a shortcut if you are only using ImDrawList calls)");
|
||||
draw_list->PushClipRect(p0, p1, true);
|
||||
draw_list->AddRectFilled(p0, p1, IM_COL32(90, 90, 120, 255));
|
||||
draw_list->AddText(text_pos, IM_COL32_WHITE, text_str);
|
||||
draw_list->PopClipRect();
|
||||
break;
|
||||
case 2:
|
||||
HelpMarker(
|
||||
"Using ImDrawList::AddText() with a fine ClipRect:\n"
|
||||
"Will alter only this specific ImDrawList::AddText() rendering.\n"
|
||||
"(this is often used internally to avoid altering the clipping rectangle and minimize draw calls)");
|
||||
ImVec4 clip_rect(p0.x, p0.y, p1.x, p1.y); // AddText() takes a ImVec4* here so let's convert.
|
||||
draw_list->AddRectFilled(p0, p1, IM_COL32(90, 90, 120, 255));
|
||||
draw_list->AddText(ImGui::GetFont(), ImGui::GetFontSize(), text_pos, IM_COL32_WHITE, text_str, NULL, 0.0f, &clip_rect);
|
||||
break;
|
||||
}
|
||||
ImGui::EndGroup();
|
||||
ImGui::PopID();
|
||||
}
|
||||
|
||||
ImGui::TreePop();
|
||||
}
|
||||
}
|
||||
@ -2874,8 +2943,8 @@ static void ShowDemoWindowPopups()
|
||||
ImGui::Text("All those beautiful files will be deleted.\nThis operation cannot be undone!\n\n");
|
||||
ImGui::Separator();
|
||||
|
||||
//static int dummy_i = 0;
|
||||
//ImGui::Combo("Combo", &dummy_i, "Delete\0Delete harder\0");
|
||||
//static int unused_i = 0;
|
||||
//ImGui::Combo("Combo", &unused_i, "Delete\0Delete harder\0");
|
||||
|
||||
static bool dont_ask_me_next_time = false;
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0, 0));
|
||||
@ -2897,7 +2966,7 @@ static void ShowDemoWindowPopups()
|
||||
{
|
||||
if (ImGui::BeginMenu("File"))
|
||||
{
|
||||
if (ImGui::MenuItem("Dummy menu item")) {}
|
||||
if (ImGui::MenuItem("Some menu item")) {}
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
ImGui::EndMenuBar();
|
||||
@ -2916,8 +2985,8 @@ static void ShowDemoWindowPopups()
|
||||
// Also demonstrate passing a bool* to BeginPopupModal(), this will create a regular close button which
|
||||
// will close the popup. Note that the visibility state of popups is owned by imgui, so the input value
|
||||
// of the bool actually doesn't matter here.
|
||||
bool dummy_open = true;
|
||||
if (ImGui::BeginPopupModal("Stacked 2", &dummy_open))
|
||||
bool unused_open = true;
|
||||
if (ImGui::BeginPopupModal("Stacked 2", &unused_open))
|
||||
{
|
||||
ImGui::Text("Hello from Stacked The Second!");
|
||||
if (ImGui::Button("Close"))
|
||||
@ -3252,7 +3321,7 @@ static void ShowDemoWindowMisc()
|
||||
if (ImGui::TreeNode("Tabbing"))
|
||||
{
|
||||
ImGui::Text("Use TAB/SHIFT+TAB to cycle through keyboard editable fields.");
|
||||
static char buf[32] = "dummy";
|
||||
static char buf[32] = "hello";
|
||||
ImGui::InputText("1", buf, IM_ARRAYSIZE(buf));
|
||||
ImGui::InputText("2", buf, IM_ARRAYSIZE(buf));
|
||||
ImGui::InputText("3", buf, IM_ARRAYSIZE(buf));
|
||||
@ -3706,6 +3775,7 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref)
|
||||
ImGui::SliderFloat("PopupRounding", &style.PopupRounding, 0.0f, 12.0f, "%.0f");
|
||||
ImGui::SliderFloat("ScrollbarRounding", &style.ScrollbarRounding, 0.0f, 12.0f, "%.0f");
|
||||
ImGui::SliderFloat("GrabRounding", &style.GrabRounding, 0.0f, 12.0f, "%.0f");
|
||||
ImGui::SliderFloat("LogSliderDeadzone", &style.LogSliderDeadzone, 0.0f, 12.0f, "%.0f");
|
||||
ImGui::SliderFloat("TabRounding", &style.TabRounding, 0.0f, 12.0f, "%.0f");
|
||||
ImGui::Text("Alignment");
|
||||
ImGui::SliderFloat2("WindowTitleAlign", (float*)&style.WindowTitleAlign, 0.0f, 1.0f, "%.2f");
|
||||
@ -3817,10 +3887,9 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref)
|
||||
"rebuild the font atlas, and call style.ScaleAllSizes() on a reference ImGuiStyle structure.\n"
|
||||
"Using those settings here will give you poor quality results.");
|
||||
static float window_scale = 1.0f;
|
||||
if (ImGui::DragFloat("window scale", &window_scale, 0.005f, MIN_SCALE, MAX_SCALE, "%.2f")) // Scale only this window
|
||||
ImGui::SetWindowFontScale(IM_MAX(window_scale, MIN_SCALE));
|
||||
if (ImGui::DragFloat("global scale", &io.FontGlobalScale, 0.005f, MIN_SCALE, MAX_SCALE, "%.2f")) // Scale everything
|
||||
io.FontGlobalScale = IM_MAX(io.FontGlobalScale, MIN_SCALE);
|
||||
if (ImGui::DragFloat("window scale", &window_scale, 0.005f, MIN_SCALE, MAX_SCALE, "%.2f", ImGuiSliderFlags_ClampOnInput)) // Scale only this window
|
||||
ImGui::SetWindowFontScale(window_scale);
|
||||
ImGui::DragFloat("global scale", &io.FontGlobalScale, 0.005f, MIN_SCALE, MAX_SCALE, "%.2f", ImGuiSliderFlags_ClampOnInput); // Scale everything
|
||||
ImGui::PopItemWidth();
|
||||
|
||||
ImGui::EndTabItem();
|
||||
@ -3830,11 +3899,34 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref)
|
||||
{
|
||||
ImGui::Checkbox("Anti-aliased lines", &style.AntiAliasedLines);
|
||||
ImGui::SameLine(); HelpMarker("When disabling anti-aliasing lines, you'll probably want to disable borders in your style as well.");
|
||||
ImGui::Checkbox("Anti-aliased lines use texture", &style.AntiAliasedLinesUseTex);
|
||||
ImGui::SameLine(); HelpMarker("Faster lines using texture data. Require back-end to render with bilinear filtering (not point/nearest filtering).");
|
||||
ImGui::Checkbox("Anti-aliased fill", &style.AntiAliasedFill);
|
||||
ImGui::PushItemWidth(100);
|
||||
ImGui::DragFloat("Curve Tessellation Tolerance", &style.CurveTessellationTol, 0.02f, 0.10f, 10.0f, "%.2f");
|
||||
if (style.CurveTessellationTol < 0.10f) style.CurveTessellationTol = 0.10f;
|
||||
ImGui::DragFloat("Circle segment Max Error", &style.CircleSegmentMaxError, 0.01f, 0.10f, 10.0f, "%.2f");
|
||||
|
||||
// When editing the "Circle Segment Max Error" value, draw a preview of its effect on auto-tessellated circles.
|
||||
ImGui::DragFloat("Circle Segment Max Error", &style.CircleSegmentMaxError, 0.01f, 0.10f, 10.0f, "%.2f");
|
||||
if (ImGui::IsItemActive())
|
||||
{
|
||||
ImGui::SetNextWindowPos(ImGui::GetCursorScreenPos());
|
||||
ImGui::BeginTooltip();
|
||||
ImVec2 p = ImGui::GetCursorScreenPos();
|
||||
float RAD_MIN = 10.0f, RAD_MAX = 80.0f;
|
||||
float off_x = 10.0f;
|
||||
for (int n = 0; n < 7; n++)
|
||||
{
|
||||
const float rad = RAD_MIN + (RAD_MAX - RAD_MIN) * (float)n / (7.0f - 1.0f);
|
||||
ImGui::GetWindowDrawList()->AddCircle(ImVec2(p.x + off_x + rad, p.y + RAD_MAX), rad, ImGui::GetColorU32(ImGuiCol_Text), 0);
|
||||
off_x += 10.0f + rad * 2.0f;
|
||||
}
|
||||
ImGui::Dummy(ImVec2(off_x, RAD_MAX * 2.0f));
|
||||
ImGui::EndTooltip();
|
||||
}
|
||||
ImGui::SameLine();
|
||||
HelpMarker("When drawing circle primitives with \"num_segments == 0\" tesselation will be calculated automatically.");
|
||||
|
||||
ImGui::DragFloat("Global Alpha", &style.Alpha, 0.005f, 0.20f, 1.0f, "%.2f"); // Not exposing zero here so user doesn't "lose" the UI (zero alpha clips all widgets). But application code could have a toggle to switch between zero and non-zero.
|
||||
ImGui::PopItemWidth();
|
||||
|
||||
@ -3885,7 +3977,7 @@ static void ShowExampleAppMainMenuBar()
|
||||
// (future version will add explicit flags to BeginMenu() to request processing shortcuts)
|
||||
static void ShowExampleMenuFile()
|
||||
{
|
||||
ImGui::MenuItem("(dummy menu)", NULL, false, false);
|
||||
ImGui::MenuItem("(demo menu)", NULL, false, false);
|
||||
if (ImGui::MenuItem("New")) {}
|
||||
if (ImGui::MenuItem("Open", "Ctrl+O")) {}
|
||||
if (ImGui::BeginMenu("Open Recent"))
|
||||
@ -4049,8 +4141,8 @@ struct ExampleAppConsole
|
||||
|
||||
// TODO: display items starting from the bottom
|
||||
|
||||
if (ImGui::SmallButton("Add Dummy Text")) { AddLog("%d some text", Items.Size); AddLog("some more text"); AddLog("display very important message here!"); } ImGui::SameLine();
|
||||
if (ImGui::SmallButton("Add Dummy Error")) { AddLog("[error] something went wrong"); } ImGui::SameLine();
|
||||
if (ImGui::SmallButton("Add Debug Text")) { AddLog("%d some text", Items.Size); AddLog("some more text"); AddLog("display very important message here!"); } ImGui::SameLine();
|
||||
if (ImGui::SmallButton("Add Debug Error")) { AddLog("[error] something went wrong"); } ImGui::SameLine();
|
||||
if (ImGui::SmallButton("Clear")) { ClearLog(); } ImGui::SameLine();
|
||||
bool copy_to_clipboard = ImGui::SmallButton("Copy");
|
||||
//static float t = 0.0f; if (ImGui::GetTime() - t > 0.02f) { t = ImGui::GetTime(); AddLog("Spam %f", t); }
|
||||
@ -4540,7 +4632,7 @@ static void ShowExampleAppLayout(bool* p_open)
|
||||
// [SECTION] Example App: Property Editor / ShowExampleAppPropertyEditor()
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
static void ShowDummyObject(const char* prefix, int uid)
|
||||
static void ShowPlaceholderObject(const char* prefix, int uid)
|
||||
{
|
||||
// Use object uid as identifier. Most commonly you could also use the object pointer as a base ID.
|
||||
ImGui::PushID(uid);
|
||||
@ -4552,13 +4644,13 @@ static void ShowDummyObject(const char* prefix, int uid)
|
||||
ImGui::NextColumn();
|
||||
if (node_open)
|
||||
{
|
||||
static float dummy_members[8] = { 0.0f,0.0f,1.0f,3.1416f,100.0f,999.0f };
|
||||
static float placeholder_members[8] = { 0.0f, 0.0f, 1.0f, 3.1416f, 100.0f, 999.0f };
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
ImGui::PushID(i); // Use field index as identifier.
|
||||
if (i < 2)
|
||||
{
|
||||
ShowDummyObject("Child", 424242);
|
||||
ShowPlaceholderObject("Child", 424242);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -4569,9 +4661,9 @@ static void ShowDummyObject(const char* prefix, int uid)
|
||||
ImGui::NextColumn();
|
||||
ImGui::SetNextItemWidth(-1);
|
||||
if (i >= 5)
|
||||
ImGui::InputFloat("##value", &dummy_members[i], 1.0f);
|
||||
ImGui::InputFloat("##value", &placeholder_members[i], 1.0f);
|
||||
else
|
||||
ImGui::DragFloat("##value", &dummy_members[i], 0.01f);
|
||||
ImGui::DragFloat("##value", &placeholder_members[i], 0.01f);
|
||||
ImGui::NextColumn();
|
||||
}
|
||||
ImGui::PopID();
|
||||
@ -4601,9 +4693,9 @@ static void ShowExampleAppPropertyEditor(bool* p_open)
|
||||
ImGui::Columns(2);
|
||||
ImGui::Separator();
|
||||
|
||||
// Iterate dummy objects with dummy members (all the same data)
|
||||
// Iterate placeholder objects (all the same data)
|
||||
for (int obj_i = 0; obj_i < 3; obj_i++)
|
||||
ShowDummyObject("Object", obj_i);
|
||||
ShowPlaceholderObject("Object", obj_i);
|
||||
|
||||
ImGui::Columns(1);
|
||||
ImGui::Separator();
|
||||
@ -4841,31 +4933,32 @@ static void ShowExampleAppCustomRendering(bool* p_open)
|
||||
// overloaded operators, etc. Define IM_VEC2_CLASS_EXTRA in imconfig.h to create implicit conversions between your
|
||||
// types and ImVec2/ImVec4. Dear ImGui defines overloaded operators but they are internal to imgui.cpp and not
|
||||
// exposed outside (to avoid messing with your types) In this example we are not using the maths operators!
|
||||
ImDrawList* draw_list = ImGui::GetWindowDrawList();
|
||||
|
||||
if (ImGui::BeginTabBar("##TabBar"))
|
||||
{
|
||||
if (ImGui::BeginTabItem("Primitives"))
|
||||
{
|
||||
ImGui::PushItemWidth(-ImGui::GetFontSize() * 10);
|
||||
ImDrawList* draw_list = ImGui::GetWindowDrawList();
|
||||
|
||||
// Draw gradients
|
||||
// (note that those are currently exacerbating our sRGB/Linear issues)
|
||||
// Calling ImGui::GetColorU32() multiplies the given colors by the current Style Alpha, but you may pass the IM_COL32() directly as well..
|
||||
ImGui::Text("Gradients");
|
||||
ImVec2 gradient_size = ImVec2(ImGui::CalcItemWidth(), ImGui::GetFrameHeight());
|
||||
{
|
||||
ImVec2 p0 = ImGui::GetCursorScreenPos();
|
||||
ImVec2 p1 = ImVec2(p0.x + gradient_size.x, p0.y + gradient_size.y);
|
||||
ImU32 col_a = ImGui::GetColorU32(ImVec4(0.0f, 0.0f, 0.0f, 1.0f));
|
||||
ImU32 col_b = ImGui::GetColorU32(ImVec4(1.0f, 1.0f, 1.0f, 1.0f));
|
||||
ImU32 col_a = ImGui::GetColorU32(IM_COL32(0, 0, 0, 255));
|
||||
ImU32 col_b = ImGui::GetColorU32(IM_COL32(255, 255, 255, 255));
|
||||
draw_list->AddRectFilledMultiColor(p0, p1, col_a, col_b, col_b, col_a);
|
||||
ImGui::InvisibleButton("##gradient1", gradient_size);
|
||||
}
|
||||
{
|
||||
ImVec2 p0 = ImGui::GetCursorScreenPos();
|
||||
ImVec2 p1 = ImVec2(p0.x + gradient_size.x, p0.y + gradient_size.y);
|
||||
ImU32 col_a = ImGui::GetColorU32(ImVec4(0.0f, 1.0f, 0.0f, 1.0f));
|
||||
ImU32 col_b = ImGui::GetColorU32(ImVec4(1.0f, 0.0f, 0.0f, 1.0f));
|
||||
ImU32 col_a = ImGui::GetColorU32(IM_COL32(0, 255, 0, 255));
|
||||
ImU32 col_b = ImGui::GetColorU32(IM_COL32(255, 0, 0, 255));
|
||||
draw_list->AddRectFilledMultiColor(p0, p1, col_a, col_b, col_b, col_a);
|
||||
ImGui::InvisibleButton("##gradient2", gradient_size);
|
||||
}
|
||||
@ -4886,6 +4979,7 @@ static void ShowExampleAppCustomRendering(bool* p_open)
|
||||
if (ImGui::SliderInt("Circle segments", &circle_segments_override_v, 3, 40))
|
||||
circle_segments_override = true;
|
||||
ImGui::ColorEdit4("Color", &colf.x);
|
||||
|
||||
const ImVec2 p = ImGui::GetCursorScreenPos();
|
||||
const ImU32 col = ImColor(colf);
|
||||
const float spacing = 10.0f;
|
||||
@ -4893,7 +4987,8 @@ static void ShowExampleAppCustomRendering(bool* p_open)
|
||||
const ImDrawCornerFlags corners_all = ImDrawCornerFlags_All;
|
||||
const ImDrawCornerFlags corners_tl_br = ImDrawCornerFlags_TopLeft | ImDrawCornerFlags_BotRight;
|
||||
const int circle_segments = circle_segments_override ? circle_segments_override_v : 0;
|
||||
float x = p.x + 4.0f, y = p.y + 4.0f;
|
||||
float x = p.x + 4.0f;
|
||||
float y = p.y + 4.0f;
|
||||
for (int n = 0; n < 2; n++)
|
||||
{
|
||||
// First line uses a thickness of 1.0f, second line uses the configurable thickness
|
||||
@ -4904,7 +4999,7 @@ static void ShowExampleAppCustomRendering(bool* p_open)
|
||||
draw_list->AddRect(ImVec2(x, y), ImVec2(x + sz, y + sz), col, 10.0f, corners_all, th); x += sz + spacing; // Square with all rounded corners
|
||||
draw_list->AddRect(ImVec2(x, y), ImVec2(x + sz, y + sz), col, 10.0f, corners_tl_br, th); x += sz + spacing; // Square with two rounded corners
|
||||
draw_list->AddTriangle(ImVec2(x+sz*0.5f,y), ImVec2(x+sz, y+sz-0.5f), ImVec2(x, y+sz-0.5f), col, th);x += sz + spacing; // Triangle
|
||||
draw_list->AddTriangle(ImVec2(x+sz*0.2f,y), ImVec2(x, y+sz-0.5f), ImVec2(x+sz*0.4f, y+sz-0.5f), col, th); x += sz*0.4f + spacing; // Thin triangle
|
||||
//draw_list->AddTriangle(ImVec2(x+sz*0.2f,y), ImVec2(x, y+sz-0.5f), ImVec2(x+sz*0.4f, y+sz-0.5f), col, th);x+= sz*0.4f + spacing; // Thin triangle
|
||||
draw_list->AddLine(ImVec2(x, y), ImVec2(x + sz, y), col, th); x += sz + spacing; // Horizontal line (note: drawing a filled rectangle will be faster!)
|
||||
draw_list->AddLine(ImVec2(x, y), ImVec2(x, y + sz), col, th); x += spacing; // Vertical line (note: drawing a filled rectangle will be faster!)
|
||||
draw_list->AddLine(ImVec2(x, y), ImVec2(x + sz, y + sz), col, th); x += sz + spacing; // Diagonal line
|
||||
@ -4918,13 +5013,13 @@ static void ShowExampleAppCustomRendering(bool* p_open)
|
||||
draw_list->AddRectFilled(ImVec2(x, y), ImVec2(x + sz, y + sz), col, 10.0f); x += sz + spacing; // Square with all rounded corners
|
||||
draw_list->AddRectFilled(ImVec2(x, y), ImVec2(x + sz, y + sz), col, 10.0f, corners_tl_br); x += sz + spacing; // Square with two rounded corners
|
||||
draw_list->AddTriangleFilled(ImVec2(x+sz*0.5f,y), ImVec2(x+sz, y+sz-0.5f), ImVec2(x, y+sz-0.5f), col); x += sz + spacing; // Triangle
|
||||
draw_list->AddTriangleFilled(ImVec2(x+sz*0.2f,y), ImVec2(x, y+sz-0.5f), ImVec2(x+sz*0.4f, y+sz-0.5f), col); x += sz*0.4f + spacing; // Thin triangle
|
||||
//draw_list->AddTriangleFilled(ImVec2(x+sz*0.2f,y), ImVec2(x, y+sz-0.5f), ImVec2(x+sz*0.4f, y+sz-0.5f), col); x += sz*0.4f + spacing; // Thin triangle
|
||||
draw_list->AddRectFilled(ImVec2(x, y), ImVec2(x + sz, y + thickness), col); x += sz + spacing; // Horizontal line (faster than AddLine, but only handle integer thickness)
|
||||
draw_list->AddRectFilled(ImVec2(x, y), ImVec2(x + thickness, y + sz), col); x += spacing * 2.0f;// Vertical line (faster than AddLine, but only handle integer thickness)
|
||||
draw_list->AddRectFilled(ImVec2(x, y), ImVec2(x + 1, y + 1), col); x += sz; // Pixel (faster than AddLine)
|
||||
draw_list->AddRectFilledMultiColor(ImVec2(x, y), ImVec2(x + sz, y + sz), IM_COL32(0, 0, 0, 255), IM_COL32(255, 0, 0, 255), IM_COL32(255, 255, 0, 255), IM_COL32(0, 255, 0, 255));
|
||||
ImGui::Dummy(ImVec2((sz + spacing) * 9.8f, (sz + spacing) * 3));
|
||||
|
||||
ImGui::Dummy(ImVec2((sz + spacing) * 8.8f, (sz + spacing) * 3.0f));
|
||||
ImGui::PopItemWidth();
|
||||
ImGui::EndTabItem();
|
||||
}
|
||||
@ -4932,55 +5027,97 @@ static void ShowExampleAppCustomRendering(bool* p_open)
|
||||
if (ImGui::BeginTabItem("Canvas"))
|
||||
{
|
||||
static ImVector<ImVec2> points;
|
||||
static ImVec2 scrolling(0.0f, 0.0f);
|
||||
static bool opt_enable_grid = true;
|
||||
static bool opt_enable_context_menu = true;
|
||||
static bool adding_line = false;
|
||||
if (ImGui::Button("Clear")) points.clear();
|
||||
if (points.Size >= 2) { ImGui::SameLine(); if (ImGui::Button("Undo")) { points.pop_back(); points.pop_back(); } }
|
||||
ImGui::Text("Left-click and drag to add lines,\nRight-click to undo");
|
||||
|
||||
// Here we are using InvisibleButton() as a convenience to 1) advance the cursor and 2) allows us to use
|
||||
// IsItemHovered(). But you can also draw directly and poll mouse/keyboard by yourself.
|
||||
// You can manipulate the cursor using GetCursorPos() and SetCursorPos().
|
||||
// If you only use the ImDrawList API, you can notify the owner window of its extends with SetCursorPos(max).
|
||||
ImVec2 canvas_p = ImGui::GetCursorScreenPos(); // ImDrawList API uses screen coordinates!
|
||||
ImGui::Checkbox("Enable grid", &opt_enable_grid);
|
||||
ImGui::Checkbox("Enable context menu", &opt_enable_context_menu);
|
||||
ImGui::Text("Mouse Left: drag to add lines,\nMouse Right: drag to scroll, click for context menu.");
|
||||
|
||||
// Typically you would use a BeginChild()/EndChild() pair to benefit from a clipping region + own scrolling.
|
||||
// Here we demonstrate that this can be replaced by simple offsetting + custom drawing + PushClipRect/PopClipRect() calls.
|
||||
// To use a child window instead we could use, e.g:
|
||||
// ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0, 0)); // Disable padding
|
||||
// ImGui::PushStyleColor(ImGuiCol_ChildBg, IM_COL32(50, 50, 50, 255)); // Set a background color
|
||||
// ImGui::BeginChild("canvas", ImVec2(0.0f, 0.0f), true, ImGuiWindowFlags_NoMove);
|
||||
// ImGui::PopStyleColor();
|
||||
// ImGui::PopStyleVar();
|
||||
// [...]
|
||||
// ImGui::EndChild();
|
||||
|
||||
// Using InvisibleButton() as a convenience 1) it will advance the layout cursor and 2) allows us to use IsItemHovered()/IsItemActive()
|
||||
ImVec2 canvas_p0 = ImGui::GetCursorScreenPos(); // ImDrawList API uses screen coordinates!
|
||||
ImVec2 canvas_sz = ImGui::GetContentRegionAvail(); // Resize canvas to what's available
|
||||
if (canvas_sz.x < 50.0f) canvas_sz.x = 50.0f;
|
||||
if (canvas_sz.y < 50.0f) canvas_sz.y = 50.0f;
|
||||
draw_list->AddRectFilledMultiColor(canvas_p, ImVec2(canvas_p.x + canvas_sz.x, canvas_p.y + canvas_sz.y), IM_COL32(50, 50, 50, 255), IM_COL32(50, 50, 60, 255), IM_COL32(60, 60, 70, 255), IM_COL32(50, 50, 60, 255));
|
||||
draw_list->AddRect(canvas_p, ImVec2(canvas_p.x + canvas_sz.x, canvas_p.y + canvas_sz.y), IM_COL32(255, 255, 255, 255));
|
||||
ImVec2 canvas_p1 = ImVec2(canvas_p0.x + canvas_sz.x, canvas_p0.y + canvas_sz.y);
|
||||
|
||||
bool adding_preview = false;
|
||||
ImGui::InvisibleButton("canvas", canvas_sz);
|
||||
ImVec2 mouse_pos_global = ImGui::GetIO().MousePos;
|
||||
ImVec2 mouse_pos_canvas = ImVec2(mouse_pos_global.x - canvas_p.x, mouse_pos_global.y - canvas_p.y);
|
||||
if (adding_line)
|
||||
// Draw border and background color
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
ImDrawList* draw_list = ImGui::GetWindowDrawList();
|
||||
draw_list->AddRectFilled(canvas_p0, canvas_p1, IM_COL32(50, 50, 50, 255));
|
||||
draw_list->AddRect(canvas_p0, canvas_p1, IM_COL32(255, 255, 255, 255));
|
||||
|
||||
// This will catch our interactions
|
||||
ImGui::InvisibleButton("canvas", canvas_sz, ImGuiButtonFlags_MouseButtonLeft | ImGuiButtonFlags_MouseButtonRight);
|
||||
const bool is_hovered = ImGui::IsItemHovered(); // Hovered
|
||||
const bool is_active = ImGui::IsItemActive(); // Held
|
||||
const ImVec2 origin(canvas_p0.x + scrolling.x, canvas_p0.y + scrolling.y); // Lock scrolled origin
|
||||
const ImVec2 mouse_pos_in_canvas(io.MousePos.x - origin.x, io.MousePos.y - origin.y);
|
||||
|
||||
// Add first and second point
|
||||
if (is_hovered && !adding_line && ImGui::IsMouseClicked(ImGuiMouseButton_Left))
|
||||
{
|
||||
adding_preview = true;
|
||||
points.push_back(mouse_pos_canvas);
|
||||
if (!ImGui::IsMouseDown(0))
|
||||
adding_line = adding_preview = false;
|
||||
}
|
||||
if (ImGui::IsItemHovered())
|
||||
{
|
||||
if (!adding_line && ImGui::IsMouseClicked(0))
|
||||
{
|
||||
points.push_back(mouse_pos_canvas);
|
||||
points.push_back(mouse_pos_in_canvas);
|
||||
points.push_back(mouse_pos_in_canvas);
|
||||
adding_line = true;
|
||||
}
|
||||
if (ImGui::IsMouseClicked(1) && !points.empty())
|
||||
if (adding_line)
|
||||
{
|
||||
adding_line = adding_preview = false;
|
||||
points.pop_back();
|
||||
points.pop_back();
|
||||
}
|
||||
points.back() = mouse_pos_in_canvas;
|
||||
if (!ImGui::IsMouseDown(ImGuiMouseButton_Left))
|
||||
adding_line = false;
|
||||
}
|
||||
|
||||
// Draw all lines in the canvas (with a clipping rectangle so they don't stray out of it).
|
||||
draw_list->PushClipRect(canvas_p, ImVec2(canvas_p.x + canvas_sz.x, canvas_p.y + canvas_sz.y), true);
|
||||
for (int i = 0; i < points.Size - 1; i += 2)
|
||||
draw_list->AddLine(ImVec2(canvas_p.x + points[i].x, canvas_p.y + points[i].y), ImVec2(canvas_p.x + points[i + 1].x, canvas_p.y + points[i + 1].y), IM_COL32(255, 255, 0, 255), 2.0f);
|
||||
// Pan (we use a zero mouse threshold when there's no context menu)
|
||||
// You may decide to make that threshold dynamic based on whether the mouse is hovering something etc.
|
||||
const float mouse_threshold_for_pan = opt_enable_context_menu ? -1.0f : 0.0f;
|
||||
if (is_active && ImGui::IsMouseDragging(ImGuiMouseButton_Right, mouse_threshold_for_pan))
|
||||
{
|
||||
scrolling.x += io.MouseDelta.x;
|
||||
scrolling.y += io.MouseDelta.y;
|
||||
}
|
||||
|
||||
// Context menu (under default mouse threshold)
|
||||
ImVec2 drag_delta = ImGui::GetMouseDragDelta(ImGuiMouseButton_Right);
|
||||
if (opt_enable_context_menu && ImGui::IsMouseReleased(ImGuiMouseButton_Right) && drag_delta.x == 0.0f && drag_delta.y == 0.0f)
|
||||
ImGui::OpenPopupContextItem("context");
|
||||
if (ImGui::BeginPopup("context"))
|
||||
{
|
||||
if (adding_line)
|
||||
points.resize(points.size() - 2);
|
||||
adding_line = false;
|
||||
if (ImGui::MenuItem("Remove one", NULL, false, points.Size > 0)) { points.resize(points.size() - 2); }
|
||||
if (ImGui::MenuItem("Remove all", NULL, false, points.Size > 0)) { points.clear(); }
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
|
||||
// Draw grid + all lines in the canvas
|
||||
draw_list->PushClipRect(canvas_p0, canvas_p1, true);
|
||||
if (opt_enable_grid)
|
||||
{
|
||||
const float GRID_STEP = 64.0f;
|
||||
for (float x = fmodf(scrolling.x, GRID_STEP); x < canvas_sz.x; x += GRID_STEP)
|
||||
draw_list->AddLine(ImVec2(canvas_p0.x + x, canvas_p0.y), ImVec2(canvas_p0.x + x, canvas_p1.y), IM_COL32(200, 200, 200, 40));
|
||||
for (float y = fmodf(scrolling.y, GRID_STEP); y < canvas_sz.y; y += GRID_STEP)
|
||||
draw_list->AddLine(ImVec2(canvas_p0.x, canvas_p0.y + y), ImVec2(canvas_p1.x, canvas_p0.y + y), IM_COL32(200, 200, 200, 40));
|
||||
}
|
||||
for (int n = 0; n < points.Size; n += 2)
|
||||
draw_list->AddLine(ImVec2(origin.x + points[n].x, origin.y + points[n].y), ImVec2(origin.x + points[n + 1].x, origin.y + points[n + 1].y), IM_COL32(255, 255, 0, 255), 2.0f);
|
||||
draw_list->PopClipRect();
|
||||
if (adding_preview)
|
||||
points.pop_back();
|
||||
|
||||
ImGui::EndTabItem();
|
||||
}
|
||||
|
||||
@ -5035,7 +5172,7 @@ struct MyDocument
|
||||
void DoForceClose() { Open = false; Dirty = false; }
|
||||
void DoSave() { Dirty = false; }
|
||||
|
||||
// Display dummy contents for the Document
|
||||
// Display placeholder contents for the Document
|
||||
static void DisplayContents(MyDocument* doc)
|
||||
{
|
||||
ImGui::PushID(doc);
|
||||
|
352
imgui_draw.cpp
352
imgui_draw.cpp
@ -1,4 +1,4 @@
|
||||
// dear imgui, v1.77
|
||||
// dear imgui, v1.78
|
||||
// (drawing and font code)
|
||||
|
||||
/*
|
||||
@ -358,6 +358,7 @@ ImDrawListSharedData::ImDrawListSharedData()
|
||||
ArcFastVtx[i] = ImVec2(ImCos(a), ImSin(a));
|
||||
}
|
||||
memset(CircleSegmentCounts, 0, sizeof(CircleSegmentCounts)); // This will be set by SetCircleSegmentMaxError()
|
||||
TexUvLines = NULL;
|
||||
}
|
||||
|
||||
void ImDrawListSharedData::SetCircleSegmentMaxError(float max_error)
|
||||
@ -516,7 +517,7 @@ void ImDrawList::_OnChangedVtxOffset()
|
||||
// We don't need to compare curr_cmd->VtxOffset != _CmdHeader.VtxOffset because we know it'll be different at the time we call this.
|
||||
_VtxCurrentIdx = 0;
|
||||
ImDrawCmd* curr_cmd = &CmdBuffer.Data[CmdBuffer.Size - 1];
|
||||
IM_ASSERT(curr_cmd->VtxOffset != _CmdHeader.VtxOffset);
|
||||
//IM_ASSERT(curr_cmd->VtxOffset != _CmdHeader.VtxOffset); // See #3349
|
||||
if (curr_cmd->ElemCount != 0)
|
||||
{
|
||||
AddDrawCmd();
|
||||
@ -581,6 +582,9 @@ void ImDrawList::PrimReserve(int idx_count, int vtx_count)
|
||||
IM_ASSERT_PARANOID(idx_count >= 0 && vtx_count >= 0);
|
||||
if (sizeof(ImDrawIdx) == 2 && (_VtxCurrentIdx + vtx_count >= (1 << 16)) && (Flags & ImDrawListFlags_AllowVtxOffset))
|
||||
{
|
||||
// FIXME: In theory we should be testing that vtx_count <64k here.
|
||||
// In practice, RenderText() relies on reserving ahead for a worst case scenario so it is currently useful for us
|
||||
// to not make that check until we rework the text functions to handle clipping and large horizontal lines better.
|
||||
_CmdHeader.VtxOffset = VtxBuffer.Size;
|
||||
_OnChangedVtxOffset();
|
||||
}
|
||||
@ -666,25 +670,38 @@ void ImDrawList::AddPolyline(const ImVec2* points, const int points_count, ImU32
|
||||
return;
|
||||
|
||||
const ImVec2 opaque_uv = _Data->TexUvWhitePixel;
|
||||
int count = points_count;
|
||||
if (!closed)
|
||||
count = points_count-1;
|
||||
|
||||
const int count = closed ? points_count : points_count - 1; // The number of line segments we need to draw
|
||||
const bool thick_line = (thickness > 1.0f);
|
||||
|
||||
if (Flags & ImDrawListFlags_AntiAliasedLines)
|
||||
{
|
||||
// Anti-aliased stroke
|
||||
const float AA_SIZE = 1.0f;
|
||||
const ImU32 col_trans = col & ~IM_COL32_A_MASK;
|
||||
|
||||
const int idx_count = thick_line ? count*18 : count*12;
|
||||
const int vtx_count = thick_line ? points_count*4 : points_count*3;
|
||||
// Thicknesses <1.0 should behave like thickness 1.0
|
||||
thickness = ImMax(thickness, 1.0f);
|
||||
const int integer_thickness = (int)thickness;
|
||||
const float fractional_thickness = thickness - integer_thickness;
|
||||
|
||||
// Do we want to draw this line using a texture?
|
||||
// - For now, only draw integer-width lines using textures to avoid issues with the way scaling occurs, could be improved.
|
||||
// - If AA_SIZE is not 1.0f we cannot use the texture path.
|
||||
const bool use_texture = (Flags & ImDrawListFlags_AntiAliasedLinesUseTex) && (integer_thickness < IM_DRAWLIST_TEX_LINES_WIDTH_MAX) && (fractional_thickness <= 0.00001f);
|
||||
|
||||
// We should never hit this, because NewFrame() doesn't set ImDrawListFlags_AntiAliasedLinesUseTex unless ImFontAtlasFlags_NoBakedLines is off
|
||||
IM_ASSERT_PARANOID(!use_texture || !(_Data->Font->ContainerAtlas->Flags & ImFontAtlasFlags_NoBakedLines));
|
||||
|
||||
const int idx_count = use_texture ? (count * 6) : (thick_line ? count * 18 : count * 12);
|
||||
const int vtx_count = use_texture ? (points_count * 2) : (thick_line ? points_count * 4 : points_count * 3);
|
||||
PrimReserve(idx_count, vtx_count);
|
||||
|
||||
// Temporary buffer
|
||||
ImVec2* temp_normals = (ImVec2*)alloca(points_count * (thick_line ? 5 : 3) * sizeof(ImVec2)); //-V630
|
||||
// The first <points_count> items are normals at each line point, then after that there are either 2 or 4 temp points for each line point
|
||||
ImVec2* temp_normals = (ImVec2*)alloca(points_count * ((use_texture || !thick_line) ? 3 : 5) * sizeof(ImVec2)); //-V630
|
||||
ImVec2* temp_points = temp_normals + points_count;
|
||||
|
||||
// Calculate normals (tangents) for each line segment
|
||||
for (int i1 = 0; i1 < count; i1++)
|
||||
{
|
||||
const int i2 = (i1 + 1) == points_count ? 0 : i1 + 1;
|
||||
@ -697,59 +714,111 @@ void ImDrawList::AddPolyline(const ImVec2* points, const int points_count, ImU32
|
||||
if (!closed)
|
||||
temp_normals[points_count - 1] = temp_normals[points_count - 2];
|
||||
|
||||
if (!thick_line)
|
||||
// If we are drawing a one-pixel-wide line without a texture, or a textured line of any width, we only need 2 or 3 vertices per point
|
||||
if (use_texture || !thick_line)
|
||||
{
|
||||
// [PATH 1] Texture-based lines (thick or non-thick)
|
||||
// [PATH 2] Non texture-based lines (non-thick)
|
||||
|
||||
// The width of the geometry we need to draw - this is essentially <thickness> pixels for the line itself, plus "one pixel" for AA.
|
||||
// - In the texture-based path, we don't use AA_SIZE here because the +1 is tied to the generated texture
|
||||
// (see ImFontAtlasBuildRenderLinesTexData() function), and so alternate values won't work without changes to that code.
|
||||
// - In the non texture-based paths, we would allow AA_SIZE to potentially be != 1.0f with a patch (e.g. fringe_scale patch to
|
||||
// allow scaling geometry while preserving one-screen-pixel AA fringe).
|
||||
const float half_draw_size = use_texture ? ((thickness * 0.5f) + 1) : AA_SIZE;
|
||||
|
||||
// If line is not closed, the first and last points need to be generated differently as there are no normals to blend
|
||||
if (!closed)
|
||||
{
|
||||
temp_points[0] = points[0] + temp_normals[0] * AA_SIZE;
|
||||
temp_points[1] = points[0] - temp_normals[0] * AA_SIZE;
|
||||
temp_points[(points_count-1)*2+0] = points[points_count-1] + temp_normals[points_count-1] * AA_SIZE;
|
||||
temp_points[(points_count-1)*2+1] = points[points_count-1] - temp_normals[points_count-1] * AA_SIZE;
|
||||
temp_points[0] = points[0] + temp_normals[0] * half_draw_size;
|
||||
temp_points[1] = points[0] - temp_normals[0] * half_draw_size;
|
||||
temp_points[(points_count-1)*2+0] = points[points_count-1] + temp_normals[points_count-1] * half_draw_size;
|
||||
temp_points[(points_count-1)*2+1] = points[points_count-1] - temp_normals[points_count-1] * half_draw_size;
|
||||
}
|
||||
|
||||
// Generate the indices to form a number of triangles for each line segment, and the vertices for the line edges
|
||||
// This takes points n and n+1 and writes into n+1, with the first point in a closed line being generated from the final one (as n+1 wraps)
|
||||
// FIXME-OPT: Merge the different loops, possibly remove the temporary buffer.
|
||||
unsigned int idx1 = _VtxCurrentIdx;
|
||||
for (int i1 = 0; i1 < count; i1++)
|
||||
unsigned int idx1 = _VtxCurrentIdx; // Vertex index for start of line segment
|
||||
for (int i1 = 0; i1 < count; i1++) // i1 is the first point of the line segment
|
||||
{
|
||||
const int i2 = (i1+1) == points_count ? 0 : i1+1;
|
||||
unsigned int idx2 = (i1+1) == points_count ? _VtxCurrentIdx : idx1+3;
|
||||
const int i2 = (i1 + 1) == points_count ? 0 : i1 + 1; // i2 is the second point of the line segment
|
||||
const unsigned int idx2 = ((i1 + 1) == points_count) ? _VtxCurrentIdx : (idx1 + (use_texture ? 2 : 3)); // Vertex index for end of segment
|
||||
|
||||
// Average normals
|
||||
float dm_x = (temp_normals[i1].x + temp_normals[i2].x) * 0.5f;
|
||||
float dm_y = (temp_normals[i1].y + temp_normals[i2].y) * 0.5f;
|
||||
IM_FIXNORMAL2F(dm_x, dm_y);
|
||||
dm_x *= AA_SIZE;
|
||||
dm_y *= AA_SIZE;
|
||||
dm_x *= half_draw_size; // dm_x, dm_y are offset to the outer edge of the AA area
|
||||
dm_y *= half_draw_size;
|
||||
|
||||
// Add temporary vertices
|
||||
// Add temporary vertexes for the outer edges
|
||||
ImVec2* out_vtx = &temp_points[i2 * 2];
|
||||
out_vtx[0].x = points[i2].x + dm_x;
|
||||
out_vtx[0].y = points[i2].y + dm_y;
|
||||
out_vtx[1].x = points[i2].x - dm_x;
|
||||
out_vtx[1].y = points[i2].y - dm_y;
|
||||
|
||||
// Add indexes
|
||||
_IdxWritePtr[0] = (ImDrawIdx)(idx2+0); _IdxWritePtr[1] = (ImDrawIdx)(idx1+0); _IdxWritePtr[2] = (ImDrawIdx)(idx1+2);
|
||||
_IdxWritePtr[3] = (ImDrawIdx)(idx1+2); _IdxWritePtr[4] = (ImDrawIdx)(idx2+2); _IdxWritePtr[5] = (ImDrawIdx)(idx2+0);
|
||||
_IdxWritePtr[6] = (ImDrawIdx)(idx2+1); _IdxWritePtr[7] = (ImDrawIdx)(idx1+1); _IdxWritePtr[8] = (ImDrawIdx)(idx1+0);
|
||||
_IdxWritePtr[9] = (ImDrawIdx)(idx1+0); _IdxWritePtr[10]= (ImDrawIdx)(idx2+0); _IdxWritePtr[11]= (ImDrawIdx)(idx2+1);
|
||||
if (use_texture)
|
||||
{
|
||||
// Add indices for two triangles
|
||||
_IdxWritePtr[0] = (ImDrawIdx)(idx2 + 0); _IdxWritePtr[1] = (ImDrawIdx)(idx1 + 0); _IdxWritePtr[2] = (ImDrawIdx)(idx1 + 1); // Right tri
|
||||
_IdxWritePtr[3] = (ImDrawIdx)(idx2 + 1); _IdxWritePtr[4] = (ImDrawIdx)(idx1 + 1); _IdxWritePtr[5] = (ImDrawIdx)(idx2 + 0); // Left tri
|
||||
_IdxWritePtr += 6;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Add indexes for four triangles
|
||||
_IdxWritePtr[0] = (ImDrawIdx)(idx2 + 0); _IdxWritePtr[1] = (ImDrawIdx)(idx1 + 0); _IdxWritePtr[2] = (ImDrawIdx)(idx1 + 2); // Right tri 1
|
||||
_IdxWritePtr[3] = (ImDrawIdx)(idx1 + 2); _IdxWritePtr[4] = (ImDrawIdx)(idx2 + 2); _IdxWritePtr[5] = (ImDrawIdx)(idx2 + 0); // Right tri 2
|
||||
_IdxWritePtr[6] = (ImDrawIdx)(idx2 + 1); _IdxWritePtr[7] = (ImDrawIdx)(idx1 + 1); _IdxWritePtr[8] = (ImDrawIdx)(idx1 + 0); // Left tri 1
|
||||
_IdxWritePtr[9] = (ImDrawIdx)(idx1 + 0); _IdxWritePtr[10] = (ImDrawIdx)(idx2 + 0); _IdxWritePtr[11] = (ImDrawIdx)(idx2 + 1); // Left tri 2
|
||||
_IdxWritePtr += 12;
|
||||
}
|
||||
|
||||
idx1 = idx2;
|
||||
}
|
||||
|
||||
// Add vertices
|
||||
// Add vertexes for each point on the line
|
||||
if (use_texture)
|
||||
{
|
||||
// If we're using textures we only need to emit the left/right edge vertices
|
||||
ImVec4 tex_uvs = _Data->TexUvLines[integer_thickness];
|
||||
if (fractional_thickness != 0.0f)
|
||||
{
|
||||
const ImVec4 tex_uvs_1 = _Data->TexUvLines[integer_thickness + 1];
|
||||
tex_uvs.x = tex_uvs.x + (tex_uvs_1.x - tex_uvs.x) * fractional_thickness; // inlined ImLerp()
|
||||
tex_uvs.y = tex_uvs.y + (tex_uvs_1.y - tex_uvs.y) * fractional_thickness;
|
||||
tex_uvs.z = tex_uvs.z + (tex_uvs_1.z - tex_uvs.z) * fractional_thickness;
|
||||
tex_uvs.w = tex_uvs.w + (tex_uvs_1.w - tex_uvs.w) * fractional_thickness;
|
||||
}
|
||||
ImVec2 tex_uv0(tex_uvs.x, tex_uvs.y);
|
||||
ImVec2 tex_uv1(tex_uvs.z, tex_uvs.w);
|
||||
for (int i = 0; i < points_count; i++)
|
||||
{
|
||||
_VtxWritePtr[0].pos = points[i]; _VtxWritePtr[0].uv = opaque_uv; _VtxWritePtr[0].col = col;
|
||||
_VtxWritePtr[1].pos = temp_points[i*2+0]; _VtxWritePtr[1].uv = opaque_uv; _VtxWritePtr[1].col = col_trans;
|
||||
_VtxWritePtr[2].pos = temp_points[i*2+1]; _VtxWritePtr[2].uv = opaque_uv; _VtxWritePtr[2].col = col_trans;
|
||||
_VtxWritePtr += 3;
|
||||
_VtxWritePtr[0].pos = temp_points[i * 2 + 0]; _VtxWritePtr[0].uv = tex_uv0; _VtxWritePtr[0].col = col; // Left-side outer edge
|
||||
_VtxWritePtr[1].pos = temp_points[i * 2 + 1]; _VtxWritePtr[1].uv = tex_uv1; _VtxWritePtr[1].col = col; // Right-side outer edge
|
||||
_VtxWritePtr += 2;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// If we're not using a texture, we need the center vertex as well
|
||||
for (int i = 0; i < points_count; i++)
|
||||
{
|
||||
_VtxWritePtr[0].pos = points[i]; _VtxWritePtr[0].uv = opaque_uv; _VtxWritePtr[0].col = col; // Center of line
|
||||
_VtxWritePtr[1].pos = temp_points[i * 2 + 0]; _VtxWritePtr[1].uv = opaque_uv; _VtxWritePtr[1].col = col_trans; // Left-side outer edge
|
||||
_VtxWritePtr[2].pos = temp_points[i * 2 + 1]; _VtxWritePtr[2].uv = opaque_uv; _VtxWritePtr[2].col = col_trans; // Right-side outer edge
|
||||
_VtxWritePtr += 3;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// [PATH 2] Non texture-based lines (thick): we need to draw the solid line core and thus require four vertices per point
|
||||
const float half_inner_thickness = (thickness - AA_SIZE) * 0.5f;
|
||||
|
||||
// If line is not closed, the first and last points need to be generated differently as there are no normals to blend
|
||||
if (!closed)
|
||||
{
|
||||
const int points_last = points_count - 1;
|
||||
@ -763,9 +832,11 @@ void ImDrawList::AddPolyline(const ImVec2* points, const int points_count, ImU32
|
||||
temp_points[points_last * 4 + 3] = points[points_last] - temp_normals[points_last] * (half_inner_thickness + AA_SIZE);
|
||||
}
|
||||
|
||||
// Generate the indices to form a number of triangles for each line segment, and the vertices for the line edges
|
||||
// This takes points n and n+1 and writes into n+1, with the first point in a closed line being generated from the final one (as n+1 wraps)
|
||||
// FIXME-OPT: Merge the different loops, possibly remove the temporary buffer.
|
||||
unsigned int idx1 = _VtxCurrentIdx;
|
||||
for (int i1 = 0; i1 < count; i1++)
|
||||
unsigned int idx1 = _VtxCurrentIdx; // Vertex index for start of line segment
|
||||
for (int i1 = 0; i1 < count; i1++) // i1 is the first point of the line segment
|
||||
{
|
||||
const int i2 = (i1 + 1) == points_count ? 0 : (i1 + 1); // i2 is the second point of the line segment
|
||||
const unsigned int idx2 = (i1 + 1) == points_count ? _VtxCurrentIdx : (idx1 + 4); // Vertex index for end of segment
|
||||
@ -816,7 +887,7 @@ void ImDrawList::AddPolyline(const ImVec2* points, const int points_count, ImU32
|
||||
}
|
||||
else
|
||||
{
|
||||
// Non Anti-aliased Stroke
|
||||
// [PATH 4] Non texture-based, Non anti-aliased lines
|
||||
const int idx_count = count * 6;
|
||||
const int vtx_count = count * 4; // FIXME-OPT: Not sharing edges
|
||||
PrimReserve(idx_count, vtx_count);
|
||||
@ -1170,7 +1241,7 @@ void ImDrawList::AddCircle(const ImVec2& center, float radius, ImU32 col, int nu
|
||||
// Because we are filling a closed shape we remove 1 from the count of segments/points
|
||||
const float a_max = (IM_PI * 2.0f) * ((float)num_segments - 1.0f) / (float)num_segments;
|
||||
if (num_segments == 12)
|
||||
PathArcToFast(center, radius - 0.5f, 0, 12);
|
||||
PathArcToFast(center, radius - 0.5f, 0, 12 - 1);
|
||||
else
|
||||
PathArcTo(center, radius - 0.5f, 0.0f, a_max, num_segments - 1);
|
||||
PathStroke(col, true, thickness);
|
||||
@ -1200,7 +1271,7 @@ void ImDrawList::AddCircleFilled(const ImVec2& center, float radius, ImU32 col,
|
||||
// Because we are filling a closed shape we remove 1 from the count of segments/points
|
||||
const float a_max = (IM_PI * 2.0f) * ((float)num_segments - 1.0f) / (float)num_segments;
|
||||
if (num_segments == 12)
|
||||
PathArcToFast(center, radius, 0, 12);
|
||||
PathArcToFast(center, radius, 0, 12 - 1);
|
||||
else
|
||||
PathArcTo(center, radius, 0.0f, a_max, num_segments - 1);
|
||||
PathFillConvex(col);
|
||||
@ -1596,10 +1667,10 @@ ImFontConfig::ImFontConfig()
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// A work of art lies ahead! (. = white layer, X = black layer, others are blank)
|
||||
// The white texels on the top left are the ones we'll use everywhere in Dear ImGui to render filled shapes.
|
||||
const int FONT_ATLAS_DEFAULT_TEX_DATA_W_HALF = 108;
|
||||
// The 2x2 white texels on the top left are the ones we'll use everywhere in Dear ImGui to render filled shapes.
|
||||
const int FONT_ATLAS_DEFAULT_TEX_DATA_W = 108; // Actual texture will be 2 times that + 1 spacing.
|
||||
const int FONT_ATLAS_DEFAULT_TEX_DATA_H = 27;
|
||||
static const char FONT_ATLAS_DEFAULT_TEX_DATA_PIXELS[FONT_ATLAS_DEFAULT_TEX_DATA_W_HALF * FONT_ATLAS_DEFAULT_TEX_DATA_H + 1] =
|
||||
static const char FONT_ATLAS_DEFAULT_TEX_DATA_PIXELS[FONT_ATLAS_DEFAULT_TEX_DATA_W * FONT_ATLAS_DEFAULT_TEX_DATA_H + 1] =
|
||||
{
|
||||
"..- -XXXXXXX- X - X -XXXXXXX - XXXXXXX- XX "
|
||||
"..- -X.....X- X.X - X.X -X.....X - X.....X- X..X "
|
||||
@ -1656,8 +1727,7 @@ ImFontAtlas::ImFontAtlas()
|
||||
TexWidth = TexHeight = 0;
|
||||
TexUvScale = ImVec2(0.0f, 0.0f);
|
||||
TexUvWhitePixel = ImVec2(0.0f, 0.0f);
|
||||
for (int n = 0; n < IM_ARRAYSIZE(CustomRectIds); n++)
|
||||
CustomRectIds[n] = -1;
|
||||
PackIdMouseCursors = PackIdLines = -1;
|
||||
}
|
||||
|
||||
ImFontAtlas::~ImFontAtlas()
|
||||
@ -1685,8 +1755,7 @@ void ImFontAtlas::ClearInputData()
|
||||
}
|
||||
ConfigData.clear();
|
||||
CustomRects.clear();
|
||||
for (int n = 0; n < IM_ARRAYSIZE(CustomRectIds); n++)
|
||||
CustomRectIds[n] = -1;
|
||||
PackIdMouseCursors = PackIdLines = -1;
|
||||
}
|
||||
|
||||
void ImFontAtlas::ClearTexData()
|
||||
@ -1926,15 +1995,15 @@ bool ImFontAtlas::GetMouseCursorTexData(ImGuiMouseCursor cursor_type, ImVec2* ou
|
||||
if (Flags & ImFontAtlasFlags_NoMouseCursors)
|
||||
return false;
|
||||
|
||||
IM_ASSERT(CustomRectIds[0] != -1);
|
||||
ImFontAtlasCustomRect& r = CustomRects[CustomRectIds[0]];
|
||||
ImVec2 pos = FONT_ATLAS_DEFAULT_TEX_CURSOR_DATA[cursor_type][0] + ImVec2((float)r.X, (float)r.Y);
|
||||
IM_ASSERT(PackIdMouseCursors != -1);
|
||||
ImFontAtlasCustomRect* r = GetCustomRectByIndex(PackIdMouseCursors);
|
||||
ImVec2 pos = FONT_ATLAS_DEFAULT_TEX_CURSOR_DATA[cursor_type][0] + ImVec2((float)r->X, (float)r->Y);
|
||||
ImVec2 size = FONT_ATLAS_DEFAULT_TEX_CURSOR_DATA[cursor_type][1];
|
||||
*out_size = size;
|
||||
*out_offset = FONT_ATLAS_DEFAULT_TEX_CURSOR_DATA[cursor_type][2];
|
||||
out_uv_border[0] = (pos) * TexUvScale;
|
||||
out_uv_border[1] = (pos + size) * TexUvScale;
|
||||
pos.x += FONT_ATLAS_DEFAULT_TEX_DATA_W_HALF + 1;
|
||||
pos.x += FONT_ATLAS_DEFAULT_TEX_DATA_W + 1;
|
||||
out_uv_fill[0] = (pos) * TexUvScale;
|
||||
out_uv_fill[1] = (pos + size) * TexUvScale;
|
||||
return true;
|
||||
@ -2216,8 +2285,11 @@ bool ImFontAtlasBuildWithStbTruetype(ImFontAtlas* atlas)
|
||||
if (src_tmp.GlyphsCount == 0)
|
||||
continue;
|
||||
|
||||
// When merging fonts with MergeMode=true:
|
||||
// - We can have multiple input fonts writing into a same destination font.
|
||||
// - dst_font->ConfigData is != from cfg which is our source configuration.
|
||||
ImFontConfig& cfg = atlas->ConfigData[src_i];
|
||||
ImFont* dst_font = cfg.DstFont; // We can have multiple input fonts writing into a same destination font (when using MergeMode=true)
|
||||
ImFont* dst_font = cfg.DstFont;
|
||||
|
||||
const float font_scale = stbtt_ScaleForPixelHeight(&src_tmp.FontInfo, cfg.SizePixels);
|
||||
int unscaled_ascent, unscaled_descent, unscaled_line_gap;
|
||||
@ -2231,20 +2303,13 @@ bool ImFontAtlasBuildWithStbTruetype(ImFontAtlas* atlas)
|
||||
|
||||
for (int glyph_i = 0; glyph_i < src_tmp.GlyphsCount; glyph_i++)
|
||||
{
|
||||
// Register glyph
|
||||
const int codepoint = src_tmp.GlyphsList[glyph_i];
|
||||
const stbtt_packedchar& pc = src_tmp.PackedChars[glyph_i];
|
||||
|
||||
const float char_advance_x_org = pc.xadvance;
|
||||
const float char_advance_x_mod = ImClamp(char_advance_x_org, cfg.GlyphMinAdvanceX, cfg.GlyphMaxAdvanceX);
|
||||
float char_off_x = font_off_x;
|
||||
if (char_advance_x_org != char_advance_x_mod)
|
||||
char_off_x += cfg.PixelSnapH ? ImFloor((char_advance_x_mod - char_advance_x_org) * 0.5f) : (char_advance_x_mod - char_advance_x_org) * 0.5f;
|
||||
|
||||
// Register glyph
|
||||
stbtt_aligned_quad q;
|
||||
float dummy_x = 0.0f, dummy_y = 0.0f;
|
||||
stbtt_GetPackedQuad(src_tmp.PackedChars, atlas->TexWidth, atlas->TexHeight, glyph_i, &dummy_x, &dummy_y, &q, 0);
|
||||
dst_font->AddGlyph((ImWchar)codepoint, q.x0 + char_off_x, q.y0 + font_off_y, q.x1 + char_off_x, q.y1 + font_off_y, q.s0, q.t0, q.s1, q.t1, char_advance_x_mod);
|
||||
float unused_x = 0.0f, unused_y = 0.0f;
|
||||
stbtt_GetPackedQuad(src_tmp.PackedChars, atlas->TexWidth, atlas->TexHeight, glyph_i, &unused_x, &unused_y, &q, 0);
|
||||
dst_font->AddGlyph(&cfg, (ImWchar)codepoint, q.x0 + font_off_x, q.y0 + font_off_y, q.x1 + font_off_x, q.y1 + font_off_y, q.s0, q.t0, q.s1, q.t1, pc.xadvance);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2256,17 +2321,6 @@ bool ImFontAtlasBuildWithStbTruetype(ImFontAtlas* atlas)
|
||||
return true;
|
||||
}
|
||||
|
||||
// Register default custom rectangles (this is called/shared by both the stb_truetype and the FreeType builder)
|
||||
void ImFontAtlasBuildInit(ImFontAtlas* atlas)
|
||||
{
|
||||
if (atlas->CustomRectIds[0] >= 0)
|
||||
return;
|
||||
if (!(atlas->Flags & ImFontAtlasFlags_NoMouseCursors))
|
||||
atlas->CustomRectIds[0] = atlas->AddCustomRectRegular(FONT_ATLAS_DEFAULT_TEX_DATA_W_HALF*2+1, FONT_ATLAS_DEFAULT_TEX_DATA_H);
|
||||
else
|
||||
atlas->CustomRectIds[0] = atlas->AddCustomRectRegular(2, 2);
|
||||
}
|
||||
|
||||
void ImFontAtlasBuildSetupFont(ImFontAtlas* atlas, ImFont* font, ImFontConfig* font_config, float ascent, float descent)
|
||||
{
|
||||
if (!font_config->MergeMode)
|
||||
@ -2274,6 +2328,7 @@ void ImFontAtlasBuildSetupFont(ImFontAtlas* atlas, ImFont* font, ImFontConfig* f
|
||||
font->ClearOutputData();
|
||||
font->FontSize = font_config->SizePixels;
|
||||
font->ConfigData = font_config;
|
||||
font->ConfigDataCount = 0;
|
||||
font->ContainerAtlas = atlas;
|
||||
font->Ascent = ascent;
|
||||
font->Descent = descent;
|
||||
@ -2308,52 +2363,113 @@ void ImFontAtlasBuildPackCustomRects(ImFontAtlas* atlas, void* stbrp_context_opa
|
||||
}
|
||||
}
|
||||
|
||||
void ImFontAtlasBuildRender1bppRectFromString(ImFontAtlas* atlas, int x, int y, int w, int h, const char* in_str, char in_marker_char, unsigned char in_marker_pixel_value)
|
||||
{
|
||||
IM_ASSERT(x >= 0 && x + w <= atlas->TexWidth);
|
||||
IM_ASSERT(y >= 0 && y + h <= atlas->TexHeight);
|
||||
unsigned char* out_pixel = atlas->TexPixelsAlpha8 + x + (y * atlas->TexWidth);
|
||||
for (int off_y = 0; off_y < h; off_y++, out_pixel += atlas->TexWidth, in_str += w)
|
||||
for (int off_x = 0; off_x < w; off_x++)
|
||||
out_pixel[off_x] = (in_str[off_x] == in_marker_char) ? in_marker_pixel_value : 0x00;
|
||||
}
|
||||
|
||||
static void ImFontAtlasBuildRenderDefaultTexData(ImFontAtlas* atlas)
|
||||
{
|
||||
IM_ASSERT(atlas->CustomRectIds[0] >= 0);
|
||||
IM_ASSERT(atlas->TexPixelsAlpha8 != NULL);
|
||||
ImFontAtlasCustomRect& r = atlas->CustomRects[atlas->CustomRectIds[0]];
|
||||
IM_ASSERT(r.IsPacked());
|
||||
ImFontAtlasCustomRect* r = atlas->GetCustomRectByIndex(atlas->PackIdMouseCursors);
|
||||
IM_ASSERT(r->IsPacked());
|
||||
|
||||
const int w = atlas->TexWidth;
|
||||
if (!(atlas->Flags & ImFontAtlasFlags_NoMouseCursors))
|
||||
{
|
||||
// Render/copy pixels
|
||||
IM_ASSERT(r.Width == FONT_ATLAS_DEFAULT_TEX_DATA_W_HALF * 2 + 1 && r.Height == FONT_ATLAS_DEFAULT_TEX_DATA_H);
|
||||
for (int y = 0, n = 0; y < FONT_ATLAS_DEFAULT_TEX_DATA_H; y++)
|
||||
for (int x = 0; x < FONT_ATLAS_DEFAULT_TEX_DATA_W_HALF; x++, n++)
|
||||
{
|
||||
const int offset0 = (int)(r.X + x) + (int)(r.Y + y) * w;
|
||||
const int offset1 = offset0 + FONT_ATLAS_DEFAULT_TEX_DATA_W_HALF + 1;
|
||||
atlas->TexPixelsAlpha8[offset0] = FONT_ATLAS_DEFAULT_TEX_DATA_PIXELS[n] == '.' ? 0xFF : 0x00;
|
||||
atlas->TexPixelsAlpha8[offset1] = FONT_ATLAS_DEFAULT_TEX_DATA_PIXELS[n] == 'X' ? 0xFF : 0x00;
|
||||
}
|
||||
IM_ASSERT(r->Width == FONT_ATLAS_DEFAULT_TEX_DATA_W * 2 + 1 && r->Height == FONT_ATLAS_DEFAULT_TEX_DATA_H);
|
||||
const int x_for_white = r->X;
|
||||
const int x_for_black = r->X + FONT_ATLAS_DEFAULT_TEX_DATA_W + 1;
|
||||
ImFontAtlasBuildRender1bppRectFromString(atlas, x_for_white, r->Y, FONT_ATLAS_DEFAULT_TEX_DATA_W, FONT_ATLAS_DEFAULT_TEX_DATA_H, FONT_ATLAS_DEFAULT_TEX_DATA_PIXELS, '.', 0xFF);
|
||||
ImFontAtlasBuildRender1bppRectFromString(atlas, x_for_black, r->Y, FONT_ATLAS_DEFAULT_TEX_DATA_W, FONT_ATLAS_DEFAULT_TEX_DATA_H, FONT_ATLAS_DEFAULT_TEX_DATA_PIXELS, 'X', 0xFF);
|
||||
}
|
||||
else
|
||||
{
|
||||
IM_ASSERT(r.Width == 2 && r.Height == 2);
|
||||
const int offset = (int)(r.X) + (int)(r.Y) * w;
|
||||
// Render 4 white pixels
|
||||
IM_ASSERT(r->Width == 2 && r->Height == 2);
|
||||
const int offset = (int)r->X + (int)r->Y * w;
|
||||
atlas->TexPixelsAlpha8[offset] = atlas->TexPixelsAlpha8[offset + 1] = atlas->TexPixelsAlpha8[offset + w] = atlas->TexPixelsAlpha8[offset + w + 1] = 0xFF;
|
||||
}
|
||||
atlas->TexUvWhitePixel = ImVec2((r.X + 0.5f) * atlas->TexUvScale.x, (r.Y + 0.5f) * atlas->TexUvScale.y);
|
||||
atlas->TexUvWhitePixel = ImVec2((r->X + 0.5f) * atlas->TexUvScale.x, (r->Y + 0.5f) * atlas->TexUvScale.y);
|
||||
}
|
||||
|
||||
static void ImFontAtlasBuildRenderLinesTexData(ImFontAtlas* atlas)
|
||||
{
|
||||
if (atlas->Flags & ImFontAtlasFlags_NoBakedLines)
|
||||
return;
|
||||
|
||||
// This generates a triangular shape in the texture, with the various line widths stacked on top of each other to allow interpolation between them
|
||||
ImFontAtlasCustomRect* r = atlas->GetCustomRectByIndex(atlas->PackIdLines);
|
||||
IM_ASSERT(r->IsPacked());
|
||||
for (unsigned int n = 0; n < IM_DRAWLIST_TEX_LINES_WIDTH_MAX + 1; n++) // +1 because of the zero-width row
|
||||
{
|
||||
// Each line consists of at least two empty pixels at the ends, with a line of solid pixels in the middle
|
||||
unsigned int y = n;
|
||||
unsigned int line_width = n;
|
||||
unsigned int pad_left = (r->Width - line_width) / 2;
|
||||
unsigned int pad_right = r->Width - (pad_left + line_width);
|
||||
|
||||
// Write each slice
|
||||
IM_ASSERT(pad_left + line_width + pad_right == r->Width && y < r->Height); // Make sure we're inside the texture bounds before we start writing pixels
|
||||
unsigned char* write_ptr = &atlas->TexPixelsAlpha8[r->X + ((r->Y + y) * atlas->TexWidth)];
|
||||
memset(write_ptr, 0x00, pad_left);
|
||||
memset(write_ptr + pad_left, 0xFF, line_width);
|
||||
memset(write_ptr + pad_left + line_width, 0x00, pad_right);
|
||||
|
||||
// Calculate UVs for this line
|
||||
ImVec2 uv0 = ImVec2((float)(r->X + pad_left - 1), (float)(r->Y + y)) * atlas->TexUvScale;
|
||||
ImVec2 uv1 = ImVec2((float)(r->X + pad_left + line_width + 1), (float)(r->Y + y + 1)) * atlas->TexUvScale;
|
||||
float half_v = (uv0.y + uv1.y) * 0.5f; // Calculate a constant V in the middle of the row to avoid sampling artifacts
|
||||
atlas->TexUvLines[n] = ImVec4(uv0.x, half_v, uv1.x, half_v);
|
||||
}
|
||||
}
|
||||
|
||||
// Note: this is called / shared by both the stb_truetype and the FreeType builder
|
||||
void ImFontAtlasBuildInit(ImFontAtlas* atlas)
|
||||
{
|
||||
// Register texture region for mouse cursors or standard white pixels
|
||||
if (atlas->PackIdMouseCursors < 0)
|
||||
{
|
||||
if (!(atlas->Flags & ImFontAtlasFlags_NoMouseCursors))
|
||||
atlas->PackIdMouseCursors = atlas->AddCustomRectRegular(FONT_ATLAS_DEFAULT_TEX_DATA_W * 2 + 1, FONT_ATLAS_DEFAULT_TEX_DATA_H);
|
||||
else
|
||||
atlas->PackIdMouseCursors = atlas->AddCustomRectRegular(2, 2);
|
||||
}
|
||||
|
||||
// Register texture region for thick lines
|
||||
// The +2 here is to give space for the end caps, whilst height +1 is to accommodate the fact we have a zero-width row
|
||||
if (atlas->PackIdLines < 0)
|
||||
{
|
||||
if (!(atlas->Flags & ImFontAtlasFlags_NoBakedLines))
|
||||
atlas->PackIdLines = atlas->AddCustomRectRegular(IM_DRAWLIST_TEX_LINES_WIDTH_MAX + 2, IM_DRAWLIST_TEX_LINES_WIDTH_MAX + 1);
|
||||
}
|
||||
}
|
||||
|
||||
// This is called/shared by both the stb_truetype and the FreeType builder.
|
||||
void ImFontAtlasBuildFinish(ImFontAtlas* atlas)
|
||||
{
|
||||
// Render into our custom data block
|
||||
// Render into our custom data blocks
|
||||
IM_ASSERT(atlas->TexPixelsAlpha8 != NULL);
|
||||
ImFontAtlasBuildRenderDefaultTexData(atlas);
|
||||
ImFontAtlasBuildRenderLinesTexData(atlas);
|
||||
|
||||
// Register custom rectangle glyphs
|
||||
for (int i = 0; i < atlas->CustomRects.Size; i++)
|
||||
{
|
||||
const ImFontAtlasCustomRect& r = atlas->CustomRects[i];
|
||||
if (r.Font == NULL || r.GlyphID == 0)
|
||||
const ImFontAtlasCustomRect* r = &atlas->CustomRects[i];
|
||||
if (r->Font == NULL || r->GlyphID == 0)
|
||||
continue;
|
||||
|
||||
IM_ASSERT(r.Font->ContainerAtlas == atlas);
|
||||
// Will ignore ImFontConfig settings: GlyphMinAdvanceX, GlyphMinAdvanceY, GlyphExtraSpacing, PixelSnapH
|
||||
IM_ASSERT(r->Font->ContainerAtlas == atlas);
|
||||
ImVec2 uv0, uv1;
|
||||
atlas->CalcCustomRectUV(&r, &uv0, &uv1);
|
||||
r.Font->AddGlyph((ImWchar)r.GlyphID, r.GlyphOffset.x, r.GlyphOffset.y, r.GlyphOffset.x + r.Width, r.GlyphOffset.y + r.Height, uv0.x, uv0.y, uv1.x, uv1.y, r.GlyphAdvanceX);
|
||||
atlas->CalcCustomRectUV(r, &uv0, &uv1);
|
||||
r->Font->AddGlyph(NULL, (ImWchar)r->GlyphID, r->GlyphOffset.x, r->GlyphOffset.y, r->GlyphOffset.x + r->Width, r->GlyphOffset.y + r->Height, uv0.x, uv0.y, uv1.x, uv1.y, r->GlyphAdvanceX);
|
||||
}
|
||||
|
||||
// Build all fonts lookup tables
|
||||
@ -2763,8 +2879,29 @@ void ImFont::GrowIndex(int new_size)
|
||||
|
||||
// x0/y0/x1/y1 are offset from the character upper-left layout position, in pixels. Therefore x0/y0 are often fairly close to zero.
|
||||
// Not to be mistaken with texture coordinates, which are held by u0/v0/u1/v1 in normalized format (0.0..1.0 on each texture axis).
|
||||
void ImFont::AddGlyph(ImWchar codepoint, float x0, float y0, float x1, float y1, float u0, float v0, float u1, float v1, float advance_x)
|
||||
// 'cfg' is not necessarily == 'this->ConfigData' because multiple source fonts+configs can be used to build one target font.
|
||||
void ImFont::AddGlyph(ImFontConfig* cfg, ImWchar codepoint, float x0, float y0, float x1, float y1, float u0, float v0, float u1, float v1, float advance_x)
|
||||
{
|
||||
if (cfg != NULL)
|
||||
{
|
||||
// Clamp & recenter if needed
|
||||
const float advance_x_original = advance_x;
|
||||
advance_x = ImClamp(advance_x, cfg->GlyphMinAdvanceX, cfg->GlyphMaxAdvanceX);
|
||||
if (advance_x != advance_x_original)
|
||||
{
|
||||
float char_off_x = cfg->PixelSnapH ? ImFloor((advance_x - advance_x_original) * 0.5f) : (advance_x - advance_x_original) * 0.5f;
|
||||
x0 += char_off_x;
|
||||
x1 += char_off_x;
|
||||
}
|
||||
|
||||
// Snap to pixel
|
||||
if (cfg->PixelSnapH)
|
||||
advance_x = IM_ROUND(advance_x);
|
||||
|
||||
// Bake spacing
|
||||
advance_x += cfg->GlyphExtraSpacing.x;
|
||||
}
|
||||
|
||||
Glyphs.resize(Glyphs.Size + 1);
|
||||
ImFontGlyph& glyph = Glyphs.back();
|
||||
glyph.Codepoint = (unsigned int)codepoint;
|
||||
@ -2777,14 +2914,13 @@ void ImFont::AddGlyph(ImWchar codepoint, float x0, float y0, float x1, float y1,
|
||||
glyph.V0 = v0;
|
||||
glyph.U1 = u1;
|
||||
glyph.V1 = v1;
|
||||
glyph.AdvanceX = advance_x + ConfigData->GlyphExtraSpacing.x; // Bake spacing into AdvanceX
|
||||
|
||||
if (ConfigData->PixelSnapH)
|
||||
glyph.AdvanceX = IM_ROUND(glyph.AdvanceX);
|
||||
glyph.AdvanceX = advance_x;
|
||||
|
||||
// Compute rough surface usage metrics (+1 to account for average padding, +0.99 to round)
|
||||
// We use (U1-U0)*TexWidth instead of X1-X0 to account for oversampling.
|
||||
float pad = ContainerAtlas->TexGlyphPadding + 0.99f;
|
||||
DirtyLookupTables = true;
|
||||
MetricsTotalSurface += (int)((glyph.U1 - glyph.U0) * ContainerAtlas->TexWidth + 1.99f) * (int)((glyph.V1 - glyph.V0) * ContainerAtlas->TexHeight + 1.99f);
|
||||
MetricsTotalSurface += (int)((glyph.U1 - glyph.U0) * ContainerAtlas->TexWidth + pad) * (int)((glyph.V1 - glyph.V0) * ContainerAtlas->TexHeight + pad);
|
||||
}
|
||||
|
||||
void ImFont::AddRemapChar(ImWchar dst, ImWchar src, bool overwrite_dst)
|
||||
@ -3293,8 +3429,8 @@ void ImGui::RenderMouseCursor(ImDrawList* draw_list, ImVec2 pos, float scale, Im
|
||||
pos -= offset;
|
||||
const ImTextureID tex_id = font_atlas->TexID;
|
||||
draw_list->PushTextureID(tex_id);
|
||||
draw_list->AddImage(tex_id, pos + ImVec2(1,0)*scale, pos + ImVec2(1,0)*scale + size*scale, uv[2], uv[3], col_shadow);
|
||||
draw_list->AddImage(tex_id, pos + ImVec2(2,0)*scale, pos + ImVec2(2,0)*scale + size*scale, uv[2], uv[3], col_shadow);
|
||||
draw_list->AddImage(tex_id, pos + ImVec2(1, 0) * scale, pos + (ImVec2(1, 0) + size) * scale, uv[2], uv[3], col_shadow);
|
||||
draw_list->AddImage(tex_id, pos + ImVec2(2, 0) * scale, pos + (ImVec2(2, 0) + size) * scale, uv[2], uv[3], col_shadow);
|
||||
draw_list->AddImage(tex_id, pos, pos + size * scale, uv[2], uv[3], col_border);
|
||||
draw_list->AddImage(tex_id, pos, pos + size * scale, uv[0], uv[1], col_fill);
|
||||
draw_list->PopTextureID();
|
||||
@ -3383,6 +3519,22 @@ void ImGui::RenderRectFilledRangeH(ImDrawList* draw_list, const ImRect& rect, Im
|
||||
draw_list->PathFillConvex(col);
|
||||
}
|
||||
|
||||
void ImGui::RenderRectFilledWithHole(ImDrawList* draw_list, ImRect outer, ImRect inner, ImU32 col, float rounding)
|
||||
{
|
||||
const bool fill_L = (inner.Min.x > outer.Min.x);
|
||||
const bool fill_R = (inner.Max.x < outer.Max.x);
|
||||
const bool fill_U = (inner.Min.y > outer.Min.y);
|
||||
const bool fill_D = (inner.Max.y < outer.Max.y);
|
||||
if (fill_L) draw_list->AddRectFilled(ImVec2(outer.Min.x, inner.Min.y), ImVec2(inner.Min.x, inner.Max.y), col, rounding, (fill_U ? 0 : ImDrawCornerFlags_TopLeft) | (fill_D ? 0 : ImDrawCornerFlags_BotLeft));
|
||||
if (fill_R) draw_list->AddRectFilled(ImVec2(inner.Max.x, inner.Min.y), ImVec2(outer.Max.x, inner.Max.y), col, rounding, (fill_U ? 0 : ImDrawCornerFlags_TopRight) | (fill_D ? 0 : ImDrawCornerFlags_BotRight));
|
||||
if (fill_U) draw_list->AddRectFilled(ImVec2(inner.Min.x, outer.Min.y), ImVec2(inner.Max.x, inner.Min.y), col, rounding, (fill_L ? 0 : ImDrawCornerFlags_TopLeft) | (fill_R ? 0 : ImDrawCornerFlags_TopRight));
|
||||
if (fill_D) draw_list->AddRectFilled(ImVec2(inner.Min.x, inner.Max.y), ImVec2(inner.Max.x, outer.Max.y), col, rounding, (fill_L ? 0 : ImDrawCornerFlags_BotLeft) | (fill_R ? 0 : ImDrawCornerFlags_BotRight));
|
||||
if (fill_L && fill_U) draw_list->AddRectFilled(ImVec2(outer.Min.x, outer.Min.y), ImVec2(inner.Min.x, inner.Min.y), col, rounding, ImDrawCornerFlags_TopLeft);
|
||||
if (fill_R && fill_U) draw_list->AddRectFilled(ImVec2(inner.Max.x, outer.Min.y), ImVec2(outer.Max.x, inner.Min.y), col, rounding, ImDrawCornerFlags_TopRight);
|
||||
if (fill_L && fill_D) draw_list->AddRectFilled(ImVec2(outer.Min.x, inner.Max.y), ImVec2(inner.Min.x, outer.Max.y), col, rounding, ImDrawCornerFlags_BotLeft);
|
||||
if (fill_R && fill_D) draw_list->AddRectFilled(ImVec2(inner.Max.x, inner.Max.y), ImVec2(outer.Max.x, outer.Max.y), col, rounding, ImDrawCornerFlags_BotRight);
|
||||
}
|
||||
|
||||
// Helper for ColorPicker4()
|
||||
// NB: This is rather brittle and will show artifact when rounding this enabled if rounded corners overlap multiple cells. Caller currently responsible for avoiding that.
|
||||
// Spent a non reasonable amount of time trying to getting this right for ColorButton with rounding+anti-aliasing+ImGuiColorEditFlags_HalfAlphaPreview flag + various grid sizes and offsets, and eventually gave up... probably more reasonable to disable rounding altogether.
|
||||
|
140
imgui_internal.h
140
imgui_internal.h
@ -1,4 +1,4 @@
|
||||
// dear imgui, v1.77
|
||||
// dear imgui, v1.78
|
||||
// (internal structures/api)
|
||||
|
||||
// You may use this file to debug, understand or extend ImGui features but we don't provide any guarantee of forward compatibility!
|
||||
@ -96,7 +96,7 @@ struct ImGuiContext; // Main Dear ImGui context
|
||||
struct ImGuiDataTypeInfo; // Type information associated to a ImGuiDataType enum
|
||||
struct ImGuiGroupData; // Stacked storage data for BeginGroup()/EndGroup()
|
||||
struct ImGuiInputTextState; // Internal state of the currently focused/edited text input box
|
||||
struct ImGuiItemHoveredDataBackup; // Backup and restore IsItemHovered() internal data
|
||||
struct ImGuiLastItemDataBackup; // Backup and restore IsItemHovered() internal data
|
||||
struct ImGuiMenuColumns; // Simple column measurement, currently used for MenuItem() only
|
||||
struct ImGuiNavMoveResult; // Result of a gamepad/keyboard directional navigation move query result
|
||||
struct ImGuiNextWindowData; // Storage for SetNextWindow** functions
|
||||
@ -114,7 +114,6 @@ struct ImGuiWindowSettings; // Storage for a window .ini settings (we ke
|
||||
typedef int ImGuiLayoutType; // -> enum ImGuiLayoutType_ // Enum: Horizontal or vertical
|
||||
typedef int ImGuiButtonFlags; // -> enum ImGuiButtonFlags_ // Flags: for ButtonEx(), ButtonBehavior()
|
||||
typedef int ImGuiColumnsFlags; // -> enum ImGuiColumnsFlags_ // Flags: BeginColumns()
|
||||
typedef int ImGuiDragFlags; // -> enum ImGuiDragFlags_ // Flags: for DragBehavior()
|
||||
typedef int ImGuiItemFlags; // -> enum ImGuiItemFlags_ // Flags: for PushItemFlag()
|
||||
typedef int ImGuiItemStatusFlags; // -> enum ImGuiItemStatusFlags_ // Flags: for DC.LastItemStatusFlags
|
||||
typedef int ImGuiNavHighlightFlags; // -> enum ImGuiNavHighlightFlags_ // Flags: for RenderNavHighlight()
|
||||
@ -123,7 +122,6 @@ typedef int ImGuiNavMoveFlags; // -> enum ImGuiNavMoveFlags_ // F
|
||||
typedef int ImGuiNextItemDataFlags; // -> enum ImGuiNextItemDataFlags_ // Flags: for SetNextItemXXX() functions
|
||||
typedef int ImGuiNextWindowDataFlags; // -> enum ImGuiNextWindowDataFlags_// Flags: for SetNextWindowXXX() functions
|
||||
typedef int ImGuiSeparatorFlags; // -> enum ImGuiSeparatorFlags_ // Flags: for SeparatorEx()
|
||||
typedef int ImGuiSliderFlags; // -> enum ImGuiSliderFlags_ // Flags: for SliderBehavior()
|
||||
typedef int ImGuiTextFlags; // -> enum ImGuiTextFlags_ // Flags: for TextEx()
|
||||
typedef int ImGuiTooltipFlags; // -> enum ImGuiTooltipFlags_ // Flags: for BeginTooltipEx()
|
||||
|
||||
@ -163,6 +161,10 @@ namespace ImStb
|
||||
#define IMGUI_DEBUG_LOG(_FMT,...) printf("[%05d] " _FMT, GImGui->FrameCount, __VA_ARGS__)
|
||||
#endif
|
||||
|
||||
// Debug Logging for selected systems. Remove the '((void)0) //' to enable.
|
||||
//#define IMGUI_DEBUG_LOG_POPUP IMGUI_DEBUG_LOG // Enable log
|
||||
#define IMGUI_DEBUG_LOG_POPUP(...) ((void)0) // Disable log
|
||||
|
||||
// Static Asserts
|
||||
#if (__cplusplus >= 201100)
|
||||
#define IM_STATIC_ASSERT(_COND) static_assert(_COND, "")
|
||||
@ -344,6 +346,12 @@ IMGUI_API void* ImFileLoadToMemory(const char* filename, const char*
|
||||
#define ImCeil(X) ceilf(X)
|
||||
static inline float ImPow(float x, float y) { return powf(x, y); } // DragBehaviorT/SliderBehaviorT uses ImPow with either float/double and need the precision
|
||||
static inline double ImPow(double x, double y) { return pow(x, y); }
|
||||
static inline float ImLog(float x) { return logf(x); } // DragBehaviorT/SliderBehaviorT uses ImLog with either float/double and need the precision
|
||||
static inline double ImLog(double x) { return log(x); }
|
||||
static inline float ImAbs(float x) { return fabsf(x); }
|
||||
static inline double ImAbs(double x) { return fabs(x); }
|
||||
static inline float ImSign(float x) { return (x < 0.0f) ? -1.0f : ((x > 0.0f) ? 1.0f : 0.0f); } // Sign operator - returns -1, 0 or 1 based on sign of argument
|
||||
static inline double ImSign(double x) { return (x < 0.0) ? -1.0 : ((x > 0.0) ? 1.0 : 0.0); }
|
||||
#endif
|
||||
// - ImMin/ImMax/ImClamp/ImLerp/ImSwap are used by widgets which support variety of types: signed/unsigned int/long long float/double
|
||||
// (Exceptionally using templates here but we could also redefine them for those types)
|
||||
@ -362,9 +370,9 @@ static inline ImVec2 ImLerp(const ImVec2& a, const ImVec2& b, float t)
|
||||
static inline ImVec2 ImLerp(const ImVec2& a, const ImVec2& b, const ImVec2& t) { return ImVec2(a.x + (b.x - a.x) * t.x, a.y + (b.y - a.y) * t.y); }
|
||||
static inline ImVec4 ImLerp(const ImVec4& a, const ImVec4& b, float t) { return ImVec4(a.x + (b.x - a.x) * t, a.y + (b.y - a.y) * t, a.z + (b.z - a.z) * t, a.w + (b.w - a.w) * t); }
|
||||
static inline float ImSaturate(float f) { return (f < 0.0f) ? 0.0f : (f > 1.0f) ? 1.0f : f; }
|
||||
static inline float ImLengthSqr(const ImVec2& lhs) { return lhs.x*lhs.x + lhs.y*lhs.y; }
|
||||
static inline float ImLengthSqr(const ImVec4& lhs) { return lhs.x*lhs.x + lhs.y*lhs.y + lhs.z*lhs.z + lhs.w*lhs.w; }
|
||||
static inline float ImInvLength(const ImVec2& lhs, float fail_value) { float d = lhs.x*lhs.x + lhs.y*lhs.y; if (d > 0.0f) return 1.0f / ImSqrt(d); return fail_value; }
|
||||
static inline float ImLengthSqr(const ImVec2& lhs) { return (lhs.x * lhs.x) + (lhs.y * lhs.y); }
|
||||
static inline float ImLengthSqr(const ImVec4& lhs) { return (lhs.x * lhs.x) + (lhs.y * lhs.y) + (lhs.z * lhs.z) + (lhs.w * lhs.w); }
|
||||
static inline float ImInvLength(const ImVec2& lhs, float fail_value) { float d = (lhs.x * lhs.x) + (lhs.y * lhs.y); if (d > 0.0f) return 1.0f / ImSqrt(d); return fail_value; }
|
||||
static inline float ImFloor(float f) { return (float)(int)(f); }
|
||||
static inline ImVec2 ImFloor(const ImVec2& v) { return ImVec2((float)(int)(v.x), (float)(int)(v.y)); }
|
||||
static inline int ImModPositive(int a, int b) { return (a + b) % b; }
|
||||
@ -544,6 +552,7 @@ struct IMGUI_API ImDrawListSharedData
|
||||
// [Internal] Lookup tables
|
||||
ImVec2 ArcFastVtx[12 * IM_DRAWLIST_ARCFAST_TESSELLATION_MULTIPLIER]; // FIXME: Bake rounded corners fill/borders in atlas
|
||||
ImU8 CircleSegmentCounts[64]; // Precomputed segment count for given radius (array index + 1) before we calculate it dynamically (to avoid calculation overhead)
|
||||
const ImVec4* TexUvLines; // UV of anti-aliased lines in the atlas
|
||||
|
||||
ImDrawListSharedData();
|
||||
void SetCircleSegmentMaxError(float max_error);
|
||||
@ -574,6 +583,7 @@ enum ImGuiItemFlags_
|
||||
ImGuiItemFlags_NoNavDefaultFocus = 1 << 4, // false
|
||||
ImGuiItemFlags_SelectableDontClosePopup = 1 << 5, // false // MenuItem/Selectable() automatically closes current Popup window
|
||||
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_Default_ = 0
|
||||
};
|
||||
|
||||
@ -598,46 +608,34 @@ enum ImGuiItemStatusFlags_
|
||||
#endif
|
||||
};
|
||||
|
||||
enum ImGuiButtonFlags_
|
||||
// Extend ImGuiButtonFlags_
|
||||
enum ImGuiButtonFlagsPrivate_
|
||||
{
|
||||
ImGuiButtonFlags_None = 0,
|
||||
ImGuiButtonFlags_Repeat = 1 << 0, // hold to repeat
|
||||
ImGuiButtonFlags_PressedOnClick = 1 << 1, // return true on click (mouse down event)
|
||||
ImGuiButtonFlags_PressedOnClickRelease = 1 << 2, // [Default] return true on click + release on same item <-- this is what the majority of Button are using
|
||||
ImGuiButtonFlags_PressedOnClickReleaseAnywhere = 1 << 3, // return true on click + release even if the release event is not done while hovering the item
|
||||
ImGuiButtonFlags_PressedOnRelease = 1 << 4, // return true on release (default requires click+release)
|
||||
ImGuiButtonFlags_PressedOnDoubleClick = 1 << 5, // return true on double-click (default requires click+release)
|
||||
ImGuiButtonFlags_PressedOnDragDropHold = 1 << 6, // return true when held into while we are drag and dropping another item (used by e.g. tree nodes, collapsing headers)
|
||||
ImGuiButtonFlags_FlattenChildren = 1 << 7, // allow interactions even if a child window is overlapping
|
||||
ImGuiButtonFlags_AllowItemOverlap = 1 << 8, // require previous frame HoveredId to either match id or be null before being usable, use along with SetItemAllowOverlap()
|
||||
ImGuiButtonFlags_DontClosePopups = 1 << 9, // disable automatically closing parent popup on press // [UNUSED]
|
||||
ImGuiButtonFlags_Disabled = 1 << 10, // disable interactions
|
||||
ImGuiButtonFlags_AlignTextBaseLine = 1 << 11, // vertically align button to match text baseline - ButtonEx() only // FIXME: Should be removed and handled by SmallButton(), not possible currently because of DC.CursorPosPrevLine
|
||||
ImGuiButtonFlags_NoKeyModifiers = 1 << 12, // disable mouse interaction if a key modifier is held
|
||||
ImGuiButtonFlags_NoHoldingActiveId = 1 << 13, // don't set ActiveId while holding the mouse (ImGuiButtonFlags_PressedOnClick only)
|
||||
ImGuiButtonFlags_NoNavFocus = 1 << 14, // don't override navigation focus when activated
|
||||
ImGuiButtonFlags_NoHoveredOnFocus = 1 << 15, // don't report as hovered when nav focus is on this item
|
||||
ImGuiButtonFlags_MouseButtonLeft = 1 << 16, // [Default] react on left mouse button
|
||||
ImGuiButtonFlags_MouseButtonRight = 1 << 17, // react on right mouse button
|
||||
ImGuiButtonFlags_MouseButtonMiddle = 1 << 18, // react on center mouse button
|
||||
|
||||
ImGuiButtonFlags_MouseButtonMask_ = ImGuiButtonFlags_MouseButtonLeft | ImGuiButtonFlags_MouseButtonRight | ImGuiButtonFlags_MouseButtonMiddle,
|
||||
ImGuiButtonFlags_MouseButtonShift_ = 16,
|
||||
ImGuiButtonFlags_MouseButtonDefault_ = ImGuiButtonFlags_MouseButtonLeft,
|
||||
ImGuiButtonFlags_PressedOnClick = 1 << 4, // return true on click (mouse down event)
|
||||
ImGuiButtonFlags_PressedOnClickRelease = 1 << 5, // [Default] return true on click + release on same item <-- this is what the majority of Button are using
|
||||
ImGuiButtonFlags_PressedOnClickReleaseAnywhere = 1 << 6, // return true on click + release even if the release event is not done while hovering the item
|
||||
ImGuiButtonFlags_PressedOnRelease = 1 << 7, // return true on release (default requires click+release)
|
||||
ImGuiButtonFlags_PressedOnDoubleClick = 1 << 8, // return true on double-click (default requires click+release)
|
||||
ImGuiButtonFlags_PressedOnDragDropHold = 1 << 9, // return true when held into while we are drag and dropping another item (used by e.g. tree nodes, collapsing headers)
|
||||
ImGuiButtonFlags_Repeat = 1 << 10, // hold to repeat
|
||||
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_DontClosePopups = 1 << 13, // disable automatically closing parent popup on press // [UNUSED]
|
||||
ImGuiButtonFlags_Disabled = 1 << 14, // disable interactions
|
||||
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
|
||||
ImGuiButtonFlags_NoKeyModifiers = 1 << 16, // disable mouse interaction if a key modifier is held
|
||||
ImGuiButtonFlags_NoHoldingActiveId = 1 << 17, // don't set ActiveId while holding the mouse (ImGuiButtonFlags_PressedOnClick only)
|
||||
ImGuiButtonFlags_NoNavFocus = 1 << 18, // don't override navigation focus when activated
|
||||
ImGuiButtonFlags_NoHoveredOnFocus = 1 << 19, // don't report as hovered when nav focus is on this item
|
||||
ImGuiButtonFlags_PressedOnMask_ = ImGuiButtonFlags_PressedOnClick | ImGuiButtonFlags_PressedOnClickRelease | ImGuiButtonFlags_PressedOnClickReleaseAnywhere | ImGuiButtonFlags_PressedOnRelease | ImGuiButtonFlags_PressedOnDoubleClick | ImGuiButtonFlags_PressedOnDragDropHold,
|
||||
ImGuiButtonFlags_PressedOnDefault_ = ImGuiButtonFlags_PressedOnClickRelease
|
||||
};
|
||||
|
||||
enum ImGuiSliderFlags_
|
||||
// Extend ImGuiSliderFlags_
|
||||
enum ImGuiSliderFlagsPrivate_
|
||||
{
|
||||
ImGuiSliderFlags_None = 0,
|
||||
ImGuiSliderFlags_Vertical = 1 << 0
|
||||
};
|
||||
|
||||
enum ImGuiDragFlags_
|
||||
{
|
||||
ImGuiDragFlags_None = 0,
|
||||
ImGuiDragFlags_Vertical = 1 << 0
|
||||
ImGuiSliderFlags_Vertical = 1 << 20, // Should this slider be orientated vertically?
|
||||
ImGuiSliderFlags_ReadOnly = 1 << 21
|
||||
};
|
||||
|
||||
// Extend ImGuiSelectableFlags_
|
||||
@ -1016,7 +1014,7 @@ struct ImGuiColumns
|
||||
float HostCursorMaxPosX; // Backup of CursorMaxPos at the time of BeginColumns()
|
||||
ImRect HostInitialClipRect; // Backup of ClipRect at the time of BeginColumns()
|
||||
ImRect HostBackupClipRect; // Backup of ClipRect during PushColumnsBackground()/PopColumnsBackground()
|
||||
ImRect HostWorkRect; // Backup of WorkRect at the time of BeginColumns()
|
||||
ImRect HostBackupParentWorkRect;//Backup of WorkRect at the time of BeginColumns()
|
||||
ImVector<ImGuiColumnData> Columns;
|
||||
ImDrawListSplitter Splitter;
|
||||
|
||||
@ -1128,17 +1126,19 @@ struct ImGuiContext
|
||||
ImGuiStorage WindowsById; // Map window's ImGuiID to ImGuiWindow*
|
||||
int WindowsActiveCount; // Number of unique windows submitted by frame
|
||||
ImGuiWindow* CurrentWindow; // Window being drawn into
|
||||
ImGuiWindow* HoveredWindow; // Will catch mouse inputs
|
||||
ImGuiWindow* HoveredRootWindow; // Will catch mouse inputs (for focus/move only)
|
||||
ImGuiWindow* MovingWindow; // Track the window we clicked on (in order to preserve focus). The actually window that is moved is generally MovingWindow->RootWindow.
|
||||
ImGuiWindow* HoveredWindow; // Window the mouse is hovering. Will typically catch mouse inputs.
|
||||
ImGuiWindow* HoveredRootWindow; // == HoveredWindow ? HoveredWindow->RootWindow : NULL, merely a shortcut to avoid null test in some situation.
|
||||
ImGuiWindow* HoveredWindowUnderMovingWindow; // Hovered window ignoring MovingWindow. Only set if MovingWindow is set.
|
||||
ImGuiWindow* MovingWindow; // Track the window we clicked on (in order to preserve focus). The actual window that is moved is generally MovingWindow->RootWindow.
|
||||
ImGuiWindow* WheelingWindow; // Track the window we started mouse-wheeling on. Until a timer elapse or mouse has moved, generally keep scrolling the same window even if during the course of scrolling the mouse ends up hovering a child window.
|
||||
ImVec2 WheelingWindowRefMousePos;
|
||||
float WheelingWindowTimer;
|
||||
|
||||
// Item/widgets state and tracking information
|
||||
ImGuiID HoveredId; // Hovered widget
|
||||
bool HoveredIdAllowOverlap;
|
||||
ImGuiID HoveredIdPreviousFrame;
|
||||
bool HoveredIdAllowOverlap;
|
||||
bool HoveredIdDisabled; // At least one widget passed the rect test, but has been discarded by disabled flag or popup inhibit. May be true even if HoveredId == 0.
|
||||
float HoveredIdTimer; // Measure contiguous hovering time
|
||||
float HoveredIdNotActiveTimer; // Measure contiguous hovering time where the item has not been active
|
||||
ImGuiID ActiveId; // Active widget
|
||||
@ -1146,6 +1146,7 @@ struct ImGuiContext
|
||||
float ActiveIdTimer;
|
||||
bool ActiveIdIsJustActivated; // Set at the time of activation for one frame
|
||||
bool ActiveIdAllowOverlap; // Active widget allows another widget to steal active id (generally for overlapping widgets, but not always)
|
||||
bool ActiveIdNoClearOnFocusLoss; // Disable losing active id if the active id window gets unfocused.
|
||||
bool ActiveIdHasBeenPressedBefore; // Track whether the active id led to a press (this is to allow changing between PressOnClick and PressOnRelease without pressing twice). Used by range_select branch.
|
||||
bool ActiveIdHasBeenEditedBefore; // Was the value associated to the widget Edited over the course of the Active state.
|
||||
bool ActiveIdHasBeenEditedThisFrame;
|
||||
@ -1274,6 +1275,8 @@ struct ImGuiContext
|
||||
float ColorEditLastSat; // Backup of last Saturation associated to LastColor[3], so we can restore Saturation in lossy RGB<>HSV round trips
|
||||
float ColorEditLastColor[3];
|
||||
ImVec4 ColorPickerRef; // Initial/reference color at the time of opening the color picker.
|
||||
float SliderCurrentAccum; // Accumulated slider delta when using navigation controls.
|
||||
bool SliderCurrentAccumDirty; // Has the accumulated slider delta changed since last time we tried to apply it?
|
||||
bool DragCurrentAccumDirty;
|
||||
float DragCurrentAccum; // Accumulator for dragging modification. Always high-precision, not rounded by end-user precision settings
|
||||
float DragSpeedDefaultRatio; // If speed == 0.0f, uses (max-min) * DragSpeedDefaultRatio
|
||||
@ -1336,19 +1339,21 @@ struct ImGuiContext
|
||||
CurrentWindow = NULL;
|
||||
HoveredWindow = NULL;
|
||||
HoveredRootWindow = NULL;
|
||||
HoveredWindowUnderMovingWindow = NULL;
|
||||
MovingWindow = NULL;
|
||||
WheelingWindow = NULL;
|
||||
WheelingWindowTimer = 0.0f;
|
||||
|
||||
HoveredId = 0;
|
||||
HoveredId = HoveredIdPreviousFrame = 0;
|
||||
HoveredIdAllowOverlap = false;
|
||||
HoveredIdPreviousFrame = 0;
|
||||
HoveredIdDisabled = false;
|
||||
HoveredIdTimer = HoveredIdNotActiveTimer = 0.0f;
|
||||
ActiveId = 0;
|
||||
ActiveIdIsAlive = 0;
|
||||
ActiveIdTimer = 0.0f;
|
||||
ActiveIdIsJustActivated = false;
|
||||
ActiveIdAllowOverlap = false;
|
||||
ActiveIdNoClearOnFocusLoss = false;
|
||||
ActiveIdHasBeenPressedBefore = false;
|
||||
ActiveIdHasBeenEditedBefore = false;
|
||||
ActiveIdHasBeenEditedThisFrame = false;
|
||||
@ -1425,6 +1430,8 @@ struct ImGuiContext
|
||||
ColorEditOptions = ImGuiColorEditFlags__OptionsDefault;
|
||||
ColorEditLastHue = ColorEditLastSat = 0.0f;
|
||||
ColorEditLastColor[0] = ColorEditLastColor[1] = ColorEditLastColor[2] = FLT_MAX;
|
||||
SliderCurrentAccum = 0.0f;
|
||||
SliderCurrentAccumDirty = false;
|
||||
DragCurrentAccumDirty = false;
|
||||
DragCurrentAccum = 0.0f;
|
||||
DragSpeedDefaultRatio = 1.0f / 100.0f;
|
||||
@ -1610,9 +1617,12 @@ struct IMGUI_API ImGuiWindow
|
||||
ImRect OuterRectClipped; // == Window->Rect() just after setup in Begin(). == window->Rect() for root window.
|
||||
ImRect InnerRect; // Inner rectangle (omit title bar, menu bar, scroll bar)
|
||||
ImRect InnerClipRect; // == InnerRect shrunk by WindowPadding*0.5f on each side, clipped within viewport or parent clip rect.
|
||||
ImRect WorkRect; // Cover the whole scrolling region, shrunk by WindowPadding*1.0f on each side. This is meant to replace ContentRegionRect over time (from 1.71+ onward).
|
||||
ImRect WorkRect; // Initially covers the whole scrolling region. Reduced by containers e.g columns/tables when active. Shrunk by WindowPadding*1.0f on each side. This is meant to replace ContentRegionRect over time (from 1.71+ onward).
|
||||
ImRect ParentWorkRect; // Backup of WorkRect before entering a container such as columns/tables. Used by e.g. SpanAllColumns functions to easily access. Stacked containers are responsible for maintaining this. // FIXME-WORKRECT: Could be a stack?
|
||||
ImRect ClipRect; // Current clipping/scissoring rectangle, evolve as we are using PushClipRect(), etc. == DrawList->clip_rect_stack.back().
|
||||
ImRect ContentRegionRect; // FIXME: This is currently confusing/misleading. It is essentially WorkRect but not handling of scrolling. We currently rely on it as right/bottom aligned sizing operation need some size to rely on.
|
||||
ImVec2ih HitTestHoleSize; // Define an optional rectangular hole where mouse will pass-through the window.
|
||||
ImVec2ih HitTestHoleOffset;
|
||||
|
||||
int LastFrameActive; // Last frame number the window was Active.
|
||||
float LastTimeActive; // Last timestamp the window was Active (using float as we don't need high precision there)
|
||||
@ -1625,7 +1635,7 @@ struct IMGUI_API ImGuiWindow
|
||||
ImDrawList* DrawList; // == &DrawListInst (for backward compatibility reason with code using imgui_internal.h we keep this a pointer)
|
||||
ImDrawList DrawListInst;
|
||||
ImGuiWindow* ParentWindow; // If we are a child _or_ popup window, this is pointing to our parent. Otherwise NULL.
|
||||
ImGuiWindow* RootWindow; // Point to ourself or first ancestor that is not a child window.
|
||||
ImGuiWindow* RootWindow; // Point to ourself or first ancestor that is not a child window == Top-level window.
|
||||
ImGuiWindow* RootWindowForTitleBarHighlight; // Point to ourself or first ancestor which will display TitleBgActive color when this window is active.
|
||||
ImGuiWindow* RootWindowForNav; // Point to ourself or first ancestor which doesn't have the NavFlattened flag.
|
||||
|
||||
@ -1659,14 +1669,14 @@ public:
|
||||
};
|
||||
|
||||
// Backup and restore just enough data to be able to use IsItemHovered() on item A after another B in the same window has overwritten the data.
|
||||
struct ImGuiItemHoveredDataBackup
|
||||
struct ImGuiLastItemDataBackup
|
||||
{
|
||||
ImGuiID LastItemId;
|
||||
ImGuiItemStatusFlags LastItemStatusFlags;
|
||||
ImRect LastItemRect;
|
||||
ImRect LastItemDisplayRect;
|
||||
|
||||
ImGuiItemHoveredDataBackup() { Backup(); }
|
||||
ImGuiLastItemDataBackup() { Backup(); }
|
||||
void Backup() { ImGuiWindow* window = GImGui->CurrentWindow; LastItemId = window->DC.LastItemId; LastItemStatusFlags = window->DC.LastItemStatusFlags; LastItemRect = window->DC.LastItemRect; LastItemDisplayRect = window->DC.LastItemDisplayRect; }
|
||||
void Restore() const { ImGuiWindow* window = GImGui->CurrentWindow; window->DC.LastItemId = LastItemId; window->DC.LastItemStatusFlags = LastItemStatusFlags; window->DC.LastItemRect = LastItemRect; window->DC.LastItemDisplayRect = LastItemDisplayRect; }
|
||||
};
|
||||
@ -1689,19 +1699,20 @@ enum ImGuiTabItemFlagsPrivate_
|
||||
ImGuiTabItemFlags_NoCloseButton = 1 << 20 // Track whether p_open was set or not (we'll need this info on the next frame to recompute ContentWidth during layout)
|
||||
};
|
||||
|
||||
// Storage for one active tab item (sizeof() 26~32 bytes)
|
||||
// Storage for one active tab item (sizeof() 28~32 bytes)
|
||||
struct ImGuiTabItem
|
||||
{
|
||||
ImGuiID ID;
|
||||
ImGuiTabItemFlags Flags;
|
||||
int LastFrameVisible;
|
||||
int LastFrameSelected; // This allows us to infer an ordered list of the last activated tabs with little maintenance
|
||||
int NameOffset; // When Window==NULL, offset to name within parent ImGuiTabBar::TabsNames
|
||||
float Offset; // Position relative to beginning of tab
|
||||
float Width; // Width currently displayed
|
||||
float ContentWidth; // Width of actual contents, stored during BeginTabItem() call
|
||||
ImS16 NameOffset; // When Window==NULL, offset to name within parent ImGuiTabBar::TabsNames
|
||||
bool WantClose; // Marked as closed by SetTabItemClosed()
|
||||
|
||||
ImGuiTabItem() { ID = 0; Flags = ImGuiTabItemFlags_None; LastFrameVisible = LastFrameSelected = -1; NameOffset = -1; Offset = Width = ContentWidth = 0.0f; }
|
||||
ImGuiTabItem() { ID = 0; Flags = ImGuiTabItemFlags_None; LastFrameVisible = LastFrameSelected = -1; NameOffset = -1; Offset = Width = ContentWidth = 0.0f; WantClose = false; }
|
||||
};
|
||||
|
||||
// Storage for a tab bar (sizeof() 92~96 bytes)
|
||||
@ -1736,7 +1747,7 @@ struct ImGuiTabBar
|
||||
int GetTabOrder(const ImGuiTabItem* tab) const { return Tabs.index_from_ptr(tab); }
|
||||
const char* GetTabName(const ImGuiTabItem* tab) const
|
||||
{
|
||||
IM_ASSERT(tab->NameOffset != -1 && tab->NameOffset < TabsNames.Buf.Size);
|
||||
IM_ASSERT(tab->NameOffset != -1 && (int)tab->NameOffset < TabsNames.Buf.Size);
|
||||
return TabsNames.Buf.Data + tab->NameOffset;
|
||||
}
|
||||
};
|
||||
@ -1773,6 +1784,7 @@ namespace ImGui
|
||||
IMGUI_API void SetWindowPos(ImGuiWindow* window, const ImVec2& pos, ImGuiCond cond = 0);
|
||||
IMGUI_API void SetWindowSize(ImGuiWindow* window, const ImVec2& size, ImGuiCond cond = 0);
|
||||
IMGUI_API void SetWindowCollapsed(ImGuiWindow* window, bool collapsed, ImGuiCond cond = 0);
|
||||
IMGUI_API void SetWindowHitTestHole(ImGuiWindow* window, const ImVec2& pos, const ImVec2& size);
|
||||
|
||||
// Windows: Display Order and Focus Order
|
||||
IMGUI_API void FocusWindow(ImGuiWindow* window);
|
||||
@ -1833,6 +1845,7 @@ namespace ImGui
|
||||
IMGUI_API bool ItemAdd(const ImRect& bb, ImGuiID id, const ImRect* nav_bb = NULL);
|
||||
IMGUI_API bool ItemHoverable(const ImRect& bb, ImGuiID id);
|
||||
IMGUI_API bool IsClippedEx(const ImRect& bb, ImGuiID id, bool clip_even_when_logged);
|
||||
IMGUI_API void SetLastItemData(ImGuiWindow* window, ImGuiID item_id, ImGuiItemStatusFlags status_flags, const ImRect& item_rect);
|
||||
IMGUI_API bool FocusableItemRegister(ImGuiWindow* window, ImGuiID id); // Return true if focus is requested
|
||||
IMGUI_API void FocusableItemUnregister(ImGuiWindow* window);
|
||||
IMGUI_API ImVec2 CalcItemSize(ImVec2 size, float default_w, float default_h);
|
||||
@ -1941,6 +1954,7 @@ namespace ImGui
|
||||
IMGUI_API void RenderMouseCursor(ImDrawList* draw_list, ImVec2 pos, float scale, ImGuiMouseCursor mouse_cursor, ImU32 col_fill, ImU32 col_border, ImU32 col_shadow);
|
||||
IMGUI_API void RenderArrowPointingAt(ImDrawList* draw_list, ImVec2 pos, ImVec2 half_sz, ImGuiDir direction, ImU32 col);
|
||||
IMGUI_API void RenderRectFilledRangeH(ImDrawList* draw_list, const ImRect& rect, ImU32 col, float x_start_norm, float x_end_norm, float rounding);
|
||||
IMGUI_API void RenderRectFilledWithHole(ImDrawList* draw_list, ImRect outer, ImRect inner, ImU32 col, float rounding);
|
||||
|
||||
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
|
||||
// [1.71: 2019/06/07: Updating prototypes of some of the internal functions. Leaving those for reference for a short while]
|
||||
@ -1964,8 +1978,8 @@ namespace ImGui
|
||||
|
||||
// Widgets low-level behaviors
|
||||
IMGUI_API bool ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool* out_held, ImGuiButtonFlags flags = 0);
|
||||
IMGUI_API bool DragBehavior(ImGuiID id, ImGuiDataType data_type, void* p_v, float v_speed, const void* p_min, const void* p_max, const char* format, float power, ImGuiDragFlags flags);
|
||||
IMGUI_API bool SliderBehavior(const ImRect& bb, ImGuiID id, ImGuiDataType data_type, void* p_v, const void* p_min, const void* p_max, const char* format, float power, ImGuiSliderFlags flags, ImRect* out_grab_bb);
|
||||
IMGUI_API bool DragBehavior(ImGuiID id, ImGuiDataType data_type, void* p_v, float v_speed, const void* p_min, const void* p_max, const char* format, ImGuiSliderFlags flags);
|
||||
IMGUI_API bool SliderBehavior(const ImRect& bb, ImGuiID id, ImGuiDataType data_type, void* p_v, const void* p_min, const void* p_max, const char* format, ImGuiSliderFlags flags, ImRect* out_grab_bb);
|
||||
IMGUI_API bool SplitterBehavior(const ImRect& bb, ImGuiID id, ImGuiAxis axis, float* size1, float* size2, float min_size1, float min_size2, float hover_extend = 0.0f, float hover_visibility_delay = 0.0f);
|
||||
IMGUI_API bool TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* label, const char* label_end = NULL);
|
||||
IMGUI_API bool TreeNodeBehaviorIsOpen(ImGuiID id, ImGuiTreeNodeFlags flags = 0); // Consume previous SetNextItemOpen() data, if any. May return true when logging
|
||||
@ -1974,9 +1988,10 @@ namespace ImGui
|
||||
// Template functions are instantiated in imgui_widgets.cpp for a finite number of types.
|
||||
// To use them externally (for custom widget) you may need an "extern template" statement in your code in order to link to existing instances and silence Clang warnings (see #2036).
|
||||
// e.g. " extern template IMGUI_API float RoundScalarWithFormatT<float, float>(const char* format, ImGuiDataType data_type, float v); "
|
||||
template<typename T, typename SIGNED_T, typename FLOAT_T> IMGUI_API bool DragBehaviorT(ImGuiDataType data_type, T* v, float v_speed, T v_min, T v_max, const char* format, float power, ImGuiDragFlags flags);
|
||||
template<typename T, typename SIGNED_T, typename FLOAT_T> IMGUI_API bool SliderBehaviorT(const ImRect& bb, ImGuiID id, ImGuiDataType data_type, T* v, T v_min, T v_max, const char* format, float power, ImGuiSliderFlags flags, ImRect* out_grab_bb);
|
||||
template<typename T, typename FLOAT_T> IMGUI_API float SliderCalcRatioFromValueT(ImGuiDataType data_type, T v, T v_min, T v_max, float power, float linear_zero_pos);
|
||||
template<typename T, typename FLOAT_T> IMGUI_API float ScaleRatioFromValueT(ImGuiDataType data_type, T v, T v_min, T v_max, bool is_logarithmic, float logarithmic_zero_epsilon, float zero_deadzone_size);
|
||||
template<typename T, typename FLOAT_T> IMGUI_API T ScaleValueFromRatioT(ImGuiDataType data_type, float t, T v_min, T v_max, bool is_logarithmic, float logarithmic_zero_epsilon, float zero_deadzone_size);
|
||||
template<typename T, typename SIGNED_T, typename FLOAT_T> IMGUI_API bool DragBehaviorT(ImGuiDataType data_type, T* v, float v_speed, T v_min, T v_max, const char* format, ImGuiSliderFlags flags);
|
||||
template<typename T, typename SIGNED_T, typename FLOAT_T> IMGUI_API bool SliderBehaviorT(const ImRect& bb, ImGuiID id, ImGuiDataType data_type, T* v, T v_min, T v_max, const char* format, ImGuiSliderFlags flags, ImRect* out_grab_bb);
|
||||
template<typename T, typename SIGNED_T> IMGUI_API T RoundScalarWithFormatT(const char* format, ImGuiDataType data_type, T v);
|
||||
|
||||
// Data type helpers
|
||||
@ -2021,6 +2036,7 @@ IMGUI_API void ImFontAtlasBuildInit(ImFontAtlas* atlas);
|
||||
IMGUI_API void ImFontAtlasBuildSetupFont(ImFontAtlas* atlas, ImFont* font, ImFontConfig* font_config, float ascent, float descent);
|
||||
IMGUI_API void ImFontAtlasBuildPackCustomRects(ImFontAtlas* atlas, void* stbrp_context_opaque);
|
||||
IMGUI_API void ImFontAtlasBuildFinish(ImFontAtlas* atlas);
|
||||
IMGUI_API void ImFontAtlasBuildRender1bppRectFromString(ImFontAtlas* atlas, int atlas_x, int atlas_y, int w, int h, const char* in_str, char in_marker_char, unsigned char in_marker_pixel_value);
|
||||
IMGUI_API void ImFontAtlasBuildMultiplyCalcLookupTable(unsigned char out_table[256], float in_multiply_factor);
|
||||
IMGUI_API void ImFontAtlasBuildMultiplyRectAlpha8(const unsigned char table[256], unsigned char* pixels, int x, int y, int w, int h, int stride);
|
||||
|
||||
@ -2028,8 +2044,8 @@ IMGUI_API void ImFontAtlasBuildMultiplyRectAlpha8(const unsigned ch
|
||||
// [SECTION] Test Engine Hooks (imgui_test_engine)
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
//#define IMGUI_ENABLE_TEST_ENGINE
|
||||
#ifdef IMGUI_ENABLE_TEST_ENGINE
|
||||
extern void ImGuiTestEngineHook_Shutdown(ImGuiContext* ctx);
|
||||
extern void ImGuiTestEngineHook_PreNewFrame(ImGuiContext* ctx);
|
||||
extern void ImGuiTestEngineHook_PostNewFrame(ImGuiContext* ctx);
|
||||
extern void ImGuiTestEngineHook_ItemAdd(ImGuiContext* ctx, const ImRect& bb, ImGuiID id);
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -382,7 +382,7 @@ bool ImFontAtlasBuildWithFreeType(FT_Library ft_library, ImFontAtlas* atlas, uns
|
||||
dst_tmp.GlyphsSet.Create(dst_tmp.GlyphsHighest + 1);
|
||||
|
||||
for (const ImWchar* src_range = src_tmp.SrcRanges; src_range[0] && src_range[1]; src_range += 2)
|
||||
for (int codepoint = src_range[0]; codepoint <= src_range[1]; codepoint++)
|
||||
for (int codepoint = src_range[0]; codepoint <= (int)src_range[1]; codepoint++)
|
||||
{
|
||||
if (dst_tmp.GlyphsSet.TestBit(codepoint)) // Don't overwrite existing glyphs. We could make this an option (e.g. MergeOverwrite)
|
||||
continue;
|
||||
@ -544,8 +544,11 @@ bool ImFontAtlasBuildWithFreeType(FT_Library ft_library, ImFontAtlas* atlas, uns
|
||||
if (src_tmp.GlyphsCount == 0)
|
||||
continue;
|
||||
|
||||
// When merging fonts with MergeMode=true:
|
||||
// - We can have multiple input fonts writing into a same destination font.
|
||||
// - dst_font->ConfigData is != from cfg which is our source configuration.
|
||||
ImFontConfig& cfg = atlas->ConfigData[src_i];
|
||||
ImFont* dst_font = cfg.DstFont; // We can have multiple input fonts writing into a same destination font (when using MergeMode=true)
|
||||
ImFont* dst_font = cfg.DstFont;
|
||||
|
||||
const float ascent = src_tmp.Font.Info.Ascender;
|
||||
const float descent = src_tmp.Font.Info.Descender;
|
||||
@ -576,14 +579,8 @@ bool ImFontAtlasBuildWithFreeType(FT_Library ft_library, ImFontAtlas* atlas, uns
|
||||
for (int y = info.Height; y > 0; y--, blit_dst += blit_dst_stride, blit_src += blit_src_stride)
|
||||
memcpy(blit_dst, blit_src, blit_src_stride);
|
||||
|
||||
float char_advance_x_org = info.AdvanceX;
|
||||
float char_advance_x_mod = ImClamp(char_advance_x_org, cfg.GlyphMinAdvanceX, cfg.GlyphMaxAdvanceX);
|
||||
float char_off_x = font_off_x;
|
||||
if (char_advance_x_org != char_advance_x_mod)
|
||||
char_off_x += cfg.PixelSnapH ? IM_FLOOR((char_advance_x_mod - char_advance_x_org) * 0.5f) : (char_advance_x_mod - char_advance_x_org) * 0.5f;
|
||||
|
||||
// Register glyph
|
||||
float x0 = info.OffsetX + char_off_x;
|
||||
float x0 = info.OffsetX + font_off_x;
|
||||
float y0 = info.OffsetY + font_off_y;
|
||||
float x1 = x0 + info.Width;
|
||||
float y1 = y0 + info.Height;
|
||||
@ -591,7 +588,7 @@ bool ImFontAtlasBuildWithFreeType(FT_Library ft_library, ImFontAtlas* atlas, uns
|
||||
float v0 = (ty) / (float)atlas->TexHeight;
|
||||
float u1 = (tx + info.Width) / (float)atlas->TexWidth;
|
||||
float v1 = (ty + info.Height) / (float)atlas->TexHeight;
|
||||
dst_font->AddGlyph((ImWchar)src_glyph.Codepoint, x0, y0, x1, y1, u0, v0, u1, v1, char_advance_x_mod);
|
||||
dst_font->AddGlyph(&cfg, (ImWchar)src_glyph.Codepoint, x0, y0, x1, y1, u0, v0, u1, v1, info.AdvanceX);
|
||||
}
|
||||
|
||||
src_tmp.Rects = NULL;
|
||||
|
Reference in New Issue
Block a user