mirror of
				https://github.com/ocornut/imgui.git
				synced 2025-10-26 12:27:30 +00:00 
			
		
		
		
	Merge branch 'master' into docking
# Conflicts: # backends/imgui_impl_opengl3.cpp # examples/imgui_examples.sln # imgui.cpp # imgui.h
This commit is contained in:
		
							
								
								
									
										8
									
								
								.github/issue_template.md
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										8
									
								
								.github/issue_template.md
									
									
									
									
										vendored
									
									
								
							| @@ -1,12 +1,12 @@ | |||||||
| (Click "Preview" above ^ to turn URL into clickable links) | (Click "Preview" above ^ to turn URL into clickable links) | ||||||
|  |  | ||||||
| 1. PLEASE CAREFULLY READ: [FAQ](https://github.com/ocornut/imgui/blob/master/docs/FAQ.md) | 1. FOR FIRST-TIME USERS ISSUES COMPILING/LINKING/RUNNING or LOADING FONTS,  please use [GitHub Discussions](https://github.com/ocornut/imgui/discussions). | ||||||
|  |  | ||||||
| 2. PLEASE CAREFULLY READ: [Issue Submitting Guidelines](https://github.com/ocornut/imgui/issues/2261) | 2. PLEASE CAREFULLY READ: [FAQ](https://github.com/ocornut/imgui/blob/master/docs/FAQ.md) | ||||||
|  |  | ||||||
| 3. FOR FIRST-TIME USERS ISSUES COMPILING/LINKING/RUNNING/LOADING FONTS,  please use [GitHub Discussions](https://github.com/ocornut/imgui/discussions). | 3. PLEASE CAREFULLY READ: [Issue Submitting Guidelines](https://github.com/ocornut/imgui/issues/2261) | ||||||
|  |  | ||||||
| 4. PLEASE MAKE SURE that you have: read the FAQ; explored the contents of `ShowDemoWindow()` including the Examples menu; searched among Issues; used your IDE to search for keywords in all sources and text files; and read the link provided in (1) (2). | 4. PLEASE MAKE SURE that you have: read the FAQ; explored the contents of `ShowDemoWindow()` including the Examples menu; searched among Issues; used your IDE to search for keywords in all sources and text files; and read the links above. | ||||||
|  |  | ||||||
| 5. Be mindful that messages are being sent to the e-mail box of "Watching" users. Try to proof-read your messages before sending them. Edits are not seen by those users. | 5. Be mindful that messages are being sent to the e-mail box of "Watching" users. Try to proof-read your messages before sending them. Edits are not seen by those users. | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										6
									
								
								.github/pull_request_template.md
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										6
									
								
								.github/pull_request_template.md
									
									
									
									
										vendored
									
									
								
							| @@ -1,6 +1,6 @@ | |||||||
| (Click "Preview" to turn any http URL into a clickable link) | (Click "Preview" to turn any http URL into a clickable link) | ||||||
|  |  | ||||||
| PLEASE CAREFULLY READ: | 1. PLEASE CAREFULLY READ: [Issue Submitting Guidelines](https://github.com/ocornut/imgui/issues/2261) | ||||||
| https://github.com/ocornut/imgui/issues/2261 |  | ||||||
|  | 2. Clear this template before submitting your PR. | ||||||
|  |  | ||||||
| (Clear this template before submitting your PR) |  | ||||||
|   | |||||||
							
								
								
									
										12
									
								
								.github/workflows/build.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										12
									
								
								.github/workflows/build.yml
									
									
									
									
										vendored
									
									
								
							| @@ -226,6 +226,18 @@ jobs: | |||||||
|         make -C examples/example_null clean |         make -C examples/example_null clean | ||||||
|         CXXFLAGS="$CXXFLAGS -m64 -Werror" CXX=clang++ make -C examples/example_null WITH_EXTRA_WARNINGS=1 |         CXXFLAGS="$CXXFLAGS -m64 -Werror" CXX=clang++ make -C examples/example_null WITH_EXTRA_WARNINGS=1 | ||||||
|  |  | ||||||
|  |     - name: Build example_null (extra warnings, empty IM_ASSERT) | ||||||
|  |       run: | | ||||||
|  |           cat > example_single_file.cpp <<'EOF' | ||||||
|  |  | ||||||
|  |           #define IM_ASSERT(x) | ||||||
|  |           #define IMGUI_IMPLEMENTATION | ||||||
|  |           #include "misc/single_file/imgui_single_file.h" | ||||||
|  |           #include "examples/example_null/main.cpp" | ||||||
|  |  | ||||||
|  |           EOF | ||||||
|  |           g++ -I. -Wall -Wformat -Wextra -Werror -Wno-zero-as-null-pointer-constant -Wno-double-promotion -Wno-variadic-macros -Wno-empty-body -o example_single_file example_single_file.cpp | ||||||
|  |  | ||||||
|     - name: Build example_null (freetype) |     - name: Build example_null (freetype) | ||||||
|       run: | |       run: | | ||||||
|         make -C examples/example_null clean |         make -C examples/example_null clean | ||||||
|   | |||||||
| @@ -171,9 +171,15 @@ void ImGui_ImplAllegro5_RenderDrawData(ImDrawData* draw_data) | |||||||
|             } |             } | ||||||
|             else |             else | ||||||
|             { |             { | ||||||
|                 // Draw |                 // Project scissor/clipping rectangles into framebuffer space | ||||||
|  |                 ImVec2 clip_min(pcmd->ClipRect.x - clip_off.x, pcmd->ClipRect.y - clip_off.y); | ||||||
|  |                 ImVec2 clip_max(pcmd->ClipRect.z - clip_off.x, pcmd->ClipRect.w - clip_off.y); | ||||||
|  |                 if (clip_max.x < clip_min.x || clip_max.y < clip_min.y) | ||||||
|  |                     continue; | ||||||
|  |  | ||||||
|  |                 // Apply scissor/clipping rectangle, Draw | ||||||
|                 ALLEGRO_BITMAP* texture = (ALLEGRO_BITMAP*)pcmd->GetTexID(); |                 ALLEGRO_BITMAP* texture = (ALLEGRO_BITMAP*)pcmd->GetTexID(); | ||||||
|                 al_set_clipping_rectangle(pcmd->ClipRect.x - clip_off.x, pcmd->ClipRect.y - clip_off.y, pcmd->ClipRect.z - pcmd->ClipRect.x, pcmd->ClipRect.w - pcmd->ClipRect.y); |                 al_set_clipping_rectangle(clip_min.x, clip_min.y, clip_max.x, clip_max.y); | ||||||
|                 al_draw_prim(&vertices[0], bd->VertexDecl, texture, idx_offset, idx_offset + pcmd->ElemCount, ALLEGRO_PRIM_TRIANGLE_LIST); |                 al_draw_prim(&vertices[0], bd->VertexDecl, texture, idx_offset, idx_offset + pcmd->ElemCount, ALLEGRO_PRIM_TRIANGLE_LIST); | ||||||
|             } |             } | ||||||
|             idx_offset += pcmd->ElemCount; |             idx_offset += pcmd->ElemCount; | ||||||
|   | |||||||
| @@ -259,8 +259,14 @@ void ImGui_ImplDX10_RenderDrawData(ImDrawData* draw_data) | |||||||
|             } |             } | ||||||
|             else |             else | ||||||
|             { |             { | ||||||
|  |                 // Project scissor/clipping rectangles into framebuffer space | ||||||
|  |                 ImVec2 clip_min(pcmd->ClipRect.x - clip_off.x, pcmd->ClipRect.y - clip_off.y); | ||||||
|  |                 ImVec2 clip_max(pcmd->ClipRect.z - clip_off.x, pcmd->ClipRect.w - clip_off.y); | ||||||
|  |                 if (clip_max.x < clip_min.x || clip_max.y < clip_min.y) | ||||||
|  |                     continue; | ||||||
|  |  | ||||||
|                 // Apply scissor/clipping rectangle |                 // Apply scissor/clipping rectangle | ||||||
|                 const D3D10_RECT r = { (LONG)(pcmd->ClipRect.x - clip_off.x), (LONG)(pcmd->ClipRect.y - clip_off.y), (LONG)(pcmd->ClipRect.z - clip_off.x), (LONG)(pcmd->ClipRect.w - clip_off.y)}; |                 const D3D10_RECT r = { (LONG)clip_min.x, (LONG)clip_min.y, (LONG)clip_max.x, (LONG)clip_max.y }; | ||||||
|                 ctx->RSSetScissorRects(1, &r); |                 ctx->RSSetScissorRects(1, &r); | ||||||
|  |  | ||||||
|                 // Bind texture, Draw |                 // Bind texture, Draw | ||||||
|   | |||||||
| @@ -269,8 +269,14 @@ void ImGui_ImplDX11_RenderDrawData(ImDrawData* draw_data) | |||||||
|             } |             } | ||||||
|             else |             else | ||||||
|             { |             { | ||||||
|  |                 // Project scissor/clipping rectangles into framebuffer space | ||||||
|  |                 ImVec2 clip_min(pcmd->ClipRect.x - clip_off.x, pcmd->ClipRect.y - clip_off.y); | ||||||
|  |                 ImVec2 clip_max(pcmd->ClipRect.z - clip_off.x, pcmd->ClipRect.w - clip_off.y); | ||||||
|  |                 if (clip_max.x < clip_min.x || clip_max.y < clip_min.y) | ||||||
|  |                     continue; | ||||||
|  |  | ||||||
|                 // Apply scissor/clipping rectangle |                 // Apply scissor/clipping rectangle | ||||||
|                 const D3D11_RECT r = { (LONG)(pcmd->ClipRect.x - clip_off.x), (LONG)(pcmd->ClipRect.y - clip_off.y), (LONG)(pcmd->ClipRect.z - clip_off.x), (LONG)(pcmd->ClipRect.w - clip_off.y) }; |                 const D3D11_RECT r = { (LONG)clip_min.x, (LONG)clip_min.y, (LONG)clip_max.x, (LONG)clip_max.y }; | ||||||
|                 ctx->RSSetScissorRects(1, &r); |                 ctx->RSSetScissorRects(1, &r); | ||||||
|  |  | ||||||
|                 // Bind texture, Draw |                 // Bind texture, Draw | ||||||
|   | |||||||
| @@ -337,16 +337,19 @@ void ImGui_ImplDX12_RenderDrawData(ImDrawData* draw_data, ID3D12GraphicsCommandL | |||||||
|             } |             } | ||||||
|             else |             else | ||||||
|             { |             { | ||||||
|                 // Apply Scissor, Bind texture, Draw |                 // Project scissor/clipping rectangles into framebuffer space | ||||||
|                 const D3D12_RECT r = { (LONG)(pcmd->ClipRect.x - clip_off.x), (LONG)(pcmd->ClipRect.y - clip_off.y), (LONG)(pcmd->ClipRect.z - clip_off.x), (LONG)(pcmd->ClipRect.w - clip_off.y) }; |                 ImVec2 clip_min(pcmd->ClipRect.x - clip_off.x, pcmd->ClipRect.y - clip_off.y); | ||||||
|                 if (r.right > r.left && r.bottom > r.top) |                 ImVec2 clip_max(pcmd->ClipRect.z - clip_off.x, pcmd->ClipRect.w - clip_off.y); | ||||||
|                 { |                 if (clip_max.x < clip_min.x || clip_max.y < clip_min.y) | ||||||
|                     D3D12_GPU_DESCRIPTOR_HANDLE texture_handle = {}; |                     continue; | ||||||
|                     texture_handle.ptr = (UINT64)pcmd->GetTexID(); |  | ||||||
|                     ctx->SetGraphicsRootDescriptorTable(1, texture_handle); |                 // Apply Scissor/clipping rectangle, Bind texture, Draw | ||||||
|                     ctx->RSSetScissorRects(1, &r); |                 const D3D12_RECT r = { (LONG)clip_min.x, (LONG)clip_min.y, (LONG)clip_max.x, (LONG)clip_max.y }; | ||||||
|                     ctx->DrawIndexedInstanced(pcmd->ElemCount, 1, pcmd->IdxOffset + global_idx_offset, pcmd->VtxOffset + global_vtx_offset, 0); |                 D3D12_GPU_DESCRIPTOR_HANDLE texture_handle = {}; | ||||||
|                 } |                 texture_handle.ptr = (UINT64)pcmd->GetTexID(); | ||||||
|  |                 ctx->SetGraphicsRootDescriptorTable(1, texture_handle); | ||||||
|  |                 ctx->RSSetScissorRects(1, &r); | ||||||
|  |                 ctx->DrawIndexedInstanced(pcmd->ElemCount, 1, pcmd->IdxOffset + global_idx_offset, pcmd->VtxOffset + global_vtx_offset, 0); | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|         global_idx_offset += cmd_list->IdxBuffer.Size; |         global_idx_offset += cmd_list->IdxBuffer.Size; | ||||||
|   | |||||||
| @@ -256,7 +256,14 @@ void ImGui_ImplDX9_RenderDrawData(ImDrawData* draw_data) | |||||||
|             } |             } | ||||||
|             else |             else | ||||||
|             { |             { | ||||||
|                 const RECT r = { (LONG)(pcmd->ClipRect.x - clip_off.x), (LONG)(pcmd->ClipRect.y - clip_off.y), (LONG)(pcmd->ClipRect.z - clip_off.x), (LONG)(pcmd->ClipRect.w - clip_off.y) }; |                 // Project scissor/clipping rectangles into framebuffer space | ||||||
|  |                 ImVec2 clip_min(pcmd->ClipRect.x - clip_off.x, pcmd->ClipRect.y - clip_off.y); | ||||||
|  |                 ImVec2 clip_max(pcmd->ClipRect.z - clip_off.x, pcmd->ClipRect.w - clip_off.y); | ||||||
|  |                 if (clip_max.x < clip_min.x || clip_max.y < clip_min.y) | ||||||
|  |                     continue; | ||||||
|  |  | ||||||
|  |                 // Apply Scissor/clipping rectangle, Bind texture, Draw | ||||||
|  |                 const RECT r = { (LONG)clip_min.x, (LONG)clip_min.y, (LONG)clip_max.x, (LONG)clip_max.y }; | ||||||
|                 const LPDIRECT3DTEXTURE9 texture = (LPDIRECT3DTEXTURE9)pcmd->GetTexID(); |                 const LPDIRECT3DTEXTURE9 texture = (LPDIRECT3DTEXTURE9)pcmd->GetTexID(); | ||||||
|                 bd->pd3dDevice->SetTexture(0, texture); |                 bd->pd3dDevice->SetTexture(0, texture); | ||||||
|                 bd->pd3dDevice->SetScissorRect(&r); |                 bd->pd3dDevice->SetScissorRect(&r); | ||||||
|   | |||||||
| @@ -14,6 +14,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-08-24: Metal: Fixed a crash when clipping rect larger than framebuffer is submitted. (#4464) | ||||||
| //  2021-05-19: Metal: Replaced direct access to ImDrawCmd::TextureId with a call to ImDrawCmd::GetTexID(). (will become a requirement) | //  2021-05-19: Metal: Replaced direct access to ImDrawCmd::TextureId with a call to ImDrawCmd::GetTexID(). (will become a requirement) | ||||||
| //  2021-02-18: Metal: Change blending equation to preserve alpha in output buffer. | //  2021-02-18: Metal: Change blending equation to preserve alpha in output buffer. | ||||||
| //  2021-01-25: Metal: Fixed texture storage mode when building on Mac Catalyst. | //  2021-01-25: Metal: Fixed texture storage mode when building on Mac Catalyst. | ||||||
| @@ -506,36 +507,37 @@ void ImGui_ImplMetal_DestroyDeviceObjects() | |||||||
|             else |             else | ||||||
|             { |             { | ||||||
|                 // Project scissor/clipping rectangles into framebuffer space |                 // Project scissor/clipping rectangles into framebuffer space | ||||||
|                 ImVec4 clip_rect; |                 ImVec2 clip_min((pcmd->ClipRect.x - clip_off.x) * clip_scale.x, (pcmd->ClipRect.y - clip_off.y) * clip_scale.y); | ||||||
|                 clip_rect.x = (pcmd->ClipRect.x - clip_off.x) * clip_scale.x; |                 ImVec2 clip_max((pcmd->ClipRect.z - clip_off.x) * clip_scale.x, (pcmd->ClipRect.w - clip_off.y) * clip_scale.y); | ||||||
|                 clip_rect.y = (pcmd->ClipRect.y - clip_off.y) * clip_scale.y; |  | ||||||
|                 clip_rect.z = (pcmd->ClipRect.z - clip_off.x) * clip_scale.x; |  | ||||||
|                 clip_rect.w = (pcmd->ClipRect.w - clip_off.y) * clip_scale.y; |  | ||||||
|  |  | ||||||
|                 if (clip_rect.x < fb_width && clip_rect.y < fb_height && clip_rect.z >= 0.0f && clip_rect.w >= 0.0f) |                 // Clamp to viewport as setScissorRect() won't accept values that are off bounds | ||||||
|  |                 if (clip_min.x < 0.0f) { clip_min.x = 0.0f; } | ||||||
|  |                 if (clip_min.y < 0.0f) { clip_min.y = 0.0f; } | ||||||
|  |                 if (clip_max.x > fb_width) { clip_max.x = (float)fb_width; } | ||||||
|  |                 if (clip_max.y > fb_height) { clip_max.y = (float)fb_height; } | ||||||
|  |                 if (clip_max.x < clip_min.x || clip_max.y < clip_min.y) | ||||||
|  |                     continue; | ||||||
|  |  | ||||||
|  |                 // Apply scissor/clipping rectangle | ||||||
|  |                 MTLScissorRect scissorRect = | ||||||
|                 { |                 { | ||||||
|                     // Apply scissor/clipping rectangle |                     .x = NSUInteger(clip_min.x), | ||||||
|                     MTLScissorRect scissorRect = |                     .y = NSUInteger(clip_min.y), | ||||||
|                     { |                     .width = NSUInteger(clip_max.x - clip_min.x), | ||||||
|                         .x = NSUInteger(clip_rect.x), |                     .height = NSUInteger(clip_max.y - clip_min.y) | ||||||
|                         .y = NSUInteger(clip_rect.y), |                 }; | ||||||
|                         .width = NSUInteger(clip_rect.z - clip_rect.x), |                 [commandEncoder setScissorRect:scissorRect]; | ||||||
|                         .height = NSUInteger(clip_rect.w - clip_rect.y) |  | ||||||
|                     }; |  | ||||||
|                     [commandEncoder setScissorRect:scissorRect]; |  | ||||||
|  |  | ||||||
|  |                 // Bind texture, Draw | ||||||
|  |                 if (ImTextureID tex_id = pcmd->GetTexID()) | ||||||
|  |                     [commandEncoder setFragmentTexture:(__bridge id<MTLTexture>)(tex_id) atIndex:0]; | ||||||
|  |  | ||||||
|                     // Bind texture, Draw |                 [commandEncoder setVertexBufferOffset:(vertexBufferOffset + pcmd->VtxOffset * sizeof(ImDrawVert)) atIndex:0]; | ||||||
|                     if (ImTextureID tex_id = pcmd->GetTexID()) |                 [commandEncoder drawIndexedPrimitives:MTLPrimitiveTypeTriangle | ||||||
|                         [commandEncoder setFragmentTexture:(__bridge id<MTLTexture>)(tex_id) atIndex:0]; |                                            indexCount:pcmd->ElemCount | ||||||
|  |                                             indexType:sizeof(ImDrawIdx) == 2 ? MTLIndexTypeUInt16 : MTLIndexTypeUInt32 | ||||||
|                     [commandEncoder setVertexBufferOffset:(vertexBufferOffset + pcmd->VtxOffset * sizeof(ImDrawVert)) atIndex:0]; |                                           indexBuffer:indexBuffer.buffer | ||||||
|                     [commandEncoder drawIndexedPrimitives:MTLPrimitiveTypeTriangle |                                     indexBufferOffset:indexBufferOffset + pcmd->IdxOffset * sizeof(ImDrawIdx)]; | ||||||
|                                                indexCount:pcmd->ElemCount |  | ||||||
|                                                 indexType:sizeof(ImDrawIdx) == 2 ? MTLIndexTypeUInt16 : MTLIndexTypeUInt32 |  | ||||||
|                                               indexBuffer:indexBuffer.buffer |  | ||||||
|                                         indexBufferOffset:indexBufferOffset + pcmd->IdxOffset * sizeof(ImDrawIdx)]; |  | ||||||
|                 } |  | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -211,21 +211,17 @@ void ImGui_ImplOpenGL2_RenderDrawData(ImDrawData* draw_data) | |||||||
|             else |             else | ||||||
|             { |             { | ||||||
|                 // Project scissor/clipping rectangles into framebuffer space |                 // Project scissor/clipping rectangles into framebuffer space | ||||||
|                 ImVec4 clip_rect; |                 ImVec2 clip_min((pcmd->ClipRect.x - clip_off.x) * clip_scale.x, (pcmd->ClipRect.y - clip_off.y) * clip_scale.y); | ||||||
|                 clip_rect.x = (pcmd->ClipRect.x - clip_off.x) * clip_scale.x; |                 ImVec2 clip_max((pcmd->ClipRect.z - clip_off.x) * clip_scale.x, (pcmd->ClipRect.w - clip_off.y) * clip_scale.y); | ||||||
|                 clip_rect.y = (pcmd->ClipRect.y - clip_off.y) * clip_scale.y; |                 if (clip_max.x < clip_min.x || clip_max.y < clip_min.y) | ||||||
|                 clip_rect.z = (pcmd->ClipRect.z - clip_off.x) * clip_scale.x; |                     continue; | ||||||
|                 clip_rect.w = (pcmd->ClipRect.w - clip_off.y) * clip_scale.y; |  | ||||||
|  |  | ||||||
|                 if (clip_rect.x < fb_width && clip_rect.y < fb_height && clip_rect.z >= 0.0f && clip_rect.w >= 0.0f) |                 // Apply scissor/clipping rectangle (Y is inverted in OpenGL) | ||||||
|                 { |                 glScissor((int)clip_min.x, (int)(fb_height - clip_max.y), (int)(clip_max.x - clip_min.x), (int)(clip_max.y - clip_min.y)); | ||||||
|                     // Apply scissor/clipping rectangle |  | ||||||
|                     glScissor((int)clip_rect.x, (int)(fb_height - clip_rect.w), (int)(clip_rect.z - clip_rect.x), (int)(clip_rect.w - clip_rect.y)); |  | ||||||
|  |  | ||||||
|                     // Bind texture, Draw |                 // Bind texture, Draw | ||||||
|                     glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->GetTexID()); |                 glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->GetTexID()); | ||||||
|                     glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, idx_buffer); |                 glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, idx_buffer); | ||||||
|                 } |  | ||||||
|             } |             } | ||||||
|             idx_buffer += pcmd->ElemCount; |             idx_buffer += pcmd->ElemCount; | ||||||
|         } |         } | ||||||
|   | |||||||
| @@ -16,6 +16,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-08-23: OpenGL: Fixed ES 3.0 shader ("#version 300 es") use normal precision floats to avoid wobbly rendering at HD resolutions. | ||||||
| //  2021-08-19: OpenGL: Embed and use our own minimal GL loader (imgui_impl_opengl3_loader.h), removing requirement and support for third-party loader. | //  2021-08-19: OpenGL: Embed and use our own minimal GL loader (imgui_impl_opengl3_loader.h), removing requirement and support for third-party loader. | ||||||
| //  2021-06-29: Reorganized backend to pull data from a single structure to facilitate usage with multiple-contexts (all g_XXXX access changed to bd->XXXX). | //  2021-06-29: Reorganized backend to pull data from a single structure to facilitate usage with multiple-contexts (all g_XXXX access changed to bd->XXXX). | ||||||
| //  2021-06-25: OpenGL: Use OES_vertex_array extension on Emscripten + backup/restore current state. | //  2021-06-25: OpenGL: Use OES_vertex_array extension on Emscripten + backup/restore current state. | ||||||
| @@ -106,6 +107,9 @@ | |||||||
| #include <GLES2/gl2ext.h> | #include <GLES2/gl2ext.h> | ||||||
| #endif | #endif | ||||||
| #elif defined(IMGUI_IMPL_OPENGL_ES3) | #elif defined(IMGUI_IMPL_OPENGL_ES3) | ||||||
|  | #if defined(__APPLE__) | ||||||
|  | #include <TargetConditionals.h> | ||||||
|  | #endif | ||||||
| #if (defined(__APPLE__) && (TARGET_OS_IOS || TARGET_OS_TV)) | #if (defined(__APPLE__) && (TARGET_OS_IOS || TARGET_OS_TV)) | ||||||
| #include <OpenGLES/ES3/gl.h>    // Use GL ES 3 | #include <OpenGLES/ES3/gl.h>    // Use GL ES 3 | ||||||
| #else | #else | ||||||
| @@ -449,26 +453,22 @@ void    ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data) | |||||||
|             else |             else | ||||||
|             { |             { | ||||||
|                 // Project scissor/clipping rectangles into framebuffer space |                 // Project scissor/clipping rectangles into framebuffer space | ||||||
|                 ImVec4 clip_rect; |                 ImVec2 clip_min((pcmd->ClipRect.x - clip_off.x) * clip_scale.x, (pcmd->ClipRect.y - clip_off.y) * clip_scale.y); | ||||||
|                 clip_rect.x = (pcmd->ClipRect.x - clip_off.x) * clip_scale.x; |                 ImVec2 clip_max((pcmd->ClipRect.z - clip_off.x) * clip_scale.x, (pcmd->ClipRect.w - clip_off.y) * clip_scale.y); | ||||||
|                 clip_rect.y = (pcmd->ClipRect.y - clip_off.y) * clip_scale.y; |                 if (clip_max.x < clip_min.x || clip_max.y < clip_min.y) | ||||||
|                 clip_rect.z = (pcmd->ClipRect.z - clip_off.x) * clip_scale.x; |                     continue; | ||||||
|                 clip_rect.w = (pcmd->ClipRect.w - clip_off.y) * clip_scale.y; |  | ||||||
|  |  | ||||||
|                 if (clip_rect.x < fb_width && clip_rect.y < fb_height && clip_rect.z >= 0.0f && clip_rect.w >= 0.0f) |                 // Apply scissor/clipping rectangle (Y is inverted in OpenGL) | ||||||
|                 { |                 glScissor((int)clip_min.x, (int)(fb_height - clip_max.y), (int)(clip_max.x - clip_min.x), (int)(clip_max.y - clip_min.y)); | ||||||
|                     // Apply scissor/clipping rectangle |  | ||||||
|                     glScissor((int)clip_rect.x, (int)(fb_height - clip_rect.w), (int)(clip_rect.z - clip_rect.x), (int)(clip_rect.w - clip_rect.y)); |  | ||||||
|  |  | ||||||
|                     // Bind texture, Draw |                 // Bind texture, Draw | ||||||
|                     glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->GetTexID()); |                 glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->GetTexID()); | ||||||
| #ifdef IMGUI_IMPL_OPENGL_MAY_HAVE_VTX_OFFSET | #ifdef IMGUI_IMPL_OPENGL_MAY_HAVE_VTX_OFFSET | ||||||
|                     if (bd->GlVersion >= 320) |                 if (bd->GlVersion >= 320) | ||||||
|                         glDrawElementsBaseVertex(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, (void*)(intptr_t)(pcmd->IdxOffset * sizeof(ImDrawIdx)), (GLint)pcmd->VtxOffset); |                     glDrawElementsBaseVertex(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, (void*)(intptr_t)(pcmd->IdxOffset * sizeof(ImDrawIdx)), (GLint)pcmd->VtxOffset); | ||||||
|                     else |                 else | ||||||
| #endif | #endif | ||||||
|                     glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, (void*)(intptr_t)(pcmd->IdxOffset * sizeof(ImDrawIdx))); |                 glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, (void*)(intptr_t)(pcmd->IdxOffset * sizeof(ImDrawIdx))); | ||||||
|                 } |  | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| @@ -636,7 +636,7 @@ bool    ImGui_ImplOpenGL3_CreateDeviceObjects() | |||||||
|         "}\n"; |         "}\n"; | ||||||
|  |  | ||||||
|     const GLchar* vertex_shader_glsl_300_es = |     const GLchar* vertex_shader_glsl_300_es = | ||||||
|         "precision mediump float;\n" |         "precision highp float;\n" | ||||||
|         "layout (location = 0) in vec2 Position;\n" |         "layout (location = 0) in vec2 Position;\n" | ||||||
|         "layout (location = 1) in vec2 UV;\n" |         "layout (location = 1) in vec2 UV;\n" | ||||||
|         "layout (location = 2) in vec4 Color;\n" |         "layout (location = 2) in vec4 Color;\n" | ||||||
|   | |||||||
| @@ -43,7 +43,7 @@ IMGUI_IMPL_API void     ImGui_ImplOpenGL3_DestroyDeviceObjects(); | |||||||
|  |  | ||||||
| // Try to detect GLES on matching platforms | // Try to detect GLES on matching platforms | ||||||
| #if defined(__APPLE__) | #if defined(__APPLE__) | ||||||
| #include "TargetConditionals.h" | #include <TargetConditionals.h> | ||||||
| #endif | #endif | ||||||
| #if (defined(__APPLE__) && (TARGET_OS_IOS || TARGET_OS_TV)) || (defined(__ANDROID__)) | #if (defined(__APPLE__) && (TARGET_OS_IOS || TARGET_OS_TV)) || (defined(__ANDROID__)) | ||||||
| #define IMGUI_IMPL_OPENGL_ES3               // iOS, Android  -> GL ES 3, "#version 300 es" | #define IMGUI_IMPL_OPENGL_ES3               // iOS, Android  -> GL ES 3, "#version 300 es" | ||||||
|   | |||||||
| @@ -473,61 +473,61 @@ union GL3WProcs { | |||||||
|     } gl; |     } gl; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| GL3W_API extern union GL3WProcs gl3wProcs; | GL3W_API extern union GL3WProcs imgl3wProcs; | ||||||
|  |  | ||||||
| /* OpenGL functions */ | /* OpenGL functions */ | ||||||
| #define glActiveTexture                  gl3wProcs.gl.ActiveTexture | #define glActiveTexture                  imgl3wProcs.gl.ActiveTexture | ||||||
| #define glAttachShader                   gl3wProcs.gl.AttachShader | #define glAttachShader                   imgl3wProcs.gl.AttachShader | ||||||
| #define glBindBuffer                     gl3wProcs.gl.BindBuffer | #define glBindBuffer                     imgl3wProcs.gl.BindBuffer | ||||||
| #define glBindSampler                    gl3wProcs.gl.BindSampler | #define glBindSampler                    imgl3wProcs.gl.BindSampler | ||||||
| #define glBindTexture                    gl3wProcs.gl.BindTexture | #define glBindTexture                    imgl3wProcs.gl.BindTexture | ||||||
| #define glBindVertexArray                gl3wProcs.gl.BindVertexArray | #define glBindVertexArray                imgl3wProcs.gl.BindVertexArray | ||||||
| #define glBlendEquation                  gl3wProcs.gl.BlendEquation | #define glBlendEquation                  imgl3wProcs.gl.BlendEquation | ||||||
| #define glBlendEquationSeparate          gl3wProcs.gl.BlendEquationSeparate | #define glBlendEquationSeparate          imgl3wProcs.gl.BlendEquationSeparate | ||||||
| #define glBlendFuncSeparate              gl3wProcs.gl.BlendFuncSeparate | #define glBlendFuncSeparate              imgl3wProcs.gl.BlendFuncSeparate | ||||||
| #define glBufferData                     gl3wProcs.gl.BufferData | #define glBufferData                     imgl3wProcs.gl.BufferData | ||||||
| #define glClear                          gl3wProcs.gl.Clear | #define glClear                          imgl3wProcs.gl.Clear | ||||||
| #define glClearColor                     gl3wProcs.gl.ClearColor | #define glClearColor                     imgl3wProcs.gl.ClearColor | ||||||
| #define glCompileShader                  gl3wProcs.gl.CompileShader | #define glCompileShader                  imgl3wProcs.gl.CompileShader | ||||||
| #define glCreateProgram                  gl3wProcs.gl.CreateProgram | #define glCreateProgram                  imgl3wProcs.gl.CreateProgram | ||||||
| #define glCreateShader                   gl3wProcs.gl.CreateShader | #define glCreateShader                   imgl3wProcs.gl.CreateShader | ||||||
| #define glDeleteBuffers                  gl3wProcs.gl.DeleteBuffers | #define glDeleteBuffers                  imgl3wProcs.gl.DeleteBuffers | ||||||
| #define glDeleteProgram                  gl3wProcs.gl.DeleteProgram | #define glDeleteProgram                  imgl3wProcs.gl.DeleteProgram | ||||||
| #define glDeleteShader                   gl3wProcs.gl.DeleteShader | #define glDeleteShader                   imgl3wProcs.gl.DeleteShader | ||||||
| #define glDeleteTextures                 gl3wProcs.gl.DeleteTextures | #define glDeleteTextures                 imgl3wProcs.gl.DeleteTextures | ||||||
| #define glDeleteVertexArrays             gl3wProcs.gl.DeleteVertexArrays | #define glDeleteVertexArrays             imgl3wProcs.gl.DeleteVertexArrays | ||||||
| #define glDetachShader                   gl3wProcs.gl.DetachShader | #define glDetachShader                   imgl3wProcs.gl.DetachShader | ||||||
| #define glDisable                        gl3wProcs.gl.Disable | #define glDisable                        imgl3wProcs.gl.Disable | ||||||
| #define glDrawElements                   gl3wProcs.gl.DrawElements | #define glDrawElements                   imgl3wProcs.gl.DrawElements | ||||||
| #define glDrawElementsBaseVertex         gl3wProcs.gl.DrawElementsBaseVertex | #define glDrawElementsBaseVertex         imgl3wProcs.gl.DrawElementsBaseVertex | ||||||
| #define glEnable                         gl3wProcs.gl.Enable | #define glEnable                         imgl3wProcs.gl.Enable | ||||||
| #define glEnableVertexAttribArray        gl3wProcs.gl.EnableVertexAttribArray | #define glEnableVertexAttribArray        imgl3wProcs.gl.EnableVertexAttribArray | ||||||
| #define glGenBuffers                     gl3wProcs.gl.GenBuffers | #define glGenBuffers                     imgl3wProcs.gl.GenBuffers | ||||||
| #define glGenTextures                    gl3wProcs.gl.GenTextures | #define glGenTextures                    imgl3wProcs.gl.GenTextures | ||||||
| #define glGenVertexArrays                gl3wProcs.gl.GenVertexArrays | #define glGenVertexArrays                imgl3wProcs.gl.GenVertexArrays | ||||||
| #define glGetAttribLocation              gl3wProcs.gl.GetAttribLocation | #define glGetAttribLocation              imgl3wProcs.gl.GetAttribLocation | ||||||
| #define glGetIntegerv                    gl3wProcs.gl.GetIntegerv | #define glGetIntegerv                    imgl3wProcs.gl.GetIntegerv | ||||||
| #define glGetProgramInfoLog              gl3wProcs.gl.GetProgramInfoLog | #define glGetProgramInfoLog              imgl3wProcs.gl.GetProgramInfoLog | ||||||
| #define glGetProgramiv                   gl3wProcs.gl.GetProgramiv | #define glGetProgramiv                   imgl3wProcs.gl.GetProgramiv | ||||||
| #define glGetShaderInfoLog               gl3wProcs.gl.GetShaderInfoLog | #define glGetShaderInfoLog               imgl3wProcs.gl.GetShaderInfoLog | ||||||
| #define glGetShaderiv                    gl3wProcs.gl.GetShaderiv | #define glGetShaderiv                    imgl3wProcs.gl.GetShaderiv | ||||||
| #define glGetString                      gl3wProcs.gl.GetString | #define glGetString                      imgl3wProcs.gl.GetString | ||||||
| #define glGetStringi                     gl3wProcs.gl.GetStringi | #define glGetStringi                     imgl3wProcs.gl.GetStringi | ||||||
| #define glGetUniformLocation             gl3wProcs.gl.GetUniformLocation | #define glGetUniformLocation             imgl3wProcs.gl.GetUniformLocation | ||||||
| #define glIsEnabled                      gl3wProcs.gl.IsEnabled | #define glIsEnabled                      imgl3wProcs.gl.IsEnabled | ||||||
| #define glLinkProgram                    gl3wProcs.gl.LinkProgram | #define glLinkProgram                    imgl3wProcs.gl.LinkProgram | ||||||
| #define glPixelStorei                    gl3wProcs.gl.PixelStorei | #define glPixelStorei                    imgl3wProcs.gl.PixelStorei | ||||||
| #define glPolygonMode                    gl3wProcs.gl.PolygonMode | #define glPolygonMode                    imgl3wProcs.gl.PolygonMode | ||||||
| #define glReadPixels                     gl3wProcs.gl.ReadPixels | #define glReadPixels                     imgl3wProcs.gl.ReadPixels | ||||||
| #define glScissor                        gl3wProcs.gl.Scissor | #define glScissor                        imgl3wProcs.gl.Scissor | ||||||
| #define glShaderSource                   gl3wProcs.gl.ShaderSource | #define glShaderSource                   imgl3wProcs.gl.ShaderSource | ||||||
| #define glTexImage2D                     gl3wProcs.gl.TexImage2D | #define glTexImage2D                     imgl3wProcs.gl.TexImage2D | ||||||
| #define glTexParameteri                  gl3wProcs.gl.TexParameteri | #define glTexParameteri                  imgl3wProcs.gl.TexParameteri | ||||||
| #define glUniform1i                      gl3wProcs.gl.Uniform1i | #define glUniform1i                      imgl3wProcs.gl.Uniform1i | ||||||
| #define glUniformMatrix4fv               gl3wProcs.gl.UniformMatrix4fv | #define glUniformMatrix4fv               imgl3wProcs.gl.UniformMatrix4fv | ||||||
| #define glUseProgram                     gl3wProcs.gl.UseProgram | #define glUseProgram                     imgl3wProcs.gl.UseProgram | ||||||
| #define glVertexAttribPointer            gl3wProcs.gl.VertexAttribPointer | #define glVertexAttribPointer            imgl3wProcs.gl.VertexAttribPointer | ||||||
| #define glViewport                       gl3wProcs.gl.Viewport | #define glViewport                       imgl3wProcs.gl.Viewport | ||||||
|  |  | ||||||
| #ifdef __cplusplus | #ifdef __cplusplus | ||||||
| } | } | ||||||
| @@ -715,13 +715,13 @@ static const char *proc_names[] = { | |||||||
|     "glViewport", |     "glViewport", | ||||||
| }; | }; | ||||||
|  |  | ||||||
| GL3W_API union GL3WProcs gl3wProcs; | GL3W_API union GL3WProcs imgl3wProcs; | ||||||
|  |  | ||||||
| static void load_procs(GL3WGetProcAddressProc proc) | static void load_procs(GL3WGetProcAddressProc proc) | ||||||
| { | { | ||||||
|     size_t i; |     size_t i; | ||||||
|     for (i = 0; i < ARRAY_SIZE(proc_names); i++) |     for (i = 0; i < ARRAY_SIZE(proc_names); i++) | ||||||
|         gl3wProcs.ptr[i] = proc(proc_names[i]); |         imgl3wProcs.ptr[i] = proc(proc_names[i]); | ||||||
| } | } | ||||||
|  |  | ||||||
| #ifdef __cplusplus | #ifdef __cplusplus | ||||||
|   | |||||||
| @@ -61,7 +61,7 @@ | |||||||
| #include <SDL.h> | #include <SDL.h> | ||||||
| #include <SDL_syswm.h> | #include <SDL_syswm.h> | ||||||
| #if defined(__APPLE__) | #if defined(__APPLE__) | ||||||
| #include "TargetConditionals.h" | #include <TargetConditionals.h> | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
| #if SDL_VERSION_ATLEAST(2,0,4) && !defined(__EMSCRIPTEN__) && !defined(__ANDROID__) && !(defined(__APPLE__) && TARGET_OS_IOS) | #if SDL_VERSION_ATLEAST(2,0,4) && !defined(__EMSCRIPTEN__) && !defined(__ANDROID__) && !(defined(__APPLE__) && TARGET_OS_IOS) | ||||||
|   | |||||||
| @@ -543,31 +543,27 @@ void ImGui_ImplVulkan_RenderDrawData(ImDrawData* draw_data, VkCommandBuffer comm | |||||||
|             else |             else | ||||||
|             { |             { | ||||||
|                 // Project scissor/clipping rectangles into framebuffer space |                 // Project scissor/clipping rectangles into framebuffer space | ||||||
|                 ImVec4 clip_rect; |                 ImVec2 clip_min((pcmd->ClipRect.x - clip_off.x) * clip_scale.x, (pcmd->ClipRect.y - clip_off.y) * clip_scale.y); | ||||||
|                 clip_rect.x = (pcmd->ClipRect.x - clip_off.x) * clip_scale.x; |                 ImVec2 clip_max((pcmd->ClipRect.z - clip_off.x) * clip_scale.x, (pcmd->ClipRect.w - clip_off.y) * clip_scale.y); | ||||||
|                 clip_rect.y = (pcmd->ClipRect.y - clip_off.y) * clip_scale.y; |  | ||||||
|                 clip_rect.z = (pcmd->ClipRect.z - clip_off.x) * clip_scale.x; |  | ||||||
|                 clip_rect.w = (pcmd->ClipRect.w - clip_off.y) * clip_scale.y; |  | ||||||
|  |  | ||||||
|                 if (clip_rect.x < fb_width && clip_rect.y < fb_height && clip_rect.z >= 0.0f && clip_rect.w >= 0.0f) |                 // Clamp to viewport as vkCmdSetScissor() won't accept values that are off bounds | ||||||
|                 { |                 if (clip_min.x < 0.0f) { clip_min.x = 0.0f; } | ||||||
|                     // Negative offsets are illegal for vkCmdSetScissor |                 if (clip_min.y < 0.0f) { clip_min.y = 0.0f; } | ||||||
|                     if (clip_rect.x < 0.0f) |                 if (clip_max.x > fb_width) { clip_max.x = (float)fb_width; } | ||||||
|                         clip_rect.x = 0.0f; |                 if (clip_max.y > fb_height) { clip_max.y = (float)fb_height; } | ||||||
|                     if (clip_rect.y < 0.0f) |                 if (clip_max.x < clip_min.x || clip_max.y < clip_min.y) | ||||||
|                         clip_rect.y = 0.0f; |                     continue; | ||||||
|  |  | ||||||
|                     // Apply scissor/clipping rectangle |                 // Apply scissor/clipping rectangle | ||||||
|                     VkRect2D scissor; |                 VkRect2D scissor; | ||||||
|                     scissor.offset.x = (int32_t)(clip_rect.x); |                 scissor.offset.x = (int32_t)(clip_min.x); | ||||||
|                     scissor.offset.y = (int32_t)(clip_rect.y); |                 scissor.offset.y = (int32_t)(clip_min.y); | ||||||
|                     scissor.extent.width = (uint32_t)(clip_rect.z - clip_rect.x); |                 scissor.extent.width = (uint32_t)(clip_max.x - clip_min.x); | ||||||
|                     scissor.extent.height = (uint32_t)(clip_rect.w - clip_rect.y); |                 scissor.extent.height = (uint32_t)(clip_max.y - clip_min.y); | ||||||
|                     vkCmdSetScissor(command_buffer, 0, 1, &scissor); |                 vkCmdSetScissor(command_buffer, 0, 1, &scissor); | ||||||
|  |  | ||||||
|                     // Draw |                 // Draw | ||||||
|                     vkCmdDrawIndexed(command_buffer, pcmd->ElemCount, 1, pcmd->IdxOffset + global_idx_offset, pcmd->VtxOffset + global_vtx_offset, 0); |                 vkCmdDrawIndexed(command_buffer, pcmd->ElemCount, 1, pcmd->IdxOffset + global_idx_offset, pcmd->VtxOffset + global_vtx_offset, 0); | ||||||
|                 } |  | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|         global_idx_offset += cmd_list->IdxBuffer.Size; |         global_idx_offset += cmd_list->IdxBuffer.Size; | ||||||
| @@ -732,7 +728,7 @@ static void ImGui_ImplVulkan_CreateShaderModules(VkDevice device, const VkAlloca | |||||||
| { | { | ||||||
|     // Create the shader modules |     // Create the shader modules | ||||||
|     ImGui_ImplVulkan_Data* bd = ImGui_ImplVulkan_GetBackendData(); |     ImGui_ImplVulkan_Data* bd = ImGui_ImplVulkan_GetBackendData(); | ||||||
|     if (bd->ShaderModuleVert == NULL) |     if (bd->ShaderModuleVert == VK_NULL_HANDLE) | ||||||
|     { |     { | ||||||
|         VkShaderModuleCreateInfo vert_info = {}; |         VkShaderModuleCreateInfo vert_info = {}; | ||||||
|         vert_info.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; |         vert_info.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; | ||||||
| @@ -741,7 +737,7 @@ static void ImGui_ImplVulkan_CreateShaderModules(VkDevice device, const VkAlloca | |||||||
|         VkResult err = vkCreateShaderModule(device, &vert_info, allocator, &bd->ShaderModuleVert); |         VkResult err = vkCreateShaderModule(device, &vert_info, allocator, &bd->ShaderModuleVert); | ||||||
|         check_vk_result(err); |         check_vk_result(err); | ||||||
|     } |     } | ||||||
|     if (bd->ShaderModuleFrag == NULL) |     if (bd->ShaderModuleFrag == VK_NULL_HANDLE) | ||||||
|     { |     { | ||||||
|         VkShaderModuleCreateInfo frag_info = {}; |         VkShaderModuleCreateInfo frag_info = {}; | ||||||
|         frag_info.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; |         frag_info.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; | ||||||
| @@ -1284,7 +1280,7 @@ void ImGui_ImplVulkanH_CreateWindowSwapChain(VkPhysicalDevice physical_device, V | |||||||
| { | { | ||||||
|     VkResult err; |     VkResult err; | ||||||
|     VkSwapchainKHR old_swapchain = wd->Swapchain; |     VkSwapchainKHR old_swapchain = wd->Swapchain; | ||||||
|     wd->Swapchain = NULL; |     wd->Swapchain = VK_NULL_HANDLE; | ||||||
|     err = vkDeviceWaitIdle(device); |     err = vkDeviceWaitIdle(device); | ||||||
|     check_vk_result(err); |     check_vk_result(err); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -13,6 +13,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-08-24: Fix for latest specs. | ||||||
| //  2021-05-24: Add support for draw_data->FramebufferScale. | //  2021-05-24: Add support for draw_data->FramebufferScale. | ||||||
| //  2021-05-19: Replaced direct access to ImDrawCmd::TextureId with a call to ImDrawCmd::GetTexID(). (will become a requirement) | //  2021-05-19: Replaced direct access to ImDrawCmd::TextureId with a call to ImDrawCmd::GetTexID(). (will become a requirement) | ||||||
| //  2021-05-16: Update to latest WebGPU specs (compatible with Emscripten 2.0.20 and Chrome Canary 92). | //  2021-05-16: Update to latest WebGPU specs (compatible with Emscripten 2.0.20 and Chrome Canary 92). | ||||||
| @@ -442,13 +443,14 @@ void ImGui_ImplWGPU_RenderDrawData(ImDrawData* draw_data, WGPURenderPassEncoder | |||||||
|                     wgpuRenderPassEncoderSetBindGroup(pass_encoder, 1, image_bind_group, 0, NULL); |                     wgpuRenderPassEncoderSetBindGroup(pass_encoder, 1, image_bind_group, 0, NULL); | ||||||
|                 } |                 } | ||||||
|  |  | ||||||
|                 // Apply Scissor, Bind texture, Draw |                 // Project scissor/clipping rectangles into framebuffer space | ||||||
|                 uint32_t clip_rect[4]; |                 ImVec2 clip_min((pcmd->ClipRect.x - clip_off.x) * clip_scale.x, (pcmd->ClipRect.y - clip_off.y) * clip_scale.y); | ||||||
|                 clip_rect[0] = (uint32_t)(clip_scale.x * (pcmd->ClipRect.x - clip_off.x)); |                 ImVec2 clip_max((pcmd->ClipRect.z - clip_off.x) * clip_scale.x, (pcmd->ClipRect.w - clip_off.y) * clip_scale.y); | ||||||
|                 clip_rect[1] = (uint32_t)(clip_scale.y * (pcmd->ClipRect.y - clip_off.y)); |                 if (clip_max.x < clip_min.x || clip_max.y < clip_min.y) | ||||||
|                 clip_rect[2] = (uint32_t)(clip_scale.x * (pcmd->ClipRect.z - clip_off.x)); |                     continue; | ||||||
|                 clip_rect[3] = (uint32_t)(clip_scale.y * (pcmd->ClipRect.w - clip_off.y)); |  | ||||||
|                 wgpuRenderPassEncoderSetScissorRect(pass_encoder, clip_rect[0], clip_rect[1], clip_rect[2] - clip_rect[0], clip_rect[3] - clip_rect[1]); |                 // Apply scissor/clipping rectangle, Draw | ||||||
|  |                 wgpuRenderPassEncoderSetScissorRect(pass_encoder, (uint32_t)clip_min.x, (uint32_t)clip_min.y, (uint32_t)(clip_max.x - clip_min.x), (uint32_t)(clip_max.y - clip_min.y)); | ||||||
|                 wgpuRenderPassEncoderDrawIndexed(pass_encoder, pcmd->ElemCount, 1, pcmd->IdxOffset + global_idx_offset, pcmd->VtxOffset + global_vtx_offset, 0); |                 wgpuRenderPassEncoderDrawIndexed(pass_encoder, pcmd->ElemCount, 1, pcmd->IdxOffset + global_idx_offset, pcmd->VtxOffset + global_vtx_offset, 0); | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
| @@ -544,7 +546,7 @@ bool ImGui_ImplWGPU_CreateDeviceObjects() | |||||||
|         ImGui_ImplWGPU_InvalidateDeviceObjects(); |         ImGui_ImplWGPU_InvalidateDeviceObjects(); | ||||||
|  |  | ||||||
|     // Create render pipeline |     // Create render pipeline | ||||||
|     WGPURenderPipelineDescriptor2 graphics_pipeline_desc = {}; |     WGPURenderPipelineDescriptor graphics_pipeline_desc = {}; | ||||||
|     graphics_pipeline_desc.primitive.topology = WGPUPrimitiveTopology_TriangleList; |     graphics_pipeline_desc.primitive.topology = WGPUPrimitiveTopology_TriangleList; | ||||||
|     graphics_pipeline_desc.primitive.stripIndexFormat = WGPUIndexFormat_Undefined; |     graphics_pipeline_desc.primitive.stripIndexFormat = WGPUIndexFormat_Undefined; | ||||||
|     graphics_pipeline_desc.primitive.frontFace = WGPUFrontFace_CW; |     graphics_pipeline_desc.primitive.frontFace = WGPUFrontFace_CW; | ||||||
| @@ -610,7 +612,7 @@ bool ImGui_ImplWGPU_CreateDeviceObjects() | |||||||
|     // Configure disabled depth-stencil state |     // Configure disabled depth-stencil state | ||||||
|     graphics_pipeline_desc.depthStencil = nullptr; |     graphics_pipeline_desc.depthStencil = nullptr; | ||||||
|  |  | ||||||
|     g_pipelineState = wgpuDeviceCreateRenderPipeline2(g_wgpuDevice, &graphics_pipeline_desc); |     g_pipelineState = wgpuDeviceCreateRenderPipeline(g_wgpuDevice, &graphics_pipeline_desc); | ||||||
|  |  | ||||||
|     ImGui_ImplWGPU_CreateFontsTexture(); |     ImGui_ImplWGPU_CreateFontsTexture(); | ||||||
|     ImGui_ImplWGPU_CreateUniformBuffer(); |     ImGui_ImplWGPU_CreateUniformBuffer(); | ||||||
|   | |||||||
| @@ -30,6 +30,55 @@ 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.85 WIP (In Progress) | ||||||
|  | ----------------------------------------------------------------------- | ||||||
|  |  | ||||||
|  | Breaking Changes: | ||||||
|  |  | ||||||
|  | - Removed GetWindowContentRegionWidth() function. keep inline redirection helper. | ||||||
|  |   Can use 'GetWindowContentRegionMax().x - GetWindowContentRegionMin().x' instead but it's not | ||||||
|  |   very useful in practice, and the only use of it in the demo was illfit. | ||||||
|  |  | ||||||
|  | Other Changes: | ||||||
|  |  | ||||||
|  | - Windows: fixed background order of overlapping childs submitted sequentially. (#4493) | ||||||
|  | - InputTextMultiline: Fixed label size not being included into window contents rect unless | ||||||
|  |   the whole widget is clipped. | ||||||
|  | - TextUnformatted: Accept null ranges including (NULL,NULL) without asserting, in order to conform | ||||||
|  |   to common idioms (e.g. passing .data(), .data() + .size() from a null string). (#3615) | ||||||
|  | - IO: Added 'io.WantCaptureMouseUnlessPopupClose' alternative to `io.WantCaptureMouse'. (#4480) | ||||||
|  |   This allows apps to receive the click on void when that click is used to close popup (by default, | ||||||
|  |   clicking on a void when a popup is open will close the popup but not release io.WantCaptureMouse). | ||||||
|  | - Fonts: imgui_freetype: Fixed crash when FT_Render_Glyph() fails to render a glyph and returns NULL | ||||||
|  |   (which apparently happens with Freetype 2.11). (#4394, #4145?). | ||||||
|  | - Fonts: Fixed ImFontAtlas::ClearInputData() marking atlas as not built. (#4455, #3487) | ||||||
|  | - Backends: OpenGL3: Fixed our new GL loader conflicting with user using GL3W. (#4445) | ||||||
|  | - Backends: WebGPU: Fixed for latest specs. (#4472) [@Kangz] | ||||||
|  | - Backends: Metal: Fixed a crash when clipping rect larger than framebuffer is submitted via | ||||||
|  |   a direct unclipped PushClipRect() call. (#4464) | ||||||
|  | - Backends: All renderers: Normalize clipping rect handling across backends. (#4464) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | ----------------------------------------------------------------------- | ||||||
|  |  VERSION 1.84.2 (Released 2021-08-23) | ||||||
|  | ----------------------------------------------------------------------- | ||||||
|  |  | ||||||
|  | Decorated log: https://github.com/ocornut/imgui/releases/tag/v1.84.2 | ||||||
|  |  | ||||||
|  | - Disabled: Fixed nested BeginDisabled()/EndDisabled() calls. (#211, #4452, #4453, #4462) [@Legulysse] | ||||||
|  | - Backends: OpenGL3: OpenGL: Fixed ES 3.0 shader ("#version 300 es") to use normal precision | ||||||
|  |   floats. Avoid wobbly rendering at HD resolutions. (#4463) [@nicolasnoble] | ||||||
|  |  | ||||||
|  |  | ||||||
|  | ----------------------------------------------------------------------- | ||||||
|  |  VERSION 1.84.1 (Released 2021-08-20) | ||||||
|  | ----------------------------------------------------------------------- | ||||||
|  |  | ||||||
|  | Decorated log: https://github.com/ocornut/imgui/releases/tag/v1.84.1 | ||||||
|  |  | ||||||
|  | - Disabled: Fixed BeginDisabled(false) - BeginDisabled(true) was working. (#211, #4452, #4453) | ||||||
|  |  | ||||||
|  |  | ||||||
| ----------------------------------------------------------------------- | ----------------------------------------------------------------------- | ||||||
|  DOCKING+MULTI-VIEWPORT BRANCH (In Progress) |  DOCKING+MULTI-VIEWPORT BRANCH (In Progress) | ||||||
|   | |||||||
| @@ -94,6 +94,8 @@ Read [BACKENDS.md](https://github.com/ocornut/imgui/blob/master/docs/BACKENDS.md | |||||||
| Read `PROGRAMMER GUIDE` section of [imgui.cpp](https://github.com/ocornut/imgui/blob/master/imgui.cpp). <BR> | Read `PROGRAMMER GUIDE` section of [imgui.cpp](https://github.com/ocornut/imgui/blob/master/imgui.cpp). <BR> | ||||||
| The [Wiki](https://github.com/ocornut/imgui/wiki) is a hub to many resources and links. | The [Wiki](https://github.com/ocornut/imgui/wiki) is a hub to many resources and links. | ||||||
|  |  | ||||||
|  | For first-time users having issues compiling/linking/running or issues loading fonts, please use [GitHub Discussions](https://github.com/ocornut/imgui/discussions). | ||||||
|  |  | ||||||
| ##### [Return to Index](#index) | ##### [Return to Index](#index) | ||||||
|  |  | ||||||
| --- | --- | ||||||
|   | |||||||
| @@ -162,7 +162,9 @@ See: [Wiki](https://github.com/ocornut/imgui/wiki) for many links, references, a | |||||||
|  |  | ||||||
| See: [Articles about the IMGUI paradigm](https://github.com/ocornut/imgui/wiki#about-the-imgui-paradigm) to read/learn about the Immediate Mode GUI paradigm. | See: [Articles about the IMGUI paradigm](https://github.com/ocornut/imgui/wiki#about-the-imgui-paradigm) to read/learn about the Immediate Mode GUI paradigm. | ||||||
|  |  | ||||||
| For questions, bug reports, requests, feedback, you may post on [GitHub Issues](https://github.com/ocornut/imgui/issues) or [GitHub Discussions](https://github.com/ocornut/imgui/discussions). Please read and fill the New Issue template carefully. | Getting started? For first-time users having issues compiling/linking/running or issues loading fonts, please use [GitHub Discussions](https://github.com/ocornut/imgui/discussions). | ||||||
|  |  | ||||||
|  | For other questions, bug reports, requests, feedback, you may post on [GitHub Issues](https://github.com/ocornut/imgui/issues). Please read and fill the New Issue template carefully. | ||||||
|  |  | ||||||
| Private support is available for paying business customers (E-mail: _contact @ dearimgui dot com_). | Private support is available for paying business customers (E-mail: _contact @ dearimgui dot com_). | ||||||
|  |  | ||||||
|   | |||||||
| @@ -8,9 +8,10 @@ | |||||||
| #include "imgui_impl_opengl3.h" | #include "imgui_impl_opengl3.h" | ||||||
| #include <stdio.h> | #include <stdio.h> | ||||||
| #include <SDL.h> | #include <SDL.h> | ||||||
| #include <SDL_opengl.h> |  | ||||||
| #if defined(IMGUI_IMPL_OPENGL_ES2) | #if defined(IMGUI_IMPL_OPENGL_ES2) | ||||||
| #include <SDL_opengles2.h> | #include <SDL_opengles2.h> | ||||||
|  | #else | ||||||
|  | #include <SDL_opengl.h> | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
| // Main code | // Main code | ||||||
|   | |||||||
							
								
								
									
										525
									
								
								imgui.cpp
									
									
									
									
									
								
							
							
						
						
									
										525
									
								
								imgui.cpp
									
									
									
									
									
								
							| @@ -1,4 +1,4 @@ | |||||||
| // dear imgui, v1.84 | // dear imgui, v1.85 WIP | ||||||
| // (main code and documentation) | // (main code and documentation) | ||||||
|  |  | ||||||
| // Help: | // Help: | ||||||
| @@ -15,7 +15,10 @@ | |||||||
| // - Wiki                  https://github.com/ocornut/imgui/wiki (lots of good stuff 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 | ||||||
| // - Issues & support      https://github.com/ocornut/imgui/issues | // - Issues & support      https://github.com/ocornut/imgui/issues | ||||||
| // - Discussions           https://github.com/ocornut/imgui/discussions |  | ||||||
|  | // Getting Started? | ||||||
|  | // - For first-time users having issues compiling/linking/running or issues loading fonts: | ||||||
|  | //   please post in https://github.com/ocornut/imgui/discussions if you cannot find a solution in resources above. | ||||||
|  |  | ||||||
| // 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). | ||||||
| @@ -386,6 +389,7 @@ CODE | |||||||
|  - 2021/XX/XX (1.XX) - Moved IME support functions from io.ImeSetInputScreenPosFn, io.ImeWindowHandle to the PlatformIO api. |  - 2021/XX/XX (1.XX) - Moved IME support functions from io.ImeSetInputScreenPosFn, io.ImeWindowHandle to the PlatformIO api. | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  - 2021/08/23 (1.85) - removed GetWindowContentRegionWidth() function. keep inline redirection helper. can use 'GetWindowContentRegionMax().x - GetWindowContentRegionMin().x' instead. | ||||||
|  - 2021/07/26 (1.84) - commented out redirecting functions/enums names that were marked obsolete in 1.67 and 1.69 (March 2019): |  - 2021/07/26 (1.84) - commented out redirecting functions/enums names that were marked obsolete in 1.67 and 1.69 (March 2019): | ||||||
|                         - ImGui::GetOverlayDrawList() -> use ImGui::GetForegroundDrawList() |                         - ImGui::GetOverlayDrawList() -> use ImGui::GetForegroundDrawList() | ||||||
|                         - ImFont::GlyphRangesBuilder  -> use ImFontGlyphRangesBuilder |                         - ImFont::GlyphRangesBuilder  -> use ImFontGlyphRangesBuilder | ||||||
| @@ -919,8 +923,9 @@ namespace ImGui | |||||||
| static void             NavUpdate(); | static void             NavUpdate(); | ||||||
| static void             NavUpdateWindowing(); | static void             NavUpdateWindowing(); | ||||||
| static void             NavUpdateWindowingOverlay(); | static void             NavUpdateWindowingOverlay(); | ||||||
| static void             NavUpdateMoveResult(); |  | ||||||
| static void             NavUpdateInitResult(); | static void             NavUpdateInitResult(); | ||||||
|  | static void             NavUpdateCancelRequest(); | ||||||
|  | static void             NavUpdateCreateMoveRequest(); | ||||||
| static float            NavUpdatePageUpPageDown(); | static float            NavUpdatePageUpPageDown(); | ||||||
| static inline void      NavUpdateAnyRequestFlag(); | static inline void      NavUpdateAnyRequestFlag(); | ||||||
| static void             NavEndFrame(); | static void             NavEndFrame(); | ||||||
| @@ -4004,6 +4009,7 @@ void ImGui::UpdateTabFocus() | |||||||
| void ImGui::UpdateHoveredWindowAndCaptureFlags() | void ImGui::UpdateHoveredWindowAndCaptureFlags() | ||||||
| { | { | ||||||
|     ImGuiContext& g = *GImGui; |     ImGuiContext& g = *GImGui; | ||||||
|  |     ImGuiIO& io = g.IO; | ||||||
|     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: | ||||||
| @@ -4020,48 +4026,61 @@ void ImGui::UpdateHoveredWindowAndCaptureFlags() | |||||||
|         clear_hovered_windows = true; |         clear_hovered_windows = true; | ||||||
|  |  | ||||||
|     // Disabled mouse? |     // Disabled mouse? | ||||||
|     if (g.IO.ConfigFlags & ImGuiConfigFlags_NoMouse) |     if (io.ConfigFlags & ImGuiConfigFlags_NoMouse) | ||||||
|         clear_hovered_windows = true; |         clear_hovered_windows = true; | ||||||
|  |  | ||||||
|     // We track click ownership. When clicked outside of a window the click is owned by the application and won't report hovering nor request capture even while dragging over our windows afterward. |     // We track click ownership. When clicked outside of a window the click is owned by the application and | ||||||
|     int mouse_earliest_button_down = -1; |     // won't report hovering nor request capture even while dragging over our windows afterward. | ||||||
|  |     const bool has_open_popup = (g.OpenPopupStack.Size > 0); | ||||||
|  |     const bool has_open_modal = (modal_window != NULL); | ||||||
|  |     int mouse_earliest_down = -1; | ||||||
|     bool mouse_any_down = false; |     bool mouse_any_down = false; | ||||||
|     for (int i = 0; i < IM_ARRAYSIZE(g.IO.MouseDown); i++) |     for (int i = 0; i < IM_ARRAYSIZE(io.MouseDown); i++) | ||||||
|     { |     { | ||||||
|         if (g.IO.MouseClicked[i]) |         if (io.MouseClicked[i]) | ||||||
|             g.IO.MouseDownOwned[i] = (g.HoveredWindow != NULL) || (g.OpenPopupStack.Size > 0); |         { | ||||||
|         mouse_any_down |= g.IO.MouseDown[i]; |             io.MouseDownOwned[i] = (g.HoveredWindow != NULL) || has_open_popup; | ||||||
|         if (g.IO.MouseDown[i]) |             io.MouseDownOwnedUnlessPopupClose[i] = (g.HoveredWindow != NULL) || has_open_modal; | ||||||
|             if (mouse_earliest_button_down == -1 || g.IO.MouseClickedTime[i] < g.IO.MouseClickedTime[mouse_earliest_button_down]) |         } | ||||||
|                 mouse_earliest_button_down = i; |         mouse_any_down |= io.MouseDown[i]; | ||||||
|  |         if (io.MouseDown[i]) | ||||||
|  |             if (mouse_earliest_down == -1 || io.MouseClickedTime[i] < io.MouseClickedTime[mouse_earliest_down]) | ||||||
|  |                 mouse_earliest_down = i; | ||||||
|     } |     } | ||||||
|     const bool mouse_avail_to_imgui = (mouse_earliest_button_down == -1) || g.IO.MouseDownOwned[mouse_earliest_button_down]; |     const bool mouse_avail = (mouse_earliest_down == -1) || io.MouseDownOwned[mouse_earliest_down]; | ||||||
|  |     const bool mouse_avail_unless_popup_close = (mouse_earliest_down == -1) || io.MouseDownOwnedUnlessPopupClose[mouse_earliest_down]; | ||||||
|  |  | ||||||
|     // If mouse was first clicked outside of ImGui bounds we also cancel out hovering. |     // If mouse was first clicked outside of ImGui bounds we also cancel out hovering. | ||||||
|     // FIXME: For patterns of drag and drop across OS windows, we may need to rework/remove this test (first committed 311c0ca9 on 2015/02) |     // FIXME: For patterns of drag and drop across OS windows, we may need to rework/remove this test (first committed 311c0ca9 on 2015/02) | ||||||
|     const bool mouse_dragging_extern_payload = g.DragDropActive && (g.DragDropSourceFlags & ImGuiDragDropFlags_SourceExtern) != 0; |     const bool mouse_dragging_extern_payload = g.DragDropActive && (g.DragDropSourceFlags & ImGuiDragDropFlags_SourceExtern) != 0; | ||||||
|     if (!mouse_avail_to_imgui && !mouse_dragging_extern_payload) |     if (!mouse_avail && !mouse_dragging_extern_payload) | ||||||
|         clear_hovered_windows = true; |         clear_hovered_windows = true; | ||||||
|  |  | ||||||
|     if (clear_hovered_windows) |     if (clear_hovered_windows) | ||||||
|         g.HoveredWindow = g.HoveredWindowUnderMovingWindow = NULL; |         g.HoveredWindow = g.HoveredWindowUnderMovingWindow = NULL; | ||||||
|  |  | ||||||
|     // Update io.WantCaptureMouse for the user application (true = dispatch mouse info to imgui, false = dispatch mouse info to Dear ImGui + app) |     // Update io.WantCaptureMouse for the user application (true = dispatch mouse info to Dear ImGui only, false = dispatch mouse to Dear ImGui + underlying app) | ||||||
|  |     // Update io.WantCaptureMouseAllowPopupClose (experimental) to give a chance for app to react to popup closure with a drag | ||||||
|     if (g.WantCaptureMouseNextFrame != -1) |     if (g.WantCaptureMouseNextFrame != -1) | ||||||
|         g.IO.WantCaptureMouse = (g.WantCaptureMouseNextFrame != 0); |     { | ||||||
|  |         io.WantCaptureMouse = io.WantCaptureMouseUnlessPopupClose = (g.WantCaptureMouseNextFrame != 0); | ||||||
|  |     } | ||||||
|     else |     else | ||||||
|         g.IO.WantCaptureMouse = (mouse_avail_to_imgui && (g.HoveredWindow != NULL || mouse_any_down)) || (g.OpenPopupStack.Size > 0); |     { | ||||||
|  |         io.WantCaptureMouse = (mouse_avail && (g.HoveredWindow != NULL || mouse_any_down)) || has_open_popup; | ||||||
|  |         io.WantCaptureMouseUnlessPopupClose = (mouse_avail_unless_popup_close && (g.HoveredWindow != NULL || mouse_any_down)) || has_open_modal; | ||||||
|  |     } | ||||||
|  |  | ||||||
|     // Update io.WantCaptureKeyboard for the user application (true = dispatch keyboard info to imgui, false = dispatch keyboard info to Dear ImGui + app) |     // Update io.WantCaptureKeyboard for the user application (true = dispatch keyboard info to Dear ImGui only, false = dispatch keyboard info to Dear ImGui + underlying app) | ||||||
|     if (g.WantCaptureKeyboardNextFrame != -1) |     if (g.WantCaptureKeyboardNextFrame != -1) | ||||||
|         g.IO.WantCaptureKeyboard = (g.WantCaptureKeyboardNextFrame != 0); |         io.WantCaptureKeyboard = (g.WantCaptureKeyboardNextFrame != 0); | ||||||
|     else |     else | ||||||
|         g.IO.WantCaptureKeyboard = (g.ActiveId != 0) || (modal_window != NULL); |         io.WantCaptureKeyboard = (g.ActiveId != 0) || (modal_window != NULL); | ||||||
|     if (g.IO.NavActive && (g.IO.ConfigFlags & ImGuiConfigFlags_NavEnableKeyboard) && !(g.IO.ConfigFlags & ImGuiConfigFlags_NavNoCaptureKeyboard)) |     if (io.NavActive && (io.ConfigFlags & ImGuiConfigFlags_NavEnableKeyboard) && !(io.ConfigFlags & ImGuiConfigFlags_NavNoCaptureKeyboard)) | ||||||
|         g.IO.WantCaptureKeyboard = true; |         io.WantCaptureKeyboard = true; | ||||||
|  |  | ||||||
|     // Update io.WantTextInput flag, this is to allow systems without a keyboard (e.g. mobile, hand-held) to show a software keyboard if possible |     // Update io.WantTextInput flag, this is to allow systems without a keyboard (e.g. mobile, hand-held) to show a software keyboard if possible | ||||||
|     g.IO.WantTextInput = (g.WantTextInputNextFrame != -1) ? (g.WantTextInputNextFrame != 0) : false; |     io.WantTextInput = (g.WantTextInputNextFrame != -1) ? (g.WantTextInputNextFrame != 0) : false; | ||||||
| } | } | ||||||
|  |  | ||||||
| ImGuiKeyModFlags ImGui::GetMergedKeyModFlags() | ImGuiKeyModFlags ImGui::GetMergedKeyModFlags() | ||||||
| @@ -6687,18 +6706,23 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) | |||||||
|                 window->DrawList->AddRectFilled(bb.Min, bb.Max, GetColorU32(ImGuiCol_NavWindowingHighlight, g.NavWindowingHighlightAlpha * 0.25f), g.Style.WindowRounding); |                 window->DrawList->AddRectFilled(bb.Min, bb.Max, GetColorU32(ImGuiCol_NavWindowingHighlight, g.NavWindowingHighlightAlpha * 0.25f), g.Style.WindowRounding); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         // Since 1.71, child window can render their decoration (bg color, border, scrollbars, etc.) within their parent to save a draw call. |         // Child windows can render their decoration (bg color, border, scrollbars, etc.) within their parent to save a draw call (since 1.71) | ||||||
|         // When using overlapping child windows, this will break the assumption that child z-order is mapped to submission order. |         // When using overlapping child windows, this will break the assumption that child z-order is mapped to submission order. | ||||||
|         // We disable this when the parent window has zero vertices, which is a common pattern leading to laying out multiple overlapping child. |         // FIXME: User code may rely on explicit sorting of overlapping child window and would need to disable this somehow. Please get in contact if you are affected (github #4493) | ||||||
|         // We also disabled this when we have dimming overlay behind this specific one child. |  | ||||||
|         // FIXME: More code may rely on explicit sorting of overlapping child window and would need to disable this somehow. Please get in contact if you are affected. |  | ||||||
|         const bool is_undocked_or_docked_visible = !window->DockIsActive || window->DockTabIsVisible; |         const bool is_undocked_or_docked_visible = !window->DockIsActive || window->DockTabIsVisible; | ||||||
|         if (is_undocked_or_docked_visible) |         if (is_undocked_or_docked_visible) | ||||||
|         { |         { | ||||||
|             bool render_decorations_in_parent = false; |             bool render_decorations_in_parent = false; | ||||||
|             if ((flags & ImGuiWindowFlags_ChildWindow) && !(flags & ImGuiWindowFlags_Popup) && !window_is_child_tooltip) |             if ((flags & ImGuiWindowFlags_ChildWindow) && !(flags & ImGuiWindowFlags_Popup) && !window_is_child_tooltip) | ||||||
|                 if (window->DrawList->CmdBuffer.back().ElemCount == 0 && parent_window->DrawList->VtxBuffer.Size > 0) |             { | ||||||
|  |                 // - We test overlap with the previous child window only (testing all would end up being O(log N) not a good investment here) | ||||||
|  |                 // - We disable this when the parent window has zero vertices, which is a common pattern leading to laying out multiple overlapping childs | ||||||
|  |                 ImGuiWindow* previous_child = parent_window->DC.ChildWindows.Size >= 2 ? parent_window->DC.ChildWindows[parent_window->DC.ChildWindows.Size - 2] : NULL; | ||||||
|  |                 bool previous_child_overlapping = previous_child ? previous_child->Rect().Overlaps(window->Rect()) : false; | ||||||
|  |                 bool parent_is_empty = parent_window->DrawList->VtxBuffer.Size > 0; | ||||||
|  |                 if (window->DrawList->CmdBuffer.back().ElemCount == 0 && parent_is_empty && !previous_child_overlapping) | ||||||
|                     render_decorations_in_parent = true; |                     render_decorations_in_parent = true; | ||||||
|  |             } | ||||||
|             if (render_decorations_in_parent) |             if (render_decorations_in_parent) | ||||||
|                 window->DrawList = parent_window->DrawList; |                 window->DrawList = parent_window->DrawList; | ||||||
|  |  | ||||||
| @@ -7162,7 +7186,7 @@ void ImGui::PopItemFlag() | |||||||
| } | } | ||||||
|  |  | ||||||
| // BeginDisabled()/EndDisabled() | // BeginDisabled()/EndDisabled() | ||||||
| // - Those can be nested but this cannot be used to enable an already disabled section (a single BeginDisabled(true) in the stack is enough to keep things disabled) | // - Those can be nested but it cannot be used to enable an already disabled section (a single BeginDisabled(true) in the stack is enough to keep everything disabled) | ||||||
| // - Visually this is currently altering alpha, but it is expected that in a future styling system this would work differently. | // - Visually this is currently altering alpha, but it is expected that in a future styling system this would work differently. | ||||||
| // - Feedback welcome at https://github.com/ocornut/imgui/issues/211 | // - Feedback welcome at https://github.com/ocornut/imgui/issues/211 | ||||||
| // - BeginDisabled(false) essentially does nothing useful but is provided to facilitate use of boolean expressions. If you can avoid calling BeginDisabled(False)/EndDisabled() best to avoid it. | // - BeginDisabled(false) essentially does nothing useful but is provided to facilitate use of boolean expressions. If you can avoid calling BeginDisabled(False)/EndDisabled() best to avoid it. | ||||||
| @@ -7173,7 +7197,10 @@ void ImGui::BeginDisabled(bool disabled) | |||||||
|     bool was_disabled = (g.CurrentItemFlags & ImGuiItemFlags_Disabled) != 0; |     bool was_disabled = (g.CurrentItemFlags & ImGuiItemFlags_Disabled) != 0; | ||||||
|     g.DisabledAlphaBackup = g.Style.Alpha; |     g.DisabledAlphaBackup = g.Style.Alpha; | ||||||
|     if (!was_disabled && disabled) |     if (!was_disabled && disabled) | ||||||
|  |     { | ||||||
|  |         g.DisabledAlphaBackup = g.Style.Alpha; | ||||||
|         g.Style.Alpha *= g.Style.DisabledAlpha; // PushStyleVar(ImGuiStyleVar_Alpha, g.Style.Alpha * g.Style.DisabledAlpha); |         g.Style.Alpha *= g.Style.DisabledAlpha; // PushStyleVar(ImGuiStyleVar_Alpha, g.Style.Alpha * g.Style.DisabledAlpha); | ||||||
|  |     } | ||||||
|     if (was_disabled || disabled) |     if (was_disabled || disabled) | ||||||
|         g.CurrentItemFlags |= ImGuiItemFlags_Disabled; |         g.CurrentItemFlags |= ImGuiItemFlags_Disabled; | ||||||
|     g.ItemFlagsStack.push_back(g.CurrentItemFlags); |     g.ItemFlagsStack.push_back(g.CurrentItemFlags); | ||||||
| @@ -7185,7 +7212,7 @@ void ImGui::EndDisabled() | |||||||
|     bool was_disabled = (g.CurrentItemFlags & ImGuiItemFlags_Disabled) != 0; |     bool was_disabled = (g.CurrentItemFlags & ImGuiItemFlags_Disabled) != 0; | ||||||
|     //PopItemFlag(); |     //PopItemFlag(); | ||||||
|     g.ItemFlagsStack.pop_back(); |     g.ItemFlagsStack.pop_back(); | ||||||
|     g.CurrentItemFlags &= ~ImGuiItemFlags_Disabled; |     g.CurrentItemFlags = g.ItemFlagsStack.back(); | ||||||
|     if (was_disabled && (g.CurrentItemFlags & ImGuiItemFlags_Disabled) == 0) |     if (was_disabled && (g.CurrentItemFlags & ImGuiItemFlags_Disabled) == 0) | ||||||
|         g.Style.Alpha = g.DisabledAlphaBackup; //PopStyleVar(); |         g.Style.Alpha = g.DisabledAlphaBackup; //PopStyleVar(); | ||||||
| } | } | ||||||
| @@ -8048,7 +8075,6 @@ void ImGuiStackSizes::CompareWithCurrentState() | |||||||
| // - GetContentRegionMaxAbs() [Internal] | // - GetContentRegionMaxAbs() [Internal] | ||||||
| // - GetContentRegionAvail(), | // - GetContentRegionAvail(), | ||||||
| // - GetWindowContentRegionMin(), GetWindowContentRegionMax() | // - GetWindowContentRegionMin(), GetWindowContentRegionMax() | ||||||
| // - GetWindowContentRegionWidth() |  | ||||||
| // - BeginGroup() | // - BeginGroup() | ||||||
| // - EndGroup() | // - EndGroup() | ||||||
| // Also see in imgui_widgets: tab bars, columns. | // Also see in imgui_widgets: tab bars, columns. | ||||||
| @@ -8416,12 +8442,6 @@ ImVec2 ImGui::GetWindowContentRegionMax() | |||||||
|     return window->ContentRegionRect.Max - window->Pos; |     return window->ContentRegionRect.Max - window->Pos; | ||||||
| } | } | ||||||
|  |  | ||||||
| float ImGui::GetWindowContentRegionWidth() |  | ||||||
| { |  | ||||||
|     ImGuiWindow* window = GImGui->CurrentWindow; |  | ||||||
|     return window->ContentRegionRect.GetWidth(); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Lock horizontal starting position + capture group bounding box into one "item" (so you can use IsItemHovered() or layout primitives such as SameLine() on whole group, etc.) | // Lock horizontal starting position + capture group bounding box into one "item" (so you can use IsItemHovered() or layout primitives such as SameLine() on whole group, etc.) | ||||||
| // Groups are currently a mishmash of functionalities which should perhaps be clarified and separated. | // Groups are currently a mishmash of functionalities which should perhaps be clarified and separated. | ||||||
| void ImGui::BeginGroup() | void ImGui::BeginGroup() | ||||||
| @@ -9074,7 +9094,7 @@ void ImGui::EndPopup() | |||||||
|     IM_ASSERT(window->Flags & ImGuiWindowFlags_Popup);  // Mismatched BeginPopup()/EndPopup() calls |     IM_ASSERT(window->Flags & ImGuiWindowFlags_Popup);  // Mismatched BeginPopup()/EndPopup() calls | ||||||
|     IM_ASSERT(g.BeginPopupStack.Size > 0); |     IM_ASSERT(g.BeginPopupStack.Size > 0); | ||||||
|  |  | ||||||
|     // Make all menus and popups wrap around for now, may need to expose that policy. |     // Make all menus and popups wrap around for now, may need to expose that policy (e.g. focus scope could include wrap/loop policy flags used by new move requests) | ||||||
|     if (g.NavWindow == window) |     if (g.NavWindow == window) | ||||||
|         NavMoveRequestTryWrapping(window, ImGuiNavMoveFlags_LoopY); |         NavMoveRequestTryWrapping(window, ImGuiNavMoveFlags_LoopY); | ||||||
|  |  | ||||||
| @@ -9587,26 +9607,26 @@ void ImGui::NavMoveRequestCancel() | |||||||
|     NavUpdateAnyRequestFlag(); |     NavUpdateAnyRequestFlag(); | ||||||
| } | } | ||||||
|  |  | ||||||
| void ImGui::NavMoveRequestForward(ImGuiDir move_dir, ImGuiDir clip_dir, const ImRect& bb_rel, ImGuiNavMoveFlags move_flags) | // Forward will reuse the move request again on the next frame (generally with modifications done to it) | ||||||
|  | void ImGui::NavMoveRequestForward(ImGuiDir move_dir, ImGuiDir clip_dir, ImGuiNavMoveFlags move_flags) | ||||||
| { | { | ||||||
|     ImGuiContext& g = *GImGui; |     ImGuiContext& g = *GImGui; | ||||||
|     IM_ASSERT(g.NavMoveRequestForward == ImGuiNavForward_None); |     IM_ASSERT(g.NavMoveRequestForwardToNextFrame == false); | ||||||
|     NavMoveRequestCancel(); |     NavMoveRequestCancel(); | ||||||
|  |     g.NavMoveRequestForwardToNextFrame = true; | ||||||
|     g.NavMoveDir = move_dir; |     g.NavMoveDir = move_dir; | ||||||
|     g.NavMoveClipDir = clip_dir; |     g.NavMoveClipDir = clip_dir; | ||||||
|     g.NavMoveRequestForward = ImGuiNavForward_ForwardQueued; |     g.NavMoveRequestFlags = move_flags | ImGuiNavMoveFlags_Forwarded; | ||||||
|     g.NavMoveRequestFlags = move_flags; |  | ||||||
|     g.NavWindow->NavRectRel[g.NavLayer] = bb_rel; |  | ||||||
| } | } | ||||||
|  |  | ||||||
| void ImGui::NavMoveRequestTryWrapping(ImGuiWindow* window, ImGuiNavMoveFlags move_flags) | // Navigation wrap-around logic is delayed to the end of the frame because this operation is only valid after entire | ||||||
|  | // popup is assembled and in case of appended popups it is not clear which EndPopup() call is final. | ||||||
|  | void ImGui::NavMoveRequestTryWrapping(ImGuiWindow* window, ImGuiNavMoveFlags wrap_flags) | ||||||
| { | { | ||||||
|     ImGuiContext& g = *GImGui; |     ImGuiContext& g = *GImGui; | ||||||
|  |     IM_ASSERT(wrap_flags != 0); // Call with _WrapX, _WrapY, _LoopX, _LoopY | ||||||
|     // Navigation wrap-around logic is delayed to the end of the frame because this operation is only valid after entire |     if (g.NavWindow == window && g.NavMoveRequest && g.NavLayer == ImGuiNavLayer_Main) | ||||||
|     // popup is assembled and in case of appended popups it is not clear which EndPopup() call is final. |         g.NavMoveRequestFlags |= wrap_flags; | ||||||
|     g.NavWrapRequestWindow = window; |  | ||||||
|     g.NavWrapRequestFlags = move_flags; |  | ||||||
| } | } | ||||||
|  |  | ||||||
| // FIXME: This could be replaced by updating a frame number in each window when (window == NavWindow) and (NavLayer == 0). | // FIXME: This could be replaced by updating a frame number in each window when (window == NavWindow) and (NavLayer == 0). | ||||||
| @@ -9756,16 +9776,14 @@ static void ImGui::NavUpdate() | |||||||
|     ImGuiIO& io = g.IO; |     ImGuiIO& io = g.IO; | ||||||
|  |  | ||||||
|     io.WantSetMousePos = false; |     io.WantSetMousePos = false; | ||||||
|     g.NavWrapRequestWindow = NULL; |  | ||||||
|     g.NavWrapRequestFlags = ImGuiNavMoveFlags_None; |  | ||||||
| #if 0 | #if 0 | ||||||
|     if (g.NavScoringCount > 0) IMGUI_DEBUG_LOG("NavScoringCount %d for '%s' layer %d (Init:%d, Move:%d)\n", g.FrameCount, g.NavScoringCount, g.NavWindow ? g.NavWindow->Name : "NULL", g.NavLayer, g.NavInitRequest || g.NavInitResultId != 0, g.NavMoveRequest); |     if (g.NavScoringCount > 0) IMGUI_DEBUG_LOG("NavScoringCount %d for '%s' layer %d (Init:%d, Move:%d)\n", g.FrameCount, g.NavScoringCount, g.NavWindow ? g.NavWindow->Name : "NULL", g.NavLayer, g.NavInitRequest || g.NavInitResultId != 0, g.NavMoveRequest); | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
|     // Set input source as Gamepad when buttons are pressed (as some features differs when used with Gamepad vs Keyboard) |     // Set input source as Gamepad when buttons are pressed (as some features differs when used with Gamepad vs Keyboard) | ||||||
|     // (do it before we map Keyboard input!) |     // (do it before we map Keyboard input!) | ||||||
|     bool nav_keyboard_active = (io.ConfigFlags & ImGuiConfigFlags_NavEnableKeyboard) != 0; |     const bool nav_keyboard_active = (io.ConfigFlags & ImGuiConfigFlags_NavEnableKeyboard) != 0; | ||||||
|     bool nav_gamepad_active = (io.ConfigFlags & ImGuiConfigFlags_NavEnableGamepad) != 0 && (io.BackendFlags & ImGuiBackendFlags_HasGamepad) != 0; |     const bool nav_gamepad_active = (io.ConfigFlags & ImGuiConfigFlags_NavEnableGamepad) != 0 && (io.BackendFlags & ImGuiBackendFlags_HasGamepad) != 0; | ||||||
|     if (nav_gamepad_active && g.NavInputSource != ImGuiInputSource_Gamepad) |     if (nav_gamepad_active && g.NavInputSource != ImGuiInputSource_Gamepad) | ||||||
|     { |     { | ||||||
|         if (io.NavInputs[ImGuiNavInput_Activate] > 0.0f || io.NavInputs[ImGuiNavInput_Input] > 0.0f || io.NavInputs[ImGuiNavInput_Cancel] > 0.0f || io.NavInputs[ImGuiNavInput_Menu] > 0.0f |         if (io.NavInputs[ImGuiNavInput_Activate] > 0.0f || io.NavInputs[ImGuiNavInput_Input] > 0.0f || io.NavInputs[ImGuiNavInput_Cancel] > 0.0f || io.NavInputs[ImGuiNavInput_Menu] > 0.0f | ||||||
| @@ -9804,16 +9822,8 @@ static void ImGui::NavUpdate() | |||||||
|  |  | ||||||
|     // Process navigation move request |     // Process navigation move request | ||||||
|     if (g.NavMoveRequest) |     if (g.NavMoveRequest) | ||||||
|         NavUpdateMoveResult(); |         NavMoveRequestApplyResult(); | ||||||
|  |     g.NavMoveRequest = false; | ||||||
|     // When a forwarded move request failed, we restore the highlight that we disabled during the forward frame |  | ||||||
|     if (g.NavMoveRequestForward == ImGuiNavForward_ForwardActive) |  | ||||||
|     { |  | ||||||
|         IM_ASSERT(g.NavMoveRequest); |  | ||||||
|         if (g.NavMoveResultLocal.ID == 0 && g.NavMoveResultOther.ID == 0) |  | ||||||
|             g.NavDisableHighlight = false; |  | ||||||
|         g.NavMoveRequestForward = ImGuiNavForward_None; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     // Apply application mouse position movement, after we had a chance to process move request result. |     // Apply application mouse position movement, after we had a chance to process move request result. | ||||||
|     if (g.NavMousePosDirty && g.NavIdIsAlive) |     if (g.NavMousePosDirty && g.NavIdIsAlive) | ||||||
| @@ -9831,7 +9841,7 @@ static void ImGui::NavUpdate() | |||||||
|     g.NavJustTabbedId = 0; |     g.NavJustTabbedId = 0; | ||||||
|     IM_ASSERT(g.NavLayer == 0 || g.NavLayer == 1); |     IM_ASSERT(g.NavLayer == 0 || g.NavLayer == 1); | ||||||
|  |  | ||||||
|     // Store our return window (for returning from Layer 1 to Layer 0) and clear it as soon as we step back in our own Layer 0 |     // Store our return window (for returning from Menu Layer to Main Layer) and clear it as soon as we step back in our own Layer 0 | ||||||
|     if (g.NavWindow) |     if (g.NavWindow) | ||||||
|         NavSaveLastChildNavWindowIntoParent(g.NavWindow); |         NavSaveLastChildNavWindowIntoParent(g.NavWindow); | ||||||
|     if (g.NavWindow && g.NavWindow->NavLastChildNavWindow != NULL && g.NavLayer == ImGuiNavLayer_Main) |     if (g.NavWindow && g.NavWindow->NavLastChildNavWindow != NULL && g.NavLayer == ImGuiNavLayer_Main) | ||||||
| @@ -9845,43 +9855,7 @@ static void ImGui::NavUpdate() | |||||||
|     io.NavVisible = (io.NavActive && g.NavId != 0 && !g.NavDisableHighlight) || (g.NavWindowingTarget != NULL); |     io.NavVisible = (io.NavActive && g.NavId != 0 && !g.NavDisableHighlight) || (g.NavWindowingTarget != NULL); | ||||||
|  |  | ||||||
|     // Process NavCancel input (to close a popup, get back to parent, clear focus) |     // Process NavCancel input (to close a popup, get back to parent, clear focus) | ||||||
|     if (IsNavInputTest(ImGuiNavInput_Cancel, ImGuiInputReadMode_Pressed)) |     NavUpdateCancelRequest(); | ||||||
|     { |  | ||||||
|         IMGUI_DEBUG_LOG_NAV("[nav] ImGuiNavInput_Cancel\n"); |  | ||||||
|         if (g.ActiveId != 0) |  | ||||||
|         { |  | ||||||
|             if (!IsActiveIdUsingNavInput(ImGuiNavInput_Cancel)) |  | ||||||
|                 ClearActiveID(); |  | ||||||
|         } |  | ||||||
|         else if (g.NavLayer != ImGuiNavLayer_Main) |  | ||||||
|         { |  | ||||||
|             // Leave the "menu" layer |  | ||||||
|             NavRestoreLayer(ImGuiNavLayer_Main); |  | ||||||
|         } |  | ||||||
|         else if (g.NavWindow && g.NavWindow != g.NavWindow->RootWindow && !(g.NavWindow->Flags & ImGuiWindowFlags_Popup) && g.NavWindow->ParentWindow) |  | ||||||
|         { |  | ||||||
|             // Exit child window |  | ||||||
|             ImGuiWindow* child_window = g.NavWindow; |  | ||||||
|             ImGuiWindow* parent_window = g.NavWindow->ParentWindow; |  | ||||||
|             IM_ASSERT(child_window->ChildId != 0); |  | ||||||
|             ImRect child_rect = child_window->Rect(); |  | ||||||
|             FocusWindow(parent_window); |  | ||||||
|             SetNavID(child_window->ChildId, ImGuiNavLayer_Main, 0, ImRect(child_rect.Min - parent_window->Pos, child_rect.Max - parent_window->Pos)); |  | ||||||
|         } |  | ||||||
|         else if (g.OpenPopupStack.Size > 0) |  | ||||||
|         { |  | ||||||
|             // Close open popup/menu |  | ||||||
|             if (!(g.OpenPopupStack.back().Window->Flags & ImGuiWindowFlags_Modal)) |  | ||||||
|                 ClosePopupToLevel(g.OpenPopupStack.Size - 1, true); |  | ||||||
|         } |  | ||||||
|         else |  | ||||||
|         { |  | ||||||
|             // Clear NavLastId for popups but keep it for regular child window so we can leave one and come back where we were |  | ||||||
|             if (g.NavWindow && ((g.NavWindow->Flags & ImGuiWindowFlags_Popup) || !(g.NavWindow->Flags & ImGuiWindowFlags_ChildWindow))) |  | ||||||
|                 g.NavWindow->NavLastIds[0] = 0; |  | ||||||
|             g.NavId = g.NavFocusScopeId = 0; |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     // Process manual activation request |     // Process manual activation request | ||||||
|     g.NavActivateId = g.NavActivateDownId = g.NavActivatePressedId = g.NavInputId = 0; |     g.NavActivateId = g.NavActivateDownId = g.NavActivatePressedId = g.NavInputId = 0; | ||||||
| @@ -9902,59 +9876,14 @@ static void ImGui::NavUpdate() | |||||||
|         g.NavDisableHighlight = true; |         g.NavDisableHighlight = true; | ||||||
|     if (g.NavActivateId != 0) |     if (g.NavActivateId != 0) | ||||||
|         IM_ASSERT(g.NavActivateDownId == g.NavActivateId); |         IM_ASSERT(g.NavActivateDownId == g.NavActivateId); | ||||||
|     g.NavMoveRequest = false; |  | ||||||
|  |  | ||||||
|     // Process programmatic activation request |     // Process programmatic activation request | ||||||
|     if (g.NavNextActivateId != 0) |     if (g.NavNextActivateId != 0) | ||||||
|         g.NavActivateId = g.NavActivateDownId = g.NavActivatePressedId = g.NavInputId = g.NavNextActivateId; |         g.NavActivateId = g.NavActivateDownId = g.NavActivatePressedId = g.NavInputId = g.NavNextActivateId; | ||||||
|     g.NavNextActivateId = 0; |     g.NavNextActivateId = 0; | ||||||
|  |  | ||||||
|     // Initiate directional inputs request |     // Process move requests | ||||||
|     if (g.NavMoveRequestForward == ImGuiNavForward_None) |     NavUpdateCreateMoveRequest(); | ||||||
|     { |  | ||||||
|         g.NavMoveDir = ImGuiDir_None; |  | ||||||
|         g.NavMoveRequestFlags = ImGuiNavMoveFlags_None; |  | ||||||
|         if (g.NavWindow && !g.NavWindowingTarget && !(g.NavWindow->Flags & ImGuiWindowFlags_NoNavInputs)) |  | ||||||
|         { |  | ||||||
|             const ImGuiInputReadMode read_mode = ImGuiInputReadMode_Repeat; |  | ||||||
|             if (!IsActiveIdUsingNavDir(ImGuiDir_Left)  && (IsNavInputTest(ImGuiNavInput_DpadLeft,  read_mode) || IsNavInputTest(ImGuiNavInput_KeyLeft_,  read_mode))) { g.NavMoveDir = ImGuiDir_Left; } |  | ||||||
|             if (!IsActiveIdUsingNavDir(ImGuiDir_Right) && (IsNavInputTest(ImGuiNavInput_DpadRight, read_mode) || IsNavInputTest(ImGuiNavInput_KeyRight_, read_mode))) { g.NavMoveDir = ImGuiDir_Right; } |  | ||||||
|             if (!IsActiveIdUsingNavDir(ImGuiDir_Up)    && (IsNavInputTest(ImGuiNavInput_DpadUp,    read_mode) || IsNavInputTest(ImGuiNavInput_KeyUp_,    read_mode))) { g.NavMoveDir = ImGuiDir_Up; } |  | ||||||
|             if (!IsActiveIdUsingNavDir(ImGuiDir_Down)  && (IsNavInputTest(ImGuiNavInput_DpadDown,  read_mode) || IsNavInputTest(ImGuiNavInput_KeyDown_,  read_mode))) { g.NavMoveDir = ImGuiDir_Down; } |  | ||||||
|         } |  | ||||||
|         g.NavMoveClipDir = g.NavMoveDir; |  | ||||||
|     } |  | ||||||
|     else |  | ||||||
|     { |  | ||||||
|         // Forwarding previous request (which has been modified, e.g. wrap around menus rewrite the requests with a starting rectangle at the other side of the window) |  | ||||||
|         // (Preserve g.NavMoveRequestFlags, g.NavMoveClipDir which were set by the NavMoveRequestForward() function) |  | ||||||
|         IM_ASSERT(g.NavMoveDir != ImGuiDir_None && g.NavMoveClipDir != ImGuiDir_None); |  | ||||||
|         IM_ASSERT(g.NavMoveRequestForward == ImGuiNavForward_ForwardQueued); |  | ||||||
|         IMGUI_DEBUG_LOG_NAV("[nav] NavMoveRequestForward %d\n", g.NavMoveDir); |  | ||||||
|         g.NavMoveRequestForward = ImGuiNavForward_ForwardActive; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     // Update PageUp/PageDown/Home/End scroll |  | ||||||
|     // FIXME-NAV: Consider enabling those keys even without the master ImGuiConfigFlags_NavEnableKeyboard flag? |  | ||||||
|     float nav_scoring_rect_offset_y = 0.0f; |  | ||||||
|     if (nav_keyboard_active) |  | ||||||
|         nav_scoring_rect_offset_y = NavUpdatePageUpPageDown(); |  | ||||||
|  |  | ||||||
|     // If we initiate a movement request and have no current NavId, we initiate a InitDefautRequest that will be used as a fallback if the direction fails to find a match |  | ||||||
|     if (g.NavMoveDir != ImGuiDir_None) |  | ||||||
|     { |  | ||||||
|         g.NavMoveRequest = true; |  | ||||||
|         g.NavMoveRequestKeyMods = io.KeyMods; |  | ||||||
|         g.NavMoveDirLast = g.NavMoveDir; |  | ||||||
|     } |  | ||||||
|     if (g.NavMoveRequest && g.NavId == 0) |  | ||||||
|     { |  | ||||||
|         IMGUI_DEBUG_LOG_NAV("[nav] NavInitRequest: from move, window \"%s\", layer=%d\n", g.NavWindow->Name, g.NavLayer); |  | ||||||
|         g.NavInitRequest = g.NavInitRequestFromMove = true; |  | ||||||
|         // Reassigning with same value, we're being explicit here. |  | ||||||
|         g.NavInitResultId = 0;     // -V1048 |  | ||||||
|         g.NavDisableHighlight = false; |  | ||||||
|     } |  | ||||||
|     NavUpdateAnyRequestFlag(); |     NavUpdateAnyRequestFlag(); | ||||||
|  |  | ||||||
|     // Scrolling |     // Scrolling | ||||||
| @@ -9963,7 +9892,7 @@ static void ImGui::NavUpdate() | |||||||
|         // *Fallback* manual-scroll with Nav directional keys when window has no navigable item |         // *Fallback* manual-scroll with Nav directional keys when window has no navigable item | ||||||
|         ImGuiWindow* window = g.NavWindow; |         ImGuiWindow* window = g.NavWindow; | ||||||
|         const float scroll_speed = IM_ROUND(window->CalcFontSize() * 100 * io.DeltaTime); // We need round the scrolling speed because sub-pixel scroll isn't reliably supported. |         const float scroll_speed = IM_ROUND(window->CalcFontSize() * 100 * io.DeltaTime); // We need round the scrolling speed because sub-pixel scroll isn't reliably supported. | ||||||
|         if (window->DC.NavLayersActiveMask == 0x00 && window->DC.NavHasScroll && g.NavMoveRequest) |         if (window->DC.NavLayersActiveMask == 0x00 && window->DC.NavHasScroll && g.NavMoveRequest) //-V560 | ||||||
|         { |         { | ||||||
|             if (g.NavMoveDir == ImGuiDir_Left || g.NavMoveDir == ImGuiDir_Right) |             if (g.NavMoveDir == ImGuiDir_Left || g.NavMoveDir == ImGuiDir_Right) | ||||||
|                 SetScrollX(window, ImFloor(window->Scroll.x + ((g.NavMoveDir == ImGuiDir_Left) ? -1.0f : +1.0f) * scroll_speed)); |                 SetScrollX(window, ImFloor(window->Scroll.x + ((g.NavMoveDir == ImGuiDir_Left) ? -1.0f : +1.0f) * scroll_speed)); | ||||||
| @@ -9980,36 +9909,7 @@ static void ImGui::NavUpdate() | |||||||
|             SetScrollY(window, ImFloor(window->Scroll.y + scroll_dir.y * scroll_speed)); |             SetScrollY(window, ImFloor(window->Scroll.y + scroll_dir.y * scroll_speed)); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     // Reset search results |     // [DEBUG] | ||||||
|     g.NavMoveResultLocal.Clear(); |  | ||||||
|     g.NavMoveResultLocalVisibleSet.Clear(); |  | ||||||
|     g.NavMoveResultOther.Clear(); |  | ||||||
|  |  | ||||||
|     // When using gamepad, we project the reference nav bounding box into window visible area. |  | ||||||
|     // This is to allow resuming navigation inside the visible area after doing a large amount of scrolling, since with gamepad every movements are relative |  | ||||||
|     // (can't focus a visible object like we can with the mouse). |  | ||||||
|     if (g.NavMoveRequest && g.NavInputSource == ImGuiInputSource_Gamepad && g.NavLayer == ImGuiNavLayer_Main) |  | ||||||
|     { |  | ||||||
|         ImGuiWindow* window = g.NavWindow; |  | ||||||
|         ImRect window_rect_rel(window->InnerRect.Min - window->Pos - ImVec2(1, 1), window->InnerRect.Max - window->Pos + ImVec2(1, 1)); |  | ||||||
|         if (!window_rect_rel.Contains(window->NavRectRel[g.NavLayer])) |  | ||||||
|         { |  | ||||||
|             IMGUI_DEBUG_LOG_NAV("[nav] NavMoveRequest: clamp NavRectRel\n"); |  | ||||||
|             float pad = window->CalcFontSize() * 0.5f; |  | ||||||
|             window_rect_rel.Expand(ImVec2(-ImMin(window_rect_rel.GetWidth(), pad), -ImMin(window_rect_rel.GetHeight(), pad))); // Terrible approximation for the intent of starting navigation from first fully visible item |  | ||||||
|             window->NavRectRel[g.NavLayer].ClipWithFull(window_rect_rel); |  | ||||||
|             g.NavId = g.NavFocusScopeId = 0; |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     // For scoring we use a single segment on the left side our current item bounding box (not touching the edge to avoid box overlap with zero-spaced items) |  | ||||||
|     ImRect nav_rect_rel = (g.NavWindow && !g.NavWindow->NavRectRel[g.NavLayer].IsInverted()) ? g.NavWindow->NavRectRel[g.NavLayer] : ImRect(0, 0, 0, 0); |  | ||||||
|     g.NavScoringRect = g.NavWindow ? ImRect(g.NavWindow->Pos + nav_rect_rel.Min, g.NavWindow->Pos + nav_rect_rel.Max) : ImRect(0, 0, 0, 0); |  | ||||||
|     g.NavScoringRect.TranslateY(nav_scoring_rect_offset_y); |  | ||||||
|     g.NavScoringRect.Min.x = ImMin(g.NavScoringRect.Min.x + 1.0f, g.NavScoringRect.Max.x); |  | ||||||
|     g.NavScoringRect.Max.x = g.NavScoringRect.Min.x; |  | ||||||
|     IM_ASSERT(!g.NavScoringRect.IsInverted()); // Ensure if we have a finite, non-inverted bounding box here will allows us to remove extraneous ImFabs() calls in NavScoreItem(). |  | ||||||
|     //GetForegroundDrawList()->AddRect(g.NavScoringRectScreen.Min, g.NavScoringRectScreen.Max, IM_COL32(255,200,0,255)); // [DEBUG] |  | ||||||
|     g.NavScoringCount = 0; |     g.NavScoringCount = 0; | ||||||
| #if IMGUI_DEBUG_NAV_RECTS | #if IMGUI_DEBUG_NAV_RECTS | ||||||
|     if (g.NavWindow) |     if (g.NavWindow) | ||||||
| @@ -10039,10 +9939,100 @@ static void ImGui::NavUpdateInitResult() | |||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| // Apply result from previous frame navigation directional move request | void ImGui::NavUpdateCreateMoveRequest() | ||||||
| static void ImGui::NavUpdateMoveResult() |  | ||||||
| { | { | ||||||
|     ImGuiContext& g = *GImGui; |     ImGuiContext& g = *GImGui; | ||||||
|  |     ImGuiIO& io = g.IO; | ||||||
|  |     ImGuiWindow* window = g.NavWindow; | ||||||
|  |  | ||||||
|  |     if (g.NavMoveRequestForwardToNextFrame) | ||||||
|  |     { | ||||||
|  |         // Forwarding previous request (which has been modified, e.g. wrap around menus rewrite the requests with a starting rectangle at the other side of the window) | ||||||
|  |         // (preserve most state, which were already set by the NavMoveRequestForward() function) | ||||||
|  |         IM_ASSERT(g.NavMoveDir != ImGuiDir_None && g.NavMoveClipDir != ImGuiDir_None); | ||||||
|  |         IM_ASSERT(g.NavMoveRequestFlags & ImGuiNavMoveFlags_Forwarded); | ||||||
|  |         IMGUI_DEBUG_LOG_NAV("[nav] NavMoveRequestForward %d\n", g.NavMoveDir); | ||||||
|  |         g.NavMoveRequestForwardToNextFrame = false; | ||||||
|  |     } | ||||||
|  |     else | ||||||
|  |     { | ||||||
|  |         // Initiate directional inputs request | ||||||
|  |         g.NavMoveDir = ImGuiDir_None; | ||||||
|  |         g.NavMoveRequestFlags = ImGuiNavMoveFlags_None; | ||||||
|  |         if (window && !g.NavWindowingTarget && !(window->Flags & ImGuiWindowFlags_NoNavInputs)) | ||||||
|  |         { | ||||||
|  |             const ImGuiInputReadMode read_mode = ImGuiInputReadMode_Repeat; | ||||||
|  |             if (!IsActiveIdUsingNavDir(ImGuiDir_Left)  && (IsNavInputTest(ImGuiNavInput_DpadLeft,  read_mode) || IsNavInputTest(ImGuiNavInput_KeyLeft_,  read_mode))) { g.NavMoveDir = ImGuiDir_Left; } | ||||||
|  |             if (!IsActiveIdUsingNavDir(ImGuiDir_Right) && (IsNavInputTest(ImGuiNavInput_DpadRight, read_mode) || IsNavInputTest(ImGuiNavInput_KeyRight_, read_mode))) { g.NavMoveDir = ImGuiDir_Right; } | ||||||
|  |             if (!IsActiveIdUsingNavDir(ImGuiDir_Up)    && (IsNavInputTest(ImGuiNavInput_DpadUp,    read_mode) || IsNavInputTest(ImGuiNavInput_KeyUp_,    read_mode))) { g.NavMoveDir = ImGuiDir_Up; } | ||||||
|  |             if (!IsActiveIdUsingNavDir(ImGuiDir_Down)  && (IsNavInputTest(ImGuiNavInput_DpadDown,  read_mode) || IsNavInputTest(ImGuiNavInput_KeyDown_,  read_mode))) { g.NavMoveDir = ImGuiDir_Down; } | ||||||
|  |         } | ||||||
|  |         g.NavMoveClipDir = g.NavMoveDir; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     // Update PageUp/PageDown/Home/End scroll | ||||||
|  |     // FIXME-NAV: Consider enabling those keys even without the master ImGuiConfigFlags_NavEnableKeyboard flag? | ||||||
|  |     const bool nav_keyboard_active = (io.ConfigFlags & ImGuiConfigFlags_NavEnableKeyboard) != 0; | ||||||
|  |     float nav_scoring_rect_offset_y = 0.0f; | ||||||
|  |     if (nav_keyboard_active) | ||||||
|  |         nav_scoring_rect_offset_y = NavUpdatePageUpPageDown(); | ||||||
|  |  | ||||||
|  |     // If we initiate a movement request and have no current NavId, we initiate a InitDefaultRequest that will be used as a fallback if the direction fails to find a match | ||||||
|  |     if (g.NavMoveDir != ImGuiDir_None) | ||||||
|  |     { | ||||||
|  |         IM_ASSERT(window != NULL); | ||||||
|  |         g.NavMoveRequest = true; | ||||||
|  |         g.NavMoveRequestKeyMods = io.KeyMods; | ||||||
|  |         g.NavMoveDirLast = g.NavMoveDir; | ||||||
|  |         g.NavMoveResultLocal.Clear(); | ||||||
|  |         g.NavMoveResultLocalVisibleSet.Clear(); | ||||||
|  |         g.NavMoveResultOther.Clear(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     // Moving with no reference triggers a init request | ||||||
|  |     if (g.NavMoveRequest && g.NavId == 0) | ||||||
|  |     { | ||||||
|  |         IMGUI_DEBUG_LOG_NAV("[nav] NavInitRequest: from move, window \"%s\", layer=%d\n", g.NavWindow->Name, g.NavLayer); | ||||||
|  |         g.NavInitRequest = g.NavInitRequestFromMove = true; | ||||||
|  |         g.NavInitResultId = 0; | ||||||
|  |         g.NavDisableHighlight = false; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     // When using gamepad, we project the reference nav bounding box into window visible area. | ||||||
|  |     // This is to allow resuming navigation inside the visible area after doing a large amount of scrolling, since with gamepad every movements are relative | ||||||
|  |     // (can't focus a visible object like we can with the mouse). | ||||||
|  |     if (g.NavMoveRequest && g.NavInputSource == ImGuiInputSource_Gamepad && g.NavLayer == ImGuiNavLayer_Main && window != NULL) | ||||||
|  |     { | ||||||
|  |         ImRect window_rect_rel(window->InnerRect.Min - window->Pos - ImVec2(1, 1), window->InnerRect.Max - window->Pos + ImVec2(1, 1)); | ||||||
|  |         if (!window_rect_rel.Contains(window->NavRectRel[g.NavLayer])) | ||||||
|  |         { | ||||||
|  |             IMGUI_DEBUG_LOG_NAV("[nav] NavMoveRequest: clamp NavRectRel\n"); | ||||||
|  |             float pad = window->CalcFontSize() * 0.5f; | ||||||
|  |             window_rect_rel.Expand(ImVec2(-ImMin(window_rect_rel.GetWidth(), pad), -ImMin(window_rect_rel.GetHeight(), pad))); // Terrible approximation for the intent of starting navigation from first fully visible item | ||||||
|  |             window->NavRectRel[g.NavLayer].ClipWithFull(window_rect_rel); | ||||||
|  |             g.NavId = g.NavFocusScopeId = 0; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     // For scoring we use a single segment on the left side our current item bounding box (not touching the edge to avoid box overlap with zero-spaced items) | ||||||
|  |     g.NavScoringRect = ImRect(); | ||||||
|  |     if (window) | ||||||
|  |     { | ||||||
|  |         ImRect nav_rect_rel = !window->NavRectRel[g.NavLayer].IsInverted() ? window->NavRectRel[g.NavLayer] : ImRect(0, 0, 0, 0); | ||||||
|  |         g.NavScoringRect = ImRect(window->Pos + nav_rect_rel.Min, window->Pos + nav_rect_rel.Max); | ||||||
|  |         g.NavScoringRect.TranslateY(nav_scoring_rect_offset_y); | ||||||
|  |         g.NavScoringRect.Min.x = ImMin(g.NavScoringRect.Min.x + 1.0f, g.NavScoringRect.Max.x); | ||||||
|  |         g.NavScoringRect.Max.x = g.NavScoringRect.Min.x; | ||||||
|  |         IM_ASSERT(!g.NavScoringRect.IsInverted()); // Ensure if we have a finite, non-inverted bounding box here will allows us to remove extraneous ImFabs() calls in NavScoreItem(). | ||||||
|  |         //GetForegroundDrawList()->AddRect(g.NavScoringRect.Min, g.NavScoringRect.Max, IM_COL32(255,200,0,255)); // [DEBUG] | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Apply result from previous frame navigation directional move request. Always called from NavUpdate() | ||||||
|  | void ImGui::NavMoveRequestApplyResult() | ||||||
|  | { | ||||||
|  |     ImGuiContext& g = *GImGui; | ||||||
|  |  | ||||||
|     if (g.NavMoveResultLocal.ID == 0 && g.NavMoveResultOther.ID == 0) |     if (g.NavMoveResultLocal.ID == 0 && g.NavMoveResultOther.ID == 0) | ||||||
|     { |     { | ||||||
|         // In a situation when there is no results but NavId != 0, re-enable the Navigation highlight (because g.NavId is not considered as a possible result) |         // In a situation when there is no results but NavId != 0, re-enable the Navigation highlight (because g.NavId is not considered as a possible result) | ||||||
| @@ -10104,7 +10094,54 @@ static void ImGui::NavUpdateMoveResult() | |||||||
|     g.NavDisableMouseHover = g.NavMousePosDirty = true; |     g.NavDisableMouseHover = g.NavMousePosDirty = true; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | // Process NavCancel input (to close a popup, get back to parent, clear focus) | ||||||
|  | // FIXME: In order to support e.g. Escape to clear a selection we'll need: | ||||||
|  | // - either to store the equivalent of ActiveIdUsingKeyInputMask for a FocusScope and test for it. | ||||||
|  | // - either to move most/all of those tests to the epilogue/end functions of the scope they are dealing with (e.g. exit child window in EndChild()) or in EndFrame(), to allow an earlier intercept | ||||||
|  | static void ImGui::NavUpdateCancelRequest() | ||||||
|  | { | ||||||
|  |     ImGuiContext& g = *GImGui; | ||||||
|  |     if (!IsNavInputTest(ImGuiNavInput_Cancel, ImGuiInputReadMode_Pressed)) | ||||||
|  |         return; | ||||||
|  |  | ||||||
|  |     IMGUI_DEBUG_LOG_NAV("[nav] ImGuiNavInput_Cancel\n"); | ||||||
|  |     if (g.ActiveId != 0) | ||||||
|  |     { | ||||||
|  |         if (!IsActiveIdUsingNavInput(ImGuiNavInput_Cancel)) | ||||||
|  |             ClearActiveID(); | ||||||
|  |     } | ||||||
|  |     else if (g.NavLayer != ImGuiNavLayer_Main) | ||||||
|  |     { | ||||||
|  |         // Leave the "menu" layer | ||||||
|  |         NavRestoreLayer(ImGuiNavLayer_Main); | ||||||
|  |     } | ||||||
|  |     else if (g.NavWindow && g.NavWindow != g.NavWindow->RootWindow && !(g.NavWindow->Flags & ImGuiWindowFlags_Popup) && g.NavWindow->ParentWindow) | ||||||
|  |     { | ||||||
|  |         // Exit child window | ||||||
|  |         ImGuiWindow* child_window = g.NavWindow; | ||||||
|  |         ImGuiWindow* parent_window = g.NavWindow->ParentWindow; | ||||||
|  |         IM_ASSERT(child_window->ChildId != 0); | ||||||
|  |         ImRect child_rect = child_window->Rect(); | ||||||
|  |         FocusWindow(parent_window); | ||||||
|  |         SetNavID(child_window->ChildId, ImGuiNavLayer_Main, 0, ImRect(child_rect.Min - parent_window->Pos, child_rect.Max - parent_window->Pos)); | ||||||
|  |     } | ||||||
|  |     else if (g.OpenPopupStack.Size > 0) | ||||||
|  |     { | ||||||
|  |         // Close open popup/menu | ||||||
|  |         if (!(g.OpenPopupStack.back().Window->Flags & ImGuiWindowFlags_Modal)) | ||||||
|  |             ClosePopupToLevel(g.OpenPopupStack.Size - 1, true); | ||||||
|  |     } | ||||||
|  |     else | ||||||
|  |     { | ||||||
|  |         // Clear NavLastId for popups but keep it for regular child window so we can leave one and come back where we were | ||||||
|  |         if (g.NavWindow && ((g.NavWindow->Flags & ImGuiWindowFlags_Popup) || !(g.NavWindow->Flags & ImGuiWindowFlags_ChildWindow))) | ||||||
|  |             g.NavWindow->NavLastIds[0] = 0; | ||||||
|  |         g.NavId = g.NavFocusScopeId = 0; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
| // Handle PageUp/PageDown/Home/End keys | // Handle PageUp/PageDown/Home/End keys | ||||||
|  | // FIXME-NAV: how to get Home/End to aim at the beginning/end of a 2D grid? | ||||||
| static float ImGui::NavUpdatePageUpPageDown() | static float ImGui::NavUpdatePageUpPageDown() | ||||||
| { | { | ||||||
|     ImGuiContext& g = *GImGui; |     ImGuiContext& g = *GImGui; | ||||||
| @@ -10120,60 +10157,60 @@ static float ImGui::NavUpdatePageUpPageDown() | |||||||
|     const bool page_down_held = IsKeyDown(io.KeyMap[ImGuiKey_PageDown]) && !IsActiveIdUsingKey(ImGuiKey_PageDown); |     const bool page_down_held = IsKeyDown(io.KeyMap[ImGuiKey_PageDown]) && !IsActiveIdUsingKey(ImGuiKey_PageDown); | ||||||
|     const bool home_pressed = IsKeyPressed(io.KeyMap[ImGuiKey_Home]) && !IsActiveIdUsingKey(ImGuiKey_Home); |     const bool home_pressed = IsKeyPressed(io.KeyMap[ImGuiKey_Home]) && !IsActiveIdUsingKey(ImGuiKey_Home); | ||||||
|     const bool end_pressed = IsKeyPressed(io.KeyMap[ImGuiKey_End]) && !IsActiveIdUsingKey(ImGuiKey_End); |     const bool end_pressed = IsKeyPressed(io.KeyMap[ImGuiKey_End]) && !IsActiveIdUsingKey(ImGuiKey_End); | ||||||
|     if (page_up_held != page_down_held || home_pressed != end_pressed) // If either (not both) are pressed |     if (page_up_held == page_down_held && home_pressed == end_pressed) // Proceed if either (not both) are pressed, otherwise early out | ||||||
|  |         return 0.0f; | ||||||
|  |  | ||||||
|  |     if (window->DC.NavLayersActiveMask == 0x00 && window->DC.NavHasScroll) | ||||||
|     { |     { | ||||||
|         if (window->DC.NavLayersActiveMask == 0x00 && window->DC.NavHasScroll) |         // Fallback manual-scroll when window has no navigable item | ||||||
|  |         if (IsKeyPressed(io.KeyMap[ImGuiKey_PageUp], true)) | ||||||
|  |             SetScrollY(window, window->Scroll.y - window->InnerRect.GetHeight()); | ||||||
|  |         else if (IsKeyPressed(io.KeyMap[ImGuiKey_PageDown], true)) | ||||||
|  |             SetScrollY(window, window->Scroll.y + window->InnerRect.GetHeight()); | ||||||
|  |         else if (home_pressed) | ||||||
|  |             SetScrollY(window, 0.0f); | ||||||
|  |         else if (end_pressed) | ||||||
|  |             SetScrollY(window, window->ScrollMax.y); | ||||||
|  |     } | ||||||
|  |     else | ||||||
|  |     { | ||||||
|  |         ImRect& nav_rect_rel = window->NavRectRel[g.NavLayer]; | ||||||
|  |         const float page_offset_y = ImMax(0.0f, window->InnerRect.GetHeight() - window->CalcFontSize() * 1.0f + nav_rect_rel.GetHeight()); | ||||||
|  |         float nav_scoring_rect_offset_y = 0.0f; | ||||||
|  |         if (IsKeyPressed(io.KeyMap[ImGuiKey_PageUp], true)) | ||||||
|         { |         { | ||||||
|             // Fallback manual-scroll when window has no navigable item |             nav_scoring_rect_offset_y = -page_offset_y; | ||||||
|             if (IsKeyPressed(io.KeyMap[ImGuiKey_PageUp], true)) |             g.NavMoveDir = ImGuiDir_Down; // Because our scoring rect is offset up, we request the down direction (so we can always land on the last item) | ||||||
|                 SetScrollY(window, window->Scroll.y - window->InnerRect.GetHeight()); |             g.NavMoveClipDir = ImGuiDir_Up; | ||||||
|             else if (IsKeyPressed(io.KeyMap[ImGuiKey_PageDown], true)) |             g.NavMoveRequestFlags = ImGuiNavMoveFlags_AllowCurrentNavId | ImGuiNavMoveFlags_AlsoScoreVisibleSet; | ||||||
|                 SetScrollY(window, window->Scroll.y + window->InnerRect.GetHeight()); |  | ||||||
|             else if (home_pressed) |  | ||||||
|                 SetScrollY(window, 0.0f); |  | ||||||
|             else if (end_pressed) |  | ||||||
|                 SetScrollY(window, window->ScrollMax.y); |  | ||||||
|         } |         } | ||||||
|         else |         else if (IsKeyPressed(io.KeyMap[ImGuiKey_PageDown], true)) | ||||||
|         { |         { | ||||||
|             ImRect& nav_rect_rel = window->NavRectRel[g.NavLayer]; |             nav_scoring_rect_offset_y = +page_offset_y; | ||||||
|             const float page_offset_y = ImMax(0.0f, window->InnerRect.GetHeight() - window->CalcFontSize() * 1.0f + nav_rect_rel.GetHeight()); |             g.NavMoveDir = ImGuiDir_Up; // Because our scoring rect is offset down, we request the up direction (so we can always land on the last item) | ||||||
|             float nav_scoring_rect_offset_y = 0.0f; |             g.NavMoveClipDir = ImGuiDir_Down; | ||||||
|             if (IsKeyPressed(io.KeyMap[ImGuiKey_PageUp], true)) |             g.NavMoveRequestFlags = ImGuiNavMoveFlags_AllowCurrentNavId | ImGuiNavMoveFlags_AlsoScoreVisibleSet; | ||||||
|             { |  | ||||||
|                 nav_scoring_rect_offset_y = -page_offset_y; |  | ||||||
|                 g.NavMoveDir = ImGuiDir_Down; // Because our scoring rect is offset up, we request the down direction (so we can always land on the last item) |  | ||||||
|                 g.NavMoveClipDir = ImGuiDir_Up; |  | ||||||
|                 g.NavMoveRequestFlags = ImGuiNavMoveFlags_AllowCurrentNavId | ImGuiNavMoveFlags_AlsoScoreVisibleSet; |  | ||||||
|             } |  | ||||||
|             else if (IsKeyPressed(io.KeyMap[ImGuiKey_PageDown], true)) |  | ||||||
|             { |  | ||||||
|                 nav_scoring_rect_offset_y = +page_offset_y; |  | ||||||
|                 g.NavMoveDir = ImGuiDir_Up; // Because our scoring rect is offset down, we request the up direction (so we can always land on the last item) |  | ||||||
|                 g.NavMoveClipDir = ImGuiDir_Down; |  | ||||||
|                 g.NavMoveRequestFlags = ImGuiNavMoveFlags_AllowCurrentNavId | ImGuiNavMoveFlags_AlsoScoreVisibleSet; |  | ||||||
|             } |  | ||||||
|             else if (home_pressed) |  | ||||||
|             { |  | ||||||
|                 // FIXME-NAV: handling of Home/End is assuming that the top/bottom most item will be visible with Scroll.y == 0/ScrollMax.y |  | ||||||
|                 // Scrolling will be handled via the ImGuiNavMoveFlags_ScrollToEdge flag, we don't scroll immediately to avoid scrolling happening before nav result. |  | ||||||
|                 // Preserve current horizontal position if we have any. |  | ||||||
|                 nav_rect_rel.Min.y = nav_rect_rel.Max.y = -window->Scroll.y; |  | ||||||
|                 if (nav_rect_rel.IsInverted()) |  | ||||||
|                     nav_rect_rel.Min.x = nav_rect_rel.Max.x = 0.0f; |  | ||||||
|                 g.NavMoveDir = ImGuiDir_Down; |  | ||||||
|                 g.NavMoveRequestFlags = ImGuiNavMoveFlags_AllowCurrentNavId | ImGuiNavMoveFlags_ScrollToEdge; |  | ||||||
|             } |  | ||||||
|             else if (end_pressed) |  | ||||||
|             { |  | ||||||
|                 nav_rect_rel.Min.y = nav_rect_rel.Max.y = window->ScrollMax.y + window->SizeFull.y - window->Scroll.y; |  | ||||||
|                 if (nav_rect_rel.IsInverted()) |  | ||||||
|                     nav_rect_rel.Min.x = nav_rect_rel.Max.x = 0.0f; |  | ||||||
|                 g.NavMoveDir = ImGuiDir_Up; |  | ||||||
|                 g.NavMoveRequestFlags = ImGuiNavMoveFlags_AllowCurrentNavId | ImGuiNavMoveFlags_ScrollToEdge; |  | ||||||
|             } |  | ||||||
|             return nav_scoring_rect_offset_y; |  | ||||||
|         } |         } | ||||||
|  |         else if (home_pressed) | ||||||
|  |         { | ||||||
|  |             // FIXME-NAV: handling of Home/End is assuming that the top/bottom most item will be visible with Scroll.y == 0/ScrollMax.y | ||||||
|  |             // Scrolling will be handled via the ImGuiNavMoveFlags_ScrollToEdge flag, we don't scroll immediately to avoid scrolling happening before nav result. | ||||||
|  |             // Preserve current horizontal position if we have any. | ||||||
|  |             nav_rect_rel.Min.y = nav_rect_rel.Max.y = -window->Scroll.y; | ||||||
|  |             if (nav_rect_rel.IsInverted()) | ||||||
|  |                 nav_rect_rel.Min.x = nav_rect_rel.Max.x = 0.0f; | ||||||
|  |             g.NavMoveDir = ImGuiDir_Down; | ||||||
|  |             g.NavMoveRequestFlags = ImGuiNavMoveFlags_AllowCurrentNavId | ImGuiNavMoveFlags_ScrollToEdge; | ||||||
|  |         } | ||||||
|  |         else if (end_pressed) | ||||||
|  |         { | ||||||
|  |             nav_rect_rel.Min.y = nav_rect_rel.Max.y = window->ScrollMax.y + window->SizeFull.y - window->Scroll.y; | ||||||
|  |             if (nav_rect_rel.IsInverted()) | ||||||
|  |                 nav_rect_rel.Min.x = nav_rect_rel.Max.x = 0.0f; | ||||||
|  |             g.NavMoveDir = ImGuiDir_Up; | ||||||
|  |             g.NavMoveRequestFlags = ImGuiNavMoveFlags_AllowCurrentNavId | ImGuiNavMoveFlags_ScrollToEdge; | ||||||
|  |         } | ||||||
|  |         return nav_scoring_rect_offset_y; | ||||||
|     } |     } | ||||||
|     return 0.0f; |     return 0.0f; | ||||||
| } | } | ||||||
| @@ -10187,13 +10224,14 @@ static void ImGui::NavEndFrame() | |||||||
|         NavUpdateWindowingOverlay(); |         NavUpdateWindowingOverlay(); | ||||||
|  |  | ||||||
|     // Perform wrap-around in menus |     // Perform wrap-around in menus | ||||||
|     ImGuiWindow* window = g.NavWrapRequestWindow; |     // FIXME-NAV: Wrap (not Loop) support could be handled by the scoring function and then WrapX would function without an extra frame. | ||||||
|     ImGuiNavMoveFlags move_flags = g.NavWrapRequestFlags; |     ImGuiWindow* window = g.NavWindow; | ||||||
|     if (window != NULL && g.NavWindow == window && NavMoveRequestButNoResultYet() && g.NavMoveRequestForward == ImGuiNavForward_None && g.NavLayer == ImGuiNavLayer_Main) |     const ImGuiNavMoveFlags move_flags = g.NavMoveRequestFlags; | ||||||
|  |     const ImGuiNavMoveFlags wanted_flags = ImGuiNavMoveFlags_WrapX | ImGuiNavMoveFlags_LoopX | ImGuiNavMoveFlags_WrapY | ImGuiNavMoveFlags_LoopY; | ||||||
|  |     if (window && NavMoveRequestButNoResultYet() && (g.NavMoveRequestFlags & wanted_flags) && (g.NavMoveRequestFlags & ImGuiNavMoveFlags_Forwarded) == 0) | ||||||
|     { |     { | ||||||
|         IM_ASSERT(move_flags != 0); // No points calling this with no wrapping |         bool do_forward = false; | ||||||
|         ImRect bb_rel = window->NavRectRel[0]; |         ImRect bb_rel = window->NavRectRel[g.NavLayer]; | ||||||
|  |  | ||||||
|         ImGuiDir clip_dir = g.NavMoveDir; |         ImGuiDir clip_dir = g.NavMoveDir; | ||||||
|         if (g.NavMoveDir == ImGuiDir_Left && (move_flags & (ImGuiNavMoveFlags_WrapX | ImGuiNavMoveFlags_LoopX))) |         if (g.NavMoveDir == ImGuiDir_Left && (move_flags & (ImGuiNavMoveFlags_WrapX | ImGuiNavMoveFlags_LoopX))) | ||||||
|         { |         { | ||||||
| @@ -10204,7 +10242,7 @@ static void ImGui::NavEndFrame() | |||||||
|                 bb_rel.TranslateY(-bb_rel.GetHeight()); |                 bb_rel.TranslateY(-bb_rel.GetHeight()); | ||||||
|                 clip_dir = ImGuiDir_Up; |                 clip_dir = ImGuiDir_Up; | ||||||
|             } |             } | ||||||
|             NavMoveRequestForward(g.NavMoveDir, clip_dir, bb_rel, move_flags); |             do_forward = true; | ||||||
|         } |         } | ||||||
|         if (g.NavMoveDir == ImGuiDir_Right && (move_flags & (ImGuiNavMoveFlags_WrapX | ImGuiNavMoveFlags_LoopX))) |         if (g.NavMoveDir == ImGuiDir_Right && (move_flags & (ImGuiNavMoveFlags_WrapX | ImGuiNavMoveFlags_LoopX))) | ||||||
|         { |         { | ||||||
| @@ -10214,7 +10252,7 @@ static void ImGui::NavEndFrame() | |||||||
|                 bb_rel.TranslateY(+bb_rel.GetHeight()); |                 bb_rel.TranslateY(+bb_rel.GetHeight()); | ||||||
|                 clip_dir = ImGuiDir_Down; |                 clip_dir = ImGuiDir_Down; | ||||||
|             } |             } | ||||||
|             NavMoveRequestForward(g.NavMoveDir, clip_dir, bb_rel, move_flags); |             do_forward = true; | ||||||
|         } |         } | ||||||
|         if (g.NavMoveDir == ImGuiDir_Up && (move_flags & (ImGuiNavMoveFlags_WrapY | ImGuiNavMoveFlags_LoopY))) |         if (g.NavMoveDir == ImGuiDir_Up && (move_flags & (ImGuiNavMoveFlags_WrapY | ImGuiNavMoveFlags_LoopY))) | ||||||
|         { |         { | ||||||
| @@ -10225,7 +10263,7 @@ static void ImGui::NavEndFrame() | |||||||
|                 bb_rel.TranslateX(-bb_rel.GetWidth()); |                 bb_rel.TranslateX(-bb_rel.GetWidth()); | ||||||
|                 clip_dir = ImGuiDir_Left; |                 clip_dir = ImGuiDir_Left; | ||||||
|             } |             } | ||||||
|             NavMoveRequestForward(g.NavMoveDir, clip_dir, bb_rel, move_flags); |             do_forward = true; | ||||||
|         } |         } | ||||||
|         if (g.NavMoveDir == ImGuiDir_Down && (move_flags & (ImGuiNavMoveFlags_WrapY | ImGuiNavMoveFlags_LoopY))) |         if (g.NavMoveDir == ImGuiDir_Down && (move_flags & (ImGuiNavMoveFlags_WrapY | ImGuiNavMoveFlags_LoopY))) | ||||||
|         { |         { | ||||||
| @@ -10235,7 +10273,12 @@ static void ImGui::NavEndFrame() | |||||||
|                 bb_rel.TranslateX(+bb_rel.GetWidth()); |                 bb_rel.TranslateX(+bb_rel.GetWidth()); | ||||||
|                 clip_dir = ImGuiDir_Right; |                 clip_dir = ImGuiDir_Right; | ||||||
|             } |             } | ||||||
|             NavMoveRequestForward(g.NavMoveDir, clip_dir, bb_rel, move_flags); |             do_forward = true; | ||||||
|  |         } | ||||||
|  |         if (do_forward) | ||||||
|  |         { | ||||||
|  |             window->NavRectRel[g.NavLayer] = bb_rel; | ||||||
|  |             NavMoveRequestForward(g.NavMoveDir, clip_dir, move_flags); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
|   | |||||||
							
								
								
									
										88
									
								
								imgui.h
									
									
									
									
									
								
							
							
						
						
									
										88
									
								
								imgui.h
									
									
									
									
									
								
							| @@ -1,4 +1,4 @@ | |||||||
| // dear imgui, v1.84 | // dear imgui, v1.85 WIP | ||||||
| // (headers) | // (headers) | ||||||
|  |  | ||||||
| // Help: | // Help: | ||||||
| @@ -15,7 +15,10 @@ | |||||||
| // - Wiki                  https://github.com/ocornut/imgui/wiki (lots of good stuff 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 | ||||||
| // - Issues & support      https://github.com/ocornut/imgui/issues | // - Issues & support      https://github.com/ocornut/imgui/issues | ||||||
| // - Discussions           https://github.com/ocornut/imgui/discussions |  | ||||||
|  | // Getting Started? | ||||||
|  | // - For first-time users having issues compiling/linking/running or issues loading fonts: | ||||||
|  | //   please post in https://github.com/ocornut/imgui/discussions if you cannot find a solution in resources above. | ||||||
|  |  | ||||||
| /* | /* | ||||||
|  |  | ||||||
| @@ -61,8 +64,8 @@ Index of this file: | |||||||
|  |  | ||||||
| // Version | // Version | ||||||
| // (Integer encoded as XYYZZ for use in #if preprocessor conditionals. Work in progress versions typically starts at XYY99 then bounce up to XYY00, XYY01 etc. when release tagging happens) | // (Integer encoded as XYYZZ for use in #if preprocessor conditionals. Work in progress versions typically starts at XYY99 then bounce up to XYY00, XYY01 etc. when release tagging happens) | ||||||
| #define IMGUI_VERSION               "1.84.1" | #define IMGUI_VERSION               "1.85 WIP" | ||||||
| #define IMGUI_VERSION_NUM           18403 | #define IMGUI_VERSION_NUM           18410 | ||||||
| #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)) | ||||||
| #define IMGUI_HAS_TABLE | #define IMGUI_HAS_TABLE | ||||||
| #define IMGUI_HAS_VIEWPORT          // Viewport WIP branch | #define IMGUI_HAS_VIEWPORT          // Viewport WIP branch | ||||||
| @@ -166,7 +169,7 @@ struct ImGuiTextFilter;             // Helper to parse and apply text filters (e | |||||||
| struct ImGuiViewport;               // A Platform Window (always 1 unless multi-viewport are enabled. One per platform window to output to). In the future may represent Platform Monitor | struct ImGuiViewport;               // A Platform Window (always 1 unless multi-viewport are enabled. One per platform window to output to). In the future may represent Platform Monitor | ||||||
| struct ImGuiWindowClass;            // Window class (rare/advanced uses: provide hints to the platform backend via altered viewport flags and parent/child info) | struct ImGuiWindowClass;            // Window class (rare/advanced uses: provide hints to the platform backend via altered viewport flags and parent/child info) | ||||||
|  |  | ||||||
| // Enums/Flags (declared as int for compatibility with old C++, to allow using as flags and to not pollute the top of this file) | // Enums/Flags (declared as int for compatibility with old C++, to allow using as flags without overhead, and to not pollute the top of this file) | ||||||
| // - Tip: Use your programming IDE navigation facilities on the names in the _central column_ below to find the actual flags/enum lists! | // - Tip: Use your programming IDE navigation facilities on the names in the _central column_ below to find the actual flags/enum lists! | ||||||
| //   In Visual Studio IDE: CTRL+comma ("Edit.NavigateTo") can follow symbols in comments, whereas CTRL+F12 ("Edit.GoToImplementation") cannot. | //   In Visual Studio IDE: CTRL+comma ("Edit.NavigateTo") can follow symbols in comments, whereas CTRL+F12 ("Edit.GoToImplementation") cannot. | ||||||
| //   With Visual Assist installed: ALT+G ("VAssistX.GoToImplementation") can also follow symbols in comments. | //   With Visual Assist installed: ALT+G ("VAssistX.GoToImplementation") can also follow symbols in comments. | ||||||
| @@ -207,27 +210,22 @@ typedef int ImGuiTreeNodeFlags;     // -> enum ImGuiTreeNodeFlags_   // Flags: f | |||||||
| typedef int ImGuiViewportFlags;     // -> enum ImGuiViewportFlags_   // Flags: for ImGuiViewport | typedef int ImGuiViewportFlags;     // -> enum ImGuiViewportFlags_   // Flags: for ImGuiViewport | ||||||
| typedef int ImGuiWindowFlags;       // -> enum ImGuiWindowFlags_     // Flags: for Begin(), BeginChild() | typedef int ImGuiWindowFlags;       // -> enum ImGuiWindowFlags_     // Flags: for Begin(), BeginChild() | ||||||
|  |  | ||||||
| // Other types | // ImTexture: user data for renderer backend to identify a texture [Compile-time configurable type] | ||||||
| #ifndef ImTextureID                 // ImTextureID [configurable type: override in imconfig.h with '#define ImTextureID xxx'] | // - To use something else than an opaque void* pointer: override with e.g. '#define ImTextureID MyTextureType*' in your imconfig.h file. | ||||||
| typedef void* ImTextureID;          // User data for rendering backend to identify a texture. This is whatever to you want it to be! read the FAQ about ImTextureID for details. | // - This can be whatever to you want it to be! read the FAQ about ImTextureID for details. | ||||||
| #endif | #ifndef ImTextureID | ||||||
| typedef unsigned int ImGuiID;       // A unique ID used by widgets, typically hashed from a stack of string. | typedef void* ImTextureID;          // Default: store a pointer or an integer fitting in a pointer (most renderer backends are ok with that) | ||||||
| typedef int (*ImGuiInputTextCallback)(ImGuiInputTextCallbackData* data);    // Callback function for ImGui::InputText() |  | ||||||
| typedef void (*ImGuiSizeCallback)(ImGuiSizeCallbackData* data);             // Callback function for ImGui::SetNextWindowSizeConstraints() |  | ||||||
| typedef void* (*ImGuiMemAllocFunc)(size_t sz, void* user_data);             // Function signature for ImGui::SetAllocatorFunctions() |  | ||||||
| typedef void (*ImGuiMemFreeFunc)(void* ptr, void* user_data);               // Function signature for ImGui::SetAllocatorFunctions() |  | ||||||
|  |  | ||||||
| // Character types |  | ||||||
| // (we generally use UTF-8 encoded string in the API. This is storage specifically for a decoded character used for keyboard input and display) |  | ||||||
| typedef unsigned short ImWchar16;   // A single decoded U16 character/code point. We encode them as multi bytes UTF-8 when used in strings. |  | ||||||
| typedef unsigned int ImWchar32;     // A single decoded U32 character/code point. We encode them as multi bytes UTF-8 when used in strings. |  | ||||||
| #ifdef IMGUI_USE_WCHAR32            // ImWchar [configurable type: override in imconfig.h with '#define IMGUI_USE_WCHAR32' to support Unicode planes 1-16] |  | ||||||
| typedef ImWchar32 ImWchar; |  | ||||||
| #else |  | ||||||
| typedef ImWchar16 ImWchar; |  | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
| // Basic scalar data types | // ImDrawIdx: vertex index. [Compile-time configurable type] | ||||||
|  | // - To use 16-bit indices + allow large meshes: backend need to set 'io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset' and handle ImDrawCmd::VtxOffset (recommended). | ||||||
|  | // - To use 32-bit indices: override with '#define ImDrawIdx unsigned int' in your imconfig.h file. | ||||||
|  | #ifndef ImDrawIdx | ||||||
|  | typedef unsigned short ImDrawIdx;   // Default: 16-bit (for maximum compatibility with renderer backends) | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | // Scalar data types | ||||||
|  | typedef unsigned int        ImGuiID;// A unique ID used by widgets (typically the result of hashing a stack of string) | ||||||
| typedef signed char         ImS8;   // 8-bit signed integer | typedef signed char         ImS8;   // 8-bit signed integer | ||||||
| typedef unsigned char       ImU8;   // 8-bit unsigned integer | typedef unsigned char       ImU8;   // 8-bit unsigned integer | ||||||
| typedef signed short        ImS16;  // 16-bit signed integer | typedef signed short        ImS16;  // 16-bit signed integer | ||||||
| @@ -246,7 +244,24 @@ typedef signed   long long  ImS64;  // 64-bit signed integer (post C++11) | |||||||
| typedef unsigned long long  ImU64;  // 64-bit unsigned integer (post C++11) | typedef unsigned long long  ImU64;  // 64-bit unsigned integer (post C++11) | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
| // 2D vector (often used to store positions or sizes) | // Character types | ||||||
|  | // (we generally use UTF-8 encoded string in the API. This is storage specifically for a decoded character used for keyboard input and display) | ||||||
|  | typedef unsigned short ImWchar16;   // A single decoded U16 character/code point. We encode them as multi bytes UTF-8 when used in strings. | ||||||
|  | typedef unsigned int ImWchar32;     // A single decoded U32 character/code point. We encode them as multi bytes UTF-8 when used in strings. | ||||||
|  | #ifdef IMGUI_USE_WCHAR32            // ImWchar [configurable type: override in imconfig.h with '#define IMGUI_USE_WCHAR32' to support Unicode planes 1-16] | ||||||
|  | typedef ImWchar32 ImWchar; | ||||||
|  | #else | ||||||
|  | typedef ImWchar16 ImWchar; | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | // Callback and functions types | ||||||
|  | typedef int     (*ImGuiInputTextCallback)(ImGuiInputTextCallbackData* data);    // Callback function for ImGui::InputText() | ||||||
|  | typedef void    (*ImGuiSizeCallback)(ImGuiSizeCallbackData* data);              // Callback function for ImGui::SetNextWindowSizeConstraints() | ||||||
|  | typedef void*   (*ImGuiMemAllocFunc)(size_t sz, void* user_data);               // Function signature for ImGui::SetAllocatorFunctions() | ||||||
|  | typedef void    (*ImGuiMemFreeFunc)(void* ptr, void* user_data);                // Function signature for ImGui::SetAllocatorFunctions() | ||||||
|  |  | ||||||
|  | // ImVec2: 2D vector used to store positions, sizes etc. [Compile-time configurable type] | ||||||
|  | // This is a frequently used type in the API. Consider using IM_VEC2_CLASS_EXTRA to create implicit cast from/to our preferred type. | ||||||
| IM_MSVC_RUNTIME_CHECKS_OFF | IM_MSVC_RUNTIME_CHECKS_OFF | ||||||
| struct ImVec2 | struct ImVec2 | ||||||
| { | { | ||||||
| @@ -260,7 +275,7 @@ struct ImVec2 | |||||||
| #endif | #endif | ||||||
| }; | }; | ||||||
|  |  | ||||||
| // 4D vector (often used to store floating-point colors) | // ImVec4: 4D vector used to store clipping rectangles, colors etc. [Compile-time configurable type] | ||||||
| struct ImVec4 | struct ImVec4 | ||||||
| { | { | ||||||
|     float                                           x, y, z, w; |     float                                           x, y, z, w; | ||||||
| @@ -377,9 +392,8 @@ namespace ImGui | |||||||
|     // - Those functions are bound to be redesigned (they are confusing, incomplete and the Min/Max return values are in local window coordinates which increases confusion) |     // - Those functions are bound to be redesigned (they are confusing, incomplete and the Min/Max return values are in local window coordinates which increases confusion) | ||||||
|     IMGUI_API ImVec2        GetContentRegionAvail();                                        // == GetContentRegionMax() - GetCursorPos() |     IMGUI_API ImVec2        GetContentRegionAvail();                                        // == GetContentRegionMax() - GetCursorPos() | ||||||
|     IMGUI_API ImVec2        GetContentRegionMax();                                          // current content boundaries (typically window boundaries including scrolling, or current column boundaries), in windows coordinates |     IMGUI_API ImVec2        GetContentRegionMax();                                          // current content boundaries (typically window boundaries including scrolling, or current column boundaries), in windows coordinates | ||||||
|     IMGUI_API ImVec2        GetWindowContentRegionMin();                                    // content boundaries min (roughly (0,0)-Scroll), in window coordinates |     IMGUI_API ImVec2        GetWindowContentRegionMin();                                    // content boundaries min for the full window (roughly (0,0)-Scroll), in window coordinates | ||||||
|     IMGUI_API ImVec2        GetWindowContentRegionMax();                                    // content boundaries max (roughly (0,0)+Size-Scroll) where Size can be override with SetNextWindowContentSize(), in window coordinates |     IMGUI_API ImVec2        GetWindowContentRegionMax();                                    // content boundaries max for the full window (roughly (0,0)+Size-Scroll) where Size can be override with SetNextWindowContentSize(), in window coordinates | ||||||
|     IMGUI_API float         GetWindowContentRegionWidth();                                  // |  | ||||||
|  |  | ||||||
|     // Windows Scrolling |     // Windows Scrolling | ||||||
|     IMGUI_API float         GetScrollX();                                                   // get scrolling amount [0 .. GetScrollMaxX()] |     IMGUI_API float         GetScrollX();                                                   // get scrolling amount [0 .. GetScrollMaxX()] | ||||||
| @@ -628,7 +642,7 @@ namespace ImGui | |||||||
|     IMGUI_API bool          ListBox(const char* label, int* current_item, bool (*items_getter)(void* data, int idx, const char** out_text), void* data, int items_count, int height_in_items = -1); |     IMGUI_API bool          ListBox(const char* label, int* current_item, bool (*items_getter)(void* data, int idx, const char** out_text), void* data, int items_count, int height_in_items = -1); | ||||||
|  |  | ||||||
|     // Widgets: Data Plotting |     // Widgets: Data Plotting | ||||||
|     // - Consider using ImPlot (https://github.com/epezent/implot) |     // - Consider using ImPlot (https://github.com/epezent/implot) which is much better! | ||||||
|     IMGUI_API void          PlotLines(const char* label, const float* values, int values_count, int values_offset = 0, const char* overlay_text = NULL, float scale_min = FLT_MAX, float scale_max = FLT_MAX, ImVec2 graph_size = ImVec2(0, 0), int stride = sizeof(float)); |     IMGUI_API void          PlotLines(const char* label, const float* values, int values_count, int values_offset = 0, const char* overlay_text = NULL, float scale_min = FLT_MAX, float scale_max = FLT_MAX, ImVec2 graph_size = ImVec2(0, 0), int stride = sizeof(float)); | ||||||
|     IMGUI_API void          PlotLines(const char* label, float(*values_getter)(void* data, int idx), void* data, int values_count, int values_offset = 0, const char* overlay_text = NULL, float scale_min = FLT_MAX, float scale_max = FLT_MAX, ImVec2 graph_size = ImVec2(0, 0)); |     IMGUI_API void          PlotLines(const char* label, float(*values_getter)(void* data, int idx), void* data, int values_count, int values_offset = 0, const char* overlay_text = NULL, float scale_min = FLT_MAX, float scale_max = FLT_MAX, ImVec2 graph_size = ImVec2(0, 0)); | ||||||
|     IMGUI_API void          PlotHistogram(const char* label, const float* values, int values_count, int values_offset = 0, const char* overlay_text = NULL, float scale_min = FLT_MAX, float scale_max = FLT_MAX, ImVec2 graph_size = ImVec2(0, 0), int stride = sizeof(float)); |     IMGUI_API void          PlotHistogram(const char* label, const float* values, int values_count, int values_offset = 0, const char* overlay_text = NULL, float scale_min = FLT_MAX, float scale_max = FLT_MAX, ImVec2 graph_size = ImVec2(0, 0), int stride = sizeof(float)); | ||||||
| @@ -831,6 +845,7 @@ namespace ImGui | |||||||
|  |  | ||||||
|     // Disabling [BETA API] |     // Disabling [BETA API] | ||||||
|     // - Disable all user interactions and dim items visuals (applying style.DisabledAlpha over current colors) |     // - Disable all user interactions and dim items visuals (applying style.DisabledAlpha over current colors) | ||||||
|  |     // - Those can be nested but it cannot be used to enable an already disabled section (a single BeginDisabled(true) in the stack is enough to keep everything disabled) | ||||||
|     // - BeginDisabled(false) essentially does nothing useful but is provided to facilitate use of boolean expressions. If you can avoid calling BeginDisabled(False)/EndDisabled() best to avoid it. |     // - BeginDisabled(false) essentially does nothing useful but is provided to facilitate use of boolean expressions. If you can avoid calling BeginDisabled(False)/EndDisabled() best to avoid it. | ||||||
|     IMGUI_API void          BeginDisabled(bool disabled = true); |     IMGUI_API void          BeginDisabled(bool disabled = true); | ||||||
|     IMGUI_API void          EndDisabled(); |     IMGUI_API void          EndDisabled(); | ||||||
| @@ -1987,6 +2002,7 @@ struct ImGuiIO | |||||||
|     // [Internal] Dear ImGui will maintain those fields. Forward compatibility not guaranteed! |     // [Internal] Dear ImGui will maintain those fields. Forward compatibility not guaranteed! | ||||||
|     //------------------------------------------------------------------ |     //------------------------------------------------------------------ | ||||||
|  |  | ||||||
|  |     bool        WantCaptureMouseUnlessPopupClose;// Alternative to WantCaptureMouse: (WantCaptureMouse == true && WantCaptureMouseUnlessPopupClose == false) when a click over void is expected to close a popup. | ||||||
|     ImGuiKeyModFlags KeyMods;                   // Key mods flags (same as io.KeyCtrl/KeyShift/KeyAlt/KeySuper but merged into flags), updated by NewFrame() |     ImGuiKeyModFlags KeyMods;                   // Key mods flags (same as io.KeyCtrl/KeyShift/KeyAlt/KeySuper but merged into flags), updated by NewFrame() | ||||||
|     ImGuiKeyModFlags KeyModsPrev;               // Previous key mods |     ImGuiKeyModFlags KeyModsPrev;               // Previous key mods | ||||||
|     ImVec2      MousePosPrev;                   // Previous mouse position (note that MouseDelta is not necessary == MousePos-MousePosPrev, in case either position is invalid) |     ImVec2      MousePosPrev;                   // Previous mouse position (note that MouseDelta is not necessary == MousePos-MousePosPrev, in case either position is invalid) | ||||||
| @@ -1995,7 +2011,8 @@ struct ImGuiIO | |||||||
|     bool        MouseClicked[5];                // Mouse button went from !Down to Down |     bool        MouseClicked[5];                // Mouse button went from !Down to Down | ||||||
|     bool        MouseDoubleClicked[5];          // Has mouse button been double-clicked? |     bool        MouseDoubleClicked[5];          // Has mouse button been double-clicked? | ||||||
|     bool        MouseReleased[5];               // Mouse button went from Down to !Down |     bool        MouseReleased[5];               // Mouse button went from Down to !Down | ||||||
|     bool        MouseDownOwned[5];              // Track if button was clicked inside a dear imgui window. We don't request mouse capture from the application if click started outside ImGui bounds. |     bool        MouseDownOwned[5];              // Track if button was clicked inside a dear imgui window or over void blocked by a popup. We don't request mouse capture from the application if click started outside ImGui bounds. | ||||||
|  |     bool        MouseDownOwnedUnlessPopupClose[5];//Track if button was clicked inside a dear imgui window. | ||||||
|     bool        MouseDownWasDoubleClick[5];     // Track if button down was a double-click |     bool        MouseDownWasDoubleClick[5];     // Track if button down was a double-click | ||||||
|     float       MouseDownDuration[5];           // Duration the mouse button has been down (0.0f == just clicked) |     float       MouseDownDuration[5];           // Duration the mouse button has been down (0.0f == just clicked) | ||||||
|     float       MouseDownDurationPrev[5];       // Previous time the mouse button has been down |     float       MouseDownDurationPrev[5];       // Previous time the mouse button has been down | ||||||
| @@ -2382,13 +2399,6 @@ struct ImDrawCmd | |||||||
|     inline ImTextureID GetTexID() const { return TextureId; } |     inline ImTextureID GetTexID() const { return TextureId; } | ||||||
| }; | }; | ||||||
|  |  | ||||||
| // Vertex index, default to 16-bit |  | ||||||
| // To allow large meshes with 16-bit indices: set 'io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset' and handle ImDrawCmd::VtxOffset in the renderer backend (recommended). |  | ||||||
| // To use 32-bit indices: override with '#define ImDrawIdx unsigned int' in imconfig.h. |  | ||||||
| #ifndef ImDrawIdx |  | ||||||
| typedef unsigned short ImDrawIdx; |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
| // Vertex layout | // Vertex layout | ||||||
| #ifndef IMGUI_OVERRIDE_DRAWVERT_STRUCT_LAYOUT | #ifndef IMGUI_OVERRIDE_DRAWVERT_STRUCT_LAYOUT | ||||||
| struct ImDrawVert | struct ImDrawVert | ||||||
| @@ -3067,6 +3077,8 @@ struct ImGuiPlatformMonitor | |||||||
| #ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS | #ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS | ||||||
| namespace ImGui | namespace ImGui | ||||||
| { | { | ||||||
|  |     // OBSOLETED in 1.85 (from August 2021) | ||||||
|  |     static inline float GetWindowContentRegionWidth() { return GetWindowContentRegionMax().x - GetWindowContentRegionMin().x; } | ||||||
|     // OBSOLETED in 1.81 (from February 2021) |     // OBSOLETED in 1.81 (from February 2021) | ||||||
|     IMGUI_API bool      ListBoxHeader(const char* label, int items_count, int height_in_items = -1); // Helper to calculate size from items_count and height_in_items |     IMGUI_API bool      ListBoxHeader(const char* label, int items_count, int height_in_items = -1); // Helper to calculate size from items_count and height_in_items | ||||||
|     static inline bool  ListBoxHeader(const char* label, const ImVec2& size = ImVec2(0, 0)) { return BeginListBox(label, size); } |     static inline bool  ListBoxHeader(const char* label, const ImVec2& size = ImVec2(0, 0)) { return BeginListBox(label, size); } | ||||||
|   | |||||||
| @@ -1,4 +1,4 @@ | |||||||
| // dear imgui, v1.84 | // dear imgui, v1.85 WIP | ||||||
| // (demo code) | // (demo code) | ||||||
|  |  | ||||||
| // Help: | // Help: | ||||||
| @@ -2427,7 +2427,7 @@ static void ShowDemoWindowLayout() | |||||||
|             ImGuiWindowFlags window_flags = ImGuiWindowFlags_HorizontalScrollbar; |             ImGuiWindowFlags window_flags = ImGuiWindowFlags_HorizontalScrollbar; | ||||||
|             if (disable_mouse_wheel) |             if (disable_mouse_wheel) | ||||||
|                 window_flags |= ImGuiWindowFlags_NoScrollWithMouse; |                 window_flags |= ImGuiWindowFlags_NoScrollWithMouse; | ||||||
|             ImGui::BeginChild("ChildL", ImVec2(ImGui::GetWindowContentRegionWidth() * 0.5f, 260), false, window_flags); |             ImGui::BeginChild("ChildL", ImVec2(ImGui::GetContentRegionAvail().x * 0.5f, 260), false, window_flags); | ||||||
|             for (int i = 0; i < 100; i++) |             for (int i = 0; i < 100; i++) | ||||||
|                 ImGui::Text("%04d: scrollable region", i); |                 ImGui::Text("%04d: scrollable region", i); | ||||||
|             ImGui::EndChild(); |             ImGui::EndChild(); | ||||||
| @@ -5536,6 +5536,7 @@ static void ShowDemoWindowMisc() | |||||||
|  |  | ||||||
|         // Display ImGuiIO output flags |         // Display ImGuiIO output flags | ||||||
|         ImGui::Text("WantCaptureMouse: %d", io.WantCaptureMouse); |         ImGui::Text("WantCaptureMouse: %d", io.WantCaptureMouse); | ||||||
|  |         ImGui::Text("WantCaptureMouseUnlessPopupClose: %d", io.WantCaptureMouseUnlessPopupClose); | ||||||
|         ImGui::Text("WantCaptureKeyboard: %d", io.WantCaptureKeyboard); |         ImGui::Text("WantCaptureKeyboard: %d", io.WantCaptureKeyboard); | ||||||
|         ImGui::Text("WantTextInput: %d", io.WantTextInput); |         ImGui::Text("WantTextInput: %d", io.WantTextInput); | ||||||
|         ImGui::Text("WantSetMousePos: %d", io.WantSetMousePos); |         ImGui::Text("WantSetMousePos: %d", io.WantSetMousePos); | ||||||
|   | |||||||
| @@ -1,4 +1,4 @@ | |||||||
| // dear imgui, v1.84 | // dear imgui, v1.85 WIP | ||||||
| // (drawing and font code) | // (drawing and font code) | ||||||
|  |  | ||||||
| /* | /* | ||||||
| @@ -2004,7 +2004,7 @@ void    ImFontAtlas::ClearInputData() | |||||||
|     ConfigData.clear(); |     ConfigData.clear(); | ||||||
|     CustomRects.clear(); |     CustomRects.clear(); | ||||||
|     PackIdMouseCursors = PackIdLines = -1; |     PackIdMouseCursors = PackIdLines = -1; | ||||||
|     TexReady = false; |     // Important: we leave TexReady untouched | ||||||
| } | } | ||||||
|  |  | ||||||
| void    ImFontAtlas::ClearTexData() | void    ImFontAtlas::ClearTexData() | ||||||
|   | |||||||
							
								
								
									
										143
									
								
								imgui_internal.h
									
									
									
									
									
								
							
							
						
						
									
										143
									
								
								imgui_internal.h
									
									
									
									
									
								
							| @@ -1,4 +1,4 @@ | |||||||
| // dear imgui, v1.84 | // dear imgui, v1.85 WIP | ||||||
| // (internal structures/api) | // (internal structures/api) | ||||||
|  |  | ||||||
| // You may use this file to debug, understand or extend ImGui features but we don't provide any guarantee of forward compatibility! | // You may use this file to debug, understand or extend ImGui features but we don't provide any guarantee of forward compatibility! | ||||||
| @@ -18,6 +18,7 @@ Index of this file: | |||||||
| // [SECTION] Generic helpers | // [SECTION] Generic helpers | ||||||
| // [SECTION] ImDrawList support | // [SECTION] ImDrawList support | ||||||
| // [SECTION] Widgets support: flags, enums, data structures | // [SECTION] Widgets support: flags, enums, data structures | ||||||
|  | // [SECTION] Navigation support | ||||||
| // [SECTION] Columns support | // [SECTION] Columns support | ||||||
| // [SECTION] Multi-select support | // [SECTION] Multi-select support | ||||||
| // [SECTION] Docking support | // [SECTION] Docking support | ||||||
| @@ -82,19 +83,13 @@ Index of this file: | |||||||
| #pragma clang diagnostic ignored "-Wzero-as-null-pointer-constant" | #pragma clang diagnostic ignored "-Wzero-as-null-pointer-constant" | ||||||
| #pragma clang diagnostic ignored "-Wdouble-promotion" | #pragma clang diagnostic ignored "-Wdouble-promotion" | ||||||
| #pragma clang diagnostic ignored "-Wimplicit-int-float-conversion"  // warning: implicit conversion from 'xxx' to 'float' may lose precision | #pragma clang diagnostic ignored "-Wimplicit-int-float-conversion"  // warning: implicit conversion from 'xxx' to 'float' may lose precision | ||||||
|  | #pragma clang diagnostic ignored "-Wmissing-noreturn"               // warning: function 'xxx' could be declared with attribute 'noreturn' | ||||||
| #elif defined(__GNUC__) | #elif defined(__GNUC__) | ||||||
| #pragma GCC diagnostic push | #pragma GCC diagnostic push | ||||||
| #pragma GCC diagnostic ignored "-Wpragmas"              // warning: unknown option after '#pragma GCC diagnostic' kind | #pragma GCC diagnostic ignored "-Wpragmas"              // warning: unknown option after '#pragma GCC diagnostic' kind | ||||||
| #pragma GCC diagnostic ignored "-Wclass-memaccess"      // [__GNUC__ >= 8] warning: 'memset/memcpy' clearing/writing an object of type 'xxxx' with no trivial copy-assignment; use assignment or value-initialization instead | #pragma GCC diagnostic ignored "-Wclass-memaccess"      // [__GNUC__ >= 8] warning: 'memset/memcpy' clearing/writing an object of type 'xxxx' with no trivial copy-assignment; use assignment or value-initialization instead | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
| // Helper macros |  | ||||||
| #if defined(__clang__) |  | ||||||
| #define IM_NORETURN     __attribute__((noreturn)) |  | ||||||
| #else |  | ||||||
| #define IM_NORETURN |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
| // Legacy defines | // Legacy defines | ||||||
| #ifdef IMGUI_DISABLE_FORMAT_STRING_FUNCTIONS            // Renamed in 1.74 | #ifdef IMGUI_DISABLE_FORMAT_STRING_FUNCTIONS            // Renamed in 1.74 | ||||||
| #error Use IMGUI_DISABLE_DEFAULT_FORMAT_FUNCTIONS | #error Use IMGUI_DISABLE_DEFAULT_FORMAT_FUNCTIONS | ||||||
| @@ -933,49 +928,6 @@ enum ImGuiInputReadMode | |||||||
|     ImGuiInputReadMode_RepeatFast |     ImGuiInputReadMode_RepeatFast | ||||||
| }; | }; | ||||||
|  |  | ||||||
| enum ImGuiNavHighlightFlags_ |  | ||||||
| { |  | ||||||
|     ImGuiNavHighlightFlags_None         = 0, |  | ||||||
|     ImGuiNavHighlightFlags_TypeDefault  = 1 << 0, |  | ||||||
|     ImGuiNavHighlightFlags_TypeThin     = 1 << 1, |  | ||||||
|     ImGuiNavHighlightFlags_AlwaysDraw   = 1 << 2,       // Draw rectangular highlight if (g.NavId == id) _even_ when using the mouse. |  | ||||||
|     ImGuiNavHighlightFlags_NoRounding   = 1 << 3 |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| enum ImGuiNavDirSourceFlags_ |  | ||||||
| { |  | ||||||
|     ImGuiNavDirSourceFlags_None         = 0, |  | ||||||
|     ImGuiNavDirSourceFlags_Keyboard     = 1 << 0, |  | ||||||
|     ImGuiNavDirSourceFlags_PadDPad      = 1 << 1, |  | ||||||
|     ImGuiNavDirSourceFlags_PadLStick    = 1 << 2 |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| enum ImGuiNavMoveFlags_ |  | ||||||
| { |  | ||||||
|     ImGuiNavMoveFlags_None                  = 0, |  | ||||||
|     ImGuiNavMoveFlags_LoopX                 = 1 << 0,   // On failed request, restart from opposite side |  | ||||||
|     ImGuiNavMoveFlags_LoopY                 = 1 << 1, |  | ||||||
|     ImGuiNavMoveFlags_WrapX                 = 1 << 2,   // On failed request, request from opposite side one line down (when NavDir==right) or one line up (when NavDir==left) |  | ||||||
|     ImGuiNavMoveFlags_WrapY                 = 1 << 3,   // This is not super useful for provided for completeness |  | ||||||
|     ImGuiNavMoveFlags_AllowCurrentNavId     = 1 << 4,   // Allow scoring and considering the current NavId as a move target candidate. This is used when the move source is offset (e.g. pressing PageDown actually needs to send a Up move request, if we are pressing PageDown from the bottom-most item we need to stay in place) |  | ||||||
|     ImGuiNavMoveFlags_AlsoScoreVisibleSet   = 1 << 5,   // Store alternate result in NavMoveResultLocalVisibleSet that only comprise elements that are already fully visible. |  | ||||||
|     ImGuiNavMoveFlags_ScrollToEdge          = 1 << 6 |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| enum ImGuiNavForward |  | ||||||
| { |  | ||||||
|     ImGuiNavForward_None, |  | ||||||
|     ImGuiNavForward_ForwardQueued, |  | ||||||
|     ImGuiNavForward_ForwardActive |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| enum ImGuiNavLayer |  | ||||||
| { |  | ||||||
|     ImGuiNavLayer_Main  = 0,    // Main scrolling layer |  | ||||||
|     ImGuiNavLayer_Menu  = 1,    // Menu layer (access with Alt/ImGuiNavInput_Menu) |  | ||||||
|     ImGuiNavLayer_COUNT |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| enum ImGuiPopupPositionPolicy | enum ImGuiPopupPositionPolicy | ||||||
| { | { | ||||||
|     ImGuiPopupPositionPolicy_Default, |     ImGuiPopupPositionPolicy_Default, | ||||||
| @@ -1122,20 +1074,6 @@ struct ImGuiPopupData | |||||||
|     ImGuiPopupData()    { memset(this, 0, sizeof(*this)); OpenFrameCount = -1; } |     ImGuiPopupData()    { memset(this, 0, sizeof(*this)); OpenFrameCount = -1; } | ||||||
| }; | }; | ||||||
|  |  | ||||||
| struct ImGuiNavItemData |  | ||||||
| { |  | ||||||
|     ImGuiWindow*        Window;         // Init,Move    // Best candidate window (result->ItemWindow->RootWindowForNav == request->Window) |  | ||||||
|     ImGuiID             ID;             // Init,Move    // Best candidate item ID |  | ||||||
|     ImGuiID             FocusScopeId;   // Init,Move    // Best candidate focus scope ID |  | ||||||
|     ImRect              RectRel;        // Init,Move    // Best candidate bounding box in window relative space |  | ||||||
|     float               DistBox;        //      Move    // Best candidate box distance to current NavId |  | ||||||
|     float               DistCenter;     //      Move    // Best candidate center distance to current NavId |  | ||||||
|     float               DistAxial;      //      Move    // Best candidate axial distance to current NavId |  | ||||||
|  |  | ||||||
|     ImGuiNavItemData()  { Clear(); } |  | ||||||
|     void Clear()        { Window = NULL; ID = FocusScopeId = 0; RectRel = ImRect(); DistBox = DistCenter = DistAxial = FLT_MAX; } |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| enum ImGuiNextWindowDataFlags_ | enum ImGuiNextWindowDataFlags_ | ||||||
| { | { | ||||||
|     ImGuiNextWindowDataFlags_None               = 0, |     ImGuiNextWindowDataFlags_None               = 0, | ||||||
| @@ -1233,6 +1171,61 @@ struct ImGuiPtrOrIndex | |||||||
|     ImGuiPtrOrIndex(int index)  { Ptr = NULL; Index = index; } |     ImGuiPtrOrIndex(int index)  { Ptr = NULL; Index = index; } | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | //----------------------------------------------------------------------------- | ||||||
|  | // [SECTION] Navigation support | ||||||
|  | //----------------------------------------------------------------------------- | ||||||
|  |  | ||||||
|  | enum ImGuiNavHighlightFlags_ | ||||||
|  | { | ||||||
|  |     ImGuiNavHighlightFlags_None             = 0, | ||||||
|  |     ImGuiNavHighlightFlags_TypeDefault      = 1 << 0, | ||||||
|  |     ImGuiNavHighlightFlags_TypeThin         = 1 << 1, | ||||||
|  |     ImGuiNavHighlightFlags_AlwaysDraw       = 1 << 2,       // Draw rectangular highlight if (g.NavId == id) _even_ when using the mouse. | ||||||
|  |     ImGuiNavHighlightFlags_NoRounding       = 1 << 3 | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | enum ImGuiNavDirSourceFlags_ | ||||||
|  | { | ||||||
|  |     ImGuiNavDirSourceFlags_None             = 0, | ||||||
|  |     ImGuiNavDirSourceFlags_Keyboard         = 1 << 0, | ||||||
|  |     ImGuiNavDirSourceFlags_PadDPad          = 1 << 1, | ||||||
|  |     ImGuiNavDirSourceFlags_PadLStick        = 1 << 2 | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | enum ImGuiNavMoveFlags_ | ||||||
|  | { | ||||||
|  |     ImGuiNavMoveFlags_None                  = 0, | ||||||
|  |     ImGuiNavMoveFlags_LoopX                 = 1 << 0,   // On failed request, restart from opposite side | ||||||
|  |     ImGuiNavMoveFlags_LoopY                 = 1 << 1, | ||||||
|  |     ImGuiNavMoveFlags_WrapX                 = 1 << 2,   // On failed request, request from opposite side one line down (when NavDir==right) or one line up (when NavDir==left) | ||||||
|  |     ImGuiNavMoveFlags_WrapY                 = 1 << 3,   // This is not super useful but provided for completeness | ||||||
|  |     ImGuiNavMoveFlags_AllowCurrentNavId     = 1 << 4,   // Allow scoring and considering the current NavId as a move target candidate. This is used when the move source is offset (e.g. pressing PageDown actually needs to send a Up move request, if we are pressing PageDown from the bottom-most item we need to stay in place) | ||||||
|  |     ImGuiNavMoveFlags_AlsoScoreVisibleSet   = 1 << 5,   // Store alternate result in NavMoveResultLocalVisibleSet that only comprise elements that are already fully visible (used by PageUp/PageDown) | ||||||
|  |     ImGuiNavMoveFlags_ScrollToEdge          = 1 << 6, | ||||||
|  |     ImGuiNavMoveFlags_Forwarded             = 1 << 7 | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | enum ImGuiNavLayer | ||||||
|  | { | ||||||
|  |     ImGuiNavLayer_Main  = 0,    // Main scrolling layer | ||||||
|  |     ImGuiNavLayer_Menu  = 1,    // Menu layer (access with Alt/ImGuiNavInput_Menu) | ||||||
|  |     ImGuiNavLayer_COUNT | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | struct ImGuiNavItemData | ||||||
|  | { | ||||||
|  |     ImGuiWindow*        Window;         // Init,Move    // Best candidate window (result->ItemWindow->RootWindowForNav == request->Window) | ||||||
|  |     ImGuiID             ID;             // Init,Move    // Best candidate item ID | ||||||
|  |     ImGuiID             FocusScopeId;   // Init,Move    // Best candidate focus scope ID | ||||||
|  |     ImRect              RectRel;        // Init,Move    // Best candidate bounding box in window relative space | ||||||
|  |     float               DistBox;        //      Move    // Best candidate box distance to current NavId | ||||||
|  |     float               DistCenter;     //      Move    // Best candidate center distance to current NavId | ||||||
|  |     float               DistAxial;      //      Move    // Best candidate axial distance to current NavId | ||||||
|  |  | ||||||
|  |     ImGuiNavItemData()  { Clear(); } | ||||||
|  |     void Clear()        { Window = NULL; ID = FocusScopeId = 0; RectRel = ImRect(); DistBox = DistCenter = DistAxial = FLT_MAX; } | ||||||
|  | }; | ||||||
|  |  | ||||||
| //----------------------------------------------------------------------------- | //----------------------------------------------------------------------------- | ||||||
| // [SECTION] Columns support | // [SECTION] Columns support | ||||||
| //----------------------------------------------------------------------------- | //----------------------------------------------------------------------------- | ||||||
| @@ -1708,22 +1701,20 @@ struct ImGuiContext | |||||||
|     bool                    NavMousePosDirty;                   // When set we will update mouse position if (io.ConfigFlags & ImGuiConfigFlags_NavEnableSetMousePos) if set (NB: this not enabled by default) |     bool                    NavMousePosDirty;                   // When set we will update mouse position if (io.ConfigFlags & ImGuiConfigFlags_NavEnableSetMousePos) if set (NB: this not enabled by default) | ||||||
|     bool                    NavDisableHighlight;                // When user starts using mouse, we hide gamepad/keyboard highlight (NB: but they are still available, which is why NavDisableHighlight isn't always != NavDisableMouseHover) |     bool                    NavDisableHighlight;                // When user starts using mouse, we hide gamepad/keyboard highlight (NB: but they are still available, which is why NavDisableHighlight isn't always != NavDisableMouseHover) | ||||||
|     bool                    NavDisableMouseHover;               // When user starts using gamepad/keyboard, we hide mouse hovering highlight until mouse is touched again. |     bool                    NavDisableMouseHover;               // When user starts using gamepad/keyboard, we hide mouse hovering highlight until mouse is touched again. | ||||||
|     bool                    NavAnyRequest;                      // ~~ NavMoveRequest || NavInitRequest |     bool                    NavAnyRequest;                      // ~~ NavMoveRequest || NavInitRequest this is to perform early out in ItemAdd() | ||||||
|     bool                    NavInitRequest;                     // Init request for appearing window to select first item |     bool                    NavInitRequest;                     // Init request for appearing window to select first item | ||||||
|     bool                    NavInitRequestFromMove; |     bool                    NavInitRequestFromMove; | ||||||
|     ImGuiID                 NavInitResultId;                    // Init request result (first item of the window, or one for which SetItemDefaultFocus() was called) |     ImGuiID                 NavInitResultId;                    // Init request result (first item of the window, or one for which SetItemDefaultFocus() was called) | ||||||
|     ImRect                  NavInitResultRectRel;               // Init request result rectangle (relative to parent window) |     ImRect                  NavInitResultRectRel;               // Init request result rectangle (relative to parent window) | ||||||
|     bool                    NavMoveRequest;                     // Move request for this frame |     bool                    NavMoveRequest;                     // Move request for this frame | ||||||
|  |     bool                    NavMoveRequestForwardToNextFrame; | ||||||
|     ImGuiNavMoveFlags       NavMoveRequestFlags; |     ImGuiNavMoveFlags       NavMoveRequestFlags; | ||||||
|     ImGuiNavForward         NavMoveRequestForward;              // None / ForwardQueued / ForwardActive (this is used to navigate sibling parent menus from a child menu) |  | ||||||
|     ImGuiKeyModFlags        NavMoveRequestKeyMods; |     ImGuiKeyModFlags        NavMoveRequestKeyMods; | ||||||
|     ImGuiDir                NavMoveDir, NavMoveDirLast;         // Direction of the move request (left/right/up/down), direction of the previous move request |     ImGuiDir                NavMoveDir, NavMoveDirLast;         // Direction of the move request (left/right/up/down), direction of the previous move request | ||||||
|     ImGuiDir                NavMoveClipDir;                     // FIXME-NAV: Describe the purpose of this better. Might want to rename? |     ImGuiDir                NavMoveClipDir;                     // FIXME-NAV: Describe the purpose of this better. Might want to rename? | ||||||
|     ImGuiNavItemData        NavMoveResultLocal;                 // Best move request candidate within NavWindow |     ImGuiNavItemData        NavMoveResultLocal;                 // Best move request candidate within NavWindow | ||||||
|     ImGuiNavItemData        NavMoveResultLocalVisibleSet;       // Best move request candidate within NavWindow that are mostly visible (when using ImGuiNavMoveFlags_AlsoScoreVisibleSet flag) |     ImGuiNavItemData        NavMoveResultLocalVisibleSet;       // Best move request candidate within NavWindow that are mostly visible (when using ImGuiNavMoveFlags_AlsoScoreVisibleSet flag) | ||||||
|     ImGuiNavItemData        NavMoveResultOther;                 // Best move request candidate within NavWindow's flattened hierarchy (when using ImGuiWindowFlags_NavFlattened flag) |     ImGuiNavItemData        NavMoveResultOther;                 // Best move request candidate within NavWindow's flattened hierarchy (when using ImGuiWindowFlags_NavFlattened flag) | ||||||
|     ImGuiWindow*            NavWrapRequestWindow;               // Window which requested trying nav wrap-around. |  | ||||||
|     ImGuiNavMoveFlags       NavWrapRequestFlags;                // Wrap-around operation flags. |  | ||||||
|  |  | ||||||
|     // Navigation: Windowing (CTRL+TAB for list, or Menu button + keys or directional pads to move/resize) |     // Navigation: Windowing (CTRL+TAB for list, or Menu button + keys or directional pads to move/resize) | ||||||
|     ImGuiWindow*            NavWindowingTarget;                 // Target window when doing CTRL+Tab (or Pad Menu + FocusPrev/Next), this window is temporarily displayed top-most! |     ImGuiWindow*            NavWindowingTarget;                 // Target window when doing CTRL+Tab (or Pad Menu + FocusPrev/Next), this window is temporarily displayed top-most! | ||||||
| @@ -1931,12 +1922,10 @@ struct ImGuiContext | |||||||
|         NavInitRequestFromMove = false; |         NavInitRequestFromMove = false; | ||||||
|         NavInitResultId = 0; |         NavInitResultId = 0; | ||||||
|         NavMoveRequest = false; |         NavMoveRequest = false; | ||||||
|  |         NavMoveRequestForwardToNextFrame = false; | ||||||
|         NavMoveRequestFlags = ImGuiNavMoveFlags_None; |         NavMoveRequestFlags = ImGuiNavMoveFlags_None; | ||||||
|         NavMoveRequestForward = ImGuiNavForward_None; |  | ||||||
|         NavMoveRequestKeyMods = ImGuiKeyModFlags_None; |         NavMoveRequestKeyMods = ImGuiKeyModFlags_None; | ||||||
|         NavMoveDir = NavMoveDirLast = NavMoveClipDir = ImGuiDir_None; |         NavMoveDir = NavMoveDirLast = NavMoveClipDir = ImGuiDir_None; | ||||||
|         NavWrapRequestWindow = NULL; |  | ||||||
|         NavWrapRequestFlags = ImGuiNavMoveFlags_None; |  | ||||||
|  |  | ||||||
|         NavWindowingTarget = NavWindowingTargetAnim = NavWindowingListWindow = NULL; |         NavWindowingTarget = NavWindowingTargetAnim = NavWindowingListWindow = NULL; | ||||||
|         NavWindowingTimer = NavWindowingHighlightAlpha = 0.0f; |         NavWindowingTimer = NavWindowingHighlightAlpha = 0.0f; | ||||||
| @@ -2659,8 +2648,8 @@ namespace ImGui | |||||||
|     //  (Old) IMGUI_VERSION_NUM  < 18209: using 'ItemAdd(....)'                              and 'bool focused = FocusableItemRegister(...)' |     //  (Old) IMGUI_VERSION_NUM  < 18209: using 'ItemAdd(....)'                              and 'bool focused = FocusableItemRegister(...)' | ||||||
|     //  (New) IMGUI_VERSION_NUM >= 18209: using 'ItemAdd(..., ImGuiItemAddFlags_Focusable)'  and 'bool focused = (GetItemStatusFlags() & ImGuiItemStatusFlags_Focused) != 0' |     //  (New) IMGUI_VERSION_NUM >= 18209: using 'ItemAdd(..., ImGuiItemAddFlags_Focusable)'  and 'bool focused = (GetItemStatusFlags() & ImGuiItemStatusFlags_Focused) != 0' | ||||||
|     // Widget code are simplified as there's no need to call FocusableItemUnregister() while managing the transition from regular widget to TempInputText() |     // Widget code are simplified as there's no need to call FocusableItemUnregister() while managing the transition from regular widget to TempInputText() | ||||||
|     inline bool FocusableItemRegister(ImGuiWindow* window, ImGuiID id)   { IM_ASSERT(0); IM_UNUSED(window); IM_UNUSED(id); return false; } // -> pass ImGuiItemAddFlags_Focusable flag to ItemAdd() |     inline bool FocusableItemRegister(ImGuiWindow* window, ImGuiID id)  { IM_ASSERT(0); IM_UNUSED(window); IM_UNUSED(id); return false; } // -> pass ImGuiItemAddFlags_Focusable flag to ItemAdd() | ||||||
|     inline IM_NORETURN void FocusableItemUnregister(ImGuiWindow* window) { IM_ASSERT(0); IM_UNUSED(window); }                              // -> unnecessary: TempInputText() uses ImGuiInputTextFlags_MergedItem |     inline void FocusableItemUnregister(ImGuiWindow* window)            { IM_ASSERT(0); IM_UNUSED(window); }                              // -> unnecessary: TempInputText() uses ImGuiInputTextFlags_MergedItem | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
|     // Logging/Capture |     // Logging/Capture | ||||||
| @@ -2684,6 +2673,7 @@ namespace ImGui | |||||||
|     IMGUI_API bool          BeginViewportSideBar(const char* name, ImGuiViewport* viewport, ImGuiDir dir, float size, ImGuiWindowFlags window_flags); |     IMGUI_API bool          BeginViewportSideBar(const char* name, ImGuiViewport* viewport, ImGuiDir dir, float size, ImGuiWindowFlags window_flags); | ||||||
|  |  | ||||||
|     // Menus |     // Menus | ||||||
|  |     IMGUI_API bool          BeginMenuEx(const char* label, const char* icon, bool enabled = true); | ||||||
|     IMGUI_API bool          MenuItemEx(const char* label, const char* icon, const char* shortcut = NULL, bool selected = false, bool enabled = true); |     IMGUI_API bool          MenuItemEx(const char* label, const char* icon, const char* shortcut = NULL, bool selected = false, bool enabled = true); | ||||||
|  |  | ||||||
|     // Combos |     // Combos | ||||||
| @@ -2693,9 +2683,10 @@ namespace ImGui | |||||||
|  |  | ||||||
|     // Gamepad/Keyboard Navigation |     // Gamepad/Keyboard Navigation | ||||||
|     IMGUI_API void          NavInitWindow(ImGuiWindow* window, bool force_reinit); |     IMGUI_API void          NavInitWindow(ImGuiWindow* window, bool force_reinit); | ||||||
|     IMGUI_API bool          NavMoveRequestButNoResultYet(); |     IMGUI_API bool          NavMoveRequestButNoResultYet(); // Should be called ~NavMoveRequestIsActiveButNoResultYet() | ||||||
|  |     IMGUI_API void          NavMoveRequestForward(ImGuiDir move_dir, ImGuiDir clip_dir, ImGuiNavMoveFlags move_flags); | ||||||
|     IMGUI_API void          NavMoveRequestCancel(); |     IMGUI_API void          NavMoveRequestCancel(); | ||||||
|     IMGUI_API void          NavMoveRequestForward(ImGuiDir move_dir, ImGuiDir clip_dir, const ImRect& bb_rel, ImGuiNavMoveFlags move_flags); |     IMGUI_API void          NavMoveRequestApplyResult(); | ||||||
|     IMGUI_API void          NavMoveRequestTryWrapping(ImGuiWindow* window, ImGuiNavMoveFlags move_flags); |     IMGUI_API void          NavMoveRequestTryWrapping(ImGuiWindow* window, ImGuiNavMoveFlags move_flags); | ||||||
|     IMGUI_API float         GetNavInputAmount(ImGuiNavInput n, ImGuiInputReadMode mode); |     IMGUI_API float         GetNavInputAmount(ImGuiNavInput n, ImGuiInputReadMode mode); | ||||||
|     IMGUI_API ImVec2        GetNavInputAmount2d(ImGuiNavDirSourceFlags dir_sources, ImGuiInputReadMode mode, float slow_factor = 0.0f, float fast_factor = 0.0f); |     IMGUI_API ImVec2        GetNavInputAmount2d(ImGuiNavDirSourceFlags dir_sources, ImGuiInputReadMode mode, float slow_factor = 0.0f, float fast_factor = 0.0f); | ||||||
|   | |||||||
| @@ -1,4 +1,4 @@ | |||||||
| // dear imgui, v1.84 | // dear imgui, v1.85 WIP | ||||||
| // (tables and columns code) | // (tables and columns code) | ||||||
|  |  | ||||||
| /* | /* | ||||||
|   | |||||||
| @@ -1,4 +1,4 @@ | |||||||
| // dear imgui, v1.84 | // dear imgui, v1.85 WIP | ||||||
| // (widgets code) | // (widgets code) | ||||||
|  |  | ||||||
| /* | /* | ||||||
| @@ -152,9 +152,13 @@ void ImGui::TextEx(const char* text, const char* text_end, ImGuiTextFlags flags) | |||||||
|     ImGuiWindow* window = GetCurrentWindow(); |     ImGuiWindow* window = GetCurrentWindow(); | ||||||
|     if (window->SkipItems) |     if (window->SkipItems) | ||||||
|         return; |         return; | ||||||
|  |  | ||||||
|     ImGuiContext& g = *GImGui; |     ImGuiContext& g = *GImGui; | ||||||
|     IM_ASSERT(text != NULL); |  | ||||||
|  |     // Accept null ranges | ||||||
|  |     if (text == text_end) | ||||||
|  |         text = text_end = ""; | ||||||
|  |  | ||||||
|  |     // Calculate length | ||||||
|     const char* text_begin = text; |     const char* text_begin = text; | ||||||
|     if (text_end == NULL) |     if (text_end == NULL) | ||||||
|         text_end = text + strlen(text); // FIXME-OPT |         text_end = text + strlen(text); // FIXME-OPT | ||||||
| @@ -3975,13 +3979,15 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_ | |||||||
|     ImGuiItemStatusFlags item_status_flags = 0; |     ImGuiItemStatusFlags item_status_flags = 0; | ||||||
|     if (is_multiline) |     if (is_multiline) | ||||||
|     { |     { | ||||||
|  |         ImVec2 backup_pos = window->DC.CursorPos; | ||||||
|  |         ItemSize(total_bb, style.FramePadding.y); | ||||||
|         if (!ItemAdd(total_bb, id, &frame_bb, ImGuiItemAddFlags_Focusable)) |         if (!ItemAdd(total_bb, id, &frame_bb, ImGuiItemAddFlags_Focusable)) | ||||||
|         { |         { | ||||||
|             ItemSize(total_bb, style.FramePadding.y); |  | ||||||
|             EndGroup(); |             EndGroup(); | ||||||
|             return false; |             return false; | ||||||
|         } |         } | ||||||
|         item_status_flags = g.LastItemData.StatusFlags; |         item_status_flags = g.LastItemData.StatusFlags; | ||||||
|  |         window->DC.CursorPos = backup_pos; | ||||||
|  |  | ||||||
|         // We reproduce the contents of BeginChildFrame() in order to provide 'label' so our window internal data are easier to read/debug. |         // We reproduce the contents of BeginChildFrame() in order to provide 'label' so our window internal data are easier to read/debug. | ||||||
|         PushStyleColor(ImGuiCol_ChildBg, style.Colors[ImGuiCol_FrameBg]); |         PushStyleColor(ImGuiCol_ChildBg, style.Colors[ImGuiCol_FrameBg]); | ||||||
| @@ -5900,12 +5906,12 @@ bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* l | |||||||
|                 toggled = true; |                 toggled = true; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         if (g.NavId == id && g.NavMoveRequest && g.NavMoveDir == ImGuiDir_Left && is_open) |         if (g.NavId == id && g.NavMoveDir == ImGuiDir_Left && is_open) | ||||||
|         { |         { | ||||||
|             toggled = true; |             toggled = true; | ||||||
|             NavMoveRequestCancel(); |             NavMoveRequestCancel(); | ||||||
|         } |         } | ||||||
|         if (g.NavId == id && g.NavMoveRequest && g.NavMoveDir == ImGuiDir_Right && !is_open) // If there's something upcoming on the line we may want to give it the priority? |         if (g.NavId == id && g.NavMoveDir == ImGuiDir_Right && !is_open) // If there's something upcoming on the line we may want to give it the priority? | ||||||
|         { |         { | ||||||
|             toggled = true; |             toggled = true; | ||||||
|             NavMoveRequestCancel(); |             NavMoveRequestCancel(); | ||||||
| @@ -6693,18 +6699,17 @@ void ImGui::EndMenuBar() | |||||||
|         ImGuiWindow* nav_earliest_child = g.NavWindow; |         ImGuiWindow* nav_earliest_child = g.NavWindow; | ||||||
|         while (nav_earliest_child->ParentWindow && (nav_earliest_child->ParentWindow->Flags & ImGuiWindowFlags_ChildMenu)) |         while (nav_earliest_child->ParentWindow && (nav_earliest_child->ParentWindow->Flags & ImGuiWindowFlags_ChildMenu)) | ||||||
|             nav_earliest_child = nav_earliest_child->ParentWindow; |             nav_earliest_child = nav_earliest_child->ParentWindow; | ||||||
|         if (nav_earliest_child->ParentWindow == window && nav_earliest_child->DC.ParentLayoutType == ImGuiLayoutType_Horizontal && g.NavMoveRequestForward == ImGuiNavForward_None) |         if (nav_earliest_child->ParentWindow == window && nav_earliest_child->DC.ParentLayoutType == ImGuiLayoutType_Horizontal && (g.NavMoveRequestFlags & ImGuiNavMoveFlags_Forwarded) == 0) | ||||||
|         { |         { | ||||||
|             // To do so we claim focus back, restore NavId and then process the movement request for yet another frame. |             // To do so we claim focus back, restore NavId and then process the movement request for yet another frame. | ||||||
|             // This involve a one-frame delay which isn't very problematic in this situation. We could remove it by scoring in advance for multiple window (probably not worth the hassle/cost) |             // This involve a one-frame delay which isn't very problematic in this situation. We could remove it by scoring in advance for multiple window (probably not worth bothering) | ||||||
|             const ImGuiNavLayer layer = ImGuiNavLayer_Menu; |             const ImGuiNavLayer layer = ImGuiNavLayer_Menu; | ||||||
|             IM_ASSERT(window->DC.NavLayersActiveMaskNext & (1 << layer)); // Sanity check |             IM_ASSERT(window->DC.NavLayersActiveMaskNext & (1 << layer)); // Sanity check | ||||||
|             FocusWindow(window); |             FocusWindow(window); | ||||||
|             SetNavID(window->NavLastIds[layer], layer, 0, window->NavRectRel[layer]); |             SetNavID(window->NavLastIds[layer], layer, 0, window->NavRectRel[layer]); | ||||||
|             g.NavDisableHighlight = true; // Hide highlight for the current frame so we don't see the intermediary selection. |             g.NavDisableHighlight = true; // Hide highlight for the current frame so we don't see the intermediary selection. | ||||||
|             g.NavDisableMouseHover = g.NavMousePosDirty = true; |             g.NavDisableMouseHover = g.NavMousePosDirty = true; | ||||||
|             g.NavMoveRequestForward = ImGuiNavForward_ForwardQueued; |             NavMoveRequestForward(g.NavMoveDir, g.NavMoveClipDir, g.NavMoveRequestFlags); // Repeat | ||||||
|             NavMoveRequestCancel(); |  | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -6797,7 +6802,7 @@ void ImGui::EndMainMenuBar() | |||||||
|     End(); |     End(); | ||||||
| } | } | ||||||
|  |  | ||||||
| bool ImGui::BeginMenu(const char* label, bool enabled) | bool ImGui::BeginMenuEx(const char* label, const char* icon, bool enabled) | ||||||
| { | { | ||||||
|     ImGuiWindow* window = GetCurrentWindow(); |     ImGuiWindow* window = GetCurrentWindow(); | ||||||
|     if (window->SkipItems) |     if (window->SkipItems) | ||||||
| @@ -6864,13 +6869,15 @@ bool ImGui::BeginMenu(const char* label, bool enabled) | |||||||
|         // (In a typical menu window where all items are BeginMenu() or MenuItem() calls, extra_w will always be 0.0f. |         // (In a typical menu window where all items are BeginMenu() or MenuItem() calls, extra_w will always be 0.0f. | ||||||
|         //  Only when they are other items sticking out we're going to add spacing, yet only register minimum width into the layout system. |         //  Only when they are other items sticking out we're going to add spacing, yet only register minimum width into the layout system. | ||||||
|         popup_pos = ImVec2(pos.x, pos.y - style.WindowPadding.y); |         popup_pos = ImVec2(pos.x, pos.y - style.WindowPadding.y); | ||||||
|         float icon_w = 0.0f; // FIXME: This not currently exposed for BeginMenu() however you can call window->DC.MenuColumns.DeclColumns(w, 0, 0, 0) yourself |         float icon_w = (icon && icon[0]) ? CalcTextSize(icon, NULL).x : 0.0f; | ||||||
|         float checkmark_w = IM_FLOOR(g.FontSize * 1.20f); |         float checkmark_w = IM_FLOOR(g.FontSize * 1.20f); | ||||||
|         float min_w = window->DC.MenuColumns.DeclColumns(icon_w, label_size.x, 0.0f, checkmark_w); // Feedback to next frame |         float min_w = window->DC.MenuColumns.DeclColumns(icon_w, label_size.x, 0.0f, checkmark_w); // Feedback to next frame | ||||||
|         float extra_w = ImMax(0.0f, GetContentRegionAvail().x - min_w); |         float extra_w = ImMax(0.0f, GetContentRegionAvail().x - min_w); | ||||||
|         ImVec2 text_pos(window->DC.CursorPos.x + offsets->OffsetLabel, window->DC.CursorPos.y + window->DC.CurrLineTextBaseOffset); |         ImVec2 text_pos(window->DC.CursorPos.x + offsets->OffsetLabel, window->DC.CursorPos.y + window->DC.CurrLineTextBaseOffset); | ||||||
|         pressed = Selectable("", menu_is_open, ImGuiSelectableFlags_NoHoldingActiveID | ImGuiSelectableFlags_SelectOnClick | ImGuiSelectableFlags_DontClosePopups | ImGuiSelectableFlags_SpanAvailWidth, ImVec2(min_w, 0.0f)); |         pressed = Selectable("", menu_is_open, ImGuiSelectableFlags_NoHoldingActiveID | ImGuiSelectableFlags_SelectOnClick | ImGuiSelectableFlags_DontClosePopups | ImGuiSelectableFlags_SpanAvailWidth, ImVec2(min_w, 0.0f)); | ||||||
|         RenderText(text_pos, label); |         RenderText(text_pos, label); | ||||||
|  |         if (icon_w > 0.0f) | ||||||
|  |             RenderText(pos + ImVec2(offsets->OffsetIcon, 0.0f), icon); | ||||||
|         RenderArrow(window->DrawList, pos + ImVec2(offsets->OffsetMark + extra_w + g.FontSize * 0.30f, 0.0f), GetColorU32(ImGuiCol_Text), ImGuiDir_Right); |         RenderArrow(window->DrawList, pos + ImVec2(offsets->OffsetMark + extra_w + g.FontSize * 0.30f, 0.0f), GetColorU32(ImGuiCol_Text), ImGuiDir_Right); | ||||||
|     } |     } | ||||||
|     if (!enabled) |     if (!enabled) | ||||||
| @@ -6918,7 +6925,7 @@ bool ImGui::BeginMenu(const char* label, bool enabled) | |||||||
|             want_close = menu_is_open; |             want_close = menu_is_open; | ||||||
|             want_open = !menu_is_open; |             want_open = !menu_is_open; | ||||||
|         } |         } | ||||||
|         if (g.NavId == id && g.NavMoveRequest && g.NavMoveDir == ImGuiDir_Right) // Nav-Right to open |         if (g.NavId == id && g.NavMoveDir == ImGuiDir_Right) // Nav-Right to open | ||||||
|         { |         { | ||||||
|             want_open = true; |             want_open = true; | ||||||
|             NavMoveRequestCancel(); |             NavMoveRequestCancel(); | ||||||
| @@ -6936,7 +6943,7 @@ bool ImGui::BeginMenu(const char* label, bool enabled) | |||||||
|         { |         { | ||||||
|             want_open = true; |             want_open = true; | ||||||
|         } |         } | ||||||
|         else if (g.NavId == id && g.NavMoveRequest && g.NavMoveDir == ImGuiDir_Down) // Nav-Down to open |         else if (g.NavId == id && g.NavMoveDir == ImGuiDir_Down) // Nav-Down to open | ||||||
|         { |         { | ||||||
|             want_open = true; |             want_open = true; | ||||||
|             NavMoveRequestCancel(); |             NavMoveRequestCancel(); | ||||||
| @@ -6975,6 +6982,11 @@ bool ImGui::BeginMenu(const char* label, bool enabled) | |||||||
|     return menu_is_open; |     return menu_is_open; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | bool ImGui::BeginMenu(const char* label, bool enabled) | ||||||
|  | { | ||||||
|  |     return BeginMenuEx(label, NULL, enabled); | ||||||
|  | } | ||||||
|  |  | ||||||
| void ImGui::EndMenu() | void ImGui::EndMenu() | ||||||
| { | { | ||||||
|     // Nav: When a left move request _within our child menu_ failed, close ourselves (the _parent_ menu). |     // Nav: When a left move request _within our child menu_ failed, close ourselves (the _parent_ menu). | ||||||
|   | |||||||
| @@ -6,6 +6,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/08/23: fixed crash when FT_Render_Glyph() fails to render a glyph and returns NULL. | ||||||
| //  2021/03/05: added ImGuiFreeTypeBuilderFlags_Bitmap to load bitmap glyphs. | //  2021/03/05: added ImGuiFreeTypeBuilderFlags_Bitmap to load bitmap glyphs. | ||||||
| //  2021/03/02: set 'atlas->TexPixelsUseColors = true' to help some backends with deciding of a prefered texture format. | //  2021/03/02: set 'atlas->TexPixelsUseColors = true' to help some backends with deciding of a prefered texture format. | ||||||
| //  2021/01/28: added support for color-layered glyphs via ImGuiFreeTypeBuilderFlags_LoadColor (require Freetype 2.10+). | //  2021/01/28: added support for color-layered glyphs via ImGuiFreeTypeBuilderFlags_LoadColor (require Freetype 2.10+). | ||||||
| @@ -539,7 +540,8 @@ bool ImFontAtlasBuildWithFreeTypeEx(FT_Library ft_library, ImFontAtlas* atlas, u | |||||||
|  |  | ||||||
|             // Render glyph into a bitmap (currently held by FreeType) |             // Render glyph into a bitmap (currently held by FreeType) | ||||||
|             const FT_Bitmap* ft_bitmap = src_tmp.Font.RenderGlyphAndGetInfo(&src_glyph.Info); |             const FT_Bitmap* ft_bitmap = src_tmp.Font.RenderGlyphAndGetInfo(&src_glyph.Info); | ||||||
|             IM_ASSERT(ft_bitmap); |             if (ft_bitmap == NULL) | ||||||
|  |                 continue; | ||||||
|  |  | ||||||
|             // Allocate new temporary chunk if needed |             // Allocate new temporary chunk if needed | ||||||
|             const int bitmap_size_in_bytes = src_glyph.Info.Width * src_glyph.Info.Height * 4; |             const int bitmap_size_in_bytes = src_glyph.Info.Width * src_glyph.Info.Height * 4; | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 ocornut
					ocornut