Merge branch 'master' into docking

# Conflicts:
#	imgui.cpp
This commit is contained in:
omar 2020-06-20 22:06:01 +02:00
commit 20d61f5f62
11 changed files with 308 additions and 189 deletions

View File

@ -107,6 +107,8 @@ Breaking Changes:
- Removed unncessary ID (first arg) of ImFontAtlas::AddCustomRectRegular() function. Please - Removed unncessary ID (first arg) of ImFontAtlas::AddCustomRectRegular() function. Please
note that this is a Beta api and will likely be reworked to support multi-monitor multi-DPI. note that this is a Beta api and will likely be reworked to support multi-monitor multi-DPI.
- Renamed OpenPopupOnItemClick() to OpenPopupContextItem(). Kept inline redirection function (will obsolete).
- Removed CalcItemRectClosestPoint() entry point which was made obsolete and asserting in December 2017.
Other Changes: Other Changes:
@ -119,12 +121,20 @@ Other Changes:
Set to 0.0f (default) to always make a close button appear on hover (same as Chrome, VS). Set to 0.0f (default) to always make a close button appear on hover (same as Chrome, VS).
Set to FLT_MAX to only display a close button when selected (merely hovering is not enough). Set to FLT_MAX to only display a close button when selected (merely hovering is not enough).
Set to an intermediary value to toggle behavior based on width (same as Firefox). Set to an intermediary value to toggle behavior based on width (same as Firefox).
- Fix GetGlyphRangesKorean() end-range to end at 0xD7A3 (instead of 0xD79D). (#348, #3217) [@marukrap] - Tab: Added a ImGuiTabItemFlags_NoTooltip flag to disable the tooltip for individual tab item
(vs ImGuiTabBarFlags_NoTooltip for entire tab bar). [@Xipiryon]
- Popups: Fix an edge case where programatically closing a popup while clicking on its empty space
would attempt to focus it and close other popups. (#2880)
- Popups: Fix BeginPopupContextVoid() when clicking over the area made unavailable by a modal. (#1636)
- Popups: Clarified some of the comments and function prototypes.
- Metrics: Added a "Settings" section with some details about persistent ini settings. - Metrics: Added a "Settings" section with some details about persistent ini settings.
- Nav, Menus: Fix vertical wrap-around in menus or popups created with multiple appending calls to - Nav, Menus: Fix vertical wrap-around in menus or popups created with multiple appending calls to
BeginMenu()/EndMenu() or BeginPopup/EndPopup(). (#3223, #1207) [@rokups] BeginMenu()/EndMenu() or BeginPopup/EndPopup(). (#3223, #1207) [@rokups]
- Drag and Drop: Fixed unintended fallback "..." tooltip display during drag operation when - Drag and Drop: Fixed unintended fallback "..." tooltip display during drag operation when
drag source uses _SourceNoPreviewTooltip flags. (#3160) [@rokups] drag source uses _SourceNoPreviewTooltip flags. (#3160) [@rokups]
- Columns: Lower overhead on column switches and switching to background channel.
Benefits Columns but was primarily made with Tables in mind!
- Fonts: Fix GetGlyphRangesKorean() end-range to end at 0xD7A3 (instead of 0xD79D). (#348, #3217) [@marukrap]
- ImDrawList: Fixed an issue where draw command merging or primitive unreserve while crossing the - ImDrawList: Fixed an issue where draw command merging or primitive unreserve while crossing the
VtxOffset boundary would lead to draw commands with wrong VtxOffset. (#3129, #3163, #3232, #2591) VtxOffset boundary would lead to draw commands with wrong VtxOffset. (#3129, #3163, #3232, #2591)
[@thedmd, @Shironekoben, @sergeyn, @ocornut] [@thedmd, @Shironekoben, @sergeyn, @ocornut]
@ -135,6 +145,8 @@ Other Changes:
VtxOffset was not zero would lead to draw commands with wrong VtxOffset. (#2591) 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 - ImDrawList, ImDrawListSplitter, Columns: Fixed an issue where starting a split right after
a callback draw command would incorrectly override the callback draw command. 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() succeed but FT_Load_Glyph() fails. - Misc, Freetype: Fix for rare case where FT_Get_Char_Index() succeed but FT_Load_Glyph() fails.
- Docs: Improved and moved font documentation to docs/FONTS.md so it can be readable on the web. - 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] Updated various links/wiki accordingly. Added FAQ entry about DPI. (#2861) [@ButternCream, @ocornut]

View File

@ -15,12 +15,13 @@ or view this file with any Markdown viewer.
| [What is this library called?](#q-what-is-this-library-called) | | [What is this library called?](#q-what-is-this-library-called) |
| [Which version should I get?](#q-which-version-should-i-get) | | [Which version should I get?](#q-which-version-should-i-get) |
| **Q&A: Integration** | | **Q&A: Integration** |
| **[How to get started?](#q-how-to-get-started)** |
| **[How can I tell whether to dispatch mouse/keyboard to Dear ImGui or to my application?](#q-how-can-i-tell-whether-to-dispatch-mousekeyboard-to-dear-imgui-or-to-my-application)** | | **[How can I tell whether to dispatch mouse/keyboard to Dear ImGui or to my application?](#q-how-can-i-tell-whether-to-dispatch-mousekeyboard-to-dear-imgui-or-to-my-application)** |
| [How can I enable keyboard or gamepad controls?](#q-how-can-i-enable-keyboard-or-gamepad-controls) | | [How can I enable keyboard or gamepad controls?](#q-how-can-i-enable-keyboard-or-gamepad-controls) |
| [How can I use this on a machine without mouse, keyboard or screen? (input share, remote display)](#q-how-can-i-use-this-on-a-machine-without-mouse-keyboard-or-screen-input-share-remote-display) | | [How can I use this on a machine without mouse, keyboard or screen? (input share, remote display)](#q-how-can-i-use-this-on-a-machine-without-mouse-keyboard-or-screen-input-share-remote-display) |
| [I integrated Dear ImGui in my engine and the text or lines are blurry..](#q-i-integrated-dear-imgui-in-my-engine-and-the-text-or-lines-are-blurry) | | [I integrated Dear ImGui in my engine and little squares are showing instead of text..](#q-i-integrated-dear-imgui-in-my-engine-and-little-squares-are-showing-instead-of-text) |
| [I integrated Dear ImGui in my engine and some elements are clipping or disappearing when I move windows around..](#q-i-integrated-dear-imgui-in-my-engine-and-some-elements-are-clipping-or-disappearing-when-i-move-windows-around) | | [I integrated Dear ImGui in my engine and some elements are clipping or disappearing when I move windows around..](#q-i-integrated-dear-imgui-in-my-engine-and-some-elements-are-clipping-or-disappearing-when-i-move-windows-around) |
| [I integrated Dear ImGui in my engine and some elements are displaying outside their expected windows boundaries..](#q-i-integrated-dear-imgui-in-my-engine-and-some-elements-are-displaying-outside-their-expected-windows-boundaries) | [I integrated Dear ImGui in my engine and some elements are displaying outside their expected windows boundaries..](#q-i-integrated-dear-imgui-in-my-engine-and-some-elements-are-displaying-outside-their-expected-windows-boundaries) |
| **Q&A: Usage** | | **Q&A: Usage** |
| **[Why are multiple widgets reacting when I interact with a single one?<br>How can I have multiple widgets with the same label or with an empty label?](#q-why-are-multiple-widgets-reacting-when-i-interact-with-a-single-one-q-how-can-i-have-multiple-widgets-with-the-same-label-or-with-an-empty-label)** | | **[Why are multiple widgets reacting when I interact with a single one?<br>How can I have multiple widgets with the same label or with an empty label?](#q-why-are-multiple-widgets-reacting-when-i-interact-with-a-single-one-q-how-can-i-have-multiple-widgets-with-the-same-label-or-with-an-empty-label)** |
| [How can I display an image? What is ImTextureID, how does it work?](#q-how-can-i-display-an-image-what-is-imtextureid-how-does-it-work)| | [How can I display an image? What is ImTextureID, how does it work?](#q-how-can-i-display-an-image-what-is-imtextureid-how-does-it-work)|
@ -88,6 +89,15 @@ You may merge in the [tables](https://github.com/ocornut/imgui/tree/tables) bran
# Q&A: Integration # Q&A: Integration
### Q: How to get started?
Read `PROGRAMMER GUIDE` section of [imgui.cpp](https://github.com/ocornut/imgui/blob/master/imgui.cpp).
Read [examples/README.txt](https://github.com/ocornut/imgui/tree/master/examples/README.txt).
##### [Return to Index](#index)
---
### Q: How can I tell whether to dispatch mouse/keyboard to Dear ImGui or to my application? ### Q: How can I tell whether to dispatch mouse/keyboard to Dear ImGui or to my application?
You can read the `io.WantCaptureMouse`, `io.WantCaptureKeyboard` and `io.WantTextInput` flags from the ImGuiIO structure. You can read the `io.WantCaptureMouse`, `io.WantCaptureKeyboard` and `io.WantTextInput` flags from the ImGuiIO structure.
@ -139,9 +149,9 @@ Console SDK also sometimes provide equivalent tooling or wrapper for Synergy-lik
--- ---
### Q: I integrated Dear ImGui in my engine and the text or lines are blurry.. ### Q: I integrated Dear ImGui in my engine and little squares are showing instead of text..
In your Render function, try translating your projection matrix by (0.5f,0.5f) or (0.375f,0.375f). This usually means that: your font texture wasn't uploaded into GPU, or your shader or other rendering state are not reading from the right texture (e.g. texture wasn't bound).
Also make sure your orthographic projection matrix and io.DisplaySize matches your actual framebuffer dimension. If this happens using the standard back-ends it is probably that the texture failed to upload, which could happens if for some reason your texture is too big. Also see [docs/FONTS.md](https://github.com/ocornut/imgui/blob/master/docs/FONTS.md).
##### [Return to Index](#index) ##### [Return to Index](#index)

View File

@ -96,7 +96,7 @@ Calling the `ImGui::ShowDemoWindow()` function will create a demo window showcas
![screenshot demo](https://raw.githubusercontent.com/wiki/ocornut/imgui/web/v167/v167-misc.png) ![screenshot demo](https://raw.githubusercontent.com/wiki/ocornut/imgui/web/v167/v167-misc.png)
You should be able to build the examples from sources (tested on Windows/Mac/Linux). If you don't, let me know! If you want to have a quick look at some Dear ImGui features, you can download Windows binaries of the demo app here: 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-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).
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)). 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)).
@ -158,7 +158,7 @@ Private support is available for paying business customers (E-mail: _contact @ d
**Which version should I get?** **Which version should I get?**
I 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. 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. 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.

View File

@ -230,12 +230,13 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i
- listbox: future api should allow to enable horizontal scrolling (#2510) - listbox: future api should allow to enable horizontal scrolling (#2510)
!- popups/menus: clarify usage of popups id, how MenuItem/Selectable closing parent popups affects the ID, etc. this is quite fishy needs improvement! (#331, #402) !- popups/menus: clarify usage of popups id, how MenuItem/Selectable closing parent popups affects the ID, etc. this is quite fishy needs improvement! (#331, #402)
- popups/modal: make modal title bar blink when trying to click outside the modal - modals: make modal title bar blink when trying to click outside the modal
- popups: reopening context menu at new position should be the behavior by default? (equivalent to internal OpenPopupEx() with reopen_existing=true) (~#1497) - modals: technically speaking, we could make Begin() with ImGuiWindowFlags_Modal work without involving popup. May help untangle a few things, as modals are more like regular windows than popups.
- popups: if the popup functions took explicit ImGuiID it would allow the user to manage the scope of those ID. (#331) - popups: if the popup functions took explicit ImGuiID it would allow the user to manage the scope of those ID. (#331)
- popups: clicking outside (to close popup) and holding shouldn't drag window below. - 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: add variant using global identifier similar to Begin/End (#402)
- popups: border options. richer api like BeginChild() perhaps? (#197) - popups: border options. richer api like BeginChild() perhaps? (#197)
- 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. - tooltip: drag and drop with tooltip near monitor edges lose/changes its last direction instead of locking one. The drag and drop tooltip should always follow without changing direction.
- tooltip: tooltip that doesn't fit in entire screen seems to lose their "last preferred direction" and may teleport when moving mouse. - tooltip: tooltip that doesn't fit in entire screen seems to lose their "last preferred direction" and may teleport when moving mouse.
@ -423,6 +424,7 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i
- examples: window minimize, maximize (#583) - examples: window minimize, maximize (#583)
- examples: provide a zero frame-rate/idle example. - examples: provide a zero frame-rate/idle example.
- examples: dx11/dx12: try to use new swapchain blit models (#2970) - examples: dx11/dx12: try to use new swapchain blit models (#2970)
- backends: report it better when not able to create texture?
- backends: apple: example_apple should be using modern GL3. - backends: apple: example_apple should be using modern GL3.
- backends: glfw: could go idle when minimized? if (glfwGetWindowAttrib(window, GLFW_ICONIFIED)) { glfwWaitEvents(); continue; } // issue: DeltaTime will be super high on resume, perhaps provide a way to let impl know (#440) - backends: glfw: could go idle when minimized? if (glfwGetWindowAttrib(window, GLFW_ICONIFIED)) { glfwWaitEvents(); continue; } // issue: DeltaTime will be super high on resume, perhaps provide a way to let impl know (#440)
- backends: opengl: rename imgui_impl_opengl2 to impl_opengl_legacy and imgui_impl_opengl3 to imgui_impl_opengl? (#1900) - backends: opengl: rename imgui_impl_opengl2 to impl_opengl_legacy and imgui_impl_opengl3 to imgui_impl_opengl? (#1900)
@ -433,7 +435,7 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i
- backends: bgfx: https://gist.github.com/RichardGale/6e2b74bc42b3005e08397236e4be0fd0 - 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) - 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)
- optimization: replace vsnprintf with stb_printf? or enable the defines/infrastructure to allow it (#1038) - 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 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) - optimization: add a flag to disable most of rendering, for the case where the user expect to skip it (#335)
- optimization: fully covered window (covered by another with non-translucent bg + WindowRounding worth of padding) may want to clip rendering. - optimization: fully covered window (covered by another with non-translucent bg + WindowRounding worth of padding) may want to clip rendering.

View File

@ -33,29 +33,34 @@ You can find binaries of some of those example applications at:
--------------------------------------- ---------------------------------------
MISC COMMENTS AND SUGGESTIONS GETTING STARTED
--------------------------------------- ---------------------------------------
- Read FAQ at http://dearimgui.org/faq
- Please read 'PROGRAMMER GUIDE' in imgui.cpp for notes on how to setup Dear ImGui in your codebase. - Please read 'PROGRAMMER GUIDE' in imgui.cpp for notes on how to setup Dear ImGui in your codebase.
Please read the comments and instruction at the top of each file. Please read the comments and instruction at the top of each file.
Please read FAQ at http://www.dearimgui.org/faq
- If you are using of the backend provided here, so you can copy the imgui_impl_xxx.cpp/h files - If you are using of the backend provided here, you can add the imgui_impl_xxx.cpp/h files
to your project and use them unmodified. Each imgui_impl_xxxx.cpp comes with its own individual to your project and use them unmodified. Each imgui_impl_xxxx.cpp comes with its own individual
ChangeLog at the top of the .cpp files, so if you want to update them later it will be easier to Changelog at the top of the .cpp files, so if you want to update them later it will be easier to
catch up with what changed. catch up with what changed.
- Dear ImGui has 0 to 1 frame of lag for most behaviors, at 60 FPS your experience should be pleasant. - Dear ImGui has no particular extra lag for most behaviors, e.g. the value of 'io.MousePos' provided in
However, consider that OS mouse cursors are typically drawn through a specific hardware accelerated path NewFrame() will result at the time of EndFrame()/Render() in a moved windows rendered following that mouse
and will feel smoother than common GPU rendered contents (including Dear ImGui windows). movement. At 60 FPS your experience should be pleasant.
You may experiment with the io.MouseDrawCursor flag to request Dear ImGui to draw a mouse cursor itself, However, consider that OS mouse cursors are typically drawn through a very specific hardware accelerated
to visualize the lag between a hardware cursor and a software cursor. However, rendering a mouse cursor path and will feel smoother than the majority of contents rendererd via regular graphics API (including,
at 60 FPS will feel slow. It might be beneficial to the user experience to switch to a software rendered but not limited to Dear ImGui windows). Because UI rendering and interaction happens on the same plane as
cursor only when an interactive drag is in progress. the mouse, that disconnect may be jarring to particularly sensitive users.
Note that some setup or GPU drivers are likely to be causing extra lag depending on their settings. You may experiment with enabling the io.MouseDrawCursor flag to request Dear ImGui to draw a mouse cursor
If you feel that dragging windows feels laggy and you are not sure who to blame: try to build an using the regular graphics API, to help you visualize the difference between a "hardware" cursor and a
application drawing a shape directly under the mouse cursor. regularly rendered software cursor.
However, rendering a mouse cursor at 60 FPS will feel sluggish so you likely won't want to enable that at
all times. It might be beneficial for the user experience to switch to a software rendered cursor _only_
when an interactive drag is in progress.
Note that some setup or GPU drivers are likely to be causing extra display lag depending on their settings.
If you feel that dragging windows feels laggy and you are not sure what the cause is: try to build a simple
drawing a flat 2D shape directly under the mouse cursor.
--------------------------------------- ---------------------------------------
@ -162,12 +167,12 @@ Those will allow you to create portable applications and will solve and abstract
Building: Building:
Unfortunately in 2020 it is still tedious to create and maintain portable build files using external Unfortunately in 2020 it is still tedious to create and maintain portable build files using external
libraries (the kind we're using here to create a window and render 3D triangles) without relying on libraries (the kind we're using here to create a window and render 3D triangles) without relying on
third party software. For most examples here I choose to provide: third party software. For most examples here we choose to provide:
- Makefiles for Linux/OSX - Makefiles for Linux/OSX
- Batch files for Visual Studio 2008+ - Batch files for Visual Studio 2008+
- A .sln project file for Visual Studio 2010+ - A .sln project file for Visual Studio 2012+
- Xcode project files for the Apple examples - Xcode project files for the Apple examples
Please let me know if they don't work with your setup! Please let us know if they don't work with your setup!
You can probably just import the imgui_impl_xxx.cpp/.h files into your own codebase or compile those You can probably just import the imgui_impl_xxx.cpp/.h files into your own codebase or compile those
directly with a command-line compiler. directly with a command-line compiler.

104
imgui.cpp
View File

@ -18,7 +18,7 @@
// Developed by Omar Cornut and every direct or indirect contributors to the GitHub. // Developed by Omar Cornut and every direct or indirect contributors to the GitHub.
// See LICENSE.txt for copyright and licensing details (standard MIT License). // See LICENSE.txt for copyright and licensing details (standard MIT License).
// This library is free but I need your support to sustain development and maintenance. // This library is free but needs your support to sustain development and maintenance.
// Businesses: you can support continued development via invoiced technical support, maintenance and sponsoring contracts. Please reach out to "contact AT dearimgui.org". // Businesses: you can support continued development via invoiced technical support, maintenance and sponsoring contracts. Please reach out to "contact AT dearimgui.org".
// Individuals: you can support continued development via donations. See docs/README or web page. // Individuals: you can support continued development via donations. See docs/README or web page.
@ -171,7 +171,7 @@ CODE
--------------------------------------------------------------- ---------------------------------------------------------------
- Run and study the examples and demo in imgui_demo.cpp to get acquainted with the library. - Run and study the examples and demo in imgui_demo.cpp to get acquainted with the library.
- In the majority of cases you should be able to use unmodified back-ends files available in the examples/ folder. - In the majority of cases you should be able to use unmodified back-ends files available in the examples/ folder.
- Add the Dear ImGui source files to your projects or using your preferred build system. - Add the Dear ImGui source files + selected back-end source files to your projects or using your preferred build system.
It is recommended you build and statically link the .cpp files as part of your project and NOT as shared library (DLL). It is recommended you build and statically link the .cpp files as part of your project and NOT as shared library (DLL).
- You can later customize the imconfig.h file to tweak some compile-time behavior, such as integrating Dear ImGui types with your own maths types. - You can later customize the imconfig.h file to tweak some compile-time behavior, such as integrating Dear ImGui types with your own maths types.
- When using Dear ImGui, your programming IDE is your friend: follow the declaration of variables, functions and types to find comments about them. - When using Dear ImGui, your programming IDE is your friend: follow the declaration of variables, functions and types to find comments about them.
@ -383,7 +383,9 @@ CODE
- 2019/XX/XX (1.XX) - Moved IME support functions from io.ImeSetInputScreenPosFn, io.ImeWindowHandle to the PlatformIO api. - 2019/XX/XX (1.XX) - Moved IME support functions from io.ImeSetInputScreenPosFn, io.ImeWindowHandle to the PlatformIO api.
- 2020/04/23 (1.77) - Removed unnecessary ID (first arg) of ImFontAtlas::AddCustomRectRegular(). - 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.
- 2020/04/23 (1.77) - removed unnecessary ID (first arg) of ImFontAtlas::AddCustomRectRegular().
- 2020/01/22 (1.75) - ImDrawList::AddCircle()/AddCircleFilled() functions don't accept negative radius any more. - 2020/01/22 (1.75) - ImDrawList::AddCircle()/AddCircleFilled() functions don't accept negative radius any more.
- 2019/12/17 (1.75) - [undid this change in 1.76] made Columns() limited to 64 columns by asserting above that limit. While the current code technically supports it, future code may not so we're putting the restriction ahead. - 2019/12/17 (1.75) - [undid this change in 1.76] made Columns() limited to 64 columns by asserting above that limit. While the current code technically supports it, future code may not so we're putting the restriction ahead.
- 2019/12/13 (1.75) - [imgui_internal.h] changed ImRect() default constructor initializes all fields to 0.0f instead of (FLT_MAX,FLT_MAX,-FLT_MAX,-FLT_MAX). If you used ImRect::Add() to create bounding boxes by adding multiple points into it, you may need to fix your initial value. - 2019/12/13 (1.75) - [imgui_internal.h] changed ImRect() default constructor initializes all fields to 0.0f instead of (FLT_MAX,FLT_MAX,-FLT_MAX,-FLT_MAX). If you used ImRect::Add() to create bounding boxes by adding multiple points into it, you may need to fix your initial value.
@ -631,18 +633,21 @@ CODE
Q: What is this library called? Q: What is this library called?
Q: Which version should I get? Q: Which version should I get?
>> This library is called "Dear ImGui", please don't call it "ImGui" :) >> This library is called "Dear ImGui", please don't call it "ImGui" :)
>> See https://www.dearimgui.org/faq >> See https://www.dearimgui.org/faq for details.
Q&A: Integration Q&A: Integration
================ ================
Q: How to get started?
A: Read 'PROGRAMMER GUIDE' above. Read examples/README.txt.
Q: How can I tell whether to dispatch mouse/keyboard to Dear ImGui or to my application? Q: How can I tell whether to dispatch mouse/keyboard to Dear ImGui or to my application?
A: You should read the 'io.WantCaptureMouse', 'io.WantCaptureKeyboard' and 'io.WantTextInput' flags! A: You should read the 'io.WantCaptureMouse', 'io.WantCaptureKeyboard' and 'io.WantTextInput' flags!
>> See https://www.dearimgui.org/faq for fully detailed answer. You really want to read this. >> See https://www.dearimgui.org/faq for fully detailed answer. You really want to read this.
Q. How can I enable keyboard controls? Q. How can I enable keyboard controls?
Q: How can I use this without a mouse, without a keyboard or without a screen? (gamepad, input share, remote display) Q: How can I use this without a mouse, without a keyboard or without a screen? (gamepad, input share, remote display)
Q: I integrated Dear ImGui in my engine and the text or lines are blurry.. Q: I integrated Dear ImGui in my engine and little squares are showing instead of text..
Q: I integrated Dear ImGui in my engine and some elements are clipping or disappearing when I move windows around.. Q: I integrated Dear ImGui in my engine and some elements are clipping or disappearing when I move windows around..
Q: I integrated Dear ImGui in my engine and some elements are displaying outside their expected windows boundaries.. Q: I integrated Dear ImGui in my engine and some elements are displaying outside their expected windows boundaries..
>> See https://www.dearimgui.org/faq >> See https://www.dearimgui.org/faq
@ -873,21 +878,21 @@ CODE
// Clang/GCC warnings with -Weverything // Clang/GCC warnings with -Weverything
#if defined(__clang__) #if defined(__clang__)
#pragma clang diagnostic ignored "-Wunknown-pragmas" // warning : unknown warning group '-Wformat-pedantic *' // not all warnings are known by all clang versions.. so ignoring warnings triggers new warnings on some configuration. great! #if __has_warning("-Wunknown-warning-option")
#pragma clang diagnostic ignored "-Wunknown-warning-option" // warning: unknown warning group 'xxx' // not all warnings are known by all Clang versions and they tend to be rename-happy.. so ignoring warnings triggers new warnings on some configuration. Great!
#endif
#pragma clang diagnostic ignored "-Wunknown-pragmas" // warning: unknown warning group 'xxx'
#pragma clang diagnostic ignored "-Wold-style-cast" // warning: use of old-style cast // yes, they are more terse. #pragma clang diagnostic ignored "-Wold-style-cast" // warning: use of old-style cast // yes, they are more terse.
#pragma clang diagnostic ignored "-Wfloat-equal" // warning: comparing floating point with == or != is unsafe // storing and comparing against same constants (typically 0.0f) is ok. #pragma clang diagnostic ignored "-Wfloat-equal" // warning: comparing floating point with == or != is unsafe // storing and comparing against same constants (typically 0.0f) is ok.
#pragma clang diagnostic ignored "-Wformat-nonliteral" // warning: format string is not a string literal // passing non-literal to vsnformat(). yes, user passing incorrect format strings can crash the code. #pragma clang diagnostic ignored "-Wformat-nonliteral" // warning: format string is not a string literal // passing non-literal to vsnformat(). yes, user passing incorrect format strings can crash the code.
#pragma clang diagnostic ignored "-Wexit-time-destructors" // warning: declaration requires an exit-time destructor // exit-time destruction order is undefined. if MemFree() leads to users code that has been disabled before exit it might cause problems. ImGui coding style welcomes static/globals. #pragma clang diagnostic ignored "-Wexit-time-destructors" // warning: declaration requires an exit-time destructor // exit-time destruction order is undefined. if MemFree() leads to users code that has been disabled before exit it might cause problems. ImGui coding style welcomes static/globals.
#pragma clang diagnostic ignored "-Wglobal-constructors" // warning: declaration requires a global destructor // similar to above, not sure what the exact difference is. #pragma clang diagnostic ignored "-Wglobal-constructors" // warning: declaration requires a global destructor // similar to above, not sure what the exact difference is.
#pragma clang diagnostic ignored "-Wsign-conversion" // warning : implicit conversion changes signedness // #pragma clang diagnostic ignored "-Wsign-conversion" // warning: implicit conversion changes signedness
#pragma clang diagnostic ignored "-Wformat-pedantic" // warning: format specifies type 'void *' but the argument has type 'xxxx *' // unreasonable, would lead to casting every %p arg to void*. probably enabled by -pedantic. #pragma clang diagnostic ignored "-Wformat-pedantic" // warning: format specifies type 'void *' but the argument has type 'xxxx *' // unreasonable, would lead to casting every %p arg to void*. probably enabled by -pedantic.
#pragma clang diagnostic ignored "-Wint-to-void-pointer-cast" // warning: cast to 'void *' from smaller integer type 'int' #pragma clang diagnostic ignored "-Wint-to-void-pointer-cast" // warning: cast to 'void *' from smaller integer type 'int'
#if __has_warning("-Wzero-as-null-pointer-constant")
#pragma clang diagnostic ignored "-Wzero-as-null-pointer-constant" // warning: zero as null pointer constant // some standard header variations use #define NULL 0 #pragma clang diagnostic ignored "-Wzero-as-null-pointer-constant" // warning: zero as null pointer constant // some standard header variations use #define NULL 0
#endif
#if __has_warning("-Wdouble-promotion")
#pragma clang diagnostic ignored "-Wdouble-promotion" // warning: implicit conversion from 'float' to 'double' when passing argument to function // using printf() is a misery with this as C++ va_arg ellipsis changes float to double. #pragma clang diagnostic ignored "-Wdouble-promotion" // warning: implicit conversion from 'float' to 'double' when passing argument to function // using printf() is a misery with this as C++ va_arg ellipsis changes float to double.
#endif #pragma clang diagnostic ignored "-Wimplicit-int-float-conversion" // warning: implicit conversion from 'xxx' to 'float' may lose precision
#elif defined(__GNUC__) #elif defined(__GNUC__)
// We disable -Wpragmas because GCC doesn't provide an has_warning equivalent and some forks/patches may not following the warning/version association. // We disable -Wpragmas because GCC doesn't provide an has_warning equivalent and some forks/patches may not following the warning/version association.
#pragma GCC diagnostic ignored "-Wpragmas" // warning: unknown option after '#pragma GCC diagnostic' kind #pragma GCC diagnostic ignored "-Wpragmas" // warning: unknown option after '#pragma GCC diagnostic' kind
@ -3228,6 +3233,10 @@ bool ImGui::ItemHoverable(const ImRect& bb, ImGuiID id)
if (window->DC.ItemFlags & ImGuiItemFlags_Disabled) if (window->DC.ItemFlags & ImGuiItemFlags_Disabled)
return false; 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.
if (id != 0)
{
SetHoveredID(id); SetHoveredID(id);
// [DEBUG] Item Picker tool! // [DEBUG] Item Picker tool!
@ -3239,6 +3248,7 @@ bool ImGui::ItemHoverable(const ImRect& bb, ImGuiID id)
GetForegroundDrawList()->AddRect(bb.Min, bb.Max, IM_COL32(255, 255, 0, 255)); GetForegroundDrawList()->AddRect(bb.Min, bb.Max, IM_COL32(255, 255, 0, 255));
if (g.DebugItemPickerBreakId == id) if (g.DebugItemPickerBreakId == id)
IM_DEBUG_BREAK(); IM_DEBUG_BREAK();
}
return true; return true;
} }
@ -3595,8 +3605,12 @@ void ImGui::UpdateMouseMovingWindowEndFrame()
// (after we're done with all our widgets, so e.g. clicking on docking tab-bar which have set HoveredId already and not get us here!) // (after we're done with all our widgets, so e.g. clicking on docking tab-bar which have set HoveredId already and not get us here!)
if (g.IO.MouseClicked[0]) if (g.IO.MouseClicked[0])
{ {
// Handle the edge case of a popup being closed while clicking in its empty space.
// If we try to focus it, FocusWindow() > ClosePopupsOverWindow() will accidentally close any parent popups because they are not linked together any more.
ImGuiWindow* root_window = g.HoveredWindow ? g.HoveredWindow->RootWindowDockStop : NULL; ImGuiWindow* root_window = g.HoveredWindow ? g.HoveredWindow->RootWindowDockStop : NULL;
if (root_window != NULL) const bool is_closed_popup = root_window && (root_window->Flags & ImGuiWindowFlags_Popup) && !IsPopupOpenAtAnyLevel(root_window->PopupId);
if (root_window != NULL && !is_closed_popup)
{ {
StartMouseMovingWindow(g.HoveredWindow); StartMouseMovingWindow(g.HoveredWindow);
if (g.IO.ConfigWindowsMoveFromTitleBarOnly) if (g.IO.ConfigWindowsMoveFromTitleBarOnly)
@ -3604,7 +3618,7 @@ void ImGui::UpdateMouseMovingWindowEndFrame()
if (!root_window->TitleBarRect().Contains(g.IO.MouseClickedPos[0])) if (!root_window->TitleBarRect().Contains(g.IO.MouseClickedPos[0]))
g.MovingWindow = NULL; g.MovingWindow = NULL;
} }
else if (g.NavWindow != NULL && GetTopMostPopupModal() == NULL) else if (root_window != NULL && g.NavWindow != NULL && GetTopMostPopupModal() == NULL)
{ {
// Clicking on void disable focus // Clicking on void disable focus
FocusWindow(NULL); FocusWindow(NULL);
@ -3868,7 +3882,7 @@ void ImGui::UpdateHoveredWindowAndCaptureFlags()
for (int i = 0; i < IM_ARRAYSIZE(g.IO.MouseDown); i++) for (int i = 0; i < IM_ARRAYSIZE(g.IO.MouseDown); i++)
{ {
if (g.IO.MouseClicked[i]) if (g.IO.MouseClicked[i])
g.IO.MouseDownOwned[i] = (g.HoveredWindow != NULL) || (!g.OpenPopupStack.empty()); g.IO.MouseDownOwned[i] = (g.HoveredWindow != NULL) || (g.OpenPopupStack.Size > 0);
mouse_any_down |= g.IO.MouseDown[i]; mouse_any_down |= g.IO.MouseDown[i];
if (g.IO.MouseDown[i]) if (g.IO.MouseDown[i])
if (mouse_earliest_button_down == -1 || g.IO.MouseClickedTime[i] < g.IO.MouseClickedTime[mouse_earliest_button_down]) if (mouse_earliest_button_down == -1 || g.IO.MouseClickedTime[i] < g.IO.MouseClickedTime[mouse_earliest_button_down])
@ -3886,7 +3900,7 @@ void ImGui::UpdateHoveredWindowAndCaptureFlags()
if (g.WantCaptureMouseNextFrame != -1) if (g.WantCaptureMouseNextFrame != -1)
g.IO.WantCaptureMouse = (g.WantCaptureMouseNextFrame != 0); g.IO.WantCaptureMouse = (g.WantCaptureMouseNextFrame != 0);
else else
g.IO.WantCaptureMouse = (mouse_avail_to_imgui && (g.HoveredWindow != NULL || mouse_any_down)) || (!g.OpenPopupStack.empty()); g.IO.WantCaptureMouse = (mouse_avail_to_imgui && (g.HoveredWindow != NULL || mouse_any_down)) || (g.OpenPopupStack.Size > 0);
// Update io.WantCaptureKeyboard for the user application (true = dispatch keyboard info to imgui, false = dispatch keyboard info to Dear ImGui + app) // Update io.WantCaptureKeyboard for the user application (true = dispatch keyboard info to imgui, false = dispatch keyboard info to Dear ImGui + app)
if (g.WantCaptureKeyboardNextFrame != -1) if (g.WantCaptureKeyboardNextFrame != -1)
@ -4387,7 +4401,12 @@ static void SetupViewportDrawData(ImGuiViewportP* viewport, ImVector<ImDrawList*
} }
} }
// When using this function it is sane to ensure that float are perfectly rounded to integer values, to that e.g. (int)(max.x-min.x) in user's render produce correct result. // Push a clipping rectangle for both ImGui logic (hit-testing etc.) and low-level ImDrawList rendering.
// - When using this function it is sane to ensure that float are perfectly rounded to integer values,
// so that e.g. (int)(max.x-min.x) in user's render produce correct result.
// - If the code here changes, may need to update code of functions like NextColumn() and PushColumnClipRect():
// some frequently called functions which to modify both channels and clipping simultaneously tend to use the
// more specialized SetWindowClipRectBeforeSetChannel() to avoid extraneous updates of underlying ImDrawCmds.
void ImGui::PushClipRect(const ImVec2& clip_rect_min, const ImVec2& clip_rect_max, bool intersect_with_current_clip_rect) void ImGui::PushClipRect(const ImVec2& clip_rect_min, const ImVec2& clip_rect_max, bool intersect_with_current_clip_rect)
{ {
ImGuiWindow* window = GetCurrentWindow(); ImGuiWindow* window = GetCurrentWindow();
@ -5592,11 +5611,13 @@ static bool ImGui::UpdateWindowManualResize(ImGuiWindow* window, const ImVec2& s
return ret_auto_fit; return ret_auto_fit;
} }
static inline void ClampWindowRect(ImGuiWindow* window, const ImRect& rect, const ImVec2& padding) static inline void ClampWindowRect(ImGuiWindow* window, const ImRect& viewport_rect, const ImVec2& padding)
{ {
ImGuiContext& g = *GImGui; ImGuiContext& g = *GImGui;
ImVec2 size_for_clamping = (g.IO.ConfigWindowsMoveFromTitleBarOnly && !(window->Flags & ImGuiWindowFlags_NoTitleBar)) ? ImVec2(window->Size.x, window->TitleBarHeight()) : window->Size; ImVec2 size_for_clamping = window->Size;
window->Pos = ImMin(rect.Max - padding, ImMax(window->Pos + size_for_clamping, rect.Min + padding) - size_for_clamping); if (g.IO.ConfigWindowsMoveFromTitleBarOnly && !(window->Flags & ImGuiWindowFlags_NoTitleBar))
size_for_clamping.y = window->TitleBarHeight();
window->Pos = ImClamp(window->Pos, viewport_rect.Min + padding - size_for_clamping, viewport_rect.Max - padding);
} }
static void ImGui::RenderWindowOuterBorders(ImGuiWindow* window) static void ImGui::RenderWindowOuterBorders(ImGuiWindow* window)
@ -6026,6 +6047,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
window->HasCloseButton = (p_open != NULL); window->HasCloseButton = (p_open != NULL);
window->ClipRect = ImVec4(-FLT_MAX,-FLT_MAX,+FLT_MAX,+FLT_MAX); window->ClipRect = ImVec4(-FLT_MAX,-FLT_MAX,+FLT_MAX,+FLT_MAX);
window->IDStack.resize(1); window->IDStack.resize(1);
window->DrawList->_ResetForNewFrame();
// Restore buffer capacity when woken from a compacted state, to avoid // Restore buffer capacity when woken from a compacted state, to avoid
if (window->MemoryCompacted) if (window->MemoryCompacted)
@ -6436,7 +6458,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
// DRAWING // DRAWING
// Setup draw list and outer clipping rectangle // Setup draw list and outer clipping rectangle
window->DrawList->_ResetForNewFrame(); IM_ASSERT(window->DrawList->CmdBuffer.Size == 1 && window->DrawList->CmdBuffer[0].ElemCount == 0);
window->DrawList->PushTextureID(g.Font->ContainerAtlas->TexID); window->DrawList->PushTextureID(g.Font->ContainerAtlas->TexID);
PushClipRect(host_rect.Min, host_rect.Max, false); PushClipRect(host_rect.Min, host_rect.Max, false);
@ -8337,18 +8359,37 @@ void ImGui::SetTooltip(const char* fmt, ...)
// [SECTION] POPUPS // [SECTION] POPUPS
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Return true if the popup is open at the current BeginPopup() level of the popup stack
bool ImGui::IsPopupOpen(ImGuiID id) bool ImGui::IsPopupOpen(ImGuiID id)
{ {
ImGuiContext& g = *GImGui; ImGuiContext& g = *GImGui;
return g.OpenPopupStack.Size > g.BeginPopupStack.Size && g.OpenPopupStack[g.BeginPopupStack.Size].PopupId == id; return g.OpenPopupStack.Size > g.BeginPopupStack.Size && g.OpenPopupStack[g.BeginPopupStack.Size].PopupId == id;
} }
// Return true if the popup is open at the current BeginPopup() level of the popup stack
bool ImGui::IsPopupOpen(const char* str_id) bool ImGui::IsPopupOpen(const char* str_id)
{ {
ImGuiContext& g = *GImGui; ImGuiContext& g = *GImGui;
return g.OpenPopupStack.Size > g.BeginPopupStack.Size && g.OpenPopupStack[g.BeginPopupStack.Size].PopupId == g.CurrentWindow->GetID(str_id); return g.OpenPopupStack.Size > g.BeginPopupStack.Size && g.OpenPopupStack[g.BeginPopupStack.Size].PopupId == g.CurrentWindow->GetID(str_id);
} }
bool ImGui::IsPopupOpenAtAnyLevel(ImGuiID id)
{
ImGuiContext& g = *GImGui;
for (int n = 0; n < g.OpenPopupStack.Size; n++)
if (g.OpenPopupStack[n].PopupId == id)
return true;
return false;
}
// Return true if any popup is open at the current BeginPopup() level of the popup stack
// This may be used to e.g. test for another popups already opened in the same frame to handle popups priorities at the same level.
bool ImGui::IsAnyPopupOpen()
{
ImGuiContext& g = *GImGui;
return g.OpenPopupStack.Size > g.BeginPopupStack.Size;
}
ImGuiWindow* ImGui::GetTopMostPopupModal() ImGuiWindow* ImGui::GetTopMostPopupModal()
{ {
ImGuiContext& g = *GImGui; ImGuiContext& g = *GImGui;
@ -8400,8 +8441,8 @@ void ImGui::OpenPopupEx(ImGuiID id)
else else
{ {
// Close child popups if any, then flag popup for open/reopen // Close child popups if any, then flag popup for open/reopen
g.OpenPopupStack.resize(current_stack_size + 1); ClosePopupToLevel(current_stack_size, false);
g.OpenPopupStack[current_stack_size] = popup_ref; g.OpenPopupStack.push_back(popup_ref);
} }
// When reopening a popup we first refocus its parent, otherwise if its parent is itself a popup it would get closed by ClosePopupsOverWindow(). // When reopening a popup we first refocus its parent, otherwise if its parent is itself a popup it would get closed by ClosePopupsOverWindow().
@ -8414,7 +8455,7 @@ void ImGui::OpenPopupEx(ImGuiID id)
void ImGui::ClosePopupsOverWindow(ImGuiWindow* ref_window, bool restore_focus_to_window_under_popup) void ImGui::ClosePopupsOverWindow(ImGuiWindow* ref_window, bool restore_focus_to_window_under_popup)
{ {
ImGuiContext& g = *GImGui; ImGuiContext& g = *GImGui;
if (g.OpenPopupStack.empty()) if (g.OpenPopupStack.Size == 0)
return; return;
// When popups are stacked, clicking on a lower level popups puts focus back to it and close popups above it. // When popups are stacked, clicking on a lower level popups puts focus back to it and close popups above it.
@ -8454,6 +8495,8 @@ void ImGui::ClosePopupToLevel(int remaining, bool restore_focus_to_window_under_
ImGuiContext& g = *GImGui; ImGuiContext& g = *GImGui;
IMGUI_DEBUG_LOG_POPUP("ClosePopupToLevel(%d), restore_focus_to_window_under_popup=%d\n", remaining, restore_focus_to_window_under_popup); 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); IM_ASSERT(remaining >= 0 && remaining < g.OpenPopupStack.Size);
// Trim open popup stack
ImGuiWindow* focus_window = g.OpenPopupStack[remaining].SourceWindow; ImGuiWindow* focus_window = g.OpenPopupStack[remaining].SourceWindow;
ImGuiWindow* popup_window = g.OpenPopupStack[remaining].Window; ImGuiWindow* popup_window = g.OpenPopupStack[remaining].Window;
g.OpenPopupStack.resize(remaining); g.OpenPopupStack.resize(remaining);
@ -8592,7 +8635,7 @@ void ImGui::EndPopup()
g.WithinEndChild = false; g.WithinEndChild = false;
} }
bool ImGui::OpenPopupOnItemClick(const char* str_id, ImGuiMouseButton mouse_button) bool ImGui::OpenPopupContextItem(const char* str_id, ImGuiMouseButton mouse_button)
{ {
ImGuiWindow* window = GImGui->CurrentWindow; ImGuiWindow* window = GImGui->CurrentWindow;
if (IsMouseReleased(mouse_button) && IsItemHovered(ImGuiHoveredFlags_AllowWhenBlockedByPopup)) if (IsMouseReleased(mouse_button) && IsItemHovered(ImGuiHoveredFlags_AllowWhenBlockedByPopup))
@ -8606,8 +8649,10 @@ bool ImGui::OpenPopupOnItemClick(const char* str_id, ImGuiMouseButton mouse_butt
} }
// This is a helper to handle the simplest case of associating one named popup to one given widget. // This is a helper to handle the simplest case of associating one named popup to one given widget.
// You may want to handle this on user side if you have specific needs (e.g. tweaking IsItemHovered() parameters). // - You can pass a NULL str_id to use the identifier of the last item.
// You can pass a NULL str_id to use the identifier of the last item. // - You may want to handle this on user side if you have specific needs (e.g. tweaking IsItemHovered() parameters).
// - This is essentially the same as calling OpenPopupContextItem() + BeginPopup() but written to avoid
// computing the ID twice because BeginPopupContextXXX functions are called very frequently.
bool ImGui::BeginPopupContextItem(const char* str_id, ImGuiMouseButton mouse_button) bool ImGui::BeginPopupContextItem(const char* str_id, ImGuiMouseButton mouse_button)
{ {
ImGuiWindow* window = GImGui->CurrentWindow; ImGuiWindow* window = GImGui->CurrentWindow;
@ -8622,9 +8667,10 @@ bool ImGui::BeginPopupContextItem(const char* str_id, ImGuiMouseButton mouse_but
bool ImGui::BeginPopupContextWindow(const char* str_id, ImGuiMouseButton mouse_button, bool also_over_items) bool ImGui::BeginPopupContextWindow(const char* str_id, ImGuiMouseButton mouse_button, bool also_over_items)
{ {
ImGuiWindow* window = GImGui->CurrentWindow;
if (!str_id) if (!str_id)
str_id = "window_context"; str_id = "window_context";
ImGuiID id = GImGui->CurrentWindow->GetID(str_id); ImGuiID id = window->GetID(str_id);
if (IsMouseReleased(mouse_button) && IsWindowHovered(ImGuiHoveredFlags_AllowWhenBlockedByPopup)) if (IsMouseReleased(mouse_button) && IsWindowHovered(ImGuiHoveredFlags_AllowWhenBlockedByPopup))
if (also_over_items || !IsAnyItemHovered()) if (also_over_items || !IsAnyItemHovered())
OpenPopupEx(id); OpenPopupEx(id);
@ -8633,10 +8679,12 @@ bool ImGui::BeginPopupContextWindow(const char* str_id, ImGuiMouseButton mouse_b
bool ImGui::BeginPopupContextVoid(const char* str_id, ImGuiMouseButton mouse_button) bool ImGui::BeginPopupContextVoid(const char* str_id, ImGuiMouseButton mouse_button)
{ {
ImGuiWindow* window = GImGui->CurrentWindow;
if (!str_id) if (!str_id)
str_id = "void_context"; str_id = "void_context";
ImGuiID id = GImGui->CurrentWindow->GetID(str_id); ImGuiID id = window->GetID(str_id);
if (IsMouseReleased(mouse_button) && !IsWindowHovered(ImGuiHoveredFlags_AnyWindow)) if (IsMouseReleased(mouse_button) && !IsWindowHovered(ImGuiHoveredFlags_AnyWindow))
if (GetTopMostPopupModal() == NULL)
OpenPopupEx(id); OpenPopupEx(id);
return BeginPopupEx(id, ImGuiWindowFlags_AlwaysAutoResize|ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoSavedSettings); return BeginPopupEx(id, ImGuiWindowFlags_AlwaysAutoResize|ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoSavedSettings);
} }

53
imgui.h
View File

@ -603,27 +603,34 @@ namespace ImGui
IMGUI_API void SetTooltipV(const char* fmt, va_list args) IM_FMTLIST(1); IMGUI_API void SetTooltipV(const char* fmt, va_list args) IM_FMTLIST(1);
// Popups, Modals // Popups, Modals
// The properties of popups windows are: // - They block normal mouse hovering detection (and therefore most mouse interactions) behind them.
// - They block normal mouse hovering detection outside them. (*1) // - If not modal: they can be closed by clicking anywhere outside them, or by pressing ESCAPE.
// - Unless modal, they can be closed by clicking anywhere outside them, or by pressing ESCAPE. // - Their visibility state (~bool) is held internally instead of being held by the programmer as we are used to with regular Begin*() calls.
// Because hovering detection is disabled outside the popup, when clicking outside the click will not be seen by underlying widgets! (*1) // - The 3 properties above are related: we need to retain popup visibility state in the library because popups may be closed as any time.
// - Their visibility state (~bool) is held internally by Dear ImGui instead of being held by the programmer as we are used to with regular Begin() calls. // - You can bypass the hovering restriction by using ImGuiHoveredFlags_AllowWhenBlockedByPopup when calling IsItemHovered() or IsWindowHovered().
// User can manipulate the visibility state by calling OpenPopup(), CloseCurrentPopup() etc. // - IMPORTANT: Popup identifiers are relative to the current ID stack, so OpenPopup and BeginPopup generally needs to be at the same level of the stack.
// - We default to use the right mouse (ImGuiMouseButton_Right=1) for the Popup Context functions. // This is sometimes leading to confusing mistakes. May rework this in the future.
// Those three properties are connected: we need to retain popup visibility state in the library because popups may be closed as any time. // Popups: begin/end functions
// (*1) You can bypass that restriction and detect hovering even when normally blocked by a popup. // - BeginPopup(): query popup state, if open start appending into the window. Call EndPopup() afterwards. ImGuiWindowFlags are forwarded to the window.
// To do this use the ImGuiHoveredFlags_AllowWhenBlockedByPopup when calling IsItemHovered() or IsWindowHovered(). // - BeginPopupModal(): block every interactions behind the window, cannot be closed by user, add a dimming background, has a title bar.
// This is what BeginPopupContextItem() and BeginPopupContextWindow() are doing already, allowing a right-click to reopen another popups without losing the click. IMGUI_API bool BeginPopup(const char* str_id, ImGuiWindowFlags flags = 0); // return true if the popup is open, and you can start outputting to it.
IMGUI_API void OpenPopup(const char* str_id); // call to mark popup as open (don't call every frame!). popups are closed when user click outside, or if CloseCurrentPopup() is called within a BeginPopup()/EndPopup() block. By default, Selectable()/MenuItem() are calling CloseCurrentPopup(). Popup identifiers are relative to the current ID-stack (so OpenPopup and BeginPopup needs to be at the same level). IMGUI_API bool BeginPopupModal(const char* name, bool* p_open = NULL, ImGuiWindowFlags flags = 0); // return true if the modal is open, and you can start outputting to it.
IMGUI_API bool BeginPopup(const char* str_id, ImGuiWindowFlags flags = 0); // return true if the popup is open, and you can start outputting to it. only call EndPopup() if BeginPopup() returns true!
IMGUI_API bool BeginPopupContextItem(const char* str_id = NULL, ImGuiMouseButton mouse_button = 1); // helper to open and begin popup when clicked on last item. if you can pass a NULL str_id only if the previous item had an id. If you want to use that on a non-interactive item such as Text() you need to pass in an explicit ID here. read comments in .cpp!
IMGUI_API bool BeginPopupContextWindow(const char* str_id = NULL, ImGuiMouseButton mouse_button = 1, bool also_over_items = true); // helper to open and begin popup when clicked on current window.
IMGUI_API bool BeginPopupContextVoid(const char* str_id = NULL, ImGuiMouseButton mouse_button = 1); // helper to open and begin popup when clicked in void (where there are no imgui windows).
IMGUI_API bool BeginPopupModal(const char* name, bool* p_open = NULL, ImGuiWindowFlags flags = 0); // modal dialog (regular window with title bar, block interactions behind the modal window, can't close the modal window by clicking outside)
IMGUI_API void EndPopup(); // only call EndPopup() if BeginPopupXXX() returns true! IMGUI_API void EndPopup(); // only call EndPopup() if BeginPopupXXX() returns true!
IMGUI_API bool OpenPopupOnItemClick(const char* str_id = NULL, ImGuiMouseButton mouse_button = 1); // helper to open popup when clicked on last item (note: actually triggers on the mouse _released_ event to be consistent with popup behaviors). return true when just opened. // Popups: open/close functions
IMGUI_API bool IsPopupOpen(const char* str_id); // return true if the popup is open at the current begin-ed level of the popup stack. // - OpenPopup(): set popup state to open.
IMGUI_API void CloseCurrentPopup(); // close the popup we have begin-ed into. clicking on a MenuItem or Selectable automatically close the current popup. // - If not modal: they can be closed by clicking anywhere outside them, or by pressing ESCAPE.
// - CloseCurrentPopup(): use inside the BeginPopup()/EndPopup() scope to close manually.
// - CloseCurrentPopup() is called by default by Selectable()/MenuItem() when activated (FIXME: need some options).
IMGUI_API void OpenPopup(const char* str_id); // call to mark popup as open (don't call every frame!).
IMGUI_API bool OpenPopupContextItem(const char* str_id = NULL, ImGuiMouseButton mouse_b = 1); // helper to open popup when clicked on last item. return true when just opened. (note: actually triggers on the mouse _released_ event to be consistent with popup behaviors)
IMGUI_API void CloseCurrentPopup(); // manually close the popup we have begin-ed into.
IMGUI_API bool IsPopupOpen(const char* str_id); // return true if the popup is open at the current BeginPopup() level of the popup stack
// Popups: open+begin combined functions helpers
// - Helpers to do OpenPopup+BeginPopup where the Open action is triggered by e.g. hovering an item and right-clicking.
// - They are convenient to easily create context menus, hence the name.
IMGUI_API bool BeginPopupContextItem(const char* str_id = NULL, ImGuiMouseButton mouse_b = 1); // open+begin popup when clicked on last item. if you can pass a NULL str_id only if the previous item had an id. If you want to use that on a non-interactive item such as Text() you need to pass in an explicit ID here. read comments in .cpp!
IMGUI_API bool BeginPopupContextWindow(const char* str_id = NULL, ImGuiMouseButton mouse_b = 1, bool also_over_items = true); // open+begin popup when clicked on current window.
IMGUI_API bool BeginPopupContextVoid(const char* str_id = NULL, ImGuiMouseButton mouse_b = 1); // open+begin popup when clicked in void (where there are no windows).
// Columns // Columns
// - You can also use SameLine(pos_x) to mimic simplified columns. // - You can also use SameLine(pos_x) to mimic simplified columns.
@ -950,7 +957,8 @@ enum ImGuiTabItemFlags_
ImGuiTabItemFlags_UnsavedDocument = 1 << 0, // Append '*' to title without affecting the ID, as a convenience to avoid using the ### operator. Also: tab is selected on closure and closure is deferred by one frame to allow code to undo it without flicker. ImGuiTabItemFlags_UnsavedDocument = 1 << 0, // Append '*' to title without affecting the ID, as a convenience to avoid using the ### operator. Also: tab is selected on closure and closure is deferred by one frame to allow code to undo it without flicker.
ImGuiTabItemFlags_SetSelected = 1 << 1, // Trigger flag to programmatically make the tab selected when calling BeginTabItem() ImGuiTabItemFlags_SetSelected = 1 << 1, // Trigger flag to programmatically make the tab selected when calling BeginTabItem()
ImGuiTabItemFlags_NoCloseWithMiddleMouseButton = 1 << 2, // Disable behavior of closing tabs (that are submitted with p_open != NULL) with middle mouse button. You can still repro this behavior on user's side with if (IsItemHovered() && IsMouseClicked(2)) *p_open = false. ImGuiTabItemFlags_NoCloseWithMiddleMouseButton = 1 << 2, // Disable behavior of closing tabs (that are submitted with p_open != NULL) with middle mouse button. You can still repro this behavior on user's side with if (IsItemHovered() && IsMouseClicked(2)) *p_open = false.
ImGuiTabItemFlags_NoPushId = 1 << 3 // Don't call PushID(tab->ID)/PopID() on BeginTabItem()/EndTabItem() ImGuiTabItemFlags_NoPushId = 1 << 3, // Don't call PushID(tab->ID)/PopID() on BeginTabItem()/EndTabItem()
ImGuiTabItemFlags_NoTooltip = 1 << 4 // Disable tooltip for the given tab
}; };
// Flags for ImGui::IsWindowFocused() // Flags for ImGui::IsWindowFocused()
@ -1736,6 +1744,8 @@ struct ImGuiPayload
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS #ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
namespace ImGui namespace ImGui
{ {
// OBSOLETED in 1.77 (from June 2020)
static inline bool OpenPopupOnItemClick(const char* str_id = NULL, ImGuiMouseButton mouse_button = 1) { return OpenPopupContextItem(str_id, mouse_button); }
// OBSOLETED in 1.72 (from July 2019) // OBSOLETED in 1.72 (from July 2019)
static inline void TreeAdvanceToLabelPos() { SetCursorPosX(GetCursorPosX() + GetTreeNodeToLabelSpacing()); } static inline void TreeAdvanceToLabelPos() { SetCursorPosX(GetCursorPosX() + GetTreeNodeToLabelSpacing()); }
// OBSOLETED in 1.71 (from June 2019) // OBSOLETED in 1.71 (from June 2019)
@ -1756,7 +1766,6 @@ namespace ImGui
// OBSOLETED in 1.60 (between Dec 2017 and Apr 2018) // OBSOLETED in 1.60 (between Dec 2017 and Apr 2018)
static inline bool IsAnyWindowFocused() { return IsWindowFocused(ImGuiFocusedFlags_AnyWindow); } static inline bool IsAnyWindowFocused() { return IsWindowFocused(ImGuiFocusedFlags_AnyWindow); }
static inline bool IsAnyWindowHovered() { return IsWindowHovered(ImGuiHoveredFlags_AnyWindow); } static inline bool IsAnyWindowHovered() { return IsWindowHovered(ImGuiHoveredFlags_AnyWindow); }
static inline ImVec2 CalcItemRectClosestPoint(const ImVec2& pos, bool on_edge = false, float outward = 0.f) { IM_UNUSED(on_edge); IM_UNUSED(outward); IM_ASSERT(0); return pos; }
} }
typedef ImGuiInputTextCallback ImGuiTextEditCallback; // OBSOLETED in 1.63 (from Aug 2018): made the names consistent typedef ImGuiInputTextCallback ImGuiTextEditCallback; // OBSOLETED in 1.63 (from Aug 2018): made the names consistent
typedef ImGuiInputTextCallbackData ImGuiTextEditCallbackData; typedef ImGuiInputTextCallbackData ImGuiTextEditCallbackData;

View File

@ -80,25 +80,27 @@ Index of this file:
#include <stdint.h> // intptr_t #include <stdint.h> // intptr_t
#endif #endif
// Visual Studio warnings
#ifdef _MSC_VER #ifdef _MSC_VER
#pragma warning (disable: 4996) // 'This function or variable may be unsafe': strcpy, strdup, sprintf, vsnprintf, sscanf, fopen #pragma warning (disable: 4996) // 'This function or variable may be unsafe': strcpy, strdup, sprintf, vsnprintf, sscanf, fopen
#endif #endif
// Clang/GCC warnings with -Weverything
#if defined(__clang__) #if defined(__clang__)
#if __has_warning("-Wunknown-warning-option")
#pragma clang diagnostic ignored "-Wunknown-warning-option" // warning: unknown warning group 'xxx' // not all warnings are known by all Clang versions and they tend to be rename-happy.. so ignoring warnings triggers new warnings on some configuration. Great!
#endif
#pragma clang diagnostic ignored "-Wunknown-pragmas" // warning: unknown warning group 'xxx'
#pragma clang diagnostic ignored "-Wold-style-cast" // warning: use of old-style cast // yes, they are more terse. #pragma clang diagnostic ignored "-Wold-style-cast" // warning: use of old-style cast // yes, they are more terse.
#pragma clang diagnostic ignored "-Wdeprecated-declarations" // warning: 'xx' is deprecated: The POSIX name for this.. // for strdup used in demo code (so user can copy & paste the code) #pragma clang diagnostic ignored "-Wdeprecated-declarations" // warning: 'xx' is deprecated: The POSIX name for this.. // for strdup used in demo code (so user can copy & paste the code)
#pragma clang diagnostic ignored "-Wint-to-void-pointer-cast" // warning: cast to 'void *' from smaller integer type #pragma clang diagnostic ignored "-Wint-to-void-pointer-cast" // warning: cast to 'void *' from smaller integer type
#pragma clang diagnostic ignored "-Wformat-security" // warning: format string is not a string literal #pragma clang diagnostic ignored "-Wformat-security" // warning: format string is not a string literal
#pragma clang diagnostic ignored "-Wexit-time-destructors" // warning: declaration requires an exit-time destructor // exit-time destruction order is undefined. if MemFree() leads to users code that has been disabled before exit it might cause problems. ImGui coding style welcomes static/globals. #pragma clang diagnostic ignored "-Wexit-time-destructors" // warning: declaration requires an exit-time destructor // exit-time destruction order is undefined. if MemFree() leads to users code that has been disabled before exit it might cause problems. ImGui coding style welcomes static/globals.
#pragma clang diagnostic ignored "-Wunused-macros" // warning: macro is not used // we define snprintf/vsnprintf on Windows so they are available, but not always used. #pragma clang diagnostic ignored "-Wunused-macros" // warning: macro is not used // we define snprintf/vsnprintf on Windows so they are available, but not always used.
#if __has_warning("-Wzero-as-null-pointer-constant")
#pragma clang diagnostic ignored "-Wzero-as-null-pointer-constant" // warning: zero as null pointer constant // some standard header variations use #define NULL 0 #pragma clang diagnostic ignored "-Wzero-as-null-pointer-constant" // warning: zero as null pointer constant // some standard header variations use #define NULL 0
#endif
#if __has_warning("-Wdouble-promotion")
#pragma clang diagnostic ignored "-Wdouble-promotion" // warning: implicit conversion from 'float' to 'double' when passing argument to function // using printf() is a misery with this as C++ va_arg ellipsis changes float to double. #pragma clang diagnostic ignored "-Wdouble-promotion" // warning: implicit conversion from 'float' to 'double' when passing argument to function // using printf() is a misery with this as C++ va_arg ellipsis changes float to double.
#endif
#if __has_warning("-Wreserved-id-macro")
#pragma clang diagnostic ignored "-Wreserved-id-macro" // warning: macro name is a reserved identifier #pragma clang diagnostic ignored "-Wreserved-id-macro" // warning: macro name is a reserved identifier
#endif #pragma clang diagnostic ignored "-Wimplicit-int-float-conversion" // warning: implicit conversion from 'xxx' to 'float' may lose precision
#elif defined(__GNUC__) #elif defined(__GNUC__)
#pragma GCC diagnostic ignored "-Wpragmas" // warning: unknown option after '#pragma GCC diagnostic' kind #pragma GCC diagnostic ignored "-Wpragmas" // warning: unknown option after '#pragma GCC diagnostic' kind
#pragma GCC diagnostic ignored "-Wint-to-pointer-cast" // warning: cast to pointer from integer of different size #pragma GCC diagnostic ignored "-Wint-to-pointer-cast" // warning: cast to pointer from integer of different size
@ -2870,7 +2872,7 @@ static void ShowDemoWindowPopups()
if (ImGui::TreeNode("Context menus")) if (ImGui::TreeNode("Context menus"))
{ {
// BeginPopupContextItem() is a helper to provide common/simple popup behavior of essentially doing: // BeginPopupContextItem() is a helper to provide common/simple popup behavior of essentially doing:
// if (IsItemHovered() && IsMouseReleased(0)) // if (IsItemHovered() && IsMouseReleased(ImGuiMouseButton_Right))
// OpenPopup(id); // OpenPopup(id);
// return BeginPopup(id); // return BeginPopup(id);
// For more advanced uses you may want to replicate and customize this code. // For more advanced uses you may want to replicate and customize this code.
@ -2886,11 +2888,11 @@ static void ShowDemoWindowPopups()
ImGui::EndPopup(); ImGui::EndPopup();
} }
// We can also use OpenPopupOnItemClick() which is the same as BeginPopupContextItem() but without the // We can also use OpenPopupContextItem() which is the same as BeginPopupContextItem() but without the
// Begin() call. So here we will make it that clicking on the text field with the right mouse button (1) // Begin() call. So here we will make it that clicking on the text field with the right mouse button (1)
// will toggle the visibility of the popup above. // will toggle the visibility of the popup above.
ImGui::Text("(You can also right-click me to open the same popup as above.)"); ImGui::Text("(You can also right-click me to open the same popup as above.)");
ImGui::OpenPopupOnItemClick("item context menu", 1); ImGui::OpenPopupContextItem("item context menu", 1);
// When used after an item that has an ID (e.g.Button), we can skip providing an ID to BeginPopupContextItem(). // When used after an item that has an ID (e.g.Button), we can skip providing an ID to BeginPopupContextItem().
// BeginPopupContextItem() will use the last item ID as the popup ID. // BeginPopupContextItem() will use the last item ID as the popup ID.

View File

@ -57,22 +57,19 @@ Index of this file:
// Clang/GCC warnings with -Weverything // Clang/GCC warnings with -Weverything
#if defined(__clang__) #if defined(__clang__)
#if __has_warning("-Wunknown-warning-option")
#pragma clang diagnostic ignored "-Wunknown-warning-option" // warning: unknown warning group 'xxx' // not all warnings are known by all Clang versions and they tend to be rename-happy.. so ignoring warnings triggers new warnings on some configuration. Great!
#endif
#pragma clang diagnostic ignored "-Wunknown-pragmas" // warning: unknown warning group 'xxx'
#pragma clang diagnostic ignored "-Wold-style-cast" // warning: use of old-style cast // yes, they are more terse. #pragma clang diagnostic ignored "-Wold-style-cast" // warning: use of old-style cast // yes, they are more terse.
#pragma clang diagnostic ignored "-Wfloat-equal" // warning: comparing floating point with == or != is unsafe // storing and comparing against same constants ok. #pragma clang diagnostic ignored "-Wfloat-equal" // warning: comparing floating point with == or != is unsafe // storing and comparing against same constants ok.
#pragma clang diagnostic ignored "-Wglobal-constructors" // warning: declaration requires a global destructor // similar to above, not sure what the exact difference is. #pragma clang diagnostic ignored "-Wglobal-constructors" // warning: declaration requires a global destructor // similar to above, not sure what the exact difference is.
#pragma clang diagnostic ignored "-Wsign-conversion" // warning : implicit conversion changes signedness // #pragma clang diagnostic ignored "-Wsign-conversion" // warning: implicit conversion changes signedness
#if __has_warning("-Wzero-as-null-pointer-constant")
#pragma clang diagnostic ignored "-Wzero-as-null-pointer-constant" // warning: zero as null pointer constant // some standard header variations use #define NULL 0 #pragma clang diagnostic ignored "-Wzero-as-null-pointer-constant" // warning: zero as null pointer constant // some standard header variations use #define NULL 0
#endif #pragma clang diagnostic ignored "-Wcomma" // warning: possible misuse of comma operator here
#if __has_warning("-Wcomma") #pragma clang diagnostic ignored "-Wreserved-id-macro" // warning: macro name is a reserved identifier
#pragma clang diagnostic ignored "-Wcomma" // warning : possible misuse of comma operator here //
#endif
#if __has_warning("-Wreserved-id-macro")
#pragma clang diagnostic ignored "-Wreserved-id-macro" // warning : macro name is a reserved identifier //
#endif
#if __has_warning("-Wdouble-promotion")
#pragma clang diagnostic ignored "-Wdouble-promotion" // warning: implicit conversion from 'float' to 'double' when passing argument to function // using printf() is a misery with this as C++ va_arg ellipsis changes float to double. #pragma clang diagnostic ignored "-Wdouble-promotion" // warning: implicit conversion from 'float' to 'double' when passing argument to function // using printf() is a misery with this as C++ va_arg ellipsis changes float to double.
#endif #pragma clang diagnostic ignored "-Wimplicit-int-float-conversion" // warning: implicit conversion from 'xxx' to 'float' may lose precision
#elif defined(__GNUC__) #elif defined(__GNUC__)
#pragma GCC diagnostic ignored "-Wpragmas" // warning: unknown option after '#pragma GCC diagnostic' kind #pragma GCC diagnostic ignored "-Wpragmas" // warning: unknown option after '#pragma GCC diagnostic' kind
#pragma GCC diagnostic ignored "-Wunused-function" // warning: 'xxxx' defined but not used #pragma GCC diagnostic ignored "-Wunused-function" // warning: 'xxxx' defined but not used
@ -108,7 +105,7 @@ namespace IMGUI_STB_NAMESPACE
#pragma clang diagnostic ignored "-Wunused-function" #pragma clang diagnostic ignored "-Wunused-function"
#pragma clang diagnostic ignored "-Wmissing-prototypes" #pragma clang diagnostic ignored "-Wmissing-prototypes"
#pragma clang diagnostic ignored "-Wimplicit-fallthrough" #pragma clang diagnostic ignored "-Wimplicit-fallthrough"
#pragma clang diagnostic ignored "-Wcast-qual" // warning : cast from 'const xxxx *' to 'xxx *' drops const qualifier // #pragma clang diagnostic ignored "-Wcast-qual" // warning: cast from 'const xxxx *' to 'xxx *' drops const qualifier
#endif #endif
#if defined(__GNUC__) #if defined(__GNUC__)
@ -2912,7 +2909,7 @@ const char* ImFont::CalcWordWrapPositionA(float scale, const char* text, const c
} }
// Allow wrapping after punctuation. // Allow wrapping after punctuation.
inside_word = !(c == '.' || c == ',' || c == ';' || c == '!' || c == '?' || c == '\"'); inside_word = (c != '.' && c != ',' && c != ';' && c != '!' && c != '?' && c != '\"');
} }
// We ignore blank width at the end of the line (they can be skipped) // We ignore blank width at the end of the line (they can be skipped)

View File

@ -57,15 +57,16 @@ Index of this file:
// Clang/GCC warnings with -Weverything // Clang/GCC warnings with -Weverything
#if defined(__clang__) #if defined(__clang__)
#pragma clang diagnostic push #pragma clang diagnostic push
#if __has_warning("-Wunknown-warning-option")
#pragma clang diagnostic ignored "-Wunknown-warning-option" // warning: unknown warning group 'xxx'
#endif
#pragma clang diagnostic ignored "-Wunknown-pragmas" // warning: unknown warning group 'xxx'
#pragma clang diagnostic ignored "-Wunused-function" // for stb_textedit.h #pragma clang diagnostic ignored "-Wunused-function" // for stb_textedit.h
#pragma clang diagnostic ignored "-Wmissing-prototypes" // for stb_textedit.h #pragma clang diagnostic ignored "-Wmissing-prototypes" // for stb_textedit.h
#pragma clang diagnostic ignored "-Wold-style-cast" #pragma clang diagnostic ignored "-Wold-style-cast"
#if __has_warning("-Wzero-as-null-pointer-constant")
#pragma clang diagnostic ignored "-Wzero-as-null-pointer-constant" #pragma clang diagnostic ignored "-Wzero-as-null-pointer-constant"
#endif
#if __has_warning("-Wdouble-promotion")
#pragma clang diagnostic ignored "-Wdouble-promotion" #pragma clang diagnostic ignored "-Wdouble-promotion"
#endif #pragma clang diagnostic ignored "-Wimplicit-int-float-conversion" // warning: implicit conversion from 'xxx' to 'float' may lose precision
#elif defined(__GNUC__) #elif defined(__GNUC__)
#pragma GCC diagnostic push #pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wpragmas" // warning: unknown option after '#pragma GCC diagnostic' kind #pragma GCC diagnostic ignored "-Wpragmas" // warning: unknown option after '#pragma GCC diagnostic' kind
@ -451,6 +452,7 @@ struct IMGUI_API ImRect
void ClipWithFull(const ImRect& r) { Min = ImClamp(Min, r.Min, r.Max); Max = ImClamp(Max, r.Min, r.Max); } // Full version, ensure both points are fully clipped. void ClipWithFull(const ImRect& r) { Min = ImClamp(Min, r.Min, r.Max); Max = ImClamp(Max, r.Min, r.Max); } // Full version, ensure both points are fully clipped.
void Floor() { Min.x = IM_FLOOR(Min.x); Min.y = IM_FLOOR(Min.y); Max.x = IM_FLOOR(Max.x); Max.y = IM_FLOOR(Max.y); } void Floor() { Min.x = IM_FLOOR(Min.x); Min.y = IM_FLOOR(Min.y); Max.x = IM_FLOOR(Max.x); Max.y = IM_FLOOR(Max.y); }
bool IsInverted() const { return Min.x > Max.x || Min.y > Max.y; } bool IsInverted() const { return Min.x > Max.x || Min.y > Max.y; }
ImVec4 ToVec4() const { return ImVec4(Min.x, Min.y, Max.x, Max.y); }
}; };
// Helper: ImBitArray // Helper: ImBitArray
@ -1036,7 +1038,8 @@ struct ImGuiColumns
float LineMinY, LineMaxY; float LineMinY, LineMaxY;
float HostCursorPosY; // Backup of CursorPos at the time of BeginColumns() float HostCursorPosY; // Backup of CursorPos at the time of BeginColumns()
float HostCursorMaxPosX; // Backup of CursorMaxPos at the time of BeginColumns() float HostCursorMaxPosX; // Backup of CursorMaxPos at the time of BeginColumns()
ImRect HostClipRect; // Backup of ClipRect 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 HostWorkRect; // Backup of WorkRect at the time of BeginColumns()
ImVector<ImGuiColumnData> Columns; ImVector<ImGuiColumnData> Columns;
ImDrawListSplitter Splitter; ImDrawListSplitter Splitter;
@ -1766,7 +1769,7 @@ struct IMGUI_API ImGuiWindow
bool WantCollapseToggle; bool WantCollapseToggle;
bool SkipItems; // Set when items can safely be all clipped (e.g. window not visible or collapsed) bool SkipItems; // Set when items can safely be all clipped (e.g. window not visible or collapsed)
bool Appearing; // Set during the frame where the window is appearing (or re-appearing) bool Appearing; // Set during the frame where the window is appearing (or re-appearing)
bool Hidden; // Do not display (== (HiddenFrames*** > 0)) bool Hidden; // Do not display (== HiddenFrames*** > 0)
bool IsFallbackWindow; // Set on the "Debug##Default" window. bool IsFallbackWindow; // Set on the "Debug##Default" window.
bool HasCloseButton; // Set when the window has a close button (p_open != NULL) bool HasCloseButton; // Set when the window has a close button (p_open != NULL)
signed char ResizeBorderHeld; // Current border being held for resize (-1: none, otherwise 0-3) signed char ResizeBorderHeld; // Current border being held for resize (-1: none, otherwise 0-3)
@ -2066,7 +2069,9 @@ namespace ImGui
IMGUI_API void OpenPopupEx(ImGuiID id); IMGUI_API void OpenPopupEx(ImGuiID id);
IMGUI_API void ClosePopupToLevel(int remaining, bool restore_focus_to_window_under_popup); IMGUI_API void ClosePopupToLevel(int remaining, bool restore_focus_to_window_under_popup);
IMGUI_API void ClosePopupsOverWindow(ImGuiWindow* ref_window, bool restore_focus_to_window_under_popup); IMGUI_API void ClosePopupsOverWindow(ImGuiWindow* ref_window, bool restore_focus_to_window_under_popup);
IMGUI_API bool IsPopupOpen(ImGuiID id); // Test for id at current popup stack level (currently begin-ed into); this doesn't scan the whole popup stack! IMGUI_API bool IsPopupOpen(ImGuiID id); // Test for id at the current BeginPopup() level of the popup stack (this doesn't scan the whole popup stack!)
IMGUI_API bool IsPopupOpenAtAnyLevel(ImGuiID id);
IMGUI_API bool IsAnyPopupOpen(); // Return true if any popup is open at the current BeginPopup() level of the popup stack
IMGUI_API bool BeginPopupEx(ImGuiID id, ImGuiWindowFlags extra_flags); IMGUI_API bool BeginPopupEx(ImGuiID id, ImGuiWindowFlags extra_flags);
IMGUI_API void BeginTooltipEx(ImGuiWindowFlags extra_flags, ImGuiTooltipFlags tooltip_flags); IMGUI_API void BeginTooltipEx(ImGuiWindowFlags extra_flags, ImGuiTooltipFlags tooltip_flags);
IMGUI_API ImGuiWindow* GetTopMostPopupModal(); IMGUI_API ImGuiWindow* GetTopMostPopupModal();
@ -2156,6 +2161,7 @@ namespace ImGui
IMGUI_API bool IsDragDropPayloadBeingAccepted(); IMGUI_API bool IsDragDropPayloadBeingAccepted();
// Internal Columns API (this is not exposed because we will encourage transitioning to the Tables API) // Internal Columns API (this is not exposed because we will encourage transitioning to the Tables API)
IMGUI_API void SetWindowClipRectBeforeSetChannel(ImGuiWindow* window, const ImRect& clip_rect);
IMGUI_API void BeginColumns(const char* str_id, int count, ImGuiColumnsFlags flags = 0); // setup number of columns. use an identifier to distinguish multiple column sets. close with EndColumns(). IMGUI_API void BeginColumns(const char* str_id, int count, ImGuiColumnsFlags flags = 0); // setup number of columns. use an identifier to distinguish multiple column sets. close with EndColumns().
IMGUI_API void EndColumns(); // close columns IMGUI_API void EndColumns(); // close columns
IMGUI_API void PushColumnClipRect(int column_index); IMGUI_API void PushColumnClipRect(int column_index);

View File

@ -58,19 +58,19 @@ Index of this file:
// Clang/GCC warnings with -Weverything // Clang/GCC warnings with -Weverything
#if defined(__clang__) #if defined(__clang__)
#if __has_warning("-Wunknown-warning-option")
#pragma clang diagnostic ignored "-Wunknown-warning-option" // warning: unknown warning group 'xxx' // not all warnings are known by all Clang versions and they tend to be rename-happy.. so ignoring warnings triggers new warnings on some configuration. Great!
#endif
#pragma clang diagnostic ignored "-Wunknown-pragmas" // warning: unknown warning group 'xxx'
#pragma clang diagnostic ignored "-Wold-style-cast" // warning: use of old-style cast // yes, they are more terse. #pragma clang diagnostic ignored "-Wold-style-cast" // warning: use of old-style cast // yes, they are more terse.
#pragma clang diagnostic ignored "-Wfloat-equal" // warning: comparing floating point with == or != is unsafe // storing and comparing against same constants (typically 0.0f) is ok. #pragma clang diagnostic ignored "-Wfloat-equal" // warning: comparing floating point with == or != is unsafe // storing and comparing against same constants (typically 0.0f) is ok.
#pragma clang diagnostic ignored "-Wformat-nonliteral" // warning: format string is not a string literal // passing non-literal to vsnformat(). yes, user passing incorrect format strings can crash the code. #pragma clang diagnostic ignored "-Wformat-nonliteral" // warning: format string is not a string literal // passing non-literal to vsnformat(). yes, user passing incorrect format strings can crash the code.
#pragma clang diagnostic ignored "-Wsign-conversion" // warning : implicit conversion changes signedness // #pragma clang diagnostic ignored "-Wsign-conversion" // warning: implicit conversion changes signedness
#if __has_warning("-Wzero-as-null-pointer-constant")
#pragma clang diagnostic ignored "-Wzero-as-null-pointer-constant" // warning: zero as null pointer constant // some standard header variations use #define NULL 0 #pragma clang diagnostic ignored "-Wzero-as-null-pointer-constant" // warning: zero as null pointer constant // some standard header variations use #define NULL 0
#endif
#if __has_warning("-Wdouble-promotion")
#pragma clang diagnostic ignored "-Wdouble-promotion" // warning: implicit conversion from 'float' to 'double' when passing argument to function // using printf() is a misery with this as C++ va_arg ellipsis changes float to double. #pragma clang diagnostic ignored "-Wdouble-promotion" // warning: implicit conversion from 'float' to 'double' when passing argument to function // using printf() is a misery with this as C++ va_arg ellipsis changes float to double.
#endif #pragma clang diagnostic ignored "-Wenum-enum-conversion" // warning: bitwise operation between different enumeration types ('XXXFlags_' and 'XXXFlagsPrivate_')
#if __has_warning("-Wdeprecated-enum-enum-conversion")
#pragma clang diagnostic ignored "-Wdeprecated-enum-enum-conversion"// warning: bitwise operation between different enumeration types ('XXXFlags_' and 'XXXFlagsPrivate_') is deprecated #pragma clang diagnostic ignored "-Wdeprecated-enum-enum-conversion"// warning: bitwise operation between different enumeration types ('XXXFlags_' and 'XXXFlagsPrivate_') is deprecated
#endif #pragma clang diagnostic ignored "-Wimplicit-int-float-conversion" // warning: implicit conversion from 'xxx' to 'float' may lose precision
#elif defined(__GNUC__) #elif defined(__GNUC__)
#pragma GCC diagnostic ignored "-Wpragmas" // warning: unknown option after '#pragma GCC diagnostic' kind #pragma GCC diagnostic ignored "-Wpragmas" // warning: unknown option after '#pragma GCC diagnostic' kind
#pragma GCC diagnostic ignored "-Wformat-nonliteral" // warning: format not a string literal, format string not checked #pragma GCC diagnostic ignored "-Wformat-nonliteral" // warning: format not a string literal, format string not checked
@ -557,7 +557,8 @@ bool ImGui::ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool
if ((flags & ImGuiButtonFlags_PressedOnRelease) && mouse_button_released != -1) if ((flags & ImGuiButtonFlags_PressedOnRelease) && mouse_button_released != -1)
{ {
// Repeat mode trumps on release behavior // Repeat mode trumps on release behavior
if (!((flags & ImGuiButtonFlags_Repeat) && g.IO.MouseDownDurationPrev[mouse_button_released] >= g.IO.KeyRepeatDelay)) const bool has_repeated_at_least_once = (flags & ImGuiButtonFlags_Repeat) && g.IO.MouseDownDurationPrev[mouse_button_released] >= g.IO.KeyRepeatDelay;
if (!has_repeated_at_least_once)
pressed = true; pressed = true;
ClearActiveID(); ClearActiveID();
} }
@ -3476,18 +3477,22 @@ static bool InputTextFilterCharacter(unsigned int* p_char, ImGuiInputTextFlags f
// Generic named filters // Generic named filters
if (flags & (ImGuiInputTextFlags_CharsDecimal | ImGuiInputTextFlags_CharsHexadecimal | ImGuiInputTextFlags_CharsUppercase | ImGuiInputTextFlags_CharsNoBlank | ImGuiInputTextFlags_CharsScientific)) if (flags & (ImGuiInputTextFlags_CharsDecimal | ImGuiInputTextFlags_CharsHexadecimal | ImGuiInputTextFlags_CharsUppercase | ImGuiInputTextFlags_CharsNoBlank | ImGuiInputTextFlags_CharsScientific))
{ {
// Allow 0-9 . - + * /
if (flags & ImGuiInputTextFlags_CharsDecimal) if (flags & ImGuiInputTextFlags_CharsDecimal)
if (!(c >= '0' && c <= '9') && (c != '.') && (c != '-') && (c != '+') && (c != '*') && (c != '/')) if (!(c >= '0' && c <= '9') && (c != '.') && (c != '-') && (c != '+') && (c != '*') && (c != '/'))
return false; return false;
// Allow 0-9 . - + * / e E
if (flags & ImGuiInputTextFlags_CharsScientific) if (flags & ImGuiInputTextFlags_CharsScientific)
if (!(c >= '0' && c <= '9') && (c != '.') && (c != '-') && (c != '+') && (c != '*') && (c != '/') && (c != 'e') && (c != 'E')) if (!(c >= '0' && c <= '9') && (c != '.') && (c != '-') && (c != '+') && (c != '*') && (c != '/') && (c != 'e') && (c != 'E'))
return false; return false;
// Allow 0-9 a-F A-F
if (flags & ImGuiInputTextFlags_CharsHexadecimal) if (flags & ImGuiInputTextFlags_CharsHexadecimal)
if (!(c >= '0' && c <= '9') && !(c >= 'a' && c <= 'f') && !(c >= 'A' && c <= 'F')) if (!(c >= '0' && c <= '9') && !(c >= 'a' && c <= 'f') && !(c >= 'A' && c <= 'F'))
return false; return false;
// Turn a-z into A-Z
if (flags & ImGuiInputTextFlags_CharsUppercase) if (flags & ImGuiInputTextFlags_CharsUppercase)
if (c >= 'a' && c <= 'z') if (c >= 'a' && c <= 'z')
*p_char = (c += (unsigned int)('A'-'a')); *p_char = (c += (unsigned int)('A'-'a'));
@ -4293,7 +4298,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
PopFont(); PopFont();
// Log as text // Log as text
if (g.LogEnabled && !(is_password && !is_displaying_hint)) if (g.LogEnabled && (!is_password || is_displaying_hint))
LogRenderedText(&draw_pos, buf_display, buf_display_end); LogRenderedText(&draw_pos, buf_display, buf_display_end);
if (label_size.x > 0) if (label_size.x > 0)
@ -4440,7 +4445,7 @@ bool ImGui::ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flag
value_changed |= DragInt(ids[n], &i[n], 1.0f, 0, hdr ? 0 : 255, fmt_table_int[fmt_idx][n]); value_changed |= DragInt(ids[n], &i[n], 1.0f, 0, hdr ? 0 : 255, fmt_table_int[fmt_idx][n]);
} }
if (!(flags & ImGuiColorEditFlags_NoOptions)) if (!(flags & ImGuiColorEditFlags_NoOptions))
OpenPopupOnItemClick("context"); OpenPopupContextItem("context");
} }
} }
else if ((flags & ImGuiColorEditFlags_DisplayHex) != 0 && (flags & ImGuiColorEditFlags_NoInputs) == 0) else if ((flags & ImGuiColorEditFlags_DisplayHex) != 0 && (flags & ImGuiColorEditFlags_NoInputs) == 0)
@ -4465,7 +4470,7 @@ bool ImGui::ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flag
sscanf(p, "%02X%02X%02X", (unsigned int*)&i[0], (unsigned int*)&i[1], (unsigned int*)&i[2]); sscanf(p, "%02X%02X%02X", (unsigned int*)&i[0], (unsigned int*)&i[1], (unsigned int*)&i[2]);
} }
if (!(flags & ImGuiColorEditFlags_NoOptions)) if (!(flags & ImGuiColorEditFlags_NoOptions))
OpenPopupOnItemClick("context"); OpenPopupContextItem("context");
} }
ImGuiWindow* picker_active_window = NULL; ImGuiWindow* picker_active_window = NULL;
@ -4486,7 +4491,7 @@ bool ImGui::ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flag
} }
} }
if (!(flags & ImGuiColorEditFlags_NoOptions)) if (!(flags & ImGuiColorEditFlags_NoOptions))
OpenPopupOnItemClick("context"); OpenPopupContextItem("context");
if (BeginPopup("picker")) if (BeginPopup("picker"))
{ {
@ -4706,7 +4711,7 @@ bool ImGui::ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags fl
} }
} }
if (!(flags & ImGuiColorEditFlags_NoOptions)) if (!(flags & ImGuiColorEditFlags_NoOptions))
OpenPopupOnItemClick("context"); OpenPopupContextItem("context");
} }
else if (flags & ImGuiColorEditFlags_PickerHueBar) else if (flags & ImGuiColorEditFlags_PickerHueBar)
{ {
@ -4719,7 +4724,7 @@ bool ImGui::ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags fl
value_changed = value_changed_sv = true; value_changed = value_changed_sv = true;
} }
if (!(flags & ImGuiColorEditFlags_NoOptions)) if (!(flags & ImGuiColorEditFlags_NoOptions))
OpenPopupOnItemClick("context"); OpenPopupContextItem("context");
// Hue bar logic // Hue bar logic
SetCursorScreenPos(ImVec2(bar0_pos_x, picker_pos.y)); SetCursorScreenPos(ImVec2(bar0_pos_x, picker_pos.y));
@ -7242,7 +7247,9 @@ bool ImGui::TabItemEx(ImGuiTabBar* tab_bar, const char* label, bool* p_open,
if (tab_bar->Tabs.Size == 1 && !(tab_bar->Flags & ImGuiTabBarFlags_AutoSelectNewTabs)) if (tab_bar->Tabs.Size == 1 && !(tab_bar->Flags & ImGuiTabBarFlags_AutoSelectNewTabs))
tab_contents_visible = true; tab_contents_visible = true;
if (tab_appearing && !(tab_bar_appearing && !tab_is_new)) // Note that tab_is_new is not necessarily the same as tab_appearing! When a tab bar stops being submitted
// and then gets submitted again, the tabs will have 'tab_appearing=true' but 'tab_is_new=false'.
if (tab_appearing && (!tab_bar_appearing || tab_is_new))
{ {
PushItemFlag(ImGuiItemFlags_NoNav | ImGuiItemFlags_NoNavDefaultFocus, true); PushItemFlag(ImGuiItemFlags_NoNav | ImGuiItemFlags_NoNavDefaultFocus, true);
ItemAdd(ImRect(), id); ItemAdd(ImRect(), id);
@ -7401,14 +7408,16 @@ bool ImGui::TabItemEx(ImGuiTabBar* tab_bar, const char* label, bool* p_open,
// Tooltip (FIXME: Won't work over the close button because ItemOverlap systems messes up with HoveredIdTimer) // Tooltip (FIXME: Won't work over the close button because ItemOverlap systems messes up with HoveredIdTimer)
// We test IsItemHovered() to discard e.g. when another item is active or drag and drop over the tab bar (which g.HoveredId ignores) // We test IsItemHovered() to discard e.g. when another item is active or drag and drop over the tab bar (which g.HoveredId ignores)
if (g.HoveredId == id && !held && g.HoveredIdNotActiveTimer > 0.50f && IsItemHovered()) if (g.HoveredId == id && !held && g.HoveredIdNotActiveTimer > 0.50f && IsItemHovered())
if (!(tab_bar->Flags & ImGuiTabBarFlags_NoTooltip)) if (!(tab_bar->Flags & ImGuiTabBarFlags_NoTooltip) && !(tab->Flags & ImGuiTabItemFlags_NoTooltip))
SetTooltip("%.*s", (int)(FindRenderedTextEnd(label) - label), label); SetTooltip("%.*s", (int)(FindRenderedTextEnd(label) - label), label);
return tab_contents_visible; return tab_contents_visible;
} }
// [Public] This is call is 100% optional but it allows to remove some one-frame glitches when a tab has been unexpectedly removed. // [Public] This is call is 100% optional but it allows to remove some one-frame glitches when a tab has been unexpectedly removed.
// To use it to need to call the function SetTabItemClosed() after BeginTabBar() and before any call to BeginTabItem() // To use it to need to call the function SetTabItemClosed() after BeginTabBar() and before any call to BeginTabItem().
// Tabs closed by the close button will automatically be flagged to avoid this issue.
// FIXME: We should aim to support calling SetTabItemClosed() after the tab submission (for next frame)
void ImGui::SetTabItemClosed(const char* label) void ImGui::SetTabItemClosed(const char* label)
{ {
ImGuiContext& g = *GImGui; ImGuiContext& g = *GImGui;
@ -7541,6 +7550,7 @@ bool ImGui::TabItemLabelAndCloseButton(ImDrawList* draw_list, const ImRect& bb,
// [SECTION] Widgets: Columns, BeginColumns, EndColumns, etc. // [SECTION] Widgets: Columns, BeginColumns, EndColumns, etc.
// In the current version, Columns are very weak. Needs to be replaced with a more full-featured system. // In the current version, Columns are very weak. Needs to be replaced with a more full-featured system.
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
// - SetWindowClipRectBeforeSetChannel() [Internal]
// - GetColumnIndex() // - GetColumnIndex()
// - GetColumnCount() // - GetColumnCount()
// - GetColumnOffset() // - GetColumnOffset()
@ -7558,6 +7568,18 @@ bool ImGui::TabItemLabelAndCloseButton(ImDrawList* draw_list, const ImRect& bb,
// - Columns() // - Columns()
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
// [Internal] Small optimization to avoid calls to PopClipRect/SetCurrentChannel/PushClipRect in sequences,
// they would meddle many times with the underlying ImDrawCmd.
// Instead, we do a preemptive overwrite of clipping rectangle _without_ altering the command-buffer and let
// the subsequent single call to SetCurrentChannel() does it things once.
void ImGui::SetWindowClipRectBeforeSetChannel(ImGuiWindow* window, const ImRect& clip_rect)
{
ImVec4 clip_rect_vec4 = clip_rect.ToVec4();
window->ClipRect = clip_rect;
window->DrawList->_CmdHeader.ClipRect = clip_rect_vec4;
window->DrawList->_ClipRectStack.Data[window->DrawList->_ClipRectStack.Size - 1] = clip_rect_vec4;
}
int ImGui::GetColumnIndex() int ImGui::GetColumnIndex()
{ {
ImGuiWindow* window = GetCurrentWindowRead(); ImGuiWindow* window = GetCurrentWindowRead();
@ -7692,11 +7714,11 @@ void ImGui::PushColumnsBackground()
ImGuiColumns* columns = window->DC.CurrentColumns; ImGuiColumns* columns = window->DC.CurrentColumns;
if (columns->Count == 1) if (columns->Count == 1)
return; return;
// Optimization: avoid SetCurrentChannel() + PushClipRect()
columns->HostBackupClipRect = window->ClipRect;
SetWindowClipRectBeforeSetChannel(window, columns->HostInitialClipRect);
columns->Splitter.SetCurrentChannel(window->DrawList, 0); columns->Splitter.SetCurrentChannel(window->DrawList, 0);
int cmd_size = window->DrawList->CmdBuffer.Size;
PushClipRect(columns->HostClipRect.Min, columns->HostClipRect.Max, false);
IM_UNUSED(cmd_size);
IM_ASSERT(cmd_size >= window->DrawList->CmdBuffer.Size); // Being in channel 0 this should not have created an ImDrawCmd
} }
void ImGui::PopColumnsBackground() void ImGui::PopColumnsBackground()
@ -7705,8 +7727,10 @@ void ImGui::PopColumnsBackground()
ImGuiColumns* columns = window->DC.CurrentColumns; ImGuiColumns* columns = window->DC.CurrentColumns;
if (columns->Count == 1) if (columns->Count == 1)
return; return;
// Optimization: avoid PopClipRect() + SetCurrentChannel()
SetWindowClipRectBeforeSetChannel(window, columns->HostBackupClipRect);
columns->Splitter.SetCurrentChannel(window->DrawList, columns->Current + 1); columns->Splitter.SetCurrentChannel(window->DrawList, columns->Current + 1);
PopClipRect();
} }
ImGuiColumns* ImGui::FindOrCreateColumns(ImGuiWindow* window, ImGuiID id) ImGuiColumns* ImGui::FindOrCreateColumns(ImGuiWindow* window, ImGuiID id)
@ -7754,7 +7778,7 @@ void ImGui::BeginColumns(const char* str_id, int columns_count, ImGuiColumnsFlag
columns->HostCursorPosY = window->DC.CursorPos.y; columns->HostCursorPosY = window->DC.CursorPos.y;
columns->HostCursorMaxPosX = window->DC.CursorMaxPos.x; columns->HostCursorMaxPosX = window->DC.CursorMaxPos.x;
columns->HostClipRect = window->ClipRect; columns->HostInitialClipRect = window->ClipRect;
columns->HostWorkRect = window->WorkRect; columns->HostWorkRect = window->WorkRect;
// Set state for first column // Set state for first column
@ -7826,25 +7850,31 @@ void ImGui::NextColumn()
IM_ASSERT(columns->Current == 0); IM_ASSERT(columns->Current == 0);
return; return;
} }
// Next column
if (++columns->Current == columns->Count)
columns->Current = 0;
PopItemWidth(); PopItemWidth();
PopClipRect();
// Optimization: avoid PopClipRect() + SetCurrentChannel() + PushClipRect()
// (which would needlessly attempt to update commands in the wrong channel, then pop or overwrite them),
ImGuiColumnData* column = &columns->Columns[columns->Current];
SetWindowClipRectBeforeSetChannel(window, column->ClipRect);
columns->Splitter.SetCurrentChannel(window->DrawList, columns->Current + 1);
const float column_padding = g.Style.ItemSpacing.x; const float column_padding = g.Style.ItemSpacing.x;
columns->LineMaxY = ImMax(columns->LineMaxY, window->DC.CursorPos.y); columns->LineMaxY = ImMax(columns->LineMaxY, window->DC.CursorPos.y);
if (++columns->Current < columns->Count) if (columns->Current > 0)
{ {
// Columns 1+ ignore IndentX (by canceling it out) // Columns 1+ ignore IndentX (by canceling it out)
// FIXME-COLUMNS: Unnecessary, could be locked? // FIXME-COLUMNS: Unnecessary, could be locked?
window->DC.ColumnsOffset.x = GetColumnOffset(columns->Current) - window->DC.Indent.x + column_padding; window->DC.ColumnsOffset.x = GetColumnOffset(columns->Current) - window->DC.Indent.x + column_padding;
columns->Splitter.SetCurrentChannel(window->DrawList, columns->Current + 1);
} }
else else
{ {
// New row/line // New row/line: column 0 honor IndentX.
// Column 0 honor IndentX
window->DC.ColumnsOffset.x = ImMax(column_padding - window->WindowPadding.x, 0.0f); window->DC.ColumnsOffset.x = ImMax(column_padding - window->WindowPadding.x, 0.0f);
columns->Splitter.SetCurrentChannel(window->DrawList, 1);
columns->Current = 0;
columns->LineMinY = columns->LineMaxY; columns->LineMinY = columns->LineMaxY;
} }
window->DC.CursorPos.x = IM_FLOOR(window->Pos.x + window->DC.Indent.x + window->DC.ColumnsOffset.x); window->DC.CursorPos.x = IM_FLOOR(window->Pos.x + window->DC.Indent.x + window->DC.ColumnsOffset.x);
@ -7852,8 +7882,6 @@ void ImGui::NextColumn()
window->DC.CurrLineSize = ImVec2(0.0f, 0.0f); window->DC.CurrLineSize = ImVec2(0.0f, 0.0f);
window->DC.CurrLineTextBaseOffset = 0.0f; window->DC.CurrLineTextBaseOffset = 0.0f;
PushColumnClipRect(columns->Current); // FIXME-COLUMNS: Could it be an overwrite?
// FIXME-COLUMNS: Share code with BeginColumns() - move code on columns setup. // FIXME-COLUMNS: Share code with BeginColumns() - move code on columns setup.
float offset_0 = GetColumnOffset(columns->Current); float offset_0 = GetColumnOffset(columns->Current);
float offset_1 = GetColumnOffset(columns->Current + 1); float offset_1 = GetColumnOffset(columns->Current + 1);