mirror of
https://github.com/Drezil/imgui.git
synced 2024-11-15 01:17:00 +00:00
TypingSelect: Added first version of GetTypingSelectRequest() API.
# Conflicts: # imgui_internal.h # imgui_widgets.cpp
This commit is contained in:
parent
7812039402
commit
0962c9fb72
@ -23,6 +23,7 @@ Index of this file:
|
|||||||
// [SECTION] Inputs support
|
// [SECTION] Inputs support
|
||||||
// [SECTION] Clipper support
|
// [SECTION] Clipper support
|
||||||
// [SECTION] Navigation support
|
// [SECTION] Navigation support
|
||||||
|
// [SECTION] Typing-select support
|
||||||
// [SECTION] Columns support
|
// [SECTION] Columns support
|
||||||
// [SECTION] Multi-select support
|
// [SECTION] Multi-select support
|
||||||
// [SECTION] Docking support
|
// [SECTION] Docking support
|
||||||
@ -153,6 +154,8 @@ struct ImGuiTableInstanceData; // Storage for one instance of a same table
|
|||||||
struct ImGuiTableTempData; // Temporary storage for one table (one per table in the stack), shared between tables.
|
struct ImGuiTableTempData; // Temporary storage for one table (one per table in the stack), shared between tables.
|
||||||
struct ImGuiTableSettings; // Storage for a table .ini settings
|
struct ImGuiTableSettings; // Storage for a table .ini settings
|
||||||
struct ImGuiTableColumnsSettings; // Storage for a column .ini settings
|
struct ImGuiTableColumnsSettings; // Storage for a column .ini settings
|
||||||
|
struct ImGuiTypingSelectData; // Storage for GetTypingSelectRequest()
|
||||||
|
struct ImGuiTypingSelectRequest; // Storage for GetTypingSelectRequest() (aimed to be public)
|
||||||
struct ImGuiWindow; // Storage for one window
|
struct ImGuiWindow; // Storage for one window
|
||||||
struct ImGuiWindowTempData; // Temporary storage for one window (that's the data which in theory we could ditch at the end of the frame, in practice we currently keep it for each window)
|
struct ImGuiWindowTempData; // Temporary storage for one window (that's the data which in theory we could ditch at the end of the frame, in practice we currently keep it for each window)
|
||||||
struct ImGuiWindowSettings; // Storage for a window .ini settings (we keep one of those even if the actual window wasn't instanced during this session)
|
struct ImGuiWindowSettings; // Storage for a window .ini settings (we keep one of those even if the actual window wasn't instanced during this session)
|
||||||
@ -178,6 +181,7 @@ typedef int ImGuiScrollFlags; // -> enum ImGuiScrollFlags_ // F
|
|||||||
typedef int ImGuiSeparatorFlags; // -> enum ImGuiSeparatorFlags_ // Flags: for SeparatorEx()
|
typedef int ImGuiSeparatorFlags; // -> enum ImGuiSeparatorFlags_ // Flags: for SeparatorEx()
|
||||||
typedef int ImGuiTextFlags; // -> enum ImGuiTextFlags_ // Flags: for TextEx()
|
typedef int ImGuiTextFlags; // -> enum ImGuiTextFlags_ // Flags: for TextEx()
|
||||||
typedef int ImGuiTooltipFlags; // -> enum ImGuiTooltipFlags_ // Flags: for BeginTooltipEx()
|
typedef int ImGuiTooltipFlags; // -> enum ImGuiTooltipFlags_ // Flags: for BeginTooltipEx()
|
||||||
|
typedef int ImGuiTypingSelectFlags; // -> enum ImGuiTypingSelectFlags_ // Flags: for GetTypingSelectRequest()
|
||||||
|
|
||||||
typedef void (*ImGuiErrorLogCallback)(void* user_data, const char* fmt, ...);
|
typedef void (*ImGuiErrorLogCallback)(void* user_data, const char* fmt, ...);
|
||||||
|
|
||||||
@ -1532,6 +1536,39 @@ struct ImGuiNavItemData
|
|||||||
void Clear() { Window = NULL; ID = FocusScopeId = 0; InFlags = 0; DistBox = DistCenter = DistAxial = FLT_MAX; }
|
void Clear() { Window = NULL; ID = FocusScopeId = 0; InFlags = 0; DistBox = DistCenter = DistAxial = FLT_MAX; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// [SECTION] Typing-select support
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Flags for GetTypingSelectRequest()
|
||||||
|
enum ImGuiTypingSelectFlags_
|
||||||
|
{
|
||||||
|
ImGuiTypingSelectFlags_None = 0,
|
||||||
|
ImGuiTypingSelectFlags_AllowBackspace = 1 << 0, // Backspace to delete character inputs. If using: ensure GetTypingSelectRequest() is not called more than once per frame (filter by e.g. focus state)
|
||||||
|
};
|
||||||
|
|
||||||
|
// Returned by GetTypingSelectRequest(), designed to eventually be public.
|
||||||
|
struct IMGUI_API ImGuiTypingSelectRequest
|
||||||
|
{
|
||||||
|
const char* SearchBuffer;
|
||||||
|
int SearchBufferLen;
|
||||||
|
bool SelectRequest; // Set when buffer was modified this frame, requesting a selection.
|
||||||
|
bool RepeatCharMode; // Notify when buffer contains same character repeated, to implement special mode.
|
||||||
|
ImS8 RepeatCharSize; // Length in bytes of first letter codepoint (1 for ascii, 2-4 for UTF-8). If (SearchBufferLen==RepeatCharSize) only 1 letter has been input.
|
||||||
|
};
|
||||||
|
|
||||||
|
// Storage for GetTypingSelectRequest()
|
||||||
|
struct IMGUI_API ImGuiTypingSelectData
|
||||||
|
{
|
||||||
|
ImGuiTypingSelectRequest Request; // User-facing data
|
||||||
|
char SearchBuffer[64]; // Search buffer: no need to make dynamic as this search is very transient.
|
||||||
|
ImGuiID FocusScope;
|
||||||
|
int LastRequestFrame = 0;
|
||||||
|
float LastRequestTime = 0.0f;
|
||||||
|
|
||||||
|
ImGuiTypingSelectData() { memset(this, 0, sizeof(*this)); }
|
||||||
|
};
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// [SECTION] Columns support
|
// [SECTION] Columns support
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
@ -2019,6 +2056,7 @@ struct ImGuiContext
|
|||||||
short TooltipOverrideCount;
|
short TooltipOverrideCount;
|
||||||
ImVector<char> ClipboardHandlerData; // If no custom clipboard handler is defined
|
ImVector<char> ClipboardHandlerData; // If no custom clipboard handler is defined
|
||||||
ImVector<ImGuiID> MenusIdSubmittedThisFrame; // A list of menu IDs that were rendered at least once
|
ImVector<ImGuiID> MenusIdSubmittedThisFrame; // A list of menu IDs that were rendered at least once
|
||||||
|
ImGuiTypingSelectData TypingSelectData;
|
||||||
|
|
||||||
// Platform support
|
// Platform support
|
||||||
ImGuiPlatformImeData PlatformImeData; // Data updated by current frame
|
ImGuiPlatformImeData PlatformImeData; // Data updated by current frame
|
||||||
@ -3057,6 +3095,9 @@ namespace ImGui
|
|||||||
IMGUI_API bool IsDragDropPayloadBeingAccepted();
|
IMGUI_API bool IsDragDropPayloadBeingAccepted();
|
||||||
IMGUI_API void RenderDragDropTargetRect(const ImRect& bb);
|
IMGUI_API void RenderDragDropTargetRect(const ImRect& bb);
|
||||||
|
|
||||||
|
// Typing-Select API
|
||||||
|
IMGUI_API const ImGuiTypingSelectRequest* GetTypingSelectRequest(ImGuiTypingSelectFlags flags = ImGuiTypingSelectFlags_None);
|
||||||
|
|
||||||
// Internal Columns API (this is not exposed because we will encourage transitioning to the Tables API)
|
// Internal Columns API (this is not exposed because we will encourage transitioning to the Tables API)
|
||||||
IMGUI_API void SetWindowClipRectBeforeSetChannel(ImGuiWindow* window, const ImRect& clip_rect);
|
IMGUI_API void SetWindowClipRectBeforeSetChannel(ImGuiWindow* window, const ImRect& clip_rect);
|
||||||
IMGUI_API void BeginColumns(const char* str_id, int count, ImGuiOldColumnFlags flags = 0); // setup number of columns. use an identifier to distinguish multiple column sets. close with EndColumns().
|
IMGUI_API void BeginColumns(const char* str_id, int count, ImGuiOldColumnFlags flags = 0); // setup number of columns. use an identifier to distinguish multiple column sets. close with EndColumns().
|
||||||
|
@ -18,6 +18,7 @@ Index of this file:
|
|||||||
// [SECTION] Widgets: ColorEdit, ColorPicker, ColorButton, etc.
|
// [SECTION] Widgets: ColorEdit, ColorPicker, ColorButton, etc.
|
||||||
// [SECTION] Widgets: TreeNode, CollapsingHeader, etc.
|
// [SECTION] Widgets: TreeNode, CollapsingHeader, etc.
|
||||||
// [SECTION] Widgets: Selectable
|
// [SECTION] Widgets: Selectable
|
||||||
|
// [SECTION] Widgets: Typing-Select support
|
||||||
// [SECTION] Widgets: ListBox
|
// [SECTION] Widgets: ListBox
|
||||||
// [SECTION] Widgets: PlotLines, PlotHistogram
|
// [SECTION] Widgets: PlotLines, PlotHistogram
|
||||||
// [SECTION] Widgets: Value helpers
|
// [SECTION] Widgets: Value helpers
|
||||||
@ -6597,6 +6598,103 @@ bool ImGui::Selectable(const char* label, bool* p_selected, ImGuiSelectableFlags
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
// [SECTION] Widgets: Typing-Select support
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// [Experimental] Currently not exposed in public API.
|
||||||
|
// Consume character inputs and return search request, if any.
|
||||||
|
// This would typically only be called on the focused window or location you want to grab inputs for, e.g.
|
||||||
|
// if (ImGui::IsWindowFocused(...))
|
||||||
|
// if (const ImGuiTypingSelectRequest* req = ImGui::GetTypingSelectRequest())
|
||||||
|
// if (req->SearchRequest)
|
||||||
|
// // perform search
|
||||||
|
// However the code is written in a way where calling it from multiple locations is safe (e.g. to obtain buffer).
|
||||||
|
const ImGuiTypingSelectRequest* ImGui::GetTypingSelectRequest(ImGuiTypingSelectFlags flags)
|
||||||
|
{
|
||||||
|
ImGuiContext& g = *GImGui;
|
||||||
|
ImGuiTypingSelectData* data = &g.TypingSelectData;
|
||||||
|
ImGuiTypingSelectRequest* out_request = &data->Request;
|
||||||
|
|
||||||
|
// Clear buffer
|
||||||
|
if (data->SearchBuffer[0] != 0)
|
||||||
|
{
|
||||||
|
const float TYPING_SELECT_RESET_TIMER = 1.70f; // FIXME: Potentially move to IO config.
|
||||||
|
bool clear_buffer = false;
|
||||||
|
clear_buffer |= (g.NavFocusScopeId != data->FocusScope);
|
||||||
|
clear_buffer |= (data->LastRequestTime + TYPING_SELECT_RESET_TIMER < g.Time);
|
||||||
|
clear_buffer |= g.NavAnyRequest;
|
||||||
|
clear_buffer |= g.ActiveId != 0 && g.NavActivateId == 0; // Allow temporary SPACE activation to not interfere
|
||||||
|
clear_buffer |= IsKeyPressed(ImGuiKey_Escape) || IsKeyPressed(ImGuiKey_Enter);
|
||||||
|
clear_buffer |= IsKeyPressed(ImGuiKey_Backspace) && (flags & ImGuiTypingSelectFlags_AllowBackspace) == 0;
|
||||||
|
//if (clear_buffer) { IMGUI_DEBUG_LOG("GetTypingSelectRequest(): Clear SearchBuffer.\n"); }
|
||||||
|
if (clear_buffer)
|
||||||
|
data->SearchBuffer[0] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Append to buffer
|
||||||
|
const int buffer_max_len = IM_ARRAYSIZE(data->SearchBuffer) - 1;
|
||||||
|
int buffer_len = (int)strlen(data->SearchBuffer);
|
||||||
|
bool buffer_changed = false;
|
||||||
|
for (ImWchar w : g.IO.InputQueueCharacters)
|
||||||
|
{
|
||||||
|
if (w < 32 || (buffer_len == 0 && ImCharIsBlankW(w))) // Ignore leading blanks
|
||||||
|
continue;
|
||||||
|
int utf8_len = ImTextCountUtf8BytesFromStr(&w, &w + 1);
|
||||||
|
if (buffer_len + utf8_len > buffer_max_len)
|
||||||
|
break;
|
||||||
|
ImTextCharToUtf8(data->SearchBuffer + buffer_len, (unsigned int)w);
|
||||||
|
buffer_len += utf8_len;
|
||||||
|
buffer_changed = true;
|
||||||
|
}
|
||||||
|
g.IO.InputQueueCharacters.resize(0);
|
||||||
|
if ((flags & ImGuiTypingSelectFlags_AllowBackspace) && IsKeyPressed(ImGuiKey_Backspace, 0, ImGuiInputFlags_Repeat))
|
||||||
|
{
|
||||||
|
char* p = (char*)(void*)ImTextFindPreviousUtf8Codepoint(data->SearchBuffer, data->SearchBuffer + buffer_len);
|
||||||
|
*p = 0;
|
||||||
|
buffer_len = (int)(p - data->SearchBuffer);
|
||||||
|
}
|
||||||
|
if (buffer_len == 0)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
// Return request if any
|
||||||
|
if (buffer_changed)
|
||||||
|
{
|
||||||
|
data->FocusScope = g.NavFocusScopeId;
|
||||||
|
data->LastRequestFrame = g.FrameCount;
|
||||||
|
data->LastRequestTime = (float)g.Time;
|
||||||
|
}
|
||||||
|
out_request->SearchBuffer = data->SearchBuffer;
|
||||||
|
out_request->SearchBufferLen = buffer_len;
|
||||||
|
out_request->SelectRequest = (data->LastRequestFrame == g.FrameCount);
|
||||||
|
out_request->RepeatCharMode = false;
|
||||||
|
out_request->RepeatCharSize = 0;
|
||||||
|
|
||||||
|
// Calculate if buffer contains the same character repeated.
|
||||||
|
// - This can be used to implement a special search mode on first character.
|
||||||
|
// - Performed on UTF-8 codepoint for correctness.
|
||||||
|
// - RepeatCharMode is always set for first input character, because it usually leads to a "next".
|
||||||
|
const char* buf_begin = out_request->SearchBuffer;
|
||||||
|
const char* buf_end = out_request->SearchBuffer + out_request->SearchBufferLen;
|
||||||
|
const int c0_len = ImTextCountUtf8BytesFromChar(buf_begin, buf_end);
|
||||||
|
const char* p = buf_begin + c0_len;
|
||||||
|
for (; p < buf_end; p += c0_len)
|
||||||
|
if (memcmp(buf_begin, p, (size_t)c0_len) != 0)
|
||||||
|
break;
|
||||||
|
out_request->RepeatCharMode = (p == buf_end);
|
||||||
|
out_request->RepeatCharSize = out_request->RepeatCharMode ? (ImS8)c0_len : 0;
|
||||||
|
|
||||||
|
return out_request;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
// [SECTION] Widgets: Multi-Select support
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
//-------------------------------------------------------------------------
|
//-------------------------------------------------------------------------
|
||||||
// [SECTION] Widgets: ListBox
|
// [SECTION] Widgets: ListBox
|
||||||
//-------------------------------------------------------------------------
|
//-------------------------------------------------------------------------
|
||||||
|
Loading…
Reference in New Issue
Block a user