2021-12-25 22:36:38 +01:00
|
|
|
/******************************************************************************
|
|
|
|
-------------------------------------------------------------------------------
|
|
|
|
File : IConsole.cpp
|
|
|
|
Date : 18:07:2021
|
|
|
|
Author : Kawe Mazidjatari
|
2022-01-12 02:53:07 +01:00
|
|
|
Purpose: Implements the in-game console front-end
|
2021-12-25 22:36:38 +01:00
|
|
|
-------------------------------------------------------------------------------
|
|
|
|
History:
|
|
|
|
- 15:06:2021 | 14:56 : Created by Kawe Mazidjatari
|
|
|
|
- 07:08:2021 | 15:22 : Multithread 'CommandExecute' operations to prevent deadlock in render thread
|
|
|
|
- 07:08:2021 | 15:25 : Fix a race condition that occured when detaching the 'CommandExecute' thread
|
|
|
|
|
|
|
|
******************************************************************************/
|
|
|
|
|
2022-01-12 02:53:07 +01:00
|
|
|
#include "core/stdafx.h"
|
|
|
|
#include "core/init.h"
|
2022-04-26 20:24:51 +02:00
|
|
|
#include "core/resource.h"
|
2022-01-18 11:23:14 +01:00
|
|
|
#include "tier0/commandline.h"
|
2022-04-09 16:16:40 +02:00
|
|
|
#include "tier1/cvar.h"
|
2022-01-12 02:53:07 +01:00
|
|
|
#include "windows/id3dx.h"
|
|
|
|
#include "windows/console.h"
|
2022-04-26 20:24:51 +02:00
|
|
|
#include "windows/resource.h"
|
2022-01-12 02:53:07 +01:00
|
|
|
#include "gameui/IConsole.h"
|
2022-04-02 12:27:35 +02:00
|
|
|
#include "client/vengineclient_impl.h"
|
2022-01-12 02:53:07 +01:00
|
|
|
|
2021-12-25 22:36:38 +01:00
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// Purpose:
|
|
|
|
//-----------------------------------------------------------------------------
|
2022-02-14 02:31:42 +01:00
|
|
|
CConsole::CConsole(void)
|
2021-12-25 22:36:38 +01:00
|
|
|
{
|
|
|
|
ClearLog();
|
2022-06-15 02:04:03 +02:00
|
|
|
memset(m_szInputBuf, '\0', sizeof(m_szInputBuf));
|
2021-12-25 22:36:38 +01:00
|
|
|
|
|
|
|
m_nHistoryPos = -1;
|
|
|
|
m_bAutoScroll = true;
|
|
|
|
m_bScrollToBottom = false;
|
2022-01-14 20:45:36 +01:00
|
|
|
m_bInitialized = false;
|
2022-06-09 02:22:01 +02:00
|
|
|
m_pszConsoleTitle = "Console";
|
2021-12-25 22:36:38 +01:00
|
|
|
|
2022-01-17 23:20:03 +01:00
|
|
|
m_vsvCommands.push_back("CLEAR");
|
|
|
|
m_vsvCommands.push_back("HELP");
|
|
|
|
m_vsvCommands.push_back("HISTORY");
|
2022-01-28 12:56:51 +01:00
|
|
|
|
|
|
|
snprintf(m_szSummary, 256, "%llu history items", m_vsvHistory.size());
|
2022-06-09 02:22:01 +02:00
|
|
|
|
|
|
|
std::thread think(&CConsole::Think, this);
|
|
|
|
think.detach();
|
2021-12-25 22:36:38 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// Purpose:
|
|
|
|
//-----------------------------------------------------------------------------
|
2022-02-14 02:31:42 +01:00
|
|
|
CConsole::~CConsole(void)
|
2021-12-25 22:36:38 +01:00
|
|
|
{
|
|
|
|
ClearLog();
|
2022-01-17 23:20:03 +01:00
|
|
|
m_vsvHistory.clear();
|
2021-12-25 22:36:38 +01:00
|
|
|
}
|
|
|
|
|
2022-04-26 20:24:51 +02:00
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// Purpose: game console setup
|
|
|
|
// Output : true on success, false otherwise
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
bool CConsole::Setup(void)
|
|
|
|
{
|
|
|
|
SetStyleVar();
|
|
|
|
|
|
|
|
int k = 0; // Get all image resources for displaying flags.
|
2022-04-26 20:35:51 +02:00
|
|
|
for (int i = IDB_PNG3; i <= IDB_PNG18; i++)
|
2022-04-26 20:24:51 +02:00
|
|
|
{
|
|
|
|
m_vFlagIcons.push_back(MODULERESOURCE());
|
|
|
|
m_vFlagIcons[k] = GetModuleResource(i);
|
|
|
|
|
|
|
|
bool ret = LoadTextureBuffer(reinterpret_cast<unsigned char*>(m_vFlagIcons[k].m_pData), static_cast<int>(m_vFlagIcons[k].m_nSize),
|
|
|
|
&m_vFlagIcons[k].m_idIcon, &m_vFlagIcons[k].m_nWidth, &m_vFlagIcons[k].m_nHeight);
|
|
|
|
if (!ret)
|
|
|
|
{
|
|
|
|
IM_ASSERT(ret);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
k++;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2021-12-25 22:36:38 +01:00
|
|
|
//-----------------------------------------------------------------------------
|
2022-01-17 23:20:03 +01:00
|
|
|
// Purpose: game console main render loop
|
2021-12-25 22:36:38 +01:00
|
|
|
//-----------------------------------------------------------------------------
|
2022-06-09 02:22:01 +02:00
|
|
|
void CConsole::Draw(void)
|
2021-12-25 22:36:38 +01:00
|
|
|
{
|
2022-01-12 02:53:07 +01:00
|
|
|
if (!m_bInitialized)
|
2021-12-25 22:36:38 +01:00
|
|
|
{
|
2022-04-26 20:24:51 +02:00
|
|
|
Setup();
|
|
|
|
m_bInitialized = true;
|
2021-12-25 22:36:38 +01:00
|
|
|
}
|
2022-01-19 19:00:40 +01:00
|
|
|
|
|
|
|
{
|
|
|
|
//ImGui::ShowStyleEditor();
|
|
|
|
//ImGui::ShowDemoWindow();
|
|
|
|
}
|
2021-12-25 22:36:38 +01:00
|
|
|
|
2022-01-28 12:56:51 +01:00
|
|
|
/**************************
|
|
|
|
* BASE PANEL SETUP *
|
|
|
|
**************************/
|
|
|
|
{
|
2022-06-09 02:22:01 +02:00
|
|
|
int nVars{};
|
|
|
|
if (!m_bActivate)
|
2022-01-17 23:20:03 +01:00
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
2022-01-28 12:56:51 +01:00
|
|
|
if (m_bDefaultTheme)
|
|
|
|
{
|
2022-06-09 02:22:01 +02:00
|
|
|
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2{ 8.f, 10.f }); nVars++;
|
|
|
|
ImGui::PushStyleVar(ImGuiStyleVar_Alpha, m_flFadeAlpha); nVars++;
|
2022-01-28 12:56:51 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2022-06-09 02:22:01 +02:00
|
|
|
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2{ 4.f, 6.f }); nVars++;
|
|
|
|
ImGui::PushStyleVar(ImGuiStyleVar_ChildBorderSize, 1.0f); nVars++;
|
|
|
|
ImGui::PushStyleVar(ImGuiStyleVar_Alpha, m_flFadeAlpha); nVars++;
|
2022-01-28 12:56:51 +01:00
|
|
|
}
|
2022-01-19 19:00:40 +01:00
|
|
|
|
2022-01-17 23:20:03 +01:00
|
|
|
ImGui::SetNextWindowSize(ImVec2(1000, 600), ImGuiCond_FirstUseEver);
|
|
|
|
ImGui::SetWindowPos(ImVec2(-1000, 50), ImGuiCond_FirstUseEver);
|
|
|
|
|
2022-06-09 02:22:01 +02:00
|
|
|
BasePanel();
|
2022-01-19 19:00:40 +01:00
|
|
|
|
2022-02-06 16:33:11 +01:00
|
|
|
ImGui::PopStyleVar(nVars);
|
2022-01-17 23:20:03 +01:00
|
|
|
}
|
|
|
|
|
2022-01-28 12:56:51 +01:00
|
|
|
/**************************
|
|
|
|
* SUGGESTION PANEL SETUP *
|
|
|
|
**************************/
|
|
|
|
{
|
2022-06-14 22:37:43 +02:00
|
|
|
int nVars{};
|
2022-01-17 23:20:03 +01:00
|
|
|
if (CanAutoComplete())
|
|
|
|
{
|
2022-01-28 12:56:51 +01:00
|
|
|
if (m_bDefaultTheme)
|
|
|
|
{
|
|
|
|
static ImGuiStyle& style = ImGui::GetStyle();
|
2022-05-27 16:28:37 +02:00
|
|
|
m_ivSuggestWindowPos.y = m_ivSuggestWindowPos.y + style.WindowPadding.y + 1.5f;
|
2022-01-28 12:56:51 +01:00
|
|
|
}
|
|
|
|
|
2022-05-27 16:28:37 +02:00
|
|
|
ImGui::SetNextWindowPos(m_ivSuggestWindowPos);
|
|
|
|
ImGui::SetNextWindowSize(m_ivSuggestWindowSize);
|
2022-01-19 19:00:40 +01:00
|
|
|
|
2022-06-14 22:37:43 +02:00
|
|
|
ImGui::PushStyleVar(ImGuiStyleVar_WindowMinSize, ImVec2(500, 37)); nVars++;
|
|
|
|
ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, 1.0f); nVars++;
|
|
|
|
ImGui::PushStyleVar(ImGuiStyleVar_Alpha, m_flFadeAlpha); nVars++;
|
2022-01-19 19:00:40 +01:00
|
|
|
|
2022-01-17 23:20:03 +01:00
|
|
|
SuggestPanel();
|
2022-01-19 19:00:40 +01:00
|
|
|
|
2022-02-06 16:33:11 +01:00
|
|
|
ImGui::PopStyleVar(nVars);
|
2022-01-17 23:20:03 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2021-12-25 22:36:38 +01:00
|
|
|
|
2022-01-17 23:20:03 +01:00
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// Purpose: runs tasks for the console while not being drawn
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
void CConsole::Think(void)
|
|
|
|
{
|
2022-06-09 02:22:01 +02:00
|
|
|
for (;;) // Loop running at 100-tps.
|
|
|
|
{
|
|
|
|
if (m_ivConLog.size() > con_max_size_logvector->GetSizeT())
|
|
|
|
{
|
|
|
|
while (m_ivConLog.size() > con_max_size_logvector->GetSizeT() / 4 * 3)
|
|
|
|
{
|
|
|
|
m_ivConLog.erase(m_ivConLog.begin());
|
|
|
|
m_nScrollBack++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
while (static_cast<int>(m_vsvHistory.size()) > 512)
|
|
|
|
{
|
|
|
|
m_vsvHistory.erase(m_vsvHistory.begin());
|
|
|
|
}
|
|
|
|
|
|
|
|
if (m_bActivate)
|
|
|
|
{
|
|
|
|
if (m_flFadeAlpha <= 1.f)
|
|
|
|
{
|
|
|
|
m_flFadeAlpha += 0.05;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else // Reset to full transparent.
|
|
|
|
{
|
|
|
|
m_flFadeAlpha = 0.f;
|
|
|
|
m_bReclaimFocus = true;
|
|
|
|
}
|
|
|
|
std::this_thread::sleep_for(std::chrono::milliseconds(10));
|
|
|
|
}
|
2022-01-17 23:20:03 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// Purpose: draws the console's main surface
|
2022-02-14 02:31:42 +01:00
|
|
|
// Input : *bDraw -
|
2022-01-17 23:20:03 +01:00
|
|
|
//-----------------------------------------------------------------------------
|
2022-06-09 02:22:01 +02:00
|
|
|
void CConsole::BasePanel(void)
|
2022-01-17 23:20:03 +01:00
|
|
|
{
|
2022-06-09 02:22:01 +02:00
|
|
|
if (!ImGui::Begin(m_pszConsoleTitle, &m_bActivate))
|
2021-12-25 22:36:38 +01:00
|
|
|
{
|
2022-01-17 23:20:03 +01:00
|
|
|
ImGui::End();
|
|
|
|
return;
|
2021-12-25 22:36:38 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// Reserve enough left-over height and width for 1 separator + 1 input text
|
|
|
|
const float footer_height_to_reserve = ImGui::GetStyle().ItemSpacing.y + ImGui::GetFrameHeightWithSpacing();
|
2022-01-17 23:20:03 +01:00
|
|
|
const float footer_width_to_reserve = ImGui::GetStyle().ItemSpacing.y + ImGui::GetWindowWidth();
|
2021-12-25 22:36:38 +01:00
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////
|
|
|
|
ImGui::Separator();
|
|
|
|
if (ImGui::BeginPopup("Options"))
|
|
|
|
{
|
2022-01-17 23:20:03 +01:00
|
|
|
OptionsPanel();
|
2021-12-25 22:36:38 +01:00
|
|
|
}
|
|
|
|
if (ImGui::Button("Options"))
|
|
|
|
{
|
|
|
|
ImGui::OpenPopup("Options");
|
|
|
|
}
|
2022-01-12 02:53:07 +01:00
|
|
|
|
2021-12-25 22:36:38 +01:00
|
|
|
ImGui::SameLine();
|
2022-01-28 12:56:51 +01:00
|
|
|
m_itFilter.Draw("Filter | ", footer_width_to_reserve - 500);
|
|
|
|
|
|
|
|
ImGui::SameLine();
|
|
|
|
ImGui::Text(m_szSummary);
|
|
|
|
|
2021-12-25 22:36:38 +01:00
|
|
|
ImGui::Separator();
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////
|
|
|
|
ImGui::BeginChild("ScrollingRegion", ImVec2(0, -footer_height_to_reserve), true, ImGuiWindowFlags_AlwaysVerticalScrollbar);
|
2022-01-12 02:53:07 +01:00
|
|
|
|
|
|
|
if (m_bCopyToClipBoard) { ImGui::LogToClipboard(); }
|
|
|
|
ColorLog();
|
|
|
|
if (m_bCopyToClipBoard)
|
2021-12-25 22:36:38 +01:00
|
|
|
{
|
|
|
|
ImGui::LogToClipboard();
|
2022-01-12 02:53:07 +01:00
|
|
|
ImGui::LogFinish();
|
2021-12-25 22:36:38 +01:00
|
|
|
|
2022-01-12 02:53:07 +01:00
|
|
|
m_bCopyToClipBoard = false;
|
2021-12-25 22:36:38 +01:00
|
|
|
}
|
|
|
|
|
2022-01-22 15:51:09 +01:00
|
|
|
if (m_nScrollBack > 0)
|
|
|
|
{
|
|
|
|
ImGui::SetScrollY(ImGui::GetScrollY() - m_nScrollBack * ImGui::GetTextLineHeightWithSpacing() - m_nScrollBack - 90);
|
|
|
|
m_nScrollBack = 0;
|
|
|
|
}
|
|
|
|
|
2022-01-12 02:53:07 +01:00
|
|
|
if (m_bScrollToBottom || (m_bAutoScroll && ImGui::GetScrollY() >= ImGui::GetScrollMaxY()))
|
|
|
|
{
|
|
|
|
ImGui::SetScrollHereY(1.0f);
|
|
|
|
m_bScrollToBottom = false;
|
|
|
|
}
|
2021-12-25 22:36:38 +01:00
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////
|
|
|
|
ImGui::EndChild();
|
|
|
|
ImGui::Separator();
|
|
|
|
|
|
|
|
ImGui::PushItemWidth(footer_width_to_reserve - 80);
|
2022-05-27 16:28:37 +02:00
|
|
|
if (ImGui::InputText("##input", m_szInputBuf, IM_ARRAYSIZE(m_szInputBuf), m_nInputFlags, &TextEditCallbackStub, reinterpret_cast<void*>(this)))
|
2021-12-25 22:36:38 +01:00
|
|
|
{
|
2022-01-17 23:20:03 +01:00
|
|
|
if (m_nSuggestPos != -1)
|
|
|
|
{
|
|
|
|
// Remove the default value from ConVar before assigning it to the input buffer.
|
2022-04-26 20:24:51 +02:00
|
|
|
string svConVar = m_vsvSuggest[m_nSuggestPos].m_svName.substr(0, m_vsvSuggest[m_nSuggestPos].m_svName.find(' ')) + " ";
|
2022-01-17 23:20:03 +01:00
|
|
|
memmove(m_szInputBuf, svConVar.c_str(), svConVar.size() + 1);
|
2021-12-25 22:36:38 +01:00
|
|
|
|
2022-03-25 13:31:31 +01:00
|
|
|
ResetAutoComplete();
|
2022-01-17 23:20:03 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2022-01-18 00:39:59 +01:00
|
|
|
if (m_szInputBuf[0])
|
|
|
|
{
|
|
|
|
ProcessCommand(m_szInputBuf);
|
|
|
|
memset(m_szInputBuf, '\0', 1);
|
|
|
|
}
|
2022-01-17 23:20:03 +01:00
|
|
|
|
2022-03-25 13:31:31 +01:00
|
|
|
ResetAutoComplete();
|
2022-01-17 23:20:03 +01:00
|
|
|
}
|
2021-12-25 22:36:38 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// Auto-focus on window apparition.
|
|
|
|
ImGui::SetItemDefaultFocus();
|
|
|
|
|
2022-01-17 23:20:03 +01:00
|
|
|
// Auto-focus previous widget.
|
2022-01-12 02:53:07 +01:00
|
|
|
if (m_bReclaimFocus)
|
2021-12-25 22:36:38 +01:00
|
|
|
{
|
2022-01-17 23:20:03 +01:00
|
|
|
ImGui::SetKeyboardFocusHere(-1);
|
2022-01-12 02:53:07 +01:00
|
|
|
m_bReclaimFocus = false;
|
2021-12-25 22:36:38 +01:00
|
|
|
}
|
|
|
|
|
2022-02-23 15:56:03 +01:00
|
|
|
int nPad = 0;
|
|
|
|
if (static_cast<int>(m_vsvSuggest.size()) > 1)
|
|
|
|
{
|
|
|
|
// Pad with 18 to keep all items in view.
|
|
|
|
nPad = 18;
|
|
|
|
}
|
2022-05-27 16:28:37 +02:00
|
|
|
m_ivSuggestWindowPos = ImGui::GetItemRectMin();
|
|
|
|
m_ivSuggestWindowPos.y += ImGui::GetItemRectSize().y;
|
|
|
|
m_ivSuggestWindowSize = ImVec2(600, nPad + std::clamp(static_cast<float>(m_vsvSuggest.size()) * 13.0f, 37.0f, 127.5f));
|
2022-01-17 23:20:03 +01:00
|
|
|
|
|
|
|
ImGui::SameLine();
|
|
|
|
if (ImGui::Button("Submit"))
|
|
|
|
{
|
2022-01-18 00:39:59 +01:00
|
|
|
if (m_szInputBuf[0])
|
|
|
|
{
|
|
|
|
ProcessCommand(m_szInputBuf);
|
|
|
|
memset(m_szInputBuf, '\0', 1);
|
|
|
|
}
|
2022-03-25 13:31:31 +01:00
|
|
|
ResetAutoComplete();
|
2022-01-17 23:20:03 +01:00
|
|
|
}
|
2021-12-25 22:36:38 +01:00
|
|
|
ImGui::End();
|
|
|
|
}
|
|
|
|
|
2022-01-12 02:53:07 +01:00
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// Purpose: draws the options panel
|
|
|
|
//-----------------------------------------------------------------------------
|
2022-01-17 23:20:03 +01:00
|
|
|
void CConsole::OptionsPanel(void)
|
2022-01-12 02:53:07 +01:00
|
|
|
{
|
|
|
|
ImGui::Checkbox("Auto-Scroll", &m_bAutoScroll);
|
|
|
|
|
|
|
|
ImGui::SameLine();
|
|
|
|
ImGui::PushItemWidth(100);
|
|
|
|
|
|
|
|
ImGui::PopItemWidth();
|
|
|
|
|
|
|
|
if (ImGui::SmallButton("Clear"))
|
|
|
|
{
|
|
|
|
ClearLog();
|
|
|
|
}
|
|
|
|
|
|
|
|
ImGui::SameLine();
|
|
|
|
m_bCopyToClipBoard = ImGui::SmallButton("Copy");
|
|
|
|
|
|
|
|
ImGui::Text("Console Hotkey:");
|
|
|
|
ImGui::SameLine();
|
|
|
|
|
|
|
|
if (ImGui::Hotkey("##OpenIConsoleBind0", &g_pImGuiConfig->IConsole_Config.m_nBind0, ImVec2(80, 80)))
|
|
|
|
{
|
|
|
|
g_pImGuiConfig->Save();
|
|
|
|
}
|
|
|
|
|
|
|
|
ImGui::Text("Browser Hotkey:");
|
|
|
|
ImGui::SameLine();
|
|
|
|
|
|
|
|
if (ImGui::Hotkey("##OpenIBrowserBind0", &g_pImGuiConfig->IBrowser_Config.m_nBind0, ImVec2(80, 80)))
|
|
|
|
{
|
|
|
|
g_pImGuiConfig->Save();
|
|
|
|
}
|
|
|
|
|
|
|
|
ImGui::EndPopup();
|
|
|
|
}
|
|
|
|
|
2022-01-16 00:59:20 +01:00
|
|
|
//-----------------------------------------------------------------------------
|
2022-01-17 23:20:03 +01:00
|
|
|
// Purpose: draws the suggestion panel with results based on user input
|
2022-01-16 00:59:20 +01:00
|
|
|
//-----------------------------------------------------------------------------
|
2022-01-17 23:20:03 +01:00
|
|
|
void CConsole::SuggestPanel(void)
|
2022-01-16 00:59:20 +01:00
|
|
|
{
|
2022-05-27 16:28:37 +02:00
|
|
|
ImGui::Begin("##suggest", nullptr, m_nSuggestFlags);
|
2022-01-17 23:20:03 +01:00
|
|
|
ImGui::PushAllowKeyboardFocus(false);
|
|
|
|
|
2022-06-15 02:04:03 +02:00
|
|
|
for (size_t i = 0; i < m_vsvSuggest.size(); i++)
|
2022-01-16 00:59:20 +01:00
|
|
|
{
|
2022-01-17 23:20:03 +01:00
|
|
|
bool bIsIndexActive = m_nSuggestPos == i;
|
|
|
|
ImGui::PushID(i);
|
2022-04-26 20:24:51 +02:00
|
|
|
|
|
|
|
if (con_suggestion_showflags->GetBool())
|
|
|
|
{
|
|
|
|
int k = ColorCodeFlags(m_vsvSuggest[i].m_nFlags);
|
|
|
|
ImGui::Image(m_vFlagIcons[k].m_idIcon, ImVec2(m_vFlagIcons[k].m_nWidth, m_vFlagIcons[k].m_nHeight));
|
|
|
|
ImGui::SameLine();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ImGui::Selectable(m_vsvSuggest[i].m_svName.c_str(), bIsIndexActive))
|
2022-01-16 00:59:20 +01:00
|
|
|
{
|
2022-01-17 23:20:03 +01:00
|
|
|
ImGui::Separator();
|
|
|
|
|
|
|
|
// Remove the default value from ConVar before assigning it to the input buffer.
|
2022-04-26 20:24:51 +02:00
|
|
|
string svConVar = m_vsvSuggest[i].m_svName.substr(0, m_vsvSuggest[i].m_svName.find(' ')) + " ";
|
2022-01-17 23:20:03 +01:00
|
|
|
memmove(m_szInputBuf, svConVar.c_str(), svConVar.size() + 1);
|
|
|
|
|
2022-03-25 13:31:31 +01:00
|
|
|
ResetAutoComplete();
|
2022-01-16 00:59:20 +01:00
|
|
|
}
|
2022-01-17 23:20:03 +01:00
|
|
|
ImGui::PopID();
|
|
|
|
|
2022-04-26 20:24:51 +02:00
|
|
|
// Make sure we bring the currently 'active' item into view.
|
|
|
|
if (m_bSuggestMoved && bIsIndexActive)
|
2022-01-16 00:59:20 +01:00
|
|
|
{
|
2022-04-26 20:24:51 +02:00
|
|
|
ImGuiWindow* pWindow = ImGui::GetCurrentWindow();
|
|
|
|
ImRect imRect = ImGui::GetCurrentContext()->LastItemData.Rect;
|
2022-01-18 11:23:14 +01:00
|
|
|
|
2022-04-26 20:24:51 +02:00
|
|
|
// Reset to keep flag in display.
|
|
|
|
imRect.Min.x = pWindow->InnerRect.Min.x;
|
|
|
|
imRect.Max.x = pWindow->InnerRect.Min.x; // Set to Min.x on purpose!
|
|
|
|
|
|
|
|
// Eliminate jiggle when going up/down in the menu.
|
|
|
|
imRect.Min.y += 1;
|
|
|
|
imRect.Max.y -= 1;
|
|
|
|
|
|
|
|
ImGui::ScrollToRect(pWindow, imRect);
|
|
|
|
m_bSuggestMoved = false;
|
2022-01-16 00:59:20 +01:00
|
|
|
}
|
2022-01-20 00:24:41 +01:00
|
|
|
|
|
|
|
if (m_bSuggestUpdate)
|
|
|
|
{
|
|
|
|
ImGui::SetScrollHereY(0.f);
|
|
|
|
m_bSuggestUpdate = false;
|
|
|
|
}
|
2022-01-16 00:59:20 +01:00
|
|
|
}
|
2022-01-17 23:20:03 +01:00
|
|
|
|
|
|
|
ImGui::PopAllowKeyboardFocus();
|
|
|
|
ImGui::End();
|
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
2022-02-13 15:16:09 +01:00
|
|
|
// Purpose: checks if the console can autocomplete based on input
|
2022-02-14 02:31:42 +01:00
|
|
|
// Output : true to perform autocomplete, false otherwise
|
2022-01-17 23:20:03 +01:00
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
bool CConsole::CanAutoComplete(void)
|
|
|
|
{
|
|
|
|
// Show ConVar/ConCommand suggestions when at least 2 characters have been entered.
|
|
|
|
if (strlen(m_szInputBuf) > 1)
|
|
|
|
{
|
2022-02-21 12:06:05 +01:00
|
|
|
static char szCurInputBuf[512]{};
|
|
|
|
if (strcmp(m_szInputBuf, szCurInputBuf) != 0) // Update suggestions if input buffer changed.
|
2022-01-17 23:20:03 +01:00
|
|
|
{
|
2022-02-21 12:06:05 +01:00
|
|
|
memmove(szCurInputBuf, m_szInputBuf, strlen(m_szInputBuf) + 1);
|
2022-01-17 23:20:03 +01:00
|
|
|
FindFromPartial();
|
|
|
|
}
|
2022-02-23 15:56:03 +01:00
|
|
|
if (static_cast<int>(m_vsvSuggest.size()) <= 0)
|
2022-01-17 23:20:03 +01:00
|
|
|
{
|
|
|
|
m_nSuggestPos = -1;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
m_nSuggestPos = -1;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Don't suggest if user tries to assign value to ConVar or execute ConCommand.
|
|
|
|
if (strstr(m_szInputBuf, " ") || strstr(m_szInputBuf, ";"))
|
|
|
|
{
|
2022-03-25 13:31:31 +01:00
|
|
|
ResetAutoComplete();
|
2022-01-17 23:20:03 +01:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
m_bSuggestActive = true;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2022-03-25 13:31:31 +01:00
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// Purpose: resets the autocomplete window
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
void CConsole::ResetAutoComplete(void)
|
|
|
|
{
|
|
|
|
m_bSuggestActive = false;
|
|
|
|
m_nSuggestPos = -1;
|
|
|
|
m_bReclaimFocus = true;
|
|
|
|
}
|
|
|
|
|
2022-01-17 23:20:03 +01:00
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// Purpose: find ConVars/ConCommands from user input and add to vector
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
void CConsole::FindFromPartial(void)
|
|
|
|
{
|
2022-01-18 11:23:14 +01:00
|
|
|
m_nSuggestPos = -1;
|
2022-01-20 00:24:41 +01:00
|
|
|
m_bSuggestUpdate = true;
|
2022-01-17 23:20:03 +01:00
|
|
|
m_vsvSuggest.clear();
|
2022-01-18 11:23:14 +01:00
|
|
|
|
2022-06-15 02:04:03 +02:00
|
|
|
for (size_t i = 0; i < m_vsvCommandBases.size(); i++)
|
2022-01-17 23:20:03 +01:00
|
|
|
{
|
|
|
|
if (m_vsvSuggest.size() < con_suggestion_limit->GetInt())
|
|
|
|
{
|
2022-04-26 20:24:51 +02:00
|
|
|
if (m_vsvCommandBases[i].m_svName.find(m_szInputBuf) != string::npos)
|
2022-01-17 23:20:03 +01:00
|
|
|
{
|
2022-04-26 20:24:51 +02:00
|
|
|
if (std::find(m_vsvSuggest.begin(), m_vsvSuggest.end(),
|
|
|
|
m_vsvCommandBases[i].m_svName) == m_vsvSuggest.end())
|
2022-01-17 23:20:03 +01:00
|
|
|
{
|
2022-04-26 20:24:51 +02:00
|
|
|
int nFlags{};
|
|
|
|
string svValue;
|
|
|
|
ConCommandBase* pCommandBase = g_pCVar->FindCommandBase(m_vsvCommandBases[i].m_svName.c_str());
|
2022-02-23 15:56:03 +01:00
|
|
|
|
2022-04-26 20:24:51 +02:00
|
|
|
if (pCommandBase)
|
2022-01-17 23:20:03 +01:00
|
|
|
{
|
2022-02-23 15:56:03 +01:00
|
|
|
if (!pCommandBase->IsCommand())
|
|
|
|
{
|
|
|
|
ConVar* pConVar = reinterpret_cast<ConVar*>(pCommandBase);
|
2022-01-19 19:00:40 +01:00
|
|
|
|
2022-02-23 21:02:37 +01:00
|
|
|
svValue = " = ["; // Assign default value to string if its a ConVar.
|
2022-02-23 15:56:03 +01:00
|
|
|
svValue.append(pConVar->GetString());
|
|
|
|
svValue.append("]");
|
|
|
|
}
|
2022-04-26 20:24:51 +02:00
|
|
|
if (con_suggestion_showhelptext->GetBool())
|
2022-01-19 19:00:40 +01:00
|
|
|
{
|
2022-02-23 15:56:03 +01:00
|
|
|
if (pCommandBase->GetHelpText())
|
2022-01-19 19:00:40 +01:00
|
|
|
{
|
2022-04-26 20:24:51 +02:00
|
|
|
string svHelpText = pCommandBase->GetHelpText();
|
2022-02-23 15:56:03 +01:00
|
|
|
if (!svHelpText.empty())
|
|
|
|
{
|
2022-02-23 21:02:37 +01:00
|
|
|
svValue.append(" - \"" + svHelpText + "\"");
|
2022-02-23 15:56:03 +01:00
|
|
|
}
|
2022-02-22 16:31:24 +01:00
|
|
|
}
|
2022-02-23 15:56:03 +01:00
|
|
|
if (pCommandBase->GetUsageText())
|
2022-02-22 16:31:24 +01:00
|
|
|
{
|
2022-04-26 20:24:51 +02:00
|
|
|
string svUsageText = pCommandBase->GetUsageText();
|
2022-02-23 15:56:03 +01:00
|
|
|
if (!svUsageText.empty())
|
|
|
|
{
|
2022-02-23 21:02:37 +01:00
|
|
|
svValue.append(" - \"" + svUsageText + "\"");
|
2022-02-23 15:56:03 +01:00
|
|
|
}
|
2022-01-19 19:00:40 +01:00
|
|
|
}
|
|
|
|
}
|
2022-04-26 20:24:51 +02:00
|
|
|
if (con_suggestion_showflags->GetBool())
|
|
|
|
{
|
|
|
|
if (con_suggestion_flags_realtime->GetBool())
|
|
|
|
{
|
|
|
|
nFlags = pCommandBase->GetFlags();
|
|
|
|
}
|
|
|
|
else // Display compile-time flags instead.
|
|
|
|
{
|
|
|
|
nFlags = m_vsvCommandBases[i].m_nFlags;
|
|
|
|
}
|
|
|
|
}
|
2022-01-17 23:20:03 +01:00
|
|
|
}
|
2022-04-26 20:24:51 +02:00
|
|
|
m_vsvSuggest.push_back(CSuggest(m_vsvCommandBases[i].m_svName + svValue, nFlags));
|
2022-01-17 23:20:03 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else { break; }
|
|
|
|
}
|
2022-04-26 20:24:51 +02:00
|
|
|
std::sort(m_vsvSuggest.begin(), m_vsvSuggest.end());
|
2022-01-16 00:59:20 +01:00
|
|
|
}
|
|
|
|
|
2021-12-25 22:36:38 +01:00
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// Purpose: executes submitted commands in a separate thread
|
2022-02-14 02:31:42 +01:00
|
|
|
// Input : pszCommand -
|
2021-12-25 22:36:38 +01:00
|
|
|
//-----------------------------------------------------------------------------
|
2022-01-14 20:45:36 +01:00
|
|
|
void CConsole::ProcessCommand(const char* pszCommand)
|
2021-12-25 22:36:38 +01:00
|
|
|
{
|
2022-05-10 23:32:44 +02:00
|
|
|
AddLog(ImVec4(1.00f, 0.80f, 0.60f, 1.00f), "# %s\n", PrintPercentageEscape(pszCommand).c_str());
|
2021-12-25 22:36:38 +01:00
|
|
|
|
2022-05-06 00:34:46 +02:00
|
|
|
std::thread t(CEngineClient_CommandExecute, this, pszCommand);
|
2021-12-25 22:36:38 +01:00
|
|
|
t.detach(); // Detach from render thread.
|
|
|
|
|
|
|
|
// This is to avoid a race condition.
|
|
|
|
std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
|
|
|
|
|
|
|
m_nHistoryPos = -1;
|
2022-02-23 15:56:03 +01:00
|
|
|
for (int i = static_cast<int>(m_vsvHistory.size()) - 1; i >= 0; i--)
|
2021-12-25 22:36:38 +01:00
|
|
|
{
|
2022-01-17 23:20:03 +01:00
|
|
|
if (Stricmp(m_vsvHistory[i].c_str(), pszCommand) == 0)
|
2021-12-25 22:36:38 +01:00
|
|
|
{
|
2022-01-17 23:20:03 +01:00
|
|
|
m_vsvHistory.erase(m_vsvHistory.begin() + i);
|
2021-12-25 22:36:38 +01:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-01-17 23:20:03 +01:00
|
|
|
m_vsvHistory.push_back(Strdup(pszCommand));
|
2022-01-14 20:45:36 +01:00
|
|
|
if (Stricmp(pszCommand, "CLEAR") == 0)
|
2021-12-25 22:36:38 +01:00
|
|
|
{
|
|
|
|
ClearLog();
|
|
|
|
}
|
2022-01-14 20:45:36 +01:00
|
|
|
else if (Stricmp(pszCommand, "HELP") == 0)
|
2021-12-25 22:36:38 +01:00
|
|
|
{
|
2022-05-10 13:26:03 +02:00
|
|
|
AddLog(ImVec4(0.81f, 0.81f, 0.81f, 1.00f), "Commands:");
|
2022-02-23 15:56:03 +01:00
|
|
|
for (int i = 0; i < static_cast<int>(m_vsvCommands.size()); i++)
|
2021-12-25 22:36:38 +01:00
|
|
|
{
|
2022-05-10 13:26:03 +02:00
|
|
|
AddLog(ImVec4(0.81f, 0.81f, 0.81f, 1.00f), "- %s", m_vsvCommands[i].c_str());
|
2021-12-25 22:36:38 +01:00
|
|
|
}
|
|
|
|
|
2022-05-10 13:26:03 +02:00
|
|
|
AddLog(ImVec4(0.81f, 0.81f, 0.81f, 1.00f), "Log types:");
|
2022-05-10 18:09:49 +02:00
|
|
|
AddLog(ImVec4(0.59f, 0.58f, 0.73f, 1.00f), "Script(S): = Server DLL (Script)");
|
|
|
|
AddLog(ImVec4(0.59f, 0.58f, 0.63f, 1.00f), "Script(C): = Client DLL (Script)");
|
|
|
|
AddLog(ImVec4(0.59f, 0.48f, 0.53f, 1.00f), "Script(U): = UI DLL (Script)");
|
2022-01-12 02:53:07 +01:00
|
|
|
|
2022-05-10 13:26:03 +02:00
|
|
|
AddLog(ImVec4(0.23f, 0.47f, 0.85f, 1.00f), "Native(S): = Server DLL (Code)");
|
|
|
|
AddLog(ImVec4(0.46f, 0.46f, 0.46f, 1.00f), "Native(C): = Client DLL (Code)");
|
|
|
|
AddLog(ImVec4(0.59f, 0.35f, 0.46f, 1.00f), "Native(U): = UI DLL (Code)");
|
2022-01-12 02:53:07 +01:00
|
|
|
|
2022-05-10 13:26:03 +02:00
|
|
|
AddLog(ImVec4(0.70f, 0.70f, 0.70f, 1.00f), "Native(E): = Engine DLL (Code)");
|
|
|
|
AddLog(ImVec4(0.32f, 0.64f, 0.72f, 1.00f), "Native(F): = FileSys DLL (Code)");
|
|
|
|
AddLog(ImVec4(0.36f, 0.70f, 0.35f, 1.00f), "Native(R): = RTech DLL (Code)");
|
|
|
|
AddLog(ImVec4(0.75f, 0.41f, 0.67f, 1.00f), "Native(M): = MatSys DLL (Code)");
|
2021-12-25 22:36:38 +01:00
|
|
|
}
|
2022-01-14 20:45:36 +01:00
|
|
|
else if (Stricmp(pszCommand, "HISTORY") == 0)
|
2021-12-25 22:36:38 +01:00
|
|
|
{
|
2022-02-23 15:56:03 +01:00
|
|
|
int nFirst = static_cast<int>(m_vsvHistory.size()) - 10;
|
|
|
|
for (int i = nFirst > 0 ? nFirst : 0; i < static_cast<int>(m_vsvHistory.size()); i++)
|
2021-12-25 22:36:38 +01:00
|
|
|
{
|
2022-05-10 13:26:03 +02:00
|
|
|
AddLog(ImVec4(0.81f, 0.81f, 0.81f, 1.00f), "%3d: %s\n", i, m_vsvHistory[i].c_str());
|
2021-12-25 22:36:38 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
m_bScrollToBottom = true;
|
|
|
|
}
|
|
|
|
|
2022-04-26 20:24:51 +02:00
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// Purpose: returns flag image index for CommandBase (must be aligned with resource.h!)
|
|
|
|
// Input : nFlags -
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
int CConsole::ColorCodeFlags(int nFlags) const
|
|
|
|
{
|
|
|
|
switch (nFlags)
|
|
|
|
{
|
|
|
|
case FCVAR_NONE:
|
|
|
|
return 1;
|
|
|
|
case FCVAR_DEVELOPMENTONLY:
|
|
|
|
return 2;
|
|
|
|
case FCVAR_GAMEDLL:
|
|
|
|
return 3;
|
|
|
|
case FCVAR_CLIENTDLL:
|
|
|
|
return 4;
|
|
|
|
case FCVAR_CHEAT:
|
|
|
|
return 5;
|
|
|
|
case FCVAR_RELEASE:
|
|
|
|
return 6;
|
|
|
|
case FCVAR_DEVELOPMENTONLY | FCVAR_GAMEDLL:
|
|
|
|
return 7;
|
|
|
|
case FCVAR_DEVELOPMENTONLY | FCVAR_CLIENTDLL:
|
|
|
|
return 8;
|
2022-04-26 20:35:51 +02:00
|
|
|
case FCVAR_DEVELOPMENTONLY | FCVAR_HIDDEN:
|
2022-04-26 20:24:51 +02:00
|
|
|
return 9;
|
2022-04-26 20:35:51 +02:00
|
|
|
case FCVAR_DEVELOPMENTONLY | FCVAR_REPLICATED:
|
2022-04-26 20:24:51 +02:00
|
|
|
return 10;
|
2022-04-26 20:35:51 +02:00
|
|
|
case FCVAR_DEVELOPMENTONLY | FCVAR_CHEAT:
|
2022-04-26 20:24:51 +02:00
|
|
|
return 11;
|
2022-04-26 20:35:51 +02:00
|
|
|
case FCVAR_REPLICATED | FCVAR_CHEAT:
|
2022-04-26 20:24:51 +02:00
|
|
|
return 12;
|
2022-04-26 20:35:51 +02:00
|
|
|
case FCVAR_REPLICATED | FCVAR_RELEASE:
|
2022-04-26 20:24:51 +02:00
|
|
|
return 13;
|
2022-04-26 20:35:51 +02:00
|
|
|
case FCVAR_GAMEDLL | FCVAR_CHEAT:
|
2022-04-26 20:24:51 +02:00
|
|
|
return 14;
|
2022-04-26 20:35:51 +02:00
|
|
|
case FCVAR_CLIENTDLL | FCVAR_CHEAT:
|
|
|
|
return 15;
|
2022-04-26 20:24:51 +02:00
|
|
|
default:
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-12-25 22:36:38 +01:00
|
|
|
//-----------------------------------------------------------------------------
|
2022-01-17 23:20:03 +01:00
|
|
|
// Purpose: console input box callback
|
2022-02-14 02:31:42 +01:00
|
|
|
// Input : *iData -
|
|
|
|
// Output :
|
2021-12-25 22:36:38 +01:00
|
|
|
//-----------------------------------------------------------------------------
|
2022-02-14 02:31:42 +01:00
|
|
|
int CConsole::TextEditCallback(ImGuiInputTextCallbackData* iData)
|
2021-12-25 22:36:38 +01:00
|
|
|
{
|
2022-02-14 02:31:42 +01:00
|
|
|
switch (iData->EventFlag)
|
2021-12-25 22:36:38 +01:00
|
|
|
{
|
|
|
|
case ImGuiInputTextFlags_CallbackCompletion:
|
|
|
|
{
|
|
|
|
// Locate beginning of current word.
|
2022-02-14 02:31:42 +01:00
|
|
|
const char* pszWordEnd = iData->Buf + iData->CursorPos;
|
2022-01-14 20:45:36 +01:00
|
|
|
const char* pszWordStart = pszWordEnd;
|
2022-02-14 02:31:42 +01:00
|
|
|
while (pszWordStart > iData->Buf)
|
2021-12-25 22:36:38 +01:00
|
|
|
{
|
2022-01-14 20:45:36 +01:00
|
|
|
const char c = pszWordStart[-1];
|
2021-12-25 22:36:38 +01:00
|
|
|
if (c == ' ' || c == '\t' || c == ',' || c == ';')
|
|
|
|
{
|
|
|
|
break;
|
|
|
|
}
|
2022-01-14 20:45:36 +01:00
|
|
|
pszWordStart--;
|
2021-12-25 22:36:38 +01:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case ImGuiInputTextFlags_CallbackHistory:
|
|
|
|
{
|
2022-01-17 23:20:03 +01:00
|
|
|
if (m_bSuggestActive)
|
2021-12-25 22:36:38 +01:00
|
|
|
{
|
2022-02-14 02:31:42 +01:00
|
|
|
if (iData->EventKey == ImGuiKey_UpArrow && m_nSuggestPos > - 1)
|
2021-12-25 22:36:38 +01:00
|
|
|
{
|
2022-01-17 23:20:03 +01:00
|
|
|
m_nSuggestPos--;
|
|
|
|
m_bSuggestMoved = true;
|
|
|
|
}
|
2022-02-14 02:31:42 +01:00
|
|
|
else if (iData->EventKey == ImGuiKey_DownArrow)
|
2022-01-17 23:20:03 +01:00
|
|
|
{
|
2022-02-23 15:56:03 +01:00
|
|
|
if (m_nSuggestPos < static_cast<int>(m_vsvSuggest.size()) - 1)
|
2021-12-25 22:36:38 +01:00
|
|
|
{
|
2022-01-17 23:20:03 +01:00
|
|
|
m_nSuggestPos++;
|
|
|
|
m_bSuggestMoved = true;
|
2021-12-25 22:36:38 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2022-01-17 23:20:03 +01:00
|
|
|
else // Allow user to navigate through the history if suggest isn't drawn.
|
2021-12-25 22:36:38 +01:00
|
|
|
{
|
2022-01-17 23:20:03 +01:00
|
|
|
const int nPrevHistoryPos = m_nHistoryPos;
|
2022-02-14 02:31:42 +01:00
|
|
|
if (iData->EventKey == ImGuiKey_UpArrow)
|
2022-01-17 23:20:03 +01:00
|
|
|
{
|
|
|
|
if (m_nHistoryPos == -1)
|
|
|
|
{
|
2022-02-23 15:56:03 +01:00
|
|
|
m_nHistoryPos = static_cast<int>(m_vsvHistory.size()) - 1;
|
2022-01-17 23:20:03 +01:00
|
|
|
}
|
|
|
|
else if (m_nHistoryPos > 0)
|
|
|
|
{
|
|
|
|
m_nHistoryPos--;
|
|
|
|
}
|
|
|
|
}
|
2022-02-14 02:31:42 +01:00
|
|
|
else if (iData->EventKey == ImGuiKey_DownArrow)
|
2022-01-17 23:20:03 +01:00
|
|
|
{
|
|
|
|
if (m_nHistoryPos != -1)
|
|
|
|
{
|
2022-02-23 15:56:03 +01:00
|
|
|
if (++m_nHistoryPos >= static_cast<int>(m_vsvHistory.size()))
|
2022-01-17 23:20:03 +01:00
|
|
|
{
|
|
|
|
m_nHistoryPos = -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (nPrevHistoryPos != m_nHistoryPos)
|
|
|
|
{
|
2022-04-26 20:24:51 +02:00
|
|
|
string svHistory = (m_nHistoryPos >= 0) ? m_vsvHistory[m_nHistoryPos] : "";
|
2022-01-17 23:20:03 +01:00
|
|
|
|
|
|
|
if (!svHistory.empty())
|
|
|
|
{
|
|
|
|
if (!strstr(m_vsvHistory[m_nHistoryPos].c_str(), " "))
|
|
|
|
{
|
|
|
|
// Append whitespace to previous entered command if absent or no parameters where passed.
|
|
|
|
svHistory.append(" ");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-02-14 02:31:42 +01:00
|
|
|
iData->DeleteChars(0, iData->BufTextLen);
|
|
|
|
iData->InsertChars(0, svHistory.c_str());
|
2022-01-17 23:20:03 +01:00
|
|
|
}
|
2021-12-25 22:36:38 +01:00
|
|
|
}
|
2022-01-17 23:20:03 +01:00
|
|
|
break;
|
2021-12-25 22:36:38 +01:00
|
|
|
}
|
2022-01-28 12:56:51 +01:00
|
|
|
case ImGuiInputTextFlags_CallbackAlways:
|
|
|
|
{
|
2022-02-21 12:06:05 +01:00
|
|
|
static char szCurInputBuf[512]{};
|
|
|
|
if (strcmp(m_szInputBuf, szCurInputBuf) != 0) // Only run if changed.
|
2022-01-28 12:56:51 +01:00
|
|
|
{
|
2022-02-21 12:06:05 +01:00
|
|
|
char szValue[512]{};
|
|
|
|
memmove(szCurInputBuf, m_szInputBuf, strlen(m_szInputBuf) + 1);
|
|
|
|
sprintf_s(szValue, sizeof(szValue), "%s", m_szInputBuf);
|
|
|
|
|
|
|
|
// Remove space or semicolon before we call 'g_pCVar->FindVar(..)'.
|
2022-06-15 02:06:30 +02:00
|
|
|
for (size_t i = 0; i < strlen(szValue); i++)
|
2022-01-28 12:56:51 +01:00
|
|
|
{
|
2022-02-21 12:06:05 +01:00
|
|
|
if (szValue[i] == ' ' || szValue[i] == ';')
|
|
|
|
{
|
|
|
|
szValue[i] = '\0';
|
|
|
|
}
|
2022-01-28 12:56:51 +01:00
|
|
|
}
|
|
|
|
|
2022-02-21 12:06:05 +01:00
|
|
|
ConVar* pConVar = g_pCVar->FindVar(szValue);
|
2022-06-15 02:06:30 +02:00
|
|
|
if (pConVar)
|
2022-02-21 12:06:05 +01:00
|
|
|
{
|
|
|
|
// Display the current and default value of ConVar if found.
|
|
|
|
snprintf(m_szSummary, 256, "(\"%s\", default \"%s\")", pConVar->GetString(), pConVar->GetDefault());
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// Display amount of history items if ConVar cannot be found.
|
|
|
|
snprintf(m_szSummary, 256, "%llu history items", m_vsvHistory.size());
|
|
|
|
}
|
|
|
|
break;
|
2022-01-28 12:56:51 +01:00
|
|
|
}
|
|
|
|
}
|
2021-12-25 22:36:38 +01:00
|
|
|
}
|
2022-03-25 13:31:31 +01:00
|
|
|
return NULL;
|
2021-12-25 22:36:38 +01:00
|
|
|
}
|
|
|
|
|
2022-01-12 02:53:07 +01:00
|
|
|
//-----------------------------------------------------------------------------
|
2022-01-17 23:20:03 +01:00
|
|
|
// Purpose: console input box callback stub
|
2022-02-14 02:31:42 +01:00
|
|
|
// Input : *iData -
|
|
|
|
// Output :
|
2022-01-12 02:53:07 +01:00
|
|
|
//-----------------------------------------------------------------------------
|
2022-02-14 02:31:42 +01:00
|
|
|
int CConsole::TextEditCallbackStub(ImGuiInputTextCallbackData* iData)
|
2022-01-12 02:53:07 +01:00
|
|
|
{
|
2022-02-23 15:56:03 +01:00
|
|
|
CConsole* pConsole = reinterpret_cast<CConsole*>(iData->UserData);
|
2022-02-14 02:31:42 +01:00
|
|
|
return pConsole->TextEditCallback(iData);
|
2022-01-12 02:53:07 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// Purpose: adds logs to the vector
|
2022-02-14 02:31:42 +01:00
|
|
|
// Input : *fmt -
|
|
|
|
// ... -
|
2022-01-12 02:53:07 +01:00
|
|
|
//-----------------------------------------------------------------------------
|
2022-05-10 13:26:03 +02:00
|
|
|
void CConsole::AddLog(ImVec4 color, const char* fmt, ...) IM_FMTARGS(2)
|
2022-01-12 02:53:07 +01:00
|
|
|
{
|
|
|
|
char buf[1024];
|
2022-03-25 13:17:57 +01:00
|
|
|
va_list args{};
|
2022-01-12 02:53:07 +01:00
|
|
|
va_start(args, fmt);
|
|
|
|
vsnprintf(buf, IM_ARRAYSIZE(buf), fmt, args);
|
|
|
|
buf[IM_ARRAYSIZE(buf) - 1] = 0;
|
|
|
|
va_end(args);
|
2022-05-10 18:09:49 +02:00
|
|
|
m_ivConLog.push_back(CConLog(Strdup(buf), color));
|
2022-01-12 02:53:07 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// Purpose: clears the entire vector
|
|
|
|
//-----------------------------------------------------------------------------
|
2022-01-17 23:20:03 +01:00
|
|
|
void CConsole::ClearLog(void)
|
2022-01-12 02:53:07 +01:00
|
|
|
{
|
2022-05-09 02:20:07 +02:00
|
|
|
//for (int i = 0; i < m_ivConLog.size(); i++) { free(m_ivConLog[i]); }
|
2022-01-12 02:53:07 +01:00
|
|
|
m_ivConLog.clear();
|
|
|
|
}
|
2021-12-25 22:36:38 +01:00
|
|
|
|
2022-01-12 02:53:07 +01:00
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// Purpose: colors important logs
|
|
|
|
//-----------------------------------------------------------------------------
|
2022-02-14 02:31:42 +01:00
|
|
|
void CConsole::ColorLog(void) const
|
2021-12-25 22:36:38 +01:00
|
|
|
{
|
2022-06-15 02:07:27 +02:00
|
|
|
for (size_t i = 0; i < m_ivConLog.size(); i++)
|
2021-12-25 22:36:38 +01:00
|
|
|
{
|
2022-05-09 02:20:07 +02:00
|
|
|
if (!m_itFilter.PassFilter(m_ivConLog[i].m_svConLog.c_str()))
|
2022-01-12 02:53:07 +01:00
|
|
|
{
|
|
|
|
continue;
|
|
|
|
}
|
2022-05-09 02:20:07 +02:00
|
|
|
|
2022-05-10 13:26:03 +02:00
|
|
|
ImGui::PushStyleColor(ImGuiCol_Text, m_ivConLog[i].m_imColor);
|
2022-05-09 02:20:07 +02:00
|
|
|
ImGui::TextWrapped(m_ivConLog[i].m_svConLog.c_str());
|
2022-01-14 20:45:36 +01:00
|
|
|
ImGui::PopStyleColor();
|
2022-05-10 13:26:03 +02:00
|
|
|
///////////////////////////////////////////////////////////////////////
|
2022-01-12 02:53:07 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// Purpose: sets the console front-end style
|
|
|
|
//-----------------------------------------------------------------------------
|
2022-01-17 23:20:03 +01:00
|
|
|
void CConsole::SetStyleVar(void)
|
2022-01-12 02:53:07 +01:00
|
|
|
{
|
2022-01-18 11:23:14 +01:00
|
|
|
ImGuiStyle& style = ImGui::GetStyle();
|
|
|
|
ImVec4* colors = style.Colors;
|
|
|
|
|
2022-04-16 00:30:46 +02:00
|
|
|
if (!CommandLine()->CheckParm("-imgui_default_theme"))
|
2022-01-18 11:23:14 +01:00
|
|
|
{
|
|
|
|
colors[ImGuiCol_Text] = ImVec4(0.81f, 0.81f, 0.81f, 1.00f);
|
|
|
|
colors[ImGuiCol_TextDisabled] = ImVec4(0.56f, 0.56f, 0.56f, 1.00f);
|
|
|
|
colors[ImGuiCol_WindowBg] = ImVec4(0.27f, 0.27f, 0.27f, 1.00f);
|
|
|
|
colors[ImGuiCol_ChildBg] = ImVec4(0.00f, 0.00f, 0.00f, 1.00f);
|
|
|
|
colors[ImGuiCol_PopupBg] = ImVec4(0.27f, 0.27f, 0.27f, 1.00f);
|
|
|
|
colors[ImGuiCol_Border] = ImVec4(0.41f, 0.41f, 0.41f, 1.00f);
|
|
|
|
colors[ImGuiCol_BorderShadow] = ImVec4(0.04f, 0.04f, 0.04f, 0.64f);
|
|
|
|
colors[ImGuiCol_FrameBg] = ImVec4(0.13f, 0.13f, 0.13f, 1.00f);
|
|
|
|
colors[ImGuiCol_FrameBgHovered] = ImVec4(0.19f, 0.19f, 0.19f, 1.00f);
|
|
|
|
colors[ImGuiCol_FrameBgActive] = ImVec4(0.24f, 0.24f, 0.24f, 1.00f);
|
|
|
|
colors[ImGuiCol_TitleBg] = ImVec4(0.22f, 0.22f, 0.22f, 1.00f);
|
|
|
|
colors[ImGuiCol_TitleBgActive] = ImVec4(0.27f, 0.27f, 0.27f, 1.00f);
|
|
|
|
colors[ImGuiCol_TitleBgCollapsed] = ImVec4(0.00f, 0.00f, 0.00f, 1.00f);
|
|
|
|
colors[ImGuiCol_MenuBarBg] = ImVec4(0.22f, 0.22f, 0.22f, 1.00f);
|
|
|
|
colors[ImGuiCol_ScrollbarBg] = ImVec4(0.10f, 0.10f, 0.10f, 1.00f);
|
|
|
|
colors[ImGuiCol_ScrollbarGrab] = ImVec4(0.41f, 0.41f, 0.41f, 1.00f);
|
|
|
|
colors[ImGuiCol_ScrollbarGrabHovered] = ImVec4(0.53f, 0.53f, 0.53f, 1.00f);
|
|
|
|
colors[ImGuiCol_ScrollbarGrabActive] = ImVec4(0.63f, 0.63f, 0.63f, 1.00f);
|
|
|
|
colors[ImGuiCol_CheckMark] = ImVec4(0.61f, 0.61f, 0.61f, 1.00f);
|
|
|
|
colors[ImGuiCol_SliderGrab] = ImVec4(0.41f, 0.41f, 0.41f, 1.00f);
|
|
|
|
colors[ImGuiCol_SliderGrabActive] = ImVec4(0.53f, 0.53f, 0.53f, 1.00f);
|
|
|
|
colors[ImGuiCol_Button] = ImVec4(0.35f, 0.35f, 0.35f, 1.00f);
|
|
|
|
colors[ImGuiCol_ButtonHovered] = ImVec4(0.45f, 0.45f, 0.45f, 1.00f);
|
|
|
|
colors[ImGuiCol_ButtonActive] = ImVec4(0.52f, 0.52f, 0.52f, 1.00f);
|
|
|
|
colors[ImGuiCol_Header] = ImVec4(0.35f, 0.35f, 0.35f, 1.00f);
|
|
|
|
colors[ImGuiCol_HeaderHovered] = ImVec4(0.45f, 0.45f, 0.45f, 1.00f);
|
|
|
|
colors[ImGuiCol_HeaderActive] = ImVec4(0.53f, 0.53f, 0.53f, 1.00f);
|
|
|
|
colors[ImGuiCol_Separator] = ImVec4(0.53f, 0.53f, 0.57f, 1.00f);
|
|
|
|
colors[ImGuiCol_SeparatorHovered] = ImVec4(0.53f, 0.53f, 0.53f, 1.00f);
|
|
|
|
colors[ImGuiCol_SeparatorActive] = ImVec4(0.63f, 0.63f, 0.63f, 1.00f);
|
|
|
|
colors[ImGuiCol_ResizeGrip] = ImVec4(0.41f, 0.41f, 0.41f, 1.00f);
|
|
|
|
colors[ImGuiCol_ResizeGripHovered] = ImVec4(0.52f, 0.52f, 0.52f, 1.00f);
|
|
|
|
colors[ImGuiCol_ResizeGripActive] = ImVec4(0.63f, 0.63f, 0.63f, 1.00f);
|
|
|
|
colors[ImGuiCol_Tab] = ImVec4(0.18f, 0.18f, 0.18f, 1.00f);
|
|
|
|
colors[ImGuiCol_TabHovered] = ImVec4(0.39f, 0.39f, 0.39f, 1.00f);
|
|
|
|
colors[ImGuiCol_TabActive] = ImVec4(0.39f, 0.39f, 0.39f, 1.00f);
|
2022-01-28 12:56:51 +01:00
|
|
|
|
|
|
|
style.WindowBorderSize = 0.0f;
|
|
|
|
style.FrameBorderSize = 1.0f;
|
|
|
|
style.ChildBorderSize = 1.0f;
|
|
|
|
style.PopupBorderSize = 1.0f;
|
|
|
|
style.TabBorderSize = 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;
|
2022-01-18 11:23:14 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2022-01-28 12:56:51 +01:00
|
|
|
colors[ImGuiCol_WindowBg] = ImVec4(0.11f, 0.13f, 0.17f, 1.00f);
|
|
|
|
colors[ImGuiCol_ChildBg] = ImVec4(0.02f, 0.04f, 0.06f, 1.00f);
|
|
|
|
colors[ImGuiCol_PopupBg] = ImVec4(0.11f, 0.13f, 0.17f, 1.00f);
|
|
|
|
colors[ImGuiCol_Border] = ImVec4(0.41f, 0.41f, 0.41f, 0.50f);
|
|
|
|
colors[ImGuiCol_BorderShadow] = ImVec4(0.04f, 0.04f, 0.04f, 0.00f);
|
|
|
|
colors[ImGuiCol_FrameBg] = ImVec4(0.02f, 0.04f, 0.06f, 1.00f);
|
|
|
|
colors[ImGuiCol_FrameBgHovered] = ImVec4(0.04f, 0.06f, 0.10f, 1.00f);
|
|
|
|
colors[ImGuiCol_FrameBgActive] = ImVec4(0.04f, 0.07f, 0.12f, 1.00f);
|
|
|
|
colors[ImGuiCol_TitleBg] = ImVec4(0.26f, 0.51f, 0.78f, 1.00f);
|
|
|
|
colors[ImGuiCol_TitleBgActive] = ImVec4(0.26f, 0.51f, 0.78f, 1.00f);
|
|
|
|
colors[ImGuiCol_MenuBarBg] = ImVec4(0.11f, 0.13f, 0.17f, 1.00f);
|
|
|
|
colors[ImGuiCol_ScrollbarBg] = ImVec4(0.14f, 0.19f, 0.24f, 1.00f);
|
|
|
|
colors[ImGuiCol_ScrollbarGrab] = ImVec4(0.23f, 0.36f, 0.51f, 1.00f);
|
|
|
|
colors[ImGuiCol_ScrollbarGrabHovered] = ImVec4(0.30f, 0.46f, 0.65f, 1.00f);
|
|
|
|
colors[ImGuiCol_ScrollbarGrabActive] = ImVec4(0.31f, 0.49f, 0.69f, 1.00f);
|
|
|
|
colors[ImGuiCol_SliderGrab] = ImVec4(0.31f, 0.43f, 0.43f, 1.00f);
|
|
|
|
colors[ImGuiCol_SliderGrabActive] = ImVec4(0.41f, 0.56f, 0.57f, 1.00f);
|
|
|
|
colors[ImGuiCol_Button] = ImVec4(0.31f, 0.43f, 0.43f, 1.00f);
|
|
|
|
colors[ImGuiCol_ButtonHovered] = ImVec4(0.38f, 0.52f, 0.53f, 1.00f);
|
|
|
|
colors[ImGuiCol_ButtonActive] = ImVec4(0.41f, 0.56f, 0.57f, 1.00f);
|
|
|
|
colors[ImGuiCol_Header] = ImVec4(0.31f, 0.43f, 0.43f, 1.00f);
|
|
|
|
colors[ImGuiCol_HeaderHovered] = ImVec4(0.38f, 0.53f, 0.53f, 1.00f);
|
|
|
|
colors[ImGuiCol_HeaderActive] = ImVec4(0.41f, 0.56f, 0.57f, 1.00f);
|
|
|
|
colors[ImGuiCol_Separator] = ImVec4(0.53f, 0.53f, 0.57f, 0.00f);
|
|
|
|
colors[ImGuiCol_ResizeGrip] = ImVec4(0.41f, 0.41f, 0.41f, 0.50f);
|
|
|
|
colors[ImGuiCol_Tab] = ImVec4(0.31f, 0.43f, 0.43f, 1.00f);
|
|
|
|
colors[ImGuiCol_TabHovered] = ImVec4(0.38f, 0.53f, 0.53f, 1.00f);
|
|
|
|
colors[ImGuiCol_TabActive] = ImVec4(0.41f, 0.56f, 0.57f, 1.00f);
|
|
|
|
colors[ImGuiCol_TableHeaderBg] = ImVec4(0.14f, 0.19f, 0.24f, 1.00f);
|
|
|
|
colors[ImGuiCol_TableBorderStrong] = ImVec4(0.20f, 0.26f, 0.33f, 1.00f);
|
|
|
|
colors[ImGuiCol_TableBorderLight] = ImVec4(0.22f, 0.29f, 0.37f, 1.00f);
|
|
|
|
|
|
|
|
style.WindowBorderSize = 1.0f;
|
|
|
|
style.FrameBorderSize = 0.0f;
|
|
|
|
style.ChildBorderSize = 0.0f;
|
|
|
|
style.PopupBorderSize = 1.0f;
|
|
|
|
style.TabBorderSize = 1.0f;
|
|
|
|
|
|
|
|
style.WindowRounding = 4.0f;
|
|
|
|
style.FrameRounding = 1.0f;
|
|
|
|
style.ChildRounding = 1.0f;
|
|
|
|
style.PopupRounding = 3.0f;
|
|
|
|
style.TabRounding = 1.0f;
|
|
|
|
style.ScrollbarRounding = 3.0f;
|
|
|
|
|
|
|
|
m_bDefaultTheme = true;
|
2022-01-18 11:23:14 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
style.ItemSpacing = ImVec2(4, 4);
|
2022-01-22 15:51:09 +01:00
|
|
|
style.FramePadding = ImVec2(4, 4);
|
2022-01-18 11:23:14 +01:00
|
|
|
style.WindowPadding = ImVec2(5, 5);
|
2022-02-23 21:02:37 +01:00
|
|
|
style.WindowMinSize = ImVec2(618, 518);
|
2021-12-25 22:36:38 +01:00
|
|
|
}
|
|
|
|
|
2022-05-27 02:46:13 +02:00
|
|
|
CConsole* g_pConsole = new CConsole();
|