mirror of
https://github.com/ocornut/imgui.git
synced 2024-11-27 16:29:02 +08:00
InputText: Fixed an undo-state corruption issue when editing buffer before reactivating item. (#4947) + Metrics: Added "InputText" section.
This commit is contained in:
parent
74f02703e6
commit
64d6c30562
@ -88,6 +88,7 @@ Other Changes:
|
|||||||
trickled with the new input queue (happened on some backends only). (#2467, #1336)
|
trickled with the new input queue (happened on some backends only). (#2467, #1336)
|
||||||
- InputText: Fixed a one-frame display glitch where pressing Escape to revert after a deletion
|
- InputText: Fixed a one-frame display glitch where pressing Escape to revert after a deletion
|
||||||
would lead to small garbage being displayed for one frame. Curiously a rather old bug! (#3008)
|
would lead to small garbage being displayed for one frame. Curiously a rather old bug! (#3008)
|
||||||
|
- InputText: Fixed an undo-state corruption issue when editing buffer before reactivating item. (#4947)
|
||||||
- Tables: Fixed incorrect border height used for logic when resizing one of several synchronized
|
- Tables: Fixed incorrect border height used for logic when resizing one of several synchronized
|
||||||
instance of a same table ID, when instances have a different height. (#3955).
|
instance of a same table ID, when instances have a different height. (#3955).
|
||||||
- Tables: Fixed incorrect auto-fit of parent windows when using non-resizable weighted columns. (#5276)
|
- Tables: Fixed incorrect auto-fit of parent windows when using non-resizable weighted columns. (#5276)
|
||||||
@ -108,6 +109,7 @@ Other Changes:
|
|||||||
you have a UTF-8 text encoding issue or a font loading issue. [@LaMarche05, @ocornut]
|
you have a UTF-8 text encoding issue or a font loading issue. [@LaMarche05, @ocornut]
|
||||||
- Demo: Add better demo of how to use SetNextFrameWantCaptureMouse()/SetNextFrameWantCaptureKeyboard().
|
- Demo: Add better demo of how to use SetNextFrameWantCaptureMouse()/SetNextFrameWantCaptureKeyboard().
|
||||||
- Metrics: Added a "UTF-8 Encoding Viewer" section using the aforementioned DebugTextEncoding() function.
|
- Metrics: Added a "UTF-8 Encoding Viewer" section using the aforementioned DebugTextEncoding() function.
|
||||||
|
- Metrics: Added "InputText" section to visualize internal state (#4947, #4949).
|
||||||
- Misc: Fixed calling GetID("label") _before_ a widget emitting this item inside a group (such as InputInt())
|
- Misc: Fixed calling GetID("label") _before_ a widget emitting this item inside a group (such as InputInt())
|
||||||
from causing an assertion when closing the group. (#5181).
|
from causing an assertion when closing the group. (#5181).
|
||||||
- Misc: Fixed IsAnyItemHovered() returning false when using navigation.
|
- Misc: Fixed IsAnyItemHovered() returning false when using navigation.
|
||||||
|
@ -12480,6 +12480,13 @@ void ImGui::ShowMetricsWindow(bool* p_open)
|
|||||||
TreePop();
|
TreePop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Details for InputText
|
||||||
|
if (TreeNode("InputText"))
|
||||||
|
{
|
||||||
|
DebugNodeInputTextState(&g.InputTextState);
|
||||||
|
TreePop();
|
||||||
|
}
|
||||||
|
|
||||||
// Details for Docking
|
// Details for Docking
|
||||||
#ifdef IMGUI_HAS_DOCK
|
#ifdef IMGUI_HAS_DOCK
|
||||||
if (TreeNode("Docking"))
|
if (TreeNode("Docking"))
|
||||||
|
2
imgui.h
2
imgui.h
@ -65,7 +65,7 @@ Index of this file:
|
|||||||
// Version
|
// Version
|
||||||
// (Integer encoded as XYYZZ for use in #if preprocessor conditionals. Work in progress versions typically starts at XYY99 then bounce up to XYY00, XYY01 etc. when release tagging happens)
|
// (Integer encoded as XYYZZ for use in #if preprocessor conditionals. Work in progress versions typically starts at XYY99 then bounce up to XYY00, XYY01 etc. when release tagging happens)
|
||||||
#define IMGUI_VERSION "1.88 WIP"
|
#define IMGUI_VERSION "1.88 WIP"
|
||||||
#define IMGUI_VERSION_NUM 18726
|
#define IMGUI_VERSION_NUM 18727
|
||||||
#define IMGUI_CHECKVERSION() ImGui::DebugCheckVersionAndDataLayout(IMGUI_VERSION, sizeof(ImGuiIO), sizeof(ImGuiStyle), sizeof(ImVec2), sizeof(ImVec4), sizeof(ImDrawVert), sizeof(ImDrawIdx))
|
#define IMGUI_CHECKVERSION() ImGui::DebugCheckVersionAndDataLayout(IMGUI_VERSION, sizeof(ImGuiIO), sizeof(ImGuiStyle), sizeof(ImVec2), sizeof(ImVec4), sizeof(ImDrawVert), sizeof(ImDrawIdx))
|
||||||
#define IMGUI_HAS_TABLE
|
#define IMGUI_HAS_TABLE
|
||||||
|
|
||||||
|
@ -2878,6 +2878,7 @@ namespace ImGui
|
|||||||
IMGUI_API void DebugNodeTabBar(ImGuiTabBar* tab_bar, const char* label);
|
IMGUI_API void DebugNodeTabBar(ImGuiTabBar* tab_bar, const char* label);
|
||||||
IMGUI_API void DebugNodeTable(ImGuiTable* table);
|
IMGUI_API void DebugNodeTable(ImGuiTable* table);
|
||||||
IMGUI_API void DebugNodeTableSettings(ImGuiTableSettings* settings);
|
IMGUI_API void DebugNodeTableSettings(ImGuiTableSettings* settings);
|
||||||
|
IMGUI_API void DebugNodeInputTextState(ImGuiInputTextState* state);
|
||||||
IMGUI_API void DebugNodeWindow(ImGuiWindow* window, const char* label);
|
IMGUI_API void DebugNodeWindow(ImGuiWindow* window, const char* label);
|
||||||
IMGUI_API void DebugNodeWindowSettings(ImGuiWindowSettings* settings);
|
IMGUI_API void DebugNodeWindowSettings(ImGuiWindowSettings* settings);
|
||||||
IMGUI_API void DebugNodeWindowsList(ImVector<ImGuiWindow*>* windows, const char* label);
|
IMGUI_API void DebugNodeWindowsList(ImVector<ImGuiWindow*>* windows, const char* label);
|
||||||
|
@ -3571,6 +3571,7 @@ bool ImGui::InputDouble(const char* label, double* v, double step, double step_f
|
|||||||
// - InputTextReindexLines() [Internal]
|
// - InputTextReindexLines() [Internal]
|
||||||
// - InputTextReindexLinesRange() [Internal]
|
// - InputTextReindexLinesRange() [Internal]
|
||||||
// - InputTextEx() [Internal]
|
// - InputTextEx() [Internal]
|
||||||
|
// - DebugNodeInputTextState() [Internal]
|
||||||
//-------------------------------------------------------------------------
|
//-------------------------------------------------------------------------
|
||||||
|
|
||||||
bool ImGui::InputText(const char* label, char* buf, size_t buf_size, ImGuiInputTextFlags flags, ImGuiInputTextCallback callback, void* user_data)
|
bool ImGui::InputText(const char* label, char* buf, size_t buf_size, ImGuiInputTextFlags flags, ImGuiInputTextCallback callback, void* user_data)
|
||||||
@ -4048,17 +4049,21 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
|||||||
state->InitialTextA.resize(buf_len + 1); // UTF-8. we use +1 to make sure that .Data is always pointing to at least an empty string.
|
state->InitialTextA.resize(buf_len + 1); // UTF-8. we use +1 to make sure that .Data is always pointing to at least an empty string.
|
||||||
memcpy(state->InitialTextA.Data, buf, buf_len + 1);
|
memcpy(state->InitialTextA.Data, buf, buf_len + 1);
|
||||||
|
|
||||||
|
// Preserve cursor position and undo/redo stack if we come back to same widget
|
||||||
|
// FIXME: Since we reworked this on 2022/06, may want to differenciate recycle_cursor vs recycle_undostate?
|
||||||
|
bool recycle_state = (state->ID == id && !init_changed_specs);
|
||||||
|
if (recycle_state && (state->CurLenA != buf_len || (state->TextAIsValid && strncmp(state->TextA.Data, buf, buf_len) != 0)))
|
||||||
|
recycle_state = false;
|
||||||
|
|
||||||
// Start edition
|
// Start edition
|
||||||
const char* buf_end = NULL;
|
const char* buf_end = NULL;
|
||||||
|
state->ID = id;
|
||||||
state->TextW.resize(buf_size + 1); // wchar count <= UTF-8 count. we use +1 to make sure that .Data is always pointing to at least an empty string.
|
state->TextW.resize(buf_size + 1); // wchar count <= UTF-8 count. we use +1 to make sure that .Data is always pointing to at least an empty string.
|
||||||
state->TextA.resize(0);
|
state->TextA.resize(0);
|
||||||
state->TextAIsValid = false; // TextA is not valid yet (we will display buf until then)
|
state->TextAIsValid = false; // TextA is not valid yet (we will display buf until then)
|
||||||
state->CurLenW = ImTextStrFromUtf8(state->TextW.Data, buf_size, buf, NULL, &buf_end);
|
state->CurLenW = ImTextStrFromUtf8(state->TextW.Data, buf_size, buf, NULL, &buf_end);
|
||||||
state->CurLenA = (int)(buf_end - buf); // We can't get the result from ImStrncpy() above because it is not UTF-8 aware. Here we'll cut off malformed UTF-8.
|
state->CurLenA = (int)(buf_end - buf); // We can't get the result from ImStrncpy() above because it is not UTF-8 aware. Here we'll cut off malformed UTF-8.
|
||||||
|
|
||||||
// Preserve cursor position and undo/redo stack if we come back to same widget
|
|
||||||
// FIXME: For non-readonly widgets we might be able to require that TextAIsValid && TextA == buf ? (untested) and discard undo stack if user buffer has changed.
|
|
||||||
const bool recycle_state = (state->ID == id && !init_changed_specs);
|
|
||||||
if (recycle_state)
|
if (recycle_state)
|
||||||
{
|
{
|
||||||
// Recycle existing cursor/selection/undo stack but clamp position
|
// Recycle existing cursor/selection/undo stack but clamp position
|
||||||
@ -4067,7 +4072,6 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
state->ID = id;
|
|
||||||
state->ScrollX = 0.0f;
|
state->ScrollX = 0.0f;
|
||||||
stb_textedit_initialize_state(&state->Stb, !is_multiline);
|
stb_textedit_initialize_state(&state->Stb, !is_multiline);
|
||||||
}
|
}
|
||||||
@ -4816,6 +4820,40 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
|||||||
return value_changed;
|
return value_changed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ImGui::DebugNodeInputTextState(ImGuiInputTextState* state)
|
||||||
|
{
|
||||||
|
#ifndef IMGUI_DISABLE_METRICS_WINDOW
|
||||||
|
ImGuiContext& g = *GImGui;
|
||||||
|
ImStb::STB_TexteditState* stb_state = &state->Stb;
|
||||||
|
ImStb::StbUndoState* undo_state = &stb_state->undostate;
|
||||||
|
Text("ID: 0x%08X, ActiveID: 0x%08X", state->ID, g.ActiveId);
|
||||||
|
Text("CurLenW: %d, CurLenA: %d, Cursor: %d, Selection: %d..%d", state->CurLenA, state->CurLenW, stb_state->cursor, stb_state->select_start, stb_state->select_end);
|
||||||
|
Text("undo_point: %d, redo_point: %d, undo_char_point: %d, redo_char_point: %d", undo_state->undo_point, undo_state->redo_point, undo_state->undo_char_point, undo_state->redo_char_point);
|
||||||
|
if (BeginChild("undopoints", ImVec2(0.0f, GetTextLineHeight() * 15), true)) // Visualize undo state
|
||||||
|
{
|
||||||
|
PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0, 0));
|
||||||
|
for (int n = 0; n < STB_TEXTEDIT_UNDOSTATECOUNT; n++)
|
||||||
|
{
|
||||||
|
ImStb::StbUndoRecord* undo_rec = &undo_state->undo_rec[n];
|
||||||
|
const char undo_rec_type = (n < undo_state->undo_point) ? 'u' : (n >= undo_state->redo_point) ? 'r' : ' ';
|
||||||
|
if (undo_rec_type == ' ')
|
||||||
|
BeginDisabled();
|
||||||
|
char buf[64] = "";
|
||||||
|
if (undo_rec_type != ' ' && undo_rec->char_storage != -1)
|
||||||
|
ImTextStrToUtf8(buf, IM_ARRAYSIZE(buf), undo_state->undo_char + undo_rec->char_storage, undo_state->undo_char + undo_rec->char_storage + undo_rec->insert_length);
|
||||||
|
Text("%c [%02d] where %03d, insert %03d, delete %03d, char_storage %03d \"%s\"",
|
||||||
|
undo_rec_type, n, undo_rec->where, undo_rec->insert_length, undo_rec->delete_length, undo_rec->char_storage, buf);
|
||||||
|
if (undo_rec_type == ' ')
|
||||||
|
EndDisabled();
|
||||||
|
}
|
||||||
|
PopStyleVar();
|
||||||
|
}
|
||||||
|
EndChild();
|
||||||
|
#else
|
||||||
|
IM_UNUSED(state);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
//-------------------------------------------------------------------------
|
//-------------------------------------------------------------------------
|
||||||
// [SECTION] Widgets: ColorEdit, ColorPicker, ColorButton, etc.
|
// [SECTION] Widgets: ColorEdit, ColorPicker, ColorButton, etc.
|
||||||
//-------------------------------------------------------------------------
|
//-------------------------------------------------------------------------
|
||||||
|
Loading…
Reference in New Issue
Block a user