diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 5bbaefd1a..4e276e1de 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -601,6 +601,10 @@ jobs: run: xcodebuild -project examples/example_apple_opengl2/example_apple_opengl2.xcodeproj -target example_osx_opengl2 if: github.event_name == 'workflow_run' + - name: Build macOS example_apple_opengl3 + run: xcodebuild -project examples/example_apple_opengl3/example_apple_opengl3.xcodeproj -target example_osx_opengl3 + if: github.event_name == 'workflow_run' + Build-iOS: runs-on: macos-14 name: Build - iOS diff --git a/.gitignore b/.gitignore index 250e7eed5..009e61ede 100644 --- a/.gitignore +++ b/.gitignore @@ -67,6 +67,7 @@ cmake-build-* ## Unix executables from our example Makefiles examples/example_apple_metal/example_apple_metal examples/example_apple_opengl2/example_apple_opengl2 +examples/example_apple_opengl3/example_apple_opengl3 examples/example_glfw_metal/example_glfw_metal examples/example_glfw_opengl2/example_glfw_opengl2 examples/example_glfw_opengl3/example_glfw_opengl3 diff --git a/backends/imgui_impl_wgpu.cpp b/backends/imgui_impl_wgpu.cpp index e4e60d60e..543d65216 100644 --- a/backends/imgui_impl_wgpu.cpp +++ b/backends/imgui_impl_wgpu.cpp @@ -22,6 +22,7 @@ // CHANGELOG // (minor and older changes stripped away, please see git history for details) +// 2026-08-18: Fixed passing non-integer sizes to `wgpuRenderPassEncoderSetViewport() when FramebufferScale is >1.0f. (#9515, #8628) // 2026-04-23: Added support for standard draw callbacks (in platform_io): DrawCallback_ResetRenderState, DrawCallback_SetSamplerLinear, DrawCallback_SetSamplerNearest. (#9378) // 2026-03-25: Added support for WGVK native backend via IMGUI_IMPL_WEBGPU_BACKEND_WGVK define, with SPIRV shaders if WGSL is not available. (#9316, #9246, #9257) // 2026-03-09: Removed support for Emscripten < 4.0.10. (#9281) @@ -442,7 +443,9 @@ static void ImGui_ImplWGPU_SetupRenderState(ImDrawData* draw_data, WGPURenderPas } // Setup viewport - wgpuRenderPassEncoderSetViewport(ctx, 0, 0, draw_data->FramebufferScale.x * draw_data->DisplaySize.x, draw_data->FramebufferScale.y * draw_data->DisplaySize.y, 0, 1); + int fb_width = (int)(draw_data->DisplaySize.x * draw_data->FramebufferScale.x); + int fb_height = (int)(draw_data->DisplaySize.y * draw_data->FramebufferScale.y); + wgpuRenderPassEncoderSetViewport(ctx, 0, 0, fb_width, fb_height, 0, 1); // Bind shader and vertex buffers wgpuRenderPassEncoderSetVertexBuffer(ctx, 0, fr->VertexBuffer, 0, fr->VertexBufferSize * sizeof(ImDrawVert)); diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 650564d7f..61510001f 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -64,9 +64,12 @@ Other Changes: - QNX: added QNX Screen backend. (#9492) [@mgorchak-blackberry] - SDL2: fixed querying framebuffer scale/density when using Metal without going through a SDL_Renderer. (#5592) [@lailoken] + - WebGPU: fixed passing non-integer sizes to `wgpuRenderPassEncoderSetViewport()` + when when `FramebufferScale` is >1.0f. (#9515, #8628) [@WayU] - Examples: - SDL2+Metal: create Metal context without using a SDL_Renderer. - QNX+OpenGL3, QNX+Vulkan: added QNX Screen examples. (#9492) [@mgorchak-blackberry] + - OSX+OpenGL3: added example_apple_opengl3/ (OSX/Cocoa + OpenGL 3.2 Core profile). Docking+Viewports Branch: diff --git a/docs/EXAMPLES.md b/docs/EXAMPLES.md index 89e9bd0df..231fe7f93 100644 --- a/docs/EXAMPLES.md +++ b/docs/EXAMPLES.md @@ -70,8 +70,10 @@ OSX & iOS + Metal4 example, Mac only.
[example_apple_opengl2/](https://github.com/ocornut/imgui/blob/master/examples/example_apple_opengl2/)
OSX + OpenGL2 example.
= main.mm + imgui_impl_osx.mm + imgui_impl_opengl2.cpp
-(NB: imgui_impl_osx.mm is currently not as feature complete as other platforms backends. - You may prefer to use the GLFW Or SDL backends, which will also support Windows and Linux.) + +[example_apple_opengl3/](https://github.com/ocornut/imgui/blob/master/examples/example_apple_opengl3/)
+OSX + OpenGL3 example.
+= main.mm + imgui_impl_osx.mm + imgui_impl_opengl3.cpp
[example_glfw_wgpu/](https://github.com/ocornut/imgui/blob/master/examples/example_glfw_wgpu/)
GLFW + WebGPU example. Supports Emscripten (web), Dawn (native), WGPU (native).
diff --git a/docs/FAQ.md b/docs/FAQ.md index d67616725..5e3bd1e83 100644 --- a/docs/FAQ.md +++ b/docs/FAQ.md @@ -570,8 +570,8 @@ typedef ImU64 ImTextureID; // Default: store up to 64-bits (any pointer or inte // Store a ImTextureID _or_ a ImTextureData*. struct ImTextureRef { - ImTextureRef() { _TexData = NULL; _TexID = ImTextureID_Invalid; } - ImTextureRef(ImTextureID tex_id) { _TexData = NULL; _TexID = tex_id; } + ImTextureRef() { _TexData = nullptr; _TexID = ImTextureID_Invalid; } + ImTextureRef(ImTextureID tex_id) { _TexData = nullptr; _TexID = tex_id; } inline ImTextureID GetTexID() const { return _TexData ? _TexData->TexID : _TexID; } // Members (either are set, never both!) @@ -589,7 +589,7 @@ struct ImTextureRef We intentionally do not provide an `ImTextureRef` constructor for this: we don't expect this to be frequently useful to the end-user, and it would be erroneously called by many legacy code. - There is no constructor to create a `ImTextureRef` from a `ImTextureData*` as we don't expect this to be useful to the end-user, and it would be erroneously called by many legacy code. - If you want to bind the current atlas when using custom rectangles, you can use `io.Fonts->TexRef`. - - Binding generators for languages such as C (which don't have constructors), should provide a helper, e.g. `inline ImTextureRef ImTextureRefFromID(ImTextureID tex_id) { ImTextureRef tex_ref = { ._TexData = NULL, .TexID = tex_id }; return tex_ref; }` + - Binding generators for languages such as C (which don't have constructors), should provide a helper, e.g. `inline ImTextureRef ImTextureRefFromID(ImTextureID tex_id) { ImTextureRef tex_ref = { ._TexData = nullptr, .TexID = tex_id }; return tex_ref; }` **Please read documentations or tutorials on your graphics API to understand how to display textures on the screen before moving onward.** @@ -780,7 +780,7 @@ style.FontScaleDpi = 2.0f; To change font size: ```cpp -ImGui::PushFont(NULL, 42.0f); // This will be multiplied by style.FontScaleDpi +ImGui::PushFont(nullptr, 42.0f); // This will be multiplied by style.FontScaleDpi ``` To change font and font size: ```cpp diff --git a/docs/FONTS.md b/docs/FONTS.md index ac93bca0c..3f1e085fe 100644 --- a/docs/FONTS.md +++ b/docs/FONTS.md @@ -96,7 +96,7 @@ atlas->AddFont(...); v1.92 introduces a newer, dynamic font system. It requires backend to support the `ImGuiBackendFlags_HasTextures` feature: - Users of icons, Asian and non-English languages do not need to pre-build all glyphs ahead of time. Saving on loading time, memory, and also reducing issues with missing glyphs. Specifying glyph ranges is not needed anymore. -- `PushFont(NULL, new_size)` may be used anytime to change font size. +- `PushFont(nullptr, new_size)` may be used anytime to change font size. - Packing custom rectangles is more convenient as pixels may be written to immediately. - Any update to fonts previously required backend specific calls to re-upload the texture, and said calls were not portable across backends. It is now possible to scale fonts etc. in a way that doesn't require you to make backend-specific calls. - It is possible to plug a custom loader/backend to any font source. diff --git a/examples/example_apple_opengl2/main.mm b/examples/example_apple_opengl2/main.mm index 68dfe71f9..3cee24a46 100644 --- a/examples/example_apple_opengl2/main.mm +++ b/examples/example_apple_opengl2/main.mm @@ -6,8 +6,9 @@ // - Documentation https://dearimgui.com/docs (same as your local docs/ folder). // - Introduction, links and more at the top of imgui.cpp -// FIXME: Multi-viewports is not yet functional in this example. May need backend rework/coordination. +// FIXME: Multi-viewports is not yet functional in this example: backend and render code would set to set current context. +#define GL_SILENCE_DEPRECATION #import #import #import @@ -34,7 +35,7 @@ #ifndef DEBUG GLint swapInterval = 1; - [[self openGLContext] setValues:&swapInterval forParameter:NSOpenGLCPSwapInterval]; + [[self openGLContext] setValues:&swapInterval forParameter:NSOpenGLContextParameterSwapInterval]; if (swapInterval == 0) NSLog(@"Error: Cannot set swap interval."); #endif diff --git a/examples/example_apple_opengl3/Makefile b/examples/example_apple_opengl3/Makefile new file mode 100644 index 000000000..c9f9d44d3 --- /dev/null +++ b/examples/example_apple_opengl3/Makefile @@ -0,0 +1,21 @@ +# Makefile for example_apple_opengl3, for macOS only (**not iOS**) +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)/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 +FRAMEWORKS = -framework Cocoa -framework OpenGL -framework GameController + +all: $(EXE) + +$(EXE): $(SOURCES) + $(CXX) $(CXXFLAGS) $(SOURCES) -o $(EXE) $(FRAMEWORKS) + +run: all + ./$(EXE) + +clean: + rm -f $(EXE) *.o diff --git a/examples/example_apple_opengl3/example_apple_opengl3.xcodeproj/project.pbxproj b/examples/example_apple_opengl3/example_apple_opengl3.xcodeproj/project.pbxproj new file mode 100644 index 000000000..50ee35fd9 --- /dev/null +++ b/examples/example_apple_opengl3/example_apple_opengl3.xcodeproj/project.pbxproj @@ -0,0 +1,334 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 48; + objects = { + +/* Begin PBXBuildFile section */ + 05E31B59274EF0700083FCB6 /* GameController.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 05E31B57274EF0360083FCB6 /* GameController.framework */; }; + 07A82EDB213941D00078D120 /* imgui_widgets.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 07A82EDA213941D00078D120 /* imgui_widgets.cpp */; }; + 4080A99820B02D340036BA46 /* main.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4080A98A20B02CD90036BA46 /* main.mm */; }; + 4080A9A220B034280036BA46 /* imgui_impl_opengl3.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4080A99E20B034280036BA46 /* imgui_impl_opengl3.cpp */; }; + 4080A9AD20B0343C0036BA46 /* imgui_demo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4080A9A620B0343C0036BA46 /* imgui_demo.cpp */; }; + 4080A9AE20B0343C0036BA46 /* imgui.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4080A9A720B0343C0036BA46 /* imgui.cpp */; }; + 4080A9AF20B0343C0036BA46 /* imgui_draw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4080A9AA20B0343C0036BA46 /* imgui_draw.cpp */; }; + 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 */; }; + 50798230257677FD0038A28D /* imgui_tables.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5079822F257677FC0038A28D /* imgui_tables.cpp */; }; +/* End PBXBuildFile section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 4080A96920B029B00036BA46 /* CopyFiles */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = /usr/share/man/man1/; + dstSubfolderSpec = 0; + files = ( + ); + runOnlyForDeploymentPostprocessing = 1; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 05E31B57274EF0360083FCB6 /* GameController.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = GameController.framework; path = System/Library/Frameworks/GameController.framework; sourceTree = SDKROOT; }; + 07A82EDA213941D00078D120 /* imgui_widgets.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui_widgets.cpp; path = ../../imgui_widgets.cpp; sourceTree = ""; }; + 4080A96B20B029B00036BA46 /* example_osx_opengl3 */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = example_osx_opengl3; sourceTree = BUILT_PRODUCTS_DIR; }; + 4080A98A20B02CD90036BA46 /* main.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = main.mm; sourceTree = SOURCE_ROOT; }; + 4080A99E20B034280036BA46 /* imgui_impl_opengl3.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui_impl_opengl3.cpp; path = ../../backends/imgui_impl_opengl3.cpp; sourceTree = ""; }; + 4080A99F20B034280036BA46 /* imgui_impl_osx.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = imgui_impl_osx.mm; path = ../../backends/imgui_impl_osx.mm; sourceTree = ""; }; + 4080A9A020B034280036BA46 /* imgui_impl_opengl3.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = imgui_impl_opengl3.h; path = ../../backends/imgui_impl_opengl3.h; sourceTree = ""; }; + 4080A9A120B034280036BA46 /* imgui_impl_osx.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = imgui_impl_osx.h; path = ../../backends/imgui_impl_osx.h; sourceTree = ""; }; + 4080A9A320B034280036BA46 /* imgui_impl_opengl3_loader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = imgui_impl_opengl3_loader.h; path = ../../backends/imgui_impl_opengl3_loader.h; sourceTree = ""; }; + 4080A9A520B0343C0036BA46 /* imgui_internal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = imgui_internal.h; path = ../../imgui_internal.h; sourceTree = ""; }; + 4080A9A620B0343C0036BA46 /* imgui_demo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui_demo.cpp; path = ../../imgui_demo.cpp; sourceTree = ""; }; + 4080A9A720B0343C0036BA46 /* imgui.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui.cpp; path = ../../imgui.cpp; sourceTree = ""; }; + 4080A9A820B0343C0036BA46 /* imgui.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = imgui.h; path = ../../imgui.h; sourceTree = ""; }; + 4080A9AA20B0343C0036BA46 /* imgui_draw.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui_draw.cpp; path = ../../imgui_draw.cpp; sourceTree = ""; }; + 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; }; + 5079822F257677FC0038A28D /* imgui_tables.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui_tables.cpp; path = ../../imgui_tables.cpp; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 4080A96820B029B00036BA46 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 4080A9B520B034EA0036BA46 /* OpenGL.framework in Frameworks */, + 4080A9B320B034E40036BA46 /* Cocoa.framework in Frameworks */, + 05E31B59274EF0700083FCB6 /* GameController.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 4080A96220B029B00036BA46 = { + isa = PBXGroup; + children = ( + 5079822F257677FC0038A28D /* imgui_tables.cpp */, + 4080A9AC20B0343C0036BA46 /* imconfig.h */, + 4080A9A720B0343C0036BA46 /* imgui.cpp */, + 4080A9A820B0343C0036BA46 /* imgui.h */, + 07A82EDA213941D00078D120 /* imgui_widgets.cpp */, + 4080A9A620B0343C0036BA46 /* imgui_demo.cpp */, + 4080A9AA20B0343C0036BA46 /* imgui_draw.cpp */, + 4080A9A520B0343C0036BA46 /* imgui_internal.h */, + 4080A99E20B034280036BA46 /* imgui_impl_opengl3.cpp */, + 4080A9A020B034280036BA46 /* imgui_impl_opengl3.h */, + 4080A9A320B034280036BA46 /* imgui_impl_opengl3_loader.h */, + 4080A9A120B034280036BA46 /* imgui_impl_osx.h */, + 4080A99F20B034280036BA46 /* imgui_impl_osx.mm */, + 4080A98A20B02CD90036BA46 /* main.mm */, + 4080A96C20B029B00036BA46 /* Products */, + 4080A9B120B034E40036BA46 /* Frameworks */, + ); + sourceTree = ""; + }; + 4080A96C20B029B00036BA46 /* Products */ = { + isa = PBXGroup; + children = ( + 4080A96B20B029B00036BA46 /* example_osx_opengl3 */, + ); + name = Products; + sourceTree = ""; + }; + 4080A9B120B034E40036BA46 /* Frameworks */ = { + isa = PBXGroup; + children = ( + 05E31B57274EF0360083FCB6 /* GameController.framework */, + 4080A9B420B034EA0036BA46 /* OpenGL.framework */, + 4080A9B220B034E40036BA46 /* Cocoa.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 4080A96A20B029B00036BA46 /* example_osx_opengl3 */ = { + isa = PBXNativeTarget; + buildConfigurationList = 4080A97220B029B00036BA46 /* Build configuration list for PBXNativeTarget "example_osx_opengl3" */; + buildPhases = ( + 4080A96720B029B00036BA46 /* Sources */, + 4080A96820B029B00036BA46 /* Frameworks */, + 4080A96920B029B00036BA46 /* CopyFiles */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = example_osx_opengl3; + productName = example_osx_opengl3; + productReference = 4080A96B20B029B00036BA46 /* example_osx_opengl3 */; + productType = "com.apple.product-type.tool"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 4080A96320B029B00036BA46 /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 0930; + ORGANIZATIONNAME = ImGui; + TargetAttributes = { + 4080A96A20B029B00036BA46 = { + CreatedOnToolsVersion = 9.3.1; + ProvisioningStyle = Automatic; + }; + }; + }; + buildConfigurationList = 4080A96620B029B00036BA46 /* Build configuration list for PBXProject "example_apple_opengl3" */; + compatibilityVersion = "Xcode 8.0"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + ); + mainGroup = 4080A96220B029B00036BA46; + productRefGroup = 4080A96C20B029B00036BA46 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 4080A96A20B029B00036BA46 /* example_osx_opengl3 */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXSourcesBuildPhase section */ + 4080A96720B029B00036BA46 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 4080A99820B02D340036BA46 /* main.mm in Sources */, + 4080A9AD20B0343C0036BA46 /* imgui_demo.cpp in Sources */, + 4080A9AF20B0343C0036BA46 /* imgui_draw.cpp in Sources */, + 4080A9A220B034280036BA46 /* imgui_impl_opengl3.cpp in Sources */, + 4080A9B020B0347A0036BA46 /* imgui_impl_osx.mm in Sources */, + 4080A9AE20B0343C0036BA46 /* imgui.cpp in Sources */, + 50798230257677FD0038A28D /* imgui_tables.cpp in Sources */, + 07A82EDB213941D00078D120 /* imgui_widgets.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin XCBuildConfiguration section */ + 4080A97020B029B00036BA46 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "-"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.13; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = macosx; + }; + name = Debug; + }; + 4080A97120B029B00036BA46 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "-"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.13; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = macosx; + }; + name = Release; + }; + 4080A97320B029B00036BA46 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + MACOSX_DEPLOYMENT_TARGET = 10.13; + PRODUCT_NAME = "$(TARGET_NAME)"; + USER_HEADER_SEARCH_PATHS = ../..; + }; + name = Debug; + }; + 4080A97420B029B00036BA46 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + MACOSX_DEPLOYMENT_TARGET = 10.13; + PRODUCT_NAME = "$(TARGET_NAME)"; + USER_HEADER_SEARCH_PATHS = ../..; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 4080A96620B029B00036BA46 /* Build configuration list for PBXProject "example_apple_opengl3" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 4080A97020B029B00036BA46 /* Debug */, + 4080A97120B029B00036BA46 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 4080A97220B029B00036BA46 /* Build configuration list for PBXNativeTarget "example_osx_opengl3" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 4080A97320B029B00036BA46 /* Debug */, + 4080A97420B029B00036BA46 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 4080A96320B029B00036BA46 /* Project object */; +} diff --git a/examples/example_apple_opengl3/main.mm b/examples/example_apple_opengl3/main.mm new file mode 100644 index 000000000..339a93789 --- /dev/null +++ b/examples/example_apple_opengl3/main.mm @@ -0,0 +1,279 @@ +// Dear ImGui: standalone example application for OSX + OpenGL3 + +// Learn about Dear ImGui: +// - FAQ https://dearimgui.com/faq +// - Getting Started https://dearimgui.com/getting-started +// - Documentation https://dearimgui.com/docs (same as your local docs/ folder). +// - Introduction, links and more at the top of imgui.cpp + +// FIXME: Multi-viewports is not yet functional in this example: backend and render code would set to set current context. + +#define GL_SILENCE_DEPRECATION +#import +#import + +#include "imgui.h" +#include "imgui_impl_opengl3.h" +#include "imgui_impl_osx.h" + +//----------------------------------------------------------------------------------- +// AppView +//----------------------------------------------------------------------------------- + +@interface AppView : NSOpenGLView +{ + NSTimer* animationTimer; +} +@end + +@implementation AppView + +-(void)prepareOpenGL +{ + [super prepareOpenGL]; + +#ifndef DEBUG + GLint swapInterval = 1; + [[self openGLContext] setValues:&swapInterval forParameter:NSOpenGLContextParameterSwapInterval]; + if (swapInterval == 0) + NSLog(@"Error: Cannot set swap interval."); +#endif +} + +-(void)initialize +{ + // Setup Dear ImGui context + // FIXME: This example doesn't have proper cleanup... + IMGUI_CHECKVERSION(); + ImGui::CreateContext(); + ImGuiIO& io = ImGui::GetIO(); (void)io; + io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls + io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls + io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; // Enable Docking + io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable; // Enable Multi-Viewport / Platform Windows + + // Setup Dear ImGui style + ImGui::StyleColorsDark(); + //ImGui::StyleColorsLight(); + + // When viewports are enabled we tweak WindowRounding/WindowBg so platform windows can look identical to regular ones. + ImGuiStyle& style = ImGui::GetStyle(); + if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) + { + style.WindowRounding = 0.0f; + style.Colors[ImGuiCol_WindowBg].w = 1.0f; + } + + // Setup Platform/Renderer backends + [[self openGLContext] makeCurrentContext]; // ImGui_ImplOpenGL3_Init() requires a current GL context. + ImGui_ImplOSX_Init(self); + ImGui_ImplOpenGL3_Init(); + + // Load Fonts + // - If fonts are not explicitly loaded, Dear ImGui will select an embedded font: either AddFontDefaultVector() or AddFontDefaultBitmap(). + // This selection is based on (style.FontSizeBase * style.FontScaleMain * style.FontScaleDpi) reaching a small threshold. + // - You can load multiple fonts and use ImGui::PushFont()/PopFont() to select them. + // - If a file cannot be loaded, AddFont functions will return a nullptr. Please handle those errors in your code (e.g. use an assertion, display an error and quit). + // - Read 'docs/FONTS.md' for more instructions and details. + // - Use '#define IMGUI_ENABLE_FREETYPE' in your imconfig file to use FreeType for higher quality font rendering. + // - Remember that in C/C++ if you want to include a backslash \ in a string literal you need to write a double backslash \\ ! + //style.FontSizeBase = 20.0f; + //io.Fonts->AddFontDefaultVector(); + //io.Fonts->AddFontDefaultBitmap(); + //io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\segoeui.ttf"); + //io.Fonts->AddFontFromFileTTF("../../misc/fonts/DroidSans.ttf"); + //io.Fonts->AddFontFromFileTTF("../../misc/fonts/Roboto-Medium.ttf"); + //io.Fonts->AddFontFromFileTTF("../../misc/fonts/Cousine-Regular.ttf"); + //ImFont* font = io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf"); + //IM_ASSERT(font != nullptr); +} + +-(void)updateAndDrawDemoView +{ + // Start the Dear ImGui frame + ImGuiIO& io = ImGui::GetIO(); + ImGui_ImplOpenGL3_NewFrame(); + ImGui_ImplOSX_NewFrame(self); + ImGui::NewFrame(); + + // Our state (make them static = more or less global) as a convenience to keep the example terse. + static bool show_demo_window = true; + static bool show_another_window = false; + static ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f); + + // 1. Show the big demo window (Most of the sample code is in ImGui::ShowDemoWindow()! You can browse its code to learn more about Dear ImGui!). + if (show_demo_window) + ImGui::ShowDemoWindow(&show_demo_window); + + // 2. Show a simple window that we create ourselves. We use a Begin/End pair to create a named window. + { + static float f = 0.0f; + static int counter = 0; + + ImGui::Begin("Hello, world!"); // Create a window called "Hello, world!" and append into it. + + ImGui::Text("This is some useful text."); // Display some text (you can use a format strings too) + ImGui::Checkbox("Demo Window", &show_demo_window); // Edit bools storing our window open/close state + ImGui::Checkbox("Another Window", &show_another_window); + + ImGui::SliderFloat("float", &f, 0.0f, 1.0f); // Edit 1 float using a slider from 0.0f to 1.0f + ImGui::ColorEdit3("clear color", (float*)&clear_color); // Edit 3 floats representing a color + + if (ImGui::Button("Button")) // Buttons return true when clicked (most widgets return true when edited/activated) + counter++; + ImGui::SameLine(); + ImGui::Text("counter = %d", counter); + + ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / io.Framerate, io.Framerate); + ImGui::End(); + } + + // 3. Show another simple window. + if (show_another_window) + { + ImGui::Begin("Another Window", &show_another_window); // Pass a pointer to our bool variable (the window will have a closing button that will clear the bool when clicked) + ImGui::Text("Hello from another window!"); + if (ImGui::Button("Close Me")) + show_another_window = false; + ImGui::End(); + } + + // Rendering + ImGui::Render(); + ImDrawData* draw_data = ImGui::GetDrawData(); + + [[self openGLContext] makeCurrentContext]; + GLsizei width = (GLsizei)(draw_data->DisplaySize.x * draw_data->FramebufferScale.x); + GLsizei height = (GLsizei)(draw_data->DisplaySize.y * draw_data->FramebufferScale.y); + glViewport(0, 0, width, height); + glClearColor(clear_color.x * clear_color.w, clear_color.y * clear_color.w, clear_color.z * clear_color.w, clear_color.w); + glClear(GL_COLOR_BUFFER_BIT); + + ImGui_ImplOpenGL3_RenderDrawData(draw_data); + + // Update and Render additional Platform Windows + if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) + { + ImGui::UpdatePlatformWindows(); + ImGui::RenderPlatformWindowsDefault(); + } + + // Present + [[self openGLContext] flushBuffer]; + + if (!animationTimer) + animationTimer = [NSTimer scheduledTimerWithTimeInterval:0.017 target:self selector:@selector(animationTimerFired:) userInfo:nil repeats:YES]; +} + +-(void)reshape { [super reshape]; [[self openGLContext] update]; [self updateAndDrawDemoView]; } +-(void)drawRect:(NSRect)bounds { [self updateAndDrawDemoView]; } +-(void)animationTimerFired:(NSTimer*)timer { [self setNeedsDisplay:YES]; } +-(void)dealloc { animationTimer = nil; } + +@end + +//----------------------------------------------------------------------------------- +// AppDelegate +//----------------------------------------------------------------------------------- + +@interface AppDelegate : NSObject +@property (nonatomic, readonly) NSWindow* window; +@end + +@implementation AppDelegate +@synthesize window = _window; + +-(BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)theApplication +{ + return YES; +} + +-(NSWindow*)window +{ + if (_window != nil) + return _window; + + NSRect viewRect = NSMakeRect(100.0, 100.0, 100.0 + 1280.0, 100 + 800.0); + + _window = [[NSWindow alloc] initWithContentRect:viewRect styleMask:NSWindowStyleMaskTitled|NSWindowStyleMaskMiniaturizable|NSWindowStyleMaskResizable|NSWindowStyleMaskClosable backing:NSBackingStoreBuffered defer:YES]; + [_window setTitle:@"Dear ImGui OSX+OpenGL3 Example"]; + [_window setAcceptsMouseMovedEvents:YES]; + [_window setOpaque:YES]; + [_window makeKeyAndOrderFront:NSApp]; + + return _window; +} + +-(void)setupMenu +{ + NSMenu* mainMenuBar = [[NSMenu alloc] init]; + NSMenu* appMenu; + NSMenuItem* menuItem; + + appMenu = [[NSMenu alloc] initWithTitle:@"Dear ImGui OSX+OpenGL3 Example"]; + menuItem = [appMenu addItemWithTitle:@"Quit Dear ImGui OSX+OpenGL3 Example" action:@selector(terminate:) keyEquivalent:@"q"]; + [menuItem setKeyEquivalentModifierMask:NSEventModifierFlagCommand]; + + menuItem = [[NSMenuItem alloc] init]; + [menuItem setSubmenu:appMenu]; + + [mainMenuBar addItem:menuItem]; + + appMenu = nil; + [NSApp setMainMenu:mainMenuBar]; +} + +-(void)dealloc +{ + _window = nil; +} + +-(void)applicationDidFinishLaunching:(NSNotification *)aNotification +{ + // Make the application a foreground application (else it won't receive keyboard events) + ProcessSerialNumber psn = {0, kCurrentProcess}; + TransformProcessType(&psn, kProcessTransformToForegroundApplication); + + // Menu + [self setupMenu]; + + NSOpenGLPixelFormatAttribute attrs[] = + { + NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion3_2Core, + NSOpenGLPFADoubleBuffer, + NSOpenGLPFADepthSize, 32, + 0 + }; + + NSOpenGLPixelFormat* format = [[NSOpenGLPixelFormat alloc] initWithAttributes:attrs]; + AppView* view = [[AppView alloc] initWithFrame:self.window.frame pixelFormat:format]; + format = nil; +#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1070 + if (floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_6) + [view setWantsBestResolutionOpenGLSurface:YES]; +#endif // MAC_OS_X_VERSION_MAX_ALLOWED >= 1070 + [self.window setContentView:view]; + + if ([view openGLContext] == nil) + NSLog(@"No OpenGL Context!"); + + [view initialize]; +} + +@end + +//----------------------------------------------------------------------------------- +// Application main() function +//----------------------------------------------------------------------------------- + +int main(int argc, const char* argv[]) +{ + @autoreleasepool + { + NSApp = [NSApplication sharedApplication]; + AppDelegate* delegate = [[AppDelegate alloc] init]; + [[NSApplication sharedApplication] setDelegate:delegate]; + [NSApp run]; + } + return NSApplicationMain(argc, argv); +} diff --git a/examples/example_glfw_wgpu/main.cpp b/examples/example_glfw_wgpu/main.cpp index 9fea4af88..fcd37301a 100644 --- a/examples/example_glfw_wgpu/main.cpp +++ b/examples/example_glfw_wgpu/main.cpp @@ -549,7 +549,7 @@ WGPUSurface CreateWGPUSurface(const WGPUInstance& instance, GLFWwindow* window) { create_info.System = "win32"; create_info.RawWindow = (void*)glfwGetWin32Window(window); - create_info.RawInstance = (void*)::GetModuleHandle(NULL); + create_info.RawInstance = (void*)::GetModuleHandle(nullptr); return ImGui_ImplWGPU_CreateWGPUSurfaceHelper(&create_info); } #else diff --git a/examples/example_sdl3_wgpu/main.cpp b/examples/example_sdl3_wgpu/main.cpp index bc1787829..6b9a24e11 100644 --- a/examples/example_sdl3_wgpu/main.cpp +++ b/examples/example_sdl3_wgpu/main.cpp @@ -505,29 +505,29 @@ WGPUSurface CreateWGPUSurface(const WGPUInstance& instance, SDL_Window* window) #if defined(SDL_PLATFORM_MACOS) { create_info.System = "cocoa"; - create_info.RawWindow = (void*)SDL_GetPointerProperty(propertiesID, SDL_PROP_WINDOW_COCOA_WINDOW_POINTER, NULL); + create_info.RawWindow = (void*)SDL_GetPointerProperty(propertiesID, SDL_PROP_WINDOW_COCOA_WINDOW_POINTER, nullptr); return ImGui_ImplWGPU_CreateWGPUSurfaceHelper(&create_info); } #elif defined(SDL_PLATFORM_LINUX) if (SDL_strcmp(SDL_GetCurrentVideoDriver(), "wayland") == 0) { create_info.System = "wayland"; - create_info.RawDisplay = (void*)SDL_GetPointerProperty(propertiesID, SDL_PROP_WINDOW_WAYLAND_DISPLAY_POINTER, NULL); - create_info.RawSurface = (void*)SDL_GetPointerProperty(propertiesID, SDL_PROP_WINDOW_WAYLAND_SURFACE_POINTER, NULL); + create_info.RawDisplay = (void*)SDL_GetPointerProperty(propertiesID, SDL_PROP_WINDOW_WAYLAND_DISPLAY_POINTER, nullptr); + create_info.RawSurface = (void*)SDL_GetPointerProperty(propertiesID, SDL_PROP_WINDOW_WAYLAND_SURFACE_POINTER, nullptr); return ImGui_ImplWGPU_CreateWGPUSurfaceHelper(&create_info); } else if (!SDL_strcmp(SDL_GetCurrentVideoDriver(), "x11")) { create_info.System = "x11"; create_info.RawWindow = (void*)SDL_GetNumberProperty(propertiesID, SDL_PROP_WINDOW_X11_WINDOW_NUMBER, 0); - create_info.RawDisplay = (void*)SDL_GetPointerProperty(propertiesID, SDL_PROP_WINDOW_X11_DISPLAY_POINTER, NULL); + create_info.RawDisplay = (void*)SDL_GetPointerProperty(propertiesID, SDL_PROP_WINDOW_X11_DISPLAY_POINTER, nullptr); return ImGui_ImplWGPU_CreateWGPUSurfaceHelper(&create_info); } #elif defined(SDL_PLATFORM_WIN32) { create_info.System = "win32"; - create_info.RawWindow = (void*)SDL_GetPointerProperty(propertiesID, SDL_PROP_WINDOW_WIN32_HWND_POINTER, NULL); - create_info.RawInstance = (void*)::GetModuleHandle(NULL); + create_info.RawWindow = (void*)SDL_GetPointerProperty(propertiesID, SDL_PROP_WINDOW_WIN32_HWND_POINTER, nullptr); + create_info.RawInstance = (void*)::GetModuleHandle(nullptr); return ImGui_ImplWGPU_CreateWGPUSurfaceHelper(&create_info); } #else diff --git a/imgui.h b/imgui.h index add91e829..c35b4d74a 100644 --- a/imgui.h +++ b/imgui.h @@ -30,7 +30,7 @@ // Library Version // (Integer encoded as XYYZZ for use in #if preprocessor conditionals, e.g. '#if IMGUI_VERSION_NUM >= 12345') #define IMGUI_VERSION "1.93.0 WIP" -#define IMGUI_VERSION_NUM 19293 +#define IMGUI_VERSION_NUM 19294 #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_VIEWPORT // In 'docking' WIP branch. @@ -1136,7 +1136,7 @@ namespace ImGui // - Reminder ImGuiKey enum include access to mouse buttons and gamepad, so key ownership can apply to them. // - The return value of SetItemKeyOwner() says if ownership has been requested for the item, which is a shortcut to calling yet non-public TestKeyOwner() function. // - Many related features are still in imgui_internal.h. For instance, most IsKeyXXX()/IsMouseXXX() functions have an owner-id-aware version. - IMGUI_API bool SetItemKeyOwner(ImGuiKey key); // Set key owner to last item ID if it is hovered or active. Return true when ownership has been set. Roughly equivalent to 'if (TestKeyOwner(key, GetItemID()) && (IsItemHovered() || IsItemActive())) { SetKeyOwner(key, GetItemID());'. + IMGUI_API bool SetItemKeyOwner(ImGuiKey key); // Set key owner to last item ID if it is hovered or active. Return true when ownership has been set. Roughly equivalent to 'if (TestKeyOwner(key, GetItemID()) && (IsItemHovered() || IsItemActive())) { SetKeyOwner(key, GetItemID());'. // Inputs Utilities: Mouse // - To refer to a mouse button, you may use named enums in your code e.g. ImGuiMouseButton_Left, ImGuiMouseButton_Right. @@ -2442,7 +2442,7 @@ struct ImGuiStyle ImGuiTreeNodeFlags TreeLinesFlags; // Default way to draw lines connecting TreeNode hierarchy. ImGuiTreeNodeFlags_DrawLinesNone or ImGuiTreeNodeFlags_DrawLinesFull or ImGuiTreeNodeFlags_DrawLinesToNodes. float TreeLinesSize; // Thickness of outlines when using ImGuiTreeNodeFlags_DrawLines. float TreeLinesRounding; // Radius of lines connecting child nodes to the vertical line. - float MenuItemRounding; // Radius of MenuItem, BeginMenu rounding. + float MenuItemRounding; // Radius of MenuItem, BeginMenu rounding. float SelectableRounding; // Radius of Selectable rounding. MODIFYING THIS IS DISCOURAGED. CONTIGUOUS SELECTIONS WILL NOT LOOK RIGHT. (#7589) float DragDropTargetRounding; // Radius of the drag and drop target frame. When <0.0f: use FrameRounding. float DragDropTargetBorderSize; // Thickness of the drag and drop target border. @@ -3880,8 +3880,8 @@ struct ImFontAtlas IMGUI_API void CompactCache(); // Compact cached glyphs and texture. IMGUI_API void SetFontLoader(const ImFontLoader* font_loader); // Change font loader at runtime. - // Clearing the atlas/fonts has little use nowadays, unless you want to batch remove all fonts. - // - Since 1.92, you can call ClearFonts() mid-frame, if you load new fonts afterwards. + // Clearing the atlas/fonts has little use nowadays, unless you want to batch remove all fonts. + // - Since 1.92, you can call ClearFonts() mid-frame, if you load new fonts afterwards. // - As we are transitioning toward our new font system the semantic for those functions gets increasingly misleading and are often a source of issues. // TL;DR; most likely, don't use any of those functions. We expect to obsolete/rework them. IMGUI_API void Clear(); // Clear everything (fonts + textures). Don't call mid-frame! diff --git a/imgui_draw.cpp b/imgui_draw.cpp index 162f00193..d2c8e68b7 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -105,7 +105,7 @@ namespace IMGUI_STB_NAMESPACE #pragma warning (push) #pragma warning (disable: 4456) // declaration of 'xx' hides previous local declaration #pragma warning (disable: 6011) // (stb_rectpack) Dereferencing NULL pointer 'cur->next'. -#pragma warning (disable: 5262) // (stb_truetype) implicit fall-through occurs here; are you missing a break statement? +#pragma warning (disable: 5262) // (stb_truetype) implicit fall-through occurs here; are you missing a break statement? #pragma warning (disable: 6385) // (stb_truetype) Reading invalid data from 'buffer': the readable size is '_Old_3`kernel_width' bytes, but '3' bytes may be read. #pragma warning (disable: 28182) // (stb_rectpack) Dereferencing NULL pointer. 'cur' contains the same NULL value as 'cur->next' did. #endif diff --git a/imgui_internal.h b/imgui_internal.h index 39ef9be4e..c9625142d 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -295,7 +295,7 @@ extern IMGUI_API ImGuiContext* GImGui; // Current implicit context pointer #define IM_F32_TO_INT8_UNBOUND(_VAL) ((int)((_VAL) * 255.0f + ((_VAL)>=0 ? 0.5f : -0.5f))) // Unsaturated, for display purpose #define IM_F32_TO_INT8_SAT(_VAL) ((int)(ImSaturate(_VAL) * 255.0f + 0.5f)) // Saturated, always output 0..255 #define IM_TRUNC(_VAL) ((float)(int)(_VAL)) // Positive values only! ImTrunc() is not inlined in MSVC debug builds -#define IM_ROUND(_VAL) ((float)(int)((_VAL) + 0.5f)) // Positive values only! +#define IM_ROUND(_VAL) ((float)(int)((_VAL) + 0.5f)) // Positive values only! //#define IM_FLOOR IM_TRUNC // [OBSOLETE] Renamed in 1.90.0 (Sept 2023) // Hint for branch prediction @@ -3487,7 +3487,7 @@ struct ImGuiTableSettings }; namespace ImGui -{ +{ // Tables: Candidates for public API IMGUI_API void TableOpenContextMenu(int column_n = -1); IMGUI_API void TableSetColumnWidth(int column_n, float width); @@ -4038,8 +4038,8 @@ namespace ImGui // Widgets: Text IMGUI_API void TextEx(const char* text, const char* text_end = NULL, ImGuiTextFlags flags = 0); - IMGUI_API void TextAligned(float align_x, float size_x, const char* fmt, ...); // FIXME-WIP: Works but API is likely to be reworked. This is designed for 1 item on the line. (#7024) - IMGUI_API void TextAlignedV(float align_x, float size_x, const char* fmt, va_list args); + IMGUI_API void TextAligned(float align_x, float width, const char* fmt, ...) IM_FMTARGS(3); // FIXME-WIP: Works but API is likely to be reworked. + IMGUI_API void TextAlignedV(float align_x, float width, const char* fmt, va_list args) IM_FMTLIST(3); // Widgets IMGUI_API bool ButtonEx(const char* label, const ImVec2& size_arg = ImVec2(0, 0), ImGuiButtonFlags flags = 0); diff --git a/imgui_tables.cpp b/imgui_tables.cpp index 8f260c873..fb1b998d0 100644 --- a/imgui_tables.cpp +++ b/imgui_tables.cpp @@ -631,7 +631,7 @@ bool ImGui::BeginTableEx(const char* name, ImGuiID id, int columns_count, ImG // At this point the ->NameOffset field of each column will be invalid until TableUpdateLayout() or the first call to TableSetupColumn() if (table->ColumnsNames.Buf.Size > 0) table->ColumnsNames.Buf.resize(0); - + return true; } @@ -3974,6 +3974,8 @@ void ImGui::TableSaveSettings(ImGuiTable* table) if (column->IsUserEnabled != ((column->Flags & ImGuiTableColumnFlags_DefaultHide) == 0)) settings->SaveFlags |= ImGuiTableFlags_Hideable; } + if (table->Flags & ImGuiTableFlags_Sortable) + settings->SaveFlags |= ImGuiTableFlags_Sortable | ImGuiTableFlags_Reorderable; settings->SaveFlags &= table->Flags; settings->RefScale = save_ref_scale ? table->RefScale : 0.0f; diff --git a/imgui_widgets.cpp b/imgui_widgets.cpp index 17968a54d..665cfc512 100644 --- a/imgui_widgets.cpp +++ b/imgui_widgets.cpp @@ -342,18 +342,18 @@ void ImGui::TextWrappedV(const char* fmt, va_list args) PopTextWrapPos(); } -void ImGui::TextAligned(float align_x, float size_x, const char* fmt, ...) +void ImGui::TextAligned(float align_x, float width, const char* fmt, ...) { va_list args; va_start(args, fmt); - TextAlignedV(align_x, size_x, fmt, args); + TextAlignedV(align_x, width, fmt, args); va_end(args); } // align_x: 0.0f = left, 0.5f = center, 1.0f = right. -// size_x : 0.0f = shortcut for GetContentRegionAvail().x -// FIXME-WIP: Works but API is likely to be reworked. This is designed for 1 item on the line. (#7024) -void ImGui::TextAlignedV(float align_x, float size_x, const char* fmt, va_list args) +// width < 0.0f (e.g. -FLT_MIN): shortcut for GetContentRegionAvail().x +// FIXME-WIP: Works but API is likely to be reworked. This is designed for 1 item on the line. (#7024, #9455) +void ImGui::TextAlignedV(float align_x, float width, const char* fmt, va_list args) { ImGuiWindow* window = GetCurrentWindow(); if (window->SkipItems) @@ -362,23 +362,25 @@ void ImGui::TextAlignedV(float align_x, float size_x, const char* fmt, va_list a const char* text, *text_end; ImFormatStringToTempBufferV(&text, &text_end, fmt, args); const ImVec2 text_size = CalcTextSize(text, text_end); - size_x = CalcItemSize(ImVec2(size_x, 0.0f), 0.0f, text_size.y).x; + const ImVec2 size = CalcItemSize(ImVec2(width, 0.0f), 0.0f, text_size.y); ImVec2 pos(window->DC.CursorPos.x, window->DC.CursorPos.y + window->DC.CurrLineTextBaseOffset); - ImVec2 pos_max(pos.x + size_x, window->ClipRect.Max.y); - ImVec2 size(ImMin(size_x, text_size.x), text_size.y); + ImVec2 pos_max(pos.x + size.x, window->ClipRect.Max.y); + window->DC.CursorMaxPos.x = ImMax(window->DC.CursorMaxPos.x, pos.x + text_size.x); window->DC.IdealMaxPos.x = ImMax(window->DC.IdealMaxPos.x, pos.x + text_size.x); - if (align_x > 0.0f && text_size.x < size_x) - pos.x += ImTrunc((size_x - text_size.x) * align_x); - RenderTextEllipsis(window->DrawList, pos, pos_max, pos_max.x, text, text_end, &text_size); - const ImVec2 backup_max_pos = window->DC.CursorMaxPos; ItemSize(size); - ItemAdd(ImRect(pos, pos + size), 0); - window->DC.CursorMaxPos.x = backup_max_pos.x; // Cancel out extending content size because right-aligned text would otherwise mess it up. + const bool is_visible = ItemAdd(ImRect(pos, pos + size), 0); + window->DC.CursorMaxPos.x = backup_max_pos.x; // Cancel out extending content to 'size' to use 'text_size' allowing auto-resize to function with align_x > 0.0f + if (!is_visible) + return; - if (size_x < text_size.x && IsItemHovered(ImGuiHoveredFlags_NoNavOverride | ImGuiHoveredFlags_AllowWhenDisabled | ImGuiHoveredFlags_ForTooltip)) + if (align_x > 0.0f && text_size.x < size.x) + pos.x += ImTrunc((size.x - text_size.x) * align_x); + RenderTextEllipsis(window->DrawList, pos, pos_max, pos_max.x, text, text_end, &text_size); + + if (size.x < text_size.x && IsItemHovered(ImGuiHoveredFlags_NoNavOverride | ImGuiHoveredFlags_AllowWhenDisabled | ImGuiHoveredFlags_ForTooltip)) SetTooltip("%.*s", (int)(text_end - text), text); } @@ -3640,6 +3642,7 @@ const char* ImParseFormatTrimDecorations(const char* fmt, char* buf, size_t buf_ const char* fmt_end = ImParseFormatFindEnd(fmt_start); if (fmt_end[0] == 0) // If we only have leading decoration, we don't need to copy the data. return fmt_start; + buf[0] = 0; // Fix false positive with caller assuming that buf could be non-initialized (#9508) ImStrncpy(buf, fmt_start, ImMin((size_t)(fmt_end - fmt_start) + 1, buf_size)); return buf; } diff --git a/misc/freetype/imgui_freetype.cpp b/misc/freetype/imgui_freetype.cpp index 3c817d20f..79dff8bfb 100644 --- a/misc/freetype/imgui_freetype.cpp +++ b/misc/freetype/imgui_freetype.cpp @@ -508,9 +508,9 @@ static bool ImGui_ImplFreeType_FontBakedLoadGlyph(ImFontAtlas* atlas, ImFontConf // Load metrics only mode const float advance_x = (slot->advance.x / FT_SCALEFACTOR) / rasterizer_density; - if (out_advance_x != NULL) + if (out_advance_x != nullptr) { - IM_ASSERT(out_glyph == NULL); + IM_ASSERT(out_glyph == nullptr); *out_advance_x = advance_x; return true; }