feat: Added hex editor segment separators
This commit is contained in:
parent
71f2f3a5fc
commit
9be9eb90f6
@ -96,6 +96,7 @@ namespace hex::ui {
|
|||||||
enum class CellType : u8 { None, Hex, ASCII };
|
enum class CellType : u8 { None, Hex, ASCII };
|
||||||
|
|
||||||
void drawCell(u64 address, const u8 *data, size_t size, bool hovered, CellType cellType);
|
void drawCell(u64 address, const u8 *data, size_t size, bool hovered, CellType cellType);
|
||||||
|
void drawSeparatorLine(u64 address, bool drawVerticalConnector);
|
||||||
void drawSelectionFrame(u32 x, u32 y, Region selection, u64 byteAddress, u16 bytesPerCell, const ImVec2 &cellPos, const ImVec2 &cellSize, const ImColor &backgroundColor) const;
|
void drawSelectionFrame(u32 x, u32 y, Region selection, u64 byteAddress, u16 bytesPerCell, const ImVec2 &cellPos, const ImVec2 &cellSize, const ImColor &backgroundColor) const;
|
||||||
void drawEditor(const ImVec2 &size);
|
void drawEditor(const ImVec2 &size);
|
||||||
void drawFooter(const ImVec2 &size);
|
void drawFooter(const ImVec2 &size);
|
||||||
@ -339,6 +340,7 @@ namespace hex::ui {
|
|||||||
std::endian m_dataVisualizerEndianness = std::endian::little;
|
std::endian m_dataVisualizerEndianness = std::endian::little;
|
||||||
std::shared_ptr<ContentRegistry::HexEditor::DataVisualizer> m_currDataVisualizer;
|
std::shared_ptr<ContentRegistry::HexEditor::DataVisualizer> m_currDataVisualizer;
|
||||||
char m_unknownDataCharacter = '?';
|
char m_unknownDataCharacter = '?';
|
||||||
|
u64 m_separatorStride = 0;
|
||||||
|
|
||||||
bool m_shouldJumpToSelection = false;
|
bool m_shouldJumpToSelection = false;
|
||||||
float m_jumpPivot = 0.0F;
|
float m_jumpPivot = 0.0F;
|
||||||
|
@ -63,6 +63,7 @@
|
|||||||
"hex.ui.common.region": "Region",
|
"hex.ui.common.region": "Region",
|
||||||
"hex.ui.common.remove": "Remove",
|
"hex.ui.common.remove": "Remove",
|
||||||
"hex.ui.common.reset": "Reset",
|
"hex.ui.common.reset": "Reset",
|
||||||
|
"hex.ui.common.segment": "Segment",
|
||||||
"hex.ui.common.set": "Set",
|
"hex.ui.common.set": "Set",
|
||||||
"hex.ui.common.settings": "Settings",
|
"hex.ui.common.settings": "Settings",
|
||||||
"hex.ui.common.size": "Size",
|
"hex.ui.common.size": "Size",
|
||||||
@ -97,6 +98,8 @@
|
|||||||
"hex.ui.hex_editor.region": "Region",
|
"hex.ui.hex_editor.region": "Region",
|
||||||
"hex.ui.hex_editor.selection": "Selection",
|
"hex.ui.hex_editor.selection": "Selection",
|
||||||
"hex.ui.hex_editor.selection.none": "None",
|
"hex.ui.hex_editor.selection.none": "None",
|
||||||
|
"hex.ui.hex_editor.separator_stride": "Segment Size: 0x{0:02X}",
|
||||||
|
"hex.ui.hex_editor.no_separator": "No Segment Separators",
|
||||||
"hex.ui.hex_editor.uppercase_hex": "Upper case Hex characters",
|
"hex.ui.hex_editor.uppercase_hex": "Upper case Hex characters",
|
||||||
"hex.ui.hex_editor.visualizer": "Data visualizer",
|
"hex.ui.hex_editor.visualizer": "Data visualizer",
|
||||||
"hex.ui.pattern_drawer.color": "Color",
|
"hex.ui.pattern_drawer.color": "Color",
|
||||||
|
@ -300,6 +300,7 @@ namespace hex::ui {
|
|||||||
std::reverse(buffer.begin(), buffer.begin() + size);
|
std::reverse(buffer.begin(), buffer.begin() + size);
|
||||||
|
|
||||||
m_currDataVisualizer->draw(address, buffer.data(), size, m_upperCaseHex);
|
m_currDataVisualizer->draw(address, buffer.data(), size, m_upperCaseHex);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
asciiVisualizer.draw(address, data, size, m_upperCaseHex);
|
asciiVisualizer.draw(address, data, size, m_upperCaseHex);
|
||||||
}
|
}
|
||||||
@ -408,6 +409,26 @@ namespace hex::ui {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void HexEditor::drawSeparatorLine(u64 address, bool drawVerticalConnector) {
|
||||||
|
if (m_separatorStride == 0) return;
|
||||||
|
|
||||||
|
const u64 regionProgress = address % m_separatorStride;
|
||||||
|
const u64 cellsPerRow = m_bytesPerRow / m_currDataVisualizer->getBytesPerCell();
|
||||||
|
const auto table = ImGui::GetCurrentTable();
|
||||||
|
if (regionProgress < cellsPerRow) {
|
||||||
|
const auto rect = ImGui::TableGetCellBgRect(table, table->CurrentColumn);
|
||||||
|
|
||||||
|
const auto drawList = ImGui::GetWindowDrawList();
|
||||||
|
|
||||||
|
const auto lineColor = ImGui::GetColorU32(ImGuiCol_SeparatorActive);
|
||||||
|
drawList->AddLine(rect.Min, ImVec2(rect.Max.x, rect.Min.y), lineColor);
|
||||||
|
if (regionProgress == 0 && drawVerticalConnector) {
|
||||||
|
drawList->AddLine(ImFloor(rect.Min), ImFloor(ImVec2(rect.Min.x, rect.Max.y)), lineColor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void HexEditor::drawSelectionFrame(u32 x, u32 y, Region selection, u64 byteAddress, u16 bytesPerCell, const ImVec2 &cellPos, const ImVec2 &cellSize, const ImColor &backgroundColor) const {
|
void HexEditor::drawSelectionFrame(u32 x, u32 y, Region selection, u64 byteAddress, u16 bytesPerCell, const ImVec2 &cellPos, const ImVec2 &cellSize, const ImColor &backgroundColor) const {
|
||||||
auto drawList = ImGui::GetWindowDrawList();
|
auto drawList = ImGui::GetWindowDrawList();
|
||||||
|
|
||||||
@ -565,7 +586,14 @@ namespace hex::ui {
|
|||||||
// Draw address column
|
// Draw address column
|
||||||
ImGui::TableNextRow();
|
ImGui::TableNextRow();
|
||||||
ImGui::TableNextColumn();
|
ImGui::TableNextColumn();
|
||||||
ImGuiExt::TextFormatted(m_upperCaseHex ? "{:08X}: " : "{:08x}: ", y * m_bytesPerRow + m_provider->getBaseAddress() + m_provider->getCurrentPageAddress());
|
|
||||||
|
const auto rowAddress = y * m_bytesPerRow + m_provider->getBaseAddress() + m_provider->getCurrentPageAddress();
|
||||||
|
|
||||||
|
if (m_separatorStride > 0 && rowAddress % m_separatorStride < m_bytesPerRow)
|
||||||
|
ImGuiExt::TextFormattedColored(ImGui::GetStyleColorVec4(ImGuiCol_SeparatorActive), "{} {}", "hex.ui.common.segment"_lang, rowAddress / m_separatorStride);
|
||||||
|
else
|
||||||
|
ImGuiExt::TextFormatted(m_upperCaseHex ? "{:08X}: " : "{:08x}: ", rowAddress);
|
||||||
|
|
||||||
ImGui::TableNextColumn();
|
ImGui::TableNextColumn();
|
||||||
|
|
||||||
const u8 validBytes = std::min<u64>(m_bytesPerRow, m_provider->getSize() - y * m_bytesPerRow);
|
const u8 validBytes = std::min<u64>(m_bytesPerRow, m_provider->getSize() - y * m_bytesPerRow);
|
||||||
@ -616,8 +644,11 @@ namespace hex::ui {
|
|||||||
const u64 byteAddress = y * m_bytesPerRow + x * bytesPerCell + m_provider->getBaseAddress() + m_provider->getCurrentPageAddress();
|
const u64 byteAddress = y * m_bytesPerRow + x * bytesPerCell + m_provider->getBaseAddress() + m_provider->getCurrentPageAddress();
|
||||||
|
|
||||||
ImGui::TableNextColumn();
|
ImGui::TableNextColumn();
|
||||||
if (isColumnSeparatorColumn(x, columnCount))
|
if (y != 0) drawSeparatorLine(byteAddress, x != 0);
|
||||||
|
if (isColumnSeparatorColumn(x, columnCount)) {
|
||||||
ImGui::TableNextColumn();
|
ImGui::TableNextColumn();
|
||||||
|
if (y != 0) drawSeparatorLine(byteAddress, false);
|
||||||
|
}
|
||||||
|
|
||||||
if (x < std::ceil(float(validBytes) / bytesPerCell)) {
|
if (x < std::ceil(float(validBytes) / bytesPerCell)) {
|
||||||
auto cellStartPos = getCellPosition();
|
auto cellStartPos = getCellPosition();
|
||||||
@ -679,6 +710,7 @@ namespace hex::ui {
|
|||||||
ImGui::PopStyleVar();
|
ImGui::PopStyleVar();
|
||||||
|
|
||||||
ImGui::TableNextColumn();
|
ImGui::TableNextColumn();
|
||||||
|
if (y != 0) drawSeparatorLine(y * m_bytesPerRow + m_provider->getBaseAddress() + m_provider->getCurrentPageAddress(), false);
|
||||||
ImGui::TableNextColumn();
|
ImGui::TableNextColumn();
|
||||||
|
|
||||||
// Draw ASCII column
|
// Draw ASCII column
|
||||||
@ -691,10 +723,11 @@ namespace hex::ui {
|
|||||||
ImGui::TableNextRow();
|
ImGui::TableNextRow();
|
||||||
|
|
||||||
for (u64 x = 0; x < m_bytesPerRow; x++) {
|
for (u64 x = 0; x < m_bytesPerRow; x++) {
|
||||||
ImGui::TableNextColumn();
|
|
||||||
|
|
||||||
const u64 byteAddress = y * m_bytesPerRow + x + m_provider->getBaseAddress() + m_provider->getCurrentPageAddress();
|
const u64 byteAddress = y * m_bytesPerRow + x + m_provider->getBaseAddress() + m_provider->getCurrentPageAddress();
|
||||||
|
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
if (y != 0) drawSeparatorLine(byteAddress, true);
|
||||||
|
|
||||||
const auto cellStartPos = getCellPosition();
|
const auto cellStartPos = getCellPosition();
|
||||||
const auto cellSize = CharacterSize + scaled(ImVec2(m_characterCellPadding, 0));
|
const auto cellSize = CharacterSize + scaled(ImVec2(m_characterCellPadding, 0));
|
||||||
|
|
||||||
@ -1029,6 +1062,11 @@ namespace hex::ui {
|
|||||||
m_bytesPerRow = bytesPerRow * this->getBytesPerCell();
|
m_bytesPerRow = bytesPerRow * this->getBytesPerCell();
|
||||||
m_encodingLineStartAddresses.clear();
|
m_encodingLineStartAddresses.clear();
|
||||||
}
|
}
|
||||||
|
{
|
||||||
|
const auto min = 0;
|
||||||
|
const auto max = m_provider->getActualSize();
|
||||||
|
ImGui::SliderScalar("##separator_stride", ImGuiDataType_U64, &m_separatorStride, &min, &max, m_separatorStride == 0 ? "hex.ui.hex_editor.no_separator"_lang : hex::format("hex.ui.hex_editor.separator_stride"_lang, m_separatorStride).c_str());
|
||||||
|
}
|
||||||
ImGui::EndPopup();
|
ImGui::EndPopup();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user