-
-
Notifications
You must be signed in to change notification settings - Fork 10.6k
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
InputText: Add a way to reset input text state. #2890
Conversation
db9846d
to
e1b34ca
Compare
It's hard to decide what's the desired behavior here, the PR is too specific to your exact need (reset undo stack, reset cursor position, select all, with widget still holding the active id) so I'll need to think about it a little further but basically I am lacking enough use case to take a suitable decision. |
I realized I never added a link to the use case: https://gist.github.com/kudaba/01337c088a0bcef0c2e22a4e846f729c Unfortunately the mouse drag drop part is using private utilities, but applying changes using the mouse wheel has the same issue of requiring this flag to make the input text box refresh its value. |
I also need a way to reset a text field after the call to My use case is a bit peculiar, but I think not really unique: I need to change the content of the input field when Backspace is pressed in a specific situation. That part is easy to do using the I tried hard to work around the problem, and I see a way in this particular situation - setting a flag that will trigger the update during the next time the "always" callback gets called. (I haven't done this yet, but I'm fairly sure it will work.) But this is a bit cumbersome. What I really need is a way to feed new content to the input field either before or after it is being committed to the draw list - after would be better, since else I would again need to define a flag. So I think the easiest and most versatile way to solve this would be to add a function that gives access to the |
@ocornut EDIT 2020-04-05: Problem solved at last. I've deleted the original text of the comment and replaced it with the following working solution. Two situations need to be covered:
I have to repeat here that neither of these would present a real challenge if it wasn't for the fact that, in my case, I cannot directly change the content of the field from inside the callback - which would be quite easy - because it would cause a flicker: for a single frame, the input field and the text items on the same line just before it, and thus already drawn would conflict and display a wrong combination of data (a chain of folder names belonging to the same path). So, I came up with the following solution:
Here is the most relevant code snippet: if (new_foldername.has_value() && ImGui::GetActiveID() != ImGui::GetID("###FolderName")) {
strcpy_s(folder_buffer, new_foldername.value().c_str());
new_foldername.reset();
}
auto flags = ImGuiInputTextFlags_CallbackAlways | ImGuiInputTextFlags_EnterReturnsTrue |
ImGuiInputTextFlags_CallbackCompletion | ImGuiInputTextFlags_CallbackCharFilter |
ImGuiInputTextFlags_CallbackHistory;
if (ImGui::InputText("###FolderName", folder_buffer, IM_ARRAYSIZE(folder_buffer), flags, [](ImGuiInputTextCallbackData* data) {
auto that = static_cast<FileDialog*>(data->UserData);
// TODO: protect against being used when path is completely empty -> crashes
if (data->EventFlag == ImGuiInputTextFlags_CallbackAlways) {
if (that->new_foldername.has_value() ) {
data->DeleteChars(0, data->BufTextLen);
data->InsertChars(0, that->new_foldername.value().c_str());
data->CursorPos = that->new_foldername.value().size();
data->SelectionStart = data->SelectionEnd = 0;
data->BufDirty = true;
that->new_foldername.reset();
}
if (ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_Backspace)) && strlen(that->folder_buffer) == 0) {
if (that->selected_folder) {
auto parent = that->selected_folder->parent;
auto& path = that->selected_folder->dir_entry.path();
that->new_foldername = parent ? path.filename().string() : path.string();
that->selectFolder(parent);
}
}
return 0;
}
...
} |
e1b34ca
to
a56b6c4
Compare
@JPGygax68 I am really confused by the complexity of your two posts above. AFAIK the flag as proposed by @kudaba would exactly solve your problem as you can set the reinit/reload frame whenever works for you. I see the desire for the behavior requested in this PR, and want to add it, but my issue boils down to that comment:
People may want to reload buffer but not select all etc. It's trivial to express those variations in user code but a single flag can't express them. |
FYI, I found one issue when trying to implement an auto complete system where it would keep the cursor position when reinitializing. I'm trying to push an updated version but sourcetree is fighting me atm. in the else block of // when (re)initializing we send the cursor to the end so typing will be at the right spot. Any options that will cause a select all will overwrite this anyway
state->Stb.cursor = state->CurLenW;
if (!is_multiline && (focus_requested_by_code || (reinitialize && (flags & ImGuiInputTextFlags_AutoSelectAll))))
select_all = true; I saw you mention this in some issues so I wanted to make sure to get this modification in before you accept the changes. Auto Complete system for reference: https://gist.github.com/kudaba/af24f859f46ca339a5dedba9074f4dee |
a56b6c4
to
e0b978b
Compare
Managed to get my local state working and updated the PR with the latest version |
I would like to find a solution - or even workaround for imgui_internal.h, but your last change pinpoint at exactly what the problem is that I pointed by my first answer.
This is absolutely arbitrary to your specific use case. |
* This is useful if the value gets modified while the text input control is in focus. * Add multiple reset modes to control the selection state after the reset occurs
e0b978b
to
eeb4234
Compare
Updated to an enum so users can control the selection behavior. |
0c1e5bd
to
bb6a60b
Compare
8b83e0a
to
d735066
Compare
b3b85d8
to
0755767
Compare
c817acb
to
8d39063
Compare
I have merged this now - better late than never :) This has been a very frequently mentioned issue, so even though I am hoping InputText V2 won't need this, this is a good workaround. My apologies for not looking into this earlier! Typical usage: if (ImGuiInputTextState* input_state = ImGui::GetInputTextState(ImGui::GetID("input"))
input_state->ReloadUserBufAndSelectAll();
ImGui::InputText("input", ....); Or ImGui::InputText("input", ...);
if (ImGuiInputTextState* input_state = ImGui::GetInputTextState(ImGui::GetItemID()))
input_state->ReloadUserBufAndSelectAll();
|
I have amended this with 1e8fc01 + 7d67623 (fix) to make the ReloadUserBufXXX() not affect the |
… value. (#2890) fix accidental comment.
commit 5360903 Author: ocornut <omarcornut@gmail.com> Date: Fri Feb 9 16:33:42 2024 +0100 Version 1.90.2 commit 7b5357d Author: ocornut <omarcornut@gmail.com> Date: Fri Feb 9 16:17:59 2024 +0100 Debug Tools: Metrics: Improved Monitors and Viewports minimap display. Highlight on hover. Added ImGuiViewport ID in Master branch. commit 70aa717 Author: ocornut <omarcornut@gmail.com> Date: Fri Feb 9 15:23:43 2024 +0100 Combo: Fixed not reusing windows optimally when used inside a popup stack. commit 5cdc4a2 Author: ocornut <omarcornut@gmail.com> Date: Fri Feb 9 14:20:12 2024 +0100 Demo: use ImGui::MemAlloc/MemFree for consistency. (ocornut#7300) commit 76e09c4 Author: ocornut <omarcornut@gmail.com> Date: Thu Feb 8 17:08:01 2024 +0100 ClosePopupsOverWindow(): amend to remove _ChildWindow test. Said test seems unnecessary and incorrect as we test hierarchy now. See test "nav_ctrl_tab_popups" in ImGuiTestSuite. commit 3a07846 Author: ocornut <omarcornut@gmail.com> Date: Thu Feb 8 16:06:55 2024 +0100 Nav: ImGuiWindowFlags_NoNavInputs is tested during scoring so NavFlattened windows can use it. commit 7d67623 Author: ocornut <omarcornut@gmail.com> Date: Thu Feb 8 15:46:17 2024 +0100 InputText: Internal: ReloadUserBufXXX functions don't override revert value. (ocornut#2890) fix accidental comment. commit a5e0e90 Author: ocornut <omarcornut@gmail.com> Date: Thu Feb 8 15:44:46 2024 +0100 Nav: tweak RenderNavHighlight() syntax. ImGuiNavHighlightFlags_TypeThin -> ImGuiNavHighlightFlags_Compact.
Pushed 324d4bb, calling ReloadUserBufXXXX now doesn't clear undo-stack so you can Ctrl+Z back your way to previous state. |
In response to #2881, I added an internal flag to trigger a text input box to reinitialize to it's current value. This resets any selection and undo state but adds opportunity for new interaction opportunities.