Edit a string of text - buf_size account for the zero-terminator, so a buf_size of 6 can hold "Hello" but not "Hello!". This is so we can easily call InputText() on static arrays using ARRAYSIZE() and to match Note that in std::string world, capacity() would omit 1 byte used by the zero-terminator. - When active, hold on a privately held copy of the text (and apply back to 'buf'). So changing 'buf
| 4697 | // - When active, hold on a privately held copy of the text (and apply back to 'buf'). So changing 'buf' while the InputText is active has no effect. |
| 4698 | // - If you want to use InputText() with std::string or any custom dynamic string type, use the wrapper in misc/cpp/imgui_stdlib.h/.cpp! |
| 4699 | bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_size, const ImVec2& size_arg, ImGuiInputTextFlags flags, ImGuiInputTextCallback callback, void* callback_user_data) |
| 4700 | { |
| 4701 | ImGuiWindow* window = GetCurrentWindow(); |
| 4702 | if (window->SkipItems) |
| 4703 | return false; |
| 4704 | |
| 4705 | IM_ASSERT(buf != NULL && buf_size >= 0); |
| 4706 | IM_ASSERT(!((flags & ImGuiInputTextFlags_CallbackHistory) && (flags & ImGuiInputTextFlags_Multiline))); // Can't use both together (they both use up/down keys) |
| 4707 | IM_ASSERT(!((flags & ImGuiInputTextFlags_CallbackCompletion) && (flags & ImGuiInputTextFlags_AllowTabInput))); // Can't use both together (they both use tab key) |
| 4708 | IM_ASSERT(!((flags & ImGuiInputTextFlags_ElideLeft) && (flags & ImGuiInputTextFlags_Multiline))); // Multiline does not not work with left-trimming |
| 4709 | IM_ASSERT((flags & ImGuiInputTextFlags_WordWrap) == 0 || (flags & ImGuiInputTextFlags_Password) == 0); // WordWrap does not work with Password mode. |
| 4710 | IM_ASSERT((flags & ImGuiInputTextFlags_WordWrap) == 0 || (flags & ImGuiInputTextFlags_Multiline) != 0); // WordWrap does not work in single-line mode. |
| 4711 | |
| 4712 | ImGuiContext& g = *GImGui; |
| 4713 | ImGuiIO& io = g.IO; |
| 4714 | const ImGuiStyle& style = g.Style; |
| 4715 | |
| 4716 | const bool RENDER_SELECTION_WHEN_INACTIVE = false; |
| 4717 | const bool is_multiline = (flags & ImGuiInputTextFlags_Multiline) != 0; |
| 4718 | |
| 4719 | if (is_multiline) // Open group before calling GetID() because groups tracks id created within their scope (including the scrollbar) |
| 4720 | BeginGroup(); |
| 4721 | const ImGuiID id = window->GetID(label); |
| 4722 | const char* label_end = FindRenderedTextEnd(label); |
| 4723 | const ImVec2 label_size = CalcTextSize(label, label_end, false); |
| 4724 | 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 |
| 4725 | const ImVec2 total_size = ImVec2(frame_size.x + (label_size.x > 0.0f ? style.ItemInnerSpacing.x + label_size.x : 0.0f), frame_size.y); |
| 4726 | |
| 4727 | const ImRect frame_bb(window->DC.CursorPos, window->DC.CursorPos + frame_size); |
| 4728 | const ImRect total_bb(frame_bb.Min, frame_bb.Min + total_size); |
| 4729 | |
| 4730 | ImGuiWindow* draw_window = window; |
| 4731 | ImVec2 inner_size = frame_size; |
| 4732 | ImGuiLastItemData item_data_backup; |
| 4733 | if (is_multiline) |
| 4734 | { |
| 4735 | ImVec2 backup_pos = window->DC.CursorPos; |
| 4736 | ItemSize(total_bb, style.FramePadding.y); |
| 4737 | bool no_clip = (g.InputTextDeactivatedState.ID == id) || (g.ActiveId == id) || (id == g.NavActivateId); // Mimic some of ItemAdd() logic + add InputTextDeactivatedState.ID check. |
| 4738 | if (!ItemAdd(total_bb, id, &frame_bb, ImGuiItemFlags_Inputable) && !no_clip) |
| 4739 | { |
| 4740 | EndGroup(); |
| 4741 | return false; |
| 4742 | } |
| 4743 | item_data_backup = g.LastItemData; |
| 4744 | window->DC.CursorPos = backup_pos; |
| 4745 | |
| 4746 | // Prevent NavActivation from explicit Tabbing when our widget accepts Tab inputs: this allows cycling through widgets without stopping. |
| 4747 | if (g.NavActivateId == id && (g.NavActivateFlags & ImGuiActivateFlags_FromTabbing) && !(g.NavActivateFlags & ImGuiActivateFlags_FromFocusApi) && (flags & ImGuiInputTextFlags_AllowTabInput)) |
| 4748 | g.NavActivateId = 0; |
| 4749 | |
| 4750 | // Prevent NavActivate reactivating in BeginChild() when we are already active. |
| 4751 | const ImGuiID backup_activate_id = g.NavActivateId; |
| 4752 | if (g.ActiveId == id) // Prevent reactivation |
| 4753 | g.NavActivateId = 0; |
| 4754 | |
| 4755 | // We reproduce the contents of BeginChildFrame() in order to provide 'label' so our window internal data are easier to read/debug. |
| 4756 | PushStyleColor(ImGuiCol_ChildBg, style.Colors[ImGuiCol_FrameBg]); |
nothing calls this directly
no test coverage detected