Created
June 7, 2024 13:53
-
-
Save petrihakkinen/c2462974ad41f72a54d9aaf2d62b2536 to your computer and use it in GitHub Desktop.
ImGui InputText with right aligned text (when text wider than widget)
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 InputTextRightAligned(const char* label, const char* text, size_t length, ImGuiInputTextFlags flags, ImGuiInputTextCallback pCallback, void* pUserData) | |
{ | |
const ImGuiContext& g = *ImGui::GetCurrentContext(); | |
const ImGuiStyle& style = ImGui::GetStyle(); | |
ImGuiWindow& window = *ImGui::GetCurrentWindow(); | |
ImGuiID id = window.GetID(label); | |
bool active = g.ActiveId == id; | |
ImVec2 labelSize = ImGui::CalcTextSize(label, nullptr, true); | |
ImVec2 frameSize = ImGui::CalcItemSize(ImVec2(0, 0), CalcItemWidth(), labelSize.y + style.FramePadding.y * 2.0f); | |
ImRect frame(window.DC.CursorPos, window.DC.CursorPos + frameSize); | |
ImVec2 textPos = frame.Min + style.FramePadding; // left aligned | |
// right align text | |
ImVec2 textSize = ImGui::CalcTextSize(text); | |
textPos.x = std::min(frame.Max.x - style.FramePadding.x - textSize.x, textPos.x); | |
bool modified = ImGui::InputText(label, text, length, flags, pCallback, pUserData); | |
// overdraw text with right aligned text when widget not active | |
if(!active) | |
{ | |
ImDrawList& drawList = *ImGui::GetWindowDrawList(); | |
ImVec4 clipRect(frame.Min.x, frame.Min.y, frame.Max.x, frame.Max.y); | |
drawList.AddRectFilled(frame.Min, frame.Max, ImColor(style.Colors[ImGuiCol_FrameBg])); | |
drawList.AddText(nullptr, 0.0f, textPos, ImColor(ImGui::GetStyle().Colors[ImGuiCol_Text]), text, nullptr, 0.0f, &clipRect); | |
} | |
// fix cursor position and scrolling when the widget becomes active | |
if(!active && ImGui::IsItemActive()) | |
{ | |
ImGuiInputTextState* state = ImGui::GetInputTextState(id); | |
if(state) | |
{ | |
const ImGuiIO& io = ImGui::GetIO(); | |
float cursorOffsetX = io.MousePos.x - textPos.x; | |
int cursor = 0; | |
int length = strlen(text); | |
while(cursor < length) | |
{ | |
if(ImGui::CalcTextSize(text, text + cursor + 1).x > cursorOffsetX) | |
break; | |
cursor++; | |
} | |
state->Stb.cursor = cursor; | |
state->Stb.select_start = cursor; | |
state->Stb.select_end = cursor; | |
state->ScrollX = std::max(frame.Min.x + style.FramePadding.x - textPos.x, 0.0f); | |
} | |
} | |
return modified; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment