2020-11-20 23:12:58 +00:00
|
|
|
#include "views/view_data_inspector.hpp"
|
|
|
|
|
2021-01-13 16:28:27 +00:00
|
|
|
#include <hex/providers/provider.hpp>
|
2020-11-20 23:12:58 +00:00
|
|
|
|
|
|
|
#include <cstring>
|
|
|
|
|
|
|
|
extern int ImTextCharFromUtf8(unsigned int* out_char, const char* in_text, const char* in_text_end);
|
|
|
|
|
|
|
|
namespace hex {
|
|
|
|
|
2021-01-13 00:24:27 +00:00
|
|
|
using NumberDisplayStyle = ContentRegistry::DataInspector::NumberDisplayStyle;
|
|
|
|
|
2021-02-11 22:09:45 +00:00
|
|
|
ViewDataInspector::ViewDataInspector() : View("hex.view.data_inspector.name"_lang) {
|
2021-01-21 09:53:12 +00:00
|
|
|
View::subscribeEvent(Events::RegionSelected, [this](auto userData) {
|
|
|
|
auto region = std::any_cast<Region>(userData);
|
2020-11-20 23:12:58 +00:00
|
|
|
|
2021-01-12 22:28:41 +00:00
|
|
|
auto provider = SharedData::currentProvider;
|
2020-12-27 14:39:06 +00:00
|
|
|
|
|
|
|
if (provider == nullptr) {
|
2020-12-21 10:23:57 +00:00
|
|
|
this->m_validBytes = 0;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (region.address == (size_t)-1) {
|
|
|
|
this->m_validBytes = 0;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2021-01-13 00:24:27 +00:00
|
|
|
this->m_validBytes = u64(provider->getSize() - region.address);
|
|
|
|
this->m_startAddress = region.address;
|
2020-11-20 23:12:58 +00:00
|
|
|
|
|
|
|
this->m_shouldInvalidate = true;
|
|
|
|
});
|
2021-01-13 00:24:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
ViewDataInspector::~ViewDataInspector() {
|
|
|
|
View::unsubscribeEvent(Events::RegionSelected);
|
|
|
|
}
|
|
|
|
|
|
|
|
void ViewDataInspector::drawContent() {
|
|
|
|
if (this->m_shouldInvalidate) {
|
|
|
|
this->m_shouldInvalidate = false;
|
|
|
|
|
|
|
|
this->m_cachedData.clear();
|
|
|
|
auto provider = SharedData::currentProvider;
|
|
|
|
for (auto &entry : ContentRegistry::DataInspector::getEntries()) {
|
|
|
|
if (this->m_validBytes < entry.requiredSize)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
std::vector<u8> buffer(entry.requiredSize);
|
|
|
|
provider->read(this->m_startAddress, buffer.data(), buffer.size());
|
|
|
|
this->m_cachedData.emplace_back(entry.name, entry.generatorFunction(buffer, this->m_endian, this->m_numberDisplayStyle));
|
2020-11-20 23:36:38 +00:00
|
|
|
}
|
2020-11-20 23:12:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2021-02-11 22:09:45 +00:00
|
|
|
if (ImGui::Begin("hex.view.data_inspector.name"_lang, &this->getWindowOpenState(), ImGuiWindowFlags_NoCollapse)) {
|
2021-01-12 22:28:41 +00:00
|
|
|
auto provider = SharedData::currentProvider;
|
2020-12-27 14:39:06 +00:00
|
|
|
|
|
|
|
if (provider != nullptr && provider->isReadable()) {
|
2021-01-03 16:12:20 +00:00
|
|
|
if (ImGui::BeginTable("##datainspector", 2,
|
|
|
|
ImGuiTableFlags_ScrollY | ImGuiTableFlags_Borders | ImGuiTableFlags_Resizable | ImGuiTableFlags_RowBg,
|
2021-01-13 00:24:27 +00:00
|
|
|
ImVec2(0, ImGui::GetTextLineHeightWithSpacing() * (this->m_cachedData.size() + 1)))) {
|
2021-01-03 16:12:20 +00:00
|
|
|
ImGui::TableSetupScrollFreeze(0, 1);
|
2021-02-11 22:09:45 +00:00
|
|
|
ImGui::TableSetupColumn("hex.view.data_inspector.table.name"_lang);
|
|
|
|
ImGui::TableSetupColumn("hex.view.data_inspector.table.value"_lang);
|
2021-01-03 16:12:20 +00:00
|
|
|
|
|
|
|
ImGui::TableHeadersRow();
|
|
|
|
|
2021-01-13 00:24:27 +00:00
|
|
|
for (const auto &[name, function] : this->m_cachedData) {
|
2021-01-03 16:12:20 +00:00
|
|
|
ImGui::TableNextRow();
|
|
|
|
ImGui::TableNextColumn();
|
|
|
|
ImGui::TextUnformatted(name.c_str());
|
|
|
|
ImGui::TableNextColumn();
|
2021-01-13 00:24:27 +00:00
|
|
|
function();
|
2020-11-20 23:12:58 +00:00
|
|
|
}
|
2021-01-03 16:12:20 +00:00
|
|
|
|
|
|
|
ImGui::EndTable();
|
|
|
|
}
|
|
|
|
|
|
|
|
ImGui::NewLine();
|
|
|
|
|
2021-02-11 22:09:45 +00:00
|
|
|
if (ImGui::RadioButton("hex.common.little_endian"_lang, this->m_endian == std::endian::little)) {
|
2021-01-03 16:12:20 +00:00
|
|
|
this->m_endian = std::endian::little;
|
|
|
|
this->m_shouldInvalidate = true;
|
|
|
|
}
|
|
|
|
ImGui::SameLine();
|
2021-02-11 22:09:45 +00:00
|
|
|
if (ImGui::RadioButton("hex.common.big_endian"_lang, this->m_endian == std::endian::big)) {
|
2021-01-03 16:12:20 +00:00
|
|
|
this->m_endian = std::endian::big;
|
|
|
|
this->m_shouldInvalidate = true;
|
2020-11-20 23:12:58 +00:00
|
|
|
}
|
2020-11-22 14:32:37 +00:00
|
|
|
|
2021-02-11 22:09:45 +00:00
|
|
|
if (ImGui::RadioButton("hex.common.decimal"_lang, this->m_numberDisplayStyle == NumberDisplayStyle::Decimal)) {
|
2021-01-03 16:12:20 +00:00
|
|
|
this->m_numberDisplayStyle = NumberDisplayStyle::Decimal;
|
|
|
|
this->m_shouldInvalidate = true;
|
|
|
|
}
|
|
|
|
ImGui::SameLine();
|
2021-02-11 22:09:45 +00:00
|
|
|
if (ImGui::RadioButton("hex.common.hexadecimal"_lang, this->m_numberDisplayStyle == NumberDisplayStyle::Hexadecimal)) {
|
2021-01-03 16:12:20 +00:00
|
|
|
this->m_numberDisplayStyle = NumberDisplayStyle::Hexadecimal;
|
2020-11-22 14:32:37 +00:00
|
|
|
this->m_shouldInvalidate = true;
|
|
|
|
}
|
|
|
|
ImGui::SameLine();
|
2021-02-11 22:09:45 +00:00
|
|
|
if (ImGui::RadioButton("hex.common.octal"_lang, this->m_numberDisplayStyle == NumberDisplayStyle::Octal)) {
|
2021-01-03 16:12:20 +00:00
|
|
|
this->m_numberDisplayStyle = NumberDisplayStyle::Octal;
|
2020-11-22 14:32:37 +00:00
|
|
|
this->m_shouldInvalidate = true;
|
|
|
|
}
|
2020-11-20 23:12:58 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
ImGui::End();
|
|
|
|
}
|
|
|
|
|
2020-12-22 17:10:01 +00:00
|
|
|
void ViewDataInspector::drawMenu() {
|
2020-11-23 22:57:19 +00:00
|
|
|
|
2020-11-20 23:12:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|