Core: added ImDrawListSharedData::TextHook called by AddText(), and ImGuiItemFlags_NoTextSelect, to allow implementing text selection externally.

This commit is contained in:
Marius PvW 2026-11-04 10:24:44 -05:00
parent 1ab953d75a
commit 34af65a1b5
4 changed files with 10 additions and 0 deletions

View File

@ -96,6 +96,10 @@ Other Changes:
- Multi-Select:
- Fixed `ImGuiSelectionBasicStorage::GetNextSelectedItem()` reading one past the
end of storage when trailing items are unselected (#9604) [@MilosLord]
- Text: added `ImDrawListSharedData::TextHook` (internal), called by `ImDrawList::AddText()`
with the font, position, clip rectangle and string of every text run before its glyphs
are emitted, and `ImGuiItemFlags_NoTextSelect` to let such a hook skip items. Enables
text selection/copy of any displayed text without changes to widget code.
- ImVec2: added a check for cases where a custom `IM_VEC2_CLASS_EXTRA` macro
adds an extra `operator=` to ImVec2. This isn't supported but should not
be needed as you should have a constructor to convert from your type to ImVec2.

View File

@ -1330,6 +1330,8 @@ enum ImGuiItemFlags_
// - If you use MixedMode and the simplest solution is to ensure LiveEdit is off but widgets where this applies.
//---------------------------------------------------------------------------------
ImGuiItemFlags_MixedValue = 1 << 9, // false // [BETA] Represent a mixed/indeterminate value. Replace value label with "-" and apply edits on validation.
ImGuiItemFlags_NoTextSelect = 1 << 10, // false // Text drawn while set is ignored by text selection implemented via ImDrawListSharedData::TextHook: not highlighted, not copied, and a click on it does not start a selection.
};
// Flags for ImGui::InputText()

View File

@ -2977,6 +2977,8 @@ 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);
}
if (_Data->TextHook != NULL)
_Data->TextHook(this, font, font_size, pos, clip_rect, text_begin, text_end, wrap_width, _Data->TextHookUserData);
font->RenderText(this, font_size, pos, col, clip_rect, text_begin, text_end, wrap_width, (cpu_fine_clip_rect != NULL) ? ImDrawTextFlags_CpuFineClip : ImDrawTextFlags_None);
}

View File

@ -975,6 +975,8 @@ struct IMGUI_API ImDrawListSharedData
ImVector<ImVec2> TempBuffer; // Temporary write buffer
ImVector<ImDrawList*> DrawLists; // All draw lists associated to this ImDrawListSharedData
ImGuiContext* Context; // [OPTIONAL] Link to Dear ImGui context. 99% of ImDrawList/ImFontAtlas can function without an ImGui context, but this facilitate handling one legacy edge case.
void (*TextHook)(ImDrawList* draw_list, ImFont* font, float font_size, const ImVec2& pos, const ImVec4& clip_rect, const char* text_begin, const char* text_end, float wrap_width, void* user_data); // [OPTIONAL] Called by AddText() before the glyphs are emitted: anything it draws ends up underneath the text. text_end may be NULL.
void* TextHookUserData;
// Lookup tables
ImVec2 ArcFastVtx[IM_DRAWLIST_ARCFAST_TABLE_SIZE]; // Sample points on the quarter of the circle.