mirror of
https://github.com/Drezil/imgui.git
synced 2024-11-25 13:07:01 +00:00
ImStrv: Step 2 - change ImStrv typedef to a class and convert functions taking being/end string pointers to use new class.
This commit is contained in:
parent
88bcafd0a3
commit
35c0f9a29b
272
imgui.cpp
272
imgui.cpp
@ -1534,6 +1534,13 @@ void ImStrncpy(char* dst, const char* src, size_t count)
|
|||||||
dst[count - 1] = 0;
|
dst[count - 1] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ImStrncpy(char* dst, ImStrv src, size_t count)
|
||||||
|
{
|
||||||
|
// Even though src does not necessarily include \0 terminator it is ok to include it. ImStrncpy above does not
|
||||||
|
// actually include that in a copy operation and inserts zero terminator manually.
|
||||||
|
ImStrncpy(dst, src.Begin, ImMin(count, IM_IMSTR_LENGTH(src) + 1));
|
||||||
|
}
|
||||||
|
|
||||||
char* ImStrdup(const char* str)
|
char* ImStrdup(const char* str)
|
||||||
{
|
{
|
||||||
size_t len = strlen(str);
|
size_t len = strlen(str);
|
||||||
@ -1541,10 +1548,20 @@ char* ImStrdup(const char* str)
|
|||||||
return (char*)memcpy(buf, (const void*)str, len + 1);
|
return (char*)memcpy(buf, (const void*)str, len + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
char* ImStrdupcpy(char* dst, size_t* p_dst_size, const char* src)
|
char* ImStrdup(ImStrv str)
|
||||||
|
{
|
||||||
|
size_t len = IM_IMSTR_LENGTH(str);
|
||||||
|
void* buf = IM_ALLOC(len + 1);
|
||||||
|
*((char*)buf + len) = 0; // str may not contain \0, it must be inserted manually.
|
||||||
|
if (len > 0)
|
||||||
|
return (char*)memcpy(buf, (const void*)str.Begin, len);
|
||||||
|
return (char*)buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
char* ImStrdupcpy(char* dst, size_t* p_dst_size, ImStrv src)
|
||||||
{
|
{
|
||||||
size_t dst_buf_size = p_dst_size ? *p_dst_size : strlen(dst) + 1;
|
size_t dst_buf_size = p_dst_size ? *p_dst_size : strlen(dst) + 1;
|
||||||
size_t src_size = strlen(src) + 1;
|
size_t src_size = IM_IMSTR_LENGTH(src) + 1;
|
||||||
if (dst_buf_size < src_size)
|
if (dst_buf_size < src_size)
|
||||||
{
|
{
|
||||||
IM_FREE(dst);
|
IM_FREE(dst);
|
||||||
@ -1552,7 +1569,15 @@ char* ImStrdupcpy(char* dst, size_t* p_dst_size, const char* src)
|
|||||||
if (p_dst_size)
|
if (p_dst_size)
|
||||||
*p_dst_size = src_size;
|
*p_dst_size = src_size;
|
||||||
}
|
}
|
||||||
return (char*)memcpy(dst, (const void*)src, src_size);
|
dst[src_size - 1] = 0; // str may not contain \0, it must be inserted manually.
|
||||||
|
if (src_size > 1)
|
||||||
|
return (char*)memcpy(dst, (const void*)src.Begin, src_size - 1);
|
||||||
|
return dst;
|
||||||
|
}
|
||||||
|
|
||||||
|
char* ImStrdupcpy(char* dst, size_t* p_dst_size, const char* src)
|
||||||
|
{
|
||||||
|
return ImStrdupcpy(dst, p_dst_size, ImStrv(src));
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* ImStrchrRange(const char* str, const char* str_end, char c)
|
const char* ImStrchrRange(const char* str, const char* str_end, char c)
|
||||||
@ -1605,6 +1630,26 @@ const char* ImStristr(const char* haystack, const char* haystack_end, const char
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char* ImStrstr(ImStrv haystack, ImStrv needle)
|
||||||
|
{
|
||||||
|
IM_IMSTR_ENSURE_HAS_END(needle);
|
||||||
|
const char un0 = (char)*needle.Begin;
|
||||||
|
while ((!haystack.End && *haystack.Begin) || (haystack.End && haystack.Begin < haystack.End))
|
||||||
|
{
|
||||||
|
if (*haystack.Begin == un0)
|
||||||
|
{
|
||||||
|
const char* b = needle.Begin + 1;
|
||||||
|
for (const char* a = haystack.Begin + 1; b < needle.End; a++, b++)
|
||||||
|
if (*a != *b)
|
||||||
|
break;
|
||||||
|
if (b == needle.End)
|
||||||
|
return haystack.Begin;
|
||||||
|
}
|
||||||
|
haystack.Begin++;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
// Trim str by offsetting contents when there's leading data + writing a \0 at the trailing position. We use this in situation where the cost is negligible.
|
// Trim str by offsetting contents when there's leading data + writing a \0 at the trailing position. We use this in situation where the cost is negligible.
|
||||||
void ImStrTrimBlanks(char* buf)
|
void ImStrTrimBlanks(char* buf)
|
||||||
{
|
{
|
||||||
@ -1722,14 +1767,15 @@ ImGuiID ImHashData(const void* data_p, size_t data_size, ImU32 seed)
|
|||||||
// - If we reach ### in the string we discard the hash so far and reset to the seed.
|
// - If we reach ### in the string we discard the hash so far and reset to the seed.
|
||||||
// - We don't do 'current += 2; continue;' after handling ### to keep the code smaller/faster (measured ~10% diff in Debug build)
|
// - We don't do 'current += 2; continue;' after handling ### to keep the code smaller/faster (measured ~10% diff in Debug build)
|
||||||
// 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.
|
||||||
ImGuiID ImHashStr(const char* data_p, size_t data_size, ImU32 seed)
|
ImGuiID ImHashStr(ImStrv str, ImU32 seed)
|
||||||
{
|
{
|
||||||
seed = ~seed;
|
seed = ~seed;
|
||||||
ImU32 crc = seed;
|
ImU32 crc = seed;
|
||||||
const unsigned char* data = (const unsigned char*)data_p;
|
const unsigned char* data = (const unsigned char*)str.Begin;
|
||||||
const ImU32* crc32_lut = GCrc32LookupTable;
|
const ImU32* crc32_lut = GCrc32LookupTable;
|
||||||
if (data_size != 0)
|
if (str.End != NULL)
|
||||||
{
|
{
|
||||||
|
size_t data_size = IM_IMSTR_LENGTH(str);
|
||||||
while (data_size-- != 0)
|
while (data_size-- != 0)
|
||||||
{
|
{
|
||||||
unsigned char c = *data++;
|
unsigned char c = *data++;
|
||||||
@ -1762,15 +1808,21 @@ ImFileHandle ImFileOpen(ImStrv filename, ImStrv mode)
|
|||||||
#if defined(_WIN32) && !defined(IMGUI_DISABLE_WIN32_FUNCTIONS) && !defined(__CYGWIN__) && !defined(__GNUC__)
|
#if defined(_WIN32) && !defined(IMGUI_DISABLE_WIN32_FUNCTIONS) && !defined(__CYGWIN__) && !defined(__GNUC__)
|
||||||
// We need a fopen() wrapper because MSVC/Windows fopen doesn't handle UTF-8 filenames.
|
// We need a fopen() wrapper because MSVC/Windows fopen doesn't handle UTF-8 filenames.
|
||||||
// Previously we used ImTextCountCharsFromUtf8/ImTextStrFromUtf8 here but we now need to support ImWchar16 and ImWchar32!
|
// Previously we used ImTextCountCharsFromUtf8/ImTextStrFromUtf8 here but we now need to support ImWchar16 and ImWchar32!
|
||||||
const int filename_wsize = ::MultiByteToWideChar(CP_UTF8, 0, filename, -1, NULL, 0);
|
const int filename_wsize = ::MultiByteToWideChar(CP_UTF8, 0, filename.Begin, (int)IM_IMSTR_LENGTH(filename) + 1, NULL, 0);
|
||||||
const int mode_wsize = ::MultiByteToWideChar(CP_UTF8, 0, mode, -1, NULL, 0);
|
const int mode_wsize = ::MultiByteToWideChar(CP_UTF8, 0, mode.Begin, (int)IM_IMSTR_LENGTH(mode) + 1, NULL, 0);
|
||||||
ImVector<ImWchar> buf;
|
ImVector<ImWchar> buf;
|
||||||
buf.resize(filename_wsize + mode_wsize);
|
buf.resize(filename_wsize + mode_wsize);
|
||||||
::MultiByteToWideChar(CP_UTF8, 0, filename, -1, (wchar_t*)&buf[0], filename_wsize);
|
::MultiByteToWideChar(CP_UTF8, 0, filename.Begin, (int)IM_IMSTR_LENGTH(filename) + 1, (wchar_t*)&buf[0], filename_wsize);
|
||||||
::MultiByteToWideChar(CP_UTF8, 0, mode, -1, (wchar_t*)&buf[filename_wsize], mode_wsize);
|
::MultiByteToWideChar(CP_UTF8, 0, mode.Begin, (int)IM_IMSTR_LENGTH(mode) + 1, (wchar_t*)&buf[filename_wsize], mode_wsize);
|
||||||
return ::_wfopen((const wchar_t*)&buf[0], (const wchar_t*)&buf[filename_wsize]);
|
return ::_wfopen((const wchar_t*)&buf[0], (const wchar_t*)&buf[filename_wsize]);
|
||||||
#else
|
#else
|
||||||
return fopen(filename, mode);
|
// ImStrv is not guaranteed to be zero-terminated.
|
||||||
|
ImStrv filename_0 = ImStrdup(filename);
|
||||||
|
ImStrv mode_0 = ImStrdup(mode);
|
||||||
|
ImFileHandle handle = fopen(filename_0.Begin, mode_0.Begin);
|
||||||
|
IM_FREE(const_cast<char*>(filename_0.Begin));
|
||||||
|
IM_FREE(const_cast<char*>(mode_0.Begin));
|
||||||
|
return handle;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2304,13 +2356,14 @@ void ImGuiTextFilter::Build()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ImGuiTextFilter::PassFilter(const char* text, const char* text_end) const
|
bool ImGuiTextFilter::PassFilter(ImStrv text) const
|
||||||
{
|
{
|
||||||
if (Filters.empty())
|
if (Filters.empty())
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (text == NULL)
|
IM_IMSTR_ENSURE_HAS_END(text);
|
||||||
text = "";
|
if (text.Empty())
|
||||||
|
text.Begin = text.End = "";
|
||||||
|
|
||||||
for (int i = 0; i != Filters.Size; i++)
|
for (int i = 0; i != Filters.Size; i++)
|
||||||
{
|
{
|
||||||
@ -2320,13 +2373,13 @@ bool ImGuiTextFilter::PassFilter(const char* text, const char* text_end) const
|
|||||||
if (f.b[0] == '-')
|
if (f.b[0] == '-')
|
||||||
{
|
{
|
||||||
// Subtract
|
// Subtract
|
||||||
if (ImStristr(text, text_end, f.b + 1, f.e) != NULL)
|
if (ImStristr(text.Begin, text.End, f.b + 1, f.e) != NULL)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Grep
|
// Grep
|
||||||
if (ImStristr(text, text_end, f.b, f.e) != NULL)
|
if (ImStristr(text.Begin, text.End, f.b, f.e) != NULL)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2354,9 +2407,9 @@ bool ImGuiTextFilter::PassFilter(const char* text, const char* text_end) const
|
|||||||
|
|
||||||
char ImGuiTextBuffer::EmptyString[1] = { 0 };
|
char ImGuiTextBuffer::EmptyString[1] = { 0 };
|
||||||
|
|
||||||
void ImGuiTextBuffer::append(const char* str, const char* str_end)
|
void ImGuiTextBuffer::append(ImStrv str)
|
||||||
{
|
{
|
||||||
int len = str_end ? (int)(str_end - str) : (int)strlen(str);
|
int len = (int)IM_IMSTR_LENGTH(str);
|
||||||
|
|
||||||
// Add zero-terminator the first time
|
// Add zero-terminator the first time
|
||||||
const int write_off = (Buf.Size != 0) ? Buf.Size : 1;
|
const int write_off = (Buf.Size != 0) ? Buf.Size : 1;
|
||||||
@ -2368,7 +2421,8 @@ void ImGuiTextBuffer::append(const char* str, const char* str_end)
|
|||||||
}
|
}
|
||||||
|
|
||||||
Buf.resize(needed_sz);
|
Buf.resize(needed_sz);
|
||||||
memcpy(&Buf[write_off - 1], str, (size_t)len);
|
if (len > 0)
|
||||||
|
memcpy(&Buf[write_off - 1], str.Begin, (size_t)len);
|
||||||
Buf[write_off - 1 + len] = 0;
|
Buf[write_off - 1 + len] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2957,20 +3011,20 @@ const char* ImGui::GetStyleColorName(ImGuiCol idx)
|
|||||||
// Also see imgui_draw.cpp for some more which have been reworked to not rely on ImGui:: context.
|
// Also see imgui_draw.cpp for some more which have been reworked to not rely on ImGui:: context.
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
const char* ImGui::FindRenderedTextEnd(const char* text, const char* text_end)
|
const char* ImGui::FindRenderedTextEnd(ImStrv text)
|
||||||
{
|
{
|
||||||
const char* text_display_end = text;
|
const char* text_display_end = text.Begin;
|
||||||
if (!text_end)
|
if (!text.End)
|
||||||
text_end = (const char*)-1;
|
text.End = (const char*)-1;
|
||||||
|
|
||||||
while (text_display_end < text_end && *text_display_end != '\0' && (text_display_end[0] != '#' || text_display_end[1] != '#'))
|
while (text_display_end < text.End && *text_display_end != '\0' && (text_display_end[0] != '#' || text_display_end[1] != '#'))
|
||||||
text_display_end++;
|
text_display_end++;
|
||||||
return text_display_end;
|
return text_display_end;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Internal ImGui functions to render text
|
// Internal ImGui functions to render text
|
||||||
// RenderText***() functions calls ImDrawList::AddText() calls ImBitmapFont::RenderText()
|
// RenderText***() functions calls ImDrawList::AddText() calls ImBitmapFont::RenderText()
|
||||||
void ImGui::RenderText(ImVec2 pos, const char* text, const char* text_end, bool hide_text_after_hash)
|
void ImGui::RenderText(ImVec2 pos, ImStrv text, bool hide_text_after_hash)
|
||||||
{
|
{
|
||||||
ImGuiContext& g = *GImGui;
|
ImGuiContext& g = *GImGui;
|
||||||
ImGuiWindow* window = g.CurrentWindow;
|
ImGuiWindow* window = g.CurrentWindow;
|
||||||
@ -2979,46 +3033,43 @@ void ImGui::RenderText(ImVec2 pos, const char* text, const char* text_end, bool
|
|||||||
const char* text_display_end;
|
const char* text_display_end;
|
||||||
if (hide_text_after_hash)
|
if (hide_text_after_hash)
|
||||||
{
|
{
|
||||||
text_display_end = FindRenderedTextEnd(text, text_end);
|
text_display_end = FindRenderedTextEnd(text);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (!text_end)
|
IM_IMSTR_ENSURE_HAS_END(text);
|
||||||
text_end = text + strlen(text); // FIXME-OPT
|
text_display_end = text.End;
|
||||||
text_display_end = text_end;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (text != text_display_end)
|
if (text.Begin != text_display_end)
|
||||||
{
|
{
|
||||||
window->DrawList->AddText(g.Font, g.FontSize, pos, GetColorU32(ImGuiCol_Text), text, text_display_end);
|
window->DrawList->AddText(g.Font, g.FontSize, pos, GetColorU32(ImGuiCol_Text), ImStrv(text.Begin, text_display_end));
|
||||||
if (g.LogEnabled)
|
if (g.LogEnabled)
|
||||||
LogRenderedText(&pos, text, text_display_end);
|
LogRenderedText(&pos, ImStrv(text.Begin, text_display_end));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImGui::RenderTextWrapped(ImVec2 pos, const char* text, const char* text_end, float wrap_width)
|
void ImGui::RenderTextWrapped(ImVec2 pos, ImStrv text, float wrap_width)
|
||||||
{
|
{
|
||||||
ImGuiContext& g = *GImGui;
|
ImGuiContext& g = *GImGui;
|
||||||
ImGuiWindow* window = g.CurrentWindow;
|
ImGuiWindow* window = g.CurrentWindow;
|
||||||
|
IM_IMSTR_ENSURE_HAS_END(text);
|
||||||
|
|
||||||
if (!text_end)
|
if (text.Begin != text.End)
|
||||||
text_end = text + strlen(text); // FIXME-OPT
|
|
||||||
|
|
||||||
if (text != text_end)
|
|
||||||
{
|
{
|
||||||
window->DrawList->AddText(g.Font, g.FontSize, pos, GetColorU32(ImGuiCol_Text), text, text_end, wrap_width);
|
window->DrawList->AddText(g.Font, g.FontSize, pos, GetColorU32(ImGuiCol_Text), text, wrap_width);
|
||||||
if (g.LogEnabled)
|
if (g.LogEnabled)
|
||||||
LogRenderedText(&pos, text, text_end);
|
LogRenderedText(&pos, text);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Default clip_rect uses (pos_min,pos_max)
|
// Default clip_rect uses (pos_min,pos_max)
|
||||||
// Handle clipping on CPU immediately (vs typically let the GPU clip the triangles that are overlapping the clipping rectangle edges)
|
// Handle clipping on CPU immediately (vs typically let the GPU clip the triangles that are overlapping the clipping rectangle edges)
|
||||||
void ImGui::RenderTextClippedEx(ImDrawList* draw_list, const ImVec2& pos_min, const ImVec2& pos_max, const char* text, const char* text_display_end, const ImVec2* text_size_if_known, const ImVec2& align, const ImRect* clip_rect)
|
void ImGui::RenderTextClippedEx(ImDrawList* draw_list, const ImVec2& pos_min, const ImVec2& pos_max, ImStrv text, const ImVec2* text_size_if_known, const ImVec2& align, const ImRect* clip_rect)
|
||||||
{
|
{
|
||||||
// Perform CPU side clipping for single clipped element to avoid using scissor state
|
// Perform CPU side clipping for single clipped element to avoid using scissor state
|
||||||
ImVec2 pos = pos_min;
|
ImVec2 pos = pos_min;
|
||||||
const ImVec2 text_size = text_size_if_known ? *text_size_if_known : CalcTextSize(text, text_display_end, false, 0.0f);
|
const ImVec2 text_size = text_size_if_known ? *text_size_if_known : CalcTextSize(text, false, 0.0f);
|
||||||
|
|
||||||
const ImVec2* clip_min = clip_rect ? &clip_rect->Min : &pos_min;
|
const ImVec2* clip_min = clip_rect ? &clip_rect->Min : &pos_min;
|
||||||
const ImVec2* clip_max = clip_rect ? &clip_rect->Max : &pos_max;
|
const ImVec2* clip_max = clip_rect ? &clip_rect->Max : &pos_max;
|
||||||
@ -3034,39 +3085,38 @@ void ImGui::RenderTextClippedEx(ImDrawList* draw_list, const ImVec2& pos_min, co
|
|||||||
if (need_clipping)
|
if (need_clipping)
|
||||||
{
|
{
|
||||||
ImVec4 fine_clip_rect(clip_min->x, clip_min->y, clip_max->x, clip_max->y);
|
ImVec4 fine_clip_rect(clip_min->x, clip_min->y, clip_max->x, clip_max->y);
|
||||||
draw_list->AddText(NULL, 0.0f, pos, GetColorU32(ImGuiCol_Text), text, text_display_end, 0.0f, &fine_clip_rect);
|
draw_list->AddText(NULL, 0.0f, pos, GetColorU32(ImGuiCol_Text), text, 0.0f, &fine_clip_rect);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
draw_list->AddText(NULL, 0.0f, pos, GetColorU32(ImGuiCol_Text), text, text_display_end, 0.0f, NULL);
|
draw_list->AddText(NULL, 0.0f, pos, GetColorU32(ImGuiCol_Text), text, 0.0f, NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImGui::RenderTextClipped(const ImVec2& pos_min, const ImVec2& pos_max, const char* text, const char* text_end, const ImVec2* text_size_if_known, const ImVec2& align, const ImRect* clip_rect)
|
void ImGui::RenderTextClipped(const ImVec2& pos_min, const ImVec2& pos_max, ImStrv text, const ImVec2* text_size_if_known, const ImVec2& align, const ImRect* clip_rect)
|
||||||
{
|
{
|
||||||
// Hide anything after a '##' string
|
// Hide anything after a '##' string
|
||||||
const char* text_display_end = FindRenderedTextEnd(text, text_end);
|
const char* text_display_end = FindRenderedTextEnd(text);
|
||||||
const int text_len = (int)(text_display_end - text);
|
const int text_len = (int)(text_display_end - text.Begin);
|
||||||
if (text_len == 0)
|
if (text_len == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ImGuiContext& g = *GImGui;
|
ImGuiContext& g = *GImGui;
|
||||||
ImGuiWindow* window = g.CurrentWindow;
|
ImGuiWindow* window = g.CurrentWindow;
|
||||||
RenderTextClippedEx(window->DrawList, pos_min, pos_max, text, text_display_end, text_size_if_known, align, clip_rect);
|
RenderTextClippedEx(window->DrawList, pos_min, pos_max, ImStrv(text.Begin, text_display_end), text_size_if_known, align, clip_rect);
|
||||||
if (g.LogEnabled)
|
if (g.LogEnabled)
|
||||||
LogRenderedText(&pos_min, text, text_display_end);
|
LogRenderedText(&pos_min, ImStrv(text.Begin, text_display_end));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Another overly complex function until we reorganize everything into a nice all-in-one helper.
|
// Another overly complex function until we reorganize everything into a nice all-in-one helper.
|
||||||
// This is made more complex because we have dissociated the layout rectangle (pos_min..pos_max) which define _where_ the ellipsis is, from actual clipping of text and limit of the ellipsis display.
|
// This is made more complex because we have dissociated the layout rectangle (pos_min..pos_max) which define _where_ the ellipsis is, from actual clipping of text and limit of the ellipsis display.
|
||||||
// This is because in the context of tabs we selectively hide part of the text when the Close Button appears, but we don't want the ellipsis to move.
|
// This is because in the context of tabs we selectively hide part of the text when the Close Button appears, but we don't want the ellipsis to move.
|
||||||
void ImGui::RenderTextEllipsis(ImDrawList* draw_list, const ImVec2& pos_min, const ImVec2& pos_max, float clip_max_x, float ellipsis_max_x, const char* text, const char* text_end_full, const ImVec2* text_size_if_known)
|
void ImGui::RenderTextEllipsis(ImDrawList* draw_list, const ImVec2& pos_min, const ImVec2& pos_max, float clip_max_x, float ellipsis_max_x, ImStrv text, const ImVec2* text_size_if_known)
|
||||||
{
|
{
|
||||||
ImGuiContext& g = *GImGui;
|
ImGuiContext& g = *GImGui;
|
||||||
if (text_end_full == NULL)
|
if (text.End == NULL)
|
||||||
text_end_full = FindRenderedTextEnd(text);
|
text.End = FindRenderedTextEnd(text);
|
||||||
const ImVec2 text_size = text_size_if_known ? *text_size_if_known : CalcTextSize(text, text_end_full, false, 0.0f);
|
const ImVec2 text_size = text_size_if_known ? *text_size_if_known : CalcTextSize(text, false, 0.0f);
|
||||||
|
|
||||||
//draw_list->AddLine(ImVec2(pos_max.x, pos_min.y - 4), ImVec2(pos_max.x, pos_max.y + 4), IM_COL32(0, 0, 255, 255));
|
//draw_list->AddLine(ImVec2(pos_max.x, pos_min.y - 4), ImVec2(pos_max.x, pos_max.y + 4), IM_COL32(0, 0, 255, 255));
|
||||||
//draw_list->AddLine(ImVec2(ellipsis_max_x, pos_min.y-2), ImVec2(ellipsis_max_x, pos_max.y+2), IM_COL32(0, 255, 0, 255));
|
//draw_list->AddLine(ImVec2(ellipsis_max_x, pos_min.y-2), ImVec2(ellipsis_max_x, pos_max.y+2), IM_COL32(0, 255, 0, 255));
|
||||||
@ -3105,22 +3155,22 @@ void ImGui::RenderTextEllipsis(ImDrawList* draw_list, const ImVec2& pos_min, con
|
|||||||
|
|
||||||
// We can now claim the space between pos_max.x and ellipsis_max.x
|
// We can now claim the space between pos_max.x and ellipsis_max.x
|
||||||
const float text_avail_width = ImMax((ImMax(pos_max.x, ellipsis_max_x) - ellipsis_total_width) - pos_min.x, 1.0f);
|
const float text_avail_width = ImMax((ImMax(pos_max.x, ellipsis_max_x) - ellipsis_total_width) - pos_min.x, 1.0f);
|
||||||
float text_size_clipped_x = font->CalcTextSizeA(font_size, text_avail_width, 0.0f, text, text_end_full, &text_end_ellipsis).x;
|
float text_size_clipped_x = font->CalcTextSizeA(font_size, text_avail_width, 0.0f, text, &text_end_ellipsis).x;
|
||||||
if (text == text_end_ellipsis && text_end_ellipsis < text_end_full)
|
if (text.Begin == text_end_ellipsis && text_end_ellipsis < text.End)
|
||||||
{
|
{
|
||||||
// Always display at least 1 character if there's no room for character + ellipsis
|
// Always display at least 1 character if there's no room for character + ellipsis
|
||||||
text_end_ellipsis = text + ImTextCountUtf8BytesFromChar(text, text_end_full);
|
text_end_ellipsis = text.Begin + ImTextCountUtf8BytesFromChar(text);
|
||||||
text_size_clipped_x = font->CalcTextSizeA(font_size, FLT_MAX, 0.0f, text, text_end_ellipsis).x;
|
text_size_clipped_x = font->CalcTextSizeA(font_size, FLT_MAX, 0.0f, ImStrv(text.Begin, text_end_ellipsis)).x;
|
||||||
}
|
}
|
||||||
while (text_end_ellipsis > text && ImCharIsBlankA(text_end_ellipsis[-1]))
|
while (text_end_ellipsis > text.Begin && ImCharIsBlankA(text_end_ellipsis[-1]))
|
||||||
{
|
{
|
||||||
// Trim trailing space before ellipsis (FIXME: Supporting non-ascii blanks would be nice, for this we need a function to backtrack in UTF-8 text)
|
// Trim trailing space before ellipsis (FIXME: Supporting non-ascii blanks would be nice, for this we need a function to backtrack in UTF-8 text)
|
||||||
text_end_ellipsis--;
|
text_end_ellipsis--;
|
||||||
text_size_clipped_x -= font->CalcTextSizeA(font_size, FLT_MAX, 0.0f, text_end_ellipsis, text_end_ellipsis + 1).x; // Ascii blanks are always 1 byte
|
text_size_clipped_x -= font->CalcTextSizeA(font_size, FLT_MAX, 0.0f, ImStrv(text_end_ellipsis, text_end_ellipsis + 1)).x; // Ascii blanks are always 1 byte
|
||||||
}
|
}
|
||||||
|
|
||||||
// Render text, render ellipsis
|
// Render text, render ellipsis
|
||||||
RenderTextClippedEx(draw_list, pos_min, ImVec2(clip_max_x, pos_max.y), text, text_end_ellipsis, &text_size, ImVec2(0.0f, 0.0f));
|
RenderTextClippedEx(draw_list, pos_min, ImVec2(clip_max_x, pos_max.y), ImStrv(text.Begin, text_end_ellipsis), &text_size, ImVec2(0.0f, 0.0f));
|
||||||
float ellipsis_x = pos_min.x + text_size_clipped_x;
|
float ellipsis_x = pos_min.x + text_size_clipped_x;
|
||||||
if (ellipsis_x + ellipsis_total_width <= ellipsis_max_x)
|
if (ellipsis_x + ellipsis_total_width <= ellipsis_max_x)
|
||||||
for (int i = 0; i < ellipsis_char_count; i++)
|
for (int i = 0; i < ellipsis_char_count; i++)
|
||||||
@ -3131,11 +3181,11 @@ void ImGui::RenderTextEllipsis(ImDrawList* draw_list, const ImVec2& pos_min, con
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
RenderTextClippedEx(draw_list, pos_min, ImVec2(clip_max_x, pos_max.y), text, text_end_full, &text_size, ImVec2(0.0f, 0.0f));
|
RenderTextClippedEx(draw_list, pos_min, ImVec2(clip_max_x, pos_max.y), text, &text_size, ImVec2(0.0f, 0.0f));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (g.LogEnabled)
|
if (g.LogEnabled)
|
||||||
LogRenderedText(&pos_min, text, text_end_full);
|
LogRenderedText(&pos_min, text);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Render a rectangle shaped with optional rounding and borders
|
// Render a rectangle shaped with optional rounding and borders
|
||||||
@ -3231,7 +3281,7 @@ ImGuiWindow::ImGuiWindow(ImGuiContext* context, ImStrv name) : DrawListInst(NULL
|
|||||||
{
|
{
|
||||||
memset(this, 0, sizeof(*this));
|
memset(this, 0, sizeof(*this));
|
||||||
Name = ImStrdup(name);
|
Name = ImStrdup(name);
|
||||||
NameBufLen = (int)strlen(name) + 1;
|
NameBufLen = (int)IM_IMSTR_LENGTH(name) + 1;
|
||||||
ID = ImHashStr(name);
|
ID = ImHashStr(name);
|
||||||
IDStack.push_back(ID);
|
IDStack.push_back(ID);
|
||||||
MoveId = GetID("#MOVE");
|
MoveId = GetID("#MOVE");
|
||||||
@ -3257,14 +3307,15 @@ ImGuiWindow::~ImGuiWindow()
|
|||||||
ColumnsStorage.clear_destruct();
|
ColumnsStorage.clear_destruct();
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGuiID ImGuiWindow::GetID(const char* str, const char* str_end)
|
ImGuiID ImGuiWindow::GetID(ImStrv str)
|
||||||
{
|
{
|
||||||
ImGuiID seed = IDStack.back();
|
ImGuiID seed = IDStack.back();
|
||||||
ImGuiID id = ImHashStr(str, str_end ? (str_end - str) : 0, seed);
|
ImGuiID id = ImHashStr(str, seed);
|
||||||
ImGui::KeepAliveID(id);
|
ImGui::KeepAliveID(id);
|
||||||
ImGuiContext& g = *GImGui;
|
ImGuiContext& g = *GImGui;
|
||||||
|
IM_IMSTR_ENSURE_HAS_END(str);
|
||||||
if (g.DebugHookIdInfo == id)
|
if (g.DebugHookIdInfo == id)
|
||||||
ImGui::DebugHookIdInfo(id, ImGuiDataType_String, str, str_end);
|
ImGui::DebugHookIdInfo(id, ImGuiDataType_String, str.Begin, str.End);
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3290,13 +3341,14 @@ ImGuiID ImGuiWindow::GetID(int n)
|
|||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGuiID ImGuiWindow::GetIDNoKeepAlive(const char* str, const char* str_end)
|
ImGuiID ImGuiWindow::GetIDNoKeepAlive(ImStrv str)
|
||||||
{
|
{
|
||||||
ImGuiID seed = IDStack.back();
|
ImGuiID seed = IDStack.back();
|
||||||
ImGuiID id = ImHashStr(str, str_end ? (str_end - str) : 0, seed);
|
IM_IMSTR_ENSURE_HAS_END(str);
|
||||||
|
ImGuiID id = ImHashStr(str.Begin, str.End - str.Begin, seed);
|
||||||
ImGuiContext& g = *GImGui;
|
ImGuiContext& g = *GImGui;
|
||||||
if (g.DebugHookIdInfo == id)
|
if (g.DebugHookIdInfo == id)
|
||||||
ImGui::DebugHookIdInfo(id, ImGuiDataType_String, str, str_end);
|
ImGui::DebugHookIdInfo(id, ImGuiDataType_String, str.Begin, str.End);
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3652,7 +3704,15 @@ void ImGui::SetClipboardText(ImStrv text)
|
|||||||
{
|
{
|
||||||
ImGuiContext& g = *GImGui;
|
ImGuiContext& g = *GImGui;
|
||||||
if (g.IO.SetClipboardTextFn)
|
if (g.IO.SetClipboardTextFn)
|
||||||
g.IO.SetClipboardTextFn(g.IO.ClipboardUserData, text);
|
{
|
||||||
|
int len = (int)IM_IMSTR_LENGTH(text);
|
||||||
|
char* text_p = (char*)IM_ALLOC(len + 1);
|
||||||
|
if (len > 0)
|
||||||
|
memcpy(text_p, text.Begin, len);
|
||||||
|
text_p[len] = 0; // text may not contain \0, it must be inserted manually.
|
||||||
|
g.IO.SetClipboardTextFn(g.IO.ClipboardUserData, text_p);
|
||||||
|
IM_FREE(text_p);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* ImGui::GetVersion()
|
const char* ImGui::GetVersion()
|
||||||
@ -4945,21 +5005,19 @@ void ImGui::Render()
|
|||||||
|
|
||||||
// Calculate text size. Text can be multi-line. Optionally ignore text after a ## marker.
|
// Calculate text size. Text can be multi-line. Optionally ignore text after a ## marker.
|
||||||
// CalcTextSize("") should return ImVec2(0.0f, g.FontSize)
|
// CalcTextSize("") should return ImVec2(0.0f, g.FontSize)
|
||||||
ImVec2 ImGui::CalcTextSize(const char* text, const char* text_end, bool hide_text_after_double_hash, float wrap_width)
|
ImVec2 ImGui::CalcTextSize(ImStrv text, bool hide_text_after_double_hash, float wrap_width)
|
||||||
{
|
{
|
||||||
ImGuiContext& g = *GImGui;
|
ImGuiContext& g = *GImGui;
|
||||||
|
|
||||||
const char* text_display_end;
|
IM_IMSTR_ENSURE_HAS_END(text);
|
||||||
if (hide_text_after_double_hash)
|
if (hide_text_after_double_hash)
|
||||||
text_display_end = FindRenderedTextEnd(text, text_end); // Hide anything after a '##' string
|
text.End = FindRenderedTextEnd(text); // Hide anything after a '##' string
|
||||||
else
|
|
||||||
text_display_end = text_end;
|
|
||||||
|
|
||||||
ImFont* font = g.Font;
|
ImFont* font = g.Font;
|
||||||
const float font_size = g.FontSize;
|
const float font_size = g.FontSize;
|
||||||
if (text == text_display_end)
|
if (text.Begin == text.End)
|
||||||
return ImVec2(0.0f, font_size);
|
return ImVec2(0.0f, font_size);
|
||||||
ImVec2 text_size = font->CalcTextSizeA(font_size, FLT_MAX, wrap_width, text, text_display_end, NULL);
|
ImVec2 text_size = font->CalcTextSizeA(font_size, FLT_MAX, wrap_width, text, NULL);
|
||||||
|
|
||||||
// Round
|
// Round
|
||||||
// FIXME: This has been here since Dec 2015 (7b0bf230) but down the line we want this out.
|
// FIXME: This has been here since Dec 2015 (7b0bf230) but down the line we want this out.
|
||||||
@ -5186,7 +5244,7 @@ bool ImGui::BeginChildEx(ImStrv name, ImGuiID id, const ImVec2& size_arg, bool b
|
|||||||
|
|
||||||
// Build up name. If you need to append to a same child from multiple location in the ID stack, use BeginChild(ImGuiID id) with a stable value.
|
// Build up name. If you need to append to a same child from multiple location in the ID stack, use BeginChild(ImGuiID id) with a stable value.
|
||||||
if (name)
|
if (name)
|
||||||
ImFormatString(g.TempBuffer, IM_ARRAYSIZE(g.TempBuffer), "%s/%s_%08X", parent_window->Name, name, id);
|
ImFormatString(g.TempBuffer, IM_ARRAYSIZE(g.TempBuffer), "%s/%.*s_%08X", parent_window->Name, (int)IM_IMSTR_LENGTH(name), name.Begin, id);
|
||||||
else
|
else
|
||||||
ImFormatString(g.TempBuffer, IM_ARRAYSIZE(g.TempBuffer), "%s/%08X", parent_window->Name, id);
|
ImFormatString(g.TempBuffer, IM_ARRAYSIZE(g.TempBuffer), "%s/%08X", parent_window->Name, id);
|
||||||
|
|
||||||
@ -5887,7 +5945,7 @@ void ImGui::RenderWindowTitleBarContents(ImGuiWindow* window, const ImRect& titl
|
|||||||
// Title bar text (with: horizontal alignment, avoiding collapse/close button, optional "unsaved document" marker)
|
// Title bar text (with: horizontal alignment, avoiding collapse/close button, optional "unsaved document" marker)
|
||||||
// FIXME: Refactor text alignment facilities along with RenderText helpers, this is WAY too much messy code..
|
// FIXME: Refactor text alignment facilities along with RenderText helpers, this is WAY too much messy code..
|
||||||
const float marker_size_x = (flags & ImGuiWindowFlags_UnsavedDocument) ? button_sz * 0.80f : 0.0f;
|
const float marker_size_x = (flags & ImGuiWindowFlags_UnsavedDocument) ? button_sz * 0.80f : 0.0f;
|
||||||
const ImVec2 text_size = CalcTextSize(name, NULL, true) + ImVec2(marker_size_x, 0.0f);
|
const ImVec2 text_size = CalcTextSize(name, true) + ImVec2(marker_size_x, 0.0f);
|
||||||
|
|
||||||
// As a nice touch we try to ensure that centered title text doesn't get affected by visibility of Close/Collapse button,
|
// As a nice touch we try to ensure that centered title text doesn't get affected by visibility of Close/Collapse button,
|
||||||
// while uncentered title text will still reach edges correctly.
|
// while uncentered title text will still reach edges correctly.
|
||||||
@ -5918,7 +5976,7 @@ void ImGui::RenderWindowTitleBarContents(ImGuiWindow* window, const ImRect& titl
|
|||||||
}
|
}
|
||||||
//if (g.IO.KeyShift) window->DrawList->AddRect(layout_r.Min, layout_r.Max, IM_COL32(255, 128, 0, 255)); // [DEBUG]
|
//if (g.IO.KeyShift) window->DrawList->AddRect(layout_r.Min, layout_r.Max, IM_COL32(255, 128, 0, 255)); // [DEBUG]
|
||||||
//if (g.IO.KeyCtrl) window->DrawList->AddRect(clip_r.Min, clip_r.Max, IM_COL32(255, 128, 0, 255)); // [DEBUG]
|
//if (g.IO.KeyCtrl) window->DrawList->AddRect(clip_r.Min, clip_r.Max, IM_COL32(255, 128, 0, 255)); // [DEBUG]
|
||||||
RenderTextClipped(layout_r.Min, layout_r.Max, name, NULL, &text_size, style.WindowTitleAlign, &clip_r);
|
RenderTextClipped(layout_r.Min, layout_r.Max, name, &text_size, style.WindowTitleAlign, &clip_r);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImGui::UpdateWindowParentAndRootLinks(ImGuiWindow* window, ImGuiWindowFlags flags, ImGuiWindow* parent_window)
|
void ImGui::UpdateWindowParentAndRootLinks(ImGuiWindow* window, ImGuiWindowFlags flags, ImGuiWindow* parent_window)
|
||||||
@ -5981,7 +6039,7 @@ bool ImGui::Begin(ImStrv name, bool* p_open, ImGuiWindowFlags flags)
|
|||||||
{
|
{
|
||||||
ImGuiContext& g = *GImGui;
|
ImGuiContext& g = *GImGui;
|
||||||
const ImGuiStyle& style = g.Style;
|
const ImGuiStyle& style = g.Style;
|
||||||
IM_ASSERT(name != NULL && name[0] != '\0'); // Window name required
|
IM_ASSERT(!name.Empty()); // Window name required
|
||||||
IM_ASSERT(g.WithinFrameScope); // Forgot to call ImGui::NewFrame()
|
IM_ASSERT(g.WithinFrameScope); // Forgot to call ImGui::NewFrame()
|
||||||
IM_ASSERT(g.FrameCountEnded != g.FrameCount); // Called ImGui::Render() or ImGui::EndFrame() and haven't called ImGui::NewFrame() again yet
|
IM_ASSERT(g.FrameCountEnded != g.FrameCount); // Called ImGui::Render() or ImGui::EndFrame() and haven't called ImGui::NewFrame() again yet
|
||||||
|
|
||||||
@ -6138,7 +6196,7 @@ bool ImGui::Begin(ImStrv name, bool* p_open, ImGuiWindowFlags flags)
|
|||||||
bool window_title_visible_elsewhere = false;
|
bool window_title_visible_elsewhere = false;
|
||||||
if (g.NavWindowingListWindow != NULL && (window->Flags & ImGuiWindowFlags_NoNavFocus) == 0) // Window titles visible when using CTRL+TAB
|
if (g.NavWindowingListWindow != NULL && (window->Flags & ImGuiWindowFlags_NoNavFocus) == 0) // Window titles visible when using CTRL+TAB
|
||||||
window_title_visible_elsewhere = true;
|
window_title_visible_elsewhere = true;
|
||||||
if (window_title_visible_elsewhere && !window_just_created && strcmp(name, window->Name) != 0)
|
if (window_title_visible_elsewhere && !window_just_created && name != ImStrv(window->Name))
|
||||||
{
|
{
|
||||||
size_t buf_len = (size_t)window->NameBufLen;
|
size_t buf_len = (size_t)window->NameBufLen;
|
||||||
window->Name = ImStrdupcpy(window->Name, &buf_len, name);
|
window->Name = ImStrdupcpy(window->Name, &buf_len, name);
|
||||||
@ -7420,7 +7478,7 @@ void ImGui::PushID(const char* str_id_begin, const char* str_id_end)
|
|||||||
{
|
{
|
||||||
ImGuiContext& g = *GImGui;
|
ImGuiContext& g = *GImGui;
|
||||||
ImGuiWindow* window = g.CurrentWindow;
|
ImGuiWindow* window = g.CurrentWindow;
|
||||||
ImGuiID id = window->GetIDNoKeepAlive(str_id_begin, str_id_end);
|
ImGuiID id = window->GetIDNoKeepAlive(ImStrv(str_id_begin, str_id_end));
|
||||||
window->IDStack.push_back(id);
|
window->IDStack.push_back(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -7479,7 +7537,7 @@ ImGuiID ImGui::GetID(ImStrv str_id)
|
|||||||
ImGuiID ImGui::GetID(const char* str_id_begin, const char* str_id_end)
|
ImGuiID ImGui::GetID(const char* str_id_begin, const char* str_id_end)
|
||||||
{
|
{
|
||||||
ImGuiWindow* window = GImGui->CurrentWindow;
|
ImGuiWindow* window = GImGui->CurrentWindow;
|
||||||
return window->GetID(str_id_begin, str_id_end);
|
return window->GetID(ImStrv(str_id_begin, str_id_end));
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGuiID ImGui::GetID(const void* ptr_id)
|
ImGuiID ImGui::GetID(const void* ptr_id)
|
||||||
@ -7963,7 +8021,7 @@ void ImGui::UpdateInputEvents(bool trickle_fast_inputs)
|
|||||||
bool ImGui::DebugCheckVersionAndDataLayout(ImStrv version, size_t sz_io, size_t sz_style, size_t sz_vec2, size_t sz_vec4, size_t sz_vert, size_t sz_idx)
|
bool ImGui::DebugCheckVersionAndDataLayout(ImStrv version, size_t sz_io, size_t sz_style, size_t sz_vec2, size_t sz_vec4, size_t sz_vert, size_t sz_idx)
|
||||||
{
|
{
|
||||||
bool error = false;
|
bool error = false;
|
||||||
if (strcmp(version, IMGUI_VERSION) != 0) { error = true; IM_ASSERT(strcmp(version, IMGUI_VERSION) == 0 && "Mismatched version string!"); }
|
if (version != ImStrv(IMGUI_VERSION)) { error = true; IM_ASSERT(version == ImStrv(IMGUI_VERSION) && "Mismatched version string!"); }
|
||||||
if (sz_io != sizeof(ImGuiIO)) { error = true; IM_ASSERT(sz_io == sizeof(ImGuiIO) && "Mismatched struct layout!"); }
|
if (sz_io != sizeof(ImGuiIO)) { error = true; IM_ASSERT(sz_io == sizeof(ImGuiIO) && "Mismatched struct layout!"); }
|
||||||
if (sz_style != sizeof(ImGuiStyle)) { error = true; IM_ASSERT(sz_style == sizeof(ImGuiStyle) && "Mismatched struct layout!"); }
|
if (sz_style != sizeof(ImGuiStyle)) { error = true; IM_ASSERT(sz_style == sizeof(ImGuiStyle) && "Mismatched struct layout!"); }
|
||||||
if (sz_vec2 != sizeof(ImVec2)) { error = true; IM_ASSERT(sz_vec2 == sizeof(ImVec2) && "Mismatched struct layout!"); }
|
if (sz_vec2 != sizeof(ImVec2)) { error = true; IM_ASSERT(sz_vec2 == sizeof(ImVec2) && "Mismatched struct layout!"); }
|
||||||
@ -11121,8 +11179,8 @@ bool ImGui::SetDragDropPayload(ImStrv type, const void* data, size_t data_size,
|
|||||||
if (cond == 0)
|
if (cond == 0)
|
||||||
cond = ImGuiCond_Always;
|
cond = ImGuiCond_Always;
|
||||||
|
|
||||||
IM_ASSERT(type != NULL);
|
IM_ASSERT(!type.Empty() && "Payload type can not be empty");
|
||||||
IM_ASSERT(strlen(type) < IM_ARRAYSIZE(payload.DataType) && "Payload type can be at most 32 characters long");
|
IM_ASSERT(IM_IMSTR_LENGTH(type) < IM_ARRAYSIZE(payload.DataType) && "Payload type can be at most 32 characters long");
|
||||||
IM_ASSERT((data != NULL && data_size > 0) || (data == NULL && data_size == 0));
|
IM_ASSERT((data != NULL && data_size > 0) || (data == NULL && data_size == 0));
|
||||||
IM_ASSERT(cond == ImGuiCond_Always || cond == ImGuiCond_Once);
|
IM_ASSERT(cond == ImGuiCond_Always || cond == ImGuiCond_Once);
|
||||||
IM_ASSERT(payload.SourceId != 0); // Not called between BeginDragDropSource() and EndDragDropSource()
|
IM_ASSERT(payload.SourceId != 0); // Not called between BeginDragDropSource() and EndDragDropSource()
|
||||||
@ -11225,7 +11283,7 @@ const ImGuiPayload* ImGui::AcceptDragDropPayload(ImStrv type, ImGuiDragDropFlags
|
|||||||
ImGuiPayload& payload = g.DragDropPayload;
|
ImGuiPayload& payload = g.DragDropPayload;
|
||||||
IM_ASSERT(g.DragDropActive); // Not called between BeginDragDropTarget() and EndDragDropTarget() ?
|
IM_ASSERT(g.DragDropActive); // Not called between BeginDragDropTarget() and EndDragDropTarget() ?
|
||||||
IM_ASSERT(payload.DataFrameCount != -1); // Forgot to call EndDragDropTarget() ?
|
IM_ASSERT(payload.DataFrameCount != -1); // Forgot to call EndDragDropTarget() ?
|
||||||
if (type != NULL && !payload.IsDataType(type))
|
if (type && !payload.IsDataType(type))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
// Accept smallest drag target bounding box, this allows us to nest drag targets conveniently without ordering constraints.
|
// Accept smallest drag target bounding box, this allows us to nest drag targets conveniently without ordering constraints.
|
||||||
@ -11316,7 +11374,7 @@ void ImGui::LogTextV(const char* fmt, va_list args)
|
|||||||
// Internal version that takes a position to decide on newline placement and pad items according to their depth.
|
// Internal version that takes a position to decide on newline placement and pad items according to their depth.
|
||||||
// We split text into individual lines to add current tree level padding
|
// We split text into individual lines to add current tree level padding
|
||||||
// FIXME: This code is a little complicated perhaps, considering simplifying the whole system.
|
// FIXME: This code is a little complicated perhaps, considering simplifying the whole system.
|
||||||
void ImGui::LogRenderedText(const ImVec2* ref_pos, const char* text, const char* text_end)
|
void ImGui::LogRenderedText(const ImVec2* ref_pos, ImStrv text)
|
||||||
{
|
{
|
||||||
ImGuiContext& g = *GImGui;
|
ImGuiContext& g = *GImGui;
|
||||||
ImGuiWindow* window = g.CurrentWindow;
|
ImGuiWindow* window = g.CurrentWindow;
|
||||||
@ -11325,8 +11383,8 @@ void ImGui::LogRenderedText(const ImVec2* ref_pos, const char* text, const char*
|
|||||||
const char* suffix = g.LogNextSuffix;
|
const char* suffix = g.LogNextSuffix;
|
||||||
g.LogNextPrefix = g.LogNextSuffix = NULL;
|
g.LogNextPrefix = g.LogNextSuffix = NULL;
|
||||||
|
|
||||||
if (!text_end)
|
if (!text.End)
|
||||||
text_end = FindRenderedTextEnd(text, text_end);
|
text.End = FindRenderedTextEnd(text);
|
||||||
|
|
||||||
const bool log_new_line = ref_pos && (ref_pos->y > g.LogLinePosY + g.Style.FramePadding.y + 1);
|
const bool log_new_line = ref_pos && (ref_pos->y > g.LogLinePosY + g.Style.FramePadding.y + 1);
|
||||||
if (ref_pos)
|
if (ref_pos)
|
||||||
@ -11345,14 +11403,14 @@ void ImGui::LogRenderedText(const ImVec2* ref_pos, const char* text, const char*
|
|||||||
g.LogDepthRef = window->DC.TreeDepth;
|
g.LogDepthRef = window->DC.TreeDepth;
|
||||||
const int tree_depth = (window->DC.TreeDepth - g.LogDepthRef);
|
const int tree_depth = (window->DC.TreeDepth - g.LogDepthRef);
|
||||||
|
|
||||||
const char* text_remaining = text;
|
const char* text_remaining = text.Begin;
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
// Split the string. Each new line (after a '\n') is followed by indentation corresponding to the current depth of our log entry.
|
// Split the string. Each new line (after a '\n') is followed by indentation corresponding to the current depth of our log entry.
|
||||||
// We don't add a trailing \n yet to allow a subsequent item on the same line to be captured.
|
// We don't add a trailing \n yet to allow a subsequent item on the same line to be captured.
|
||||||
const char* line_start = text_remaining;
|
const char* line_start = text_remaining;
|
||||||
const char* line_end = ImStreolRange(line_start, text_end);
|
const char* line_end = ImStreolRange(line_start, text.End);
|
||||||
const bool is_last_line = (line_end == text_end);
|
const bool is_last_line = (line_end == text.End);
|
||||||
if (line_start != line_end || !is_last_line)
|
if (line_start != line_end || !is_last_line)
|
||||||
{
|
{
|
||||||
const int line_length = (int)(line_end - line_start);
|
const int line_length = (int)(line_end - line_start);
|
||||||
@ -11421,9 +11479,9 @@ void ImGui::LogToFile(int auto_open_depth, ImStrv filename)
|
|||||||
// FIXME: We could probably open the file in text mode "at", however note that clipboard/buffer logging will still
|
// FIXME: We could probably open the file in text mode "at", however note that clipboard/buffer logging will still
|
||||||
// be subject to outputting OS-incompatible carriage return if within strings the user doesn't use IM_NEWLINE.
|
// be subject to outputting OS-incompatible carriage return if within strings the user doesn't use IM_NEWLINE.
|
||||||
// By opening the file in binary mode "ab" we have consistent output everywhere.
|
// By opening the file in binary mode "ab" we have consistent output everywhere.
|
||||||
if (!filename)
|
if (filename.Empty())
|
||||||
filename = g.IO.LogFilename;
|
filename = g.IO.LogFilename;
|
||||||
if (!filename || !filename[0])
|
if (filename.Empty())
|
||||||
return;
|
return;
|
||||||
ImFileHandle f = ImFileOpen(filename, "ab");
|
ImFileHandle f = ImFileOpen(filename, "ab");
|
||||||
if (!f)
|
if (!f)
|
||||||
@ -11580,21 +11638,27 @@ void ImGui::MarkIniSettingsDirty(ImGuiWindow* window)
|
|||||||
ImGuiWindowSettings* ImGui::CreateNewWindowSettings(ImStrv name)
|
ImGuiWindowSettings* ImGui::CreateNewWindowSettings(ImStrv name)
|
||||||
{
|
{
|
||||||
ImGuiContext& g = *GImGui;
|
ImGuiContext& g = *GImGui;
|
||||||
|
const size_t name_len = IM_IMSTR_LENGTH(name);
|
||||||
|
if (!name_len)
|
||||||
|
{
|
||||||
|
IM_ASSERT(false && "Name must not be empty.");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
#if !IMGUI_DEBUG_INI_SETTINGS
|
#if !IMGUI_DEBUG_INI_SETTINGS
|
||||||
// Skip to the "###" marker if any. We don't skip past to match the behavior of GetID()
|
// Skip to the "###" marker if any. We don't skip past to match the behavior of GetID()
|
||||||
// Preserve the full string when IMGUI_DEBUG_INI_SETTINGS is set to make .ini inspection easier.
|
// Preserve the full string when IMGUI_DEBUG_INI_SETTINGS is set to make .ini inspection easier.
|
||||||
if (const char* p = strstr(name, "###"))
|
if (const char* p = ImStrstr(name, "###"))
|
||||||
name = p;
|
name.Begin = p;
|
||||||
#endif
|
#endif
|
||||||
const size_t name_len = strlen(name);
|
|
||||||
|
|
||||||
// Allocate chunk
|
// Allocate chunk
|
||||||
const size_t chunk_size = sizeof(ImGuiWindowSettings) + name_len + 1;
|
const size_t chunk_size = sizeof(ImGuiWindowSettings) + name_len + 1;
|
||||||
ImGuiWindowSettings* settings = g.SettingsWindows.alloc_chunk(chunk_size);
|
ImGuiWindowSettings* settings = g.SettingsWindows.alloc_chunk(chunk_size);
|
||||||
IM_PLACEMENT_NEW(settings) ImGuiWindowSettings();
|
IM_PLACEMENT_NEW(settings) ImGuiWindowSettings();
|
||||||
settings->ID = ImHashStr(name, name_len);
|
settings->ID = ImHashStr(name);
|
||||||
memcpy(settings->GetName(), name, name_len + 1); // Store with zero terminator
|
memcpy(settings->GetName(), name.Begin, name_len);
|
||||||
|
settings->GetName()[name_len] = 0; // name may not contain \0, it must be inserted manually.
|
||||||
|
|
||||||
return settings;
|
return settings;
|
||||||
}
|
}
|
||||||
@ -11655,11 +11719,11 @@ void ImGui::LoadIniSettingsFromMemory(ImStrv ini_data, size_t ini_size)
|
|||||||
// For user convenience, we allow passing a non zero-terminated string (hence the ini_size parameter).
|
// For user convenience, we allow passing a non zero-terminated string (hence the ini_size parameter).
|
||||||
// For our convenience and to make the code simpler, we'll also write zero-terminators within the buffer. So let's create a writable copy..
|
// For our convenience and to make the code simpler, we'll also write zero-terminators within the buffer. So let's create a writable copy..
|
||||||
if (ini_size == 0)
|
if (ini_size == 0)
|
||||||
ini_size = strlen(ini_data);
|
ini_size = IM_IMSTR_LENGTH(ini_data);
|
||||||
g.SettingsIniData.Buf.resize((int)ini_size + 1);
|
g.SettingsIniData.Buf.resize((int)ini_size + 1);
|
||||||
char* const buf = g.SettingsIniData.Buf.Data;
|
char* const buf = g.SettingsIniData.Buf.Data;
|
||||||
char* const buf_end = buf + ini_size;
|
char* const buf_end = buf + ini_size;
|
||||||
memcpy(buf, ini_data, ini_size);
|
memcpy(buf, ini_data.Begin, ini_size);
|
||||||
buf_end[0] = 0;
|
buf_end[0] = 0;
|
||||||
|
|
||||||
// Call pre-read handlers
|
// Call pre-read handlers
|
||||||
@ -11707,7 +11771,7 @@ void ImGui::LoadIniSettingsFromMemory(ImStrv ini_data, size_t ini_size)
|
|||||||
g.SettingsLoaded = true;
|
g.SettingsLoaded = true;
|
||||||
|
|
||||||
// [DEBUG] Restore untouched copy so it can be browsed in Metrics (not strictly necessary)
|
// [DEBUG] Restore untouched copy so it can be browsed in Metrics (not strictly necessary)
|
||||||
memcpy(buf, ini_data, ini_size);
|
memcpy(buf, ini_data.Begin, ini_size);
|
||||||
|
|
||||||
// Call post-read handlers
|
// Call post-read handlers
|
||||||
for (int handler_n = 0; handler_n < g.SettingsHandlers.Size; handler_n++)
|
for (int handler_n = 0; handler_n < g.SettingsHandlers.Size; handler_n++)
|
||||||
|
86
imgui.h
86
imgui.h
@ -268,9 +268,47 @@ struct ImVec4
|
|||||||
IM_VEC4_CLASS_EXTRA // Define additional constructors and implicit cast operators in imconfig.h to convert back and forth between your math types and ImVec4.
|
IM_VEC4_CLASS_EXTRA // Define additional constructors and implicit cast operators in imconfig.h to convert back and forth between your math types and ImVec4.
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
IM_MSVC_RUNTIME_CHECKS_RESTORE
|
|
||||||
|
|
||||||
typedef const char* ImStrv;
|
#define IM_IMSTR_LENGTH(s) (s.Begin ? (s.End ? (size_t)(s.End - s.Begin) : strlen(s.Begin)) : 0)
|
||||||
|
#define IM_IMSTR_ENSURE_HAS_END(s) if (s.End == NULL) s.End = s.Begin + strlen(s.Begin)
|
||||||
|
|
||||||
|
// String view class.
|
||||||
|
#define IMGUI_HAS_IMSTR
|
||||||
|
struct ImStrv
|
||||||
|
{
|
||||||
|
const char* Begin;
|
||||||
|
const char* End;
|
||||||
|
ImStrv() { Begin = End = NULL; }
|
||||||
|
ImStrv(const char* b) { Begin = b; End = NULL; }
|
||||||
|
ImStrv(const char* b, const char* e) { Begin = b; End = e; }
|
||||||
|
ImStrv(const char* b, size_t size) { Begin = b; End = b + size; }
|
||||||
|
bool Empty() const { return Begin == NULL || Begin == End || Begin[0] == 0; }
|
||||||
|
// void EnsureHasEnd() { if (End == NULL) End = Begin + Length(); }
|
||||||
|
// size_t Length() const
|
||||||
|
// {
|
||||||
|
// if (Begin == NULL)
|
||||||
|
// return 0;
|
||||||
|
// if (End == NULL)
|
||||||
|
// return strlen(Begin);
|
||||||
|
// return (size_t)(End - Begin);
|
||||||
|
// }
|
||||||
|
bool operator==(ImStrv other) const
|
||||||
|
{
|
||||||
|
if (Begin == other.Begin && End == other.End)
|
||||||
|
return true;
|
||||||
|
size_t len = IM_IMSTR_LENGTH((*this));
|
||||||
|
if (len == IM_IMSTR_LENGTH(other))
|
||||||
|
return memcmp(Begin, other.Begin, len) == 0;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
operator bool() const { return Begin != NULL; }
|
||||||
|
char operator[](int index) const { return Begin[index]; }
|
||||||
|
#ifdef IM_IMSTR_CLASS_EXTRA
|
||||||
|
IM_IMSTR_CLASS_EXTRA // Define additional constructors and implicit cast operators in imconfig.h to convert back and forth between your math types and ImStrv.
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
IM_MSVC_RUNTIME_CHECKS_RESTORE
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// [SECTION] Dear ImGui end-user API functions
|
// [SECTION] Dear ImGui end-user API functions
|
||||||
@ -465,16 +503,18 @@ namespace ImGui
|
|||||||
// - In this header file we use the "label"/"name" terminology to denote a string that will be displayed + used as an ID,
|
// - In this header file we use the "label"/"name" terminology to denote a string that will be displayed + used as an ID,
|
||||||
// whereas "str_id" denote a string that is only used as an ID and not normally displayed.
|
// whereas "str_id" denote a string that is only used as an ID and not normally displayed.
|
||||||
IMGUI_API void PushID(ImStrv str_id); // push string into the ID stack (will hash string).
|
IMGUI_API void PushID(ImStrv str_id); // push string into the ID stack (will hash string).
|
||||||
IMGUI_API void PushID(const char* str_id_begin, const char* str_id_end); // push string into the ID stack (will hash string).
|
IMGUI_API void PushID(const char* str_id_begin, const char* str_id_end = NULL);// push string into the ID stack (will hash string).
|
||||||
IMGUI_API void PushID(const void* ptr_id); // push pointer into the ID stack (will hash pointer).
|
IMGUI_API void PushID(const void* ptr_id); // push pointer into the ID stack (will hash pointer).
|
||||||
IMGUI_API void PushID(int int_id); // push integer into the ID stack (will hash integer).
|
IMGUI_API void PushID(int int_id); // push integer into the ID stack (will hash integer).
|
||||||
IMGUI_API void PopID(); // pop from the ID stack.
|
IMGUI_API void PopID(); // pop from the ID stack.
|
||||||
IMGUI_API ImGuiID GetID(ImStrv str_id); // calculate unique ID (hash of whole ID stack + given parameter). e.g. if you want to query into ImGuiStorage yourself
|
IMGUI_API ImGuiID GetID(ImStrv str_id); // calculate unique ID (hash of whole ID stack + given parameter). e.g. if you want to query into ImGuiStorage yourself
|
||||||
IMGUI_API ImGuiID GetID(const char* str_id_begin, const char* str_id_end);
|
IMGUI_API ImGuiID GetID(const char* str_id_begin, const char* str_id_end = NULL);
|
||||||
IMGUI_API ImGuiID GetID(const void* ptr_id);
|
IMGUI_API ImGuiID GetID(const void* ptr_id);
|
||||||
|
|
||||||
// Widgets: Text
|
// Widgets: Text
|
||||||
IMGUI_API void TextUnformatted(const char* text, const char* text_end = NULL); // raw text without formatting. Roughly equivalent to Text("%s", text) but: A) doesn't require null terminated string if 'text_end' is specified, B) it's faster, no memory copy is done, no buffer size limits, recommended for long chunks of text.
|
// FIXME-IMSTR: Functions taking format should use ImStrv. It breaks IM_FMTARGS() macro however.
|
||||||
|
IMGUI_API void TextUnformatted(ImStrv text); // raw text without formatting. Roughly equivalent to Text("%s", text) but: A) doesn't require null terminated string if 'text_end' is specified, B) it's faster, no memory copy is done, no buffer size limits, recommended for long chunks of text.
|
||||||
|
inline void TextUnformatted(const char* text, const char* text_end) { TextUnformatted(ImStrv(text, text_end)); }
|
||||||
IMGUI_API void Text(const char* fmt, ...) IM_FMTARGS(1); // formatted text
|
IMGUI_API void Text(const char* fmt, ...) IM_FMTARGS(1); // formatted text
|
||||||
IMGUI_API void TextV(const char* fmt, va_list args) IM_FMTLIST(1);
|
IMGUI_API void TextV(const char* fmt, va_list args) IM_FMTLIST(1);
|
||||||
IMGUI_API void TextColored(const ImVec4& col, const char* fmt, ...) IM_FMTARGS(2); // shortcut for PushStyleColor(ImGuiCol_Text, col); Text(fmt, ...); PopStyleColor();
|
IMGUI_API void TextColored(const ImVec4& col, const char* fmt, ...) IM_FMTARGS(2); // shortcut for PushStyleColor(ImGuiCol_Text, col); Text(fmt, ...); PopStyleColor();
|
||||||
@ -491,7 +531,7 @@ namespace ImGui
|
|||||||
// Widgets: Main
|
// Widgets: Main
|
||||||
// - Most widgets return true when the value has been changed or when pressed/selected
|
// - Most widgets return true when the value has been changed or when pressed/selected
|
||||||
// - You may also use one of the many IsItemXXX functions (e.g. IsItemActive, IsItemHovered, etc.) to query widget state.
|
// - You may also use one of the many IsItemXXX functions (e.g. IsItemActive, IsItemHovered, etc.) to query widget state.
|
||||||
IMGUI_API bool Button(const ImStrv label, const ImVec2& size = ImVec2(0, 0)); // button
|
IMGUI_API bool Button(ImStrv label, const ImVec2& size = ImVec2(0, 0)); // button
|
||||||
IMGUI_API bool SmallButton(ImStrv label); // button with FramePadding=(0,0) to easily embed within text
|
IMGUI_API bool SmallButton(ImStrv label); // button with FramePadding=(0,0) to easily embed within text
|
||||||
IMGUI_API bool InvisibleButton(ImStrv str_id, const ImVec2& size, ImGuiButtonFlags flags = 0); // flexible button behavior without the visuals, frequently useful to build custom behaviors using the public api (along with IsItemActive, IsItemHovered, etc.)
|
IMGUI_API bool InvisibleButton(ImStrv str_id, const ImVec2& size, ImGuiButtonFlags flags = 0); // flexible button behavior without the visuals, frequently useful to build custom behaviors using the public api (along with IsItemActive, IsItemHovered, etc.)
|
||||||
IMGUI_API bool ArrowButton(ImStrv str_id, ImGuiDir dir); // square button with an arrow shape
|
IMGUI_API bool ArrowButton(ImStrv str_id, ImGuiDir dir); // square button with an arrow shape
|
||||||
@ -867,7 +907,8 @@ namespace ImGui
|
|||||||
IMGUI_API void EndChildFrame(); // always call EndChildFrame() regardless of BeginChildFrame() return values (which indicates a collapsed/clipped window)
|
IMGUI_API void EndChildFrame(); // always call EndChildFrame() regardless of BeginChildFrame() return values (which indicates a collapsed/clipped window)
|
||||||
|
|
||||||
// Text Utilities
|
// Text Utilities
|
||||||
IMGUI_API ImVec2 CalcTextSize(const char* text, const char* text_end = NULL, bool hide_text_after_double_hash = false, float wrap_width = -1.0f);
|
IMGUI_API ImVec2 CalcTextSize(ImStrv text, bool hide_text_after_double_hash = false, float wrap_width = -1.0f);
|
||||||
|
inline ImVec2 CalcTextSize(const char* text, const char* text_end, bool hide_text_after_double_hash = false, float wrap_width = -1.0f) { return CalcTextSize(ImStrv(text, text_end), hide_text_after_double_hash, wrap_width); }
|
||||||
|
|
||||||
// Color Utilities
|
// Color Utilities
|
||||||
IMGUI_API ImVec4 ColorConvertU32ToFloat4(ImU32 in);
|
IMGUI_API ImVec4 ColorConvertU32ToFloat4(ImU32 in);
|
||||||
@ -2083,7 +2124,7 @@ struct ImGuiInputTextCallbackData
|
|||||||
ImWchar EventChar; // Character input // Read-write // [CharFilter] Replace character with another one, or set to zero to drop. return 1 is equivalent to setting EventChar=0;
|
ImWchar EventChar; // Character input // Read-write // [CharFilter] Replace character with another one, or set to zero to drop. return 1 is equivalent to setting EventChar=0;
|
||||||
ImGuiKey EventKey; // Key pressed (Up/Down/TAB) // Read-only // [Completion,History]
|
ImGuiKey EventKey; // Key pressed (Up/Down/TAB) // Read-only // [Completion,History]
|
||||||
char* Buf; // Text buffer // Read-write // [Resize] Can replace pointer / [Completion,History,Always] Only write to pointed data, don't replace the actual pointer!
|
char* Buf; // Text buffer // Read-write // [Resize] Can replace pointer / [Completion,History,Always] Only write to pointed data, don't replace the actual pointer!
|
||||||
int BufTextLen; // Text length (in bytes) // Read-write // [Resize,Completion,History,Always] Exclude zero-terminator storage. In C land: == strlen(some_text), in C++ land: string.length()
|
int BufTextLen; // Text length (in bytes) // Read-write // [Resize,Completion,History,Always] Exclude zero-terminator storage. In C land: == strlen(some_text), in C++ land: IM_IMSTR_LENGTH(string)
|
||||||
int BufSize; // Buffer size (in bytes) = capacity+1 // Read-only // [Resize,Completion,History,Always] Include zero-terminator storage. In C land == ARRAYSIZE(my_char_array), in C++ land: string.capacity()+1
|
int BufSize; // Buffer size (in bytes) = capacity+1 // Read-only // [Resize,Completion,History,Always] Include zero-terminator storage. In C land == ARRAYSIZE(my_char_array), in C++ land: string.capacity()+1
|
||||||
bool BufDirty; // Set if you modify Buf/BufTextLen! // Write // [Completion,History,Always]
|
bool BufDirty; // Set if you modify Buf/BufTextLen! // Write // [Completion,History,Always]
|
||||||
int CursorPos; // // Read-write // [Completion,History,Always]
|
int CursorPos; // // Read-write // [Completion,History,Always]
|
||||||
@ -2094,7 +2135,8 @@ struct ImGuiInputTextCallbackData
|
|||||||
// Use those function to benefit from the CallbackResize behaviors. Calling those function reset the selection.
|
// Use those function to benefit from the CallbackResize behaviors. Calling those function reset the selection.
|
||||||
IMGUI_API ImGuiInputTextCallbackData();
|
IMGUI_API ImGuiInputTextCallbackData();
|
||||||
IMGUI_API void DeleteChars(int pos, int bytes_count);
|
IMGUI_API void DeleteChars(int pos, int bytes_count);
|
||||||
IMGUI_API void InsertChars(int pos, const char* text, const char* text_end = NULL);
|
IMGUI_API void InsertChars(int pos, ImStrv text);
|
||||||
|
inline void InsertChars(int pos, const char* text, const char* text_end) { InsertChars(pos, ImStrv(text, text_end)); }
|
||||||
void SelectAll() { SelectionStart = 0; SelectionEnd = BufTextLen; }
|
void SelectAll() { SelectionStart = 0; SelectionEnd = BufTextLen; }
|
||||||
void ClearSelection() { SelectionStart = SelectionEnd = BufTextLen; }
|
void ClearSelection() { SelectionStart = SelectionEnd = BufTextLen; }
|
||||||
bool HasSelection() const { return SelectionStart != SelectionEnd; }
|
bool HasSelection() const { return SelectionStart != SelectionEnd; }
|
||||||
@ -2127,7 +2169,7 @@ struct ImGuiPayload
|
|||||||
|
|
||||||
ImGuiPayload() { Clear(); }
|
ImGuiPayload() { Clear(); }
|
||||||
void Clear() { SourceId = SourceParentId = 0; Data = NULL; DataSize = 0; memset(DataType, 0, sizeof(DataType)); DataFrameCount = -1; Preview = Delivery = false; }
|
void Clear() { SourceId = SourceParentId = 0; Data = NULL; DataSize = 0; memset(DataType, 0, sizeof(DataType)); DataFrameCount = -1; Preview = Delivery = false; }
|
||||||
bool IsDataType(ImStrv type) const { return DataFrameCount != -1 && strcmp(type, DataType) == 0; }
|
bool IsDataType(ImStrv type) const { return DataFrameCount != -1 && type == ImStrv(DataType); }
|
||||||
bool IsPreview() const { return Preview; }
|
bool IsPreview() const { return Preview; }
|
||||||
bool IsDelivery() const { return Delivery; }
|
bool IsDelivery() const { return Delivery; }
|
||||||
};
|
};
|
||||||
@ -2182,7 +2224,8 @@ struct ImGuiTextFilter
|
|||||||
{
|
{
|
||||||
IMGUI_API ImGuiTextFilter(ImStrv default_filter = "");
|
IMGUI_API ImGuiTextFilter(ImStrv default_filter = "");
|
||||||
IMGUI_API bool Draw(ImStrv label = "Filter (inc,-exc)", float width = 0.0f); // Helper calling InputText+Build
|
IMGUI_API bool Draw(ImStrv label = "Filter (inc,-exc)", float width = 0.0f); // Helper calling InputText+Build
|
||||||
IMGUI_API bool PassFilter(const char* text, const char* text_end = NULL) const;
|
IMGUI_API bool PassFilter(ImStrv text) const;
|
||||||
|
inline bool PassFilter(const char* text, const char* text_end = NULL) const { return PassFilter(ImStrv(text, text_end)); }
|
||||||
IMGUI_API void Build();
|
IMGUI_API void Build();
|
||||||
void Clear() { InputBuf[0] = 0; Build(); }
|
void Clear() { InputBuf[0] = 0; Build(); }
|
||||||
bool IsActive() const { return !Filters.empty(); }
|
bool IsActive() const { return !Filters.empty(); }
|
||||||
@ -2219,7 +2262,8 @@ struct ImGuiTextBuffer
|
|||||||
void clear() { Buf.clear(); }
|
void clear() { Buf.clear(); }
|
||||||
void reserve(int capacity) { Buf.reserve(capacity); }
|
void reserve(int capacity) { Buf.reserve(capacity); }
|
||||||
const char* c_str() const { return Buf.Data ? Buf.Data : EmptyString; }
|
const char* c_str() const { return Buf.Data ? Buf.Data : EmptyString; }
|
||||||
IMGUI_API void append(const char* str, const char* str_end = NULL);
|
IMGUI_API void append(ImStrv str);
|
||||||
|
inline void append(const char* str, const char* str_end) { append(ImStrv(str, str_end)); }
|
||||||
IMGUI_API void appendf(const char* fmt, ...) IM_FMTARGS(2);
|
IMGUI_API void appendf(const char* fmt, ...) IM_FMTARGS(2);
|
||||||
IMGUI_API void appendfv(const char* fmt, va_list args) IM_FMTLIST(2);
|
IMGUI_API void appendfv(const char* fmt, va_list args) IM_FMTLIST(2);
|
||||||
};
|
};
|
||||||
@ -2548,8 +2592,10 @@ struct ImDrawList
|
|||||||
IMGUI_API void AddCircleFilled(const ImVec2& center, float radius, ImU32 col, int num_segments = 0);
|
IMGUI_API void AddCircleFilled(const ImVec2& center, float radius, ImU32 col, int num_segments = 0);
|
||||||
IMGUI_API void AddNgon(const ImVec2& center, float radius, ImU32 col, int num_segments, float thickness = 1.0f);
|
IMGUI_API void AddNgon(const ImVec2& center, float radius, ImU32 col, int num_segments, float thickness = 1.0f);
|
||||||
IMGUI_API void AddNgonFilled(const ImVec2& center, float radius, ImU32 col, int num_segments);
|
IMGUI_API void AddNgonFilled(const ImVec2& center, float radius, ImU32 col, int num_segments);
|
||||||
IMGUI_API void AddText(const ImVec2& pos, ImU32 col, const char* text_begin, const char* text_end = NULL);
|
IMGUI_API void AddText(const ImVec2& pos, ImU32 col, ImStrv text);
|
||||||
IMGUI_API void AddText(const ImFont* font, float font_size, const ImVec2& pos, ImU32 col, const char* text_begin, const char* text_end = NULL, float wrap_width = 0.0f, const ImVec4* cpu_fine_clip_rect = NULL);
|
inline void AddText(const ImVec2& pos, ImU32 col, const char* text_begin, const char* text_end) { AddText(NULL, 0.0f, pos, col, ImStrv(text_begin, text_end)); }
|
||||||
|
IMGUI_API void AddText(const ImFont* font, float font_size, const ImVec2& pos, ImU32 col, ImStrv text, float wrap_width = 0.0f, const ImVec4* cpu_fine_clip_rect = NULL);
|
||||||
|
inline void AddText(const ImFont* font, float font_size, const ImVec2& pos, ImU32 col, const char* text_begin, const char* text_end, float wrap_width = 0.0f, const ImVec4* cpu_fine_clip_rect = NULL) { AddText(font, font_size, pos, col, ImStrv(text_begin, text_end), wrap_width, cpu_fine_clip_rect); }
|
||||||
IMGUI_API void AddPolyline(const ImVec2* points, int num_points, ImU32 col, ImDrawFlags flags, float thickness);
|
IMGUI_API void AddPolyline(const ImVec2* points, int num_points, ImU32 col, ImDrawFlags flags, float thickness);
|
||||||
IMGUI_API void AddConvexPolyFilled(const ImVec2* points, int num_points, ImU32 col); // Note: Anti-aliased filling requires points to be in clockwise order.
|
IMGUI_API void AddConvexPolyFilled(const ImVec2* points, int num_points, ImU32 col); // Note: Anti-aliased filling requires points to be in clockwise order.
|
||||||
IMGUI_API void AddBezierCubic(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, ImU32 col, float thickness, int num_segments = 0); // Cubic Bezier (4 control points)
|
IMGUI_API void AddBezierCubic(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, ImU32 col, float thickness, int num_segments = 0); // Cubic Bezier (4 control points)
|
||||||
@ -2695,7 +2741,8 @@ struct ImFontGlyphRangesBuilder
|
|||||||
inline bool GetBit(size_t n) const { int off = (int)(n >> 5); ImU32 mask = 1u << (n & 31); return (UsedChars[off] & mask) != 0; } // Get bit n in the array
|
inline bool GetBit(size_t n) const { int off = (int)(n >> 5); ImU32 mask = 1u << (n & 31); return (UsedChars[off] & mask) != 0; } // Get bit n in the array
|
||||||
inline void SetBit(size_t n) { int off = (int)(n >> 5); ImU32 mask = 1u << (n & 31); UsedChars[off] |= mask; } // Set bit n in the array
|
inline void SetBit(size_t n) { int off = (int)(n >> 5); ImU32 mask = 1u << (n & 31); UsedChars[off] |= mask; } // Set bit n in the array
|
||||||
inline void AddChar(ImWchar c) { SetBit(c); } // Add character
|
inline 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(ImStrv text); // Add string (each character of the UTF-8 string are added)
|
||||||
|
inline void AddText(const char* text, const char* text_end = NULL) { AddText(ImStrv(text, text_end)); }
|
||||||
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
|
||||||
IMGUI_API void BuildRanges(ImVector<ImWchar>* out_ranges); // Output new ranges
|
IMGUI_API void BuildRanges(ImVector<ImWchar>* out_ranges); // Output new ranges
|
||||||
};
|
};
|
||||||
@ -2876,10 +2923,13 @@ struct ImFont
|
|||||||
|
|
||||||
// 'max_width' stops rendering after a certain width (could be turned into a 2d size). FLT_MAX to disable.
|
// 'max_width' stops rendering after a certain width (could be turned into a 2d size). FLT_MAX to disable.
|
||||||
// 'wrap_width' enable automatic word-wrapping across multiple lines to fit into given width. 0.0f to disable.
|
// 'wrap_width' enable automatic word-wrapping across multiple lines to fit into given width. 0.0f to disable.
|
||||||
IMGUI_API ImVec2 CalcTextSizeA(float size, float max_width, float wrap_width, const char* text_begin, const char* text_end = NULL, const char** remaining = NULL) const; // utf8
|
IMGUI_API ImVec2 CalcTextSizeA(float size, float max_width, float wrap_width, ImStrv text, const char** remaining = NULL) const; // utf8
|
||||||
IMGUI_API const char* CalcWordWrapPositionA(float scale, const char* text, const char* text_end, float wrap_width) const;
|
inline ImVec2 CalcTextSizeA(float size, float max_width, float wrap_width, const char* text_begin, const char* text_end, const char** remaining = NULL) const { return CalcTextSizeA(size, max_width, wrap_width, ImStrv(text_begin, text_end), remaining); }
|
||||||
|
IMGUI_API const char* CalcWordWrapPositionA(float scale, ImStrv text, float wrap_width) const;
|
||||||
|
inline const char* CalcWordWrapPositionA(float scale, const char* text, const char* text_end, float wrap_width) const { return CalcWordWrapPositionA(scale, ImStrv(text, text_end), wrap_width); }
|
||||||
IMGUI_API void RenderChar(ImDrawList* draw_list, float size, ImVec2 pos, ImU32 col, ImWchar c) const;
|
IMGUI_API void RenderChar(ImDrawList* draw_list, float size, ImVec2 pos, ImU32 col, ImWchar c) const;
|
||||||
IMGUI_API void RenderText(ImDrawList* draw_list, float size, ImVec2 pos, ImU32 col, const ImVec4& clip_rect, const char* text_begin, const char* text_end, float wrap_width = 0.0f, bool cpu_fine_clip = false) const;
|
IMGUI_API void RenderText(ImDrawList* draw_list, float size, ImVec2 pos, ImU32 col, const ImVec4& clip_rect, ImStrv text, float wrap_width = 0.0f, bool cpu_fine_clip = false) const;
|
||||||
|
inline void RenderText(ImDrawList* draw_list, float size, ImVec2 pos, ImU32 col, const ImVec4& clip_rect, const char* text_begin, const char* text_end, float wrap_width = 0.0f, bool cpu_fine_clip = false) const { RenderText(draw_list, size, pos, col, clip_rect, ImStrv(text_begin, text_end), wrap_width, cpu_fine_clip); }
|
||||||
|
|
||||||
// [Internal] Don't use!
|
// [Internal] Don't use!
|
||||||
IMGUI_API void BuildLookupTable();
|
IMGUI_API void BuildLookupTable();
|
||||||
|
@ -3240,7 +3240,7 @@ static void ShowDemoWindowLayout()
|
|||||||
"(this is often used internally to avoid altering the clipping rectangle and minimize draw calls)");
|
"(this is often used internally to avoid altering the clipping rectangle and minimize draw calls)");
|
||||||
ImVec4 clip_rect(p0.x, p0.y, p1.x, p1.y); // AddText() takes a ImVec4* here so let's convert.
|
ImVec4 clip_rect(p0.x, p0.y, p1.x, p1.y); // AddText() takes a ImVec4* here so let's convert.
|
||||||
draw_list->AddRectFilled(p0, p1, IM_COL32(90, 90, 120, 255));
|
draw_list->AddRectFilled(p0, p1, IM_COL32(90, 90, 120, 255));
|
||||||
draw_list->AddText(ImGui::GetFont(), ImGui::GetFontSize(), text_pos, IM_COL32_WHITE, text_str, NULL, 0.0f, &clip_rect);
|
draw_list->AddText(ImGui::GetFont(), ImGui::GetFontSize(), text_pos, IM_COL32_WHITE, text_str, 0.0f, &clip_rect);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
ImGui::EndGroup();
|
ImGui::EndGroup();
|
||||||
@ -6768,7 +6768,7 @@ struct ExampleAppConsole
|
|||||||
if (match_len > 0)
|
if (match_len > 0)
|
||||||
{
|
{
|
||||||
data->DeleteChars((int)(word_start - data->Buf), (int)(word_end - word_start));
|
data->DeleteChars((int)(word_start - data->Buf), (int)(word_end - word_start));
|
||||||
data->InsertChars(data->CursorPos, candidates[0], candidates[0] + match_len);
|
data->InsertChars(data->CursorPos, ImStrv(candidates[0], (size_t)match_len));
|
||||||
}
|
}
|
||||||
|
|
||||||
// List matches
|
// List matches
|
||||||
@ -6902,8 +6902,8 @@ struct ExampleAppLog
|
|||||||
{
|
{
|
||||||
const char* line_start = buf + LineOffsets[line_no];
|
const char* line_start = buf + LineOffsets[line_no];
|
||||||
const char* line_end = (line_no + 1 < LineOffsets.Size) ? (buf + LineOffsets[line_no + 1] - 1) : buf_end;
|
const char* line_end = (line_no + 1 < LineOffsets.Size) ? (buf + LineOffsets[line_no + 1] - 1) : buf_end;
|
||||||
if (Filter.PassFilter(line_start, line_end))
|
if (Filter.PassFilter(ImStrv(line_start, line_end)))
|
||||||
ImGui::TextUnformatted(line_start, line_end);
|
ImGui::TextUnformatted(ImStrv(line_start, line_end));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -6929,7 +6929,7 @@ struct ExampleAppLog
|
|||||||
{
|
{
|
||||||
const char* line_start = buf + LineOffsets[line_no];
|
const char* line_start = buf + LineOffsets[line_no];
|
||||||
const char* line_end = (line_no + 1 < LineOffsets.Size) ? (buf + LineOffsets[line_no + 1] - 1) : buf_end;
|
const char* line_end = (line_no + 1 < LineOffsets.Size) ? (buf + LineOffsets[line_no + 1] - 1) : buf_end;
|
||||||
ImGui::TextUnformatted(line_start, line_end);
|
ImGui::TextUnformatted(ImStrv(line_start, line_end));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
clipper.End();
|
clipper.End();
|
||||||
@ -7162,7 +7162,7 @@ static void ShowExampleAppLongText(bool* p_open)
|
|||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
// Single call to TextUnformatted() with a big buffer
|
// Single call to TextUnformatted() with a big buffer
|
||||||
ImGui::TextUnformatted(log.begin(), log.end());
|
ImGui::TextUnformatted(ImStrv(log.begin(), log.end()));
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
{
|
{
|
||||||
|
@ -1573,14 +1573,13 @@ void ImDrawList::AddBezierQuadratic(const ImVec2& p1, const ImVec2& p2, const Im
|
|||||||
PathStroke(col, 0, thickness);
|
PathStroke(col, 0, thickness);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImDrawList::AddText(const ImFont* font, float font_size, const ImVec2& pos, ImU32 col, const char* text_begin, const char* text_end, float wrap_width, const ImVec4* cpu_fine_clip_rect)
|
void ImDrawList::AddText(const ImFont* font, float font_size, const ImVec2& pos, ImU32 col, ImStrv text, float wrap_width, const ImVec4* cpu_fine_clip_rect)
|
||||||
{
|
{
|
||||||
if ((col & IM_COL32_A_MASK) == 0)
|
if ((col & IM_COL32_A_MASK) == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (text_end == NULL)
|
IM_IMSTR_ENSURE_HAS_END(text);
|
||||||
text_end = text_begin + strlen(text_begin);
|
if (text.Empty())
|
||||||
if (text_begin == text_end)
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Pull default font/size from the shared ImDrawListSharedData instance
|
// Pull default font/size from the shared ImDrawListSharedData instance
|
||||||
@ -1599,12 +1598,12 @@ void ImDrawList::AddText(const ImFont* font, float font_size, const ImVec2& pos,
|
|||||||
clip_rect.z = ImMin(clip_rect.z, cpu_fine_clip_rect->z);
|
clip_rect.z = ImMin(clip_rect.z, cpu_fine_clip_rect->z);
|
||||||
clip_rect.w = ImMin(clip_rect.w, cpu_fine_clip_rect->w);
|
clip_rect.w = ImMin(clip_rect.w, cpu_fine_clip_rect->w);
|
||||||
}
|
}
|
||||||
font->RenderText(this, font_size, pos, col, clip_rect, text_begin, text_end, wrap_width, cpu_fine_clip_rect != NULL);
|
font->RenderText(this, font_size, pos, col, clip_rect, text, wrap_width, cpu_fine_clip_rect != NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImDrawList::AddText(const ImVec2& pos, ImU32 col, const char* text_begin, const char* text_end)
|
void ImDrawList::AddText(const ImVec2& pos, ImU32 col, ImStrv text)
|
||||||
{
|
{
|
||||||
AddText(NULL, 0.0f, pos, col, text_begin, text_end);
|
AddText(NULL, 0.0f, pos, col, text);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImDrawList::AddImage(ImTextureID user_texture_id, const ImVec2& p_min, const ImVec2& p_max, const ImVec2& uv_min, const ImVec2& uv_max, ImU32 col)
|
void ImDrawList::AddImage(ImTextureID user_texture_id, const ImVec2& p_min, const ImVec2& p_max, const ImVec2& uv_min, const ImVec2& uv_max, ImU32 col)
|
||||||
@ -2110,11 +2109,11 @@ static const char* GetDefaultCompressedFontDataTTFBase85();
|
|||||||
static unsigned int Decode85Byte(char c) { return c >= '\\' ? c-36 : c-35; }
|
static unsigned int Decode85Byte(char c) { return c >= '\\' ? c-36 : c-35; }
|
||||||
static void Decode85(ImStrv src, unsigned char* dst)
|
static void Decode85(ImStrv src, unsigned char* dst)
|
||||||
{
|
{
|
||||||
while (*src)
|
while (!src.Empty())
|
||||||
{
|
{
|
||||||
unsigned int tmp = Decode85Byte(src[0]) + 85 * (Decode85Byte(src[1]) + 85 * (Decode85Byte(src[2]) + 85 * (Decode85Byte(src[3]) + 85 * Decode85Byte(src[4]))));
|
unsigned int tmp = Decode85Byte(src[0]) + 85 * (Decode85Byte(src[1]) + 85 * (Decode85Byte(src[2]) + 85 * (Decode85Byte(src[3]) + 85 * Decode85Byte(src[4]))));
|
||||||
dst[0] = ((tmp >> 0) & 0xFF); dst[1] = ((tmp >> 8) & 0xFF); dst[2] = ((tmp >> 16) & 0xFF); dst[3] = ((tmp >> 24) & 0xFF); // We can't assume little-endianness.
|
dst[0] = ((tmp >> 0) & 0xFF); dst[1] = ((tmp >> 8) & 0xFF); dst[2] = ((tmp >> 16) & 0xFF); dst[3] = ((tmp >> 24) & 0xFF); // We can't assume little-endianness.
|
||||||
src += 5;
|
src.Begin += 5;
|
||||||
dst += 4;
|
dst += 4;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2156,8 +2155,9 @@ ImFont* ImFontAtlas::AddFontFromFileTTF(ImStrv filename, float size_pixels, cons
|
|||||||
{
|
{
|
||||||
// Store a short copy of filename into into the font name for convenience
|
// Store a short copy of filename into into the font name for convenience
|
||||||
const char* p;
|
const char* p;
|
||||||
for (p = filename + strlen(filename); p > filename && p[-1] != '/' && p[-1] != '\\'; p--) {}
|
for (p = filename.Begin + IM_IMSTR_LENGTH(filename); p > filename.Begin && p[-1] != '/' && p[-1] != '\\'; p--) {}
|
||||||
ImFormatString(font_cfg.Name, IM_ARRAYSIZE(font_cfg.Name), "%s, %.0fpx", p, size_pixels);
|
filename.Begin = p;
|
||||||
|
ImFormatString(font_cfg.Name, IM_ARRAYSIZE(font_cfg.Name), "%.*s, %.0fpx", (int)IM_IMSTR_LENGTH(filename), filename.Begin, size_pixels);
|
||||||
}
|
}
|
||||||
return AddFontFromMemoryTTF(data, (int)data_size, size_pixels, &font_cfg, glyph_ranges);
|
return AddFontFromMemoryTTF(data, (int)data_size, size_pixels, &font_cfg, glyph_ranges);
|
||||||
}
|
}
|
||||||
@ -2190,7 +2190,7 @@ ImFont* ImFontAtlas::AddFontFromMemoryCompressedTTF(const void* compressed_ttf_d
|
|||||||
|
|
||||||
ImFont* ImFontAtlas::AddFontFromMemoryCompressedBase85TTF(ImStrv compressed_ttf_data_base85, float size_pixels, const ImFontConfig* font_cfg, const ImWchar* glyph_ranges)
|
ImFont* ImFontAtlas::AddFontFromMemoryCompressedBase85TTF(ImStrv compressed_ttf_data_base85, float size_pixels, const ImFontConfig* font_cfg, const ImWchar* glyph_ranges)
|
||||||
{
|
{
|
||||||
int compressed_ttf_size = (((int)strlen(compressed_ttf_data_base85) + 4) / 5) * 4;
|
int compressed_ttf_size = (((int)IM_IMSTR_LENGTH(compressed_ttf_data_base85) + 4) / 5) * 4;
|
||||||
void* compressed_ttf = IM_ALLOC((size_t)compressed_ttf_size);
|
void* compressed_ttf = IM_ALLOC((size_t)compressed_ttf_size);
|
||||||
Decode85(compressed_ttf_data_base85, (unsigned char*)compressed_ttf);
|
Decode85(compressed_ttf_data_base85, (unsigned char*)compressed_ttf);
|
||||||
ImFont* font = AddFontFromMemoryCompressedTTF(compressed_ttf, compressed_ttf_size, size_pixels, font_cfg, glyph_ranges);
|
ImFont* font = AddFontFromMemoryCompressedTTF(compressed_ttf, compressed_ttf_size, size_pixels, font_cfg, glyph_ranges);
|
||||||
@ -3064,13 +3064,13 @@ const ImWchar* ImFontAtlas::GetGlyphRangesVietnamese()
|
|||||||
// [SECTION] ImFontGlyphRangesBuilder
|
// [SECTION] ImFontGlyphRangesBuilder
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
void ImFontGlyphRangesBuilder::AddText(const char* text, const char* text_end)
|
void ImFontGlyphRangesBuilder::AddText(ImStrv text)
|
||||||
{
|
{
|
||||||
while (text_end ? (text < text_end) : *text)
|
while (!text.Empty())
|
||||||
{
|
{
|
||||||
unsigned int c = 0;
|
unsigned int c = 0;
|
||||||
int c_len = ImTextCharFromUtf8(&c, text, text_end);
|
int c_len = ImTextCharFromUtf8(&c, text.Begin, text.End);
|
||||||
text += c_len;
|
text.Begin += c_len;
|
||||||
if (c_len == 0)
|
if (c_len == 0)
|
||||||
break;
|
break;
|
||||||
AddChar((ImWchar)c);
|
AddChar((ImWchar)c);
|
||||||
@ -3329,7 +3329,7 @@ const ImFontGlyph* ImFont::FindGlyphNoFallback(ImWchar c) const
|
|||||||
return &Glyphs.Data[i];
|
return &Glyphs.Data[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* ImFont::CalcWordWrapPositionA(float scale, const char* text, const char* text_end, float wrap_width) const
|
const char* ImFont::CalcWordWrapPositionA(float scale, ImStrv text, float wrap_width) const
|
||||||
{
|
{
|
||||||
// Simple word-wrapping for English, not full-featured. Please submit failing cases!
|
// Simple word-wrapping for English, not full-featured. Please submit failing cases!
|
||||||
// FIXME: Much possible improvements (don't cut things like "word !", "word!!!" but cut within "word,,,,", more sensible support for punctuations, support for Unicode punctuations, etc.)
|
// FIXME: Much possible improvements (don't cut things like "word !", "word!!!" but cut within "word,,,,", more sensible support for punctuations, support for Unicode punctuations, etc.)
|
||||||
@ -3345,25 +3345,26 @@ const char* ImFont::CalcWordWrapPositionA(float scale, const char* text, const c
|
|||||||
|
|
||||||
// Cut words that cannot possibly fit within one line.
|
// Cut words that cannot possibly fit within one line.
|
||||||
// e.g.: "The tropical fish" with ~5 characters worth of width --> "The tr" "opical" "fish"
|
// e.g.: "The tropical fish" with ~5 characters worth of width --> "The tr" "opical" "fish"
|
||||||
|
IM_IMSTR_ENSURE_HAS_END(text);
|
||||||
|
|
||||||
float line_width = 0.0f;
|
float line_width = 0.0f;
|
||||||
float word_width = 0.0f;
|
float word_width = 0.0f;
|
||||||
float blank_width = 0.0f;
|
float blank_width = 0.0f;
|
||||||
wrap_width /= scale; // We work with unscaled widths to avoid scaling every characters
|
wrap_width /= scale; // We work with unscaled widths to avoid scaling every characters
|
||||||
|
|
||||||
const char* word_end = text;
|
const char* word_end = text.Begin;
|
||||||
const char* prev_word_end = NULL;
|
const char* prev_word_end = NULL;
|
||||||
bool inside_word = true;
|
bool inside_word = true;
|
||||||
|
|
||||||
const char* s = text;
|
const char* s = text.Begin;
|
||||||
while (s < text_end)
|
while (s < text.End)
|
||||||
{
|
{
|
||||||
unsigned int c = (unsigned int)*s;
|
unsigned int c = (unsigned int)*s;
|
||||||
const char* next_s;
|
const char* next_s;
|
||||||
if (c < 0x80)
|
if (c < 0x80)
|
||||||
next_s = s + 1;
|
next_s = s + 1;
|
||||||
else
|
else
|
||||||
next_s = s + ImTextCharFromUtf8(&c, s, text_end);
|
next_s = s + ImTextCharFromUtf8(&c, s, text.End);
|
||||||
if (c == 0)
|
if (c == 0)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -3428,10 +3429,9 @@ const char* ImFont::CalcWordWrapPositionA(float scale, const char* text, const c
|
|||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
ImVec2 ImFont::CalcTextSizeA(float size, float max_width, float wrap_width, const char* text_begin, const char* text_end, const char** remaining) const
|
ImVec2 ImFont::CalcTextSizeA(float size, float max_width, float wrap_width, ImStrv text, const char** remaining) const
|
||||||
{
|
{
|
||||||
if (!text_end)
|
IM_IMSTR_ENSURE_HAS_END(text);
|
||||||
text_end = text_begin + strlen(text_begin); // FIXME-OPT: Need to avoid this.
|
|
||||||
|
|
||||||
const float line_height = size;
|
const float line_height = size;
|
||||||
const float scale = size / FontSize;
|
const float scale = size / FontSize;
|
||||||
@ -3442,15 +3442,15 @@ ImVec2 ImFont::CalcTextSizeA(float size, float max_width, float wrap_width, cons
|
|||||||
const bool word_wrap_enabled = (wrap_width > 0.0f);
|
const bool word_wrap_enabled = (wrap_width > 0.0f);
|
||||||
const char* word_wrap_eol = NULL;
|
const char* word_wrap_eol = NULL;
|
||||||
|
|
||||||
const char* s = text_begin;
|
const char* s = text.Begin;
|
||||||
while (s < text_end)
|
while (s < text.End)
|
||||||
{
|
{
|
||||||
if (word_wrap_enabled)
|
if (word_wrap_enabled)
|
||||||
{
|
{
|
||||||
// Calculate how far we can render. Requires two passes on the string data but keeps the code simple and not intrusive for what's essentially an uncommon feature.
|
// Calculate how far we can render. Requires two passes on the string data but keeps the code simple and not intrusive for what's essentially an uncommon feature.
|
||||||
if (!word_wrap_eol)
|
if (!word_wrap_eol)
|
||||||
{
|
{
|
||||||
word_wrap_eol = CalcWordWrapPositionA(scale, s, text_end, wrap_width - line_width);
|
word_wrap_eol = CalcWordWrapPositionA(scale, ImStrv(s, text.End), wrap_width - line_width);
|
||||||
if (word_wrap_eol == s) // Wrap_width is too small to fit anything. Force displaying 1 character to minimize the height discontinuity.
|
if (word_wrap_eol == s) // Wrap_width is too small to fit anything. Force displaying 1 character to minimize the height discontinuity.
|
||||||
word_wrap_eol++; // +1 may not be a character start point in UTF-8 but it's ok because we use s >= word_wrap_eol below
|
word_wrap_eol++; // +1 may not be a character start point in UTF-8 but it's ok because we use s >= word_wrap_eol below
|
||||||
}
|
}
|
||||||
@ -3464,7 +3464,7 @@ ImVec2 ImFont::CalcTextSizeA(float size, float max_width, float wrap_width, cons
|
|||||||
word_wrap_eol = NULL;
|
word_wrap_eol = NULL;
|
||||||
|
|
||||||
// Wrapping skips upcoming blanks
|
// Wrapping skips upcoming blanks
|
||||||
while (s < text_end)
|
while (s < text.End)
|
||||||
{
|
{
|
||||||
const char c = *s;
|
const char c = *s;
|
||||||
if (ImCharIsBlankA(c)) { s++; } else if (c == '\n') { s++; break; } else { break; }
|
if (ImCharIsBlankA(c)) { s++; } else if (c == '\n') { s++; break; } else { break; }
|
||||||
@ -3482,7 +3482,7 @@ ImVec2 ImFont::CalcTextSizeA(float size, float max_width, float wrap_width, cons
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
s += ImTextCharFromUtf8(&c, s, text_end);
|
s += ImTextCharFromUtf8(&c, s, text.End);
|
||||||
if (c == 0) // Malformed UTF-8?
|
if (c == 0) // Malformed UTF-8?
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -3538,10 +3538,9 @@ void ImFont::RenderChar(ImDrawList* draw_list, float size, ImVec2 pos, ImU32 col
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Note: as with every ImDrawList drawing function, this expects that the font atlas texture is bound.
|
// Note: as with every ImDrawList drawing function, this expects that the font atlas texture is bound.
|
||||||
void ImFont::RenderText(ImDrawList* draw_list, float size, ImVec2 pos, ImU32 col, const ImVec4& clip_rect, const char* text_begin, const char* text_end, float wrap_width, bool cpu_fine_clip) const
|
void ImFont::RenderText(ImDrawList* draw_list, float size, ImVec2 pos, ImU32 col, const ImVec4& clip_rect, ImStrv text, float wrap_width, bool cpu_fine_clip) const
|
||||||
{
|
{
|
||||||
if (!text_end)
|
IM_IMSTR_ENSURE_HAS_END(text); // ImGui:: functions generally already provides a valid text_end, so this is merely to handle direct calls.
|
||||||
text_end = text_begin + strlen(text_begin); // ImGui:: functions generally already provides a valid text_end, so this is merely to handle direct calls.
|
|
||||||
|
|
||||||
// Align to be pixel perfect
|
// Align to be pixel perfect
|
||||||
pos.x = IM_FLOOR(pos.x);
|
pos.x = IM_FLOOR(pos.x);
|
||||||
@ -3557,35 +3556,35 @@ void ImFont::RenderText(ImDrawList* draw_list, float size, ImVec2 pos, ImU32 col
|
|||||||
const char* word_wrap_eol = NULL;
|
const char* word_wrap_eol = NULL;
|
||||||
|
|
||||||
// Fast-forward to first visible line
|
// Fast-forward to first visible line
|
||||||
const char* s = text_begin;
|
const char* s = text.Begin;
|
||||||
if (y + line_height < clip_rect.y && !word_wrap_enabled)
|
if (y + line_height < clip_rect.y && !word_wrap_enabled)
|
||||||
while (y + line_height < clip_rect.y && s < text_end)
|
while (y + line_height < clip_rect.y && s < text.End)
|
||||||
{
|
{
|
||||||
s = (const char*)memchr(s, '\n', text_end - s);
|
s = (const char*)memchr(s, '\n', text.End - s);
|
||||||
s = s ? s + 1 : text_end;
|
s = s ? s + 1 : text.End;
|
||||||
y += line_height;
|
y += line_height;
|
||||||
}
|
}
|
||||||
|
|
||||||
// For large text, scan for the last visible line in order to avoid over-reserving in the call to PrimReserve()
|
// For large text, scan for the last visible line in order to avoid over-reserving in the call to PrimReserve()
|
||||||
// Note that very large horizontal line will still be affected by the issue (e.g. a one megabyte string buffer without a newline will likely crash atm)
|
// Note that very large horizontal line will still be affected by the issue (e.g. a one megabyte string buffer without a newline will likely crash atm)
|
||||||
if (text_end - s > 10000 && !word_wrap_enabled)
|
if (text.End - s > 10000 && !word_wrap_enabled)
|
||||||
{
|
{
|
||||||
const char* s_end = s;
|
const char* s_end = s;
|
||||||
float y_end = y;
|
float y_end = y;
|
||||||
while (y_end < clip_rect.w && s_end < text_end)
|
while (y_end < clip_rect.w && s_end < text.End)
|
||||||
{
|
{
|
||||||
s_end = (const char*)memchr(s_end, '\n', text_end - s_end);
|
s_end = (const char*)memchr(s_end, '\n', text.End - s_end);
|
||||||
s_end = s_end ? s_end + 1 : text_end;
|
s_end = s_end ? s_end + 1 : text.End;
|
||||||
y_end += line_height;
|
y_end += line_height;
|
||||||
}
|
}
|
||||||
text_end = s_end;
|
text.End = s_end;
|
||||||
}
|
}
|
||||||
if (s == text_end)
|
if (s == text.End)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Reserve vertices for remaining worse case (over-reserving is useful and easily amortized)
|
// Reserve vertices for remaining worse case (over-reserving is useful and easily amortized)
|
||||||
const int vtx_count_max = (int)(text_end - s) * 4;
|
const int vtx_count_max = (int)(text.End - s) * 4;
|
||||||
const int idx_count_max = (int)(text_end - s) * 6;
|
const int idx_count_max = (int)(text.End - s) * 6;
|
||||||
const int idx_expected_size = draw_list->IdxBuffer.Size + idx_count_max;
|
const int idx_expected_size = draw_list->IdxBuffer.Size + idx_count_max;
|
||||||
draw_list->PrimReserve(idx_count_max, vtx_count_max);
|
draw_list->PrimReserve(idx_count_max, vtx_count_max);
|
||||||
|
|
||||||
@ -3595,14 +3594,14 @@ void ImFont::RenderText(ImDrawList* draw_list, float size, ImVec2 pos, ImU32 col
|
|||||||
|
|
||||||
const ImU32 col_untinted = col | ~IM_COL32_A_MASK;
|
const ImU32 col_untinted = col | ~IM_COL32_A_MASK;
|
||||||
|
|
||||||
while (s < text_end)
|
while (s < text.End)
|
||||||
{
|
{
|
||||||
if (word_wrap_enabled)
|
if (word_wrap_enabled)
|
||||||
{
|
{
|
||||||
// Calculate how far we can render. Requires two passes on the string data but keeps the code simple and not intrusive for what's essentially an uncommon feature.
|
// Calculate how far we can render. Requires two passes on the string data but keeps the code simple and not intrusive for what's essentially an uncommon feature.
|
||||||
if (!word_wrap_eol)
|
if (!word_wrap_eol)
|
||||||
{
|
{
|
||||||
word_wrap_eol = CalcWordWrapPositionA(scale, s, text_end, wrap_width - (x - pos.x));
|
word_wrap_eol = CalcWordWrapPositionA(scale, ImStrv(s, text.End), wrap_width - (x - pos.x));
|
||||||
if (word_wrap_eol == s) // Wrap_width is too small to fit anything. Force displaying 1 character to minimize the height discontinuity.
|
if (word_wrap_eol == s) // Wrap_width is too small to fit anything. Force displaying 1 character to minimize the height discontinuity.
|
||||||
word_wrap_eol++; // +1 may not be a character start point in UTF-8 but it's ok because we use s >= word_wrap_eol below
|
word_wrap_eol++; // +1 may not be a character start point in UTF-8 but it's ok because we use s >= word_wrap_eol below
|
||||||
}
|
}
|
||||||
@ -3614,7 +3613,7 @@ void ImFont::RenderText(ImDrawList* draw_list, float size, ImVec2 pos, ImU32 col
|
|||||||
word_wrap_eol = NULL;
|
word_wrap_eol = NULL;
|
||||||
|
|
||||||
// Wrapping skips upcoming blanks
|
// Wrapping skips upcoming blanks
|
||||||
while (s < text_end)
|
while (s < text.End)
|
||||||
{
|
{
|
||||||
const char c = *s;
|
const char c = *s;
|
||||||
if (ImCharIsBlankA(c)) { s++; } else if (c == '\n') { s++; break; } else { break; }
|
if (ImCharIsBlankA(c)) { s++; } else if (c == '\n') { s++; break; } else { break; }
|
||||||
@ -3631,7 +3630,7 @@ void ImFont::RenderText(ImDrawList* draw_list, float size, ImVec2 pos, ImU32 col
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
s += ImTextCharFromUtf8(&c, s, text_end);
|
s += ImTextCharFromUtf8(&c, s, text.End);
|
||||||
if (c == 0) // Malformed UTF-8?
|
if (c == 0) // Malformed UTF-8?
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -295,7 +295,8 @@ namespace ImStb
|
|||||||
|
|
||||||
// Helpers: Hashing
|
// Helpers: Hashing
|
||||||
IMGUI_API ImGuiID ImHashData(const void* data, size_t data_size, ImU32 seed = 0);
|
IMGUI_API ImGuiID ImHashData(const void* data, size_t data_size, ImU32 seed = 0);
|
||||||
IMGUI_API ImGuiID ImHashStr(const char* data, size_t data_size = 0, ImU32 seed = 0);
|
IMGUI_API ImGuiID ImHashStr(ImStrv str, ImU32 seed = 0);
|
||||||
|
static inline ImGuiID ImHashStr(const char* data, size_t data_size = 0, ImU32 seed = 0) { return ImHashStr(ImStrv(data, data_size ? data + data_size : NULL), seed); }
|
||||||
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
|
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
|
||||||
static inline ImGuiID ImHash(const void* data, int size, ImU32 seed = 0) { return size ? ImHashData(data, (size_t)size, seed) : ImHashStr((const char*)data, 0, seed); } // [moved to ImHashStr/ImHashData in 1.68]
|
static inline ImGuiID ImHash(const void* data, int size, ImU32 seed = 0) { return size ? ImHashData(data, (size_t)size, seed) : ImHashStr((const char*)data, 0, seed); } // [moved to ImHashStr/ImHashData in 1.68]
|
||||||
#endif
|
#endif
|
||||||
@ -316,14 +317,18 @@ static inline int ImUpperPowerOfTwo(int v) { v--; v |= v >> 1; v |=
|
|||||||
// Helpers: String, Formatting
|
// Helpers: String, Formatting
|
||||||
IMGUI_API int ImStricmp(const char* str1, const char* str2);
|
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, ImStrv src, 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* ImStrdup(ImStrv str);
|
||||||
|
IMGUI_API char* ImStrdupcpy(char* dst, size_t* p_dst_size, ImStrv str);
|
||||||
IMGUI_API char* ImStrdupcpy(char* dst, size_t* p_dst_size, 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
|
||||||
IMGUI_API const ImWchar*ImStrbolW(const ImWchar* buf_mid_line, const ImWchar* buf_begin); // Find beginning-of-line
|
IMGUI_API const ImWchar*ImStrbolW(const ImWchar* buf_mid_line, const ImWchar* buf_begin); // Find beginning-of-line
|
||||||
IMGUI_API const char* ImStristr(const char* haystack, const char* haystack_end, const char* needle, const char* needle_end);
|
IMGUI_API const char* ImStristr(const char* haystack, const char* haystack_end, const char* needle, const char* needle_end);
|
||||||
|
IMGUI_API const char* ImStrstr(ImStrv haystack, ImStrv needle);
|
||||||
IMGUI_API void ImStrTrimBlanks(char* str);
|
IMGUI_API void ImStrTrimBlanks(char* str);
|
||||||
IMGUI_API const char* ImStrSkipBlank(const char* str);
|
IMGUI_API const char* ImStrSkipBlank(const char* str);
|
||||||
IMGUI_API int ImFormatString(char* buf, size_t buf_size, const char* fmt, ...) IM_FMTARGS(3);
|
IMGUI_API int ImFormatString(char* buf, size_t buf_size, const char* fmt, ...) IM_FMTARGS(3);
|
||||||
@ -334,6 +339,8 @@ IMGUI_API const char* ImParseFormatTrimDecorations(const char* format, char* b
|
|||||||
IMGUI_API int ImParseFormatPrecision(const char* format, int default_value);
|
IMGUI_API int ImParseFormatPrecision(const char* format, int default_value);
|
||||||
static inline bool ImCharIsBlankA(char c) { return c == ' ' || c == '\t'; }
|
static inline bool ImCharIsBlankA(char c) { return c == ' ' || c == '\t'; }
|
||||||
static inline bool ImCharIsBlankW(unsigned int c) { return c == ' ' || c == '\t' || c == 0x3000; }
|
static inline bool ImCharIsBlankW(unsigned int c) { return c == ' ' || c == '\t' || c == 0x3000; }
|
||||||
|
static inline size_t ImStrlen(const char* str) { return strlen(str); }
|
||||||
|
static inline size_t ImStrlen(const ImWchar* str) { const ImWchar* e = str; while (*e) ++e; return (size_t)(e - str); }
|
||||||
|
|
||||||
// Helpers: UTF-8 <> wchar conversions
|
// Helpers: UTF-8 <> wchar conversions
|
||||||
IMGUI_API const char* ImTextCharToUtf8(char out_buf[5], unsigned int c); // return out_buf
|
IMGUI_API const char* ImTextCharToUtf8(char out_buf[5], unsigned int c); // return out_buf
|
||||||
@ -2110,10 +2117,13 @@ public:
|
|||||||
ImGuiWindow(ImGuiContext* context, ImStrv name);
|
ImGuiWindow(ImGuiContext* context, ImStrv name);
|
||||||
~ImGuiWindow();
|
~ImGuiWindow();
|
||||||
|
|
||||||
ImGuiID GetID(const char* str, const char* str_end = NULL);
|
ImGuiID GetID(ImStrv str);
|
||||||
|
ImGuiID GetID(const char* str) { return GetID(ImStrv(str)); }
|
||||||
|
ImGuiID GetID(const char* str, const char* str_end) { return GetID(ImStrv(str, str_end)); }
|
||||||
ImGuiID GetID(const void* ptr);
|
ImGuiID GetID(const void* ptr);
|
||||||
ImGuiID GetID(int n);
|
ImGuiID GetID(int n);
|
||||||
ImGuiID GetIDNoKeepAlive(const char* str, const char* str_end = NULL);
|
ImGuiID GetIDNoKeepAlive(ImStrv str);
|
||||||
|
ImGuiID GetIDNoKeepAlive(const char* str, const char* str_end = NULL) { return GetIDNoKeepAlive(ImStrv(str, str_end));}
|
||||||
ImGuiID GetIDNoKeepAlive(const void* ptr);
|
ImGuiID GetIDNoKeepAlive(const void* ptr);
|
||||||
ImGuiID GetIDNoKeepAlive(int n);
|
ImGuiID GetIDNoKeepAlive(int n);
|
||||||
ImGuiID GetIDFromRectangle(const ImRect& r_abs);
|
ImGuiID GetIDFromRectangle(const ImRect& r_abs);
|
||||||
@ -2596,7 +2606,8 @@ namespace ImGui
|
|||||||
// Logging/Capture
|
// Logging/Capture
|
||||||
IMGUI_API void LogBegin(ImGuiLogType type, int auto_open_depth); // -> BeginCapture() when we design v2 api, for now stay under the radar by using the old name.
|
IMGUI_API void LogBegin(ImGuiLogType type, int auto_open_depth); // -> BeginCapture() when we design v2 api, for now stay under the radar by using the old name.
|
||||||
IMGUI_API void LogToBuffer(int auto_open_depth = -1); // Start logging/capturing to internal buffer
|
IMGUI_API void LogToBuffer(int auto_open_depth = -1); // Start logging/capturing to internal buffer
|
||||||
IMGUI_API void LogRenderedText(const ImVec2* ref_pos, const char* text, const char* text_end = NULL);
|
IMGUI_API void LogRenderedText(const ImVec2* ref_pos, ImStrv text);
|
||||||
|
inline void LogRenderedText(const ImVec2* ref_pos, const char* text, const char* text_end) { LogRenderedText(ref_pos, ImStrv(text, text_end)); }
|
||||||
IMGUI_API void LogSetNextTextDecoration(const char* prefix, const char* suffix);
|
IMGUI_API void LogSetNextTextDecoration(const char* prefix, const char* suffix);
|
||||||
|
|
||||||
// Popups, Modals, Tooltips
|
// Popups, Modals, Tooltips
|
||||||
@ -2753,16 +2764,21 @@ namespace ImGui
|
|||||||
// Render helpers
|
// Render helpers
|
||||||
// AVOID USING OUTSIDE OF IMGUI.CPP! NOT FOR PUBLIC CONSUMPTION. THOSE FUNCTIONS ARE A MESS. THEIR SIGNATURE AND BEHAVIOR WILL CHANGE, THEY NEED TO BE REFACTORED INTO SOMETHING DECENT.
|
// AVOID USING OUTSIDE OF IMGUI.CPP! NOT FOR PUBLIC CONSUMPTION. THOSE FUNCTIONS ARE A MESS. THEIR SIGNATURE AND BEHAVIOR WILL CHANGE, THEY NEED TO BE REFACTORED INTO SOMETHING DECENT.
|
||||||
// NB: All position are in absolute pixels coordinates (we are never using window coordinates internally)
|
// NB: All position are in absolute pixels coordinates (we are never using window coordinates internally)
|
||||||
IMGUI_API void RenderText(ImVec2 pos, const char* text, const char* text_end = NULL, bool hide_text_after_hash = true);
|
IMGUI_API void RenderText(ImVec2 pos, ImStrv text, bool hide_text_after_hash = true);
|
||||||
IMGUI_API void RenderTextWrapped(ImVec2 pos, const char* text, const char* text_end, float wrap_width);
|
inline void RenderText(ImVec2 pos, const char* text, const char* text_end, bool hide_text_after_hash = true) { RenderText(pos, ImStrv(text, text_end), hide_text_after_hash); }
|
||||||
IMGUI_API void RenderTextClipped(const ImVec2& pos_min, const ImVec2& pos_max, const char* text, const char* text_end, const ImVec2* text_size_if_known, const ImVec2& align = ImVec2(0, 0), const ImRect* clip_rect = NULL);
|
IMGUI_API void RenderTextWrapped(ImVec2 pos, ImStrv text, float wrap_width);
|
||||||
IMGUI_API void RenderTextClippedEx(ImDrawList* draw_list, const ImVec2& pos_min, const ImVec2& pos_max, const char* text, const char* text_end, const ImVec2* text_size_if_known, const ImVec2& align = ImVec2(0, 0), const ImRect* clip_rect = NULL);
|
inline void RenderTextWrapped(ImVec2 pos, const char* text, const char* text_end, float wrap_width) { RenderTextWrapped(pos, ImStrv(text, text_end), wrap_width); }
|
||||||
IMGUI_API void RenderTextEllipsis(ImDrawList* draw_list, const ImVec2& pos_min, const ImVec2& pos_max, float clip_max_x, float ellipsis_max_x, const char* text, const char* text_end, const ImVec2* text_size_if_known);
|
IMGUI_API void RenderTextClipped(const ImVec2& pos_min, const ImVec2& pos_max, ImStrv text, const ImVec2* text_size_if_known, const ImVec2& align = ImVec2(0, 0), const ImRect* clip_rect = NULL);
|
||||||
|
inline void RenderTextClipped(const ImVec2& pos_min, const ImVec2& pos_max, const char* text, const char* text_end, const ImVec2* text_size_if_known, const ImVec2& align = ImVec2(0,0), const ImRect* clip_rect = NULL) { RenderTextClipped(pos_min, pos_max, ImStrv(text, text_end), text_size_if_known, align, clip_rect); }
|
||||||
|
IMGUI_API void RenderTextClippedEx(ImDrawList* draw_list, const ImVec2& pos_min, const ImVec2& pos_max, ImStrv text, const ImVec2* text_size_if_known, const ImVec2& align = ImVec2(0, 0), const ImRect* clip_rect = NULL);
|
||||||
|
inline void RenderTextClippedEx(ImDrawList* draw_list, const ImVec2& pos_min, const ImVec2& pos_max, const char* text, const char* text_end, const ImVec2* text_size_if_known, const ImVec2& align = ImVec2(0, 0), const ImRect* clip_rect = NULL) { RenderTextClippedEx(draw_list, pos_min, pos_max, ImStrv(text, text_end), text_size_if_known, align, clip_rect); }
|
||||||
|
IMGUI_API void RenderTextEllipsis(ImDrawList* draw_list, const ImVec2& pos_min, const ImVec2& pos_max, float clip_max_x, float ellipsis_max_x, ImStrv text, const ImVec2* text_size_if_known);
|
||||||
IMGUI_API void RenderFrame(ImVec2 p_min, ImVec2 p_max, ImU32 fill_col, bool border = true, float rounding = 0.0f);
|
IMGUI_API void RenderFrame(ImVec2 p_min, ImVec2 p_max, ImU32 fill_col, bool border = true, float rounding = 0.0f);
|
||||||
IMGUI_API void RenderFrameBorder(ImVec2 p_min, ImVec2 p_max, float rounding = 0.0f);
|
IMGUI_API void RenderFrameBorder(ImVec2 p_min, ImVec2 p_max, float rounding = 0.0f);
|
||||||
IMGUI_API void RenderColorRectWithAlphaCheckerboard(ImDrawList* draw_list, ImVec2 p_min, ImVec2 p_max, ImU32 fill_col, float grid_step, ImVec2 grid_off, float rounding = 0.0f, ImDrawFlags flags = 0);
|
IMGUI_API void RenderColorRectWithAlphaCheckerboard(ImDrawList* draw_list, ImVec2 p_min, ImVec2 p_max, ImU32 fill_col, float grid_step, ImVec2 grid_off, float rounding = 0.0f, ImDrawFlags flags = 0);
|
||||||
IMGUI_API void RenderNavHighlight(const ImRect& bb, ImGuiID id, ImGuiNavHighlightFlags flags = ImGuiNavHighlightFlags_TypeDefault); // Navigation highlight
|
IMGUI_API void RenderNavHighlight(const ImRect& bb, ImGuiID id, ImGuiNavHighlightFlags flags = ImGuiNavHighlightFlags_TypeDefault); // Navigation highlight
|
||||||
IMGUI_API const char* FindRenderedTextEnd(const char* text, const char* text_end = NULL); // Find the optional ## from which we stop displaying text.
|
IMGUI_API const char* FindRenderedTextEnd(ImStrv text); // Find the optional ## from which we stop displaying text.
|
||||||
|
inline const char* FindRenderedTextEnd(const char* text, const char* text_end) { return FindRenderedTextEnd(ImStrv(text, text_end)); }
|
||||||
IMGUI_API void RenderMouseCursor(ImVec2 pos, float scale, ImGuiMouseCursor mouse_cursor, ImU32 col_fill, ImU32 col_border, ImU32 col_shadow);
|
IMGUI_API void RenderMouseCursor(ImVec2 pos, float scale, ImGuiMouseCursor mouse_cursor, ImU32 col_fill, ImU32 col_border, ImU32 col_shadow);
|
||||||
|
|
||||||
// Render helpers (those functions don't access any ImGui state!)
|
// Render helpers (those functions don't access any ImGui state!)
|
||||||
@ -2780,7 +2796,8 @@ namespace ImGui
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Widgets
|
// Widgets
|
||||||
IMGUI_API void TextEx(const char* text, const char* text_end = NULL, ImGuiTextFlags flags = 0);
|
IMGUI_API void TextEx(ImStrv text, ImGuiTextFlags flags = 0);
|
||||||
|
inline void TextEx(const char* text, const char* text_end, ImGuiTextFlags flags = 0) { TextEx(ImStrv(text, text_end), flags); }
|
||||||
IMGUI_API bool ButtonEx(ImStrv label, const ImVec2& size_arg = ImVec2(0, 0), ImGuiButtonFlags flags = 0);
|
IMGUI_API bool ButtonEx(ImStrv label, const ImVec2& size_arg = ImVec2(0, 0), ImGuiButtonFlags flags = 0);
|
||||||
IMGUI_API bool CloseButton(ImGuiID id, const ImVec2& pos);
|
IMGUI_API bool CloseButton(ImGuiID id, const ImVec2& pos);
|
||||||
IMGUI_API bool CollapseButton(ImGuiID id, const ImVec2& pos);
|
IMGUI_API bool CollapseButton(ImGuiID id, const ImVec2& pos);
|
||||||
@ -2801,7 +2818,7 @@ namespace ImGui
|
|||||||
IMGUI_API bool DragBehavior(ImGuiID id, ImGuiDataType data_type, void* p_v, float v_speed, const void* p_min, const void* p_max, const char* format, ImGuiSliderFlags flags);
|
IMGUI_API bool DragBehavior(ImGuiID id, ImGuiDataType data_type, void* p_v, float v_speed, const void* p_min, const void* p_max, const char* format, ImGuiSliderFlags flags);
|
||||||
IMGUI_API bool SliderBehavior(const ImRect& bb, ImGuiID id, ImGuiDataType data_type, void* p_v, const void* p_min, const void* p_max, const char* format, ImGuiSliderFlags flags, ImRect* out_grab_bb);
|
IMGUI_API bool SliderBehavior(const ImRect& bb, ImGuiID id, ImGuiDataType data_type, void* p_v, const void* p_min, const void* p_max, const char* format, ImGuiSliderFlags flags, ImRect* out_grab_bb);
|
||||||
IMGUI_API bool SplitterBehavior(const ImRect& bb, ImGuiID id, ImGuiAxis axis, float* size1, float* size2, float min_size1, float min_size2, float hover_extend = 0.0f, float hover_visibility_delay = 0.0f);
|
IMGUI_API bool SplitterBehavior(const ImRect& bb, ImGuiID id, ImGuiAxis axis, float* size1, float* size2, float min_size1, float min_size2, float hover_extend = 0.0f, float hover_visibility_delay = 0.0f);
|
||||||
IMGUI_API bool TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* label, const char* label_end = NULL);
|
IMGUI_API bool TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, ImStrv label);
|
||||||
IMGUI_API bool TreeNodeBehaviorIsOpen(ImGuiID id, ImGuiTreeNodeFlags flags = 0); // Consume previous SetNextItemOpen() data, if any. May return true when logging
|
IMGUI_API bool TreeNodeBehaviorIsOpen(ImGuiID id, ImGuiTreeNodeFlags flags = 0); // Consume previous SetNextItemOpen() data, if any. May return true when logging
|
||||||
IMGUI_API void TreePushOverrideID(ImGuiID id);
|
IMGUI_API void TreePushOverrideID(ImGuiID id);
|
||||||
|
|
||||||
@ -2813,7 +2830,7 @@ namespace ImGui
|
|||||||
template<typename T, typename SIGNED_T, typename FLOAT_T> IMGUI_API bool DragBehaviorT(ImGuiDataType data_type, T* v, float v_speed, T v_min, T v_max, const char* format, ImGuiSliderFlags flags);
|
template<typename T, typename SIGNED_T, typename FLOAT_T> IMGUI_API bool DragBehaviorT(ImGuiDataType data_type, T* v, float v_speed, T v_min, T v_max, const char* format, ImGuiSliderFlags flags);
|
||||||
template<typename T, typename SIGNED_T, typename FLOAT_T> IMGUI_API bool SliderBehaviorT(const ImRect& bb, ImGuiID id, ImGuiDataType data_type, T* v, T v_min, T v_max, const char* format, ImGuiSliderFlags flags, ImRect* out_grab_bb);
|
template<typename T, typename SIGNED_T, typename FLOAT_T> IMGUI_API bool SliderBehaviorT(const ImRect& bb, ImGuiID id, ImGuiDataType data_type, T* v, T v_min, T v_max, const char* format, ImGuiSliderFlags flags, ImRect* out_grab_bb);
|
||||||
template<typename T, typename SIGNED_T> IMGUI_API T RoundScalarWithFormatT(const char* format, ImGuiDataType data_type, T v);
|
template<typename T, typename SIGNED_T> IMGUI_API T RoundScalarWithFormatT(const char* format, ImGuiDataType data_type, T v);
|
||||||
template<typename T> IMGUI_API bool CheckboxFlagsT(const char* label, T* flags, T flags_value);
|
template<typename T> IMGUI_API bool CheckboxFlagsT(ImStrv label, T* flags, T flags_value);
|
||||||
|
|
||||||
// Data type helpers
|
// Data type helpers
|
||||||
IMGUI_API const ImGuiDataTypeInfo* DataTypeGetInfo(ImGuiDataType data_type);
|
IMGUI_API const ImGuiDataTypeInfo* DataTypeGetInfo(ImGuiDataType data_type);
|
||||||
@ -2902,7 +2919,7 @@ IMGUI_API void ImFontAtlasBuildMultiplyRectAlpha8(const unsigned char table
|
|||||||
|
|
||||||
#ifdef IMGUI_ENABLE_TEST_ENGINE
|
#ifdef IMGUI_ENABLE_TEST_ENGINE
|
||||||
extern void ImGuiTestEngineHook_ItemAdd(ImGuiContext* ctx, const ImRect& bb, ImGuiID id);
|
extern void ImGuiTestEngineHook_ItemAdd(ImGuiContext* ctx, const ImRect& bb, ImGuiID id);
|
||||||
extern void ImGuiTestEngineHook_ItemInfo(ImGuiContext* ctx, ImGuiID id, const char* label, ImGuiItemStatusFlags flags);
|
extern void ImGuiTestEngineHook_ItemInfo(ImGuiContext* ctx, ImGuiID id, ImStrv label, ImGuiItemStatusFlags flags);
|
||||||
extern void ImGuiTestEngineHook_Log(ImGuiContext* ctx, const char* fmt, ...);
|
extern void ImGuiTestEngineHook_Log(ImGuiContext* ctx, const char* fmt, ...);
|
||||||
extern const char* ImGuiTestEngine_FindItemDebugLabel(ImGuiContext* ctx, ImGuiID id);
|
extern const char* ImGuiTestEngine_FindItemDebugLabel(ImGuiContext* ctx, ImGuiID id);
|
||||||
|
|
||||||
|
@ -301,7 +301,7 @@ ImGuiTable* ImGui::TableFindByID(ImGuiID id)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Read about "TABLE SIZING" at the top of this file.
|
// Read about "TABLE SIZING" at the top of this file.
|
||||||
bool ImGui::BeginTable(const char* str_id, int columns_count, ImGuiTableFlags flags, const ImVec2& outer_size, float inner_width)
|
bool ImGui::BeginTable(ImStrv str_id, int columns_count, ImGuiTableFlags flags, const ImVec2& outer_size, float inner_width)
|
||||||
{
|
{
|
||||||
ImGuiID id = GetID(str_id);
|
ImGuiID id = GetID(str_id);
|
||||||
return BeginTableEx(str_id, id, columns_count, flags, outer_size, inner_width);
|
return BeginTableEx(str_id, id, columns_count, flags, outer_size, inner_width);
|
||||||
@ -1394,7 +1394,7 @@ void ImGui::EndTable()
|
|||||||
|
|
||||||
// See "COLUMN SIZING POLICIES" comments at the top of this file
|
// See "COLUMN SIZING POLICIES" comments at the top of this file
|
||||||
// If (init_width_or_weight <= 0.0f) it is ignored
|
// If (init_width_or_weight <= 0.0f) it is ignored
|
||||||
void ImGui::TableSetupColumn(const char* label, ImGuiTableColumnFlags flags, float init_width_or_weight, ImGuiID user_id)
|
void ImGui::TableSetupColumn(ImStrv label, ImGuiTableColumnFlags flags, float init_width_or_weight, ImGuiID user_id)
|
||||||
{
|
{
|
||||||
ImGuiContext& g = *GImGui;
|
ImGuiContext& g = *GImGui;
|
||||||
ImGuiTable* table = g.CurrentTable;
|
ImGuiTable* table = g.CurrentTable;
|
||||||
@ -1456,8 +1456,10 @@ void ImGui::TableSetupColumn(const char* label, ImGuiTableColumnFlags flags, flo
|
|||||||
column->NameOffset = -1;
|
column->NameOffset = -1;
|
||||||
if (label != NULL && label[0] != 0)
|
if (label != NULL && label[0] != 0)
|
||||||
{
|
{
|
||||||
|
char zero_terminator = 0;
|
||||||
column->NameOffset = (ImS16)table->ColumnsNames.size();
|
column->NameOffset = (ImS16)table->ColumnsNames.size();
|
||||||
table->ColumnsNames.append(label, label + strlen(label) + 1);
|
table->ColumnsNames.append(label.Begin, label.Begin + IM_IMSTR_LENGTH(label));
|
||||||
|
table->ColumnsNames.append(&zero_terminator, &zero_terminator + 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2856,7 +2858,7 @@ void ImGui::TableHeadersRow()
|
|||||||
// Emit a column header (text + optional sort order)
|
// Emit a column header (text + optional sort order)
|
||||||
// We cpu-clip text here so that all columns headers can be merged into a same draw call.
|
// We cpu-clip text here so that all columns headers can be merged into a same draw call.
|
||||||
// Note that because of how we cpu-clip and display sorting indicators, you _cannot_ use SameLine() after a TableHeader()
|
// Note that because of how we cpu-clip and display sorting indicators, you _cannot_ use SameLine() after a TableHeader()
|
||||||
void ImGui::TableHeader(const char* label)
|
void ImGui::TableHeader(ImStrv label)
|
||||||
{
|
{
|
||||||
ImGuiContext& g = *GImGui;
|
ImGuiContext& g = *GImGui;
|
||||||
ImGuiWindow* window = g.CurrentWindow;
|
ImGuiWindow* window = g.CurrentWindow;
|
||||||
@ -2870,10 +2872,11 @@ void ImGui::TableHeader(const char* label)
|
|||||||
ImGuiTableColumn* column = &table->Columns[column_n];
|
ImGuiTableColumn* column = &table->Columns[column_n];
|
||||||
|
|
||||||
// Label
|
// Label
|
||||||
if (label == NULL)
|
if (!label)
|
||||||
label = "";
|
label = "";
|
||||||
const char* label_end = FindRenderedTextEnd(label);
|
ImGuiID id = window->GetID(label);
|
||||||
ImVec2 label_size = CalcTextSize(label, label_end, true);
|
label.End = FindRenderedTextEnd(label);
|
||||||
|
ImVec2 label_size = CalcTextSize(label.Begin, label.End, true);
|
||||||
ImVec2 label_pos = window->DC.CursorPos;
|
ImVec2 label_pos = window->DC.CursorPos;
|
||||||
|
|
||||||
// If we already got a row height, there's use that.
|
// If we already got a row height, there's use that.
|
||||||
@ -2903,7 +2906,6 @@ void ImGui::TableHeader(const char* label)
|
|||||||
|
|
||||||
// Keep header highlighted when context menu is open.
|
// Keep header highlighted when context menu is open.
|
||||||
const bool selected = (table->IsContextPopupOpen && table->ContextPopupColumn == column_n && table->InstanceInteracted == table->InstanceCurrent);
|
const bool selected = (table->IsContextPopupOpen && table->ContextPopupColumn == column_n && table->InstanceInteracted == table->InstanceCurrent);
|
||||||
ImGuiID id = window->GetID(label);
|
|
||||||
ImRect bb(cell_r.Min.x, cell_r.Min.y, cell_r.Max.x, ImMax(cell_r.Max.y, cell_r.Min.y + label_height + g.Style.CellPadding.y * 2.0f));
|
ImRect bb(cell_r.Min.x, cell_r.Min.y, cell_r.Max.x, ImMax(cell_r.Max.y, cell_r.Min.y + label_height + g.Style.CellPadding.y * 2.0f));
|
||||||
ItemSize(ImVec2(0.0f, label_height)); // Don't declare unclipped width, it'll be fed ContentMaxPosHeadersIdeal
|
ItemSize(ImVec2(0.0f, label_height)); // Don't declare unclipped width, it'll be fed ContentMaxPosHeadersIdeal
|
||||||
if (!ItemAdd(bb, id))
|
if (!ItemAdd(bb, id))
|
||||||
@ -2984,11 +2986,11 @@ void ImGui::TableHeader(const char* label)
|
|||||||
// Render clipped label. Clipping here ensure that in the majority of situations, all our header cells will
|
// Render clipped label. Clipping here ensure that in the majority of situations, all our header cells will
|
||||||
// be merged into a single draw call.
|
// be merged into a single draw call.
|
||||||
//window->DrawList->AddCircleFilled(ImVec2(ellipsis_max, label_pos.y), 40, IM_COL32_WHITE);
|
//window->DrawList->AddCircleFilled(ImVec2(ellipsis_max, label_pos.y), 40, IM_COL32_WHITE);
|
||||||
RenderTextEllipsis(window->DrawList, label_pos, ImVec2(ellipsis_max, label_pos.y + label_height + g.Style.FramePadding.y), ellipsis_max, ellipsis_max, label, label_end, &label_size);
|
RenderTextEllipsis(window->DrawList, label_pos, ImVec2(ellipsis_max, label_pos.y + label_height + g.Style.FramePadding.y), ellipsis_max, ellipsis_max, label, &label_size);
|
||||||
|
|
||||||
const bool text_clipped = label_size.x > (ellipsis_max - label_pos.x);
|
const bool text_clipped = label_size.x > (ellipsis_max - label_pos.x);
|
||||||
if (text_clipped && hovered && g.HoveredIdNotActiveTimer > g.TooltipSlowDelay)
|
if (text_clipped && hovered && g.HoveredIdNotActiveTimer > g.TooltipSlowDelay)
|
||||||
SetTooltip("%.*s", (int)(label_end - label), label);
|
SetTooltip("%.*s", (int)(label.End - label.Begin), label.Begin);
|
||||||
|
|
||||||
// We don't use BeginPopupContextItem() because we want the popup to stay up even after the column is hidden
|
// We don't use BeginPopupContextItem() because we want the popup to stay up even after the column is hidden
|
||||||
if (IsMouseReleased(1) && IsItemHovered())
|
if (IsMouseReleased(1) && IsItemHovered())
|
||||||
@ -3810,7 +3812,7 @@ ImGuiOldColumns* ImGui::FindOrCreateColumns(ImGuiWindow* window, ImGuiID id)
|
|||||||
return columns;
|
return columns;
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGuiID ImGui::GetColumnsID(const char* str_id, int columns_count)
|
ImGuiID ImGui::GetColumnsID(ImStrv str_id, int columns_count)
|
||||||
{
|
{
|
||||||
ImGuiWindow* window = GetCurrentWindow();
|
ImGuiWindow* window = GetCurrentWindow();
|
||||||
|
|
||||||
@ -3823,7 +3825,7 @@ ImGuiID ImGui::GetColumnsID(const char* str_id, int columns_count)
|
|||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImGui::BeginColumns(const char* str_id, int columns_count, ImGuiOldColumnFlags flags)
|
void ImGui::BeginColumns(ImStrv str_id, int columns_count, ImGuiOldColumnFlags flags)
|
||||||
{
|
{
|
||||||
ImGuiContext& g = *GImGui;
|
ImGuiContext& g = *GImGui;
|
||||||
ImGuiWindow* window = GetCurrentWindow();
|
ImGuiWindow* window = GetCurrentWindow();
|
||||||
|
@ -148,33 +148,26 @@ static ImVec2 InputTextCalcTextSizeW(const ImWchar* text_begin, const
|
|||||||
// - BulletTextV()
|
// - BulletTextV()
|
||||||
//-------------------------------------------------------------------------
|
//-------------------------------------------------------------------------
|
||||||
|
|
||||||
void ImGui::TextEx(const char* text, const char* text_end, ImGuiTextFlags flags)
|
void ImGui::TextEx(ImStrv text, ImGuiTextFlags flags)
|
||||||
{
|
{
|
||||||
ImGuiWindow* window = GetCurrentWindow();
|
ImGuiWindow* window = GetCurrentWindow();
|
||||||
if (window->SkipItems)
|
if (window->SkipItems || text.Empty())
|
||||||
return;
|
return;
|
||||||
ImGuiContext& g = *GImGui;
|
ImGuiContext& g = *GImGui;
|
||||||
|
|
||||||
// Accept null ranges
|
IM_IMSTR_ENSURE_HAS_END(text);
|
||||||
if (text == text_end)
|
|
||||||
text = text_end = "";
|
|
||||||
|
|
||||||
// Calculate length
|
|
||||||
const char* text_begin = text;
|
|
||||||
if (text_end == NULL)
|
|
||||||
text_end = text + strlen(text); // FIXME-OPT
|
|
||||||
|
|
||||||
const ImVec2 text_pos(window->DC.CursorPos.x, window->DC.CursorPos.y + window->DC.CurrLineTextBaseOffset);
|
const ImVec2 text_pos(window->DC.CursorPos.x, window->DC.CursorPos.y + window->DC.CurrLineTextBaseOffset);
|
||||||
const float wrap_pos_x = window->DC.TextWrapPos;
|
const float wrap_pos_x = window->DC.TextWrapPos;
|
||||||
const bool wrap_enabled = (wrap_pos_x >= 0.0f);
|
const bool wrap_enabled = (wrap_pos_x >= 0.0f);
|
||||||
if (text_end - text > 2000 && !wrap_enabled)
|
if (IM_IMSTR_LENGTH(text) > 2000 && !wrap_enabled)
|
||||||
{
|
{
|
||||||
// Long text!
|
// Long text!
|
||||||
// Perform manual coarse clipping to optimize for long multi-line text
|
// Perform manual coarse clipping to optimize for long multi-line text
|
||||||
// - From this point we will only compute the width of lines that are visible. Optimization only available when word-wrapping is disabled.
|
// - From this point we will only compute the width of lines that are visible. Optimization only available when word-wrapping is disabled.
|
||||||
// - We also don't vertically center the text within the line full height, which is unlikely to matter because we are likely the biggest and only item on the line.
|
// - We also don't vertically center the text within the line full height, which is unlikely to matter because we are likely the biggest and only item on the line.
|
||||||
// - We use memchr(), pay attention that well optimized versions of those str/mem functions are much faster than a casually written loop.
|
// - We use memchr(), pay attention that well optimized versions of those str/mem functions are much faster than a casually written loop.
|
||||||
const char* line = text;
|
const char* line = text.Begin;
|
||||||
const float line_height = GetTextLineHeight();
|
const float line_height = GetTextLineHeight();
|
||||||
ImVec2 text_size(0, 0);
|
ImVec2 text_size(0, 0);
|
||||||
|
|
||||||
@ -186,11 +179,11 @@ void ImGui::TextEx(const char* text, const char* text_end, ImGuiTextFlags flags)
|
|||||||
if (lines_skippable > 0)
|
if (lines_skippable > 0)
|
||||||
{
|
{
|
||||||
int lines_skipped = 0;
|
int lines_skipped = 0;
|
||||||
while (line < text_end && lines_skipped < lines_skippable)
|
while (line < text.End && lines_skipped < lines_skippable)
|
||||||
{
|
{
|
||||||
const char* line_end = (const char*)memchr(line, '\n', text_end - line);
|
const char* line_end = (const char*)memchr(line, '\n', text.End - line);
|
||||||
if (!line_end)
|
if (!line_end)
|
||||||
line_end = text_end;
|
line_end = text.End;
|
||||||
if ((flags & ImGuiTextFlags_NoWidthForLargeClippedText) == 0)
|
if ((flags & ImGuiTextFlags_NoWidthForLargeClippedText) == 0)
|
||||||
text_size.x = ImMax(text_size.x, CalcTextSize(line, line_end).x);
|
text_size.x = ImMax(text_size.x, CalcTextSize(line, line_end).x);
|
||||||
line = line_end + 1;
|
line = line_end + 1;
|
||||||
@ -201,19 +194,19 @@ void ImGui::TextEx(const char* text, const char* text_end, ImGuiTextFlags flags)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Lines to render
|
// Lines to render
|
||||||
if (line < text_end)
|
if (line < text.End)
|
||||||
{
|
{
|
||||||
ImRect line_rect(pos, pos + ImVec2(FLT_MAX, line_height));
|
ImRect line_rect(pos, pos + ImVec2(FLT_MAX, line_height));
|
||||||
while (line < text_end)
|
while (line < text.End)
|
||||||
{
|
{
|
||||||
if (IsClippedEx(line_rect, 0))
|
if (IsClippedEx(line_rect, 0))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
const char* line_end = (const char*)memchr(line, '\n', text_end - line);
|
const char* line_end = (const char*)memchr(line, '\n', text.End - line);
|
||||||
if (!line_end)
|
if (!line_end)
|
||||||
line_end = text_end;
|
line_end = text.End;
|
||||||
text_size.x = ImMax(text_size.x, CalcTextSize(line, line_end).x);
|
text_size.x = ImMax(text_size.x, CalcTextSize(line, line_end).x);
|
||||||
RenderText(pos, line, line_end, false);
|
RenderText(pos, ImStrv(line, line_end), false);
|
||||||
line = line_end + 1;
|
line = line_end + 1;
|
||||||
line_rect.Min.y += line_height;
|
line_rect.Min.y += line_height;
|
||||||
line_rect.Max.y += line_height;
|
line_rect.Max.y += line_height;
|
||||||
@ -222,11 +215,11 @@ void ImGui::TextEx(const char* text, const char* text_end, ImGuiTextFlags flags)
|
|||||||
|
|
||||||
// Count remaining lines
|
// Count remaining lines
|
||||||
int lines_skipped = 0;
|
int lines_skipped = 0;
|
||||||
while (line < text_end)
|
while (line < text.End)
|
||||||
{
|
{
|
||||||
const char* line_end = (const char*)memchr(line, '\n', text_end - line);
|
const char* line_end = (const char*)memchr(line, '\n', text.End - line);
|
||||||
if (!line_end)
|
if (!line_end)
|
||||||
line_end = text_end;
|
line_end = text.End;
|
||||||
if ((flags & ImGuiTextFlags_NoWidthForLargeClippedText) == 0)
|
if ((flags & ImGuiTextFlags_NoWidthForLargeClippedText) == 0)
|
||||||
text_size.x = ImMax(text_size.x, CalcTextSize(line, line_end).x);
|
text_size.x = ImMax(text_size.x, CalcTextSize(line, line_end).x);
|
||||||
line = line_end + 1;
|
line = line_end + 1;
|
||||||
@ -243,7 +236,7 @@ void ImGui::TextEx(const char* text, const char* text_end, ImGuiTextFlags flags)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
const float wrap_width = wrap_enabled ? CalcWrapWidthForPos(window->DC.CursorPos, wrap_pos_x) : 0.0f;
|
const float wrap_width = wrap_enabled ? CalcWrapWidthForPos(window->DC.CursorPos, wrap_pos_x) : 0.0f;
|
||||||
const ImVec2 text_size = CalcTextSize(text_begin, text_end, false, wrap_width);
|
const ImVec2 text_size = CalcTextSize(text, false, wrap_width);
|
||||||
|
|
||||||
ImRect bb(text_pos, text_pos + text_size);
|
ImRect bb(text_pos, text_pos + text_size);
|
||||||
ItemSize(text_size, 0.0f);
|
ItemSize(text_size, 0.0f);
|
||||||
@ -251,13 +244,13 @@ void ImGui::TextEx(const char* text, const char* text_end, ImGuiTextFlags flags)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
// Render (we don't hide text after ## in this end-user function)
|
// Render (we don't hide text after ## in this end-user function)
|
||||||
RenderTextWrapped(bb.Min, text_begin, text_end, wrap_width);
|
RenderTextWrapped(bb.Min, text, wrap_width);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImGui::TextUnformatted(const char* text, const char* text_end)
|
void ImGui::TextUnformatted(ImStrv text)
|
||||||
{
|
{
|
||||||
TextEx(text, text_end, ImGuiTextFlags_NoWidthForLargeClippedText);
|
TextEx(text, ImGuiTextFlags_NoWidthForLargeClippedText);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImGui::Text(const char* fmt, ...)
|
void ImGui::Text(const char* fmt, ...)
|
||||||
@ -277,7 +270,7 @@ void ImGui::TextV(const char* fmt, va_list args)
|
|||||||
// FIXME-OPT: Handle the %s shortcut?
|
// FIXME-OPT: Handle the %s shortcut?
|
||||||
ImGuiContext& g = *GImGui;
|
ImGuiContext& g = *GImGui;
|
||||||
const char* text_end = g.TempBuffer + ImFormatStringV(g.TempBuffer, IM_ARRAYSIZE(g.TempBuffer), fmt, args);
|
const char* text_end = g.TempBuffer + ImFormatStringV(g.TempBuffer, IM_ARRAYSIZE(g.TempBuffer), fmt, args);
|
||||||
TextEx(g.TempBuffer, text_end, ImGuiTextFlags_NoWidthForLargeClippedText);
|
TextEx(ImStrv(g.TempBuffer, text_end), ImGuiTextFlags_NoWidthForLargeClippedText);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImGui::TextColored(const ImVec4& col, const char* fmt, ...)
|
void ImGui::TextColored(const ImVec4& col, const char* fmt, ...)
|
||||||
@ -358,11 +351,12 @@ void ImGui::LabelTextV(ImStrv label, const char* fmt, va_list args)
|
|||||||
const ImGuiStyle& style = g.Style;
|
const ImGuiStyle& style = g.Style;
|
||||||
const float w = CalcItemWidth();
|
const float w = CalcItemWidth();
|
||||||
|
|
||||||
const char* value_text_begin = &g.TempBuffer[0];
|
ImStrv value_text;
|
||||||
const char* value_text_end = value_text_begin + ImFormatStringV(g.TempBuffer, IM_ARRAYSIZE(g.TempBuffer), fmt, args);
|
value_text.Begin = &g.TempBuffer[0];
|
||||||
const ImVec2 value_size = CalcTextSize(value_text_begin, value_text_end, false);
|
value_text.End = value_text.Begin + ImFormatStringV(g.TempBuffer, IM_ARRAYSIZE(g.TempBuffer), fmt, args);
|
||||||
const ImVec2 label_size = CalcTextSize(label, NULL, true);
|
|
||||||
|
|
||||||
|
const ImVec2 value_size = CalcTextSize(value_text, false);
|
||||||
|
const ImVec2 label_size = CalcTextSize(label, true);
|
||||||
const ImVec2 pos = window->DC.CursorPos;
|
const ImVec2 pos = window->DC.CursorPos;
|
||||||
const ImRect value_bb(pos, pos + ImVec2(w, value_size.y + style.FramePadding.y * 2));
|
const ImRect value_bb(pos, pos + ImVec2(w, value_size.y + style.FramePadding.y * 2));
|
||||||
const ImRect total_bb(pos, pos + ImVec2(w + (label_size.x > 0.0f ? style.ItemInnerSpacing.x + label_size.x : 0.0f), ImMax(value_size.y, label_size.y) + style.FramePadding.y * 2));
|
const ImRect total_bb(pos, pos + ImVec2(w + (label_size.x > 0.0f ? style.ItemInnerSpacing.x + label_size.x : 0.0f), ImMax(value_size.y, label_size.y) + style.FramePadding.y * 2));
|
||||||
@ -371,7 +365,7 @@ void ImGui::LabelTextV(ImStrv label, const char* fmt, va_list args)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
// Render
|
// Render
|
||||||
RenderTextClipped(value_bb.Min + style.FramePadding, value_bb.Max, value_text_begin, value_text_end, &value_size, ImVec2(0.0f, 0.0f));
|
RenderTextClipped(value_bb.Min + style.FramePadding, value_bb.Max, value_text, &value_size, ImVec2(0.0f, 0.0f));
|
||||||
if (label_size.x > 0.0f)
|
if (label_size.x > 0.0f)
|
||||||
RenderText(ImVec2(value_bb.Max.x + style.ItemInnerSpacing.x, value_bb.Min.y + style.FramePadding.y), label);
|
RenderText(ImVec2(value_bb.Max.x + style.ItemInnerSpacing.x, value_bb.Min.y + style.FramePadding.y), label);
|
||||||
}
|
}
|
||||||
@ -408,7 +402,7 @@ void ImGui::BulletTextV(const char* fmt, va_list args)
|
|||||||
// Render
|
// Render
|
||||||
ImU32 text_col = GetColorU32(ImGuiCol_Text);
|
ImU32 text_col = GetColorU32(ImGuiCol_Text);
|
||||||
RenderBullet(window->DrawList, bb.Min + ImVec2(style.FramePadding.x + g.FontSize * 0.5f, g.FontSize * 0.5f), text_col);
|
RenderBullet(window->DrawList, bb.Min + ImVec2(style.FramePadding.x + g.FontSize * 0.5f, g.FontSize * 0.5f), text_col);
|
||||||
RenderText(bb.Min + ImVec2(g.FontSize + style.FramePadding.x * 2, 0.0f), text_begin, text_end, false);
|
RenderText(bb.Min + ImVec2(g.FontSize + style.FramePadding.x * 2, 0.0f), ImStrv(text_begin, text_end), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
//-------------------------------------------------------------------------
|
//-------------------------------------------------------------------------
|
||||||
@ -677,7 +671,7 @@ bool ImGui::ButtonEx(ImStrv label, const ImVec2& size_arg, ImGuiButtonFlags flag
|
|||||||
ImGuiContext& g = *GImGui;
|
ImGuiContext& g = *GImGui;
|
||||||
const ImGuiStyle& style = g.Style;
|
const ImGuiStyle& style = g.Style;
|
||||||
const ImGuiID id = window->GetID(label);
|
const ImGuiID id = window->GetID(label);
|
||||||
const ImVec2 label_size = CalcTextSize(label, NULL, true);
|
const ImVec2 label_size = CalcTextSize(label, true);
|
||||||
|
|
||||||
ImVec2 pos = window->DC.CursorPos;
|
ImVec2 pos = window->DC.CursorPos;
|
||||||
if ((flags & ImGuiButtonFlags_AlignTextBaseLine) && style.FramePadding.y < window->DC.CurrLineTextBaseOffset) // Try to vertically align buttons that are smaller/have no padding so that text baseline matches (bit hacky, since it shouldn't be a flag)
|
if ((flags & ImGuiButtonFlags_AlignTextBaseLine) && style.FramePadding.y < window->DC.CurrLineTextBaseOffset) // Try to vertically align buttons that are smaller/have no padding so that text baseline matches (bit hacky, since it shouldn't be a flag)
|
||||||
@ -702,7 +696,7 @@ bool ImGui::ButtonEx(ImStrv label, const ImVec2& size_arg, ImGuiButtonFlags flag
|
|||||||
|
|
||||||
if (g.LogEnabled)
|
if (g.LogEnabled)
|
||||||
LogSetNextTextDecoration("[", "]");
|
LogSetNextTextDecoration("[", "]");
|
||||||
RenderTextClipped(bb.Min + style.FramePadding, bb.Max - style.FramePadding, label, NULL, &label_size, style.ButtonTextAlign, &bb);
|
RenderTextClipped(bb.Min + style.FramePadding, bb.Max - style.FramePadding, label, &label_size, style.ButtonTextAlign, &bb);
|
||||||
|
|
||||||
// Automatically close popups
|
// Automatically close popups
|
||||||
//if (pressed && !(flags & ImGuiButtonFlags_DontClosePopups) && (window->Flags & ImGuiWindowFlags_Popup))
|
//if (pressed && !(flags & ImGuiButtonFlags_DontClosePopups) && (window->Flags & ImGuiWindowFlags_Popup))
|
||||||
@ -1082,7 +1076,7 @@ bool ImGui::Checkbox(ImStrv label, bool* v)
|
|||||||
ImGuiContext& g = *GImGui;
|
ImGuiContext& g = *GImGui;
|
||||||
const ImGuiStyle& style = g.Style;
|
const ImGuiStyle& style = g.Style;
|
||||||
const ImGuiID id = window->GetID(label);
|
const ImGuiID id = window->GetID(label);
|
||||||
const ImVec2 label_size = CalcTextSize(label, NULL, true);
|
const ImVec2 label_size = CalcTextSize(label, true);
|
||||||
|
|
||||||
const float square_sz = GetFrameHeight();
|
const float square_sz = GetFrameHeight();
|
||||||
const ImVec2 pos = window->DC.CursorPos;
|
const ImVec2 pos = window->DC.CursorPos;
|
||||||
@ -1188,7 +1182,7 @@ bool ImGui::RadioButton(ImStrv label, bool active)
|
|||||||
ImGuiContext& g = *GImGui;
|
ImGuiContext& g = *GImGui;
|
||||||
const ImGuiStyle& style = g.Style;
|
const ImGuiStyle& style = g.Style;
|
||||||
const ImGuiID id = window->GetID(label);
|
const ImGuiID id = window->GetID(label);
|
||||||
const ImVec2 label_size = CalcTextSize(label, NULL, true);
|
const ImVec2 label_size = CalcTextSize(label, true);
|
||||||
|
|
||||||
const float square_sz = GetFrameHeight();
|
const float square_sz = GetFrameHeight();
|
||||||
const ImVec2 pos = window->DC.CursorPos;
|
const ImVec2 pos = window->DC.CursorPos;
|
||||||
@ -1273,9 +1267,9 @@ void ImGui::ProgressBar(float fraction, const ImVec2& size_arg, ImStrv overlay)
|
|||||||
overlay = overlay_buf;
|
overlay = overlay_buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
ImVec2 overlay_size = CalcTextSize(overlay, NULL);
|
ImVec2 overlay_size = CalcTextSize(overlay);
|
||||||
if (overlay_size.x > 0.0f)
|
if (overlay_size.x > 0.0f)
|
||||||
RenderTextClipped(ImVec2(ImClamp(fill_br.x + style.ItemSpacing.x, bb.Min.x, bb.Max.x - overlay_size.x - style.ItemInnerSpacing.x), bb.Min.y), bb.Max, overlay, NULL, &overlay_size, ImVec2(0.0f, 0.5f), &bb);
|
RenderTextClipped(ImVec2(ImClamp(fill_br.x + style.ItemSpacing.x, bb.Min.x, bb.Max.x - overlay_size.x - style.ItemInnerSpacing.x), bb.Min.y), bb.Max, overlay, &overlay_size, ImVec2(0.0f, 0.5f), &bb);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImGui::Bullet()
|
void ImGui::Bullet()
|
||||||
@ -1587,7 +1581,7 @@ bool ImGui::BeginCombo(ImStrv label, ImStrv preview_value, ImGuiComboFlags flags
|
|||||||
IM_ASSERT((flags & (ImGuiComboFlags_NoArrowButton | ImGuiComboFlags_NoPreview)) != (ImGuiComboFlags_NoArrowButton | ImGuiComboFlags_NoPreview)); // Can't use both flags together
|
IM_ASSERT((flags & (ImGuiComboFlags_NoArrowButton | ImGuiComboFlags_NoPreview)) != (ImGuiComboFlags_NoArrowButton | ImGuiComboFlags_NoPreview)); // Can't use both flags together
|
||||||
|
|
||||||
const float arrow_size = (flags & ImGuiComboFlags_NoArrowButton) ? 0.0f : GetFrameHeight();
|
const float arrow_size = (flags & ImGuiComboFlags_NoArrowButton) ? 0.0f : GetFrameHeight();
|
||||||
const ImVec2 label_size = CalcTextSize(label, NULL, true);
|
const ImVec2 label_size = CalcTextSize(label, true);
|
||||||
const float w = (flags & ImGuiComboFlags_NoPreview) ? arrow_size : CalcItemWidth();
|
const float w = (flags & ImGuiComboFlags_NoPreview) ? arrow_size : CalcItemWidth();
|
||||||
const ImRect bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(w, label_size.y + style.FramePadding.y * 2.0f));
|
const ImRect bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(w, label_size.y + style.FramePadding.y * 2.0f));
|
||||||
const ImRect total_bb(bb.Min, bb.Max + ImVec2(label_size.x > 0.0f ? style.ItemInnerSpacing.x + label_size.x : 0.0f, 0.0f));
|
const ImRect total_bb(bb.Min, bb.Max + ImVec2(label_size.x > 0.0f ? style.ItemInnerSpacing.x + label_size.x : 0.0f, 0.0f));
|
||||||
@ -1626,7 +1620,7 @@ bool ImGui::BeginCombo(ImStrv label, ImStrv preview_value, ImGuiComboFlags flags
|
|||||||
if (flags & ImGuiComboFlags_CustomPreview)
|
if (flags & ImGuiComboFlags_CustomPreview)
|
||||||
{
|
{
|
||||||
g.ComboPreviewData.PreviewRect = ImRect(bb.Min.x, bb.Min.y, value_x2, bb.Max.y);
|
g.ComboPreviewData.PreviewRect = ImRect(bb.Min.x, bb.Min.y, value_x2, bb.Max.y);
|
||||||
IM_ASSERT(preview_value == NULL || preview_value[0] == 0);
|
IM_ASSERT(!preview_value || preview_value[0] == 0);
|
||||||
preview_value = NULL;
|
preview_value = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1635,7 +1629,7 @@ bool ImGui::BeginCombo(ImStrv label, ImStrv preview_value, ImGuiComboFlags flags
|
|||||||
{
|
{
|
||||||
if (g.LogEnabled)
|
if (g.LogEnabled)
|
||||||
LogSetNextTextDecoration("{", "}");
|
LogSetNextTextDecoration("{", "}");
|
||||||
RenderTextClipped(bb.Min + style.FramePadding, ImVec2(value_x2, bb.Max.y), preview_value, NULL, NULL);
|
RenderTextClipped(bb.Min + style.FramePadding, ImVec2(value_x2, bb.Max.y), preview_value, NULL);
|
||||||
}
|
}
|
||||||
if (label_size.x > 0)
|
if (label_size.x > 0)
|
||||||
RenderText(ImVec2(bb.Max.x + style.ItemInnerSpacing.x, bb.Min.y + style.FramePadding.y), label);
|
RenderText(ImVec2(bb.Max.x + style.ItemInnerSpacing.x, bb.Min.y + style.FramePadding.y), label);
|
||||||
@ -2334,7 +2328,7 @@ bool ImGui::DragBehavior(ImGuiID id, ImGuiDataType data_type, void* p_v, float v
|
|||||||
|
|
||||||
// Note: p_data, p_min and p_max are _pointers_ to a memory address holding the data. For a Drag widget, p_min and p_max are optional.
|
// Note: p_data, p_min and p_max are _pointers_ to a memory address holding the data. For a Drag widget, p_min and p_max are optional.
|
||||||
// Read code of e.g. DragFloat(), DragInt() etc. or examples in 'Demo->Widgets->Data Types' to understand how to use this function directly.
|
// Read code of e.g. DragFloat(), DragInt() etc. or examples in 'Demo->Widgets->Data Types' to understand how to use this function directly.
|
||||||
bool ImGui::DragScalar(ImStrv label, ImGuiDataType data_type, void* p_data, float v_speed, const void* p_min, const void* p_max, ImStrv format, ImGuiSliderFlags flags)
|
bool ImGui::DragScalar(ImStrv label, ImGuiDataType data_type, void* p_data, float v_speed, const void* p_min, const void* p_max, ImStrv format_p, ImGuiSliderFlags flags)
|
||||||
{
|
{
|
||||||
ImGuiWindow* window = GetCurrentWindow();
|
ImGuiWindow* window = GetCurrentWindow();
|
||||||
if (window->SkipItems)
|
if (window->SkipItems)
|
||||||
@ -2345,7 +2339,7 @@ bool ImGui::DragScalar(ImStrv label, ImGuiDataType data_type, void* p_data, floa
|
|||||||
const ImGuiID id = window->GetID(label);
|
const ImGuiID id = window->GetID(label);
|
||||||
const float w = CalcItemWidth();
|
const float w = CalcItemWidth();
|
||||||
|
|
||||||
const ImVec2 label_size = CalcTextSize(label, NULL, true);
|
const ImVec2 label_size = CalcTextSize(label, true);
|
||||||
const ImRect frame_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(w, label_size.y + style.FramePadding.y * 2.0f));
|
const ImRect frame_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(w, label_size.y + style.FramePadding.y * 2.0f));
|
||||||
const ImRect total_bb(frame_bb.Min, frame_bb.Max + ImVec2(label_size.x > 0.0f ? style.ItemInnerSpacing.x + label_size.x : 0.0f, 0.0f));
|
const ImRect total_bb(frame_bb.Min, frame_bb.Max + ImVec2(label_size.x > 0.0f ? style.ItemInnerSpacing.x + label_size.x : 0.0f, 0.0f));
|
||||||
|
|
||||||
@ -2354,10 +2348,15 @@ bool ImGui::DragScalar(ImStrv label, ImGuiDataType data_type, void* p_data, floa
|
|||||||
if (!ItemAdd(total_bb, id, &frame_bb, temp_input_allowed ? ImGuiItemFlags_Inputable : 0))
|
if (!ItemAdd(total_bb, id, &frame_bb, temp_input_allowed ? ImGuiItemFlags_Inputable : 0))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
char format_0[64]; // format may not end with \0
|
||||||
|
const char* format = format_0;
|
||||||
|
IM_ASSERT(IM_IMSTR_LENGTH(format_p) < IM_ARRAYSIZE(format_0));
|
||||||
|
ImStrncpy(format_0, format_p, IM_ARRAYSIZE(format_0));
|
||||||
|
|
||||||
// Default format string when passing NULL
|
// Default format string when passing NULL
|
||||||
if (format == NULL)
|
if (format_p.Empty())
|
||||||
format = DataTypeGetInfo(data_type)->PrintFmt;
|
format = DataTypeGetInfo(data_type)->PrintFmt;
|
||||||
else if (data_type == ImGuiDataType_S32 && strcmp(format, "%d") != 0) // (FIXME-LEGACY: Patch old "%.0f" format string to use "%d", read function more details.)
|
else if (data_type == ImGuiDataType_S32 && format_p != ImStrv("%d")) // (FIXME-LEGACY: Patch old "%.0f" format string to use "%d", read function more details.)
|
||||||
format = PatchFormatStringFloatToInt(format);
|
format = PatchFormatStringFloatToInt(format);
|
||||||
|
|
||||||
// Tabbing or CTRL-clicking on Drag turns it into an InputText
|
// Tabbing or CTRL-clicking on Drag turns it into an InputText
|
||||||
@ -2411,7 +2410,7 @@ bool ImGui::DragScalar(ImStrv label, ImGuiDataType data_type, void* p_data, floa
|
|||||||
const char* value_buf_end = value_buf + DataTypeFormatString(value_buf, IM_ARRAYSIZE(value_buf), data_type, p_data, format);
|
const char* value_buf_end = value_buf + DataTypeFormatString(value_buf, IM_ARRAYSIZE(value_buf), data_type, p_data, format);
|
||||||
if (g.LogEnabled)
|
if (g.LogEnabled)
|
||||||
LogSetNextTextDecoration("{", "}");
|
LogSetNextTextDecoration("{", "}");
|
||||||
RenderTextClipped(frame_bb.Min, frame_bb.Max, value_buf, value_buf_end, NULL, ImVec2(0.5f, 0.5f));
|
RenderTextClipped(frame_bb.Min, frame_bb.Max, ImStrv(value_buf, value_buf_end), NULL, ImVec2(0.5f, 0.5f));
|
||||||
|
|
||||||
if (label_size.x > 0.0f)
|
if (label_size.x > 0.0f)
|
||||||
RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, frame_bb.Min.y + style.FramePadding.y), label);
|
RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, frame_bb.Min.y + style.FramePadding.y), label);
|
||||||
@ -2445,10 +2444,10 @@ bool ImGui::DragScalarN(ImStrv label, ImGuiDataType data_type, void* p_data, int
|
|||||||
PopID();
|
PopID();
|
||||||
|
|
||||||
const char* label_end = FindRenderedTextEnd(label);
|
const char* label_end = FindRenderedTextEnd(label);
|
||||||
if (label != label_end)
|
if (label.Begin != label_end)
|
||||||
{
|
{
|
||||||
SameLine(0, g.Style.ItemInnerSpacing.x);
|
SameLine(0, g.Style.ItemInnerSpacing.x);
|
||||||
TextEx(label, label_end);
|
TextEx(ImStrv(label.Begin, label_end));
|
||||||
}
|
}
|
||||||
|
|
||||||
EndGroup();
|
EndGroup();
|
||||||
@ -2501,7 +2500,7 @@ bool ImGui::DragFloatRange2(ImStrv label, float* v_current_min, float* v_current
|
|||||||
PopItemWidth();
|
PopItemWidth();
|
||||||
SameLine(0, g.Style.ItemInnerSpacing.x);
|
SameLine(0, g.Style.ItemInnerSpacing.x);
|
||||||
|
|
||||||
TextEx(label, FindRenderedTextEnd(label));
|
TextEx(ImStrv(label.Begin, FindRenderedTextEnd(label)));
|
||||||
EndGroup();
|
EndGroup();
|
||||||
PopID();
|
PopID();
|
||||||
|
|
||||||
@ -2555,7 +2554,7 @@ bool ImGui::DragIntRange2(ImStrv label, int* v_current_min, int* v_current_max,
|
|||||||
PopItemWidth();
|
PopItemWidth();
|
||||||
SameLine(0, g.Style.ItemInnerSpacing.x);
|
SameLine(0, g.Style.ItemInnerSpacing.x);
|
||||||
|
|
||||||
TextEx(label, FindRenderedTextEnd(label));
|
TextEx(ImStrv(label.Begin, FindRenderedTextEnd(label)));
|
||||||
EndGroup();
|
EndGroup();
|
||||||
PopID();
|
PopID();
|
||||||
|
|
||||||
@ -2952,7 +2951,7 @@ bool ImGui::SliderBehavior(const ImRect& bb, ImGuiID id, ImGuiDataType data_type
|
|||||||
|
|
||||||
// Note: p_data, p_min and p_max are _pointers_ to a memory address holding the data. For a slider, they are all required.
|
// Note: p_data, p_min and p_max are _pointers_ to a memory address holding the data. For a slider, they are all required.
|
||||||
// Read code of e.g. SliderFloat(), SliderInt() etc. or examples in 'Demo->Widgets->Data Types' to understand how to use this function directly.
|
// Read code of e.g. SliderFloat(), SliderInt() etc. or examples in 'Demo->Widgets->Data Types' to understand how to use this function directly.
|
||||||
bool ImGui::SliderScalar(ImStrv label, ImGuiDataType data_type, void* p_data, const void* p_min, const void* p_max, ImStrv format, ImGuiSliderFlags flags)
|
bool ImGui::SliderScalar(ImStrv label, ImGuiDataType data_type, void* p_data, const void* p_min, const void* p_max, ImStrv format_p, ImGuiSliderFlags flags)
|
||||||
{
|
{
|
||||||
ImGuiWindow* window = GetCurrentWindow();
|
ImGuiWindow* window = GetCurrentWindow();
|
||||||
if (window->SkipItems)
|
if (window->SkipItems)
|
||||||
@ -2963,7 +2962,7 @@ bool ImGui::SliderScalar(ImStrv label, ImGuiDataType data_type, void* p_data, co
|
|||||||
const ImGuiID id = window->GetID(label);
|
const ImGuiID id = window->GetID(label);
|
||||||
const float w = CalcItemWidth();
|
const float w = CalcItemWidth();
|
||||||
|
|
||||||
const ImVec2 label_size = CalcTextSize(label, NULL, true);
|
const ImVec2 label_size = CalcTextSize(label, true);
|
||||||
const ImRect frame_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(w, label_size.y + style.FramePadding.y * 2.0f));
|
const ImRect frame_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(w, label_size.y + style.FramePadding.y * 2.0f));
|
||||||
const ImRect total_bb(frame_bb.Min, frame_bb.Max + ImVec2(label_size.x > 0.0f ? style.ItemInnerSpacing.x + label_size.x : 0.0f, 0.0f));
|
const ImRect total_bb(frame_bb.Min, frame_bb.Max + ImVec2(label_size.x > 0.0f ? style.ItemInnerSpacing.x + label_size.x : 0.0f, 0.0f));
|
||||||
|
|
||||||
@ -2972,11 +2971,19 @@ bool ImGui::SliderScalar(ImStrv label, ImGuiDataType data_type, void* p_data, co
|
|||||||
if (!ItemAdd(total_bb, id, &frame_bb, temp_input_allowed ? ImGuiItemFlags_Inputable : 0))
|
if (!ItemAdd(total_bb, id, &frame_bb, temp_input_allowed ? ImGuiItemFlags_Inputable : 0))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
char format_0[64]; // format may not end with \0
|
||||||
|
const char* format = format_0;
|
||||||
|
IM_ASSERT(IM_IMSTR_LENGTH(format_p) < IM_ARRAYSIZE(format_0));
|
||||||
|
|
||||||
// Default format string when passing NULL
|
// Default format string when passing NULL
|
||||||
if (format == NULL)
|
if (format_p.Empty())
|
||||||
format = DataTypeGetInfo(data_type)->PrintFmt;
|
format = DataTypeGetInfo(data_type)->PrintFmt;
|
||||||
else if (data_type == ImGuiDataType_S32 && strcmp(format, "%d") != 0) // (FIXME-LEGACY: Patch old "%.0f" format string to use "%d", read function more details.)
|
else
|
||||||
|
{
|
||||||
|
ImStrncpy(format_0, format_p, IM_ARRAYSIZE(format_0));
|
||||||
|
if (data_type == ImGuiDataType_S32 && format_p != ImStrv("%d")) // (FIXME-LEGACY: Patch old "%.0f" format string to use "%d", read function more details.)
|
||||||
format = PatchFormatStringFloatToInt(format);
|
format = PatchFormatStringFloatToInt(format);
|
||||||
|
}
|
||||||
|
|
||||||
// Tabbing or CTRL-clicking on Slider turns it into an input box
|
// Tabbing or CTRL-clicking on Slider turns it into an input box
|
||||||
const bool hovered = ItemHoverable(frame_bb, id);
|
const bool hovered = ItemHoverable(frame_bb, id);
|
||||||
@ -3023,7 +3030,7 @@ bool ImGui::SliderScalar(ImStrv label, ImGuiDataType data_type, void* p_data, co
|
|||||||
const char* value_buf_end = value_buf + DataTypeFormatString(value_buf, IM_ARRAYSIZE(value_buf), data_type, p_data, format);
|
const char* value_buf_end = value_buf + DataTypeFormatString(value_buf, IM_ARRAYSIZE(value_buf), data_type, p_data, format);
|
||||||
if (g.LogEnabled)
|
if (g.LogEnabled)
|
||||||
LogSetNextTextDecoration("{", "}");
|
LogSetNextTextDecoration("{", "}");
|
||||||
RenderTextClipped(frame_bb.Min, frame_bb.Max, value_buf, value_buf_end, NULL, ImVec2(0.5f, 0.5f));
|
RenderTextClipped(frame_bb.Min, frame_bb.Max, ImStrv(value_buf, value_buf_end), NULL, ImVec2(0.5f, 0.5f));
|
||||||
|
|
||||||
if (label_size.x > 0.0f)
|
if (label_size.x > 0.0f)
|
||||||
RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, frame_bb.Min.y + style.FramePadding.y), label);
|
RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, frame_bb.Min.y + style.FramePadding.y), label);
|
||||||
@ -3058,10 +3065,10 @@ bool ImGui::SliderScalarN(ImStrv label, ImGuiDataType data_type, void* v, int co
|
|||||||
PopID();
|
PopID();
|
||||||
|
|
||||||
const char* label_end = FindRenderedTextEnd(label);
|
const char* label_end = FindRenderedTextEnd(label);
|
||||||
if (label != label_end)
|
if (label.Begin != label_end)
|
||||||
{
|
{
|
||||||
SameLine(0, g.Style.ItemInnerSpacing.x);
|
SameLine(0, g.Style.ItemInnerSpacing.x);
|
||||||
TextEx(label, label_end);
|
TextEx(ImStrv(label.Begin, label_end));
|
||||||
}
|
}
|
||||||
|
|
||||||
EndGroup();
|
EndGroup();
|
||||||
@ -3090,7 +3097,7 @@ bool ImGui::SliderFloat4(ImStrv label, float v[4], float v_min, float v_max, ImS
|
|||||||
|
|
||||||
bool ImGui::SliderAngle(ImStrv label, float* v_rad, float v_degrees_min, float v_degrees_max, ImStrv format, ImGuiSliderFlags flags)
|
bool ImGui::SliderAngle(ImStrv label, float* v_rad, float v_degrees_min, float v_degrees_max, ImStrv format, ImGuiSliderFlags flags)
|
||||||
{
|
{
|
||||||
if (format == NULL)
|
if (format.Empty())
|
||||||
format = "%.0f deg";
|
format = "%.0f deg";
|
||||||
float v_deg = (*v_rad) * 360.0f / (2 * IM_PI);
|
float v_deg = (*v_rad) * 360.0f / (2 * IM_PI);
|
||||||
bool value_changed = SliderFloat(label, &v_deg, v_degrees_min, v_degrees_max, format, flags);
|
bool value_changed = SliderFloat(label, &v_deg, v_degrees_min, v_degrees_max, format, flags);
|
||||||
@ -3118,7 +3125,7 @@ bool ImGui::SliderInt4(ImStrv label, int v[4], int v_min, int v_max, ImStrv form
|
|||||||
return SliderScalarN(label, ImGuiDataType_S32, v, 4, &v_min, &v_max, format, flags);
|
return SliderScalarN(label, ImGuiDataType_S32, v, 4, &v_min, &v_max, format, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ImGui::VSliderScalar(ImStrv label, const ImVec2& size, ImGuiDataType data_type, void* p_data, const void* p_min, const void* p_max, ImStrv format, ImGuiSliderFlags flags)
|
bool ImGui::VSliderScalar(ImStrv label, const ImVec2& size, ImGuiDataType data_type, void* p_data, const void* p_min, const void* p_max, ImStrv format_p, ImGuiSliderFlags flags)
|
||||||
{
|
{
|
||||||
ImGuiWindow* window = GetCurrentWindow();
|
ImGuiWindow* window = GetCurrentWindow();
|
||||||
if (window->SkipItems)
|
if (window->SkipItems)
|
||||||
@ -3128,7 +3135,7 @@ bool ImGui::VSliderScalar(ImStrv label, const ImVec2& size, ImGuiDataType data_t
|
|||||||
const ImGuiStyle& style = g.Style;
|
const ImGuiStyle& style = g.Style;
|
||||||
const ImGuiID id = window->GetID(label);
|
const ImGuiID id = window->GetID(label);
|
||||||
|
|
||||||
const ImVec2 label_size = CalcTextSize(label, NULL, true);
|
const ImVec2 label_size = CalcTextSize(label, true);
|
||||||
const ImRect frame_bb(window->DC.CursorPos, window->DC.CursorPos + size);
|
const ImRect frame_bb(window->DC.CursorPos, window->DC.CursorPos + size);
|
||||||
const ImRect bb(frame_bb.Min, frame_bb.Max + ImVec2(label_size.x > 0.0f ? style.ItemInnerSpacing.x + label_size.x : 0.0f, 0.0f));
|
const ImRect bb(frame_bb.Min, frame_bb.Max + ImVec2(label_size.x > 0.0f ? style.ItemInnerSpacing.x + label_size.x : 0.0f, 0.0f));
|
||||||
|
|
||||||
@ -3136,11 +3143,19 @@ bool ImGui::VSliderScalar(ImStrv label, const ImVec2& size, ImGuiDataType data_t
|
|||||||
if (!ItemAdd(frame_bb, id))
|
if (!ItemAdd(frame_bb, id))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
char format_0[64]; // format may not end with \0
|
||||||
|
const char* format = format_0;
|
||||||
|
IM_ASSERT(IM_IMSTR_LENGTH(format_p) < IM_ARRAYSIZE(format_0));
|
||||||
|
|
||||||
// Default format string when passing NULL
|
// Default format string when passing NULL
|
||||||
if (format == NULL)
|
if (format_p.Empty())
|
||||||
format = DataTypeGetInfo(data_type)->PrintFmt;
|
format = DataTypeGetInfo(data_type)->PrintFmt;
|
||||||
else if (data_type == ImGuiDataType_S32 && strcmp(format, "%d") != 0) // (FIXME-LEGACY: Patch old "%.0f" format string to use "%d", read function more details.)
|
else
|
||||||
|
{
|
||||||
|
ImStrncpy(format_0, format_p, IM_ARRAYSIZE(format_0));
|
||||||
|
if (data_type == ImGuiDataType_S32 && format_p != ImStrv("%d")) // (FIXME-LEGACY: Patch old "%.0f" format string to use "%d", read function more details.)
|
||||||
format = PatchFormatStringFloatToInt(format);
|
format = PatchFormatStringFloatToInt(format);
|
||||||
|
}
|
||||||
|
|
||||||
const bool hovered = ItemHoverable(frame_bb, id);
|
const bool hovered = ItemHoverable(frame_bb, id);
|
||||||
if ((hovered && g.IO.MouseClicked[0]) || g.NavActivateId == id || g.NavActivateInputId == id)
|
if ((hovered && g.IO.MouseClicked[0]) || g.NavActivateId == id || g.NavActivateInputId == id)
|
||||||
@ -3170,7 +3185,7 @@ bool ImGui::VSliderScalar(ImStrv label, const ImVec2& size, ImGuiDataType data_t
|
|||||||
// For the vertical slider we allow centered text to overlap the frame padding
|
// For the vertical slider we allow centered text to overlap the frame padding
|
||||||
char value_buf[64];
|
char value_buf[64];
|
||||||
const char* value_buf_end = value_buf + DataTypeFormatString(value_buf, IM_ARRAYSIZE(value_buf), data_type, p_data, format);
|
const char* value_buf_end = value_buf + DataTypeFormatString(value_buf, IM_ARRAYSIZE(value_buf), data_type, p_data, format);
|
||||||
RenderTextClipped(ImVec2(frame_bb.Min.x, frame_bb.Min.y + style.FramePadding.y), frame_bb.Max, value_buf, value_buf_end, NULL, ImVec2(0.5f, 0.0f));
|
RenderTextClipped(ImVec2(frame_bb.Min.x, frame_bb.Min.y + style.FramePadding.y), frame_bb.Max, ImStrv(value_buf, value_buf_end), NULL, ImVec2(0.5f, 0.0f));
|
||||||
if (label_size.x > 0.0f)
|
if (label_size.x > 0.0f)
|
||||||
RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, frame_bb.Min.y + style.FramePadding.y), label);
|
RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, frame_bb.Min.y + style.FramePadding.y), label);
|
||||||
|
|
||||||
@ -3369,7 +3384,7 @@ bool ImGui::TempInputScalar(const ImRect& bb, ImGuiID id, ImStrv label, ImGuiDat
|
|||||||
|
|
||||||
// Note: p_data, p_step, p_step_fast are _pointers_ to a memory address holding the data. For an Input widget, p_step and p_step_fast are optional.
|
// Note: p_data, p_step, p_step_fast are _pointers_ to a memory address holding the data. For an Input widget, p_step and p_step_fast are optional.
|
||||||
// Read code of e.g. InputFloat(), InputInt() etc. or examples in 'Demo->Widgets->Data Types' to understand how to use this function directly.
|
// Read code of e.g. InputFloat(), InputInt() etc. or examples in 'Demo->Widgets->Data Types' to understand how to use this function directly.
|
||||||
bool ImGui::InputScalar(ImStrv label, ImGuiDataType data_type, void* p_data, const void* p_step, const void* p_step_fast, ImStrv format, ImGuiInputTextFlags flags)
|
bool ImGui::InputScalar(ImStrv label, ImGuiDataType data_type, void* p_data, const void* p_step, const void* p_step_fast, ImStrv format_p, ImGuiInputTextFlags flags)
|
||||||
{
|
{
|
||||||
ImGuiWindow* window = GetCurrentWindow();
|
ImGuiWindow* window = GetCurrentWindow();
|
||||||
if (window->SkipItems)
|
if (window->SkipItems)
|
||||||
@ -3378,7 +3393,12 @@ bool ImGui::InputScalar(ImStrv label, ImGuiDataType data_type, void* p_data, con
|
|||||||
ImGuiContext& g = *GImGui;
|
ImGuiContext& g = *GImGui;
|
||||||
ImGuiStyle& style = g.Style;
|
ImGuiStyle& style = g.Style;
|
||||||
|
|
||||||
if (format == NULL)
|
char format_0[64]; // format may not end with \0
|
||||||
|
const char* format = format_0;
|
||||||
|
IM_ASSERT(IM_IMSTR_LENGTH(format_p) < IM_ARRAYSIZE(format_0));
|
||||||
|
ImStrncpy(format_0, format_p, IM_ARRAYSIZE(format_0));
|
||||||
|
|
||||||
|
if (format_p.Empty())
|
||||||
format = DataTypeGetInfo(data_type)->PrintFmt;
|
format = DataTypeGetInfo(data_type)->PrintFmt;
|
||||||
|
|
||||||
char buf[64];
|
char buf[64];
|
||||||
@ -3422,10 +3442,10 @@ bool ImGui::InputScalar(ImStrv label, ImGuiDataType data_type, void* p_data, con
|
|||||||
EndDisabled();
|
EndDisabled();
|
||||||
|
|
||||||
const char* label_end = FindRenderedTextEnd(label);
|
const char* label_end = FindRenderedTextEnd(label);
|
||||||
if (label != label_end)
|
if (label.Begin != label_end)
|
||||||
{
|
{
|
||||||
SameLine(0, style.ItemInnerSpacing.x);
|
SameLine(0, style.ItemInnerSpacing.x);
|
||||||
TextEx(label, label_end);
|
TextEx(ImStrv(label.Begin, label_end));
|
||||||
}
|
}
|
||||||
style.FramePadding = backup_frame_padding;
|
style.FramePadding = backup_frame_padding;
|
||||||
|
|
||||||
@ -3468,10 +3488,10 @@ bool ImGui::InputScalarN(ImStrv label, ImGuiDataType data_type, void* p_data, in
|
|||||||
PopID();
|
PopID();
|
||||||
|
|
||||||
const char* label_end = FindRenderedTextEnd(label);
|
const char* label_end = FindRenderedTextEnd(label);
|
||||||
if (label != label_end)
|
if (label.Begin != label_end)
|
||||||
{
|
{
|
||||||
SameLine(0.0f, g.Style.ItemInnerSpacing.x);
|
SameLine(0.0f, g.Style.ItemInnerSpacing.x);
|
||||||
TextEx(label, label_end);
|
TextEx(ImStrv(label.Begin, label_end));
|
||||||
}
|
}
|
||||||
|
|
||||||
EndGroup();
|
EndGroup();
|
||||||
@ -3770,10 +3790,10 @@ void ImGuiInputTextCallbackData::DeleteChars(int pos, int bytes_count)
|
|||||||
BufTextLen -= bytes_count;
|
BufTextLen -= bytes_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImGuiInputTextCallbackData::InsertChars(int pos, const char* new_text, const char* new_text_end)
|
void ImGuiInputTextCallbackData::InsertChars(int pos, ImStrv new_text)
|
||||||
{
|
{
|
||||||
const bool is_resizable = (Flags & ImGuiInputTextFlags_CallbackResize) != 0;
|
const bool is_resizable = (Flags & ImGuiInputTextFlags_CallbackResize) != 0;
|
||||||
const int new_text_len = new_text_end ? (int)(new_text_end - new_text) : (int)strlen(new_text);
|
const int new_text_len = (int)IM_IMSTR_LENGTH(new_text);
|
||||||
if (new_text_len + BufTextLen >= BufSize)
|
if (new_text_len + BufTextLen >= BufSize)
|
||||||
{
|
{
|
||||||
if (!is_resizable)
|
if (!is_resizable)
|
||||||
@ -3792,7 +3812,8 @@ void ImGuiInputTextCallbackData::InsertChars(int pos, const char* new_text, cons
|
|||||||
|
|
||||||
if (BufTextLen != pos)
|
if (BufTextLen != pos)
|
||||||
memmove(Buf + pos + new_text_len, Buf + pos, (size_t)(BufTextLen - pos));
|
memmove(Buf + pos + new_text_len, Buf + pos, (size_t)(BufTextLen - pos));
|
||||||
memcpy(Buf + pos, new_text, (size_t)new_text_len * sizeof(char));
|
if (new_text_len > 0)
|
||||||
|
memcpy(Buf + pos, new_text.Begin, (size_t)new_text_len * sizeof(char));
|
||||||
Buf[BufTextLen + new_text_len] = '\0';
|
Buf[BufTextLen + new_text_len] = '\0';
|
||||||
|
|
||||||
if (CursorPos >= pos)
|
if (CursorPos >= pos)
|
||||||
@ -3925,7 +3946,7 @@ bool ImGui::InputTextEx(ImStrv label, ImStrv hint, char* buf, int buf_size, cons
|
|||||||
if (is_multiline) // Open group before calling GetID() because groups tracks id created within their scope (including the scrollbar)
|
if (is_multiline) // Open group before calling GetID() because groups tracks id created within their scope (including the scrollbar)
|
||||||
BeginGroup();
|
BeginGroup();
|
||||||
const ImGuiID id = window->GetID(label);
|
const ImGuiID id = window->GetID(label);
|
||||||
const ImVec2 label_size = CalcTextSize(label, NULL, true);
|
const ImVec2 label_size = CalcTextSize(label, true);
|
||||||
const ImVec2 frame_size = CalcItemSize(size_arg, CalcItemWidth(), (is_multiline ? g.FontSize * 8.0f : label_size.y) + style.FramePadding.y * 2.0f); // Arbitrary default of 8 lines high for multi-line
|
const ImVec2 frame_size = CalcItemSize(size_arg, CalcItemWidth(), (is_multiline ? g.FontSize * 8.0f : label_size.y) + style.FramePadding.y * 2.0f); // Arbitrary default of 8 lines high for multi-line
|
||||||
const ImVec2 total_size = ImVec2(frame_size.x + (label_size.x > 0.0f ? style.ItemInnerSpacing.x + label_size.x : 0.0f), frame_size.y);
|
const ImVec2 total_size = ImVec2(frame_size.x + (label_size.x > 0.0f ? style.ItemInnerSpacing.x + label_size.x : 0.0f), frame_size.y);
|
||||||
|
|
||||||
@ -4103,7 +4124,7 @@ bool ImGui::InputTextEx(ImStrv label, ImStrv hint, char* buf, int buf_size, cons
|
|||||||
|
|
||||||
// Select the buffer to render.
|
// Select the buffer to render.
|
||||||
const bool buf_display_from_state = (render_cursor || render_selection || g.ActiveId == id) && !is_readonly && state && state->TextAIsValid;
|
const bool buf_display_from_state = (render_cursor || render_selection || g.ActiveId == id) && !is_readonly && state && state->TextAIsValid;
|
||||||
const bool is_displaying_hint = (hint != NULL && (buf_display_from_state ? state->TextA.Data : buf)[0] == 0);
|
const bool is_displaying_hint = (!hint.Empty() && (buf_display_from_state ? state->TextA.Data : buf)[0] == 0);
|
||||||
|
|
||||||
// Password pushes a temporary font with only a fallback glyph
|
// Password pushes a temporary font with only a fallback glyph
|
||||||
if (is_password && !is_displaying_hint)
|
if (is_password && !is_displaying_hint)
|
||||||
@ -4336,16 +4357,17 @@ bool ImGui::InputTextEx(ImStrv label, ImStrv hint, char* buf, int buf_size, cons
|
|||||||
}
|
}
|
||||||
else if (is_paste)
|
else if (is_paste)
|
||||||
{
|
{
|
||||||
if (const char* clipboard = GetClipboardText())
|
if (ImStrv clipboard = GetClipboardText())
|
||||||
{
|
{
|
||||||
// Filter pasted buffer
|
// Filter pasted buffer
|
||||||
const int clipboard_len = (int)strlen(clipboard);
|
IM_IMSTR_ENSURE_HAS_END(clipboard);
|
||||||
|
const int clipboard_len = (int)IM_IMSTR_LENGTH(clipboard);
|
||||||
ImWchar* clipboard_filtered = (ImWchar*)IM_ALLOC((clipboard_len + 1) * sizeof(ImWchar));
|
ImWchar* clipboard_filtered = (ImWchar*)IM_ALLOC((clipboard_len + 1) * sizeof(ImWchar));
|
||||||
int clipboard_filtered_len = 0;
|
int clipboard_filtered_len = 0;
|
||||||
for (const char* s = clipboard; *s; )
|
for (const char* s = clipboard.Begin; *s; )
|
||||||
{
|
{
|
||||||
unsigned int c;
|
unsigned int c;
|
||||||
s += ImTextCharFromUtf8(&c, s, NULL);
|
s += ImTextCharFromUtf8(&c, s, clipboard.End);
|
||||||
if (c == 0)
|
if (c == 0)
|
||||||
break;
|
break;
|
||||||
if (!InputTextFilterCharacter(&c, flags, callback, callback_user_data, ImGuiInputSource_Clipboard))
|
if (!InputTextFilterCharacter(&c, flags, callback, callback_user_data, ImGuiInputSource_Clipboard))
|
||||||
@ -4548,8 +4570,9 @@ bool ImGui::InputTextEx(ImStrv label, ImStrv hint, char* buf, int buf_size, cons
|
|||||||
const char* buf_display_end = NULL; // We have specialized paths below for setting the length
|
const char* buf_display_end = NULL; // We have specialized paths below for setting the length
|
||||||
if (is_displaying_hint)
|
if (is_displaying_hint)
|
||||||
{
|
{
|
||||||
buf_display = hint;
|
IM_IMSTR_ENSURE_HAS_END(hint);
|
||||||
buf_display_end = hint + strlen(hint);
|
buf_display = hint.Begin;
|
||||||
|
buf_display_end = hint.End;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Render text. We currently only render selection when the widget is active or while scrolling.
|
// Render text. We currently only render selection when the widget is active or while scrolling.
|
||||||
@ -4696,7 +4719,7 @@ bool ImGui::InputTextEx(ImStrv label, ImStrv hint, char* buf, int buf_size, cons
|
|||||||
if (is_multiline || (buf_display_end - buf_display) < buf_display_max_length)
|
if (is_multiline || (buf_display_end - buf_display) < buf_display_max_length)
|
||||||
{
|
{
|
||||||
ImU32 col = GetColorU32(is_displaying_hint ? ImGuiCol_TextDisabled : ImGuiCol_Text);
|
ImU32 col = GetColorU32(is_displaying_hint ? ImGuiCol_TextDisabled : ImGuiCol_Text);
|
||||||
draw_window->DrawList->AddText(g.Font, g.FontSize, draw_pos - draw_scroll, col, buf_display, buf_display_end, 0.0f, is_multiline ? NULL : &clip_rect);
|
draw_window->DrawList->AddText(g.Font, g.FontSize, draw_pos - draw_scroll, col, ImStrv(buf_display, buf_display_end), 0.0f, is_multiline ? NULL : &clip_rect);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw blinking cursor
|
// Draw blinking cursor
|
||||||
@ -4731,7 +4754,7 @@ bool ImGui::InputTextEx(ImStrv label, ImStrv hint, char* buf, int buf_size, cons
|
|||||||
if (is_multiline || (buf_display_end - buf_display) < buf_display_max_length)
|
if (is_multiline || (buf_display_end - buf_display) < buf_display_max_length)
|
||||||
{
|
{
|
||||||
ImU32 col = GetColorU32(is_displaying_hint ? ImGuiCol_TextDisabled : ImGuiCol_Text);
|
ImU32 col = GetColorU32(is_displaying_hint ? ImGuiCol_TextDisabled : ImGuiCol_Text);
|
||||||
draw_window->DrawList->AddText(g.Font, g.FontSize, draw_pos, col, buf_display, buf_display_end, 0.0f, is_multiline ? NULL : &clip_rect);
|
draw_window->DrawList->AddText(g.Font, g.FontSize, draw_pos, col, ImStrv(buf_display, buf_display_end), 0.0f, is_multiline ? NULL : &clip_rect);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4763,7 +4786,7 @@ bool ImGui::InputTextEx(ImStrv label, ImStrv hint, char* buf, int buf_size, cons
|
|||||||
if (g.LogEnabled && (!is_password || is_displaying_hint))
|
if (g.LogEnabled && (!is_password || is_displaying_hint))
|
||||||
{
|
{
|
||||||
LogSetNextTextDecoration("{", "}");
|
LogSetNextTextDecoration("{", "}");
|
||||||
LogRenderedText(&draw_pos, buf_display, buf_display_end);
|
LogRenderedText(&draw_pos, ImStrv(buf_display, buf_display_end));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (label_size.x > 0)
|
if (label_size.x > 0)
|
||||||
@ -4982,9 +5005,9 @@ bool ImGui::ColorEdit4(ImStrv label, float col[4], ImGuiColorEditFlags flags)
|
|||||||
if (BeginPopup("picker"))
|
if (BeginPopup("picker"))
|
||||||
{
|
{
|
||||||
picker_active_window = g.CurrentWindow;
|
picker_active_window = g.CurrentWindow;
|
||||||
if (label != label_display_end)
|
if (label.Begin != label_display_end)
|
||||||
{
|
{
|
||||||
TextEx(label, label_display_end);
|
TextEx(ImStrv(label.Begin, label_display_end));
|
||||||
Spacing();
|
Spacing();
|
||||||
}
|
}
|
||||||
ImGuiColorEditFlags picker_flags_to_forward = ImGuiColorEditFlags_DataTypeMask_ | ImGuiColorEditFlags_PickerMask_ | ImGuiColorEditFlags_InputMask_ | ImGuiColorEditFlags_HDR | ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_AlphaBar;
|
ImGuiColorEditFlags picker_flags_to_forward = ImGuiColorEditFlags_DataTypeMask_ | ImGuiColorEditFlags_PickerMask_ | ImGuiColorEditFlags_InputMask_ | ImGuiColorEditFlags_HDR | ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_AlphaBar;
|
||||||
@ -4995,10 +5018,10 @@ bool ImGui::ColorEdit4(ImStrv label, float col[4], ImGuiColorEditFlags flags)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (label != label_display_end && !(flags & ImGuiColorEditFlags_NoLabel))
|
if (label.Begin != label_display_end && !(flags & ImGuiColorEditFlags_NoLabel))
|
||||||
{
|
{
|
||||||
SameLine(0.0f, style.ItemInnerSpacing.x);
|
SameLine(0.0f, style.ItemInnerSpacing.x);
|
||||||
TextEx(label, label_display_end);
|
TextEx(ImStrv(label.Begin, label_display_end));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert back
|
// Convert back
|
||||||
@ -5241,11 +5264,11 @@ bool ImGui::ColorPicker4(ImStrv label, float col[4], ImGuiColorEditFlags flags,
|
|||||||
if (!(flags & ImGuiColorEditFlags_NoLabel))
|
if (!(flags & ImGuiColorEditFlags_NoLabel))
|
||||||
{
|
{
|
||||||
const char* label_display_end = FindRenderedTextEnd(label);
|
const char* label_display_end = FindRenderedTextEnd(label);
|
||||||
if (label != label_display_end)
|
if (label.Begin != label_display_end)
|
||||||
{
|
{
|
||||||
if ((flags & ImGuiColorEditFlags_NoSidePreview))
|
if ((flags & ImGuiColorEditFlags_NoSidePreview))
|
||||||
SameLine(0, style.ItemInnerSpacing.x);
|
SameLine(0, style.ItemInnerSpacing.x);
|
||||||
TextEx(label, label_display_end);
|
TextEx(ImStrv(label.Begin, label_display_end));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5561,10 +5584,10 @@ void ImGui::ColorTooltip(ImStrv text, const float* col, ImGuiColorEditFlags flag
|
|||||||
ImGuiContext& g = *GImGui;
|
ImGuiContext& g = *GImGui;
|
||||||
|
|
||||||
BeginTooltipEx(ImGuiTooltipFlags_OverridePreviousTooltip, ImGuiWindowFlags_None);
|
BeginTooltipEx(ImGuiTooltipFlags_OverridePreviousTooltip, ImGuiWindowFlags_None);
|
||||||
const char* text_end = text ? FindRenderedTextEnd(text, NULL) : text;
|
const char* text_end = text ? FindRenderedTextEnd(text) : text.Begin;
|
||||||
if (text_end > text)
|
if (text_end > text.Begin)
|
||||||
{
|
{
|
||||||
TextEx(text, text_end);
|
TextEx(ImStrv(text.Begin, text_end));
|
||||||
Separator();
|
Separator();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5717,7 +5740,7 @@ bool ImGui::TreeNode(ImStrv label)
|
|||||||
ImGuiWindow* window = GetCurrentWindow();
|
ImGuiWindow* window = GetCurrentWindow();
|
||||||
if (window->SkipItems)
|
if (window->SkipItems)
|
||||||
return false;
|
return false;
|
||||||
return TreeNodeBehavior(window->GetID(label), 0, label, NULL);
|
return TreeNodeBehavior(window->GetID(label), 0, label);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ImGui::TreeNodeV(ImStrv str_id, const char* fmt, va_list args)
|
bool ImGui::TreeNodeV(ImStrv str_id, const char* fmt, va_list args)
|
||||||
@ -5736,7 +5759,7 @@ bool ImGui::TreeNodeEx(ImStrv label, ImGuiTreeNodeFlags flags)
|
|||||||
if (window->SkipItems)
|
if (window->SkipItems)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return TreeNodeBehavior(window->GetID(label), flags, label, NULL);
|
return TreeNodeBehavior(window->GetID(label), flags, label);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ImGui::TreeNodeEx(ImStrv str_id, ImGuiTreeNodeFlags flags, const char* fmt, ...)
|
bool ImGui::TreeNodeEx(ImStrv str_id, ImGuiTreeNodeFlags flags, const char* fmt, ...)
|
||||||
@ -5765,7 +5788,7 @@ bool ImGui::TreeNodeExV(ImStrv str_id, ImGuiTreeNodeFlags flags, const char* fmt
|
|||||||
|
|
||||||
ImGuiContext& g = *GImGui;
|
ImGuiContext& g = *GImGui;
|
||||||
const char* label_end = g.TempBuffer + ImFormatStringV(g.TempBuffer, IM_ARRAYSIZE(g.TempBuffer), fmt, args);
|
const char* label_end = g.TempBuffer + ImFormatStringV(g.TempBuffer, IM_ARRAYSIZE(g.TempBuffer), fmt, args);
|
||||||
return TreeNodeBehavior(window->GetID(str_id), flags, g.TempBuffer, label_end);
|
return TreeNodeBehavior(window->GetID(str_id), flags, ImStrv(g.TempBuffer, label_end));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ImGui::TreeNodeExV(const void* ptr_id, ImGuiTreeNodeFlags flags, const char* fmt, va_list args)
|
bool ImGui::TreeNodeExV(const void* ptr_id, ImGuiTreeNodeFlags flags, const char* fmt, va_list args)
|
||||||
@ -5776,7 +5799,7 @@ bool ImGui::TreeNodeExV(const void* ptr_id, ImGuiTreeNodeFlags flags, const char
|
|||||||
|
|
||||||
ImGuiContext& g = *GImGui;
|
ImGuiContext& g = *GImGui;
|
||||||
const char* label_end = g.TempBuffer + ImFormatStringV(g.TempBuffer, IM_ARRAYSIZE(g.TempBuffer), fmt, args);
|
const char* label_end = g.TempBuffer + ImFormatStringV(g.TempBuffer, IM_ARRAYSIZE(g.TempBuffer), fmt, args);
|
||||||
return TreeNodeBehavior(window->GetID(ptr_id), flags, g.TempBuffer, label_end);
|
return TreeNodeBehavior(window->GetID(ptr_id), flags, ImStrv(g.TempBuffer, label_end));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ImGui::TreeNodeBehaviorIsOpen(ImGuiID id, ImGuiTreeNodeFlags flags)
|
bool ImGui::TreeNodeBehaviorIsOpen(ImGuiID id, ImGuiTreeNodeFlags flags)
|
||||||
@ -5825,7 +5848,7 @@ bool ImGui::TreeNodeBehaviorIsOpen(ImGuiID id, ImGuiTreeNodeFlags flags)
|
|||||||
return is_open;
|
return is_open;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* label, const char* label_end)
|
bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, ImStrv label)
|
||||||
{
|
{
|
||||||
ImGuiWindow* window = GetCurrentWindow();
|
ImGuiWindow* window = GetCurrentWindow();
|
||||||
if (window->SkipItems)
|
if (window->SkipItems)
|
||||||
@ -5836,9 +5859,9 @@ bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* l
|
|||||||
const bool display_frame = (flags & ImGuiTreeNodeFlags_Framed) != 0;
|
const bool display_frame = (flags & ImGuiTreeNodeFlags_Framed) != 0;
|
||||||
const ImVec2 padding = (display_frame || (flags & ImGuiTreeNodeFlags_FramePadding)) ? style.FramePadding : ImVec2(style.FramePadding.x, ImMin(window->DC.CurrLineTextBaseOffset, style.FramePadding.y));
|
const ImVec2 padding = (display_frame || (flags & ImGuiTreeNodeFlags_FramePadding)) ? style.FramePadding : ImVec2(style.FramePadding.x, ImMin(window->DC.CurrLineTextBaseOffset, style.FramePadding.y));
|
||||||
|
|
||||||
if (!label_end)
|
if (!label.End)
|
||||||
label_end = FindRenderedTextEnd(label);
|
label.End = FindRenderedTextEnd(label);
|
||||||
const ImVec2 label_size = CalcTextSize(label, label_end, false);
|
const ImVec2 label_size = CalcTextSize(label, false);
|
||||||
|
|
||||||
// We vertically grow up to current line height up the typical widget height.
|
// We vertically grow up to current line height up the typical widget height.
|
||||||
const float frame_height = ImMax(ImMin(window->DC.CurrLineSize.y, g.FontSize + style.FramePadding.y * 2), label_size.y + padding.y * 2);
|
const float frame_height = ImMax(ImMin(window->DC.CurrLineSize.y, g.FontSize + style.FramePadding.y * 2), label_size.y + padding.y * 2);
|
||||||
@ -5986,7 +6009,7 @@ bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* l
|
|||||||
|
|
||||||
if (g.LogEnabled)
|
if (g.LogEnabled)
|
||||||
LogSetNextTextDecoration("###", "###");
|
LogSetNextTextDecoration("###", "###");
|
||||||
RenderTextClipped(text_pos, frame_bb.Max, label, label_end, &label_size);
|
RenderTextClipped(text_pos, frame_bb.Max, label, &label_size);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -6003,7 +6026,7 @@ bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* l
|
|||||||
RenderArrow(window->DrawList, ImVec2(text_pos.x - text_offset_x + padding.x, text_pos.y + g.FontSize * 0.15f), text_col, is_open ? ImGuiDir_Down : ImGuiDir_Right, 0.70f);
|
RenderArrow(window->DrawList, ImVec2(text_pos.x - text_offset_x + padding.x, text_pos.y + g.FontSize * 0.15f), text_col, is_open ? ImGuiDir_Down : ImGuiDir_Right, 0.70f);
|
||||||
if (g.LogEnabled)
|
if (g.LogEnabled)
|
||||||
LogSetNextTextDecoration(">", NULL);
|
LogSetNextTextDecoration(">", NULL);
|
||||||
RenderText(text_pos, label, label_end, false);
|
RenderText(text_pos, label, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_open && !(flags & ImGuiTreeNodeFlags_NoTreePushOnOpen))
|
if (is_open && !(flags & ImGuiTreeNodeFlags_NoTreePushOnOpen))
|
||||||
@ -6146,7 +6169,7 @@ bool ImGui::Selectable(ImStrv label, bool selected, ImGuiSelectableFlags flags,
|
|||||||
|
|
||||||
// Submit label or explicit size to ItemSize(), whereas ItemAdd() will submit a larger/spanning rectangle.
|
// Submit label or explicit size to ItemSize(), whereas ItemAdd() will submit a larger/spanning rectangle.
|
||||||
ImGuiID id = window->GetID(label);
|
ImGuiID id = window->GetID(label);
|
||||||
ImVec2 label_size = CalcTextSize(label, NULL, true);
|
ImVec2 label_size = CalcTextSize(label, true);
|
||||||
ImVec2 size(size_arg.x != 0.0f ? size_arg.x : label_size.x, size_arg.y != 0.0f ? size_arg.y : label_size.y);
|
ImVec2 size(size_arg.x != 0.0f ? size_arg.x : label_size.x, size_arg.y != 0.0f ? size_arg.y : label_size.y);
|
||||||
ImVec2 pos = window->DC.CursorPos;
|
ImVec2 pos = window->DC.CursorPos;
|
||||||
pos.y += window->DC.CurrLineTextBaseOffset;
|
pos.y += window->DC.CurrLineTextBaseOffset;
|
||||||
@ -6267,7 +6290,7 @@ bool ImGui::Selectable(ImStrv label, bool selected, ImGuiSelectableFlags flags,
|
|||||||
else if (span_all_columns && g.CurrentTable)
|
else if (span_all_columns && g.CurrentTable)
|
||||||
TablePopBackgroundChannel();
|
TablePopBackgroundChannel();
|
||||||
|
|
||||||
RenderTextClipped(text_min, text_max, label, NULL, &label_size, style.SelectableTextAlign, &bb);
|
RenderTextClipped(text_min, text_max, label, &label_size, style.SelectableTextAlign, &bb);
|
||||||
|
|
||||||
// Automatically close popups
|
// Automatically close popups
|
||||||
if (pressed && (window->Flags & ImGuiWindowFlags_Popup) && !(flags & ImGuiSelectableFlags_DontClosePopups) && !(g.LastItemData.InFlags & ImGuiItemFlags_SelectableDontClosePopup))
|
if (pressed && (window->Flags & ImGuiWindowFlags_Popup) && !(flags & ImGuiSelectableFlags_DontClosePopups) && !(g.LastItemData.InFlags & ImGuiItemFlags_SelectableDontClosePopup))
|
||||||
@ -6309,7 +6332,7 @@ bool ImGui::BeginListBox(ImStrv label, const ImVec2& size_arg)
|
|||||||
|
|
||||||
const ImGuiStyle& style = g.Style;
|
const ImGuiStyle& style = g.Style;
|
||||||
const ImGuiID id = GetID(label);
|
const ImGuiID id = GetID(label);
|
||||||
const ImVec2 label_size = CalcTextSize(label, NULL, true);
|
const ImVec2 label_size = CalcTextSize(label, true);
|
||||||
|
|
||||||
// Size default to hold ~7.25 items.
|
// Size default to hold ~7.25 items.
|
||||||
// Fractional number of items helps seeing that we can scroll down/up without looking at scrollbar.
|
// Fractional number of items helps seeing that we can scroll down/up without looking at scrollbar.
|
||||||
@ -6439,7 +6462,7 @@ int ImGui::PlotEx(ImGuiPlotType plot_type, ImStrv label, float (*values_getter)(
|
|||||||
const ImGuiStyle& style = g.Style;
|
const ImGuiStyle& style = g.Style;
|
||||||
const ImGuiID id = window->GetID(label);
|
const ImGuiID id = window->GetID(label);
|
||||||
|
|
||||||
const ImVec2 label_size = CalcTextSize(label, NULL, true);
|
const ImVec2 label_size = CalcTextSize(label, true);
|
||||||
if (frame_size.x == 0.0f)
|
if (frame_size.x == 0.0f)
|
||||||
frame_size.x = CalcItemWidth();
|
frame_size.x = CalcItemWidth();
|
||||||
if (frame_size.y == 0.0f)
|
if (frame_size.y == 0.0f)
|
||||||
@ -6537,7 +6560,7 @@ int ImGui::PlotEx(ImGuiPlotType plot_type, ImStrv label, float (*values_getter)(
|
|||||||
|
|
||||||
// Text overlay
|
// Text overlay
|
||||||
if (overlay_text)
|
if (overlay_text)
|
||||||
RenderTextClipped(ImVec2(frame_bb.Min.x, frame_bb.Min.y + style.FramePadding.y), frame_bb.Max, overlay_text, NULL, NULL, ImVec2(0.5f, 0.0f));
|
RenderTextClipped(ImVec2(frame_bb.Min.x, frame_bb.Min.y + style.FramePadding.y), frame_bb.Max, overlay_text, NULL, ImVec2(0.5f, 0.0f));
|
||||||
|
|
||||||
if (label_size.x > 0.0f)
|
if (label_size.x > 0.0f)
|
||||||
RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, inner_bb.Min.y), label);
|
RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, inner_bb.Min.y), label);
|
||||||
@ -6593,17 +6616,17 @@ void ImGui::PlotHistogram(ImStrv label, float (*values_getter)(void* data, int i
|
|||||||
|
|
||||||
void ImGui::Value(ImStrv prefix, bool b)
|
void ImGui::Value(ImStrv prefix, bool b)
|
||||||
{
|
{
|
||||||
Text("%s: %s", prefix, (b ? "true" : "false"));
|
Text("%.*s: %s", (int)IM_IMSTR_LENGTH(prefix), prefix.Begin, (b ? "true" : "false"));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImGui::Value(ImStrv prefix, int v)
|
void ImGui::Value(ImStrv prefix, int v)
|
||||||
{
|
{
|
||||||
Text("%s: %d", prefix, v);
|
Text("%.*s: %d", (int)IM_IMSTR_LENGTH(prefix), prefix.Begin, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImGui::Value(ImStrv prefix, unsigned int v)
|
void ImGui::Value(ImStrv prefix, unsigned int v)
|
||||||
{
|
{
|
||||||
Text("%s: %d", prefix, v);
|
Text("%.*s: %d", (int)IM_IMSTR_LENGTH(prefix), prefix.Begin, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImGui::Value(ImStrv prefix, float v, ImStrv float_format)
|
void ImGui::Value(ImStrv prefix, float v, ImStrv float_format)
|
||||||
@ -6611,12 +6634,12 @@ void ImGui::Value(ImStrv prefix, float v, ImStrv float_format)
|
|||||||
if (float_format)
|
if (float_format)
|
||||||
{
|
{
|
||||||
char fmt[64];
|
char fmt[64];
|
||||||
ImFormatString(fmt, IM_ARRAYSIZE(fmt), "%%s: %s", float_format);
|
ImFormatString(fmt, IM_ARRAYSIZE(fmt), "%%.*s: %.*s", (int)IM_IMSTR_LENGTH(float_format), float_format.Begin);
|
||||||
Text(fmt, prefix, v);
|
Text(fmt, (int)IM_IMSTR_LENGTH(prefix), prefix.Begin, v);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Text("%s: %.3f", prefix, v);
|
Text("%.*s: %.3f", (int)IM_IMSTR_LENGTH(prefix), prefix.Begin, v);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -6871,7 +6894,7 @@ bool ImGui::BeginMenuEx(ImStrv label, ImStrv icon, bool enabled)
|
|||||||
// Tag menu as used. Next time BeginMenu() with same ID is called it will append to existing menu
|
// Tag menu as used. Next time BeginMenu() with same ID is called it will append to existing menu
|
||||||
g.MenusIdSubmittedThisFrame.push_back(id);
|
g.MenusIdSubmittedThisFrame.push_back(id);
|
||||||
|
|
||||||
ImVec2 label_size = CalcTextSize(label, NULL, true);
|
ImVec2 label_size = CalcTextSize(label, true);
|
||||||
|
|
||||||
// Odd hack to allow hovering across menus of a same menu-set (otherwise we wouldn't be able to hover parent without always being a Child window)
|
// Odd hack to allow hovering across menus of a same menu-set (otherwise we wouldn't be able to hover parent without always being a Child window)
|
||||||
const bool menuset_is_open = IsRootOfOpenMenuSet();
|
const bool menuset_is_open = IsRootOfOpenMenuSet();
|
||||||
@ -7017,7 +7040,7 @@ bool ImGui::BeginMenuEx(ImStrv label, ImStrv icon, bool enabled)
|
|||||||
return menu_is_open;
|
return menu_is_open;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ImGui::BeginMenu(const char* label, bool enabled)
|
bool ImGui::BeginMenu(ImStrv label, bool enabled)
|
||||||
{
|
{
|
||||||
return BeginMenuEx(label, NULL, enabled);
|
return BeginMenuEx(label, NULL, enabled);
|
||||||
}
|
}
|
||||||
@ -7048,7 +7071,7 @@ bool ImGui::MenuItemEx(ImStrv label, ImStrv icon, ImStrv shortcut, bool selected
|
|||||||
ImGuiContext& g = *GImGui;
|
ImGuiContext& g = *GImGui;
|
||||||
ImGuiStyle& style = g.Style;
|
ImGuiStyle& style = g.Style;
|
||||||
ImVec2 pos = window->DC.CursorPos;
|
ImVec2 pos = window->DC.CursorPos;
|
||||||
ImVec2 label_size = CalcTextSize(label, NULL, true);
|
ImVec2 label_size = CalcTextSize(label, true);
|
||||||
|
|
||||||
const bool menuset_is_open = IsRootOfOpenMenuSet();
|
const bool menuset_is_open = IsRootOfOpenMenuSet();
|
||||||
ImGuiWindow* backed_nav_window = g.NavWindow;
|
ImGuiWindow* backed_nav_window = g.NavWindow;
|
||||||
@ -7082,8 +7105,8 @@ bool ImGui::MenuItemEx(ImStrv label, ImStrv icon, ImStrv shortcut, bool selected
|
|||||||
// Menu item inside a vertical menu
|
// Menu item inside a vertical menu
|
||||||
// (In a typical menu window where all items are BeginMenu() or MenuItem() calls, extra_w will always be 0.0f.
|
// (In a typical menu window where all items are BeginMenu() or MenuItem() calls, extra_w will always be 0.0f.
|
||||||
// Only when they are other items sticking out we're going to add spacing, yet only register minimum width into the layout system.
|
// Only when they are other items sticking out we're going to add spacing, yet only register minimum width into the layout system.
|
||||||
float icon_w = (icon && icon[0]) ? CalcTextSize(icon, NULL).x : 0.0f;
|
float icon_w = (icon && icon[0]) ? CalcTextSize(icon).x : 0.0f;
|
||||||
float shortcut_w = (shortcut && shortcut[0]) ? CalcTextSize(shortcut, NULL).x : 0.0f;
|
float shortcut_w = (shortcut && shortcut[0]) ? CalcTextSize(shortcut).x : 0.0f;
|
||||||
float checkmark_w = IM_FLOOR(g.FontSize * 1.20f);
|
float checkmark_w = IM_FLOOR(g.FontSize * 1.20f);
|
||||||
float min_w = window->DC.MenuColumns.DeclColumns(icon_w, label_size.x, shortcut_w, checkmark_w); // Feedback for next frame
|
float min_w = window->DC.MenuColumns.DeclColumns(icon_w, label_size.x, shortcut_w, checkmark_w); // Feedback for next frame
|
||||||
float stretch_w = ImMax(0.0f, GetContentRegionAvail().x - min_w);
|
float stretch_w = ImMax(0.0f, GetContentRegionAvail().x - min_w);
|
||||||
@ -7094,7 +7117,7 @@ bool ImGui::MenuItemEx(ImStrv label, ImStrv icon, ImStrv shortcut, bool selected
|
|||||||
if (shortcut_w > 0.0f)
|
if (shortcut_w > 0.0f)
|
||||||
{
|
{
|
||||||
PushStyleColor(ImGuiCol_Text, style.Colors[ImGuiCol_TextDisabled]);
|
PushStyleColor(ImGuiCol_Text, style.Colors[ImGuiCol_TextDisabled]);
|
||||||
RenderText(pos + ImVec2(offsets->OffsetShortcut + stretch_w, 0.0f), shortcut, NULL, false);
|
RenderText(pos + ImVec2(offsets->OffsetShortcut + stretch_w, 0.0f), shortcut, false);
|
||||||
PopStyleColor();
|
PopStyleColor();
|
||||||
}
|
}
|
||||||
if (selected)
|
if (selected)
|
||||||
@ -7962,7 +7985,8 @@ bool ImGui::TabItemEx(ImGuiTabBar* tab_bar, ImStrv label, bool* p_open, ImGui
|
|||||||
|
|
||||||
// Append name with zero-terminator
|
// Append name with zero-terminator
|
||||||
tab->NameOffset = (ImS32)tab_bar->TabsNames.size();
|
tab->NameOffset = (ImS32)tab_bar->TabsNames.size();
|
||||||
tab_bar->TabsNames.append(label, label + strlen(label) + 1);
|
tab_bar->TabsNames.append(label);
|
||||||
|
tab_bar->TabsNames.append(ImStrv("\0", 1));
|
||||||
|
|
||||||
// Update selected tab
|
// Update selected tab
|
||||||
if (tab_appearing && (tab_bar->Flags & ImGuiTabBarFlags_AutoSelectNewTabs) && tab_bar->NextSelectedTabId == 0)
|
if (tab_appearing && (tab_bar->Flags & ImGuiTabBarFlags_AutoSelectNewTabs) && tab_bar->NextSelectedTabId == 0)
|
||||||
@ -8105,7 +8129,7 @@ bool ImGui::TabItemEx(ImGuiTabBar* tab_bar, ImStrv label, bool* p_open, ImGui
|
|||||||
// FIXME: We may want disabled tab to still display the tooltip?
|
// FIXME: We may want disabled tab to still display the tooltip?
|
||||||
if (text_clipped && g.HoveredId == id && !held && g.HoveredIdNotActiveTimer > g.TooltipSlowDelay && IsItemHovered())
|
if (text_clipped && g.HoveredId == id && !held && g.HoveredIdNotActiveTimer > g.TooltipSlowDelay && IsItemHovered())
|
||||||
if (!(tab_bar->Flags & ImGuiTabBarFlags_NoTooltip) && !(tab->Flags & ImGuiTabItemFlags_NoTooltip))
|
if (!(tab_bar->Flags & ImGuiTabBarFlags_NoTooltip) && !(tab->Flags & ImGuiTabItemFlags_NoTooltip))
|
||||||
SetTooltip("%.*s", (int)(FindRenderedTextEnd(label) - label), label);
|
SetTooltip("%.*s", (int)(FindRenderedTextEnd(label) - label.Begin), label.Begin);
|
||||||
|
|
||||||
IM_ASSERT(!is_tab_button || !(tab_bar->SelectedTabId == tab->ID && is_tab_button)); // TabItemButton should not be selected
|
IM_ASSERT(!is_tab_button || !(tab_bar->SelectedTabId == tab->ID && is_tab_button)); // TabItemButton should not be selected
|
||||||
if (is_tab_button)
|
if (is_tab_button)
|
||||||
@ -8132,7 +8156,7 @@ void ImGui::SetTabItemClosed(ImStrv label)
|
|||||||
ImVec2 ImGui::TabItemCalcSize(ImStrv label, bool has_close_button)
|
ImVec2 ImGui::TabItemCalcSize(ImStrv label, bool has_close_button)
|
||||||
{
|
{
|
||||||
ImGuiContext& g = *GImGui;
|
ImGuiContext& g = *GImGui;
|
||||||
ImVec2 label_size = CalcTextSize(label, NULL, true);
|
ImVec2 label_size = CalcTextSize(label, true);
|
||||||
ImVec2 size = ImVec2(label_size.x + g.Style.FramePadding.x, label_size.y + g.Style.FramePadding.y * 2.0f);
|
ImVec2 size = ImVec2(label_size.x + g.Style.FramePadding.x, label_size.y + g.Style.FramePadding.y * 2.0f);
|
||||||
if (has_close_button)
|
if (has_close_button)
|
||||||
size.x += g.Style.FramePadding.x + (g.Style.ItemInnerSpacing.x + g.FontSize); // We use Y intentionally to fit the close button circle.
|
size.x += g.Style.FramePadding.x + (g.Style.ItemInnerSpacing.x + g.FontSize); // We use Y intentionally to fit the close button circle.
|
||||||
@ -8171,7 +8195,7 @@ void ImGui::TabItemBackground(ImDrawList* draw_list, const ImRect& bb, ImGuiTabI
|
|||||||
void ImGui::TabItemLabelAndCloseButton(ImDrawList* draw_list, const ImRect& bb, ImGuiTabItemFlags flags, ImVec2 frame_padding, ImStrv label, ImGuiID tab_id, ImGuiID close_button_id, bool is_contents_visible, bool* out_just_closed, bool* out_text_clipped)
|
void ImGui::TabItemLabelAndCloseButton(ImDrawList* draw_list, const ImRect& bb, ImGuiTabItemFlags flags, ImVec2 frame_padding, ImStrv label, ImGuiID tab_id, ImGuiID close_button_id, bool is_contents_visible, bool* out_just_closed, bool* out_text_clipped)
|
||||||
{
|
{
|
||||||
ImGuiContext& g = *GImGui;
|
ImGuiContext& g = *GImGui;
|
||||||
ImVec2 label_size = CalcTextSize(label, NULL, true);
|
ImVec2 label_size = CalcTextSize(label, true);
|
||||||
|
|
||||||
if (out_just_closed)
|
if (out_just_closed)
|
||||||
*out_just_closed = false;
|
*out_just_closed = false;
|
||||||
@ -8245,7 +8269,7 @@ void ImGui::TabItemLabelAndCloseButton(ImDrawList* draw_list, const ImRect& bb,
|
|||||||
text_ellipsis_clip_bb.Max.x -= unsaved_marker_visible ? (button_sz * 0.80f) : 0.0f;
|
text_ellipsis_clip_bb.Max.x -= unsaved_marker_visible ? (button_sz * 0.80f) : 0.0f;
|
||||||
ellipsis_max_x = text_pixel_clip_bb.Max.x;
|
ellipsis_max_x = text_pixel_clip_bb.Max.x;
|
||||||
}
|
}
|
||||||
RenderTextEllipsis(draw_list, text_ellipsis_clip_bb.Min, text_ellipsis_clip_bb.Max, text_pixel_clip_bb.Max.x, ellipsis_max_x, label, NULL, &label_size);
|
RenderTextEllipsis(draw_list, text_ellipsis_clip_bb.Min, text_ellipsis_clip_bb.Max, text_pixel_clip_bb.Max.x, ellipsis_max_x, label, &label_size);
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
if (!is_contents_visible)
|
if (!is_contents_visible)
|
||||||
|
Loading…
Reference in New Issue
Block a user