From 8b428e8c74c013bd84cf4284e69192c0e222a4c9 Mon Sep 17 00:00:00 2001 From: ocornut Date: Sat, 7 May 2016 19:54:27 +0200 Subject: [PATCH] Added CreateContext/DestroyContext/GetCurrentContext/SetCurrentContext() (#586, #269) --- imgui.cpp | 35 ++++++++++++++++++++++++----------- imgui.h | 10 ++++++---- imgui_draw.cpp | 4 ++-- imgui_internal.h | 13 ++++++------- 4 files changed, 38 insertions(+), 24 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index b982a71e4532..fe1fde54bf81 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -153,6 +153,7 @@ Here is a change-log of API breaking changes, if you are using one of the functions listed, expect to have to fix some code. Also read releases logs https://github.com/ocornut/imgui/releases for more details. + - 2016/05/07 (1.49) - removed confusing set of GetInternalState(), GetInternalStateSize(), SetInternalState() functions. Now using CreateContext(), DestroyContext(), GetCurrentContext(), SetCurrentContext(). - 2016/05/02 (1.49) - renamed SetNextTreeNodeOpened() to SetNextTreeNodeOpen(), no redirection. - 2016/05/01 (1.49) - obsoleted old signature of CollapsingHeader(const char* label, const char* str_id = NULL, bool display_frame = true, bool default_open = false) as extra parameters were badly designed and rarely used. You can replace the "default_open = true" flag in new API with CollapsingHeader(label, ImGuiTreeNodeFlags_DefaultOpen). - 2016/04/26 (1.49) - changed ImDrawList::PushClipRect(ImVec4 rect) to ImDraw::PushClipRect(Imvec2 min,ImVec2 max,bool intersect_with_current_clip_rect=false). Note that higher-level ImGui::PushClipRect() is preferable because it will clip at logic/widget level, whereas ImDrawList::PushClipRect() only affect your renderer. @@ -694,12 +695,12 @@ static void ImeSetInputScreenPosFn_DefaultImpl(int x, int y); //----------------------------------------------------------------------------- // We access everything through this pointer (always assumed to be != NULL) -// You can swap the pointer to a different context by calling ImGui::SetInternalState() -static ImGuiState GImDefaultState; -ImGuiState* GImGui = &GImDefaultState; +// You can swap the pointer to a different context by calling ImGui::SetCurrentContext() +static ImGuiState GImDefaultContext; +ImGuiState* GImGui = &GImDefaultContext; // Statically allocated default font atlas. This is merely a maneuver to keep ImFontAtlas definition at the bottom of the .h file (otherwise it'd be inside ImGuiIO) -// Also we wouldn't be able to new() one at this point, before users may define IO.MemAllocFn. +// Also we wouldn't be able to new() one at this point, before users have a chance to setup their allocator. static ImFontAtlas GImDefaultFontAtlas; //----------------------------------------------------------------------------- @@ -1888,21 +1889,33 @@ const char* ImGui::GetVersion() // Internal state access - if you want to share ImGui state between modules (e.g. DLL) or allocate it yourself // Note that we still point to some static data and members (such as GFontAtlas), so the state instance you end up using will point to the static data within its module -void* ImGui::GetInternalState() +ImGuiState* ImGui::GetCurrentContext() { return GImGui; } -size_t ImGui::GetInternalStateSize() +void ImGui::SetCurrentContext(ImGuiState* ctx) { - return sizeof(ImGuiState); + GImGui = ctx; } -void ImGui::SetInternalState(void* state, bool construct) +ImGuiState* ImGui::CreateContext(void* (*malloc_fn)(size_t), void (*free_fn)(void*)) { - if (construct) - IM_PLACEMENT_NEW(state) ImGuiState(); - GImGui = (ImGuiState*)state; + if (!malloc_fn) malloc_fn = malloc; + ImGuiState* ctx = (ImGuiState*)malloc_fn(sizeof(ImGuiState)); + IM_PLACEMENT_NEW(ctx) ImGuiState(); + ctx->IO.MemAllocFn = malloc_fn; + ctx->IO.MemFreeFn = free_fn ? free_fn : free; + return ctx; +} + +void ImGui::DestroyContext(ImGuiState* ctx) +{ + void (*free_fn)(void*) = ctx->IO.MemFreeFn; + ctx->~ImGuiState(); + free_fn(ctx); + if (GImGui == ctx) + GImGui = NULL; } ImGuiIO& ImGui::GetIO() diff --git a/imgui.h b/imgui.h index 2683308c1e42..d547980358df 100644 --- a/imgui.h +++ b/imgui.h @@ -54,6 +54,7 @@ struct ImGuiTextFilter; // Parse and apply text filters. In format " struct ImGuiTextBuffer; // Text buffer for logging/accumulating text struct ImGuiTextEditCallbackData; // Shared state of ImGui::InputText() when using custom callbacks (advanced) struct ImGuiListClipper; // Helper to manually clip large list of items +struct ImGuiState; // ImGui context (opaque) // Enumerations (declared as int for compatibility and to not pollute the top of this file) typedef unsigned int ImU32; @@ -442,11 +443,12 @@ namespace ImGui IMGUI_API const char* GetClipboardText(); IMGUI_API void SetClipboardText(const char* text); - // Internal state/context access - if you want to use multiple ImGui context, or share context between modules (e.g. DLL), or allocate the memory yourself + // Internal context access - if you want to use multiple context, share context between modules (e.g. DLL). There is a default context created and active by default. IMGUI_API const char* GetVersion(); - IMGUI_API void* GetInternalState(); - IMGUI_API size_t GetInternalStateSize(); - IMGUI_API void SetInternalState(void* state, bool construct = false); + IMGUI_API ImGuiState* CreateContext(void* (*malloc_fn)(size_t) = NULL, void (*free_fn)(void*) = NULL); + IMGUI_API void DestroyContext(ImGuiState* ctx); + IMGUI_API ImGuiState* GetCurrentContext(); + IMGUI_API void SetCurrentContext(ImGuiState* ctx); // Obsolete (will be removed) #ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS diff --git a/imgui_draw.cpp b/imgui_draw.cpp index 8bfdaa787c16..007e48eedbf7 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -245,7 +245,7 @@ void ImDrawList::PushClipRect(ImVec2 cr_min, ImVec2 cr_max, bool intersect_with_ void ImDrawList::PushClipRectFullScreen() { PushClipRect(ImVec2(GNullClipRect.x, GNullClipRect.y), ImVec2(GNullClipRect.z, GNullClipRect.w)); - //PushClipRect(GetVisibleRect()); // FIXME-OPT: This would be more correct but we're not supposed to access ImGuiState from here? + //PushClipRect(GetVisibleRect()); // FIXME-OPT: This would be more correct but we're not supposed to access ImGuiContext from here? } void ImDrawList::PopClipRect() @@ -1665,7 +1665,7 @@ ImFont::~ImFont() // If you want to delete fonts you need to do it between Render() and NewFrame(). // FIXME-CLEANUP /* - ImGuiState& g = *GImGui; + ImGuiContext& g = *GImGui; if (g.Font == this) g.Font = NULL; */ diff --git a/imgui_internal.h b/imgui_internal.h index 0b31fa324f0f..4eee4f7dd884 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -33,7 +33,6 @@ struct ImGuiTextEditState; struct ImGuiIniData; struct ImGuiMouseCursorData; struct ImGuiPopupRef; -struct ImGuiState; struct ImGuiWindow; typedef int ImGuiLayoutType; // enum ImGuiLayoutType_ @@ -71,7 +70,7 @@ namespace ImGuiStb // Context //----------------------------------------------------------------------------- -extern IMGUI_API ImGuiState* GImGui; +extern IMGUI_API ImGuiState* GImGui; // current implicit ImGui context pointer //----------------------------------------------------------------------------- // Helpers @@ -144,7 +143,7 @@ static inline ImVec2 ImFloor(ImVec2 v) struct ImPlacementNewDummy {}; inline void* operator new(size_t, ImPlacementNewDummy, void* ptr) { return ptr; } inline void operator delete(void*, ImPlacementNewDummy, void*) {} -#define IM_PLACEMENT_NEW(_PTR) new(ImPlacementNewDummy() ,_PTR) +#define IM_PLACEMENT_NEW(_PTR) new(ImPlacementNewDummy(), _PTR) #endif //----------------------------------------------------------------------------- @@ -274,7 +273,7 @@ struct ImGuiColumnData //float IndentX; }; -// Simple column measurement currently used for MenuItem() only. This is very short-sighted for now and NOT a generic helper. +// Simple column measurement currently used for MenuItem() only. This is very short-sighted/throw-away code and NOT a generic helper. struct IMGUI_API ImGuiSimpleColumns { int Count; @@ -283,9 +282,9 @@ struct IMGUI_API ImGuiSimpleColumns float Pos[8], NextWidths[8]; ImGuiSimpleColumns(); - void Update(int count, float spacing, bool clear); - float DeclColumns(float w0, float w1, float w2); - float CalcExtraSpace(float avail_w); + void Update(int count, float spacing, bool clear); + float DeclColumns(float w0, float w1, float w2); + float CalcExtraSpace(float avail_w); }; // Internal state of the currently focused/edited text input box