mirror of
https://github.com/ocornut/imgui.git
synced 2024-11-15 19:43:28 +01:00
Merge branch 'master' into viewport
# Conflicts: # imgui.cpp # imgui.h
This commit is contained in:
commit
c96aaef132
@ -107,11 +107,14 @@ Other Changes:
|
|||||||
- InputFloat: When using ImGuiInputTextFlags_ReadOnly the step buttons are disabled. (#2257)
|
- 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
|
- 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)
|
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
|
- 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)
|
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.
|
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
|
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.
|
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: 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: 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
|
- 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)
|
- OpenSceneGraph/OSG: [gist](https://gist.github.com/fulezi/d2442ca7626bf270226014501357042c)
|
||||||
- ORX: [pr #1843](https://github.com/ocornut/imgui/pull/1843)
|
- ORX: [pr #1843](https://github.com/ocornut/imgui/pull/1843)
|
||||||
- LÖVE+Lua: [love-imgui](https://github.com/slages/love-imgui)
|
- 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)
|
- 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)
|
- 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)
|
- SFML: [imgui-sfml](https://github.com/EliasD/imgui-sfml)
|
||||||
|
@ -334,6 +334,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: 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 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: 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: 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/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
|
- optimization: turn some the various stack vectors into statically-sized arrays
|
||||||
|
98
imgui.cpp
98
imgui.cpp
@ -1284,11 +1284,25 @@ void ImStrncpy(char* dst, const char* src, size_t count)
|
|||||||
dst[count-1] = 0;
|
dst[count-1] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
char* ImStrdup(const char *str)
|
char* ImStrdup(const char* str)
|
||||||
{
|
{
|
||||||
size_t len = strlen(str) + 1;
|
size_t len = strlen(str);
|
||||||
void* buf = ImGui::MemAlloc(len);
|
void* buf = ImGui::MemAlloc(len + 1);
|
||||||
return (char*)memcpy(buf, (const void*)str, len);
|
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)
|
const char* ImStrchrRange(const char* str, const char* str_end, char c)
|
||||||
@ -1362,6 +1376,12 @@ void ImStrTrimBlanks(char* buf)
|
|||||||
// B) When buf==NULL vsnprintf() will return the output size.
|
// B) When buf==NULL vsnprintf() will return the output size.
|
||||||
#ifndef IMGUI_DISABLE_FORMAT_STRING_FUNCTIONS
|
#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)
|
#if defined(_MSC_VER) && !defined(vsnprintf)
|
||||||
#define vsnprintf _vsnprintf
|
#define vsnprintf _vsnprintf
|
||||||
#endif
|
#endif
|
||||||
@ -1370,7 +1390,11 @@ int ImFormatString(char* buf, size_t buf_size, const char* fmt, ...)
|
|||||||
{
|
{
|
||||||
va_list args;
|
va_list args;
|
||||||
va_start(args, fmt);
|
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);
|
int w = vsnprintf(buf, buf_size, fmt, args);
|
||||||
|
#endif
|
||||||
va_end(args);
|
va_end(args);
|
||||||
if (buf == NULL)
|
if (buf == NULL)
|
||||||
return w;
|
return w;
|
||||||
@ -1382,7 +1406,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)
|
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);
|
int w = vsnprintf(buf, buf_size, fmt, args);
|
||||||
|
#endif
|
||||||
if (buf == NULL)
|
if (buf == NULL)
|
||||||
return w;
|
return w;
|
||||||
if (w == -1 || w >= (int)buf_size)
|
if (w == -1 || w >= (int)buf_size)
|
||||||
@ -1392,7 +1420,9 @@ int ImFormatStringV(char* buf, size_t buf_size, const char* fmt, va_list args)
|
|||||||
}
|
}
|
||||||
#endif // #ifdef IMGUI_DISABLE_FORMAT_STRING_FUNCTIONS
|
#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.
|
// 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)
|
ImU32 ImHash(const void* data, int data_size, ImU32 seed)
|
||||||
{
|
{
|
||||||
@ -1791,15 +1821,15 @@ ImU32 ImGui::GetColorU32(ImU32 col)
|
|||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
// std::lower_bound but without the bullshit
|
// 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();
|
ImGuiStorage::Pair* first = data.Data;
|
||||||
ImVector<ImGuiStorage::Pair>::iterator last = data.end();
|
ImGuiStorage::Pair* last = data.Data + data.Size;
|
||||||
size_t count = (size_t)(last - first);
|
size_t count = (size_t)(last - first);
|
||||||
while (count > 0)
|
while (count > 0)
|
||||||
{
|
{
|
||||||
size_t count2 = count >> 1;
|
size_t count2 = count >> 1;
|
||||||
ImVector<ImGuiStorage::Pair>::iterator mid = first + count2;
|
ImGuiStorage::Pair* mid = first + count2;
|
||||||
if (mid->key < key)
|
if (mid->key < key)
|
||||||
{
|
{
|
||||||
first = ++mid;
|
first = ++mid;
|
||||||
@ -1832,7 +1862,7 @@ void ImGuiStorage::BuildSortByKey()
|
|||||||
|
|
||||||
int ImGuiStorage::GetInt(ImGuiID key, int default_val) const
|
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)
|
if (it == Data.end() || it->key != key)
|
||||||
return default_val;
|
return default_val;
|
||||||
return it->val_i;
|
return it->val_i;
|
||||||
@ -1845,7 +1875,7 @@ bool ImGuiStorage::GetBool(ImGuiID key, bool default_val) const
|
|||||||
|
|
||||||
float ImGuiStorage::GetFloat(ImGuiID key, float 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)
|
if (it == Data.end() || it->key != key)
|
||||||
return default_val;
|
return default_val;
|
||||||
return it->val_f;
|
return it->val_f;
|
||||||
@ -1853,7 +1883,7 @@ float ImGuiStorage::GetFloat(ImGuiID key, float default_val) const
|
|||||||
|
|
||||||
void* ImGuiStorage::GetVoidPtr(ImGuiID key) 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)
|
if (it == Data.end() || it->key != key)
|
||||||
return NULL;
|
return NULL;
|
||||||
return it->val_p;
|
return it->val_p;
|
||||||
@ -1862,7 +1892,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.
|
// 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)
|
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)
|
if (it == Data.end() || it->key != key)
|
||||||
it = Data.insert(it, Pair(key, default_val));
|
it = Data.insert(it, Pair(key, default_val));
|
||||||
return &it->val_i;
|
return &it->val_i;
|
||||||
@ -1875,7 +1905,7 @@ bool* ImGuiStorage::GetBoolRef(ImGuiID key, bool default_val)
|
|||||||
|
|
||||||
float* ImGuiStorage::GetFloatRef(ImGuiID key, float 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)
|
if (it == Data.end() || it->key != key)
|
||||||
it = Data.insert(it, Pair(key, default_val));
|
it = Data.insert(it, Pair(key, default_val));
|
||||||
return &it->val_f;
|
return &it->val_f;
|
||||||
@ -1883,7 +1913,7 @@ float* ImGuiStorage::GetFloatRef(ImGuiID key, float default_val)
|
|||||||
|
|
||||||
void** ImGuiStorage::GetVoidPtrRef(ImGuiID key, void* 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)
|
if (it == Data.end() || it->key != key)
|
||||||
it = Data.insert(it, Pair(key, default_val));
|
it = Data.insert(it, Pair(key, default_val));
|
||||||
return &it->val_p;
|
return &it->val_p;
|
||||||
@ -1892,7 +1922,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)
|
// 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)
|
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)
|
if (it == Data.end() || it->key != key)
|
||||||
{
|
{
|
||||||
Data.insert(it, Pair(key, val));
|
Data.insert(it, Pair(key, val));
|
||||||
@ -1908,7 +1938,7 @@ void ImGuiStorage::SetBool(ImGuiID key, bool val)
|
|||||||
|
|
||||||
void ImGuiStorage::SetFloat(ImGuiID key, float 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)
|
if (it == Data.end() || it->key != key)
|
||||||
{
|
{
|
||||||
Data.insert(it, Pair(key, val));
|
Data.insert(it, Pair(key, val));
|
||||||
@ -1919,7 +1949,7 @@ void ImGuiStorage::SetFloat(ImGuiID key, float val)
|
|||||||
|
|
||||||
void ImGuiStorage::SetVoidPtr(ImGuiID key, void* 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)
|
if (it == Data.end() || it->key != key)
|
||||||
{
|
{
|
||||||
Data.insert(it, Pair(key, val));
|
Data.insert(it, Pair(key, val));
|
||||||
@ -2420,6 +2450,7 @@ ImGuiWindow::ImGuiWindow(ImGuiContext* context, const char* name)
|
|||||||
WindowPadding = ImVec2(0.0f, 0.0f);
|
WindowPadding = ImVec2(0.0f, 0.0f);
|
||||||
WindowRounding = 0.0f;
|
WindowRounding = 0.0f;
|
||||||
WindowBorderSize = 0.0f;
|
WindowBorderSize = 0.0f;
|
||||||
|
NameBufLen = (int)strlen(name) + 1;
|
||||||
MoveId = GetID("#MOVE");
|
MoveId = GetID("#MOVE");
|
||||||
ChildId = 0;
|
ChildId = 0;
|
||||||
Scroll = ImVec2(0.0f, 0.0f);
|
Scroll = ImVec2(0.0f, 0.0f);
|
||||||
@ -2669,7 +2700,8 @@ void ImGui::ItemSize(const ImVec2& size, float text_offset_y)
|
|||||||
const float text_base_offset = ImMax(window->DC.CurrentLineTextBaseOffset, 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]
|
//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.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.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);
|
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]
|
//if (g.IO.KeyAlt) window->DrawList->AddCircle(window->DC.CursorMaxPos, 3.0f, IM_COL32(255,0,0,255), 4); // [DEBUG]
|
||||||
@ -2715,7 +2747,8 @@ bool ImGui::ItemAdd(const ImRect& bb, ImGuiID id, const ImRect* nav_bb_arg)
|
|||||||
window->DC.LastItemStatusFlags = ImGuiItemStatusFlags_None;
|
window->DC.LastItemStatusFlags = ImGuiItemStatusFlags_None;
|
||||||
|
|
||||||
#ifdef IMGUI_ENABLE_TEST_ENGINE
|
#ifdef IMGUI_ENABLE_TEST_ENGINE
|
||||||
ImGuiTestEngineHook_ItemAdd(bb, id);
|
if (id != 0)
|
||||||
|
ImGuiTestEngineHook_ItemAdd(&g, bb, id);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Clipping test
|
// Clipping test
|
||||||
@ -3330,7 +3363,7 @@ void ImGui::NewFrame()
|
|||||||
ImGuiContext& g = *GImGui;
|
ImGuiContext& g = *GImGui;
|
||||||
|
|
||||||
#ifdef IMGUI_ENABLE_TEST_ENGINE
|
#ifdef IMGUI_ENABLE_TEST_ENGINE
|
||||||
ImGuiTestEngineHook_PreNewFrame();
|
ImGuiTestEngineHook_PreNewFrame(&g);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Check user data
|
// Check user data
|
||||||
@ -3552,7 +3585,7 @@ void ImGui::NewFrame()
|
|||||||
g.FrameScopePushedImplicitWindow = true;
|
g.FrameScopePushedImplicitWindow = true;
|
||||||
|
|
||||||
#ifdef IMGUI_ENABLE_TEST_ENGINE
|
#ifdef IMGUI_ENABLE_TEST_ENGINE
|
||||||
ImGuiTestEngineHook_PostNewFrame();
|
ImGuiTestEngineHook_PostNewFrame(&g);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4553,7 +4586,7 @@ static ImGuiWindow* CreateNewWindow(const char* name, ImVec2 size, ImGuiWindowFl
|
|||||||
if (ImGuiWindowSettings* settings = ImGui::FindWindowSettings(window->ID))
|
if (ImGuiWindowSettings* settings = ImGui::FindWindowSettings(window->ID))
|
||||||
{
|
{
|
||||||
// Retrieve settings from .ini file
|
// 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);
|
SetWindowConditionAllowFlags(window, ImGuiCond_FirstUseEver, false);
|
||||||
if (settings->ViewportId)
|
if (settings->ViewportId)
|
||||||
{
|
{
|
||||||
@ -5036,13 +5069,18 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
|
|||||||
window->ClipRect = ImVec4(-FLT_MAX,-FLT_MAX,+FLT_MAX,+FLT_MAX);
|
window->ClipRect = ImVec4(-FLT_MAX,-FLT_MAX,+FLT_MAX,+FLT_MAX);
|
||||||
window->IDStack.resize(1);
|
window->IDStack.resize(1);
|
||||||
|
|
||||||
// Update stored window name when it changes (which can only happen with the "###" operator).
|
// 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 storage if the title is displayed to the end-user in a different place.
|
// 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 = (window->Viewport && window->Viewport->Window == window);
|
bool window_title_visible_elsewhere = false;
|
||||||
if (!window_just_created && window_title_visible_elsewhere && strcmp(name, window->Name) != 0)
|
if (window->Viewport && window->Viewport->Window == window)
|
||||||
|
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);
|
size_t buf_len = (size_t)window->NameBufLen;
|
||||||
window->Name = ImStrdup(name);
|
window->Name = ImStrdupcpy(window->Name, &buf_len, name);
|
||||||
|
window->NameBufLen = (int)buf_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
// UPDATE CONTENTS SIZE, UPDATE HIDDEN STATUS
|
// UPDATE CONTENTS SIZE, UPDATE HIDDEN STATUS
|
||||||
@ -9999,7 +10037,7 @@ static void SettingsHandlerWindow_WriteAll(ImGuiContext* imgui_ctx, ImGuiSetting
|
|||||||
if (!settings)
|
if (!settings)
|
||||||
{
|
{
|
||||||
settings = ImGui::CreateNewWindowSettings(window->Name);
|
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);
|
IM_ASSERT(settings->ID == window->ID);
|
||||||
settings->Pos = window->Pos - window->ViewportPos;
|
settings->Pos = window->Pos - window->ViewportPos;
|
||||||
|
90
imgui.h
90
imgui.h
@ -13,14 +13,14 @@ Index of this file:
|
|||||||
// Forward declarations and basic types
|
// Forward declarations and basic types
|
||||||
// ImGui API (Dear ImGui end-user API)
|
// ImGui API (Dear ImGui end-user API)
|
||||||
// Flags & Enumerations
|
// Flags & Enumerations
|
||||||
// ImVector
|
// ImVector<>
|
||||||
// ImGuiStyle
|
// ImGuiStyle
|
||||||
// ImGuiIO
|
// ImGuiIO
|
||||||
// Misc data structures (ImGuiInputTextCallbackData, ImGuiSizeCallbackData, ImGuiPayload)
|
// Misc data structures (ImGuiInputTextCallbackData, ImGuiSizeCallbackData, ImGuiPayload)
|
||||||
// Obsolete functions
|
// Obsolete functions
|
||||||
// Helpers (ImGuiOnceUponAFrame, ImGuiTextFilter, ImGuiTextBuffer, ImGuiStorage, ImGuiListClipper, ImColor)
|
// Helpers (ImGuiOnceUponAFrame, ImGuiTextFilter, ImGuiTextBuffer, ImGuiStorage, ImGuiListClipper, ImColor)
|
||||||
// Draw List API (ImDrawCmd, ImDrawIdx, ImDrawVert, ImDrawChannel, ImDrawListFlags, ImDrawList, ImDrawData)
|
// 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)
|
// Platform interface for multi-viewport support (ImGuiPlatformMonitor, ImGuiPlatformIO, ImGuiViewport)
|
||||||
|
|
||||||
*/
|
*/
|
||||||
@ -1189,73 +1189,63 @@ enum ImGuiCond_
|
|||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Helper: ImVector<>
|
// 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.
|
// 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,
|
// 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>
|
template<typename T>
|
||||||
class ImVector
|
struct ImVector
|
||||||
{
|
{
|
||||||
public:
|
|
||||||
int Size;
|
int Size;
|
||||||
int Capacity;
|
int Capacity;
|
||||||
T* Data;
|
T* Data;
|
||||||
|
|
||||||
|
// Provide standard typedefs but we don't use them ourselves.
|
||||||
typedef T value_type;
|
typedef T value_type;
|
||||||
typedef value_type* iterator;
|
typedef value_type* iterator;
|
||||||
typedef const value_type* const_iterator;
|
typedef const value_type* const_iterator;
|
||||||
|
|
||||||
|
// Constructors, destructor
|
||||||
inline ImVector() { Size = Capacity = 0; Data = NULL; }
|
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(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; }
|
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 bool empty() const { return Size == 0; }
|
||||||
inline int size() const { return Size; }
|
inline int size() const { return Size; }
|
||||||
inline int capacity() const { return Capacity; }
|
inline int capacity() const { return Capacity; }
|
||||||
inline value_type& operator[](int i) { IM_ASSERT(i < Size); return Data[i]; }
|
inline T& 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 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 void clear() { if (Data) { Size = Capacity = 0; ImGui::MemFree(Data); Data = NULL; } }
|
||||||
inline iterator begin() { return Data; }
|
inline T* begin() { return Data; }
|
||||||
inline const_iterator begin() const { return Data; }
|
inline const T* begin() const { return Data; }
|
||||||
inline iterator end() { return Data + Size; }
|
inline T* end() { return Data + Size; }
|
||||||
inline const_iterator end() const { return Data + Size; }
|
inline const T* end() const { return Data + Size; }
|
||||||
inline value_type& front() { IM_ASSERT(Size > 0); return Data[0]; }
|
inline T& front() { IM_ASSERT(Size > 0); return Data[0]; }
|
||||||
inline const value_type& front() const { IM_ASSERT(Size > 0); return Data[0]; }
|
inline const T& front() const { IM_ASSERT(Size > 0); return Data[0]; }
|
||||||
inline value_type& back() { IM_ASSERT(Size > 0); return Data[Size - 1]; }
|
inline T& back() { IM_ASSERT(Size > 0); return Data[Size - 1]; }
|
||||||
inline const value_type& back() const { 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<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 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 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) { 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 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)
|
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; }
|
||||||
{
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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.
|
// 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 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 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 void push_front(const T& 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 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 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 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 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 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 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 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 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 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_pointer(const_iterator it) const { IM_ASSERT(it >= Data && it <= Data+Size); const ptrdiff_t off = it - Data; return (int)off; }
|
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; }
|
||||||
};
|
};
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
@ -1893,11 +1883,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);
|
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()
|
// 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 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 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); PathClear(); } // Note: Anti-aliased filling requires points to be in clockwise order.
|
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); PathClear(); }
|
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 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 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);
|
IMGUI_API void PathBezierCurveTo(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, int num_segments = 0);
|
||||||
@ -1989,12 +1979,14 @@ struct ImFontGlyph
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Helper to build glyph ranges from text/string data. Feed your application strings/characters to it then call BuildRanges().
|
// 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
|
struct ImFontGlyphRangesBuilder
|
||||||
{
|
{
|
||||||
ImVector<unsigned char> UsedChars; // Store 1-bit per Unicode code point (0=unused, 1=used)
|
ImVector<int> 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; }
|
ImFontGlyphRangesBuilder() { UsedChars.resize(0x10000 / 32); memset(UsedChars.Data, 0, 0x10000 / 32); }
|
||||||
void SetBit(int n) { UsedChars[n >> 3] |= 1 << (n & 7); } // Set bit 'c' in the array
|
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
|
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 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
|
IMGUI_API void AddRanges(const ImWchar* ranges); // Add ranges, e.g. builder.AddRanges(ImFontAtlas::GetGlyphRangesDefault()) to force add all of ASCII/Latin+Ext
|
||||||
|
@ -4066,7 +4066,7 @@ void ShowExampleAppDocuments(bool* p_open)
|
|||||||
{
|
{
|
||||||
static ExampleAppDocuments app;
|
static ExampleAppDocuments app;
|
||||||
|
|
||||||
if (!ImGui::Begin("Examples: Documents", p_open, ImGuiWindowFlags_MenuBar))
|
if (!ImGui::Begin("Example: Documents", p_open, ImGuiWindowFlags_MenuBar))
|
||||||
{
|
{
|
||||||
ImGui::End();
|
ImGui::End();
|
||||||
return;
|
return;
|
||||||
|
116
imgui_draw.cpp
116
imgui_draw.cpp
@ -656,7 +656,13 @@ void ImDrawList::PrimQuadUV(const ImVec2& a, const ImVec2& b, const ImVec2& c, c
|
|||||||
_IdxWritePtr += 6;
|
_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.
|
// 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)
|
void ImDrawList::AddPolyline(const ImVec2* points, const int points_count, ImU32 col, bool closed, float thickness)
|
||||||
{
|
{
|
||||||
if (points_count < 2)
|
if (points_count < 2)
|
||||||
@ -686,10 +692,11 @@ void ImDrawList::AddPolyline(const ImVec2* points, const int points_count, ImU32
|
|||||||
for (int i1 = 0; i1 < count; i1++)
|
for (int i1 = 0; i1 < count; i1++)
|
||||||
{
|
{
|
||||||
const int i2 = (i1+1) == points_count ? 0 : i1+1;
|
const int i2 = (i1+1) == points_count ? 0 : i1+1;
|
||||||
ImVec2 diff = points[i2] - points[i1];
|
float dx = points[i2].x - points[i1].x;
|
||||||
diff *= ImInvLength(diff, 1.0f);
|
float dy = points[i2].y - points[i1].y;
|
||||||
temp_normals[i1].x = diff.y;
|
IM_NORMALIZE2F_OVER_ZERO(dx, dy);
|
||||||
temp_normals[i1].y = -diff.x;
|
temp_normals[i1].x = dy;
|
||||||
|
temp_normals[i1].y = -dx;
|
||||||
}
|
}
|
||||||
if (!closed)
|
if (!closed)
|
||||||
temp_normals[points_count-1] = temp_normals[points_count-2];
|
temp_normals[points_count-1] = temp_normals[points_count-2];
|
||||||
@ -712,17 +719,18 @@ void ImDrawList::AddPolyline(const ImVec2* points, const int points_count, ImU32
|
|||||||
unsigned int idx2 = (i1+1) == points_count ? _VtxCurrentIdx : idx1+3;
|
unsigned int idx2 = (i1+1) == points_count ? _VtxCurrentIdx : idx1+3;
|
||||||
|
|
||||||
// Average normals
|
// Average normals
|
||||||
ImVec2 dm = (temp_normals[i1] + temp_normals[i2]) * 0.5f;
|
float dm_x = (temp_normals[i1].x + temp_normals[i2].x) * 0.5f;
|
||||||
float dmr2 = dm.x*dm.x + dm.y*dm.y;
|
float dm_y = (temp_normals[i1].y + temp_normals[i2].y) * 0.5f;
|
||||||
if (dmr2 > 0.000001f)
|
IM_NORMALIZE2F_OVER_EPSILON_CLAMP(dm_x, dm_y, 0.000001f, 100.0f)
|
||||||
{
|
dm_x *= AA_SIZE;
|
||||||
float scale = 1.0f / dmr2;
|
dm_y *= AA_SIZE;
|
||||||
if (scale > 100.0f) scale = 100.0f;
|
|
||||||
dm *= scale;
|
// Add temporary vertexes
|
||||||
}
|
ImVec2* out_vtx = &temp_points[i2*2];
|
||||||
dm *= AA_SIZE;
|
out_vtx[0].x = points[i2].x + dm_x;
|
||||||
temp_points[i2*2+0] = points[i2] + dm;
|
out_vtx[0].y = points[i2].y + dm_y;
|
||||||
temp_points[i2*2+1] = points[i2] - dm;
|
out_vtx[1].x = points[i2].x - dm_x;
|
||||||
|
out_vtx[1].y = points[i2].y - dm_y;
|
||||||
|
|
||||||
// Add indexes
|
// Add indexes
|
||||||
_IdxWritePtr[0] = (ImDrawIdx)(idx2+0); _IdxWritePtr[1] = (ImDrawIdx)(idx1+0); _IdxWritePtr[2] = (ImDrawIdx)(idx1+2);
|
_IdxWritePtr[0] = (ImDrawIdx)(idx2+0); _IdxWritePtr[1] = (ImDrawIdx)(idx1+0); _IdxWritePtr[2] = (ImDrawIdx)(idx1+2);
|
||||||
@ -766,20 +774,24 @@ void ImDrawList::AddPolyline(const ImVec2* points, const int points_count, ImU32
|
|||||||
unsigned int idx2 = (i1+1) == points_count ? _VtxCurrentIdx : idx1+4;
|
unsigned int idx2 = (i1+1) == points_count ? _VtxCurrentIdx : idx1+4;
|
||||||
|
|
||||||
// Average normals
|
// Average normals
|
||||||
ImVec2 dm = (temp_normals[i1] + temp_normals[i2]) * 0.5f;
|
float dm_x = (temp_normals[i1].x + temp_normals[i2].x) * 0.5f;
|
||||||
float dmr2 = dm.x*dm.x + dm.y*dm.y;
|
float dm_y = (temp_normals[i1].y + temp_normals[i2].y) * 0.5f;
|
||||||
if (dmr2 > 0.000001f)
|
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 scale = 1.0f / dmr2;
|
float dm_out_y = dm_y * (half_inner_thickness + AA_SIZE);
|
||||||
if (scale > 100.0f) scale = 100.0f;
|
float dm_in_x = dm_x * half_inner_thickness;
|
||||||
dm *= scale;
|
float dm_in_y = dm_y * half_inner_thickness;
|
||||||
}
|
|
||||||
ImVec2 dm_out = dm * (half_inner_thickness + AA_SIZE);
|
// Add temporary vertexes
|
||||||
ImVec2 dm_in = dm * half_inner_thickness;
|
ImVec2* out_vtx = &temp_points[i2*4];
|
||||||
temp_points[i2*4+0] = points[i2] + dm_out;
|
out_vtx[0].x = points[i2].x + dm_out_x;
|
||||||
temp_points[i2*4+1] = points[i2] + dm_in;
|
out_vtx[0].y = points[i2].y + dm_out_y;
|
||||||
temp_points[i2*4+2] = points[i2] - dm_in;
|
out_vtx[1].x = points[i2].x + dm_in_x;
|
||||||
temp_points[i2*4+3] = points[i2] - dm_out;
|
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
|
// Add indexes
|
||||||
_IdxWritePtr[0] = (ImDrawIdx)(idx2+1); _IdxWritePtr[1] = (ImDrawIdx)(idx1+1); _IdxWritePtr[2] = (ImDrawIdx)(idx1+2);
|
_IdxWritePtr[0] = (ImDrawIdx)(idx2+1); _IdxWritePtr[1] = (ImDrawIdx)(idx1+1); _IdxWritePtr[2] = (ImDrawIdx)(idx1+2);
|
||||||
@ -817,11 +829,13 @@ void ImDrawList::AddPolyline(const ImVec2* points, const int points_count, ImU32
|
|||||||
const int i2 = (i1+1) == points_count ? 0 : i1+1;
|
const int i2 = (i1+1) == points_count ? 0 : i1+1;
|
||||||
const ImVec2& p1 = points[i1];
|
const ImVec2& p1 = points[i1];
|
||||||
const ImVec2& p2 = points[i2];
|
const ImVec2& p2 = points[i2];
|
||||||
ImVec2 diff = p2 - p1;
|
|
||||||
diff *= ImInvLength(diff, 1.0f);
|
|
||||||
|
|
||||||
const float dx = diff.x * (thickness * 0.5f);
|
float dx = p2.x - p1.x;
|
||||||
const float dy = diff.y * (thickness * 0.5f);
|
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[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[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;
|
_VtxWritePtr[2].pos.x = p2.x - dy; _VtxWritePtr[2].pos.y = p2.y + dx; _VtxWritePtr[2].uv = uv; _VtxWritePtr[2].col = col;
|
||||||
@ -836,6 +850,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)
|
void ImDrawList::AddConvexPolyFilled(const ImVec2* points, const int points_count, ImU32 col)
|
||||||
{
|
{
|
||||||
if (points_count < 3)
|
if (points_count < 3)
|
||||||
@ -867,10 +882,11 @@ void ImDrawList::AddConvexPolyFilled(const ImVec2* points, const int points_coun
|
|||||||
{
|
{
|
||||||
const ImVec2& p0 = points[i0];
|
const ImVec2& p0 = points[i0];
|
||||||
const ImVec2& p1 = points[i1];
|
const ImVec2& p1 = points[i1];
|
||||||
ImVec2 diff = p1 - p0;
|
float dx = p1.x - p0.x;
|
||||||
diff *= ImInvLength(diff, 1.0f);
|
float dy = p1.y - p0.y;
|
||||||
temp_normals[i0].x = diff.y;
|
IM_NORMALIZE2F_OVER_ZERO(dx, dy);
|
||||||
temp_normals[i0].y = -diff.x;
|
temp_normals[i0].x = dy;
|
||||||
|
temp_normals[i0].y = -dx;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i0 = points_count-1, i1 = 0; i1 < points_count; i0 = i1++)
|
for (int i0 = points_count-1, i1 = 0; i1 < points_count; i0 = i1++)
|
||||||
@ -878,19 +894,15 @@ void ImDrawList::AddConvexPolyFilled(const ImVec2* points, const int points_coun
|
|||||||
// Average normals
|
// Average normals
|
||||||
const ImVec2& n0 = temp_normals[i0];
|
const ImVec2& n0 = temp_normals[i0];
|
||||||
const ImVec2& n1 = temp_normals[i1];
|
const ImVec2& n1 = temp_normals[i1];
|
||||||
ImVec2 dm = (n0 + n1) * 0.5f;
|
float dm_x = (n0.x + n1.x) * 0.5f;
|
||||||
float dmr2 = dm.x*dm.x + dm.y*dm.y;
|
float dm_y = (n0.y + n1.y) * 0.5f;
|
||||||
if (dmr2 > 0.000001f)
|
IM_NORMALIZE2F_OVER_EPSILON_CLAMP(dm_x, dm_y, 0.000001f, 100.0f);
|
||||||
{
|
dm_x *= AA_SIZE * 0.5f;
|
||||||
float scale = 1.0f / dmr2;
|
dm_y *= AA_SIZE * 0.5f;
|
||||||
if (scale > 100.0f) scale = 100.0f;
|
|
||||||
dm *= scale;
|
|
||||||
}
|
|
||||||
dm *= AA_SIZE * 0.5f;
|
|
||||||
|
|
||||||
// Add vertices
|
// Add vertices
|
||||||
_VtxWritePtr[0].pos = (points[i1] - dm); _VtxWritePtr[0].uv = uv; _VtxWritePtr[0].col = col; // Inner
|
_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 = (points[i1] + dm); _VtxWritePtr[1].uv = uv; _VtxWritePtr[1].col = col_trans; // Outer
|
_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;
|
_VtxWritePtr += 2;
|
||||||
|
|
||||||
// Add indexes for fringes
|
// Add indexes for fringes
|
||||||
@ -2422,7 +2434,7 @@ const ImFontGlyph* ImFont::FindGlyph(ImWchar c) const
|
|||||||
{
|
{
|
||||||
if (c >= IndexLookup.Size)
|
if (c >= IndexLookup.Size)
|
||||||
return FallbackGlyph;
|
return FallbackGlyph;
|
||||||
const ImWchar i = IndexLookup[c];
|
const ImWchar i = IndexLookup.Data[c];
|
||||||
if (i == (ImWchar)-1)
|
if (i == (ImWchar)-1)
|
||||||
return FallbackGlyph;
|
return FallbackGlyph;
|
||||||
return &Glyphs.Data[i];
|
return &Glyphs.Data[i];
|
||||||
@ -2432,7 +2444,7 @@ const ImFontGlyph* ImFont::FindGlyphNoFallback(ImWchar c) const
|
|||||||
{
|
{
|
||||||
if (c >= IndexLookup.Size)
|
if (c >= IndexLookup.Size)
|
||||||
return NULL;
|
return NULL;
|
||||||
const ImWchar i = IndexLookup[c];
|
const ImWchar i = IndexLookup.Data[c];
|
||||||
if (i == (ImWchar)-1)
|
if (i == (ImWchar)-1)
|
||||||
return NULL;
|
return NULL;
|
||||||
return &Glyphs.Data[i];
|
return &Glyphs.Data[i];
|
||||||
@ -2492,7 +2504,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 (ImCharIsBlankW(c))
|
||||||
{
|
{
|
||||||
if (inside_word)
|
if (inside_word)
|
||||||
@ -2609,7 +2621,7 @@ ImVec2 ImFont::CalcTextSizeA(float size, float max_width, float wrap_width, cons
|
|||||||
continue;
|
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)
|
if (line_width + char_width >= max_width)
|
||||||
{
|
{
|
||||||
s = prev_s;
|
s = prev_s;
|
||||||
|
@ -6,8 +6,27 @@
|
|||||||
// #define IMGUI_DEFINE_MATH_OPERATORS
|
// #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)
|
// 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
|
#pragma once
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Header mess
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
#ifndef IMGUI_VERSION
|
#ifndef IMGUI_VERSION
|
||||||
#error Must include imgui.h before imgui_internal.h
|
#error Must include imgui.h before imgui_internal.h
|
||||||
#endif
|
#endif
|
||||||
@ -30,7 +49,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Forward Declarations
|
// Forward declarations
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
struct ImRect; // An axis-aligned rectangle (2 points)
|
struct ImRect; // An axis-aligned rectangle (2 points)
|
||||||
@ -68,7 +87,7 @@ typedef int ImGuiSliderFlags; // -> enum ImGuiSliderFlags_ // Flags:
|
|||||||
typedef int ImGuiDragFlags; // -> enum ImGuiDragFlags_ // Flags: for DragBehavior()
|
typedef int ImGuiDragFlags; // -> enum ImGuiDragFlags_ // Flags: for DragBehavior()
|
||||||
|
|
||||||
//-------------------------------------------------------------------------
|
//-------------------------------------------------------------------------
|
||||||
// STB libraries
|
// STB libraries includes
|
||||||
//-------------------------------------------------------------------------
|
//-------------------------------------------------------------------------
|
||||||
|
|
||||||
namespace ImGuiStb
|
namespace ImGuiStb
|
||||||
@ -84,7 +103,7 @@ namespace ImGuiStb
|
|||||||
} // namespace ImGuiStb
|
} // namespace ImGuiStb
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Context
|
// Context pointer
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
#ifndef GImGui
|
#ifndef GImGui
|
||||||
@ -92,7 +111,7 @@ extern IMGUI_API ImGuiContext* GImGui; // Current implicit ImGui context pointe
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Helpers
|
// Generic helpers
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
#define IM_PI 3.14159265358979323846f
|
#define IM_PI 3.14159265358979323846f
|
||||||
@ -144,6 +163,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 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 void ImStrncpy(char* dst, const char* src, size_t count);
|
||||||
IMGUI_API char* ImStrdup(const char* str);
|
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 const char* ImStrchrRange(const char* str_begin, const char* str_end, char c);
|
||||||
IMGUI_API int ImStrlenW(const ImWchar* str);
|
IMGUI_API int ImStrlenW(const ImWchar* str);
|
||||||
IMGUI_API const char* ImStreolRange(const char* str, const char* str_end); // End end-of-line
|
IMGUI_API const char* ImStreolRange(const char* str, const char* str_end); // End end-of-line
|
||||||
@ -242,7 +262,7 @@ struct IMGUI_API ImPool
|
|||||||
};
|
};
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Types
|
// Misc data structures
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
enum ImGuiButtonFlags_
|
enum ImGuiButtonFlags_
|
||||||
@ -336,8 +356,8 @@ enum ImGuiItemStatusFlags_
|
|||||||
// FIXME: this is in development, not exposed/functional as a generic feature yet.
|
// FIXME: this is in development, not exposed/functional as a generic feature yet.
|
||||||
enum ImGuiLayoutType_
|
enum ImGuiLayoutType_
|
||||||
{
|
{
|
||||||
ImGuiLayoutType_Vertical,
|
ImGuiLayoutType_Vertical = 0,
|
||||||
ImGuiLayoutType_Horizontal
|
ImGuiLayoutType_Horizontal = 1
|
||||||
};
|
};
|
||||||
|
|
||||||
enum ImGuiAxis
|
enum ImGuiAxis
|
||||||
@ -1138,6 +1158,7 @@ struct IMGUI_API ImGuiWindow
|
|||||||
ImVec2 WindowPadding; // Window padding at the time of begin.
|
ImVec2 WindowPadding; // Window padding at the time of begin.
|
||||||
float WindowRounding; // Window rounding at the time of begin.
|
float WindowRounding; // Window rounding at the time of begin.
|
||||||
float WindowBorderSize; // Window border size 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 MoveId; // == window->GetID("#MOVE")
|
||||||
ImGuiID ChildId; // ID of corresponding item in parent window (for navigation to return from child window to parent window)
|
ImGuiID ChildId; // ID of corresponding item in parent window (for navigation to return from child window to parent window)
|
||||||
ImVec2 Scroll;
|
ImVec2 Scroll;
|
||||||
@ -1239,7 +1260,7 @@ struct ImGuiItemHoveredDataBackup
|
|||||||
};
|
};
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Tab Bar, Tab Item
|
// Tab bar, tab item
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
enum ImGuiTabBarFlagsPrivate_
|
enum ImGuiTabBarFlagsPrivate_
|
||||||
@ -1288,7 +1309,7 @@ struct ImGuiTabBar
|
|||||||
short LastTabItemIdx; // For BeginTabItem()/EndTabItem()
|
short LastTabItemIdx; // For BeginTabItem()/EndTabItem()
|
||||||
|
|
||||||
ImGuiTabBar();
|
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); }
|
||||||
};
|
};
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
@ -1502,11 +1523,11 @@ IMGUI_API void ImFontAtlasBuildMultiplyRectAlpha8(const unsigned ch
|
|||||||
// Test engine hooks (imgui-test)
|
// Test engine hooks (imgui-test)
|
||||||
//#define IMGUI_ENABLE_TEST_ENGINE
|
//#define IMGUI_ENABLE_TEST_ENGINE
|
||||||
#ifdef IMGUI_ENABLE_TEST_ENGINE
|
#ifdef IMGUI_ENABLE_TEST_ENGINE
|
||||||
extern void ImGuiTestEngineHook_PreNewFrame();
|
extern void ImGuiTestEngineHook_PreNewFrame(ImGuiContext* ctx);
|
||||||
extern void ImGuiTestEngineHook_PostNewFrame();
|
extern void ImGuiTestEngineHook_PostNewFrame(ImGuiContext* ctx);
|
||||||
extern void ImGuiTestEngineHook_ItemAdd(const ImRect& bb, ImGuiID id);
|
extern void ImGuiTestEngineHook_ItemAdd(ImGuiContext* ctx, const ImRect& bb, ImGuiID id);
|
||||||
extern void ImGuiTestEngineHook_ItemInfo(ImGuiID id, const char* label, int flags);
|
extern void ImGuiTestEngineHook_ItemInfo(ImGuiContext* ctx, ImGuiID id, const char* label, int flags);
|
||||||
#define IMGUI_TEST_ENGINE_ITEM_INFO(_ID, _LABEL, _FLAGS) ImGuiTestEngineHook_ItemInfo(_ID, _LABEL, _FLAGS) // Register status flags
|
#define IMGUI_TEST_ENGINE_ITEM_INFO(_ID, _LABEL, _FLAGS) ImGuiTestEngineHook_ItemInfo(&g, _ID, _LABEL, _FLAGS) // Register status flags
|
||||||
#else
|
#else
|
||||||
#define IMGUI_TEST_ENGINE_ITEM_INFO(_ID, _LABEL, _FLAGS) do { } while (0)
|
#define IMGUI_TEST_ENGINE_ITEM_INFO(_ID, _LABEL, _FLAGS) do { } while (0)
|
||||||
#endif
|
#endif
|
||||||
|
@ -204,7 +204,7 @@ void ImGui::TextUnformatted(const char* text, const char* text_end)
|
|||||||
}
|
}
|
||||||
|
|
||||||
ImRect bb(text_pos, text_pos + text_size);
|
ImRect bb(text_pos, text_pos + text_size);
|
||||||
ItemSize(bb);
|
ItemSize(text_size);
|
||||||
ItemAdd(bb, 0);
|
ItemAdd(bb, 0);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -282,10 +282,12 @@ void ImGui::TextWrapped(const char* fmt, ...)
|
|||||||
|
|
||||||
void ImGui::TextWrappedV(const char* fmt, va_list args)
|
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
|
bool need_backup = (GImGui->CurrentWindow->DC.TextWrapPos < 0.0f); // Keep existing wrap position if one is already set
|
||||||
if (need_wrap) PushTextWrapPos(0.0f);
|
if (need_backup)
|
||||||
|
PushTextWrapPos(0.0f);
|
||||||
TextV(fmt, args);
|
TextV(fmt, args);
|
||||||
if (need_wrap) PopTextWrapPos();
|
if (need_backup)
|
||||||
|
PopTextWrapPos();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImGui::LabelText(const char* label, const char* fmt, ...)
|
void ImGui::LabelText(const char* label, const char* fmt, ...)
|
||||||
@ -397,8 +399,8 @@ bool ImGui::ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool
|
|||||||
g.HoveredWindow = window;
|
g.HoveredWindow = window;
|
||||||
|
|
||||||
#ifdef IMGUI_ENABLE_TEST_ENGINE
|
#ifdef IMGUI_ENABLE_TEST_ENGINE
|
||||||
if (window->DC.LastItemId != id)
|
if (id != 0 && window->DC.LastItemId != id)
|
||||||
ImGuiTestEngineHook_ItemAdd(bb, id);
|
ImGuiTestEngineHook_ItemAdd(&g, bb, id);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
bool pressed = false;
|
bool pressed = false;
|
||||||
@ -546,7 +548,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);
|
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);
|
const ImRect bb(pos, pos + size);
|
||||||
ItemSize(bb, style.FramePadding.y);
|
ItemSize(size, style.FramePadding.y);
|
||||||
if (!ItemAdd(bb, id))
|
if (!ItemAdd(bb, id))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@ -600,7 +602,7 @@ bool ImGui::InvisibleButton(const char* str_id, const ImVec2& size_arg)
|
|||||||
const ImGuiID id = window->GetID(str_id);
|
const ImGuiID id = window->GetID(str_id);
|
||||||
ImVec2 size = CalcItemSize(size_arg, 0.0f, 0.0f);
|
ImVec2 size = CalcItemSize(size_arg, 0.0f, 0.0f);
|
||||||
const ImRect bb(window->DC.CursorPos, window->DC.CursorPos + size);
|
const ImRect bb(window->DC.CursorPos, window->DC.CursorPos + size);
|
||||||
ItemSize(bb);
|
ItemSize(size);
|
||||||
if (!ItemAdd(bb, id))
|
if (!ItemAdd(bb, id))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@ -5033,7 +5035,7 @@ bool ImGui::Selectable(const char* label, bool selected, ImGuiSelectableFlags fl
|
|||||||
bb.Min.y -= spacing_U;
|
bb.Min.y -= spacing_U;
|
||||||
bb.Max.x += spacing_R;
|
bb.Max.x += spacing_R;
|
||||||
bb.Max.y += spacing_D;
|
bb.Max.y += spacing_D;
|
||||||
if (!ItemAdd(bb, (flags & ImGuiSelectableFlags_Disabled) ? 0 : id))
|
if (!ItemAdd(bb, id))
|
||||||
{
|
{
|
||||||
if ((flags & ImGuiSelectableFlags_SpanAllColumns) && window->DC.ColumnsSet)
|
if ((flags & ImGuiSelectableFlags_SpanAllColumns) && window->DC.ColumnsSet)
|
||||||
PushColumnClipRect();
|
PushColumnClipRect();
|
||||||
@ -6289,7 +6291,7 @@ bool ImGui::TabItemEx(ImGuiTabBar* tab_bar, const char* label, bool* p_open,
|
|||||||
tab->Width = size.x;
|
tab->Width = size.x;
|
||||||
tab_is_new = true;
|
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;
|
tab->WidthContents = size.x;
|
||||||
|
|
||||||
const bool tab_bar_appearing = (tab_bar->PrevFrameVisible + 1 < g.FrameCount);
|
const bool tab_bar_appearing = (tab_bar->PrevFrameVisible + 1 < g.FrameCount);
|
||||||
|
Loading…
Reference in New Issue
Block a user