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

InputFloat3 can't accept changes when ImGui::IsItemDeactivatedAfterEdit() #8065

Closed
timbeaudet opened this issue Oct 16, 2024 · 9 comments
Closed
Labels

Comments

@timbeaudet
Copy link

Version/Branch of Dear ImGui:

1.89.9

Back-ends:

imgui_impl_XXX.cpp + imgui_impl_XXX.cpp

Compiler, OS:

Windows 10, MSVC 2022

Full config/build information:

Dear ImGui 1.89.9 (18990)
--------------------------------

sizeof(size_t): 8, sizeof(ImDrawIdx): 2, sizeof(ImDrawVert): 20
define: __cplusplus=199711
define: _WIN32
define: _WIN64
define: _MSC_VER=1941
define: _MSVC_LANG=202002
--------------------------------

io.BackendPlatformName: NULL
io.BackendRendererName: NULL
io.ConfigFlags: 0x00000000
io.ConfigInputTextCursorBlink
io.ConfigWindowsMoveFromTitleBarOnly
io.ConfigMemoryCompactTimer = 60.0
io.BackendFlags: 0x00000000
--------------------------------

io.Fonts: 1 fonts, Flags: 0x00000000, TexSize: 512,64
io.DisplaySize: 1864.00,946.00
io.DisplayFramebufferScale: 1.00,1.00
--------------------------------

style.WindowPadding: 12.00,12.00
style.WindowBorderSize: 0.00
style.FramePadding: 20.00,3.40
style.FrameRounding: 11.90
style.FrameBorderSize: 0.00
style.ItemSpacing: 4.30,5.50
style.ItemInnerSpacing: 7.10,1.80

Details:

I can't get InputFloat3 to accept the value on Enter and loss of focus like I can with InputText. As far as I can tell, ImGui::IsItemDeactivatedAfterEdit() isn't working with InputFloat3(), or at least not when combined with ImGuiInputTextFlags_EnterReturnsTrue

I want InputFloat to behave by accepting the change on Enter (ImGuiInputTextFlags_EnterReturnsTrue) with a combination of keeping them when IsItemDeactivatedAfterEdit() to keep values when tabbing or clicking to another control. The following code-block works perfectly for InputText:

bool MyInputText(const String& label, String* value)
{
	const bool pressedEnter = ImGui::InputText(label.c_str(), value, ImGuiInputTextFlags_EnterReturnsTrue);
	if (true == pressedEnter)
	{
		ImGui::SetItemDefaultFocus();
	}

	return (true == pressedEnter || true == ImGui::IsItemDeactivatedAfterEdit());
}

However that doesn't work with the InputFloat3, my suspicion is this stems from there being 3 InputBoxes in the float3? Is there a way to get that same behavior, I think it might even help the value drift issue from #3936, but I have created a new ticket because they may be unrelated, no values are drifting in this instance for me. The following code allows the value to change on enter, but does not change the value if I change the focus to anything else, including tabbing from X to Y (internally with the Float3), or Z to another control (externally).

bool MyInputFloat3(const String& label, float values[3], const char* format, ImGuiInputTextFlags flags)
{
	const bool pressedEnter = ImGui::InputFloat3(label.c_str(), values, format, flags | ImGuiInputTextFlags_EnterReturnsTrue);
	if (true == pressedEnter)
	{
		ImGui::SetItemDefaultFocus();
	}

	const bool itemDeactivatedAfterEdit = ImGui::IsItemDeactivatedAfterEdit();
	return (true == pressedEnter || true == itemDeactivatedAfterEdit);
}

Screenshots/Video:

No response

Minimal, Complete and Verifiable Example code:

bool MyInputFloat3(const String& label, float values[3], const char* format, ImGuiInputTextFlags flags)
{
	const bool pressedEnter = ImGui::InputFloat3(label.c_str(), values, format, flags | ImGuiInputTextFlags_EnterReturnsTrue);
	if (true == pressedEnter)
	{
		ImGui::SetItemDefaultFocus();
	}

	const bool itemDeactivatedAfterEdit = ImGui::IsItemDeactivatedAfterEdit();
	return (true == pressedEnter || true == itemDeactivatedAfterEdit);
}
@ocornut ocornut added the bug label Oct 16, 2024
@ocornut
Copy link
Owner

ocornut commented Oct 16, 2024

I'm currently noticing odd behavior with InputFloat() and ImGuiInputTextFlags_EnterReturnsTrue where data is not written back to buffer anyhow, which is very problematic. It happens both on latest and 1.89.9.

I am not entirely sure that ImGuiInputTextFlags_EnterReturnsTrue ever worked for InputFloat(), InputFloat3().

However, may I ask why you need ImGuiInputTextFlags_EnterReturnsTrue since without it then IsItemDeactivatedAfterEdit() will cover it?

@timbeaudet
Copy link
Author

timbeaudet commented Oct 16, 2024

ImGuiInputTextFlags_EnterReturnsTrue seems to be working for InputFloat3 fwiw, and I need/want it because when the designer presses Enter after typing it feels natural for that to set the value and then Deactivate by SetItemDefaultFocus(). Perhaps there other ways to do it?, but this was the solution I stumbled on with InputText that felt that way I wanted.

Also IsItemDeactivatedAfterEdit() seems to be the majority of my issues rather than ImGuiInputTextFlags_EnterReturnsTrue so it's interesting you found opposite problems?

@ocornut
Copy link
Owner

ocornut commented Oct 16, 2024

and I need/want it because when the designer presses Enter after typing it feels natural for that to set the value and then Deactivate by

But pressing enter will always deactivate either way.
And IsItemDeactivatedAfterEdit() will return true if pressing Enter after a change. So i don’t understand why you need ImGuiInputTextFlags_EnterReturnsTrue here.

Also IsItemDeactivatedAfterEdit() seems to be the majority of my issues rather than ImGuiInputTextFlags_EnterReturnsTrue so it's interesting you found opposite problems?

_EnterReturnsTrue essentially breaks editing for those specific widgets. So its only natural that other signals would be broken.

@timbeaudet
Copy link
Author

And IsItemDeactivatedAfterEdit() will return true if pressing Enter after a change. So i don’t understand why you need ImGuiInputTextFlags_EnterReturnsTrue here.

Simply because I don't know all the ins and outs of the back end of ImGui perfectly. This was a solution that was doing as I desired, whether it was all necessary or not. I think I started with _EnterReturnsTrue and found that wasn't quite everything I wanted, then later found IsItemDeactivatedAfterEdit() and the combination worked; things are different when you have a full understanding of the ins/outs of the backend, which I do not.

@ocornut
Copy link
Owner

ocornut commented Oct 17, 2024

So:

  • I agree and see there is an issue caused by _EnterReturnsTrue which I will investigate.
  • But I would like to confirm that using only IsItemDeactivatedAfterEdit() (and NOT _EnterReturnsTrue) SHOULD resolve what you wanted? if not I am happy to talk about it.

@ocornut
Copy link
Owner

ocornut commented Oct 17, 2024

(
Unrelated to your issue, but note that SetItemDefaultFocus() is roughly equivalent to if (IsWindowAppearing()) { SetKeyboardFocusHere(-1) aka it only does processing when the window appears, so I am not sure you used it correctly it, it seems like maybe you wanted to use SetKeyboardFocusHere(-1) which means "focus previous item".

SetItemDefaultFocus() and SetKeyboardFocusHere() are amount of last remnant of some old API i will rework and improve. I agree they can be confusing.

I am not even sure it is possible to use SetKeyboardFocusHere() to refocus the last focused sub-field of a 3-elements widget, because you currently cannot tell which one of the three was last focused.
)

@timbeaudet
Copy link
Author

To be clear my usage of SetItemDefaultFocus() was intended to clear item focus, not necessarily got back to previous item. Perhaps I was still using it wrong.

But I would like to confirm that using only IsItemDeactivatedAfterEdit() (and NOT _EnterReturnsTrue) SHOULD resolve what you wanted? if not I am happy to talk about it.

I modified the code to the following (for both this and my InputText version) and it seems to behave exactly as I was trying to get working. Including on enter as you said; as far as my needs go this is a good solution!

ImGui::InputFloat3(label.c_str(), values, format, flags);
if (true == ImGui::IsItemDeactivatedAfterEdit()) { ... }

@ocornut
Copy link
Owner

ocornut commented Oct 17, 2024

Thanks for confirming. I will investigate the remaining bug now.

ocornut added a commit that referenced this issue Oct 17, 2024
…rReturnsTrue is not supported by InputFloat, InputInt etc. (#8065)

It was never correctly supported. Please open an issue if you this would be useful to you. Otherwise use IsItemDeactivatedAfterEdit().
@ocornut
Copy link
Owner

ocornut commented Oct 17, 2024

I've looked into that and established that ImGuiInputTextFlags_EnterReturnsTrue never ever worked with InputFloat/InputInt/InputScalar functions. I have added an assert to warn about it for now: 604f2fa.

I tried to make it work, which led me to do a little bit of refactor of some systems 38617a5 used by InputScalar(), but it would requires some extra awkward change to support it. At this point I believe _EnterReturnsTrue it almost never the right thing to use for that so I've decided to keep the assert for now.

If someone comes up with a need for it the asserts tells them to open an issue.

Standalone test-bed:

{
    const bool PressedEnter = ImGui::InputFloat("float1", &clear_color.x, 1.0f, 1.0f, "%.3f", ImGuiInputTextFlags_EnterReturnsTrue);
    ImGui::Text("PressedEnter: %s / DeactivatedAfterEdit: %s", PressedEnter ? "XXXX" : "____", ImGui::IsItemDeactivatedAfterEdit() ? "XXXX" : "____");
}
{
    const bool PressedEnter = ImGui::InputFloat3("float3", &clear_color.x, "%.3f", ImGuiInputTextFlags_EnterReturnsTrue);
    ImGui::Text("PressedEnter: %s / DeactivatedAfterEdit: %s", PressedEnter ? "XXXX" : "____", ImGui::IsItemDeactivatedAfterEdit() ? "XXXX" : "____");
}

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

No branches or pull requests

2 participants