Imgui: Move cursor to end of InputText / Multiline on initial focus.

Created on 28 Jul 2018  Â·  13Comments  Â·  Source: ocornut/imgui

Unsure if I've missed something obvious here ( I'm guessing I have) , but when I open up a PopupModal window, which contains an InputTextMultiline() field that already has data ( non empty ), how does one position the cursor to the end of the data, ie, an append mode?

Currently the cursor appears at the start of the text data each time.

inputtext

Most helpful comment

+1, looking for this feature too for log output

All 13 comments

I've been blindly digging through the source code and came up with the following trial modification.

It works so long as the flag is set, however after I remove the flag from my InputTextMultiline() call after the initial draw the cursor returns to the start of the text; ie, the cursor location is not persistent between frames. Clearly it isn't correct behaviour to constantly move the cursor to the end with every frame (cannot move the cursor anywhere else).

What am I missing to make the cursor location persist between frames?

This is not meant as a proper submission, this is just me trying to work out how might be able to do it.

        edit_state.BufSizeA = buf_size;

        // Although we are active we don't prevent mouse from hovering other elements unless we are interacting right now with the widget.
        // Down the line we should have a cleaner library-wide concept of Selected vs Active.
        g.ActiveIdAllowOverlap = !io.MouseDown[0];
        g.WantTextInputNextFrame = 1;

        //  Start of attempt to add "append by default" 
        // 
        // imgui.cpp:10105
        //
          if (flags & ImGuiInputTextFlags_AppendOnFocus) {
               int n = edit_state.Text.size();
                   edit_state.StbState.cursor = n; //stb_text_locate_coord(str, x, y);
               edit_state.StbState.select_start = edit_state.StbState.cursor;
               edit_state.StbState.select_end = edit_state.StbState.cursor;
               edit_state.StbState.has_preferred_x = 0;
               edit_state.CursorAnimReset();
          }
        // 
        //
        //  END of attempt to add "append by default" 


        // Edit in progress
        const float mouse_x = (io.MousePos.x - frame_bb.Min.x - style.FramePadding.x) + edit_state.ScrollX;
        const float mouse_y = (is_multiline ? (io.MousePos.y - draw_window->DC.CursorPos.y - style.FramePadding.y) : (g.FontSize*0.5f));

I do this in ImGui::InputTextEx with an added ImGuiInputTextFlags_AutoCaretEnd flag (1 << 17)

In the first occuring if (g.ActiveId != id) (after the stb state has been init'ed or reused):

        if (flags & ImGuiInputTextFlags_AutoCaretEnd)
        {
            edit_state.StbState.cursor = edit_state.CurLenW;
            bypassClick = true; // declared out of the parent `if` and initialized as false
        }

And below that (inside of the if (g.ActiveId == id) block) changing:

else if (io.MouseClicked[0] && !edit_state.SelectedAllMouseLock)

into

else if (io.MouseClicked[0] && !edit_state.SelectedAllMouseLock && !bypassClick)

Could probably be done better. Gist: https://gist.github.com/JSandusky/47cf5397dbe48dc68e5ce8a19a3ae1ac

Look for // JS: EDIT to see the 3 changes.

I can see there's a pending issue coming up with potentially running out of flag bits or is it assumed "int" is 32-bit minimum?

I copied the code snippets and it persists between invocations, is that what you had planned? I was having trouble between persistence between frames (but the same invocation).

Regards

I'm many months out of date, you may need to adjust. The behaviour I see is that on first activation of an InputText with the flag set the cursor is placed at the end - from then on everything on that same InputText behaves as normal.

Apologies if it's so far out of date to be useless.

It's fine - I managed to merge the state preservation changes you made with the one-time initialisation I did, and now it seems to be "good enough".

I dare say though that in the future if such a feature is implemented in the master code it'll be done quite differently :)

Thanks.

Disregard my message (that I've now edited over). Just realised, I'll simply submodule off my own fork of the ImGui. Clearly not thinking very well today. Sorry about that.

@inflex @JSandusky Sorry I didn't have the time to dig into this issue.
You may have noticed some unrelated InputText changes went into 1.63 and then the whole function was moved to imgui_widgets.cpp in 1.64, but looking at the patch above it shouldn't be too much trouble to update.

Before we can think of a proper solution (and I think JS's one may be right apart from the flag name), could you both give me more context about the situation where you are using and are in need of this feature?

I can see there's a pending issue coming up with potentially running out of flag bits

We are fine for ImGuiInputTextFlags, "only" using 20 bits for now and they don't really grow fast.

@ocornut the primary use case for me is when I wish to pull up an existing filled form and by default in a Multiline I need to append / continue with adding more data; eg, working on repairing a circuit board, I want to bring up the job log and append more information to a specific individual task that was done but I've subsequently done some more work to. It could be argued I can resolve this by capturing the new data and appending it to the original item after submission, though it's not uncommon to have the need to revise older data, as such having it as a single body of text would be advantageous for my requirements.

The second situation is where I have a InputText and I have data I need to prefix to what ever the user is about to type in (I could do this after the user has submitted the data but it is preferable to have it present in the field as sometimes it needs to be edited as well)

@ocornut I only used it in 2 places: 1 identifier/name fields where a complete wipe of the text or prepend of the text was the least common thing to do on the text. 2 editing key names in a hashtable, which is not truly necessary as it's just fudgery until I wrap it in a proper compound-control to deal with hash-collision issues.

+1, looking for this feature too for log output

@jha Currently the simplest way to create a log window is to use text statement + a copy button/context menu.
For this specific goal I think the desirable end-goal for us is more to go toward being able to make any text selectable (and thus copiable) rather than using an InputText().

@ocornut Hi, I'm currently also working on a console/log window hybrid that needs "tail" functionality and in the window it should – optimally – be possible to highlight/select & copy text at any arbitrary position with any length via mouse input. I'm just wondering: Are there any plans/recent news on making any text in ImGui selectable? If that was possible I could also switch to the way the ExampleAppConsole works in the demo (with BeginChild/ScrollingRegion and TextUnformatted), although the feature to control the vertical scrollbar of InputTextMultiline would be nice to have as well.

Proposition:

I think the best solution would be to implement the feature from https://github.com/ocornut/imgui/pull/3130 (I also need intra-text coloring) and then give the InputTextMultiline the "tail" functionality. If these two were merged, the need to have the more unflexible TextUnformatted in the demo would also go away (granted that the user only wants to log (colored) text and not any complex widgets/controls inside the console).
In fact I was a bit confused when I read the demo code of the console since I was expecting an InputTextMultiline instead of the BeginChild/ScrollingRegion and TextUnformatted combination.
If logging of complex widgets/controls inside the console was desired, there is also the possibility to have two versions of the ExampleAppConsole demo, one for just text logging and one for the more complex variant.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

namuda picture namuda  Â·  3Comments

mkanakis picture mkanakis  Â·  3Comments

BlackWatersInc picture BlackWatersInc  Â·  3Comments

spaderthomas picture spaderthomas  Â·  3Comments

SlNPacifist picture SlNPacifist  Â·  3Comments