diff --git a/imgui.cpp b/imgui.cpp index ae6d48f16..f187231da 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -1417,7 +1417,7 @@ static void NavUpdateContextMenuRequest(); static void NavUpdateCreateMoveRequest(); static void NavUpdateCreateTabbingRequest(); static float NavUpdatePageUpPageDown(); -static inline void NavUpdateAnyRequestFlag(); +static void NavUpdateAnyRequestFlag(); static void NavUpdateCreateWrappingRequest(); static void NavEndFrame(); static bool NavScoreItem(ImGuiNavItemData* result, const ImRect& nav_bb); diff --git a/imgui.cppm b/imgui.cppm new file mode 100644 index 000000000..68398de6e --- /dev/null +++ b/imgui.cppm @@ -0,0 +1,154 @@ +// dear imgui +// (C++20 named module interface: 'import imgui;') + +// Usage: +// - Compile this file as the (primary) module interface unit of module 'imgui', e.g. with CMake (see misc/cxx_module/CMakeLists.txt): +// add_library(imgui) +// target_sources(imgui PUBLIC FILE_SET CXX_MODULES FILES imgui.cppm) +// set_target_properties(imgui PROPERTIES CXX_SCAN_FOR_MODULES ON CXX_MODULE_STD ON) +// Do NOT additionally compile imgui.cpp, imgui_demo.cpp, imgui_draw.cpp, imgui_tables.cpp, imgui_widgets.cpp: +// they are compiled as part of this unit (see the private module fragment at the bottom of this file). +// - Requires C++20 modules + the C++23 standard library modules ('import std.compat;', usable as an extension in C++20 by Clang/MSVC/GCC). +// - Then, in your code: +// import imgui; +// ImGui::CreateContext(); +// ImGui::NewFrame(); ... +// - Compile-time configuration (IMGUI_USER_CONFIG, imconfig.h, IMGUI_DISABLE_XXX, ImTextureID etc.) applies when compiling +// THIS file. Every consumer of the module sees the configuration the module was built with. + +// Design: +// - This follows the "ABI-breaking style" described in https://clang.llvm.org/docs/StandardCPlusPlusModules.html#abi-breaking-style +// (as opposed to an "export-using style" wrapper that would list 'export using ::ImGui::Xxx;' for every symbol): +// imgui.h is included in the module purview, so its declarations are attached to module 'imgui'. +// Symbols are mangled differently from a regular (non-module) build of Dear ImGui: don't link both into the same program. +// - IMGUI_CXX_MODULE is defined below, before anything else. It is used by imgui.h and the .cpp files to: +// - define IMGUI_EXPORT as 'export' and IMGUI_EXPORT_BEGIN/IMGUI_EXPORT_END as 'export {' / '}' (they expand to nothing in regular builds). +// Namespaces of imgui.h are prefixed by IMGUI_EXPORT; declarations of the global namespace are enclosed in IMGUI_EXPORT_BEGIN/END blocks. +// - skip including system/standard headers. The C library comes from 'import std.compat;'; the few headers still needed +// for their macros (and OS headers) are included here in the global module fragment, so they remain attached to the global module. +// - imgui_internal.h is NOT part of the exported interface: it is only included by the .cpp files in the private module fragment. +// Types that are opaque in imgui.h (e.g. ImGuiContext, ImDrawListSharedData) remain incomplete for importers. +// - Maths operators for ImVec2/ImVec4 (IMGUI_DEFINE_MATH_OPERATORS) are always enabled and exported, +// since the implementation requires them. (Being found by ADL, they couldn't be hidden from importers anyway.) +// - Macros are not exported by C++20 modules: IMGUI_VERSION, IMGUI_CHECKVERSION(), IM_ASSERT(), IM_COL32(), IM_COUNTOF() etc. +// are provided by imgui_macros.h, which importers may include (before or after 'import imgui;'). +// Some have exported constexpr alternatives, e.g. ImCol32(), ImCol32_White, ImCountOf(), ImGui::CheckVersion() (see imgui.h). + +// Limitations (for now): +// - The private module fragment requires this file to be the only unit of module 'imgui'. +// Backends are expected to be provided as separate modules that 'import imgui;'. +// - Not supported yet: IMGUI_ENABLE_FREETYPE, IMGUI_ENABLE_TEST_ENGINE, and linking stb_truetype/stb_rect_pack/stb_sprintf +// implementations from another translation unit (IMGUI_DISABLE_STB_XXX_IMPLEMENTATION, IMGUI_DISABLE_STB_SPRINTF_IMPLEMENTATION), +// since the corresponding declarations would be attached to module 'imgui' while their definitions are not. + +//----------------------------------------------------------------------------- +// [SECTION] Global module fragment +//----------------------------------------------------------------------------- + +module; + +#define IMGUI_CXX_MODULE 1 + +// Version, configuration file with compile-time options (imconfig.h) and macros +// (included here rather than from imgui.h, so any user declarations stay attached to the global module) +#include "imgui_macros.h" + +#if defined(IMGUI_ENABLE_FREETYPE) +#error "The 'imgui' C++20 module doesn't support IMGUI_ENABLE_FREETYPE yet." +#endif +#if defined(IMGUI_ENABLE_TEST_ENGINE) +#error "The 'imgui' C++20 module doesn't support IMGUI_ENABLE_TEST_ENGINE yet." +#endif + +#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_WARNINGS) +#define _CRT_SECURE_NO_WARNINGS +#endif + +// C library functions and types come from 'import std.compat;' below. Modules don't export macros, so we still need: +#include // FLT_MAX, FLT_MIN, DBL_MAX +#include // INT_MAX, INT_MIN, UINT_MAX +#include // va_start, va_end, va_copy +#include // offsetof +#include // stdout +#ifndef IMGUI_DISABLE_TIME_FUNCTIONS +#include // localtime_r (POSIX) +#endif + +// SSE intrinsics (same condition as in imgui_internal.h) +#if (defined __SSE__ || defined __x86_64__ || defined _M_X64 || (defined(_M_IX86_FP) && (_M_IX86_FP >= 1))) && !defined(IMGUI_DISABLE_SSE) && !defined(_M_ARM64) && !defined(_M_ARM64EC) +#include +#if (defined __AVX__ || defined __SSE4_2__) +#include +#endif +#endif + +// [Windows] OS specific includes (see imgui.cpp) +#if defined(_WIN32) && !defined(IMGUI_DISABLE_WIN32_FUNCTIONS) +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN +#endif +#ifndef NOMINMAX +#define NOMINMAX +#endif +#include +#ifndef IMGUI_DISABLE_DEFAULT_SHELL_FUNCTIONS +#include // ShellExecuteW() +#endif +#include // ImmGetContext() etc. +#endif + +// [Apple] OS specific includes (see imgui.cpp) +#if defined(__APPLE__) +#include +#if defined(TARGET_OS_OSX) && TARGET_OS_OSX && defined(IMGUI_ENABLE_OSX_DEFAULT_CLIPBOARD_FUNCTIONS) +#include +#endif +#endif + +// [POSIX] Default shell functions (see imgui.cpp) +#if !defined(_WIN32) && !defined(IMGUI_DISABLE_DEFAULT_SHELL_FUNCTIONS) && defined(__has_include) +#if __has_include() && __has_include() +#include +#include +#endif +#endif + +// [Emscripten] (see imgui_demo.cpp) +#ifdef __EMSCRIPTEN__ +#include +#endif + +//----------------------------------------------------------------------------- +// [SECTION] Module interface +//----------------------------------------------------------------------------- + +export module imgui; + +import std.compat; + +// Always enable maths operators: the implementation requires them, and imgui.h won't be included again by the .cpp files. +#ifndef IMGUI_DEFINE_MATH_OPERATORS +#define IMGUI_DEFINE_MATH_OPERATORS +#endif + +#include "imgui.h" + +// Internal functions used by backends (declared in imgui_internal.h) +#ifndef IMGUI_DISABLE +export namespace ImGui { IMGUI_API ImGuiIO& GetIO(ImGuiContext* ctx); } // imgui_impl_glfw.cpp +export IMGUI_API ImGuiID ImHashData(const void* data, size_t data_size, ImGuiID seed); // imgui_impl_wgpu.cpp +#endif + +//----------------------------------------------------------------------------- +// [SECTION] Private module fragment (implementation) +//----------------------------------------------------------------------------- +// Nothing below is reachable from importers: this includes imgui_internal.h and all file-local (static) helpers. +// (same order as misc/single_file/imgui_single_file.h) + +module :private; + +#include "imgui.cpp" +#include "imgui_demo.cpp" +#include "imgui_draw.cpp" +#include "imgui_tables.cpp" +#include "imgui_widgets.cpp" diff --git a/imgui.h b/imgui.h index 7f0b2915e..64af3a168 100644 --- a/imgui.h +++ b/imgui.h @@ -95,6 +95,8 @@ Index of this file: #pragma GCC diagnostic ignored "-Wclass-memaccess" // [__GNUC__ >= 8] warning: 'memset/memcpy' clearing/writing an object of type 'xxxx' with no trivial copy-assignment; use assignment or value-initialization instead #endif +IMGUI_EXPORT_BEGIN + //----------------------------------------------------------------------------- // [SECTION] Forward declarations and basic types //----------------------------------------------------------------------------- @@ -316,12 +318,14 @@ struct ImTextureRef }; IM_MSVC_RUNTIME_CHECKS_RESTORE +IMGUI_EXPORT_END + //----------------------------------------------------------------------------- // [SECTION] Dear ImGui end-user API functions // (Note that ImGui:: being a namespace, you can add extra ImGui:: functions in your own separate file. Please don't modify imgui source files!) //----------------------------------------------------------------------------- -namespace ImGui +IMGUI_EXPORT namespace ImGui { // Context creation and access // - Each context create its own ImFontAtlas by default. You may instance one yourself and pass it to CreateContext() to share a font atlas between contexts. @@ -1098,6 +1102,8 @@ namespace ImGui } // namespace ImGui +IMGUI_EXPORT_BEGIN + //----------------------------------------------------------------------------- // [SECTION] Flags & Enumerations //----------------------------------------------------------------------------- @@ -3868,6 +3874,8 @@ struct ImFont IMGUI_API bool IsGlyphRangeUnused(unsigned int c_begin, unsigned int c_last); }; +IMGUI_EXPORT_END + // This is provided for consistency (but we don't actually use this) inline ImTextureID ImTextureRef::GetTexID() const { @@ -3888,6 +3896,8 @@ inline ImTextureID ImDrawCmd::GetTexID() const return tex_id; } +IMGUI_EXPORT_BEGIN + //----------------------------------------------------------------------------- // [SECTION] Viewports //----------------------------------------------------------------------------- @@ -4013,12 +4023,15 @@ struct ImGuiPlatformImeData ImGuiPlatformImeData() { memset((void*)this, 0, sizeof(*this)); } }; +IMGUI_EXPORT_END + //----------------------------------------------------------------------------- // [SECTION] Constexpr alternatives to macros -// (requires C++17: see IMGUI_HAS_CONSTEXPR in imgui_macros.h) +// (requires C++17: see IMGUI_HAS_CONSTEXPR in imgui_macros.h. Exported by the C++20 module, which doesn't export macros) //----------------------------------------------------------------------------- #ifdef IMGUI_HAS_CONSTEXPR +IMGUI_EXPORT_BEGIN // Version (= IMGUI_VERSION, IMGUI_VERSION_NUM) inline constexpr char ImGuiVersion[] = IMGUI_VERSION; inline constexpr int ImGuiVersionNum = IMGUI_VERSION_NUM; @@ -4044,9 +4057,10 @@ inline constexpr ImU32 ImCol32_AMask = IM_COL32_A_MASK; // Size of a static C-style array (= IM_COUNTOF(), but won't compile with pointers) template constexpr int ImCountOf(const T (&arr)[N]) { return IM_COUNTOF(arr); } +IMGUI_EXPORT_END // Check that version and structures layouts are matching between compiled imgui code and caller (= IMGUI_CHECKVERSION()) -namespace ImGui +IMGUI_EXPORT namespace ImGui { inline bool CheckVersion() { return IMGUI_CHECKVERSION(); } } @@ -4059,7 +4073,7 @@ namespace ImGui //----------------------------------------------------------------------------- #ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS -namespace ImGui +IMGUI_EXPORT namespace ImGui { // OBSOLETED in 1.92.9 (from July 2026) IMGUI_API void SetColorEditOptions(ImGuiColorEditFlags flags); // set current options for if you want to select a default format, picker type, etc. User will be able to change those settings, unless you pass the _NoOptions flag to your calls. @@ -4154,12 +4168,14 @@ namespace ImGui //static inline void SetScrollPosHere() { SetScrollHere(); } // OBSOLETED in 1.42 } +IMGUI_EXPORT_BEGIN //-- OBSOLETED in 1.92.0: ImFontAtlasCustomRect becomes ImTextureRect // - ImFontAtlasCustomRect::X,Y --> ImTextureRect::x,y // - ImFontAtlasCustomRect::Width,Height --> ImTextureRect::w,h // - ImFontAtlasCustomRect::GlyphColored --> if you need to write to this, instead you can write to 'font->Glyphs.back()->Colored' after calling AddCustomRectFontGlyph() // We could make ImTextureRect an union to use old names, but 1) this would be confusing 2) the fix is easy 3) ImFontAtlasCustomRect was always a rather esoteric api. typedef ImFontAtlasRect ImFontAtlasCustomRect; +IMGUI_EXPORT_END /*struct ImFontAtlasCustomRect { unsigned short X, Y; // Output // Packed position in Atlas diff --git a/imgui_macros.h b/imgui_macros.h index e8189f0d9..cccf990b2 100644 --- a/imgui_macros.h +++ b/imgui_macros.h @@ -3,6 +3,10 @@ // Version, compile-time configuration and all preprocessor macros of the public API. // - This is included by imgui.h: you don't need to include it yourself when using imgui.h. +// - Macros are not exported by C++20 modules: when using 'import imgui;' (see imgui.cppm), include this file to access them: +// #include "imgui_macros.h" +// import imgui; +// Use the same compile-time configuration (IMGUI_USER_CONFIG, imconfig.h, defines) as the one the module was built with. #pragma once @@ -36,9 +40,24 @@ #define IMGUI_IMPL_API IMGUI_API #endif +// Export declarations from the C++20 named module 'imgui' (see imgui.cppm): +// - IMGUI_EXPORT namespace ImGui { ... } exports a namespace and everything in it. +// - Declarations of the global namespace are exported by enclosing them in IMGUI_EXPORT_BEGIN / IMGUI_EXPORT_END. +// (out-of-line definitions of member functions can't be exported: keep them outside of those blocks) +// IMGUI_CXX_MODULE is defined by imgui.cppm only: don't define it yourself. In regular (header) builds, those expand to nothing. +#ifdef IMGUI_CXX_MODULE +#define IMGUI_EXPORT export +#define IMGUI_EXPORT_BEGIN export { +#define IMGUI_EXPORT_END } +#else +#define IMGUI_EXPORT +#define IMGUI_EXPORT_BEGIN +#define IMGUI_EXPORT_END +#endif + // Constexpr alternatives to some of the macros below (e.g. ImCol32() for IM_COL32()) are declared in imgui.h ('Constexpr alternatives to macros' section) when compiling as C++17 or later. -// (C++17 is required for 'inline' variables) -#if (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) || __cplusplus >= 201703L +// (always the case for the C++20 module; C++17 is required for 'inline' variables) +#if defined(IMGUI_CXX_MODULE) || (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) || __cplusplus >= 201703L #define IMGUI_HAS_CONSTEXPR #endif