First of all, I am aware of the other posts regarding this issue: https://github.com/ocornut/imgui/issues/952 https://github.com/ocornut/imgui/issues/1062
This is a little bit different, I would like to attempt to implement this myself since this is not a high priority but I have a couple of questions.
Digging through the source code, I found that the editor is a slightly modified version of https://github.com/nothings/stb/blob/master/stb_textedit.h and, there is this particular paragraph commenting on word-wrapping:
// STB_TEXTEDIT_LAYOUTROW returns information about the shape of one displayed
// row of characters assuming they start on the i'th character--the width and
// the height and the number of characters consumed. This allows this library
// to traverse the entire layout incrementally. You need to compute word-wrapping
// here.
I see that that function is indeed implemented in imgui, more specifically in imgui_widgets.cpp:
static void STB_TEXTEDIT_LAYOUTROW(StbTexteditRow* r, STB_TEXTEDIT_STRING* obj, int line_start_idx)
{
const ImWchar* text = obj->TextW.Data;
const ImWchar* text_remaining = NULL;
const ImVec2 size = InputTextCalcTextSizeW(text + line_start_idx, text + obj->CurLenW, &text_remaining, NULL, true);
r->x0 = 0.0f;
r->x1 = size.x;
r->baseline_y_delta = size.y;
r->ymin = 0.0f;
r->ymax = size.y;
r->num_chars = (int)(text_remaining - (text + line_start_idx));
}
So if my understanding is correct, that function gets called when the cursor moves on the text (either by mouse or keyboard), but then I do not understand how that function would aid text wrapping.
That function does not get called when inserting new text, which should be were the wrapping should be checked.
So more specifically:
ImDrawList::AddText has a wrap_width parameter, I guess that if as a first step I should try to modify the calls to that function in ImGui::InputTextEx, is that correct?Thank you for your understanding, I want to build a note taking application and, for me, this is a requirement so I would like this feature, if someone can help I would greatly appreciate that.
Why not using the full featured text editor widgets listed in the wiki ?
I have checked those projects and I do not require that much. Also adding this to the current implementation would help many developers such as myself.
I have been digging through the code and added the correct wrap_size to both AddText calls and the text does indeed get wrapped:
draw_window->DrawList->AddText(g.Font, g.FontSize, draw_pos - draw_scroll, col, buf_display, buf_display_end, inner_size.x, is_multiline ? NULL : &clip_rect);
But, the cursor is not updated correctly. I am trying to update the cursor myself when I detect that the text has been wrapped, I want to add a copy of ImFont::CalcWordWrapPositionA that would return the number of "wrapped lines" and update the cursor accordingly.
Although I have correctly ported the function (as static in the meantime) I am not 100% sure where the cursor is stored to update it.
I will try to dig around a little bit more, but any help will be welcomed :)
I got some advances but the code is very complex and I did not have enough time to look at it over the weekend.
I have a better grasp on the complexity of the modifications:
Looking good!
I haven't answered your questions above because I don't know what the answers are without digging deeper in that. My whole impression is that we should ditch stb_textedit and rewrite the whole thing anyway without the utf-8<>utf16 round trips.
You'll notice they are various shortcuts involved in InputText inner-loops, namely to allow for very large text and because we don't retain much data. If we rewrite we should probably try to retain more data, in particular line offsets, to make performances more acceptable.
I have seen those inner loops indeed, but I am afraid I lack the expertise to improve the whole TextEdit code, there are many functions that are still unclear to me.
Still, I will try to implement the wrapping as it is something I need. Do you know if the TextEdit rewrite is still a low priority? I guess not a lot of people would benefit from it, but in my case it is crucial.
Also, thank you for answering, and for doing so so quickly!
InputText rewrite is not a low priority but there are so many things competing for high priority at the moment it is a little tricky for me to try to even order them. There are many desirable InputText changes that would benefit from that larger refactor. I guess someone should sit down for 2 weeks and rewrite the whole thing from stratch with a check-list derived from entries in TODO.txt and inputtext tagged issues. That's not very helpful for you however.
I still believe the easiest path for you is to use one of the existing full-featured text editor.
I understand, unfortunately I do not have the time nor the expertise for a full rewrite addressing all the open issues.
I wish I could contribute more, I just made a small donation in the hopes that this awesome project continues and some brave developer rewrites the TextEdit code :)
Thank you again for your time and your replies! I will try to use one of the existing text-editors in the meantime, as you suggested :)
Most helpful comment
I got some advances but the code is very complex and I did not have enough time to look at it over the weekend.
https://youtu.be/BBTho4ZnMIc
I have a better grasp on the complexity of the modifications: