From 34fddd52a8ef7f1ac6c9dbf068afced44637f520 Mon Sep 17 00:00:00 2001 From: Kawe Mazidjatari <48657826+Mauler125@users.noreply.github.com> Date: Thu, 29 Dec 2022 13:30:33 +0100 Subject: [PATCH] Add cvar/command flag tooltip Show a more detailed description of all flags set on cvar/command when user hovers its mouse over the flags texture. --- r5dev/gameui/IConsole.cpp | 41 +++++++++++++++++++++++++++++++++++++-- r5dev/public/iconvar.h | 38 ++++++++++++++++++++++++++++++++++++ r5dev/tier1/IConVar.cpp | 30 +++------------------------- r5dev/windows/resource.h | 7 ++++--- 4 files changed, 84 insertions(+), 32 deletions(-) diff --git a/r5dev/gameui/IConsole.cpp b/r5dev/gameui/IConsole.cpp index 0d012646..0d4dbad1 100644 --- a/r5dev/gameui/IConsole.cpp +++ b/r5dev/gameui/IConsole.cpp @@ -370,8 +370,45 @@ void CConsole::SuggestPanel(void) if (con_suggestion_showflags->GetBool()) { - const int k = GetFlagTextureIndex(suggest.m_nFlags); - ImGui::Image(m_vFlagIcons[k].m_idIcon, ImVec2(m_vFlagIcons[k].m_nWidth, m_vFlagIcons[k].m_nHeight)); + // Show the flag texture before the cvar name. + const int mainTexIdx = GetFlagTextureIndex(suggest.m_nFlags); + const MODULERESOURCE& mainRes = m_vFlagIcons[mainTexIdx]; + ImGui::Image(mainRes.m_idIcon, ImVec2(mainRes.m_nWidth, mainRes.m_nHeight)); + + // Show a more detailed description of the flag when user hovers over the texture. + if (ImGui::IsItemHovered(ImGuiHoveredFlags_RectOnly)) + { + std::function fnAddHint = [&](const ConVarFlagsToString_t& cvarInfo) + { + const int hintTexIdx = GetFlagTextureIndex(cvarInfo.m_nFlag); + const MODULERESOURCE& hintRes = m_vFlagIcons[hintTexIdx]; + + ImGui::Image(hintRes.m_idIcon, ImVec2(hintRes.m_nWidth, hintRes.m_nHeight)); + ImGui::SameLine(); + ImGui::Text(cvarInfo.m_pszDesc); + }; + + ImGui::BeginTooltip(); + bool bFlagSet = false; + + // Reverse loop to display the most significant flag first. + for (int j = IM_ARRAYSIZE(g_PrintConVarFlags); (j--) > 0;) + { + const ConVarFlagsToString_t& info = g_PrintConVarFlags[j]; + if (suggest.m_nFlags & info.m_nFlag) + { + bFlagSet = true; + fnAddHint(info); + } + } + if (!bFlagSet) // Display the FCVAR_NONE flag if no flags are set. + { + fnAddHint(g_PrintConVarFlags[FCVAR_NONE]); + } + + ImGui::EndTooltip(); + } + ImGui::SameLine(); } diff --git a/r5dev/public/iconvar.h b/r5dev/public/iconvar.h index 5d00d029..296a5890 100644 --- a/r5dev/public/iconvar.h +++ b/r5dev/public/iconvar.h @@ -147,5 +147,43 @@ public: virtual int GetSplitScreenPlayerSlot() const = 0; }; +struct ConVarFlagsToString_t +{ + int m_nFlag; + const char* m_pszDesc; +}; + +inline ConVarFlagsToString_t g_PrintConVarFlags[] = +{ + { FCVAR_NONE, "none" }, + { FCVAR_UNREGISTERED, "unregistered" }, + { FCVAR_DEVELOPMENTONLY, "development_only" }, + { FCVAR_GAMEDLL, "game" }, + { FCVAR_CLIENTDLL, "client" }, + { FCVAR_HIDDEN, "hidden" }, + { FCVAR_PROTECTED, "protected" }, + { FCVAR_SPONLY, "singleplayer" }, + { FCVAR_ARCHIVE, "archive" }, + { FCVAR_NOTIFY, "notify" }, + { FCVAR_USERINFO, "userinfo" }, + { FCVAR_PRINTABLEONLY, "printable_only" }, + { FCVAR_UNLOGGED, "unlogged" }, + { FCVAR_NEVER_AS_STRING, "never_as_string" }, + { FCVAR_REPLICATED, "replicated" }, + { FCVAR_CHEAT, "cheat" }, + { FCVAR_SS, "splitscreen" }, + { FCVAR_DEMO, "demo" }, + { FCVAR_DONTRECORD, "dont_record" }, + { FCVAR_SS_ADDED, "splitscreen_added" }, + { FCVAR_RELEASE, "release" }, + { FCVAR_RELOAD_MATERIALS, "reload_materials" }, + { FCVAR_RELOAD_TEXTURES, "reload_textures" }, + { FCVAR_NOT_CONNECTED, "not_connected" }, + { FCVAR_MATERIAL_SYSTEM_THREAD, "materialsystem_thread" }, + { FCVAR_ARCHIVE_PLAYERPROFILE, "playerprofile" }, + { FCVAR_SERVER_CAN_EXECUTE, "server_can_execute" }, + { FCVAR_SERVER_CANNOT_QUERY, "server_cannot_query" }, + { FCVAR_CLIENTCMD_CAN_EXECUTE, "clientcmd_can_execute" }, +}; #endif // ICONVAR_H diff --git a/r5dev/tier1/IConVar.cpp b/r5dev/tier1/IConVar.cpp index 7c3ce40a..5c1a2b99 100644 --- a/r5dev/tier1/IConVar.cpp +++ b/r5dev/tier1/IConVar.cpp @@ -941,30 +941,6 @@ bool ConVar::IsFlagSetInternal(const ConVar* pConVar, int nFlags) return pConVar->HasFlags(nFlags) != 0; } -/////////////////////////////////////////////////////////////////////////////// -struct PrintConVarFlags_t -{ - int flag; - const char* desc; -}; - -static PrintConVarFlags_t g_PrintConVarFlags[] = -{ - { FCVAR_GAMEDLL, "game" }, - { FCVAR_CLIENTDLL, "client" }, - { FCVAR_ARCHIVE, "archive" }, - { FCVAR_NOTIFY, "notify" }, - { FCVAR_SPONLY, "singleplayer" }, - { FCVAR_NOT_CONNECTED, "notconnected" }, - { FCVAR_CHEAT, "cheat" }, - { FCVAR_REPLICATED, "replicated" }, - { FCVAR_SERVER_CAN_EXECUTE, "server_can_execute" }, - { FCVAR_CLIENTCMD_CAN_EXECUTE, "clientcmd_can_execute" }, - { FCVAR_USERINFO, "user" }, - { FCVAR_SS, "ss" }, - { FCVAR_SS_ADDED, "ss_added" }, -}; - //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- @@ -972,11 +948,11 @@ void ConVar_AppendFlags(ConCommandBase* var, char* buf, size_t bufsize) { for (int i = 0; i < ARRAYSIZE(g_PrintConVarFlags); ++i) { - const PrintConVarFlags_t& info = g_PrintConVarFlags[i]; - if (var->IsFlagSet(info.flag)) + const ConVarFlagsToString_t& info = g_PrintConVarFlags[i]; + if (var->IsFlagSet(info.m_nFlag)) { char append[128]; - V_snprintf(append, sizeof(append), " %s", info.desc); + V_snprintf(append, sizeof(append), " %s", info.m_pszDesc); V_strncat(buf, append, bufsize); } } diff --git a/r5dev/windows/resource.h b/r5dev/windows/resource.h index 713288c4..5fa47639 100644 --- a/r5dev/windows/resource.h +++ b/r5dev/windows/resource.h @@ -10,13 +10,14 @@ struct MODULERESOURCE m_nWidth = NULL; m_nHeight = NULL; } - MODULERESOURCE(LPVOID pData, DWORD nSize, ID3D11ShaderResourceView* pIcon = nullptr) + MODULERESOURCE(LPVOID pData, DWORD nSize, ID3D11ShaderResourceView* pIcon = nullptr, + int nWidth = NULL, int nHeight = NULL) { m_pData = pData; m_nSize = nSize; m_idIcon = pIcon; - m_nWidth = NULL; - m_nHeight = NULL; + m_nWidth = nWidth; + m_nHeight = nHeight; } LPVOID m_pData; DWORD m_nSize;