Merge remote-tracking branch 'origin/master' into docking

# Conflicts:
#	backends/imgui_impl_opengl3.cpp
This commit is contained in:
ocornut 2021-04-15 19:57:52 +02:00
commit 34d4bc620d
20 changed files with 277 additions and 135 deletions

View File

@ -196,7 +196,7 @@ void ImGui_ImplDX10_RenderDrawData(ImDrawData* draw_data)
DXGI_FORMAT IndexBufferFormat; DXGI_FORMAT IndexBufferFormat;
ID3D10InputLayout* InputLayout; ID3D10InputLayout* InputLayout;
}; };
BACKUP_DX10_STATE old; BACKUP_DX10_STATE old = {};
old.ScissorRectsCount = old.ViewportsCount = D3D10_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE; old.ScissorRectsCount = old.ViewportsCount = D3D10_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE;
ctx->RSGetScissorRects(&old.ScissorRectsCount, old.ScissorRects); ctx->RSGetScissorRects(&old.ScissorRectsCount, old.ScissorRects);
ctx->RSGetViewports(&old.ViewportsCount, old.Viewports); ctx->RSGetViewports(&old.ViewportsCount, old.Viewports);

View File

@ -204,7 +204,7 @@ void ImGui_ImplDX11_RenderDrawData(ImDrawData* draw_data)
DXGI_FORMAT IndexBufferFormat; DXGI_FORMAT IndexBufferFormat;
ID3D11InputLayout* InputLayout; ID3D11InputLayout* InputLayout;
}; };
BACKUP_DX11_STATE old; BACKUP_DX11_STATE old = {};
old.ScissorRectsCount = old.ViewportsCount = D3D11_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE; old.ScissorRectsCount = old.ViewportsCount = D3D11_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE;
ctx->RSGetScissorRects(&old.ScissorRectsCount, old.ScissorRects); ctx->RSGetScissorRects(&old.ScissorRectsCount, old.ScissorRects);
ctx->RSGetViewports(&old.ViewportsCount, old.Viewports); ctx->RSGetViewports(&old.ViewportsCount, old.Viewports);

View File

@ -15,6 +15,7 @@
// CHANGELOG // CHANGELOG
// (minor and older changes stripped away, please see git history for details) // (minor and older changes stripped away, please see git history for details)
// 2021-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface. // 2021-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
// 2021-04-06: OpenGL: Don't try to read GL_CLIP_ORIGIN unless we're OpenGL 4.5 or greater.
// 2021-02-18: OpenGL: Change blending equation to preserve alpha in output buffer. // 2021-02-18: OpenGL: Change blending equation to preserve alpha in output buffer.
// 2021-01-03: OpenGL: Backup, setup and restore GL_STENCIL_TEST state. // 2021-01-03: OpenGL: Backup, setup and restore GL_STENCIL_TEST state.
// 2020-10-23: OpenGL: Backup, setup and restore GL_PRIMITIVE_RESTART state. // 2020-10-23: OpenGL: Backup, setup and restore GL_PRIMITIVE_RESTART state.
@ -273,11 +274,14 @@ static void ImGui_ImplOpenGL3_SetupRenderState(ImDrawData* draw_data, int fb_wid
#endif #endif
// Support for GL 4.5 rarely used glClipControl(GL_UPPER_LEFT) // Support for GL 4.5 rarely used glClipControl(GL_UPPER_LEFT)
#if defined(GL_CLIP_ORIGIN) && !defined(__APPLE__) #if defined(GL_CLIP_ORIGIN)
bool clip_origin_lower_left = true; bool clip_origin_lower_left = true;
GLenum current_clip_origin = 0; glGetIntegerv(GL_CLIP_ORIGIN, (GLint*)&current_clip_origin); if (g_GlVersion >= 450)
if (current_clip_origin == GL_UPPER_LEFT) {
clip_origin_lower_left = false; GLenum current_clip_origin = 0; glGetIntegerv(GL_CLIP_ORIGIN, (GLint*)&current_clip_origin);
if (current_clip_origin == GL_UPPER_LEFT)
clip_origin_lower_left = false;
}
#endif #endif
// Setup viewport, orthographic projection matrix // Setup viewport, orthographic projection matrix
@ -287,7 +291,7 @@ static void ImGui_ImplOpenGL3_SetupRenderState(ImDrawData* draw_data, int fb_wid
float R = draw_data->DisplayPos.x + draw_data->DisplaySize.x; float R = draw_data->DisplayPos.x + draw_data->DisplaySize.x;
float T = draw_data->DisplayPos.y; float T = draw_data->DisplayPos.y;
float B = draw_data->DisplayPos.y + draw_data->DisplaySize.y; float B = draw_data->DisplayPos.y + draw_data->DisplaySize.y;
#if defined(GL_CLIP_ORIGIN) && !defined(__APPLE__) #if defined(GL_CLIP_ORIGIN)
if (!clip_origin_lower_left) { float tmp = T; T = B; B = tmp; } // Swap top and bottom if origin is upper left if (!clip_origin_lower_left) { float tmp = T; T = B; B = tmp; } // Swap top and bottom if origin is upper left
#endif #endif
const float ortho_projection[4][4] = const float ortho_projection[4][4] =

View File

@ -17,6 +17,8 @@ your application or engine to easily integrate Dear ImGui.** Each backend is typ
An application usually combines 1 Platform backend + 1 Renderer backend + main Dear ImGui sources. An application usually combines 1 Platform backend + 1 Renderer backend + main Dear ImGui sources.
For example, the [example_win32_directx11](https://github.com/ocornut/imgui/tree/master/examples/example_win32_directx11) application combines imgui_impl_win32.cpp + imgui_impl_dx11.cpp. There are 20+ examples in the [examples/](https://github.com/ocornut/imgui/blob/master/examples/) folder. See [EXAMPLES.MD](https://github.com/ocornut/imgui/blob/master/docs/EXAMPLES.md) for details. For example, the [example_win32_directx11](https://github.com/ocornut/imgui/tree/master/examples/example_win32_directx11) application combines imgui_impl_win32.cpp + imgui_impl_dx11.cpp. There are 20+ examples in the [examples/](https://github.com/ocornut/imgui/blob/master/examples/) folder. See [EXAMPLES.MD](https://github.com/ocornut/imgui/blob/master/docs/EXAMPLES.md) for details.
**Once Dear ImGui is setup and running, run and refer to `ImGui::ShowDemoWindow()` in imgui_demo.cpp for usage of the end-user API.**
### What are backends ### What are backends

View File

@ -109,6 +109,7 @@ Other Changes:
- Scrolling: Fix scroll tracking with e.g. SetScrollHereX/Y() when WindowPadding < ItemSpacing. - Scrolling: Fix scroll tracking with e.g. SetScrollHereX/Y() when WindowPadding < ItemSpacing.
- Scrolling: Fix scroll snapping on edge of scroll region when both scrollbars are enabled. - Scrolling: Fix scroll snapping on edge of scroll region when both scrollbars are enabled.
- Scrolling: Fix mouse wheel axis swap when using SHIFT on macOS (system already does it). (#4010)
- Window: Fix IsWindowAppearing() from returning true twice in most cases. (#3982, #1497, #1061) - Window: Fix IsWindowAppearing() from returning true twice in most cases. (#3982, #1497, #1061)
- Tables: Expose TableSetColumnEnabled() in public api. (#3935) - Tables: Expose TableSetColumnEnabled() in public api. (#3935)
- TabBar: Fixed mouse reordering with very fast movements (e.g. crossing multiple tabs in a single - TabBar: Fixed mouse reordering with very fast movements (e.g. crossing multiple tabs in a single
@ -117,17 +118,28 @@ Other Changes:
consistent with the compile-time default. (#3922) consistent with the compile-time default. (#3922)
- DragScalar: Add default value for v_speed argument to match higher-level functions. (#3922) [@eliasdaler] - DragScalar: Add default value for v_speed argument to match higher-level functions. (#3922) [@eliasdaler]
- ColorEdit4: Alpha default to 255 (instead of 0) when omitted in hex input. (#3973) [@squadack] - ColorEdit4: Alpha default to 255 (instead of 0) when omitted in hex input. (#3973) [@squadack]
- InputText: Do not filter private unicode codepoints (e.g. icons) when pasted from clipboard. (#4005) [@dougbinks]
- LabelText: Fixed clipping of multi-line value text when label is single-line. (#4004)
- LabelText: Fixed vertical alignment of single-line value text when label is multi-line. (#4004)
- Popups: Added 'OpenPopup(ImGuiID id)' overload to facilitate calling from nested stacks. (#3993, #331) [@zlash]
- ImDrawList: Fixed PathArcTo() regression from 1.82 preventing use of counter-clockwise angles. (#4030, #3491) [@thedmd]
- Demo: Improved popups demo and comments.
- Backends: SDL: Rework global mouse pos availability check listing supported platforms explicitly, - Backends: SDL: Rework global mouse pos availability check listing supported platforms explicitly,
effectively fixing mouse access on Raspberry Pi. (#2837, #3950) [@lethal-guitar, @hinxx] effectively fixing mouse access on Raspberry Pi. (#2837, #3950) [@lethal-guitar, @hinxx]
- Backends: Win32: Clearing keyboard down array when losing focus (WM_KILLFOCUS). (#2062, #3532, #3961) - Backends: Win32: Clearing keyboard down array when losing focus (WM_KILLFOCUS). (#2062, #3532, #3961)
[@1025798851] [@1025798851]
- Backends: DirectX9: calling IDirect3DStateBlock9::Capture() after CreateStateBlock() which appears to - Backends: DirectX9: calling IDirect3DStateBlock9::Capture() after CreateStateBlock() which appears to
workaround/fix state restoring issues. Unknown exactly why so, but bit of a cargo-cult fix. (#3857) workaround/fix state restoring issues. Unknown exactly why so, but bit of a cargo-cult fix. (#3857)
- Backends: DirectX10, DirectX11: fixed a crash when backing/restoring state if nothing is bound when
entering the rendering function. (#4045) [@Nemirtingas]
- Backends: Vulkan: Fix mapped memory Vulkan validation error when buffer sizes are not multiple of - Backends: Vulkan: Fix mapped memory Vulkan validation error when buffer sizes are not multiple of
VkPhysicalDeviceLimits::nonCoherentAtomSize. (#3957) [@AgentX1994] VkPhysicalDeviceLimits::nonCoherentAtomSize. (#3957) [@AgentX1994]
- Examples: Add OpenGL ES 2.0 support to modern GL examples. (#2837, #3951) [@lethal-guitar, @hinxx] - Backends: OpenGL3: Don't try to read GL_CLIP_ORIGIN unless we're OpenGL 4.5. (#3998, #2366, #2186) [@s7jones]
- Examples: OpenGL: Add OpenGL ES 2.0 support to modern GL examples. (#2837, #3951) [@lethal-guitar, @hinxx]
- Examples: Vulkan: Rebuild swapchain on VK_SUBOPTIMAL_KHR. (#3881) - Examples: Vulkan: Rebuild swapchain on VK_SUBOPTIMAL_KHR. (#3881)
- Examples: Vulkan: Prefer using discrete GPU if there are more than one available. (#4012) [@rokups]
- Examples: SDL2: Link with shell32.lib required by SDL2main.lib since SDL 2.0.12. [#3988] - Examples: SDL2: Link with shell32.lib required by SDL2main.lib since SDL 2.0.12. [#3988]
- Examples: Android: Make Android example build compatible with Gradle 7.0. (#3446)
- Docs: Improvements to minor mistakes in documentation comments (#3923) [@ANF-Studios] - Docs: Improvements to minor mistakes in documentation comments (#3923) [@ANF-Studios]
Docking+Viewports Branch: Docking+Viewports Branch:

View File

@ -3,7 +3,11 @@ _(You may browse this at https://github.com/ocornut/imgui/blob/master/docs/EXAMP
## Dear ImGui: Examples ## Dear ImGui: Examples
**The [examples/](https://github.com/ocornut/imgui/blob/master/examples) folder example applications (standalone, ready-to-build) for variety of **The [examples/](https://github.com/ocornut/imgui/blob/master/examples) folder example applications (standalone, ready-to-build) for variety of
platforms and graphics APIs.** They all use standard backends from the [backends/](https://github.com/ocornut/imgui/blob/master/backends) folder. platforms and graphics APIs.** They all use standard backends from the [backends/](https://github.com/ocornut/imgui/blob/master/backends) folder (see [BACKENDS.md](https://github.com/ocornut/imgui/blob/master/docs/BACKENDS.md)).
The purpose of Examples is to showcase integration with backends, let you try Dear ImGui, and guide you toward
integrating Dear ImGui in your own application/game/engine.
**Once Dear ImGui is setup and running, run and refer to `ImGui::ShowDemoWindow()` in imgui_demo.cpp for usage of the end-user API.**
You can find Windows binaries for some of those example applications at: You can find Windows binaries for some of those example applications at:
http://www.dearimgui.org/binaries http://www.dearimgui.org/binaries

View File

@ -199,7 +199,7 @@ Ongoing Dear ImGui development is currently financially supported by users and p
- [Blizzard](https://careers.blizzard.com/en-us/openings/engineering/all/all/all/1), [Google](https://github.com/google/filament), [Nvidia](https://developer.nvidia.com/nvidia-omniverse), [Ubisoft](https://montreal.ubisoft.com/en/ubisoft-sponsors-user-interface-library-for-c-dear-imgui/) - [Blizzard](https://careers.blizzard.com/en-us/openings/engineering/all/all/all/1), [Google](https://github.com/google/filament), [Nvidia](https://developer.nvidia.com/nvidia-omniverse), [Ubisoft](https://montreal.ubisoft.com/en/ubisoft-sponsors-user-interface-library-for-c-dear-imgui/)
*Double-chocolate and Salty caramel sponsors* *Double-chocolate and Salty caramel sponsors*
- [Activision](https://careers.activision.com/c/programmingsoftware-engineering-jobs), [Aras Pranckevičius](https://aras-p.info), [Arkane Studios](https://www.arkane-studios.com), [Framefield](http://framefield.com), [Grinding Gear Games](https://www.grindinggear.com), [Kylotonn](https://www.kylotonn.com), [Next Level Games](https://www.nextlevelgames.com), [RAD Game Tools](http://www.radgametools.com/), [Supercell](http://www.supercell.com) - [Activision](https://careers.activision.com/c/programmingsoftware-engineering-jobs), [Aras Pranckevičius](https://aras-p.info), [Arkane Studios](https://www.arkane-studios.com), [Framefield](http://framefield.com), [Grinding Gear Games](https://www.grindinggear.com), [Kylotonn](https://www.kylotonn.com), [Next Level Games](https://www.nextlevelgames.com), [RAD Game Tools](http://www.radgametools.com/), [Supercell](https://supercell.com)
Please see [detailed list of Dear ImGui supporters](https://github.com/ocornut/imgui/wiki/Sponsors) for past sponsors. Please see [detailed list of Dear ImGui supporters](https://github.com/ocornut/imgui/wiki/Sponsors) for past sponsors.
From November 2014 to December 2019, ongoing development has also been financially supported by its users on Patreon and through individual donations. From November 2014 to December 2019, ongoing development has also been financially supported by its users on Patreon and through individual donations.
@ -214,12 +214,12 @@ Dear ImGui is using software and services provided free of charge for open sourc
Credits Credits
------- -------
Developed by [Omar Cornut](http://www.miracleworld.net) and every direct or indirect [contributors](https://github.com/ocornut/imgui/graphs/contributors) to the GitHub. The early version of this library was developed with the support of [Media Molecule](http://www.mediamolecule.com) and first used internally on the game [Tearaway](http://tearaway.mediamolecule.com) (PS Vita). Developed by [Omar Cornut](https://www.miracleworld.net) and every direct or indirect [contributors](https://github.com/ocornut/imgui/graphs/contributors) to the GitHub. The early version of this library was developed with the support of [Media Molecule](https://www.mediamolecule.com) and first used internally on the game [Tearaway](https://tearaway.mediamolecule.com) (PS Vita).
Recurring contributors (2020): Omar Cornut [@ocornut](https://github.com/ocornut), Rokas Kupstys [@rokups](https://github.com/rokups), Ben Carter [@ShironekoBen](https://github.com/ShironekoBen). Recurring contributors (2020): Omar Cornut [@ocornut](https://github.com/ocornut), Rokas Kupstys [@rokups](https://github.com/rokups), Ben Carter [@ShironekoBen](https://github.com/ShironekoBen).
A large portion of work on automation systems, regression tests and other features are currently unpublished. A large portion of work on automation systems, regression tests and other features are currently unpublished.
Omar: "I first discovered the IMGUI paradigm at [Q-Games](http://www.q-games.com) where Atman Binstock had dropped his own simple implementation in the codebase, which I spent quite some time improving and thinking about. It turned out that Atman was exposed to the concept directly by working with Casey. When I moved to Media Molecule I rewrote a new library trying to overcome the flaws and limitations of the first one I've worked with. It became this library and since then I have spent an unreasonable amount of time iterating and improving it." Omar: "I first discovered the IMGUI paradigm at [Q-Games](https://www.q-games.com) where Atman Binstock had dropped his own simple implementation in the codebase, which I spent quite some time improving and thinking about. It turned out that Atman was exposed to the concept directly by working with Casey. When I moved to Media Molecule I rewrote a new library trying to overcome the flaws and limitations of the first one I've worked with. It became this library and since then I have spent an unreasonable amount of time iterating and improving it."
Embeds [ProggyClean.ttf](http://upperbounds.net) font by Tristan Grimmer (MIT license). Embeds [ProggyClean.ttf](http://upperbounds.net) font by Tristan Grimmer (MIT license).

View File

@ -1 +1,7 @@
See EXAMPLES and BACKENDS files in the docs/ folder. See BACKENDS and EXAMPLES files in the docs/ folder.
Backends = Helper code to facilitate integration with platforms/graphics api (used by Examples + should be used by your app).
Examples = Standalone applications showcasing integration with platforms/graphics api.
Once Dear ImGui is running (in either examples or your own application/game/engine),
run and refer to ImGui::ShowDemoWindow() in imgui_demo.cpp for the end-user API.

View File

@ -1,12 +1,12 @@
buildscript { buildscript {
ext.kotlin_version = '1.4.30' ext.kotlin_version = '1.4.31'
repositories { repositories {
google() google()
jcenter() mavenCentral()
} }
dependencies { dependencies {
classpath 'com.android.tools.build:gradle:4.0.1' classpath 'com.android.tools.build:gradle:4.1.0'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
} }
@ -15,7 +15,7 @@ buildscript {
allprojects { allprojects {
repositories { repositories {
google() google()
jcenter() mavenCentral()
} }
} }

View File

@ -14,9 +14,10 @@ SOURCES += $(IMGUI_DIR)/backends/imgui_impl_glfw.cpp $(IMGUI_DIR)/backends/imgui
OBJS = $(addsuffix .o, $(basename $(notdir $(SOURCES)))) OBJS = $(addsuffix .o, $(basename $(notdir $(SOURCES))))
LIBS = -framework Metal -framework MetalKit -framework Cocoa -framework IOKit -framework CoreVideo -framework QuartzCore LIBS = -framework Metal -framework MetalKit -framework Cocoa -framework IOKit -framework CoreVideo -framework QuartzCore
LIBS += -L/usr/local/lib -lglfw LIBS += -L/usr/local/lib -L/opt/homebrew/lib
LIBS += -lglfw
CXXFLAGS = -I$(IMGUI_DIR) -I$(IMGUI_DIR)/backends -I/usr/local/include CXXFLAGS = -I$(IMGUI_DIR) -I$(IMGUI_DIR)/backends -I/usr/local/include -I/opt/homebrew/include
CXXFLAGS += -Wall -Wformat CXXFLAGS += -Wall -Wformat
CFLAGS = $(CXXFLAGS) CFLAGS = $(CXXFLAGS)

View File

@ -41,11 +41,11 @@ endif
ifeq ($(UNAME_S), Darwin) #APPLE ifeq ($(UNAME_S), Darwin) #APPLE
ECHO_MESSAGE = "Mac OS X" ECHO_MESSAGE = "Mac OS X"
LIBS += -framework OpenGL -framework Cocoa -framework IOKit -framework CoreVideo LIBS += -framework OpenGL -framework Cocoa -framework IOKit -framework CoreVideo
LIBS += -L/usr/local/lib -L/opt/local/lib LIBS += -L/usr/local/lib -L/opt/local/lib -L/opt/homebrew/lib
#LIBS += -lglfw3 #LIBS += -lglfw3
LIBS += -lglfw LIBS += -lglfw
CXXFLAGS += -I/usr/local/include -I/opt/local/include CXXFLAGS += -I/usr/local/include -I/opt/local/include -I/opt/homebrew/include
CFLAGS = $(CXXFLAGS) CFLAGS = $(CXXFLAGS)
endif endif

View File

@ -80,11 +80,11 @@ endif
ifeq ($(UNAME_S), Darwin) #APPLE ifeq ($(UNAME_S), Darwin) #APPLE
ECHO_MESSAGE = "Mac OS X" ECHO_MESSAGE = "Mac OS X"
LIBS += -framework OpenGL -framework Cocoa -framework IOKit -framework CoreVideo LIBS += -framework OpenGL -framework Cocoa -framework IOKit -framework CoreVideo
LIBS += -L/usr/local/lib -L/opt/local/lib LIBS += -L/usr/local/lib -L/opt/local/lib -L/opt/homebrew/lib
#LIBS += -lglfw3 #LIBS += -lglfw3
LIBS += -lglfw LIBS += -lglfw
CXXFLAGS += -I/usr/local/include -I/opt/local/include CXXFLAGS += -I/usr/local/include -I/opt/local/include -I/opt/homebrew/include
CFLAGS = $(CXXFLAGS) CFLAGS = $(CXXFLAGS)
endif endif

View File

@ -122,10 +122,22 @@ static void SetupVulkan(const char** extensions, uint32_t extensions_count)
err = vkEnumeratePhysicalDevices(g_Instance, &gpu_count, gpus); err = vkEnumeratePhysicalDevices(g_Instance, &gpu_count, gpus);
check_vk_result(err); check_vk_result(err);
// If a number >1 of GPUs got reported, you should find the best fit GPU for your purpose // If a number >1 of GPUs got reported, find discrete GPU if present, or use first one available. This covers
// e.g. VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU if available, or with the greatest memory available, etc. // most common cases (multi-gpu/integrated+dedicated graphics). Handling more complicated setups (multiple
// for sake of simplicity we'll just take the first one, assuming it has a graphics queue family. // dedicated GPUs) is out of scope of this sample.
g_PhysicalDevice = gpus[0]; int use_gpu = 0;
for (int i = 0; i < (int)gpu_count; i++)
{
VkPhysicalDeviceProperties properties;
vkGetPhysicalDeviceProperties(gpus[i], &properties);
if (properties.deviceType == VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU)
{
use_gpu = i;
break;
}
}
g_PhysicalDevice = gpus[use_gpu];
free(gpus); free(gpus);
} }

View File

@ -114,10 +114,22 @@ static void SetupVulkan(const char** extensions, uint32_t extensions_count)
err = vkEnumeratePhysicalDevices(g_Instance, &gpu_count, gpus); err = vkEnumeratePhysicalDevices(g_Instance, &gpu_count, gpus);
check_vk_result(err); check_vk_result(err);
// If a number >1 of GPUs got reported, you should find the best fit GPU for your purpose // If a number >1 of GPUs got reported, find discrete GPU if present, or use first one available. This covers
// e.g. VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU if available, or with the greatest memory available, etc. // most common cases (multi-gpu/integrated+dedicated graphics). Handling more complicated setups (multiple
// for sake of simplicity we'll just take the first one, assuming it has a graphics queue family. // dedicated GPUs) is out of scope of this sample.
g_PhysicalDevice = gpus[0]; int use_gpu = 0;
for (int i = 0; i < (int)gpu_count; i++)
{
VkPhysicalDeviceProperties properties;
vkGetPhysicalDeviceProperties(gpus[i], &properties);
if (properties.deviceType == VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU)
{
use_gpu = i;
break;
}
}
g_PhysicalDevice = gpus[use_gpu];
free(gpus); free(gpus);
} }

View File

@ -11,16 +11,16 @@
// - FAQ http://dearimgui.org/faq // - FAQ http://dearimgui.org/faq
// - Homepage & latest https://github.com/ocornut/imgui // - Homepage & latest https://github.com/ocornut/imgui
// - Releases & changelog https://github.com/ocornut/imgui/releases // - Releases & changelog https://github.com/ocornut/imgui/releases
// - Gallery https://github.com/ocornut/imgui/issues/3488 (please post your screenshots/video there!) // - Gallery https://github.com/ocornut/imgui/issues/3793 (please post your screenshots/video there!)
// - Wiki https://github.com/ocornut/imgui/wiki (lots of good stuff there)
// - Glossary https://github.com/ocornut/imgui/wiki/Glossary // - Glossary https://github.com/ocornut/imgui/wiki/Glossary
// - Wiki https://github.com/ocornut/imgui/wiki
// - Issues & support https://github.com/ocornut/imgui/issues // - Issues & support https://github.com/ocornut/imgui/issues
// - Discussions https://github.com/ocornut/imgui/discussions // - Discussions https://github.com/ocornut/imgui/discussions
// 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 needs 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.com".
// 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.
// It is recommended that you don't modify imgui.cpp! It will become difficult for you to update the library. // It is recommended that you don't modify imgui.cpp! It will become difficult for you to update the library.
@ -135,13 +135,13 @@ CODE
READ FIRST READ FIRST
---------- ----------
- Remember to read the FAQ (https://www.dearimgui.org/faq) - Remember to check the wonderful Wiki (https://github.com/ocornut/imgui/wiki)
- Your code creates the UI, if your code doesn't run the UI is gone! The UI can be highly dynamic, there are no construction or - Your code creates the UI, if your code doesn't run the UI is gone! The UI can be highly dynamic, there are no construction or
destruction steps, less superfluous data retention on your side, less state duplication, less state synchronization, fewer bugs. destruction steps, less superfluous data retention on your side, less state duplication, less state synchronization, fewer bugs.
- Call and read ImGui::ShowDemoWindow() for demo code demonstrating most features. - Call and read ImGui::ShowDemoWindow() for demo code demonstrating most features.
- The library is designed to be built from sources. Avoid pre-compiled binaries and packaged versions. See imconfig.h to configure your build. - The library is designed to be built from sources. Avoid pre-compiled binaries and packaged versions. See imconfig.h to configure your build.
- Dear ImGui is an implementation of the IMGUI paradigm (immediate-mode graphical user interface, a term coined by Casey Muratori). - Dear ImGui is an implementation of the IMGUI paradigm (immediate-mode graphical user interface, a term coined by Casey Muratori).
You can learn about IMGUI principles at http://www.johno.se/book/imgui.html, http://mollyrocket.com/861 & more links in the FAQ. You can learn about IMGUI principles at http://www.johno.se/book/imgui.html, http://mollyrocket.com/861 & more links in Wiki.
- Dear ImGui is a "single pass" rasterizing implementation of the IMGUI paradigm, aimed at ease of use and high-performances. - Dear ImGui is a "single pass" rasterizing implementation of the IMGUI paradigm, aimed at ease of use and high-performances.
For every application frame, your UI code will be called only once. This is in contrast to e.g. Unity's implementation of an IMGUI, For every application frame, your UI code will be called only once. This is in contrast to e.g. Unity's implementation of an IMGUI,
where the UI code is called multiple times ("multiple passes") from a single entry point. There are pros and cons to both approaches. where the UI code is called multiple times ("multiple passes") from a single entry point. There are pros and cons to both approaches.
@ -586,7 +586,7 @@ CODE
- 2017/07/20 (1.51) - removed IsPosHoveringAnyWindow(ImVec2), which was partly broken and misleading. ASSERT + redirect user to io.WantCaptureMouse - 2017/07/20 (1.51) - removed IsPosHoveringAnyWindow(ImVec2), which was partly broken and misleading. ASSERT + redirect user to io.WantCaptureMouse
- 2017/05/26 (1.50) - removed ImFontConfig::MergeGlyphCenterV in favor of a more multipurpose ImFontConfig::GlyphOffset. - 2017/05/26 (1.50) - removed ImFontConfig::MergeGlyphCenterV in favor of a more multipurpose ImFontConfig::GlyphOffset.
- 2017/05/01 (1.50) - renamed ImDrawList::PathFill() (rarely used directly) to ImDrawList::PathFillConvex() for clarity. - 2017/05/01 (1.50) - renamed ImDrawList::PathFill() (rarely used directly) to ImDrawList::PathFillConvex() for clarity.
- 2016/11/06 (1.50) - BeginChild(const char*) now applies the stack id to the provided label, consistently with other functions as it should always have been. It shouldn't affect you unless (extremely unlikely) you were appending multiple times to a same child from different locations of the stack id. If that's the case, generate an id with GetId() and use it instead of passing string to BeginChild(). - 2016/11/06 (1.50) - BeginChild(const char*) now applies the stack id to the provided label, consistently with other functions as it should always have been. It shouldn't affect you unless (extremely unlikely) you were appending multiple times to a same child from different locations of the stack id. If that's the case, generate an id with GetID() and use it instead of passing string to BeginChild().
- 2016/10/15 (1.50) - avoid 'void* user_data' parameter to io.SetClipboardTextFn/io.GetClipboardTextFn pointers. We pass io.ClipboardUserData to it. - 2016/10/15 (1.50) - avoid 'void* user_data' parameter to io.SetClipboardTextFn/io.GetClipboardTextFn pointers. We pass io.ClipboardUserData to it.
- 2016/09/25 (1.50) - style.WindowTitleAlign is now a ImVec2 (ImGuiAlign enum was removed). set to (0.5f,0.5f) for horizontal+vertical centering, (0.0f,0.0f) for upper-left, etc. - 2016/09/25 (1.50) - style.WindowTitleAlign is now a ImVec2 (ImGuiAlign enum was removed). set to (0.5f,0.5f) for horizontal+vertical centering, (0.0f,0.0f) for upper-left, etc.
- 2016/07/30 (1.50) - SameLine(x) with x>0.0f is now relative to left of column/group if any, and not always to left of window. This was sort of always the intent and hopefully, breakage should be minimal. - 2016/07/30 (1.50) - SameLine(x) with x>0.0f is now relative to left of column/group if any, and not always to left of window. This was sort of always the intent and hopefully, breakage should be minimal.
@ -754,14 +754,14 @@ CODE
============== ==============
Q: How can I help? Q: How can I help?
A: - Businesses: please reach out to "contact AT dearimgui.org" if you work in a place using Dear ImGui! A: - Businesses: please reach out to "contact AT dearimgui.com" if you work in a place using Dear ImGui!
We can discuss ways for your company to fund development via invoiced technical support, maintenance or sponsoring contacts. We can discuss ways for your company to fund development via invoiced technical support, maintenance or sponsoring contacts.
This is among the most useful thing you can do for Dear ImGui. With increased funding, we can hire more people working on this project. This is among the most useful thing you can do for Dear ImGui. With increased funding, we can hire more people working on this project.
- Individuals: you can support continued development via PayPal donations. See README. - Individuals: you can support continued development via PayPal donations. See README.
- If you are experienced with Dear ImGui and C++, look at the GitHub issues, look at the Wiki, read docs/TODO.txt - If you are experienced with Dear ImGui and C++, look at the GitHub issues, look at the Wiki, read docs/TODO.txt
and see how you want to help and can help! and see how you want to help and can help!
- Disclose your usage of Dear ImGui via a dev blog post, a tweet, a screenshot, a mention somewhere etc. - Disclose your usage of Dear ImGui via a dev blog post, a tweet, a screenshot, a mention somewhere etc.
You may post screenshot or links in the gallery threads (github.com/ocornut/imgui/issues/3488). Visuals are ideal as they inspire other programmers. You may post screenshot or links in the gallery threads. Visuals are ideal as they inspire other programmers.
But even without visuals, disclosing your use of dear imgui helps the library grow credibility, and help other teams and programmers with taking decisions. But even without visuals, disclosing your use of dear imgui helps the library grow credibility, and help other teams and programmers with taking decisions.
- If you have issues or if you need to hack into the library, even if you don't expect any support it is useful that you share your issues (on GitHub or privately). - If you have issues or if you need to hack into the library, even if you don't expect any support it is useful that you share your issues (on GitHub or privately).
@ -3863,10 +3863,17 @@ void ImGui::UpdateMouseWheel()
// Mouse wheel scrolling // Mouse wheel scrolling
// If a child window has the ImGuiWindowFlags_NoScrollWithMouse flag, we give a chance to scroll its parent // If a child window has the ImGuiWindowFlags_NoScrollWithMouse flag, we give a chance to scroll its parent
if (g.IO.KeyCtrl)
return;
// As a standard behavior holding SHIFT while using Vertical Mouse Wheel triggers Horizontal scroll instead
// (we avoid doing it on OSX as it the OS input layer handles this already)
const bool swap_axis = g.IO.KeyShift && !g.IO.ConfigMacOSXBehaviors;
const float wheel_y = swap_axis ? 0.0f : g.IO.MouseWheel;
const float wheel_x = swap_axis ? g.IO.MouseWheel : g.IO.MouseWheelH;
// Vertical Mouse Wheel scrolling // Vertical Mouse Wheel scrolling
const float wheel_y = (g.IO.MouseWheel != 0.0f && !g.IO.KeyShift) ? g.IO.MouseWheel : 0.0f; if (wheel_y != 0.0f)
if (wheel_y != 0.0f && !g.IO.KeyCtrl)
{ {
StartLockWheelingWindow(window); StartLockWheelingWindow(window);
while ((window->Flags & ImGuiWindowFlags_ChildWindow) && ((window->ScrollMax.y == 0.0f) || ((window->Flags & ImGuiWindowFlags_NoScrollWithMouse) && !(window->Flags & ImGuiWindowFlags_NoMouseInputs)))) while ((window->Flags & ImGuiWindowFlags_ChildWindow) && ((window->ScrollMax.y == 0.0f) || ((window->Flags & ImGuiWindowFlags_NoScrollWithMouse) && !(window->Flags & ImGuiWindowFlags_NoMouseInputs))))
@ -3880,8 +3887,7 @@ void ImGui::UpdateMouseWheel()
} }
// Horizontal Mouse Wheel scrolling, or Vertical Mouse Wheel w/ Shift held // Horizontal Mouse Wheel scrolling, or Vertical Mouse Wheel w/ Shift held
const float wheel_x = (g.IO.MouseWheelH != 0.0f && !g.IO.KeyShift) ? g.IO.MouseWheelH : (g.IO.MouseWheel != 0.0f && g.IO.KeyShift) ? g.IO.MouseWheel : 0.0f; if (wheel_x != 0.0f)
if (wheel_x != 0.0f && !g.IO.KeyCtrl)
{ {
StartLockWheelingWindow(window); StartLockWheelingWindow(window);
while ((window->Flags & ImGuiWindowFlags_ChildWindow) && ((window->ScrollMax.x == 0.0f) || ((window->Flags & ImGuiWindowFlags_NoScrollWithMouse) && !(window->Flags & ImGuiWindowFlags_NoMouseInputs)))) while ((window->Flags & ImGuiWindowFlags_ChildWindow) && ((window->ScrollMax.x == 0.0f) || ((window->Flags & ImGuiWindowFlags_NoScrollWithMouse) && !(window->Flags & ImGuiWindowFlags_NoMouseInputs))))
@ -8764,6 +8770,11 @@ void ImGui::OpenPopup(const char* str_id, ImGuiPopupFlags popup_flags)
OpenPopupEx(g.CurrentWindow->GetID(str_id), popup_flags); OpenPopupEx(g.CurrentWindow->GetID(str_id), popup_flags);
} }
void ImGui::OpenPopup(ImGuiID id, ImGuiPopupFlags popup_flags)
{
OpenPopupEx(id, popup_flags);
}
// Mark popup as open (toggle toward open state). // Mark popup as open (toggle toward open state).
// Popups are closed when user click outside, or activate a pressable item, or CloseCurrentPopup() is called within a BeginPopup()/EndPopup() block. // Popups are closed when user click outside, or activate a pressable item, or CloseCurrentPopup() is called within a BeginPopup()/EndPopup() block.
// Popup identifiers are relative to the current ID-stack (so OpenPopup and BeginPopup needs to be at the same level). // Popup identifiers are relative to the current ID-stack (so OpenPopup and BeginPopup needs to be at the same level).
@ -9023,10 +9034,21 @@ void ImGui::OpenPopupOnItemClick(const char* str_id, ImGuiPopupFlags popup_flags
} }
// 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 can pass a NULL str_id to use the identifier of the last item. // - To create a popup associated to the last item, you generally want to pass a NULL value to str_id.
// - You may want to handle this on user side if you have specific needs (e.g. tweaking IsItemHovered() parameters). // - To create a popup with a specific identifier, pass it in str_id.
// - This is essentially the same as calling OpenPopupOnItemClick() + BeginPopup() but written to avoid // - This is useful when using using BeginPopupContextItem() on an item which doesn't have an identifier, e.g. a Text() call.
// computing the ID twice because BeginPopupContextXXX functions may be called very frequently. // - This is useful when multiple code locations may want to manipulate/open the same popup, given an explicit id.
// - You may want to handle the whole on user side if you have specific needs (e.g. tweaking IsItemHovered() parameters).
// This is essentially the same as:
// id = str_id ? GetID(str_id) : GetItemID();
// OpenPopupOnItemClick(str_id);
// return BeginPopup(id);
// Which is essentially the same as:
// id = str_id ? GetID(str_id) : GetItemID();
// if (IsItemHovered() && IsMouseReleased(ImGuiMouseButton_Right))
// OpenPopup(id);
// return BeginPopup(id);
// The main difference being that this is tweaked to avoid computing the ID twice.
bool ImGui::BeginPopupContextItem(const char* str_id, ImGuiPopupFlags popup_flags) bool ImGui::BeginPopupContextItem(const char* str_id, ImGuiPopupFlags popup_flags)
{ {
ImGuiWindow* window = GImGui->CurrentWindow; ImGuiWindow* window = GImGui->CurrentWindow;
@ -16377,7 +16399,7 @@ void ImGui::ShowMetricsWindow(bool* p_open)
// Misc Details // Misc Details
if (TreeNode("Internal state")) if (TreeNode("Internal state"))
{ {
const char* input_source_names[] = { "None", "Mouse", "Nav", "NavKeyboard", "NavGamepad" }; IM_ASSERT(IM_ARRAYSIZE(input_source_names) == ImGuiInputSource_COUNT); const char* input_source_names[] = { "None", "Mouse", "Keyboard", "Gamepad", "Nav", "Clipboard" }; IM_ASSERT(IM_ARRAYSIZE(input_source_names) == ImGuiInputSource_COUNT);
Text("WINDOWING"); Text("WINDOWING");
Indent(); Indent();

View File

@ -11,9 +11,9 @@
// - FAQ http://dearimgui.org/faq // - FAQ http://dearimgui.org/faq
// - Homepage & latest https://github.com/ocornut/imgui // - Homepage & latest https://github.com/ocornut/imgui
// - Releases & changelog https://github.com/ocornut/imgui/releases // - Releases & changelog https://github.com/ocornut/imgui/releases
// - Gallery https://github.com/ocornut/imgui/issues/3488 (please post your screenshots/video there!) // - Gallery https://github.com/ocornut/imgui/issues/3793 (please post your screenshots/video there!)
// - Wiki https://github.com/ocornut/imgui/wiki (lots of good stuff there)
// - Glossary https://github.com/ocornut/imgui/wiki/Glossary // - Glossary https://github.com/ocornut/imgui/wiki/Glossary
// - Wiki https://github.com/ocornut/imgui/wiki
// - Issues & support https://github.com/ocornut/imgui/issues // - Issues & support https://github.com/ocornut/imgui/issues
// - Discussions https://github.com/ocornut/imgui/discussions // - Discussions https://github.com/ocornut/imgui/discussions
@ -663,6 +663,7 @@ namespace ImGui
// - Use ImGuiPopupFlags_NoOpenOverExistingPopup to avoid opening a popup if there's already one at the same level. This is equivalent to e.g. testing for !IsAnyPopupOpen() prior to OpenPopup(). // - Use ImGuiPopupFlags_NoOpenOverExistingPopup to avoid opening a popup if there's already one at the same level. This is equivalent to e.g. testing for !IsAnyPopupOpen() prior to OpenPopup().
// - Use IsWindowAppearing() after BeginPopup() to tell if a window just opened. // - Use IsWindowAppearing() after BeginPopup() to tell if a window just opened.
IMGUI_API void OpenPopup(const char* str_id, ImGuiPopupFlags popup_flags = 0); // call to mark popup as open (don't call every frame!). IMGUI_API void OpenPopup(const char* str_id, ImGuiPopupFlags popup_flags = 0); // call to mark popup as open (don't call every frame!).
IMGUI_API void OpenPopup(ImGuiID id, ImGuiPopupFlags popup_flags = 0); // id overload to facilitate calling from nested stacks
IMGUI_API void OpenPopupOnItemClick(const char* str_id = NULL, ImGuiPopupFlags popup_flags = 1); // helper to open popup when clicked on last item. Default to ImGuiPopupFlags_MouseButtonRight == 1. (note: actually triggers on the mouse _released_ event to be consistent with popup behaviors) IMGUI_API void OpenPopupOnItemClick(const char* str_id = NULL, ImGuiPopupFlags popup_flags = 1); // helper to open popup when clicked on last item. Default to ImGuiPopupFlags_MouseButtonRight == 1. (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 void CloseCurrentPopup(); // manually close the popup we have begin-ed into.
// Popups: open+begin combined functions helpers // Popups: open+begin combined functions helpers
@ -670,7 +671,7 @@ namespace ImGui
// - They are convenient to easily create context menus, hence the name. // - They are convenient to easily create context menus, hence the name.
// - IMPORTANT: Notice that BeginPopupContextXXX takes ImGuiPopupFlags just like OpenPopup() and unlike BeginPopup(). For full consistency, we may add ImGuiWindowFlags to the BeginPopupContextXXX functions in the future. // - IMPORTANT: Notice that BeginPopupContextXXX takes ImGuiPopupFlags just like OpenPopup() and unlike BeginPopup(). For full consistency, we may add ImGuiWindowFlags to the BeginPopupContextXXX functions in the future.
// - IMPORTANT: we exceptionally default their flags to 1 (== ImGuiPopupFlags_MouseButtonRight) for backward compatibility with older API taking 'int mouse_button = 1' parameter, so if you add other flags remember to re-add the ImGuiPopupFlags_MouseButtonRight. // - IMPORTANT: we exceptionally default their flags to 1 (== ImGuiPopupFlags_MouseButtonRight) for backward compatibility with older API taking 'int mouse_button = 1' parameter, so if you add other flags remember to re-add the ImGuiPopupFlags_MouseButtonRight.
IMGUI_API bool BeginPopupContextItem(const char* str_id = NULL, ImGuiPopupFlags popup_flags = 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 BeginPopupContextItem(const char* str_id = NULL, ImGuiPopupFlags popup_flags = 1); // open+begin popup when clicked on last item. Use str_id==NULL to associate the popup to previous item. 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, ImGuiPopupFlags popup_flags = 1);// open+begin popup when clicked on current window. IMGUI_API bool BeginPopupContextWindow(const char* str_id = NULL, ImGuiPopupFlags popup_flags = 1);// open+begin popup when clicked on current window.
IMGUI_API bool BeginPopupContextVoid(const char* str_id = NULL, ImGuiPopupFlags popup_flags = 1); // open+begin popup when clicked in void (where there are no windows). IMGUI_API bool BeginPopupContextVoid(const char* str_id = NULL, ImGuiPopupFlags popup_flags = 1); // open+begin popup when clicked in void (where there are no windows).
// Popups: query functions // Popups: query functions

View File

@ -3247,46 +3247,84 @@ static void ShowDemoWindowPopups()
if (ImGui::TreeNode("Context menus")) if (ImGui::TreeNode("Context menus"))
{ {
HelpMarker("\"Context\" functions are simple helpers to associate a Popup to a given Item or Window identifier.");
// 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(ImGuiMouseButton_Right)) // if (id == 0)
// OpenPopup(id); // id = GetItemID(); // Use last item id
// return BeginPopup(id); // if (IsItemHovered() && IsMouseReleased(ImGuiMouseButton_Right))
// For more advanced uses you may want to replicate and customize this code. // OpenPopup(id);
// See details in BeginPopupContextItem(). // return BeginPopup(id);
static float value = 0.5f; // For advanced advanced uses you may want to replicate and customize this code.
ImGui::Text("Value = %.3f (<-- right-click here)", value); // See more details in BeginPopupContextItem().
if (ImGui::BeginPopupContextItem("item context menu"))
// Example 1
// When used after an item that has an ID (e.g. Button), we can skip providing an ID to BeginPopupContextItem(),
// and BeginPopupContextItem() will use the last item ID as the popup ID.
{ {
if (ImGui::Selectable("Set to zero")) value = 0.0f; const char* names[5] = { "Label1", "Label2", "Label3", "Label4", "Label5" };
if (ImGui::Selectable("Set to PI")) value = 3.1415f; for (int n = 0; n < 5; n++)
ImGui::SetNextItemWidth(-FLT_MIN); {
ImGui::DragFloat("##Value", &value, 0.1f, 0.0f, 0.0f); ImGui::Selectable(names[n]);
ImGui::EndPopup(); if (ImGui::BeginPopupContextItem()) // <-- use last item id as popup id
{
ImGui::Text("This a popup for \"%s\"!", names[n]);
if (ImGui::Button("Close"))
ImGui::CloseCurrentPopup();
ImGui::EndPopup();
}
if (ImGui::IsItemHovered())
ImGui::SetTooltip("Right-click to open popup");
}
} }
// We can also use OpenPopupOnItemClick() which is the same as BeginPopupContextItem() but without the // Example 2
// Begin() call. So here we will make it that clicking on the text field with the right mouse button (1) // Popup on a Text() element which doesn't have an identifier: we need to provide an identifier to BeginPopupContextItem().
// will toggle the visibility of the popup above. // Using an explicit identifier is also convenient if you want to activate the popups from different locations.
ImGui::Text("(You can also right-click me to open the same popup as above.)");
ImGui::OpenPopupOnItemClick("item context menu", 1);
// 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.
// In addition here, we want to include your editable label inside the button label.
// We use the ### operator to override the ID (read FAQ about ID for details)
static char name[32] = "Label1";
char buf[64];
sprintf(buf, "Button: %s###Button", name); // ### operator override ID ignoring the preceding label
ImGui::Button(buf);
if (ImGui::BeginPopupContextItem())
{ {
ImGui::Text("Edit name:"); HelpMarker("Text() elements don't have stable identifiers so we need to provide one.");
ImGui::InputText("##edit", name, IM_ARRAYSIZE(name)); static float value = 0.5f;
if (ImGui::Button("Close")) ImGui::Text("Value = %.3f <-- (1) right-click this value", value);
ImGui::CloseCurrentPopup(); if (ImGui::BeginPopupContextItem("my popup"))
ImGui::EndPopup(); {
if (ImGui::Selectable("Set to zero")) value = 0.0f;
if (ImGui::Selectable("Set to PI")) value = 3.1415f;
ImGui::SetNextItemWidth(-FLT_MIN);
ImGui::DragFloat("##Value", &value, 0.1f, 0.0f, 0.0f);
ImGui::EndPopup();
}
// We can also use OpenPopupOnItemClick() to toggle the visibility of a given popup.
// Here we make it that right-clicking this other text element opens the same popup as above.
// The popup itself will be submitted by the code above.
ImGui::Text("(2) Or right-click this text");
ImGui::OpenPopupOnItemClick("my popup", ImGuiPopupFlags_MouseButtonRight);
// Back to square one: manually open the same popup.
if (ImGui::Button("(3) Or click this button"))
ImGui::OpenPopup("my popup");
}
// Example 3
// When using BeginPopupContextItem() with an implicit identifier (NULL == use last item ID),
// we need to make sure your item identifier is stable.
// In this example we showcase altering the item label while preserving its identifier, using the ### operator (see FAQ).
{
HelpMarker("Showcase using a popup ID linked to item ID, with the item having a changing label + stable ID using the ### operator.");
static char name[32] = "Label1";
char buf[64];
sprintf(buf, "Button: %s###Button", name); // ### operator override ID ignoring the preceding label
ImGui::Button(buf);
if (ImGui::BeginPopupContextItem())
{
ImGui::Text("Edit name:");
ImGui::InputText("##edit", name, IM_ARRAYSIZE(name));
if (ImGui::Button("Close"))
ImGui::CloseCurrentPopup();
ImGui::EndPopup();
}
ImGui::SameLine(); ImGui::Text("(<-- right-click here)");
} }
ImGui::SameLine(); ImGui::Text("(<-- right-click here)");
ImGui::TreePop(); ImGui::TreePop();
} }

View File

@ -145,7 +145,7 @@ namespace IMGUI_STB_NAMESPACE
#define STBTT_sqrt(x) ImSqrt(x) #define STBTT_sqrt(x) ImSqrt(x)
#define STBTT_pow(x,y) ImPow(x,y) #define STBTT_pow(x,y) ImPow(x,y)
#define STBTT_fabs(x) ImFabs(x) #define STBTT_fabs(x) ImFabs(x)
#define STBTT_ifloor(x) ((int)ImFloorStd(x)) #define STBTT_ifloor(x) ((int)ImFloorSigned(x))
#define STBTT_iceil(x) ((int)ImCeil(x)) #define STBTT_iceil(x) ((int)ImCeil(x))
#define STBTT_STATIC #define STBTT_STATIC
#define STB_TRUETYPE_IMPLEMENTATION #define STB_TRUETYPE_IMPLEMENTATION
@ -1043,7 +1043,6 @@ void ImDrawList::_PathArcToFastEx(const ImVec2& center, float radius, int a_min_
_Path.push_back(center); _Path.push_back(center);
return; return;
} }
IM_ASSERT(a_min_sample <= a_max_sample);
// Calculate arc auto segment step size // Calculate arc auto segment step size
if (a_step <= 0) if (a_step <= 0)
@ -1052,17 +1051,7 @@ void ImDrawList::_PathArcToFastEx(const ImVec2& center, float radius, int a_min_
// Make sure we never do steps larger than one quarter of the circle // Make sure we never do steps larger than one quarter of the circle
a_step = ImClamp(a_step, 1, IM_DRAWLIST_ARCFAST_TABLE_SIZE / 4); a_step = ImClamp(a_step, 1, IM_DRAWLIST_ARCFAST_TABLE_SIZE / 4);
// Normalize a_min_sample to always start lie in [0..IM_DRAWLIST_ARCFAST_SAMPLE_MAX] range. const int sample_range = ImAbs(a_max_sample - a_min_sample);
if (a_min_sample < 0)
{
int normalized_sample = a_min_sample % IM_DRAWLIST_ARCFAST_SAMPLE_MAX;
if (normalized_sample < 0)
normalized_sample += IM_DRAWLIST_ARCFAST_SAMPLE_MAX;
a_max_sample += (normalized_sample - a_min_sample);
a_min_sample = normalized_sample;
}
const int sample_range = a_max_sample - a_min_sample;
const int a_next_step = a_step; const int a_next_step = a_step;
int samples = sample_range + 1; int samples = sample_range + 1;
@ -1088,16 +1077,40 @@ void ImDrawList::_PathArcToFastEx(const ImVec2& center, float radius, int a_min_
ImVec2* out_ptr = _Path.Data + (_Path.Size - samples); ImVec2* out_ptr = _Path.Data + (_Path.Size - samples);
int sample_index = a_min_sample; int sample_index = a_min_sample;
for (int a = a_min_sample; a <= a_max_sample; a += a_step, sample_index += a_step, a_step = a_next_step) if (sample_index < 0 || sample_index >= IM_DRAWLIST_ARCFAST_SAMPLE_MAX)
{ {
// a_step is clamped to IM_DRAWLIST_ARCFAST_SAMPLE_MAX, so we have guaranteed that it will not wrap over range twice or more sample_index = sample_index % IM_DRAWLIST_ARCFAST_SAMPLE_MAX;
if (sample_index >= IM_DRAWLIST_ARCFAST_SAMPLE_MAX) if (sample_index < 0)
sample_index -= IM_DRAWLIST_ARCFAST_SAMPLE_MAX; sample_index += IM_DRAWLIST_ARCFAST_SAMPLE_MAX;
}
const ImVec2 s = _Data->ArcFastVtx[sample_index]; if (a_max_sample >= a_min_sample)
out_ptr->x = center.x + s.x * radius; {
out_ptr->y = center.y + s.y * radius; for (int a = a_min_sample; a <= a_max_sample; a += a_step, sample_index += a_step, a_step = a_next_step)
out_ptr++; {
// a_step is clamped to IM_DRAWLIST_ARCFAST_SAMPLE_MAX, so we have guaranteed that it will not wrap over range twice or more
if (sample_index >= IM_DRAWLIST_ARCFAST_SAMPLE_MAX)
sample_index -= IM_DRAWLIST_ARCFAST_SAMPLE_MAX;
const ImVec2 s = _Data->ArcFastVtx[sample_index];
out_ptr->x = center.x + s.x * radius;
out_ptr->y = center.y + s.y * radius;
out_ptr++;
}
}
else
{
for (int a = a_min_sample; a >= a_max_sample; a -= a_step, sample_index -= a_step, a_step = a_next_step)
{
// a_step is clamped to IM_DRAWLIST_ARCFAST_SAMPLE_MAX, so we have guaranteed that it will not wrap over range twice or more
if (sample_index < 0)
sample_index += IM_DRAWLIST_ARCFAST_SAMPLE_MAX;
const ImVec2 s = _Data->ArcFastVtx[sample_index];
out_ptr->x = center.x + s.x * radius;
out_ptr->y = center.y + s.y * radius;
out_ptr++;
}
} }
if (extra_max_sample) if (extra_max_sample)
@ -1122,7 +1135,6 @@ void ImDrawList::_PathArcToN(const ImVec2& center, float radius, float a_min, fl
_Path.push_back(center); _Path.push_back(center);
return; return;
} }
IM_ASSERT(a_min <= a_max);
// Note that we are adding a point at both a_min and a_max. // Note that we are adding a point at both a_min and a_max.
// If you are trying to draw a full closed circle you don't want the overlapping points! // If you are trying to draw a full closed circle you don't want the overlapping points!
@ -1142,7 +1154,6 @@ void ImDrawList::PathArcToFast(const ImVec2& center, float radius, int a_min_of_
_Path.push_back(center); _Path.push_back(center);
return; return;
} }
IM_ASSERT(a_min_of_12 <= a_max_of_12);
_PathArcToFastEx(center, radius, a_min_of_12 * IM_DRAWLIST_ARCFAST_SAMPLE_MAX / 12, a_max_of_12 * IM_DRAWLIST_ARCFAST_SAMPLE_MAX / 12, 0); _PathArcToFastEx(center, radius, a_min_of_12 * IM_DRAWLIST_ARCFAST_SAMPLE_MAX / 12, a_max_of_12 * IM_DRAWLIST_ARCFAST_SAMPLE_MAX / 12, 0);
} }
@ -1153,7 +1164,6 @@ void ImDrawList::PathArcTo(const ImVec2& center, float radius, float a_min, floa
_Path.push_back(center); _Path.push_back(center);
return; return;
} }
IM_ASSERT(a_min <= a_max);
if (num_segments > 0) if (num_segments > 0)
{ {
@ -1164,28 +1174,33 @@ void ImDrawList::PathArcTo(const ImVec2& center, float radius, float a_min, floa
// Automatic segment count // Automatic segment count
if (radius <= _Data->ArcFastRadiusCutoff) if (radius <= _Data->ArcFastRadiusCutoff)
{ {
const bool a_is_reverse = a_max < a_min;
// We are going to use precomputed values for mid samples. // We are going to use precomputed values for mid samples.
// Determine first and last sample in lookup table that belong to the arc. // Determine first and last sample in lookup table that belong to the arc.
const int a_min_sample = (int)ImCeil(IM_DRAWLIST_ARCFAST_SAMPLE_MAX * a_min / (IM_PI * 2.0f)); const float a_min_sample_f = IM_DRAWLIST_ARCFAST_SAMPLE_MAX * a_min / (IM_PI * 2.0f);
const int a_max_sample = (int)( IM_DRAWLIST_ARCFAST_SAMPLE_MAX * a_max / (IM_PI * 2.0f)); const float a_max_sample_f = IM_DRAWLIST_ARCFAST_SAMPLE_MAX * a_max / (IM_PI * 2.0f);
const int a_mid_samples = ImMax(a_max_sample - a_min_sample, 0);
const int a_min_sample = a_is_reverse ? (int)ImFloorSigned(a_min_sample_f) : (int)ImCeil(a_min_sample_f);
const int a_max_sample = a_is_reverse ? (int)ImCeil(a_max_sample_f) : (int)ImFloorSigned(a_max_sample_f);
const int a_mid_samples = a_is_reverse ? ImMax(a_min_sample - a_max_sample, 0) : ImMax(a_max_sample - a_min_sample, 0);
const float a_min_segment_angle = a_min_sample * IM_PI * 2.0f / IM_DRAWLIST_ARCFAST_SAMPLE_MAX; const float a_min_segment_angle = a_min_sample * IM_PI * 2.0f / IM_DRAWLIST_ARCFAST_SAMPLE_MAX;
const float a_max_segment_angle = a_max_sample * IM_PI * 2.0f / IM_DRAWLIST_ARCFAST_SAMPLE_MAX; const float a_max_segment_angle = a_max_sample * IM_PI * 2.0f / IM_DRAWLIST_ARCFAST_SAMPLE_MAX;
const bool a_emit_start = (a_min_segment_angle - a_min) > 0.0f; const bool a_emit_start = (a_min_segment_angle - a_min) != 0.0f;
const bool a_emit_end = (a_max - a_max_segment_angle) > 0.0f; const bool a_emit_end = (a_max - a_max_segment_angle) != 0.0f;
_Path.reserve(_Path.Size + (a_mid_samples + 1 + (a_emit_start ? 1 : 0) + (a_emit_end ? 1 : 0))); _Path.reserve(_Path.Size + (a_mid_samples + 1 + (a_emit_start ? 1 : 0) + (a_emit_end ? 1 : 0)));
if (a_emit_start) if (a_emit_start)
_Path.push_back(ImVec2(center.x + ImCos(a_min) * radius, center.y + ImSin(a_min) * radius)); _Path.push_back(ImVec2(center.x + ImCos(a_min) * radius, center.y + ImSin(a_min) * radius));
if (a_max_sample >= a_min_sample) if (a_mid_samples > 0)
_PathArcToFastEx(center, radius, a_min_sample, a_max_sample, 0); _PathArcToFastEx(center, radius, a_min_sample, a_max_sample, 0);
if (a_emit_end) if (a_emit_end)
_Path.push_back(ImVec2(center.x + ImCos(a_max) * radius, center.y + ImSin(a_max) * radius)); _Path.push_back(ImVec2(center.x + ImCos(a_max) * radius, center.y + ImSin(a_max) * radius));
} }
else else
{ {
const float arc_length = a_max - a_min; const float arc_length = ImAbs(a_max - a_min);
const int circle_segment_count = _CalcCircleAutoSegmentCount(radius); const int circle_segment_count = _CalcCircleAutoSegmentCount(radius);
const int arc_segment_count = ImMax((int)ImCeil(circle_segment_count * arc_length / (IM_PI * 2.0f)), (int)(2.0f * IM_PI / arc_length)); const int arc_segment_count = ImMax((int)ImCeil(circle_segment_count * arc_length / (IM_PI * 2.0f)), (int)(2.0f * IM_PI / arc_length));
_PathArcToN(center, radius, a_min, a_max, arc_segment_count); _PathArcToN(center, radius, a_min, a_max, arc_segment_count);
@ -3475,6 +3490,7 @@ ImVec2 ImFont::CalcTextSizeA(float size, float max_width, float wrap_width, cons
return text_size; return text_size;
} }
// Note: as with every ImDrawList drawing function, this expects that the font atlas texture is bound.
void ImFont::RenderChar(ImDrawList* draw_list, float size, ImVec2 pos, ImU32 col, ImWchar c) const void ImFont::RenderChar(ImDrawList* draw_list, float size, ImVec2 pos, ImU32 col, ImWchar c) const
{ {
const ImFontGlyph* glyph = FindGlyph(c); const ImFontGlyph* glyph = FindGlyph(c);
@ -3489,6 +3505,7 @@ void ImFont::RenderChar(ImDrawList* draw_list, float size, ImVec2 pos, ImU32 col
draw_list->PrimRectUV(ImVec2(pos.x + glyph->X0 * scale, pos.y + glyph->Y0 * scale), ImVec2(pos.x + glyph->X1 * scale, pos.y + glyph->Y1 * scale), ImVec2(glyph->U0, glyph->V0), ImVec2(glyph->U1, glyph->V1), col); draw_list->PrimRectUV(ImVec2(pos.x + glyph->X0 * scale, pos.y + glyph->Y0 * scale), ImVec2(pos.x + glyph->X1 * scale, pos.y + glyph->Y1 * scale), ImVec2(glyph->U0, glyph->V0), ImVec2(glyph->U1, glyph->V1), col);
} }
// Note: as with every ImDrawList drawing function, this expects that the font atlas texture is bound.
void ImFont::RenderText(ImDrawList* draw_list, float size, ImVec2 pos, ImU32 col, const ImVec4& clip_rect, const char* text_begin, const char* text_end, float wrap_width, bool cpu_fine_clip) const void ImFont::RenderText(ImDrawList* draw_list, float size, ImVec2 pos, ImU32 col, const ImVec4& clip_rect, const char* text_begin, const char* text_end, float wrap_width, bool cpu_fine_clip) const
{ {
if (!text_end) if (!text_end)

View File

@ -64,6 +64,7 @@ Index of this file:
#pragma clang diagnostic ignored "-Wunknown-warning-option" // warning: unknown warning group 'xxx' #pragma clang diagnostic ignored "-Wunknown-warning-option" // warning: unknown warning group 'xxx'
#endif #endif
#pragma clang diagnostic ignored "-Wunknown-pragmas" // warning: unknown warning group 'xxx' #pragma clang diagnostic ignored "-Wunknown-pragmas" // warning: unknown warning group 'xxx'
#pragma clang diagnostic ignored "-Wfloat-equal" // warning: comparing floating point with == or != is unsafe // storing and comparing against same constants ok, for ImFloorSigned()
#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"
@ -376,12 +377,13 @@ IMGUI_API void* ImFileLoadToMemory(const char* filename, const char*
#define ImAcos(X) acosf(X) #define ImAcos(X) acosf(X)
#define ImAtan2(Y, X) atan2f((Y), (X)) #define ImAtan2(Y, X) atan2f((Y), (X))
#define ImAtof(STR) atof(STR) #define ImAtof(STR) atof(STR)
#define ImFloorStd(X) floorf(X) // We already uses our own ImFloor() { return (float)(int)v } internally so the standard one wrapper is named differently (it's used by e.g. stb_truetype) //#define ImFloorStd(X) floorf(X) // We use our own, see ImFloor() and ImFloorSigned()
#define ImCeil(X) ceilf(X) #define ImCeil(X) ceilf(X)
static inline float ImPow(float x, float y) { return powf(x, y); } // DragBehaviorT/SliderBehaviorT uses ImPow with either float/double and need the precision static inline float ImPow(float x, float y) { return powf(x, y); } // DragBehaviorT/SliderBehaviorT uses ImPow with either float/double and need the precision
static inline double ImPow(double x, double y) { return pow(x, y); } static inline double ImPow(double x, double y) { return pow(x, y); }
static inline float ImLog(float x) { return logf(x); } // DragBehaviorT/SliderBehaviorT uses ImLog with either float/double and need the precision static inline float ImLog(float x) { return logf(x); } // DragBehaviorT/SliderBehaviorT uses ImLog with either float/double and need the precision
static inline double ImLog(double x) { return log(x); } static inline double ImLog(double x) { return log(x); }
static inline int ImAbs(int x) { return x < 0 ? -x : x; }
static inline float ImAbs(float x) { return fabsf(x); } static inline float ImAbs(float x) { return fabsf(x); }
static inline double ImAbs(double x) { return fabs(x); } static inline double ImAbs(double x) { return fabs(x); }
static inline float ImSign(float x) { return (x < 0.0f) ? -1.0f : ((x > 0.0f) ? 1.0f : 0.0f); } // Sign operator - returns -1, 0 or 1 based on sign of argument static inline float ImSign(float x) { return (x < 0.0f) ? -1.0f : ((x > 0.0f) ? 1.0f : 0.0f); } // Sign operator - returns -1, 0 or 1 based on sign of argument
@ -408,6 +410,7 @@ static inline float ImLengthSqr(const ImVec2& lhs)
static inline float ImLengthSqr(const ImVec4& lhs) { return (lhs.x * lhs.x) + (lhs.y * lhs.y) + (lhs.z * lhs.z) + (lhs.w * lhs.w); } static inline float ImLengthSqr(const ImVec4& lhs) { return (lhs.x * lhs.x) + (lhs.y * lhs.y) + (lhs.z * lhs.z) + (lhs.w * lhs.w); }
static inline float ImInvLength(const ImVec2& lhs, float fail_value) { float d = (lhs.x * lhs.x) + (lhs.y * lhs.y); if (d > 0.0f) return 1.0f / ImSqrt(d); return fail_value; } static inline float ImInvLength(const ImVec2& lhs, float fail_value) { float d = (lhs.x * lhs.x) + (lhs.y * lhs.y); if (d > 0.0f) return 1.0f / ImSqrt(d); return fail_value; }
static inline float ImFloor(float f) { return (float)(int)(f); } static inline float ImFloor(float f) { return (float)(int)(f); }
static inline float ImFloorSigned(float f) { return (float)((f >= 0 || (int)f == f) ? (int)f : (int)f - 1); } // Decent replacement for floorf()
static inline ImVec2 ImFloor(const ImVec2& v) { return ImVec2((float)(int)(v.x), (float)(int)(v.y)); } static inline ImVec2 ImFloor(const ImVec2& v) { return ImVec2((float)(int)(v.x), (float)(int)(v.y)); }
static inline int ImModPositive(int a, int b) { return (a + b) % b; } static inline int ImModPositive(int a, int b) { return (a + b) % b; }
static inline float ImDot(const ImVec2& a, const ImVec2& b) { return a.x * b.x + a.y * b.y; } static inline float ImDot(const ImVec2& a, const ImVec2& b) { return a.x * b.x + a.y * b.y; }
@ -839,6 +842,7 @@ enum ImGuiInputSource
ImGuiInputSource_Keyboard, ImGuiInputSource_Keyboard,
ImGuiInputSource_Gamepad, ImGuiInputSource_Gamepad,
ImGuiInputSource_Nav, // Stored in g.ActiveIdSource only ImGuiInputSource_Nav, // Stored in g.ActiveIdSource only
ImGuiInputSource_Clipboard, // Currently only used by InputText()
ImGuiInputSource_COUNT ImGuiInputSource_COUNT
}; };

View File

@ -122,7 +122,7 @@ static const ImU64 IM_U64_MAX = (2ULL * 9223372036854775807LL + 1);
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
// For InputTextEx() // For InputTextEx()
static bool InputTextFilterCharacter(unsigned int* p_char, ImGuiInputTextFlags flags, ImGuiInputTextCallback callback, void* user_data); static bool InputTextFilterCharacter(unsigned int* p_char, ImGuiInputTextFlags flags, ImGuiInputTextCallback callback, void* user_data, ImGuiInputSource input_source);
static int InputTextCalcTextLenAndLineCount(const char* text_begin, const char** out_text_end); static int InputTextCalcTextLenAndLineCount(const char* text_begin, const char** out_text_end);
static ImVec2 InputTextCalcTextSizeW(const ImWchar* text_begin, const ImWchar* text_end, const ImWchar** remaining = NULL, ImVec2* out_offset = NULL, bool stop_on_new_line = false); static ImVec2 InputTextCalcTextSizeW(const ImWchar* text_begin, const ImWchar* text_end, const ImWchar** remaining = NULL, ImVec2* out_offset = NULL, bool stop_on_new_line = false);
@ -350,17 +350,20 @@ void ImGui::LabelTextV(const char* label, const char* fmt, va_list args)
const ImGuiStyle& style = g.Style; const ImGuiStyle& style = g.Style;
const float w = CalcItemWidth(); const float w = CalcItemWidth();
const char* value_text_begin = &g.TempBuffer[0];
const char* value_text_end = value_text_begin + ImFormatStringV(g.TempBuffer, IM_ARRAYSIZE(g.TempBuffer), fmt, args);
const ImVec2 value_size = CalcTextSize(value_text_begin, value_text_end, false);
const ImVec2 label_size = CalcTextSize(label, NULL, true); const ImVec2 label_size = CalcTextSize(label, NULL, true);
const ImRect value_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(w, label_size.y + style.FramePadding.y * 2));
const ImRect total_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(w + (label_size.x > 0.0f ? style.ItemInnerSpacing.x : 0.0f), style.FramePadding.y * 2) + label_size); const ImVec2 pos = window->DC.CursorPos;
const ImRect value_bb(pos, pos + ImVec2(w, value_size.y + style.FramePadding.y * 2));
const ImRect total_bb(pos, pos + ImVec2(w + (label_size.x > 0.0f ? style.ItemInnerSpacing.x + label_size.x : 0.0f), ImMax(value_size.y, label_size.y) + style.FramePadding.y * 2));
ItemSize(total_bb, style.FramePadding.y); ItemSize(total_bb, style.FramePadding.y);
if (!ItemAdd(total_bb, 0)) if (!ItemAdd(total_bb, 0))
return; return;
// Render // Render
const char* value_text_begin = &g.TempBuffer[0]; RenderTextClipped(value_bb.Min + style.FramePadding, value_bb.Max, value_text_begin, value_text_end, &value_size, ImVec2(0.0f, 0.0f));
const char* value_text_end = value_text_begin + ImFormatStringV(g.TempBuffer, IM_ARRAYSIZE(g.TempBuffer), fmt, args);
RenderTextClipped(value_bb.Min, value_bb.Max, value_text_begin, value_text_end, NULL, ImVec2(0.0f, 0.5f));
if (label_size.x > 0.0f) if (label_size.x > 0.0f)
RenderText(ImVec2(value_bb.Max.x + style.ItemInnerSpacing.x, value_bb.Min.y + style.FramePadding.y), label); RenderText(ImVec2(value_bb.Max.x + style.ItemInnerSpacing.x, value_bb.Min.y + style.FramePadding.y), label);
} }
@ -3771,8 +3774,9 @@ void ImGuiInputTextCallbackData::InsertChars(int pos, const char* new_text, cons
} }
// Return false to discard a character. // Return false to discard a character.
static bool InputTextFilterCharacter(unsigned int* p_char, ImGuiInputTextFlags flags, ImGuiInputTextCallback callback, void* user_data) static bool InputTextFilterCharacter(unsigned int* p_char, ImGuiInputTextFlags flags, ImGuiInputTextCallback callback, void* user_data, ImGuiInputSource input_source)
{ {
IM_ASSERT(input_source == ImGuiInputSource_Keyboard || input_source == ImGuiInputSource_Clipboard);
unsigned int c = *p_char; unsigned int c = *p_char;
// Filter non-printable (NB: isprint is unreliable! see #2467) // Filter non-printable (NB: isprint is unreliable! see #2467)
@ -3785,15 +3789,18 @@ static bool InputTextFilterCharacter(unsigned int* p_char, ImGuiInputTextFlags f
return false; return false;
} }
// We ignore Ascii representation of delete (emitted from Backspace on OSX, see #2578, #2817) if (input_source != ImGuiInputSource_Clipboard)
if (c == 127) {
return false; // We ignore Ascii representation of delete (emitted from Backspace on OSX, see #2578, #2817)
if (c == 127)
return false;
// Filter private Unicode range. GLFW on OSX seems to send private characters for special keys like arrow keys (FIXME) // Filter private Unicode range. GLFW on OSX seems to send private characters for special keys like arrow keys (FIXME)
if (c >= 0xE000 && c <= 0xF8FF) if (c >= 0xE000 && c <= 0xF8FF)
return false; return false;
}
// Filter Unicode ranges we are not handling in this build. // Filter Unicode ranges we are not handling in this build
if (c > IM_UNICODE_CODEPOINT_MAX) if (c > IM_UNICODE_CODEPOINT_MAX)
return false; return false;
@ -4118,7 +4125,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
if (!io.InputQueueCharacters.contains('\t')) if (!io.InputQueueCharacters.contains('\t'))
{ {
unsigned int c = '\t'; // Insert TAB unsigned int c = '\t'; // Insert TAB
if (InputTextFilterCharacter(&c, flags, callback, callback_user_data)) if (InputTextFilterCharacter(&c, flags, callback, callback_user_data, ImGuiInputSource_Keyboard))
state->OnKeyPressed((int)c); state->OnKeyPressed((int)c);
} }
@ -4133,7 +4140,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
unsigned int c = (unsigned int)io.InputQueueCharacters[n]; unsigned int c = (unsigned int)io.InputQueueCharacters[n];
if (c == '\t' && io.KeyShift) if (c == '\t' && io.KeyShift)
continue; continue;
if (InputTextFilterCharacter(&c, flags, callback, callback_user_data)) if (InputTextFilterCharacter(&c, flags, callback, callback_user_data, ImGuiInputSource_Keyboard))
state->OnKeyPressed((int)c); state->OnKeyPressed((int)c);
} }
@ -4197,7 +4204,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
else if (!is_readonly) else if (!is_readonly)
{ {
unsigned int c = '\n'; // Insert new line unsigned int c = '\n'; // Insert new line
if (InputTextFilterCharacter(&c, flags, callback, callback_user_data)) if (InputTextFilterCharacter(&c, flags, callback, callback_user_data, ImGuiInputSource_Keyboard))
state->OnKeyPressed((int)c); state->OnKeyPressed((int)c);
} }
} }
@ -4250,7 +4257,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
s += ImTextCharFromUtf8(&c, s, NULL); s += ImTextCharFromUtf8(&c, s, NULL);
if (c == 0) if (c == 0)
break; break;
if (!InputTextFilterCharacter(&c, flags, callback, callback_user_data)) if (!InputTextFilterCharacter(&c, flags, callback, callback_user_data, ImGuiInputSource_Clipboard))
continue; continue;
clipboard_filtered[clipboard_filtered_len++] = (ImWchar)c; clipboard_filtered[clipboard_filtered_len++] = (ImWchar)c;
} }