diff --git a/CHANGELOG.txt b/CHANGELOG.txt
index ac672e74..999a4066 100644
--- a/CHANGELOG.txt
+++ b/CHANGELOG.txt
@@ -136,6 +136,7 @@ Other Changes:
- ImFontAtlas: Added ImFontAtlasFlags_NoPowerOfTwoHeight flag to disable padding font height to nearest power of two. (#1613)
- ImFontAtlas: Added ImFontAtlasFlags_NoMouseCursors flag to disable baking software mouse cursors, mostly to save texture memory on very low end hardware. (#1613)
- ImDrawList: Fixed AddRect() with antialiasing disabled (lower-right corner pixel was often missing, rounding looks a little better.) (#1646)
+- ImDrawList: Added CloneOutput() helper to facilitate the cloning of ImDrawData or ImDrawList for multi-threaded rendering.
- Misc: Functions passed to libc qsort are explicitely marked cdecl to support compiling with vectorcall as the default calling convention. (#1230, #1611) [@RandyGaul]
- Misc: ImVec2: added [] operator. This is becoming desirable for some types of code, better added sooner than later.
- Misc: Exposed IM_OFFSETOF() helper in imgui.h.
diff --git a/README.md b/README.md
index 5773278a..080ae31d 100644
--- a/README.md
+++ b/README.md
@@ -11,7 +11,7 @@ Monthly donations via Patreon:
One-off donations via PayPal:
[![PayPal](https://www.paypalobjects.com/en_US/i/btn/btn_donate_LG.gif)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=5Q73FPZ9C526U)
-Dear ImGui is a bloat-free graphical user interface library for C++. It outputs optimized vertex buffers that you can render anytime in your 3D-pipeline enabled application. It is fast, portable, renderer agnostic and self-contained (no external dependencies).**
+Dear ImGui is a bloat-free graphical user interface library for C++. It outputs optimized vertex buffers that you can render anytime in your 3D-pipeline enabled application. It is fast, portable, renderer agnostic and self-contained (no external dependencies).
Dear ImGui is designed to enable fast iterations and to empower programmers to create content creation tools and visualization / debug tools (as opposed to UI for the average end-user). It favors simplicity and productivity toward this goal, and lacks certain features normally found in more high-level libraries.
diff --git a/TODO.txt b/TODO.txt
index 6da01e73..9276e67e 100644
--- a/TODO.txt
+++ b/TODO.txt
@@ -137,8 +137,10 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i
- drag float: added leeway on edge (e.g. a few invisible steps past the clamp limits)
- combo: use clipper: make it easier to disable clipper with a single flag.
- - combo: option for BeginCombo to not return true when unchanged (#1182)
+ - combo: flag for BeginCombo to not return true when unchanged (#1182)
+ - combo: a way/helper to customize the combo preview (#1658)
- combo/listbox: keyboard control. need InputText-like non-active focus + key handling. considering keyboard for custom listbox (pr #203)
+ - listbox: refactor and clean the begin/end api
- listbox: multiple selection.
- listbox: unselect option (#1208)
- listbox: make it easier/more natural to implement range-select (need some sort of info/ref about the last clicked/focused item that user can translate to an index?) (wip stash)
@@ -207,6 +209,7 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i
- filters: fuzzy matches (may use code at blog.forrestthewoods.com/4cffeed33fdb)
- drag and drop: add demo. (#143, #479)
+ - drag and drop: allow using with other mouse buttons (where activeid won't be set). (#1637)
- drag and drop: test with reordering nodes (in a list, or a tree node). (#143)
- drag and drop: test integrating with os drag and drop.
- node/graph editor (#306)
@@ -258,6 +261,8 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i
- misc: make the ImGuiCond values linear (non-power-of-two). internal storage for ImGuiWindow can use integers to combine into flags (Why?)
- misc: provide a way to compile out the entire implementation while providing a dummy API (e.g. #define IMGUI_DUMMY_IMPL)
- misc: fix for compilation settings where stdcall isn't the default (e.g. vectorcall) (#1230)
+ - misc: PushItemFlag(): add a flag to disable keyboard capture when used with mouse? (#1682)
+
- remote: make a system like RemoteImGui first-class citizen/project (#75)
- demo: add vertical separator demo
diff --git a/imgui.h b/imgui.h
index 65a66ff7..d8125f08 100644
--- a/imgui.h
+++ b/imgui.h
@@ -1176,7 +1176,7 @@ namespace ImGui
//-----------------------------------------------------------------------------
// Lightweight std::vector<> like class to avoid dragging dependencies (also: Windows implementation of STL with debug enabled is absurdly slow, so let's bypass it so our code runs fast in debug).
-// Our implementation does NOT call C++ constructors/destructors. This is intentional and we do not require it. Do not use this class as a straight std::vector replacement in your code!
+// *Important* Our implementation does NOT call C++ constructors/destructors. This is intentional, we do not require it but you have to be mindful of that. Do not use this class as a straight std::vector replacement in your code!
template
class ImVector
{
@@ -1191,6 +1191,8 @@ public:
inline ImVector() { Size = Capacity = 0; Data = NULL; }
inline ~ImVector() { if (Data) ImGui::MemFree(Data); }
+ inline ImVector(const ImVector& src) { Size = Capacity = 0; Data = NULL; operator=(src); }
+ inline ImVector& operator=(const ImVector& src) { clear(); resize(src.Size); memcpy(Data, src.Data, (size_t)Size * sizeof(value_type)); return *this; }
inline bool empty() const { return Size == 0; }
inline int size() const { return Size; }
@@ -1207,25 +1209,25 @@ public:
inline const value_type& front() const { IM_ASSERT(Size > 0); return Data[0]; }
inline value_type& back() { IM_ASSERT(Size > 0); return Data[Size - 1]; }
inline const value_type& back() const { IM_ASSERT(Size > 0); return Data[Size - 1]; }
- inline void swap(ImVector& rhs) { int rhs_size = rhs.Size; rhs.Size = Size; Size = rhs_size; int rhs_cap = rhs.Capacity; rhs.Capacity = Capacity; Capacity = rhs_cap; value_type* rhs_data = rhs.Data; rhs.Data = Data; Data = rhs_data; }
+ inline void swap(ImVector& rhs) { int rhs_size = rhs.Size; rhs.Size = Size; Size = rhs_size; int rhs_cap = rhs.Capacity; rhs.Capacity = Capacity; Capacity = rhs_cap; value_type* rhs_data = rhs.Data; rhs.Data = Data; Data = rhs_data; }
inline int _grow_capacity(int sz) const { int new_capacity = Capacity ? (Capacity + Capacity/2) : 8; return new_capacity > sz ? new_capacity : sz; }
inline void resize(int new_size) { if (new_size > Capacity) reserve(_grow_capacity(new_size)); Size = new_size; }
- inline void resize(int new_size, const T& v) { if (new_size > Capacity) reserve(_grow_capacity(new_size)); if (new_size > Size) for (int n = Size; n < new_size; n++) Data[n] = v; Size = new_size; }
+ inline void resize(int new_size,const value_type& v){ if (new_size > Capacity) reserve(_grow_capacity(new_size)); if (new_size > Size) for (int n = Size; n < new_size; n++) memcpy(&Data[n], &v, sizeof(v)); Size = new_size; }
inline void reserve(int new_capacity)
{
if (new_capacity <= Capacity)
return;
- T* new_data = (value_type*)ImGui::MemAlloc((size_t)new_capacity * sizeof(T));
+ value_type* new_data = (value_type*)ImGui::MemAlloc((size_t)new_capacity * sizeof(value_type));
if (Data)
- memcpy(new_data, Data, (size_t)Size * sizeof(T));
+ memcpy(new_data, Data, (size_t)Size * sizeof(value_type));
ImGui::MemFree(Data);
Data = new_data;
Capacity = new_capacity;
}
// NB: &v cannot be pointing inside the ImVector Data itself! e.g. v.push_back(v[10]) is forbidden.
- inline void push_back(const value_type& v) { if (Size == Capacity) reserve(_grow_capacity(Size + 1)); Data[Size++] = v; }
+ inline void push_back(const value_type& v) { if (Size == Capacity) reserve(_grow_capacity(Size + 1)); memcpy(&Data[Size], &v, sizeof(v)); Size++; }
inline void pop_back() { IM_ASSERT(Size > 0); Size--; }
inline void push_front(const value_type& v) { if (Size == 0) push_back(v); else insert(Data, v); }
inline iterator erase(const_iterator it) { IM_ASSERT(it >= Data && it < Data+Size); const ptrdiff_t off = it - Data; memmove(Data + off, Data + off + 1, ((size_t)Size - (size_t)off - 1) * sizeof(value_type)); Size--; return Data + off; }
@@ -1635,6 +1637,7 @@ struct ImDrawList
// Advanced
IMGUI_API void AddCallback(ImDrawCallback callback, void* callback_data); // Your rendering function must check for 'UserCallback' in ImDrawCmd and call the function instead of rendering triangles.
IMGUI_API void AddDrawCmd(); // This is useful if you need to forcefully create a new draw call (to allow for dependent rendering / blending). Otherwise primitives are merged into the same draw-call as much as possible
+ IMGUI_API ImDrawList* CloneOutput() const; // Create a clone of the CmdBuffer/IdxBuffer/VtxBuffer.
// Internal helpers
// NB: all primitives needs to be reserved via PrimReserve() beforehand!
@@ -1652,21 +1655,23 @@ struct ImDrawList
};
// All draw data to render an ImGui frame
+// (NB: the style and the naming convention here is a little inconsistent but we preserve them for backward compatibility purpose)
struct ImDrawData
{
bool Valid; // Only valid after Render() is called and before the next NewFrame() is called.
- ImDrawList** CmdLists;
- int CmdListsCount;
- int TotalVtxCount; // For convenience, sum of all cmd_lists vtx_buffer.Size
- int TotalIdxCount; // For convenience, sum of all cmd_lists idx_buffer.Size
+ ImDrawList** CmdLists; // Array of ImDrawList* to render. The ImDrawList are owned by ImGuiContext and only pointed to from here.
+ int CmdListsCount; // Number of ImDrawList* to render
+ int TotalIdxCount; // For convenience, sum of all ImDrawList's IdxBuffer.Size
+ int TotalVtxCount; // For convenience, sum of all ImDrawList's VtxBuffer.Size
ImVec2 DisplayPos; // Virtual upper-left position of the viewport to render (== ImVec2(0,0) for the main viewport == upper-left of the orthogonal projection matrix to use)
ImVec2 DisplaySize; // Size of the viewport to render (== io.DisplaySize for the main viewport) (DisplayPos + DisplaySize == lower-right of the orthogonal projection matrix to use)
// Functions
- ImDrawData() { Clear(); }
- void Clear() { Valid = false; CmdLists = NULL; CmdListsCount = TotalVtxCount = TotalIdxCount = 0; DisplayPos = DisplaySize = ImVec2(0.f, 0.f); } // Draw lists are owned by the ImGuiContext and only pointed to here.
- IMGUI_API void DeIndexAllBuffers(); // Convenience: convert all buffers from indexed to non-indexed, in case you cannot render indexed. Note: this is slow and most likely a waste of resources. Always prefer indexed rendering!
- IMGUI_API void ScaleClipRects(const ImVec2& sc); // Helper to scale the ClipRect field of each ImDrawCmd. Use if your final output buffer is at a different scale than ImGui expects, or if there is a difference between your window resolution and framebuffer resolution.
+ ImDrawData() { Valid = false; Clear(); }
+ ~ImDrawData() { Clear(); }
+ void Clear() { Valid = false; CmdLists = NULL; CmdListsCount = TotalVtxCount = TotalIdxCount = 0; DisplayPos = DisplaySize = ImVec2(0.f, 0.f); } // The ImDrawList are owned by ImGuiContext!
+ IMGUI_API void DeIndexAllBuffers(); // Helper to convert all buffers from indexed to non-indexed, in case you cannot render indexed. Note: this is slow and most likely a waste of resources. Always prefer indexed rendering!
+ IMGUI_API void ScaleClipRects(const ImVec2& sc); // Helper to scale the ClipRect field of each ImDrawCmd. Use if your final output buffer is at a different scale than ImGui expects, or if there is a difference between your window resolution and framebuffer resolution.
};
struct ImFontConfig
diff --git a/imgui_draw.cpp b/imgui_draw.cpp
index b86ee869..a6bda8a5 100644
--- a/imgui_draw.cpp
+++ b/imgui_draw.cpp
@@ -34,7 +34,6 @@
#ifdef _MSC_VER
#pragma warning (disable: 4505) // unreferenced local function has been removed (stb stuff)
#pragma warning (disable: 4996) // 'This function or variable may be unsafe': strcpy, strdup, sprintf, vsnprintf, sscanf, fopen
-#define snprintf _snprintf
#endif
#ifdef __clang__
@@ -339,6 +338,16 @@ void ImDrawList::ClearFreeMemory()
_Channels.clear();
}
+ImDrawList* ImDrawList::CloneOutput() const
+{
+ ImDrawList* dst = IM_NEW(ImDrawList(NULL));
+ dst->CmdBuffer = CmdBuffer;
+ dst->IdxBuffer = IdxBuffer;
+ dst->VtxBuffer = VtxBuffer;
+ dst->Flags = Flags;
+ return dst;
+}
+
// Using macros because C++ is a terrible language, we want guaranteed inline, no code in header, and no overhead in Debug builds
#define GetCurrentClipRect() (_ClipRectStack.Size ? _ClipRectStack.Data[_ClipRectStack.Size-1] : _Data->ClipRectFullscreen)
#define GetCurrentTextureId() (_TextureIdStack.Size ? _TextureIdStack.Data[_TextureIdStack.Size-1] : NULL)