diff --git a/include/views/view_data_inspector.hpp b/include/views/view_data_inspector.hpp index 38b4573b1..09847abd5 100644 --- a/include/views/view_data_inspector.hpp +++ b/include/views/view_data_inspector.hpp @@ -49,6 +49,12 @@ namespace hex { size_t size; }; + enum class NumberDisplayStyle { + Decimal, + Hexadecimal, + Octal + }; + class ViewDataInspector : public View { public: explicit ViewDataInspector(); @@ -60,7 +66,8 @@ namespace hex { private: bool m_shouldInvalidate = true; - std::endian m_endianess = std::endian::native; + std::endian m_endian = std::endian::native; + NumberDisplayStyle m_numberDisplayStyle = NumberDisplayStyle::Decimal; PreviewData m_previewData = { 0 }; size_t m_validBytes = 0; diff --git a/source/views/view_data_inspector.cpp b/source/views/view_data_inspector.cpp index 9cb3e20b7..0548eee21 100644 --- a/source/views/view_data_inspector.cpp +++ b/source/views/view_data_inspector.cpp @@ -50,17 +50,34 @@ namespace hex { this->m_cachedData.emplace_back("Binary (8 bit)", binary, sizeof(u8)); } - this->m_cachedData.emplace_back("uint8_t", hex::format("%u", hex::changeEndianess(this->m_previewData.unsigned8, this->m_endianess)), sizeof(u8)); - this->m_cachedData.emplace_back("int8_t", hex::format("%d", hex::changeEndianess(this->m_previewData.signed8, this->m_endianess)), sizeof(s8)); - this->m_cachedData.emplace_back("uint16_t", hex::format("%u", hex::changeEndianess(this->m_previewData.unsigned16, this->m_endianess)), sizeof(u16)); - this->m_cachedData.emplace_back("int16_t", hex::format("%d", hex::changeEndianess(this->m_previewData.signed16, this->m_endianess)), sizeof(s16)); - this->m_cachedData.emplace_back("uint32_t", hex::format("%lu", hex::changeEndianess(this->m_previewData.unsigned32, this->m_endianess)), sizeof(u32)); - this->m_cachedData.emplace_back("int32_t", hex::format("%ld", hex::changeEndianess(this->m_previewData.signed32, this->m_endianess)), sizeof(s32)); - this->m_cachedData.emplace_back("uint64_t", hex::format("%llu", hex::changeEndianess(this->m_previewData.unsigned64, this->m_endianess)), sizeof(u64)); - this->m_cachedData.emplace_back("int64_t", hex::format("%lld", hex::changeEndianess(this->m_previewData.signed64, this->m_endianess)), sizeof(s64)); + std::string unsignedFormat, signedFormat; - this->m_cachedData.emplace_back("ASCII Character", hex::format("'%s'", makePrintable(this->m_previewData.ansiChar).c_str()), sizeof(char)); - this->m_cachedData.emplace_back("Wide Character", hex::format("'%lc'", this->m_previewData.wideChar == 0 ? '\x01' : hex::changeEndianess(this->m_previewData.wideChar, this->m_endianess)), sizeof(wchar_t)); + switch (this->m_numberDisplayStyle) { + case NumberDisplayStyle::Decimal: + unsignedFormat = "%llu"; + signedFormat = "%lld"; + break; + case NumberDisplayStyle::Hexadecimal: + unsignedFormat = "0x%llX"; + signedFormat = "0x%llX"; + break; + case NumberDisplayStyle::Octal: + unsignedFormat = "0o%llo"; + signedFormat = "0o%llo"; + break; + } + + this->m_cachedData.emplace_back("uint8_t", hex::format(unsignedFormat.c_str(), hex::changeEndianess(this->m_previewData.unsigned8, this->m_endian)), sizeof(u8)); + this->m_cachedData.emplace_back("int8_t", hex::format(signedFormat.c_str(), hex::changeEndianess(this->m_previewData.signed8, this->m_endian)), sizeof(s8)); + this->m_cachedData.emplace_back("uint16_t", hex::format(unsignedFormat.c_str(), hex::changeEndianess(this->m_previewData.unsigned16, this->m_endian)), sizeof(u16)); + this->m_cachedData.emplace_back("int16_t", hex::format(signedFormat.c_str(), hex::changeEndianess(this->m_previewData.signed16, this->m_endian)), sizeof(s16)); + this->m_cachedData.emplace_back("uint32_t", hex::format(unsignedFormat.c_str(), hex::changeEndianess(this->m_previewData.unsigned32, this->m_endian)), sizeof(u32)); + this->m_cachedData.emplace_back("int32_t", hex::format(signedFormat.c_str(), hex::changeEndianess(this->m_previewData.signed32, this->m_endian)), sizeof(s32)); + this->m_cachedData.emplace_back("uint64_t", hex::format(unsignedFormat.c_str(), hex::changeEndianess(this->m_previewData.unsigned64, this->m_endian)), sizeof(u64)); + this->m_cachedData.emplace_back("int64_t", hex::format(signedFormat.c_str(), hex::changeEndianess(this->m_previewData.signed64, this->m_endian)), sizeof(s64)); + + this->m_cachedData.emplace_back("ASCII Character", hex::format("'%s'", makePrintable(this->m_previewData.ansiChar).c_str()), sizeof(char)); + this->m_cachedData.emplace_back("Wide Character", hex::format("'%lc'", this->m_previewData.wideChar == 0 ? '\x01' : hex::changeEndianess(this->m_previewData.wideChar, this->m_endian)), sizeof(wchar_t)); { char buffer[5] = { 0 }; char codepointString[5] = { 0 }; @@ -73,12 +90,12 @@ namespace hex { this->m_cachedData.emplace_back("UTF-8 code point", hex::format("'%s' (U+%04lx)", codepoint == 0xFFFD ? "Invalid" : codepointString, codepoint), sizeof(char8_t)); } - this->m_cachedData.emplace_back("float (32 bit)", hex::format("%e", hex::changeEndianess(this->m_previewData.float32, this->m_endianess)), sizeof(float)); - this->m_cachedData.emplace_back("double (64 bit)", hex::format("%e", hex::changeEndianess(this->m_previewData.float64, this->m_endianess)), sizeof(double)); + this->m_cachedData.emplace_back("float (32 bit)", hex::format("%e", hex::changeEndianess(this->m_previewData.float32, this->m_endian)), sizeof(float)); + this->m_cachedData.emplace_back("double (64 bit)", hex::format("%e", hex::changeEndianess(this->m_previewData.float64, this->m_endian)), sizeof(double)); #if defined(OS_WINDOWS) && defined(ARCH_64_BIT) { - auto endianAdjustedTime = hex::changeEndianess(this->m_previewData.time32, this->m_endianess); + auto endianAdjustedTime = hex::changeEndianess(this->m_previewData.time32, this->m_endian); std::tm * ptm = _localtime32(&endianAdjustedTime); char buffer[32]; if (ptm != nullptr && std::strftime(buffer, 32, "%a, %d.%m.%Y %H:%M:%S", ptm)) @@ -88,7 +105,7 @@ namespace hex { } { - auto endianAdjustedTime = hex::changeEndianess(this->m_previewData.time64, this->m_endianess); + auto endianAdjustedTime = hex::changeEndianess(this->m_previewData.time64, this->m_endian); std::tm * ptm = _localtime64(&endianAdjustedTime); char buffer[64]; if (ptm != nullptr && std::strftime(buffer, 64, "%a, %d.%m.%Y %H:%M:%S", ptm) != 0) @@ -98,7 +115,7 @@ namespace hex { } #else { - auto endianAdjustedTime = hex::changeEndianess(this->m_previewData.time, this->m_endianess); + auto endianAdjustedTime = hex::changeEndianess(this->m_previewData.time, this->m_endian); std::tm * ptm = localtime(&endianAdjustedTime); char buffer[64]; if (ptm != nullptr && std::strftime(buffer, 64, "%a, %d.%m.%Y %H:%M:%S", ptm) != 0) @@ -110,9 +127,9 @@ namespace hex { this->m_cachedData.emplace_back("GUID", hex::format("%s{%08lX-%04hX-%04hX-%02hhX%02hhX-%02hhX%02hhX%02hhX%02hhX%02hhX%02hhX}", (this->m_previewData.guid.data3 >> 12) <= 5 && ((this->m_previewData.guid.data4[0] >> 4) >= 8 || (this->m_previewData.guid.data4[0] >> 4) == 0) ? "" : "Invalid ", - hex::changeEndianess(this->m_previewData.guid.data1, this->m_endianess), - hex::changeEndianess(this->m_previewData.guid.data2, this->m_endianess), - hex::changeEndianess(this->m_previewData.guid.data3, this->m_endianess), + hex::changeEndianess(this->m_previewData.guid.data1, this->m_endian), + hex::changeEndianess(this->m_previewData.guid.data2, this->m_endian), + hex::changeEndianess(this->m_previewData.guid.data3, this->m_endian), this->m_previewData.guid.data4[0], this->m_previewData.guid.data4[1], this->m_previewData.guid.data4[2], this->m_previewData.guid.data4[3], this->m_previewData.guid.data4[4], this->m_previewData.guid.data4[5], this->m_previewData.guid.data4[6], this->m_previewData.guid.data4[7]), sizeof(GUID)); @@ -123,45 +140,62 @@ namespace hex { auto provider = prv::Provider::getCurrentProvider(); if (provider != nullptr && provider->isReadable()) { - if (ImGui::BeginChild("##scrolling", ImVec2(0, ImGui::GetWindowHeight() - 60))) { - if (ImGui::BeginTable("##datainspector", 2, ImGuiTableFlags_Borders | ImGuiTableFlags_Resizable | ImGuiTableFlags_RowBg | ImGuiTableFlags_NoBordersInBody)) { - ImGui::TableSetupColumn("Name"); - ImGui::TableSetupColumn("Value"); + if (ImGui::BeginTable("##datainspector", 2, + ImGuiTableFlags_ScrollY | ImGuiTableFlags_Borders | ImGuiTableFlags_Resizable | ImGuiTableFlags_RowBg, + ImVec2(0, ImGui::GetTextLineHeightWithSpacing() * (this->m_cachedData.size() + 2)))) { + ImGui::TableSetupScrollFreeze(0, 1); + ImGui::TableSetupColumn("Name"); + ImGui::TableSetupColumn("Value"); - ImGui::TableHeadersRow(); + ImGui::TableHeadersRow(); - for (const auto &[name, value, size] : this->m_cachedData) { - if (this->m_validBytes < size) continue; + for (const auto &[name, value, size] : this->m_cachedData) { + if (this->m_validBytes < size) continue; - ImGui::TableNextRow(); - ImGui::TableNextColumn(); - ImGui::TextUnformatted(name.c_str()); - ImGui::TableNextColumn(); - ImGui::TextUnformatted(value.c_str()); - } - - if (this->m_validBytes >= 4) { - ImGui::TableNextRow(); - ImGui::TableNextColumn(); - ImGui::TextUnformatted("RGBA Color"); - ImGui::TableNextColumn(); - ImGui::ColorButton("##nolabel", ImColor(hex::changeEndianess(this->m_previewData.unsigned32, this->m_endianess)), - ImGuiColorEditFlags_None, ImVec2(ImGui::GetColumnWidth(), 15)); - } - - - ImGui::EndTable(); + ImGui::TableNextRow(); + ImGui::TableNextColumn(); + ImGui::TextUnformatted(name.c_str()); + ImGui::TableNextColumn(); + ImGui::TextUnformatted(value.c_str()); } - } - ImGui::EndChild(); - if (ImGui::RadioButton("Little Endian", this->m_endianess == std::endian::little)) { - this->m_endianess = std::endian::little; + if (this->m_validBytes >= 4) { + ImGui::TableNextRow(); + ImGui::TableNextColumn(); + ImGui::TextUnformatted("RGBA Color"); + ImGui::TableNextColumn(); + ImGui::ColorButton("##nolabel", ImColor(hex::changeEndianess(this->m_previewData.unsigned32, this->m_endian)), + ImGuiColorEditFlags_None, ImVec2(ImGui::GetColumnWidth(), 15)); + } + + ImGui::EndTable(); + } + + ImGui::NewLine(); + + if (ImGui::RadioButton("Little Endian", this->m_endian == std::endian::little)) { + this->m_endian = std::endian::little; this->m_shouldInvalidate = true; } ImGui::SameLine(); - if (ImGui::RadioButton("Big Endian", this->m_endianess == std::endian::big)) { - this->m_endianess = std::endian::big; + if (ImGui::RadioButton("Big Endian", this->m_endian == std::endian::big)) { + this->m_endian = std::endian::big; + this->m_shouldInvalidate = true; + } + + + if (ImGui::RadioButton("Decimal", this->m_numberDisplayStyle == NumberDisplayStyle::Decimal)) { + this->m_numberDisplayStyle = NumberDisplayStyle::Decimal; + this->m_shouldInvalidate = true; + } + ImGui::SameLine(); + if (ImGui::RadioButton("Hexadecimal", this->m_numberDisplayStyle == NumberDisplayStyle::Hexadecimal)) { + this->m_numberDisplayStyle = NumberDisplayStyle::Hexadecimal; + this->m_shouldInvalidate = true; + } + ImGui::SameLine(); + if (ImGui::RadioButton("Octal", this->m_numberDisplayStyle == NumberDisplayStyle::Octal)) { + this->m_numberDisplayStyle = NumberDisplayStyle::Octal; this->m_shouldInvalidate = true; } }