From a1f96797c0876c4789a77a1021874b014e325957 Mon Sep 17 00:00:00 2001 From: Amos <48657826+Mauler125@users.noreply.github.com> Date: Sat, 22 Jan 2022 15:51:09 +0100 Subject: [PATCH] Console and Browser UX improvements * Log warnings * Improve style * Vector size is now controlled by ConVar instead * Keep current item in view when console is cleaning up the vector. This doesn't work ideally as its hard to keep track of the current item, and the scroll is a float. In the future it might be better to grab the first vertex of the center line on the console and track that perhaps. --- r5dev/gameui/IBrowser.cpp | 38 +++++++------ r5dev/gameui/IConsole.cpp | 57 +++++++++---------- r5dev/gameui/IConsole.h | 1 + .../thirdparty/imgui/include/imgui_utility.h | 6 +- r5dev/thirdparty/imgui/src/imgui_utility.cpp | 4 -- r5dev/tier0/IConVar.cpp | 5 +- r5dev/tier0/cvar.cpp | 1 + r5dev/tier0/cvar.h | 1 + 8 files changed, 57 insertions(+), 56 deletions(-) diff --git a/r5dev/gameui/IBrowser.cpp b/r5dev/gameui/IBrowser.cpp index 7e49732a..ea7c08ea 100644 --- a/r5dev/gameui/IBrowser.cpp +++ b/r5dev/gameui/IBrowser.cpp @@ -180,12 +180,14 @@ void IBrowser::ServerBrowserSection() const float FooterHeight = ImGui::GetStyle().ItemSpacing.y + ImGui::GetFrameHeightWithSpacing(); ImGui::BeginChild("ServerListChild", { 0, -FooterHeight }, true, ImGuiWindowFlags_AlwaysVerticalScrollbar); + + ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(4, 0)); if (ImGui::BeginTable("##ServerBrowser_ServerList", 5, ImGuiTableFlags_Resizable)) { - ImGui::TableSetupColumn("Name", ImGuiTableColumnFlags_WidthStretch, 20); - ImGui::TableSetupColumn("Map", ImGuiTableColumnFlags_WidthStretch, 25); + ImGui::TableSetupColumn("Name", ImGuiTableColumnFlags_WidthStretch, 25); + ImGui::TableSetupColumn("Map", ImGuiTableColumnFlags_WidthStretch, 20); ImGui::TableSetupColumn("Port", ImGuiTableColumnFlags_WidthStretch, 5); - ImGui::TableSetupColumn("Playlist", ImGuiTableColumnFlags_WidthStretch, 5); + ImGui::TableSetupColumn("Playlist", ImGuiTableColumnFlags_WidthStretch, 10); ImGui::TableSetupColumn("", ImGuiTableColumnFlags_WidthStretch, 5); ImGui::TableHeadersRow(); @@ -224,6 +226,7 @@ void IBrowser::ServerBrowserSection() } ImGui::EndTable(); + ImGui::PopStyleVar(1); } ImGui::EndChild(); @@ -757,22 +760,23 @@ void IBrowser::SetStyleVar() colors[ImGuiCol_WindowBg] = ImVec4(0.06f, 0.06f, 0.06f, 0.97f); } - style.WindowBorderSize = 0.0f; - style.FrameBorderSize = 1.0f; - style.ChildBorderSize = 1.0f; - style.PopupBorderSize = 1.0f; - style.TabBorderSize = 1.0f; + style.WindowBorderSize = 0.0f; + style.FrameBorderSize = 1.0f; + style.ChildBorderSize = 1.0f; + style.PopupBorderSize = 1.0f; + style.TabBorderSize = 1.0f; - style.WindowRounding = 2.5f; - style.FrameRounding = 1.0f; - style.ChildRounding = 0.0f; - style.PopupRounding = 0.0f; - style.TabRounding = 1.0f; - style.ScrollbarRounding = 1.0f; + style.WindowRounding = 4.0f; + style.FrameRounding = 1.0f; + style.ChildRounding = 1.0f; + style.PopupRounding = 3.0f; + style.TabRounding = 1.0f; + style.ScrollbarRounding = 1.0f; - style.ItemSpacing = ImVec2(4, 4); - style.WindowPadding = ImVec2(5, 5); - style.WindowMinSize = ImVec2(750, 510); + style.ItemSpacing = ImVec2(4, 4); + style.FramePadding = ImVec2(4, 4); + style.WindowPadding = ImVec2(5, 5); + style.WindowMinSize = ImVec2(750, 510); } IBrowser* g_pIBrowser = new IBrowser(); \ No newline at end of file diff --git a/r5dev/gameui/IConsole.cpp b/r5dev/gameui/IConsole.cpp index 8c87bd8e..50e34d52 100644 --- a/r5dev/gameui/IConsole.cpp +++ b/r5dev/gameui/IConsole.cpp @@ -102,18 +102,19 @@ void CConsole::Draw(const char* pszTitle, bool* bDraw) //----------------------------------------------------------------------------- void CConsole::Think(void) { - if (g_pImGuiConfig->IConsole_Config.m_bAutoClear) // Check if Auto-Clear is enabled. - { - // Loop and clear the beginning of the vector until we are below our limit. - while (m_ivConLog.Size > g_pImGuiConfig->IConsole_Config.m_nAutoClearLimit) - { - m_ivConLog.erase(m_ivConLog.begin()); - } - while ((int)m_vsvHistory.size() > 512) - { - m_vsvHistory.erase(m_vsvHistory.begin()); - } - } + if (m_ivConLog.Size > con_max_size_logvector->GetInt()) + { + while (m_ivConLog.Size > con_max_size_logvector->GetInt() / 4 * 3) + { + m_ivConLog.erase(m_ivConLog.begin()); + m_nScrollBack++; + } + } + + while ((int)m_vsvHistory.size() > 512) + { + m_vsvHistory.erase(m_vsvHistory.begin()); + } } //----------------------------------------------------------------------------- @@ -159,6 +160,12 @@ void CConsole::BasePanel(bool* bDraw) m_bCopyToClipBoard = false; } + if (m_nScrollBack > 0) + { + ImGui::SetScrollY(ImGui::GetScrollY() - m_nScrollBack * ImGui::GetTextLineHeightWithSpacing() - m_nScrollBack - 90); + m_nScrollBack = 0; + } + if (m_bScrollToBottom || (m_bAutoScroll && ImGui::GetScrollY() >= ImGui::GetScrollMaxY())) { ImGui::SetScrollHereY(1.0f); @@ -210,7 +217,7 @@ void CConsole::BasePanel(bool* bDraw) m_vecSuggestWindowPos = ImGui::GetItemRectMin(); m_vecSuggestWindowPos.y += ImGui::GetItemRectSize().y; - m_vecSuggestWindowSize = ImVec2(500, std::clamp((int)m_vsvSuggest.size() * 18, 37, 122)); + m_vecSuggestWindowSize = ImVec2(500, std::clamp((int)m_vsvSuggest.size() * (int)ImGui::GetTextLineHeight(), 37, 122)); ImGui::SameLine(); if (ImGui::Button("Submit")) @@ -234,19 +241,9 @@ void CConsole::OptionsPanel(void) { ImGui::Checkbox("Auto-Scroll", &m_bAutoScroll); - if (ImGui::Checkbox("Auto-Clear", &g_pImGuiConfig->IConsole_Config.m_bAutoClear)) - { - g_pImGuiConfig->Save(); - } - ImGui::SameLine(); ImGui::PushItemWidth(100); - if (ImGui::InputInt("Limit##AutoClearFirstIConsole", &g_pImGuiConfig->IConsole_Config.m_nAutoClearLimit)) - { - g_pImGuiConfig->Save(); - } - ImGui::PopItemWidth(); if (ImGui::SmallButton("Clear")) @@ -620,9 +617,9 @@ void CConsole::ColorLog(void) if (strstr(pszConLog, "Script(X):")) { imColor = ImVec4(0.59f, 0.58f, 0.63f, 1.00f); true; } // Native per game dll - if (strstr(pszConLog, "Native(S):")) { imColor = ImVec4(0.59f, 0.58f, 0.73f, 1.00f); true; } - if (strstr(pszConLog, "Native(C):")) { imColor = ImVec4(0.59f, 0.58f, 0.63f, 1.00f); true; } - if (strstr(pszConLog, "Native(U):")) { imColor = ImVec4(0.59f, 0.48f, 0.53f, 1.00f); true; } + if (strstr(pszConLog, "Native(S):")) { imColor = ImVec4(0.23f, 0.47f, 0.85f, 1.00f); true; } + if (strstr(pszConLog, "Native(C):")) { imColor = ImVec4(0.46f, 0.46f, 0.46f, 1.00f); true; } + if (strstr(pszConLog, "Native(U):")) { imColor = ImVec4(0.59f, 0.35f, 0.46f, 1.00f); true; } // Native per sys dll if (strstr(pszConLog, "Native(E):")) { imColor = ImVec4(0.70f, 0.70f, 0.70f, 1.00f); true; } @@ -644,6 +641,7 @@ void CConsole::ColorLog(void) if (strstr(pszConLog, ".gnut #")) { imColor = ImVec4(1.00f, 0.00f, 0.00f, 1.00f); true; } if (strstr(pszConLog, ".nut #")) { imColor = ImVec4(1.00f, 0.00f, 0.00f, 1.00f); true; } if (strstr(pszConLog, "): -> ")) { imColor = ImVec4(1.00f, 0.00f, 0.00f, 1.00f); true; } + if (strstr(pszConLog, "):Warning:")) { imColor = ImVec4(1.00f, 1.00f, 0.00f, 1.00f); true; } // Squirrel VM script debug if (strstr(pszConLog, "CALLSTACK")) { imColor = ImVec4(1.00f, 1.00f, 0.00f, 0.80f); true; } @@ -723,14 +721,15 @@ void CConsole::SetStyleVar(void) style.PopupBorderSize = 1.0f; style.TabBorderSize = 1.0f; - style.WindowRounding = 2.5f; + style.WindowRounding = 4.0f; style.FrameRounding = 1.0f; - style.ChildRounding = 0.0f; - style.PopupRounding = 0.0f; + style.ChildRounding = 1.0f; + style.PopupRounding = 3.0f; style.TabRounding = 1.0f; style.ScrollbarRounding = 1.0f; style.ItemSpacing = ImVec2(4, 4); + style.FramePadding = ImVec2(4, 4); style.WindowPadding = ImVec2(5, 5); style.WindowMinSize = ImVec2(518, 518); } diff --git a/r5dev/gameui/IConsole.h b/r5dev/gameui/IConsole.h index 7ffaad9c..5b11d92e 100644 --- a/r5dev/gameui/IConsole.h +++ b/r5dev/gameui/IConsole.h @@ -11,6 +11,7 @@ private: std::vector m_vsvCommands; std::vector m_vsvHistory; int m_nHistoryPos = -1; + int m_nScrollBack = 0; ImGuiTextFilter m_itFilter; bool m_bInitialized = false; bool m_bReclaimFocus = false; diff --git a/r5dev/thirdparty/imgui/include/imgui_utility.h b/r5dev/thirdparty/imgui/include/imgui_utility.h index d221c4c9..5bcfb824 100644 --- a/r5dev/thirdparty/imgui/include/imgui_utility.h +++ b/r5dev/thirdparty/imgui/include/imgui_utility.h @@ -12,10 +12,8 @@ class ImGuiConfig public: struct { - int m_nBind0 = VK_OEM_3; - int m_nBind1 = VK_INSERT; - int m_nAutoClearLimit = 300; - bool m_bAutoClear = true; + int m_nBind0 = VK_OEM_3; + int m_nBind1 = VK_INSERT; } IConsole_Config; struct diff --git a/r5dev/thirdparty/imgui/src/imgui_utility.cpp b/r5dev/thirdparty/imgui/src/imgui_utility.cpp index fda55ca1..7925141a 100644 --- a/r5dev/thirdparty/imgui/src/imgui_utility.cpp +++ b/r5dev/thirdparty/imgui/src/imgui_utility.cpp @@ -61,8 +61,6 @@ void ImGuiConfig::Load() // IConsole IConsole_Config.m_nBind0 = jsIn["config"]["IConsole"]["bind0"].get(); IConsole_Config.m_nBind1 = jsIn["config"]["IConsole"]["bind1"].get(); - IConsole_Config.m_nAutoClearLimit = jsIn["config"]["IConsole"]["autoClearLimit"].get(); - IConsole_Config.m_bAutoClear = jsIn["config"]["IConsole"]["autoClear"].get(); // IBrowser IBrowser_Config.m_nBind0 = jsIn["config"]["IBrowser"]["bind0"].get(); @@ -84,8 +82,6 @@ void ImGuiConfig::Save() // IConsole jsOut["config"]["IConsole"]["bind0"] = IConsole_Config.m_nBind0; jsOut["config"]["IConsole"]["bind1"] = IConsole_Config.m_nBind1; - jsOut["config"]["IConsole"]["autoClearLimit"] = IConsole_Config.m_nAutoClearLimit; - jsOut["config"]["IConsole"]["autoClear"] = IConsole_Config.m_bAutoClear; // IBrowser jsOut["config"]["IBrowser"]["bind0"] = IBrowser_Config.m_nBind0; diff --git a/r5dev/tier0/IConVar.cpp b/r5dev/tier0/IConVar.cpp index 530e06c5..30d44941 100644 --- a/r5dev/tier0/IConVar.cpp +++ b/r5dev/tier0/IConVar.cpp @@ -76,7 +76,8 @@ void ConVar::Init(void) cl_gpustats_offset_x = new ConVar("cl_gpustats_offset_x", "1250", FCVAR_DEVELOPMENTONLY, "X offset for texture streaming debug overlay.", false, 0.f, false, 0.f, nullptr, nullptr); cl_gpustats_offset_y = new ConVar("cl_gpustats_offset_y", "900", FCVAR_DEVELOPMENTONLY, "Y offset for texture streaming debug overlay.", false, 0.f, false, 0.f, nullptr, nullptr); - con_suggestion_limit = new ConVar("con_suggestion_limit", "120", FCVAR_DEVELOPMENTONLY, "Maximum number of suggestions the autocomplete window will show for the console.", false, 0.f, false, 0.f, nullptr, nullptr); + con_max_size_logvector = new ConVar("con_max_size_logvector", "1000", FCVAR_DEVELOPMENTONLY, "Maximum number of logs in the console until cleanup starts.", false, 0.f, false, 0.f, nullptr, nullptr); + con_suggestion_limit = new ConVar("con_suggestion_limit", "120", FCVAR_DEVELOPMENTONLY, "Maximum number of suggestions the autocomplete window will show for the console.", false, 0.f, false, 0.f, nullptr, nullptr); con_suggestion_helptext = new ConVar("con_suggestion_helptext", "0", FCVAR_DEVELOPMENTONLY, "Show ConVar help text in autocomplete window. Disabled by default to keep window less populated.", false, 0.f, false, 0.f, nullptr, nullptr); //------------------------------------------------------------------------- // FILESYSTEM | @@ -90,7 +91,7 @@ void ConVar::Init(void) // SQUIRREL | sq_showrsonloading = new ConVar("sq_showrsonloading", "0", FCVAR_DEVELOPMENTONLY, "Logs all 'rson' files loaded by the SQVM ( !slower! ).", false, 0.f, false, 0.f, nullptr, nullptr); sq_showscriptloading = new ConVar("sq_showscriptloading", "0", FCVAR_DEVELOPMENTONLY, "Logs all scripts loaded by the SQVM to be pre-compiled ( !slower! ).", false, 0.f, false, 0.f, nullptr, nullptr); - sq_showvmoutput = new ConVar("sq_showvmoutput", "1", FCVAR_DEVELOPMENTONLY, "Prints the VM output to the console. 1 = Log to file. 2 = 1 + log to console. 3 = 1 + 2 + log to overhead console. 4 = only log to overhead console.", false, 0.f, false, 0.f, nullptr, nullptr); + sq_showvmoutput = new ConVar("sq_showvmoutput", "0", FCVAR_DEVELOPMENTONLY, "Prints the VM output to the console. 1 = Log to file. 2 = 1 + log to console. 3 = 1 + 2 + log to overhead console. 4 = only log to overhead console.", false, 0.f, false, 0.f, nullptr, nullptr); sq_showvmwarning = new ConVar("sq_showvmwarning", "0", FCVAR_DEVELOPMENTONLY, "Prints the VM warning output to the console. 1 = Log to file. 2 = 1 + log to console.", false, 0.f, false, 0.f, nullptr, nullptr); //------------------------------------------------------------------------- // NETCHANNEL | diff --git a/r5dev/tier0/cvar.cpp b/r5dev/tier0/cvar.cpp index 1aba21cf..22ce8aae 100644 --- a/r5dev/tier0/cvar.cpp +++ b/r5dev/tier0/cvar.cpp @@ -32,6 +32,7 @@ ConVar* cl_showgpustats = new ConVar(); ConVar* cl_gpustats_offset_x = new ConVar(); ConVar* cl_gpustats_offset_y = new ConVar(); +ConVar* con_max_size_logvector = new ConVar(); ConVar* con_suggestion_limit = new ConVar(); ConVar* con_suggestion_helptext = new ConVar(); //----------------------------------------------------------------------------- diff --git a/r5dev/tier0/cvar.h b/r5dev/tier0/cvar.h index 7798fbde..741ae274 100644 --- a/r5dev/tier0/cvar.h +++ b/r5dev/tier0/cvar.h @@ -44,6 +44,7 @@ extern ConVar* cl_showgpustats;; extern ConVar* cl_gpustats_offset_x; extern ConVar* cl_gpustats_offset_y; +extern ConVar* con_max_size_logvector; extern ConVar* con_suggestion_limit; extern ConVar* con_suggestion_helptext; //-------------------------------------------------------------------------