mirror of
https://github.com/ocornut/imgui.git
synced 2024-11-27 16:29:02 +08:00
InputText: Internal: added reload from user-buf feature. (#2890)
Very highly requested feature (#6962, #5219, #3290, #4627, #5054, #3878, #2881, #1506, #1216, #968). Also useful for interactive completion/selection popups (#2057, #718) Based on @kudaba PR. Design for Inputtext V2 should make this obsolete.
This commit is contained in:
parent
f50ddc431e
commit
06ce312745
@ -68,8 +68,10 @@ Other changes:
|
|||||||
update stopped setting default values. (#7232) [@GrigoryGraborenko]
|
update stopped setting default values. (#7232) [@GrigoryGraborenko]
|
||||||
- Backends: WebGPU: Fixed pipeline layout leak. (#7245) [@rajveermalviya]
|
- Backends: WebGPU: Fixed pipeline layout leak. (#7245) [@rajveermalviya]
|
||||||
- Backends: OpenGL3: Backup and restore GL_PIXEL_UNPACK_BUFFER. (#7253)
|
- Backends: OpenGL3: Backup and restore GL_PIXEL_UNPACK_BUFFER. (#7253)
|
||||||
- Internals: Various improvements related to yet unpublicized shortcut routing and input ownership
|
- Internals: Many improvements related to yet unpublicized shortcut routing and input ownership systems.
|
||||||
systems.
|
- Internals: InputText: Add way to force reload of user-buf when active. (#2890) [@kudaba, @ocornut]
|
||||||
|
Often requested in some form (#6962, #5219, #3290, #4627, #5054, #3878, #2881, #1506, #1216, #968),
|
||||||
|
and useful for interactive completion/suggestions popups (#2057, #718)
|
||||||
|
|
||||||
|
|
||||||
-----------------------------------------------------------------------
|
-----------------------------------------------------------------------
|
||||||
|
@ -12257,6 +12257,8 @@ void ImGui::NavMoveRequestApplyResult()
|
|||||||
g.NavWindow = result->Window;
|
g.NavWindow = result->Window;
|
||||||
g.NavLastValidSelectionUserData = ImGuiSelectionUserData_Invalid;
|
g.NavLastValidSelectionUserData = ImGuiSelectionUserData_Invalid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FIXME: Could become optional e.g. ImGuiNavMoveFlags_NoClearActiveId if we later want to apply navigation requests without altering active input.
|
||||||
if (g.ActiveId != result->ID)
|
if (g.ActiveId != result->ID)
|
||||||
ClearActiveID();
|
ClearActiveID();
|
||||||
|
|
||||||
|
2
imgui.h
2
imgui.h
@ -24,7 +24,7 @@
|
|||||||
// Library Version
|
// Library Version
|
||||||
// (Integer encoded as XYYZZ for use in #if preprocessor conditionals, e.g. '#if IMGUI_VERSION_NUM >= 12345')
|
// (Integer encoded as XYYZZ for use in #if preprocessor conditionals, e.g. '#if IMGUI_VERSION_NUM >= 12345')
|
||||||
#define IMGUI_VERSION "1.90.2 WIP"
|
#define IMGUI_VERSION "1.90.2 WIP"
|
||||||
#define IMGUI_VERSION_NUM 19016
|
#define IMGUI_VERSION_NUM 19017
|
||||||
#define IMGUI_HAS_TABLE
|
#define IMGUI_HAS_TABLE
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1079,6 +1079,9 @@ struct IMGUI_API ImGuiInputTextState
|
|||||||
bool SelectedAllMouseLock; // after a double-click to select all, we ignore further mouse drags to update selection
|
bool SelectedAllMouseLock; // after a double-click to select all, we ignore further mouse drags to update selection
|
||||||
bool Edited; // edited this frame
|
bool Edited; // edited this frame
|
||||||
ImGuiInputTextFlags Flags; // copy of InputText() flags. may be used to check if e.g. ImGuiInputTextFlags_Password is set.
|
ImGuiInputTextFlags Flags; // copy of InputText() flags. may be used to check if e.g. ImGuiInputTextFlags_Password is set.
|
||||||
|
bool ReloadUserBuf; // force a reload of user buf so it may be modified externally. may be automatic in future version.
|
||||||
|
int ReloadSelectionStart; // POSITIONS ARE IN IMWCHAR units *NOT* UTF-8 this is why this is not exposed yet.
|
||||||
|
int ReloadSelectionEnd;
|
||||||
|
|
||||||
ImGuiInputTextState() { memset(this, 0, sizeof(*this)); }
|
ImGuiInputTextState() { memset(this, 0, sizeof(*this)); }
|
||||||
void ClearText() { CurLenW = CurLenA = 0; TextW[0] = 0; TextA[0] = 0; CursorClamp(); }
|
void ClearText() { CurLenW = CurLenA = 0; TextW[0] = 0; TextA[0] = 0; CursorClamp(); }
|
||||||
@ -1096,6 +1099,16 @@ struct IMGUI_API ImGuiInputTextState
|
|||||||
int GetSelectionStart() const { return Stb.select_start; }
|
int GetSelectionStart() const { return Stb.select_start; }
|
||||||
int GetSelectionEnd() const { return Stb.select_end; }
|
int GetSelectionEnd() const { return Stb.select_end; }
|
||||||
void SelectAll() { Stb.select_start = 0; Stb.cursor = Stb.select_end = CurLenW; Stb.has_preferred_x = 0; }
|
void SelectAll() { Stb.select_start = 0; Stb.cursor = Stb.select_end = CurLenW; Stb.has_preferred_x = 0; }
|
||||||
|
|
||||||
|
// Reload user buf (WIP #2890)
|
||||||
|
// If you modify underlying user-passed const char* while active you need to call this (InputText V2 may lift this)
|
||||||
|
// strcpy(my_buf, "hello");
|
||||||
|
// if (ImGuiInputTextState* state = ImGui::GetInputTextState(id)) // id may be ImGui::GetItemID() is last item
|
||||||
|
// state->ReloadUserBufAndSelectAll();
|
||||||
|
void ReloadUserBufAndSelectAll() { ReloadUserBuf = true; ReloadSelectionStart = 0; ReloadSelectionEnd = INT_MAX; }
|
||||||
|
void ReloadUserBufAndKeepSelection() { ReloadUserBuf = true; ReloadSelectionStart = Stb.select_start; ReloadSelectionEnd = Stb.select_end; }
|
||||||
|
void ReloadUserBufAndMoveToEnd() { ReloadUserBuf = true; ReloadSelectionStart = ReloadSelectionEnd = INT_MAX; }
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
enum ImGuiNextWindowDataFlags_
|
enum ImGuiNextWindowDataFlags_
|
||||||
|
@ -4185,14 +4185,16 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
|||||||
|
|
||||||
float scroll_y = is_multiline ? draw_window->Scroll.y : FLT_MAX;
|
float scroll_y = is_multiline ? draw_window->Scroll.y : FLT_MAX;
|
||||||
|
|
||||||
|
const bool init_reload_from_user_buf = (state != NULL && state->ReloadUserBuf);
|
||||||
const bool init_changed_specs = (state != NULL && state->Stb.single_line != !is_multiline); // state != NULL means its our state.
|
const bool init_changed_specs = (state != NULL && state->Stb.single_line != !is_multiline); // state != NULL means its our state.
|
||||||
const bool init_make_active = (user_clicked || user_scroll_finish || input_requested_by_nav);
|
const bool init_make_active = (user_clicked || user_scroll_finish || input_requested_by_nav);
|
||||||
const bool init_state = (init_make_active || user_scroll_active);
|
const bool init_state = (init_make_active || user_scroll_active);
|
||||||
if ((init_state && g.ActiveId != id) || init_changed_specs)
|
if ((init_state && g.ActiveId != id) || init_changed_specs || init_reload_from_user_buf)
|
||||||
{
|
{
|
||||||
// Access state even if we don't own it yet.
|
// Access state even if we don't own it yet.
|
||||||
state = &g.InputTextState;
|
state = &g.InputTextState;
|
||||||
state->CursorAnimReset();
|
state->CursorAnimReset();
|
||||||
|
state->ReloadUserBuf = false;
|
||||||
|
|
||||||
// Backup state of deactivating item so they'll have a chance to do a write to output buffer on the same frame they report IsItemDeactivatedAfterEdit (#4714)
|
// Backup state of deactivating item so they'll have a chance to do a write to output buffer on the same frame they report IsItemDeactivatedAfterEdit (#4714)
|
||||||
InputTextDeactivateHook(state->ID);
|
InputTextDeactivateHook(state->ID);
|
||||||
@ -4204,8 +4206,8 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
|||||||
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
|
// 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?
|
// FIXME: Since we reworked this on 2022/06, may want to differentiate recycle_cursor vs recycle_undostate?
|
||||||
bool recycle_state = (state->ID == id && !init_changed_specs);
|
bool recycle_state = (state->ID == id && !init_changed_specs && !init_reload_from_user_buf);
|
||||||
if (recycle_state && (state->CurLenA != buf_len || (state->TextAIsValid && strncmp(state->TextA.Data, buf, buf_len) != 0)))
|
if (recycle_state && (state->CurLenA != buf_len || (state->TextAIsValid && strncmp(state->TextA.Data, buf, buf_len) != 0)))
|
||||||
recycle_state = false;
|
recycle_state = false;
|
||||||
|
|
||||||
@ -4230,7 +4232,13 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
|||||||
stb_textedit_initialize_state(&state->Stb, !is_multiline);
|
stb_textedit_initialize_state(&state->Stb, !is_multiline);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!is_multiline)
|
if (init_reload_from_user_buf)
|
||||||
|
{
|
||||||
|
state->Stb.select_start = state->ReloadSelectionStart;
|
||||||
|
state->Stb.cursor = state->Stb.select_end = state->ReloadSelectionEnd;
|
||||||
|
state->CursorClamp();
|
||||||
|
}
|
||||||
|
else if (!is_multiline)
|
||||||
{
|
{
|
||||||
if (flags & ImGuiInputTextFlags_AutoSelectAll)
|
if (flags & ImGuiInputTextFlags_AutoSelectAll)
|
||||||
select_all = true;
|
select_all = true;
|
||||||
|
Loading…
Reference in New Issue
Block a user