Made tools registry more in-line with the other APIs

This commit is contained in:
WerWolv 2021-01-13 13:18:03 +01:00
parent 95437b2afe
commit 0e32dd667d
5 changed files with 175 additions and 182 deletions

View File

@ -110,9 +110,14 @@ namespace hex {
struct Tools { struct Tools {
Tools() = delete; Tools() = delete;
static void add(const std::function<void()> &function); struct Entry {
std::string name;
std::function<void()> function;
};
static std::vector<std::function<void()>>& getEntries(); static void add(std::string_view name, const std::function<void()> &function);
static std::vector<Entry>& getEntries();
}; };
/* Data Inspector Registry. Allows adding of new types to the data inspector */ /* Data Inspector Registry. Allows adding of new types to the data inspector */

View File

@ -51,7 +51,7 @@ namespace hex {
static std::vector<ContentRegistry::CommandPaletteCommands::Entry> commandPaletteCommands; static std::vector<ContentRegistry::CommandPaletteCommands::Entry> commandPaletteCommands;
static std::map<std::string, ContentRegistry::PatternLanguageFunctions::Function> patternLanguageFunctions; static std::map<std::string, ContentRegistry::PatternLanguageFunctions::Function> patternLanguageFunctions;
static std::vector<View*> views; static std::vector<View*> views;
static std::vector<std::function<void()>> toolsEntries; static std::vector<ContentRegistry::Tools::Entry> toolsEntries;
static std::vector<ContentRegistry::DataInspector::Entry> dataInspectorEntries; static std::vector<ContentRegistry::DataInspector::Entry> dataInspectorEntries;
static int mainArgc; static int mainArgc;

View File

@ -102,11 +102,11 @@ namespace hex {
/* Tools */ /* Tools */
void ContentRegistry::Tools::add(const std::function<void()> &function) { void ContentRegistry::Tools::add(std::string_view name, const std::function<void()> &function) {
getEntries().push_back(function); getEntries().emplace_back(Entry{ name.data(), function });
} }
std::vector<std::function<void()>>& ContentRegistry::Tools::getEntries() { std::vector<ContentRegistry::Tools::Entry>& ContentRegistry::Tools::getEntries() {
return SharedData::toolsEntries; return SharedData::toolsEntries;
} }

View File

@ -12,7 +12,7 @@ namespace hex {
std::vector<ContentRegistry::CommandPaletteCommands::Entry> SharedData::commandPaletteCommands; std::vector<ContentRegistry::CommandPaletteCommands::Entry> SharedData::commandPaletteCommands;
std::map<std::string, ContentRegistry::PatternLanguageFunctions::Function> SharedData::patternLanguageFunctions; std::map<std::string, ContentRegistry::PatternLanguageFunctions::Function> SharedData::patternLanguageFunctions;
std::vector<View*> SharedData::views; std::vector<View*> SharedData::views;
std::vector<std::function<void()>> SharedData::toolsEntries; std::vector<ContentRegistry::Tools::Entry> SharedData::toolsEntries;
std::vector<ContentRegistry::DataInspector::Entry> SharedData::dataInspectorEntries; std::vector<ContentRegistry::DataInspector::Entry> SharedData::dataInspectorEntries;
int SharedData::mainArgc; int SharedData::mainArgc;

View File

@ -64,6 +64,12 @@ namespace hex {
return { }; return { };
}, 2, 2); }, 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() { ViewTools::~ViewTools() {
@ -77,245 +83,227 @@ namespace hex {
} }
void ViewTools::drawDemangler() { void ViewTools::drawDemangler() {
if (ImGui::CollapsingHeader("Itanium/MSVC demangler")) { if (ImGui::InputText("Mangled name", this->m_mangledBuffer, 0xF'FFFF)) {
if (ImGui::InputText("Mangled name", this->m_mangledBuffer, 0xF'FFFF)) { this->m_demangledName = llvm::demangle(this->m_mangledBuffer);
this->m_demangledName = llvm::demangle(this->m_mangledBuffer);
}
ImGui::InputText("Demangled name", this->m_demangledName.data(), this->m_demangledName.size(), ImGuiInputTextFlags_ReadOnly);
ImGui::NewLine();
} }
ImGui::InputText("Demangled name", this->m_demangledName.data(), this->m_demangledName.size(), ImGuiInputTextFlags_ReadOnly);
ImGui::NewLine();
} }
void ViewTools::drawASCIITable() { void ViewTools::drawASCIITable() {
if (ImGui::CollapsingHeader("ASCII table")) { ImGui::BeginTable("##asciitable", 4);
ImGui::BeginTable("##asciitable", 4); ImGui::TableSetupColumn("");
ImGui::TableSetupColumn(""); ImGui::TableSetupColumn("");
ImGui::TableSetupColumn(""); ImGui::TableSetupColumn("");
ImGui::TableSetupColumn(""); ImGui::TableSetupColumn("");
ImGui::TableSetupColumn("");
ImGui::TableNextColumn(); ImGui::TableNextColumn();
for (u8 tablePart = 0; tablePart < 4; tablePart++) { for (u8 tablePart = 0; tablePart < 4; tablePart++) {
ImGui::BeginTable("##asciitablepart", this->m_asciiTableShowOctal ? 4 : 3, ImGuiTableFlags_BordersInnerV | ImGuiTableFlags_BordersOuter | ImGuiTableFlags_RowBg); ImGui::BeginTable("##asciitablepart", this->m_asciiTableShowOctal ? 4 : 3, ImGuiTableFlags_BordersInnerV | ImGuiTableFlags_BordersOuter | ImGuiTableFlags_RowBg);
ImGui::TableSetupColumn("dec"); ImGui::TableSetupColumn("dec");
if (this->m_asciiTableShowOctal) if (this->m_asciiTableShowOctal)
ImGui::TableSetupColumn("oct"); ImGui::TableSetupColumn("oct");
ImGui::TableSetupColumn("hex"); ImGui::TableSetupColumn("hex");
ImGui::TableSetupColumn("char"); ImGui::TableSetupColumn("char");
ImGui::TableHeadersRow(); ImGui::TableHeadersRow();
u32 rowCount = 0; u32 rowCount = 0;
for (u8 i = 0; i < 0x80 / 4; i++) { for (u8 i = 0; i < 0x80 / 4; i++) {
ImGui::TableNextRow(ImGuiTableRowFlags_Headers); ImGui::TableNextRow(ImGuiTableRowFlags_Headers);
ImGui::TableNextColumn();
ImGui::Text("%02d", i + 32 * tablePart);
if (this->m_asciiTableShowOctal) {
ImGui::TableNextColumn(); ImGui::TableNextColumn();
ImGui::Text("%02d", i + 32 * tablePart); ImGui::Text("0o%02o", 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::TableNextColumn();
} ImGui::Text("0x%02x", i + 32 * tablePart);
ImGui::EndTable();
ImGui::Checkbox("Show octal", &this->m_asciiTableShowOctal); ImGui::TableNextColumn();
ImGui::NewLine(); 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() { void ViewTools::drawRegexReplacer() {
if (ImGui::CollapsingHeader("Regex replacer")) { bool shouldInvalidate;
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();
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() { void ViewTools::drawColorPicker() {
if (ImGui::CollapsingHeader("Color picker")) { ImGui::SetNextItemWidth(300.0F);
ImGui::SetNextItemWidth(300.0F); ImGui::ColorPicker4("Color Picker", this->m_pickedColor.data(),
ImGui::ColorPicker4("Color Picker", this->m_pickedColor.data(), ImGuiColorEditFlags_Uint8 | ImGuiColorEditFlags_AlphaBar | ImGuiColorEditFlags_DisplayRGB | ImGuiColorEditFlags_DisplayHex);
ImGuiColorEditFlags_Uint8 | ImGuiColorEditFlags_AlphaBar | ImGuiColorEditFlags_DisplayRGB | ImGuiColorEditFlags_DisplayHex); ImGui::NewLine();
ImGui::NewLine();
}
} }
void ViewTools::drawMathEvaluator() { void ViewTools::drawMathEvaluator() {
if (ImGui::CollapsingHeader("Calculator")) { if (ImGui::InputText("Input", this->m_mathInput, 0xFFFF, ImGuiInputTextFlags_EnterReturnsTrue | ImGuiInputTextFlags_AutoSelectAll)) {
if (ImGui::InputText("Input", this->m_mathInput, 0xFFFF, ImGuiInputTextFlags_EnterReturnsTrue | ImGuiInputTextFlags_AutoSelectAll)) { ImGui::SetKeyboardFocusHere();
ImGui::SetKeyboardFocusHere(); std::optional<long double> result;
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();
}
try {
result = this->m_mathEvaluator.evaluate(this->m_mathInput);
} catch (std::invalid_argument &e) {
this->m_lastMathError = e.what();
} }
if (!this->m_lastMathError.empty()) if (result.has_value()) {
ImGui::TextColored(ImColor(0xA00040FF), "Last Error: %s", this->m_lastMathError.c_str()); this->m_mathHistory.push_back(result.value());
else std::memset(this->m_mathInput, 0x00, 0xFFFF);
ImGui::NewLine(); this->m_lastMathError.clear();
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(); if (!this->m_lastMathError.empty())
ImGui::TableNextColumn(); ImGui::TextColored(ImColor(0xA00040FF), "Last Error: %s", this->m_lastMathError.c_str());
if (ImGui::BeginTable("##mathHistory", 1, ImGuiTableFlags_ScrollY | ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg, ImVec2(0, 400))) { else
ImGui::TableSetupScrollFreeze(0, 1); ImGui::NewLine();
ImGui::TableSetupColumn("History");
ImGuiListClipper clipper; enum class MathDisplayType { Standard, Scientific, Engineering, Programmer } mathDisplayType;
clipper.Begin(this->m_mathHistory.size()); 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::TableHeadersRow(); ImGui::EndTabBar();
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(); if (ImGui::BeginTable("##mathWrapper", 2)) {
ImGui::TableNextColumn(); ImGui::TableSetupColumn("##results");
ImGui::TableSetupColumn("##variables", ImGuiTableColumnFlags_WidthStretch, 0.7);
switch (mathDisplayType) { ImGui::TableNextRow();
case MathDisplayType::Standard: ImGui::TableNextColumn();
ImGui::Text("%.3Lf", this->m_mathHistory[(this->m_mathHistory.size() - 1) - i]); if (ImGui::BeginTable("##mathHistory", 1, ImGuiTableFlags_ScrollY | ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg, ImVec2(0, 400))) {
break; ImGui::TableSetupScrollFreeze(0, 1);
case MathDisplayType::Scientific: ImGui::TableSetupColumn("History");
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) ImGuiListClipper clipper;
ImGui::PopStyleColor(); clipper.Begin(this->m_mathHistory.size());
}
}
clipper.End(); 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::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::TableNextRow();
ImGui::TableNextColumn(); ImGui::TableNextColumn();
ImGui::TextUnformatted(name.c_str());
ImGui::TableNextColumn();
switch (mathDisplayType) { switch (mathDisplayType) {
case MathDisplayType::Standard: case MathDisplayType::Standard:
ImGui::Text("%.3Lf", value); ImGui::Text("%.3Lf", this->m_mathHistory[(this->m_mathHistory.size() - 1) - i]);
break; break;
case MathDisplayType::Scientific: case MathDisplayType::Scientific:
ImGui::Text("%.6Le", value); ImGui::Text("%.6Le", this->m_mathHistory[(this->m_mathHistory.size() - 1) - i]);
break; break;
case MathDisplayType::Engineering: case MathDisplayType::Engineering:
ImGui::Text("%s", hex::toEngineeringString(value).c_str()); ImGui::Text("%s", hex::toEngineeringString(this->m_mathHistory[(this->m_mathHistory.size() - 1) - i]).c_str());
break; break;
case MathDisplayType::Programmer: case MathDisplayType::Programmer:
ImGui::Text("0x%llX (%llu)", u64(value), u64(value)); 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; break;
} }
}
ImGui::EndTable(); 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();
} }
ImGui::EndTable();
} }
} }
void ViewTools::drawContent() { void ViewTools::drawContent() {
if (ImGui::Begin("Tools", &this->getWindowOpenState(), ImGuiWindowFlags_NoCollapse)) { if (ImGui::Begin("Tools", &this->getWindowOpenState(), ImGuiWindowFlags_NoCollapse)) {
for (const auto& [name, function] : ContentRegistry::Tools::getEntries()) {
this->drawDemangler(); if (ImGui::CollapsingHeader(name.c_str())) {
this->drawASCIITable(); function();
this->drawRegexReplacer(); }
this->drawMathEvaluator(); }
this->drawColorPicker();
for (const auto& entries : ContentRegistry::Tools::getEntries())
entries();
} }
ImGui::End(); ImGui::End();
} }