mirror of
https://github.com/WerWolv/ImHex.git
synced 2026-04-02 21:47:40 -05:00
Huge refactoring of builtin features into an external plugin
This commit is contained in:
@@ -2,35 +2,12 @@
|
||||
|
||||
#include <GLFW/glfw3.h>
|
||||
|
||||
#include "helpers/math_evaluator.hpp"
|
||||
|
||||
namespace hex {
|
||||
|
||||
ViewCommandPalette::ViewCommandPalette() : View("Command Palette") {
|
||||
this->getWindowOpenState() = true;
|
||||
|
||||
this->m_commandBuffer.resize(1024, 0x00);
|
||||
|
||||
ContentRegistry::CommandPaletteCommands::add(
|
||||
ContentRegistry::CommandPaletteCommands::Type::SymbolCommand,
|
||||
"#", "Calculator",
|
||||
[](auto input) {
|
||||
MathEvaluator evaluator;
|
||||
evaluator.registerStandardVariables();
|
||||
evaluator.registerStandardFunctions();
|
||||
|
||||
std::optional<long double> result;
|
||||
|
||||
try {
|
||||
result = evaluator.evaluate(input);
|
||||
} catch (std::runtime_error &e) {}
|
||||
|
||||
if (result.has_value())
|
||||
return hex::format("#%s = %Lf", input.data(), result.value());
|
||||
else
|
||||
return hex::format("#%s = ???", input.data());
|
||||
});
|
||||
|
||||
this->m_lastResults = this->getCommandResults("");
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#include "views/view_data_inspector.hpp"
|
||||
|
||||
#include <hex/providers/provider.hpp>
|
||||
#include <hex/helpers/utils.hpp>
|
||||
|
||||
#include <cstring>
|
||||
|
||||
@@ -32,170 +31,6 @@ namespace hex {
|
||||
|
||||
this->m_shouldInvalidate = true;
|
||||
});
|
||||
|
||||
|
||||
ContentRegistry::DataInspector::add("Binary (8 bit)", sizeof(u8), [](auto buffer, auto endian, auto style) {
|
||||
std::string binary;
|
||||
for (u8 i = 0; i < 8; i++)
|
||||
binary += ((buffer[0] << i) & 0x80) == 0 ? '0' : '1';
|
||||
|
||||
return [binary] { ImGui::TextUnformatted(binary.c_str()); };
|
||||
});
|
||||
|
||||
ContentRegistry::DataInspector::add("uint8_t", sizeof(u8), [](auto buffer, auto endian, auto style) {
|
||||
auto format = (style == NumberDisplayStyle::Decimal) ? "%u" : ((style == NumberDisplayStyle::Hexadecimal) ? "0x%X" : "0o%o");
|
||||
auto value = hex::format(format, *reinterpret_cast<u8*>(buffer.data()));
|
||||
return [value] { ImGui::TextUnformatted(value.c_str()); };
|
||||
});
|
||||
|
||||
ContentRegistry::DataInspector::add("int8_t", sizeof(s8), [](auto buffer, auto endian, auto style) {
|
||||
auto format = (style == NumberDisplayStyle::Decimal) ? "%d" : ((style == NumberDisplayStyle::Hexadecimal) ? "0x%X" : "0o%o");
|
||||
auto value = hex::format(format, *reinterpret_cast<s8*>(buffer.data()));
|
||||
return [value] { ImGui::TextUnformatted(value.c_str()); };
|
||||
});
|
||||
|
||||
ContentRegistry::DataInspector::add("uint16_t", sizeof(u16), [](auto buffer, auto endian, auto style) {
|
||||
auto format = (style == NumberDisplayStyle::Decimal) ? "%u" : ((style == NumberDisplayStyle::Hexadecimal) ? "0x%X" : "0o%o");
|
||||
auto value = hex::format(format, hex::changeEndianess(*reinterpret_cast<u16*>(buffer.data()), endian));
|
||||
return [value] { ImGui::TextUnformatted(value.c_str()); };
|
||||
});
|
||||
|
||||
ContentRegistry::DataInspector::add("int16_t", sizeof(s16), [](auto buffer, auto endian, auto style) {
|
||||
auto format = (style == NumberDisplayStyle::Decimal) ? "%d" : ((style == NumberDisplayStyle::Hexadecimal) ? "0x%X" : "0o%o");
|
||||
auto value = hex::format(format, hex::changeEndianess(*reinterpret_cast<s16*>(buffer.data()), endian));
|
||||
return [value] { ImGui::TextUnformatted(value.c_str()); };
|
||||
});
|
||||
|
||||
ContentRegistry::DataInspector::add("uint32_t", sizeof(u32), [](auto buffer, auto endian, auto style) {
|
||||
auto format = (style == NumberDisplayStyle::Decimal) ? "%u" : ((style == NumberDisplayStyle::Hexadecimal) ? "0x%X" : "0o%o");
|
||||
auto value = hex::format(format, hex::changeEndianess(*reinterpret_cast<u32*>(buffer.data()), endian));
|
||||
return [value] { ImGui::TextUnformatted(value.c_str()); };
|
||||
});
|
||||
|
||||
ContentRegistry::DataInspector::add("int32_t", sizeof(s32), [](auto buffer, auto endian, auto style) {
|
||||
auto format = (style == NumberDisplayStyle::Decimal) ? "%d" : ((style == NumberDisplayStyle::Hexadecimal) ? "0x%X" : "0o%o");
|
||||
auto value = hex::format(format, hex::changeEndianess(*reinterpret_cast<s32*>(buffer.data()), endian));
|
||||
return [value] { ImGui::TextUnformatted(value.c_str()); };
|
||||
});
|
||||
|
||||
ContentRegistry::DataInspector::add("uint64_t", sizeof(u64), [](auto buffer, auto endian, auto style) {
|
||||
auto format = (style == NumberDisplayStyle::Decimal) ? "%lu" : ((style == NumberDisplayStyle::Hexadecimal) ? "0x%lX" : "0o%lo");
|
||||
auto value = hex::format(format, hex::changeEndianess(*reinterpret_cast<u64*>(buffer.data()), endian));
|
||||
return [value] { ImGui::TextUnformatted(value.c_str()); };
|
||||
});
|
||||
|
||||
ContentRegistry::DataInspector::add("int64_t", sizeof(s64), [](auto buffer, auto endian, auto style) {
|
||||
auto format = (style == NumberDisplayStyle::Decimal) ? "%ld" : ((style == NumberDisplayStyle::Hexadecimal) ? "0x%lX" : "0o%lo");
|
||||
auto value = hex::format(format, hex::changeEndianess(*reinterpret_cast<s64*>(buffer.data()), endian));
|
||||
return [value] { ImGui::TextUnformatted(value.c_str()); };
|
||||
});
|
||||
|
||||
ContentRegistry::DataInspector::add("float (32 bit)", sizeof(float), [](auto buffer, auto endian, auto style) {
|
||||
auto value = hex::format("%e", hex::changeEndianess(*reinterpret_cast<float*>(buffer.data()), endian));
|
||||
return [value] { ImGui::TextUnformatted(value.c_str()); };
|
||||
});
|
||||
|
||||
ContentRegistry::DataInspector::add("double (64 bit)", sizeof(double), [](auto buffer, auto endian, auto style) {
|
||||
auto value = hex::format("%e", hex::changeEndianess(*reinterpret_cast<double*>(buffer.data()), endian));
|
||||
return [value] { ImGui::TextUnformatted(value.c_str()); };
|
||||
});
|
||||
|
||||
ContentRegistry::DataInspector::add("ASCII Character", sizeof(char8_t), [](auto buffer, auto endian, auto style) {
|
||||
auto value = hex::format("'%s'", makePrintable(*reinterpret_cast<char8_t*>(buffer.data())).c_str());
|
||||
return [value] { ImGui::TextUnformatted(value.c_str()); };
|
||||
});
|
||||
|
||||
ContentRegistry::DataInspector::add("Wide Character", sizeof(char16_t), [](auto buffer, auto endian, auto style) {
|
||||
auto c = *reinterpret_cast<char16_t*>(buffer.data());
|
||||
auto value = hex::format("'%lc'", c == 0 ? '\x01' : hex::changeEndianess(c, endian));
|
||||
return [value] { ImGui::TextUnformatted(value.c_str()); };
|
||||
});
|
||||
|
||||
ContentRegistry::DataInspector::add("UTF-8 code point", sizeof(char8_t) * 4, [](auto buffer, auto endian, auto style) {
|
||||
char utf8Buffer[5] = { 0 };
|
||||
char codepointString[5] = { 0 };
|
||||
u32 codepoint = 0;
|
||||
|
||||
std::memcpy(utf8Buffer, reinterpret_cast<char8_t*>(buffer.data()), 4);
|
||||
u8 codepointSize = ImTextCharFromUtf8(&codepoint, utf8Buffer, utf8Buffer + 4);
|
||||
|
||||
std::memcpy(codepointString, &codepoint, std::min(codepointSize, u8(4)));
|
||||
auto value = hex::format("'%s' (U+%04lx)", codepoint == 0xFFFD ? "Invalid" :
|
||||
codepoint < 0xFF ? makePrintable(codepoint).c_str() :
|
||||
codepointString,
|
||||
codepoint);
|
||||
|
||||
return [value] { ImGui::TextUnformatted(value.c_str()); };
|
||||
});
|
||||
|
||||
#if defined(OS_WINDOWS) && defined(ARCH_64_BIT)
|
||||
|
||||
ContentRegistry::DataInspector::add("__time32_t", sizeof(__time32_t), [](auto buffer, auto endian, auto style) {
|
||||
auto endianAdjustedTime = hex::changeEndianess(*reinterpret_cast<__time32_t*>(buffer.data()), endian);
|
||||
std::tm * ptm = _localtime32(&endianAdjustedTime);
|
||||
char timeBuffer[32];
|
||||
std::string value;
|
||||
if (ptm != nullptr && std::strftime(timeBuffer, 32, "%a, %d.%m.%Y %H:%M:%S", ptm))
|
||||
value = timeBuffer;
|
||||
else
|
||||
value = "Invalid";
|
||||
|
||||
return [value] { ImGui::TextUnformatted(value.c_str()); };
|
||||
});
|
||||
|
||||
ContentRegistry::DataInspector::add("__time64_t", sizeof(__time64_t), [](auto buffer, auto endian, auto style) {
|
||||
auto endianAdjustedTime = hex::changeEndianess(*reinterpret_cast<__time64_t*>(buffer.data()), endian);
|
||||
std::tm * ptm = _localtime64(&endianAdjustedTime);
|
||||
char timeBuffer[64];
|
||||
std::string value;
|
||||
if (ptm != nullptr && std::strftime(timeBuffer, 64, "%a, %d.%m.%Y %H:%M:%S", ptm))
|
||||
value = timeBuffer;
|
||||
else
|
||||
value = "Invalid";
|
||||
|
||||
return [value] { ImGui::TextUnformatted(value.c_str()); };
|
||||
});
|
||||
|
||||
#else
|
||||
|
||||
ContentRegistry::DataInspector::add("time_t", sizeof(time_t), [](auto buffer, auto endian, auto style) {
|
||||
auto endianAdjustedTime = hex::changeEndianess(*reinterpret_cast<time_t*>(buffer.data()), endian);
|
||||
std::tm * ptm = localtime(&endianAdjustedTime);
|
||||
char timeBuffer[64];
|
||||
std::string value;
|
||||
if (ptm != nullptr && std::strftime(timeBuffer, 64, "%a, %d.%m.%Y %H:%M:%S", ptm))
|
||||
value = timeBuffer;
|
||||
else
|
||||
value = "Invalid";
|
||||
|
||||
return [value] { ImGui::TextUnformatted(value.c_str()); };
|
||||
});
|
||||
|
||||
#endif
|
||||
|
||||
ContentRegistry::DataInspector::add("GUID", sizeof(GUID), [](auto buffer, auto endian, auto style) {
|
||||
GUID guid;
|
||||
std::memcpy(&guid, buffer.data(), sizeof(GUID));
|
||||
auto value = hex::format("%s{%08lX-%04hX-%04hX-%02hhX%02hhX-%02hhX%02hhX%02hhX%02hhX%02hhX%02hhX}",
|
||||
(hex::changeEndianess(guid.data3, endian) >> 12) <= 5 && ((guid.data4[0] >> 4) >= 8 || (guid.data4[0] >> 4) == 0) ? "" : "Invalid ",
|
||||
hex::changeEndianess(guid.data1, endian),
|
||||
hex::changeEndianess(guid.data2, endian),
|
||||
hex::changeEndianess(guid.data3, endian),
|
||||
guid.data4[0], guid.data4[1], guid.data4[2], guid.data4[3],
|
||||
guid.data4[4], guid.data4[5], guid.data4[6], guid.data4[7]);
|
||||
|
||||
return [value] { ImGui::TextUnformatted(value.c_str()); };
|
||||
});
|
||||
|
||||
ContentRegistry::DataInspector::add("RGBA Color", sizeof(u32), [](auto buffer, auto endian, auto style) {
|
||||
ImColor value(hex::changeEndianess(*reinterpret_cast<u32*>(buffer.data()), endian));
|
||||
|
||||
return [value] {
|
||||
ImGui::ColorButton("##inspectorColor", value,
|
||||
ImGuiColorEditFlags_None,
|
||||
ImVec2(ImGui::GetColumnWidth(), ImGui::GetTextLineHeight()));
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
ViewDataInspector::~ViewDataInspector() {
|
||||
|
||||
@@ -235,7 +235,7 @@ namespace hex {
|
||||
}
|
||||
ImGui::EndChild();
|
||||
|
||||
ImGui::SetCursorPosX((ImGui::GetContentRegionAvailWidth() - 300) / 2);
|
||||
ImGui::SetCursorPosX((ImGui::GetContentRegionAvail().x - 300) / 2);
|
||||
if (ImGui::Button("Disassemble", ImVec2(300, 20)))
|
||||
this->m_shouldInvalidate = true;
|
||||
ImGui::NewLine();
|
||||
|
||||
@@ -1,13 +1,8 @@
|
||||
#include "views/view_pattern.hpp"
|
||||
|
||||
#include <hex/lang/preprocessor.hpp>
|
||||
#include <hex/lang/parser.hpp>
|
||||
#include <hex/lang/lexer.hpp>
|
||||
#include <hex/lang/validator.hpp>
|
||||
#include <hex/lang/evaluator.hpp>
|
||||
|
||||
#include "helpers/project_file_handler.hpp"
|
||||
#include <hex/helpers/utils.hpp>
|
||||
#include <hex/lang/preprocessor.hpp>
|
||||
|
||||
#include <magic.h>
|
||||
|
||||
@@ -47,8 +42,12 @@ namespace hex {
|
||||
outEnd = inEnd;
|
||||
paletteIndex = TextEditor::PaletteIndex::Default;
|
||||
}
|
||||
else if (TokenizeCStyleIdentifier(inBegin, inEnd, outBegin, outEnd))
|
||||
paletteIndex = TextEditor::PaletteIndex::Identifier;
|
||||
else if (TokenizeCStyleIdentifier(inBegin, inEnd, outBegin, outEnd)) {
|
||||
if (SharedData::patternLanguageFunctions.contains(std::string(outBegin, outEnd - outBegin)))
|
||||
paletteIndex = TextEditor::PaletteIndex::LineNumber;
|
||||
else
|
||||
paletteIndex = TextEditor::PaletteIndex::Identifier;
|
||||
}
|
||||
else if (TokenizeCStyleNumber(inBegin, inEnd, outBegin, outEnd))
|
||||
paletteIndex = TextEditor::PaletteIndex::Number;
|
||||
else if (TokenizeCStyleCharacterLiteral(inBegin, inEnd, outBegin, outEnd))
|
||||
@@ -76,6 +75,7 @@ namespace hex {
|
||||
|
||||
|
||||
ViewPattern::ViewPattern(std::vector<lang::PatternData*> &patternData) : View("Pattern"), m_patternData(patternData) {
|
||||
this->m_patternLanguageRuntime = new lang::PatternLanguage(SharedData::currentProvider);
|
||||
|
||||
this->m_textEditor.SetLanguageDefinition(PatternLanguage());
|
||||
this->m_textEditor.SetShowWhitespaces(false);
|
||||
@@ -335,62 +335,15 @@ namespace hex {
|
||||
this->m_console.clear();
|
||||
this->postEvent(Events::PatternChanged);
|
||||
|
||||
hex::lang::Preprocessor preprocessor;
|
||||
std::endian defaultDataEndianess = std::endian::native;
|
||||
auto result = this->m_patternLanguageRuntime->executeString(buffer);
|
||||
|
||||
preprocessor.addPragmaHandler("endian", [&defaultDataEndianess](std::string value) {
|
||||
if (value == "big") {
|
||||
defaultDataEndianess = std::endian::big;
|
||||
return true;
|
||||
} else if (value == "little") {
|
||||
defaultDataEndianess = std::endian::little;
|
||||
return true;
|
||||
} else if (value == "native") {
|
||||
defaultDataEndianess = std::endian::native;
|
||||
return true;
|
||||
} else
|
||||
return false;
|
||||
});
|
||||
preprocessor.addDefaultPragmaHandlers();
|
||||
|
||||
auto preprocessedCode = preprocessor.preprocess(buffer);
|
||||
if (!preprocessedCode.has_value()) {
|
||||
this->m_textEditor.SetErrorMarkers({ preprocessor.getError() });
|
||||
return;
|
||||
if (!result.has_value()) {
|
||||
this->m_textEditor.SetErrorMarkers({ this->m_patternLanguageRuntime->getError().value() });
|
||||
}
|
||||
|
||||
hex::lang::Lexer lexer;
|
||||
auto tokens = lexer.lex(preprocessedCode.value());
|
||||
if (!tokens.has_value()) {
|
||||
this->m_textEditor.SetErrorMarkers({ lexer.getError() });
|
||||
return;
|
||||
}
|
||||
this->m_console = this->m_patternLanguageRuntime->getConsoleLog();
|
||||
|
||||
hex::lang::Parser parser;
|
||||
auto ast = parser.parse(tokens.value());
|
||||
if (!ast.has_value()) {
|
||||
this->m_textEditor.SetErrorMarkers({ parser.getError() });
|
||||
return;
|
||||
}
|
||||
|
||||
SCOPE_EXIT( for(auto &node : ast.value()) delete node; );
|
||||
|
||||
hex::lang::Validator validator;
|
||||
auto validatorResult = validator.validate(ast.value());
|
||||
if (!validatorResult) {
|
||||
this->m_textEditor.SetErrorMarkers({ validator.getError() });
|
||||
return;
|
||||
}
|
||||
|
||||
auto provider = SharedData::currentProvider;
|
||||
hex::lang::Evaluator evaluator(provider, defaultDataEndianess);
|
||||
|
||||
auto patternData = evaluator.evaluate(ast.value());
|
||||
this->m_console = evaluator.getConsole().getLog();
|
||||
if (!patternData.has_value())
|
||||
return;
|
||||
|
||||
this->m_patternData = patternData.value();
|
||||
this->m_patternData = result.value();
|
||||
View::postEvent(Events::PatternChanged);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,302 +1,12 @@
|
||||
#include "views/view_tools.hpp"
|
||||
|
||||
#include <cstring>
|
||||
#include <regex>
|
||||
#include <optional>
|
||||
|
||||
#include <hex/providers/provider.hpp>
|
||||
#include <hex/helpers/utils.hpp>
|
||||
|
||||
#include "helpers/plugin_handler.hpp"
|
||||
|
||||
#include <llvm/Demangle/Demangle.h>
|
||||
|
||||
namespace hex {
|
||||
|
||||
ViewTools::ViewTools() : View("Tools") {
|
||||
this->m_mangledBuffer = new char[0xF'FFFF];
|
||||
std::memset(this->m_mangledBuffer, 0x00, 0xF'FFFF);
|
||||
ViewTools::ViewTools() : View("Tools") { }
|
||||
|
||||
this->m_regexInput = new char[0xF'FFFF];
|
||||
this->m_regexPattern = new char[0xF'FFFF];
|
||||
this->m_replacePattern = new char[0xF'FFFF];
|
||||
std::memset(this->m_regexInput, 0x00, 0xF'FFFF);
|
||||
std::memset(this->m_regexPattern, 0x00, 0xF'FFFF);
|
||||
std::memset(this->m_replacePattern, 0x00, 0xF'FFFF);
|
||||
|
||||
|
||||
this->m_mathInput = new char[0xFFFF];
|
||||
std::memset(this->m_mathInput, 0x00, 0xFFFF);
|
||||
this->m_mathEvaluator.registerStandardVariables();
|
||||
this->m_mathEvaluator.registerStandardFunctions();
|
||||
|
||||
this->m_mathEvaluator.setFunction("clear", [this](auto args) -> std::optional<long double> {
|
||||
this->m_mathHistory.clear();
|
||||
this->m_lastMathError.clear();
|
||||
this->m_mathEvaluator.getVariables().clear();
|
||||
this->m_mathEvaluator.registerStandardVariables();
|
||||
std::memset(this->m_mathInput, 0x00, 0xFFFF);
|
||||
|
||||
return { };
|
||||
}, 0, 0);
|
||||
|
||||
this->m_mathEvaluator.setFunction("read", [this](auto args) -> std::optional<long double> {
|
||||
u8 value = 0;
|
||||
|
||||
auto provider = SharedData::currentProvider;
|
||||
if (provider == nullptr || !provider->isReadable() || args[0] >= provider->getActualSize())
|
||||
return { };
|
||||
|
||||
provider->read(args[0], &value, sizeof(u8));
|
||||
|
||||
return value;
|
||||
}, 1, 1);
|
||||
|
||||
this->m_mathEvaluator.setFunction("write", [this](auto args) -> std::optional<long double> {
|
||||
auto provider = SharedData::currentProvider;
|
||||
if (provider == nullptr || !provider->isWritable() || args[0] >= provider->getActualSize())
|
||||
return { };
|
||||
|
||||
if (args[1] > 0xFF)
|
||||
return { };
|
||||
|
||||
u8 value = args[1];
|
||||
provider->write(args[0], &value, sizeof(u8));
|
||||
|
||||
return { };
|
||||
}, 2, 2);
|
||||
|
||||
ContentRegistry::Tools::add("Itanium/MSVC demangler", [this]{ this->drawDemangler(); });
|
||||
ContentRegistry::Tools::add("ASCII table", [this]{ this->drawASCIITable(); });
|
||||
ContentRegistry::Tools::add("Regex replacer", [this]{ this->drawRegexReplacer(); });
|
||||
ContentRegistry::Tools::add("Color picker", [this]{ this->drawColorPicker(); });
|
||||
ContentRegistry::Tools::add("Calculator", [this]{ this->drawMathEvaluator(); });
|
||||
}
|
||||
|
||||
ViewTools::~ViewTools() {
|
||||
delete[] this->m_mangledBuffer;
|
||||
|
||||
delete[] this->m_regexInput;
|
||||
delete[] this->m_regexPattern;
|
||||
delete[] this->m_replacePattern;
|
||||
|
||||
delete[] this->m_mathInput;
|
||||
}
|
||||
|
||||
void ViewTools::drawDemangler() {
|
||||
if (ImGui::InputText("Mangled name", this->m_mangledBuffer, 0xF'FFFF)) {
|
||||
this->m_demangledName = llvm::demangle(this->m_mangledBuffer);
|
||||
}
|
||||
|
||||
ImGui::InputText("Demangled name", this->m_demangledName.data(), this->m_demangledName.size(), ImGuiInputTextFlags_ReadOnly);
|
||||
ImGui::NewLine();
|
||||
}
|
||||
|
||||
void ViewTools::drawASCIITable() {
|
||||
ImGui::BeginTable("##asciitable", 4);
|
||||
ImGui::TableSetupColumn("");
|
||||
ImGui::TableSetupColumn("");
|
||||
ImGui::TableSetupColumn("");
|
||||
ImGui::TableSetupColumn("");
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
|
||||
for (u8 tablePart = 0; tablePart < 4; tablePart++) {
|
||||
ImGui::BeginTable("##asciitablepart", this->m_asciiTableShowOctal ? 4 : 3, ImGuiTableFlags_BordersInnerV | ImGuiTableFlags_BordersOuter | ImGuiTableFlags_RowBg);
|
||||
ImGui::TableSetupColumn("dec");
|
||||
if (this->m_asciiTableShowOctal)
|
||||
ImGui::TableSetupColumn("oct");
|
||||
ImGui::TableSetupColumn("hex");
|
||||
ImGui::TableSetupColumn("char");
|
||||
|
||||
ImGui::TableHeadersRow();
|
||||
|
||||
u32 rowCount = 0;
|
||||
for (u8 i = 0; i < 0x80 / 4; i++) {
|
||||
ImGui::TableNextRow(ImGuiTableRowFlags_Headers);
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("%02d", i + 32 * tablePart);
|
||||
|
||||
if (this->m_asciiTableShowOctal) {
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("0o%02o", i + 32 * tablePart);
|
||||
}
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("0x%02x", i + 32 * tablePart);
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("%s", makePrintable(i + 32 * tablePart).c_str());
|
||||
|
||||
ImGui::TableSetBgColor(ImGuiTableBgTarget_RowBg0, ((rowCount % 2) == 0) ? 0xFF101010 : 0xFF303030);
|
||||
|
||||
rowCount++;
|
||||
}
|
||||
|
||||
ImGui::EndTable();
|
||||
ImGui::TableNextColumn();
|
||||
}
|
||||
ImGui::EndTable();
|
||||
|
||||
ImGui::Checkbox("Show octal", &this->m_asciiTableShowOctal);
|
||||
ImGui::NewLine();
|
||||
}
|
||||
|
||||
void ViewTools::drawRegexReplacer() {
|
||||
bool shouldInvalidate;
|
||||
|
||||
shouldInvalidate = ImGui::InputText("Regex pattern", this->m_regexPattern, 0xF'FFFF);
|
||||
shouldInvalidate = ImGui::InputText("Replace pattern", this->m_replacePattern, 0xF'FFFF) || shouldInvalidate;
|
||||
shouldInvalidate = ImGui::InputTextMultiline("Input", this->m_regexInput, 0xF'FFFF) || shouldInvalidate;
|
||||
|
||||
if (shouldInvalidate) {
|
||||
try {
|
||||
this->m_regexOutput = std::regex_replace(this->m_regexInput, std::regex(this->m_regexPattern), this->m_replacePattern);
|
||||
} catch (std::regex_error&) {}
|
||||
}
|
||||
|
||||
ImGui::InputTextMultiline("Output", this->m_regexOutput.data(), this->m_regexOutput.size(), ImVec2(0, 0), ImGuiInputTextFlags_ReadOnly);
|
||||
ImGui::NewLine();
|
||||
}
|
||||
|
||||
void ViewTools::drawColorPicker() {
|
||||
ImGui::SetNextItemWidth(300.0F);
|
||||
ImGui::ColorPicker4("Color Picker", this->m_pickedColor.data(),
|
||||
ImGuiColorEditFlags_Uint8 | ImGuiColorEditFlags_AlphaBar | ImGuiColorEditFlags_DisplayRGB | ImGuiColorEditFlags_DisplayHex);
|
||||
ImGui::NewLine();
|
||||
}
|
||||
|
||||
void ViewTools::drawMathEvaluator() {
|
||||
if (ImGui::InputText("Input", this->m_mathInput, 0xFFFF, ImGuiInputTextFlags_EnterReturnsTrue | ImGuiInputTextFlags_AutoSelectAll)) {
|
||||
ImGui::SetKeyboardFocusHere();
|
||||
std::optional<long double> result;
|
||||
|
||||
try {
|
||||
result = this->m_mathEvaluator.evaluate(this->m_mathInput);
|
||||
} catch (std::invalid_argument &e) {
|
||||
this->m_lastMathError = e.what();
|
||||
}
|
||||
|
||||
if (result.has_value()) {
|
||||
this->m_mathHistory.push_back(result.value());
|
||||
std::memset(this->m_mathInput, 0x00, 0xFFFF);
|
||||
this->m_lastMathError.clear();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (!this->m_lastMathError.empty())
|
||||
ImGui::TextColored(ImColor(0xA00040FF), "Last Error: %s", this->m_lastMathError.c_str());
|
||||
else
|
||||
ImGui::NewLine();
|
||||
|
||||
enum class MathDisplayType { Standard, Scientific, Engineering, Programmer } mathDisplayType;
|
||||
if (ImGui::BeginTabBar("##mathFormatTabBar")) {
|
||||
if (ImGui::BeginTabItem("Standard")) {
|
||||
mathDisplayType = MathDisplayType::Standard;
|
||||
ImGui::EndTabItem();
|
||||
}
|
||||
if (ImGui::BeginTabItem("Scientific")) {
|
||||
mathDisplayType = MathDisplayType::Scientific;
|
||||
ImGui::EndTabItem();
|
||||
}
|
||||
if (ImGui::BeginTabItem("Engineering")) {
|
||||
mathDisplayType = MathDisplayType::Engineering;
|
||||
ImGui::EndTabItem();
|
||||
}
|
||||
if (ImGui::BeginTabItem("Programmer")) {
|
||||
mathDisplayType = MathDisplayType::Programmer;
|
||||
ImGui::EndTabItem();
|
||||
}
|
||||
|
||||
ImGui::EndTabBar();
|
||||
}
|
||||
|
||||
if (ImGui::BeginTable("##mathWrapper", 2)) {
|
||||
ImGui::TableSetupColumn("##results");
|
||||
ImGui::TableSetupColumn("##variables", ImGuiTableColumnFlags_WidthStretch, 0.7);
|
||||
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
if (ImGui::BeginTable("##mathHistory", 1, ImGuiTableFlags_ScrollY | ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg, ImVec2(0, 400))) {
|
||||
ImGui::TableSetupScrollFreeze(0, 1);
|
||||
ImGui::TableSetupColumn("History");
|
||||
|
||||
ImGuiListClipper clipper;
|
||||
clipper.Begin(this->m_mathHistory.size());
|
||||
|
||||
ImGui::TableHeadersRow();
|
||||
while (clipper.Step()) {
|
||||
for (u64 i = clipper.DisplayStart; i < clipper.DisplayEnd; i++) {
|
||||
if (i == 0)
|
||||
ImGui::PushStyleColor(ImGuiCol_Text, ImU32(ImColor(0xA5, 0x45, 0x45)));
|
||||
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
|
||||
switch (mathDisplayType) {
|
||||
case MathDisplayType::Standard:
|
||||
ImGui::Text("%.3Lf", this->m_mathHistory[(this->m_mathHistory.size() - 1) - i]);
|
||||
break;
|
||||
case MathDisplayType::Scientific:
|
||||
ImGui::Text("%.6Le", this->m_mathHistory[(this->m_mathHistory.size() - 1) - i]);
|
||||
break;
|
||||
case MathDisplayType::Engineering:
|
||||
ImGui::Text("%s", hex::toEngineeringString(this->m_mathHistory[(this->m_mathHistory.size() - 1) - i]).c_str());
|
||||
break;
|
||||
case MathDisplayType::Programmer:
|
||||
ImGui::Text("0x%llX (%llu)",
|
||||
u64(this->m_mathHistory[(this->m_mathHistory.size() - 1) - i]),
|
||||
u64(this->m_mathHistory[(this->m_mathHistory.size() - 1) - i]));
|
||||
break;
|
||||
}
|
||||
|
||||
if (i == 0)
|
||||
ImGui::PopStyleColor();
|
||||
}
|
||||
}
|
||||
|
||||
clipper.End();
|
||||
|
||||
ImGui::EndTable();
|
||||
}
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
if (ImGui::BeginTable("##mathVariables", 2, ImGuiTableFlags_ScrollY | ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg, ImVec2(0, 400))) {
|
||||
ImGui::TableSetupScrollFreeze(0, 1);
|
||||
ImGui::TableSetupColumn("Name");
|
||||
ImGui::TableSetupColumn("Value");
|
||||
|
||||
ImGui::TableHeadersRow();
|
||||
for (const auto &[name, value] : this->m_mathEvaluator.getVariables()) {
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::TextUnformatted(name.c_str());
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
switch (mathDisplayType) {
|
||||
case MathDisplayType::Standard:
|
||||
ImGui::Text("%.3Lf", value);
|
||||
break;
|
||||
case MathDisplayType::Scientific:
|
||||
ImGui::Text("%.6Le", value);
|
||||
break;
|
||||
case MathDisplayType::Engineering:
|
||||
ImGui::Text("%s", hex::toEngineeringString(value).c_str());
|
||||
break;
|
||||
case MathDisplayType::Programmer:
|
||||
ImGui::Text("0x%llX (%llu)", u64(value), u64(value));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::EndTable();
|
||||
}
|
||||
|
||||
ImGui::EndTable();
|
||||
}
|
||||
}
|
||||
ViewTools::~ViewTools() { }
|
||||
|
||||
void ViewTools::drawContent() {
|
||||
if (ImGui::Begin("Tools", &this->getWindowOpenState(), ImGuiWindowFlags_NoCollapse)) {
|
||||
|
||||
Reference in New Issue
Block a user