ImGui: console and browser code style refactor

Made the style of the code more consistent. Not much logic-wise had changed during the refactor, but there are some.

Console:
* Removed m_bSuggestUpdate and the logic bound to it, this var was never set and the logic was never used. This was the initial workaround for resetting the autocomplete selection pos to kPark (-1), but this is currently done in a more mature way, but the old code was never removed
* CreateSuggestionsFromPartial() (previously, FindFromPartial()) would break if a ConCommand/ConVar was found that was already added in the list. Although this is an engine/sdk level bug, we shouldn't stop iterating there. Added an assert instead and made the loop continue.
* Removed member m_bCopyToClipBoard, this was used to check if the copy button was pressed, to copy the text the next frame. The copy now happens directly in the site of the Copy button which is a better approach.
* Due to the changes with removing m_bCopyToClipBoard, the mutex for m_colorTextLogger is now released right after rendering the color text to fully minimize blocking time between other threads.

Browser:
* Moved ImGui::Begin() call from RunFrame() to DrawSurface(), it fits better there and we can now also return false if the frame didn't render.
* Improved the "Broadcasting" text formatting when server browser is hosting and broadcasting without a server token (public server).

Both:
* Added virtual Shutdown() method.
This commit is contained in:
Kawe Mazidjatari 2024-03-01 13:39:06 +01:00
parent 5229125915
commit 7f36220448
5 changed files with 607 additions and 536 deletions

View File

@ -43,18 +43,18 @@ static ConCommand togglebrowser("togglebrowser", CBrowser::ToggleBrowser_f, "Sho
// Purpose:
//-----------------------------------------------------------------------------
CBrowser::CBrowser(void)
: m_bReclaimFocusTokenField(false)
, m_bQueryListNonRecursive(false)
, m_bQueryGlobalBanList(true)
, m_HostMessageColor(1.00f, 1.00f, 1.00f, 1.00f)
, m_ivHiddenServerMessageColor(0.00f, 1.00f, 0.00f, 1.00f)
: m_reclaimFocusOnTokenField(false)
, m_queryNewListNonRecursive(false)
, m_queryGlobalBanList(true)
, m_hostMessageColor(1.00f, 1.00f, 1.00f, 1.00f)
, m_hiddenServerMessageColor(0.00f, 1.00f, 0.00f, 1.00f)
{
m_surfaceLabel = "Server Browser";
memset(m_szServerAddressBuffer, '\0', sizeof(m_szServerAddressBuffer));
memset(m_szServerEncKeyBuffer, '\0', sizeof(m_szServerEncKeyBuffer));
memset(m_serverAddressTextBuf, '\0', sizeof(m_serverAddressTextBuf));
memset(m_serverNetKeyTextBuf, '\0', sizeof(m_serverNetKeyTextBuf));
m_rLockedIconBlob = GetModuleResource(IDB_PNG2);
m_lockedIconDataResource = GetModuleResource(IDB_PNG2);
}
//-----------------------------------------------------------------------------
@ -62,10 +62,7 @@ CBrowser::CBrowser(void)
//-----------------------------------------------------------------------------
CBrowser::~CBrowser(void)
{
if (m_idLockedIcon)
{
m_idLockedIcon->Release();
}
Shutdown();
}
//-----------------------------------------------------------------------------
@ -75,13 +72,24 @@ bool CBrowser::Init(void)
{
SetStyleVar(928.f, 524.f, -500.f, 50.f);
bool ret = LoadTextureBuffer(reinterpret_cast<unsigned char*>(m_rLockedIconBlob.m_pData), int(m_rLockedIconBlob.m_nSize),
&m_idLockedIcon, &m_rLockedIconBlob.m_nWidth, &m_rLockedIconBlob.m_nHeight);
bool ret = LoadTextureBuffer(reinterpret_cast<unsigned char*>(m_lockedIconDataResource.m_pData), int(m_lockedIconDataResource.m_nSize),
&m_lockedIconShaderResource, &m_lockedIconDataResource.m_nWidth, &m_lockedIconDataResource.m_nHeight);
IM_ASSERT(ret && m_idLockedIcon);
IM_ASSERT(ret && m_lockedIconShaderResource);
return ret;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CBrowser::Shutdown(void)
{
if (m_lockedIconShaderResource)
{
m_lockedIconShaderResource->Release();
}
}
//-----------------------------------------------------------------------------
// Purpose: draws the main browser front-end
//-----------------------------------------------------------------------------
@ -102,36 +110,29 @@ void CBrowser::RunFrame(void)
Animate();
RunTask();
int nVars = 0;
float flWidth;
float flHeight;
int baseWindowStyleVars = 0;
ImVec2 minBaseWindowRect;
if (m_surfaceStyle == ImGuiStyle_t::MODERN)
{
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2{ 8.f, 10.f }); nVars++;
ImGui::PushStyleVar(ImGuiStyleVar_Alpha, m_fadeAlpha); nVars++;
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2{ 8.f, 10.f }); baseWindowStyleVars++;
ImGui::PushStyleVar(ImGuiStyleVar_Alpha, m_fadeAlpha); baseWindowStyleVars++;
flWidth = 621.f;
flHeight = 532.f;
minBaseWindowRect = ImVec2(621.f, 532.f);
}
else
{
if (m_surfaceStyle == ImGuiStyle_t::LEGACY)
{
flWidth = 619.f;
flHeight = 526.f;
}
else
{
flWidth = 618.f;
flHeight = 524.f;
minBaseWindowRect = m_surfaceStyle == ImGuiStyle_t::LEGACY
? ImVec2(619.f, 526.f)
: ImVec2(618.f, 524.f);
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2{ 6.f, 6.f }); baseWindowStyleVars++;
ImGui::PushStyleVar(ImGuiStyleVar_Alpha, m_fadeAlpha); baseWindowStyleVars++;
ImGui::PushStyleVar(ImGuiStyleVar_ChildBorderSize, 1.0f); baseWindowStyleVars++;
}
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2{ 6.f, 6.f }); nVars++;
ImGui::PushStyleVar(ImGuiStyleVar_Alpha, m_fadeAlpha); nVars++;
ImGui::PushStyleVar(ImGuiStyleVar_ChildBorderSize, 1.0f); nVars++;
}
ImGui::PushStyleVar(ImGuiStyleVar_WindowMinSize, ImVec2(flWidth, flHeight)); nVars++;
ImGui::PushStyleVar(ImGuiStyleVar_WindowMinSize, minBaseWindowRect); baseWindowStyleVars++;
if (m_activated && m_reclaimFocus) // Reclaim focus on window apparition.
{
@ -139,17 +140,8 @@ void CBrowser::RunFrame(void)
m_reclaimFocus = false;
}
if (!ImGui::Begin(m_surfaceLabel, &m_activated, ImGuiWindowFlags_NoScrollbar, &ResetInput))
{
ImGui::End();
ImGui::PopStyleVar(nVars);
return;
}
DrawSurface();
ImGui::End();
ImGui::PopStyleVar(nVars);
ImGui::PopStyleVar(baseWindowStyleVars);
}
//-----------------------------------------------------------------------------
@ -174,38 +166,47 @@ void CBrowser::RunTask()
if (m_activated)
{
if (m_bQueryListNonRecursive)
if (m_queryNewListNonRecursive)
{
m_bQueryListNonRecursive = false;
m_queryNewListNonRecursive = false;
RefreshServerList();
}
}
else // Refresh server list the next time 'm_activated' evaluates to true.
{
m_bReclaimFocusTokenField = true;
m_bQueryListNonRecursive = true;
m_reclaimFocusOnTokenField = true;
m_queryNewListNonRecursive = true;
}
}
//-----------------------------------------------------------------------------
// Purpose: draws the compmenu
// Purpose: draws the server browser's main surface
// Output : true if a frame has been drawn, false otherwise
//-----------------------------------------------------------------------------
bool CBrowser::DrawSurface(void)
{
if (!ImGui::Begin(m_surfaceLabel, &m_activated, ImGuiWindowFlags_NoScrollbar, &ResetInput))
{
ImGui::End();
return false;
}
ImGui::BeginTabBar("CompMenu");
if (ImGui::BeginTabItem("Browsing"))
{
BrowserPanel();
DrawBrowserPanel();
ImGui::EndTabItem();
}
#ifndef CLIENT_DLL
if (ImGui::BeginTabItem("Hosting"))
{
HostPanel();
DrawHostPanel();
ImGui::EndTabItem();
}
#endif // !CLIENT_DLL
ImGui::EndTabBar();
ImGui::End();
return true;
}
@ -213,38 +214,38 @@ bool CBrowser::DrawSurface(void)
//-----------------------------------------------------------------------------
// Purpose: draws the server browser section
//-----------------------------------------------------------------------------
void CBrowser::BrowserPanel(void)
void CBrowser::DrawBrowserPanel(void)
{
ImGui::BeginGroup();
m_imServerBrowserFilter.Draw();
m_serverBrowserTextFilter.Draw();
ImGui::SameLine();
if (ImGui::Button("Refresh"))
{
m_svServerListMessage.clear();
m_serverListMessage.clear();
RefreshServerList();
}
ImGui::EndGroup();
ImGui::TextColored(ImVec4(1.00f, 0.00f, 0.00f, 1.00f), "%s", m_svServerListMessage.c_str());
ImGui::TextColored(ImVec4(1.00f, 0.00f, 0.00f, 1.00f), "%s", m_serverListMessage.c_str());
ImGui::Separator();
int iVars = 0; // Eliminate borders around server list table.
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2{ 1.f, 0.f }); iVars++;
int windowStyleVars = 0; // Eliminate borders around server list table.
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2{ 1.f, 0.f }); windowStyleVars++;
const float fFooterHeight = ImGui::GetStyle().ItemSpacing.y + ImGui::GetFrameHeightWithSpacing();
ImGui::BeginChild("##ServerBrowser_ServerList", { 0, -fFooterHeight }, true, ImGuiWindowFlags_AlwaysVerticalScrollbar);
if (ImGui::BeginTable("##ServerBrowser_ServerListTable", 6, ImGuiTableFlags_Resizable))
{
int nVars = 0;
int frameStyleVars = 0;
if (m_surfaceStyle == ImGuiStyle_t::MODERN)
{
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2{ 8.f, 0.f }); nVars++;
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2{ 8.f, 0.f }); frameStyleVars++;
}
else
{
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2{ 4.f, 0.f }); nVars++;
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2{ 4.f, 0.f }); frameStyleVars++;
}
ImGui::TableSetupColumn("Name", ImGuiTableColumnFlags_WidthStretch, 25);
@ -265,9 +266,9 @@ void CBrowser::BrowserPanel(void)
char pszHostPort[32];
sprintf(pszHostPort, "%d", server.port);
if (m_imServerBrowserFilter.PassFilter(pszHostName)
|| m_imServerBrowserFilter.PassFilter(pszHostMap)
|| m_imServerBrowserFilter.PassFilter(pszHostPort))
if (m_serverBrowserTextFilter.PassFilter(pszHostName)
|| m_serverBrowserTextFilter.PassFilter(pszHostMap)
|| m_serverBrowserTextFilter.PassFilter(pszHostPort))
{
ImGui::TableNextColumn();
ImGui::Text("%s", pszHostName);
@ -297,11 +298,11 @@ void CBrowser::BrowserPanel(void)
g_ServerListManager.m_Mutex.unlock();
ImGui::EndTable();
ImGui::PopStyleVar(nVars);
ImGui::PopStyleVar(frameStyleVars);
}
ImGui::EndChild();
ImGui::PopStyleVar(iVars);
ImGui::PopStyleVar(windowStyleVars);
ImGui::Separator();
@ -315,17 +316,17 @@ void CBrowser::BrowserPanel(void)
ImGui::PushItemWidth(itemWidth);
{
ImGui::InputTextWithHint("##ServerBrowser_ServerCon", "Server address and port", m_szServerAddressBuffer, IM_ARRAYSIZE(m_szServerAddressBuffer));
ImGui::InputTextWithHint("##ServerBrowser_ServerCon", "Server address and port", m_serverAddressTextBuf, IM_ARRAYSIZE(m_serverAddressTextBuf));
ImGui::SameLine();
ImGui::InputTextWithHint("##ServerBrowser_ServerKey", "Encryption key", m_szServerEncKeyBuffer, IM_ARRAYSIZE(m_szServerEncKeyBuffer));
ImGui::InputTextWithHint("##ServerBrowser_ServerKey", "Encryption key", m_serverNetKeyTextBuf, IM_ARRAYSIZE(m_serverNetKeyTextBuf));
ImGui::SameLine();
if (ImGui::Button("Connect", ImVec2(itemWidth, ImGui::GetFrameHeight())))
{
if (m_szServerAddressBuffer[0])
if (m_serverAddressTextBuf[0])
{
g_ServerListManager.ConnectToServer(m_szServerAddressBuffer, m_szServerEncKeyBuffer);
g_ServerListManager.ConnectToServer(m_serverAddressTextBuf, m_serverNetKeyTextBuf);
}
}
@ -351,15 +352,16 @@ void CBrowser::RefreshServerList(void)
// Thread the request, and let the main thread assign status message back
std::thread request([&]
{
std::string svServerListMessage;
g_ServerListManager.RefreshServerList(svServerListMessage);
std::string serverListMessage;
g_ServerListManager.RefreshServerList(serverListMessage);
g_TaskQueue.Dispatch([&, svServerListMessage]
g_TaskQueue.Dispatch([&, serverListMessage]
{
SetServerListMessage(svServerListMessage.c_str());
SetServerListMessage(serverListMessage.c_str());
}, 0);
}
);
request.detach();
}
@ -368,32 +370,31 @@ void CBrowser::RefreshServerList(void)
//-----------------------------------------------------------------------------
void CBrowser::HiddenServersModal(void)
{
float flHeight; // Set the padding accordingly for each theme.
float modalWindowHeight; // Set the padding accordingly for each theme.
switch (m_surfaceStyle)
{
case ImGuiStyle_t::LEGACY:
flHeight = 207.f;
modalWindowHeight = 207.f;
break;
case ImGuiStyle_t::MODERN:
flHeight = 214.f;
modalWindowHeight = 214.f;
break;
default:
flHeight = 206.f;
modalWindowHeight = 206.f;
break;
}
int nVars = 0;
bool bModalOpen = true;
int modalStyleVars = 0;
ImGui::PushStyleVar(ImGuiStyleVar_WindowMinSize, ImVec2(408.f, modalWindowHeight)); modalStyleVars++;
ImGui::PushStyleVar(ImGuiStyleVar_WindowMinSize, ImVec2(408.f, flHeight)); nVars++;
if (ImGui::BeginPopupModal("Private Server", &bModalOpen, ImGuiWindowFlags_NoResize))
bool isModalStillOpen = true;
if (ImGui::BeginPopupModal("Private Server", &isModalStillOpen, ImGuiWindowFlags_NoResize))
{
ImGui::SetWindowSize(ImVec2(408.f, flHeight), ImGuiCond_Always);
ImGui::SetWindowSize(ImVec2(408.f, modalWindowHeight), ImGuiCond_Always);
ImGui::PushStyleColor(ImGuiCol_ChildBg, ImVec4(0.00f, 0.00f, 0.00f, 0.00f)); // Override the style color for child bg.
ImGui::BeginChild("##HiddenServersConnectModal_IconParent", ImVec2(float(m_rLockedIconBlob.m_nWidth), float(m_rLockedIconBlob.m_nHeight)));
ImGui::Image(m_idLockedIcon, ImVec2(float(m_rLockedIconBlob.m_nWidth), float(m_rLockedIconBlob.m_nHeight))); // Display texture.
ImGui::BeginChild("##HiddenServersConnectModal_IconParent", ImVec2(float(m_lockedIconDataResource.m_nWidth), float(m_lockedIconDataResource.m_nHeight)));
ImGui::Image(m_lockedIconShaderResource, ImVec2(float(m_lockedIconDataResource.m_nWidth), float(m_lockedIconDataResource.m_nHeight))); // Display texture.
ImGui::EndChild();
ImGui::PopStyleColor(); // Pop the override for the child bg.
@ -409,82 +410,82 @@ void CBrowser::HiddenServersModal(void)
ImGui::PopItemWidth();
if (m_bReclaimFocusTokenField)
if (m_reclaimFocusOnTokenField)
{
ImGui::SetKeyboardFocusHere(-1); // -1 means previous widget.
m_bReclaimFocusTokenField = false;
m_reclaimFocusOnTokenField = false;
}
ImGui::Dummy(ImVec2(contentRegionMax.x, 19.f)); // Place a dummy, basically making space inserting a blank element.
ImGui::TextColored(m_ivHiddenServerMessageColor, "%s", m_svHiddenServerRequestMessage.c_str());
ImGui::TextColored(m_hiddenServerMessageColor, "%s", m_hiddenServerRequestMessage.c_str());
ImGui::Separator();
if (ImGui::Button("Connect", ImVec2(contentRegionMax.x, 24)))
{
m_svHiddenServerRequestMessage.clear();
m_bReclaimFocusTokenField = true;
m_hiddenServerRequestMessage.clear();
m_reclaimFocusOnTokenField = true;
if (!hiddenServerToken.empty())
{
NetGameServer_t server;
bool result = g_MasterServer.GetServerByToken(server, m_svHiddenServerRequestMessage, hiddenServerToken); // Send token connect request.
const bool result = g_MasterServer.GetServerByToken(server, m_hiddenServerRequestMessage, hiddenServerToken); // Send token connect request.
if (result && !server.name.empty())
{
g_ServerListManager.ConnectToServer(server.address, server.port, server.netKey); // Connect to the server
m_svHiddenServerRequestMessage = Format("Found server: %s", server.name.c_str());
m_ivHiddenServerMessageColor = ImVec4(0.00f, 1.00f, 0.00f, 1.00f);
m_hiddenServerRequestMessage = Format("Found server: %s", server.name.c_str());
m_hiddenServerMessageColor = ImVec4(0.00f, 1.00f, 0.00f, 1.00f);
ImGui::CloseCurrentPopup();
}
else
{
if (m_svHiddenServerRequestMessage.empty())
if (m_hiddenServerRequestMessage.empty())
{
m_svHiddenServerRequestMessage = "Unknown error.";
m_hiddenServerRequestMessage = "Unknown error.";
}
else // Display error message.
{
m_svHiddenServerRequestMessage = Format("Error: %s", m_svHiddenServerRequestMessage.c_str());
m_hiddenServerRequestMessage = Format("Error: %s", m_hiddenServerRequestMessage.c_str());
}
m_ivHiddenServerMessageColor = ImVec4(1.00f, 0.00f, 0.00f, 1.00f);
m_hiddenServerMessageColor = ImVec4(1.00f, 0.00f, 0.00f, 1.00f);
}
}
else
{
m_svHiddenServerRequestMessage = "Token is required.";
m_ivHiddenServerMessageColor = ImVec4(1.00f, 0.00f, 0.00f, 1.00f);
m_hiddenServerRequestMessage = "Token is required.";
m_hiddenServerMessageColor = ImVec4(1.00f, 0.00f, 0.00f, 1.00f);
}
}
if (ImGui::Button("Close", ImVec2(contentRegionMax.x, 24)))
{
m_svHiddenServerRequestMessage.clear();
m_bReclaimFocusTokenField = true;
m_hiddenServerRequestMessage.clear();
m_reclaimFocusOnTokenField = true;
ImGui::CloseCurrentPopup();
}
ImGui::EndPopup();
ImGui::PopStyleVar(nVars);
ImGui::PopStyleVar(modalStyleVars);
}
else if (!bModalOpen)
else if (!isModalStillOpen)
{
m_svHiddenServerRequestMessage.clear();
m_bReclaimFocusTokenField = true;
m_hiddenServerRequestMessage.clear();
m_reclaimFocusOnTokenField = true;
ImGui::PopStyleVar(nVars);
ImGui::PopStyleVar(modalStyleVars);
}
else
{
ImGui::PopStyleVar(nVars);
ImGui::PopStyleVar(modalStyleVars);
}
}
//-----------------------------------------------------------------------------
// Purpose: draws the host section
//-----------------------------------------------------------------------------
void CBrowser::HostPanel(void)
void CBrowser::DrawHostPanel(void)
{
#ifndef CLIENT_DLL
std::lock_guard<std::mutex> l(g_ServerListManager.m_Mutex);
@ -527,10 +528,10 @@ void CBrowser::HostPanel(void)
ImGui::EndCombo();
}
m_bQueryGlobalBanList = sv_globalBanlist.GetBool(); // Sync toggle with 'sv_globalBanlist'.
if (ImGui::Checkbox("Load global banned list", &m_bQueryGlobalBanList))
m_queryGlobalBanList = sv_globalBanlist.GetBool(); // Sync toggle with 'sv_globalBanlist'.
if (ImGui::Checkbox("Load global banned list", &m_queryGlobalBanList))
{
sv_globalBanlist.SetValue(m_bQueryGlobalBanList);
sv_globalBanlist.SetValue(m_queryGlobalBanList);
}
ImGui::Text("Server visibility");
@ -548,47 +549,51 @@ void CBrowser::HostPanel(void)
g_ServerListManager.m_ServerVisibility = EServerVisibility_t::PUBLIC;
}
ImGui::TextColored(m_HostMessageColor, "%s", m_svHostMessage.c_str());
if (!m_svHostToken.empty())
ImGui::TextColored(m_hostMessageColor, "%s", m_hostMessage.c_str());
if (!m_hostToken.empty())
{
ImGui::InputText("##ServerHost_HostToken", &m_svHostToken, ImGuiInputTextFlags_ReadOnly);
ImGui::InputText("##ServerHost_HostToken", &m_hostToken, ImGuiInputTextFlags_ReadOnly);
}
ImGui::Spacing();
const ImVec2 contentRegionMax = ImGui::GetContentRegionAvail();
const bool bServerActive = g_pServer->IsActive();
const bool serverActive = g_pServer->IsActive();
if (!g_pHostState->m_bActiveGame)
{
if (ImGui::Button("Start server", ImVec2(contentRegionMax.x, 32)))
{
m_svHostMessage.clear();
m_hostMessage.clear();
bool bEnforceField = g_ServerListManager.m_ServerVisibility == EServerVisibility_t::OFFLINE ? true : !g_ServerListManager.m_Server.name.empty();
if (bEnforceField && !g_ServerListManager.m_Server.playlist.empty() && !g_ServerListManager.m_Server.map.empty())
const bool enforceField = g_ServerListManager.m_ServerVisibility == EServerVisibility_t::OFFLINE
? true
: !g_ServerListManager.m_Server.name.empty();
if (enforceField && !g_ServerListManager.m_Server.playlist.empty() && !g_ServerListManager.m_Server.map.empty())
{
g_ServerListManager.LaunchServer(bServerActive); // Launch server.
g_ServerListManager.LaunchServer(serverActive); // Launch server.
}
else
{
if (g_ServerListManager.m_Server.name.empty())
{
m_svHostMessage = "Server name is required.";
m_HostMessageColor = ImVec4(1.00f, 0.00f, 0.00f, 1.00f);
m_hostMessage = "Server name is required.";
m_hostMessageColor = ImVec4(1.00f, 0.00f, 0.00f, 1.00f);
}
else if (g_ServerListManager.m_Server.playlist.empty())
{
m_svHostMessage = "Playlist is required.";
m_HostMessageColor = ImVec4(1.00f, 0.00f, 0.00f, 1.00f);
m_hostMessage = "Playlist is required.";
m_hostMessageColor = ImVec4(1.00f, 0.00f, 0.00f, 1.00f);
}
else if (g_ServerListManager.m_Server.map.empty())
{
m_svHostMessage = "Level name is required.";
m_HostMessageColor = ImVec4(1.00f, 0.00f, 0.00f, 1.00f);
m_hostMessage = "Level name is required.";
m_hostMessageColor = ImVec4(1.00f, 0.00f, 0.00f, 1.00f);
}
}
}
if (ImGui::Button("Reload playlist", ImVec2(contentRegionMax.x, 32)))
{
v_Playlists_Download_f();
@ -612,16 +617,16 @@ void CBrowser::HostPanel(void)
{
if (!g_ServerListManager.m_Server.map.empty())
{
g_ServerListManager.LaunchServer(bServerActive);
g_ServerListManager.LaunchServer(serverActive);
}
else
{
m_svHostMessage = "Failed to change level: 'levelname' was empty.";
m_HostMessageColor = ImVec4(1.00f, 0.00f, 0.00f, 1.00f);
m_hostMessage = "Failed to change level: 'levelname' was empty.";
m_hostMessageColor = ImVec4(1.00f, 0.00f, 0.00f, 1.00f);
}
}
if (bServerActive)
if (serverActive)
{
ImGui::Spacing();
ImGui::Separator();
@ -677,16 +682,16 @@ void CBrowser::UpdateHostingStatus(void)
{
case EHostStatus_t::NOT_HOSTING:
{
if (!m_svHostToken.empty())
if (!m_hostToken.empty())
{
m_svHostToken.clear();
m_hostToken.clear();
}
if (ImGui::ColorConvertFloat4ToU32(m_HostMessageColor) == // Only clear if this is green (a valid hosting message).
if (ImGui::ColorConvertFloat4ToU32(m_hostMessageColor) == // Only clear if this is green (a valid hosting message).
ImGui::ColorConvertFloat4ToU32(ImVec4(0.00f, 1.00f, 0.00f, 1.00f)))
{
m_svHostMessage.clear();
m_HostMessageColor = ImVec4(1.00f, 1.00f, 1.00f, 1.00f);
m_hostMessage.clear();
m_hostMessageColor = ImVec4(1.00f, 1.00f, 1.00f, 1.00f);
}
break;
@ -780,8 +785,8 @@ void CBrowser::SendHostingPostRequest(const NetGameServer_t& gameServer)
void CBrowser::InstallHostingDetails(const bool postFailed, const char* const hostMessage, const char* const hostToken, const string& hostIp)
{
#ifndef CLIENT_DLL
m_svHostMessage = hostMessage;
m_svHostToken = hostToken;
m_hostMessage = hostMessage;
m_hostToken = hostToken;
if (!hostIp.empty())
{
@ -790,18 +795,19 @@ void CBrowser::InstallHostingDetails(const bool postFailed, const char* const ho
if (postFailed)
{
m_HostMessageColor = ImVec4(0.00f, 1.00f, 0.00f, 1.00f);
m_hostMessageColor = ImVec4(0.00f, 1.00f, 0.00f, 1.00f);
stringstream ssMessage;
ssMessage << "Broadcasting: ";
if (!m_svHostToken.empty())
ssMessage << "Broadcasting";
if (!m_hostToken.empty())
{
ssMessage << "share the following token for clients to connect: ";
ssMessage << ": share the following token for clients to connect: ";
}
m_svHostMessage = ssMessage.str();
m_hostMessage = ssMessage.str();
}
else
{
m_HostMessageColor = ImVec4(1.00f, 0.00f, 0.00f, 1.00f);
m_hostMessageColor = ImVec4(1.00f, 0.00f, 0.00f, 1.00f);
}
#endif // !CLIENT_DLL
}

View File

@ -15,17 +15,18 @@ public:
virtual ~CBrowser(void);
virtual bool Init(void);
virtual void Shutdown(void);
virtual void RunFrame(void);
void RunTask(void);
virtual bool DrawSurface(void);
void BrowserPanel(void);
void DrawBrowserPanel(void);
void RefreshServerList(void);
void HiddenServersModal(void);
void HostPanel(void);
void DrawHostPanel(void);
void UpdateHostingStatus(void);
void InstallHostingDetails(const bool postFailed, const char* const hostMessage, const char* const hostToken, const string& hostIp);
@ -38,38 +39,38 @@ public:
static void ToggleBrowser_f();
private:
inline void SetServerListMessage(const char* const message) { m_svServerListMessage = message; };
inline void SetHostMessage(const char* const message) { m_svHostMessage = message; }
inline void SetHostToken(const char* const message) { m_svHostToken = message; }
inline void SetServerListMessage(const char* const message) { m_serverListMessage = message; };
inline void SetHostMessage(const char* const message) { m_hostMessage = message; }
inline void SetHostToken(const char* const message) { m_hostToken = message; }
private:
bool m_bReclaimFocusTokenField;
bool m_bQueryListNonRecursive; // When set, refreshes the server list once the next frame.
bool m_bQueryGlobalBanList;
char m_szServerAddressBuffer[128];
char m_szServerEncKeyBuffer[30];
bool m_reclaimFocusOnTokenField;
bool m_queryNewListNonRecursive; // When set, refreshes the server list once the next frame.
bool m_queryGlobalBanList;
char m_serverAddressTextBuf[128];
char m_serverNetKeyTextBuf[30];
ID3D11ShaderResourceView* m_idLockedIcon;
MODULERESOURCE m_rLockedIconBlob;
ID3D11ShaderResourceView* m_lockedIconShaderResource;
MODULERESOURCE m_lockedIconDataResource;
////////////////////
// Server List //
////////////////////
ImGuiTextFilter m_imServerBrowserFilter;
string m_svServerListMessage;
ImGuiTextFilter m_serverBrowserTextFilter;
string m_serverListMessage;
////////////////////
// Host Server //
////////////////////
string m_svHostMessage;
string m_svHostToken;
ImVec4 m_HostMessageColor;
string m_hostMessage;
string m_hostToken;
ImVec4 m_hostMessageColor;
////////////////////
// Private Server //
////////////////////
string m_svHiddenServerRequestMessage;
ImVec4 m_ivHiddenServerMessageColor;
string m_hiddenServerRequestMessage;
ImVec4 m_hiddenServerMessageColor;
};
extern CBrowser g_Browser;

File diff suppressed because it is too large Load Diff

View File

@ -15,28 +15,29 @@ public:
virtual ~CConsole(void);
virtual bool Init(void);
virtual void Shutdown(void);
virtual void RunFrame(void);
virtual bool DrawSurface(void);
private:
void OptionsPanel(void);
void SuggestPanel(void);
void DrawOptionsPanel(void);
void DrawAutoCompletePanel(void);
bool AutoComplete(void);
void ResetAutoComplete(void);
bool RunAutoComplete(void);
void ResetAutoCompleteData(void);
void FindFromPartial(void);
void ProcessCommand(string svCommand);
void CreateSuggestionsFromPartial(void);
void ProcessCommand(const char* const inputText);
void BuildSummary(string svConVar = "");
void BuildSummaryText(const char* const inputText);
struct CSuggest;
void BuildInputFromSelected(const CSuggest& suggest, string& svInput);
void BuildSuggestPanelRect(void);
struct ConAutoCompleteSuggest_s;
void DetermineInputTextFromSelectedSuggestion(const ConAutoCompleteSuggest_s& suggest, string& svInput);
void DetermineAutoCompleteWindowRect(void);
bool LoadFlagIcons(void);
int GetFlagTextureIndex(int nFlags) const;
int GetFlagTextureIndex(const int flags) const;
int TextEditCallback(ImGuiInputTextCallbackData* pData);
static int TextEditCallbackStub(ImGuiInputTextCallbackData* pData);
@ -66,70 +67,106 @@ private: // Internals.
void ClampHistorySize(void);
private:
enum PositionMode_t
enum ConAutoCompletePos_e
{
// Park means the position is out of screen.
kPark = -1,
kFirst,
};
struct CSuggest
struct ConAutoCompleteSuggest_s
{
CSuggest(const string& svName, int nFlags)
ConAutoCompleteSuggest_s(const string& inText, const int inFlags)
{
m_svName = svName;
m_nFlags = nFlags;
text = inText;
flags = inFlags;
}
bool operator==(const string& a) const
{
return m_svName.compare(a) == 0;
return text.compare(a) == 0;
}
bool operator<(const CSuggest& a) const
bool operator<(const ConAutoCompleteSuggest_s& a) const
{
return m_svName < a.m_svName;
return text < a.text;
}
string m_svName;
int m_nFlags;
string text;
int flags;
};
private:
///////////////////////////////////////////////////////////////////////////
const char* m_pszLoggingLabel;
char m_szInputBuf[512];
char m_szSummary[256];
char m_szWindowLabel[128];
const char* m_loggerLabel;
char m_inputTextBuf[512];
char m_summaryTextBuf[256];
string m_svInputConVar;
ssize_t m_nHistoryPos;
ssize_t m_nSuggestPos;
int m_nScrollBack;
int m_nSelectBack;
int m_nInputTextLen;
float m_flScrollX;
float m_flScrollY;
// The selected ConVar from the suggestions in the autocomplete window gets
// copied into this buffer.
string m_selectedSuggestionText;
int m_selectedSuggestionTextLen;
bool m_bCopyToClipBoard;
bool m_bModifyInput;
// The positions in the history buffer; when there is nothing in the input
// text field, the arrow keys would instead iterate over the previously
// submitted commands and show the currently selected one right in the
// input text field.
int m_historyPos;
bool m_bCanAutoComplete;
bool m_bSuggestActive;
bool m_bSuggestMoved;
bool m_bSuggestUpdate;
// The position in the autocomplete window; this dictates the current
// (highlighted) suggestion, and copies that one into m_selectedSuggestion
// once selected.
int m_suggestPos;
vector<CSuggest> m_vSuggest;
vector<MODULERESOURCE> m_vFlagIcons;
vector<string> m_vHistory;
// Scroll and select back amount; if text lines are getting removed to
// clamp the size to the maximum allowed, we need to scroll back (and
// if text has been selected, select back this amount) to prevent the
// view or selection from drifting.
int m_scrollBackAmount;
int m_selectBackAmount;
ImVec2 m_ivSuggestWindowPos;
ImVec2 m_ivSuggestWindowSize;
// Scroll position of the last drawn frame, after any scroll back has been
// applied, this is used as a base for scrolling back when entries are
// getting removed.
ImVec2 m_lastFrameScrollPos;
CTextLogger m_Logger;
mutable CThreadFastMutex m_Mutex;
// Set when the input text has been modified, used to rebuild suggestions
// shown in the autocomplete window.
bool m_inputTextBufModified;
ImGuiInputTextFlags m_nInputFlags;
ImGuiWindowFlags m_nSuggestFlags;
ImGuiWindowFlags m_nLoggingFlags;
// Determines whether we can autocomplete and build a list of suggestions,
// e.g. when you type "map " (with a trailing white space ' '), and "map"
// happens to be a ConCommand with an autocomplete function, this gets set
// and the autocomplete function of that ConCommand will be called to
// create a list of suggestions to be shown in the autocomplete window.
// This member is always false when the input text is empty.
bool m_canAutoComplete;
// Whether the autocomplete window is active. If this is set, the arrow up
// and down keys will be used for the auto complete window instead of the
// history (previously submitted commands) scroller.
bool m_autoCompleteActive;
// If the position in the autocomplete window had moved, this var will be
// set. This is used to check if we need to adjust the scroll position in
// the autocomplete window to keep the current selection visible.
bool m_autoCompletePosMoved;
// The position and rect of the autocomplete window, the pos is set to that
// of the input text field + an offset to move it under the item.
ImVec2 m_autoCompleteWindowPos;
ImVec2 m_autoCompleteWindowRect;
vector<ConAutoCompleteSuggest_s> m_vecSuggest;
vector<MODULERESOURCE> m_vecFlagIcons;
vector<string> m_vecHistory;
// The color logger in which text gets added, note that the mutex lock
// should always be acquired when using this as this is accessed from
// multiple threads!
CTextLogger m_colorTextLogger;
mutable CThreadFastMutex m_colorTextLoggerMutex;
ImGuiInputTextFlags m_inputTextFieldFlags;
ImGuiWindowFlags m_autoCompleteWindowFlags;
ImGuiWindowFlags m_colorLoggerWindowFlags;
};
///////////////////////////////////////////////////////////////////////////////

View File

@ -10,7 +10,9 @@ class CImguiSurface
public:
CImguiSurface();
virtual ~CImguiSurface() { };
virtual bool Init() = 0;
virtual void Shutdown() = 0;
virtual void Animate();
virtual void RunFrame() = 0;