diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 4e276e1de..f7c637cab 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -712,6 +712,8 @@ jobs: # Fix SDK and toolset for samples that require newer SDK/toolset. At the moment it is only dx12. (Get-Content $_.FullName) -Replace "v140","v142" | Set-Content -Path $_.FullName (Get-Content $_.FullName) -Replace "10.0.14393.0","10.0.20348.0" | Set-Content -Path $_.FullName + # Stack Layout: the test engine's projects do not list imgui_stacklayout.cpp. + (Get-Content $_.FullName) -Replace '^(\s*)','$1$&' | Set-Content -Path $_.FullName } - name: Build Tests @@ -756,7 +758,10 @@ jobs: - name: Build Tests working-directory: ${{ github.workspace }}/imgui_test_engine/imgui_test_suite - run: make -j$(nproc) + run: | + # Stack Layout: the test engine's Makefile does not list imgui_stacklayout.cpp. + sed -i 's|$(IMGUI_DIR)/imgui_tables.cpp|$(IMGUI_DIR)/imgui_stacklayout.cpp $(IMGUI_DIR)/imgui_tables.cpp|' Makefile + make -j$(nproc) - name: Run Tests working-directory: ${{ github.workspace }}/imgui_test_engine/imgui_test_suite diff --git a/examples/example_allegro5/example_allegro5.vcxproj b/examples/example_allegro5/example_allegro5.vcxproj index 36c55bb10..e5d3ffbfd 100644 --- a/examples/example_allegro5/example_allegro5.vcxproj +++ b/examples/example_allegro5/example_allegro5.vcxproj @@ -164,6 +164,7 @@ + @@ -174,6 +175,8 @@ + + diff --git a/examples/example_allegro5/example_allegro5.vcxproj.filters b/examples/example_allegro5/example_allegro5.vcxproj.filters index 84881d371..99a9e8ce9 100644 --- a/examples/example_allegro5/example_allegro5.vcxproj.filters +++ b/examples/example_allegro5/example_allegro5.vcxproj.filters @@ -28,6 +28,9 @@ sources + + imgui + imgui @@ -45,6 +48,12 @@ imgui + + imgui + + + imgui + sources diff --git a/examples/example_android_opengl3/CMakeLists.txt b/examples/example_android_opengl3/CMakeLists.txt index 63531f4dc..87e8aa186 100644 --- a/examples/example_android_opengl3/CMakeLists.txt +++ b/examples/example_android_opengl3/CMakeLists.txt @@ -11,6 +11,7 @@ add_library(${CMAKE_PROJECT_NAME} SHARED ${CMAKE_CURRENT_SOURCE_DIR}/../../imgui.cpp ${CMAKE_CURRENT_SOURCE_DIR}/../../imgui_demo.cpp ${CMAKE_CURRENT_SOURCE_DIR}/../../imgui_draw.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/../../imgui_stacklayout.cpp ${CMAKE_CURRENT_SOURCE_DIR}/../../imgui_tables.cpp ${CMAKE_CURRENT_SOURCE_DIR}/../../imgui_widgets.cpp ${CMAKE_CURRENT_SOURCE_DIR}/../../backends/imgui_impl_android.cpp diff --git a/examples/example_apple_metal/Makefile b/examples/example_apple_metal/Makefile index 9412c9b53..937da71e2 100644 --- a/examples/example_apple_metal/Makefile +++ b/examples/example_apple_metal/Makefile @@ -3,7 +3,7 @@ CXX = clang++ EXE = example_apple_metal IMGUI_DIR = ../../ SOURCES = main.mm -SOURCES += $(IMGUI_DIR)/imgui.cpp $(IMGUI_DIR)/imgui_demo.cpp $(IMGUI_DIR)/imgui_draw.cpp $(IMGUI_DIR)/imgui_tables.cpp $(IMGUI_DIR)/imgui_widgets.cpp +SOURCES += $(IMGUI_DIR)/imgui.cpp $(IMGUI_DIR)/imgui_demo.cpp $(IMGUI_DIR)/imgui_draw.cpp $(IMGUI_DIR)/imgui_stacklayout.cpp $(IMGUI_DIR)/imgui_tables.cpp $(IMGUI_DIR)/imgui_widgets.cpp SOURCES += $(IMGUI_DIR)/backends/imgui_impl_osx.mm $(IMGUI_DIR)/backends/imgui_impl_metal.mm CXXFLAGS = -std=c++11 -ObjC++ -fobjc-arc -Wall -Wextra -I$(IMGUI_DIR) -I$(IMGUI_DIR)/backends diff --git a/examples/example_apple_metal/example_apple_metal.xcodeproj/project.pbxproj b/examples/example_apple_metal/example_apple_metal.xcodeproj/project.pbxproj index bf3c80d6e..dc0bb2def 100644 --- a/examples/example_apple_metal/example_apple_metal.xcodeproj/project.pbxproj +++ b/examples/example_apple_metal/example_apple_metal.xcodeproj/project.pbxproj @@ -10,6 +10,7 @@ 05318E0F274C397200A8DE2E /* GameController.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 05318E0E274C397200A8DE2E /* GameController.framework */; }; 07A82ED82139413D0078D120 /* imgui_widgets.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 07A82ED72139413C0078D120 /* imgui_widgets.cpp */; }; 07A82ED92139418F0078D120 /* imgui_widgets.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 07A82ED72139413C0078D120 /* imgui_widgets.cpp */; }; + 5A1A002E257677DB0038A28D /* imgui_stacklayout.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5A1A002D257677DB0038A28D /* imgui_stacklayout.cpp */; }; 5079822E257677DB0038A28D /* imgui_tables.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5079822D257677DB0038A28D /* imgui_tables.cpp */; }; 8309BD8F253CCAAA0045E2A1 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8309BD8E253CCAAA0045E2A1 /* UIKit.framework */; }; 8309BDA5253CCC070045E2A1 /* main.mm in Sources */ = {isa = PBXBuildFile; fileRef = 8309BDA0253CCBC10045E2A1 /* main.mm */; }; @@ -36,6 +37,7 @@ 05318E0E274C397200A8DE2E /* GameController.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = GameController.framework; path = System/Library/Frameworks/GameController.framework; sourceTree = SDKROOT; }; 07A82ED62139413C0078D120 /* imgui_internal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = imgui_internal.h; path = ../../imgui_internal.h; sourceTree = ""; }; 07A82ED72139413C0078D120 /* imgui_widgets.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui_widgets.cpp; path = ../../imgui_widgets.cpp; sourceTree = ""; }; + 5A1A002D257677DB0038A28D /* imgui_stacklayout.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui_stacklayout.cpp; path = ../../imgui_stacklayout.cpp; sourceTree = ""; }; 5079822D257677DB0038A28D /* imgui_tables.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui_tables.cpp; path = ../../imgui_tables.cpp; sourceTree = ""; }; 8307E7C420E9F9C900473790 /* example_apple_metal.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = example_apple_metal.app; sourceTree = BUILT_PRODUCTS_DIR; }; 8307E7DA20E9F9C900473790 /* example_apple_metal.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = example_apple_metal.app; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -152,6 +154,7 @@ 83BBE9F020EB544400295997 /* imgui */ = { isa = PBXGroup; children = ( + 5A1A002D257677DB0038A28D /* imgui_stacklayout.cpp */, 5079822D257677DB0038A28D /* imgui_tables.cpp */, 8309BDB5253CCC9D0045E2A1 /* imgui_impl_metal.mm */, 8309BDB6253CCC9D0045E2A1 /* imgui_impl_osx.mm */, @@ -270,6 +273,7 @@ 83BBEA0920EB54E700295997 /* imgui.cpp in Sources */, 83BBEA0720EB54E700295997 /* imgui_demo.cpp in Sources */, 83BBEA0520EB54E700295997 /* imgui_draw.cpp in Sources */, + 5A1A002E257677DB0038A28D /* imgui_stacklayout.cpp in Sources */, 5079822E257677DB0038A28D /* imgui_tables.cpp in Sources */, 07A82ED82139413D0078D120 /* imgui_widgets.cpp in Sources */, 8309BDA5253CCC070045E2A1 /* main.mm in Sources */, @@ -285,6 +289,7 @@ 83BBEA0A20EB54E700295997 /* imgui.cpp in Sources */, 83BBEA0820EB54E700295997 /* imgui_demo.cpp in Sources */, 83BBEA0620EB54E700295997 /* imgui_draw.cpp in Sources */, + 5A1A002E257677DB0038A28D /* imgui_stacklayout.cpp in Sources */, 5079822E257677DB0038A28D /* imgui_tables.cpp in Sources */, 07A82ED92139418F0078D120 /* imgui_widgets.cpp in Sources */, 8309BDA8253CCC080045E2A1 /* main.mm in Sources */, diff --git a/examples/example_apple_metal4/Makefile b/examples/example_apple_metal4/Makefile index 35cdac769..818a5dabe 100644 --- a/examples/example_apple_metal4/Makefile +++ b/examples/example_apple_metal4/Makefile @@ -3,7 +3,7 @@ CXX = clang++ EXE = example_apple_metal4 IMGUI_DIR = ../../ SOURCES = main.mm -SOURCES += $(IMGUI_DIR)/imgui.cpp $(IMGUI_DIR)/imgui_demo.cpp $(IMGUI_DIR)/imgui_draw.cpp $(IMGUI_DIR)/imgui_tables.cpp $(IMGUI_DIR)/imgui_widgets.cpp +SOURCES += $(IMGUI_DIR)/imgui.cpp $(IMGUI_DIR)/imgui_demo.cpp $(IMGUI_DIR)/imgui_draw.cpp $(IMGUI_DIR)/imgui_stacklayout.cpp $(IMGUI_DIR)/imgui_tables.cpp $(IMGUI_DIR)/imgui_widgets.cpp SOURCES += $(IMGUI_DIR)/backends/imgui_impl_osx.mm $(IMGUI_DIR)/backends/imgui_impl_metal4.mm CXXFLAGS = -std=c++11 -ObjC++ -fobjc-arc -Wall -Wextra -I$(IMGUI_DIR) -I$(IMGUI_DIR)/backends diff --git a/examples/example_apple_metal4/example_apple_metal4.xcodeproj/project.pbxproj b/examples/example_apple_metal4/example_apple_metal4.xcodeproj/project.pbxproj index ed60054fd..3239296c1 100644 --- a/examples/example_apple_metal4/example_apple_metal4.xcodeproj/project.pbxproj +++ b/examples/example_apple_metal4/example_apple_metal4.xcodeproj/project.pbxproj @@ -7,12 +7,14 @@ objects = { /* Begin PBXBuildFile section */ + 5A1A00AB2768052600AB6805 /* imgui_stacklayout.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5A1A002D257677DB0038A28D /* imgui_stacklayout.cpp */; }; 050450AB2768052600AB6805 /* imgui_tables.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5079822D257677DB0038A28D /* imgui_tables.cpp */; }; 050450AD276863B000AB6805 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 050450AC276863B000AB6805 /* QuartzCore.framework */; }; 05318E0F274C397200A8DE2E /* GameController.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 05318E0E274C397200A8DE2E /* GameController.framework */; }; 05A275442773BEA20084EF39 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 05A275432773BEA20084EF39 /* QuartzCore.framework */; }; 07A82ED82139413D0078D120 /* imgui_widgets.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 07A82ED72139413C0078D120 /* imgui_widgets.cpp */; }; 07A82ED92139418F0078D120 /* imgui_widgets.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 07A82ED72139413C0078D120 /* imgui_widgets.cpp */; }; + 5A1A002E257677DB0038A28D /* imgui_stacklayout.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5A1A002D257677DB0038A28D /* imgui_stacklayout.cpp */; }; 5079822E257677DB0038A28D /* imgui_tables.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5079822D257677DB0038A28D /* imgui_tables.cpp */; }; 8309BD8F253CCAAA0045E2A1 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8309BD8E253CCAAA0045E2A1 /* UIKit.framework */; }; 8309BDA5253CCC070045E2A1 /* main.mm in Sources */ = {isa = PBXBuildFile; fileRef = 8309BDA0253CCBC10045E2A1 /* main.mm */; }; @@ -43,6 +45,7 @@ 05A275432773BEA20084EF39 /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS15.2.sdk/System/Library/Frameworks/QuartzCore.framework; sourceTree = DEVELOPER_DIR; }; 07A82ED62139413C0078D120 /* imgui_internal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = imgui_internal.h; path = ../../imgui_internal.h; sourceTree = ""; }; 07A82ED72139413C0078D120 /* imgui_widgets.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui_widgets.cpp; path = ../../imgui_widgets.cpp; sourceTree = ""; }; + 5A1A002D257677DB0038A28D /* imgui_stacklayout.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui_stacklayout.cpp; path = ../../imgui_stacklayout.cpp; sourceTree = ""; }; 5079822D257677DB0038A28D /* imgui_tables.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui_tables.cpp; path = ../../imgui_tables.cpp; sourceTree = ""; }; 8307E7C420E9F9C900473790 /* example_apple_metal.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = example_apple_metal.app; sourceTree = BUILT_PRODUCTS_DIR; }; 8307E7DA20E9F9C900473790 /* example_apple_metal.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = example_apple_metal.app; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -163,6 +166,7 @@ 83BBE9F020EB544400295997 /* imgui */ = { isa = PBXGroup; children = ( + 5A1A002D257677DB0038A28D /* imgui_stacklayout.cpp */, 5079822D257677DB0038A28D /* imgui_tables.cpp */, 05A2754027728F5B0084EF39 /* imgui_impl_metal4.h */, 8309BDB5253CCC9D0045E2A1 /* imgui_impl_metal4.mm */, @@ -283,6 +287,7 @@ 83BBEA0920EB54E700295997 /* imgui.cpp in Sources */, 83BBEA0720EB54E700295997 /* imgui_demo.cpp in Sources */, 83BBEA0520EB54E700295997 /* imgui_draw.cpp in Sources */, + 5A1A002E257677DB0038A28D /* imgui_stacklayout.cpp in Sources */, 5079822E257677DB0038A28D /* imgui_tables.cpp in Sources */, 07A82ED82139413D0078D120 /* imgui_widgets.cpp in Sources */, 8309BDA5253CCC070045E2A1 /* main.mm in Sources */, @@ -298,6 +303,7 @@ 83BBEA0A20EB54E700295997 /* imgui.cpp in Sources */, 83BBEA0820EB54E700295997 /* imgui_demo.cpp in Sources */, 83BBEA0620EB54E700295997 /* imgui_draw.cpp in Sources */, + 5A1A00AB2768052600AB6805 /* imgui_stacklayout.cpp in Sources */, 050450AB2768052600AB6805 /* imgui_tables.cpp in Sources */, 07A82ED92139418F0078D120 /* imgui_widgets.cpp in Sources */, 8309BDA8253CCC080045E2A1 /* main.mm in Sources */, diff --git a/examples/example_apple_opengl2/Makefile b/examples/example_apple_opengl2/Makefile index 4ad5fa692..db471a7c0 100644 --- a/examples/example_apple_opengl2/Makefile +++ b/examples/example_apple_opengl2/Makefile @@ -3,7 +3,7 @@ CXX = clang++ EXE = example_apple_opengl2 IMGUI_DIR = ../../ SOURCES = main.mm -SOURCES += $(IMGUI_DIR)/imgui.cpp $(IMGUI_DIR)/imgui_demo.cpp $(IMGUI_DIR)/imgui_draw.cpp $(IMGUI_DIR)/imgui_tables.cpp $(IMGUI_DIR)/imgui_widgets.cpp +SOURCES += $(IMGUI_DIR)/imgui.cpp $(IMGUI_DIR)/imgui_demo.cpp $(IMGUI_DIR)/imgui_draw.cpp $(IMGUI_DIR)/imgui_stacklayout.cpp $(IMGUI_DIR)/imgui_tables.cpp $(IMGUI_DIR)/imgui_widgets.cpp SOURCES += $(IMGUI_DIR)/backends/imgui_impl_osx.mm $(IMGUI_DIR)/backends/imgui_impl_opengl2.cpp CXXFLAGS = -std=c++11 -ObjC++ -fobjc-arc -Wall -Wextra -I$(IMGUI_DIR) -I$(IMGUI_DIR)/backends diff --git a/examples/example_apple_opengl2/example_apple_opengl2.xcodeproj/project.pbxproj b/examples/example_apple_opengl2/example_apple_opengl2.xcodeproj/project.pbxproj index 9770e4396..f4d177a8a 100644 --- a/examples/example_apple_opengl2/example_apple_opengl2.xcodeproj/project.pbxproj +++ b/examples/example_apple_opengl2/example_apple_opengl2.xcodeproj/project.pbxproj @@ -17,6 +17,7 @@ 4080A9B020B0347A0036BA46 /* imgui_impl_osx.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4080A99F20B034280036BA46 /* imgui_impl_osx.mm */; }; 4080A9B320B034E40036BA46 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4080A9B220B034E40036BA46 /* Cocoa.framework */; }; 4080A9B520B034EA0036BA46 /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4080A9B420B034EA0036BA46 /* OpenGL.framework */; }; + 5A1A0030257677FD0038A28D /* imgui_stacklayout.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5A1A002F257677FC0038A28D /* imgui_stacklayout.cpp */; }; 50798230257677FD0038A28D /* imgui_tables.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5079822F257677FC0038A28D /* imgui_tables.cpp */; }; /* End PBXBuildFile section */ @@ -49,6 +50,7 @@ 4080A9AC20B0343C0036BA46 /* imconfig.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = imconfig.h; path = ../../imconfig.h; sourceTree = ""; }; 4080A9B220B034E40036BA46 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; }; 4080A9B420B034EA0036BA46 /* OpenGL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGL.framework; path = System/Library/Frameworks/OpenGL.framework; sourceTree = SDKROOT; }; + 5A1A002F257677FC0038A28D /* imgui_stacklayout.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui_stacklayout.cpp; path = ../../imgui_stacklayout.cpp; sourceTree = ""; }; 5079822F257677FC0038A28D /* imgui_tables.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui_tables.cpp; path = ../../imgui_tables.cpp; sourceTree = ""; }; /* End PBXFileReference section */ @@ -69,6 +71,7 @@ 4080A96220B029B00036BA46 = { isa = PBXGroup; children = ( + 5A1A002F257677FC0038A28D /* imgui_stacklayout.cpp */, 5079822F257677FC0038A28D /* imgui_tables.cpp */, 4080A9AC20B0343C0036BA46 /* imconfig.h */, 4080A9A720B0343C0036BA46 /* imgui.cpp */, @@ -168,6 +171,7 @@ 4080A9A220B034280036BA46 /* imgui_impl_opengl2.cpp in Sources */, 4080A9B020B0347A0036BA46 /* imgui_impl_osx.mm in Sources */, 4080A9AE20B0343C0036BA46 /* imgui.cpp in Sources */, + 5A1A0030257677FD0038A28D /* imgui_stacklayout.cpp in Sources */, 50798230257677FD0038A28D /* imgui_tables.cpp in Sources */, 07A82EDB213941D00078D120 /* imgui_widgets.cpp in Sources */, ); diff --git a/examples/example_apple_opengl3/Makefile b/examples/example_apple_opengl3/Makefile index c9f9d44d3..ece086a36 100644 --- a/examples/example_apple_opengl3/Makefile +++ b/examples/example_apple_opengl3/Makefile @@ -3,7 +3,7 @@ CXX = clang++ EXE = example_apple_opengl3 IMGUI_DIR = ../../ SOURCES = main.mm -SOURCES += $(IMGUI_DIR)/imgui.cpp $(IMGUI_DIR)/imgui_demo.cpp $(IMGUI_DIR)/imgui_draw.cpp $(IMGUI_DIR)/imgui_tables.cpp $(IMGUI_DIR)/imgui_widgets.cpp +SOURCES += $(IMGUI_DIR)/imgui.cpp $(IMGUI_DIR)/imgui_demo.cpp $(IMGUI_DIR)/imgui_draw.cpp $(IMGUI_DIR)/imgui_stacklayout.cpp $(IMGUI_DIR)/imgui_tables.cpp $(IMGUI_DIR)/imgui_widgets.cpp SOURCES += $(IMGUI_DIR)/backends/imgui_impl_osx.mm $(IMGUI_DIR)/backends/imgui_impl_opengl3.cpp CXXFLAGS = -std=c++11 -ObjC++ -fobjc-arc -Wall -Wextra -I$(IMGUI_DIR) -I$(IMGUI_DIR)/backends diff --git a/examples/example_apple_opengl3/example_apple_opengl3.xcodeproj/project.pbxproj b/examples/example_apple_opengl3/example_apple_opengl3.xcodeproj/project.pbxproj index 50ee35fd9..327a7a3cf 100644 --- a/examples/example_apple_opengl3/example_apple_opengl3.xcodeproj/project.pbxproj +++ b/examples/example_apple_opengl3/example_apple_opengl3.xcodeproj/project.pbxproj @@ -17,6 +17,7 @@ 4080A9B020B0347A0036BA46 /* imgui_impl_osx.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4080A99F20B034280036BA46 /* imgui_impl_osx.mm */; }; 4080A9B320B034E40036BA46 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4080A9B220B034E40036BA46 /* Cocoa.framework */; }; 4080A9B520B034EA0036BA46 /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4080A9B420B034EA0036BA46 /* OpenGL.framework */; }; + 5A1A0030257677FD0038A28D /* imgui_stacklayout.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5A1A002F257677FC0038A28D /* imgui_stacklayout.cpp */; }; 50798230257677FD0038A28D /* imgui_tables.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5079822F257677FC0038A28D /* imgui_tables.cpp */; }; /* End PBXBuildFile section */ @@ -50,6 +51,7 @@ 4080A9AC20B0343C0036BA46 /* imconfig.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = imconfig.h; path = ../../imconfig.h; sourceTree = ""; }; 4080A9B220B034E40036BA46 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; }; 4080A9B420B034EA0036BA46 /* OpenGL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGL.framework; path = System/Library/Frameworks/OpenGL.framework; sourceTree = SDKROOT; }; + 5A1A002F257677FC0038A28D /* imgui_stacklayout.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui_stacklayout.cpp; path = ../../imgui_stacklayout.cpp; sourceTree = ""; }; 5079822F257677FC0038A28D /* imgui_tables.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui_tables.cpp; path = ../../imgui_tables.cpp; sourceTree = ""; }; /* End PBXFileReference section */ @@ -70,6 +72,7 @@ 4080A96220B029B00036BA46 = { isa = PBXGroup; children = ( + 5A1A002F257677FC0038A28D /* imgui_stacklayout.cpp */, 5079822F257677FC0038A28D /* imgui_tables.cpp */, 4080A9AC20B0343C0036BA46 /* imconfig.h */, 4080A9A720B0343C0036BA46 /* imgui.cpp */, @@ -170,6 +173,7 @@ 4080A9A220B034280036BA46 /* imgui_impl_opengl3.cpp in Sources */, 4080A9B020B0347A0036BA46 /* imgui_impl_osx.mm in Sources */, 4080A9AE20B0343C0036BA46 /* imgui.cpp in Sources */, + 5A1A0030257677FD0038A28D /* imgui_stacklayout.cpp in Sources */, 50798230257677FD0038A28D /* imgui_tables.cpp in Sources */, 07A82EDB213941D00078D120 /* imgui_widgets.cpp in Sources */, ); diff --git a/examples/example_glfw_metal/Makefile b/examples/example_glfw_metal/Makefile index 32a7aeca2..30782cb9f 100644 --- a/examples/example_glfw_metal/Makefile +++ b/examples/example_glfw_metal/Makefile @@ -9,7 +9,7 @@ EXE = example_glfw_metal IMGUI_DIR = ../.. SOURCES = main.mm -SOURCES += $(IMGUI_DIR)/imgui.cpp $(IMGUI_DIR)/imgui_demo.cpp $(IMGUI_DIR)/imgui_draw.cpp $(IMGUI_DIR)/imgui_tables.cpp $(IMGUI_DIR)/imgui_widgets.cpp +SOURCES += $(IMGUI_DIR)/imgui.cpp $(IMGUI_DIR)/imgui_demo.cpp $(IMGUI_DIR)/imgui_draw.cpp $(IMGUI_DIR)/imgui_stacklayout.cpp $(IMGUI_DIR)/imgui_tables.cpp $(IMGUI_DIR)/imgui_widgets.cpp SOURCES += $(IMGUI_DIR)/backends/imgui_impl_glfw.cpp $(IMGUI_DIR)/backends/imgui_impl_metal.mm OBJS = $(addsuffix .o, $(basename $(notdir $(SOURCES)))) diff --git a/examples/example_glfw_opengl2/Makefile b/examples/example_glfw_opengl2/Makefile index a8a0128dc..a68ce712d 100644 --- a/examples/example_glfw_opengl2/Makefile +++ b/examples/example_glfw_opengl2/Makefile @@ -17,7 +17,7 @@ EXE = example_glfw_opengl2 IMGUI_DIR = ../.. SOURCES = main.cpp -SOURCES += $(IMGUI_DIR)/imgui.cpp $(IMGUI_DIR)/imgui_demo.cpp $(IMGUI_DIR)/imgui_draw.cpp $(IMGUI_DIR)/imgui_tables.cpp $(IMGUI_DIR)/imgui_widgets.cpp +SOURCES += $(IMGUI_DIR)/imgui.cpp $(IMGUI_DIR)/imgui_demo.cpp $(IMGUI_DIR)/imgui_draw.cpp $(IMGUI_DIR)/imgui_stacklayout.cpp $(IMGUI_DIR)/imgui_tables.cpp $(IMGUI_DIR)/imgui_widgets.cpp SOURCES += $(IMGUI_DIR)/backends/imgui_impl_glfw.cpp $(IMGUI_DIR)/backends/imgui_impl_opengl2.cpp OBJS = $(addsuffix .o, $(basename $(notdir $(SOURCES)))) UNAME_S := $(shell uname -s) diff --git a/examples/example_glfw_opengl2/example_glfw_opengl2.vcxproj b/examples/example_glfw_opengl2/example_glfw_opengl2.vcxproj index 18d95894f..c7e727d23 100644 --- a/examples/example_glfw_opengl2/example_glfw_opengl2.vcxproj +++ b/examples/example_glfw_opengl2/example_glfw_opengl2.vcxproj @@ -164,6 +164,7 @@ + @@ -174,6 +175,8 @@ + + diff --git a/examples/example_glfw_opengl2/example_glfw_opengl2.vcxproj.filters b/examples/example_glfw_opengl2/example_glfw_opengl2.vcxproj.filters index 049b0b1a3..8c6e69bb5 100644 --- a/examples/example_glfw_opengl2/example_glfw_opengl2.vcxproj.filters +++ b/examples/example_glfw_opengl2/example_glfw_opengl2.vcxproj.filters @@ -22,6 +22,9 @@ imgui + + imgui + imgui @@ -45,6 +48,12 @@ imgui + + imgui + + + imgui + sources diff --git a/examples/example_glfw_opengl3/Makefile b/examples/example_glfw_opengl3/Makefile index 252ce5714..25f63a32f 100644 --- a/examples/example_glfw_opengl3/Makefile +++ b/examples/example_glfw_opengl3/Makefile @@ -17,7 +17,7 @@ EXE = example_glfw_opengl3 IMGUI_DIR = ../.. SOURCES = main.cpp -SOURCES += $(IMGUI_DIR)/imgui.cpp $(IMGUI_DIR)/imgui_demo.cpp $(IMGUI_DIR)/imgui_draw.cpp $(IMGUI_DIR)/imgui_tables.cpp $(IMGUI_DIR)/imgui_widgets.cpp +SOURCES += $(IMGUI_DIR)/imgui.cpp $(IMGUI_DIR)/imgui_demo.cpp $(IMGUI_DIR)/imgui_draw.cpp $(IMGUI_DIR)/imgui_stacklayout.cpp $(IMGUI_DIR)/imgui_tables.cpp $(IMGUI_DIR)/imgui_widgets.cpp SOURCES += $(IMGUI_DIR)/backends/imgui_impl_glfw.cpp $(IMGUI_DIR)/backends/imgui_impl_opengl3.cpp OBJS = $(addsuffix .o, $(basename $(notdir $(SOURCES)))) UNAME_S := $(shell uname -s) diff --git a/examples/example_glfw_opengl3/Makefile.emscripten b/examples/example_glfw_opengl3/Makefile.emscripten index 8d2f6e7bd..8a32693ad 100644 --- a/examples/example_glfw_opengl3/Makefile.emscripten +++ b/examples/example_glfw_opengl3/Makefile.emscripten @@ -19,7 +19,7 @@ WEB_DIR = web EXE = $(WEB_DIR)/index.html IMGUI_DIR = ../.. SOURCES = main.cpp -SOURCES += $(IMGUI_DIR)/imgui.cpp $(IMGUI_DIR)/imgui_demo.cpp $(IMGUI_DIR)/imgui_draw.cpp $(IMGUI_DIR)/imgui_tables.cpp $(IMGUI_DIR)/imgui_widgets.cpp +SOURCES += $(IMGUI_DIR)/imgui.cpp $(IMGUI_DIR)/imgui_demo.cpp $(IMGUI_DIR)/imgui_draw.cpp $(IMGUI_DIR)/imgui_stacklayout.cpp $(IMGUI_DIR)/imgui_tables.cpp $(IMGUI_DIR)/imgui_widgets.cpp SOURCES += $(IMGUI_DIR)/backends/imgui_impl_glfw.cpp $(IMGUI_DIR)/backends/imgui_impl_opengl3.cpp OBJS = $(addsuffix .o, $(basename $(notdir $(SOURCES)))) UNAME_S := $(shell uname -s) diff --git a/examples/example_glfw_opengl3/example_glfw_opengl3.vcxproj b/examples/example_glfw_opengl3/example_glfw_opengl3.vcxproj index 3e9d71e13..0ea36129b 100644 --- a/examples/example_glfw_opengl3/example_glfw_opengl3.vcxproj +++ b/examples/example_glfw_opengl3/example_glfw_opengl3.vcxproj @@ -164,6 +164,7 @@ + @@ -174,6 +175,8 @@ + + diff --git a/examples/example_glfw_opengl3/example_glfw_opengl3.vcxproj.filters b/examples/example_glfw_opengl3/example_glfw_opengl3.vcxproj.filters index bc79bb197..e81bf5043 100644 --- a/examples/example_glfw_opengl3/example_glfw_opengl3.vcxproj.filters +++ b/examples/example_glfw_opengl3/example_glfw_opengl3.vcxproj.filters @@ -22,6 +22,9 @@ imgui + + imgui + imgui @@ -45,6 +48,12 @@ imgui + + imgui + + + imgui + sources diff --git a/examples/example_glfw_vulkan/CMakeLists.txt b/examples/example_glfw_vulkan/CMakeLists.txt index 75475dbae..6d89557eb 100644 --- a/examples/example_glfw_vulkan/CMakeLists.txt +++ b/examples/example_glfw_vulkan/CMakeLists.txt @@ -42,6 +42,6 @@ include_directories(${GLFW_DIR}/deps) file(GLOB sources *.cpp) -add_executable(example_glfw_vulkan ${sources} ${IMGUI_DIR}/backends/imgui_impl_glfw.cpp ${IMGUI_DIR}/backends/imgui_impl_vulkan.cpp ${IMGUI_DIR}/imgui.cpp ${IMGUI_DIR}/imgui_draw.cpp ${IMGUI_DIR}/imgui_demo.cpp ${IMGUI_DIR}/imgui_tables.cpp ${IMGUI_DIR}/imgui_widgets.cpp) +add_executable(example_glfw_vulkan ${sources} ${IMGUI_DIR}/backends/imgui_impl_glfw.cpp ${IMGUI_DIR}/backends/imgui_impl_vulkan.cpp ${IMGUI_DIR}/imgui.cpp ${IMGUI_DIR}/imgui_draw.cpp ${IMGUI_DIR}/imgui_demo.cpp ${IMGUI_DIR}/imgui_stacklayout.cpp ${IMGUI_DIR}/imgui_tables.cpp ${IMGUI_DIR}/imgui_widgets.cpp) target_link_libraries(example_glfw_vulkan ${LIBRARIES}) diff --git a/examples/example_glfw_vulkan/Makefile b/examples/example_glfw_vulkan/Makefile index 1a84082d1..2b962b8cd 100644 --- a/examples/example_glfw_vulkan/Makefile +++ b/examples/example_glfw_vulkan/Makefile @@ -17,7 +17,7 @@ EXE = example_glfw_vulkan IMGUI_DIR = ../.. SOURCES = main.cpp -SOURCES += $(IMGUI_DIR)/imgui.cpp $(IMGUI_DIR)/imgui_demo.cpp $(IMGUI_DIR)/imgui_draw.cpp $(IMGUI_DIR)/imgui_tables.cpp $(IMGUI_DIR)/imgui_widgets.cpp +SOURCES += $(IMGUI_DIR)/imgui.cpp $(IMGUI_DIR)/imgui_demo.cpp $(IMGUI_DIR)/imgui_draw.cpp $(IMGUI_DIR)/imgui_stacklayout.cpp $(IMGUI_DIR)/imgui_tables.cpp $(IMGUI_DIR)/imgui_widgets.cpp SOURCES += $(IMGUI_DIR)/backends/imgui_impl_glfw.cpp $(IMGUI_DIR)/backends/imgui_impl_vulkan.cpp OBJS = $(addsuffix .o, $(basename $(notdir $(SOURCES)))) UNAME_S := $(shell uname -s) diff --git a/examples/example_glfw_vulkan/example_glfw_vulkan.vcxproj b/examples/example_glfw_vulkan/example_glfw_vulkan.vcxproj index 492aa0e3f..b800c5436 100644 --- a/examples/example_glfw_vulkan/example_glfw_vulkan.vcxproj +++ b/examples/example_glfw_vulkan/example_glfw_vulkan.vcxproj @@ -168,6 +168,7 @@ + @@ -178,6 +179,8 @@ + + diff --git a/examples/example_glfw_vulkan/example_glfw_vulkan.vcxproj.filters b/examples/example_glfw_vulkan/example_glfw_vulkan.vcxproj.filters index 510fc8547..7b133550d 100644 --- a/examples/example_glfw_vulkan/example_glfw_vulkan.vcxproj.filters +++ b/examples/example_glfw_vulkan/example_glfw_vulkan.vcxproj.filters @@ -22,6 +22,9 @@ imgui + + imgui + imgui @@ -45,6 +48,12 @@ imgui + + imgui + + + imgui + sources diff --git a/examples/example_glfw_wgpu/CMakeLists.txt b/examples/example_glfw_wgpu/CMakeLists.txt index b76054877..8b61b8b28 100644 --- a/examples/example_glfw_wgpu/CMakeLists.txt +++ b/examples/example_glfw_wgpu/CMakeLists.txt @@ -52,6 +52,7 @@ set(IMGUI_EXAMPLE_SOURCE_FILES ${IMGUI_DIR}/imgui.cpp ${IMGUI_DIR}/imgui_draw.cpp ${IMGUI_DIR}/imgui_demo.cpp + ${IMGUI_DIR}/imgui_stacklayout.cpp ${IMGUI_DIR}/imgui_tables.cpp ${IMGUI_DIR}/imgui_widgets.cpp ) diff --git a/examples/example_glfw_wgpu/Makefile.emscripten b/examples/example_glfw_wgpu/Makefile.emscripten index ff386fec5..75b6eedab 100644 --- a/examples/example_glfw_wgpu/Makefile.emscripten +++ b/examples/example_glfw_wgpu/Makefile.emscripten @@ -20,7 +20,7 @@ EXE = $(WEB_DIR)/index.html IMGUI_DIR = ../.. SOURCES = main.cpp SOURCES += $(IMGUI_DIR)/backends/imgui_impl_glfw.cpp $(IMGUI_DIR)/backends/imgui_impl_wgpu.cpp -SOURCES += $(IMGUI_DIR)/imgui.cpp $(IMGUI_DIR)/imgui_demo.cpp $(IMGUI_DIR)/imgui_draw.cpp $(IMGUI_DIR)/imgui_tables.cpp $(IMGUI_DIR)/imgui_widgets.cpp +SOURCES += $(IMGUI_DIR)/imgui.cpp $(IMGUI_DIR)/imgui_demo.cpp $(IMGUI_DIR)/imgui_draw.cpp $(IMGUI_DIR)/imgui_stacklayout.cpp $(IMGUI_DIR)/imgui_tables.cpp $(IMGUI_DIR)/imgui_widgets.cpp OBJS = $(addsuffix .o, $(basename $(notdir $(SOURCES)))) UNAME_S := $(shell uname -s) CPPFLAGS = diff --git a/examples/example_glut_opengl2/Makefile b/examples/example_glut_opengl2/Makefile index 7af289dc4..f361980d6 100644 --- a/examples/example_glut_opengl2/Makefile +++ b/examples/example_glut_opengl2/Makefile @@ -12,7 +12,7 @@ EXE = example_glut_opengl2 IMGUI_DIR = ../.. SOURCES = main.cpp -SOURCES += $(IMGUI_DIR)/imgui.cpp $(IMGUI_DIR)/imgui_demo.cpp $(IMGUI_DIR)/imgui_draw.cpp $(IMGUI_DIR)/imgui_tables.cpp $(IMGUI_DIR)/imgui_widgets.cpp +SOURCES += $(IMGUI_DIR)/imgui.cpp $(IMGUI_DIR)/imgui_demo.cpp $(IMGUI_DIR)/imgui_draw.cpp $(IMGUI_DIR)/imgui_stacklayout.cpp $(IMGUI_DIR)/imgui_tables.cpp $(IMGUI_DIR)/imgui_widgets.cpp SOURCES += $(IMGUI_DIR)/backends/imgui_impl_glut.cpp $(IMGUI_DIR)/backends/imgui_impl_opengl2.cpp OBJS = $(addsuffix .o, $(basename $(notdir $(SOURCES)))) UNAME_S := $(shell uname -s) diff --git a/examples/example_glut_opengl2/example_glut_opengl2.vcxproj b/examples/example_glut_opengl2/example_glut_opengl2.vcxproj index bdd9af440..f989009a4 100644 --- a/examples/example_glut_opengl2/example_glut_opengl2.vcxproj +++ b/examples/example_glut_opengl2/example_glut_opengl2.vcxproj @@ -164,6 +164,7 @@ + @@ -174,6 +175,8 @@ + + diff --git a/examples/example_glut_opengl2/example_glut_opengl2.vcxproj.filters b/examples/example_glut_opengl2/example_glut_opengl2.vcxproj.filters index 0ac4a0b2e..3f9fac856 100644 --- a/examples/example_glut_opengl2/example_glut_opengl2.vcxproj.filters +++ b/examples/example_glut_opengl2/example_glut_opengl2.vcxproj.filters @@ -22,6 +22,9 @@ imgui + + imgui + imgui @@ -45,6 +48,12 @@ imgui + + imgui + + + imgui + sources diff --git a/examples/example_null/Makefile b/examples/example_null/Makefile index 4a67cecd8..0df019473 100644 --- a/examples/example_null/Makefile +++ b/examples/example_null/Makefile @@ -13,7 +13,7 @@ WITH_FREETYPE ?= 0 EXE = example_null IMGUI_DIR = ../.. SOURCES = main.cpp -SOURCES += $(IMGUI_DIR)/imgui.cpp $(IMGUI_DIR)/imgui_demo.cpp $(IMGUI_DIR)/imgui_draw.cpp $(IMGUI_DIR)/imgui_tables.cpp $(IMGUI_DIR)/imgui_widgets.cpp +SOURCES += $(IMGUI_DIR)/imgui.cpp $(IMGUI_DIR)/imgui_demo.cpp $(IMGUI_DIR)/imgui_draw.cpp $(IMGUI_DIR)/imgui_stacklayout.cpp $(IMGUI_DIR)/imgui_tables.cpp $(IMGUI_DIR)/imgui_widgets.cpp OBJS = $(addsuffix .o, $(basename $(notdir $(SOURCES)))) UNAME_S := $(shell uname -s) diff --git a/examples/example_null/example_null.vcxproj b/examples/example_null/example_null.vcxproj index 61e388f96..1ce6e1e4d 100644 --- a/examples/example_null/example_null.vcxproj +++ b/examples/example_null/example_null.vcxproj @@ -155,6 +155,8 @@ + + @@ -166,6 +168,7 @@ + diff --git a/examples/example_null/example_null.vcxproj.filters b/examples/example_null/example_null.vcxproj.filters index 6d575a8f5..6772cc4c4 100644 --- a/examples/example_null/example_null.vcxproj.filters +++ b/examples/example_null/example_null.vcxproj.filters @@ -18,6 +18,12 @@ imgui + + imgui + + + imgui + sources @@ -35,6 +41,9 @@ imgui + + imgui + imgui diff --git a/examples/example_qnx_opengl3/common.mk b/examples/example_qnx_opengl3/common.mk index d162d684e..0f07c7933 100644 --- a/examples/example_qnx_opengl3/common.mk +++ b/examples/example_qnx_opengl3/common.mk @@ -10,6 +10,7 @@ SRCS = \ imgui.cpp \ imgui_demo.cpp \ imgui_draw.cpp \ + imgui_stacklayout.cpp \ imgui_tables.cpp \ imgui_widgets.cpp \ imgui_impl_qnx.cpp \ diff --git a/examples/example_qnx_vulkan/common.mk b/examples/example_qnx_vulkan/common.mk index 7d99539aa..7d698e020 100644 --- a/examples/example_qnx_vulkan/common.mk +++ b/examples/example_qnx_vulkan/common.mk @@ -10,6 +10,7 @@ SRCS = \ imgui.cpp \ imgui_demo.cpp \ imgui_draw.cpp \ + imgui_stacklayout.cpp \ imgui_tables.cpp \ imgui_widgets.cpp \ imgui_impl_qnx.cpp \ diff --git a/examples/example_sdl2_directx11/example_sdl2_directx11.vcxproj b/examples/example_sdl2_directx11/example_sdl2_directx11.vcxproj index afa9d5de4..f07edc79a 100644 --- a/examples/example_sdl2_directx11/example_sdl2_directx11.vcxproj +++ b/examples/example_sdl2_directx11/example_sdl2_directx11.vcxproj @@ -165,6 +165,7 @@ + @@ -175,6 +176,8 @@ + + diff --git a/examples/example_sdl2_directx11/example_sdl2_directx11.vcxproj.filters b/examples/example_sdl2_directx11/example_sdl2_directx11.vcxproj.filters index 92d11f88e..709de7c7c 100644 --- a/examples/example_sdl2_directx11/example_sdl2_directx11.vcxproj.filters +++ b/examples/example_sdl2_directx11/example_sdl2_directx11.vcxproj.filters @@ -18,6 +18,12 @@ imgui + + imgui + + + imgui + sources @@ -38,6 +44,9 @@ imgui + + imgui + imgui diff --git a/examples/example_sdl2_metal/Makefile b/examples/example_sdl2_metal/Makefile index 53c5f75db..57d267aae 100644 --- a/examples/example_sdl2_metal/Makefile +++ b/examples/example_sdl2_metal/Makefile @@ -9,7 +9,7 @@ EXE = example_sdl2_metal IMGUI_DIR = ../.. SOURCES = main.mm -SOURCES += $(IMGUI_DIR)/imgui.cpp $(IMGUI_DIR)/imgui_demo.cpp $(IMGUI_DIR)/imgui_draw.cpp $(IMGUI_DIR)/imgui_tables.cpp $(IMGUI_DIR)/imgui_widgets.cpp +SOURCES += $(IMGUI_DIR)/imgui.cpp $(IMGUI_DIR)/imgui_demo.cpp $(IMGUI_DIR)/imgui_draw.cpp $(IMGUI_DIR)/imgui_stacklayout.cpp $(IMGUI_DIR)/imgui_tables.cpp $(IMGUI_DIR)/imgui_widgets.cpp SOURCES += $(IMGUI_DIR)/backends/imgui_impl_sdl2.cpp $(IMGUI_DIR)/backends/imgui_impl_metal.mm OBJS = $(addsuffix .o, $(basename $(notdir $(SOURCES)))) diff --git a/examples/example_sdl2_opengl2/Makefile b/examples/example_sdl2_opengl2/Makefile index a85ced023..7bf9674cc 100644 --- a/examples/example_sdl2_opengl2/Makefile +++ b/examples/example_sdl2_opengl2/Makefile @@ -17,7 +17,7 @@ EXE = example_sdl2_opengl2 IMGUI_DIR = ../.. SOURCES = main.cpp -SOURCES += $(IMGUI_DIR)/imgui.cpp $(IMGUI_DIR)/imgui_demo.cpp $(IMGUI_DIR)/imgui_draw.cpp $(IMGUI_DIR)/imgui_tables.cpp $(IMGUI_DIR)/imgui_widgets.cpp +SOURCES += $(IMGUI_DIR)/imgui.cpp $(IMGUI_DIR)/imgui_demo.cpp $(IMGUI_DIR)/imgui_draw.cpp $(IMGUI_DIR)/imgui_stacklayout.cpp $(IMGUI_DIR)/imgui_tables.cpp $(IMGUI_DIR)/imgui_widgets.cpp SOURCES += $(IMGUI_DIR)/backends/imgui_impl_sdl2.cpp $(IMGUI_DIR)/backends/imgui_impl_opengl2.cpp OBJS = $(addsuffix .o, $(basename $(notdir $(SOURCES)))) UNAME_S := $(shell uname -s) diff --git a/examples/example_sdl2_opengl2/example_sdl2_opengl2.vcxproj b/examples/example_sdl2_opengl2/example_sdl2_opengl2.vcxproj index 35b7ed7df..a241fce7b 100644 --- a/examples/example_sdl2_opengl2/example_sdl2_opengl2.vcxproj +++ b/examples/example_sdl2_opengl2/example_sdl2_opengl2.vcxproj @@ -164,6 +164,7 @@ + @@ -174,6 +175,8 @@ + + diff --git a/examples/example_sdl2_opengl2/example_sdl2_opengl2.vcxproj.filters b/examples/example_sdl2_opengl2/example_sdl2_opengl2.vcxproj.filters index 752a1965d..c06d9bce8 100644 --- a/examples/example_sdl2_opengl2/example_sdl2_opengl2.vcxproj.filters +++ b/examples/example_sdl2_opengl2/example_sdl2_opengl2.vcxproj.filters @@ -22,6 +22,9 @@ sources + + imgui + imgui @@ -45,6 +48,12 @@ imgui + + imgui + + + imgui + sources diff --git a/examples/example_sdl2_opengl3/Makefile b/examples/example_sdl2_opengl3/Makefile index 5b4f9419c..4bd9aceec 100644 --- a/examples/example_sdl2_opengl3/Makefile +++ b/examples/example_sdl2_opengl3/Makefile @@ -17,7 +17,7 @@ EXE = example_sdl2_opengl3 IMGUI_DIR = ../.. SOURCES = main.cpp -SOURCES += $(IMGUI_DIR)/imgui.cpp $(IMGUI_DIR)/imgui_demo.cpp $(IMGUI_DIR)/imgui_draw.cpp $(IMGUI_DIR)/imgui_tables.cpp $(IMGUI_DIR)/imgui_widgets.cpp +SOURCES += $(IMGUI_DIR)/imgui.cpp $(IMGUI_DIR)/imgui_demo.cpp $(IMGUI_DIR)/imgui_draw.cpp $(IMGUI_DIR)/imgui_stacklayout.cpp $(IMGUI_DIR)/imgui_tables.cpp $(IMGUI_DIR)/imgui_widgets.cpp SOURCES += $(IMGUI_DIR)/backends/imgui_impl_sdl2.cpp $(IMGUI_DIR)/backends/imgui_impl_opengl3.cpp OBJS = $(addsuffix .o, $(basename $(notdir $(SOURCES)))) UNAME_S := $(shell uname -s) diff --git a/examples/example_sdl2_opengl3/Makefile.emscripten b/examples/example_sdl2_opengl3/Makefile.emscripten index bc06adeb7..ea4708645 100644 --- a/examples/example_sdl2_opengl3/Makefile.emscripten +++ b/examples/example_sdl2_opengl3/Makefile.emscripten @@ -19,7 +19,7 @@ WEB_DIR = web EXE = $(WEB_DIR)/index.html IMGUI_DIR = ../.. SOURCES = main.cpp -SOURCES += $(IMGUI_DIR)/imgui.cpp $(IMGUI_DIR)/imgui_demo.cpp $(IMGUI_DIR)/imgui_draw.cpp $(IMGUI_DIR)/imgui_tables.cpp $(IMGUI_DIR)/imgui_widgets.cpp +SOURCES += $(IMGUI_DIR)/imgui.cpp $(IMGUI_DIR)/imgui_demo.cpp $(IMGUI_DIR)/imgui_draw.cpp $(IMGUI_DIR)/imgui_stacklayout.cpp $(IMGUI_DIR)/imgui_tables.cpp $(IMGUI_DIR)/imgui_widgets.cpp SOURCES += $(IMGUI_DIR)/backends/imgui_impl_sdl2.cpp $(IMGUI_DIR)/backends/imgui_impl_opengl3.cpp OBJS = $(addsuffix .o, $(basename $(notdir $(SOURCES)))) UNAME_S := $(shell uname -s) diff --git a/examples/example_sdl2_opengl3/example_sdl2_opengl3.vcxproj b/examples/example_sdl2_opengl3/example_sdl2_opengl3.vcxproj index b5a80197e..3d6849e9c 100644 --- a/examples/example_sdl2_opengl3/example_sdl2_opengl3.vcxproj +++ b/examples/example_sdl2_opengl3/example_sdl2_opengl3.vcxproj @@ -164,6 +164,7 @@ + @@ -174,6 +175,8 @@ + + diff --git a/examples/example_sdl2_opengl3/example_sdl2_opengl3.vcxproj.filters b/examples/example_sdl2_opengl3/example_sdl2_opengl3.vcxproj.filters index 846d55759..277bb6b12 100644 --- a/examples/example_sdl2_opengl3/example_sdl2_opengl3.vcxproj.filters +++ b/examples/example_sdl2_opengl3/example_sdl2_opengl3.vcxproj.filters @@ -28,6 +28,9 @@ sources + + imgui + imgui @@ -45,6 +48,12 @@ imgui + + imgui + + + imgui + sources diff --git a/examples/example_sdl2_sdlrenderer2/Makefile b/examples/example_sdl2_sdlrenderer2/Makefile index 5820d9bc7..9080ab5d5 100644 --- a/examples/example_sdl2_sdlrenderer2/Makefile +++ b/examples/example_sdl2_sdlrenderer2/Makefile @@ -17,7 +17,7 @@ EXE = example_sdl2_sdlrenderer2 IMGUI_DIR = ../.. SOURCES = main.cpp -SOURCES += $(IMGUI_DIR)/imgui.cpp $(IMGUI_DIR)/imgui_demo.cpp $(IMGUI_DIR)/imgui_draw.cpp $(IMGUI_DIR)/imgui_tables.cpp $(IMGUI_DIR)/imgui_widgets.cpp +SOURCES += $(IMGUI_DIR)/imgui.cpp $(IMGUI_DIR)/imgui_demo.cpp $(IMGUI_DIR)/imgui_draw.cpp $(IMGUI_DIR)/imgui_stacklayout.cpp $(IMGUI_DIR)/imgui_tables.cpp $(IMGUI_DIR)/imgui_widgets.cpp SOURCES += $(IMGUI_DIR)/backends/imgui_impl_sdl2.cpp $(IMGUI_DIR)/backends/imgui_impl_sdlrenderer2.cpp OBJS = $(addsuffix .o, $(basename $(notdir $(SOURCES)))) UNAME_S := $(shell uname -s) diff --git a/examples/example_sdl2_sdlrenderer2/example_sdl2_sdlrenderer2.vcxproj b/examples/example_sdl2_sdlrenderer2/example_sdl2_sdlrenderer2.vcxproj index 9d7951be8..14881946d 100644 --- a/examples/example_sdl2_sdlrenderer2/example_sdl2_sdlrenderer2.vcxproj +++ b/examples/example_sdl2_sdlrenderer2/example_sdl2_sdlrenderer2.vcxproj @@ -165,6 +165,7 @@ + @@ -175,6 +176,8 @@ + + diff --git a/examples/example_sdl2_sdlrenderer2/example_sdl2_sdlrenderer2.vcxproj.filters b/examples/example_sdl2_sdlrenderer2/example_sdl2_sdlrenderer2.vcxproj.filters index 5c6da42e3..7ae21857f 100644 --- a/examples/example_sdl2_sdlrenderer2/example_sdl2_sdlrenderer2.vcxproj.filters +++ b/examples/example_sdl2_sdlrenderer2/example_sdl2_sdlrenderer2.vcxproj.filters @@ -22,6 +22,9 @@ sources + + imgui + imgui @@ -45,6 +48,12 @@ imgui + + imgui + + + imgui + sources diff --git a/examples/example_sdl2_vulkan/Makefile b/examples/example_sdl2_vulkan/Makefile index e722ab035..37f9c7517 100644 --- a/examples/example_sdl2_vulkan/Makefile +++ b/examples/example_sdl2_vulkan/Makefile @@ -17,7 +17,7 @@ EXE = example_sdl2_vulkan IMGUI_DIR = ../.. SOURCES = main.cpp -SOURCES += $(IMGUI_DIR)/imgui.cpp $(IMGUI_DIR)/imgui_demo.cpp $(IMGUI_DIR)/imgui_draw.cpp $(IMGUI_DIR)/imgui_tables.cpp $(IMGUI_DIR)/imgui_widgets.cpp +SOURCES += $(IMGUI_DIR)/imgui.cpp $(IMGUI_DIR)/imgui_demo.cpp $(IMGUI_DIR)/imgui_draw.cpp $(IMGUI_DIR)/imgui_stacklayout.cpp $(IMGUI_DIR)/imgui_tables.cpp $(IMGUI_DIR)/imgui_widgets.cpp SOURCES += $(IMGUI_DIR)/backends/imgui_impl_sdl2.cpp $(IMGUI_DIR)/backends/imgui_impl_vulkan.cpp OBJS = $(addsuffix .o, $(basename $(notdir $(SOURCES)))) UNAME_S := $(shell uname -s) diff --git a/examples/example_sdl2_vulkan/example_sdl2_vulkan.vcxproj b/examples/example_sdl2_vulkan/example_sdl2_vulkan.vcxproj index b2269bc9d..77ae5d5a4 100644 --- a/examples/example_sdl2_vulkan/example_sdl2_vulkan.vcxproj +++ b/examples/example_sdl2_vulkan/example_sdl2_vulkan.vcxproj @@ -168,6 +168,7 @@ + @@ -178,6 +179,8 @@ + + diff --git a/examples/example_sdl2_vulkan/example_sdl2_vulkan.vcxproj.filters b/examples/example_sdl2_vulkan/example_sdl2_vulkan.vcxproj.filters index ab4248515..2e09d8de2 100644 --- a/examples/example_sdl2_vulkan/example_sdl2_vulkan.vcxproj.filters +++ b/examples/example_sdl2_vulkan/example_sdl2_vulkan.vcxproj.filters @@ -31,6 +31,9 @@ imgui + + imgui + imgui @@ -45,6 +48,12 @@ imgui + + imgui + + + imgui + sources diff --git a/examples/example_sdl2_wgpu/CMakeLists.txt b/examples/example_sdl2_wgpu/CMakeLists.txt index 0a8fed305..21a882fda 100644 --- a/examples/example_sdl2_wgpu/CMakeLists.txt +++ b/examples/example_sdl2_wgpu/CMakeLists.txt @@ -52,6 +52,7 @@ set(IMGUI_EXAMPLE_SOURCE_FILES ${IMGUI_DIR}/imgui.cpp ${IMGUI_DIR}/imgui_draw.cpp ${IMGUI_DIR}/imgui_demo.cpp + ${IMGUI_DIR}/imgui_stacklayout.cpp ${IMGUI_DIR}/imgui_tables.cpp ${IMGUI_DIR}/imgui_widgets.cpp ) diff --git a/examples/example_sdl2_wgpu/Makefile.emscripten b/examples/example_sdl2_wgpu/Makefile.emscripten index ebc7f97c9..9144aa550 100644 --- a/examples/example_sdl2_wgpu/Makefile.emscripten +++ b/examples/example_sdl2_wgpu/Makefile.emscripten @@ -20,7 +20,7 @@ EXE = $(WEB_DIR)/index.html IMGUI_DIR = ../.. SOURCES = main.cpp SOURCES += $(IMGUI_DIR)/backends/imgui_impl_sdl2.cpp $(IMGUI_DIR)/backends/imgui_impl_wgpu.cpp -SOURCES += $(IMGUI_DIR)/imgui.cpp $(IMGUI_DIR)/imgui_demo.cpp $(IMGUI_DIR)/imgui_draw.cpp $(IMGUI_DIR)/imgui_tables.cpp $(IMGUI_DIR)/imgui_widgets.cpp +SOURCES += $(IMGUI_DIR)/imgui.cpp $(IMGUI_DIR)/imgui_demo.cpp $(IMGUI_DIR)/imgui_draw.cpp $(IMGUI_DIR)/imgui_stacklayout.cpp $(IMGUI_DIR)/imgui_tables.cpp $(IMGUI_DIR)/imgui_widgets.cpp OBJS = $(addsuffix .o, $(basename $(notdir $(SOURCES)))) UNAME_S := $(shell uname -s) CPPFLAGS = diff --git a/examples/example_sdl3_directx11/example_sdl3_directx11.vcxproj b/examples/example_sdl3_directx11/example_sdl3_directx11.vcxproj index 057874196..6c73dbe35 100644 --- a/examples/example_sdl3_directx11/example_sdl3_directx11.vcxproj +++ b/examples/example_sdl3_directx11/example_sdl3_directx11.vcxproj @@ -165,6 +165,7 @@ + @@ -175,6 +176,8 @@ + + diff --git a/examples/example_sdl3_directx11/example_sdl3_directx11.vcxproj.filters b/examples/example_sdl3_directx11/example_sdl3_directx11.vcxproj.filters index 0579b7a64..a4359e35b 100644 --- a/examples/example_sdl3_directx11/example_sdl3_directx11.vcxproj.filters +++ b/examples/example_sdl3_directx11/example_sdl3_directx11.vcxproj.filters @@ -18,6 +18,12 @@ imgui + + imgui + + + imgui + sources @@ -38,6 +44,9 @@ imgui + + imgui + imgui diff --git a/examples/example_sdl3_metal/Makefile b/examples/example_sdl3_metal/Makefile index 9093ae133..15ade8437 100644 --- a/examples/example_sdl3_metal/Makefile +++ b/examples/example_sdl3_metal/Makefile @@ -9,7 +9,7 @@ EXE = example_sdl3_metal IMGUI_DIR = ../.. SOURCES = main.mm -SOURCES += $(IMGUI_DIR)/imgui.cpp $(IMGUI_DIR)/imgui_demo.cpp $(IMGUI_DIR)/imgui_draw.cpp $(IMGUI_DIR)/imgui_tables.cpp $(IMGUI_DIR)/imgui_widgets.cpp +SOURCES += $(IMGUI_DIR)/imgui.cpp $(IMGUI_DIR)/imgui_demo.cpp $(IMGUI_DIR)/imgui_draw.cpp $(IMGUI_DIR)/imgui_stacklayout.cpp $(IMGUI_DIR)/imgui_tables.cpp $(IMGUI_DIR)/imgui_widgets.cpp SOURCES += $(IMGUI_DIR)/backends/imgui_impl_sdl3.cpp $(IMGUI_DIR)/backends/imgui_impl_metal.mm OBJS = $(addsuffix .o, $(basename $(notdir $(SOURCES)))) diff --git a/examples/example_sdl3_metal4/Makefile b/examples/example_sdl3_metal4/Makefile index 55c83416c..21f102bef 100644 --- a/examples/example_sdl3_metal4/Makefile +++ b/examples/example_sdl3_metal4/Makefile @@ -9,7 +9,7 @@ EXE = example_sdl3_metal4 IMGUI_DIR = ../.. SOURCES = main.mm -SOURCES += $(IMGUI_DIR)/imgui.cpp $(IMGUI_DIR)/imgui_demo.cpp $(IMGUI_DIR)/imgui_draw.cpp $(IMGUI_DIR)/imgui_tables.cpp $(IMGUI_DIR)/imgui_widgets.cpp +SOURCES += $(IMGUI_DIR)/imgui.cpp $(IMGUI_DIR)/imgui_demo.cpp $(IMGUI_DIR)/imgui_draw.cpp $(IMGUI_DIR)/imgui_stacklayout.cpp $(IMGUI_DIR)/imgui_tables.cpp $(IMGUI_DIR)/imgui_widgets.cpp SOURCES += $(IMGUI_DIR)/backends/imgui_impl_sdl3.cpp $(IMGUI_DIR)/backends/imgui_impl_metal4.mm OBJS = $(addsuffix .o, $(basename $(notdir $(SOURCES)))) diff --git a/examples/example_sdl3_opengl3/Makefile b/examples/example_sdl3_opengl3/Makefile index d9c6eac9e..eb3bcd9fb 100644 --- a/examples/example_sdl3_opengl3/Makefile +++ b/examples/example_sdl3_opengl3/Makefile @@ -10,7 +10,7 @@ EXE = example_sdl3_opengl3 IMGUI_DIR = ../.. SOURCES = main.cpp -SOURCES += $(IMGUI_DIR)/imgui.cpp $(IMGUI_DIR)/imgui_demo.cpp $(IMGUI_DIR)/imgui_draw.cpp $(IMGUI_DIR)/imgui_tables.cpp $(IMGUI_DIR)/imgui_widgets.cpp +SOURCES += $(IMGUI_DIR)/imgui.cpp $(IMGUI_DIR)/imgui_demo.cpp $(IMGUI_DIR)/imgui_draw.cpp $(IMGUI_DIR)/imgui_stacklayout.cpp $(IMGUI_DIR)/imgui_tables.cpp $(IMGUI_DIR)/imgui_widgets.cpp SOURCES += $(IMGUI_DIR)/backends/imgui_impl_sdl3.cpp $(IMGUI_DIR)/backends/imgui_impl_opengl3.cpp OBJS = $(addsuffix .o, $(basename $(notdir $(SOURCES)))) UNAME_S := $(shell uname -s) diff --git a/examples/example_sdl3_opengl3/Makefile.emscripten b/examples/example_sdl3_opengl3/Makefile.emscripten index ce873ed1a..ae927447f 100644 --- a/examples/example_sdl3_opengl3/Makefile.emscripten +++ b/examples/example_sdl3_opengl3/Makefile.emscripten @@ -23,7 +23,7 @@ WEB_DIR = web EXE = $(WEB_DIR)/index.html IMGUI_DIR = ../.. SOURCES = main.cpp -SOURCES += $(IMGUI_DIR)/imgui.cpp $(IMGUI_DIR)/imgui_demo.cpp $(IMGUI_DIR)/imgui_draw.cpp $(IMGUI_DIR)/imgui_tables.cpp $(IMGUI_DIR)/imgui_widgets.cpp +SOURCES += $(IMGUI_DIR)/imgui.cpp $(IMGUI_DIR)/imgui_demo.cpp $(IMGUI_DIR)/imgui_draw.cpp $(IMGUI_DIR)/imgui_stacklayout.cpp $(IMGUI_DIR)/imgui_tables.cpp $(IMGUI_DIR)/imgui_widgets.cpp SOURCES += $(IMGUI_DIR)/backends/imgui_impl_sdl3.cpp $(IMGUI_DIR)/backends/imgui_impl_opengl3.cpp OBJS = $(addsuffix .o, $(basename $(notdir $(SOURCES)))) UNAME_S := $(shell uname -s) diff --git a/examples/example_sdl3_opengl3/example_sdl3_opengl3.vcxproj b/examples/example_sdl3_opengl3/example_sdl3_opengl3.vcxproj index dbe1fa915..f35f33c95 100644 --- a/examples/example_sdl3_opengl3/example_sdl3_opengl3.vcxproj +++ b/examples/example_sdl3_opengl3/example_sdl3_opengl3.vcxproj @@ -164,6 +164,7 @@ + @@ -174,6 +175,8 @@ + + diff --git a/examples/example_sdl3_opengl3/example_sdl3_opengl3.vcxproj.filters b/examples/example_sdl3_opengl3/example_sdl3_opengl3.vcxproj.filters index f365473c4..79f38f4eb 100644 --- a/examples/example_sdl3_opengl3/example_sdl3_opengl3.vcxproj.filters +++ b/examples/example_sdl3_opengl3/example_sdl3_opengl3.vcxproj.filters @@ -28,6 +28,9 @@ sources + + imgui + imgui @@ -45,6 +48,12 @@ imgui + + imgui + + + imgui + sources diff --git a/examples/example_sdl3_sdlgpu3/Makefile b/examples/example_sdl3_sdlgpu3/Makefile index c3159d888..4f7d7d1ce 100644 --- a/examples/example_sdl3_sdlgpu3/Makefile +++ b/examples/example_sdl3_sdlgpu3/Makefile @@ -10,7 +10,7 @@ EXE = example_sdl3_sdlgpu3 IMGUI_DIR = ../.. SOURCES = main.cpp -SOURCES += $(IMGUI_DIR)/imgui.cpp $(IMGUI_DIR)/imgui_demo.cpp $(IMGUI_DIR)/imgui_draw.cpp $(IMGUI_DIR)/imgui_tables.cpp $(IMGUI_DIR)/imgui_widgets.cpp +SOURCES += $(IMGUI_DIR)/imgui.cpp $(IMGUI_DIR)/imgui_demo.cpp $(IMGUI_DIR)/imgui_draw.cpp $(IMGUI_DIR)/imgui_stacklayout.cpp $(IMGUI_DIR)/imgui_tables.cpp $(IMGUI_DIR)/imgui_widgets.cpp SOURCES += $(IMGUI_DIR)/backends/imgui_impl_sdl3.cpp $(IMGUI_DIR)/backends/imgui_impl_sdlgpu3.cpp OBJS = $(addsuffix .o, $(basename $(notdir $(SOURCES)))) UNAME_S := $(shell uname -s) diff --git a/examples/example_sdl3_sdlgpu3/example_sdl3_sdlgpu3.vcxproj b/examples/example_sdl3_sdlgpu3/example_sdl3_sdlgpu3.vcxproj index bd83258d8..7e9826f2b 100644 --- a/examples/example_sdl3_sdlgpu3/example_sdl3_sdlgpu3.vcxproj +++ b/examples/example_sdl3_sdlgpu3/example_sdl3_sdlgpu3.vcxproj @@ -169,6 +169,7 @@ + @@ -180,6 +181,8 @@ + + diff --git a/examples/example_sdl3_sdlgpu3/example_sdl3_sdlgpu3.vcxproj.filters b/examples/example_sdl3_sdlgpu3/example_sdl3_sdlgpu3.vcxproj.filters index 4710b550c..ad292af81 100644 --- a/examples/example_sdl3_sdlgpu3/example_sdl3_sdlgpu3.vcxproj.filters +++ b/examples/example_sdl3_sdlgpu3/example_sdl3_sdlgpu3.vcxproj.filters @@ -19,6 +19,9 @@ imgui + + imgui + imgui @@ -45,6 +48,12 @@ imgui + + imgui + + + imgui + diff --git a/examples/example_sdl3_sdlrenderer3/Makefile b/examples/example_sdl3_sdlrenderer3/Makefile index c278f7830..8eab06e9f 100644 --- a/examples/example_sdl3_sdlrenderer3/Makefile +++ b/examples/example_sdl3_sdlrenderer3/Makefile @@ -10,7 +10,7 @@ EXE = example_sdl3_sdlrenderer3 IMGUI_DIR = ../.. SOURCES = main.cpp -SOURCES += $(IMGUI_DIR)/imgui.cpp $(IMGUI_DIR)/imgui_demo.cpp $(IMGUI_DIR)/imgui_draw.cpp $(IMGUI_DIR)/imgui_tables.cpp $(IMGUI_DIR)/imgui_widgets.cpp +SOURCES += $(IMGUI_DIR)/imgui.cpp $(IMGUI_DIR)/imgui_demo.cpp $(IMGUI_DIR)/imgui_draw.cpp $(IMGUI_DIR)/imgui_stacklayout.cpp $(IMGUI_DIR)/imgui_tables.cpp $(IMGUI_DIR)/imgui_widgets.cpp SOURCES += $(IMGUI_DIR)/backends/imgui_impl_sdl3.cpp $(IMGUI_DIR)/backends/imgui_impl_sdlrenderer3.cpp OBJS = $(addsuffix .o, $(basename $(notdir $(SOURCES)))) UNAME_S := $(shell uname -s) diff --git a/examples/example_sdl3_sdlrenderer3/example_sdl3_sdlrenderer3.vcxproj b/examples/example_sdl3_sdlrenderer3/example_sdl3_sdlrenderer3.vcxproj index 35fc962ad..b4c58aebe 100644 --- a/examples/example_sdl3_sdlrenderer3/example_sdl3_sdlrenderer3.vcxproj +++ b/examples/example_sdl3_sdlrenderer3/example_sdl3_sdlrenderer3.vcxproj @@ -165,6 +165,7 @@ + @@ -175,6 +176,8 @@ + + diff --git a/examples/example_sdl3_sdlrenderer3/example_sdl3_sdlrenderer3.vcxproj.filters b/examples/example_sdl3_sdlrenderer3/example_sdl3_sdlrenderer3.vcxproj.filters index c41210d67..3fb37d3c8 100644 --- a/examples/example_sdl3_sdlrenderer3/example_sdl3_sdlrenderer3.vcxproj.filters +++ b/examples/example_sdl3_sdlrenderer3/example_sdl3_sdlrenderer3.vcxproj.filters @@ -25,6 +25,9 @@ sources + + imgui + imgui @@ -45,6 +48,12 @@ imgui + + imgui + + + imgui + sources diff --git a/examples/example_sdl3_vulkan/Makefile b/examples/example_sdl3_vulkan/Makefile index e1956ff67..35fd10b49 100644 --- a/examples/example_sdl3_vulkan/Makefile +++ b/examples/example_sdl3_vulkan/Makefile @@ -12,7 +12,7 @@ EXE = example_sdl3_vulkan IMGUI_DIR = ../.. SOURCES = main.cpp -SOURCES += $(IMGUI_DIR)/imgui.cpp $(IMGUI_DIR)/imgui_demo.cpp $(IMGUI_DIR)/imgui_draw.cpp $(IMGUI_DIR)/imgui_tables.cpp $(IMGUI_DIR)/imgui_widgets.cpp +SOURCES += $(IMGUI_DIR)/imgui.cpp $(IMGUI_DIR)/imgui_demo.cpp $(IMGUI_DIR)/imgui_draw.cpp $(IMGUI_DIR)/imgui_stacklayout.cpp $(IMGUI_DIR)/imgui_tables.cpp $(IMGUI_DIR)/imgui_widgets.cpp SOURCES += $(IMGUI_DIR)/backends/imgui_impl_sdl3.cpp $(IMGUI_DIR)/backends/imgui_impl_vulkan.cpp OBJS = $(addsuffix .o, $(basename $(notdir $(SOURCES)))) UNAME_S := $(shell uname -s) diff --git a/examples/example_sdl3_vulkan/example_sdl3_vulkan.vcxproj b/examples/example_sdl3_vulkan/example_sdl3_vulkan.vcxproj index c3a200cf5..3d9431f66 100644 --- a/examples/example_sdl3_vulkan/example_sdl3_vulkan.vcxproj +++ b/examples/example_sdl3_vulkan/example_sdl3_vulkan.vcxproj @@ -168,6 +168,7 @@ + @@ -178,6 +179,8 @@ + + diff --git a/examples/example_sdl3_vulkan/example_sdl3_vulkan.vcxproj.filters b/examples/example_sdl3_vulkan/example_sdl3_vulkan.vcxproj.filters index 46ebb5829..7df46f162 100644 --- a/examples/example_sdl3_vulkan/example_sdl3_vulkan.vcxproj.filters +++ b/examples/example_sdl3_vulkan/example_sdl3_vulkan.vcxproj.filters @@ -31,6 +31,9 @@ imgui + + imgui + imgui @@ -45,6 +48,12 @@ imgui + + imgui + + + imgui + sources diff --git a/examples/example_sdl3_wgpu/CMakeLists.txt b/examples/example_sdl3_wgpu/CMakeLists.txt index b05dcd459..7589ba7a9 100644 --- a/examples/example_sdl3_wgpu/CMakeLists.txt +++ b/examples/example_sdl3_wgpu/CMakeLists.txt @@ -52,6 +52,7 @@ set(IMGUI_EXAMPLE_SOURCE_FILES ${IMGUI_DIR}/imgui.cpp ${IMGUI_DIR}/imgui_draw.cpp ${IMGUI_DIR}/imgui_demo.cpp + ${IMGUI_DIR}/imgui_stacklayout.cpp ${IMGUI_DIR}/imgui_tables.cpp ${IMGUI_DIR}/imgui_widgets.cpp ) diff --git a/examples/example_sdl3_wgpu/Makefile.emscripten b/examples/example_sdl3_wgpu/Makefile.emscripten index c84acc77f..77a79800a 100644 --- a/examples/example_sdl3_wgpu/Makefile.emscripten +++ b/examples/example_sdl3_wgpu/Makefile.emscripten @@ -20,7 +20,7 @@ EXE = $(WEB_DIR)/index.html IMGUI_DIR = ../.. SOURCES = main.cpp SOURCES += $(IMGUI_DIR)/backends/imgui_impl_sdl3.cpp $(IMGUI_DIR)/backends/imgui_impl_wgpu.cpp -SOURCES += $(IMGUI_DIR)/imgui.cpp $(IMGUI_DIR)/imgui_demo.cpp $(IMGUI_DIR)/imgui_draw.cpp $(IMGUI_DIR)/imgui_tables.cpp $(IMGUI_DIR)/imgui_widgets.cpp +SOURCES += $(IMGUI_DIR)/imgui.cpp $(IMGUI_DIR)/imgui_demo.cpp $(IMGUI_DIR)/imgui_draw.cpp $(IMGUI_DIR)/imgui_stacklayout.cpp $(IMGUI_DIR)/imgui_tables.cpp $(IMGUI_DIR)/imgui_widgets.cpp OBJS = $(addsuffix .o, $(basename $(notdir $(SOURCES)))) UNAME_S := $(shell uname -s) CPPFLAGS = diff --git a/examples/example_win32_directx10/example_win32_directx10.vcxproj b/examples/example_win32_directx10/example_win32_directx10.vcxproj index add37ed97..2316a6d81 100644 --- a/examples/example_win32_directx10/example_win32_directx10.vcxproj +++ b/examples/example_win32_directx10/example_win32_directx10.vcxproj @@ -154,6 +154,8 @@ + + @@ -161,6 +163,7 @@ + diff --git a/examples/example_win32_directx10/example_win32_directx10.vcxproj.filters b/examples/example_win32_directx10/example_win32_directx10.vcxproj.filters index 33ab99b51..fb449f27b 100644 --- a/examples/example_win32_directx10/example_win32_directx10.vcxproj.filters +++ b/examples/example_win32_directx10/example_win32_directx10.vcxproj.filters @@ -18,6 +18,12 @@ imgui + + imgui + + + imgui + sources @@ -44,6 +50,9 @@ sources + + imgui + imgui diff --git a/examples/example_win32_directx11/example_win32_directx11.vcxproj b/examples/example_win32_directx11/example_win32_directx11.vcxproj index ed0b509a8..53d5ec862 100644 --- a/examples/example_win32_directx11/example_win32_directx11.vcxproj +++ b/examples/example_win32_directx11/example_win32_directx11.vcxproj @@ -154,6 +154,8 @@ + + @@ -161,6 +163,7 @@ + diff --git a/examples/example_win32_directx11/example_win32_directx11.vcxproj.filters b/examples/example_win32_directx11/example_win32_directx11.vcxproj.filters index 63032a6aa..040fb9683 100644 --- a/examples/example_win32_directx11/example_win32_directx11.vcxproj.filters +++ b/examples/example_win32_directx11/example_win32_directx11.vcxproj.filters @@ -18,6 +18,12 @@ imgui + + imgui + + + imgui + sources @@ -47,6 +53,9 @@ sources + + imgui + imgui diff --git a/examples/example_win32_directx12/example_win32_directx12.vcxproj b/examples/example_win32_directx12/example_win32_directx12.vcxproj index 27b501d85..4479d0d78 100644 --- a/examples/example_win32_directx12/example_win32_directx12.vcxproj +++ b/examples/example_win32_directx12/example_win32_directx12.vcxproj @@ -156,6 +156,8 @@ + + @@ -163,6 +165,7 @@ + diff --git a/examples/example_win32_directx12/example_win32_directx12.vcxproj.filters b/examples/example_win32_directx12/example_win32_directx12.vcxproj.filters index 23a99526f..8d887c775 100644 --- a/examples/example_win32_directx12/example_win32_directx12.vcxproj.filters +++ b/examples/example_win32_directx12/example_win32_directx12.vcxproj.filters @@ -18,6 +18,12 @@ imgui + + imgui + + + imgui + sources @@ -44,6 +50,9 @@ sources + + imgui + imgui diff --git a/examples/example_win32_directx9/example_win32_directx9.vcxproj b/examples/example_win32_directx9/example_win32_directx9.vcxproj index 84e16c9c6..66219ec2c 100644 --- a/examples/example_win32_directx9/example_win32_directx9.vcxproj +++ b/examples/example_win32_directx9/example_win32_directx9.vcxproj @@ -154,6 +154,7 @@ + @@ -164,6 +165,8 @@ + + diff --git a/examples/example_win32_directx9/example_win32_directx9.vcxproj.filters b/examples/example_win32_directx9/example_win32_directx9.vcxproj.filters index 5ed89d6fd..c19999fbc 100644 --- a/examples/example_win32_directx9/example_win32_directx9.vcxproj.filters +++ b/examples/example_win32_directx9/example_win32_directx9.vcxproj.filters @@ -28,6 +28,9 @@ sources + + imgui + imgui @@ -45,6 +48,12 @@ imgui + + imgui + + + imgui + sources diff --git a/examples/example_win32_opengl3/example_win32_opengl3.vcxproj b/examples/example_win32_opengl3/example_win32_opengl3.vcxproj index 2ffb7d413..b8ab2c48f 100644 --- a/examples/example_win32_opengl3/example_win32_opengl3.vcxproj +++ b/examples/example_win32_opengl3/example_win32_opengl3.vcxproj @@ -154,6 +154,7 @@ + @@ -164,6 +165,8 @@ + + diff --git a/examples/example_win32_opengl3/example_win32_opengl3.vcxproj.filters b/examples/example_win32_opengl3/example_win32_opengl3.vcxproj.filters index 47ed299bc..ababe07a0 100644 --- a/examples/example_win32_opengl3/example_win32_opengl3.vcxproj.filters +++ b/examples/example_win32_opengl3/example_win32_opengl3.vcxproj.filters @@ -28,6 +28,9 @@ sources + + imgui + imgui @@ -45,6 +48,12 @@ imgui + + imgui + + + imgui + sources diff --git a/examples/example_win32_vulkan/example_win32_vulkan.vcxproj b/examples/example_win32_vulkan/example_win32_vulkan.vcxproj index bede521e2..14db55cb1 100644 --- a/examples/example_win32_vulkan/example_win32_vulkan.vcxproj +++ b/examples/example_win32_vulkan/example_win32_vulkan.vcxproj @@ -157,6 +157,8 @@ + + @@ -164,6 +166,7 @@ + diff --git a/examples/example_win32_vulkan/example_win32_vulkan.vcxproj.filters b/examples/example_win32_vulkan/example_win32_vulkan.vcxproj.filters index c91a95810..3d2d9835e 100644 --- a/examples/example_win32_vulkan/example_win32_vulkan.vcxproj.filters +++ b/examples/example_win32_vulkan/example_win32_vulkan.vcxproj.filters @@ -18,6 +18,12 @@ imgui + + imgui + + + imgui + sources @@ -47,6 +53,9 @@ sources + + imgui + imgui diff --git a/imgui.cpp b/imgui.cpp index 910c34e9b..1428c3510 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -1581,6 +1581,7 @@ ImGuiStyle::ImGuiStyle() ScrollbarPadding = 2.0f; // Padding of scrollbar grab within its frame (same for both axes) GrabMinSize = 12.0f; // Minimum width/height of a grab box for slider/scrollbar GrabRounding = 0.0f; // Radius of grabs corners rounding. Set to 0.0f to have rectangular slider grabs. + LayoutAlign = 0.5f; // Element alignment inside horizontal and vertical layouts (0.0f - left/top, 1.0f - right/bottom, 0.5f - center). LogSliderDeadzone = 4.0f; // The size in pixels of the dead-zone around zero on logarithmic sliders that cross zero. ImageRounding = 0.0f; // Rounding of Image() calls. ImageBorderSize = 0.0f; // Thickness of border around Image() calls. @@ -3812,6 +3813,7 @@ static const ImGuiStyleVarInfo GStyleVarsInfo[] = { 1, ImGuiDataType_Float, (ImU32)offsetof(ImGuiStyle, SeparatorTextBorderSize)}, // ImGuiStyleVar_SeparatorTextBorderSize { 2, ImGuiDataType_Float, (ImU32)offsetof(ImGuiStyle, SeparatorTextAlign) }, // ImGuiStyleVar_SeparatorTextAlign { 2, ImGuiDataType_Float, (ImU32)offsetof(ImGuiStyle, SeparatorTextPadding) }, // ImGuiStyleVar_SeparatorTextPadding + { 1, ImGuiDataType_Float, (ImU32)offsetof(ImGuiStyle, LayoutAlign) }, // ImGuiStyleVar_LayoutAlign }; const ImGuiStyleVarInfo* ImGui::GetStyleVarInfo(ImGuiStyleVar idx) @@ -11357,6 +11359,9 @@ void ImGui::ErrorRecoveryTryToRecoverWindowState(const ImGuiErrorRecoveryStat IM_ASSERT_USER_ERROR(0, "Missing EndMultiSelect()"); EndMultiSelect(); } +#ifdef IMGUI_HAS_STACK_LAYOUT + ImGuiStackLayout::ErrorRecoveryTryToRecoverWindowState(state_in); +#endif if (window->DC.MenuBarAppending) //-V1044 { IM_ASSERT_USER_ERROR(0, "Missing EndMenuBar()"); diff --git a/imgui.h b/imgui.h index df2d42675..e55049cec 100644 --- a/imgui.h +++ b/imgui.h @@ -33,6 +33,7 @@ #define IMGUI_VERSION_NUM 19300 #define IMGUI_HAS_TABLE // Added BeginTable() - from IMGUI_VERSION_NUM >= 18000 #define IMGUI_HAS_TEXTURES // Added ImGuiBackendFlags_RendererHasTextures - from IMGUI_VERSION_NUM >= 19198 +#define IMGUI_HAS_STACK_LAYOUT // Stack-Layout PR #846 /* @@ -1901,6 +1902,7 @@ enum ImGuiStyleVar_ ImGuiStyleVar_SeparatorTextBorderSize, // float SeparatorTextBorderSize ImGuiStyleVar_SeparatorTextAlign, // ImVec2 SeparatorTextAlign ImGuiStyleVar_SeparatorTextPadding, // ImVec2 SeparatorTextPadding + ImGuiStyleVar_LayoutAlign, // float LayoutAlign ImGuiStyleVar_COUNT }; @@ -2360,6 +2362,7 @@ struct ImGuiStyle float ScrollbarPadding; // Padding of scrollbar grab within its frame (same for both axes). float GrabMinSize; // Minimum width/height of a grab box for slider/scrollbar. float GrabRounding; // Radius of grabs corners rounding. Set to 0.0f to have rectangular slider grabs. + float LayoutAlign; // Element alignment inside horizontal and vertical layouts (0.0f - left/top, 1.0f - right/bottom, 0.5f - center). float LogSliderDeadzone; // The size in pixels of the dead-zone around zero on logarithmic sliders that cross zero. float ImageRounding; // Rounding of Image() calls. float ImageBorderSize; // Thickness of border around Image() calls. @@ -4393,6 +4396,10 @@ typedef ImFontAtlasRect ImFontAtlasCustomRect; #pragma warning (pop) #endif +#ifdef IMGUI_HAS_STACK_LAYOUT +#include "imgui_stacklayout.h" +#endif + // Include imgui_user.h at the end of imgui.h // May be convenient for some users to only explicitly include vanilla imgui.h and have extra stuff included. #ifdef IMGUI_INCLUDE_IMGUI_USER_H diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 13734d316..ffc84d1c7 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -5520,6 +5520,88 @@ static void DemoWindowLayout() ImGui::TreePop(); } + +#ifdef IMGUI_HAS_STACK_LAYOUT + IMGUI_DEMO_MARKER("Layout/Stack Layout"); + if (ImGui::TreeNode("Stack Layout")) + { + static bool widget_a = true, widget_b = true, widget_c = true; + static bool spring_a = true, spring_ab = true, spring_bc = true, spring_c = true; + static bool minimize_width = false, minimize_height = true; + static bool horizontal = true, draw_springs = true; + static ImVec2 item_spacing = ImGui::GetStyle().ItemSpacing; + static float a_c_spring_weight = 0.0f; + static float ab_spring_weight = 0.5f; + static float alignment = 0.5f; + + ImGui::Checkbox("Widget A", &widget_a); ImGui::SameLine(); + ImGui::Checkbox("Widget B", &widget_b); ImGui::SameLine(); + ImGui::Checkbox("Widget C", &widget_c); + ImGui::Checkbox("Spring A", &spring_a); ImGui::SameLine(); + ImGui::Checkbox("Spring AB", &spring_ab); ImGui::SameLine(); + ImGui::Checkbox("Spring BC", &spring_bc); ImGui::SameLine(); + ImGui::Checkbox("Spring C", &spring_c); + ImGui::Checkbox("Horizontal", &horizontal); ImGui::SameLine(); + ImGui::Checkbox("Minimize Width", &minimize_width); ImGui::SameLine(); + ImGui::Checkbox("Minimize Height", &minimize_height); + ImGui::Checkbox("Draw Springs", &draw_springs); ImGui::SameLine(); + ImGui::TextUnformatted(" "); ImGui::SameLine(); + ImGui::ColorButton("- Spring", ImColor(80, 20, 80), ImGuiColorEditFlags_NoTooltip | ImGuiColorEditFlags_NoPicker); ImGui::SameLine(); + ImGui::TextUnformatted("Spring"); ImGui::SameLine(); + ImGui::TextUnformatted(" "); ImGui::SameLine(); + ImGui::ColorButton("- Spacing", ImColor(80, 20, 20), ImGuiColorEditFlags_NoTooltip | ImGuiColorEditFlags_NoPicker); ImGui::SameLine(); + ImGui::TextUnformatted("Item Spacing"); + ImGui::DragFloat("Item Spacing", horizontal ? &item_spacing.x : &item_spacing.y, 0.1f, 0.0f, 50.0f); + ImGui::DragFloat("A & C Spring Weight", &a_c_spring_weight, 0.002f, 0.0f, 1.0f); + ImGui::DragFloat("AB Spring Weight", &ab_spring_weight, 0.002f, 0.0f, 1.0f); + if (ImGui::IsItemHovered()) ImGui::SetTooltip("BC Spring Weight = 1 - AB Spring Weight"); + ImGui::DragFloat("Minor Axis Alignment", &alignment, 0.002f, 0.0f, 1.0f); + if (ImGui::IsItemHovered()) ImGui::SetTooltip("This is vertical alignment for horizontal layouts and horizontal alignment for vertical layouts."); + ImGui::Text("Layout widgets:"); + ImGui::Text("| Spring A | Widget A | Spring AB | Widget B | Spring BC | Widget C | Spring C |"); + + ImGui::Spacing(); + + ImVec2 widget_size; + widget_size.x = floorf(ImGui::GetContentRegionAvail().x / 4); + widget_size.y = horizontal ? floorf(widget_size.x / 3) : widget_size.x; + + ImVec2 small_widget_size = widget_size; + if (horizontal) + small_widget_size.y = floorf(small_widget_size.y / 2); + else + small_widget_size.x = floorf(small_widget_size.x / 2); + + ImVec2 layout_size = ImVec2(widget_size.x * 4, widget_size.y * 4); + if (minimize_width) layout_size.x = 0.0f; + if (minimize_height) layout_size.y = 0.0f; + + // Minor axis alignment can be set by style or directly in BeginHorizontal/BeginVertical + // Example: + // ImGui::PushStyleVar(ImGuiStyleVar_LayoutAlign, alignment); + + ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(floorf(item_spacing.x), floorf(item_spacing.y))); + + // The layout draws its springs: their sizes are known once the layout ends. + ImGui::SetNextLayoutDebugFlags(draw_springs ? ImGuiLayoutDebugFlags_DrawSprings : ImGuiLayoutDebugFlags_None); + if (horizontal) { ImGui::BeginHorizontal("h1", layout_size, alignment); } else { ImGui::BeginVertical("v1", layout_size, alignment); } + if (spring_a) { ImGui::Spring(a_c_spring_weight); } + if (widget_a) { ImGui::Button("Widget A", widget_size); } + if (spring_ab) { ImGui::Spring(ab_spring_weight); } + if (widget_b) { ImGui::Button("Widget B", small_widget_size); } + if (spring_bc) { ImGui::Spring(1.0f - ab_spring_weight); } + if (widget_c) { ImGui::Button("Widget C", widget_size); } + if (spring_c) { ImGui::Spring(a_c_spring_weight); } + if (horizontal) { ImGui::EndHorizontal(); } else { ImGui::EndVertical(); } + + ImGui::PopStyleVar(); + + ImDrawList* draw_list = ImGui::GetWindowDrawList(); + draw_list->AddRect(ImGui::GetItemRectMin(), ImGui::GetItemRectMax(), ImGui::GetColorU32(ImGuiCol_Border)); + + ImGui::TreePop(); + } +#endif // IMGUI_HAS_STACK_LAYOUT } //----------------------------------------------------------------------------- @@ -8799,6 +8881,10 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref) SameLine(); HelpMarker("Alignment applies when a button is larger than its text content."); SliderFloat2("SelectableTextAlign", (float*)&style.SelectableTextAlign, 0.0f, 1.0f, "%.2f"); SameLine(); HelpMarker("Alignment applies when a selectable is larger than its text content."); +#ifdef IMGUI_HAS_STACK_LAYOUT + SliderFloat("LayoutAlign", &style.LayoutAlign, 0.0f, 1.0f, "%.2f"); + SameLine(); HelpMarker("Alignment of items on the other axis of BeginHorizontal()/BeginVertical() layouts, when they are given no alignment."); +#endif SliderFloat("SeparatorSize", &style.SeparatorSize, 0.0f, 10.0f, "%.0f"); SliderFloat("SeparatorTextBorderSize", &style.SeparatorTextBorderSize, 0.0f, 10.0f, "%.0f"); SliderFloat2("SeparatorTextAlign", (float*)&style.SeparatorTextAlign, 0.0f, 1.0f, "%.2f"); diff --git a/imgui_internal.h b/imgui_internal.h index 2932cb53a..273b4cab6 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -11,6 +11,7 @@ Index of this file: // [SECTION] Forward declarations // [SECTION] Context pointer // [SECTION] STB libraries includes +// [SECTION] Stack Layout includes // [SECTION] Macros // [SECTION] Generic helpers // [SECTION] ImDrawList support @@ -229,6 +230,14 @@ typedef ImU16 ImGuiTableDrawChannelIdx; extern IMGUI_API ImGuiContext* GImGui; // Current implicit context pointer #endif +//------------------------------------------------------------------------- +// [SECTION] Stack Layout includes +//------------------------------------------------------------------------- + +#ifdef IMGUI_HAS_STACK_LAYOUT +# include "imgui_stacklayout_internal.h" +#endif + //----------------------------------------------------------------------------- // [SECTION] Macros //----------------------------------------------------------------------------- diff --git a/imgui_stacklayout.cpp b/imgui_stacklayout.cpp new file mode 100644 index 000000000..3793fa525 --- /dev/null +++ b/imgui_stacklayout.cpp @@ -0,0 +1,1382 @@ +// dear imgui: stack layouts +// (stack layout code) + +/* + +Index of this file: + +// [SECTION] Commentary +// [SECTION] Header mess +// [SECTION] Stack layout: Forward declarations +// [SECTION] Stack layout: flags, enums, data structures +// [SECTION] Stack Layout: Context forward declarations +// [SECTION] Stack Layout: Internal code forward declarations +// [SECTION] Stack Layout: Context +// [SECTION] Stack Layout: Internal code +// [SECTION] Stack Layout: Internal API +// [SECTION] Stack Layout: Public API + +*/ + +// Navigating this file: +// - 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. + +//----------------------------------------------------------------------------- +// [SECTION] Commentary +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// Typical call flow: (root level is generally public API): +//----------------------------------------------------------------------------- +// +// - BeginHorizontal/BeginVertical() user begin into a layout +// - [...] user emit contents +// - | Spring() - separate widget groups in layout +// - | SuspendLayout() - stop any layout operations +// - | ResumeLayout() - resume layout operations +//----------------------------------------------------------------------------- +// - EndHorizontal/EndVertical() user ends the layout +//----------------------------------------------------------------------------- + + +//----------------------------------------------------------------------------- +// [SECTION] Header mess +//----------------------------------------------------------------------------- + +#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_WARNINGS) +#define _CRT_SECURE_NO_WARNINGS +#endif + +#ifndef IMGUI_DEFINE_MATH_OPERATORS +#define IMGUI_DEFINE_MATH_OPERATORS +#endif + +#include "imgui.h" +#ifndef IMGUI_DISABLE +#include "imgui_internal.h" + +// Clang/GCC warnings with -Weverything +#if defined(__clang__) +#if __has_warning("-Wunknown-warning-option") +#pragma clang diagnostic ignored "-Wunknown-warning-option" // warning: unknown warning group 'xxx' // not all warnings are known by all Clang versions and they tend to be rename-happy.. so ignoring warnings triggers new warnings on some configuration. Great! +#endif +#pragma clang diagnostic ignored "-Wunknown-pragmas" // warning: unknown warning group 'xxx' +#pragma clang diagnostic ignored "-Wold-style-cast" // warning: use of old-style cast // yes, they are more terse. +#pragma clang diagnostic ignored "-Wfloat-equal" // warning: comparing floating point with == or != is unsafe // storing and comparing against same constants (typically 0.0f) is ok. +#pragma clang diagnostic ignored "-Wsign-conversion" // warning: implicit conversion changes signedness +#pragma clang diagnostic ignored "-Wunsafe-buffer-usage" // warning: 'xxx' is an unsafe pointer used for buffer access +#elif defined(__GNUC__) +#pragma GCC diagnostic ignored "-Wpragmas" // warning: unknown option after '#pragma GCC diagnostic' kind +#pragma GCC diagnostic ignored "-Wfloat-equal" // warning: comparing floating-point with '==' or '!=' is unsafe +#pragma GCC diagnostic ignored "-Wconversion" // warning: conversion to 'xxxx' from 'xxxx' may change value +#pragma GCC diagnostic ignored "-Wsign-conversion" // warning: conversion to 'xxxx' from 'xxxx' may change the sign of the result +#endif + +namespace ImGuiStackLayout +{ + +//----------------------------------------------------------------------------- +// [SECTION] Stack layout: Forward declarations +//----------------------------------------------------------------------------- + +// Use your programming IDE "Go to definition" facility on the names of the center columns to find the actual flags/enum lists. +typedef int ImGuiLayoutItemType; // -> enum ImGuiLayoutItemType_ // Enum: Item or Spring + + +//----------------------------------------------------------------------------- +// [SECTION] Stack layout: flags, enums, data structures +//----------------------------------------------------------------------------- + +enum ImGuiLayoutItemType_ +{ + ImGuiLayoutItemType_Item, + ImGuiLayoutItemType_Spring +}; + +// sizeof() == 48 +struct ImGuiLayoutItem +{ + ImGuiLayoutItemType Type; // Type of an item + ImRect MeasuredBounds; + + float SpringWeight; // Weight of a spring + float SpringSpacing; // Spring spacing + float SpringSize; // Calculated spring size + + float CurrentAlign; + float CurrentAlignOffset; + + int VertexIndexBegin; + int VertexIndexEnd; + + ImGuiLayoutItem(ImGuiLayoutItemType type) + { + Type = type; + MeasuredBounds = ImRect(0, 0, 0, 0); // FIXME: @thedmd are you sure the default ImRect value FLT_MAX,FLT_MAX,-FLT_MAX,-FLT_MAX aren't enough here? + SpringWeight = 1.0f; + SpringSpacing = -1.0f; + SpringSize = 0.0f; + CurrentAlign = 0.0f; + CurrentAlignOffset = 0.0f; + VertexIndexBegin = VertexIndexEnd = 0; + } +}; + +struct ImGuiLayout +{ + ImGuiID Id; + ImGuiLayoutType Type; + int LastFrameUsed; + float LastTimeUsed; + int InstanceCount; // Further uses of the ID in the current frame. + int IDStackSize; // Size of the ID stack before BeginLayout() pushed the ID. + int GroupStackSize; // Size of the group stack when BeginLayout() was called. + ImVec2 Size; // Size passed to BeginLayout + ImVec2 CurrentSize; // Bounds of layout known at the beginning the frame. + ImVec2 MinimumSize; // Minimum possible size when springs are collapsed. + ImVec2 MeasuredSize; // Measured size with springs expanded. + + ImVector Items; + int CurrentItemIndex; + int ParentItemIndex; + ImGuiLayout* Parent; + ImGuiLayout* FirstChild; + ImGuiLayout* NextSibling; + float Align; // Current item alignment. + ImVec2 StartPos; // Initial cursor position when BeginLayout is called. + ImVec2 StartCursorMaxPos; // Maximum cursor position when BeginLayout is called. + + // Line state of the enclosing flow, restored by EndLayout() as EndGroup() does. + ImVec2 BackupCursorPosPrevLine; + ImVec1 BackupIndent; + ImVec2 BackupCurrLineSize; + float BackupCurrLineTextBaseOffset; + bool BackupIsSameLine; + ImGuiLayoutType BackupLayoutType; + + // Last item when the current layout item began, to tell whether an item was submitted inside it. + ImGuiID ItemBeginLastItemId; + ImRect ItemBeginLastItemRect; + + bool ClipRectPushed; + + // Root layouts: how far corrections can move items, and the clip rect widened by it while items are submitted. + ImVec2 SpringSizeInTree; // Spring sizes of the layout and its nested layouts at the end of the previous frame, per axis. + bool WideClipRectPushed; + int WideClipRectCmdIndex; + ImVec4 WideClipRect; + ImVec4 NarrowClipRect; + ImGuiLayoutDebugFlags DebugFlags; + + ImGuiLayout(ImGuiID id, ImGuiLayoutType type) + { + Id = id; + Type = type; + LastFrameUsed = -1; + LastTimeUsed = -1.0f; + InstanceCount = 0; + IDStackSize = 0; + GroupStackSize = 0; + Size = CurrentSize = MinimumSize = MeasuredSize = ImVec2(0, 0); + CurrentItemIndex = 0; + ParentItemIndex = 0; + Parent = FirstChild = NextSibling = NULL; + Align = -1.0f; + StartPos = ImVec2(0, 0); + StartCursorMaxPos = ImVec2(0, 0); + BackupCursorPosPrevLine = BackupCurrLineSize = ImVec2(0, 0); + BackupCurrLineTextBaseOffset = 0.0f; + BackupIsSameLine = false; + BackupLayoutType = ImGuiLayoutType_Vertical; + ItemBeginLastItemId = 0; + ClipRectPushed = false; + SpringSizeInTree = ImVec2(0, 0); + WideClipRectPushed = false; + WideClipRectCmdIndex = 0; + WideClipRect = NarrowClipRect = ImVec4(0, 0, 0, 0); + DebugFlags = ImGuiLayoutDebugFlags_None; + } +}; + +struct ImGuiLayoutSuspendBackup +{ + ImGuiLayoutType LayoutType; + ImVec2 CursorMaxPos; + int IDStackSize; // Size of the ID stack before SuspendLayout() pushed the current ID again. +}; + +struct ImGuiLayoutWindowState +{ + ImGuiWindow* Window; + ImGuiLayout* CurrentLayout; + ImVector LayoutStack; + ImVector SuspendStack; + ImGuiStorage Layouts; + + ImGuiLayoutWindowState() + { + Window = NULL; + CurrentLayout = NULL; + } +}; + +struct ImGuiLayoutContextState +{ + ImGuiStorage WindowStates; // ImGuiLayoutWindowState* by window ID + ImGuiLayoutWindowState* LastWindowState; + ImGuiLayoutDebugFlags NextDebugFlags; + + ImGuiLayoutContextState() + { + LastWindowState = NULL; + NextDebugFlags = ImGuiLayoutDebugFlags_None; + } +}; + + +//----------------------------------------------------------------------------- +// [SECTION] Stack Layout: Context forward declarations +//----------------------------------------------------------------------------- + +// The state of a context is the UserData of its Shutdown hook, found by the hook owner. +static ImGuiID GetHookOwnerID(); +static ImGuiLayoutContextState* FindContextState(ImGuiContext& g); +static ImGuiLayoutContextState* GetContextState(ImGuiContext& g); +static void NewFramePreHook(ImGuiContext* ctx, ImGuiContextHook* hook); +static void ShutdownHook(ImGuiContext* ctx, ImGuiContextHook* hook); + +static ImGuiLayoutWindowState* GetCurrentWindowLayoutState(); +static void DestroyWindowLayoutState(ImGuiLayoutWindowState* window_state); + + +//----------------------------------------------------------------------------- +// [SECTION] Stack Layout: Internal code forward declarations +//----------------------------------------------------------------------------- + +// Stack Layout +static ImGuiLayout* FindLayout(ImGuiID id, ImGuiLayoutType type); +static ImGuiLayout* CreateNewLayout(ImGuiID id, ImGuiLayoutType type, ImVec2 size); +static void BeginLayout(ImGuiID id, ImGuiLayoutType type, ImVec2 size, float align); +static void EndLayout(ImGuiLayoutWindowState* window_state); +static ImVec2 CalculateLayoutSize(ImGuiLayout& layout, bool collapse_springs); +static void PushLayout(ImGuiLayout* layout); +static void PopLayout(ImGuiLayout* layout); +static void BalanceLayoutSprings(ImGuiLayout& layout); +static ImVec2 BalanceLayoutItemAlignment(ImGuiLayout& layout, ImGuiLayoutItem& item); +static void BalanceLayoutItemsAlignment(ImGuiLayout& layout); +static bool HasAnyNonZeroSpring(ImGuiLayout& layout); +static void BalanceChildLayouts(ImGuiLayout& layout); +static void BeginLayoutClipRect(ImGuiLayout& layout, bool measured); +static void EndLayoutClipRect(ImGuiLayout& layout); +static void BeginLayoutWideClipRect(ImGuiLayout& layout); +static void EndLayoutWideClipRect(ImGuiLayout& layout); +static ImVec2 CalculateSpringSizeInTree(const ImGuiLayout& layout); +static ImGuiLayoutItem* GenerateLayoutItem(ImGuiLayout& layout, ImGuiLayoutItemType type); +static float CalculateLayoutItemAlignmentOffset(ImGuiLayout& layout, ImGuiLayoutItem& item); +static void TranslateLayoutItem(ImGuiLayoutItem& item, const ImVec2& offset); +static void SignedIndent(float indent); +static void MarkLayoutLastItem(ImGuiLayout& layout); +static void BeginLayoutItem(ImGuiLayout& layout); +static void EndLayoutItem(ImGuiLayout& layout); +static void AddLayoutSpring(ImGuiLayout& layout, float weight, float spacing); +static void DebugDrawLayout(const ImGuiLayout& layout); + + +//----------------------------------------------------------------------------- +// [SECTION] Stack Layout: Context +//----------------------------------------------------------------------------- + +static ImGuiID GetHookOwnerID() +{ + static const ImGuiID owner_id = ImHashStr("ImGuiStackLayout"); + return owner_id; +} + +static ImGuiLayoutContextState* FindContextState(ImGuiContext& g) +{ + const ImGuiID owner_id = GetHookOwnerID(); + for (ImGuiContextHook& hook : g.Hooks) + if (hook.Owner == owner_id && hook.Type == ImGuiContextHookType_Shutdown) + return (ImGuiLayoutContextState*)hook.UserData; + return NULL; +} + +static ImGuiLayoutContextState* GetContextState(ImGuiContext& g) +{ + if (ImGuiLayoutContextState* state = FindContextState(g)) + return state; + + ImGuiLayoutContextState* state = IM_NEW(ImGuiLayoutContextState); + + ImGuiContextHook hook; + hook.Owner = GetHookOwnerID(); + hook.UserData = state; + hook.Type = ImGuiContextHookType_NewFramePre; + hook.Callback = NewFramePreHook; + ImGui::AddContextHook(&g, &hook); + hook.Type = ImGuiContextHookType_Shutdown; + hook.Callback = ShutdownHook; + ImGui::AddContextHook(&g, &hook); + + return state; +} + +static void NewFramePreHook(ImGuiContext* ctx, ImGuiContextHook* hook) +{ + ImGuiContext& g = *ctx; + ImGuiLayoutContextState* state = (ImGuiLayoutContextState*)hook->UserData; + + // Same policy as windows and tables: free layouts unused for io.ConfigMemoryCompactTimer, all of a compacted window. + const bool gc_all = (g.GcCompactAll || g.IO.ConfigMemoryCompactTimer < 0.0f); + const float memory_compact_start_time = gc_all ? FLT_MAX : (float)g.Time - g.IO.ConfigMemoryCompactTimer; + + ImVector& window_states = state->WindowStates.Data; + int window_states_kept = 0; + for (ImGuiStoragePair& window_pair : window_states) + { + ImGuiLayoutWindowState* window_state = (ImGuiLayoutWindowState*)window_pair.val_p; + + // Error recovery in End() closes layouts left open, unless disabled. + if (window_state->LayoutStack.Size > 0) + { + IM_ASSERT_USER_ERROR(0, "Missing EndHorizontal(), EndVertical() or ResumeLayout() at the end of the frame!"); + window_state->LayoutStack.resize(0); + window_state->SuspendStack.resize(0); + window_state->CurrentLayout = NULL; + } + + if (window_state->Window->MemoryCompacted) + { + DestroyWindowLayoutState(window_state); + continue; + } + + ImVector& layouts = window_state->Layouts.Data; + int layouts_kept = 0; + for (ImGuiStoragePair& layout_pair : layouts) + { + ImGuiLayout* layout = (ImGuiLayout*)layout_pair.val_p; + if (layout->LastFrameUsed != g.FrameCount && layout->LastTimeUsed < memory_compact_start_time) + IM_DELETE(layout); + else + layouts[layouts_kept++] = layout_pair; + } + layouts.resize(layouts_kept); + + window_states[window_states_kept++] = window_pair; + } + window_states.resize(window_states_kept); + state->LastWindowState = NULL; +} + +static void ShutdownHook(ImGuiContext* ctx, ImGuiContextHook* hook) +{ + IM_UNUSED(ctx); + ImGuiLayoutContextState* state = (ImGuiLayoutContextState*)hook->UserData; + for (ImGuiStoragePair& window_pair : state->WindowStates.Data) + DestroyWindowLayoutState((ImGuiLayoutWindowState*)window_pair.val_p); + IM_DELETE(state); + hook->UserData = NULL; +} + +static ImGuiLayoutWindowState* GetCurrentWindowLayoutState() +{ + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; + ImGuiLayoutContextState* state = GetContextState(g); + if (state->LastWindowState != NULL && state->LastWindowState->Window == window) + return state->LastWindowState; + + ImGuiLayoutWindowState* window_state = (ImGuiLayoutWindowState*)state->WindowStates.GetVoidPtr(window->ID); + if (window_state == NULL) + { + window_state = IM_NEW(ImGuiLayoutWindowState); + window_state->Window = window; + state->WindowStates.SetVoidPtr(window->ID, window_state); + } + state->LastWindowState = window_state; + return window_state; +} + +static void DestroyWindowLayoutState(ImGuiLayoutWindowState* window_state) +{ + for (ImGuiStoragePair& layout_pair : window_state->Layouts.Data) + IM_DELETE((ImGuiLayout*)layout_pair.val_p); + IM_DELETE(window_state); +} + + +//----------------------------------------------------------------------------- +// [SECTION] Stack Layout: Internal code +//----------------------------------------------------------------------------- + +static ImGuiLayout* FindLayout(ImGuiID id, ImGuiLayoutType type) +{ + IM_ASSERT(type == ImGuiLayoutType_Horizontal || type == ImGuiLayoutType_Vertical); + + ImGuiLayoutWindowState* window_state = GetCurrentWindowLayoutState(); + ImGuiLayout* layout = (ImGuiLayout*)window_state->Layouts.GetVoidPtr(id); + if (!layout) + return NULL; + + if (layout->Type != type) + { + layout->Type = type; + layout->MinimumSize = ImVec2(0.0f, 0.0f); + layout->Items.clear(); + } + + return layout; +} + +static ImGuiLayout* CreateNewLayout(ImGuiID id, ImGuiLayoutType type, ImVec2 size) +{ + IM_ASSERT(type == ImGuiLayoutType_Horizontal || type == ImGuiLayoutType_Vertical); + + ImGuiLayoutWindowState* window_state = GetCurrentWindowLayoutState(); + + ImGuiLayout* layout = IM_NEW(ImGuiLayout)(id, type); + layout->Size = size; + + window_state->Layouts.SetVoidPtr(id, layout); + + return layout; +} + +static void BeginLayout(ImGuiID id, ImGuiLayoutType type, ImVec2 size, float align) +{ + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; + + if (size.x < 0.0f || size.y < 0.0f) + size = ImGui::CalcItemSize(size, 0.0f, 0.0f); + + const int id_stack_size = window->IDStack.Size; + ImGui::PushOverrideID(id); + + // Find or create + ImGuiLayout* layout = FindLayout(id, type); + if (!layout) + layout = CreateNewLayout(id, type, size); + + // Each further use of the ID in a frame gets a layout of its own, as table instances do. + if (layout->LastFrameUsed == g.FrameCount) + { + IM_ASSERT_USER_ERROR(0, "BeginHorizontal()/BeginVertical() with an ID already used in this frame! Use PushID() to make IDs unique."); + const int instance_no = ++layout->InstanceCount; + const ImGuiID instance_id = ImHashData(&instance_no, sizeof(instance_no), id); + ImGuiLayout* instance = FindLayout(instance_id, type); + layout = instance ? instance : CreateNewLayout(instance_id, type, size); + } + else + { + layout->InstanceCount = 0; + } + + const bool measured = (layout->LastFrameUsed == g.FrameCount - 1); + layout->LastFrameUsed = g.FrameCount; + layout->LastTimeUsed = (float)g.Time; + layout->IDStackSize = id_stack_size; + layout->GroupStackSize = g.GroupStack.Size; + + PushLayout(layout); + + ImGuiLayoutContextState* context_state = GetContextState(g); + layout->DebugFlags = context_state->NextDebugFlags | (layout->Parent ? layout->Parent->DebugFlags : ImGuiLayoutDebugFlags_None); + context_state->NextDebugFlags = ImGuiLayoutDebugFlags_None; + + if (layout->Size.x != size.x || layout->Size.y != size.y) + layout->Size = size; + + if (align < 0.0f) + layout->Align = -1.0f; + else + layout->Align = ImClamp(align, 0.0f, 1.0f); + + // Start capture + layout->CurrentItemIndex = 0; + + layout->CurrentSize.x = layout->Size.x > 0.0f ? layout->Size.x : layout->MinimumSize.x; + layout->CurrentSize.y = layout->Size.y > 0.0f ? layout->Size.y : layout->MinimumSize.y; + + // The layout is a block starting at the cursor, like a group: save the line it is on. + layout->StartPos = window->DC.CursorPos; + layout->StartCursorMaxPos = window->DC.CursorMaxPos; + layout->BackupCursorPosPrevLine = window->DC.CursorPosPrevLine; + layout->BackupIndent = window->DC.Indent; + layout->BackupCurrLineSize = window->DC.CurrLineSize; + layout->BackupCurrLineTextBaseOffset = window->DC.CurrLineTextBaseOffset; + layout->BackupIsSameLine = window->DC.IsSameLine; + layout->BackupLayoutType = window->DC.LayoutType; + + // ItemSize() flows items along the layout axis. New lines start at the layout's left edge. + window->DC.LayoutType = type; + window->DC.Indent.x = layout->StartPos.x - window->Pos.x - window->DC.ColumnsOffset.x; + window->DC.CurrLineSize = ImVec2(0.0f, 0.0f); + + if (layout->Parent == NULL) + BeginLayoutWideClipRect(*layout); + BeginLayoutClipRect(*layout, measured); + + BeginLayoutItem(*layout); +} + +static void EndLayout(ImGuiLayoutWindowState* window_state) +{ + ImGuiLayout* layout = window_state->CurrentLayout; + ImGuiWindow* window = window_state->Window; + + EndLayoutItem(*layout); + + if (layout->CurrentItemIndex < layout->Items.Size) + layout->Items.resize(layout->CurrentItemIndex); + + PopLayout(layout); + + const bool auto_width = layout->Size.x <= 0.0f; + const bool auto_height = layout->Size.y <= 0.0f; + + ImVec2 new_size = layout->Size; + if (auto_width) + new_size.x = layout->CurrentSize.x; + if (auto_height) + new_size.y = layout->CurrentSize.y; + + ImVec2 new_minimum_size = CalculateLayoutSize(*layout, true); + + if (new_minimum_size.x != layout->MinimumSize.x || new_minimum_size.y != layout->MinimumSize.y) + { + layout->MinimumSize = new_minimum_size; + + // Shrink + if (auto_width) + new_size.x = new_minimum_size.x; + if (auto_height) + new_size.y = new_minimum_size.y; + } + + if (!auto_width) + new_size.x = layout->Size.x; + if (!auto_height) + new_size.y = layout->Size.y; + + layout->CurrentSize = new_size; + + ImVec2 measured_size = new_size; + // Inflate to parent size only when there are springs that need the free space. + if ((auto_width || auto_height) && layout->Parent && HasAnyNonZeroSpring(*layout)) + { + if (layout->Type == ImGuiLayoutType_Horizontal && auto_width && layout->Parent->CurrentSize.x > 0) + layout->CurrentSize.x = layout->Parent->CurrentSize.x; + else if (layout->Type == ImGuiLayoutType_Vertical && auto_height && layout->Parent->CurrentSize.y > 0) + layout->CurrentSize.y = layout->Parent->CurrentSize.y; + + BalanceLayoutSprings(*layout); + + measured_size = layout->CurrentSize; + } + + layout->CurrentSize = new_size; + layout->MeasuredSize = measured_size; + + IM_ASSERT_USER_ERROR(window->IDStack.Size == layout->IDStackSize + 1, "Mismatching PushID()/PopID() inside a layout!"); + while (window->IDStack.Size > layout->IDStackSize) + ImGui::PopID(); + + EndLayoutClipRect(*layout); + EndLayoutWideClipRect(*layout); + + // Restore the enclosing line, then submit the layout as one item, as EndGroup() does. + window->DC.CursorPos = layout->StartPos; + window->DC.CursorPosPrevLine = layout->BackupCursorPosPrevLine; + window->DC.CursorMaxPos = layout->StartCursorMaxPos; + window->DC.Indent = layout->BackupIndent; + window->DC.CurrLineSize = layout->BackupCurrLineSize; + window->DC.CurrLineTextBaseOffset = layout->BackupCurrLineTextBaseOffset; + window->DC.IsSameLine = layout->BackupIsSameLine; + window->DC.LayoutType = layout->BackupLayoutType; + ImGui::ItemSize(new_size); + // The item rect includes the inflation to the parent, which GetItemRect*() users draw with, except inside a group + // opened in the parent: EndGroup() would include it, feeding the parent's size back into itself. + const bool in_group_of_parent = layout->Parent != NULL && layout->GroupStackSize > layout->Parent->GroupStackSize; + ImGui::ItemAdd(ImRect(layout->StartPos, layout->StartPos + (in_group_of_parent ? new_size : measured_size)), 0); + + // The parent measures this layout by the size given to ItemSize(), without the inflation in the item rect. + if (window_state->CurrentLayout) + MarkLayoutLastItem(*window_state->CurrentLayout); + + if (layout->Parent == NULL) + { + BalanceChildLayouts(*layout); + layout->SpringSizeInTree = CalculateSpringSizeInTree(*layout); + } + + if (layout->DebugFlags != ImGuiLayoutDebugFlags_None) + DebugDrawLayout(*layout); + + //window->DrawList->AddRect(layout->StartPos, layout->StartPos + measured_size, IM_COL32(0,255,0,255)); // [DEBUG] + //window->DrawList->AddRect(window->DC.LastItemRect.Min, window->DC.LastItemRect.Max, IM_COL32(255,255,0,255)); // [DEBUG] +} + +static ImVec2 CalculateLayoutSize(ImGuiLayout& layout, bool collapse_springs) +{ + ImVec2 bounds = ImVec2(0.0f, 0.0f); + + if (layout.Type == ImGuiLayoutType_Vertical) + { + for (int i = 0; i < layout.Items.Size; i++) + { + ImGuiLayoutItem& item = layout.Items[i]; + ImVec2 item_size = item.MeasuredBounds.GetSize(); + + if (item.Type == ImGuiLayoutItemType_Item) + { + bounds.x = ImMax(bounds.x, item_size.x); + bounds.y += item_size.y; + } + else + { + bounds.y += ImFloor(item.SpringSpacing); + + if (!collapse_springs) + bounds.y += item.SpringSize; + } + } + } + else + { + for (int i = 0; i < layout.Items.Size; i++) + { + ImGuiLayoutItem& item = layout.Items[i]; + ImVec2 item_size = item.MeasuredBounds.GetSize(); + + if (item.Type == ImGuiLayoutItemType_Item) + { + bounds.x += item_size.x; + bounds.y = ImMax(bounds.y, item_size.y); + } + else + { + bounds.x += ImFloor(item.SpringSpacing); + + if (!collapse_springs) + bounds.x += item.SpringSize; + } + } + } + + return bounds; +} + +static void PushLayout(ImGuiLayout* layout) +{ + ImGuiLayoutWindowState* window_state = GetCurrentWindowLayoutState(); + + if (layout) + { + layout->Parent = window_state->CurrentLayout; + if (layout->Parent != NULL) + layout->ParentItemIndex = layout->Parent->CurrentItemIndex; + if (window_state->CurrentLayout) + { + layout->NextSibling = window_state->CurrentLayout->FirstChild; + layout->FirstChild = NULL; + window_state->CurrentLayout->FirstChild = layout; + } + else + { + layout->NextSibling = NULL; + layout->FirstChild = NULL; + } + } + + window_state->LayoutStack.push_back(layout); + window_state->CurrentLayout = layout; +} + +static void PopLayout(ImGuiLayout* layout) +{ + ImGuiLayoutWindowState* window_state = GetCurrentWindowLayoutState(); + + IM_ASSERT(!window_state->LayoutStack.empty()); + IM_ASSERT(window_state->LayoutStack.back() == layout); + IM_UNUSED(layout); + + window_state->LayoutStack.pop_back(); + window_state->CurrentLayout = window_state->LayoutStack.empty() ? NULL : window_state->LayoutStack.back(); +} + +static void BalanceLayoutSprings(ImGuiLayout& layout) +{ + // Accumulate amount of occupied space and springs weights + float total_spring_weight = 0.0f; + + int last_spring_item_index = -1; + for (int i = 0; i < layout.Items.Size; i++) + { + ImGuiLayoutItem& item = layout.Items[i]; + if (item.Type == ImGuiLayoutItemType_Spring) + { + total_spring_weight += item.SpringWeight; + last_spring_item_index = i; + } + } + + // Determine occupied space and available space depending on layout type + const bool is_horizontal = (layout.Type == ImGuiLayoutType_Horizontal); + const bool is_auto_sized = ((is_horizontal ? layout.Size.x : layout.Size.y) <= 0.0f) && (layout.Parent == NULL); + const float occupied_space = is_horizontal ? layout.MinimumSize.x : layout.MinimumSize.y; + const float available_space = is_auto_sized ? occupied_space : (is_horizontal ? layout.CurrentSize.x : layout.CurrentSize.y); + const float free_space = ImMax(available_space - occupied_space, 0.0f); + + // Springs that change size move the items after them, to avoid one frame visual bugs. Offsets accumulate, so each + // item is translated once. + ImVec2 offset = ImVec2(0.0f, 0.0f); + float span_start = 0.0f; + float current_weight = 0.0f; + for (int i = 0; i < layout.Items.Size; i++) + { + ImGuiLayoutItem& item = layout.Items[i]; + if (item.Type != ImGuiLayoutItemType_Spring) + { + if (offset.x != 0.0f || offset.y != 0.0f) + { + TranslateLayoutItem(item, offset); + item.MeasuredBounds.Min += offset; + item.MeasuredBounds.Max += offset; + } + continue; + } + + float last_spring_size = item.SpringSize; + + if (free_space > 0.0f && total_spring_weight > 0.0f) + { + float next_weight = current_weight + item.SpringWeight; + float span_end = ImFloor((i == last_spring_item_index) ? free_space : (free_space * next_weight / total_spring_weight)); + float spring_size = span_end - span_start; + item.SpringSize = spring_size; + span_start = span_end; + current_weight = next_weight; + } + else + { + item.SpringSize = 0.0f; + } + + item.MeasuredBounds.Min += offset; + item.MeasuredBounds.Max += offset; + if (last_spring_size != item.SpringSize) + { + float difference = item.SpringSize - last_spring_size; + ImVec2 spring_offset = is_horizontal ? ImVec2(difference, 0.0f) : ImVec2(0.0f, difference); + item.MeasuredBounds.Max += spring_offset; + offset += spring_offset; + } + } +} + +static ImVec2 BalanceLayoutItemAlignment(ImGuiLayout& layout, ImGuiLayoutItem& item) +{ + // Fixup item alignment if necessary. + ImVec2 position_correction = ImVec2(0.0f, 0.0f); + if (item.CurrentAlign > 0.0f) + { + float item_align_offset = CalculateLayoutItemAlignmentOffset(layout, item); + if (item.CurrentAlignOffset != item_align_offset) + { + float offset = item_align_offset - item.CurrentAlignOffset; + + if (layout.Type == ImGuiLayoutType_Horizontal) + position_correction.y = offset; + else + position_correction.x = offset; + + TranslateLayoutItem(item, position_correction); + + item.CurrentAlignOffset = item_align_offset; + } + } + + return position_correction; +} + +static void BalanceLayoutItemsAlignment(ImGuiLayout& layout) +{ + for (int i = 0; i < layout.Items.Size; ++i) + { + ImGuiLayoutItem& item = layout.Items[i]; + BalanceLayoutItemAlignment(layout, item); + } +} + +static bool HasAnyNonZeroSpring(ImGuiLayout& layout) +{ + for (int i = 0; i < layout.Items.Size; ++i) + { + ImGuiLayoutItem& item = layout.Items[i]; + if (item.Type != ImGuiLayoutItemType_Spring) + continue; + if (item.SpringWeight > 0) + return true; + } + return false; +} + +static void BalanceChildLayouts(ImGuiLayout& layout) +{ + for (ImGuiLayout* child = layout.FirstChild; child != NULL; child = child->NextSibling) + { + //ImVec2 child_layout_size = child->CurrentSize; + + // Propagate layout size down to child layouts. + // + // TODO: Distribution assume inner layout is only + // element inside parent item and assigns + // all available space to it. + // + // Investigate how to split space between + // adjacent layouts. + // + // Investigate how to measure non-layout items + // to treat them as fixed size blocks. + // + if (child->Type == ImGuiLayoutType_Horizontal && child->Size.x <= 0.0f) + child->CurrentSize.x = layout.CurrentSize.x; + else if (child->Type == ImGuiLayoutType_Vertical && child->Size.y <= 0.0f) + child->CurrentSize.y = layout.CurrentSize.y; + + BalanceChildLayouts(*child); + + //child->CurrentSize = child_layout_size; + + if (HasAnyNonZeroSpring(*child)) + { + // Expand item measured bounds to make alignment correct. + ImGuiLayoutItem& item = layout.Items[child->ParentItemIndex]; + + if (child->Type == ImGuiLayoutType_Horizontal && child->Size.x <= 0.0f) + item.MeasuredBounds.Max.x = ImMax(item.MeasuredBounds.Max.x, item.MeasuredBounds.Min.x + layout.CurrentSize.x); + else if (child->Type == ImGuiLayoutType_Vertical && child->Size.y <= 0.0f) + item.MeasuredBounds.Max.y = ImMax(item.MeasuredBounds.Max.y, item.MeasuredBounds.Min.y + layout.CurrentSize.y); + } + } + + BalanceLayoutSprings(layout); + BalanceLayoutItemsAlignment(layout); +} + +// Only fixed-size axes clip, and only when the contents measured in the previous frame overflow them. +static void BeginLayoutClipRect(ImGuiLayout& layout, bool measured) +{ + const bool clip_x = layout.Size.x > 0.0f && (!measured || layout.MinimumSize.x > layout.Size.x); + const bool clip_y = layout.Size.y > 0.0f && (!measured || layout.MinimumSize.y > layout.Size.y); + layout.ClipRectPushed = clip_x || clip_y; + if (!layout.ClipRectPushed) + return; + + ImVec2 clip_rect_min(clip_x ? layout.StartPos.x : -FLT_MAX, clip_y ? layout.StartPos.y : -FLT_MAX); + ImVec2 clip_rect_max(clip_x ? layout.StartPos.x + layout.Size.x : FLT_MAX, clip_y ? layout.StartPos.y + layout.Size.y : FLT_MAX); + ImGui::PushClipRect(clip_rect_min, clip_rect_max, true); +} + +static void EndLayoutClipRect(ImGuiLayout& layout) +{ + if (layout.ClipRectPushed) + ImGui::PopClipRect(); +} + +// Until the root layout corrects them, items can land too far by up to the spring sizes of the tree in the previous +// frame. The clip rect is widened by that much toward the far side meanwhile, so that ItemAdd() and text rendering do +// not cull them. Not toward the near side: hover tests use it too, and items scrolled under the title bar would take +// its clicks. +static void BeginLayoutWideClipRect(ImGuiLayout& layout) +{ + layout.WideClipRectPushed = layout.SpringSizeInTree.x > 0.0f || layout.SpringSizeInTree.y > 0.0f; + if (!layout.WideClipRectPushed) + return; + + ImDrawList* draw_list = ImGui::GetWindowDrawList(); + const ImVec2 margin = layout.SpringSizeInTree; + layout.NarrowClipRect = draw_list->_CmdHeader.ClipRect; + ImGui::PushClipRect(ImVec2(layout.NarrowClipRect.x, layout.NarrowClipRect.y), ImVec2(layout.NarrowClipRect.z + margin.x, layout.NarrowClipRect.w + margin.y), false); + layout.WideClipRect = draw_list->_CmdHeader.ClipRect; + layout.WideClipRectCmdIndex = draw_list->CmdBuffer.Size - 1; +} + +// Commands drawn under the wide clip rect get the original one back, then merge where it made them split. +static void EndLayoutWideClipRect(ImGuiLayout& layout) +{ + if (!layout.WideClipRectPushed) + return; + ImGui::PopClipRect(); + + ImDrawList* draw_list = ImGui::GetWindowDrawList(); + const ImVec4 wide = layout.WideClipRect; + const ImVec4 narrow = layout.NarrowClipRect; + for (int n = layout.WideClipRectCmdIndex; n < draw_list->CmdBuffer.Size; n++) + { + // Clip rects pushed without intersecting (e.g. full screen ones) are not inside the wide one: they stay. + ImVec4& clip_rect = draw_list->CmdBuffer[n].ClipRect; + if (clip_rect.x < wide.x || clip_rect.y < wide.y || clip_rect.z > wide.z || clip_rect.w > wide.w) + continue; + clip_rect.x = ImClamp(clip_rect.x, narrow.x, narrow.z); + clip_rect.y = ImClamp(clip_rect.y, narrow.y, narrow.w); + clip_rect.z = ImClamp(clip_rect.z, clip_rect.x, narrow.z); + clip_rect.w = ImClamp(clip_rect.w, clip_rect.y, narrow.w); + } + + // Same header comparison as ImDrawList::_TryMergeDrawCmds(): clip rect, texture and vertex offset. + const size_t header_size = offsetof(ImDrawCmd, VtxOffset) + sizeof(unsigned int); + int dst = ImMax(layout.WideClipRectCmdIndex - 1, 0); + for (int src = dst + 1; src < draw_list->CmdBuffer.Size; src++) + { + ImDrawCmd& prev_cmd = draw_list->CmdBuffer[dst]; + ImDrawCmd& cmd = draw_list->CmdBuffer[src]; + if (memcmp(&prev_cmd, &cmd, header_size) == 0 && prev_cmd.IdxOffset + prev_cmd.ElemCount == cmd.IdxOffset && prev_cmd.UserCallback == NULL && cmd.UserCallback == NULL) + prev_cmd.ElemCount += cmd.ElemCount; + else + draw_list->CmdBuffer[++dst] = cmd; + } + draw_list->CmdBuffer.resize(dst + 1); +} + +static ImVec2 CalculateSpringSizeInTree(const ImGuiLayout& layout) +{ + ImVec2 size(0.0f, 0.0f); + const int axis = (layout.Type == ImGuiLayoutType_Horizontal) ? 0 : 1; + for (const ImGuiLayoutItem& item : layout.Items) + if (item.Type == ImGuiLayoutItemType_Spring) + size[axis] += item.SpringSize; + for (const ImGuiLayout* child = layout.FirstChild; child != NULL; child = child->NextSibling) + size += CalculateSpringSizeInTree(*child); + return size; +} + +static ImGuiLayoutItem* GenerateLayoutItem(ImGuiLayout& layout, ImGuiLayoutItemType type) +{ + IM_ASSERT(layout.CurrentItemIndex <= layout.Items.Size); + + if (layout.CurrentItemIndex < layout.Items.Size) + { + ImGuiLayoutItem& item = layout.Items[layout.CurrentItemIndex]; + if (item.Type != type) + item = ImGuiLayoutItem(type); + } + else + { + layout.Items.push_back(ImGuiLayoutItem(type)); + } + + return &layout.Items[layout.CurrentItemIndex]; +} + +// Calculate how many pixels from top/left layout edge item need to be moved to match +// layout alignment. +static float CalculateLayoutItemAlignmentOffset(ImGuiLayout& layout, ImGuiLayoutItem& item) +{ + if (item.CurrentAlign <= 0.0f) + return 0.0f; + + ImVec2 item_size = item.MeasuredBounds.GetSize(); + + float layout_extent = (layout.Type == ImGuiLayoutType_Horizontal) ? layout.CurrentSize.y : layout.CurrentSize.x; + float item_extent = (layout.Type == ImGuiLayoutType_Horizontal) ? item_size.y : item_size.x; + + if (item_extent <= 0/* || layout_extent <= item_extent*/) + return 0.0f; + + float align_offset = ImFloor(item.CurrentAlign * (layout_extent - item_extent)); + + return align_offset; +} + +static void TranslateLayoutItem(ImGuiLayoutItem& item, const ImVec2& offset) +{ + if ((offset.x == 0.0f && offset.y == 0.0f) || (item.VertexIndexBegin == item.VertexIndexEnd)) + return; + + //IMGUI_DEBUG_LOG("TranslateLayoutItem by %f,%f\n", offset.x, offset.y); + ImDrawList* draw_list = ImGui::GetWindowDrawList(); + + ImDrawVert* begin = draw_list->VtxBuffer.Data + item.VertexIndexBegin; + ImDrawVert* end = draw_list->VtxBuffer.Data + item.VertexIndexEnd; + + for (ImDrawVert* vtx = begin; vtx < end; ++vtx) + { + vtx->pos.x += offset.x; + vtx->pos.y += offset.y; + } +} + +static void SignedIndent(float indent) +{ + if (indent > 0.0f) + ImGui::Indent(indent); + else if (indent < 0.0f) + ImGui::Unindent(-indent); +} + +// EndLayoutItem() includes the last item rect only if an item was submitted after this. +static void MarkLayoutLastItem(ImGuiLayout& layout) +{ + ImGuiContext& g = *GImGui; + layout.ItemBeginLastItemId = g.LastItemData.ID; + layout.ItemBeginLastItemRect = g.LastItemData.Rect; +} + +static void BeginLayoutItem(ImGuiLayout& layout) +{ + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; + ImGuiLayoutItem& item = *GenerateLayoutItem(layout, ImGuiLayoutItemType_Item); + + item.CurrentAlign = layout.Align; + if (item.CurrentAlign < 0.0f) + item.CurrentAlign = ImClamp(g.Style.LayoutAlign, 0.0f, 1.0f); + + // Align item according to data from previous frame. + // If layout changes in current frame alignment will + // be corrected in EndLayout() to it visualy coherent. + item.CurrentAlignOffset = CalculateLayoutItemAlignmentOffset(layout, item); + if (layout.Type == ImGuiLayoutType_Horizontal) + { + window->DC.CursorPos.y = layout.StartPos.y + item.CurrentAlignOffset; + } + else if (item.CurrentAlign > 0.0f) + { + float new_position = window->DC.CursorPos.x + item.CurrentAlignOffset; + + // Make placement behave like in horizontal case when next + // widget is placed at very same Y position. This indent + // make sure for vertical layout placed widgets has same X position. + SignedIndent(item.CurrentAlignOffset); + + window->DC.CursorPos.x = new_position; + } + + // Each item starts its own line and is measured like a group, from what its contents extend CursorMaxPos to. + window->DC.CurrLineSize = ImVec2(0.0f, 0.0f); + window->DC.IsSameLine = false; + window->DC.CursorMaxPos = window->DC.CursorPos; + MarkLayoutLastItem(layout); + + item.MeasuredBounds.Min = item.MeasuredBounds.Max = window->DC.CursorPos; + item.VertexIndexBegin = item.VertexIndexEnd = window->DrawList->VtxBuffer.Size; +} + +static void EndLayoutItem(ImGuiLayout& layout) +{ + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; + IM_ASSERT(layout.CurrentItemIndex < layout.Items.Size); + + ImGuiLayoutItem& item = layout.Items[layout.CurrentItemIndex]; + + // Like EndGroup(), include the last item submitted inside, for e.g. EndTable() undershooting with CursorMaxPos. + item.MeasuredBounds.Max = ImMax(item.MeasuredBounds.Max, window->DC.CursorMaxPos); + if (g.LastItemData.ID != layout.ItemBeginLastItemId || memcmp(&g.LastItemData.Rect, &layout.ItemBeginLastItemRect, sizeof(ImRect)) != 0) + item.MeasuredBounds.Max = ImMax(item.MeasuredBounds.Max, g.LastItemData.Rect.Max); + + ImDrawList* draw_list = window->DrawList; + item.VertexIndexEnd = draw_list->VtxBuffer.Size; + + if (item.CurrentAlign > 0.0f && layout.Type == ImGuiLayoutType_Vertical) + SignedIndent(-item.CurrentAlignOffset); + + // Fixup item alignment in case item size changed in current frame. + ImVec2 position_correction = BalanceLayoutItemAlignment(layout, item); + + item.MeasuredBounds.Min += position_correction; + item.MeasuredBounds.Max += position_correction; + + if (layout.Type == ImGuiLayoutType_Horizontal) + window->DC.CursorPos.y = layout.StartPos.y; + else + window->DC.CursorPos.x = layout.StartPos.x; + + layout.CurrentItemIndex++; +} + +static void AddLayoutSpring(ImGuiLayout& layout, float weight, float spacing) +{ + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; + + EndLayoutItem(layout); + + // Undo item padding, spring should consume all space between items. + ImGuiLayoutItem* previous_item = &layout.Items[layout.CurrentItemIndex - 1]; + if (layout.Type == ImGuiLayoutType_Horizontal) + window->DC.CursorPos.x = previous_item->MeasuredBounds.Max.x; + else + window->DC.CursorPos.y = previous_item->MeasuredBounds.Max.y; + window->DC.IsSameLine = false; + + previous_item = NULL; // may be invalid after call to GenerateLayoutItem() + + ImGuiLayoutItem* spring_item = GenerateLayoutItem(layout, ImGuiLayoutItemType_Spring); + + spring_item->MeasuredBounds.Min = spring_item->MeasuredBounds.Max = window->DC.CursorPos; + + if (weight < 0.0f) + weight = 0.0f; + + if (spring_item->SpringWeight != weight) + spring_item->SpringWeight = weight; + + if (spacing < 0.0f) + { + ImVec2 style_spacing = g.Style.ItemSpacing; + if (layout.Type == ImGuiLayoutType_Horizontal) + spacing = style_spacing.x; + else + spacing = style_spacing.y; + } + + if (spring_item->SpringSpacing != spacing) + spring_item->SpringSpacing = spacing; + + // Submitted even when empty, so that GetItemRect*() and IsItem*() after Spring() refer to the spring. + ImVec2 spring_size, spring_spacing; + if (layout.Type == ImGuiLayoutType_Horizontal) + { + spring_spacing = ImVec2(0.0f, g.Style.ItemSpacing.y); + spring_size = ImVec2(spacing + spring_item->SpringSize, layout.CurrentSize.y); + } + else + { + spring_spacing = ImVec2(g.Style.ItemSpacing.x, 0.0f); + spring_size = ImVec2(layout.CurrentSize.x, spacing + spring_item->SpringSize); + } + + ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImFloor(spring_spacing)); + ImGui::Dummy(ImFloor(spring_size)); + ImGui::PopStyleVar(); + + spring_item->MeasuredBounds.Max = spring_item->MeasuredBounds.Min + ImFloor(spring_size); + + layout.CurrentItemIndex++; + + BeginLayoutItem(layout); +} + +static void DebugDrawLayout(const ImGuiLayout& layout) +{ + ImDrawList* draw_list = ImGui::GetWindowDrawList(); + const int axis = (layout.Type == ImGuiLayoutType_Horizontal) ? 0 : 1; + const ImRect layout_rect(layout.StartPos, layout.StartPos + layout.MeasuredSize); + for (const ImGuiLayoutItem& item : layout.Items) + { + if (item.Type == ImGuiLayoutItemType_Item) + { + if (layout.DebugFlags & ImGuiLayoutDebugFlags_DrawItems) + draw_list->AddRect(item.MeasuredBounds.Min, item.MeasuredBounds.Max, IM_COL32(255, 255, 0, 160)); + continue; + } + if ((layout.DebugFlags & ImGuiLayoutDebugFlags_DrawSprings) == 0) + continue; + + // Along the layout: the spring, then its spacing. Across it: the whole layout. + ImRect rect = item.MeasuredBounds; + rect.Min[axis ^ 1] = layout_rect.Min[axis ^ 1]; + rect.Max[axis ^ 1] = layout_rect.Max[axis ^ 1]; + const float length = rect.Max[axis] - rect.Min[axis]; + if (length <= 0.0f) + continue; + const float spacing = ImMin(ImFloor(item.SpringSpacing), length); + ImRect spring_rect = rect, spacing_rect = rect; + spring_rect.Max[axis] = spacing_rect.Min[axis] = rect.Max[axis] - spacing; + + draw_list->PushClipRect(rect.Min, rect.Max, true); + draw_list->AddRectFilled(spring_rect.Min, spring_rect.Max, IM_COL32(80, 20, 80, 255)); + draw_list->AddRectFilled(spacing_rect.Min, spacing_rect.Max, IM_COL32(80, 20, 20, 255)); + + // Zig-zag along the middle of the spring. + const float zig_zag_size = 3.0f; + ImVec2 direction(0.0f, 0.0f); + direction[axis] = 1.0f; + ImVec2 normal(-direction.y, direction.x); + ImVec2 origin = ImFloor(rect.GetCenter()); + origin[axis] = ImFloor(rect.Min[axis]); + origin += ImVec2(0.5f, 0.5f); + draw_list->PathLineTo(origin); + for (float x = zig_zag_size * 0.5f; x <= length - spacing; x += zig_zag_size) + { + draw_list->PathLineTo(origin + direction * x + normal * zig_zag_size); + normal = -normal; + } + draw_list->PathStroke(IM_COL32(255, 255, 255, 190), 1.0f); + draw_list->PopClipRect(); + } +} + + +//----------------------------------------------------------------------------- +// [SECTION] Stack Layout: Internal API +//----------------------------------------------------------------------------- + +void ErrorRecoveryTryToRecoverWindowState(const ImGuiErrorRecoveryState* state_in) +{ + // Called for every window, so it creates no state. + ImGuiContext& g = *GImGui; + ImGuiLayoutContextState* context_state = FindContextState(g); + ImGuiLayoutWindowState* state = context_state ? (ImGuiLayoutWindowState*)context_state->WindowStates.GetVoidPtr(g.CurrentWindow->ID) : NULL; + if (state == NULL) + return; + + // Layouts and suspensions each push onto the ID stack: those begun after state_in was stored are above its size. + while (state->LayoutStack.Size > 0) //-V1044 + { + if (state->CurrentLayout == NULL) + { + if (state->SuspendStack.back().IDStackSize < state_in->SizeOfIDStack) + break; + IM_ASSERT_USER_ERROR(0, "Missing ResumeLayout()"); + ImGui::ResumeLayout(); + } + else + { + if (state->CurrentLayout->IDStackSize < state_in->SizeOfIDStack) + break; + if (state->CurrentLayout->Type == ImGuiLayoutType_Horizontal) + { + IM_ASSERT_USER_ERROR(0, "Missing EndHorizontal()"); + ImGui::EndHorizontal(); + } + else + { + IM_ASSERT_USER_ERROR(0, "Missing EndVertical()"); + ImGui::EndVertical(); + } + } + } +} + + +} // namespace ImGuiStackLayout + +//----------------------------------------------------------------------------- +// [SECTION] Stack Layout: Public API +//----------------------------------------------------------------------------- + +void ImGui::BeginHorizontal(const char* str_id, const ImVec2& size/* = ImVec2(0, 0)*/, float align/* = -1*/) +{ + ImGuiWindow* window = GetCurrentWindow(); + ImGuiStackLayout::BeginLayout(window->GetID(str_id), ImGuiLayoutType_Horizontal, size, align); +} + +void ImGui::BeginHorizontal(const void* ptr_id, const ImVec2& size/* = ImVec2(0, 0)*/, float align/* = -1*/) +{ + ImGuiWindow* window = GetCurrentWindow(); + ImGuiStackLayout::BeginLayout(window->GetID(ptr_id), ImGuiLayoutType_Horizontal, size, align); +} + +void ImGui::BeginHorizontal(int id, const ImVec2& size/* = ImVec2(0, 0)*/, float align/* = -1*/) +{ + ImGuiWindow* window = GetCurrentWindow(); + ImGuiStackLayout::BeginLayout(window->GetID(id), ImGuiLayoutType_Horizontal, size, align); +} + +void ImGui::EndHorizontal() +{ + ImGuiStackLayout::ImGuiLayoutWindowState* window_state = ImGuiStackLayout::GetCurrentWindowLayoutState(); + IM_ASSERT_USER_ERROR_RET(window_state->CurrentLayout != NULL || window_state->LayoutStack.Size == 0, "Calling EndHorizontal() between SuspendLayout() and ResumeLayout()!"); + IM_ASSERT_USER_ERROR_RET(window_state->CurrentLayout != NULL, "Calling EndHorizontal() too many times!"); + IM_ASSERT_USER_ERROR(window_state->CurrentLayout->Type == ImGuiLayoutType_Horizontal, "Calling EndHorizontal() to end a vertical layout!"); + ImGuiStackLayout::EndLayout(window_state); +} + +void ImGui::BeginVertical(const char* str_id, const ImVec2& size/* = ImVec2(0, 0)*/, float align/* = -1*/) +{ + ImGuiWindow* window = GetCurrentWindow(); + ImGuiStackLayout::BeginLayout(window->GetID(str_id), ImGuiLayoutType_Vertical, size, align); +} + +void ImGui::BeginVertical(const void* ptr_id, const ImVec2& size/* = ImVec2(0, 0)*/, float align/* = -1*/) +{ + ImGuiWindow* window = GetCurrentWindow(); + ImGuiStackLayout::BeginLayout(window->GetID(ptr_id), ImGuiLayoutType_Vertical, size, align); +} + +void ImGui::BeginVertical(int id, const ImVec2& size/* = ImVec2(0, 0)*/, float align/* = -1*/) +{ + ImGuiWindow* window = GetCurrentWindow(); + ImGuiStackLayout::BeginLayout(window->GetID(id), ImGuiLayoutType_Vertical, size, align); +} + +void ImGui::EndVertical() +{ + ImGuiStackLayout::ImGuiLayoutWindowState* window_state = ImGuiStackLayout::GetCurrentWindowLayoutState(); + IM_ASSERT_USER_ERROR_RET(window_state->CurrentLayout != NULL || window_state->LayoutStack.Size == 0, "Calling EndVertical() between SuspendLayout() and ResumeLayout()!"); + IM_ASSERT_USER_ERROR_RET(window_state->CurrentLayout != NULL, "Calling EndVertical() too many times!"); + IM_ASSERT_USER_ERROR(window_state->CurrentLayout->Type == ImGuiLayoutType_Vertical, "Calling EndVertical() to end a horizontal layout!"); + ImGuiStackLayout::EndLayout(window_state); +} + +// Inserts spring separator in layout +// weight <= 0 : spring will always have zero size +// weight > 0 : power of current spring +// spacing < 0 : use default spacing if pos_x == 0, no spacing if pos_x != 0 +// spacing >= 0 : enforce spacing amount +void ImGui::Spring(float weight/* = 1.0f*/, float spacing/* = -1.0f*/) +{ + ImGuiStackLayout::ImGuiLayoutWindowState* window_state = ImGuiStackLayout::GetCurrentWindowLayoutState(); + IM_ASSERT_USER_ERROR_RET(window_state->CurrentLayout != NULL, "Calling Spring() outside of a layout, or between SuspendLayout() and ResumeLayout()!"); + + ImGuiStackLayout::AddLayoutSpring(*window_state->CurrentLayout, weight, spacing); +} + +void ImGui::SuspendLayout() +{ + ImGuiWindow* window = GetCurrentWindow(); + ImGuiStackLayout::ImGuiLayoutWindowState* window_state = ImGuiStackLayout::GetCurrentWindowLayoutState(); + + // Items in between flow as they would outside of the outermost layout, and are not measured by the layout. + // Pushing the current ID again leaves item IDs unchanged, and orders the suspension for error recovery. + ImGuiStackLayout::ImGuiLayoutSuspendBackup backup; + backup.LayoutType = window->DC.LayoutType; + backup.CursorMaxPos = window->DC.CursorMaxPos; + backup.IDStackSize = window->IDStack.Size; + window_state->SuspendStack.push_back(backup); + PushOverrideID(window->IDStack.back()); + for (ImGuiStackLayout::ImGuiLayout* layout : window_state->LayoutStack) + { + if (layout != NULL) + { + window->DC.LayoutType = layout->BackupLayoutType; + break; + } + } + + ImGuiStackLayout::PushLayout(NULL); +} + +void ImGui::ResumeLayout() +{ + ImGuiWindow* window = GetCurrentWindow(); + ImGuiStackLayout::ImGuiLayoutWindowState* window_state = ImGuiStackLayout::GetCurrentWindowLayoutState(); + IM_ASSERT_USER_ERROR_RET(window_state->SuspendStack.Size > 0, "Calling ResumeLayout() without SuspendLayout()!"); + IM_ASSERT_USER_ERROR_RET(window_state->CurrentLayout == NULL, "Missing EndHorizontal() or EndVertical() before ResumeLayout()!"); + ImGuiStackLayout::PopLayout(NULL); + + const ImGuiStackLayout::ImGuiLayoutSuspendBackup& backup = window_state->SuspendStack.back(); + IM_ASSERT_USER_ERROR(window->IDStack.Size == backup.IDStackSize + 1, "Mismatching PushID()/PopID() between SuspendLayout() and ResumeLayout()!"); + while (window->IDStack.Size > backup.IDStackSize) + PopID(); + window->DC.LayoutType = backup.LayoutType; + window->DC.CursorMaxPos = backup.CursorMaxPos; + window_state->SuspendStack.pop_back(); + if (window_state->CurrentLayout) + ImGuiStackLayout::MarkLayoutLastItem(*window_state->CurrentLayout); +} + +void ImGui::SetNextLayoutDebugFlags(ImGuiLayoutDebugFlags flags) +{ + ImGuiStackLayout::GetContextState(*GImGui)->NextDebugFlags = flags; +} + +//----------------------------------------------------------------------------- + +#endif // #ifndef IMGUI_DISABLE diff --git a/imgui_stacklayout.h b/imgui_stacklayout.h new file mode 100644 index 000000000..61f57e925 --- /dev/null +++ b/imgui_stacklayout.h @@ -0,0 +1,193 @@ +// dear imgui: stack layouts +// (stack layout headers) + +/* + +Index of this file: +// [SECTION] Stack Layout API + +*/ + +/* + +CHANGELOG +========= + +----------------------------------------------------------------------- + 2026/10/17 (Stack Layout v2.2, Dear ImGui 1.93.0) +----------------------------------------------------------------------- + +Breaking Changes: + +- Layout: sizes follow CalcItemSize(): negative values are relative to the far edge of the content + region (-FLT_MIN fills it). They used to mean automatic, like 0.0f. +- Layout: items flow with Dear ImGui's own layout type (window->DC.LayoutType), as in menu bars, + and layouts measure their items like groups. ItemSize() and ItemAdd() no longer call into + stack layouts. Inside horizontal layouts, Separator() draws a vertical separator, + MenuItem()/BeginMenu() render as in a menu bar, and NewLine() starts a new row. + +Other Changes: + +- Layout: fixed SameLine() inside horizontal layouts placing the next item over the previous + one. Widgets calling SameLine() (DragFloat3(), InputInt(), ColorEdit3(), ...) collapsed. +- Layout: fixed BeginVertical() after SameLine() moving its contents down by the height of the + previous line, where the layout clip rect hid them. +- Layout: fixed ImGuiListClipper inside BeginVertical() collapsing the scroll range of the + window: items are measured by how far they move the cursor, as in groups. +- Layout: fixed tables without scrolling inside horizontal layouts laying out their cells + horizontally. This needs the fix to BeginTable() submitted to Dear ImGui with this release. +- Layout: fixed a crash ending a layout begun while its parent was suspended, and on nested + SuspendLayout() calls. +- Clipping: layouts no longer split draw commands into channels or clamp them to their measured + size. Fixed the nav cursor, outlines and other decorations drawn around items at the edge of a + layout being cut, draw calls no longer batching across layouts, and content moved by the root + layout being clipped for one frame. Fixed-size axes still clip contents that overflow them. +- Nested layouts: fixed an automatic parent never shrinking when a nested layout with springs is + wrapped in BeginGroup()/EndGroup(). Inside such a group, the item rect of the nested layout + (GetItemRectMin()/GetItemRectMax() after EndHorizontal()/EndVertical()) is its own size rather + than the size it grows to in the parent. +- Layout: items outside of stack layouts no longer cost a lookup of the layout state. +- Context: layout state is kept per context and per window, instead of in a process-global map. + Fixed crashes and hooks piling up with one context per thread (thread-local GImGui), and + modules sharing a context (plugin DLLs, hot reload) each keeping their own layout state. +- Context: the module that submits the first layout of a context registers its hooks. Keep it + loaded as long as the context lives. +- Context: fixed layout state for IDs from changing data never being freed. Layouts unused for + io.ConfigMemoryCompactTimer are freed, as windows and tables are, and so are all layouts of a + window whose memory is compacted. +- Context: fixed an allocation outliving DestroyContext(). +- Error Handling: layouts left open at the end of the frame while error recovery is disabled are + reported and discarded at the next frame. +- Error Handling: fixed the same layout ID used twice in a frame hanging builds without asserts. + It is reported, and each further use gets a layout state of its own, as table instances do. +- Error Handling: fixed ErrorRecoveryTryToRecoverState() closing layouts begun before + ErrorRecoveryStoreState(). SuspendLayout() pushes the current ID again, which leaves item IDs + unchanged and orders suspensions for recovery. +- Error Handling: misuse is reported and recovered instead of asserting, then crashing: + Spring() outside of a layout, EndHorizontal()/EndVertical() without a layout, while suspended + or on the other type of layout, and ResumeLayout() without SuspendLayout(). +- Error Handling: unbalanced PushID()/PopID() inside a layout or a suspension is reported, and + the ID stack is restored when the layout ends or resumes. +- Springs: corrections made within the frame translate the vertices of each item once, instead of + once per spring that changed size. +- Springs: Spring() always submits an item, so GetItemRect*() and IsItem*() after it refer to the + spring. A spring with no size and no spacing used to leave the previous item there. +- Springs: fixed items after an item that appears missing parts (e.g. their text) for one frame: + placed with the previous frame's spring sizes, they were culled outside of the clip rect before + the root layout moved them into view. +- Debug: added SetNextLayoutDebugFlags() with ImGuiLayoutDebugFlags_DrawSprings and + ImGuiLayoutDebugFlags_DrawItems: the layout draws its springs or items where it placed them. +- Docs: the ID scope of layouts is documented with BeginHorizontal()/BeginVertical(), with how to + open a popup inside a layout and begin it outside. +- Examples: added imgui_stacklayout.cpp to the example projects (Visual Studio, Makefiles, + CMake, Xcode, QNX), which did not link without it. +- Misc: added imgui_stacklayout.cpp to misc/single_file/imgui_single_file.h, so single-file + (unity) builds link. +- CI: the test suite jobs add imgui_stacklayout.cpp to the project files of imgui_test_suite, + which do not list it. +- Demo: added style.LayoutAlign to the style editor. +- Demo: springs are drawn with ImGuiLayoutDebugFlags_DrawSprings. The demo drew them from + GetItemRect*() after Spring(), which held the previous item when a spring submitted none, and + sizes from the previous frame. +- Misc: added IMGUI_STACK_LAYOUT_VERSION and IMGUI_STACK_LAYOUT_VERSION_NUM. +- Misc: the headers of the stack layout files no longer quote a Dear ImGui version. +- Misc: imgui_stacklayout.cpp ignores the same Clang/GCC warnings as Dear ImGui's sources. Builds + with -Weverything or -Wsign-conversion reported old-style casts, float comparisons and sign + conversions in it. +- Internals: moved internal types and functions to namespace ImGuiStackLayout. They were in + the global and ImGui namespaces, where same-named user code or future Dear ImGui code clash. + +----------------------------------------------------------------------- + 2026/10/11 (Stack Layout v2.1, Dear ImGui 1.93.0 WIP) +----------------------------------------------------------------------- + +Breaking Changes: + +- IDs: BeginHorizontal()/BeginVertical() scope their contents like PushID() with the same + identifier, as BeginTable() and TreeNode() do. Contents were already scoped, by the layout ID + hashed a second time: IDs of items submitted inside stack layouts change, and settings saved + under them (e.g. tables in imgui.ini) reset once. + +Other Changes: + +- Nested layouts: fixed content submitted after a nested layout not being displayed, and + content drawn by the parent before a nested layout ending up over it. Each layout now + clips and merges its draw commands when it ends. (thedmd/imgui#10, ocornut/imgui#846) [@pthom] +- Nested layouts: fixed an enclosing BeginGroup()/EndGroup() growing but never shrinking: + an auto-sized nested layout grows to its parent's size only when it has springs. + (thedmd/imgui#9) [@pthom] +- Horizontal layouts: fixed vertical drift of items with a fractional height. + (thedmd/imgui#9, ocornut/imgui#9333) [@pthom] +- Style: fixed ImGuiStyleVar_LayoutAlign not matching its GStyleVarsInfo[] entry, which made + PushStyleVar() modify the wrong field, or assert, for it and for every style variable + declared after it. (thedmd/imgui#7) [@firesgc] +- Layout: fixed SameLine() in menu bars and custom combo previews moving the next item one row + down and over the previous one. Outside of stack layouts, ItemSize() behaves as upstream. +- Springs, alignment: fixed corrections made within the frame moving unrelated vertices in + windows with more than 64K vertices. +- Error Handling: fixed asserting on a layout left open at the end of the frame (e.g. in a + window missing End()) before error recovery could close it. +- Error Handling: fixed a crash recovering from SuspendLayout() without ResumeLayout(). +- Misc: fixed unused parameter/variable warnings. (thedmd/imgui#9) [@pthom] + + +ACKNOWLEDGMENTS +=============== + +Thanks to everyone who reported issues and contributed fixes: +- @pthom: nested layout, fractional height and warning fixes (thedmd/imgui#9, thedmd/imgui#10), + report of ocornut/imgui#9333. +- @firesgc: ImGuiStyleVar_LayoutAlign fix (thedmd/imgui#7). +- @wkster: report of content missing after a nested layout (ocornut/imgui#846). +- @gnif: missing intptr_t include fix (thedmd/imgui#4). + +*/ + +#pragma once + +#include "imgui.h" + +// Version of the stack layout code, independent of IMGUI_VERSION. X.Y is X * 10000 + Y * 100 in IMGUI_STACK_LAYOUT_VERSION_NUM. +#define IMGUI_STACK_LAYOUT_VERSION "2.2" +#define IMGUI_STACK_LAYOUT_VERSION_NUM 20200 + +#ifndef IMGUI_DISABLE + +//----------------------------------------------------------------------------- +// [SECTION] Stack Layout API +//----------------------------------------------------------------------------- + +typedef int ImGuiLayoutDebugFlags; // -> enum ImGuiLayoutDebugFlags_ // Flags: for SetNextLayoutDebugFlags() + +// Flags for SetNextLayoutDebugFlags() +enum ImGuiLayoutDebugFlags_ +{ + ImGuiLayoutDebugFlags_None = 0, + ImGuiLayoutDebugFlags_DrawSprings = 1 << 0, // Draw springs and their spacing. + ImGuiLayoutDebugFlags_DrawItems = 1 << 1, // Draw the bounds of the items between springs. +}; + +namespace ImGui +{ + // Stack layouts: items flow along the layout, and springs share the free space by weight. + // - size: 0.0f = automatic, > 0.0f = fixed, < 0.0f = relative to the far edge of the content region, as in CalcItemSize() (-FLT_MIN fills it). + // - align: position of items on the other axis, from 0.0f (left/top) to 1.0f (right/bottom). < 0.0f uses style.LayoutAlign. + // - IDs: contents are scoped like PushID() with the same identifier. To reach an ID across the scope, take it outside, + // e.g. ImGuiID popup_id = GetID("popup") before BeginHorizontal(), OpenPopup(popup_id) inside, BeginPopup("popup") after EndHorizontal(). + IMGUI_API void BeginHorizontal(const char* str_id, const ImVec2& size = ImVec2(0, 0), float align = -1.0f); + IMGUI_API void BeginHorizontal(const void* ptr_id, const ImVec2& size = ImVec2(0, 0), float align = -1.0f); + IMGUI_API void BeginHorizontal(int id, const ImVec2& size = ImVec2(0, 0), float align = -1); + IMGUI_API void EndHorizontal(); + IMGUI_API void BeginVertical(const char* str_id, const ImVec2& size = ImVec2(0, 0), float align = -1.0f); + IMGUI_API void BeginVertical(const void* ptr_id, const ImVec2& size = ImVec2(0, 0), float align = -1.0f); + IMGUI_API void BeginVertical(int id, const ImVec2& size = ImVec2(0, 0), float align = -1); + IMGUI_API void EndVertical(); + IMGUI_API void Spring(float weight = 1.0f, float spacing = -1.0f); + IMGUI_API void SuspendLayout(); + IMGUI_API void ResumeLayout(); + IMGUI_API void SetNextLayoutDebugFlags(ImGuiLayoutDebugFlags flags); // Draw the next layout and the layouts nested in it. Exact once the outermost layout ends, as their sizes settle there. + +} // namespace ImGui + + +#endif // #ifndef IMGUI_DISABLE diff --git a/imgui_stacklayout_internal.h b/imgui_stacklayout_internal.h new file mode 100644 index 000000000..03df9ae2f --- /dev/null +++ b/imgui_stacklayout_internal.h @@ -0,0 +1,28 @@ +// dear imgui: stack layouts +// (stack layout internal headers) + +/* + +Index of this file: +// [SECTION] Stack Layout Internal API + +*/ + +#pragma once + +#include "imgui_internal.h" +#include "imgui_stacklayout.h" + +#ifndef IMGUI_DISABLE + +//----------------------------------------------------------------------------- +// [SECTION] Stack Layout Internal API +//----------------------------------------------------------------------------- + +namespace ImGuiStackLayout +{ + IMGUI_API void ErrorRecoveryTryToRecoverWindowState(const ImGuiErrorRecoveryState* state_in); +} // namespace ImGuiStackLayout + + +#endif // #ifndef IMGUI_DISABLE diff --git a/misc/single_file/imgui_single_file.h b/misc/single_file/imgui_single_file.h index bea1cb6b6..5201b70e0 100644 --- a/misc/single_file/imgui_single_file.h +++ b/misc/single_file/imgui_single_file.h @@ -21,6 +21,7 @@ #include "../../imgui.cpp" #include "../../imgui_demo.cpp" #include "../../imgui_draw.cpp" +#include "../../imgui_stacklayout.cpp" #include "../../imgui_tables.cpp" #include "../../imgui_widgets.cpp" #ifdef IMGUI_ENABLE_FREETYPE