From da299a002ca3b72ff0f9d409dad8ab56857f5dab Mon Sep 17 00:00:00 2001 From: Kawe Mazidjatari <48657826+Mauler125@users.noreply.github.com> Date: Mon, 20 Jun 2022 20:21:52 +0200 Subject: [PATCH] Reimplement text filter Could be better at some point, currently removes anything not matching criteria resulting in gaps. But on the other side it might be good as the location of all occurrences are known (should make it easier to see when it is logged during the process). Revisit in the future. --- r5dev/gameui/IConsole.cpp | 4 +- r5dev/gameui/IConsole.h | 1 - r5dev/thirdparty/imgui/include/imgui_logger.h | 12 +- r5dev/thirdparty/imgui/src/imgui_logger.cpp | 295 ++++++++++-------- 4 files changed, 174 insertions(+), 138 deletions(-) diff --git a/r5dev/gameui/IConsole.cpp b/r5dev/gameui/IConsole.cpp index 508ca97c..98dfbc1a 100644 --- a/r5dev/gameui/IConsole.cpp +++ b/r5dev/gameui/IConsole.cpp @@ -218,7 +218,7 @@ void CConsole::BasePanel(void) } ImGui::SameLine(); - m_itFilter.Draw("Filter | ", flFooterWidthReserve - 500); + m_Logger.m_itFilter.Draw("Filter | ", flFooterWidthReserve - 500); ImGui::SameLine(); ImGui::Text(m_szSummary); @@ -806,7 +806,7 @@ void CConsole::AddLog(const ImVec4& color, const char* fmt, ...) IM_FMTARGS(2) //----------------------------------------------------------------------------- void CConsole::ClearLog(void) { - m_Logger.RemoveLine(0, m_Logger.GetTotalLines()); + m_Logger.RemoveLine(0, m_Logger.GetTotalLines() - 1); } //----------------------------------------------------------------------------- diff --git a/r5dev/gameui/IConsole.h b/r5dev/gameui/IConsole.h index 7baf0234..bc086a7c 100644 --- a/r5dev/gameui/IConsole.h +++ b/r5dev/gameui/IConsole.h @@ -36,7 +36,6 @@ private: int m_nHistoryPos = -1; int m_nScrollBack = 0; float m_flFadeAlpha = 0.f; - ImGuiTextFilter m_itFilter; bool m_bInitialized = false; bool m_bDefaultTheme = false; bool m_bReclaimFocus = false; diff --git a/r5dev/thirdparty/imgui/include/imgui_logger.h b/r5dev/thirdparty/imgui/include/imgui_logger.h index 2ba7a8fa..7d8a4903 100644 --- a/r5dev/thirdparty/imgui/include/imgui_logger.h +++ b/r5dev/thirdparty/imgui/include/imgui_logger.h @@ -120,12 +120,15 @@ public: void SetTextLines(const std::vector<CConLog>& aLines); std::vector<std::string> GetTextLines() const; + ImGuiTextFilter GetFilter() const { return m_itFilter; }; std::string GetSelectedText() const; - std::string GetCurrentLineText()const; + std::string GetCurrentLineText() const; + std::string GetTextFromLine(const Line& aLine) const; + int GetTotalFilterMatches() const; int GetTotalLines() const { return (int)m_Lines.size(); } - bool IsOverwrite() const { return m_Overwrite; } + bool IsOverwrite() const { return m_Overwrite; } bool IsCursorPositionChanged() const { return m_bCursorPositionChanged; } Coordinates GetCursorPosition() const { return GetActualCursorCoordinates(); } @@ -167,7 +170,6 @@ public: void Copy(); private: - struct EditorState { Coordinates m_SelectionStart; @@ -226,6 +228,8 @@ private: Coordinates m_InteractiveEnd; std::string m_svLineBuffer; uint64_t m_nStartTime; - float m_flLastClick; + +public: + ImGuiTextFilter m_itFilter; }; diff --git a/r5dev/thirdparty/imgui/src/imgui_logger.cpp b/r5dev/thirdparty/imgui/src/imgui_logger.cpp index 2b9364d8..8be8b825 100644 --- a/r5dev/thirdparty/imgui/src/imgui_logger.cpp +++ b/r5dev/thirdparty/imgui/src/imgui_logger.cpp @@ -739,166 +739,168 @@ void CTextLogger::Render() auto lineMax = std::max(0, std::min((int)m_Lines.size() - 1, lineNo + (int)floor((scrollY + contentSize.y) / m_CharAdvance.y))); //m_flTextStart = ImGui::GetFont()->CalcTextSizeA(ImGui::GetFontSize(), FLT_MAX, -1.0f, buf, nullptr, nullptr).x + m_nLeftMargin; - if (!m_Lines.empty()) { float spaceSize = ImGui::GetFont()->CalcTextSizeA(ImGui::GetFontSize(), FLT_MAX, -1.0f, " ", nullptr, nullptr).x; - while (lineNo <= lineMax) { - ImVec2 lineStartScreenPos = ImVec2(cursorScreenPos.x, cursorScreenPos.y + lineNo * m_CharAdvance.y); - ImVec2 textScreenPos = ImVec2(lineStartScreenPos.x + m_flTextStart, lineStartScreenPos.y); - auto& line = m_Lines[lineNo]; - longest = std::max(m_flTextStart + TextDistanceToLineStart(Coordinates(lineNo, GetLineMaxColumn(lineNo))), longest); - auto columnNo = 0; - Coordinates lineStartCoord(lineNo, 0); - Coordinates lineEndCoord(lineNo, GetLineMaxColumn(lineNo)); - - // Draw selection for the current line - float sstart = -1.0f; - float ssend = -1.0f; - - assert(m_State.m_SelectionStart <= m_State.m_SelectionEnd); - if (m_State.m_SelectionStart <= lineEndCoord) - sstart = m_State.m_SelectionStart > lineStartCoord ? TextDistanceToLineStart(m_State.m_SelectionStart) : 0.0f; - if (m_State.m_SelectionEnd > lineStartCoord) - ssend = TextDistanceToLineStart(m_State.m_SelectionEnd < lineEndCoord ? m_State.m_SelectionEnd : lineEndCoord); - - if (m_State.m_SelectionEnd.m_nLine > lineNo) - ssend += m_CharAdvance.x; - - if (sstart != -1 && ssend != -1 && sstart < ssend) + if (m_itFilter.PassFilter(GetTextFromLine(line).c_str())) { - ImVec2 vstart(lineStartScreenPos.x + m_flTextStart + sstart, lineStartScreenPos.y); - ImVec2 vend(lineStartScreenPos.x + m_flTextStart + ssend, lineStartScreenPos.y + m_CharAdvance.y); - drawList->AddRectFilled(vstart, vend, ImGui::GetColorU32(ImGuiCol_TextSelectedBg)); - } + ImVec2 lineStartScreenPos = ImVec2(cursorScreenPos.x, cursorScreenPos.y + lineNo * m_CharAdvance.y); + ImVec2 textScreenPos = ImVec2(lineStartScreenPos.x + m_flTextStart, lineStartScreenPos.y); - if (m_State.m_CursorPosition.m_nLine == lineNo) - { - bool focused = ImGui::IsWindowFocused(); - ImVec2 start = ImVec2(lineStartScreenPos.x + scrollX, lineStartScreenPos.y); + longest = std::max(m_flTextStart + TextDistanceToLineStart(Coordinates(lineNo, GetLineMaxColumn(lineNo))), longest); + auto columnNo = 0; + Coordinates lineStartCoord(lineNo, 0); + Coordinates lineEndCoord(lineNo, GetLineMaxColumn(lineNo)); - // Highlight the current line (where the cursor is) - //if (!HasSelection()) - //{ - // auto end = ImVec2(start.x + contentSize.x + scrollX, start.y + m_CharAdvance.y); - // drawList->AddRectFilled(start, end, 0x80a06020); - // drawList->AddRect(start, end, 0x80a06020, 1.0f); - //} + // Draw selection for the current line + float sstart = -1.0f; + float ssend = -1.0f; - // Render the cursor - if (focused) + assert(m_State.m_SelectionStart <= m_State.m_SelectionEnd); + if (m_State.m_SelectionStart <= lineEndCoord) + sstart = m_State.m_SelectionStart > lineStartCoord ? TextDistanceToLineStart(m_State.m_SelectionStart) : 0.0f; + if (m_State.m_SelectionEnd > lineStartCoord) + ssend = TextDistanceToLineStart(m_State.m_SelectionEnd < lineEndCoord ? m_State.m_SelectionEnd : lineEndCoord); + + if (m_State.m_SelectionEnd.m_nLine > lineNo) + ssend += m_CharAdvance.x; + + if (sstart != -1 && ssend != -1 && sstart < ssend) { - auto timeEnd = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).count(); - auto elapsed = timeEnd - m_nStartTime; - if (elapsed > 400) - { - float width = 1.0f; - auto cindex = GetCharacterIndex(m_State.m_CursorPosition); - float cx = TextDistanceToLineStart(m_State.m_CursorPosition); + ImVec2 vstart(lineStartScreenPos.x + m_flTextStart + sstart, lineStartScreenPos.y); + ImVec2 vend(lineStartScreenPos.x + m_flTextStart + ssend, lineStartScreenPos.y + m_CharAdvance.y); + drawList->AddRectFilled(vstart, vend, ImGui::GetColorU32(ImGuiCol_TextSelectedBg)); + } - if (m_Overwrite && cindex < (int)line.size()) + if (m_State.m_CursorPosition.m_nLine == lineNo) + { + bool focused = ImGui::IsWindowFocused(); + ImVec2 start = ImVec2(lineStartScreenPos.x + scrollX, lineStartScreenPos.y); + + // Highlight the current line (where the cursor is) + //if (!HasSelection()) + //{ + // auto end = ImVec2(start.x + contentSize.x + scrollX, start.y + m_CharAdvance.y); + // drawList->AddRectFilled(start, end, 0x80a06020); + // drawList->AddRect(start, end, 0x80a06020, 1.0f); + //} + + // Render the cursor + if (focused) + { + auto timeEnd = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).count(); + auto elapsed = timeEnd - m_nStartTime; + if (elapsed > 400) { - auto c = line[cindex].m_Char; - if (c == '\t') + float width = 1.0f; + auto cindex = GetCharacterIndex(m_State.m_CursorPosition); + float cx = TextDistanceToLineStart(m_State.m_CursorPosition); + + if (m_Overwrite && cindex < (int)line.size()) { - auto x = (1.0f + std::floor((1.0f + cx) / (float(m_nTabSize) * spaceSize))) * (float(m_nTabSize) * spaceSize); - width = x - cx; - } - else - { - char buf2[2]; - buf2[0] = line[cindex].m_Char; - buf2[1] = '\0'; - width = ImGui::GetFont()->CalcTextSizeA(ImGui::GetFontSize(), FLT_MAX, -1.0f, buf2).x; + auto c = line[cindex].m_Char; + if (c == '\t') + { + auto x = (1.0f + std::floor((1.0f + cx) / (float(m_nTabSize) * spaceSize))) * (float(m_nTabSize) * spaceSize); + width = x - cx; + } + else + { + char buf2[2]; + buf2[0] = line[cindex].m_Char; + buf2[1] = '\0'; + width = ImGui::GetFont()->CalcTextSizeA(ImGui::GetFontSize(), FLT_MAX, -1.0f, buf2).x; + } } + ImVec2 cstart(textScreenPos.x + cx, lineStartScreenPos.y); + ImVec2 cend(textScreenPos.x + cx + width, lineStartScreenPos.y + m_CharAdvance.y); + drawList->AddRectFilled(cstart, cend, 0xffe0e0e0); + if (elapsed > 800) + m_nStartTime = timeEnd; } - ImVec2 cstart(textScreenPos.x + cx, lineStartScreenPos.y); - ImVec2 cend(textScreenPos.x + cx + width, lineStartScreenPos.y + m_CharAdvance.y); - drawList->AddRectFilled(cstart, cend, 0xffe0e0e0); - if (elapsed > 800) - m_nStartTime = timeEnd; } } - } - // Render colorized text - //auto prevColor = GetGlyphColor(line[0]); - ImVec2 bufferOffset; + // Render colorized text + //auto prevColor = GetGlyphColor(line[0]); + ImVec2 bufferOffset; - for (size_t i = 0; i < line.size();) - { - auto& glyph = line[i]; - auto color = GetGlyphColor(glyph); + for (size_t i = 0; i < line.size();) + { + auto& glyph = line[i]; + auto color = GetGlyphColor(glyph); - if ((glyph.m_Char == '\t' || glyph.m_Char == '\n' || glyph.m_Char == ' ') && !m_svLineBuffer.empty()) + if ((glyph.m_Char == '\t' || glyph.m_Char == '\n' || glyph.m_Char == ' ') && !m_svLineBuffer.empty()) + { + const ImVec2 newOffset(textScreenPos.x + bufferOffset.x, textScreenPos.y + bufferOffset.y); + drawList->AddText(newOffset, color, m_svLineBuffer.c_str()); + auto textSize = ImGui::GetFont()->CalcTextSizeA(ImGui::GetFontSize(), FLT_MAX, -1.0f, m_svLineBuffer.c_str(), nullptr, nullptr); + bufferOffset.x += textSize.x; + m_svLineBuffer.clear(); + } + + if (glyph.m_Char == '\t' || glyph.m_Char == '\n') + { + auto oldX = bufferOffset.x; + bufferOffset.x = (1.0f + std::floor((1.0f + bufferOffset.x) / (float(m_nTabSize) * spaceSize))) * (float(m_nTabSize) * spaceSize); + ++i; + + if (m_bShowWhiteSpaces) + { + const auto s = ImGui::GetFontSize(); + const auto x1 = textScreenPos.x + oldX + 1.0f; + const auto x2 = textScreenPos.x + bufferOffset.x - 1.0f; + const auto y = textScreenPos.y + bufferOffset.y + s * 0.5f; + const ImVec2 p1(x1, y); + const ImVec2 p2(x2, y); + const ImVec2 p3(x2 - s * 0.2f, y - s * 0.2f); + const ImVec2 p4(x2 - s * 0.2f, y + s * 0.2f); + drawList->AddLine(p1, p2, 0x90909090); + drawList->AddLine(p2, p3, 0x90909090); + drawList->AddLine(p2, p4, 0x90909090); + } + } + else if (glyph.m_Char == ' ') + { + if (m_bShowWhiteSpaces) + { + const auto s = ImGui::GetFontSize(); + const auto x = textScreenPos.x + bufferOffset.x + spaceSize * 0.5f; + const auto y = textScreenPos.y + bufferOffset.y + s * 0.5f; + drawList->AddCircleFilled(ImVec2(x, y), 1.5f, 0x80808080, 4); + } + bufferOffset.x += spaceSize; + i++; + } + else + { + m_svLineBuffer.push_back(line[i++].m_Char); + //auto l = UTF8CharLength(glyph.m_Char); // !TODO: (this currently causes crashes) + //while (l-- > 0) + //{ + // m_svLineBuffer.push_back(line[i++].m_Char); + //} + } + ++columnNo; + } + + if (!m_svLineBuffer.empty()) { const ImVec2 newOffset(textScreenPos.x + bufferOffset.x, textScreenPos.y + bufferOffset.y); - drawList->AddText(newOffset, color, m_svLineBuffer.c_str()); - auto textSize = ImGui::GetFont()->CalcTextSizeA(ImGui::GetFontSize(), FLT_MAX, -1.0f, m_svLineBuffer.c_str(), nullptr, nullptr); - bufferOffset.x += textSize.x; + drawList->AddText(newOffset, 0xffffffff, m_svLineBuffer.c_str()); // COLOR (obtain from glyph?) m_svLineBuffer.clear(); } - - if (glyph.m_Char == '\t' || glyph.m_Char == '\n') - { - auto oldX = bufferOffset.x; - bufferOffset.x = (1.0f + std::floor((1.0f + bufferOffset.x) / (float(m_nTabSize) * spaceSize))) * (float(m_nTabSize) * spaceSize); - ++i; - - if (m_bShowWhiteSpaces) - { - const auto s = ImGui::GetFontSize(); - const auto x1 = textScreenPos.x + oldX + 1.0f; - const auto x2 = textScreenPos.x + bufferOffset.x - 1.0f; - const auto y = textScreenPos.y + bufferOffset.y + s * 0.5f; - const ImVec2 p1(x1, y); - const ImVec2 p2(x2, y); - const ImVec2 p3(x2 - s * 0.2f, y - s * 0.2f); - const ImVec2 p4(x2 - s * 0.2f, y + s * 0.2f); - drawList->AddLine(p1, p2, 0x90909090); - drawList->AddLine(p2, p3, 0x90909090); - drawList->AddLine(p2, p4, 0x90909090); - } - } - else if (glyph.m_Char == ' ') - { - if (m_bShowWhiteSpaces) - { - const auto s = ImGui::GetFontSize(); - const auto x = textScreenPos.x + bufferOffset.x + spaceSize * 0.5f; - const auto y = textScreenPos.y + bufferOffset.y + s * 0.5f; - drawList->AddCircleFilled(ImVec2(x, y), 1.5f, 0x80808080, 4); - } - bufferOffset.x += spaceSize; - i++; - } - else - { - m_svLineBuffer.push_back(line[i++].m_Char); - //auto l = UTF8CharLength(glyph.m_Char); // !TODO: (this currently causes crashes) - //while (l-- > 0) - //{ - // m_svLineBuffer.push_back(line[i++].m_Char); - //} - } - ++columnNo; } - - if (!m_svLineBuffer.empty()) - { - const ImVec2 newOffset(textScreenPos.x + bufferOffset.x, textScreenPos.y + bufferOffset.y); - drawList->AddText(newOffset, 0xffffffff, m_svLineBuffer.c_str()); // COLOR (obtain from glyph?) - m_svLineBuffer.clear(); - } - - ++lineNo; + if (m_itFilter.IsActive() && m_itFilter.PassFilter(GetTextFromLine(line).c_str())) + ++lineNo; + else /*if (!m_itFilter.IsActive())*/ + ++lineNo; } } - ImGui::Dummy(ImVec2((longest + 2), m_Lines.size() * m_CharAdvance.y)); if (m_bScrollToCursor) @@ -1372,6 +1374,37 @@ std::string CTextLogger::GetCurrentLineText()const Coordinates(m_State.m_CursorPosition.m_nLine, lineLength)); } +std::string CTextLogger::GetTextFromLine(const Line& aLine) const +{ + std::string result; + for (size_t i = 0; i < aLine.size(); i++) + { + result += (aLine[i].m_Char); + } + return result; +} + +int CTextLogger::GetTotalFilterMatches() const +{ + if (!m_itFilter.IsActive()) + return static_cast<int>(m_Lines.size()); + + int result = 0; + for (size_t i = 0; i < m_Lines.size(); i++) + { + std::string svLineBuffer; + for (size_t j = 0; j < m_Lines[i].size(); j++) + { + svLineBuffer += m_Lines[i][j].m_Char; + } + if (m_itFilter.PassFilter(svLineBuffer.c_str())) + { + result++; + } + } + return result; +} + float CTextLogger::TextDistanceToLineStart(const Coordinates& aFrom) const { auto& line = m_Lines[aFrom.m_nLine];