Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Wrap multiline text #952

Open
funbiscuit opened this issue Dec 25, 2016 · 11 comments
Open

Wrap multiline text #952

funbiscuit opened this issue Dec 25, 2016 · 11 comments

Comments

@funbiscuit
Copy link

Hello! Is it possible to set up automatic wrapping of editable multiline text (ImGui::InputTextMultiline)? Since it is already available for normal noneditable text.

@ocornut
Copy link
Owner

ocornut commented Jan 1, 2017

Sorry this is unavailable, and probably won't be for a while (the input text code needs a large refactor before attempting more changes of that nature).

@ocornut
Copy link
Owner

ocornut commented Jan 1, 2017

You may still look into it yourself if you are curious, I don't think the actual change will be very difficult, but that piece of code is quite fragile right now because it does so many things and attempts to do it with decent performances.

Adding automatic wrapping means we can't fast skip through text to calculate the text height, so it would be quite heavy for long piece of text. We should probably introduce an internal cache for non-activated multi-lines input boxes to store size and wrapping data given known inputs.

@colesnicov
Copy link

Perhaps would be to use something like (pseudocode):

char buf[...];
ImVec2 areaSize(..., ...);
InputTextMultiline(..., buf ..., areaSize, ... ImGuiTextEditCallback, ...);

ImGuiTextEditCallback(ImGuiTextEditCallbackData* data) {
     if (ImGui::CalcTextSize(data->Buf) == areaSize.x)
     {
         data->Buf + = "\ n";
     }
}

Something like this? I have not tried, but theoretically could something like this could go? Then I see this as a problem that it is hard wrapping. It should be if there is a change in the size of the widget, so it would need to recalculate ...

Ala google translate...

@colesnicov
Copy link

colesnicov commented Jan 10, 2017

Rather, something like this?

It needs to pass a callback and flag ImGuiInputTextFlags_CallbackAlways

    char[1024*16];
    float w = ImGui::CalcItemWidth();
    ImGui::InputTextMultiline("##text", buf, IM_ARRAYSIZE(buf), ImVec2(-1, ImGui::GetWindowContentRegionMax().y ), ImGuiInputTextFlags_CallbackAlways, CLB, &(w));

A callback might look like this

int CLB(ImGuiTextEditCallbackData* data)
{
    static int lines = 1;

    float controlWidth = *(float*)data->UserData,
          charHeight = ImGui::CalcTextSize("W").x,
          pos = (data->CursorPos*charHeight)/lines;

    if(data->EventKey == ImGuiKey_Enter)
    {
        lines++;
    }

    if(controlWidth <= pos)
    {
        data->InsertChars(data->CursorPos, "\n");
        data->BufDirty = true;
        lines++;
    }

    return data->BufTextLen;
}

Or

int CLB(ImGuiTextEditCallbackData* data)
{

    float controlWidth = *(float*)data->UserData,
          textWidth = ImGui::CalcTextSize(data->Buf).x;

    if(controlWidth <= textWidth)
    {
        data->InsertChars(data->CursorPos-1, "\n");
        data->BufDirty = true;
    }

    return data->BufTextLen;
}

The second realization seems to me to be a better ...

But it is still a problems"

  1. One is a "hard" breaking a line
  2. Line breaks in the wrong place
  3. Disregards the integrity of words

But as a springboard or a simple solution?? Funbiscuit?

Ala google translate

@ocornut
Copy link
Owner

ocornut commented Jan 10, 2017

I don't think that solution is remotely correct or acceptable, nor what @funbiscuit had in mind. ?

We will implement correct line-wrapping for multi-line text edit but later at it is a non-trivial amount of development to get right (and fast) with the current state of the text editor.

@colesnicov
Copy link

I agree. But such considerations...

@ocornut
Copy link
Owner

ocornut commented Jan 10, 2017

Always good discussing ideas :)

@colesnicov
Copy link

colesnicov commented Jan 10, 2017

You right, but. In C ++ I'm not so good (I came from PHP), currently is teaching him. 3D will also teach. But when I look at stb_textedit.h so we see there: you implement display, word-wrapping, and low-level string... I have not tried it yet at confess and did not look into the code ImGui :: InputTextMultiline (actually, looking - it's a lot of code :)) so nowadays I have no idea what is going on inside the function. But until I finish what's unfinished already have, so maybe I turn Debugger and try to get into it. But aside from that not sooner than a week ...

But for now, if some madman wanted to use what I showed above: https://gist.github.com/colesnicov/638b8e605ed21fe981f197a768561bae

@s9w
Copy link

s9w commented Oct 3, 2019

This seems like a huge missing thing in the otherwise very comprehensive amount of things you can do in imgui. Has there been any progress on this? I'm having trouble implementing this correctly myself.

@ocornut
Copy link
Owner

ocornut commented Oct 3, 2019

Everyone has "one huge missing thing" in mind. The software doesn't write itself. On my end it is unlikely to happen before a rewrite of InputText().

@aardappel
Copy link

aardappel commented Jul 5, 2023

Ran into this today as well.. we have long text strings that need to be edited, and its not great seeing only a small part of them.

Manually inserting linefeeds means that needs to be redone when earlier parts of the text change.. and then needs to be undone before use.

I suppose for now I can write my own wrapping function that I call on the string each frame, but that will likely interact badly with text editing. [Edit: yes, this indeed doesn't work fully, I am guessing InputTextMultiline internally caches information on how many lines it is dealing with, so if you externally insert a new linefeed in the string it is ignored.. I wonder if there is a way to reset its internal state]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants