Browse Source

Merge branch 'master' into docking (incl merge moved CurrentDpiScale field)

# Conflicts:
#	backends/imgui_impl_osx.mm
#	backends/imgui_impl_win32.cpp
#	imgui.cpp
pull/7462/merge
ocornut 6 months ago
parent
commit
eabe98f6d5
  1. 1
      backends/imgui_impl_allegro5.cpp
  2. 2
      backends/imgui_impl_android.cpp
  3. 1
      backends/imgui_impl_dx10.cpp
  4. 1
      backends/imgui_impl_dx11.cpp
  5. 1
      backends/imgui_impl_dx12.cpp
  6. 1
      backends/imgui_impl_dx9.cpp
  7. 1
      backends/imgui_impl_glfw.cpp
  8. 1
      backends/imgui_impl_glut.cpp
  9. 6
      backends/imgui_impl_metal.mm
  10. 1
      backends/imgui_impl_opengl2.cpp
  11. 1
      backends/imgui_impl_opengl3.cpp
  12. 9
      backends/imgui_impl_osx.mm
  13. 1
      backends/imgui_impl_sdl2.cpp
  14. 1
      backends/imgui_impl_sdl3.cpp
  15. 1
      backends/imgui_impl_sdlrenderer2.cpp
  16. 1
      backends/imgui_impl_sdlrenderer3.cpp
  17. 1
      backends/imgui_impl_vulkan.cpp
  18. 1
      backends/imgui_impl_wgpu.cpp
  19. 12
      backends/imgui_impl_win32.cpp
  20. 24
      docs/CHANGELOG.txt
  21. 34
      docs/FAQ.md
  22. 80
      imgui.cpp
  23. 11
      imgui.h
  24. 5
      imgui_demo.cpp
  25. 2
      imgui_draw.cpp
  26. 10
      imgui_internal.h
  27. 15
      imgui_tables.cpp
  28. 5
      imgui_widgets.cpp

1
backends/imgui_impl_allegro5.cpp

@ -424,6 +424,7 @@ static ImGuiKey ImGui_ImplAllegro5_KeyCodeToImGuiKey(int key_code)
bool ImGui_ImplAllegro5_Init(ALLEGRO_DISPLAY* display) bool ImGui_ImplAllegro5_Init(ALLEGRO_DISPLAY* display)
{ {
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
IMGUI_CHECKVERSION();
IM_ASSERT(io.BackendPlatformUserData == nullptr && "Already initialized a platform backend!"); IM_ASSERT(io.BackendPlatformUserData == nullptr && "Already initialized a platform backend!");
// Setup backend capabilities flags // Setup backend capabilities flags

2
backends/imgui_impl_android.cpp

@ -264,6 +264,8 @@ int32_t ImGui_ImplAndroid_HandleInputEvent(const AInputEvent* input_event)
bool ImGui_ImplAndroid_Init(ANativeWindow* window) bool ImGui_ImplAndroid_Init(ANativeWindow* window)
{ {
IMGUI_CHECKVERSION();
g_Window = window; g_Window = window;
g_Time = 0.0; g_Time = 0.0;

1
backends/imgui_impl_dx10.cpp

@ -540,6 +540,7 @@ void ImGui_ImplDX10_InvalidateDeviceObjects()
bool ImGui_ImplDX10_Init(ID3D10Device* device) bool ImGui_ImplDX10_Init(ID3D10Device* device)
{ {
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
IMGUI_CHECKVERSION();
IM_ASSERT(io.BackendRendererUserData == nullptr && "Already initialized a renderer backend!"); IM_ASSERT(io.BackendRendererUserData == nullptr && "Already initialized a renderer backend!");
// Setup backend capabilities flags // Setup backend capabilities flags

1
backends/imgui_impl_dx11.cpp

@ -552,6 +552,7 @@ void ImGui_ImplDX11_InvalidateDeviceObjects()
bool ImGui_ImplDX11_Init(ID3D11Device* device, ID3D11DeviceContext* device_context) bool ImGui_ImplDX11_Init(ID3D11Device* device, ID3D11DeviceContext* device_context)
{ {
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
IMGUI_CHECKVERSION();
IM_ASSERT(io.BackendRendererUserData == nullptr && "Already initialized a renderer backend!"); IM_ASSERT(io.BackendRendererUserData == nullptr && "Already initialized a renderer backend!");
// Setup backend capabilities flags // Setup backend capabilities flags

1
backends/imgui_impl_dx12.cpp

@ -777,6 +777,7 @@ bool ImGui_ImplDX12_Init(ID3D12Device* device, int num_frames_in_flight, DXGI_FO
D3D12_CPU_DESCRIPTOR_HANDLE font_srv_cpu_desc_handle, D3D12_GPU_DESCRIPTOR_HANDLE font_srv_gpu_desc_handle) D3D12_CPU_DESCRIPTOR_HANDLE font_srv_cpu_desc_handle, D3D12_GPU_DESCRIPTOR_HANDLE font_srv_gpu_desc_handle)
{ {
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
IMGUI_CHECKVERSION();
IM_ASSERT(io.BackendRendererUserData == nullptr && "Already initialized a renderer backend!"); IM_ASSERT(io.BackendRendererUserData == nullptr && "Already initialized a renderer backend!");
// Setup backend capabilities flags // Setup backend capabilities flags

1
backends/imgui_impl_dx9.cpp

@ -298,6 +298,7 @@ void ImGui_ImplDX9_RenderDrawData(ImDrawData* draw_data)
bool ImGui_ImplDX9_Init(IDirect3DDevice9* device) bool ImGui_ImplDX9_Init(IDirect3DDevice9* device)
{ {
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
IMGUI_CHECKVERSION();
IM_ASSERT(io.BackendRendererUserData == nullptr && "Already initialized a renderer backend!"); IM_ASSERT(io.BackendRendererUserData == nullptr && "Already initialized a renderer backend!");
// Setup backend capabilities flags // Setup backend capabilities flags

1
backends/imgui_impl_glfw.cpp

@ -572,6 +572,7 @@ void ImGui_ImplGlfw_SetCallbacksChainForAllWindows(bool chain_for_all_windows)
static bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks, GlfwClientApi client_api) static bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks, GlfwClientApi client_api)
{ {
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
IMGUI_CHECKVERSION();
IM_ASSERT(io.BackendPlatformUserData == nullptr && "Already initialized a platform backend!"); IM_ASSERT(io.BackendPlatformUserData == nullptr && "Already initialized a platform backend!");
//printf("GLFW_VERSION: %d.%d.%d (%d)", GLFW_VERSION_MAJOR, GLFW_VERSION_MINOR, GLFW_VERSION_REVISION, GLFW_VERSION_COMBINED); //printf("GLFW_VERSION: %d.%d.%d (%d)", GLFW_VERSION_MAJOR, GLFW_VERSION_MINOR, GLFW_VERSION_REVISION, GLFW_VERSION_COMBINED);

1
backends/imgui_impl_glut.cpp

@ -167,6 +167,7 @@ static ImGuiKey ImGui_ImplGLUT_KeyToImGuiKey(int key)
bool ImGui_ImplGLUT_Init() bool ImGui_ImplGLUT_Init()
{ {
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
IMGUI_CHECKVERSION();
#ifdef FREEGLUT #ifdef FREEGLUT
io.BackendPlatformName = "imgui_impl_glut (freeglut)"; io.BackendPlatformName = "imgui_impl_glut (freeglut)";

6
backends/imgui_impl_metal.mm

@ -87,7 +87,6 @@ struct ImGui_ImplMetal_Data
ImGui_ImplMetal_Data() { memset(this, 0, sizeof(*this)); } ImGui_ImplMetal_Data() { memset(this, 0, sizeof(*this)); }
}; };
static ImGui_ImplMetal_Data* ImGui_ImplMetal_CreateBackendData() { return IM_NEW(ImGui_ImplMetal_Data)(); }
static ImGui_ImplMetal_Data* ImGui_ImplMetal_GetBackendData() { return ImGui::GetCurrentContext() ? (ImGui_ImplMetal_Data*)ImGui::GetIO().BackendRendererUserData : nullptr; } static ImGui_ImplMetal_Data* ImGui_ImplMetal_GetBackendData() { return ImGui::GetCurrentContext() ? (ImGui_ImplMetal_Data*)ImGui::GetIO().BackendRendererUserData : nullptr; }
static void ImGui_ImplMetal_DestroyBackendData(){ IM_DELETE(ImGui_ImplMetal_GetBackendData()); } static void ImGui_ImplMetal_DestroyBackendData(){ IM_DELETE(ImGui_ImplMetal_GetBackendData()); }
@ -133,8 +132,11 @@ bool ImGui_ImplMetal_CreateDeviceObjects(MTL::Device* device)
bool ImGui_ImplMetal_Init(id<MTLDevice> device) bool ImGui_ImplMetal_Init(id<MTLDevice> device)
{ {
ImGui_ImplMetal_Data* bd = ImGui_ImplMetal_CreateBackendData();
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
IMGUI_CHECKVERSION();
IM_ASSERT(io.BackendRendererUserData == nullptr && "Already initialized a renderer backend!");
ImGui_ImplMetal_Data* bd = IM_NEW(ImGui_ImplMetal_Data)();
io.BackendRendererUserData = (void*)bd; io.BackendRendererUserData = (void*)bd;
io.BackendRendererName = "imgui_impl_metal"; io.BackendRendererName = "imgui_impl_metal";
io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset; // We can honor the ImDrawCmd::VtxOffset field, allowing for large meshes. io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset; // We can honor the ImDrawCmd::VtxOffset field, allowing for large meshes.

1
backends/imgui_impl_opengl2.cpp

@ -89,6 +89,7 @@ static void ImGui_ImplOpenGL2_ShutdownPlatformInterface();
bool ImGui_ImplOpenGL2_Init() bool ImGui_ImplOpenGL2_Init()
{ {
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
IMGUI_CHECKVERSION();
IM_ASSERT(io.BackendRendererUserData == nullptr && "Already initialized a renderer backend!"); IM_ASSERT(io.BackendRendererUserData == nullptr && "Already initialized a renderer backend!");
// Setup backend capabilities flags // Setup backend capabilities flags

1
backends/imgui_impl_opengl3.cpp

@ -281,6 +281,7 @@ struct ImGui_ImplOpenGL3_VtxAttribState
bool ImGui_ImplOpenGL3_Init(const char* glsl_version) bool ImGui_ImplOpenGL3_Init(const char* glsl_version)
{ {
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
IMGUI_CHECKVERSION();
IM_ASSERT(io.BackendRendererUserData == nullptr && "Already initialized a renderer backend!"); IM_ASSERT(io.BackendRendererUserData == nullptr && "Already initialized a renderer backend!");
// Initialize our loader // Initialize our loader

9
backends/imgui_impl_osx.mm

@ -90,7 +90,6 @@ struct ImGui_ImplOSX_Data
ImGui_ImplOSX_Data() { memset(this, 0, sizeof(*this)); } ImGui_ImplOSX_Data() { memset(this, 0, sizeof(*this)); }
}; };
static ImGui_ImplOSX_Data* ImGui_ImplOSX_CreateBackendData() { return IM_NEW(ImGui_ImplOSX_Data)(); }
static ImGui_ImplOSX_Data* ImGui_ImplOSX_GetBackendData() { return (ImGui_ImplOSX_Data*)ImGui::GetIO().BackendPlatformUserData; } static ImGui_ImplOSX_Data* ImGui_ImplOSX_GetBackendData() { return (ImGui_ImplOSX_Data*)ImGui::GetIO().BackendPlatformUserData; }
static void ImGui_ImplOSX_DestroyBackendData() { IM_DELETE(ImGui_ImplOSX_GetBackendData()); } static void ImGui_ImplOSX_DestroyBackendData() { IM_DELETE(ImGui_ImplOSX_GetBackendData()); }
@ -423,15 +422,17 @@ IMGUI_IMPL_API void ImGui_ImplOSX_NewFrame(void* _Nullable view) {
bool ImGui_ImplOSX_Init(NSView* view) bool ImGui_ImplOSX_Init(NSView* view)
{ {
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
ImGui_ImplOSX_Data* bd = ImGui_ImplOSX_CreateBackendData(); IMGUI_CHECKVERSION();
io.BackendPlatformUserData = (void*)bd; IM_ASSERT(io.BackendPlatformUserData == nullptr && "Already initialized a platform backend!");
// Setup backend capabilities flags // Setup backend capabilities flags
ImGui_ImplOSX_Data* bd = IM_NEW(ImGui_ImplOSX_Data)();
io.BackendPlatformUserData = (void*)bd;
io.BackendPlatformName = "imgui_impl_osx";
io.BackendFlags |= ImGuiBackendFlags_HasMouseCursors; // We can honor GetMouseCursor() values (optional) io.BackendFlags |= ImGuiBackendFlags_HasMouseCursors; // We can honor GetMouseCursor() values (optional)
//io.BackendFlags |= ImGuiBackendFlags_HasSetMousePos; // We can honor io.WantSetMousePos requests (optional, rarely used) //io.BackendFlags |= ImGuiBackendFlags_HasSetMousePos; // We can honor io.WantSetMousePos requests (optional, rarely used)
io.BackendFlags |= ImGuiBackendFlags_PlatformHasViewports; // We can create multi-viewports on the Platform side (optional) io.BackendFlags |= ImGuiBackendFlags_PlatformHasViewports; // We can create multi-viewports on the Platform side (optional)
//io.BackendFlags |= ImGuiBackendFlags_HasMouseHoveredViewport; // We can call io.AddMouseViewportEvent() with correct data (optional) //io.BackendFlags |= ImGuiBackendFlags_HasMouseHoveredViewport; // We can call io.AddMouseViewportEvent() with correct data (optional)
io.BackendPlatformName = "imgui_impl_osx";
bd->Observer = [ImGuiObserver new]; bd->Observer = [ImGuiObserver new];
bd->Window = view.window ?: NSApp.orderedWindows.firstObject; bd->Window = view.window ?: NSApp.orderedWindows.firstObject;

1
backends/imgui_impl_sdl2.cpp

@ -449,6 +449,7 @@ bool ImGui_ImplSDL2_ProcessEvent(const SDL_Event* event)
static bool ImGui_ImplSDL2_Init(SDL_Window* window, SDL_Renderer* renderer, void* sdl_gl_context) static bool ImGui_ImplSDL2_Init(SDL_Window* window, SDL_Renderer* renderer, void* sdl_gl_context)
{ {
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
IMGUI_CHECKVERSION();
IM_ASSERT(io.BackendPlatformUserData == nullptr && "Already initialized a platform backend!"); IM_ASSERT(io.BackendPlatformUserData == nullptr && "Already initialized a platform backend!");
// Check and store if we are on a SDL backend that supports global mouse position // Check and store if we are on a SDL backend that supports global mouse position

1
backends/imgui_impl_sdl3.cpp

@ -411,6 +411,7 @@ static void ImGui_ImplSDL3_SetupPlatformHandles(ImGuiViewport* viewport, SDL_Win
static bool ImGui_ImplSDL3_Init(SDL_Window* window, SDL_Renderer* renderer, void* sdl_gl_context) static bool ImGui_ImplSDL3_Init(SDL_Window* window, SDL_Renderer* renderer, void* sdl_gl_context)
{ {
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
IMGUI_CHECKVERSION();
IM_ASSERT(io.BackendPlatformUserData == nullptr && "Already initialized a platform backend!"); IM_ASSERT(io.BackendPlatformUserData == nullptr && "Already initialized a platform backend!");
IM_UNUSED(sdl_gl_context); // Unused in this branch IM_UNUSED(sdl_gl_context); // Unused in this branch

1
backends/imgui_impl_sdlrenderer2.cpp

@ -65,6 +65,7 @@ static ImGui_ImplSDLRenderer2_Data* ImGui_ImplSDLRenderer2_GetBackendData()
bool ImGui_ImplSDLRenderer2_Init(SDL_Renderer* renderer) bool ImGui_ImplSDLRenderer2_Init(SDL_Renderer* renderer)
{ {
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
IMGUI_CHECKVERSION();
IM_ASSERT(io.BackendRendererUserData == nullptr && "Already initialized a renderer backend!"); IM_ASSERT(io.BackendRendererUserData == nullptr && "Already initialized a renderer backend!");
IM_ASSERT(renderer != nullptr && "SDL_Renderer not initialized!"); IM_ASSERT(renderer != nullptr && "SDL_Renderer not initialized!");

1
backends/imgui_impl_sdlrenderer3.cpp

@ -61,6 +61,7 @@ static ImGui_ImplSDLRenderer3_Data* ImGui_ImplSDLRenderer3_GetBackendData()
bool ImGui_ImplSDLRenderer3_Init(SDL_Renderer* renderer) bool ImGui_ImplSDLRenderer3_Init(SDL_Renderer* renderer)
{ {
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
IMGUI_CHECKVERSION();
IM_ASSERT(io.BackendRendererUserData == nullptr && "Already initialized a renderer backend!"); IM_ASSERT(io.BackendRendererUserData == nullptr && "Already initialized a renderer backend!");
IM_ASSERT(renderer != nullptr && "SDL_Renderer not initialized!"); IM_ASSERT(renderer != nullptr && "SDL_Renderer not initialized!");

1
backends/imgui_impl_vulkan.cpp

@ -1123,6 +1123,7 @@ bool ImGui_ImplVulkan_Init(ImGui_ImplVulkan_InitInfo* info)
} }
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
IMGUI_CHECKVERSION();
IM_ASSERT(io.BackendRendererUserData == nullptr && "Already initialized a renderer backend!"); IM_ASSERT(io.BackendRendererUserData == nullptr && "Already initialized a renderer backend!");
// Setup backend capabilities flags // Setup backend capabilities flags

1
backends/imgui_impl_wgpu.cpp

@ -726,6 +726,7 @@ void ImGui_ImplWGPU_InvalidateDeviceObjects()
bool ImGui_ImplWGPU_Init(ImGui_ImplWGPU_InitInfo* init_info) bool ImGui_ImplWGPU_Init(ImGui_ImplWGPU_InitInfo* init_info)
{ {
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
IMGUI_CHECKVERSION();
IM_ASSERT(io.BackendRendererUserData == nullptr && "Already initialized a renderer backend!"); IM_ASSERT(io.BackendRendererUserData == nullptr && "Already initialized a renderer backend!");
// Setup backend capabilities flags // Setup backend capabilities flags

12
backends/imgui_impl_win32.cpp

@ -154,6 +154,7 @@ static void ImGui_ImplWin32_UpdateKeyboardCodePage()
static bool ImGui_ImplWin32_InitEx(void* hwnd, bool platform_has_own_dc) static bool ImGui_ImplWin32_InitEx(void* hwnd, bool platform_has_own_dc)
{ {
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
IMGUI_CHECKVERSION();
IM_ASSERT(io.BackendPlatformUserData == nullptr && "Already initialized a platform backend!"); IM_ASSERT(io.BackendPlatformUserData == nullptr && "Already initialized a platform backend!");
INT64 perf_frequency, perf_counter; INT64 perf_frequency, perf_counter;
@ -653,11 +654,10 @@ static ImGuiMouseSource GetMouseSourceFromMessageExtraInfo()
IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{ {
// Most backends don't have silent checks like this one, but we need it because WndProc are called early in CreateWindow(). // Most backends don't have silent checks like this one, but we need it because WndProc are called early in CreateWindow().
if (ImGui::GetCurrentContext() == nullptr) // We silently allow both context or just only backend data to be nullptr.
return 0;
ImGui_ImplWin32_Data* bd = ImGui_ImplWin32_GetBackendData(); ImGui_ImplWin32_Data* bd = ImGui_ImplWin32_GetBackendData();
IM_ASSERT(bd != nullptr && "Context or backend not initialized! Did you call ImGui_ImplWin32_Init()?"); if (bd == nullptr)
return 0;
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
switch (msg) switch (msg)
@ -686,7 +686,7 @@ IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARA
::ScreenToClient(hwnd, &mouse_pos); ::ScreenToClient(hwnd, &mouse_pos);
io.AddMouseSourceEvent(mouse_source); io.AddMouseSourceEvent(mouse_source);
io.AddMousePosEvent((float)mouse_pos.x, (float)mouse_pos.y); io.AddMousePosEvent((float)mouse_pos.x, (float)mouse_pos.y);
break; return 0;
} }
case WM_MOUSELEAVE: case WM_MOUSELEAVE:
case WM_NCMOUSELEAVE: case WM_NCMOUSELEAVE:
@ -699,7 +699,7 @@ IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARA
bd->MouseTrackedArea = 0; bd->MouseTrackedArea = 0;
io.AddMousePosEvent(-FLT_MAX, -FLT_MAX); io.AddMousePosEvent(-FLT_MAX, -FLT_MAX);
} }
break; return 0;
} }
case WM_LBUTTONDOWN: case WM_LBUTTONDBLCLK: case WM_LBUTTONDOWN: case WM_LBUTTONDBLCLK:
case WM_RBUTTONDOWN: case WM_RBUTTONDBLCLK: case WM_RBUTTONDOWN: case WM_RBUTTONDBLCLK:

24
docs/CHANGELOG.txt

@ -35,6 +35,30 @@ HOW TO UPDATE?
and API updates have been a little more frequent lately. They are documented below and in imgui.cpp and should not affect all users. and API updates have been a little more frequent lately. They are documented below and in imgui.cpp and should not affect all users.
- Please report any issue! - Please report any issue!
-----------------------------------------------------------------------
VERSION 1.90.7 WIP (In Progress)
-----------------------------------------------------------------------
Breaking changes:
Other changes:
- Nav: fixed holding Ctrl or gamepad L1 from not slowing down keyboard/gamepad tweak speed.
Broken during a refactor refactor for 1.89. Holding Shift/R1 to speed up wasn't broken.
- Tables: fixed cell background of fully clipped row overlapping with header. (#7575, #7041) [@prabuinet]
- Backends: all backends + demo now call IMGUI_CHECKVERSION() to verify ABI compatibility between caller
code and compiled version of Dear ImGui. If you get an assert it most likely mean you have a build issue,
read comments near the assert. (#7568)
- Backends: Win32: undo an assert introduced in 1.90.6 which didn't allow WndProc
handler to be called before backend initialization. Because of how ::CreateWindow()
calls in WndProc this is facilitating. (#6275) [@MennoVink]
Docking+Viewports Branch:
- Tables: resizing border hit-rect scales according to current monitor dpi scale.
----------------------------------------------------------------------- -----------------------------------------------------------------------
VERSION 1.90.6 (Released 2024-05-08) VERSION 1.90.6 (Released 2024-05-08)
----------------------------------------------------------------------- -----------------------------------------------------------------------

34
docs/FAQ.md

@ -23,7 +23,7 @@ or view this file with any Markdown viewer.
| [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** |
| **[About the ID Stack system..<br>Why is my widget not reacting when I click on it?<br>How can I have widgets with an empty label?<br>How can I have multiple widgets with the same label?<br>How can I have multiple windows with the same label?](#q-about-the-id-stack-system)** | | **[About the ID Stack system..<br>Why is my widget not reacting when I click on it?<br>Why is the wrong widget reacting when I click on one?<br>How can I have widgets with an empty label?<br>How can I have multiple widgets with the same label?<br>How can I have multiple windows with the same label?](#q-about-the-id-stack-system)** |
| [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)|
| [How can I use maths operators with ImVec2?](#q-how-can-i-use-maths-operators-with-imvec2) | | [How can I use maths operators with ImVec2?](#q-how-can-i-use-maths-operators-with-imvec2) |
| [How can I use my own maths types instead of ImVec2/ImVec4?](#q-how-can-i-use-my-own-maths-types-instead-of-imvec2imvec4) | | [How can I use my own maths types instead of ImVec2/ImVec4?](#q-how-can-i-use-my-own-maths-types-instead-of-imvec2imvec4) |
@ -199,10 +199,42 @@ ctx->RSSetScissorRects(1, &r);
### Q: About the ID Stack system... ### Q: About the ID Stack system...
### Q: Why is my widget not reacting when I click on it? ### Q: Why is my widget not reacting when I click on it?
### Q: Why is the wrong widget reacting when I click on one?
### Q: How can I have widgets with an empty label? ### Q: How can I have widgets with an empty label?
### Q: How can I have multiple widgets with the same label? ### Q: How can I have multiple widgets with the same label?
### Q: How can I have multiple windows with the same label? ### Q: How can I have multiple windows with the same label?
**USING THE SAME LABEL+ID IS THE MOST COMMON USER MISTAKE:**
<table>
<tr>
<td><img src="https://github.com/ocornut/imgui/assets/8225057/76eb9467-74d1-4e95-9f56-be81c6dd029d"></td>
<td>
<pre lang="cpp">
ImGui::Begin("Incorrect!");
ImGui::DragFloat2("My value", &objects[0]->pos.x);
ImGui::DragFloat2("My value", &objects[1]->pos.x);
ImGui::DragFloat2("My value", &objects[2]->pos.x);
ImGui::End();
&nbsp;
ImGui::Begin("Correct!");
ImGui::DragFloat2("My value", &objects[0]->pos.x);
ImGui::DragFloat2("My value##2", &objects[1]->pos.x);
ImGui::DragFloat2("My value##3", &objects[2]->pos.x);
ImGui::End();
&nbsp;
ImGui::Begin("Also Correct!");
for (int n = 0; n < 3; n++)
{
ImGui::PushID(n);
ImGui::DragFloat2("My value", &objects[n]->pos.x);
ImGui::PopID();
}
ImGui::End();
</pre>
</td>
</tr>
</table>
A primer on labels and the ID Stack... A primer on labels and the ID Stack...
Dear ImGui internally needs to uniquely identify UI elements. Dear ImGui internally needs to uniquely identify UI elements.

80
imgui.cpp

@ -1,4 +1,4 @@
// dear imgui, v1.90.6 // dear imgui, v1.90.7 WIP
// (main code and documentation) // (main code and documentation)
// Help: // Help:
@ -1088,7 +1088,6 @@ static const float DOCKING_TRANSPARENT_PAYLOAD_ALPHA = 0.50f; // For u
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
static void SetCurrentWindow(ImGuiWindow* window); static void SetCurrentWindow(ImGuiWindow* window);
static void FindHoveredWindow();
static ImGuiWindow* CreateNewWindow(const char* name, ImGuiWindowFlags flags); static ImGuiWindow* CreateNewWindow(const char* name, ImGuiWindowFlags flags);
static ImVec2 CalcNextScrollFromScrollTargetAndClamp(ImGuiWindow* window); static ImVec2 CalcNextScrollFromScrollTargetAndClamp(ImGuiWindow* window);
@ -4657,6 +4656,9 @@ void ImGui::UpdateHoveredWindowAndCaptureFlags()
{ {
ImGuiContext& g = *GImGui; ImGuiContext& g = *GImGui;
ImGuiIO& io = g.IO; ImGuiIO& io = g.IO;
// FIXME-DPI: This storage was added on 2021/03/31 for test engine, but if we want to multiply WINDOWS_HOVER_PADDING
// by DpiScale, we need to make this window-agnostic anyhow, maybe need storing inside ImGuiWindow.
g.WindowsHoverPadding = ImMax(g.Style.TouchExtraPadding, ImVec2(WINDOWS_HOVER_PADDING, WINDOWS_HOVER_PADDING)); g.WindowsHoverPadding = ImMax(g.Style.TouchExtraPadding, ImVec2(WINDOWS_HOVER_PADDING, WINDOWS_HOVER_PADDING));
// Find the window hovered by mouse: // Find the window hovered by mouse:
@ -4664,7 +4666,7 @@ void ImGui::UpdateHoveredWindowAndCaptureFlags()
// - When moving a window we can skip the search, which also conveniently bypasses the fact that window->WindowRectClipped is lagging as this point of the frame. // - When moving a window we can skip the search, which also conveniently bypasses the fact that window->WindowRectClipped is lagging as this point of the frame.
// - We also support the moved window toggling the NoInputs flag after moving has started in order to be able to detect windows below it, which is useful for e.g. docking mechanisms. // - We also support the moved window toggling the NoInputs flag after moving has started in order to be able to detect windows below it, which is useful for e.g. docking mechanisms.
bool clear_hovered_windows = false; bool clear_hovered_windows = false;
FindHoveredWindow(); FindHoveredWindowEx(g.IO.MousePos, false, &g.HoveredWindow, &g.HoveredWindowUnderMovingWindow);
IM_ASSERT(g.HoveredWindow == NULL || g.HoveredWindow == g.MovingWindow || g.HoveredWindow->Viewport == g.MouseViewport); IM_ASSERT(g.HoveredWindow == NULL || g.HoveredWindow == g.MovingWindow || g.HoveredWindow->Viewport == g.MouseViewport);
// Modal windows prevents mouse from hovering behind them. // Modal windows prevents mouse from hovering behind them.
@ -5465,22 +5467,26 @@ ImVec2 ImGui::CalcTextSize(const char* text, const char* text_end, bool hide_tex
} }
// Find window given position, search front-to-back // Find window given position, search front-to-back
// FIXME: Note that we have an inconsequential lag here: OuterRectClipped is updated in Begin(), so windows moved programmatically // - Typically write output back to g.HoveredWindow and g.HoveredWindowUnderMovingWindow.
// with SetWindowPos() and not SetNextWindowPos() will have that rectangle lagging by a frame at the time FindHoveredWindow() is // - FIXME: Note that we have an inconsequential lag here: OuterRectClipped is updated in Begin(), so windows moved programmatically
// called, aka before the next Begin(). Moving window isn't affected. // with SetWindowPos() and not SetNextWindowPos() will have that rectangle lagging by a frame at the time FindHoveredWindow() is
static void FindHoveredWindow() // called, aka before the next Begin(). Moving window isn't affected.
// - The 'find_first_and_in_any_viewport = true' mode is only used by TestEngine. It is simpler to maintain here.
void ImGui::FindHoveredWindowEx(const ImVec2& pos, bool find_first_and_in_any_viewport, ImGuiWindow** out_hovered_window, ImGuiWindow** out_hovered_window_under_moving_window)
{ {
ImGuiContext& g = *GImGui; ImGuiContext& g = *GImGui;
ImGuiWindow* hovered_window = NULL;
ImGuiWindow* hovered_window_under_moving_window = NULL;
// Special handling for the window being moved: Ignore the mouse viewport check (because it may reset/lose its viewport during the undocking frame) // Special handling for the window being moved: Ignore the mouse viewport check (because it may reset/lose its viewport during the undocking frame)
ImGuiViewportP* moving_window_viewport = g.MovingWindow ? g.MovingWindow->Viewport : NULL; ImGuiViewportP* backup_moving_window_viewport = NULL;
if (g.MovingWindow) if (find_first_and_in_any_viewport == false && g.MovingWindow)
{
backup_moving_window_viewport = g.MovingWindow->Viewport;
g.MovingWindow->Viewport = g.MouseViewport; g.MovingWindow->Viewport = g.MouseViewport;
if (!(g.MovingWindow->Flags & ImGuiWindowFlags_NoMouseInputs))
ImGuiWindow* hovered_window = NULL; hovered_window = g.MovingWindow;
ImGuiWindow* hovered_window_ignoring_moving_window = NULL; }
if (g.MovingWindow && !(g.MovingWindow->Flags & ImGuiWindowFlags_NoMouseInputs))
hovered_window = g.MovingWindow;
ImVec2 padding_regular = g.Style.TouchExtraPadding; ImVec2 padding_regular = g.Style.TouchExtraPadding;
ImVec2 padding_for_resize = g.IO.ConfigWindowsResizeFromEdges ? g.WindowsHoverPadding : padding_regular; ImVec2 padding_for_resize = g.IO.ConfigWindowsResizeFromEdges ? g.WindowsHoverPadding : padding_regular;
@ -5498,7 +5504,7 @@ static void FindHoveredWindow()
// Using the clipped AABB, a child window will typically be clipped by its parent (not always) // Using the clipped AABB, a child window will typically be clipped by its parent (not always)
ImVec2 hit_padding = (window->Flags & (ImGuiWindowFlags_NoResize | ImGuiWindowFlags_AlwaysAutoResize)) ? padding_regular : padding_for_resize; ImVec2 hit_padding = (window->Flags & (ImGuiWindowFlags_NoResize | ImGuiWindowFlags_AlwaysAutoResize)) ? padding_regular : padding_for_resize;
if (!window->OuterRectClipped.ContainsWithPad(g.IO.MousePos, hit_padding)) if (!window->OuterRectClipped.ContainsWithPad(pos, hit_padding))
continue; continue;
// Support for one rectangular hole in any given window // Support for one rectangular hole in any given window
@ -5507,24 +5513,32 @@ static void FindHoveredWindow()
{ {
ImVec2 hole_pos(window->Pos.x + (float)window->HitTestHoleOffset.x, window->Pos.y + (float)window->HitTestHoleOffset.y); ImVec2 hole_pos(window->Pos.x + (float)window->HitTestHoleOffset.x, window->Pos.y + (float)window->HitTestHoleOffset.y);
ImVec2 hole_size((float)window->HitTestHoleSize.x, (float)window->HitTestHoleSize.y); ImVec2 hole_size((float)window->HitTestHoleSize.x, (float)window->HitTestHoleSize.y);
if (ImRect(hole_pos, hole_pos + hole_size).Contains(g.IO.MousePos)) if (ImRect(hole_pos, hole_pos + hole_size).Contains(pos))
continue; continue;
} }
if (hovered_window == NULL) if (find_first_and_in_any_viewport)
{
hovered_window = window; hovered_window = window;
IM_MSVC_WARNING_SUPPRESS(28182); // [Static Analyzer] Dereferencing NULL pointer.
if (hovered_window_ignoring_moving_window == NULL && (!g.MovingWindow || window->RootWindowDockTree != g.MovingWindow->RootWindowDockTree))
hovered_window_ignoring_moving_window = window;
if (hovered_window && hovered_window_ignoring_moving_window)
break; break;
}
else
{
if (hovered_window == NULL)
hovered_window = window;
IM_MSVC_WARNING_SUPPRESS(28182); // [Static Analyzer] Dereferencing NULL pointer.
if (hovered_window_under_moving_window == NULL && (!g.MovingWindow || window->RootWindowDockTree != g.MovingWindow->RootWindowDockTree))
hovered_window_under_moving_window = window;
if (hovered_window && hovered_window_under_moving_window)
break;
}
} }
g.HoveredWindow = hovered_window; *out_hovered_window = hovered_window;
g.HoveredWindowUnderMovingWindow = hovered_window_ignoring_moving_window; if (out_hovered_window_under_moving_window != NULL)
*out_hovered_window_under_moving_window = hovered_window_under_moving_window;
if (g.MovingWindow) if (find_first_and_in_any_viewport == false && g.MovingWindow)
g.MovingWindow->Viewport = moving_window_viewport; g.MovingWindow->Viewport = backup_moving_window_viewport;
} }
bool ImGui::IsItemActive() bool ImGui::IsItemActive()
@ -10271,8 +10285,8 @@ bool ImGui::Shortcut(ImGuiKeyChord key_chord, ImGuiID owner_id, ImGuiInputFlags
// [SECTION] ERROR CHECKING // [SECTION] ERROR CHECKING
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Helper function to verify ABI compatibility between caller code and compiled version of Dear ImGui. // Verify ABI compatibility between caller code and compiled version of Dear ImGui. This helps detects some build issues.
// This is called by IMGUI_CHECKVERSION(). // Called by IMGUI_CHECKVERSION().
// Verify that the type sizes are matching between the calling file's compilation unit and imgui.cpp's compilation unit // Verify that the type sizes are matching between the calling file's compilation unit and imgui.cpp's compilation unit
// If this triggers you have mismatched headers and compiled code versions. // If this triggers you have mismatched headers and compiled code versions.
// - It could be because of a build issue (using new headers with old compiled code) // - It could be because of a build issue (using new headers with old compiled code)
@ -10285,12 +10299,12 @@ bool ImGui::DebugCheckVersionAndDataLayout(const char* version, size_t sz_io, si
{ {
bool error = false; bool error = false;
if (strcmp(version, IMGUI_VERSION) != 0) { error = true; IM_ASSERT(strcmp(version, IMGUI_VERSION) == 0 && "Mismatched version string!"); } if (strcmp(version, IMGUI_VERSION) != 0) { error = true; IM_ASSERT(strcmp(version, IMGUI_VERSION) == 0 && "Mismatched version string!"); }
if (sz_io != sizeof(ImGuiIO)) { error = true; IM_ASSERT(sz_io == sizeof(ImGuiIO) && "Mismatched struct layout!"); } if (sz_io != sizeof(ImGuiIO)) { error = true; IM_ASSERT(sz_io == sizeof(ImGuiIO) && "Mismatched struct layout!"); }
if (sz_style != sizeof(ImGuiStyle)) { error = true; IM_ASSERT(sz_style == sizeof(ImGuiStyle) && "Mismatched struct layout!"); } if (sz_style != sizeof(ImGuiStyle)) { error = true; IM_ASSERT(sz_style == sizeof(ImGuiStyle) && "Mismatched struct layout!"); }
if (sz_vec2 != sizeof(ImVec2)) { error = true; IM_ASSERT(sz_vec2 == sizeof(ImVec2) && "Mismatched struct layout!"); } if (sz_vec2 != sizeof(ImVec2)) { error = true; IM_ASSERT(sz_vec2 == sizeof(ImVec2) && "Mismatched struct layout!"); }
if (sz_vec4 != sizeof(ImVec4)) { error = true; IM_ASSERT(sz_vec4 == sizeof(ImVec4) && "Mismatched struct layout!"); } if (sz_vec4 != sizeof(ImVec4)) { error = true; IM_ASSERT(sz_vec4 == sizeof(ImVec4) && "Mismatched struct layout!"); }
if (sz_vert != sizeof(ImDrawVert)) { error = true; IM_ASSERT(sz_vert == sizeof(ImDrawVert) && "Mismatched struct layout!"); } if (sz_vert != sizeof(ImDrawVert)) { error = true; IM_ASSERT(sz_vert == sizeof(ImDrawVert) && "Mismatched struct layout!"); }
if (sz_idx != sizeof(ImDrawIdx)) { error = true; IM_ASSERT(sz_idx == sizeof(ImDrawIdx) && "Mismatched struct layout!"); } if (sz_idx != sizeof(ImDrawIdx)) { error = true; IM_ASSERT(sz_idx == sizeof(ImDrawIdx) && "Mismatched struct layout!"); }
return !error; return !error;
} }

11
imgui.h

@ -1,4 +1,4 @@
// dear imgui, v1.90.6 WIP // dear imgui, v1.90.7 WIP
// (headers) // (headers)
// Help: // Help:
@ -27,8 +27,8 @@
// Library Version // Library Version
// (Integer encoded as XYYZZ for use in #if preprocessor conditionals, e.g. '#if IMGUI_VERSION_NUM >= 12345') // (Integer encoded as XYYZZ for use in #if preprocessor conditionals, e.g. '#if IMGUI_VERSION_NUM >= 12345')
#define IMGUI_VERSION "1.90.6" #define IMGUI_VERSION "1.90.7 WIP"
#define IMGUI_VERSION_NUM 19060 #define IMGUI_VERSION_NUM 19062
#define IMGUI_HAS_TABLE #define IMGUI_HAS_TABLE
#define IMGUI_HAS_VIEWPORT // Viewport WIP branch #define IMGUI_HAS_VIEWPORT // Viewport WIP branch
#define IMGUI_HAS_DOCK // Docking WIP branch #define IMGUI_HAS_DOCK // Docking WIP branch
@ -92,6 +92,8 @@ Index of this file:
#endif #endif
#define IM_ARRAYSIZE(_ARR) ((int)(sizeof(_ARR) / sizeof(*(_ARR)))) // Size of a static C-style array. Don't use on pointers! #define IM_ARRAYSIZE(_ARR) ((int)(sizeof(_ARR) / sizeof(*(_ARR)))) // Size of a static C-style array. Don't use on pointers!
#define IM_UNUSED(_VAR) ((void)(_VAR)) // Used to silence "unused variable warnings". Often useful as asserts may be stripped out from final builds. #define IM_UNUSED(_VAR) ((void)(_VAR)) // Used to silence "unused variable warnings". Often useful as asserts may be stripped out from final builds.
// Check that version and structures layouts are matching between compiled imgui code and caller. Read comments above DebugCheckVersionAndDataLayout() for details.
#define IMGUI_CHECKVERSION() ImGui::DebugCheckVersionAndDataLayout(IMGUI_VERSION, sizeof(ImGuiIO), sizeof(ImGuiStyle), sizeof(ImVec2), sizeof(ImVec4), sizeof(ImDrawVert), sizeof(ImDrawIdx)) #define IMGUI_CHECKVERSION() ImGui::DebugCheckVersionAndDataLayout(IMGUI_VERSION, sizeof(ImGuiIO), sizeof(ImGuiStyle), sizeof(ImVec2), sizeof(ImVec4), sizeof(ImDrawVert), sizeof(ImDrawIdx))
// Helper Macros - IM_FMTARGS, IM_FMTLIST: Apply printf-style warnings to our formatting functions. // Helper Macros - IM_FMTARGS, IM_FMTLIST: Apply printf-style warnings to our formatting functions.
@ -706,7 +708,8 @@ namespace ImGui
// Tooltips // Tooltips
// - Tooltips are windows following the mouse. They do not take focus away. // - Tooltips are windows following the mouse. They do not take focus away.
// - A tooltip window can contain items of any types. SetTooltip() is a shortcut for the 'if (BeginTooltip()) { Text(...); EndTooltip(); }' idiom. // - A tooltip window can contain items of any types.
// - SetTooltip() is more or less a shortcut for the 'if (BeginTooltip()) { Text(...); EndTooltip(); }' idiom (with a subtlety that it discard any previously submitted tooltip)
IMGUI_API bool BeginTooltip(); // begin/append a tooltip window. IMGUI_API bool BeginTooltip(); // begin/append a tooltip window.
IMGUI_API void EndTooltip(); // only call EndTooltip() if BeginTooltip()/BeginItemTooltip() returns true! IMGUI_API void EndTooltip(); // only call EndTooltip() if BeginTooltip()/BeginItemTooltip() returns true!
IMGUI_API void SetTooltip(const char* fmt, ...) IM_FMTARGS(1); // set a text-only tooltip. Often used after a ImGui::IsItemHovered() check. Override any previous call to SetTooltip(). IMGUI_API void SetTooltip(const char* fmt, ...) IM_FMTARGS(1); // set a text-only tooltip. Often used after a ImGui::IsItemHovered() check. Override any previous call to SetTooltip().

5
imgui_demo.cpp

@ -1,4 +1,4 @@
// dear imgui, v1.90.6 // dear imgui, v1.90.7 WIP
// (demo code) // (demo code)
// Help: // Help:
@ -278,6 +278,9 @@ void ImGui::ShowDemoWindow(bool* p_open)
// Most functions would normally just assert/crash if the context is missing. // Most functions would normally just assert/crash if the context is missing.
IM_ASSERT(ImGui::GetCurrentContext() != NULL && "Missing Dear ImGui context. Refer to examples app!"); IM_ASSERT(ImGui::GetCurrentContext() != NULL && "Missing Dear ImGui context. Refer to examples app!");
// Verify ABI compatibility between caller code and compiled version of Dear ImGui. This helps detects some build issues.
IMGUI_CHECKVERSION();
// Examples Apps (accessible from the "Examples" menu) // Examples Apps (accessible from the "Examples" menu)
static bool show_app_main_menu_bar = false; static bool show_app_main_menu_bar = false;
static bool show_app_console = false; static bool show_app_console = false;

2
imgui_draw.cpp

@ -1,4 +1,4 @@
// dear imgui, v1.90.6 // dear imgui, v1.90.7 WIP
// (drawing and font code) // (drawing and font code)
/* /*

10
imgui_internal.h

@ -1,4 +1,4 @@
// dear imgui, v1.90.6 // dear imgui, v1.90.7 WIP
// (internal structures/api) // (internal structures/api)
// You may use this file to debug, understand or extend Dear ImGui features but we don't provide any guarantee of forward compatibility. // You may use this file to debug, understand or extend Dear ImGui features but we don't provide any guarantee of forward compatibility.
@ -2135,6 +2135,7 @@ struct ImGuiContext
ImFont* Font; // (Shortcut) == FontStack.empty() ? IO.Font : FontStack.back() ImFont* Font; // (Shortcut) == FontStack.empty() ? IO.Font : FontStack.back()
float FontSize; // (Shortcut) == FontBaseSize * g.CurrentWindow->FontWindowScale == window->FontSize(). Text height for current window. float FontSize; // (Shortcut) == FontBaseSize * g.CurrentWindow->FontWindowScale == window->FontSize(). Text height for current window.
float FontBaseSize; // (Shortcut) == IO.FontGlobalScale * Font->Scale * Font->FontSize. Base text height. float FontBaseSize; // (Shortcut) == IO.FontGlobalScale * Font->Scale * Font->FontSize. Base text height.
float CurrentDpiScale; // Current window/viewport DpiScale == CurrentViewport->DpiScale
ImDrawListSharedData DrawListSharedData; ImDrawListSharedData DrawListSharedData;
double Time; double Time;
int FrameCount; int FrameCount;
@ -2161,7 +2162,7 @@ struct ImGuiContext
ImVector<ImGuiWindowStackData> CurrentWindowStack; ImVector<ImGuiWindowStackData> CurrentWindowStack;
ImGuiStorage WindowsById; // Map window's ImGuiID to ImGuiWindow* ImGuiStorage WindowsById; // Map window's ImGuiID to ImGuiWindow*
int WindowsActiveCount; // Number of unique windows submitted by frame int WindowsActiveCount; // Number of unique windows submitted by frame
ImVec2 WindowsHoverPadding; // Padding around resizable windows for which hovering on counts as hovering the window == ImMax(style.TouchExtraPadding, WINDOWS_HOVER_PADDING) ImVec2 WindowsHoverPadding; // Padding around resizable windows for which hovering on counts as hovering the window == ImMax(style.TouchExtraPadding, WINDOWS_HOVER_PADDING).
ImGuiID DebugBreakInWindow; // Set to break in Begin() call. ImGuiID DebugBreakInWindow; // Set to break in Begin() call.
ImGuiWindow* CurrentWindow; // Window being drawn into ImGuiWindow* CurrentWindow; // Window being drawn into
ImGuiWindow* HoveredWindow; // Window the mouse is hovering. Will typically catch mouse inputs. ImGuiWindow* HoveredWindow; // Window the mouse is hovering. Will typically catch mouse inputs.
@ -2244,7 +2245,6 @@ struct ImGuiContext
// Viewports // Viewports
ImVector<ImGuiViewportP*> Viewports; // Active viewports (always 1+, and generally 1 unless multi-viewports are enabled). Each viewports hold their copy of ImDrawData. ImVector<ImGuiViewportP*> Viewports; // Active viewports (always 1+, and generally 1 unless multi-viewports are enabled). Each viewports hold their copy of ImDrawData.
float CurrentDpiScale; // == CurrentViewport->DpiScale
ImGuiViewportP* CurrentViewport; // We track changes of viewport (happening in Begin) so we can call Platform_OnChangedViewport() ImGuiViewportP* CurrentViewport; // We track changes of viewport (happening in Begin) so we can call Platform_OnChangedViewport()
ImGuiViewportP* MouseViewport; ImGuiViewportP* MouseViewport;
ImGuiViewportP* MouseLastHoveredViewport; // Last known viewport that was hovered by mouse (even if we are not hovering any viewport any more) + honoring the _NoInputs flag. ImGuiViewportP* MouseLastHoveredViewport; // Last known viewport that was hovered by mouse (even if we are not hovering any viewport any more) + honoring the _NoInputs flag.
@ -2480,7 +2480,7 @@ struct ImGuiContext
ConfigFlagsCurrFrame = ConfigFlagsLastFrame = ImGuiConfigFlags_None; ConfigFlagsCurrFrame = ConfigFlagsLastFrame = ImGuiConfigFlags_None;
FontAtlasOwnedByContext = shared_font_atlas ? false : true; FontAtlasOwnedByContext = shared_font_atlas ? false : true;
Font = NULL; Font = NULL;
FontSize = FontBaseSize = 0.0f; FontSize = FontBaseSize = CurrentDpiScale = 0.0f;
IO.Fonts = shared_font_atlas ? shared_font_atlas : IM_NEW(ImFontAtlas)(); IO.Fonts = shared_font_atlas ? shared_font_atlas : IM_NEW(ImFontAtlas)();
Time = 0.0f; Time = 0.0f;
FrameCount = 0; FrameCount = 0;
@ -2540,7 +2540,6 @@ struct ImGuiContext
CurrentItemFlags = ImGuiItemFlags_None; CurrentItemFlags = ImGuiItemFlags_None;
DebugShowGroupRects = false; DebugShowGroupRects = false;
CurrentDpiScale = 0.0f;
CurrentViewport = NULL; CurrentViewport = NULL;
MouseViewport = MouseLastHoveredViewport = NULL; MouseViewport = MouseLastHoveredViewport = NULL;
PlatformLastFocusedViewportId = 0; PlatformLastFocusedViewportId = 0;
@ -3310,6 +3309,7 @@ namespace ImGui
// NewFrame // NewFrame
IMGUI_API void UpdateInputEvents(bool trickle_fast_inputs); IMGUI_API void UpdateInputEvents(bool trickle_fast_inputs);
IMGUI_API void UpdateHoveredWindowAndCaptureFlags(); IMGUI_API void UpdateHoveredWindowAndCaptureFlags();
IMGUI_API void FindHoveredWindowEx(const ImVec2& pos, bool find_first_and_in_any_viewport, ImGuiWindow** out_hovered_window, ImGuiWindow** out_hovered_window_under_moving_window);
IMGUI_API void StartMouseMovingWindow(ImGuiWindow* window); IMGUI_API void StartMouseMovingWindow(ImGuiWindow* window);
IMGUI_API void StartMouseMovingWindowOrNode(ImGuiWindow* window, ImGuiDockNode* node, bool undock); IMGUI_API void StartMouseMovingWindowOrNode(ImGuiWindow* window, ImGuiDockNode* node, bool undock);
IMGUI_API void UpdateMouseMovingWindowNewFrame(); IMGUI_API void UpdateMouseMovingWindowNewFrame();

15
imgui_tables.cpp

@ -1,4 +1,4 @@
// dear imgui, v1.90.6 // dear imgui, v1.90.7 WIP
// (tables and columns code) // (tables and columns code)
/* /*
@ -1256,7 +1256,7 @@ void ImGui::TableUpdateBorders(ImGuiTable* table)
// really problematic (whereas the actual visual will be displayed in EndTable() and using the current frame height). // really problematic (whereas the actual visual will be displayed in EndTable() and using the current frame height).
// Actual columns highlight/render will be performed in EndTable() and not be affected. // Actual columns highlight/render will be performed in EndTable() and not be affected.
ImGuiTableInstanceData* table_instance = TableGetInstanceData(table, table->InstanceCurrent); ImGuiTableInstanceData* table_instance = TableGetInstanceData(table, table->InstanceCurrent);
const float hit_half_width = TABLE_RESIZE_SEPARATOR_HALF_THICKNESS; const float hit_half_width = ImTrunc(TABLE_RESIZE_SEPARATOR_HALF_THICKNESS * g.CurrentDpiScale);
const float hit_y1 = (table->FreezeRowsCount >= 1 ? table->OuterRect.Min.y : table->WorkRect.Min.y) + table->AngledHeadersHeight; const float hit_y1 = (table->FreezeRowsCount >= 1 ? table->OuterRect.Min.y : table->WorkRect.Min.y) + table->AngledHeadersHeight;
const float hit_y2_body = ImMax(table->OuterRect.Max.y, hit_y1 + table_instance->LastOuterHeight - table->AngledHeadersHeight); const float hit_y2_body = ImMax(table->OuterRect.Max.y, hit_y1 + table_instance->LastOuterHeight - table->AngledHeadersHeight);
const float hit_y2_head = hit_y1 + table_instance->LastTopHeadersRowHeight; const float hit_y2_head = hit_y1 + table_instance->LastTopHeadersRowHeight;
@ -1433,7 +1433,7 @@ void ImGui::EndTable()
if (table->ResizedColumn != -1 && table->InstanceCurrent == table->InstanceInteracted) if (table->ResizedColumn != -1 && table->InstanceCurrent == table->InstanceInteracted)
{ {
ImGuiTableColumn* column = &table->Columns[table->ResizedColumn]; ImGuiTableColumn* column = &table->Columns[table->ResizedColumn];
const float new_x2 = (g.IO.MousePos.x - g.ActiveIdClickOffset.x + TABLE_RESIZE_SEPARATOR_HALF_THICKNESS); const float new_x2 = (g.IO.MousePos.x - g.ActiveIdClickOffset.x + ImTrunc(TABLE_RESIZE_SEPARATOR_HALF_THICKNESS * g.CurrentDpiScale));
const float new_width = ImTrunc(new_x2 - column->MinX - table->CellSpacingX1 - table->CellPaddingX * 2.0f); const float new_width = ImTrunc(new_x2 - column->MinX - table->CellSpacingX1 - table->CellPaddingX * 2.0f);
table->ResizedColumnNextWidth = new_width; table->ResizedColumnNextWidth = new_width;
} }
@ -1963,7 +1963,8 @@ void ImGui::TableEndRow(ImGuiTable* table)
cell_bg_rect.ClipWith(table->BgClipRect); cell_bg_rect.ClipWith(table->BgClipRect);
cell_bg_rect.Min.x = ImMax(cell_bg_rect.Min.x, column->ClipRect.Min.x); // So that first column after frozen one gets clipped when scrolling cell_bg_rect.Min.x = ImMax(cell_bg_rect.Min.x, column->ClipRect.Min.x); // So that first column after frozen one gets clipped when scrolling
cell_bg_rect.Max.x = ImMin(cell_bg_rect.Max.x, column->MaxX); cell_bg_rect.Max.x = ImMin(cell_bg_rect.Max.x, column->MaxX);
window->DrawList->AddRectFilled(cell_bg_rect.Min, cell_bg_rect.Max, cell_data->BgColor); if (cell_bg_rect.Min.y < cell_bg_rect.Max.y)
window->DrawList->AddRectFilled(cell_bg_rect.Min, cell_bg_rect.Max, cell_data->BgColor);
} }
} }
@ -4040,7 +4041,7 @@ float ImGui::GetColumnNormFromOffset(const ImGuiOldColumns* columns, float offse
return offset / (columns->OffMaxX - columns->OffMinX); return offset / (columns->OffMaxX - columns->OffMinX);
} }
static const float COLUMNS_HIT_RECT_HALF_WIDTH = 4.0f; static const float COLUMNS_HIT_RECT_HALF_THICKNESS = 4.0f;
static float GetDraggedColumnOffset(ImGuiOldColumns* columns, int column_index) static float GetDraggedColumnOffset(ImGuiOldColumns* columns, int column_index)
{ {
@ -4051,7 +4052,7 @@ static float GetDraggedColumnOffset(ImGuiOldColumns* columns, int column_index)
IM_ASSERT(column_index > 0); // We are not supposed to drag column 0. IM_ASSERT(column_index > 0); // We are not supposed to drag column 0.
IM_ASSERT(g.ActiveId == columns->ID + ImGuiID(column_index)); IM_ASSERT(g.ActiveId == columns->ID + ImGuiID(column_index));
float x = g.IO.MousePos.x - g.ActiveIdClickOffset.x + COLUMNS_HIT_RECT_HALF_WIDTH - window->Pos.x; float x = g.IO.MousePos.x - g.ActiveIdClickOffset.x + ImTrunc(COLUMNS_HIT_RECT_HALF_THICKNESS * g.CurrentDpiScale) - window->Pos.x;
x = ImMax(x, ImGui::GetColumnOffset(column_index - 1) + g.Style.ColumnsMinSpacing); x = ImMax(x, ImGui::GetColumnOffset(column_index - 1) + g.Style.ColumnsMinSpacing);
if ((columns->Flags & ImGuiOldColumnFlags_NoPreserveWidths)) if ((columns->Flags & ImGuiOldColumnFlags_NoPreserveWidths))
x = ImMin(x, ImGui::GetColumnOffset(column_index + 1) - g.Style.ColumnsMinSpacing); x = ImMin(x, ImGui::GetColumnOffset(column_index + 1) - g.Style.ColumnsMinSpacing);
@ -4366,7 +4367,7 @@ void ImGui::EndColumns()
ImGuiOldColumnData* column = &columns->Columns[n]; ImGuiOldColumnData* column = &columns->Columns[n];
float x = window->Pos.x + GetColumnOffset(n); float x = window->Pos.x + GetColumnOffset(n);
const ImGuiID column_id = columns->ID + ImGuiID(n); const ImGuiID column_id = columns->ID + ImGuiID(n);
const float column_hit_hw = COLUMNS_HIT_RECT_HALF_WIDTH; const float column_hit_hw = ImTrunc(COLUMNS_HIT_RECT_HALF_THICKNESS * g.CurrentDpiScale);
const ImRect column_hit_rect(ImVec2(x - column_hit_hw, y1), ImVec2(x + column_hit_hw, y2)); const ImRect column_hit_rect(ImVec2(x - column_hit_hw, y1), ImVec2(x + column_hit_hw, y2));
if (!ItemAdd(column_hit_rect, column_id, NULL, ImGuiItemFlags_NoNav)) if (!ItemAdd(column_hit_rect, column_id, NULL, ImGuiItemFlags_NoNav))
continue; continue;

5
imgui_widgets.cpp

@ -1,4 +1,4 @@
// dear imgui, v1.90.6 // dear imgui, v1.90.7 WIP
// (widgets code) // (widgets code)
/* /*
@ -2315,7 +2315,7 @@ bool ImGui::DragBehaviorT(ImGuiDataType data_type, TYPE* v, float v_speed, const
const int decimal_precision = is_floating_point ? ImParseFormatPrecision(format, 3) : 0; const int decimal_precision = is_floating_point ? ImParseFormatPrecision(format, 3) : 0;
const bool tweak_slow = IsKeyDown((g.NavInputSource == ImGuiInputSource_Gamepad) ? ImGuiKey_NavGamepadTweakSlow : ImGuiKey_NavKeyboardTweakSlow); const bool tweak_slow = IsKeyDown((g.NavInputSource == ImGuiInputSource_Gamepad) ? ImGuiKey_NavGamepadTweakSlow : ImGuiKey_NavKeyboardTweakSlow);
const bool tweak_fast = IsKeyDown((g.NavInputSource == ImGuiInputSource_Gamepad) ? ImGuiKey_NavGamepadTweakFast : ImGuiKey_NavKeyboardTweakFast); const bool tweak_fast = IsKeyDown((g.NavInputSource == ImGuiInputSource_Gamepad) ? ImGuiKey_NavGamepadTweakFast : ImGuiKey_NavKeyboardTweakFast);
const float tweak_factor = tweak_slow ? 1.0f / 1.0f : tweak_fast ? 10.0f : 1.0f; const float tweak_factor = tweak_slow ? 1.0f / 10.0f : tweak_fast ? 10.0f : 1.0f;
adjust_delta = GetNavTweakPressedAmount(axis) * tweak_factor; adjust_delta = GetNavTweakPressedAmount(axis) * tweak_factor;
v_speed = ImMax(v_speed, GetMinimumStepAtDecimalPrecision(decimal_precision)); v_speed = ImMax(v_speed, GetMinimumStepAtDecimalPrecision(decimal_precision));
} }
@ -4512,6 +4512,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
const bool is_cancel = Shortcut(ImGuiKey_Escape, id, f_repeat) || (nav_gamepad_active && Shortcut(ImGuiKey_NavGamepadCancel, id, f_repeat)); const bool is_cancel = Shortcut(ImGuiKey_Escape, id, f_repeat) || (nav_gamepad_active && Shortcut(ImGuiKey_NavGamepadCancel, id, f_repeat));
// FIXME: Should use more Shortcut() and reduce IsKeyPressed()+SetKeyOwner(), but requires modifiers combination to be taken account of. // FIXME: Should use more Shortcut() and reduce IsKeyPressed()+SetKeyOwner(), but requires modifiers combination to be taken account of.
// FIXME-OSX: Missing support for Alt(option)+Right/Left = go to end of line, or next line if already in end of line.
if (IsKeyPressed(ImGuiKey_LeftArrow)) { state->OnKeyPressed((is_startend_key_down ? STB_TEXTEDIT_K_LINESTART : is_wordmove_key_down ? STB_TEXTEDIT_K_WORDLEFT : STB_TEXTEDIT_K_LEFT) | k_mask); } if (IsKeyPressed(ImGuiKey_LeftArrow)) { state->OnKeyPressed((is_startend_key_down ? STB_TEXTEDIT_K_LINESTART : is_wordmove_key_down ? STB_TEXTEDIT_K_WORDLEFT : STB_TEXTEDIT_K_LEFT) | k_mask); }
else if (IsKeyPressed(ImGuiKey_RightArrow)) { state->OnKeyPressed((is_startend_key_down ? STB_TEXTEDIT_K_LINEEND : is_wordmove_key_down ? STB_TEXTEDIT_K_WORDRIGHT : STB_TEXTEDIT_K_RIGHT) | k_mask); } else if (IsKeyPressed(ImGuiKey_RightArrow)) { state->OnKeyPressed((is_startend_key_down ? STB_TEXTEDIT_K_LINEEND : is_wordmove_key_down ? STB_TEXTEDIT_K_WORDRIGHT : STB_TEXTEDIT_K_RIGHT) | k_mask); }
else if (IsKeyPressed(ImGuiKey_UpArrow) && is_multiline) { if (io.KeyCtrl) SetScrollY(draw_window, ImMax(draw_window->Scroll.y - g.FontSize, 0.0f)); else state->OnKeyPressed((is_startend_key_down ? STB_TEXTEDIT_K_TEXTSTART : STB_TEXTEDIT_K_UP) | k_mask); } else if (IsKeyPressed(ImGuiKey_UpArrow) && is_multiline) { if (io.KeyCtrl) SetScrollY(draw_window, ImMax(draw_window->Scroll.y - g.FontSize, 0.0f)); else state->OnKeyPressed((is_startend_key_down ? STB_TEXTEDIT_K_TEXTSTART : STB_TEXTEDIT_K_UP) | k_mask); }

Loading…
Cancel
Save