Created
November 5, 2020 17:51
-
-
Save kudaba/a28f63d5bf32aa3ff8ed1e0620fec6a0 to your computer and use it in GitHub Desktop.
ImGui helper to draw text that will cut off and add an elipsis character
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
bool IsSpace(char aCharacter) | |
{ | |
// all space characters are values 32 or less (space is 32) | |
// so we can convert them to a bitmask and use a single condition | |
const int mask = (1 << (' ' - 1)) | (1 << ('\f' - 1)) | (1 << ('\n' - 1)) | (1 << ('\r' - 1)) | (1 << ('\t' - 1)) | (1 << ('\v' - 1)); | |
return (mask & (1 << ((aCharacter && aCharacter <= 32) * (aCharacter - 1)))) != 0; | |
} | |
//------------------------------------------------------------------------------------------------- | |
// Todo: Add support for soft-hyphens when using word boundaries? | |
//------------------------------------------------------------------------------------------------- | |
void TextWithEllipsis(char const* aString, float aMaxWidth, bool useWordBoundaries, float aSpacing) | |
{ | |
char const* partStart = aString; | |
char const* partEnd = aString; | |
ImWchar elipsisChar = ImGui::GetFont()->EllipsisChar; | |
char elipsisText[8]; | |
ImTextStrToUtf8(elipsisText, sizeof(elipsisText), &elipsisChar, (&elipsisChar) + 1); | |
if (aSpacing < 0.0f) aSpacing = ImGui::GetStyle().ItemSpacing.x; | |
float const ellipsisWidth = ImGui::CalcTextSize(elipsisText).x + aSpacing; | |
float width = 0; | |
bool addElipsis = false; | |
while (*partStart != 0) | |
{ | |
// Add space to next segment | |
while (IsSpace(*partEnd)) partEnd++; | |
if (useWordBoundaries) | |
{ | |
// get next 'word' by looking for space after non-space | |
while (*partEnd != 0 && !IsSpace(*partEnd)) ++partEnd; | |
} | |
else | |
{ | |
if (*partEnd != 0) ++partEnd; | |
} | |
ImVec2 const wordSize = ImGui::CalcTextSize(partStart, partEnd); | |
// Clearly we have space for this word so just add it | |
if (wordSize.x + width + ellipsisWidth < aMaxWidth) | |
{ | |
width += wordSize.x; | |
partStart = partEnd; | |
} | |
// If we're just at the end of the word and we just fit then we can commit here | |
else if (*partEnd == 0 && wordSize.x + width < aMaxWidth) | |
{ | |
width += wordSize.x; | |
partStart = partEnd; | |
} | |
// we're done so add elipsis where the current segment starts | |
else | |
{ | |
addElipsis = true; | |
break; | |
} | |
} | |
ImGui::TextUnformatted(aString, partStart); | |
if (addElipsis) | |
{ | |
ImGui::SameLine(0.0f, aSpacing); | |
ImGui::TextUnformatted(elipsisText); | |
} | |
} |
Author
kudaba
commented
Nov 5, 2020
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment