1
0
mirror of synced 2024-11-28 09:30:51 +01:00

refactor: Move tools to correct namespace, move data processor nodes

This commit is contained in:
WerWolv 2023-12-01 13:53:51 +01:00
parent a50bb39978
commit 519d965a36
27 changed files with 2124 additions and 2155 deletions

View File

@ -1,28 +1,26 @@
#include <hex/helpers/literals.hpp>
namespace hex::plugin::builtin {
namespace impl {
void drawDemangler();
void drawASCIITable();
void drawRegexReplacer();
void drawColorPicker();
void drawMathEvaluator();
void drawGraphingCalculator();
void drawBaseConverter();
void drawByteSwapper();
void drawPermissionsCalculator();
// void drawFileUploader();
void drawWikiExplainer();
void drawDemangler();
void drawASCIITable();
void drawRegexReplacer();
void drawColorPicker();
void drawMathEvaluator();
void drawGraphingCalculator();
void drawBaseConverter();
void drawByteSwapper();
void drawPermissionsCalculator();
// void drawFileUploader();
void drawWikiExplainer();
void drawIEEE754Decoder();
void drawInvariantMultiplicationDecoder();
void drawTCPClientServer();
void drawEuclidianAlgorithm();
void drawFileToolShredder();
void drawFileToolSplitter();
void drawFileToolCombiner();
void drawIEEE754Decoder();
void drawInvariantMultiplicationDecoder();
void drawTCPClientServer();
void drawEuclidianAlgorithm();
void drawFileToolShredder();
void drawFileToolSplitter();
void drawFileToolCombiner();
}
}

View File

@ -1,59 +1,58 @@
#include <hex/helpers/utils.hpp>
#include <hex/api/localization_manager.hpp>
#include <content/tools_entries.hpp>
#include <imgui.h>
#include <hex/ui/imgui_imhex_extensions.h>
namespace hex::plugin::builtin {
namespace impl {
void drawASCIITable() {
static bool asciiTableShowOctal = false;
ImGui::BeginTable("##asciitable", 4);
ImGui::TableSetupColumn("");
ImGui::TableSetupColumn("");
ImGui::TableSetupColumn("");
ImGui::TableSetupColumn("");
void drawASCIITable() {
static bool asciiTableShowOctal = false;
ImGui::TableNextColumn();
ImGui::BeginTable("##asciitable", 4);
ImGui::TableSetupColumn("");
ImGui::TableSetupColumn("");
ImGui::TableSetupColumn("");
ImGui::TableSetupColumn("");
for (u8 tablePart = 0; tablePart < 4; tablePart++) {
ImGui::BeginTable("##asciitablepart", asciiTableShowOctal ? 4 : 3, ImGuiTableFlags_BordersInnerV | ImGuiTableFlags_BordersOuter | ImGuiTableFlags_RowBg);
ImGui::TableSetupColumn("dec");
if (asciiTableShowOctal)
ImGui::TableSetupColumn("oct");
ImGui::TableSetupColumn("hex");
ImGui::TableSetupColumn("char");
ImGui::TableNextColumn();
ImGui::TableHeadersRow();
for (u8 tablePart = 0; tablePart < 4; tablePart++) {
ImGui::BeginTable("##asciitablepart", asciiTableShowOctal ? 4 : 3, ImGuiTableFlags_BordersInnerV | ImGuiTableFlags_BordersOuter | ImGuiTableFlags_RowBg);
ImGui::TableSetupColumn("dec");
if (asciiTableShowOctal)
ImGui::TableSetupColumn("oct");
ImGui::TableSetupColumn("hex");
ImGui::TableSetupColumn("char");
for (u8 i = 0; i < 0x80 / 4; i++) {
ImGui::TableNextRow();
ImGui::TableHeadersRow();
for (u8 i = 0; i < 0x80 / 4; i++) {
ImGui::TableNextRow();
ImGui::TableNextColumn();
ImGuiExt::TextFormatted("{0:03d}", i + 32 * tablePart);
if (asciiTableShowOctal) {
ImGui::TableNextColumn();
ImGuiExt::TextFormatted("{0:03d}", i + 32 * tablePart);
if (asciiTableShowOctal) {
ImGui::TableNextColumn();
ImGuiExt::TextFormatted("0o{0:03o}", i + 32 * tablePart);
}
ImGui::TableNextColumn();
ImGuiExt::TextFormatted("0x{0:02X}", i + 32 * tablePart);
ImGui::TableNextColumn();
ImGuiExt::TextFormatted("{0}", hex::makePrintable(i + 32 * tablePart));
ImGuiExt::TextFormatted("0o{0:03o}", i + 32 * tablePart);
}
ImGui::EndTable();
ImGui::TableNextColumn();
}
ImGui::EndTable();
ImGuiExt::TextFormatted("0x{0:02X}", i + 32 * tablePart);
ImGui::Checkbox("hex.builtin.tools.ascii_table.octal"_lang, &asciiTableShowOctal);
ImGui::TableNextColumn();
ImGuiExt::TextFormatted("{0}", hex::makePrintable(i + 32 * tablePart));
}
ImGui::EndTable();
ImGui::TableNextColumn();
}
ImGui::EndTable();
ImGui::Checkbox("hex.builtin.tools.ascii_table.octal"_lang, &asciiTableShowOctal);
}
}

View File

@ -2,54 +2,52 @@
#include <hex/helpers/fmt.hpp>
#include <hex/api/localization_manager.hpp>
#include <hex/ui/view.hpp>
#include <content/tools_entries.hpp>
#include <hex/ui/imgui_imhex_extensions.h>
#include <fonts/codicons_font.h>
namespace hex::plugin::builtin {
namespace impl {
void drawBaseConverter() {
static std::array<std::string, 4> buffers;
static auto ConvertBases = [](u8 base) {
u64 number;
void drawBaseConverter() {
static std::array<std::string, 4> buffers;
switch (base) {
case 16:
number = std::strtoull(buffers[1].c_str(), nullptr, base);
break;
case 10:
number = std::strtoull(buffers[0].c_str(), nullptr, base);
break;
case 8:
number = std::strtoull(buffers[2].c_str(), nullptr, base);
break;
case 2:
number = std::strtoull(buffers[3].c_str(), nullptr, base);
break;
default:
return;
}
static auto ConvertBases = [](u8 base) {
u64 number;
buffers[0] = std::to_string(number);
buffers[1] = hex::format("0x{0:X}", number);
buffers[2] = hex::format("{0:#o}", number);
buffers[3] = hex::toBinaryString(number);
};
switch (base) {
case 16:
number = std::strtoull(buffers[1].c_str(), nullptr, base);
break;
case 10:
number = std::strtoull(buffers[0].c_str(), nullptr, base);
break;
case 8:
number = std::strtoull(buffers[2].c_str(), nullptr, base);
break;
case 2:
number = std::strtoull(buffers[3].c_str(), nullptr, base);
break;
default:
return;
}
if (ImGuiExt::InputTextIcon("hex.builtin.tools.base_converter.dec"_lang, ICON_VS_SYMBOL_NUMERIC, buffers[0]))
ConvertBases(10);
buffers[0] = std::to_string(number);
buffers[1] = hex::format("0x{0:X}", number);
buffers[2] = hex::format("{0:#o}", number);
buffers[3] = hex::toBinaryString(number);
};
if (ImGuiExt::InputTextIcon("hex.builtin.tools.base_converter.hex"_lang, ICON_VS_SYMBOL_NUMERIC, buffers[1]))
ConvertBases(16);
if (ImGuiExt::InputTextIcon("hex.builtin.tools.base_converter.dec"_lang, ICON_VS_SYMBOL_NUMERIC, buffers[0]))
ConvertBases(10);
if (ImGuiExt::InputTextIcon("hex.builtin.tools.base_converter.oct"_lang, ICON_VS_SYMBOL_NUMERIC, buffers[2]))
ConvertBases(8);
if (ImGuiExt::InputTextIcon("hex.builtin.tools.base_converter.hex"_lang, ICON_VS_SYMBOL_NUMERIC, buffers[1]))
ConvertBases(16);
if (ImGuiExt::InputTextIcon("hex.builtin.tools.base_converter.bin"_lang, ICON_VS_SYMBOL_NUMERIC, buffers[3]))
ConvertBases(2);
}
if (ImGuiExt::InputTextIcon("hex.builtin.tools.base_converter.oct"_lang, ICON_VS_SYMBOL_NUMERIC, buffers[2]))
ConvertBases(8);
if (ImGuiExt::InputTextIcon("hex.builtin.tools.base_converter.bin"_lang, ICON_VS_SYMBOL_NUMERIC, buffers[3]))
ConvertBases(2);
}
}

View File

@ -1,37 +1,34 @@
#include <hex/api/localization_manager.hpp>
#include <hex/ui/view.hpp>
#include <algorithm>
#include <content/tools_entries.hpp>
#include <imgui.h>
#include <hex/ui/imgui_imhex_extensions.h>
#include <fonts/codicons_font.h>
namespace hex::plugin::builtin {
namespace impl {
void drawByteSwapper() {
static std::string input, buffer, output;
if (ImGuiExt::InputTextIcon("hex.builtin.tools.input"_lang, ICON_VS_SYMBOL_NUMERIC, input, ImGuiInputTextFlags_CharsHexadecimal)) {
auto nextAlignedSize = std::max<size_t>(2, std::bit_ceil(input.size()));
void drawByteSwapper() {
static std::string input, buffer, output;
buffer.clear();
buffer.resize(nextAlignedSize - input.size(), '0');
buffer += input;
if (ImGuiExt::InputTextIcon("hex.builtin.tools.input"_lang, ICON_VS_SYMBOL_NUMERIC, input, ImGuiInputTextFlags_CharsHexadecimal)) {
auto nextAlignedSize = std::max<size_t>(2, std::bit_ceil(input.size()));
output.clear();
for (u32 i = 0; i < buffer.size(); i += 2) {
output += buffer[buffer.size() - i - 2];
output += buffer[buffer.size() - i - 1];
}
buffer.clear();
buffer.resize(nextAlignedSize - input.size(), '0');
buffer += input;
output.clear();
for (u32 i = 0; i < buffer.size(); i += 2) {
output += buffer[buffer.size() - i - 2];
output += buffer[buffer.size() - i - 1];
}
ImGui::PushStyleVar(ImGuiStyleVar_Alpha, ImGui::GetStyle().DisabledAlpha);
ImGuiExt::InputTextIcon("hex.builtin.tools.output"_lang, ICON_VS_SYMBOL_NUMERIC, output, ImGuiInputTextFlags_ReadOnly);
ImGui::PopStyleVar();
}
ImGui::PushStyleVar(ImGuiStyleVar_Alpha, ImGui::GetStyle().DisabledAlpha);
ImGuiExt::InputTextIcon("hex.builtin.tools.output"_lang, ICON_VS_SYMBOL_NUMERIC, output, ImGuiInputTextFlags_ReadOnly);
ImGui::PopStyleVar();
}
}

View File

@ -4,7 +4,6 @@
#include <hex/api/localization_manager.hpp>
#include <content/helpers/math_evaluator.hpp>
#include <content/tools_entries.hpp>
#include <imgui.h>
@ -13,215 +12,215 @@
#include <romfs/romfs.hpp>
namespace hex::plugin::builtin {
namespace impl {
void drawColorPicker() {
static std::array<float, 4> pickedColor = { 0 };
static std::string rgba8;
struct BitValue {
int bits;
float color;
float saturationMultiplier;
char name;
u8 index;
};
void drawColorPicker() {
static std::array<float, 4> pickedColor = { 0 };
static std::string rgba8;
static std::array bitValues = {
BitValue{ 8, 0.00F, 1.0F, 'R', 0 },
BitValue{ 8, 0.33F, 1.0F, 'G', 1 },
BitValue{ 8, 0.66F, 1.0F, 'B', 2 },
BitValue{ 8, 0.00F, 0.0F, 'A', 3 }
};
struct BitValue {
int bits;
float color;
float saturationMultiplier;
char name;
u8 index;
};
if (ImGui::BeginTable("##color_picker_table", 3, ImGuiTableFlags_BordersInnerV)) {
ImGui::TableSetupColumn(" Color Picker", ImGuiTableColumnFlags_WidthFixed | ImGuiTableColumnFlags_NoResize, 300_scaled);
ImGui::TableSetupColumn(" Components", ImGuiTableColumnFlags_WidthFixed | ImGuiTableColumnFlags_NoResize, 105_scaled);
ImGui::TableSetupColumn(" Formats", ImGuiTableColumnFlags_WidthStretch | ImGuiTableColumnFlags_NoResize);
static std::array bitValues = {
BitValue{ 8, 0.00F, 1.0F, 'R', 0 },
BitValue{ 8, 0.33F, 1.0F, 'G', 1 },
BitValue{ 8, 0.66F, 1.0F, 'B', 2 },
BitValue{ 8, 0.00F, 0.0F, 'A', 3 }
};
ImGui::TableHeadersRow();
if (ImGui::BeginTable("##color_picker_table", 3, ImGuiTableFlags_BordersInnerV)) {
ImGui::TableSetupColumn(" Color Picker", ImGuiTableColumnFlags_WidthFixed | ImGuiTableColumnFlags_NoResize, 300_scaled);
ImGui::TableSetupColumn(" Components", ImGuiTableColumnFlags_WidthFixed | ImGuiTableColumnFlags_NoResize, 105_scaled);
ImGui::TableSetupColumn(" Formats", ImGuiTableColumnFlags_WidthStretch | ImGuiTableColumnFlags_NoResize);
ImGui::TableNextRow();
ImGui::TableNextColumn();
ImGui::TableHeadersRow();
// Draw main color picker widget
ImVec2 startCursor, endCursor;
{
ImGui::PushItemWidth(-1);
startCursor = ImGui::GetCursorPos();
ImGui::ColorPicker4("hex.builtin.tools.color"_lang, pickedColor.data(), ImGuiColorEditFlags_Uint8 | ImGuiColorEditFlags_AlphaBar | ImGuiColorEditFlags_NoSidePreview | ImGuiColorEditFlags_NoSmallPreview | ImGuiColorEditFlags_DisplayRGB | ImGuiColorEditFlags_DisplayHSV | ImGuiColorEditFlags_DisplayHex);
endCursor = ImGui::GetCursorPos();
ImGui::ColorButton("##color_button", ImColor(pickedColor[0], pickedColor[1], pickedColor[2], pickedColor[3]), ImGuiColorEditFlags_NoPicker | ImGuiColorEditFlags_NoDragDrop | ImGuiColorEditFlags_AlphaPreviewHalf, ImVec2(300_scaled, 0));
ImGui::PopItemWidth();
ImGui::TableNextRow();
ImGui::TableNextColumn();
// Draw main color picker widget
ImVec2 startCursor, endCursor;
{
ImGui::PushItemWidth(-1);
startCursor = ImGui::GetCursorPos();
ImGui::ColorPicker4("hex.builtin.tools.color"_lang, pickedColor.data(), ImGuiColorEditFlags_Uint8 | ImGuiColorEditFlags_AlphaBar | ImGuiColorEditFlags_NoSidePreview | ImGuiColorEditFlags_NoSmallPreview | ImGuiColorEditFlags_DisplayRGB | ImGuiColorEditFlags_DisplayHSV | ImGuiColorEditFlags_DisplayHex);
endCursor = ImGui::GetCursorPos();
ImGui::ColorButton("##color_button", ImColor(pickedColor[0], pickedColor[1], pickedColor[2], pickedColor[3]), ImGuiColorEditFlags_NoPicker | ImGuiColorEditFlags_NoDragDrop | ImGuiColorEditFlags_AlphaPreviewHalf, ImVec2(300_scaled, 0));
ImGui::PopItemWidth();
}
ImGui::TableNextColumn();
const auto colorFormatName = hex::format("{}{}{}{}", bitValues[0].name, bitValues[1].name, bitValues[2].name, bitValues[3].name);
// Draw color bit count sliders
{
ImGui::Indent();
static auto drawBitsSlider = [&](BitValue *bitValue) {
// Change slider color
ImGui::PushStyleColor(ImGuiCol_FrameBg, ImColor::HSV(bitValue->color, 0.5f * bitValue->saturationMultiplier, 0.5f).Value);
ImGui::PushStyleColor(ImGuiCol_FrameBgHovered, ImColor::HSV(bitValue->color, 0.6f * bitValue->saturationMultiplier, 0.5f).Value);
ImGui::PushStyleColor(ImGuiCol_FrameBgActive, ImColor::HSV(bitValue->color, 0.7f * bitValue->saturationMultiplier, 0.5f).Value);
ImGui::PushStyleColor(ImGuiCol_SliderGrab, ImColor::HSV(bitValue->color, 0.9f * bitValue->saturationMultiplier, 0.9f).Value);
// Draw slider
ImGui::PushID(&bitValue->bits);
auto format = hex::format("%d\n{}", bitValue->name);
ImGui::VSliderInt("##slider", ImVec2(18_scaled, (endCursor - startCursor).y - 3_scaled), &bitValue->bits, 0, 16, format.c_str(), ImGuiSliderFlags_AlwaysClamp);
ImGui::PopID();
ImGui::PopStyleColor(4);
};
// Force sliders closer together
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(4, 4));
// Draw a slider for each color component
for (u32 index = 0; auto &bitValue : bitValues) {
// Draw slider
drawBitsSlider(&bitValue);
// Configure drag and drop source and target
if (ImGui::BeginDragDropSource(ImGuiDragDropFlags_None)) {
// Set the current slider index as the payload
ImGui::SetDragDropPayload("BIT_VALUE", &index, sizeof(u32));
// Draw a color button to show the color being dragged
ImGui::ColorButton("##color_button", ImColor::HSV(bitValue.color, 0.5f * bitValue.saturationMultiplier, 0.5f).Value);
ImGui::EndDragDropSource();
}
if (ImGui::BeginDragDropTarget()) {
if (const ImGuiPayload *payload = ImGui::AcceptDragDropPayload("BIT_VALUE"); payload != nullptr) {
auto otherIndex = *static_cast<const u32 *>(payload->Data);
// Swap the currently hovered slider with the one being dragged
std::swap(bitValues[index], bitValues[otherIndex]);
}
ImGui::EndDragDropTarget();
}
ImGui::SameLine();
index += 1;
}
ImGui::TableNextColumn();
ImGui::NewLine();
const auto colorFormatName = hex::format("{}{}{}{}", bitValues[0].name, bitValues[1].name, bitValues[2].name, bitValues[3].name);
// Draw color name below sliders
ImGuiExt::TextFormatted("{}", colorFormatName);
// Draw color bit count sliders
{
ImGui::Indent();
ImGui::PopStyleVar();
static auto drawBitsSlider = [&](BitValue *bitValue) {
// Change slider color
ImGui::PushStyleColor(ImGuiCol_FrameBg, ImColor::HSV(bitValue->color, 0.5f * bitValue->saturationMultiplier, 0.5f).Value);
ImGui::PushStyleColor(ImGuiCol_FrameBgHovered, ImColor::HSV(bitValue->color, 0.6f * bitValue->saturationMultiplier, 0.5f).Value);
ImGui::PushStyleColor(ImGuiCol_FrameBgActive, ImColor::HSV(bitValue->color, 0.7f * bitValue->saturationMultiplier, 0.5f).Value);
ImGui::PushStyleColor(ImGuiCol_SliderGrab, ImColor::HSV(bitValue->color, 0.9f * bitValue->saturationMultiplier, 0.9f).Value);
ImGui::Unindent();
}
// Draw slider
ImGui::PushID(&bitValue->bits);
auto format = hex::format("%d\n{}", bitValue->name);
ImGui::VSliderInt("##slider", ImVec2(18_scaled, (endCursor - startCursor).y - 3_scaled), &bitValue->bits, 0, 16, format.c_str(), ImGuiSliderFlags_AlwaysClamp);
ImGui::TableNextColumn();
// Draw encoded color values
{
// Calculate int and float representations of the selected color
std::array<u32, 4> intColor = {};
std::array<float, 4> floatColor = {};
for (u32 index = 0; auto &bitValue : bitValues) {
intColor[index] = u64(std::round(static_cast<long double>(pickedColor[bitValue.index]) * std::numeric_limits<u32>::max())) >> (32 - bitValue.bits);
floatColor[index] = pickedColor[bitValue.index];
index += 1;
}
// Draw a table with the color values
if (ImGui::BeginTable("##value_table", 2, ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg | ImGuiTableFlags_NoHostExtendX , ImVec2(0, 0))) {
ImGui::TableSetupColumn("name", ImGuiTableColumnFlags_WidthFixed);
ImGui::TableSetupColumn("value", ImGuiTableColumnFlags_WidthStretch);
const static auto drawValue = [](const char *name, auto formatter) {
ImGui::TableNextRow();
ImGui::TableNextColumn();
// Draw name of the formatting
ImGui::TextUnformatted(name);
ImGui::TableNextColumn();
// Draw value
ImGui::PushID(name);
ImGuiExt::TextFormattedSelectable("{}", formatter());
ImGui::PopID();
ImGui::PopStyleColor(4);
};
// Force sliders closer together
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(4, 4));
const u32 bitCount = bitValues[0].bits + bitValues[1].bits + bitValues[2].bits + bitValues[3].bits;
// Draw a slider for each color component
for (u32 index = 0; auto &bitValue : bitValues) {
// Draw slider
drawBitsSlider(&bitValue);
// Draw the different representations
// Configure drag and drop source and target
if (ImGui::BeginDragDropSource(ImGuiDragDropFlags_None)) {
// Set the current slider index as the payload
ImGui::SetDragDropPayload("BIT_VALUE", &index, sizeof(u32));
// Draw a color button to show the color being dragged
ImGui::ColorButton("##color_button", ImColor::HSV(bitValue.color, 0.5f * bitValue.saturationMultiplier, 0.5f).Value);
ImGui::EndDragDropSource();
}
if (ImGui::BeginDragDropTarget()) {
if (const ImGuiPayload *payload = ImGui::AcceptDragDropPayload("BIT_VALUE"); payload != nullptr) {
auto otherIndex = *static_cast<const u32 *>(payload->Data);
// Swap the currently hovered slider with the one being dragged
std::swap(bitValues[index], bitValues[otherIndex]);
}
ImGui::EndDragDropTarget();
drawValue("HEX", [&] {
u64 hexValue = 0;
for (u32 index = 0; auto &bitValue : bitValues) {
hexValue <<= bitValue.bits;
hexValue |= u64(intColor[index]) & hex::bitmask(bitValue.bits);
index += 1;
}
ImGui::SameLine();
return hex::format("#{0:0{1}X}", hexValue, bitCount / 4);
});
index += 1;
}
drawValue(colorFormatName.c_str(), [&] {
return hex::format("{}({}, {}, {}, {})", colorFormatName, intColor[0], intColor[1], intColor[2], intColor[3]);
});
ImGui::NewLine();
drawValue("Vector4f", [&] {
return hex::format("{{ {:.2}F, {:.2}F, {:.2}F, {:.2}F }}", floatColor[0], floatColor[1], floatColor[2], floatColor[3]);
});
// Draw color name below sliders
ImGuiExt::TextFormatted("{}", colorFormatName);
drawValue("Percentage", [&] {
return hex::format("{{ {}%, {}%, {}%, {}% }}", u32(floatColor[0] * 100), u32(floatColor[1] * 100), u32(floatColor[2] * 100), u32(floatColor[3] * 100));
});
ImGui::PopStyleVar();
drawValue("Color Name", [&] -> std::string {
const static auto ColorTable = [] {
auto colorMap = nlohmann::json::parse(romfs::get("assets/common/color_names.json").string()).get<std::map<std::string, std::string>>();
ImGui::Unindent();
}
ImGui::TableNextColumn();
// Draw encoded color values
{
// Calculate int and float representations of the selected color
std::array<u32, 4> intColor = {};
std::array<float, 4> floatColor = {};
for (u32 index = 0; auto &bitValue : bitValues) {
intColor[index] = u64(std::round(static_cast<long double>(pickedColor[bitValue.index]) * std::numeric_limits<u32>::max())) >> (32 - bitValue.bits);
floatColor[index] = pickedColor[bitValue.index];
index += 1;
}
// Draw a table with the color values
if (ImGui::BeginTable("##value_table", 2, ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg | ImGuiTableFlags_NoHostExtendX , ImVec2(0, 0))) {
ImGui::TableSetupColumn("name", ImGuiTableColumnFlags_WidthFixed);
ImGui::TableSetupColumn("value", ImGuiTableColumnFlags_WidthStretch);
const static auto drawValue = [](const char *name, auto formatter) {
ImGui::TableNextRow();
ImGui::TableNextColumn();
// Draw name of the formatting
ImGui::TextUnformatted(name);
ImGui::TableNextColumn();
// Draw value
ImGui::PushID(name);
ImGuiExt::TextFormattedSelectable("{}", formatter());
ImGui::PopID();
};
const u32 bitCount = bitValues[0].bits + bitValues[1].bits + bitValues[2].bits + bitValues[3].bits;
// Draw the different representations
drawValue("HEX", [&] {
u64 hexValue = 0;
for (u32 index = 0; auto &bitValue : bitValues) {
hexValue <<= bitValue.bits;
hexValue |= u64(intColor[index]) & hex::bitmask(bitValue.bits);
index += 1;
std::map<u8, std::map<u8, std::map<u8, std::string>>> result;
for (const auto &[colorValue, colorName] : colorMap) {
result
[hex::parseHexString(colorValue.substr(0, 2))[0]]
[hex::parseHexString(colorValue.substr(2, 2))[0]]
[hex::parseHexString(colorValue.substr(4, 2))[0]] = colorName;
}
return hex::format("#{0:0{1}X}", hexValue, bitCount / 4);
});
return result;
}();
drawValue(colorFormatName.c_str(), [&] {
return hex::format("{}({}, {}, {}, {})", colorFormatName, intColor[0], intColor[1], intColor[2], intColor[3]);
});
const auto r = pickedColor[0] * 0xFF;
const auto g = pickedColor[1] * 0xFF;
const auto b = pickedColor[2] * 0xFF;
drawValue("Vector4f", [&] {
return hex::format("{{ {:.2}F, {:.2}F, {:.2}F, {:.2}F }}", floatColor[0], floatColor[1], floatColor[2], floatColor[3]);
});
auto gTable = ColorTable.lower_bound(r);
if (gTable == ColorTable.end())
return "???";
drawValue("Percentage", [&] {
return hex::format("{{ {}%, {}%, {}%, {}% }}", u32(floatColor[0] * 100), u32(floatColor[1] * 100), u32(floatColor[2] * 100), u32(floatColor[3] * 100));
});
auto bTable = gTable->second.lower_bound(g);
if (bTable == gTable->second.end())
return "???";
drawValue("Color Name", [&] -> std::string {
const static auto ColorTable = [] {
auto colorMap = nlohmann::json::parse(romfs::get("assets/common/color_names.json").string()).get<std::map<std::string, std::string>>();
auto name = bTable->second.lower_bound(b);
if (name == bTable->second.end())
return "???";
std::map<u8, std::map<u8, std::map<u8, std::string>>> result;
for (const auto &[colorValue, colorName] : colorMap) {
result
[hex::parseHexString(colorValue.substr(0, 2))[0]]
[hex::parseHexString(colorValue.substr(2, 2))[0]]
[hex::parseHexString(colorValue.substr(4, 2))[0]] = colorName;
}
return name->second;
});
return result;
}();
const auto r = pickedColor[0] * 0xFF;
const auto g = pickedColor[1] * 0xFF;
const auto b = pickedColor[2] * 0xFF;
auto gTable = ColorTable.lower_bound(r);
if (gTable == ColorTable.end())
return "???";
auto bTable = gTable->second.lower_bound(g);
if (bTable == gTable->second.end())
return "???";
auto name = bTable->second.lower_bound(b);
if (name == bTable->second.end())
return "???";
return name->second;
});
ImGui::EndTable();
}
ImGui::EndTable();
}
ImGui::EndTable();
}
ImGui::EndTable();
}
}
}

View File

@ -4,61 +4,60 @@
#include <llvm/Demangle/Demangle.h>
#include <imgui.h>
#include <TextEditor.h>
#include <hex/ui/imgui_imhex_extensions.h>
#include <TextEditor.h>
namespace hex::plugin::builtin {
namespace impl {
void drawDemangler() {
static std::string mangledName, demangledName, wrappedDemangledName;
static TextEditor outputField = []{
TextEditor editor;
editor.SetReadOnly(true);
editor.SetShowLineNumbers(false);
editor.SetShowWhitespaces(false);
editor.SetShowCursor(false);
editor.SetImGuiChildIgnored(true);
auto languageDef = TextEditor::LanguageDefinition::CPlusPlus();
for (auto &[name, identifier] : languageDef.mIdentifiers)
identifier.mDeclaration = "";
void drawDemangler() {
static std::string mangledName, demangledName, wrappedDemangledName;
static TextEditor outputField = []{
TextEditor editor;
editor.SetReadOnly(true);
editor.SetShowLineNumbers(false);
editor.SetShowWhitespaces(false);
editor.SetShowCursor(false);
editor.SetImGuiChildIgnored(true);
editor.SetLanguageDefinition(languageDef);
auto languageDef = TextEditor::LanguageDefinition::CPlusPlus();
for (auto &[name, identifier] : languageDef.mIdentifiers)
identifier.mDeclaration = "";
return editor;
}();
static float prevWindowWidth;
editor.SetLanguageDefinition(languageDef);
if (ImGui::InputTextWithHint("hex.builtin.tools.demangler.mangled"_lang, "Itanium, MSVC, Dlang & Rust", mangledName)) {
demangledName = llvm::demangle(mangledName);
return editor;
}();
static float prevWindowWidth;
if (demangledName == mangledName) {
demangledName = "???";
}
if (ImGui::InputTextWithHint("hex.builtin.tools.demangler.mangled"_lang, "Itanium, MSVC, Dlang & Rust", mangledName)) {
demangledName = llvm::demangle(mangledName);
prevWindowWidth = 0;
if (demangledName == mangledName) {
demangledName = "???";
}
const auto windowWidth = ImGui::GetContentRegionAvail().x;
if (prevWindowWidth != windowWidth) {
wrappedDemangledName = wolv::util::wrapMonospacedString(
demangledName,
ImGui::CalcTextSize("M").x,
ImGui::GetContentRegionAvail().x - ImGui::GetStyle().ScrollbarSize - ImGui::GetStyle().FrameBorderSize
);
outputField.SetText(wrappedDemangledName);
prevWindowWidth = windowWidth;
}
ImGuiExt::Header("hex.builtin.tools.demangler.demangled"_lang);
if (ImGui::BeginChild("Demangled", ImVec2(ImGui::GetContentRegionAvail().x, 150_scaled), true, ImGuiWindowFlags_NoMove)) {
outputField.Render("Demangled", ImVec2(ImGui::GetContentRegionAvail().x, 150_scaled), true);
}
ImGui::EndChild();
prevWindowWidth = 0;
}
const auto windowWidth = ImGui::GetContentRegionAvail().x;
if (prevWindowWidth != windowWidth) {
wrappedDemangledName = wolv::util::wrapMonospacedString(
demangledName,
ImGui::CalcTextSize("M").x,
ImGui::GetContentRegionAvail().x - ImGui::GetStyle().ScrollbarSize - ImGui::GetStyle().FrameBorderSize
);
outputField.SetText(wrappedDemangledName);
prevWindowWidth = windowWidth;
}
ImGuiExt::Header("hex.builtin.tools.demangler.demangled"_lang);
if (ImGui::BeginChild("Demangled", ImVec2(ImGui::GetContentRegionAvail().x, 150_scaled), true, ImGuiWindowFlags_NoMove)) {
outputField.Render("Demangled", ImVec2(ImGui::GetContentRegionAvail().x, 150_scaled), true);
}
ImGui::EndChild();
}
}

View File

@ -1,7 +1,5 @@
#include <hex/api/localization_manager.hpp>
#include <content/tools_entries.hpp>
#include <imgui.h>
#include <hex/ui/imgui_imhex_extensions.h>
#include <fonts/codicons_font.h>
@ -9,81 +7,81 @@
#include <numeric>
namespace hex::plugin::builtin {
namespace impl {
void drawEuclidianAlgorithm() {
static u64 a, b;
static i64 gcdResult = 0;
static i64 lcmResult = 0;
static i64 p = 0, q = 0;
static bool overflow = false;
void drawEuclidianAlgorithm() {
static u64 a, b;
constexpr static auto extendedGcd = []<typename T>(T a, T b) -> std::pair<T, T> {
T x = 1, y = 0;
static i64 gcdResult = 0;
static i64 lcmResult = 0;
static i64 p = 0, q = 0;
static bool overflow = false;
T xLast = 0, yLast = 1;
constexpr static auto extendedGcd = []<typename T>(T a, T b) -> std::pair<T, T> {
T x = 1, y = 0;
while (b > 0) {
T quotient = a / b;
T xLast = 0, yLast = 1;
std::tie(x, xLast) = std::tuple { xLast, x - quotient * xLast };
std::tie(y, yLast) = std::tuple { yLast, y - quotient * yLast };
std::tie(a, b) = std::tuple { b, a - quotient * b };
}
while (b > 0) {
T quotient = a / b;
return { x, y };
};
ImGuiExt::TextFormattedWrapped("{}", "hex.builtin.tools.euclidean_algorithm.description"_lang);
ImGui::NewLine();
if (ImGuiExt::BeginBox()) {
bool hasChanged = false;
hasChanged = ImGui::InputScalar("A", ImGuiDataType_U64, &a) || hasChanged;
hasChanged = ImGui::InputScalar("B", ImGuiDataType_U64, &b) || hasChanged;
// Update results when input changed
if (hasChanged) {
// Detect overflow
const u64 multiplicationResult = a * b;
if (a != 0 && multiplicationResult / a != b) {
gcdResult = 0;
lcmResult = 0;
p = 0;
q = 0;
overflow = true;
} else {
gcdResult = std::gcd<i128, i128>(a, b);
lcmResult = std::lcm<i128, i128>(a, b);
std::tie(p, q) = extendedGcd(a, b);
overflow = false;
}
}
ImGui::Separator();
ImGui::PushStyleVar(ImGuiStyleVar_Alpha, ImGui::GetStyle().DisabledAlpha);
ImGui::InputScalar("gcd(A, B)", ImGuiDataType_S64, &gcdResult, nullptr, nullptr, "%llu", ImGuiInputTextFlags_ReadOnly);
ImGui::Indent();
ImGuiExt::TextFormatted(ICON_VS_ARROW_RIGHT " a \u00D7 p + b \u00D7 q = ({0}) \u00D7 ({1}) + ({2}) \u00D7 ({3})", a, p, b, q);
ImGui::Unindent();
ImGui::InputScalar("lcm(A, B)", ImGuiDataType_S64, &lcmResult, nullptr, nullptr, "%llu", ImGuiInputTextFlags_ReadOnly);
ImGui::PopStyleVar();
ImGuiExt::EndBox();
std::tie(x, xLast) = std::tuple { xLast, x - quotient * xLast };
std::tie(y, yLast) = std::tuple { yLast, y - quotient * yLast };
std::tie(a, b) = std::tuple { b, a - quotient * b };
}
if (overflow)
ImGuiExt::TextFormattedColored(ImGuiExt::GetCustomColorVec4(ImGuiCustomCol_ToolbarRed), "{}", "hex.builtin.tools.euclidean_algorithm.overflow"_lang);
else
ImGui::NewLine();
return { x, y };
};
ImGuiExt::TextFormattedWrapped("{}", "hex.builtin.tools.euclidean_algorithm.description"_lang);
ImGui::NewLine();
if (ImGuiExt::BeginBox()) {
bool hasChanged = false;
hasChanged = ImGui::InputScalar("A", ImGuiDataType_U64, &a) || hasChanged;
hasChanged = ImGui::InputScalar("B", ImGuiDataType_U64, &b) || hasChanged;
// Update results when input changed
if (hasChanged) {
// Detect overflow
const u64 multiplicationResult = a * b;
if (a != 0 && multiplicationResult / a != b) {
gcdResult = 0;
lcmResult = 0;
p = 0;
q = 0;
overflow = true;
} else {
gcdResult = std::gcd<i128, i128>(a, b);
lcmResult = std::lcm<i128, i128>(a, b);
std::tie(p, q) = extendedGcd(a, b);
overflow = false;
}
}
ImGui::Separator();
ImGui::PushStyleVar(ImGuiStyleVar_Alpha, ImGui::GetStyle().DisabledAlpha);
ImGui::InputScalar("gcd(A, B)", ImGuiDataType_S64, &gcdResult, nullptr, nullptr, "%llu", ImGuiInputTextFlags_ReadOnly);
ImGui::Indent();
ImGuiExt::TextFormatted(ICON_VS_ARROW_RIGHT " a \u00D7 p + b \u00D7 q = ({0}) \u00D7 ({1}) + ({2}) \u00D7 ({3})", a, p, b, q);
ImGui::Unindent();
ImGui::InputScalar("lcm(A, B)", ImGuiDataType_S64, &lcmResult, nullptr, nullptr, "%llu", ImGuiInputTextFlags_ReadOnly);
ImGui::PopStyleVar();
ImGuiExt::EndBox();
}
if (overflow)
ImGuiExt::TextFormattedColored(ImGuiExt::GetCustomColorVec4(ImGuiCustomCol_ToolbarRed), "{}", "hex.builtin.tools.euclidean_algorithm.overflow"_lang);
else
ImGui::NewLine();
}
}

View File

@ -14,140 +14,140 @@
#include <wolv/io/file.hpp>
namespace hex::plugin::builtin {
namespace impl {
void drawFileToolCombiner() {
static std::vector<std::fs::path> files;
static std::u8string outputPath;
static u32 selectedIndex;
static TaskHolder combinerTask;
if (ImGui::BeginTable("files_table", 2, ImGuiTableFlags_SizingStretchProp)) {
ImGui::TableSetupColumn("file list", ImGuiTableColumnFlags_NoHeaderLabel, 10);
ImGui::TableSetupColumn("buttons", ImGuiTableColumnFlags_NoHeaderLabel, 1);
ImGui::TableNextRow();
ImGui::TableNextColumn();
void drawFileToolCombiner() {
static std::vector<std::fs::path> files;
static std::u8string outputPath;
static u32 selectedIndex;
static TaskHolder combinerTask;
if (ImGui::BeginListBox("##files", { -FLT_MIN, 10 * ImGui::GetTextLineHeightWithSpacing() })) {
u32 index = 0;
for (auto &file : files) {
if (ImGui::Selectable(wolv::util::toUTF8String(file).c_str(), index == selectedIndex))
selectedIndex = index;
index++;
}
if (ImGui::BeginTable("files_table", 2, ImGuiTableFlags_SizingStretchProp)) {
ImGui::TableSetupColumn("file list", ImGuiTableColumnFlags_NoHeaderLabel, 10);
ImGui::TableSetupColumn("buttons", ImGuiTableColumnFlags_NoHeaderLabel, 1);
ImGui::TableNextRow();
ImGui::TableNextColumn();
ImGui::EndListBox();
if (ImGui::BeginListBox("##files", { -FLT_MIN, 10 * ImGui::GetTextLineHeightWithSpacing() })) {
u32 index = 0;
for (auto &file : files) {
if (ImGui::Selectable(wolv::util::toUTF8String(file).c_str(), index == selectedIndex))
selectedIndex = index;
index++;
}
ImGui::TableNextColumn();
ImGui::BeginDisabled(selectedIndex <= 0);
{
if (ImGui::ArrowButton("move_up", ImGuiDir_Up)) {
std::iter_swap(files.begin() + selectedIndex, files.begin() + selectedIndex - 1);
selectedIndex--;
}
}
ImGui::EndDisabled();
ImGui::BeginDisabled(files.empty() || selectedIndex >= files.size() - 1);
{
if (ImGui::ArrowButton("move_down", ImGuiDir_Down)) {
std::iter_swap(files.begin() + selectedIndex, files.begin() + selectedIndex + 1);
selectedIndex++;
}
}
ImGui::EndDisabled();
ImGui::TableNextRow();
ImGui::TableNextColumn();
ImGui::BeginDisabled(combinerTask.isRunning());
{
if (ImGui::Button("hex.builtin.tools.file_tools.combiner.add"_lang)) {
fs::openFileBrowser(fs::DialogMode::Open, {}, [](const auto &path) {
files.push_back(path);
}, "", true);
}
ImGui::SameLine();
ImGui::BeginDisabled(files.empty() || selectedIndex >= files.size());
if (ImGui::Button("hex.builtin.tools.file_tools.combiner.delete"_lang)) {
files.erase(files.begin() + selectedIndex);
if (selectedIndex > 0)
selectedIndex--;
}
ImGui::EndDisabled();
ImGui::SameLine();
ImGui::BeginDisabled(files.empty());
if (ImGui::Button("hex.builtin.tools.file_tools.combiner.clear"_lang)) {
files.clear();
}
ImGui::EndDisabled();
}
ImGui::EndDisabled();
ImGui::EndTable();
ImGui::EndListBox();
}
ImGui::TableNextColumn();
ImGui::BeginDisabled(selectedIndex <= 0);
{
if (ImGui::ArrowButton("move_up", ImGuiDir_Up)) {
std::iter_swap(files.begin() + selectedIndex, files.begin() + selectedIndex - 1);
selectedIndex--;
}
}
ImGui::EndDisabled();
ImGui::BeginDisabled(files.empty() || selectedIndex >= files.size() - 1);
{
if (ImGui::ArrowButton("move_down", ImGuiDir_Down)) {
std::iter_swap(files.begin() + selectedIndex, files.begin() + selectedIndex + 1);
selectedIndex++;
}
}
ImGui::EndDisabled();
ImGui::TableNextRow();
ImGui::TableNextColumn();
ImGui::BeginDisabled(combinerTask.isRunning());
{
ImGui::InputText("##output_path", outputPath);
ImGui::SameLine();
if (ImGui::Button("...")) {
fs::openFileBrowser(fs::DialogMode::Save, {}, [](const auto &path) {
outputPath = path.u8string();
});
if (ImGui::Button("hex.builtin.tools.file_tools.combiner.add"_lang)) {
fs::openFileBrowser(fs::DialogMode::Open, {}, [](const auto &path) {
files.push_back(path);
}, "", true);
}
ImGui::SameLine();
ImGui::TextUnformatted("hex.builtin.tools.file_tools.combiner.output"_lang);
ImGui::BeginDisabled(files.empty() || selectedIndex >= files.size());
if (ImGui::Button("hex.builtin.tools.file_tools.combiner.delete"_lang)) {
files.erase(files.begin() + selectedIndex);
if (selectedIndex > 0)
selectedIndex--;
}
ImGui::EndDisabled();
ImGui::SameLine();
ImGui::BeginDisabled(files.empty());
if (ImGui::Button("hex.builtin.tools.file_tools.combiner.clear"_lang)) {
files.clear();
}
ImGui::EndDisabled();
}
ImGui::EndDisabled();
ImGui::BeginDisabled(files.empty() || outputPath.empty());
{
if (combinerTask.isRunning())
ImGuiExt::TextSpinner("hex.builtin.tools.file_tools.combiner.combining"_lang);
else {
if (ImGui::Button("hex.builtin.tools.file_tools.combiner.combine"_lang)) {
combinerTask = TaskManager::createTask("hex.builtin.tools.file_tools.combiner.combining", 0, [](auto &task) {
wolv::io::File output(outputPath, wolv::io::File::Mode::Create);
ImGui::EndTable();
}
if (!output.isValid()) {
PopupError::open("hex.builtin.tools.file_tools.combiner.error.open_output"_lang);
ImGui::BeginDisabled(combinerTask.isRunning());
{
ImGui::InputText("##output_path", outputPath);
ImGui::SameLine();
if (ImGui::Button("...")) {
fs::openFileBrowser(fs::DialogMode::Save, {}, [](const auto &path) {
outputPath = path.u8string();
});
}
ImGui::SameLine();
ImGui::TextUnformatted("hex.builtin.tools.file_tools.combiner.output"_lang);
}
ImGui::EndDisabled();
ImGui::BeginDisabled(files.empty() || outputPath.empty());
{
if (combinerTask.isRunning())
ImGuiExt::TextSpinner("hex.builtin.tools.file_tools.combiner.combining"_lang);
else {
if (ImGui::Button("hex.builtin.tools.file_tools.combiner.combine"_lang)) {
combinerTask = TaskManager::createTask("hex.builtin.tools.file_tools.combiner.combining", 0, [](auto &task) {
wolv::io::File output(outputPath, wolv::io::File::Mode::Create);
if (!output.isValid()) {
PopupError::open("hex.builtin.tools.file_tools.combiner.error.open_output"_lang);
return;
}
task.setMaxValue(files.size());
u64 fileIndex = 0;
for (const auto &file : files) {
task.update(fileIndex);
fileIndex++;
wolv::io::File input(file, wolv::io::File::Mode::Read);
if (!input.isValid()) {
PopupError::open(hex::format("hex.builtin.tools.file_tools.combiner.open_input"_lang, wolv::util::toUTF8String(file)));
return;
}
task.setMaxValue(files.size());
u64 fileIndex = 0;
for (const auto &file : files) {
task.update(fileIndex);
fileIndex++;
wolv::io::File input(file, wolv::io::File::Mode::Read);
if (!input.isValid()) {
PopupError::open(hex::format("hex.builtin.tools.file_tools.combiner.open_input"_lang, wolv::util::toUTF8String(file)));
return;
}
constexpr static auto BufferSize = 0xFF'FFFF;
auto inputSize = input.getSize();
for (u64 inputOffset = 0; inputOffset < inputSize; inputOffset += BufferSize) {
output.writeVector(input.readVector(std::min<u64>(BufferSize, inputSize - inputOffset)));
output.flush();
}
constexpr static auto BufferSize = 0xFF'FFFF;
auto inputSize = input.getSize();
for (u64 inputOffset = 0; inputOffset < inputSize; inputOffset += BufferSize) {
output.writeVector(input.readVector(std::min<u64>(BufferSize, inputSize - inputOffset)));
output.flush();
}
}
files.clear();
selectedIndex = 0;
outputPath.clear();
files.clear();
selectedIndex = 0;
outputPath.clear();
PopupInfo::open("hex.builtin.tools.file_tools.combiner.success"_lang);
});
}
PopupInfo::open("hex.builtin.tools.file_tools.combiner.success"_lang);
});
}
}
ImGui::EndDisabled();
}
ImGui::EndDisabled();
}
}

View File

@ -13,127 +13,127 @@
#include <wolv/utils/guards.hpp>
namespace hex::plugin::builtin {
namespace impl {
void drawFileToolShredder() {
static std::u8string selectedFile;
static bool fastMode = false;
static TaskHolder shredderTask;
ImGui::TextUnformatted("hex.builtin.tools.file_tools.shredder.warning"_lang);
ImGui::NewLine();
void drawFileToolShredder() {
static std::u8string selectedFile;
static bool fastMode = false;
static TaskHolder shredderTask;
if (ImGui::BeginChild("settings", { 0, ImGui::GetTextLineHeightWithSpacing() * 4 }, true, ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoScrollWithMouse)) {
ImGui::BeginDisabled(shredderTask.isRunning());
{
ImGui::TextUnformatted("hex.builtin.tools.file_tools.shredder.input"_lang);
ImGui::SameLine();
ImGui::InputText("##path", selectedFile);
ImGui::SameLine();
if (ImGui::Button("...")) {
fs::openFileBrowser(fs::DialogMode::Open, {}, [](const auto &path) {
selectedFile = path.u8string();
});
}
ImGui::TextUnformatted("hex.builtin.tools.file_tools.shredder.warning"_lang);
ImGui::NewLine();
ImGui::Checkbox("hex.builtin.tools.file_tools.shredder.fast"_lang, &fastMode);
if (ImGui::BeginChild("settings", { 0, ImGui::GetTextLineHeightWithSpacing() * 4 }, true, ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoScrollWithMouse)) {
ImGui::BeginDisabled(shredderTask.isRunning());
{
ImGui::TextUnformatted("hex.builtin.tools.file_tools.shredder.input"_lang);
ImGui::SameLine();
ImGui::InputText("##path", selectedFile);
ImGui::SameLine();
if (ImGui::Button("...")) {
fs::openFileBrowser(fs::DialogMode::Open, {}, [](const auto &path) {
selectedFile = path.u8string();
});
}
ImGui::EndDisabled();
}
ImGui::EndChild();
if (shredderTask.isRunning())
ImGuiExt::TextSpinner("hex.builtin.tools.file_tools.shredder.shredding"_lang);
else {
ImGui::BeginDisabled(selectedFile.empty());
{
if (ImGui::Button("hex.builtin.tools.file_tools.shredder.shred"_lang)) {
shredderTask = TaskManager::createTask("hex.builtin.tools.file_tools.shredder.shredding", 0, [](auto &task) {
ON_SCOPE_EXIT {
selectedFile.clear();
ImGui::Checkbox("hex.builtin.tools.file_tools.shredder.fast"_lang, &fastMode);
}
ImGui::EndDisabled();
}
ImGui::EndChild();
if (shredderTask.isRunning())
ImGuiExt::TextSpinner("hex.builtin.tools.file_tools.shredder.shredding"_lang);
else {
ImGui::BeginDisabled(selectedFile.empty());
{
if (ImGui::Button("hex.builtin.tools.file_tools.shredder.shred"_lang)) {
shredderTask = TaskManager::createTask("hex.builtin.tools.file_tools.shredder.shredding", 0, [](auto &task) {
ON_SCOPE_EXIT {
selectedFile.clear();
};
wolv::io::File file(selectedFile, wolv::io::File::Mode::Write);
if (!file.isValid()) {
PopupError::open("hex.builtin.tools.file_tools.shredder.error.open"_lang);
return;
}
task.setMaxValue(file.getSize());
std::vector<std::array<u8, 3>> overwritePattern;
if (fastMode) {
/* Should be sufficient for modern disks */
overwritePattern.push_back({ 0x00, 0x00, 0x00 });
overwritePattern.push_back({ 0xFF, 0xFF, 0xFF });
} else {
/* Gutmann's method. Secure for magnetic storage */
std::random_device rd;
std::uniform_int_distribution<u8> dist(0x00, 0xFF);
/* Fill fixed patterns */
overwritePattern = {
{ },
{ },
{},
{},
{ 0x55, 0x55, 0x55 },
{ 0xAA, 0xAA, 0xAA },
{ 0x92, 0x49, 0x24 },
{ 0x49, 0x24, 0x92 },
{ 0x24, 0x92, 0x49 },
{ 0x00, 0x00, 0x00 },
{ 0x11, 0x11, 0x11 },
{ 0x22, 0x22, 0x22 },
{ 0x33, 0x33, 0x44 },
{ 0x55, 0x55, 0x55 },
{ 0x66, 0x66, 0x66 },
{ 0x77, 0x77, 0x77 },
{ 0x88, 0x88, 0x88 },
{ 0x99, 0x99, 0x99 },
{ 0xAA, 0xAA, 0xAA },
{ 0xBB, 0xBB, 0xBB },
{ 0xCC, 0xCC, 0xCC },
{ 0xDD, 0xDD, 0xDD },
{ 0xEE, 0xEE, 0xEE },
{ 0xFF, 0xFF, 0xFF },
{ 0x92, 0x49, 0x24 },
{ 0x49, 0x24, 0x92 },
{ 0x24, 0x92, 0x49 },
{ 0x6D, 0xB6, 0xDB },
{ 0xB6, 0xDB, 0x6D },
{ 0xBD, 0x6D, 0xB6 },
{},
{},
{},
{}
};
wolv::io::File file(selectedFile, wolv::io::File::Mode::Write);
if (!file.isValid()) {
PopupError::open("hex.builtin.tools.file_tools.shredder.error.open"_lang);
return;
/* Fill random patterns */
for (u8 i = 0; i < 4; i++)
overwritePattern[i] = { dist(rd), dist(rd), dist(rd) };
for (u8 i = 0; i < 4; i++)
overwritePattern[overwritePattern.size() - 1 - i] = { dist(rd), dist(rd), dist(rd) };
}
size_t fileSize = file.getSize();
for (const auto &pattern : overwritePattern) {
for (u64 offset = 0; offset < fileSize; offset += 3) {
file.writeBuffer(pattern.data(), std::min<u64>(pattern.size(), fileSize - offset));
task.update(offset);
}
task.setMaxValue(file.getSize());
file.flush();
}
std::vector<std::array<u8, 3>> overwritePattern;
if (fastMode) {
/* Should be sufficient for modern disks */
overwritePattern.push_back({ 0x00, 0x00, 0x00 });
overwritePattern.push_back({ 0xFF, 0xFF, 0xFF });
} else {
/* Gutmann's method. Secure for magnetic storage */
std::random_device rd;
std::uniform_int_distribution<u8> dist(0x00, 0xFF);
file.remove();
/* Fill fixed patterns */
overwritePattern = {
{ },
{ },
{},
{},
{ 0x55, 0x55, 0x55 },
{ 0xAA, 0xAA, 0xAA },
{ 0x92, 0x49, 0x24 },
{ 0x49, 0x24, 0x92 },
{ 0x24, 0x92, 0x49 },
{ 0x00, 0x00, 0x00 },
{ 0x11, 0x11, 0x11 },
{ 0x22, 0x22, 0x22 },
{ 0x33, 0x33, 0x44 },
{ 0x55, 0x55, 0x55 },
{ 0x66, 0x66, 0x66 },
{ 0x77, 0x77, 0x77 },
{ 0x88, 0x88, 0x88 },
{ 0x99, 0x99, 0x99 },
{ 0xAA, 0xAA, 0xAA },
{ 0xBB, 0xBB, 0xBB },
{ 0xCC, 0xCC, 0xCC },
{ 0xDD, 0xDD, 0xDD },
{ 0xEE, 0xEE, 0xEE },
{ 0xFF, 0xFF, 0xFF },
{ 0x92, 0x49, 0x24 },
{ 0x49, 0x24, 0x92 },
{ 0x24, 0x92, 0x49 },
{ 0x6D, 0xB6, 0xDB },
{ 0xB6, 0xDB, 0x6D },
{ 0xBD, 0x6D, 0xB6 },
{},
{},
{},
{}
};
/* Fill random patterns */
for (u8 i = 0; i < 4; i++)
overwritePattern[i] = { dist(rd), dist(rd), dist(rd) };
for (u8 i = 0; i < 4; i++)
overwritePattern[overwritePattern.size() - 1 - i] = { dist(rd), dist(rd), dist(rd) };
}
size_t fileSize = file.getSize();
for (const auto &pattern : overwritePattern) {
for (u64 offset = 0; offset < fileSize; offset += 3) {
file.writeBuffer(pattern.data(), std::min<u64>(pattern.size(), fileSize - offset));
task.update(offset);
}
file.flush();
}
file.remove();
PopupInfo::open("hex.builtin.tools.file_tools.shredder.success"_lang);
});
}
PopupInfo::open("hex.builtin.tools.file_tools.shredder.success"_lang);
});
}
ImGui::EndDisabled();
}
ImGui::EndDisabled();
}
}
}

View File

@ -15,132 +15,132 @@
#include <wolv/utils/guards.hpp>
namespace hex::plugin::builtin {
namespace impl {
using namespace hex::literals;
void drawFileToolSplitter() {
std::array sizeText = {
static_cast<const char*>("hex.builtin.tools.file_tools.splitter.sizes.5_75_floppy"_lang),
static_cast<const char*>("hex.builtin.tools.file_tools.splitter.sizes.3_5_floppy"_lang),
static_cast<const char*>("hex.builtin.tools.file_tools.splitter.sizes.zip100"_lang),
static_cast<const char*>("hex.builtin.tools.file_tools.splitter.sizes.zip200"_lang),
static_cast<const char*>("hex.builtin.tools.file_tools.splitter.sizes.cdrom650"_lang),
static_cast<const char*>("hex.builtin.tools.file_tools.splitter.sizes.cdrom700"_lang),
static_cast<const char*>("hex.builtin.tools.file_tools.splitter.sizes.fat32"_lang),
static_cast<const char*>("hex.builtin.tools.file_tools.splitter.sizes.custom"_lang)
};
std::array<u64, sizeText.size()> sizes = {
1200_KiB,
1400_KiB,
100_MiB,
200_MiB,
650_MiB,
700_MiB,
4_GiB,
1
};
using namespace hex::literals;
static std::u8string selectedFile;
static std::u8string baseOutputPath;
static u64 splitSize = sizes[0];
static int selectedItem = 0;
static TaskHolder splitterTask;
void drawFileToolSplitter() {
std::array sizeText = {
static_cast<const char*>("hex.builtin.tools.file_tools.splitter.sizes.5_75_floppy"_lang),
static_cast<const char*>("hex.builtin.tools.file_tools.splitter.sizes.3_5_floppy"_lang),
static_cast<const char*>("hex.builtin.tools.file_tools.splitter.sizes.zip100"_lang),
static_cast<const char*>("hex.builtin.tools.file_tools.splitter.sizes.zip200"_lang),
static_cast<const char*>("hex.builtin.tools.file_tools.splitter.sizes.cdrom650"_lang),
static_cast<const char*>("hex.builtin.tools.file_tools.splitter.sizes.cdrom700"_lang),
static_cast<const char*>("hex.builtin.tools.file_tools.splitter.sizes.fat32"_lang),
static_cast<const char*>("hex.builtin.tools.file_tools.splitter.sizes.custom"_lang)
};
std::array<u64, sizeText.size()> sizes = {
1200_KiB,
1400_KiB,
100_MiB,
200_MiB,
650_MiB,
700_MiB,
4_GiB,
1
};
if (ImGui::BeginChild("split_settings", { 0, ImGui::GetTextLineHeightWithSpacing() * 7 }, true, ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoScrollWithMouse)) {
ImGui::BeginDisabled(splitterTask.isRunning());
{
ImGui::InputText("##path", selectedFile);
ImGui::SameLine();
if (ImGui::Button("...##input")) {
fs::openFileBrowser(fs::DialogMode::Open, {}, [](const auto &path) {
selectedFile = path.u8string();
});
}
ImGui::SameLine();
ImGui::TextUnformatted("hex.builtin.tools.file_tools.splitter.input"_lang);
static std::u8string selectedFile;
static std::u8string baseOutputPath;
static u64 splitSize = sizes[0];
static int selectedItem = 0;
static TaskHolder splitterTask;
ImGui::InputText("##base_path", baseOutputPath);
ImGui::SameLine();
if (ImGui::Button("...##output")) {
fs::openFileBrowser(fs::DialogMode::Save, {}, [](const auto &path) {
baseOutputPath = path.u8string();
});
}
ImGui::SameLine();
ImGui::TextUnformatted("hex.builtin.tools.file_tools.splitter.output"_lang);
ImGui::Separator();
if (ImGui::Combo("###part_size", &selectedItem, sizeText.data(), sizeText.size())) {
splitSize = sizes[selectedItem];
}
}
ImGui::EndDisabled();
ImGui::BeginDisabled(splitterTask.isRunning() || selectedItem != sizes.size() - 1);
{
ImGui::InputScalar("###custom_size", ImGuiDataType_U64, &splitSize);
ImGui::SameLine();
ImGui::TextUnformatted("Bytes");
}
ImGui::EndDisabled();
}
ImGui::EndChild();
ImGui::BeginDisabled(selectedFile.empty() || baseOutputPath.empty() || splitSize == 0);
if (ImGui::BeginChild("split_settings", { 0, ImGui::GetTextLineHeightWithSpacing() * 7 }, true, ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoScrollWithMouse)) {
ImGui::BeginDisabled(splitterTask.isRunning());
{
if (splitterTask.isRunning())
ImGuiExt::TextSpinner("hex.builtin.tools.file_tools.splitter.picker.splitting"_lang);
else {
if (ImGui::Button("hex.builtin.tools.file_tools.splitter.picker.split"_lang)) {
splitterTask = TaskManager::createTask("hex.builtin.tools.file_tools.splitter.picker.splitting", 0, [](auto &task) {
ON_SCOPE_EXIT {
selectedFile.clear();
baseOutputPath.clear();
};
ImGui::InputText("##path", selectedFile);
ImGui::SameLine();
if (ImGui::Button("...##input")) {
fs::openFileBrowser(fs::DialogMode::Open, {}, [](const auto &path) {
selectedFile = path.u8string();
});
}
ImGui::SameLine();
ImGui::TextUnformatted("hex.builtin.tools.file_tools.splitter.input"_lang);
wolv::io::File file(selectedFile, wolv::io::File::Mode::Read);
ImGui::InputText("##base_path", baseOutputPath);
ImGui::SameLine();
if (ImGui::Button("...##output")) {
fs::openFileBrowser(fs::DialogMode::Save, {}, [](const auto &path) {
baseOutputPath = path.u8string();
});
}
ImGui::SameLine();
ImGui::TextUnformatted("hex.builtin.tools.file_tools.splitter.output"_lang);
if (!file.isValid()) {
PopupError::open("hex.builtin.tools.file_tools.splitter.picker.error.open"_lang);
return;
}
ImGui::Separator();
if (file.getSize() < splitSize) {
PopupError::open("hex.builtin.tools.file_tools.splitter.picker.error.size"_lang);
return;
}
task.setMaxValue(file.getSize());
u32 index = 1;
for (u64 offset = 0; offset < file.getSize(); offset += splitSize) {
task.update(offset);
std::fs::path path = baseOutputPath;
path += hex::format(".{:05}", index);
wolv::io::File partFile(path, wolv::io::File::Mode::Create);
if (!partFile.isValid()) {
PopupError::open(hex::format("hex.builtin.tools.file_tools.splitter.picker.error.create"_lang, index));
return;
}
constexpr static auto BufferSize = 0xFF'FFFF;
for (u64 partOffset = 0; partOffset < splitSize; partOffset += BufferSize) {
partFile.writeVector(file.readVector(std::min<u64>(BufferSize, splitSize - partOffset)));
partFile.flush();
}
index++;
}
PopupInfo::open("hex.builtin.tools.file_tools.splitter.picker.success"_lang);
});
}
if (ImGui::Combo("###part_size", &selectedItem, sizeText.data(), sizeText.size())) {
splitSize = sizes[selectedItem];
}
}
ImGui::EndDisabled();
ImGui::BeginDisabled(splitterTask.isRunning() || selectedItem != sizes.size() - 1);
{
ImGui::InputScalar("###custom_size", ImGuiDataType_U64, &splitSize);
ImGui::SameLine();
ImGui::TextUnformatted("Bytes");
}
ImGui::EndDisabled();
}
ImGui::EndChild();
ImGui::BeginDisabled(selectedFile.empty() || baseOutputPath.empty() || splitSize == 0);
{
if (splitterTask.isRunning())
ImGuiExt::TextSpinner("hex.builtin.tools.file_tools.splitter.picker.splitting"_lang);
else {
if (ImGui::Button("hex.builtin.tools.file_tools.splitter.picker.split"_lang)) {
splitterTask = TaskManager::createTask("hex.builtin.tools.file_tools.splitter.picker.splitting", 0, [](auto &task) {
ON_SCOPE_EXIT {
selectedFile.clear();
baseOutputPath.clear();
};
wolv::io::File file(selectedFile, wolv::io::File::Mode::Read);
if (!file.isValid()) {
PopupError::open("hex.builtin.tools.file_tools.splitter.picker.error.open"_lang);
return;
}
if (file.getSize() < splitSize) {
PopupError::open("hex.builtin.tools.file_tools.splitter.picker.error.size"_lang);
return;
}
task.setMaxValue(file.getSize());
u32 index = 1;
for (u64 offset = 0; offset < file.getSize(); offset += splitSize) {
task.update(offset);
std::fs::path path = baseOutputPath;
path += hex::format(".{:05}", index);
wolv::io::File partFile(path, wolv::io::File::Mode::Create);
if (!partFile.isValid()) {
PopupError::open(hex::format("hex.builtin.tools.file_tools.splitter.picker.error.create"_lang, index));
return;
}
constexpr static auto BufferSize = 0xFF'FFFF;
for (u64 partOffset = 0; partOffset < splitSize; partOffset += BufferSize) {
partFile.writeVector(file.readVector(std::min<u64>(BufferSize, splitSize - partOffset)));
partFile.flush();
}
index++;
}
PopupInfo::open("hex.builtin.tools.file_tools.splitter.picker.success"_lang);
});
}
}
}
ImGui::EndDisabled();
}
}

View File

@ -1,96 +1,95 @@
namespace hex::plugin::builtin {
namespace impl {
/*void drawFileUploader() {
struct UploadedFile {
std::string fileName, link, size;
};
/*void drawFileUploader() {
struct UploadedFile {
std::string fileName, link, size;
};
static HttpRequest request("POST", "https://api.anonfiles.com/upload");
static std::future<HttpRequest::Result<std::string>> uploadProcess;
static std::fs::path currFile;
static std::vector<UploadedFile> links;
static HttpRequest request("POST", "https://api.anonfiles.com/upload");
static std::future<HttpRequest::Result<std::string>> uploadProcess;
static std::fs::path currFile;
static std::vector<UploadedFile> links;
bool uploading = uploadProcess.valid() && uploadProcess.wait_for(0s) != std::future_status::ready;
bool uploading = uploadProcess.valid() && uploadProcess.wait_for(0s) != std::future_status::ready;
ImGuiExt::Header("hex.builtin.tools.file_uploader.control"_lang, true);
if (!uploading) {
if (ImGui::Button("hex.builtin.tools.file_uploader.upload"_lang)) {
fs::openFileBrowser(fs::DialogMode::Open, {}, [&](auto path) {
uploadProcess = request.uploadFile(path);
currFile = path;
ImGuiExt::Header("hex.builtin.tools.file_uploader.control"_lang, true);
if (!uploading) {
if (ImGui::Button("hex.builtin.tools.file_uploader.upload"_lang)) {
fs::openFileBrowser(fs::DialogMode::Open, {}, [&](auto path) {
uploadProcess = request.uploadFile(path);
currFile = path;
});
}
} else {
if (ImGui::Button("hex.builtin.common.cancel"_lang)) {
request.cancel();
}
}
ImGui::SameLine();
ImGui::ProgressBar(request.getProgress(), ImVec2(0, 0), uploading ? nullptr : "Done!");
ImGuiExt::Header("hex.builtin.tools.file_uploader.recent"_lang);
if (ImGui::BeginTable("##links", 3, ImGuiTableFlags_ScrollY | ImGuiTableFlags_Borders | ImGuiTableFlags_Resizable | ImGuiTableFlags_RowBg, ImVec2(0, 200))) {
ImGui::TableSetupColumn("hex.builtin.common.file"_lang);
ImGui::TableSetupColumn("hex.builtin.common.link"_lang);
ImGui::TableSetupColumn("hex.builtin.common.size"_lang);
ImGui::TableSetupScrollFreeze(0, 1);
ImGui::TableHeadersRow();
ImGuiListClipper clipper;
clipper.Begin(links.size());
while (clipper.Step()) {
for (i32 i = clipper.DisplayEnd - 1; i >= clipper.DisplayStart; i--) {
auto &[fileName, link, size] = links[i];
ImGui::TableNextRow();
ImGui::TableNextColumn();
ImGui::TextUnformatted(fileName.c_str());
ImGui::TableNextColumn();
if (ImGuiExt::Hyperlink(link.c_str())) {
if (ImGui::IsKeyDown(ImGuiKey_LeftCtrl))
hex::openWebpage(link);
else
ImGui::SetClipboardText(link.c_str());
}
ImGuiExt::InfoTooltip("hex.builtin.tools.file_uploader.tooltip"_lang);
ImGui::TableNextColumn();
ImGui::TextUnformatted(size.c_str());
}
}
clipper.End();
ImGui::EndTable();
}
if (uploadProcess.valid() && uploadProcess.wait_for(0s) == std::future_status::ready) {
auto response = uploadProcess.get();
if (response.getStatusCode() == 200) {
try {
auto json = nlohmann::json::parse(response.getData());
links.push_back({
wolv::util::toUTF8String(currFile.filename()),
json.at("data").at("file").at("url").at("short"),
json.at("data").at("file").at("metadata").at("size").at("readable")
});
} catch (...) {
PopupError::open("hex.builtin.tools.file_uploader.invalid_response"_lang);
}
} else {
if (ImGui::Button("hex.builtin.common.cancel"_lang)) {
request.cancel();
}
}
} else if (response.getStatusCode() == 0) {
// Canceled by user, no action needed
} else PopupError::open(hex::format("hex.builtin.tools.file_uploader.error"_lang, response.getStatusCode()));
ImGui::SameLine();
uploadProcess = {};
currFile.clear();
}
}*/
ImGui::ProgressBar(request.getProgress(), ImVec2(0, 0), uploading ? nullptr : "Done!");
ImGuiExt::Header("hex.builtin.tools.file_uploader.recent"_lang);
if (ImGui::BeginTable("##links", 3, ImGuiTableFlags_ScrollY | ImGuiTableFlags_Borders | ImGuiTableFlags_Resizable | ImGuiTableFlags_RowBg, ImVec2(0, 200))) {
ImGui::TableSetupColumn("hex.builtin.common.file"_lang);
ImGui::TableSetupColumn("hex.builtin.common.link"_lang);
ImGui::TableSetupColumn("hex.builtin.common.size"_lang);
ImGui::TableSetupScrollFreeze(0, 1);
ImGui::TableHeadersRow();
ImGuiListClipper clipper;
clipper.Begin(links.size());
while (clipper.Step()) {
for (i32 i = clipper.DisplayEnd - 1; i >= clipper.DisplayStart; i--) {
auto &[fileName, link, size] = links[i];
ImGui::TableNextRow();
ImGui::TableNextColumn();
ImGui::TextUnformatted(fileName.c_str());
ImGui::TableNextColumn();
if (ImGuiExt::Hyperlink(link.c_str())) {
if (ImGui::IsKeyDown(ImGuiKey_LeftCtrl))
hex::openWebpage(link);
else
ImGui::SetClipboardText(link.c_str());
}
ImGuiExt::InfoTooltip("hex.builtin.tools.file_uploader.tooltip"_lang);
ImGui::TableNextColumn();
ImGui::TextUnformatted(size.c_str());
}
}
clipper.End();
ImGui::EndTable();
}
if (uploadProcess.valid() && uploadProcess.wait_for(0s) == std::future_status::ready) {
auto response = uploadProcess.get();
if (response.getStatusCode() == 200) {
try {
auto json = nlohmann::json::parse(response.getData());
links.push_back({
wolv::util::toUTF8String(currFile.filename()),
json.at("data").at("file").at("url").at("short"),
json.at("data").at("file").at("metadata").at("size").at("readable")
});
} catch (...) {
PopupError::open("hex.builtin.tools.file_uploader.invalid_response"_lang);
}
} else if (response.getStatusCode() == 0) {
// Canceled by user, no action needed
} else PopupError::open(hex::format("hex.builtin.tools.file_uploader.error"_lang, response.getStatusCode()));
uploadProcess = {};
currFile.clear();
}
}*/
}
}

View File

@ -1,77 +1,70 @@
#include <hex/helpers/http_requests.hpp>
#include <hex/ui/view.hpp>
#include <regex>
#include <llvm/Demangle/Demangle.h>
#include <content/helpers/math_evaluator.hpp>
#include <content/tools_entries.hpp>
#include <imgui.h>
#include <implot.h>
#include <hex/ui/imgui_imhex_extensions.h>
#include <wolv/net/socket_server.hpp>
#include <fonts/codicons_font.h>
namespace hex::plugin::builtin {
namespace impl {
void drawGraphingCalculator() {
static std::array<long double, 1000> x, y;
static std::string mathInput;
static ImPlotRect limits;
static double prevPos = 0;
static long double stepSize = 0.1;
if (ImPlot::BeginPlot("Function", ImVec2(-1, 0), ImPlotFlags_NoTitle | ImPlotFlags_NoMenus | ImPlotFlags_NoBoxSelect | ImPlotFlags_NoMouseText | ImPlotFlags_NoFrame)) {
ImPlot::SetupAxesLimits(-10, 10, -5, 5, ImPlotCond_Once);
void drawGraphingCalculator() {
static std::array<long double, 1000> x, y;
static std::string mathInput;
static ImPlotRect limits;
static double prevPos = 0;
static long double stepSize = 0.1;
limits = ImPlot::GetPlotLimits(ImAxis_X1, ImAxis_Y1);
if (ImPlot::BeginPlot("Function", ImVec2(-1, 0), ImPlotFlags_NoTitle | ImPlotFlags_NoMenus | ImPlotFlags_NoBoxSelect | ImPlotFlags_NoMouseText | ImPlotFlags_NoFrame)) {
ImPlot::SetupAxesLimits(-10, 10, -5, 5, ImPlotCond_Once);
ImPlot::PlotLine("f(x)", x.data(), y.data(), x.size());
ImPlot::EndPlot();
}
ImGui::PushItemWidth(-1);
ImGuiExt::InputTextIcon("##graphing_math_input", ICON_VS_SYMBOL_OPERATOR, mathInput, ImGuiInputTextFlags_EnterReturnsTrue | ImGuiInputTextFlags_AutoSelectAll);
ImGui::PopItemWidth();
if ((prevPos != limits.X.Min && (ImGui::IsMouseReleased(ImGuiMouseButton_Left) || ImGui::GetIO().MouseWheel != 0)) || (ImGui::IsItemFocused() && ImGui::IsKeyPressed(ImGuiKey_Enter))) {
MathEvaluator<long double> evaluator;
y = {};
u32 i = 0;
evaluator.setFunction("y", [&](auto args) -> std::optional<long double> {
i32 index = i + args[0];
if (index < 0 || u32(index) >= y.size())
return 0;
else
return y[index];
}, 1, 1);
evaluator.registerStandardVariables();
evaluator.registerStandardFunctions();
stepSize = (limits.X.Size()) / x.size();
for (i = 0; i < x.size(); i++) {
evaluator.setVariable("x", limits.X.Min + i * stepSize);
x[i] = limits.X.Min + i * stepSize;
y[i] = evaluator.evaluate(mathInput).value_or(0);
if (y[i] < limits.Y.Min)
limits.Y.Min = y[i];
if (y[i] > limits.Y.Max)
limits.X.Max = y[i];
}
limits.X.Max = limits.X.Min + x.size() * stepSize;
prevPos = limits.X.Min;
}
limits = ImPlot::GetPlotLimits(ImAxis_X1, ImAxis_Y1);
ImPlot::PlotLine("f(x)", x.data(), y.data(), x.size());
ImPlot::EndPlot();
}
ImGui::PushItemWidth(-1);
ImGuiExt::InputTextIcon("##graphing_math_input", ICON_VS_SYMBOL_OPERATOR, mathInput, ImGuiInputTextFlags_EnterReturnsTrue | ImGuiInputTextFlags_AutoSelectAll);
ImGui::PopItemWidth();
if ((prevPos != limits.X.Min && (ImGui::IsMouseReleased(ImGuiMouseButton_Left) || ImGui::GetIO().MouseWheel != 0)) || (ImGui::IsItemFocused() && ImGui::IsKeyPressed(ImGuiKey_Enter))) {
MathEvaluator<long double> evaluator;
y = {};
u32 i = 0;
evaluator.setFunction("y", [&](auto args) -> std::optional<long double> {
i32 index = i + args[0];
if (index < 0 || u32(index) >= y.size())
return 0;
else
return y[index];
}, 1, 1);
evaluator.registerStandardVariables();
evaluator.registerStandardFunctions();
stepSize = (limits.X.Size()) / x.size();
for (i = 0; i < x.size(); i++) {
evaluator.setVariable("x", limits.X.Min + i * stepSize);
x[i] = limits.X.Min + i * stepSize;
y[i] = evaluator.evaluate(mathInput).value_or(0);
if (y[i] < limits.Y.Min)
limits.Y.Min = y[i];
if (y[i] > limits.Y.Max)
limits.X.Max = y[i];
}
limits.X.Max = limits.X.Min + x.size() * stepSize;
prevPos = limits.X.Min;
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,11 +1,11 @@
#include <hex/api/localization_manager.hpp>
#include <hex/api/imhex_api.hpp>
#include <hex/providers/provider.hpp>
#include <hex/ui/imgui_imhex_extensions.h>
#include <hex/helpers/utils.hpp>
#include <content/helpers/math_evaluator.hpp>
#include <imgui.h>
#include <hex/ui/imgui_imhex_extensions.h>
#include <fonts/fontawesome_font.h>
#include <fonts/codicons_font.h>
@ -13,322 +13,322 @@
#include <string>
namespace hex::plugin::builtin {
namespace impl {
void drawMathEvaluator() {
static std::vector<long double> mathHistory;
static std::string lastMathError;
static std::string mathInput;
bool evaluate = false;
static MathEvaluator<long double> mathEvaluator = [&] {
MathEvaluator<long double> evaluator;
void drawMathEvaluator() {
static std::vector<long double> mathHistory;
static std::string lastMathError;
static std::string mathInput;
bool evaluate = false;
evaluator.registerStandardVariables();
evaluator.registerStandardFunctions();
static MathEvaluator<long double> mathEvaluator = [&] {
MathEvaluator<long double> evaluator;
evaluator.setFunction(
"clear", [&](auto args) -> std::optional<long double> {
hex::unused(args);
evaluator.registerStandardVariables();
evaluator.registerStandardFunctions();
mathHistory.clear();
lastMathError.clear();
mathEvaluator.getVariables().clear();
mathEvaluator.registerStandardVariables();
mathInput.clear();
evaluator.setFunction(
"clear", [&](auto args) -> std::optional<long double> {
hex::unused(args);
mathHistory.clear();
lastMathError.clear();
mathEvaluator.getVariables().clear();
mathEvaluator.registerStandardVariables();
mathInput.clear();
return std::nullopt;
},
0,
0);
evaluator.setFunction(
"read", [](auto args) -> std::optional<long double> {
u8 value = 0;
auto provider = ImHexApi::Provider::get();
if (!ImHexApi::Provider::isValid() || !provider->isReadable() || args[0] >= provider->getActualSize())
return std::nullopt;
},
0,
0);
evaluator.setFunction(
"read", [](auto args) -> std::optional<long double> {
u8 value = 0;
provider->read(args[0], &value, sizeof(u8));
auto provider = ImHexApi::Provider::get();
if (!ImHexApi::Provider::isValid() || !provider->isReadable() || args[0] >= provider->getActualSize())
return std::nullopt;
provider->read(args[0], &value, sizeof(u8));
return value;
},
1,
1);
evaluator.setFunction(
"write", [](auto args) -> std::optional<long double> {
auto provider = ImHexApi::Provider::get();
if (!ImHexApi::Provider::isValid() || !provider->isWritable() || args[0] >= provider->getActualSize())
return std::nullopt;
if (args[1] > 0xFF)
return std::nullopt;
u8 value = args[1];
provider->write(args[0], &value, sizeof(u8));
return value;
},
1,
1);
evaluator.setFunction(
"write", [](auto args) -> std::optional<long double> {
auto provider = ImHexApi::Provider::get();
if (!ImHexApi::Provider::isValid() || !provider->isWritable() || args[0] >= provider->getActualSize())
return std::nullopt;
},
2,
2);
return evaluator;
}();
if (args[1] > 0xFF)
return std::nullopt;
enum class MathDisplayType : u8 {
Standard,
Scientific,
Engineering,
Programmer
} mathDisplayType = MathDisplayType::Standard;
u8 value = args[1];
provider->write(args[0], &value, sizeof(u8));
if (ImGui::BeginTabBar("##mathFormatTabBar")) {
if (ImGui::BeginTabItem("hex.builtin.tools.format.standard"_lang)) {
mathDisplayType = MathDisplayType::Standard;
ImGui::EndTabItem();
}
if (ImGui::BeginTabItem("hex.builtin.tools.format.scientific"_lang)) {
mathDisplayType = MathDisplayType::Scientific;
ImGui::EndTabItem();
}
if (ImGui::BeginTabItem("hex.builtin.tools.format.engineering"_lang)) {
mathDisplayType = MathDisplayType::Engineering;
ImGui::EndTabItem();
}
if (ImGui::BeginTabItem("hex.builtin.tools.format.programmer"_lang)) {
mathDisplayType = MathDisplayType::Programmer;
ImGui::EndTabItem();
}
return std::nullopt;
},
2,
2);
ImGui::EndTabBar();
return evaluator;
}();
enum class MathDisplayType : u8 {
Standard,
Scientific,
Engineering,
Programmer
} mathDisplayType = MathDisplayType::Standard;
if (ImGui::BeginTabBar("##mathFormatTabBar")) {
if (ImGui::BeginTabItem("hex.builtin.tools.format.standard"_lang)) {
mathDisplayType = MathDisplayType::Standard;
ImGui::EndTabItem();
}
if (ImGui::BeginTabItem("hex.builtin.tools.format.scientific"_lang)) {
mathDisplayType = MathDisplayType::Scientific;
ImGui::EndTabItem();
}
if (ImGui::BeginTabItem("hex.builtin.tools.format.engineering"_lang)) {
mathDisplayType = MathDisplayType::Engineering;
ImGui::EndTabItem();
}
if (ImGui::BeginTabItem("hex.builtin.tools.format.programmer"_lang)) {
mathDisplayType = MathDisplayType::Programmer;
ImGui::EndTabItem();
}
if (ImGui::BeginTable("##mathWrapper", 3)) {
ImGui::TableSetupColumn("##keypad", ImGuiTableColumnFlags_WidthFixed | ImGuiTableColumnFlags_NoResize);
ImGui::TableSetupColumn("##results", ImGuiTableColumnFlags_WidthStretch, 0.666);
ImGui::TableSetupColumn("##variables", ImGuiTableColumnFlags_WidthStretch, 0.666);
ImGui::EndTabBar();
}
ImGui::TableNextRow();
ImGui::TableNextColumn();
if (ImGui::BeginTable("##mathWrapper", 3)) {
ImGui::TableSetupColumn("##keypad", ImGuiTableColumnFlags_WidthFixed | ImGuiTableColumnFlags_NoResize);
ImGui::TableSetupColumn("##results", ImGuiTableColumnFlags_WidthStretch, 0.666);
ImGui::TableSetupColumn("##variables", ImGuiTableColumnFlags_WidthStretch, 0.666);
auto buttonSize = ImVec2(3, 2) * ImGui::GetTextLineHeightWithSpacing();
ImGui::TableNextRow();
ImGui::TableNextColumn();
if (ImGui::Button("Ans", buttonSize)) mathInput += "ans";
ImGui::SameLine();
if (ImGui::Button("Pi", buttonSize)) mathInput += "pi";
ImGui::SameLine();
if (ImGui::Button("e", buttonSize)) mathInput += "e";
ImGui::SameLine();
if (ImGui::Button("CE", buttonSize)) mathInput.clear();
ImGui::SameLine();
if (ImGui::Button(ICON_FA_BACKSPACE, buttonSize)) mathInput.clear();
auto buttonSize = ImVec2(3, 2) * ImGui::GetTextLineHeightWithSpacing();
ImGui::SameLine();
ImGui::NewLine();
if (ImGui::Button("Ans", buttonSize)) mathInput += "ans";
ImGui::SameLine();
if (ImGui::Button("Pi", buttonSize)) mathInput += "pi";
ImGui::SameLine();
if (ImGui::Button("e", buttonSize)) mathInput += "e";
ImGui::SameLine();
if (ImGui::Button("CE", buttonSize)) mathInput.clear();
ImGui::SameLine();
if (ImGui::Button(ICON_FA_BACKSPACE, buttonSize)) mathInput.clear();
switch (mathDisplayType) {
case MathDisplayType::Standard:
case MathDisplayType::Scientific:
case MathDisplayType::Engineering:
if (ImGui::Button("", buttonSize)) mathInput += "** 2";
ImGui::SameLine();
if (ImGui::Button("1/x", buttonSize)) mathInput += "1/";
ImGui::SameLine();
if (ImGui::Button("|x|", buttonSize)) mathInput += "abs";
ImGui::SameLine();
if (ImGui::Button("exp", buttonSize)) mathInput += "e ** ";
ImGui::SameLine();
if (ImGui::Button("%", buttonSize)) mathInput += "%";
ImGui::SameLine();
break;
case MathDisplayType::Programmer:
if (ImGui::Button("<<", buttonSize)) mathInput += "<<";
ImGui::SameLine();
if (ImGui::Button(">>", buttonSize)) mathInput += ">>";
ImGui::SameLine();
if (ImGui::Button("&", buttonSize)) mathInput += "&";
ImGui::SameLine();
if (ImGui::Button("|", buttonSize)) mathInput += "|";
ImGui::SameLine();
if (ImGui::Button("^", buttonSize)) mathInput += "^";
ImGui::SameLine();
break;
}
ImGui::NewLine();
if (ImGui::Button("sqrt", buttonSize)) mathInput += "sqrt";
ImGui::SameLine();
if (ImGui::Button("(", buttonSize)) mathInput += "(";
ImGui::SameLine();
if (ImGui::Button(")", buttonSize)) mathInput += ")";
ImGui::SameLine();
if (ImGui::Button("sign", buttonSize)) mathInput += "sign";
ImGui::SameLine();
if (ImGui::Button("÷", buttonSize)) mathInput += "/";
ImGui::SameLine();
ImGui::NewLine();
if (ImGui::Button("", buttonSize)) mathInput += "**";
ImGui::SameLine();
if (ImGui::Button("7", buttonSize)) mathInput += "7";
ImGui::SameLine();
if (ImGui::Button("8", buttonSize)) mathInput += "8";
ImGui::SameLine();
if (ImGui::Button("9", buttonSize)) mathInput += "9";
ImGui::SameLine();
if (ImGui::Button("×", buttonSize)) mathInput += "*";
ImGui::SameLine();
ImGui::NewLine();
if (ImGui::Button("log", buttonSize)) mathInput += "log";
ImGui::SameLine();
if (ImGui::Button("4", buttonSize)) mathInput += "4";
ImGui::SameLine();
if (ImGui::Button("5", buttonSize)) mathInput += "5";
ImGui::SameLine();
if (ImGui::Button("6", buttonSize)) mathInput += "6";
ImGui::SameLine();
if (ImGui::Button("-", buttonSize)) mathInput += "-";
ImGui::SameLine();
ImGui::NewLine();
if (ImGui::Button("ln", buttonSize)) mathInput += "ln";
ImGui::SameLine();
if (ImGui::Button("1", buttonSize)) mathInput += "1";
ImGui::SameLine();
if (ImGui::Button("2", buttonSize)) mathInput += "2";
ImGui::SameLine();
if (ImGui::Button("3", buttonSize)) mathInput += "3";
ImGui::SameLine();
if (ImGui::Button("+", buttonSize)) mathInput += "+";
ImGui::SameLine();
ImGui::NewLine();
if (ImGui::Button("lb", buttonSize)) mathInput += "lb";
ImGui::SameLine();
if (ImGui::Button("x=", buttonSize)) mathInput += "=";
ImGui::SameLine();
if (ImGui::Button("0", buttonSize)) mathInput += "0";
ImGui::SameLine();
if (ImGui::Button(".", buttonSize)) mathInput += ".";
ImGui::SameLine();
ImGui::SameLine();
ImGui::NewLine();
ImGui::PushStyleColor(ImGuiCol_Button, ImGuiExt::GetCustomColorVec4(ImGuiCustomCol_DescButtonHovered));
ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImGuiExt::GetCustomColorVec4(ImGuiCustomCol_DescButton));
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImGuiExt::GetCustomColorVec4(ImGuiCustomCol_DescButtonActive));
if (ImGui::Button("=", buttonSize)) evaluate = true;
ImGui::SameLine();
ImGui::PopStyleColor(3);
switch (mathDisplayType) {
case MathDisplayType::Standard:
case MathDisplayType::Scientific:
case MathDisplayType::Engineering:
if (ImGui::Button("", buttonSize)) mathInput += "** 2";
ImGui::SameLine();
if (ImGui::Button("1/x", buttonSize)) mathInput += "1/";
ImGui::SameLine();
if (ImGui::Button("|x|", buttonSize)) mathInput += "abs";
ImGui::SameLine();
if (ImGui::Button("exp", buttonSize)) mathInput += "e ** ";
ImGui::SameLine();
if (ImGui::Button("%", buttonSize)) mathInput += "%";
ImGui::SameLine();
break;
case MathDisplayType::Programmer:
if (ImGui::Button("<<", buttonSize)) mathInput += "<<";
ImGui::SameLine();
if (ImGui::Button(">>", buttonSize)) mathInput += ">>";
ImGui::SameLine();
if (ImGui::Button("&", buttonSize)) mathInput += "&";
ImGui::SameLine();
if (ImGui::Button("|", buttonSize)) mathInput += "|";
ImGui::SameLine();
if (ImGui::Button("^", buttonSize)) mathInput += "^";
ImGui::SameLine();
break;
}
ImGui::NewLine();
if (ImGui::Button("sqrt", buttonSize)) mathInput += "sqrt";
ImGui::SameLine();
if (ImGui::Button("(", buttonSize)) mathInput += "(";
ImGui::SameLine();
if (ImGui::Button(")", buttonSize)) mathInput += ")";
ImGui::SameLine();
if (ImGui::Button("sign", buttonSize)) mathInput += "sign";
ImGui::SameLine();
if (ImGui::Button("÷", buttonSize)) mathInput += "/";
ImGui::SameLine();
ImGui::NewLine();
if (ImGui::Button("", buttonSize)) mathInput += "**";
ImGui::SameLine();
if (ImGui::Button("7", buttonSize)) mathInput += "7";
ImGui::SameLine();
if (ImGui::Button("8", buttonSize)) mathInput += "8";
ImGui::SameLine();
if (ImGui::Button("9", buttonSize)) mathInput += "9";
ImGui::SameLine();
if (ImGui::Button("×", buttonSize)) mathInput += "*";
ImGui::SameLine();
ImGui::NewLine();
if (ImGui::Button("log", buttonSize)) mathInput += "log";
ImGui::SameLine();
if (ImGui::Button("4", buttonSize)) mathInput += "4";
ImGui::SameLine();
if (ImGui::Button("5", buttonSize)) mathInput += "5";
ImGui::SameLine();
if (ImGui::Button("6", buttonSize)) mathInput += "6";
ImGui::SameLine();
if (ImGui::Button("-", buttonSize)) mathInput += "-";
ImGui::SameLine();
ImGui::NewLine();
if (ImGui::Button("ln", buttonSize)) mathInput += "ln";
ImGui::SameLine();
if (ImGui::Button("1", buttonSize)) mathInput += "1";
ImGui::SameLine();
if (ImGui::Button("2", buttonSize)) mathInput += "2";
ImGui::SameLine();
if (ImGui::Button("3", buttonSize)) mathInput += "3";
ImGui::SameLine();
if (ImGui::Button("+", buttonSize)) mathInput += "+";
ImGui::SameLine();
ImGui::NewLine();
if (ImGui::Button("lb", buttonSize)) mathInput += "lb";
ImGui::SameLine();
if (ImGui::Button("x=", buttonSize)) mathInput += "=";
ImGui::SameLine();
if (ImGui::Button("0", buttonSize)) mathInput += "0";
ImGui::SameLine();
if (ImGui::Button(".", buttonSize)) mathInput += ".";
ImGui::SameLine();
ImGui::NewLine();
ImGui::PushStyleColor(ImGuiCol_Button, ImGuiExt::GetCustomColorVec4(ImGuiCustomCol_DescButtonHovered));
ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImGuiExt::GetCustomColorVec4(ImGuiCustomCol_DescButton));
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImGuiExt::GetCustomColorVec4(ImGuiCustomCol_DescButtonActive));
if (ImGui::Button("=", buttonSize)) evaluate = true;
ImGui::SameLine();
ImGui::PopStyleColor(3);
ImGui::TableNextColumn();
ImGui::NewLine();
if (ImGui::BeginTable("##mathHistory", 1, ImGuiTableFlags_ScrollY | ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg, ImVec2(0, 300))) {
ImGui::TableSetupColumn("hex.builtin.tools.history"_lang);
ImGui::TableSetupScrollFreeze(0, 1);
ImGui::TableNextColumn();
ImGuiListClipper clipper;
clipper.Begin(mathHistory.size());
if (ImGui::BeginTable("##mathHistory", 1, ImGuiTableFlags_ScrollY | ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg, ImVec2(0, 300))) {
ImGui::TableSetupColumn("hex.builtin.tools.history"_lang);
ImGui::TableSetupScrollFreeze(0, 1);
ImGui::TableHeadersRow();
while (clipper.Step()) {
for (int i = clipper.DisplayStart; i < clipper.DisplayEnd; i++) {
if (i == 0)
ImGui::PushStyleColor(ImGuiCol_Text, ImU32(ImColor(0xA5, 0x45, 0x45)));
ImGuiListClipper clipper;
clipper.Begin(mathHistory.size());
ImGui::TableNextRow();
ImGui::TableNextColumn();
switch (mathDisplayType) {
case MathDisplayType::Standard:
ImGuiExt::TextFormatted("{0:.3Lf}", mathHistory[(mathHistory.size() - 1) - i]);
break;
case MathDisplayType::Scientific:
ImGuiExt::TextFormatted("{0:.6Lg}", mathHistory[(mathHistory.size() - 1) - i]);
break;
case MathDisplayType::Engineering:
ImGuiExt::TextFormatted("{0}", hex::toEngineeringString(mathHistory[(mathHistory.size() - 1) - i]).c_str());
break;
case MathDisplayType::Programmer:
ImGuiExt::TextFormatted("0x{0:X} ({1})",
u64(mathHistory[(mathHistory.size() - 1) - i]),
u64(mathHistory[(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, 300))) {
ImGui::TableSetupColumn("hex.builtin.tools.name"_lang);
ImGui::TableSetupColumn("hex.builtin.tools.value"_lang);
ImGui::TableSetupScrollFreeze(0, 1);
ImGui::TableHeadersRow();
for (const auto &[name, variable] : mathEvaluator.getVariables()) {
const auto &[value, constant] = variable;
if (constant)
continue;
ImGui::TableHeadersRow();
while (clipper.Step()) {
for (int i = clipper.DisplayStart; i < clipper.DisplayEnd; i++) {
if (i == 0)
ImGui::PushStyleColor(ImGuiCol_Text, ImU32(ImColor(0xA5, 0x45, 0x45)));
ImGui::TableNextRow();
ImGui::TableNextColumn();
ImGui::TextUnformatted(name.c_str());
ImGui::TableNextColumn();
switch (mathDisplayType) {
case MathDisplayType::Standard:
ImGuiExt::TextFormatted("{0:.3Lf}", value);
ImGuiExt::TextFormatted("{0:.3Lf}", mathHistory[(mathHistory.size() - 1) - i]);
break;
case MathDisplayType::Scientific:
ImGuiExt::TextFormatted("{0:.6Lg}", value);
ImGuiExt::TextFormatted("{0:.6Lg}", mathHistory[(mathHistory.size() - 1) - i]);
break;
case MathDisplayType::Engineering:
ImGuiExt::TextFormatted("{}", hex::toEngineeringString(value));
ImGuiExt::TextFormatted("{0}", hex::toEngineeringString(mathHistory[(mathHistory.size() - 1) - i]).c_str());
break;
case MathDisplayType::Programmer:
ImGuiExt::TextFormatted("0x{0:X} ({1})", u64(value), u64(value));
ImGuiExt::TextFormatted("0x{0:X} ({1})",
u64(mathHistory[(mathHistory.size() - 1) - i]),
u64(mathHistory[(mathHistory.size() - 1) - i]));
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, 300))) {
ImGui::TableSetupColumn("hex.builtin.tools.name"_lang);
ImGui::TableSetupColumn("hex.builtin.tools.value"_lang);
ImGui::TableSetupScrollFreeze(0, 1);
ImGui::TableHeadersRow();
for (const auto &[name, variable] : mathEvaluator.getVariables()) {
const auto &[value, constant] = variable;
if (constant)
continue;
ImGui::TableNextRow();
ImGui::TableNextColumn();
ImGui::TextUnformatted(name.c_str());
ImGui::TableNextColumn();
switch (mathDisplayType) {
case MathDisplayType::Standard:
ImGuiExt::TextFormatted("{0:.3Lf}", value);
break;
case MathDisplayType::Scientific:
ImGuiExt::TextFormatted("{0:.6Lg}", value);
break;
case MathDisplayType::Engineering:
ImGuiExt::TextFormatted("{}", hex::toEngineeringString(value));
break;
case MathDisplayType::Programmer:
ImGuiExt::TextFormatted("0x{0:X} ({1})", u64(value), u64(value));
break;
}
}
ImGui::EndTable();
}
ImGui::PushItemWidth(ImGui::GetContentRegionAvail().x);
if (ImGuiExt::InputTextIcon("##input", ICON_VS_SYMBOL_OPERATOR, mathInput, ImGuiInputTextFlags_EnterReturnsTrue | ImGuiInputTextFlags_AutoSelectAll)) {
ImGui::SetKeyboardFocusHere();
evaluate = true;
}
ImGui::PopItemWidth();
ImGui::EndTable();
}
if (!lastMathError.empty())
ImGuiExt::TextFormattedColored(ImColor(0xA00040FF), "hex.builtin.tools.error"_lang, lastMathError);
else
ImGui::NewLine();
ImGui::PushItemWidth(ImGui::GetContentRegionAvail().x);
if (ImGuiExt::InputTextIcon("##input", ICON_VS_SYMBOL_OPERATOR, mathInput, ImGuiInputTextFlags_EnterReturnsTrue | ImGuiInputTextFlags_AutoSelectAll)) {
ImGui::SetKeyboardFocusHere();
evaluate = true;
}
ImGui::PopItemWidth();
if (evaluate) {
try {
auto result = mathEvaluator.evaluate(mathInput);
mathInput.clear();
if (result.has_value()) {
mathHistory.push_back(result.value());
lastMathError.clear();
} else {
lastMathError = mathEvaluator.getLastError().value_or("");
}
} catch (std::invalid_argument &e) {
lastMathError = e.what();
if (!lastMathError.empty())
ImGuiExt::TextFormattedColored(ImColor(0xA00040FF), "hex.builtin.tools.error"_lang, lastMathError);
else
ImGui::NewLine();
if (evaluate) {
try {
auto result = mathEvaluator.evaluate(mathInput);
mathInput.clear();
if (result.has_value()) {
mathHistory.push_back(result.value());
lastMathError.clear();
} else {
lastMathError = mathEvaluator.getLastError().value_or("");
}
} catch (std::invalid_argument &e) {
lastMathError = e.what();
}
}
}
}

View File

@ -1,66 +1,63 @@
#include <hex/helpers/utils.hpp>
#include <hex/api/localization_manager.hpp>
#include <content/tools_entries.hpp>
#include <imgui.h>
#include <hex/ui/imgui_imhex_extensions.h>
namespace hex::plugin::builtin {
namespace impl {
void drawInvariantMultiplicationDecoder() {
static u64 divisor = 1;
static u64 multiplier = 1;
static u64 numBits = 32;
ImGuiExt::TextFormattedWrapped("{}", "hex.builtin.tools.invariant_multiplication.description"_lang);
void drawInvariantMultiplicationDecoder() {
static u64 divisor = 1;
static u64 multiplier = 1;
static u64 numBits = 32;
ImGuiExt::TextFormattedWrapped("{}", "hex.builtin.tools.invariant_multiplication.description"_lang);
ImGui::NewLine();
if (ImGui::BeginChild("##calculator", ImVec2(0, ImGui::GetTextLineHeightWithSpacing() * 5), true)) {
constexpr static u64 min = 1, max = 64;
ImGui::SliderScalar("hex.builtin.tools.invariant_multiplication.num_bits"_lang, ImGuiDataType_U64, &numBits, &min, &max);
ImGui::NewLine();
if (ImGui::BeginChild("##calculator", ImVec2(0, ImGui::GetTextLineHeightWithSpacing() * 5), true)) {
constexpr static u64 min = 1, max = 64;
ImGui::SliderScalar("hex.builtin.tools.invariant_multiplication.num_bits"_lang, ImGuiDataType_U64, &numBits, &min, &max);
ImGui::NewLine();
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0, 0));
ImGui::PushStyleColor(ImGuiCol_ChildBg, ImGui::GetStyleColorVec4(ImGuiCol_TableRowBgAlt));
if (ImGui::BeginChild("##calculator", ImVec2(0, ImGui::GetTextLineHeightWithSpacing() + 12_scaled), true)) {
ImGui::PushItemWidth(100_scaled);
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0, 0));
ImGui::PushStyleColor(ImGuiCol_ChildBg, ImGui::GetStyleColorVec4(ImGuiCol_TableRowBgAlt));
if (ImGui::BeginChild("##calculator", ImVec2(0, ImGui::GetTextLineHeightWithSpacing() + 12_scaled), true)) {
ImGui::PushItemWidth(100_scaled);
ImGui::TextUnformatted("X /");
ImGui::SameLine();
if (ImGui::InputScalar("##divisor", ImGuiDataType_U64, &divisor)) {
if (divisor == 0)
divisor = 1;
ImGui::TextUnformatted("X /");
ImGui::SameLine();
if (ImGui::InputScalar("##divisor", ImGuiDataType_U64, &divisor)) {
if (divisor == 0)
divisor = 1;
multiplier = ((1LLU << (numBits + 1)) / divisor) + 1;
}
ImGui::SameLine();
ImGui::TextUnformatted(" <=> ");
ImGui::SameLine();
ImGui::TextUnformatted("( X *");
ImGui::SameLine();
if (ImGuiExt::InputHexadecimal("##multiplier", &multiplier)) {
if (multiplier == 0)
multiplier = 1;
divisor = ((1LLU << (numBits + 1)) / multiplier) + 1;
}
ImGui::SameLine();
ImGuiExt::TextFormatted(") >> {}", numBits + 1);
ImGui::PopItemWidth();
multiplier = ((1LLU << (numBits + 1)) / divisor) + 1;
}
ImGui::EndChild();
ImGui::PopStyleColor();
ImGui::PopStyleVar();
ImGui::SameLine();
ImGui::TextUnformatted(" <=> ");
ImGui::SameLine();
ImGui::TextUnformatted("( X *");
ImGui::SameLine();
if (ImGuiExt::InputHexadecimal("##multiplier", &multiplier)) {
if (multiplier == 0)
multiplier = 1;
divisor = ((1LLU << (numBits + 1)) / multiplier) + 1;
}
ImGui::SameLine();
ImGuiExt::TextFormatted(") >> {}", numBits + 1);
ImGui::PopItemWidth();
}
ImGui::EndChild();
ImGui::PopStyleColor();
ImGui::PopStyleVar();
}
ImGui::EndChild();
}
}

View File

@ -2,64 +2,63 @@
#include <hex/api/localization_manager.hpp>
#include <imgui.h>
#include <hex/ui/imgui_imhex_extensions.h>
namespace hex::plugin::builtin {
namespace impl {
void drawPermissionsCalculator() {
static bool setuid, setgid, sticky;
static bool r[3], w[3], x[3];
ImGuiExt::Header("hex.builtin.tools.permissions.perm_bits"_lang, true);
void drawPermissionsCalculator() {
static bool setuid, setgid, sticky;
static bool r[3], w[3], x[3];
if (ImGui::BeginTable("Permissions", 4, ImGuiTableFlags_Borders)) {
ImGui::TableSetupColumn("Special", ImGuiTableColumnFlags_NoSort);
ImGui::TableSetupColumn("User", ImGuiTableColumnFlags_NoSort);
ImGui::TableSetupColumn("Group", ImGuiTableColumnFlags_NoSort);
ImGui::TableSetupColumn("Other", ImGuiTableColumnFlags_NoSort);
ImGui::TableSetupScrollFreeze(0, 1);
ImGuiExt::Header("hex.builtin.tools.permissions.perm_bits"_lang, true);
ImGui::TableHeadersRow();
if (ImGui::BeginTable("Permissions", 4, ImGuiTableFlags_Borders)) {
ImGui::TableSetupColumn("Special", ImGuiTableColumnFlags_NoSort);
ImGui::TableSetupColumn("User", ImGuiTableColumnFlags_NoSort);
ImGui::TableSetupColumn("Group", ImGuiTableColumnFlags_NoSort);
ImGui::TableSetupColumn("Other", ImGuiTableColumnFlags_NoSort);
ImGui::TableSetupScrollFreeze(0, 1);
ImGui::TableNextRow();
ImGui::TableHeadersRow();
ImGui::TableNextRow();
ImGui::TableNextColumn();
ImGui::Checkbox("setuid", &setuid);
ImGui::Checkbox("setgid", &setgid);
ImGui::Checkbox("Sticky bit", &sticky);
for (u8 i = 0; i < 3; i++) {
ImGui::TableNextColumn();
ImGui::Checkbox("setuid", &setuid);
ImGui::Checkbox("setgid", &setgid);
ImGui::Checkbox("Sticky bit", &sticky);
for (u8 i = 0; i < 3; i++) {
ImGui::TableNextColumn();
ImGui::PushID(i);
ImGui::Checkbox("Read", &r[i]);
ImGui::Checkbox("Write", &w[i]);
ImGui::Checkbox("Execute", &x[i]);
ImGui::PopID();
}
ImGui::EndTable();
ImGui::PushID(i);
ImGui::Checkbox("Read", &r[i]);
ImGui::Checkbox("Write", &w[i]);
ImGui::Checkbox("Execute", &x[i]);
ImGui::PopID();
}
ImGuiExt::Header("hex.builtin.tools.permissions.absolute"_lang);
auto result = hex::format("{}{}{}{}",
(setuid << 2) | (setgid << 1) | (sticky << 0),
(r[0] << 2) | (w[0] << 1) | (x[0] << 0),
(r[1] << 2) | (w[1] << 1) | (x[1] << 0),
(r[2] << 2) | (w[2] << 1) | (x[2] << 0));
ImGui::InputText("##permissions_absolute", result.data(), result.size(), ImGuiInputTextFlags_ReadOnly);
ImGui::NewLine();
constexpr static auto WarningColor = ImColor(0.92F, 0.25F, 0.2F, 1.0F);
if (setuid && !x[0])
ImGuiExt::TextFormattedColored(WarningColor, "{}", "hex.builtin.tools.permissions.setuid_error"_lang);
if (setgid && !x[1])
ImGuiExt::TextFormattedColored(WarningColor, "{}", "hex.builtin.tools.permissions.setgid_error"_lang);
if (sticky && !x[2])
ImGuiExt::TextFormattedColored(WarningColor, "{}", "hex.builtin.tools.permissions.sticky_error"_lang);
ImGui::EndTable();
}
ImGuiExt::Header("hex.builtin.tools.permissions.absolute"_lang);
auto result = hex::format("{}{}{}{}",
(setuid << 2) | (setgid << 1) | (sticky << 0),
(r[0] << 2) | (w[0] << 1) | (x[0] << 0),
(r[1] << 2) | (w[1] << 1) | (x[1] << 0),
(r[2] << 2) | (w[2] << 1) | (x[2] << 0));
ImGui::InputText("##permissions_absolute", result.data(), result.size(), ImGuiInputTextFlags_ReadOnly);
ImGui::NewLine();
constexpr static auto WarningColor = ImColor(0.92F, 0.25F, 0.2F, 1.0F);
if (setuid && !x[0])
ImGuiExt::TextFormattedColored(WarningColor, "{}", "hex.builtin.tools.permissions.setuid_error"_lang);
if (setgid && !x[1])
ImGuiExt::TextFormattedColored(WarningColor, "{}", "hex.builtin.tools.permissions.setgid_error"_lang);
if (sticky && !x[2])
ImGuiExt::TextFormattedColored(WarningColor, "{}", "hex.builtin.tools.permissions.sticky_error"_lang);
}
}

View File

@ -2,38 +2,35 @@
#include <hex/helpers/utils.hpp>
#include <hex/api/localization_manager.hpp>
#include <hex/ui/view.hpp>
#include <regex>
#include <content/tools_entries.hpp>
#include <imgui.h>
#include <hex/ui/imgui_imhex_extensions.h>
#include <fonts/codicons_font.h>
namespace hex::plugin::builtin {
namespace impl {
void drawRegexReplacer() {
static auto regexInput = [] { std::string s; s.reserve(0xFFF); return s; }();
static auto regexPattern = [] { std::string s; s.reserve(0xFFF); return s; }();
static auto replacePattern = [] { std::string s; s.reserve(0xFFF); return s; }();
static auto regexOutput = [] { std::string s; s.reserve(0xFFF); return s; }();
ImGui::PushItemWidth(-150_scaled);
bool changed1 = ImGuiExt::InputTextIcon("hex.builtin.tools.regex_replacer.pattern"_lang, ICON_VS_REGEX, regexPattern);
bool changed2 = ImGuiExt::InputTextIcon("hex.builtin.tools.regex_replacer.replace"_lang, ICON_VS_REGEX, replacePattern);
bool changed3 = ImGui::InputTextMultiline("hex.builtin.tools.regex_replacer.input"_lang, regexInput, ImVec2(0, 0));
void drawRegexReplacer() {
static auto regexInput = [] { std::string s; s.reserve(0xFFF); return s; }();
static auto regexPattern = [] { std::string s; s.reserve(0xFFF); return s; }();
static auto replacePattern = [] { std::string s; s.reserve(0xFFF); return s; }();
static auto regexOutput = [] { std::string s; s.reserve(0xFFF); return s; }();
if (changed1 || changed2 || changed3) {
try {
regexOutput = std::regex_replace(regexInput.data(), std::regex(regexPattern.data()), replacePattern.data());
} catch (std::regex_error &) { }
}
ImGui::PushItemWidth(-150_scaled);
bool changed1 = ImGuiExt::InputTextIcon("hex.builtin.tools.regex_replacer.pattern"_lang, ICON_VS_REGEX, regexPattern);
bool changed2 = ImGuiExt::InputTextIcon("hex.builtin.tools.regex_replacer.replace"_lang, ICON_VS_REGEX, replacePattern);
bool changed3 = ImGui::InputTextMultiline("hex.builtin.tools.regex_replacer.input"_lang, regexInput, ImVec2(0, 0));
ImGui::InputTextMultiline("hex.builtin.tools.regex_replacer.output"_lang, regexOutput.data(), regexOutput.size(), ImVec2(0, 0), ImGuiInputTextFlags_ReadOnly);
ImGui::PopItemWidth();
if (changed1 || changed2 || changed3) {
try {
regexOutput = std::regex_replace(regexInput.data(), std::regex(regexPattern.data()), replacePattern.data());
} catch (std::regex_error &) { }
}
ImGui::InputTextMultiline("hex.builtin.tools.regex_replacer.output"_lang, regexOutput.data(), regexOutput.size(), ImVec2(0, 0), ImGuiInputTextFlags_ReadOnly);
ImGui::PopItemWidth();
}
}

View File

@ -1,194 +1,194 @@
#include <hex/api/localization_manager.hpp>
#include <hex/helpers/utils.hpp>
#include <hex/ui/imgui_imhex_extensions.h>
#include <wolv/net/socket_client.hpp>
#include <wolv/net/socket_server.hpp>
#include <fonts/codicons_font.h>
#include <imgui.h>
#include <jthread.hpp>
#include <hex/ui/imgui_imhex_extensions.h>
#include <jthread.hpp>
#include <string>
#include <vector>
namespace hex::plugin::builtin {
namespace impl {
using namespace std::literals::chrono_literals;
void drawTCPClientServer() {
if (ImGui::BeginTabBar("##tcpTransceiver", ImGuiTabBarFlags_None)) {
if (ImGui::BeginTabItem("hex.builtin.tools.tcp_client_server.client"_lang)) {
static wolv::net::SocketClient client;
using namespace std::literals::chrono_literals;
static std::string ipAddress;
static int port;
void drawTCPClientServer() {
if (ImGui::BeginTabBar("##tcpTransceiver", ImGuiTabBarFlags_None)) {
if (ImGui::BeginTabItem("hex.builtin.tools.tcp_client_server.client"_lang)) {
static wolv::net::SocketClient client;
static std::vector<std::string> messages;
static std::string input;
static std::jthread receiverThread;
static std::mutex receiverMutex;
static std::string ipAddress;
static int port;
ImGuiExt::Header("hex.builtin.tools.tcp_client_server.settings"_lang, true);
static std::vector<std::string> messages;
static std::string input;
static std::jthread receiverThread;
static std::mutex receiverMutex;
ImGui::BeginDisabled(client.isConnected());
{
ImGui::PushItemWidth(ImGui::GetContentRegionAvail().x * 0.3F);
ImGui::InputText("##ipAddress", ipAddress);
ImGui::PopItemWidth();
ImGui::SameLine(0, 0);
ImGui::TextUnformatted(":");
ImGui::SameLine(0, 0);
ImGui::PushItemWidth(ImGui::GetContentRegionAvail().x * 0.2F);
ImGui::InputInt("##port", &port, 0, 0);
ImGui::PopItemWidth();
}
ImGui::EndDisabled();
ImGuiExt::Header("hex.builtin.tools.tcp_client_server.settings"_lang, true);
ImGui::SameLine();
ImGui::PushItemWidth(ImGui::GetContentRegionAvail().x * 0.2F);
if (client.isConnected()) {
if (ImGuiExt::IconButton(ICON_VS_DEBUG_DISCONNECT, ImGuiExt::GetCustomColorVec4(ImGuiCustomCol_ToolbarRed))) {
client.disconnect();
receiverThread.request_stop();
receiverThread.join();
}
} else {
if (ImGuiExt::IconButton(ICON_VS_PLAY, ImGuiExt::GetCustomColorVec4(ImGuiCustomCol_ToolbarGreen))) {
client.connect(ipAddress, port);
receiverThread = std::jthread([](const std::stop_token& stopToken) {
while (!stopToken.stop_requested()) {
auto message = client.readString();
if (!message.empty()) {
std::scoped_lock lock(receiverMutex);
messages.push_back(message);
}
}
});
}
}
ImGui::BeginDisabled(client.isConnected());
{
ImGui::PushItemWidth(ImGui::GetContentRegionAvail().x * 0.3F);
ImGui::InputText("##ipAddress", ipAddress);
ImGui::PopItemWidth();
ImGui::SameLine(0, 0);
ImGui::TextUnformatted(":");
ImGui::SameLine(0, 0);
ImGui::PushItemWidth(ImGui::GetContentRegionAvail().x * 0.2F);
ImGui::InputInt("##port", &port, 0, 0);
ImGui::PopItemWidth();
}
ImGui::EndDisabled();
if (port < 1)
port = 1;
else if (port > 65535)
port = 65535;
ImGui::SameLine();
ImGuiExt::Header("hex.builtin.tools.tcp_client_server.messages"_lang);
if (ImGui::BeginTable("##response", 1, ImGuiTableFlags_ScrollY | ImGuiTableFlags_RowBg | ImGuiTableFlags_Borders, ImVec2(0, 200_scaled))) {
{
std::scoped_lock lock(receiverMutex);
for (const auto &message : messages) {
ImGui::TableNextRow();
ImGui::TableNextColumn();
ImGuiExt::TextFormattedSelectable("{}", message.c_str());
ImGui::PushItemWidth(ImGui::GetContentRegionAvail().x * 0.2F);
if (client.isConnected()) {
if (ImGuiExt::IconButton(ICON_VS_DEBUG_DISCONNECT, ImGuiExt::GetCustomColorVec4(ImGuiCustomCol_ToolbarRed))) {
client.disconnect();
receiverThread.request_stop();
receiverThread.join();
}
} else {
if (ImGuiExt::IconButton(ICON_VS_PLAY, ImGuiExt::GetCustomColorVec4(ImGuiCustomCol_ToolbarGreen))) {
client.connect(ipAddress, port);
receiverThread = std::jthread([](const std::stop_token& stopToken) {
while (!stopToken.stop_requested()) {
auto message = client.readString();
if (!message.empty()) {
std::scoped_lock lock(receiverMutex);
messages.push_back(message);
}
}
}
ImGui::EndTable();
});
}
}
ImGui::PopItemWidth();
ImGui::BeginDisabled(!client.isConnected());
if (port < 1)
port = 1;
else if (port > 65535)
port = 65535;
ImGuiExt::Header("hex.builtin.tools.tcp_client_server.messages"_lang);
if (ImGui::BeginTable("##response", 1, ImGuiTableFlags_ScrollY | ImGuiTableFlags_RowBg | ImGuiTableFlags_Borders, ImVec2(0, 200_scaled))) {
{
ImGui::PushItemWidth(-(50_scaled));
bool pressedEnter = ImGui::InputText("##input", input, ImGuiInputTextFlags_EnterReturnsTrue);
ImGui::PopItemWidth();
ImGui::SameLine();
if (pressedEnter)
ImGui::SetKeyboardFocusHere(-1);
if (ImGuiExt::IconButton(ICON_VS_DEBUG_STACKFRAME, ImGui::GetStyleColorVec4(ImGuiCol_Text)) || pressedEnter) {
client.writeString(input);
input.clear();
std::scoped_lock lock(receiverMutex);
for (const auto &message : messages) {
ImGui::TableNextRow();
ImGui::TableNextColumn();
ImGuiExt::TextFormattedSelectable("{}", message.c_str());
}
}
ImGui::EndDisabled();
ImGui::EndTabItem();
ImGui::EndTable();
}
if (ImGui::BeginTabItem("hex.builtin.tools.tcp_client_server.server"_lang)) {
static wolv::net::SocketServer server;
static int port;
static std::vector<std::string> messages;
static std::mutex receiverMutex;
static std::jthread receiverThread;
ImGuiExt::Header("hex.builtin.tools.tcp_client_server.settings"_lang, true);
ImGui::BeginDisabled(server.isActive());
{
ImGui::PushItemWidth(ImGui::GetContentRegionAvail().x * 0.2F);
ImGui::InputInt("##port", &port, 0, 0);
ImGui::PopItemWidth();
}
ImGui::EndDisabled();
ImGui::BeginDisabled(!client.isConnected());
{
ImGui::PushItemWidth(-(50_scaled));
bool pressedEnter = ImGui::InputText("##input", input, ImGuiInputTextFlags_EnterReturnsTrue);
ImGui::PopItemWidth();
ImGui::SameLine();
if (port < 1)
port = 1;
else if (port > 65535)
port = 65535;
if (pressedEnter)
ImGui::SetKeyboardFocusHere(-1);
ImGui::PushItemWidth(ImGui::GetContentRegionAvail().x * 0.2F);
if (server.isActive()) {
if (ImGuiExt::IconButton(ICON_VS_DEBUG_DISCONNECT, ImGuiExt::GetCustomColorVec4(ImGuiCustomCol_ToolbarRed))) {
server.shutdown();
receiverThread.request_stop();
receiverThread.join();
}
} else {
if (ImGuiExt::IconButton(ICON_VS_PLAY, ImGuiExt::GetCustomColorVec4(ImGuiCustomCol_ToolbarGreen))) {
receiverThread = std::jthread([](const std::stop_token& stopToken){
server = wolv::net::SocketServer(port);
while (!stopToken.stop_requested()) {
server.accept([](wolv::net::SocketHandle, const std::vector<u8> &data) -> std::vector<u8> {
std::scoped_lock lock(receiverMutex);
messages.emplace_back(data.begin(), data.end());
return {};
}, nullptr, true);
std::this_thread::sleep_for(100ms);
}
});
}
if (ImGuiExt::IconButton(ICON_VS_DEBUG_STACKFRAME, ImGui::GetStyleColorVec4(ImGuiCol_Text)) || pressedEnter) {
client.writeString(input);
input.clear();
}
ImGui::PopItemWidth();
ImGuiExt::Header("hex.builtin.tools.tcp_client_server.messages"_lang);
if (ImGui::BeginTable("##response", 1, ImGuiTableFlags_ScrollY | ImGuiTableFlags_RowBg | ImGuiTableFlags_Borders, ImVec2(0, 200_scaled))) {
{
std::scoped_lock lock(receiverMutex);
u32 index = 0;
for (const auto &message : messages) {
ImGui::TableNextRow();
ImGui::TableNextColumn();
ImGui::PushID(index);
ImGuiExt::TextFormattedSelectable("{}", message.c_str());
ImGui::PopID();
index += 1;
}
}
ImGui::EndTable();
}
ImGui::EndTabItem();
}
ImGui::EndDisabled();
ImGui::EndTabBar();
ImGui::EndTabItem();
}
if (ImGui::BeginTabItem("hex.builtin.tools.tcp_client_server.server"_lang)) {
static wolv::net::SocketServer server;
static int port;
static std::vector<std::string> messages;
static std::mutex receiverMutex;
static std::jthread receiverThread;
ImGuiExt::Header("hex.builtin.tools.tcp_client_server.settings"_lang, true);
ImGui::BeginDisabled(server.isActive());
{
ImGui::PushItemWidth(ImGui::GetContentRegionAvail().x * 0.2F);
ImGui::InputInt("##port", &port, 0, 0);
ImGui::PopItemWidth();
}
ImGui::EndDisabled();
ImGui::SameLine();
if (port < 1)
port = 1;
else if (port > 65535)
port = 65535;
ImGui::PushItemWidth(ImGui::GetContentRegionAvail().x * 0.2F);
if (server.isActive()) {
if (ImGuiExt::IconButton(ICON_VS_DEBUG_DISCONNECT, ImGuiExt::GetCustomColorVec4(ImGuiCustomCol_ToolbarRed))) {
server.shutdown();
receiverThread.request_stop();
receiverThread.join();
}
} else {
if (ImGuiExt::IconButton(ICON_VS_PLAY, ImGuiExt::GetCustomColorVec4(ImGuiCustomCol_ToolbarGreen))) {
receiverThread = std::jthread([](const std::stop_token& stopToken){
server = wolv::net::SocketServer(port);
while (!stopToken.stop_requested()) {
server.accept([](wolv::net::SocketHandle, const std::vector<u8> &data) -> std::vector<u8> {
std::scoped_lock lock(receiverMutex);
messages.emplace_back(data.begin(), data.end());
return {};
}, nullptr, true);
std::this_thread::sleep_for(100ms);
}
});
}
}
ImGui::PopItemWidth();
ImGuiExt::Header("hex.builtin.tools.tcp_client_server.messages"_lang);
if (ImGui::BeginTable("##response", 1, ImGuiTableFlags_ScrollY | ImGuiTableFlags_RowBg | ImGuiTableFlags_Borders, ImVec2(0, 200_scaled))) {
{
std::scoped_lock lock(receiverMutex);
u32 index = 0;
for (const auto &message : messages) {
ImGui::TableNextRow();
ImGui::TableNextColumn();
ImGui::PushID(index);
ImGuiExt::TextFormattedSelectable("{}", message.c_str());
ImGui::PopID();
index += 1;
}
}
ImGui::EndTable();
}
ImGui::EndTabItem();
}
ImGui::EndTabBar();
}
}
}

View File

@ -3,92 +3,90 @@
#include <hex/helpers/http_requests.hpp>
#include <hex/api/localization_manager.hpp>
#include <hex/ui/view.hpp>
#include <content/tools_entries.hpp>
#include <imgui.h>
#include <hex/ui/imgui_imhex_extensions.h>
#include <fonts/codicons_font.h>
#include <nlohmann/json.hpp>
namespace hex::plugin::builtin {
namespace impl {
using namespace std::literals::string_literals;
using namespace std::literals::chrono_literals;
std::string getWikipediaApiUrl() {
std::string setting = ContentRegistry::Settings::read("hex.builtin.setting.interface", "hex.builtin.setting.interface.wiki_explain_language", "en").get<std::string>();
return "https://" + setting + ".wikipedia.org/w/api.php?format=json&action=query&prop=extracts&explaintext&redirects=10&formatversion=2";
using namespace std::literals::string_literals;
using namespace std::literals::chrono_literals;
std::string getWikipediaApiUrl() {
std::string setting = ContentRegistry::Settings::read("hex.builtin.setting.interface", "hex.builtin.setting.interface.wiki_explain_language", "en").get<std::string>();
return "https://" + setting + ".wikipedia.org/w/api.php?format=json&action=query&prop=extracts&explaintext&redirects=10&formatversion=2";
}
void drawWikiExplainer() {
static HttpRequest request("GET", "");
static std::string resultTitle, resultExtract;
static std::future<HttpRequest::Result<std::string>> searchProcess;
static bool extendedSearch = false;
static std::string searchString;
ImGuiExt::Header("hex.builtin.tools.wiki_explain.control"_lang, true);
bool startSearch = ImGuiExt::InputTextIcon("##search", ICON_VS_SYMBOL_KEY, searchString, ImGuiInputTextFlags_EnterReturnsTrue);
ImGui::SameLine();
ImGui::BeginDisabled((searchProcess.valid() && searchProcess.wait_for(0s) != std::future_status::ready) || searchString.empty());
startSearch = ImGui::Button("hex.builtin.tools.wiki_explain.search"_lang) || startSearch;
ImGui::EndDisabled();
if (startSearch && !searchString.empty()) {
request.setUrl(getWikipediaApiUrl() + "&exintro"s + "&titles="s + HttpRequest::urlEncode(searchString));
searchProcess = request.execute();
}
void drawWikiExplainer() {
static HttpRequest request("GET", "");
static std::string resultTitle, resultExtract;
static std::future<HttpRequest::Result<std::string>> searchProcess;
static bool extendedSearch = false;
static std::string searchString;
ImGuiExt::Header("hex.builtin.tools.wiki_explain.results"_lang);
ImGuiExt::Header("hex.builtin.tools.wiki_explain.control"_lang, true);
bool startSearch = ImGuiExt::InputTextIcon("##search", ICON_VS_SYMBOL_KEY, searchString, ImGuiInputTextFlags_EnterReturnsTrue);
ImGui::SameLine();
ImGui::BeginDisabled((searchProcess.valid() && searchProcess.wait_for(0s) != std::future_status::ready) || searchString.empty());
startSearch = ImGui::Button("hex.builtin.tools.wiki_explain.search"_lang) || startSearch;
ImGui::EndDisabled();
if (startSearch && !searchString.empty()) {
request.setUrl(getWikipediaApiUrl() + "&exintro"s + "&titles="s + HttpRequest::urlEncode(searchString));
searchProcess = request.execute();
if (ImGui::BeginChild("##summary", ImVec2(0, 300), true)) {
if (!resultTitle.empty() && !resultExtract.empty()) {
ImGuiExt::HeaderColored(resultTitle.c_str(), ImGuiExt::GetCustomColorVec4(ImGuiCustomCol_Highlight), true);
ImGuiExt::TextFormattedWrapped("{}", resultExtract.c_str());
}
}
ImGui::EndChild();
ImGuiExt::Header("hex.builtin.tools.wiki_explain.results"_lang);
if (searchProcess.valid() && searchProcess.wait_for(0s) == std::future_status::ready) {
try {
auto response = searchProcess.get();
if (response.getStatusCode() != 200) throw std::runtime_error("Invalid response");
if (ImGui::BeginChild("##summary", ImVec2(0, 300), true)) {
if (!resultTitle.empty() && !resultExtract.empty()) {
ImGuiExt::HeaderColored(resultTitle.c_str(), ImGuiExt::GetCustomColorVec4(ImGuiCustomCol_Highlight), true);
ImGuiExt::TextFormattedWrapped("{}", resultExtract.c_str());
}
}
ImGui::EndChild();
auto json = nlohmann::json::parse(response.getData());
if (searchProcess.valid() && searchProcess.wait_for(0s) == std::future_status::ready) {
try {
auto response = searchProcess.get();
if (response.getStatusCode() != 200) throw std::runtime_error("Invalid response");
resultTitle = json.at("query").at("pages").at(0).at("title").get<std::string>();
resultExtract = json.at("query").at("pages").at(0).at("extract").get<std::string>();
auto json = nlohmann::json::parse(response.getData());
if (!extendedSearch && resultExtract.ends_with(':')) {
extendedSearch = true;
resultTitle = json.at("query").at("pages").at(0).at("title").get<std::string>();
resultExtract = json.at("query").at("pages").at(0).at("extract").get<std::string>();
request.setUrl(getWikipediaApiUrl() + "&titles="s + HttpRequest::urlEncode(searchString));
searchProcess = request.execute();
if (!extendedSearch && resultExtract.ends_with(':')) {
extendedSearch = true;
request.setUrl(getWikipediaApiUrl() + "&titles="s + HttpRequest::urlEncode(searchString));
searchProcess = request.execute();
resultTitle.clear();
resultExtract.clear();
searchString.clear();
} else {
extendedSearch = false;
searchString.clear();
}
} catch (...) {
searchString.clear();
resultTitle.clear();
resultExtract.clear();
searchString.clear();
} else {
extendedSearch = false;
searchProcess = {};
resultTitle = "???";
resultExtract = "hex.builtin.tools.wiki_explain.invalid_response"_lang.get();
searchString.clear();
}
} catch (...) {
searchString.clear();
resultTitle.clear();
resultExtract.clear();
extendedSearch = false;
searchProcess = {};
resultTitle = "???";
resultExtract = "hex.builtin.tools.wiki_explain.invalid_response"_lang.get();
}
}
}
}

View File

@ -8,47 +8,45 @@
namespace hex::plugin::builtin {
namespace impl {
void drawFileTools() {
if (ImGui::BeginTabBar("file_tools_tabs")) {
if (ImGui::BeginTabItem("hex.builtin.tools.file_tools.shredder"_lang)) {
drawFileToolShredder();
ImGui::EndTabItem();
}
if (ImGui::BeginTabItem("hex.builtin.tools.file_tools.splitter"_lang)) {
drawFileToolSplitter();
ImGui::EndTabItem();
}
if (ImGui::BeginTabItem("hex.builtin.tools.file_tools.combiner"_lang)) {
impl::drawFileToolCombiner();
ImGui::EndTabItem();
}
ImGui::EndTabBar();
void drawFileTools() {
if (ImGui::BeginTabBar("file_tools_tabs")) {
if (ImGui::BeginTabItem("hex.builtin.tools.file_tools.shredder"_lang)) {
drawFileToolShredder();
ImGui::EndTabItem();
}
if (ImGui::BeginTabItem("hex.builtin.tools.file_tools.splitter"_lang)) {
drawFileToolSplitter();
ImGui::EndTabItem();
}
if (ImGui::BeginTabItem("hex.builtin.tools.file_tools.combiner"_lang)) {
drawFileToolCombiner();
ImGui::EndTabItem();
}
ImGui::EndTabBar();
}
}
void registerToolEntries() {
ContentRegistry::Tools::add("hex.builtin.tools.demangler", impl::drawDemangler);
ContentRegistry::Tools::add("hex.builtin.tools.ascii_table", impl::drawASCIITable);
ContentRegistry::Tools::add("hex.builtin.tools.regex_replacer", impl::drawRegexReplacer);
ContentRegistry::Tools::add("hex.builtin.tools.color", impl::drawColorPicker);
ContentRegistry::Tools::add("hex.builtin.tools.calc", impl::drawMathEvaluator);
ContentRegistry::Tools::add("hex.builtin.tools.graphing", impl::drawGraphingCalculator);
ContentRegistry::Tools::add("hex.builtin.tools.base_converter", impl::drawBaseConverter);
ContentRegistry::Tools::add("hex.builtin.tools.byte_swapper", impl::drawByteSwapper);
ContentRegistry::Tools::add("hex.builtin.tools.permissions", impl::drawPermissionsCalculator);
// ContentRegistry::Tools::add("hex.builtin.tools.file_uploader", impl::drawFileUploader);
ContentRegistry::Tools::add("hex.builtin.tools.wiki_explain", impl::drawWikiExplainer);
ContentRegistry::Tools::add("hex.builtin.tools.file_tools", impl::drawFileTools);
ContentRegistry::Tools::add("hex.builtin.tools.ieee754", impl::drawIEEE754Decoder);
ContentRegistry::Tools::add("hex.builtin.tools.invariant_multiplication", impl::drawInvariantMultiplicationDecoder);
ContentRegistry::Tools::add("hex.builtin.tools.tcp_client_server", impl::drawTCPClientServer);
ContentRegistry::Tools::add("hex.builtin.tools.euclidean_algorithm", impl::drawEuclidianAlgorithm);
ContentRegistry::Tools::add("hex.builtin.tools.demangler", drawDemangler);
ContentRegistry::Tools::add("hex.builtin.tools.ascii_table", drawASCIITable);
ContentRegistry::Tools::add("hex.builtin.tools.regex_replacer", drawRegexReplacer);
ContentRegistry::Tools::add("hex.builtin.tools.color", drawColorPicker);
ContentRegistry::Tools::add("hex.builtin.tools.calc", drawMathEvaluator);
ContentRegistry::Tools::add("hex.builtin.tools.graphing", drawGraphingCalculator);
ContentRegistry::Tools::add("hex.builtin.tools.base_converter", drawBaseConverter);
ContentRegistry::Tools::add("hex.builtin.tools.byte_swapper", drawByteSwapper);
ContentRegistry::Tools::add("hex.builtin.tools.permissions", drawPermissionsCalculator);
//ContentRegistry::Tools::add("hex.builtin.tools.file_uploader", drawFileUploader);
ContentRegistry::Tools::add("hex.builtin.tools.wiki_explain", drawWikiExplainer);
ContentRegistry::Tools::add("hex.builtin.tools.file_tools", drawFileTools);
ContentRegistry::Tools::add("hex.builtin.tools.ieee754", drawIEEE754Decoder);
ContentRegistry::Tools::add("hex.builtin.tools.invariant_multiplication", drawInvariantMultiplicationDecoder);
ContentRegistry::Tools::add("hex.builtin.tools.tcp_client_server", drawTCPClientServer);
ContentRegistry::Tools::add("hex.builtin.tools.euclidean_algorithm", drawEuclidianAlgorithm);
}
}