[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 (ImGuiTypingSelectRequest* req = ImGui::GetTypingSelectRequest()) focus_idx = ImGui::TypingSelectFindMatch(req, my_items.size(), [](void*, int n) {
| 7540 | // focus_idx = ImGui::TypingSelectFindMatch(req, my_items.size(), [](void*, int n) { return my_items[n]->Name; }, &my_items, -1); |
| 7541 | // However the code is written in a way where calling it from multiple locations is safe (e.g. to obtain buffer). |
| 7542 | ImGuiTypingSelectRequest* ImGui::GetTypingSelectRequest(ImGuiTypingSelectFlags flags) |
| 7543 | { |
| 7544 | ImGuiContext& g = *GImGui; |
| 7545 | ImGuiTypingSelectState* data = &g.TypingSelectState; |
| 7546 | ImGuiTypingSelectRequest* out_request = &data->Request; |
| 7547 | |
| 7548 | // Clear buffer |
| 7549 | const float TYPING_SELECT_RESET_TIMER = 1.80f; // FIXME: Potentially move to IO config. |
| 7550 | const int TYPING_SELECT_SINGLE_CHAR_COUNT_FOR_LOCK = 4; // Lock single char matching when repeating same char 4 times |
| 7551 | if (data->SearchBuffer[0] != 0) |
| 7552 | { |
| 7553 | bool clear_buffer = false; |
| 7554 | clear_buffer |= (g.NavFocusScopeId != data->FocusScope); |
| 7555 | clear_buffer |= (data->LastRequestTime + TYPING_SELECT_RESET_TIMER < g.Time); |
| 7556 | clear_buffer |= g.NavAnyRequest; |
| 7557 | clear_buffer |= g.ActiveId != 0 && g.NavActivateId == 0; // Allow temporary SPACE activation to not interfere |
| 7558 | clear_buffer |= IsKeyPressed(ImGuiKey_Escape) || IsKeyPressed(ImGuiKey_Enter); |
| 7559 | clear_buffer |= IsKeyPressed(ImGuiKey_Backspace) && (flags & ImGuiTypingSelectFlags_AllowBackspace) == 0; |
| 7560 | //if (clear_buffer) { IMGUI_DEBUG_LOG("GetTypingSelectRequest(): Clear SearchBuffer.\n"); } |
| 7561 | if (clear_buffer) |
| 7562 | data->Clear(); |
| 7563 | } |
| 7564 | |
| 7565 | // Append to buffer |
| 7566 | const int buffer_max_len = IM_COUNTOF(data->SearchBuffer) - 1; |
| 7567 | int buffer_len = (int)ImStrlen(data->SearchBuffer); |
| 7568 | bool select_request = false; |
| 7569 | for (ImWchar w : g.IO.InputQueueCharacters) |
| 7570 | { |
| 7571 | const int w_len = ImTextCountUtf8BytesFromStr(&w, &w + 1); |
| 7572 | if (w < 32 || (buffer_len == 0 && ImCharIsBlankW(w)) || (buffer_len + w_len > buffer_max_len)) // Ignore leading blanks |
| 7573 | continue; |
| 7574 | char w_buf[5]; |
| 7575 | ImTextCharToUtf8(w_buf, (unsigned int)w); |
| 7576 | if (data->SingleCharModeLock && w_len == out_request->SingleCharSize && memcmp(w_buf, data->SearchBuffer, w_len) == 0) |
| 7577 | { |
| 7578 | select_request = true; // Same character: don't need to append to buffer. |
| 7579 | continue; |
| 7580 | } |
| 7581 | if (data->SingleCharModeLock) |
| 7582 | { |
| 7583 | data->Clear(); // Different character: clear |
| 7584 | buffer_len = 0; |
| 7585 | } |
| 7586 | memcpy(data->SearchBuffer + buffer_len, w_buf, w_len + 1); // Append |
| 7587 | buffer_len += w_len; |
| 7588 | select_request = true; |
| 7589 | } |
| 7590 | g.IO.InputQueueCharacters.resize(0); |
| 7591 | |
| 7592 | // Handle backspace |
| 7593 | if ((flags & ImGuiTypingSelectFlags_AllowBackspace) && IsKeyPressed(ImGuiKey_Backspace, ImGuiInputFlags_Repeat)) |
| 7594 | { |
| 7595 | char* p = (char*)(void*)ImTextFindPreviousUtf8Codepoint(data->SearchBuffer, data->SearchBuffer + buffer_len); |
| 7596 | *p = 0; |
| 7597 | buffer_len = (int)(p - data->SearchBuffer); |
| 7598 | } |
| 7599 |
nothing calls this directly
no test coverage detected