mirror of
				https://github.com/Drezil/imgui.git
				synced 2025-11-04 07:01:04 +01:00 
			
		
		
		
	Merge branch 'viewport' into docking
# Conflicts: # imgui.cpp
This commit is contained in:
		@@ -125,11 +125,14 @@ Other Changes:
 | 
			
		||||
- InputFloat: When using ImGuiInputTextFlags_ReadOnly the step buttons are disabled. (#2257)
 | 
			
		||||
- Nav: Fixed an keyboard issue where holding Activate/Space for longer than two frames on a button would unnecessary 
 | 
			
		||||
  keep the focus on the parent window, which could steal it from newly appearing windows. (#787)
 | 
			
		||||
- Nav: Fixed animated window titles from being updated when displayed in the CTRL+Tab list. (#787)
 | 
			
		||||
- Error recovery: Extraneous/undesired calls to End() are now being caught by an assert in the End() function closer
 | 
			
		||||
  to the user call site (instead of being reported in EndFrame). Past the assert, they don't lead to crashes any more. (#1651)
 | 
			
		||||
  Missing calls to End(), past the assert, should not lead to crashes or to the fallback Debug window appearing on screen.
 | 
			
		||||
  Those changes makes it easier to integrate dear imgui with a scripting language allowing, given asserts are redirected
 | 
			
		||||
  into e.g. an error log and stopping the script execution.
 | 
			
		||||
- ImDrawList: Optimized some of the functions for performance of debug builds where non-inline function call cost are non-negligible.
 | 
			
		||||
  (Our test UI scene on VS2015 Debug Win64 with /RTC1 went ~5.9 ms -> ~4.9 ms. In Release same scene stays at ~0.3 ms.)
 | 
			
		||||
- IO: Added BackendPlatformUserData, BackendRendererUserData, BackendLanguageUserData void* for storage use by back-ends.
 | 
			
		||||
- IO: Renamed InputCharacters[], marked internal as was always intended. Please don't access directly, and use AddInputCharacter() instead!
 | 
			
		||||
- IO: AddInputCharacter() goes into a queue which can receive as many characters as needed during the frame. This is useful
 | 
			
		||||
 
 | 
			
		||||
@@ -147,7 +147,7 @@ Frameworks:
 | 
			
		||||
- OpenSceneGraph/OSG: [gist](https://gist.github.com/fulezi/d2442ca7626bf270226014501357042c)
 | 
			
		||||
- ORX: [pr #1843](https://github.com/ocornut/imgui/pull/1843)
 | 
			
		||||
- LÖVE+Lua: [love-imgui](https://github.com/slages/love-imgui)
 | 
			
		||||
- Magnum: [magnum-imgui](https://github.com/lecopivo/magnum-imgui), [MagnumImguiPort](https://github.com/lecopivo/MagnumImguiPort)
 | 
			
		||||
- Magnum: [ImGuiIntegration](https://doc.magnum.graphics/magnum/namespaceMagnum_1_1ImGuiIntegration.html) ([example](https://doc.magnum.graphics/magnum/examples-imgui.html))
 | 
			
		||||
- NanoRT: [syoyo/imgui](https://github.com/syoyo/imgui/tree/nanort)
 | 
			
		||||
- Qt3d: [imgui-qt3d](https://github.com/alpqr/imgui-qt3d), QOpenGLWindow [qtimgui](https://github.com/ocornut/imgui/issues/1910)
 | 
			
		||||
- SFML: [imgui-sfml](https://github.com/EliasD/imgui-sfml)
 | 
			
		||||
 
 | 
			
		||||
@@ -358,6 +358,7 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i
 | 
			
		||||
 - optimization: replace vsnprintf with stb_printf? or enable the defines/infrastructure to allow it (#1038)
 | 
			
		||||
 - optimization: add clipping for multi-component widgets (SliderFloatX, ColorEditX, etc.). one problem is that nav branch can't easily clip parent group when there is a move request.
 | 
			
		||||
 - optimization: add a flag to disable most of rendering, for the case where the user expect to skip it (#335)
 | 
			
		||||
 - optimization: fully covered window (covered by another with non-translucent bg + WindowRounding worth of padding) may want to clip rendering.
 | 
			
		||||
 - optimization: use another hash function than crc32, e.g. FNV1a
 | 
			
		||||
 - optimization/render: merge command-lists with same clip-rect into one even if they aren't sequential? (as long as in-between clip rectangle don't overlap)?
 | 
			
		||||
 - optimization: turn some the various stack vectors into statically-sized arrays
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										98
									
								
								imgui.cpp
									
									
									
									
									
								
							
							
						
						
									
										98
									
								
								imgui.cpp
									
									
									
									
									
								
							@@ -1296,11 +1296,25 @@ void ImStrncpy(char* dst, const char* src, size_t count)
 | 
			
		||||
    dst[count-1] = 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
char* ImStrdup(const char *str)
 | 
			
		||||
char* ImStrdup(const char* str)
 | 
			
		||||
{
 | 
			
		||||
    size_t len = strlen(str) + 1;
 | 
			
		||||
    void* buf = ImGui::MemAlloc(len);
 | 
			
		||||
    return (char*)memcpy(buf, (const void*)str, len);
 | 
			
		||||
    size_t len = strlen(str);
 | 
			
		||||
    void* buf = ImGui::MemAlloc(len + 1);
 | 
			
		||||
    return (char*)memcpy(buf, (const void*)str, len + 1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
char* ImStrdupcpy(char* dst, size_t* p_dst_size, const char* src)
 | 
			
		||||
{
 | 
			
		||||
    size_t dst_buf_size = p_dst_size ? *p_dst_size : strlen(dst) + 1;
 | 
			
		||||
    size_t src_size = strlen(src) + 1;
 | 
			
		||||
    if (dst_buf_size < src_size)
 | 
			
		||||
    {
 | 
			
		||||
        ImGui::MemFree(dst);
 | 
			
		||||
        dst = (char*)ImGui::MemAlloc(src_size);
 | 
			
		||||
        if (p_dst_size)
 | 
			
		||||
            *p_dst_size = src_size;
 | 
			
		||||
    }
 | 
			
		||||
    return (char*)memcpy(dst, (const void*)src, src_size);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const char* ImStrchrRange(const char* str, const char* str_end, char c)
 | 
			
		||||
@@ -1381,6 +1395,12 @@ const char* ImStrSkipBlank(const char* str)
 | 
			
		||||
// B) When buf==NULL vsnprintf() will return the output size.
 | 
			
		||||
#ifndef IMGUI_DISABLE_FORMAT_STRING_FUNCTIONS
 | 
			
		||||
 | 
			
		||||
//#define IMGUI_USE_STB_SPRINTF
 | 
			
		||||
#ifdef IMGUI_USE_STB_SPRINTF
 | 
			
		||||
#define STB_SPRINTF_IMPLEMENTATION
 | 
			
		||||
#include "imstb_sprintf.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if defined(_MSC_VER) && !defined(vsnprintf)
 | 
			
		||||
#define vsnprintf _vsnprintf
 | 
			
		||||
#endif
 | 
			
		||||
@@ -1389,7 +1409,11 @@ int ImFormatString(char* buf, size_t buf_size, const char* fmt, ...)
 | 
			
		||||
{
 | 
			
		||||
    va_list args;
 | 
			
		||||
    va_start(args, fmt);
 | 
			
		||||
#ifdef IMGUI_USE_STB_SPRINTF
 | 
			
		||||
    int w = stbsp_vsnprintf(buf, (int)buf_size, fmt, args);
 | 
			
		||||
#else
 | 
			
		||||
    int w = vsnprintf(buf, buf_size, fmt, args);
 | 
			
		||||
#endif
 | 
			
		||||
    va_end(args);
 | 
			
		||||
    if (buf == NULL)
 | 
			
		||||
        return w;
 | 
			
		||||
@@ -1401,7 +1425,11 @@ int ImFormatString(char* buf, size_t buf_size, const char* fmt, ...)
 | 
			
		||||
 | 
			
		||||
int ImFormatStringV(char* buf, size_t buf_size, const char* fmt, va_list args)
 | 
			
		||||
{
 | 
			
		||||
#ifdef IMGUI_USE_STB_SPRINTF
 | 
			
		||||
    int w = stbsp_vsnprintf(buf, (int)buf_size, fmt, args);
 | 
			
		||||
#else
 | 
			
		||||
    int w = vsnprintf(buf, buf_size, fmt, args);
 | 
			
		||||
#endif
 | 
			
		||||
    if (buf == NULL)
 | 
			
		||||
        return w;
 | 
			
		||||
    if (w == -1 || w >= (int)buf_size)
 | 
			
		||||
@@ -1411,7 +1439,9 @@ int ImFormatStringV(char* buf, size_t buf_size, const char* fmt, va_list args)
 | 
			
		||||
}
 | 
			
		||||
#endif // #ifdef IMGUI_DISABLE_FORMAT_STRING_FUNCTIONS
 | 
			
		||||
 | 
			
		||||
// Pass data_size==0 for zero-terminated strings
 | 
			
		||||
// Pass data_size == 0 for zero-terminated strings, data_size > 0 for non-string data.
 | 
			
		||||
// Pay attention that data_size==0 will yield different results than passing strlen(data) because the zero-terminated codepath handles ###.
 | 
			
		||||
// This should technically be split into two distinct functions (ImHashData/ImHashStr), perhaps once we remove the silly static variable.
 | 
			
		||||
// FIXME-OPT: Replace with e.g. FNV1a hash? CRC32 pretty much randomly access 1KB. Need to do proper measurements.
 | 
			
		||||
ImU32 ImHash(const void* data, int data_size, ImU32 seed)
 | 
			
		||||
{
 | 
			
		||||
@@ -1810,15 +1840,15 @@ ImU32 ImGui::GetColorU32(ImU32 col)
 | 
			
		||||
//-----------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
// std::lower_bound but without the bullshit
 | 
			
		||||
static ImVector<ImGuiStorage::Pair>::iterator LowerBound(ImVector<ImGuiStorage::Pair>& data, ImGuiID key)
 | 
			
		||||
static ImGuiStorage::Pair* LowerBound(ImVector<ImGuiStorage::Pair>& data, ImGuiID key)
 | 
			
		||||
{
 | 
			
		||||
    ImVector<ImGuiStorage::Pair>::iterator first = data.begin();
 | 
			
		||||
    ImVector<ImGuiStorage::Pair>::iterator last = data.end();
 | 
			
		||||
    ImGuiStorage::Pair* first = data.Data;
 | 
			
		||||
    ImGuiStorage::Pair* last = data.Data + data.Size;
 | 
			
		||||
    size_t count = (size_t)(last - first);
 | 
			
		||||
    while (count > 0)
 | 
			
		||||
    {
 | 
			
		||||
        size_t count2 = count >> 1;
 | 
			
		||||
        ImVector<ImGuiStorage::Pair>::iterator mid = first + count2;
 | 
			
		||||
        ImGuiStorage::Pair* mid = first + count2;
 | 
			
		||||
        if (mid->key < key)
 | 
			
		||||
        {
 | 
			
		||||
            first = ++mid;
 | 
			
		||||
@@ -1851,7 +1881,7 @@ void ImGuiStorage::BuildSortByKey()
 | 
			
		||||
 | 
			
		||||
int ImGuiStorage::GetInt(ImGuiID key, int default_val) const
 | 
			
		||||
{
 | 
			
		||||
    ImVector<Pair>::iterator it = LowerBound(const_cast<ImVector<ImGuiStorage::Pair>&>(Data), key);
 | 
			
		||||
    ImGuiStorage::Pair* it = LowerBound(const_cast<ImVector<ImGuiStorage::Pair>&>(Data), key);
 | 
			
		||||
    if (it == Data.end() || it->key != key)
 | 
			
		||||
        return default_val;
 | 
			
		||||
    return it->val_i;
 | 
			
		||||
@@ -1864,7 +1894,7 @@ bool ImGuiStorage::GetBool(ImGuiID key, bool default_val) const
 | 
			
		||||
 | 
			
		||||
float ImGuiStorage::GetFloat(ImGuiID key, float default_val) const
 | 
			
		||||
{
 | 
			
		||||
    ImVector<Pair>::iterator it = LowerBound(const_cast<ImVector<ImGuiStorage::Pair>&>(Data), key);
 | 
			
		||||
    ImGuiStorage::Pair* it = LowerBound(const_cast<ImVector<ImGuiStorage::Pair>&>(Data), key);
 | 
			
		||||
    if (it == Data.end() || it->key != key)
 | 
			
		||||
        return default_val;
 | 
			
		||||
    return it->val_f;
 | 
			
		||||
@@ -1872,7 +1902,7 @@ float ImGuiStorage::GetFloat(ImGuiID key, float default_val) const
 | 
			
		||||
 | 
			
		||||
void* ImGuiStorage::GetVoidPtr(ImGuiID key) const
 | 
			
		||||
{
 | 
			
		||||
    ImVector<Pair>::iterator it = LowerBound(const_cast<ImVector<ImGuiStorage::Pair>&>(Data), key);
 | 
			
		||||
    ImGuiStorage::Pair* it = LowerBound(const_cast<ImVector<ImGuiStorage::Pair>&>(Data), key);
 | 
			
		||||
    if (it == Data.end() || it->key != key)
 | 
			
		||||
        return NULL;
 | 
			
		||||
    return it->val_p;
 | 
			
		||||
@@ -1881,7 +1911,7 @@ void* ImGuiStorage::GetVoidPtr(ImGuiID key) const
 | 
			
		||||
// References are only valid until a new value is added to the storage. Calling a Set***() function or a Get***Ref() function invalidates the pointer.
 | 
			
		||||
int* ImGuiStorage::GetIntRef(ImGuiID key, int default_val)
 | 
			
		||||
{
 | 
			
		||||
    ImVector<Pair>::iterator it = LowerBound(Data, key);
 | 
			
		||||
    ImGuiStorage::Pair* it = LowerBound(Data, key);
 | 
			
		||||
    if (it == Data.end() || it->key != key)
 | 
			
		||||
        it = Data.insert(it, Pair(key, default_val));
 | 
			
		||||
    return &it->val_i;
 | 
			
		||||
@@ -1894,7 +1924,7 @@ bool* ImGuiStorage::GetBoolRef(ImGuiID key, bool default_val)
 | 
			
		||||
 | 
			
		||||
float* ImGuiStorage::GetFloatRef(ImGuiID key, float default_val)
 | 
			
		||||
{
 | 
			
		||||
    ImVector<Pair>::iterator it = LowerBound(Data, key);
 | 
			
		||||
    ImGuiStorage::Pair* it = LowerBound(Data, key);
 | 
			
		||||
    if (it == Data.end() || it->key != key)
 | 
			
		||||
        it = Data.insert(it, Pair(key, default_val));
 | 
			
		||||
    return &it->val_f;
 | 
			
		||||
@@ -1902,7 +1932,7 @@ float* ImGuiStorage::GetFloatRef(ImGuiID key, float default_val)
 | 
			
		||||
 | 
			
		||||
void** ImGuiStorage::GetVoidPtrRef(ImGuiID key, void* default_val)
 | 
			
		||||
{
 | 
			
		||||
    ImVector<Pair>::iterator it = LowerBound(Data, key);
 | 
			
		||||
    ImGuiStorage::Pair* it = LowerBound(Data, key);
 | 
			
		||||
    if (it == Data.end() || it->key != key)
 | 
			
		||||
        it = Data.insert(it, Pair(key, default_val));
 | 
			
		||||
    return &it->val_p;
 | 
			
		||||
@@ -1911,7 +1941,7 @@ void** ImGuiStorage::GetVoidPtrRef(ImGuiID key, void* default_val)
 | 
			
		||||
// FIXME-OPT: Need a way to reuse the result of lower_bound when doing GetInt()/SetInt() - not too bad because it only happens on explicit interaction (maximum one a frame)
 | 
			
		||||
void ImGuiStorage::SetInt(ImGuiID key, int val)
 | 
			
		||||
{
 | 
			
		||||
    ImVector<Pair>::iterator it = LowerBound(Data, key);
 | 
			
		||||
    ImGuiStorage::Pair* it = LowerBound(Data, key);
 | 
			
		||||
    if (it == Data.end() || it->key != key)
 | 
			
		||||
    {
 | 
			
		||||
        Data.insert(it, Pair(key, val));
 | 
			
		||||
@@ -1927,7 +1957,7 @@ void ImGuiStorage::SetBool(ImGuiID key, bool val)
 | 
			
		||||
 | 
			
		||||
void ImGuiStorage::SetFloat(ImGuiID key, float val)
 | 
			
		||||
{
 | 
			
		||||
    ImVector<Pair>::iterator it = LowerBound(Data, key);
 | 
			
		||||
    ImGuiStorage::Pair* it = LowerBound(Data, key);
 | 
			
		||||
    if (it == Data.end() || it->key != key)
 | 
			
		||||
    {
 | 
			
		||||
        Data.insert(it, Pair(key, val));
 | 
			
		||||
@@ -1938,7 +1968,7 @@ void ImGuiStorage::SetFloat(ImGuiID key, float val)
 | 
			
		||||
 | 
			
		||||
void ImGuiStorage::SetVoidPtr(ImGuiID key, void* val)
 | 
			
		||||
{
 | 
			
		||||
    ImVector<Pair>::iterator it = LowerBound(Data, key);
 | 
			
		||||
    ImGuiStorage::Pair* it = LowerBound(Data, key);
 | 
			
		||||
    if (it == Data.end() || it->key != key)
 | 
			
		||||
    {
 | 
			
		||||
        Data.insert(it, Pair(key, val));
 | 
			
		||||
@@ -2439,6 +2469,7 @@ ImGuiWindow::ImGuiWindow(ImGuiContext* context, const char* name)
 | 
			
		||||
    WindowPadding = ImVec2(0.0f, 0.0f);
 | 
			
		||||
    WindowRounding = 0.0f;
 | 
			
		||||
    WindowBorderSize = 0.0f;
 | 
			
		||||
    NameBufLen = (int)strlen(name) + 1;
 | 
			
		||||
    MoveId = GetID("#MOVE");
 | 
			
		||||
    ChildId = 0;
 | 
			
		||||
    Scroll = ImVec2(0.0f, 0.0f);
 | 
			
		||||
@@ -2695,7 +2726,8 @@ void ImGui::ItemSize(const ImVec2& size, float text_offset_y)
 | 
			
		||||
    const float text_base_offset = ImMax(window->DC.CurrentLineTextBaseOffset, text_offset_y);
 | 
			
		||||
    //if (g.IO.KeyAlt) window->DrawList->AddRect(window->DC.CursorPos, window->DC.CursorPos + ImVec2(size.x, line_height), IM_COL32(255,0,0,200)); // [DEBUG]
 | 
			
		||||
    window->DC.CursorPosPrevLine = ImVec2(window->DC.CursorPos.x + size.x, window->DC.CursorPos.y);
 | 
			
		||||
    window->DC.CursorPos = ImVec2((float)(int)(window->Pos.x + window->DC.Indent.x + window->DC.ColumnsOffset.x), (float)(int)(window->DC.CursorPos.y + line_height + g.Style.ItemSpacing.y));
 | 
			
		||||
    window->DC.CursorPos.x = (float)(int)(window->Pos.x + window->DC.Indent.x + window->DC.ColumnsOffset.x);
 | 
			
		||||
    window->DC.CursorPos.y = (float)(int)(window->DC.CursorPos.y + line_height + g.Style.ItemSpacing.y);
 | 
			
		||||
    window->DC.CursorMaxPos.x = ImMax(window->DC.CursorMaxPos.x, window->DC.CursorPosPrevLine.x);
 | 
			
		||||
    window->DC.CursorMaxPos.y = ImMax(window->DC.CursorMaxPos.y, window->DC.CursorPos.y - g.Style.ItemSpacing.y);
 | 
			
		||||
    //if (g.IO.KeyAlt) window->DrawList->AddCircle(window->DC.CursorMaxPos, 3.0f, IM_COL32(255,0,0,255), 4); // [DEBUG]
 | 
			
		||||
@@ -2741,7 +2773,8 @@ bool ImGui::ItemAdd(const ImRect& bb, ImGuiID id, const ImRect* nav_bb_arg)
 | 
			
		||||
    window->DC.LastItemStatusFlags = ImGuiItemStatusFlags_None;
 | 
			
		||||
 | 
			
		||||
#ifdef IMGUI_ENABLE_TEST_ENGINE
 | 
			
		||||
    ImGuiTestEngineHook_ItemAdd(bb, id);
 | 
			
		||||
    if (id != 0)
 | 
			
		||||
        ImGuiTestEngineHook_ItemAdd(&g, bb, id);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    // Clipping test
 | 
			
		||||
@@ -3357,7 +3390,7 @@ void ImGui::NewFrame()
 | 
			
		||||
    ImGuiContext& g = *GImGui;
 | 
			
		||||
 | 
			
		||||
#ifdef IMGUI_ENABLE_TEST_ENGINE
 | 
			
		||||
    ImGuiTestEngineHook_PreNewFrame();
 | 
			
		||||
    ImGuiTestEngineHook_PreNewFrame(&g);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    // Check user data
 | 
			
		||||
@@ -3587,7 +3620,7 @@ void ImGui::NewFrame()
 | 
			
		||||
    g.FrameScopePushedImplicitWindow = true;
 | 
			
		||||
 | 
			
		||||
#ifdef IMGUI_ENABLE_TEST_ENGINE
 | 
			
		||||
    ImGuiTestEngineHook_PostNewFrame();
 | 
			
		||||
    ImGuiTestEngineHook_PostNewFrame(&g);
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -4650,7 +4683,7 @@ static ImGuiWindow* CreateNewWindow(const char* name, ImVec2 size, ImGuiWindowFl
 | 
			
		||||
        if (ImGuiWindowSettings* settings = ImGui::FindWindowSettings(window->ID))
 | 
			
		||||
        {
 | 
			
		||||
            // Retrieve settings from .ini file
 | 
			
		||||
            window->SettingsIdx = g.SettingsWindows.index_from_pointer(settings);
 | 
			
		||||
            window->SettingsIdx = g.SettingsWindows.index_from_ptr(settings);
 | 
			
		||||
            SetWindowConditionAllowFlags(window, ImGuiCond_FirstUseEver, false);
 | 
			
		||||
            if (settings->ViewportId)
 | 
			
		||||
            {
 | 
			
		||||
@@ -5166,13 +5199,18 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
 | 
			
		||||
        window->ClipRect = ImVec4(-FLT_MAX,-FLT_MAX,+FLT_MAX,+FLT_MAX);
 | 
			
		||||
        window->IDStack.resize(1);
 | 
			
		||||
 | 
			
		||||
        // Update stored window name when it changes (which can only happen with the "###" operator).
 | 
			
		||||
        // The title bar always display the 'name' parameter, so we only update storage if the title is displayed to the end-user in a different place.
 | 
			
		||||
        bool window_title_visible_elsewhere = (window->Viewport && window->Viewport->Window == window) || (window->DockIsActive);
 | 
			
		||||
        if (!window_just_created && window_title_visible_elsewhere && strcmp(name, window->Name) != 0)
 | 
			
		||||
        // Update stored window name when it changes (which can _only_ happen with the "###" operator, so the ID would stay unchanged).
 | 
			
		||||
        // The title bar always display the 'name' parameter, so we only update the string storage if it needs to be visible to the end-user elsewhere.
 | 
			
		||||
        bool window_title_visible_elsewhere = false;
 | 
			
		||||
        if ((window->Viewport && window->Viewport->Window == window) || (window->DockIsActive))
 | 
			
		||||
            window_title_visible_elsewhere = true;
 | 
			
		||||
        else if (g.NavWindowingList != NULL && (window->Flags & ImGuiWindowFlags_NoNavFocus) == 0)   // Window titles visible when using CTRL+TAB
 | 
			
		||||
            window_title_visible_elsewhere = true;
 | 
			
		||||
        if (window_title_visible_elsewhere && !window_just_created && strcmp(name, window->Name) != 0)
 | 
			
		||||
        {
 | 
			
		||||
            IM_DELETE(window->Name);
 | 
			
		||||
            window->Name = ImStrdup(name);
 | 
			
		||||
            size_t buf_len = (size_t)window->NameBufLen;
 | 
			
		||||
            window->Name = ImStrdupcpy(window->Name, &buf_len, name);
 | 
			
		||||
            window->NameBufLen = (int)buf_len;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // UPDATE CONTENTS SIZE, UPDATE HIDDEN STATUS
 | 
			
		||||
@@ -13254,7 +13292,7 @@ static void SettingsHandlerWindow_WriteAll(ImGuiContext* imgui_ctx, ImGuiSetting
 | 
			
		||||
        if (!settings)
 | 
			
		||||
        {
 | 
			
		||||
            settings = ImGui::CreateNewWindowSettings(window->Name);
 | 
			
		||||
            window->SettingsIdx = g.SettingsWindows.index_from_pointer(settings);
 | 
			
		||||
            window->SettingsIdx = g.SettingsWindows.index_from_ptr(settings);
 | 
			
		||||
        }
 | 
			
		||||
        IM_ASSERT(settings->ID == window->ID);
 | 
			
		||||
        settings->Pos = window->Pos - window->ViewportPos;
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										114
									
								
								imgui.h
									
									
									
									
									
								
							
							
						
						
									
										114
									
								
								imgui.h
									
									
									
									
									
								
							@@ -13,14 +13,14 @@ Index of this file:
 | 
			
		||||
// Forward declarations and basic types
 | 
			
		||||
// ImGui API (Dear ImGui end-user API)
 | 
			
		||||
// Flags & Enumerations
 | 
			
		||||
// ImVector
 | 
			
		||||
// ImVector<>
 | 
			
		||||
// ImGuiStyle
 | 
			
		||||
// ImGuiIO
 | 
			
		||||
// Misc data structures (ImGuiInputTextCallbackData, ImGuiSizeCallbackData, ImGuiPayload, ImGuiWindowClass)
 | 
			
		||||
// Obsolete functions
 | 
			
		||||
// Helpers (ImGuiOnceUponAFrame, ImGuiTextFilter, ImGuiTextBuffer, ImGuiStorage, ImGuiListClipper, ImColor)
 | 
			
		||||
// Draw List API (ImDrawCmd, ImDrawIdx, ImDrawVert, ImDrawChannel, ImDrawListFlags, ImDrawList, ImDrawData)
 | 
			
		||||
// Font API (ImFontConfig, ImFontGlyph, ImFontAtlasFlags, ImFontAtlas, ImFont)
 | 
			
		||||
// Font API (ImFontConfig, ImFontGlyph, ImFontGlyphRangesBuilder, ImFontAtlasFlags, ImFontAtlas, ImFont)
 | 
			
		||||
// Platform interface for multi-viewport support (ImGuiPlatformMonitor, ImGuiPlatformIO, ImGuiViewport)
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
@@ -1225,73 +1225,63 @@ enum ImGuiCond_
 | 
			
		||||
 | 
			
		||||
//-----------------------------------------------------------------------------
 | 
			
		||||
// Helper: ImVector<>
 | 
			
		||||
// Lightweight std::vector<>-like class to avoid dragging dependencies (also: some implementations of STL with debug enabled are absurdly slow, we bypass it so our code runs fast in debug).
 | 
			
		||||
// Lightweight std::vector<>-like class to avoid dragging dependencies (also, some implementations of STL with debug enabled are absurdly slow, we bypass it so our code runs fast in debug).
 | 
			
		||||
// You generally do NOT need to care or use this ever. But we need to make it available in imgui.h because some of our data structures are relying on it.
 | 
			
		||||
// Important: clear() frees memory, resize(0) keep the allocated buffer. We use resize(0) a lot to intentionally recycle allocated buffers across frames and amortize our costs.
 | 
			
		||||
// Important: our implementation does NOT call C++ constructors/destructors, we treat everything as raw data! This is intentional but be extra mindful of that, 
 | 
			
		||||
// do NOT use this class as a std::vector replacement in your own code!
 | 
			
		||||
// do NOT use this class as a std::vector replacement in your own code! Many of the structures used by dear imgui can be safely initialized by a zero-memset.
 | 
			
		||||
//-----------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
template<typename T>
 | 
			
		||||
class ImVector
 | 
			
		||||
struct ImVector
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    int                         Size;
 | 
			
		||||
    int                         Capacity;
 | 
			
		||||
    T*                          Data;
 | 
			
		||||
    int                 Size;
 | 
			
		||||
    int                 Capacity;
 | 
			
		||||
    T*                  Data;
 | 
			
		||||
 | 
			
		||||
    // Provide standard typedefs but we don't use them ourselves.
 | 
			
		||||
    typedef T                   value_type;
 | 
			
		||||
    typedef value_type*         iterator;
 | 
			
		||||
    typedef const value_type*   const_iterator;
 | 
			
		||||
 | 
			
		||||
    inline ImVector()           { Size = Capacity = 0; Data = NULL; }
 | 
			
		||||
    inline ~ImVector()          { if (Data) ImGui::MemFree(Data); }
 | 
			
		||||
    inline ImVector(const ImVector<T>& src)                     { Size = Capacity = 0; Data = NULL; operator=(src); }
 | 
			
		||||
    inline ImVector<T>& operator=(const ImVector<T>& src)       { clear(); resize(src.Size); memcpy(Data, src.Data, (size_t)Size * sizeof(value_type)); return *this; }
 | 
			
		||||
    // Constructors, destructor
 | 
			
		||||
    inline ImVector()                                       { Size = Capacity = 0; Data = NULL; }
 | 
			
		||||
    inline ImVector(const ImVector<T>& src)                 { Size = Capacity = 0; Data = NULL; operator=(src); }
 | 
			
		||||
    inline ImVector<T>& operator=(const ImVector<T>& src)   { clear(); resize(src.Size); memcpy(Data, src.Data, (size_t)Size * sizeof(T)); return *this; }
 | 
			
		||||
    inline ~ImVector()                                      { if (Data) ImGui::MemFree(Data); }
 | 
			
		||||
 | 
			
		||||
    inline bool                 empty() const                   { return Size == 0; }
 | 
			
		||||
    inline int                  size() const                    { return Size; }
 | 
			
		||||
    inline int                  capacity() const                { return Capacity; }
 | 
			
		||||
    inline value_type&          operator[](int i)               { IM_ASSERT(i < Size); return Data[i]; }
 | 
			
		||||
    inline const value_type&    operator[](int i) const         { IM_ASSERT(i < Size); return Data[i]; }
 | 
			
		||||
    inline bool         empty() const                       { return Size == 0; }
 | 
			
		||||
    inline int          size() const                        { return Size; }
 | 
			
		||||
    inline int          capacity() const                    { return Capacity; }
 | 
			
		||||
    inline T&           operator[](int i)                   { IM_ASSERT(i < Size); return Data[i]; }
 | 
			
		||||
    inline const T&     operator[](int i) const             { IM_ASSERT(i < Size); return Data[i]; }
 | 
			
		||||
 | 
			
		||||
    inline void                 clear()                         { if (Data) { Size = Capacity = 0; ImGui::MemFree(Data); Data = NULL; } }
 | 
			
		||||
    inline iterator             begin()                         { return Data; }
 | 
			
		||||
    inline const_iterator       begin() const                   { return Data; }
 | 
			
		||||
    inline iterator             end()                           { return Data + Size; }
 | 
			
		||||
    inline const_iterator       end() const                     { return Data + Size; }
 | 
			
		||||
    inline value_type&          front()                         { IM_ASSERT(Size > 0); return Data[0]; }
 | 
			
		||||
    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<value_type>& 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         clear()                             { if (Data) { Size = Capacity = 0; ImGui::MemFree(Data); Data = NULL; } }
 | 
			
		||||
    inline T*           begin()                             { return Data; }
 | 
			
		||||
    inline const T*     begin() const                       { return Data; }
 | 
			
		||||
    inline T*           end()                               { return Data + Size; }
 | 
			
		||||
    inline const T*     end() const                         { return Data + Size; }
 | 
			
		||||
    inline T&           front()                             { IM_ASSERT(Size > 0); return Data[0]; }
 | 
			
		||||
    inline const T&     front() const                       { IM_ASSERT(Size > 0); return Data[0]; }
 | 
			
		||||
    inline T&           back()                              { IM_ASSERT(Size > 0); return Data[Size - 1]; }
 | 
			
		||||
    inline const T&     back() const                        { IM_ASSERT(Size > 0); return Data[Size - 1]; }
 | 
			
		||||
    inline void         swap(ImVector<T>& rhs)              { int rhs_size = rhs.Size; rhs.Size = Size; Size = rhs_size; int rhs_cap = rhs.Capacity; rhs.Capacity = Capacity; Capacity = rhs_cap; T* 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 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;
 | 
			
		||||
        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(value_type));
 | 
			
		||||
            ImGui::MemFree(Data);
 | 
			
		||||
        }
 | 
			
		||||
        Data = new_data;
 | 
			
		||||
        Capacity = new_capacity;
 | 
			
		||||
    }
 | 
			
		||||
    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++) memcpy(&Data[n], &v, sizeof(v)); Size = new_size; }
 | 
			
		||||
    inline void         reserve(int new_capacity)           { if (new_capacity <= Capacity) return; T* new_data = (T*)ImGui::MemAlloc((size_t)new_capacity * sizeof(T)); if (Data) { memcpy(new_data, Data, (size_t)Size * sizeof(T)); ImGui::MemFree(Data); } Data = new_data; Capacity = new_capacity; }
 | 
			
		||||
 | 
			
		||||
    // NB: It is illegal to call push_back/push_front/insert with a reference 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)); 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; }
 | 
			
		||||
    inline iterator     erase(const_iterator it, const_iterator it_last){ IM_ASSERT(it >= Data && it < Data+Size && it_last > it && it_last <= Data+Size); const ptrdiff_t count = it_last - it; const ptrdiff_t off = it - Data; memmove(Data + off, Data + off + count, ((size_t)Size - (size_t)off - count) * sizeof(value_type)); Size -= (int)count; return Data + off; }
 | 
			
		||||
    inline iterator     erase_unsorted(const_iterator it)               { IM_ASSERT(it >= Data && it < Data+Size);  const ptrdiff_t off = it - Data; if (it < Data+Size-1) memcpy(Data + off, Data + Size - 1, sizeof(value_type)); Size--; return Data + off; }
 | 
			
		||||
    inline iterator     insert(const_iterator it, const value_type& v)  { IM_ASSERT(it >= Data && it <= Data+Size); const ptrdiff_t off = it - Data; if (Size == Capacity) reserve(_grow_capacity(Size + 1)); if (off < (int)Size) memmove(Data + off + 1, Data + off, ((size_t)Size - (size_t)off) * sizeof(value_type)); memcpy(&Data[off], &v, sizeof(v)); Size++; return Data + off; }
 | 
			
		||||
    inline bool         contains(const value_type& v) const             { const T* data = Data;  const T* data_end = Data + Size; while (data < data_end) if (*data++ == v) return true; return false; }
 | 
			
		||||
    inline int          index_from_pointer(const_iterator it) const     { IM_ASSERT(it >= Data && it <= Data+Size); const ptrdiff_t off = it - Data; return (int)off; }
 | 
			
		||||
    inline void         push_back(const T& 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 T& v)              { if (Size == 0) push_back(v); else insert(Data, v); }
 | 
			
		||||
    inline T*           erase(const T* 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(T)); Size--; return Data + off; }
 | 
			
		||||
    inline T*           erase(const T* it, const T* it_last){ IM_ASSERT(it >= Data && it < Data+Size && it_last > it && it_last <= Data+Size); const ptrdiff_t count = it_last - it; const ptrdiff_t off = it - Data; memmove(Data + off, Data + off + count, ((size_t)Size - (size_t)off - count) * sizeof(T)); Size -= (int)count; return Data + off; }
 | 
			
		||||
    inline T*           erase_unsorted(const T* it)         { IM_ASSERT(it >= Data && it < Data+Size);  const ptrdiff_t off = it - Data; if (it < Data+Size-1) memcpy(Data + off, Data + Size - 1, sizeof(T)); Size--; return Data + off; }
 | 
			
		||||
    inline T*           insert(const T* it, const T& v)     { IM_ASSERT(it >= Data && it <= Data+Size); const ptrdiff_t off = it - Data; if (Size == Capacity) reserve(_grow_capacity(Size + 1)); if (off < (int)Size) memmove(Data + off + 1, Data + off, ((size_t)Size - (size_t)off) * sizeof(T)); memcpy(&Data[off], &v, sizeof(v)); Size++; return Data + off; }
 | 
			
		||||
    inline bool         contains(const T& v) const          { const T* data = Data;  const T* data_end = Data + Size; while (data < data_end) if (*data++ == v) return true; return false; }
 | 
			
		||||
    inline int          index_from_ptr(const T* it) const   { IM_ASSERT(it >= Data && it <= Data+Size); const ptrdiff_t off = it - Data; return (int)off; }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
//-----------------------------------------------------------------------------
 | 
			
		||||
@@ -1936,11 +1926,11 @@ struct ImDrawList
 | 
			
		||||
    IMGUI_API void  AddBezierCurve(const ImVec2& pos0, const ImVec2& cp0, const ImVec2& cp1, const ImVec2& pos1, ImU32 col, float thickness, int num_segments = 0);
 | 
			
		||||
 | 
			
		||||
    // Stateful path API, add points then finish with PathFillConvex() or PathStroke()
 | 
			
		||||
    inline    void  PathClear()                                                 { _Path.resize(0); }
 | 
			
		||||
    inline    void  PathClear()                                                 { _Path.Size = 0; }
 | 
			
		||||
    inline    void  PathLineTo(const ImVec2& pos)                               { _Path.push_back(pos); }
 | 
			
		||||
    inline    void  PathLineToMergeDuplicate(const ImVec2& pos)                 { if (_Path.Size == 0 || memcmp(&_Path[_Path.Size-1], &pos, 8) != 0) _Path.push_back(pos); }
 | 
			
		||||
    inline    void  PathFillConvex(ImU32 col)                                   { AddConvexPolyFilled(_Path.Data, _Path.Size, col); PathClear(); }  // Note: Anti-aliased filling requires points to be in clockwise order.
 | 
			
		||||
    inline    void  PathStroke(ImU32 col, bool closed, float thickness = 1.0f)  { AddPolyline(_Path.Data, _Path.Size, col, closed, thickness); PathClear(); }
 | 
			
		||||
    inline    void  PathLineToMergeDuplicate(const ImVec2& pos)                 { if (_Path.Size == 0 || memcmp(&_Path.Data[_Path.Size-1], &pos, 8) != 0) _Path.push_back(pos); }
 | 
			
		||||
    inline    void  PathFillConvex(ImU32 col)                                   { AddConvexPolyFilled(_Path.Data, _Path.Size, col); _Path.Size = 0; }  // Note: Anti-aliased filling requires points to be in clockwise order.
 | 
			
		||||
    inline    void  PathStroke(ImU32 col, bool closed, float thickness = 1.0f)  { AddPolyline(_Path.Data, _Path.Size, col, closed, thickness); _Path.Size = 0; }
 | 
			
		||||
    IMGUI_API void  PathArcTo(const ImVec2& centre, float radius, float a_min, float a_max, int num_segments = 10);
 | 
			
		||||
    IMGUI_API void  PathArcToFast(const ImVec2& centre, float radius, int a_min_of_12, int a_max_of_12);                                            // Use precomputed angles for a 12 steps circle
 | 
			
		||||
    IMGUI_API void  PathBezierCurveTo(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, int num_segments = 0);
 | 
			
		||||
@@ -2032,12 +2022,14 @@ struct ImFontGlyph
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// Helper to build glyph ranges from text/string data. Feed your application strings/characters to it then call BuildRanges().
 | 
			
		||||
// This is essentially a tightly packed of vector of 64k booleans = 8KB storage.
 | 
			
		||||
struct ImFontGlyphRangesBuilder
 | 
			
		||||
{
 | 
			
		||||
    ImVector<unsigned char> UsedChars;  // Store 1-bit per Unicode code point (0=unused, 1=used)
 | 
			
		||||
    ImFontGlyphRangesBuilder()          { UsedChars.resize(0x10000 / 8); memset(UsedChars.Data, 0, 0x10000 / 8); }
 | 
			
		||||
    bool           GetBit(int n) const  { return (UsedChars[n >> 3] & (1 << (n & 7))) != 0; }
 | 
			
		||||
    void           SetBit(int n)        { UsedChars[n >> 3] |= 1 << (n & 7); }  // Set bit 'c' in the array
 | 
			
		||||
    ImVector<int> UsedChars;            // Store 1-bit per Unicode code point (0=unused, 1=used)
 | 
			
		||||
 | 
			
		||||
    ImFontGlyphRangesBuilder()          { UsedChars.resize(0x10000 / 32); memset(UsedChars.Data, 0, 0x10000 / 32); }
 | 
			
		||||
    bool           GetBit(int n) const  { int off = (n >> 5); int mask = 1 << (n & 31); return (UsedChars[off] & mask) != 0; } // Get bit n in the array
 | 
			
		||||
    void           SetBit(int n)        { int off = (n >> 5); int mask = 1 << (n & 31); UsedChars[off] |= mask; }              // Set bit n in the array
 | 
			
		||||
    void           AddChar(ImWchar c)   { SetBit(c); }                          // Add character
 | 
			
		||||
    IMGUI_API void AddText(const char* text, const char* text_end = NULL);      // Add string (each character of the UTF-8 string are added)
 | 
			
		||||
    IMGUI_API void AddRanges(const ImWchar* ranges);                            // Add ranges, e.g. builder.AddRanges(ImFontAtlas::GetGlyphRangesDefault()) to force add all of ASCII/Latin+Ext
 | 
			
		||||
 
 | 
			
		||||
@@ -4201,7 +4201,7 @@ void ShowExampleAppDocuments(bool* p_open)
 | 
			
		||||
{
 | 
			
		||||
    static ExampleAppDocuments app;
 | 
			
		||||
 | 
			
		||||
    if (!ImGui::Begin("Examples: Documents", p_open, ImGuiWindowFlags_MenuBar))
 | 
			
		||||
    if (!ImGui::Begin("Example: Documents", p_open, ImGuiWindowFlags_MenuBar))
 | 
			
		||||
    {
 | 
			
		||||
        ImGui::End();
 | 
			
		||||
        return;
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										116
									
								
								imgui_draw.cpp
									
									
									
									
									
								
							
							
						
						
									
										116
									
								
								imgui_draw.cpp
									
									
									
									
									
								
							@@ -662,7 +662,13 @@ void ImDrawList::PrimQuadUV(const ImVec2& a, const ImVec2& b, const ImVec2& c, c
 | 
			
		||||
    _IdxWritePtr += 6;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// On AddPolyline() and AddConvexPolyFilled() we intentionally avoid using ImVec2 and superflous function calls to optimize debug/non-inlined builds.
 | 
			
		||||
// Those macros expects l-values.
 | 
			
		||||
#define IM_NORMALIZE2F_OVER_ZERO(VX,VY)                         { float d2 = VX*VX + VY*VY; if (d2 > 0.0f) { float inv_len = 1.0f / ImSqrt(d2); VX *= inv_len; VY *= inv_len; } }
 | 
			
		||||
#define IM_NORMALIZE2F_OVER_EPSILON_CLAMP(VX,VY,EPS,INVLENMAX)  { float d2 = VX*VX + VY*VY; if (d2 > EPS)  { float inv_len = 1.0f / ImSqrt(d2); if (inv_len > INVLENMAX) inv_len = INVLENMAX; VX *= inv_len; VY *= inv_len; } }
 | 
			
		||||
 | 
			
		||||
// TODO: Thickness anti-aliased lines cap are missing their AA fringe.
 | 
			
		||||
// We avoid using the ImVec2 math operators here to reduce cost to a minimum for debug/non-inlined builds.
 | 
			
		||||
void ImDrawList::AddPolyline(const ImVec2* points, const int points_count, ImU32 col, bool closed, float thickness)
 | 
			
		||||
{
 | 
			
		||||
    if (points_count < 2)
 | 
			
		||||
@@ -692,10 +698,11 @@ void ImDrawList::AddPolyline(const ImVec2* points, const int points_count, ImU32
 | 
			
		||||
        for (int i1 = 0; i1 < count; i1++)
 | 
			
		||||
        {
 | 
			
		||||
            const int i2 = (i1+1) == points_count ? 0 : i1+1;
 | 
			
		||||
            ImVec2 diff = points[i2] - points[i1];
 | 
			
		||||
            diff *= ImInvLength(diff, 1.0f);
 | 
			
		||||
            temp_normals[i1].x = diff.y;
 | 
			
		||||
            temp_normals[i1].y = -diff.x;
 | 
			
		||||
            float dx = points[i2].x - points[i1].x;
 | 
			
		||||
            float dy = points[i2].y - points[i1].y;
 | 
			
		||||
            IM_NORMALIZE2F_OVER_ZERO(dx, dy);
 | 
			
		||||
            temp_normals[i1].x = dy;
 | 
			
		||||
            temp_normals[i1].y = -dx;
 | 
			
		||||
        }
 | 
			
		||||
        if (!closed)
 | 
			
		||||
            temp_normals[points_count-1] = temp_normals[points_count-2];
 | 
			
		||||
@@ -718,17 +725,18 @@ void ImDrawList::AddPolyline(const ImVec2* points, const int points_count, ImU32
 | 
			
		||||
                unsigned int idx2 = (i1+1) == points_count ? _VtxCurrentIdx : idx1+3;
 | 
			
		||||
 | 
			
		||||
                // Average normals
 | 
			
		||||
                ImVec2 dm = (temp_normals[i1] + temp_normals[i2]) * 0.5f;
 | 
			
		||||
                float dmr2 = dm.x*dm.x + dm.y*dm.y;
 | 
			
		||||
                if (dmr2 > 0.000001f)
 | 
			
		||||
                {
 | 
			
		||||
                    float scale = 1.0f / dmr2;
 | 
			
		||||
                    if (scale > 100.0f) scale = 100.0f;
 | 
			
		||||
                    dm *= scale;
 | 
			
		||||
                }
 | 
			
		||||
                dm *= AA_SIZE;
 | 
			
		||||
                temp_points[i2*2+0] = points[i2] + dm;
 | 
			
		||||
                temp_points[i2*2+1] = points[i2] - dm;
 | 
			
		||||
                float dm_x = (temp_normals[i1].x + temp_normals[i2].x) * 0.5f;
 | 
			
		||||
                float dm_y = (temp_normals[i1].y + temp_normals[i2].y) * 0.5f;
 | 
			
		||||
                IM_NORMALIZE2F_OVER_EPSILON_CLAMP(dm_x, dm_y, 0.000001f, 100.0f)
 | 
			
		||||
                dm_x *= AA_SIZE;
 | 
			
		||||
                dm_y *= AA_SIZE;
 | 
			
		||||
 | 
			
		||||
                // Add temporary vertexes
 | 
			
		||||
                ImVec2* out_vtx = &temp_points[i2*2];
 | 
			
		||||
                out_vtx[0].x = points[i2].x + dm_x;
 | 
			
		||||
                out_vtx[0].y = points[i2].y + dm_y;
 | 
			
		||||
                out_vtx[1].x = points[i2].x - dm_x;
 | 
			
		||||
                out_vtx[1].y = points[i2].y - dm_y;
 | 
			
		||||
 | 
			
		||||
                // Add indexes
 | 
			
		||||
                _IdxWritePtr[0] = (ImDrawIdx)(idx2+0); _IdxWritePtr[1] = (ImDrawIdx)(idx1+0); _IdxWritePtr[2] = (ImDrawIdx)(idx1+2);
 | 
			
		||||
@@ -772,20 +780,24 @@ void ImDrawList::AddPolyline(const ImVec2* points, const int points_count, ImU32
 | 
			
		||||
                unsigned int idx2 = (i1+1) == points_count ? _VtxCurrentIdx : idx1+4;
 | 
			
		||||
 | 
			
		||||
                // Average normals
 | 
			
		||||
                ImVec2 dm = (temp_normals[i1] + temp_normals[i2]) * 0.5f;
 | 
			
		||||
                float dmr2 = dm.x*dm.x + dm.y*dm.y;
 | 
			
		||||
                if (dmr2 > 0.000001f)
 | 
			
		||||
                {
 | 
			
		||||
                    float scale = 1.0f / dmr2;
 | 
			
		||||
                    if (scale > 100.0f) scale = 100.0f;
 | 
			
		||||
                    dm *= scale;
 | 
			
		||||
                }
 | 
			
		||||
                ImVec2 dm_out = dm * (half_inner_thickness + AA_SIZE);
 | 
			
		||||
                ImVec2 dm_in = dm * half_inner_thickness;
 | 
			
		||||
                temp_points[i2*4+0] = points[i2] + dm_out;
 | 
			
		||||
                temp_points[i2*4+1] = points[i2] + dm_in;
 | 
			
		||||
                temp_points[i2*4+2] = points[i2] - dm_in;
 | 
			
		||||
                temp_points[i2*4+3] = points[i2] - dm_out;
 | 
			
		||||
                float dm_x = (temp_normals[i1].x + temp_normals[i2].x) * 0.5f;
 | 
			
		||||
                float dm_y = (temp_normals[i1].y + temp_normals[i2].y) * 0.5f;
 | 
			
		||||
                IM_NORMALIZE2F_OVER_EPSILON_CLAMP(dm_x, dm_y, 0.000001f, 100.0f);
 | 
			
		||||
                float dm_out_x = dm_x * (half_inner_thickness + AA_SIZE);
 | 
			
		||||
                float dm_out_y = dm_y * (half_inner_thickness + AA_SIZE);
 | 
			
		||||
                float dm_in_x = dm_x * half_inner_thickness;
 | 
			
		||||
                float dm_in_y = dm_y * half_inner_thickness;
 | 
			
		||||
 | 
			
		||||
                // Add temporary vertexes
 | 
			
		||||
                ImVec2* out_vtx = &temp_points[i2*4];
 | 
			
		||||
                out_vtx[0].x = points[i2].x + dm_out_x;
 | 
			
		||||
                out_vtx[0].y = points[i2].y + dm_out_y;
 | 
			
		||||
                out_vtx[1].x = points[i2].x + dm_in_x;
 | 
			
		||||
                out_vtx[1].y = points[i2].y + dm_in_y;
 | 
			
		||||
                out_vtx[2].x = points[i2].x - dm_in_x;
 | 
			
		||||
                out_vtx[2].y = points[i2].y - dm_in_y;
 | 
			
		||||
                out_vtx[3].x = points[i2].x - dm_out_x;
 | 
			
		||||
                out_vtx[3].y = points[i2].y - dm_out_y;
 | 
			
		||||
 | 
			
		||||
                // Add indexes
 | 
			
		||||
                _IdxWritePtr[0]  = (ImDrawIdx)(idx2+1); _IdxWritePtr[1]  = (ImDrawIdx)(idx1+1); _IdxWritePtr[2]  = (ImDrawIdx)(idx1+2);
 | 
			
		||||
@@ -823,11 +835,13 @@ void ImDrawList::AddPolyline(const ImVec2* points, const int points_count, ImU32
 | 
			
		||||
            const int i2 = (i1+1) == points_count ? 0 : i1+1;
 | 
			
		||||
            const ImVec2& p1 = points[i1];
 | 
			
		||||
            const ImVec2& p2 = points[i2];
 | 
			
		||||
            ImVec2 diff = p2 - p1;
 | 
			
		||||
            diff *= ImInvLength(diff, 1.0f);
 | 
			
		||||
 | 
			
		||||
            const float dx = diff.x * (thickness * 0.5f);
 | 
			
		||||
            const float dy = diff.y * (thickness * 0.5f);
 | 
			
		||||
            float dx = p2.x - p1.x;
 | 
			
		||||
            float dy = p2.y - p1.y;
 | 
			
		||||
            IM_NORMALIZE2F_OVER_ZERO(dx, dy);
 | 
			
		||||
            dx *= (thickness * 0.5f);
 | 
			
		||||
            dy *= (thickness * 0.5f);
 | 
			
		||||
 | 
			
		||||
            _VtxWritePtr[0].pos.x = p1.x + dy; _VtxWritePtr[0].pos.y = p1.y - dx; _VtxWritePtr[0].uv = uv; _VtxWritePtr[0].col = col;
 | 
			
		||||
            _VtxWritePtr[1].pos.x = p2.x + dy; _VtxWritePtr[1].pos.y = p2.y - dx; _VtxWritePtr[1].uv = uv; _VtxWritePtr[1].col = col;
 | 
			
		||||
            _VtxWritePtr[2].pos.x = p2.x - dy; _VtxWritePtr[2].pos.y = p2.y + dx; _VtxWritePtr[2].uv = uv; _VtxWritePtr[2].col = col;
 | 
			
		||||
@@ -842,6 +856,7 @@ void ImDrawList::AddPolyline(const ImVec2* points, const int points_count, ImU32
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// We intentionally avoid using ImVec2 and its math operators here to reduce cost to a minimum for debug/non-inlined builds.
 | 
			
		||||
void ImDrawList::AddConvexPolyFilled(const ImVec2* points, const int points_count, ImU32 col)
 | 
			
		||||
{
 | 
			
		||||
    if (points_count < 3)
 | 
			
		||||
@@ -873,10 +888,11 @@ void ImDrawList::AddConvexPolyFilled(const ImVec2* points, const int points_coun
 | 
			
		||||
        {
 | 
			
		||||
            const ImVec2& p0 = points[i0];
 | 
			
		||||
            const ImVec2& p1 = points[i1];
 | 
			
		||||
            ImVec2 diff = p1 - p0;
 | 
			
		||||
            diff *= ImInvLength(diff, 1.0f);
 | 
			
		||||
            temp_normals[i0].x = diff.y;
 | 
			
		||||
            temp_normals[i0].y = -diff.x;
 | 
			
		||||
            float dx = p1.x - p0.x;
 | 
			
		||||
            float dy = p1.y - p0.y;
 | 
			
		||||
            IM_NORMALIZE2F_OVER_ZERO(dx, dy);
 | 
			
		||||
            temp_normals[i0].x = dy;
 | 
			
		||||
            temp_normals[i0].y = -dx;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        for (int i0 = points_count-1, i1 = 0; i1 < points_count; i0 = i1++)
 | 
			
		||||
@@ -884,19 +900,15 @@ void ImDrawList::AddConvexPolyFilled(const ImVec2* points, const int points_coun
 | 
			
		||||
            // Average normals
 | 
			
		||||
            const ImVec2& n0 = temp_normals[i0];
 | 
			
		||||
            const ImVec2& n1 = temp_normals[i1];
 | 
			
		||||
            ImVec2 dm = (n0 + n1) * 0.5f;
 | 
			
		||||
            float dmr2 = dm.x*dm.x + dm.y*dm.y;
 | 
			
		||||
            if (dmr2 > 0.000001f)
 | 
			
		||||
            {
 | 
			
		||||
                float scale = 1.0f / dmr2;
 | 
			
		||||
                if (scale > 100.0f) scale = 100.0f;
 | 
			
		||||
                dm *= scale;
 | 
			
		||||
            }
 | 
			
		||||
            dm *= AA_SIZE * 0.5f;
 | 
			
		||||
            float dm_x = (n0.x + n1.x) * 0.5f;
 | 
			
		||||
            float dm_y = (n0.y + n1.y) * 0.5f;
 | 
			
		||||
            IM_NORMALIZE2F_OVER_EPSILON_CLAMP(dm_x, dm_y, 0.000001f, 100.0f);
 | 
			
		||||
            dm_x *= AA_SIZE * 0.5f;
 | 
			
		||||
            dm_y *= AA_SIZE * 0.5f;
 | 
			
		||||
 | 
			
		||||
            // Add vertices
 | 
			
		||||
            _VtxWritePtr[0].pos = (points[i1] - dm); _VtxWritePtr[0].uv = uv; _VtxWritePtr[0].col = col;        // Inner
 | 
			
		||||
            _VtxWritePtr[1].pos = (points[i1] + dm); _VtxWritePtr[1].uv = uv; _VtxWritePtr[1].col = col_trans;  // Outer
 | 
			
		||||
            _VtxWritePtr[0].pos.x = (points[i1].x - dm_x); _VtxWritePtr[0].pos.y = (points[i1].y - dm_y); _VtxWritePtr[0].uv = uv; _VtxWritePtr[0].col = col;        // Inner
 | 
			
		||||
            _VtxWritePtr[1].pos.x = (points[i1].x + dm_x); _VtxWritePtr[1].pos.y = (points[i1].y + dm_y); _VtxWritePtr[1].uv = uv; _VtxWritePtr[1].col = col_trans;  // Outer
 | 
			
		||||
            _VtxWritePtr += 2;
 | 
			
		||||
 | 
			
		||||
            // Add indexes for fringes
 | 
			
		||||
@@ -2428,7 +2440,7 @@ const ImFontGlyph* ImFont::FindGlyph(ImWchar c) const
 | 
			
		||||
{
 | 
			
		||||
    if (c >= IndexLookup.Size)
 | 
			
		||||
        return FallbackGlyph;
 | 
			
		||||
    const ImWchar i = IndexLookup[c];
 | 
			
		||||
    const ImWchar i = IndexLookup.Data[c];
 | 
			
		||||
    if (i == (ImWchar)-1)
 | 
			
		||||
        return FallbackGlyph;
 | 
			
		||||
    return &Glyphs.Data[i];
 | 
			
		||||
@@ -2438,7 +2450,7 @@ const ImFontGlyph* ImFont::FindGlyphNoFallback(ImWchar c) const
 | 
			
		||||
{
 | 
			
		||||
    if (c >= IndexLookup.Size)
 | 
			
		||||
        return NULL;
 | 
			
		||||
    const ImWchar i = IndexLookup[c];
 | 
			
		||||
    const ImWchar i = IndexLookup.Data[c];
 | 
			
		||||
    if (i == (ImWchar)-1)
 | 
			
		||||
        return NULL;
 | 
			
		||||
    return &Glyphs.Data[i];
 | 
			
		||||
@@ -2498,7 +2510,7 @@ const char* ImFont::CalcWordWrapPositionA(float scale, const char* text, const c
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        const float char_width = ((int)c < IndexAdvanceX.Size ? IndexAdvanceX[(int)c] : FallbackAdvanceX);
 | 
			
		||||
        const float char_width = ((int)c < IndexAdvanceX.Size ? IndexAdvanceX.Data[c] : FallbackAdvanceX);
 | 
			
		||||
        if (ImCharIsBlankW(c))
 | 
			
		||||
        {
 | 
			
		||||
            if (inside_word)
 | 
			
		||||
@@ -2615,7 +2627,7 @@ ImVec2 ImFont::CalcTextSizeA(float size, float max_width, float wrap_width, cons
 | 
			
		||||
                continue;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        const float char_width = ((int)c < IndexAdvanceX.Size ? IndexAdvanceX[(int)c] : FallbackAdvanceX) * scale;
 | 
			
		||||
        const float char_width = ((int)c < IndexAdvanceX.Size ? IndexAdvanceX.Data[c] : FallbackAdvanceX) * scale;
 | 
			
		||||
        if (line_width + char_width >= max_width)
 | 
			
		||||
        {
 | 
			
		||||
            s = prev_s;
 | 
			
		||||
 
 | 
			
		||||
@@ -6,8 +6,27 @@
 | 
			
		||||
//   #define IMGUI_DEFINE_MATH_OPERATORS
 | 
			
		||||
// To implement maths operators for ImVec2 (disabled by default to not collide with using IM_VEC2_CLASS_EXTRA along with your own math types+operators)
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 | 
			
		||||
Index of this file:
 | 
			
		||||
// Header mess
 | 
			
		||||
// Forward declarations
 | 
			
		||||
// STB libraries includes
 | 
			
		||||
// Context pointer
 | 
			
		||||
// Generic helpers
 | 
			
		||||
// Misc data structures
 | 
			
		||||
// Main imgui context
 | 
			
		||||
// Tab bar, tab item
 | 
			
		||||
// Internal API
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
//-----------------------------------------------------------------------------
 | 
			
		||||
// Header mess
 | 
			
		||||
//-----------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
#ifndef IMGUI_VERSION
 | 
			
		||||
#error Must include imgui.h before imgui_internal.h
 | 
			
		||||
#endif
 | 
			
		||||
@@ -30,7 +49,7 @@
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
//-----------------------------------------------------------------------------
 | 
			
		||||
// Forward Declarations
 | 
			
		||||
// Forward declarations
 | 
			
		||||
//-----------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
struct ImRect;                      // An axis-aligned rectangle (2 points)
 | 
			
		||||
@@ -71,7 +90,7 @@ typedef int ImGuiSliderFlags;       // -> enum ImGuiSliderFlags_       // Flags:
 | 
			
		||||
typedef int ImGuiDragFlags;         // -> enum ImGuiDragFlags_         // Flags: for DragBehavior()
 | 
			
		||||
 | 
			
		||||
//-------------------------------------------------------------------------
 | 
			
		||||
// STB libraries
 | 
			
		||||
// STB libraries includes
 | 
			
		||||
//-------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
namespace ImGuiStb
 | 
			
		||||
@@ -87,7 +106,7 @@ namespace ImGuiStb
 | 
			
		||||
} // namespace ImGuiStb
 | 
			
		||||
 | 
			
		||||
//-----------------------------------------------------------------------------
 | 
			
		||||
// Context
 | 
			
		||||
// Context pointer
 | 
			
		||||
//-----------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
#ifndef GImGui
 | 
			
		||||
@@ -98,7 +117,7 @@ extern IMGUI_API ImGuiContext* GImGui;  // Current implicit ImGui context pointe
 | 
			
		||||
#define IMGUI_PAYLOAD_TYPE_WINDOW       "_IMWINDOW"     // Payload == ImGuiWindow*
 | 
			
		||||
 | 
			
		||||
//-----------------------------------------------------------------------------
 | 
			
		||||
// Helpers
 | 
			
		||||
// Generic helpers
 | 
			
		||||
//-----------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
#define IM_PI           3.14159265358979323846f
 | 
			
		||||
@@ -150,6 +169,7 @@ IMGUI_API int           ImStricmp(const char* str1, const char* str2);
 | 
			
		||||
IMGUI_API int           ImStrnicmp(const char* str1, const char* str2, size_t count);
 | 
			
		||||
IMGUI_API void          ImStrncpy(char* dst, const char* src, size_t count);
 | 
			
		||||
IMGUI_API char*         ImStrdup(const char* str);
 | 
			
		||||
IMGUI_API char*         ImStrdupcpy(char* dst, size_t* p_dst_size, const char* str);
 | 
			
		||||
IMGUI_API const char*   ImStrchrRange(const char* str_begin, const char* str_end, char c);
 | 
			
		||||
IMGUI_API int           ImStrlenW(const ImWchar* str);
 | 
			
		||||
IMGUI_API const char*   ImStreolRange(const char* str, const char* str_end);                // End end-of-line
 | 
			
		||||
@@ -249,7 +269,7 @@ struct IMGUI_API ImPool
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
//-----------------------------------------------------------------------------
 | 
			
		||||
// Types
 | 
			
		||||
// Misc data structures
 | 
			
		||||
//-----------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
enum ImGuiButtonFlags_
 | 
			
		||||
@@ -343,8 +363,8 @@ enum ImGuiItemStatusFlags_
 | 
			
		||||
// FIXME: this is in development, not exposed/functional as a generic feature yet.
 | 
			
		||||
enum ImGuiLayoutType_
 | 
			
		||||
{
 | 
			
		||||
    ImGuiLayoutType_Vertical,
 | 
			
		||||
    ImGuiLayoutType_Horizontal
 | 
			
		||||
    ImGuiLayoutType_Vertical = 0,
 | 
			
		||||
    ImGuiLayoutType_Horizontal = 1
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
enum ImGuiAxis
 | 
			
		||||
@@ -1217,6 +1237,7 @@ struct IMGUI_API ImGuiWindow
 | 
			
		||||
    ImVec2                  WindowPadding;                      // Window padding at the time of begin.
 | 
			
		||||
    float                   WindowRounding;                     // Window rounding at the time of begin.
 | 
			
		||||
    float                   WindowBorderSize;                   // Window border size at the time of begin.
 | 
			
		||||
    int                     NameBufLen;                         // Size of buffer storing Name. May be larger than strlen(Name)!
 | 
			
		||||
    ImGuiID                 MoveId;                             // == window->GetID("#MOVE")
 | 
			
		||||
    ImGuiID                 ChildId;                            // ID of corresponding item in parent window (for navigation to return from child window to parent window)
 | 
			
		||||
    ImVec2                  Scroll;
 | 
			
		||||
@@ -1332,7 +1353,7 @@ struct ImGuiItemHoveredDataBackup
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
//-----------------------------------------------------------------------------
 | 
			
		||||
// Tab Bar, Tab Item
 | 
			
		||||
// Tab bar, tab item
 | 
			
		||||
//-----------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
enum ImGuiTabBarFlagsPrivate_
 | 
			
		||||
@@ -1389,7 +1410,7 @@ struct ImGuiTabBar
 | 
			
		||||
    short               LastTabItemIdx;         // For BeginTabItem()/EndTabItem()
 | 
			
		||||
 | 
			
		||||
    ImGuiTabBar();
 | 
			
		||||
    int                 GetTabOrder(const ImGuiTabItem* tab) const { return Tabs.index_from_pointer(tab); }
 | 
			
		||||
    int                 GetTabOrder(const ImGuiTabItem* tab) const { return Tabs.index_from_ptr(tab); }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
//-----------------------------------------------------------------------------
 | 
			
		||||
@@ -1638,11 +1659,11 @@ IMGUI_API void              ImFontAtlasBuildMultiplyRectAlpha8(const unsigned ch
 | 
			
		||||
// Test engine hooks (imgui-test)
 | 
			
		||||
//#define IMGUI_ENABLE_TEST_ENGINE
 | 
			
		||||
#ifdef IMGUI_ENABLE_TEST_ENGINE
 | 
			
		||||
extern void                 ImGuiTestEngineHook_PreNewFrame();
 | 
			
		||||
extern void                 ImGuiTestEngineHook_PostNewFrame();
 | 
			
		||||
extern void                 ImGuiTestEngineHook_ItemAdd(const ImRect& bb, ImGuiID id);
 | 
			
		||||
extern void                 ImGuiTestEngineHook_ItemInfo(ImGuiID id, const char* label, int flags);
 | 
			
		||||
#define IMGUI_TEST_ENGINE_ITEM_INFO(_ID, _LABEL, _FLAGS)  ImGuiTestEngineHook_ItemInfo(_ID, _LABEL, _FLAGS)   // Register status flags
 | 
			
		||||
extern void                 ImGuiTestEngineHook_PreNewFrame(ImGuiContext* ctx);
 | 
			
		||||
extern void                 ImGuiTestEngineHook_PostNewFrame(ImGuiContext* ctx);
 | 
			
		||||
extern void                 ImGuiTestEngineHook_ItemAdd(ImGuiContext* ctx, const ImRect& bb, ImGuiID id);
 | 
			
		||||
extern void                 ImGuiTestEngineHook_ItemInfo(ImGuiContext* ctx, ImGuiID id, const char* label, int flags);
 | 
			
		||||
#define IMGUI_TEST_ENGINE_ITEM_INFO(_ID, _LABEL, _FLAGS)  ImGuiTestEngineHook_ItemInfo(&g, _ID, _LABEL, _FLAGS)   // Register status flags
 | 
			
		||||
#else
 | 
			
		||||
#define IMGUI_TEST_ENGINE_ITEM_INFO(_ID, _LABEL, _FLAGS)  do { } while (0)
 | 
			
		||||
#endif
 | 
			
		||||
 
 | 
			
		||||
@@ -204,7 +204,7 @@ void ImGui::TextUnformatted(const char* text, const char* text_end)
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        ImRect bb(text_pos, text_pos + text_size);
 | 
			
		||||
        ItemSize(bb);
 | 
			
		||||
        ItemSize(text_size);
 | 
			
		||||
        ItemAdd(bb, 0);
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
@@ -282,10 +282,12 @@ void ImGui::TextWrapped(const char* fmt, ...)
 | 
			
		||||
 | 
			
		||||
void ImGui::TextWrappedV(const char* fmt, va_list args)
 | 
			
		||||
{
 | 
			
		||||
    bool need_wrap = (GImGui->CurrentWindow->DC.TextWrapPos < 0.0f);    // Keep existing wrap position is one ia already set
 | 
			
		||||
    if (need_wrap) PushTextWrapPos(0.0f);
 | 
			
		||||
    bool need_backup = (GImGui->CurrentWindow->DC.TextWrapPos < 0.0f);  // Keep existing wrap position if one is already set
 | 
			
		||||
    if (need_backup)
 | 
			
		||||
        PushTextWrapPos(0.0f);
 | 
			
		||||
    TextV(fmt, args);
 | 
			
		||||
    if (need_wrap) PopTextWrapPos();
 | 
			
		||||
    if (need_backup)
 | 
			
		||||
        PopTextWrapPos();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ImGui::LabelText(const char* label, const char* fmt, ...)
 | 
			
		||||
@@ -398,8 +400,8 @@ bool ImGui::ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool
 | 
			
		||||
        g.HoveredWindow = window;
 | 
			
		||||
 | 
			
		||||
#ifdef IMGUI_ENABLE_TEST_ENGINE
 | 
			
		||||
    if (window->DC.LastItemId != id)
 | 
			
		||||
        ImGuiTestEngineHook_ItemAdd(bb, id);
 | 
			
		||||
    if (id != 0 && window->DC.LastItemId != id)
 | 
			
		||||
        ImGuiTestEngineHook_ItemAdd(&g, bb, id);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    bool pressed = false;
 | 
			
		||||
@@ -547,7 +549,7 @@ bool ImGui::ButtonEx(const char* label, const ImVec2& size_arg, ImGuiButtonFlags
 | 
			
		||||
    ImVec2 size = CalcItemSize(size_arg, label_size.x + style.FramePadding.x * 2.0f, label_size.y + style.FramePadding.y * 2.0f);
 | 
			
		||||
 | 
			
		||||
    const ImRect bb(pos, pos + size);
 | 
			
		||||
    ItemSize(bb, style.FramePadding.y);
 | 
			
		||||
    ItemSize(size, style.FramePadding.y);
 | 
			
		||||
    if (!ItemAdd(bb, id))
 | 
			
		||||
        return false;
 | 
			
		||||
 | 
			
		||||
@@ -601,7 +603,7 @@ bool ImGui::InvisibleButton(const char* str_id, const ImVec2& size_arg)
 | 
			
		||||
    const ImGuiID id = window->GetID(str_id);
 | 
			
		||||
    ImVec2 size = CalcItemSize(size_arg, 0.0f, 0.0f);
 | 
			
		||||
    const ImRect bb(window->DC.CursorPos, window->DC.CursorPos + size);
 | 
			
		||||
    ItemSize(bb);
 | 
			
		||||
    ItemSize(size);
 | 
			
		||||
    if (!ItemAdd(bb, id))
 | 
			
		||||
        return false;
 | 
			
		||||
 | 
			
		||||
@@ -5064,7 +5066,7 @@ bool ImGui::Selectable(const char* label, bool selected, ImGuiSelectableFlags fl
 | 
			
		||||
    bb.Min.y -= spacing_U;
 | 
			
		||||
    bb.Max.x += spacing_R;
 | 
			
		||||
    bb.Max.y += spacing_D;
 | 
			
		||||
    if (!ItemAdd(bb, (flags & ImGuiSelectableFlags_Disabled) ? 0 : id))
 | 
			
		||||
    if (!ItemAdd(bb, id))
 | 
			
		||||
    {
 | 
			
		||||
        if ((flags & ImGuiSelectableFlags_SpanAllColumns) && window->DC.ColumnsSet)
 | 
			
		||||
            PushColumnClipRect();
 | 
			
		||||
@@ -6395,7 +6397,7 @@ bool    ImGui::TabItemEx(ImGuiTabBar* tab_bar, const char* label, bool* p_open,
 | 
			
		||||
        tab->Width = size.x;
 | 
			
		||||
        tab_is_new = true;
 | 
			
		||||
    }
 | 
			
		||||
    tab_bar->LastTabItemIdx = (short)tab_bar->Tabs.index_from_pointer(tab);
 | 
			
		||||
    tab_bar->LastTabItemIdx = (short)tab_bar->Tabs.index_from_ptr(tab);
 | 
			
		||||
    tab->WidthContents = size.x;
 | 
			
		||||
 | 
			
		||||
    const bool tab_bar_appearing = (tab_bar->PrevFrameVisible + 1 < g.FrameCount);
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user