Browse Source

Added CreateContext/DestroyContext/GetCurrentContext/SetCurrentContext() (#586, #269)

ocornut 9 years ago
parent
commit
8b428e8c74
4 changed files with 38 additions and 24 deletions
  1. 24 11
      imgui.cpp
  2. 6 4
      imgui.h
  3. 2 2
      imgui_draw.cpp
  4. 6 7
      imgui_internal.h

+ 24 - 11
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()

+ 6 - 4
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

+ 2 - 2
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;
     */

+ 6 - 7
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