mirror of
https://github.com/ocornut/imgui.git
synced 2026-05-09 21:29:26 +08:00
ImStrv: Step 2 - change ImStrv typedef to struct, perform all other logic conversion.
Squashed commits (initially a commit from rokups + many rework by ocornut. keeping them separate commits made rebasing unnecessarily tricking so merged from 2024/02) ImStrv: many fixes (see details), added imconfig class extension example, added natvis description. ImStrv: rework toward ensuring End is always set to constant can be compile time calculated ImStrv: using length(), fix ambiguous empty() function, fix altered behaviors, removed unused operators. ImStrv: various tweaks and fixes. removed ImGuiTextRange from ImGuiTextFilter, fix test engine hooks, removed constructor only used twice.
This commit is contained in:
@@ -114,6 +114,15 @@
|
||||
//---- ...Or use Dear ImGui's own very basic math operators.
|
||||
//#define IMGUI_DEFINE_MATH_OPERATORS
|
||||
|
||||
//---- Define constructor to convert your string type to ImStrv (which is a non-owning begin/end pair)
|
||||
// This will be inlined as part of ImStrv class declaration.
|
||||
// This has two benefits: you won't need to use .c_str(), if length is already computed it is faster.
|
||||
//#include <string>
|
||||
//#include <string_view>
|
||||
//#define IM_STRV_CLASS_EXTRA ImStrv(const std::string& s) { Begin = s.c_str(); End = Begin + s.length(); }
|
||||
//#define IM_STRV_CLASS_EXTRA ImStrv(const std::string_view& s) { Begin = s.data(); End = Begin + s.length(); }
|
||||
//#define IM_STRV_CLASS_EXTRA ImStrv(const MyString& s) { Begin = s.Data; End = s.end(); }
|
||||
|
||||
//---- Use 32-bit vertex indices (default is 16-bit) is one way to allow large meshes with more than 64K vertices.
|
||||
// Your renderer backend will need to support it (most example renderer backends support both 16/32-bit indices).
|
||||
// Another way to allow large meshes while keeping 16-bit indices is to handle ImDrawCmd::VtxOffset in your renderer.
|
||||
|
||||
@@ -58,6 +58,8 @@ Index of this file:
|
||||
|
||||
*/
|
||||
|
||||
#define IMGUI_HAS_IMSTR
|
||||
|
||||
#pragma once
|
||||
|
||||
// Configuration file with compile-time options
|
||||
@@ -314,9 +316,27 @@ 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.
|
||||
#endif
|
||||
};
|
||||
IM_MSVC_RUNTIME_CHECKS_RESTORE
|
||||
|
||||
typedef const char* ImStrv;
|
||||
// String view (non-owning pair of begin/end pointers, not necessarily zero-terminated)
|
||||
// ImStrv are used as function parameters instead of passing a pair of const char*.
|
||||
struct ImStrv
|
||||
{
|
||||
const char* Begin;
|
||||
const char* End;
|
||||
ImStrv() { Begin = End = NULL; }
|
||||
ImStrv(const char* b) { Begin = b; End = b ? b + strlen(b) : NULL; }
|
||||
ImStrv(const char* b, const char* e){ Begin = b; End = e ? e : b + strlen(b); }
|
||||
inline size_t length() const { return (size_t)(End - Begin); }
|
||||
inline bool empty() const { return Begin == End; } // == "" or == NULL
|
||||
inline operator bool() const { return Begin != NULL; } // return true when valid ("" is valid, NULL construction is not)
|
||||
#ifdef IM_STRV_CLASS_EXTRA
|
||||
IM_STRV_CLASS_EXTRA // Define additional constructor in imconfig.h to convert your string types (e.g. std::string, std::string_view) to ImStrV.
|
||||
#endif
|
||||
// private: bool operator==(ImStrv) { return false; } // [DEBUG] Uncomment to catch undesirable uses of operators
|
||||
// private: bool operator!=(ImStrv) { return false; }
|
||||
};
|
||||
|
||||
IM_MSVC_RUNTIME_CHECKS_RESTORE
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// [SECTION] Texture identifiers (ImTextureID, ImTextureRef)
|
||||
@@ -605,17 +625,19 @@ namespace ImGui
|
||||
// - 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.
|
||||
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(int int_id); // push integer into the ID stack (will hash integer).
|
||||
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(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(int int_id);
|
||||
|
||||
// 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 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();
|
||||
@@ -633,7 +655,7 @@ namespace ImGui
|
||||
// Widgets: Main
|
||||
// - 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.
|
||||
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.y == 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 ArrowButton(ImStrv str_id, ImGuiDir dir); // square button with an arrow shape
|
||||
@@ -1049,7 +1071,8 @@ namespace ImGui
|
||||
IMGUI_API ImGuiStorage* GetStateStorage();
|
||||
|
||||
// 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
|
||||
IMGUI_API ImVec4 ColorConvertU32ToFloat4(ImU32 in);
|
||||
@@ -1132,7 +1155,7 @@ namespace ImGui
|
||||
// - Set io.IniFilename to NULL to load/save manually. Read io.WantSaveIniSettings description about handling .ini saving manually.
|
||||
// - Important: default value "imgui.ini" is relative to current working dir! Most apps will want to lock this to an absolute path (e.g. same path as executables).
|
||||
IMGUI_API void LoadIniSettingsFromDisk(ImStrv ini_filename); // call after CreateContext() and before the first call to NewFrame(). NewFrame() automatically calls LoadIniSettingsFromDisk(io.IniFilename).
|
||||
IMGUI_API void LoadIniSettingsFromMemory(ImStrv ini_data, size_t ini_size= 0); // call after CreateContext() and before the first call to NewFrame() to provide .ini data from your own data source.
|
||||
IMGUI_API void LoadIniSettingsFromMemory(ImStrv ini_data); // call after CreateContext() and before the first call to NewFrame() to provide .ini data from your own data source.
|
||||
IMGUI_API void SaveIniSettingsToDisk(ImStrv ini_filename); // this is automatically called (if io.IniFilename is not empty) a few seconds after any modification that should be reflected in the .ini file (and also by DestroyContext).
|
||||
IMGUI_API const char* SaveIniSettingsToMemory(size_t* out_ini_size = NULL); // return a zero-terminated string with the .ini data which you can save by your own mean. call when io.WantSaveIniSettings is set, then save data by your own mean and clear io.WantSaveIniSettings.
|
||||
|
||||
@@ -2667,8 +2690,9 @@ struct ImGuiInputTextCallbackData
|
||||
// Use those function to benefit from the CallbackResize behaviors. Calling those function reset the selection.
|
||||
IMGUI_API ImGuiInputTextCallbackData();
|
||||
IMGUI_API void DeleteChars(int pos, int bytes_count);
|
||||
IMGUI_API void InsertChars(int pos, const char* text, const char* text_end = NULL);
|
||||
void SelectAll() { SelectionStart = 0; CursorPos = SelectionEnd = BufTextLen; }
|
||||
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 SetSelection(int s, int e) { IM_ASSERT(s >= 0 && s <= BufTextLen); IM_ASSERT(e >= 0 && e <= BufTextLen); SelectionStart = s; CursorPos = SelectionEnd = e; }
|
||||
void ClearSelection() { SelectionStart = SelectionEnd = BufTextLen; }
|
||||
bool HasSelection() const { return SelectionStart != SelectionEnd; }
|
||||
@@ -2701,7 +2725,7 @@ struct ImGuiPayload
|
||||
|
||||
ImGuiPayload() { Clear(); }
|
||||
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 { size_t len = type.length(); return DataFrameCount != -1 && memcmp(DataType, type.Begin, len) == 0 && DataType[len] == 0; }
|
||||
bool IsPreview() const { return Preview; }
|
||||
bool IsDelivery() const { return Delivery; }
|
||||
};
|
||||
@@ -2732,24 +2756,14 @@ struct ImGuiTextFilter
|
||||
{
|
||||
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 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();
|
||||
void Clear() { InputBuf[0] = 0; Build(); }
|
||||
bool IsActive() const { return !Filters.empty(); }
|
||||
|
||||
// [Internal]
|
||||
struct ImGuiTextRange
|
||||
{
|
||||
const char* b;
|
||||
const char* e;
|
||||
|
||||
ImGuiTextRange() { b = e = NULL; }
|
||||
ImGuiTextRange(const char* _b, const char* _e) { b = _b; e = _e; }
|
||||
bool empty() const { return b == e; }
|
||||
IMGUI_API void split(char separator, ImVector<ImGuiTextRange>* out) const;
|
||||
};
|
||||
char InputBuf[256];
|
||||
ImVector<ImGuiTextRange>Filters;
|
||||
ImVector<ImStrv> Filters;
|
||||
int CountGrep;
|
||||
};
|
||||
|
||||
@@ -2770,7 +2784,8 @@ struct ImGuiTextBuffer
|
||||
void resize(int size) { if (Buf.Size > size) Buf.Data[size] = 0; Buf.resize(size ? size + 1 : 0, 0); } // Similar to resize(0) on ImVector: empty string but don't free buffer.
|
||||
void reserve(int capacity) { Buf.reserve(capacity); }
|
||||
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 appendfv(const char* fmt, va_list args) IM_FMTLIST(2);
|
||||
};
|
||||
@@ -3337,8 +3352,10 @@ struct ImDrawList
|
||||
IMGUI_API void AddNgonFilled(const ImVec2& center, float radius, ImU32 col, int num_segments);
|
||||
IMGUI_API void AddEllipse(const ImVec2& center, const ImVec2& radius, ImU32 col, float rot = 0.0f, int num_segments = 0, float thickness = 1.0f);
|
||||
IMGUI_API void AddEllipseFilled(const ImVec2& center, const ImVec2& radius, ImU32 col, float rot = 0.0f, int num_segments = 0);
|
||||
IMGUI_API void AddText(const ImVec2& pos, ImU32 col, const char* text_begin, const char* text_end = NULL);
|
||||
IMGUI_API void AddText(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);
|
||||
IMGUI_API void AddText(const ImVec2& pos, ImU32 col, ImStrv text);
|
||||
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(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(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 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 AddBezierQuadratic(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, ImU32 col, float thickness, int num_segments = 0); // Quadratic Bezier (3 control points)
|
||||
|
||||
@@ -3617,7 +3634,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 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
|
||||
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 BuildRanges(ImVector<ImWchar>* out_ranges); // Output new ranges
|
||||
};
|
||||
@@ -3900,12 +3918,16 @@ struct ImFont
|
||||
// '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.
|
||||
IMGUI_API ImFontBaked* GetFontBaked(float font_size, float density = -1.0f); // Get or create baked data for given size
|
||||
IMGUI_API ImVec2 CalcTextSizeA(float size, float max_width, float wrap_width, const char* text_begin, const char* text_end = NULL, const char** out_remaining = NULL);
|
||||
IMGUI_API const char* CalcWordWrapPosition(float size, const char* text, const char* text_end, float wrap_width);
|
||||
IMGUI_API void RenderChar(ImDrawList* draw_list, float size, const ImVec2& pos, ImU32 col, ImWchar c, const ImVec4* cpu_fine_clip = NULL);
|
||||
IMGUI_API void RenderText(ImDrawList* draw_list, float size, const ImVec2& pos, ImU32 col, const ImVec4& clip_rect, const char* text_begin, const char* text_end, float wrap_width = 0.0f, ImDrawTextFlags flags = 0);
|
||||
IMGUI_API void RenderText(ImDrawList* draw_list, float size, const ImVec2& pos, ImU32 col, const ImVec4& clip_rect, ImStrv text, float wrap_width = 0.0f, ImDrawTextFlags flags = 0);
|
||||
inline void RenderText(ImDrawList* draw_list, float size, const ImVec2& pos, ImU32 col, const ImVec4& clip_rect, const char* text_begin, const char* text_end, float wrap_width = 0.0f, ImDrawTextFlags flags = 0) { RenderText(draw_list, size, pos, col, clip_rect, ImStrv(text_begin, text_end), wrap_width, flags); }
|
||||
IMGUI_API ImVec2 CalcTextSizeA(float size, float max_width, float wrap_width, ImStrv text, const char** remaining = NULL); // utf8
|
||||
IMGUI_API const char* CalcWordWrapPosition(float scale, ImStrv text, float wrap_width);
|
||||
|
||||
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
|
||||
inline const char* CalcWordWrapPositionA(float scale, const char* text, const char* text_end, float wrap_width) { return CalcWordWrapPosition(LegacySize * scale, text, text_end, wrap_width); }
|
||||
inline ImVec2 CalcTextSizeA(float size, float max_width, float wrap_width, const char* text_begin, const char* text_end, const char** remaining = NULL) { return CalcTextSizeA(size, max_width, wrap_width, ImStrv(text_begin, text_end), remaining); }
|
||||
inline const char* CalcWordWrapPosition(float size, const char* text, const char* text_end, float wrap_width) { return CalcWordWrapPosition(size, ImStrv(text, text_end), wrap_width); }
|
||||
inline const char* CalcWordWrapPositionA(float scale, const char* text, const char* text_end, float wrap_width) { return CalcWordWrapPosition(LegacySize * scale, ImStrv(text, text_end), wrap_width); }
|
||||
#endif
|
||||
|
||||
// [Internal] Don't use!
|
||||
|
||||
+6
-6
@@ -5200,7 +5200,7 @@ static void DemoWindowLayout()
|
||||
case 2:
|
||||
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->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;
|
||||
}
|
||||
}
|
||||
@@ -9191,7 +9191,7 @@ struct ExampleAppConsole
|
||||
if (match_len > 0)
|
||||
{
|
||||
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], candidates[0] + match_len));
|
||||
}
|
||||
|
||||
// List matches
|
||||
@@ -9326,8 +9326,8 @@ struct ExampleAppLog
|
||||
{
|
||||
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;
|
||||
if (Filter.PassFilter(line_start, line_end))
|
||||
ImGui::TextUnformatted(line_start, line_end);
|
||||
if (Filter.PassFilter(ImStrv(line_start, line_end)))
|
||||
ImGui::TextUnformatted(ImStrv(line_start, line_end));
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -9353,7 +9353,7 @@ struct ExampleAppLog
|
||||
{
|
||||
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;
|
||||
ImGui::TextUnformatted(line_start, line_end);
|
||||
ImGui::TextUnformatted(ImStrv(line_start, line_end));
|
||||
}
|
||||
}
|
||||
clipper.End();
|
||||
@@ -9753,7 +9753,7 @@ static void ShowExampleAppLongText(bool* p_open)
|
||||
{
|
||||
case 0:
|
||||
// Single call to TextUnformatted() with a big buffer
|
||||
ImGui::TextUnformatted(log.begin(), log.end());
|
||||
ImGui::TextUnformatted(ImStrv(log.begin(), log.end()));
|
||||
break;
|
||||
case 1:
|
||||
{
|
||||
|
||||
+33
-36
@@ -1698,15 +1698,14 @@ void ImDrawList::AddBezierQuadratic(const ImVec2& p1, const ImVec2& p2, const Im
|
||||
PathStroke(col, 0, thickness);
|
||||
}
|
||||
|
||||
void ImDrawList::AddText(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(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)
|
||||
return;
|
||||
|
||||
// Accept null ranges
|
||||
if (text_begin == text_end || text_begin[0] == 0)
|
||||
if (text.Begin == text.End)
|
||||
return;
|
||||
// No need to strlen() here: font->RenderText() will do it and may early out.
|
||||
|
||||
// Pull default font/size from the shared ImDrawListSharedData instance
|
||||
if (font == NULL)
|
||||
@@ -1722,12 +1721,12 @@ void ImDrawList::AddText(ImFont* font, float font_size, const ImVec2& pos, ImU32
|
||||
clip_rect.z = ImMin(clip_rect.z, cpu_fine_clip_rect->z);
|
||||
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) ? ImDrawTextFlags_CpuFineClip : ImDrawTextFlags_None);
|
||||
font->RenderText(this, font_size, pos, col, clip_rect, text, wrap_width, (cpu_fine_clip_rect != NULL) ? ImDrawTextFlags_CpuFineClip : ImDrawTextFlags_None);
|
||||
}
|
||||
|
||||
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(_Data->Font, _Data->FontSize, pos, col, text_begin, text_end);
|
||||
AddText(_Data->Font, _Data->FontSize, pos, col, text);
|
||||
}
|
||||
|
||||
void ImDrawList::AddImage(ImTextureRef tex_ref, const ImVec2& p_min, const ImVec2& p_max, const ImVec2& uv_min, const ImVec2& uv_max, ImU32 col)
|
||||
@@ -3105,11 +3104,13 @@ static unsigned int stb_decompress(unsigned char* output, const unsigned char* i
|
||||
static unsigned int Decode85Byte(char c) { return c >= '\\' ? c-36 : c-35; }
|
||||
static void Decode85(ImStrv src, unsigned char* dst)
|
||||
{
|
||||
while (*src)
|
||||
const char* p = src.Begin;
|
||||
const char* p_end = src.End;
|
||||
while (p < p_end)
|
||||
{
|
||||
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(p[0]) + 85 * (Decode85Byte(p[1]) + 85 * (Decode85Byte(p[2]) + 85 * (Decode85Byte(p[3]) + 85 * Decode85Byte(p[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.
|
||||
src += 5;
|
||||
p += 5;
|
||||
dst += 4;
|
||||
}
|
||||
}
|
||||
@@ -3210,8 +3211,9 @@ ImFont* ImFontAtlas::AddFontFromFileTTF(ImStrv filename, float size_pixels, cons
|
||||
{
|
||||
// Store a short copy of filename into the font name for convenience
|
||||
const char* p;
|
||||
for (p = filename + ImStrlen(filename); p > filename && p[-1] != '/' && p[-1] != '\\'; p--) {}
|
||||
ImFormatString(font_cfg.Name, IM_COUNTOF(font_cfg.Name), "%s", p);
|
||||
for (p = filename.End; p > filename.Begin && p[-1] != '/' && p[-1] != '\\'; p--) {}
|
||||
filename.Begin = p;
|
||||
ImFormatString(font_cfg.Name, IM_COUNTOF(font_cfg.Name), "%.*s", (int)filename.length(), filename.Begin);
|
||||
}
|
||||
return AddFontFromMemoryTTF(data, (int)data_size, size_pixels, &font_cfg, glyph_ranges);
|
||||
}
|
||||
@@ -3245,7 +3247,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)
|
||||
{
|
||||
int compressed_ttf_size = (((int)ImStrlen(compressed_ttf_data_base85) + 4) / 5) * 4;
|
||||
int compressed_ttf_size = (((int)compressed_ttf_data_base85.length() + 4) / 5) * 4;
|
||||
void* compressed_ttf = IM_ALLOC((size_t)compressed_ttf_size);
|
||||
Decode85(compressed_ttf_data_base85, (unsigned char*)compressed_ttf);
|
||||
ImFont* font = AddFontFromMemoryCompressedTTF(compressed_ttf, compressed_ttf_size, size_pixels, font_cfg, glyph_ranges);
|
||||
@@ -5099,15 +5101,13 @@ const ImWchar* ImFontAtlas::GetGlyphRangesVietnamese()
|
||||
// [SECTION] ImFontGlyphRangesBuilder
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void ImFontGlyphRangesBuilder::AddText(const char* text, const char* text_end)
|
||||
void ImFontGlyphRangesBuilder::AddText(ImStrv text)
|
||||
{
|
||||
if (text_end == NULL)
|
||||
text_end = text + strlen(text);
|
||||
while (text < text_end)
|
||||
while (text.Begin < text.End)
|
||||
{
|
||||
unsigned int c = 0;
|
||||
int c_len = ImTextCharFromUtf8(&c, text, text_end);
|
||||
text += c_len;
|
||||
int c_len = ImTextCharFromUtf8(&c, text.Begin, text.End);
|
||||
text.Begin += c_len;
|
||||
if (c_len == 0)
|
||||
break;
|
||||
AddChar((ImWchar)c);
|
||||
@@ -5491,7 +5491,7 @@ void ImTextInitClassifiers()
|
||||
// Simple word-wrapping for English, not full-featured. Please submit failing cases!
|
||||
// This will return the next location to wrap from. If no wrapping if necessary, this will fast-forward to e.g. text_end.
|
||||
// Refer to imgui_test_suite's "drawlist_text_wordwrap_1" for tests.
|
||||
const char* ImFontCalcWordWrapPositionEx(ImFont* font, float size, const char* text, const char* text_end, float wrap_width, ImDrawTextFlags flags)
|
||||
const char* ImFontCalcWordWrapPositionEx(ImFont* font, float size, const char* text_begin, const char* text_end, float wrap_width, ImDrawTextFlags flags)
|
||||
{
|
||||
// For references, possible wrap point marked with ^
|
||||
// "aaa bbb, ccc,ddd. eee fff. ggg!"
|
||||
@@ -5510,7 +5510,7 @@ const char* ImFontCalcWordWrapPositionEx(ImFont* font, float size, const char* t
|
||||
float blank_width = 0.0f;
|
||||
wrap_width /= scale; // We work with unscaled widths to avoid scaling every characters
|
||||
|
||||
const char* s = text;
|
||||
const char* s = text_begin;
|
||||
IM_ASSERT(text_end != NULL);
|
||||
|
||||
int prev_type = ImWcharClass_Other;
|
||||
@@ -5601,30 +5601,29 @@ const char* ImFontCalcWordWrapPositionEx(ImFont* font, float size, const char* t
|
||||
|
||||
// Wrap_width is too small to fit anything. Force displaying 1 character to minimize the height discontinuity.
|
||||
// +1 may not be a character start point in UTF-8 but it's ok because caller loops use (text >= word_wrap_eol).
|
||||
if (s == text && text < text_end)
|
||||
if (s == text_begin && text_begin < text_end)
|
||||
return s + ImTextCountUtf8BytesFromChar(s, text_end);
|
||||
return s;
|
||||
}
|
||||
|
||||
const char* ImFont::CalcWordWrapPosition(float size, const char* text, const char* text_end, float wrap_width)
|
||||
const char* ImFont::CalcWordWrapPosition(float size, ImStrv text, float wrap_width)
|
||||
{
|
||||
return ImFontCalcWordWrapPositionEx(this, size, text, text_end, wrap_width, ImDrawTextFlags_None);
|
||||
return ImFontCalcWordWrapPositionEx(this, size, text.Begin, text.End, wrap_width, ImDrawTextFlags_None);
|
||||
}
|
||||
|
||||
ImVec2 ImFontCalcTextSizeEx(ImFont* font, float size, float max_width, float wrap_width, const char* text_begin, const char* text_end_display, const char* text_end, const char** out_remaining, ImVec2* out_offset, ImDrawTextFlags flags)
|
||||
{
|
||||
if (!text_end)
|
||||
text_end = text_begin + ImStrlen(text_begin); // FIXME-OPT: Need to avoid this.
|
||||
if (!text_end_display)
|
||||
text_end_display = text_end;
|
||||
|
||||
ImFontBaked* baked = font->GetFontBaked(size);
|
||||
|
||||
const float line_height = size;
|
||||
const float scale = line_height / baked->Size;
|
||||
|
||||
ImVec2 text_size = ImVec2(0, 0);
|
||||
float line_width = 0.0f;
|
||||
|
||||
if (!text_end_display)
|
||||
text_end_display = text_end;
|
||||
|
||||
const bool word_wrap_enabled = (wrap_width > 0.0f);
|
||||
const char* word_wrap_eol = NULL;
|
||||
|
||||
@@ -5702,9 +5701,9 @@ ImVec2 ImFontCalcTextSizeEx(ImFont* font, float size, float max_width, float wra
|
||||
return text_size;
|
||||
}
|
||||
|
||||
ImVec2 ImFont::CalcTextSizeA(float size, float max_width, float wrap_width, const char* text_begin, const char* text_end, const char** out_remaining)
|
||||
ImVec2 ImFont::CalcTextSizeA(float size, float max_width, float wrap_width, ImStrv text, const char** out_remaining)
|
||||
{
|
||||
return ImFontCalcTextSizeEx(this, size, max_width, wrap_width, text_begin, text_end, text_end, out_remaining, NULL, ImDrawTextFlags_None);
|
||||
return ImFontCalcTextSizeEx(this, size, max_width, wrap_width, text.Begin, text.End, text.End, out_remaining, NULL, ImDrawTextFlags_None);
|
||||
}
|
||||
|
||||
// Note: as with every ImDrawList drawing function, this expects that the font atlas texture is bound.
|
||||
@@ -5748,7 +5747,7 @@ void ImFont::RenderChar(ImDrawList* draw_list, float size, const ImVec2& pos, Im
|
||||
|
||||
// Note: as with every ImDrawList drawing function, this expects that the font atlas texture is bound.
|
||||
// DO NOT CALL DIRECTLY THIS WILL CHANGE WILDLY IN 2026. Use ImDrawList::AddText().
|
||||
void ImFont::RenderText(ImDrawList* draw_list, float size, const ImVec2& pos, ImU32 col, const ImVec4& clip_rect, const char* text_begin, const char* text_end, float wrap_width, ImDrawTextFlags flags)
|
||||
void ImFont::RenderText(ImDrawList* draw_list, float size, const ImVec2& pos, ImU32 col, const ImVec4& clip_rect, ImStrv text, float wrap_width, ImDrawTextFlags flags)
|
||||
{
|
||||
// Align to be pixel perfect
|
||||
begin:
|
||||
@@ -5757,9 +5756,6 @@ begin:
|
||||
if (y > clip_rect.w)
|
||||
return;
|
||||
|
||||
if (!text_end)
|
||||
text_end = text_begin + ImStrlen(text_begin); // ImGui:: functions generally already provides a valid text_end, so this is merely to handle direct calls.
|
||||
|
||||
const float line_height = size;
|
||||
ImFontBaked* baked = GetFontBaked(size);
|
||||
|
||||
@@ -5768,7 +5764,8 @@ begin:
|
||||
const bool word_wrap_enabled = (wrap_width > 0.0f);
|
||||
|
||||
// Fast-forward to first visible line
|
||||
const char* s = text_begin;
|
||||
const char* s = text.Begin;
|
||||
const char* text_end = text.End;
|
||||
if (y + line_height < clip_rect.y)
|
||||
while (y + line_height < clip_rect.y && s < text_end)
|
||||
{
|
||||
@@ -5783,7 +5780,7 @@ begin:
|
||||
}
|
||||
else
|
||||
{
|
||||
s = line_end ? line_end + 1 : text_end;
|
||||
s = line_end ? line_end + 1 : text.End;
|
||||
}
|
||||
y += line_height;
|
||||
}
|
||||
|
||||
+40
-25
@@ -367,8 +367,9 @@ extern IMGUI_API ImGuiContext* GImGui; // Current implicit context pointer
|
||||
|
||||
// Helpers: Hashing
|
||||
IMGUI_API ImGuiID ImHashData(const void* data, size_t data_size, ImGuiID seed = 0);
|
||||
IMGUI_API ImGuiID ImHashStr(const char* data, size_t data_size = 0, ImGuiID seed = 0);
|
||||
IMGUI_API const char* ImHashSkipUncontributingPrefix(const char* label);
|
||||
IMGUI_API ImGuiID ImHashStr(ImStrv str, ImGuiID seed = 0);
|
||||
static inline ImGuiID ImHashStr(const char* data, size_t data_size = 0, ImGuiID seed = 0) { return ImHashStr(ImStrv(data, data_size ? data + data_size : NULL), seed); }
|
||||
IMGUI_API const char* ImHashSkipUncontributingPrefix(ImStrv label);
|
||||
|
||||
// Helpers: Sorting
|
||||
#ifndef ImQsort
|
||||
@@ -387,20 +388,26 @@ inline unsigned int ImCountSetBits(unsigned int v) { unsigned int count
|
||||
// Helpers: String
|
||||
#define ImStrlen strlen
|
||||
#define ImMemchr memchr
|
||||
IMGUI_API int ImStrcmp(ImStrv str1, ImStrv str2);
|
||||
IMGUI_API int ImStricmp(const char* str1, const char* str2); // Case insensitive compare.
|
||||
IMGUI_API int ImStrnicmp(const char* str1, const char* str2, size_t count); // Case insensitive compare to a certain count.
|
||||
IMGUI_API void ImStrncpy(char* dst, const char* src, size_t count); // Copy to a certain count and always zero terminate (strncpy doesn't).
|
||||
IMGUI_API char* ImStrdup(const char* str); // Duplicate a string.
|
||||
IMGUI_API void ImStrncpy(char* dst, ImStrv src, size_t count); // Copy to a certain count and always zero terminate (strncpy doesn't).
|
||||
IMGUI_API void ImStrncpy(char* dst, const char* src, size_t count);
|
||||
IMGUI_API char* ImStrdup(ImStrv str); // Duplicate a string.
|
||||
IMGUI_API char* ImStrdup(const char* str);
|
||||
IMGUI_API char* ImStrdupcpy(char* dst, size_t* p_dst_size, ImStrv str); // Copy in provided buffer, recreate buffer if needed.
|
||||
IMGUI_API char* ImStrdupcpy(char* dst, size_t* p_dst_size, const char* str);
|
||||
IMGUI_API void* ImMemdup(const void* src, size_t size); // Duplicate a chunk of memory.
|
||||
IMGUI_API char* ImStrdupcpy(char* dst, size_t* p_dst_size, const char* str); // Copy in provided buffer, recreate buffer if needed.
|
||||
IMGUI_API const char* ImStrchrRange(const char* str_begin, const char* str_end, char c); // Find first occurrence of 'c' in string range.
|
||||
IMGUI_API const char* ImStreolRange(const char* str, const char* str_end); // End end-of-line
|
||||
IMGUI_API const char* ImStristr(const char* haystack, const char* haystack_end, const char* needle, const char* needle_end); // Find a substring in a string range.
|
||||
IMGUI_API const char* ImStrstr(ImStrv haystack, ImStrv needle); // Find a substring in a string range.
|
||||
IMGUI_API const char* ImStristr(const char* haystack, const char* haystack_end, const char* needle, const char* needle_end);
|
||||
IMGUI_API void ImStrTrimBlanks(char* str); // Remove leading and trailing blanks from a buffer.
|
||||
IMGUI_API const char* ImStrSkipBlank(const char* str); // Find first non-blank character.
|
||||
IMGUI_API int ImStrlenW(const ImWchar* str); // Computer string length (ImWchar string)
|
||||
IMGUI_API const char* ImStrbol(const char* buf_mid_line, const char* buf_begin); // Find beginning-of-line
|
||||
IM_MSVC_RUNTIME_CHECKS_OFF
|
||||
inline int ImStrcmp(const char* str1, const char* str2) { return strcmp(str1, str2); }
|
||||
inline char ImToUpper(char c) { return (c >= 'a' && c <= 'z') ? c &= ~32 : c; }
|
||||
inline bool ImCharIsBlankA(char c) { return c == ' ' || c == '\t'; }
|
||||
inline bool ImCharIsBlankW(unsigned int c) { return c == ' ' || c == '\t' || c == 0x3000; }
|
||||
@@ -410,8 +417,8 @@ IM_MSVC_RUNTIME_CHECKS_RESTORE
|
||||
// Helpers: Formatting
|
||||
IMGUI_API int ImFormatString(char* buf, size_t buf_size, const char* fmt, ...) IM_FMTARGS(3);
|
||||
IMGUI_API int ImFormatStringV(char* buf, size_t buf_size, const char* fmt, va_list args) IM_FMTLIST(3);
|
||||
IMGUI_API void ImFormatStringToTempBuffer(const char** out_buf, const char** out_buf_end, const char* fmt, ...) IM_FMTARGS(3);
|
||||
IMGUI_API void ImFormatStringToTempBufferV(const char** out_buf, const char** out_buf_end, const char* fmt, va_list args) IM_FMTLIST(3);
|
||||
IMGUI_API void ImFormatStringToTempBuffer(ImStrv* out_buf, const char* fmt, ...) IM_FMTARGS(2);
|
||||
IMGUI_API void ImFormatStringToTempBufferV(ImStrv* out_buf, const char* fmt, va_list args) IM_FMTLIST(2);
|
||||
IMGUI_API const char* ImParseFormatFindStart(const char* format);
|
||||
IMGUI_API const char* ImParseFormatFindEnd(const char* format);
|
||||
IMGUI_API const char* ImParseFormatTrimDecorations(const char* format, char* buf, size_t buf_size);
|
||||
@@ -429,7 +436,7 @@ IMGUI_API int ImTextCountUtf8BytesFromChar(const char* in_text, const
|
||||
IMGUI_API int ImTextCountUtf8BytesFromStr(const ImWchar* in_text, const ImWchar* in_text_end); // return number of bytes to express string in UTF-8
|
||||
IMGUI_API const char* ImTextFindPreviousUtf8Codepoint(const char* in_text_start, const char* in_p); // return previous UTF-8 code-point.
|
||||
IMGUI_API const char* ImTextFindValidUtf8CodepointEnd(const char* in_text_start, const char* in_text_end, const char* in_p); // return previous UTF-8 code-point if 'in_p' is not the end of a valid one.
|
||||
IMGUI_API int ImTextCountLines(const char* in_text, const char* in_text_end); // return number of lines taken by text. trailing carriage return doesn't count as an extra line.
|
||||
IMGUI_API int ImTextCountLines(ImStrv in_text); // return number of lines taken by text. trailing carriage return doesn't count as an extra line.
|
||||
|
||||
// Helpers: High-level text functions (DO NOT USE!!! THIS IS A MINIMAL SUBSET OF LARGER UPCOMING CHANGES)
|
||||
enum ImDrawTextFlags_
|
||||
@@ -2772,7 +2779,9 @@ public:
|
||||
ImGuiWindow(ImGuiContext* context, ImStrv name);
|
||||
~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(int n);
|
||||
ImGuiID GetIDFromPos(const ImVec2& p_abs);
|
||||
@@ -3324,7 +3333,8 @@ namespace ImGui
|
||||
// Logging/Capture
|
||||
IMGUI_API void LogBegin(ImGuiLogFlags flags, 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 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);
|
||||
|
||||
// Childs
|
||||
@@ -3616,11 +3626,15 @@ namespace ImGui
|
||||
// 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.
|
||||
// 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 RenderTextWrapped(ImVec2 pos, const char* text, const char* text_end, float wrap_width);
|
||||
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 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);
|
||||
IMGUI_API void RenderTextEllipsis(ImDrawList* draw_list, const ImVec2& pos_min, const ImVec2& pos_max, float ellipsis_max_x, const char* text, const char* text_end, const ImVec2* text_size_if_known);
|
||||
IMGUI_API void RenderText(ImVec2 pos, ImStrv text, bool hide_text_after_hash = true);
|
||||
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 RenderTextWrapped(ImVec2 pos, ImStrv text, float wrap_width);
|
||||
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 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 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 borders = true, float rounding = 0.0f);
|
||||
IMGUI_API void RenderFrameBorder(ImVec2 p_min, ImVec2 p_max, float rounding = 0.0f);
|
||||
IMGUI_API void RenderColorComponentMarker(const ImRect& bb, ImU32 col, float rounding);
|
||||
@@ -3629,7 +3643,8 @@ namespace ImGui
|
||||
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
|
||||
inline void RenderNavHighlight(const ImRect& bb, ImGuiID id, ImGuiNavRenderCursorFlags flags = ImGuiNavRenderCursorFlags_None) { RenderNavCursor(bb, id, flags); } // Renamed in 1.91.4
|
||||
#endif
|
||||
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);
|
||||
|
||||
// Render helpers (those functions don't access any ImGui state!)
|
||||
@@ -3641,17 +3656,17 @@ namespace ImGui
|
||||
IMGUI_API void RenderRectFilledWithHole(ImDrawList* draw_list, const ImRect& outer, const ImRect& inner, ImU32 col, float rounding);
|
||||
IMGUI_API ImDrawFlags CalcRoundingFlagsForRectInRect(const ImRect& r_in, const ImRect& r_outer, float threshold);
|
||||
|
||||
// Widgets: Text
|
||||
IMGUI_API void TextEx(const char* text, const char* text_end = NULL, ImGuiTextFlags flags = 0);
|
||||
// Widgets
|
||||
// Widgets
|
||||
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 void TextAligned(float align_x, float size_x, const char* fmt, ...); // FIXME-WIP: Works but API is likely to be reworked. This is designed for 1 item on the line. (#7024)
|
||||
IMGUI_API void TextAlignedV(float align_x, float size_x, const char* fmt, va_list args);
|
||||
|
||||
// Widgets
|
||||
IMGUI_API bool ButtonEx(ImStrv label, const ImVec2& size_arg = ImVec2(0, 0), ImGuiButtonFlags flags = 0);
|
||||
IMGUI_API bool ArrowButtonEx(ImStrv str_id, ImGuiDir dir, ImVec2 size_arg, ImGuiButtonFlags flags = 0);
|
||||
IMGUI_API bool ImageButtonEx(ImGuiID id, ImTextureRef tex_ref, const ImVec2& image_size, const ImVec2& uv0, const ImVec2& uv1, const ImVec4& bg_col, const ImVec4& tint_col, ImGuiButtonFlags flags = 0);
|
||||
IMGUI_API void SeparatorEx(ImGuiSeparatorFlags flags, float thickness = 1.0f);
|
||||
IMGUI_API void SeparatorTextEx(ImGuiID id, const char* label, const char* label_end, float extra_width);
|
||||
IMGUI_API void SeparatorTextEx(ImGuiID id, ImStrv label, float extra_width);
|
||||
IMGUI_API bool CheckboxFlags(ImStrv label, ImS64* flags, ImS64 flags_value);
|
||||
IMGUI_API bool CheckboxFlags(ImStrv label, ImU64* flags, ImU64 flags_value);
|
||||
|
||||
@@ -3673,7 +3688,7 @@ namespace ImGui
|
||||
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, ImU32 bg_col = 0);
|
||||
|
||||
// Widgets: Tree Nodes
|
||||
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 void TreeNodeDrawLineToChildNode(const ImVec2& target_pos);
|
||||
IMGUI_API void TreeNodeDrawLineToTreePop(const ImGuiTreeNodeStackData* data);
|
||||
IMGUI_API void TreePushOverrideID(ImGuiID id);
|
||||
@@ -3688,7 +3703,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 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> 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
|
||||
IMGUI_API const ImGuiDataTypeInfo* DataTypeGetInfo(ImGuiDataType data_type);
|
||||
@@ -3992,7 +4007,7 @@ IMGUI_API bool ImFontAtlasGetMouseCursorTexData(ImFontAtlas* atlas, ImGuiMo
|
||||
|
||||
#ifdef IMGUI_ENABLE_TEST_ENGINE
|
||||
extern void ImGuiTestEngineHook_ItemAdd(ImGuiContext* ctx, ImGuiID id, const ImRect& bb, const ImGuiLastItemData* item_data); // item_data may be NULL
|
||||
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 const char* ImGuiTestEngine_FindItemDebugLabel(ImGuiContext* ctx, ImGuiID id);
|
||||
|
||||
|
||||
+18
-16
@@ -1701,10 +1701,12 @@ void ImGui::TableSetupColumn(ImStrv label, ImGuiTableColumnFlags flags, float in
|
||||
// Store name (append with zero-terminator in contiguous buffer)
|
||||
// FIXME: If we recorded the number of \n in names we could compute header row height
|
||||
column->NameOffset = -1;
|
||||
if (label != NULL && label[0] != 0)
|
||||
if (!label.empty())
|
||||
{
|
||||
char zero_terminator = 0;
|
||||
column->NameOffset = (ImS16)table->ColumnsNames.size();
|
||||
table->ColumnsNames.append(label, label + ImStrlen(label) + 1);
|
||||
table->ColumnsNames.append(label.Begin, label.End);
|
||||
table->ColumnsNames.append(&zero_terminator, &zero_terminator + 1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3192,10 +3194,11 @@ void ImGui::TableHeader(ImStrv label)
|
||||
ImGuiTableColumn* column = &table->Columns[column_n];
|
||||
|
||||
// Label
|
||||
if (label == NULL)
|
||||
if (!label)
|
||||
label = "";
|
||||
const char* label_end = FindRenderedTextEnd(label);
|
||||
ImVec2 label_size = CalcTextSize(label, label_end, false);
|
||||
ImGuiID id = window->GetID(label);
|
||||
ImStrv label_for_display(label.Begin, FindRenderedTextEnd(label));
|
||||
ImVec2 label_size = CalcTextSize(label_for_display, false);
|
||||
ImVec2 label_pos = window->DC.CursorPos;
|
||||
|
||||
// If we already got a row height, there's use that.
|
||||
@@ -3227,7 +3230,6 @@ void ImGui::TableHeader(ImStrv label)
|
||||
column->ContentMaxXHeadersIdeal = ImMax(column->ContentMaxXHeadersIdeal, max_pos_x);
|
||||
|
||||
// Keep header highlighted when context menu is open.
|
||||
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));
|
||||
ItemSize(ImVec2(0.0f, label_height)); // Don't declare unclipped width, it'll be fed ContentMaxPosHeadersIdeal
|
||||
if (!ItemAdd(bb, id))
|
||||
@@ -3305,11 +3307,11 @@ void ImGui::TableHeader(ImStrv label)
|
||||
// Render clipped label. Clipping here ensure that in the majority of situations, all our header cells will
|
||||
// be merged into a single draw call.
|
||||
//window->DrawList->AddCircleFilled(ImVec2(ellipsis_max, label_pos.y), 40, IM_COL32_WHITE);
|
||||
RenderTextEllipsis(window->DrawList, label_pos, ImVec2(ellipsis_max, bb.Max.y), ellipsis_max, label, label_end, &label_size);
|
||||
RenderTextEllipsis(window->DrawList, label_pos, ImVec2(ellipsis_max, bb.Max.y), ellipsis_max, label_for_display, &label_size);
|
||||
|
||||
const bool text_clipped = label_size.x > (ellipsis_max - label_pos.x);
|
||||
if (text_clipped && hovered && g.ActiveId == 0)
|
||||
SetItemTooltip("%.*s", (int)(label_end - label), label);
|
||||
SetItemTooltip("%.*s", (int)(label_for_display.End - label_for_display.Begin), label_for_display.Begin);
|
||||
|
||||
// We don't use BeginPopupContextItem() because we want the popup to stay up even after the column is hidden
|
||||
if (IsPopupOpenRequestForItem(ImGuiPopupFlags_None, id))
|
||||
@@ -3430,10 +3432,10 @@ void ImGui::TableAngledHeadersRowEx(ImGuiID row_id, float angle, float max_label
|
||||
// Draw label
|
||||
// - First draw at an offset where RenderTextXXX() function won't meddle with applying current ClipRect, then transform to final offset.
|
||||
// - Handle multiple lines manually, as we want each lines to follow on the horizontal border, rather than see a whole block rotated.
|
||||
const char* label_name = TableGetColumnName(table, column_n);
|
||||
const char* label_name_end = FindRenderedTextEnd(label_name);
|
||||
const char* label_name_s = TableGetColumnName(table, column_n);
|
||||
ImStrv label_name(label_name_s, FindRenderedTextEnd(label_name_s));
|
||||
const float line_off_step_x = (g.FontSize / -sin_a);
|
||||
const int label_lines = ImTextCountLines(label_name, label_name_end);
|
||||
const int label_lines = ImTextCountLines(label_name);
|
||||
|
||||
// Left<>Right alignment
|
||||
float line_off_curr_x = flip_label ? (label_lines - 1) * line_off_step_x : 0.0f;
|
||||
@@ -3443,20 +3445,20 @@ void ImGui::TableAngledHeadersRowEx(ImGuiID row_id, float angle, float max_label
|
||||
// Register header width
|
||||
column->ContentMaxXHeadersUsed = column->ContentMaxXHeadersIdeal = column->WorkMinX + ImCeil(label_lines * line_off_step_x - line_off_for_align_x);
|
||||
|
||||
while (label_name < label_name_end)
|
||||
while (label_name.Begin < label_name.End)
|
||||
{
|
||||
const char* label_name_eol = strchr(label_name, '\n');
|
||||
const char* label_name_eol = ImStrchrRange(label_name.Begin, label_name.End, '\n');
|
||||
if (label_name_eol == NULL)
|
||||
label_name_eol = label_name_end;
|
||||
label_name_eol = label_name.End;
|
||||
|
||||
// FIXME: Individual line clipping for right-most column is broken for negative angles.
|
||||
ImVec2 label_size = CalcTextSize(label_name, label_name_eol);
|
||||
ImVec2 label_size = CalcTextSize(ImStrv(label_name.Begin, label_name_eol));
|
||||
float clip_width = max_label_width - padding.y; // Using padding.y*2.0f would be symmetrical but hide more text.
|
||||
float clip_height = ImMin(label_size.y, column->ClipRect.Max.x - column->WorkMinX - line_off_curr_x);
|
||||
ImRect clip_r(window->ClipRect.Min, window->ClipRect.Min + ImVec2(clip_width, clip_height));
|
||||
int vtx_idx_begin = draw_list->_VtxCurrentIdx;
|
||||
PushStyleColor(ImGuiCol_Text, request->TextColor);
|
||||
RenderTextEllipsis(draw_list, clip_r.Min, clip_r.Max, clip_r.Max.x, label_name, label_name_eol, &label_size);
|
||||
RenderTextEllipsis(draw_list, clip_r.Min, clip_r.Max, clip_r.Max.x, ImStrv(label_name.Begin, label_name_eol), &label_size);
|
||||
PopStyleColor();
|
||||
int vtx_idx_end = draw_list->_VtxCurrentIdx;
|
||||
|
||||
|
||||
+209
-184
File diff suppressed because it is too large
Load Diff
@@ -51,6 +51,11 @@ More information at: https://docs.microsoft.com/en-us/visualstudio/debugger/crea
|
||||
</Expand>
|
||||
</Type>
|
||||
|
||||
<!-- String view (non zero-terminated begin/end pair) -->
|
||||
<Type Name="ImStrv">
|
||||
<DisplayString>{Begin,[End-Begin]s} ({End-Begin,d})</DisplayString>
|
||||
</Type>
|
||||
|
||||
<Type Name="ImGuiWindow">
|
||||
<DisplayString>{{Name {Name,s} Active {(Active||WasActive)?1:0,d} Child {(Flags & 0x01000000)?1:0,d} Popup {(Flags & 0x04000000)?1:0,d} Hidden {(Hidden)?1:0,d}}</DisplayString>
|
||||
</Type>
|
||||
|
||||
Reference in New Issue
Block a user