@@ -47,6 +47,13 @@ Index of this file:
47
47
// System includes
48
48
#include <stdint.h> // intptr_t
49
49
50
+ // [ADAPT_IMGUI_BUNDLE]
51
+ // for InputTextMultiline tooltip within node editor
52
+ #include <string>
53
+ #include <vector>
54
+ #include <sstream>
55
+ // [/ADAPT_IMGUI_BUNDLE]
56
+
50
57
//-------------------------------------------------------------------------
51
58
// Warnings
52
59
//-------------------------------------------------------------------------
@@ -3846,9 +3853,137 @@ bool ImGui::InputText(const char* label, char* buf, size_t buf_size, ImGuiInputT
3846
3853
return InputTextEx(label, NULL, buf, (int)buf_size, ImVec2(0, 0), flags, callback, user_data);
3847
3854
}
3848
3855
3856
+ // [ADAPT_IMGUI_BUNDLE] cf
3857
+ bool Priv_ImGuiNodeEditor_IsInCanvas();
3858
+ // [/ADAPT_IMGUI_BUNDLE]
3859
+
3860
+
3849
3861
bool ImGui::InputTextMultiline(const char* label, char* buf, size_t buf_size, const ImVec2& size, ImGuiInputTextFlags flags, ImGuiInputTextCallback callback, void* user_data)
3850
3862
{
3851
- return InputTextEx(label, NULL, buf, (int)buf_size, size, flags | ImGuiInputTextFlags_Multiline, callback, user_data);
3863
+ // [ADAPT_IMGUI_BUNDLE] cf
3864
+ // When inside imgui-node-editor canvas, we cannot open child windows
3865
+ // In this case, we present a one line version of the input text,
3866
+ // and offer the possibility to open a popup to edit the text in a multiline widget
3867
+ if (Priv_ImGuiNodeEditor_IsInCanvas())
3868
+ {
3869
+ // Helper function to split and format the text for a tooltip
3870
+ // to show an extract of the full text when hovering the button,
3871
+ auto fn_format_tooltip = [](
3872
+ const char* text, size_t max_line_length, size_t max_lines) -> std::string
3873
+ {
3874
+ auto fn_cut_string_after_max_length = [](const std::string& text, size_t max_length) -> std::string
3875
+ {
3876
+ if (text.size() <= max_length)
3877
+ return text;
3878
+ std::string r = text.substr(0, max_length - 3) + "...";
3879
+ return r;
3880
+ };
3881
+ auto fn_split_lines = [](const std::string& s) -> std::vector<std::string>
3882
+ {
3883
+ std::vector<std::string> lines;
3884
+ std::istringstream f(s);
3885
+ std::string line;
3886
+ while (std::getline(f, line))
3887
+ lines.push_back(line);
3888
+ return lines;
3889
+ };
3890
+ std::string r = "";
3891
+ auto lines = fn_split_lines(text);
3892
+ size_t n = 0;
3893
+ for (const auto& line : lines)
3894
+ {
3895
+ if (n >= max_lines)
3896
+ {
3897
+ r += "...\n";
3898
+ break;
3899
+ }
3900
+ r += fn_cut_string_after_max_length(line, max_line_length) + "\n";
3901
+ n++;
3902
+ }
3903
+ return r;
3904
+ };
3905
+
3906
+ // Helper function to make the text color more red
3907
+ auto fn_redify_color = [](const ImVec4& color) -> ImVec4
3908
+ {
3909
+ ImVec4 redified_color;
3910
+ redified_color.x = color.x;
3911
+ redified_color.y = 0.6f * color.y;
3912
+ redified_color.z = 0.6f * color.z;
3913
+ redified_color.w = color.w;
3914
+ return redified_color;
3915
+ };
3916
+
3917
+ // Intro
3918
+ PushID(label); // make sure to use unique ids
3919
+ bool changed = false;
3920
+ ImGui::BeginGroup();
3921
+
3922
+ // A- One line version text, without the label
3923
+ ImGuiStyle& style = ImGui::GetStyle();
3924
+ ImVec2 pos = ImGui::GetCursorScreenPos();
3925
+ float btn_additional_width = CalcTextSize("...").x + style.FramePadding.x * 2.0f;// + style.ItemInnerSpacing.x;
3926
+ float one_line_widget_width = size.x > 0.f ? size.x : CalcItemWidth();
3927
+ one_line_widget_width -= btn_additional_width;
3928
+ ImGui::SetNextItemWidth(one_line_widget_width);
3929
+ if (InputText("##hidden_label", buf, buf_size, flags, callback, user_data))
3930
+ changed = true;
3931
+
3932
+ // B- Add a button to open a popup to edit the text
3933
+ // i. First, move the cursor to the left, so that the button appears right next to the input text
3934
+ //ImVec2 pos = ImGui::GetCursorScreenPos();
3935
+ //pos.x = pos.x - style.ItemSpacing.x; // + style.ItemInnerSpacing.x;
3936
+ pos.x += one_line_widget_width - 1.f;
3937
+ ImGui::SetCursorScreenPos(pos);
3938
+ // ii. Then add the button
3939
+ bool shall_display_tooltip = strchr(buf, '\n') != NULL;
3940
+ if (shall_display_tooltip)
3941
+ {
3942
+ ImVec4 color = ImGui::GetStyleColorVec4(ImGuiCol_Text);
3943
+ ImGui::PushStyleColor(ImGuiCol_Text, fn_redify_color(color));
3944
+ }
3945
+ bool was_button_pressed = false;
3946
+ if (Button("..."))
3947
+ {
3948
+ was_button_pressed = true;
3949
+ OpenPopup("InputTextMultilinePopup");
3950
+ }
3951
+ if (shall_display_tooltip)
3952
+ ImGui::PopStyleColor();
3953
+
3954
+ if (shall_display_tooltip && ! was_button_pressed)
3955
+ ImGui::SetItemTooltip("%s", fn_format_tooltip(buf, 60, 3).c_str());
3956
+
3957
+ // C. Finally, add the label (up until "##")
3958
+ const char* label_end = FindRenderedTextEnd(label);
3959
+ pos.x += style.ItemInnerSpacing.x + btn_additional_width;
3960
+ ImGui::SetCursorScreenPos(pos);
3961
+ TextUnformatted(label, label_end);
3962
+
3963
+ ImGui::EndGroup();
3964
+
3965
+ // D. Handle the popup
3966
+ if (ImGui::BeginPopup("InputTextMultilinePopup"))
3967
+ {
3968
+ // Note: there is no infinite recursion here, since we are not inside the canvas anymore
3969
+ // (as soon as BeginPopup return true, we are outside the canvas)
3970
+ // (iif the patches https://github.com/thedmd/imgui-node-editor/issues/242#issuecomment-1681806764
3971
+ // and https://github.com/thedmd/imgui-node-editor/issues/242#issuecomment-2404714757 are applied)
3972
+ ImVec2 size_multiline = size;
3973
+ size_multiline.x = one_line_widget_width;
3974
+ if (InputTextMultiline("##edit", buf, buf_size, size_multiline, flags, callback, user_data))
3975
+ changed = true;
3976
+ EndPopup();
3977
+ }
3978
+ PopID();
3979
+ return changed;
3980
+ }
3981
+ // [/ADAPT_IMGUI_BUNDLE]
3982
+ else
3983
+ {
3984
+ // Standard behavior outside of imgui-node-editor canvas
3985
+ return InputTextEx(label, NULL, buf, (int)buf_size, size, flags | ImGuiInputTextFlags_Multiline, callback, user_data);
3986
+ }
3852
3987
}
3853
3988
3854
3989
bool ImGui::InputTextWithHint(const char* label, const char* hint, char* buf, size_t buf_size, ImGuiInputTextFlags flags, ImGuiInputTextCallback callback, void* user_data)
0 commit comments