657 lines
22 KiB
C++
657 lines
22 KiB
C++
// Copyright (c) 2020 - present, Roland Munguia
|
|
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
|
|
|
|
//#pragma once
|
|
|
|
#include <string>
|
|
#include "imgui_console.h"
|
|
#include "imgui_internal.h"
|
|
#include <cstring>
|
|
|
|
// The following three functions (InputTextCallback_UserData, InputTextCallback, InputText) are obtained from misc/cpp/imgui_stdlib.h
|
|
// Which are licensed under MIT License (https://github.com/ocornut/imgui/blob/master/LICENSE.txt)
|
|
namespace ImGui {
|
|
struct InputTextCallback_UserData
|
|
{
|
|
std::string* Str;
|
|
ImGuiInputTextCallback ChainCallback;
|
|
void* ChainCallbackUserData;
|
|
};
|
|
|
|
static int InputTextCallback(ImGuiInputTextCallbackData* data)
|
|
{
|
|
auto* user_data = (InputTextCallback_UserData*)data->UserData;
|
|
if (data->EventFlag == ImGuiInputTextFlags_CallbackResize)
|
|
{
|
|
// Resize string callback
|
|
// If for some reason we refuse the new length (BufTextLen) and/or capacity (BufSize) we need to set them back to what we want.
|
|
std::string* str = user_data->Str;
|
|
IM_ASSERT(data->Buf == str->c_str());
|
|
str->resize(data->BufTextLen);
|
|
data->Buf = (char*)str->c_str();
|
|
} else if (user_data->ChainCallback)
|
|
{
|
|
// Forward to user callback, if any
|
|
data->UserData = user_data->ChainCallbackUserData;
|
|
return user_data->ChainCallback(data);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
bool InputText(const char* label, std::string* str, ImGuiInputTextFlags flags, ImGuiInputTextCallback callback, void* user_data)
|
|
{
|
|
IM_ASSERT((flags & ImGuiInputTextFlags_CallbackResize) == 0);
|
|
flags |= ImGuiInputTextFlags_CallbackResize;
|
|
|
|
InputTextCallback_UserData cb_user_data;
|
|
cb_user_data.Str = str;
|
|
cb_user_data.ChainCallback = callback;
|
|
cb_user_data.ChainCallbackUserData = user_data;
|
|
return InputText(label, (char*)str->c_str(), str->capacity() + 1, flags, InputTextCallback, &cb_user_data);
|
|
}
|
|
}
|
|
|
|
ImGuiConsole::ImGuiConsole(std::string c_name, size_t inputBufferSize) : m_ConsoleName(std::move(c_name))
|
|
{
|
|
// Set input buffer size.
|
|
m_Buffer.resize(inputBufferSize);
|
|
m_HistoryIndex = std::numeric_limits<size_t>::min();
|
|
|
|
// Specify custom data to be store/loaded from imgui.ini
|
|
InitIniSettings();
|
|
|
|
// Set Console ImGui default settings
|
|
if (!m_LoadedFromIni)
|
|
{
|
|
DefaultSettings();
|
|
}
|
|
|
|
// Custom functions.
|
|
RegisterConsoleCommands();
|
|
}
|
|
|
|
void ImGuiConsole::Draw()
|
|
{
|
|
///////////////////////////////////////////////////////////////////////////
|
|
// Window and Settings ////////////////////////////////////////////////////
|
|
///////////////////////////////////////////////////////////////////////////
|
|
|
|
// Begin Console Window.
|
|
ImGui::PushStyleVar(ImGuiStyleVar_Alpha, m_WindowAlpha);
|
|
if (!ImGui::Begin(m_ConsoleName.data(), nullptr, ImGuiWindowFlags_MenuBar))
|
|
{
|
|
ImGui::PopStyleVar();
|
|
ImGui::End();
|
|
return;
|
|
}
|
|
ImGui::PopStyleVar();
|
|
|
|
///////////////
|
|
// Menu bar //
|
|
///////////////
|
|
MenuBar();
|
|
|
|
////////////////
|
|
// Filter bar //
|
|
////////////////
|
|
if (m_FilterBar)
|
|
{
|
|
FilterBar();
|
|
}
|
|
|
|
//////////////////
|
|
// Console Logs //
|
|
//////////////////
|
|
LogWindow();
|
|
|
|
// Section off.
|
|
ImGui::Separator();
|
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
// Command-line ///////////////////////////////////////////////////////////
|
|
///////////////////////////////////////////////////////////////////////////
|
|
|
|
InputBar();
|
|
|
|
ImGui::End();
|
|
}
|
|
|
|
csys::System& ImGuiConsole::System()
|
|
{
|
|
return m_ConsoleSystem;
|
|
}
|
|
|
|
void ImGuiConsole::InitIniSettings()
|
|
{
|
|
ImGuiContext& g = *ImGui::GetCurrentContext();
|
|
|
|
// Load from .ini
|
|
if (g.Initialized && !g.SettingsLoaded && !m_LoadedFromIni)
|
|
{
|
|
ImGuiSettingsHandler console_ini_handler;
|
|
console_ini_handler.TypeName = "imgui-console";
|
|
console_ini_handler.TypeHash = ImHashStr("imgui-console");
|
|
console_ini_handler.ClearAllFn = SettingsHandler_ClearALl;
|
|
console_ini_handler.ApplyAllFn = SettingsHandler_ApplyAll;
|
|
console_ini_handler.ReadInitFn = SettingsHandler_ReadInit;
|
|
console_ini_handler.ReadOpenFn = SettingsHandler_ReadOpen;
|
|
console_ini_handler.ReadLineFn = SettingsHandler_ReadLine;
|
|
console_ini_handler.WriteAllFn = SettingsHandler_WriteAll;
|
|
console_ini_handler.UserData = this;
|
|
g.SettingsHandlers.push_back(console_ini_handler);
|
|
}
|
|
// else Ini settings already loaded!
|
|
}
|
|
|
|
void ImGuiConsole::DefaultSettings()
|
|
{
|
|
// Settings
|
|
m_AutoScroll = true;
|
|
m_ScrollToBottom = false;
|
|
m_ColoredOutput = true;
|
|
m_FilterBar = true;
|
|
m_TimeStamps = true;
|
|
|
|
// Style
|
|
m_WindowAlpha = 1;
|
|
m_ColorPalette[COL_COMMAND] = ImVec4(1.f, 1.f, 1.f, 1.f);
|
|
m_ColorPalette[COL_LOG] = ImVec4(1.f, 1.f, 1.f, 0.5f);
|
|
m_ColorPalette[COL_WARNING] = ImVec4(1.0f, 0.87f, 0.37f, 1.f);
|
|
m_ColorPalette[COL_ERROR] = ImVec4(1.f, 0.365f, 0.365f, 1.f);
|
|
m_ColorPalette[COL_INFO] = ImVec4(0.46f, 0.96f, 0.46f, 1.f);
|
|
m_ColorPalette[COL_TIMESTAMP] = ImVec4(1.f, 1.f, 1.f, 0.5f);
|
|
}
|
|
|
|
void ImGuiConsole::RegisterConsoleCommands()
|
|
{
|
|
m_ConsoleSystem.RegisterCommand("clear", "Clear console log", [this]()
|
|
{
|
|
m_ConsoleSystem.Items().clear();
|
|
});
|
|
|
|
m_ConsoleSystem.RegisterCommand("filter", "Set screen filter", [this](const csys::String& filter)
|
|
{
|
|
// Reset filter buffer.
|
|
std::memset(m_TextFilter.InputBuf, '\0', 256);
|
|
|
|
// Copy filter input buffer from client.
|
|
std::copy(filter.m_String.c_str(), filter.m_String.c_str() + std::min(static_cast<int>(filter.m_String.length()), 255), m_TextFilter.InputBuf);
|
|
|
|
// Build text filter.
|
|
m_TextFilter.Build();
|
|
|
|
}, csys::Arg<csys::String>("filter_str"));
|
|
|
|
m_ConsoleSystem.RegisterCommand("run", "Run given script", [this](const csys::String& filter)
|
|
{
|
|
// Logs command.
|
|
m_ConsoleSystem.RunScript(filter.m_String);
|
|
}, csys::Arg<csys::String>("script_name"));
|
|
}
|
|
|
|
void ImGuiConsole::FilterBar()
|
|
{
|
|
m_TextFilter.Draw("Filter", ImGui::GetWindowWidth() * 0.25f);
|
|
ImGui::Separator();
|
|
}
|
|
|
|
void ImGuiConsole::LogWindow()
|
|
{
|
|
const float footerHeightToReserve = ImGui::GetStyle().ItemSpacing.y + ImGui::GetFrameHeightWithSpacing();
|
|
if (ImGui::BeginChild("ScrollRegion##", ImVec2(0, -footerHeightToReserve), false, 0))
|
|
{
|
|
// Display colored command output.
|
|
static const float timestamp_width = ImGui::CalcTextSize("00:00:00:0000").x; // Timestamp.
|
|
int count = 0; // Item count.
|
|
|
|
// Wrap items.
|
|
ImGui::PushTextWrapPos();
|
|
|
|
// Display items.
|
|
for (const auto& item : m_ConsoleSystem.Items())
|
|
{
|
|
// Exit if word is filtered.
|
|
if (!m_TextFilter.PassFilter(item.Get().c_str()))
|
|
continue;
|
|
|
|
// Spacing between commands.
|
|
if (item.m_Type == csys::eCOMMAND)
|
|
{
|
|
if (m_TimeStamps) ImGui::PushTextWrapPos(ImGui::GetColumnWidth() - timestamp_width); // Wrap before timestamps start.
|
|
if (count++ != 0) ImGui::Dummy(ImVec2(-1, ImGui::GetFontSize())); // No space for the first command.
|
|
}
|
|
|
|
// Items.
|
|
if (m_ColoredOutput)
|
|
{
|
|
ImGui::PushStyleColor(ImGuiCol_Text, m_ColorPalette[item.m_Type]);
|
|
ImGui::TextUnformatted(item.Get().data());
|
|
ImGui::PopStyleColor();
|
|
} else
|
|
{
|
|
ImGui::TextUnformatted(item.Get().data());
|
|
}
|
|
|
|
|
|
// Time stamp.
|
|
if (item.m_Type == csys::eCOMMAND && m_TimeStamps)
|
|
{
|
|
// No wrap for timestamps
|
|
ImGui::PopTextWrapPos();
|
|
|
|
// Right align.
|
|
ImGui::SameLine(ImGui::GetColumnWidth(-1) - timestamp_width);
|
|
|
|
// Draw time stamp.
|
|
ImGui::PushStyleColor(ImGuiCol_Text, m_ColorPalette[COL_TIMESTAMP]);
|
|
ImGui::Text("%02d:%02d:%02d:%04d", ((item.m_TimeStamp / 1000 / 3600) % 24), ((item.m_TimeStamp / 1000 / 60) % 60),
|
|
((item.m_TimeStamp / 1000) % 60), item.m_TimeStamp % 1000);
|
|
ImGui::PopStyleColor();
|
|
|
|
}
|
|
}
|
|
|
|
// Stop wrapping since we are done displaying console items.
|
|
ImGui::PopTextWrapPos();
|
|
|
|
// Auto-scroll logs.
|
|
if ((m_ScrollToBottom && (ImGui::GetScrollY() >= ImGui::GetScrollMaxY() || m_AutoScroll)))
|
|
ImGui::SetScrollHereY(1.0f);
|
|
m_ScrollToBottom = false;
|
|
|
|
// Loop through command string vector.
|
|
ImGui::EndChild();
|
|
}
|
|
}
|
|
|
|
void ImGuiConsole::InputBar()
|
|
{
|
|
// Variables.
|
|
ImGuiInputTextFlags inputTextFlags =
|
|
ImGuiInputTextFlags_CallbackHistory | ImGuiInputTextFlags_CallbackCharFilter | ImGuiInputTextFlags_CallbackCompletion |
|
|
ImGuiInputTextFlags_EnterReturnsTrue | ImGuiInputTextFlags_CallbackAlways;
|
|
|
|
// Only reclaim after enter key is pressed!
|
|
bool reclaimFocus = false;
|
|
|
|
// Input widget. (Width an always fixed width)
|
|
ImGui::PushItemWidth(-ImGui::GetStyle().ItemSpacing.x * 7);
|
|
if (ImGui::InputText("Input", &m_Buffer, inputTextFlags, InputCallback, this))
|
|
{
|
|
// Validate.
|
|
if (!m_Buffer.empty())
|
|
{
|
|
// Run command line input.
|
|
m_ConsoleSystem.RunCommand(m_Buffer);
|
|
|
|
// Scroll to bottom after its ran.
|
|
m_ScrollToBottom = true;
|
|
}
|
|
|
|
// Keep focus.
|
|
reclaimFocus = true;
|
|
|
|
// Clear command line.
|
|
m_Buffer.clear();
|
|
}
|
|
ImGui::PopItemWidth();
|
|
|
|
// Reset suggestions when client provides char input.
|
|
if (ImGui::IsItemEdited() && !m_WasPrevFrameTabCompletion)
|
|
{
|
|
m_CmdSuggestions.clear();
|
|
}
|
|
m_WasPrevFrameTabCompletion = false;
|
|
|
|
// Auto-focus on window apparition
|
|
ImGui::SetItemDefaultFocus();
|
|
if (reclaimFocus)
|
|
ImGui::SetKeyboardFocusHere(-1); // Focus on command line after clearing.
|
|
}
|
|
|
|
void ImGuiConsole::MenuBar()
|
|
{
|
|
if (ImGui::BeginMenuBar())
|
|
{
|
|
// Settings menu.
|
|
if (ImGui::BeginMenu("Settings"))
|
|
{
|
|
// Colored output
|
|
ImGui::Checkbox("Colored Output", &m_ColoredOutput);
|
|
ImGui::SameLine();
|
|
HelpMaker("Enable colored command output");
|
|
|
|
// Auto Scroll
|
|
ImGui::Checkbox("Auto Scroll", &m_AutoScroll);
|
|
ImGui::SameLine();
|
|
HelpMaker("Automatically scroll to bottom of console log");
|
|
|
|
// Filter bar
|
|
ImGui::Checkbox("Filter Bar", &m_FilterBar);
|
|
ImGui::SameLine();
|
|
HelpMaker("Enable console filter bar");
|
|
|
|
// Time stamp
|
|
ImGui::Checkbox("Time Stamps", &m_TimeStamps);
|
|
ImGui::SameLine();
|
|
HelpMaker("Display command execution timestamps");
|
|
|
|
// Reset to default settings
|
|
if (ImGui::Button("Reset settings", ImVec2(ImGui::GetColumnWidth(), 0)))
|
|
ImGui::OpenPopup("Reset Settings?");
|
|
|
|
// Confirmation
|
|
if (ImGui::BeginPopupModal("Reset Settings?", nullptr, ImGuiWindowFlags_AlwaysAutoResize))
|
|
{
|
|
ImGui::Text("All settings will be reset to default.\nThis operation cannot be undone!\n\n");
|
|
ImGui::Separator();
|
|
|
|
if (ImGui::Button("Reset", ImVec2(120, 0)))
|
|
{
|
|
DefaultSettings();
|
|
ImGui::CloseCurrentPopup();
|
|
}
|
|
|
|
ImGui::SetItemDefaultFocus();
|
|
ImGui::SameLine();
|
|
if (ImGui::Button("Cancel", ImVec2(120, 0)))
|
|
{
|
|
ImGui::CloseCurrentPopup();
|
|
}
|
|
ImGui::EndPopup();
|
|
}
|
|
|
|
ImGui::EndMenu();
|
|
}
|
|
|
|
// View settings.
|
|
if (ImGui::BeginMenu("Appearance"))
|
|
{
|
|
// Logging Colors
|
|
ImGuiColorEditFlags flags =
|
|
ImGuiColorEditFlags_Float | ImGuiColorEditFlags_AlphaPreview | ImGuiColorEditFlags_NoInputs | ImGuiColorEditFlags_AlphaBar;
|
|
|
|
ImGui::TextUnformatted("Color Palette");
|
|
ImGui::Indent();
|
|
ImGui::ColorEdit4("Command##", (float*)&m_ColorPalette[COL_COMMAND], flags);
|
|
ImGui::ColorEdit4("Log##", (float*)&m_ColorPalette[COL_LOG], flags);
|
|
ImGui::ColorEdit4("Warning##", (float*)&m_ColorPalette[COL_WARNING], flags);
|
|
ImGui::ColorEdit4("Error##", (float*)&m_ColorPalette[COL_ERROR], flags);
|
|
ImGui::ColorEdit4("Info##", (float*)&m_ColorPalette[COL_INFO], flags);
|
|
ImGui::ColorEdit4("Time Stamp##", (float*)&m_ColorPalette[COL_TIMESTAMP], flags);
|
|
ImGui::Unindent();
|
|
|
|
ImGui::Separator();
|
|
|
|
// Window transparency.
|
|
ImGui::TextUnformatted("Background");
|
|
ImGui::SliderFloat("Transparency##", &m_WindowAlpha, 0.1f, 1.f);
|
|
|
|
ImGui::EndMenu();
|
|
}
|
|
|
|
// All scripts.
|
|
if (ImGui::BeginMenu("Scripts"))
|
|
{
|
|
// Show registered scripts.
|
|
for (const auto& scr_pair : m_ConsoleSystem.Scripts())
|
|
{
|
|
if (ImGui::MenuItem(scr_pair.first.c_str()))
|
|
{
|
|
m_ConsoleSystem.RunScript(scr_pair.first);
|
|
m_ScrollToBottom = true;
|
|
}
|
|
}
|
|
|
|
// Reload scripts.
|
|
ImGui::Separator();
|
|
if (ImGui::Button("Reload Scripts", ImVec2(ImGui::GetColumnWidth(), 0)))
|
|
{
|
|
for (const auto& scr_pair : m_ConsoleSystem.Scripts())
|
|
{
|
|
scr_pair.second->Reload();
|
|
}
|
|
}
|
|
ImGui::EndMenu();
|
|
}
|
|
|
|
ImGui::EndMenuBar();
|
|
}
|
|
}
|
|
|
|
// From imgui_demo.cpp
|
|
void ImGuiConsole::HelpMaker(const char* desc)
|
|
{
|
|
ImGui::TextDisabled("(?)");
|
|
if (ImGui::IsItemHovered())
|
|
{
|
|
ImGui::BeginTooltip();
|
|
ImGui::PushTextWrapPos(ImGui::GetFontSize() * 35.0f);
|
|
ImGui::TextUnformatted(desc);
|
|
ImGui::PopTextWrapPos();
|
|
ImGui::EndTooltip();
|
|
}
|
|
}
|
|
|
|
int ImGuiConsole::InputCallback(ImGuiInputTextCallbackData* data)
|
|
{
|
|
|
|
// Exit if no buffer.
|
|
if (data->BufTextLen == 0 && (data->EventFlag != ImGuiInputTextFlags_CallbackHistory))
|
|
return 0;
|
|
|
|
// Get input string and console.
|
|
std::string input_str = data->Buf;
|
|
std::string trim_str;
|
|
auto console = static_cast<ImGuiConsole*>(data->UserData);
|
|
|
|
// Optimize by only using positions.
|
|
// Trim start and end spaces.
|
|
size_t startPos = console->m_Buffer.find_first_not_of(' ');
|
|
size_t endPos = console->m_Buffer.find_last_not_of(' ');
|
|
|
|
// Get trimmed string.
|
|
if (startPos != std::string::npos && endPos != std::string::npos)
|
|
trim_str = console->m_Buffer.substr(startPos, endPos + 1);
|
|
else
|
|
trim_str = console->m_Buffer;
|
|
|
|
switch (data->EventFlag)
|
|
{
|
|
case ImGuiInputTextFlags_CallbackCompletion:
|
|
{
|
|
// Find last word.
|
|
size_t startSubtrPos = trim_str.find_last_of(' ');
|
|
csys::AutoComplete* console_autocomplete;
|
|
|
|
// Command line is an entire word/string (No whitespace)
|
|
// Determine which autocomplete tree to use.
|
|
if (startSubtrPos == std::string::npos)
|
|
{
|
|
startSubtrPos = 0;
|
|
console_autocomplete = &console->m_ConsoleSystem.CmdAutocomplete();
|
|
} else
|
|
{
|
|
startSubtrPos += 1;
|
|
console_autocomplete = &console->m_ConsoleSystem.VarAutocomplete();
|
|
}
|
|
|
|
// Validate str
|
|
if (!trim_str.empty())
|
|
{
|
|
// Display suggestions on console.
|
|
if (!console->m_CmdSuggestions.empty())
|
|
{
|
|
console->m_ConsoleSystem.Log(csys::eCOMMAND) << "Suggestions: " << csys::endl;
|
|
|
|
for (const auto& suggestion : console->m_CmdSuggestions)
|
|
console->m_ConsoleSystem.Log(csys::eLOG) << suggestion << csys::endl;
|
|
|
|
console->m_CmdSuggestions.clear();
|
|
}
|
|
|
|
// Get partial completion and suggestions.
|
|
std::string partial = console_autocomplete->Suggestions(trim_str.substr(startSubtrPos, endPos + 1), console->m_CmdSuggestions);
|
|
|
|
// Autocomplete only when one work is available.
|
|
if (!console->m_CmdSuggestions.empty() && console->m_CmdSuggestions.size() == 1)
|
|
{
|
|
data->DeleteChars(static_cast<int>(startSubtrPos), static_cast<int>(data->BufTextLen - startSubtrPos));
|
|
data->InsertChars(static_cast<int>(startSubtrPos), console->m_CmdSuggestions[0].data());
|
|
console->m_CmdSuggestions.clear();
|
|
} else
|
|
{
|
|
// Partially complete word.
|
|
if (!partial.empty())
|
|
{
|
|
data->DeleteChars(static_cast<int>(startSubtrPos), static_cast<int>(data->BufTextLen - startSubtrPos));
|
|
data->InsertChars(static_cast<int>(startSubtrPos), partial.data());
|
|
}
|
|
}
|
|
}
|
|
|
|
// We have performed the completion event.
|
|
console->m_WasPrevFrameTabCompletion = true;
|
|
}
|
|
break;
|
|
|
|
case ImGuiInputTextFlags_CallbackHistory:
|
|
{
|
|
// Clear buffer.
|
|
data->DeleteChars(0, data->BufTextLen);
|
|
|
|
// Init history index
|
|
if (console->m_HistoryIndex == std::numeric_limits<size_t>::min())
|
|
console->m_HistoryIndex = console->m_ConsoleSystem.History().GetNewIndex();
|
|
|
|
// Traverse history.
|
|
if (data->EventKey == ImGuiKey_UpArrow)
|
|
{
|
|
if (console->m_HistoryIndex) --(console->m_HistoryIndex);
|
|
} else
|
|
{
|
|
if (console->m_HistoryIndex < console->m_ConsoleSystem.History().Size()) ++(console->m_HistoryIndex);
|
|
}
|
|
|
|
// Get history.
|
|
std::string prevCommand = console->m_ConsoleSystem.History()[console->m_HistoryIndex];
|
|
|
|
// Insert commands.
|
|
data->InsertChars(data->CursorPos, prevCommand.data());
|
|
}
|
|
break;
|
|
|
|
case ImGuiInputTextFlags_CallbackCharFilter:
|
|
case ImGuiInputTextFlags_CallbackAlways:
|
|
default:
|
|
break;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
void ImGuiConsole::SettingsHandler_ClearALl(ImGuiContext* ctx, ImGuiSettingsHandler* handler)
|
|
{
|
|
}
|
|
|
|
void ImGuiConsole::SettingsHandler_ReadInit(ImGuiContext* ctx, ImGuiSettingsHandler* handler)
|
|
{
|
|
}
|
|
|
|
void* ImGuiConsole::SettingsHandler_ReadOpen(ImGuiContext* ctx, ImGuiSettingsHandler* handler, const char* name)
|
|
{
|
|
if (!handler->UserData)
|
|
return nullptr;
|
|
|
|
auto console = static_cast<ImGuiConsole*>(handler->UserData);
|
|
|
|
if (strcmp(name, console->m_ConsoleName.c_str()) != 0)
|
|
return nullptr;
|
|
return (void*)1;
|
|
}
|
|
|
|
void ImGuiConsole::SettingsHandler_ReadLine(ImGuiContext* ctx, ImGuiSettingsHandler* handler, void* entry, const char* line)
|
|
{
|
|
if (!handler->UserData)
|
|
return;
|
|
|
|
// Get console.
|
|
auto console = static_cast<ImGuiConsole*>(handler->UserData);
|
|
|
|
// Ensure console doesn't reset variables.
|
|
console->m_LoadedFromIni = true;
|
|
|
|
// Disable warning regarding sscanf when using MVSC
|
|
#pragma warning( push )
|
|
#pragma warning( disable:4996 )
|
|
|
|
#define INI_CONSOLE_LOAD_COLOR(type) (std::sscanf(line, #type"=%i,%i,%i,%i", &r, &g, &b, &a) == 4) { console->m_ColorPalette[type] = ImColor(r, g, b, a); }
|
|
#define INI_CONSOLE_LOAD_FLOAT(var) (std::sscanf(line, #var"=%f", &f) == 1) { console->var = f; }
|
|
#define INI_CONSOLE_LOAD_BOOL(var) (std::sscanf(line, #var"=%i", &b) == 1) {console->var = b == 1;}
|
|
|
|
float f;
|
|
int r, g, b, a;
|
|
|
|
// Window style/visuals
|
|
if INI_CONSOLE_LOAD_COLOR(COL_COMMAND)
|
|
else if INI_CONSOLE_LOAD_COLOR(COL_LOG)
|
|
else if INI_CONSOLE_LOAD_COLOR(COL_WARNING)
|
|
else if INI_CONSOLE_LOAD_COLOR(COL_ERROR)
|
|
else if INI_CONSOLE_LOAD_COLOR(COL_INFO)
|
|
else if INI_CONSOLE_LOAD_COLOR(COL_TIMESTAMP)
|
|
else if INI_CONSOLE_LOAD_FLOAT(m_WindowAlpha)
|
|
|
|
// Window settings
|
|
else if INI_CONSOLE_LOAD_BOOL(m_AutoScroll)
|
|
else if INI_CONSOLE_LOAD_BOOL(m_ScrollToBottom)
|
|
else if INI_CONSOLE_LOAD_BOOL(m_ColoredOutput)
|
|
else if INI_CONSOLE_LOAD_BOOL(m_FilterBar)
|
|
else if INI_CONSOLE_LOAD_BOOL(m_TimeStamps)
|
|
|
|
#pragma warning( pop )
|
|
}
|
|
|
|
void ImGuiConsole::SettingsHandler_ApplyAll(ImGuiContext* ctx, ImGuiSettingsHandler* handler)
|
|
{
|
|
if (!handler->UserData)
|
|
return;
|
|
}
|
|
|
|
void ImGuiConsole::SettingsHandler_WriteAll(ImGuiContext* ctx, ImGuiSettingsHandler* handler, ImGuiTextBuffer* buf)
|
|
{
|
|
if (!handler->UserData)
|
|
return;
|
|
|
|
// Get console.
|
|
auto console = static_cast<ImGuiConsole*>(handler->UserData);
|
|
|
|
#define INI_CONSOLE_SAVE_COLOR(type) buf->appendf(#type"=%i,%i,%i,%i\n", (int)(console->m_ColorPalette[type].x * 255),\
|
|
(int)(console->m_ColorPalette[type].y * 255),\
|
|
(int)(console->m_ColorPalette[type].z * 255),\
|
|
(int)(console->m_ColorPalette[type].w * 255))
|
|
|
|
#define INI_CONSOLE_SAVE_FLOAT(var) buf->appendf(#var"=%.3f\n", console->var)
|
|
#define INI_CONSOLE_SAVE_BOOL(var) buf->appendf(#var"=%i\n", console->var)
|
|
|
|
// Set header for CONSOLE Console
|
|
buf->appendf("[%s][%s]\n", handler->TypeName, console->m_ConsoleName.data());
|
|
|
|
// Window settings.
|
|
INI_CONSOLE_SAVE_BOOL(m_AutoScroll);
|
|
INI_CONSOLE_SAVE_BOOL(m_ScrollToBottom);
|
|
INI_CONSOLE_SAVE_BOOL(m_ColoredOutput);
|
|
INI_CONSOLE_SAVE_BOOL(m_FilterBar);
|
|
INI_CONSOLE_SAVE_BOOL(m_TimeStamps);
|
|
|
|
// Window style/visuals
|
|
INI_CONSOLE_SAVE_FLOAT(m_WindowAlpha);
|
|
INI_CONSOLE_SAVE_COLOR(COL_COMMAND);
|
|
INI_CONSOLE_SAVE_COLOR(COL_LOG);
|
|
INI_CONSOLE_SAVE_COLOR(COL_WARNING);
|
|
INI_CONSOLE_SAVE_COLOR(COL_ERROR);
|
|
INI_CONSOLE_SAVE_COLOR(COL_INFO);
|
|
INI_CONSOLE_SAVE_COLOR(COL_TIMESTAMP);
|
|
|
|
// End saving.
|
|
buf->append("\n");
|
|
}
|