2022-08-22 01:10:18 +02:00
|
|
|
|
/******************************************************************************
|
2021-12-25 22:36:38 +01:00
|
|
|
|
-------------------------------------------------------------------------------
|
|
|
|
|
File : IConsole.cpp
|
2023-09-17 11:38:00 +02:00
|
|
|
|
Date : 15:06:2021
|
2021-12-25 22:36:38 +01:00
|
|
|
|
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
|
2022-09-09 19:47:31 +02:00
|
|
|
|
- 07:08:2021 | 15:22 : Multi-thread 'CommandExecute' operations to prevent deadlock in render thread
|
|
|
|
|
- 07:08:2021 | 15:25 : Fix a race condition that occurred when detaching the 'CommandExecute' thread
|
2021-12-25 22:36:38 +01:00
|
|
|
|
|
|
|
|
|
******************************************************************************/
|
|
|
|
|
|
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-08-19 21:33:31 +02:00
|
|
|
|
#include "tier0/frametask.h"
|
2022-01-18 11:23:14 +01:00
|
|
|
|
#include "tier0/commandline.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"
|
2023-05-10 00:05:38 +02:00
|
|
|
|
#include "engine/cmd.h"
|
2022-01-12 02:53:07 +01:00
|
|
|
|
#include "gameui/IConsole.h"
|
|
|
|
|
|
2021-12-25 22:36:38 +01:00
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
// Purpose:
|
|
|
|
|
//-----------------------------------------------------------------------------
|
2022-10-19 16:10:36 +02:00
|
|
|
|
CConsole::CConsole(void)
|
|
|
|
|
: m_pszConsoleLabel("Console")
|
|
|
|
|
, m_pszLoggingLabel("LoggingRegion")
|
2023-09-17 11:38:00 +02:00
|
|
|
|
, m_nHistoryPos(PositionMode_t::kPark)
|
|
|
|
|
, m_nSuggestPos(PositionMode_t::kPark)
|
2022-10-19 16:10:36 +02:00
|
|
|
|
, m_nScrollBack(0)
|
|
|
|
|
, m_nSelectBack(0)
|
2022-11-10 22:01:34 +01:00
|
|
|
|
, m_nInputTextLen(0)
|
2022-10-19 16:10:36 +02:00
|
|
|
|
, m_flScrollX(0.f)
|
|
|
|
|
, m_flScrollY(0.f)
|
|
|
|
|
, m_flFadeAlpha(0.f)
|
|
|
|
|
, m_bInitialized(false)
|
|
|
|
|
, m_bReclaimFocus(false)
|
|
|
|
|
, m_bCopyToClipBoard(false)
|
|
|
|
|
, m_bModifyInput(false)
|
|
|
|
|
, m_bCanAutoComplete(false)
|
|
|
|
|
, m_bSuggestActive(false)
|
|
|
|
|
, m_bSuggestMoved(false)
|
|
|
|
|
, m_bSuggestUpdate(false)
|
|
|
|
|
, m_Style(ImGuiStyle_t::NONE)
|
2023-04-08 17:46:08 +02:00
|
|
|
|
, m_bActivate(false)
|
2021-12-25 22:36:38 +01:00
|
|
|
|
{
|
2022-10-19 16:10:36 +02:00
|
|
|
|
m_nInputFlags =
|
|
|
|
|
ImGuiInputTextFlags_EnterReturnsTrue |
|
|
|
|
|
ImGuiInputTextFlags_CallbackCompletion |
|
|
|
|
|
ImGuiInputTextFlags_CallbackHistory |
|
|
|
|
|
ImGuiInputTextFlags_CallbackAlways |
|
2022-11-10 21:19:17 +01:00
|
|
|
|
ImGuiInputTextFlags_CallbackCharFilter |
|
2022-10-19 16:10:36 +02:00
|
|
|
|
ImGuiInputTextFlags_CallbackEdit |
|
|
|
|
|
ImGuiInputTextFlags_AutoCaretEnd;
|
|
|
|
|
|
|
|
|
|
m_nSuggestFlags =
|
|
|
|
|
ImGuiWindowFlags_NoTitleBar |
|
|
|
|
|
ImGuiWindowFlags_NoMove |
|
|
|
|
|
ImGuiWindowFlags_NoSavedSettings |
|
|
|
|
|
ImGuiWindowFlags_NoFocusOnAppearing |
|
|
|
|
|
ImGuiWindowFlags_AlwaysVerticalScrollbar |
|
|
|
|
|
ImGuiWindowFlags_AlwaysHorizontalScrollbar;
|
|
|
|
|
|
|
|
|
|
m_nLoggingFlags =
|
|
|
|
|
ImGuiWindowFlags_NoMove |
|
|
|
|
|
ImGuiWindowFlags_HorizontalScrollbar |
|
|
|
|
|
ImGuiWindowFlags_AlwaysVerticalScrollbar;
|
2021-12-25 22:36:38 +01:00
|
|
|
|
|
2022-10-19 16:10:36 +02:00
|
|
|
|
memset(m_szInputBuf, '\0', sizeof(m_szInputBuf));
|
|
|
|
|
memset(m_szWindowLabel, '\0', sizeof(m_szWindowLabel));
|
2022-06-26 16:47:00 +02:00
|
|
|
|
snprintf(m_szSummary, sizeof(m_szSummary), "%zu history items", m_vHistory.size());
|
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
|
|
|
|
{
|
2023-04-23 20:34:36 +02:00
|
|
|
|
for (MODULERESOURCE& flagIcon : m_vFlagIcons)
|
|
|
|
|
{
|
|
|
|
|
if (flagIcon.m_idIcon)
|
|
|
|
|
{
|
|
|
|
|
flagIcon.m_idIcon->Release();
|
|
|
|
|
}
|
|
|
|
|
}
|
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
|
|
|
|
|
//-----------------------------------------------------------------------------
|
2022-08-14 15:43:49 +02:00
|
|
|
|
bool CConsole::Init(void)
|
2022-04-26 20:24:51 +02:00
|
|
|
|
{
|
|
|
|
|
SetStyleVar();
|
2022-06-24 12:22:04 +02:00
|
|
|
|
return LoadFlagIcons();
|
2022-04-26 20:24:51 +02:00
|
|
|
|
}
|
|
|
|
|
|
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-08-14 15:43:49 +02:00
|
|
|
|
void CConsole::RunFrame(void)
|
2021-12-25 22:36:38 +01:00
|
|
|
|
{
|
2022-10-20 12:29:21 +02:00
|
|
|
|
// Uncomment these when adjusting the theme or layout.
|
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-10-20 12:29:21 +02:00
|
|
|
|
if (!m_bInitialized)
|
|
|
|
|
{
|
|
|
|
|
Init();
|
|
|
|
|
m_bInitialized = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int nVars = 0;
|
2023-01-30 01:59:25 +01:00
|
|
|
|
float flWidth;
|
2023-01-30 01:52:32 +01:00
|
|
|
|
float flHeight;
|
2022-08-22 01:10:18 +02:00
|
|
|
|
if (m_Style == ImGuiStyle_t::MODERN)
|
2022-01-28 12:56:51 +01:00
|
|
|
|
{
|
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++;
|
2023-01-30 01:52:32 +01:00
|
|
|
|
|
2023-01-30 01:59:25 +01:00
|
|
|
|
flWidth = 621.f;
|
2023-01-30 01:52:32 +01:00
|
|
|
|
flHeight = 532.f;
|
2022-01-28 12:56:51 +01:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2023-01-30 01:52:32 +01:00
|
|
|
|
if (m_Style == ImGuiStyle_t::LEGACY)
|
|
|
|
|
{
|
2023-01-30 01:59:25 +01:00
|
|
|
|
flWidth = 619.f;
|
2023-01-30 01:52:32 +01:00
|
|
|
|
flHeight = 526.f;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2023-01-30 01:59:25 +01:00
|
|
|
|
flWidth = 618.f;
|
2023-01-30 01:52:32 +01:00
|
|
|
|
flHeight = 524.f;
|
|
|
|
|
}
|
|
|
|
|
|
2022-06-24 12:45:47 +02:00
|
|
|
|
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2{ 6.f, 6.f }); nVars++;
|
2022-06-09 02:22:01 +02:00
|
|
|
|
ImGui::PushStyleVar(ImGuiStyleVar_Alpha, m_flFadeAlpha); nVars++;
|
2022-01-28 12:56:51 +01:00
|
|
|
|
}
|
2023-01-30 01:59:25 +01:00
|
|
|
|
ImGui::PushStyleVar(ImGuiStyleVar_WindowMinSize, ImVec2(flWidth, flHeight)); nVars++;
|
2022-01-17 23:20:03 +01:00
|
|
|
|
|
2022-08-14 15:43:49 +02:00
|
|
|
|
DrawSurface();
|
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-18 18:11:05 +02:00
|
|
|
|
int nVars = 0;
|
2022-06-22 03:24:46 +02:00
|
|
|
|
if (AutoComplete())
|
2022-01-17 23:20:03 +01:00
|
|
|
|
{
|
2022-08-22 01:10:18 +02:00
|
|
|
|
if (m_Style == ImGuiStyle_t::MODERN)
|
2022-01-28 12:56:51 +01:00
|
|
|
|
{
|
2023-06-17 16:30:10 +02:00
|
|
|
|
const 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-06-26 16:47:00 +02:00
|
|
|
|
if (m_bSuggestUpdate)
|
|
|
|
|
{
|
|
|
|
|
ImGui::SetNextWindowScroll(ImVec2(0.f, 0.f));
|
|
|
|
|
m_bSuggestUpdate = false;
|
|
|
|
|
}
|
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
|
|
|
|
//-----------------------------------------------------------------------------
|
2022-08-20 01:48:42 +02:00
|
|
|
|
// Purpose: runs tasks for the console while not being drawn
|
|
|
|
|
// (!!! RunTask and RunFrame must be called from the same thread !!!)
|
2022-01-17 23:20:03 +01:00
|
|
|
|
//-----------------------------------------------------------------------------
|
2022-10-24 00:50:07 +02:00
|
|
|
|
void CConsole::RunTask(void)
|
2022-01-17 23:20:03 +01:00
|
|
|
|
{
|
2022-10-19 16:10:36 +02:00
|
|
|
|
// m_Logger and m_vHistory are modified.
|
|
|
|
|
std::lock_guard<std::mutex> l(m_Mutex);
|
|
|
|
|
|
2022-08-22 01:10:18 +02:00
|
|
|
|
ClampLogSize();
|
|
|
|
|
ClampHistorySize();
|
2022-08-20 01:48:42 +02:00
|
|
|
|
}
|
2022-06-09 02:22:01 +02:00
|
|
|
|
|
2022-08-20 01:48:42 +02:00
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
// Purpose: think
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
void CConsole::Think(void)
|
|
|
|
|
{
|
2022-08-29 02:21:32 +02:00
|
|
|
|
if (m_bActivate)
|
2022-08-20 01:48:42 +02:00
|
|
|
|
{
|
2022-10-18 02:11:52 +02:00
|
|
|
|
if (m_flFadeAlpha < 1.f)
|
2022-06-09 02:22:01 +02:00
|
|
|
|
{
|
2023-04-16 02:45:22 +02:00
|
|
|
|
m_flFadeAlpha += .05f;
|
|
|
|
|
m_flFadeAlpha = (std::min)(m_flFadeAlpha, 1.f);
|
2022-06-09 02:22:01 +02:00
|
|
|
|
}
|
2022-08-29 02:21:32 +02:00
|
|
|
|
}
|
|
|
|
|
else // Reset to full transparent.
|
|
|
|
|
{
|
2023-04-16 02:45:22 +02:00
|
|
|
|
if (m_flFadeAlpha > 0.f)
|
|
|
|
|
{
|
|
|
|
|
m_flFadeAlpha -= .05f;
|
|
|
|
|
m_flFadeAlpha = (std::max)(m_flFadeAlpha, 0.f);
|
|
|
|
|
}
|
|
|
|
|
|
2022-08-29 02:21:32 +02:00
|
|
|
|
m_bReclaimFocus = true;
|
2022-06-09 02:22:01 +02:00
|
|
|
|
}
|
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-08-14 15:43:49 +02:00
|
|
|
|
void CConsole::DrawSurface(void)
|
2022-01-17 23:20:03 +01:00
|
|
|
|
{
|
2022-10-20 01:17:51 +02:00
|
|
|
|
if (!ImGui::Begin(m_pszConsoleLabel, &m_bActivate, ImGuiWindowFlags_None, &ResetInput))
|
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
|
|
|
|
}
|
|
|
|
|
|
2023-06-17 16:30:10 +02:00
|
|
|
|
const ImGuiStyle& style = ImGui::GetStyle();
|
|
|
|
|
|
2021-12-25 22:36:38 +01:00
|
|
|
|
// Reserve enough left-over height and width for 1 separator + 1 input text
|
2023-06-17 16:30:10 +02:00
|
|
|
|
const float flFooterHeightReserve = style.ItemSpacing.y + ImGui::GetFrameHeightWithSpacing();
|
|
|
|
|
const float flFooterWidthReserve = style.ItemSpacing.y + ImGui::GetWindowWidth();
|
2021-12-25 22:36:38 +01:00
|
|
|
|
|
2022-06-22 03:24:46 +02:00
|
|
|
|
ImVec2 fontSize = ImGui::GetFont()->CalcTextSizeA(ImGui::GetFontSize(), FLT_MAX, -1.0f, "#", nullptr, nullptr);
|
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();
|
2023-04-09 22:35:55 +02:00
|
|
|
|
m_Logger.GetFilter().Draw("Filter | ", flFooterWidthReserve - 500);
|
2022-01-28 12:56:51 +01:00
|
|
|
|
|
|
|
|
|
ImGui::SameLine();
|
2023-04-08 19:10:59 +02:00
|
|
|
|
ImGui::Text("%s", m_szSummary);
|
2022-01-28 12:56:51 +01:00
|
|
|
|
|
2021-12-25 22:36:38 +01:00
|
|
|
|
ImGui::Separator();
|
|
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////
|
2023-04-09 22:35:55 +02:00
|
|
|
|
if (!m_Logger.IsScrolledToBottom() && m_nScrollBack > 0)
|
2022-06-26 16:47:00 +02:00
|
|
|
|
{
|
|
|
|
|
ImGuiWindow* pWindow = ImGui::GetCurrentWindow();
|
|
|
|
|
ImGuiID nID = pWindow->GetID(m_pszLoggingLabel);
|
|
|
|
|
|
|
|
|
|
snprintf(m_szWindowLabel, sizeof(m_szWindowLabel), "%s/%s_%08X", m_pszConsoleLabel, m_pszLoggingLabel, nID);
|
|
|
|
|
ImGui::SetWindowScrollY(m_szWindowLabel, m_flScrollY - m_nScrollBack * fontSize.y);
|
|
|
|
|
}
|
|
|
|
|
m_nScrollBack = 0;
|
|
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////
|
2023-01-30 01:52:32 +01:00
|
|
|
|
int iVars = 0; // Eliminate borders around log window.
|
|
|
|
|
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2{ 1.f, 1.f }); iVars++;
|
2022-06-26 16:47:00 +02:00
|
|
|
|
ImGui::BeginChild(m_pszLoggingLabel, ImVec2(0, -flFooterHeightReserve), true, m_nLoggingFlags);
|
2022-08-22 01:10:18 +02:00
|
|
|
|
|
2022-10-19 16:10:36 +02:00
|
|
|
|
// Mutex is locked here, as we start using/modifying
|
|
|
|
|
// non-atomic members that are used from several threads.
|
|
|
|
|
std::lock_guard<std::mutex> l(m_Mutex);
|
2022-06-20 10:31:09 +02:00
|
|
|
|
m_Logger.Render();
|
2022-01-12 02:53:07 +01:00
|
|
|
|
|
|
|
|
|
if (m_bCopyToClipBoard)
|
2021-12-25 22:36:38 +01:00
|
|
|
|
{
|
2022-06-21 23:25:15 +02:00
|
|
|
|
m_Logger.Copy(true);
|
2022-01-12 02:53:07 +01:00
|
|
|
|
m_bCopyToClipBoard = false;
|
2021-12-25 22:36:38 +01:00
|
|
|
|
}
|
|
|
|
|
|
2022-06-26 16:47:00 +02:00
|
|
|
|
m_flScrollX = ImGui::GetScrollX();
|
|
|
|
|
m_flScrollY = ImGui::GetScrollY();
|
2022-01-22 15:51:09 +01:00
|
|
|
|
|
2021-12-25 22:36:38 +01:00
|
|
|
|
ImGui::EndChild();
|
2023-01-30 01:52:32 +01:00
|
|
|
|
ImGui::PopStyleVar(iVars);
|
|
|
|
|
|
2021-12-25 22:36:38 +01:00
|
|
|
|
ImGui::Separator();
|
|
|
|
|
|
2023-02-06 21:43:43 +01:00
|
|
|
|
std::function<void(void)> fnHandleInput = [&](void)
|
|
|
|
|
{
|
|
|
|
|
if (m_szInputBuf[0])
|
|
|
|
|
{
|
|
|
|
|
ProcessCommand(m_szInputBuf);
|
2023-09-17 16:15:42 +02:00
|
|
|
|
ResetAutoComplete();
|
2023-02-06 21:43:43 +01:00
|
|
|
|
|
|
|
|
|
m_bModifyInput = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BuildSummary();
|
|
|
|
|
m_bReclaimFocus = true;
|
|
|
|
|
};
|
|
|
|
|
|
2022-10-19 16:10:36 +02:00
|
|
|
|
///////////////////////////////////////////////////////////////////////
|
2022-06-18 18:11:05 +02:00
|
|
|
|
ImGui::PushItemWidth(flFooterWidthReserve - 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
|
|
|
|
{
|
2023-09-17 11:38:00 +02:00
|
|
|
|
if (m_nSuggestPos > PositionMode_t::kPark)
|
2022-01-17 23:20:03 +01:00
|
|
|
|
{
|
2023-02-05 19:21:39 +01:00
|
|
|
|
BuildInputFromSelected(m_vSuggest[m_nSuggestPos], m_svInputConVar);
|
2023-02-06 21:43:43 +01:00
|
|
|
|
BuildSummary(m_svInputConVar);
|
2021-12-25 22:36:38 +01:00
|
|
|
|
|
2023-02-06 21:43:43 +01:00
|
|
|
|
m_bModifyInput = true;
|
2023-02-06 00:04:08 +01:00
|
|
|
|
m_bReclaimFocus = true;
|
2022-01-17 23:20:03 +01:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2023-02-06 21:43:43 +01:00
|
|
|
|
fnHandleInput();
|
2022-01-17 23:20:03 +01:00
|
|
|
|
}
|
2021-12-25 22:36:38 +01:00
|
|
|
|
}
|
|
|
|
|
|
2022-10-20 01:17:51 +02:00
|
|
|
|
// Auto-focus input field on window apparition.
|
|
|
|
|
ImGui::SetItemDefaultFocus();
|
2021-12-25 22:36:38 +01:00
|
|
|
|
|
2022-10-20 01:17:51 +02:00
|
|
|
|
// Auto-focus input field if reclaim is demanded.
|
2022-01-12 02:53:07 +01:00
|
|
|
|
if (m_bReclaimFocus)
|
2021-12-25 22:36:38 +01:00
|
|
|
|
{
|
2022-10-20 01:17:51 +02:00
|
|
|
|
ImGui::SetKeyboardFocusHere(-1); // -1 means previous widget.
|
2022-01-12 02:53:07 +01:00
|
|
|
|
m_bReclaimFocus = false;
|
2021-12-25 22:36:38 +01:00
|
|
|
|
}
|
|
|
|
|
|
2022-08-31 13:00:02 +02:00
|
|
|
|
BuildSuggestPanelRect();
|
2022-01-17 23:20:03 +01:00
|
|
|
|
|
|
|
|
|
ImGui::SameLine();
|
|
|
|
|
if (ImGui::Button("Submit"))
|
|
|
|
|
{
|
2023-02-06 21:43:43 +01:00
|
|
|
|
fnHandleInput();
|
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
|
|
|
|
{
|
2023-01-28 14:21:18 +01:00
|
|
|
|
ImGui::Checkbox("Auto-scroll", &m_Logger.m_bAutoScroll);
|
2022-01-12 02:53:07 +01:00
|
|
|
|
|
|
|
|
|
ImGui::SameLine();
|
|
|
|
|
ImGui::PushItemWidth(100);
|
|
|
|
|
|
|
|
|
|
ImGui::PopItemWidth();
|
|
|
|
|
|
|
|
|
|
if (ImGui::SmallButton("Clear"))
|
|
|
|
|
{
|
|
|
|
|
ClearLog();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ImGui::SameLine();
|
|
|
|
|
m_bCopyToClipBoard = ImGui::SmallButton("Copy");
|
|
|
|
|
|
2023-01-28 14:21:18 +01:00
|
|
|
|
ImGui::Text("Console hotkey:");
|
2022-01-12 02:53:07 +01:00
|
|
|
|
ImGui::SameLine();
|
|
|
|
|
|
2022-10-20 12:29:21 +02:00
|
|
|
|
if (ImGui::Hotkey("##ToggleConsole", &g_pImGuiConfig->m_ConsoleConfig.m_nBind0, ImVec2(80, 80)))
|
2022-01-12 02:53:07 +01:00
|
|
|
|
{
|
|
|
|
|
g_pImGuiConfig->Save();
|
|
|
|
|
}
|
|
|
|
|
|
2023-01-28 14:21:18 +01:00
|
|
|
|
ImGui::Text("Browser hotkey:");
|
2022-01-12 02:53:07 +01:00
|
|
|
|
ImGui::SameLine();
|
|
|
|
|
|
2022-10-20 12:29:21 +02:00
|
|
|
|
if (ImGui::Hotkey("##ToggleBrowser", &g_pImGuiConfig->m_BrowserConfig.m_nBind0, ImVec2(80, 80)))
|
2022-01-12 02:53:07 +01:00
|
|
|
|
{
|
|
|
|
|
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-10-20 15:22:20 +02:00
|
|
|
|
for (size_t i = 0, ns = m_vSuggest.size(); i < ns; i++)
|
2022-01-16 00:59:20 +01:00
|
|
|
|
{
|
2022-10-20 15:22:20 +02:00
|
|
|
|
const CSuggest& suggest = m_vSuggest[i];
|
2023-04-02 12:09:43 +02:00
|
|
|
|
const bool bIsIndexActive = m_nSuggestPos == ssize_t(i);
|
2022-10-20 15:22:20 +02:00
|
|
|
|
|
2022-08-21 19:35:06 +02:00
|
|
|
|
ImGui::PushID(static_cast<int>(i));
|
2022-04-26 20:24:51 +02:00
|
|
|
|
|
2023-07-22 15:01:00 +02:00
|
|
|
|
if (con_suggest_showflags->GetBool())
|
2022-04-26 20:24:51 +02:00
|
|
|
|
{
|
2022-12-29 13:30:33 +01:00
|
|
|
|
// Show the flag texture before the cvar name.
|
|
|
|
|
const int mainTexIdx = GetFlagTextureIndex(suggest.m_nFlags);
|
|
|
|
|
const MODULERESOURCE& mainRes = m_vFlagIcons[mainTexIdx];
|
2023-04-02 00:59:24 +02:00
|
|
|
|
ImGui::Image(mainRes.m_idIcon, ImVec2(float(mainRes.m_nWidth), float(mainRes.m_nHeight)));
|
2022-12-29 13:30:33 +01:00
|
|
|
|
|
|
|
|
|
// Show a more detailed description of the flag when user hovers over the texture.
|
2023-02-05 19:21:39 +01:00
|
|
|
|
if (ImGui::IsItemHovered(ImGuiHoveredFlags_RectOnly) &&
|
|
|
|
|
suggest.m_nFlags != COMMAND_COMPLETION_MARKER)
|
2022-12-29 13:30:33 +01:00
|
|
|
|
{
|
2023-07-03 13:48:13 +02:00
|
|
|
|
std::function<void(const ConVarFlags::FlagDesc_t&)> fnAddHint = [&](const ConVarFlags::FlagDesc_t& cvarInfo)
|
2022-12-29 13:30:33 +01:00
|
|
|
|
{
|
2023-07-03 13:48:13 +02:00
|
|
|
|
const int hintTexIdx = GetFlagTextureIndex(cvarInfo.bit);
|
2022-12-29 13:30:33 +01:00
|
|
|
|
const MODULERESOURCE& hintRes = m_vFlagIcons[hintTexIdx];
|
|
|
|
|
|
2023-04-02 00:59:24 +02:00
|
|
|
|
ImGui::Image(hintRes.m_idIcon, ImVec2(float(hintRes.m_nWidth), float(hintRes.m_nHeight)));
|
2022-12-29 13:30:33 +01:00
|
|
|
|
ImGui::SameLine();
|
2023-07-03 13:48:13 +02:00
|
|
|
|
ImGui::Text("%s", cvarInfo.shortdesc);
|
2022-12-29 13:30:33 +01:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
ImGui::BeginTooltip();
|
|
|
|
|
bool bFlagSet = false;
|
|
|
|
|
|
|
|
|
|
// Reverse loop to display the most significant flag first.
|
2023-07-03 13:48:13 +02:00
|
|
|
|
for (int j = IM_ARRAYSIZE(g_ConVarFlags.m_FlagsToDesc); (j--) > 0;)
|
2022-12-29 13:30:33 +01:00
|
|
|
|
{
|
2023-07-03 13:48:13 +02:00
|
|
|
|
const ConVarFlags::FlagDesc_t& info = g_ConVarFlags.m_FlagsToDesc[j];
|
|
|
|
|
if (suggest.m_nFlags & info.bit)
|
2022-12-29 13:30:33 +01:00
|
|
|
|
{
|
|
|
|
|
bFlagSet = true;
|
|
|
|
|
fnAddHint(info);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (!bFlagSet) // Display the FCVAR_NONE flag if no flags are set.
|
|
|
|
|
{
|
2023-07-03 13:48:13 +02:00
|
|
|
|
fnAddHint(g_ConVarFlags.m_FlagsToDesc[0]);
|
2022-12-29 13:30:33 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ImGui::EndTooltip();
|
|
|
|
|
}
|
|
|
|
|
|
2022-04-26 20:24:51 +02:00
|
|
|
|
ImGui::SameLine();
|
|
|
|
|
}
|
|
|
|
|
|
2022-10-20 15:22:20 +02:00
|
|
|
|
if (ImGui::Selectable(suggest.m_svName.c_str(), bIsIndexActive))
|
2022-01-16 00:59:20 +01:00
|
|
|
|
{
|
2022-01-17 23:20:03 +01:00
|
|
|
|
ImGui::Separator();
|
2023-02-05 19:21:39 +01:00
|
|
|
|
string svConVar;
|
2022-01-17 23:20:03 +01:00
|
|
|
|
|
2023-02-06 21:43:43 +01:00
|
|
|
|
BuildInputFromSelected(suggest, svConVar);
|
2022-10-19 16:10:36 +02:00
|
|
|
|
memmove(m_szInputBuf, svConVar.data(), svConVar.size() + 1);
|
2023-02-06 02:12:53 +01:00
|
|
|
|
|
|
|
|
|
m_bCanAutoComplete = true;
|
2023-02-06 00:04:08 +01:00
|
|
|
|
m_bReclaimFocus = true;
|
2022-10-19 16:10:36 +02:00
|
|
|
|
|
2022-06-22 03:24:46 +02:00
|
|
|
|
BuildSummary(svConVar);
|
2022-01-16 00:59:20 +01:00
|
|
|
|
}
|
2023-09-17 01:25:44 +02:00
|
|
|
|
|
2022-01-17 23:20:03 +01:00
|
|
|
|
ImGui::PopID();
|
|
|
|
|
|
2023-09-17 01:25:44 +02:00
|
|
|
|
// Update the suggest position
|
2023-09-17 12:06:38 +02:00
|
|
|
|
if (m_bSuggestMoved)
|
2022-01-16 00:59:20 +01:00
|
|
|
|
{
|
2023-09-17 01:25:44 +02:00
|
|
|
|
if (bIsIndexActive) // Bring the 'active' element into view
|
|
|
|
|
{
|
2023-09-17 12:06:38 +02:00
|
|
|
|
ImGuiWindow* const pWindow = ImGui::GetCurrentWindow();
|
|
|
|
|
ImRect imRect = ImGui::GetCurrentContext()->LastItemData.Rect;
|
|
|
|
|
|
2023-09-17 01:25:44 +02:00
|
|
|
|
// Reset to keep flag in display.
|
|
|
|
|
imRect.Min.x = pWindow->InnerRect.Min.x;
|
2023-09-17 12:06:38 +02:00
|
|
|
|
imRect.Max.x = pWindow->InnerRect.Max.x;
|
2023-09-17 01:25:44 +02:00
|
|
|
|
|
|
|
|
|
// Eliminate jiggle when going up/down in the menu.
|
|
|
|
|
imRect.Min.y += 1;
|
|
|
|
|
imRect.Max.y -= 1;
|
2022-04-26 20:24:51 +02:00
|
|
|
|
|
2023-09-17 12:06:38 +02:00
|
|
|
|
ImGui::ScrollToRect(pWindow, imRect);
|
|
|
|
|
m_bSuggestMoved = false;
|
2023-09-17 01:25:44 +02:00
|
|
|
|
}
|
2023-09-17 12:06:38 +02:00
|
|
|
|
else if (m_nSuggestPos == PositionMode_t::kPark)
|
2023-09-17 01:25:44 +02:00
|
|
|
|
{
|
2023-09-17 12:06:38 +02:00
|
|
|
|
// Reset position; kPark = no active element.
|
|
|
|
|
ImGui::SetScrollX(0.0f);
|
|
|
|
|
ImGui::SetScrollY(0.0f);
|
2023-09-17 01:25:44 +02:00
|
|
|
|
|
2023-09-17 12:06:38 +02:00
|
|
|
|
m_bSuggestMoved = false;
|
2023-09-17 01:25:44 +02:00
|
|
|
|
}
|
2022-01-16 00:59:20 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
2022-01-17 23:20:03 +01:00
|
|
|
|
|
|
|
|
|
ImGui::PopAllowKeyboardFocus();
|
|
|
|
|
ImGui::End();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
2022-11-10 21:19:17 +01:00
|
|
|
|
// Purpose: runs the auto complete for the console
|
|
|
|
|
// Output : true if auto complete is performed, false otherwise
|
2022-01-17 23:20:03 +01:00
|
|
|
|
//-----------------------------------------------------------------------------
|
2022-06-22 03:24:46 +02:00
|
|
|
|
bool CConsole::AutoComplete(void)
|
2022-01-17 23:20:03 +01:00
|
|
|
|
{
|
2023-02-05 19:21:39 +01:00
|
|
|
|
// Don't suggest if user tries to assign value to ConVar or execute ConCommand.
|
|
|
|
|
if (!m_szInputBuf[0] || strstr(m_szInputBuf, ";"))
|
|
|
|
|
{
|
2023-02-05 22:50:11 +01:00
|
|
|
|
if (m_bSuggestActive)
|
|
|
|
|
{
|
2023-09-17 16:15:42 +02:00
|
|
|
|
ResetAutoComplete();
|
2023-02-05 22:50:11 +01:00
|
|
|
|
}
|
2023-02-05 19:21:39 +01:00
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!strstr(m_szInputBuf, " "))
|
2022-01-17 23:20:03 +01:00
|
|
|
|
{
|
2022-06-22 03:24:46 +02:00
|
|
|
|
if (m_bCanAutoComplete)
|
2022-01-17 23:20:03 +01:00
|
|
|
|
{
|
|
|
|
|
FindFromPartial();
|
|
|
|
|
}
|
|
|
|
|
}
|
2023-02-05 21:10:39 +01:00
|
|
|
|
else if (m_bCanAutoComplete) // Command completion callback.
|
2022-01-17 23:20:03 +01:00
|
|
|
|
{
|
2023-09-17 16:15:42 +02:00
|
|
|
|
ResetAutoComplete();
|
2023-02-05 19:21:39 +01:00
|
|
|
|
string svCommand;
|
2022-09-07 01:55:52 +02:00
|
|
|
|
|
2023-02-05 19:21:39 +01:00
|
|
|
|
for (size_t i = 0; i < sizeof(m_szInputBuf); i++)
|
|
|
|
|
{
|
|
|
|
|
if (isspace(m_szInputBuf[i]))
|
|
|
|
|
{
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
svCommand += m_szInputBuf[i];
|
|
|
|
|
}
|
2022-01-17 23:20:03 +01:00
|
|
|
|
|
2023-03-17 00:17:35 +01:00
|
|
|
|
ConCommand* pCommand = g_pCVar->FindCommand(svCommand.c_str());
|
2022-08-28 17:28:53 +02:00
|
|
|
|
|
2023-03-17 00:17:35 +01:00
|
|
|
|
if (pCommand && pCommand->CanAutoComplete())
|
|
|
|
|
{
|
|
|
|
|
CUtlVector< CUtlString > commands;
|
2023-03-17 19:24:54 +01:00
|
|
|
|
int iret = pCommand->AutoCompleteSuggest(m_szInputBuf, commands);
|
2023-02-05 19:21:39 +01:00
|
|
|
|
|
|
|
|
|
if (!iret)
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < iret; ++i)
|
|
|
|
|
{
|
2023-03-17 00:17:35 +01:00
|
|
|
|
m_vSuggest.push_back(CSuggest(commands[i].String(), COMMAND_COMPLETION_MARKER));
|
2023-02-05 19:21:39 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2022-01-17 23:20:03 +01:00
|
|
|
|
}
|
2023-02-05 19:21:39 +01:00
|
|
|
|
|
2023-02-05 21:10:39 +01:00
|
|
|
|
if (m_vSuggest.empty())
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2022-01-17 23:20:03 +01:00
|
|
|
|
m_bSuggestActive = true;
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2022-03-25 13:31:31 +01:00
|
|
|
|
//-----------------------------------------------------------------------------
|
2022-11-10 21:19:17 +01:00
|
|
|
|
// Purpose: resets the auto complete window
|
2022-03-25 13:31:31 +01:00
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
void CConsole::ResetAutoComplete(void)
|
|
|
|
|
{
|
2023-09-17 16:15:42 +02:00
|
|
|
|
m_nSuggestPos = PositionMode_t::kPark;
|
2023-09-17 12:47:36 +02:00
|
|
|
|
m_bCanAutoComplete = false;
|
2022-03-25 13:31:31 +01:00
|
|
|
|
m_bSuggestActive = false;
|
2023-09-17 01:37:01 +02:00
|
|
|
|
m_bSuggestMoved = true;
|
2022-06-22 03:24:46 +02:00
|
|
|
|
m_vSuggest.clear();
|
2022-06-18 18:11:05 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
// Purpose: find ConVars/ConCommands from user input and add to vector
|
2022-10-20 12:29:21 +02:00
|
|
|
|
// - Ignores ConVars marked FCVAR_HIDDEN
|
2022-06-18 18:11:05 +02:00
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
void CConsole::FindFromPartial(void)
|
|
|
|
|
{
|
2023-09-17 16:15:42 +02:00
|
|
|
|
ResetAutoComplete();
|
2022-01-18 11:23:14 +01:00
|
|
|
|
|
2023-07-22 14:51:15 +02:00
|
|
|
|
ICvar::Iterator iter(g_pCVar);
|
|
|
|
|
for (iter.SetFirst(); iter.IsValid(); iter.Next())
|
2022-01-17 23:20:03 +01:00
|
|
|
|
{
|
2023-09-17 16:15:42 +02:00
|
|
|
|
if (m_vSuggest.size() >= con_suggest_limit->GetInt())
|
2022-01-17 23:20:03 +01:00
|
|
|
|
{
|
2023-07-22 14:51:15 +02:00
|
|
|
|
break;
|
2022-10-07 22:31:16 +02:00
|
|
|
|
}
|
2023-07-22 14:51:15 +02:00
|
|
|
|
|
|
|
|
|
const ConCommandBase* pCommandBase = iter.Get();
|
|
|
|
|
if (pCommandBase->IsFlagSet(FCVAR_HIDDEN))
|
2022-10-07 22:31:16 +02:00
|
|
|
|
{
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
2023-07-22 14:51:15 +02:00
|
|
|
|
const char* pCommandName = pCommandBase->GetName();
|
|
|
|
|
if (!V_stristr(pCommandName, m_szInputBuf))
|
2022-10-07 22:31:16 +02:00
|
|
|
|
{
|
2023-07-22 14:51:15 +02:00
|
|
|
|
continue;
|
|
|
|
|
}
|
2022-10-07 22:31:16 +02:00
|
|
|
|
|
2023-07-22 14:51:15 +02:00
|
|
|
|
if (std::find(m_vSuggest.begin(), m_vSuggest.end(),
|
|
|
|
|
pCommandName) == m_vSuggest.end())
|
|
|
|
|
{
|
|
|
|
|
string svValue;
|
2022-02-23 15:56:03 +01:00
|
|
|
|
|
2022-10-07 22:31:16 +02:00
|
|
|
|
if (!pCommandBase->IsCommand())
|
|
|
|
|
{
|
2022-10-11 01:22:21 +02:00
|
|
|
|
const ConVar* pConVar = reinterpret_cast<const ConVar*>(pCommandBase);
|
2022-10-07 22:31:16 +02:00
|
|
|
|
|
|
|
|
|
svValue = " = ["; // Assign default value to string if its a ConVar.
|
|
|
|
|
svValue.append(pConVar->GetString());
|
|
|
|
|
svValue.append("]");
|
|
|
|
|
}
|
2023-07-22 15:01:00 +02:00
|
|
|
|
if (con_suggest_showhelptext->GetBool())
|
2022-10-07 22:31:16 +02:00
|
|
|
|
{
|
2023-08-08 02:21:33 +02:00
|
|
|
|
std::function<void(string& , const char*)> fnAppendDocString = [&](string& svTarget, const char* pszDocString)
|
2022-10-07 22:31:16 +02:00
|
|
|
|
{
|
2023-08-08 02:21:33 +02:00
|
|
|
|
if (VALID_CHARSTAR(pszDocString))
|
2022-10-07 22:31:16 +02:00
|
|
|
|
{
|
2023-08-08 02:21:33 +02:00
|
|
|
|
svTarget.append(" - \"");
|
|
|
|
|
svTarget.append(pszDocString);
|
|
|
|
|
svTarget.append("\"");
|
2022-10-07 22:31:16 +02:00
|
|
|
|
}
|
2023-08-08 02:21:33 +02:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
fnAppendDocString(svValue, pCommandBase->GetHelpText());
|
|
|
|
|
fnAppendDocString(svValue, pCommandBase->GetUsageText());
|
2022-01-17 23:20:03 +01:00
|
|
|
|
}
|
2023-07-22 14:51:15 +02:00
|
|
|
|
m_vSuggest.push_back(CSuggest(pCommandName + svValue, pCommandBase->GetFlags()));
|
2022-01-17 23:20:03 +01:00
|
|
|
|
}
|
|
|
|
|
else { break; }
|
|
|
|
|
}
|
2022-10-19 16:10:36 +02:00
|
|
|
|
|
2022-06-22 03:24:46 +02:00
|
|
|
|
std::sort(m_vSuggest.begin(), m_vSuggest.end());
|
2022-01-16 00:59:20 +01:00
|
|
|
|
}
|
|
|
|
|
|
2021-12-25 22:36:38 +01:00
|
|
|
|
//-----------------------------------------------------------------------------
|
2022-08-21 19:35:06 +02:00
|
|
|
|
// Purpose: processes submitted commands for the main thread
|
2022-10-20 12:29:21 +02:00
|
|
|
|
// Input : svCommand -
|
2021-12-25 22:36:38 +01:00
|
|
|
|
//-----------------------------------------------------------------------------
|
2022-10-20 12:29:21 +02:00
|
|
|
|
void CConsole::ProcessCommand(string svCommand)
|
2021-12-25 22:36:38 +01:00
|
|
|
|
{
|
2022-10-20 12:29:21 +02:00
|
|
|
|
StringRTrim(svCommand, " "); // Remove trailing white space characters to prevent history duplication.
|
|
|
|
|
AddLog(ImVec4(1.00f, 0.80f, 0.60f, 1.00f), "%s] %s\n", Plat_GetProcessUpTime(), svCommand.c_str());
|
2021-12-25 22:36:38 +01:00
|
|
|
|
|
2022-10-20 12:29:21 +02:00
|
|
|
|
Cbuf_AddText(Cbuf_GetCurrentPlayer(), svCommand.c_str(), cmd_source_t::kCommandSrcCode);
|
2023-09-17 11:38:00 +02:00
|
|
|
|
m_nHistoryPos = PositionMode_t::kPark;
|
2022-10-20 12:29:21 +02:00
|
|
|
|
|
2022-10-19 16:10:36 +02:00
|
|
|
|
for (size_t i = m_vHistory.size(); i-- > 0;)
|
2021-12-25 22:36:38 +01:00
|
|
|
|
{
|
2022-10-20 12:29:21 +02:00
|
|
|
|
if (m_vHistory[i].compare(svCommand) == 0)
|
2021-12-25 22:36:38 +01:00
|
|
|
|
{
|
2022-06-22 03:24:46 +02:00
|
|
|
|
m_vHistory.erase(m_vHistory.begin() + i);
|
2021-12-25 22:36:38 +01:00
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-10-20 15:07:40 +02:00
|
|
|
|
m_vHistory.push_back(svCommand);
|
2023-04-09 22:35:55 +02:00
|
|
|
|
m_Logger.ShouldScrollToBottom(true);
|
2021-12-25 22:36:38 +01:00
|
|
|
|
}
|
|
|
|
|
|
2022-06-24 12:22:04 +02:00
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
// Purpose: builds the console summary
|
|
|
|
|
// Input : svConVar -
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
void CConsole::BuildSummary(string svConVar)
|
|
|
|
|
{
|
|
|
|
|
if (!svConVar.empty())
|
|
|
|
|
{
|
2022-10-24 00:50:07 +02:00
|
|
|
|
// Remove trailing space and/or semicolon before we call 'g_pCVar->FindVar(..)'.
|
2022-11-11 01:19:49 +01:00
|
|
|
|
StringRTrim(svConVar, " ;", true);
|
2023-10-15 10:41:17 +02:00
|
|
|
|
const ConVar* const pConVar = g_pCVar->FindVar(svConVar.c_str());
|
2022-06-24 12:22:04 +02:00
|
|
|
|
|
2023-10-15 10:41:17 +02:00
|
|
|
|
if (pConVar && !pConVar->IsFlagSet(FCVAR_HIDDEN))
|
2022-06-24 12:22:04 +02:00
|
|
|
|
{
|
|
|
|
|
// Display the current and default value of ConVar if found.
|
|
|
|
|
snprintf(m_szSummary, sizeof(m_szSummary), "(\"%s\", default \"%s\")", pConVar->GetString(), pConVar->GetDefault());
|
2022-10-20 12:29:21 +02:00
|
|
|
|
return;
|
2022-06-24 12:22:04 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
2023-02-06 21:43:43 +01:00
|
|
|
|
|
2022-10-20 12:29:21 +02:00
|
|
|
|
snprintf(m_szSummary, sizeof(m_szSummary), "%zu history items", m_vHistory.size());
|
2022-06-24 12:22:04 +02:00
|
|
|
|
}
|
|
|
|
|
|
2023-02-05 19:21:39 +01:00
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
// Purpose: builds the selected suggestion for input field
|
|
|
|
|
// Input : &suggest -
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
void CConsole::BuildInputFromSelected(const CSuggest& suggest, string& svInput)
|
|
|
|
|
{
|
|
|
|
|
if (suggest.m_nFlags == COMMAND_COMPLETION_MARKER)
|
|
|
|
|
{
|
|
|
|
|
svInput = suggest.m_svName + ' ';
|
|
|
|
|
}
|
|
|
|
|
else // Remove the default value from ConVar before assigning it to the input buffer.
|
|
|
|
|
{
|
|
|
|
|
svInput = suggest.m_svName.substr(0, suggest.m_svName.find(' ')) + ' ';
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-08-31 13:00:02 +02:00
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
// Purpose: builds the suggestion panel rect
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
void CConsole::BuildSuggestPanelRect(void)
|
|
|
|
|
{
|
|
|
|
|
float flSinglePadding = 0.f;
|
2022-10-19 16:10:36 +02:00
|
|
|
|
const float flItemHeight = ImGui::GetTextLineHeightWithSpacing() + 1.0f;
|
2022-08-31 13:00:02 +02:00
|
|
|
|
|
|
|
|
|
if (m_vSuggest.size() > 1)
|
|
|
|
|
{
|
|
|
|
|
// Pad with 18 to keep all items in view.
|
|
|
|
|
flSinglePadding = flItemHeight;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
m_ivSuggestWindowPos = ImGui::GetItemRectMin();
|
|
|
|
|
m_ivSuggestWindowPos.y += ImGui::GetItemRectSize().y;
|
|
|
|
|
|
2022-10-19 16:10:36 +02:00
|
|
|
|
const float flWindowHeight = (flSinglePadding + std::clamp(
|
|
|
|
|
static_cast<float>(m_vSuggest.size()) * (flItemHeight), 37.0f, 127.5f));
|
|
|
|
|
|
2022-08-31 13:00:02 +02:00
|
|
|
|
m_ivSuggestWindowSize = ImVec2(600, flWindowHeight);
|
|
|
|
|
}
|
|
|
|
|
|
2022-08-22 01:10:18 +02:00
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
// Purpose: clamps the size of the log vector
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
void CConsole::ClampLogSize(void)
|
|
|
|
|
{
|
2022-10-19 16:10:36 +02:00
|
|
|
|
const int nMaxLines = con_max_lines->GetInt();
|
|
|
|
|
|
|
|
|
|
if (m_Logger.GetTotalLines() > nMaxLines)
|
2022-08-22 01:10:18 +02:00
|
|
|
|
{
|
2022-10-19 16:10:36 +02:00
|
|
|
|
while (m_Logger.GetTotalLines() > nMaxLines)
|
2022-08-22 01:10:18 +02:00
|
|
|
|
{
|
|
|
|
|
m_Logger.RemoveLine(0);
|
|
|
|
|
m_nScrollBack++;
|
|
|
|
|
m_nSelectBack++;
|
|
|
|
|
}
|
|
|
|
|
m_Logger.MoveSelection(m_nSelectBack, false);
|
|
|
|
|
m_Logger.MoveCursor(m_nSelectBack, false);
|
|
|
|
|
m_nSelectBack = 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
// Purpose: clamps the size of the history vector
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
void CConsole::ClampHistorySize(void)
|
|
|
|
|
{
|
2023-09-17 16:15:42 +02:00
|
|
|
|
while (m_vHistory.size() > con_max_history->GetInt())
|
2022-08-22 01:10:18 +02:00
|
|
|
|
{
|
|
|
|
|
m_vHistory.erase(m_vHistory.begin());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-06-24 12:22:04 +02:00
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
// Purpose: loads flag images from resource section (must be aligned with resource.h!)
|
|
|
|
|
// Output : true on success, false on failure
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
bool CConsole::LoadFlagIcons(void)
|
|
|
|
|
{
|
2022-10-19 16:10:36 +02:00
|
|
|
|
bool ret = false;
|
|
|
|
|
|
2022-11-11 20:12:20 +01:00
|
|
|
|
// Get all flag image resources for displaying flags.
|
2023-02-05 19:21:39 +01:00
|
|
|
|
for (int i = IDB_PNG3, k = NULL; i <= IDB_PNG32; i++, k++)
|
2022-06-24 12:22:04 +02:00
|
|
|
|
{
|
2022-10-19 16:10:36 +02:00
|
|
|
|
m_vFlagIcons.push_back(MODULERESOURCE(GetModuleResource(i)));
|
|
|
|
|
MODULERESOURCE& rFlagIcon = m_vFlagIcons[k];
|
2022-06-24 12:22:04 +02:00
|
|
|
|
|
2023-04-02 17:02:04 +02:00
|
|
|
|
ret = LoadTextureBuffer(reinterpret_cast<unsigned char*>(rFlagIcon.m_pData), // !TODO: Fall-back texture.
|
2022-10-19 16:10:36 +02:00
|
|
|
|
static_cast<int>(rFlagIcon.m_nSize), &rFlagIcon.m_idIcon, &rFlagIcon.m_nWidth, &rFlagIcon.m_nHeight);
|
|
|
|
|
|
|
|
|
|
IM_ASSERT(ret);
|
2023-04-16 00:41:48 +02:00
|
|
|
|
if (!ret)
|
|
|
|
|
{
|
|
|
|
|
break;
|
|
|
|
|
}
|
2022-06-24 12:22:04 +02:00
|
|
|
|
}
|
2022-10-19 16:10:36 +02:00
|
|
|
|
return ret;
|
2022-06-24 12:22:04 +02:00
|
|
|
|
}
|
|
|
|
|
|
2022-04-26 20:24:51 +02:00
|
|
|
|
//-----------------------------------------------------------------------------
|
2022-11-10 01:17:53 +01:00
|
|
|
|
// Purpose: returns flag texture index for CommandBase (must be aligned with resource.h!)
|
2022-11-10 21:19:17 +01:00
|
|
|
|
// in the future we should build the texture procedurally with use of popcnt.
|
2022-04-26 20:24:51 +02:00
|
|
|
|
// Input : nFlags -
|
|
|
|
|
//-----------------------------------------------------------------------------
|
2022-11-10 01:17:53 +01:00
|
|
|
|
int CConsole::GetFlagTextureIndex(int nFlags) const
|
2022-04-26 20:24:51 +02:00
|
|
|
|
{
|
2022-11-10 01:17:53 +01:00
|
|
|
|
switch (nFlags) // All indices for single/dual flag textures.
|
2022-04-26 20:24:51 +02:00
|
|
|
|
{
|
|
|
|
|
case FCVAR_DEVELOPMENTONLY:
|
2022-11-11 20:12:20 +01:00
|
|
|
|
return 9;
|
2022-04-26 20:24:51 +02:00
|
|
|
|
case FCVAR_GAMEDLL:
|
2022-11-11 20:12:20 +01:00
|
|
|
|
return 10;
|
2022-04-26 20:24:51 +02:00
|
|
|
|
case FCVAR_CLIENTDLL:
|
2022-11-11 20:12:20 +01:00
|
|
|
|
return 11;
|
2022-10-11 01:22:21 +02:00
|
|
|
|
case FCVAR_REPLICATED:
|
2022-11-11 20:12:20 +01:00
|
|
|
|
return 12;
|
2022-10-11 01:22:21 +02:00
|
|
|
|
case FCVAR_CHEAT:
|
2022-11-11 20:12:20 +01:00
|
|
|
|
return 13;
|
2022-10-11 01:22:21 +02:00
|
|
|
|
case FCVAR_RELEASE:
|
2022-11-11 20:12:20 +01:00
|
|
|
|
return 14;
|
2022-10-11 01:22:21 +02:00
|
|
|
|
case FCVAR_MATERIAL_SYSTEM_THREAD:
|
2022-11-11 20:12:20 +01:00
|
|
|
|
return 15;
|
2022-10-11 01:22:21 +02:00
|
|
|
|
case FCVAR_DEVELOPMENTONLY | FCVAR_GAMEDLL:
|
2022-11-11 20:12:20 +01:00
|
|
|
|
return 16;
|
2022-10-11 01:22:21 +02:00
|
|
|
|
case FCVAR_DEVELOPMENTONLY | FCVAR_CLIENTDLL:
|
2022-11-11 20:12:20 +01:00
|
|
|
|
return 17;
|
2022-10-11 01:22:21 +02:00
|
|
|
|
case FCVAR_DEVELOPMENTONLY | FCVAR_REPLICATED:
|
2022-11-11 20:12:20 +01:00
|
|
|
|
return 18;
|
2022-10-11 01:22:21 +02:00
|
|
|
|
case FCVAR_DEVELOPMENTONLY | FCVAR_CHEAT:
|
2022-11-11 20:12:20 +01:00
|
|
|
|
return 19;
|
2022-10-11 01:22:21 +02:00
|
|
|
|
case FCVAR_DEVELOPMENTONLY | FCVAR_MATERIAL_SYSTEM_THREAD:
|
2022-11-11 20:12:20 +01:00
|
|
|
|
return 20;
|
2022-10-11 01:22:21 +02:00
|
|
|
|
case FCVAR_REPLICATED | FCVAR_CHEAT:
|
2022-11-11 20:12:20 +01:00
|
|
|
|
return 21;
|
2022-10-11 01:22:21 +02:00
|
|
|
|
case FCVAR_REPLICATED | FCVAR_RELEASE:
|
2022-11-11 20:12:20 +01:00
|
|
|
|
return 22;
|
2022-10-11 01:22:21 +02:00
|
|
|
|
case FCVAR_GAMEDLL | FCVAR_CHEAT:
|
2022-11-11 20:12:20 +01:00
|
|
|
|
return 23;
|
2022-10-11 01:22:21 +02:00
|
|
|
|
case FCVAR_GAMEDLL | FCVAR_RELEASE:
|
2022-11-11 20:12:20 +01:00
|
|
|
|
return 24;
|
2022-10-11 01:22:21 +02:00
|
|
|
|
case FCVAR_CLIENTDLL | FCVAR_CHEAT:
|
2022-11-11 20:12:20 +01:00
|
|
|
|
return 25;
|
2022-10-11 01:22:21 +02:00
|
|
|
|
case FCVAR_CLIENTDLL | FCVAR_RELEASE:
|
2022-11-11 20:12:20 +01:00
|
|
|
|
return 26;
|
2022-10-11 01:22:21 +02:00
|
|
|
|
case FCVAR_MATERIAL_SYSTEM_THREAD | FCVAR_CHEAT:
|
2022-11-11 20:12:20 +01:00
|
|
|
|
return 27;
|
2022-10-11 01:22:21 +02:00
|
|
|
|
case FCVAR_MATERIAL_SYSTEM_THREAD | FCVAR_RELEASE:
|
2022-11-11 20:12:20 +01:00
|
|
|
|
return 28;
|
2023-02-05 19:21:39 +01:00
|
|
|
|
case COMMAND_COMPLETION_MARKER:
|
|
|
|
|
return 29;
|
2022-11-10 01:17:53 +01:00
|
|
|
|
|
2022-11-11 20:12:20 +01:00
|
|
|
|
default: // Hit when flag is zero/non-indexed or 3+ bits are set.
|
2022-11-10 01:17:53 +01:00
|
|
|
|
|
|
|
|
|
int v = __popcnt(nFlags);
|
|
|
|
|
switch (v)
|
|
|
|
|
{
|
|
|
|
|
case 0:
|
2022-11-10 21:19:17 +01:00
|
|
|
|
return 0; // Pink checker texture (FCVAR_NONE)
|
2022-11-10 01:17:53 +01:00
|
|
|
|
case 1:
|
2022-11-10 21:19:17 +01:00
|
|
|
|
return 1; // Yellow checker texture (non-indexed).
|
2022-11-10 01:17:53 +01:00
|
|
|
|
default:
|
2022-11-10 21:19:17 +01:00
|
|
|
|
|
|
|
|
|
// If 3 or more bits are set, we test the flags
|
|
|
|
|
// and display the appropriate checker texture.
|
|
|
|
|
bool mul = v > 2;
|
2022-11-10 01:17:53 +01:00
|
|
|
|
|
|
|
|
|
if (nFlags & FCVAR_DEVELOPMENTONLY)
|
|
|
|
|
{
|
2022-11-11 20:12:20 +01:00
|
|
|
|
return mul ? 4 : 3;
|
2022-11-10 01:17:53 +01:00
|
|
|
|
}
|
|
|
|
|
else if (nFlags & FCVAR_CHEAT)
|
|
|
|
|
{
|
2022-11-11 20:12:20 +01:00
|
|
|
|
return mul ? 6 : 5;
|
|
|
|
|
}
|
|
|
|
|
else if (nFlags & FCVAR_RELEASE && // RELEASE command but no context restriction.
|
|
|
|
|
!(nFlags & FCVAR_SERVER_CAN_EXECUTE) &&
|
|
|
|
|
!(nFlags & FCVAR_CLIENTCMD_CAN_EXECUTE))
|
|
|
|
|
{
|
|
|
|
|
return mul ? 8 : 7;
|
2022-11-10 01:17:53 +01:00
|
|
|
|
}
|
|
|
|
|
|
2022-11-10 21:19:17 +01:00
|
|
|
|
// Rainbow checker texture (user needs to manually check flags).
|
|
|
|
|
// These commands are not restricted if ran from the same context.
|
|
|
|
|
return 2;
|
2022-11-10 01:17:53 +01:00
|
|
|
|
}
|
2022-04-26 20:24:51 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
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-06-24 12:22:04 +02:00
|
|
|
|
if (m_nSuggestPos < static_cast<ssize_t>(m_vSuggest.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-11-10 21:19:17 +01:00
|
|
|
|
else // Allow user to navigate through the history if suggest panel isn't drawn.
|
2021-12-25 22:36:38 +01:00
|
|
|
|
{
|
2022-08-14 18:35:01 +02:00
|
|
|
|
const ssize_t nPrevHistoryPos = m_nHistoryPos;
|
2022-02-14 02:31:42 +01:00
|
|
|
|
if (iData->EventKey == ImGuiKey_UpArrow)
|
2022-01-17 23:20:03 +01:00
|
|
|
|
{
|
2023-09-17 11:38:00 +02:00
|
|
|
|
if (m_nHistoryPos == PositionMode_t::kPark)
|
2022-01-17 23:20:03 +01:00
|
|
|
|
{
|
2022-06-24 12:22:04 +02:00
|
|
|
|
m_nHistoryPos = static_cast<ssize_t>(m_vHistory.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
|
|
|
|
{
|
2023-09-17 11:38:00 +02:00
|
|
|
|
if (m_nHistoryPos != PositionMode_t::kPark)
|
2022-01-17 23:20:03 +01:00
|
|
|
|
{
|
2022-06-24 12:22:04 +02:00
|
|
|
|
if (++m_nHistoryPos >= static_cast<ssize_t>(m_vHistory.size()))
|
2022-01-17 23:20:03 +01:00
|
|
|
|
{
|
2023-09-17 11:38:00 +02:00
|
|
|
|
m_nHistoryPos = PositionMode_t::kPark;
|
2022-01-17 23:20:03 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (nPrevHistoryPos != m_nHistoryPos)
|
|
|
|
|
{
|
2022-06-22 03:24:46 +02:00
|
|
|
|
string svHistory = (m_nHistoryPos >= 0) ? m_vHistory[m_nHistoryPos] : "";
|
2022-01-17 23:20:03 +01:00
|
|
|
|
if (!svHistory.empty())
|
|
|
|
|
{
|
2023-08-08 02:19:45 +02:00
|
|
|
|
if (svHistory.find(' ') == string::npos)
|
2022-01-17 23:20:03 +01:00
|
|
|
|
{
|
|
|
|
|
// 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-06-22 03:24:46 +02:00
|
|
|
|
BuildSummary(iData->Buf);
|
2022-01-17 23:20:03 +01:00
|
|
|
|
break;
|
2021-12-25 22:36:38 +01:00
|
|
|
|
}
|
2022-09-02 01:18:36 +02:00
|
|
|
|
case ImGuiInputTextFlags_CallbackAlways:
|
|
|
|
|
{
|
2022-11-10 22:01:34 +01:00
|
|
|
|
m_nInputTextLen = iData->BufTextLen;
|
2022-11-10 21:19:17 +01:00
|
|
|
|
if (m_bModifyInput) // User entered a value in the input field.
|
2022-09-02 01:18:36 +02:00
|
|
|
|
{
|
2022-11-10 22:01:34 +01:00
|
|
|
|
iData->DeleteChars(0, m_nInputTextLen);
|
2022-09-07 01:55:52 +02:00
|
|
|
|
|
2022-11-10 21:19:17 +01:00
|
|
|
|
if (!m_svInputConVar.empty()) // User selected a ConVar from the suggestion window, copy it to the buffer.
|
2022-09-02 01:18:36 +02:00
|
|
|
|
{
|
|
|
|
|
iData->InsertChars(0, m_svInputConVar.c_str());
|
|
|
|
|
m_svInputConVar.clear();
|
2023-02-05 22:50:11 +01:00
|
|
|
|
|
2023-02-06 02:12:53 +01:00
|
|
|
|
m_bCanAutoComplete = true;
|
2023-02-06 00:04:08 +01:00
|
|
|
|
m_bReclaimFocus = true;
|
2022-09-02 01:18:36 +02:00
|
|
|
|
}
|
|
|
|
|
m_bModifyInput = false;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
2022-11-10 21:19:17 +01:00
|
|
|
|
case ImGuiInputTextFlags_CallbackCharFilter:
|
2022-01-28 12:56:51 +01:00
|
|
|
|
{
|
2022-11-10 21:19:17 +01:00
|
|
|
|
const ImWchar c = iData->EventChar;
|
2022-11-10 22:01:34 +01:00
|
|
|
|
if (!m_nInputTextLen)
|
2022-06-24 14:23:12 +02:00
|
|
|
|
{
|
2022-12-21 23:46:27 +01:00
|
|
|
|
if (c == '~') // Discard tilde character as first input.
|
2022-06-24 14:23:12 +02:00
|
|
|
|
{
|
2022-11-10 21:19:17 +01:00
|
|
|
|
iData->EventChar = 0;
|
|
|
|
|
return 1;
|
2022-06-24 14:23:12 +02:00
|
|
|
|
}
|
2022-11-10 21:19:17 +01:00
|
|
|
|
}
|
|
|
|
|
if (c == '`') // Discard back quote character (default console invoke key).
|
|
|
|
|
{
|
|
|
|
|
iData->EventChar = 0;
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
2022-09-05 01:33:40 +02:00
|
|
|
|
|
2022-11-10 21:19:17 +01:00
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
case ImGuiInputTextFlags_CallbackEdit:
|
|
|
|
|
{
|
2022-11-10 22:03:27 +01:00
|
|
|
|
// If user selected all text in the input field and replaces it with
|
|
|
|
|
// a tilde or space character, it will be set as the first character
|
|
|
|
|
// in the input field as m_nInputTextLen is set before the actual edit.
|
|
|
|
|
while (iData->Buf[0] == '~' || iData->Buf[0] == ' ')
|
|
|
|
|
{
|
|
|
|
|
iData->DeleteChars(0, 1);
|
|
|
|
|
}
|
|
|
|
|
|
2022-11-10 22:01:34 +01:00
|
|
|
|
if (iData->BufTextLen) // Attempt to build a summary..
|
2022-11-10 21:19:17 +01:00
|
|
|
|
{
|
2022-09-05 01:33:40 +02:00
|
|
|
|
BuildSummary(iData->Buf);
|
2023-02-06 02:12:53 +01:00
|
|
|
|
m_bCanAutoComplete = true;
|
2022-09-05 01:33:40 +02:00
|
|
|
|
}
|
|
|
|
|
else // Reset state and enable history scrolling when buffer is empty.
|
|
|
|
|
{
|
2023-09-17 16:15:42 +02:00
|
|
|
|
ResetAutoComplete();
|
2022-06-24 14:23:12 +02:00
|
|
|
|
}
|
|
|
|
|
|
2022-06-22 03:24:46 +02:00
|
|
|
|
break;
|
2022-01-28 12:56:51 +01:00
|
|
|
|
}
|
2021-12-25 22:36:38 +01:00
|
|
|
|
}
|
2022-11-10 21:19:17 +01:00
|
|
|
|
return 0;
|
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
|
|
|
|
}
|
|
|
|
|
|
2022-06-20 10:31:09 +02:00
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
// Purpose: adds logs to the vector
|
|
|
|
|
// Input : &conLog -
|
|
|
|
|
//-----------------------------------------------------------------------------
|
2022-06-26 17:40:02 +02:00
|
|
|
|
void CConsole::AddLog(const ConLog_t& conLog)
|
2022-06-20 10:31:09 +02:00
|
|
|
|
{
|
2022-08-22 01:10:18 +02:00
|
|
|
|
std::lock_guard<std::mutex> l(m_Mutex);
|
2022-06-20 10:31:09 +02:00
|
|
|
|
m_Logger.InsertText(conLog);
|
|
|
|
|
}
|
|
|
|
|
|
2022-01-12 02:53:07 +01:00
|
|
|
|
//-----------------------------------------------------------------------------
|
2022-08-21 19:35:06 +02:00
|
|
|
|
// Purpose: adds logs to the vector (internal)
|
2022-10-19 16:10:36 +02:00
|
|
|
|
// Only call when mutex lock is obtained!
|
|
|
|
|
// Input : &color -
|
|
|
|
|
// *fmt -
|
2022-02-14 02:31:42 +01:00
|
|
|
|
// ... -
|
2022-01-12 02:53:07 +01:00
|
|
|
|
//-----------------------------------------------------------------------------
|
2023-04-01 21:42:34 +02:00
|
|
|
|
void CConsole::AddLog(const ImVec4& color, const char* fmt, ...) /*IM_FMTARGS(2)*/
|
2022-01-12 02:53:07 +01:00
|
|
|
|
{
|
2023-04-01 21:42:34 +02:00
|
|
|
|
string result;
|
|
|
|
|
va_list args;
|
|
|
|
|
|
2022-01-12 02:53:07 +01:00
|
|
|
|
va_start(args, fmt);
|
2023-04-01 21:42:34 +02:00
|
|
|
|
result = FormatV(fmt, args);
|
2022-01-12 02:53:07 +01:00
|
|
|
|
va_end(args);
|
|
|
|
|
|
2023-04-01 21:42:34 +02:00
|
|
|
|
m_Logger.InsertText(ConLog_t(result, color));
|
2022-01-12 02:53:07 +01:00
|
|
|
|
}
|
2021-12-25 22:36:38 +01:00
|
|
|
|
|
2022-10-18 02:11:52 +02:00
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
// Purpose: removes lines from console with sanitized start and end indices
|
|
|
|
|
// input : nStart -
|
|
|
|
|
// nEnd -
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
void CConsole::RemoveLog(int nStart, int nEnd)
|
|
|
|
|
{
|
2022-10-24 00:50:07 +02:00
|
|
|
|
std::lock_guard<std::mutex> l(m_Mutex);
|
2022-10-18 02:11:52 +02:00
|
|
|
|
int nLines = m_Logger.GetTotalLines();
|
2022-10-24 00:50:07 +02:00
|
|
|
|
|
2022-10-18 02:11:52 +02:00
|
|
|
|
if (nEnd >= nLines)
|
|
|
|
|
{
|
|
|
|
|
// Sanitize for last array elem.
|
|
|
|
|
nEnd = (nLines - 1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (nStart >= nEnd)
|
|
|
|
|
{
|
|
|
|
|
if (nEnd > 0)
|
|
|
|
|
{
|
|
|
|
|
nStart = (nEnd - 1);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
// First elem cannot be removed!
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (nStart < 0)
|
|
|
|
|
{
|
|
|
|
|
nStart = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// User wants to remove everything.
|
|
|
|
|
if (nLines <= (nStart - nEnd))
|
|
|
|
|
{
|
|
|
|
|
ClearLog();
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
m_Logger.RemoveLine(nStart, nEnd);
|
|
|
|
|
}
|
|
|
|
|
|
2022-01-12 02:53:07 +01:00
|
|
|
|
//-----------------------------------------------------------------------------
|
2022-06-20 10:31:09 +02:00
|
|
|
|
// Purpose: clears the entire log vector
|
2022-01-12 02:53:07 +01:00
|
|
|
|
//-----------------------------------------------------------------------------
|
2022-06-20 10:31:09 +02:00
|
|
|
|
void CConsole::ClearLog(void)
|
2021-12-25 22:36:38 +01:00
|
|
|
|
{
|
2022-08-22 01:10:18 +02:00
|
|
|
|
std::lock_guard<std::mutex> l(m_Mutex);
|
2022-06-24 12:22:04 +02:00
|
|
|
|
m_Logger.RemoveLine(0, (m_Logger.GetTotalLines() - 1));
|
2022-01-12 02:53:07 +01:00
|
|
|
|
}
|
|
|
|
|
|
2022-10-19 16:10:36 +02:00
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
// Purpose: gets all console submissions
|
|
|
|
|
// Output : vector of strings
|
|
|
|
|
//-----------------------------------------------------------------------------
|
2022-10-24 00:50:07 +02:00
|
|
|
|
vector<string> CConsole::GetHistory(void) const
|
2022-10-19 16:10:36 +02:00
|
|
|
|
{
|
|
|
|
|
std::lock_guard<std::mutex> l(m_Mutex);
|
|
|
|
|
return m_vHistory;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
// Purpose: clears the entire submission history vector
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
void CConsole::ClearHistory(void)
|
|
|
|
|
{
|
|
|
|
|
std::lock_guard<std::mutex> l(m_Mutex);
|
|
|
|
|
m_vHistory.clear();
|
|
|
|
|
BuildSummary();
|
|
|
|
|
}
|
|
|
|
|
|
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-08-22 01:10:18 +02:00
|
|
|
|
m_Style = g_pImGuiConfig->InitStyle();
|
2022-06-24 12:22:04 +02:00
|
|
|
|
|
2022-06-24 12:45:47 +02:00
|
|
|
|
ImGui::SetNextWindowSize(ImVec2(1200, 524), ImGuiCond_FirstUseEver);
|
2022-06-24 12:22:04 +02:00
|
|
|
|
ImGui::SetWindowPos(ImVec2(-1000, 50), ImGuiCond_FirstUseEver);
|
2021-12-25 22:36:38 +01:00
|
|
|
|
}
|
|
|
|
|
|
2022-05-27 02:46:13 +02:00
|
|
|
|
CConsole* g_pConsole = new CConsole();
|