1
0
mirror of synced 2024-11-13 18:50:53 +01:00

impr: Better handling of hex editor selections

This commit is contained in:
WerWolv 2023-07-20 20:58:28 +02:00
parent 3c97759aa7
commit 18dd754b31
4 changed files with 57 additions and 35 deletions

View File

@ -54,12 +54,28 @@ namespace hex::plugin::builtin::ui {
const size_t maxAddress = this->m_provider->getActualSize() + this->m_provider->getBaseAddress() - 1;
this->m_selectionChanged = this->m_selectionStart != start || this->m_selectionEnd != end;
constexpr static auto alignDown = [](u128 value, u128 alignment) {
return value & ~(alignment - 1);
};
if (!this->m_selectionStart.has_value()) this->m_selectionStart = start;
if (!this->m_selectionEnd.has_value()) this->m_selectionEnd = end;
if (auto bytesPerCell = this->m_currDataVisualizer->getBytesPerCell(); bytesPerCell > 1) {
if (end > start) {
start = alignDown(start, bytesPerCell);
end = alignDown(end, bytesPerCell) + (bytesPerCell - 1);
} else {
start = alignDown(start, bytesPerCell) + (bytesPerCell - 1);
end = alignDown(end, bytesPerCell);
}
}
this->m_selectionStart = std::clamp<u128>(start, 0, maxAddress);
this->m_selectionEnd = std::clamp<u128>(end, 0, maxAddress);
this->m_cursorPosition = this->m_selectionEnd;
this->m_selectionChanged = this->m_selectionStart != start || this->m_selectionEnd != end;
if (this->m_selectionChanged) {
auto selection = this->getSelection();
EventManager::post<EventRegionSelected>(ImHexApi::HexEditor::ProviderRegion{ { selection.address, selection.size }, this->m_provider });
@ -109,6 +125,10 @@ namespace hex::plugin::builtin::ui {
return this->m_bytesPerRow;
}
[[nodiscard]] u16 getBytesPerCell() const {
return this->m_currDataVisualizer->getBytesPerCell();
}
void setBytesPerRow(u16 bytesPerRow) {
this->m_bytesPerRow = bytesPerRow;
}

View File

@ -283,17 +283,6 @@ namespace hex::plugin::builtin {
return false;
});
ContentRegistry::Settings::add("hex.builtin.setting.hex_editor", "hex.builtin.setting.hex_editor.bytes_per_row", 16, [](auto name, nlohmann::json &setting) {
static int columns = static_cast<int>(setting);
if (ImGui::SliderInt(name.data(), &columns, 1, 32)) {
setting = columns;
return true;
}
return false;
});
ContentRegistry::Settings::add("hex.builtin.setting.hex_editor", "hex.builtin.setting.hex_editor.sync_scrolling", 0, [](auto name, nlohmann::json &setting) {
static bool syncScrolling = static_cast<int>(setting);

View File

@ -739,7 +739,7 @@ namespace hex::plugin::builtin {
auto cursor = this->m_hexEditor.getCursorPosition().value_or(selection.getEndAddress());
if (cursor > 0) {
auto pos = cursor - 1;
auto pos = cursor - this->m_hexEditor.getBytesPerCell();
this->setSelection(pos, pos);
this->m_hexEditor.scrollToSelection();
this->m_hexEditor.jumpIfOffScreen();
@ -749,7 +749,7 @@ namespace hex::plugin::builtin {
auto selection = getSelection();
auto cursor = this->m_hexEditor.getCursorPosition().value_or(selection.getEndAddress());
auto pos = cursor + 1;
auto pos = cursor + this->m_hexEditor.getBytesPerCell();
this->setSelection(pos, pos);
this->m_hexEditor.scrollToSelection();
this->m_hexEditor.jumpIfOffScreen();
@ -762,7 +762,7 @@ namespace hex::plugin::builtin {
u64 visibleByteCount = this->m_hexEditor.getBytesPerRow() * this->m_hexEditor.getVisibleRowCount();
if (cursor >= visibleByteCount) {
auto pos = cursor - visibleByteCount;
this->setSelection(pos, pos);
this->setSelection(pos, pos + this->m_hexEditor.getBytesPerCell());
this->m_hexEditor.scrollToSelection();
this->m_hexEditor.jumpIfOffScreen();
}
@ -772,7 +772,7 @@ namespace hex::plugin::builtin {
auto cursor = this->m_hexEditor.getCursorPosition().value_or(selection.getEndAddress());
auto pos = cursor + (this->m_hexEditor.getBytesPerRow() * this->m_hexEditor.getVisibleRowCount());
this->setSelection(pos, pos);
this->setSelection(pos, pos + this->m_hexEditor.getBytesPerCell());
this->m_hexEditor.scrollToSelection();
this->m_hexEditor.jumpIfOffScreen();
});
@ -782,7 +782,7 @@ namespace hex::plugin::builtin {
auto selection = getSelection();
auto cursor = this->m_hexEditor.getCursorPosition();
if (cursor == selection.getEndAddress()) {
if (cursor != selection.getStartAddress()) {
auto newCursor = std::max<u64>(cursor.value_or(selection.getEndAddress()), this->m_hexEditor.getBytesPerRow()) - this->m_hexEditor.getBytesPerRow();
setSelection(selection.getStartAddress(), newCursor);
this->m_hexEditor.setCursorPosition(newCursor);
@ -799,7 +799,7 @@ namespace hex::plugin::builtin {
auto selection = getSelection();
auto cursor = this->m_hexEditor.getCursorPosition();
if (cursor == selection.getEndAddress()) {
if (cursor != selection.getStartAddress()) {
auto newCursor = cursor.value_or(selection.getEndAddress()) + this->m_hexEditor.getBytesPerRow();
setSelection(selection.getStartAddress(), newCursor);
this->m_hexEditor.setCursorPosition(newCursor);
@ -816,12 +816,12 @@ namespace hex::plugin::builtin {
auto selection = getSelection();
auto cursor = this->m_hexEditor.getCursorPosition();
if (cursor == selection.getEndAddress()) {
auto newCursor = std::max<u64>(cursor.value_or(selection.getEndAddress()), 1) - 1;
if (cursor != selection.getStartAddress()) {
auto newCursor = cursor.value_or(selection.getEndAddress()) - this->m_hexEditor.getBytesPerCell();
setSelection(selection.getStartAddress(), newCursor);
this->m_hexEditor.setCursorPosition(newCursor);
} else {
auto newCursor = std::max<u64>(cursor.value_or(selection.getEndAddress()), 1) - 1;
auto newCursor = cursor.value_or(selection.getEndAddress()) - this->m_hexEditor.getBytesPerCell();
setSelection(newCursor, selection.getEndAddress());
this->m_hexEditor.setCursorPosition(newCursor);
}
@ -833,12 +833,12 @@ namespace hex::plugin::builtin {
auto selection = getSelection();
auto cursor = this->m_hexEditor.getCursorPosition();
if (cursor == selection.getEndAddress()) {
auto newCursor = cursor.value_or(selection.getEndAddress()) + 1;
if (cursor != selection.getStartAddress()) {
auto newCursor = cursor.value_or(selection.getEndAddress()) + this->m_hexEditor.getBytesPerCell();
setSelection(selection.getStartAddress(), newCursor);
this->m_hexEditor.setCursorPosition(newCursor);
} else {
auto newCursor = cursor.value_or(selection.getEndAddress()) + 1;
auto newCursor = cursor.value_or(selection.getEndAddress()) + this->m_hexEditor.getBytesPerCell();
setSelection(newCursor, selection.getEndAddress());
this->m_hexEditor.setCursorPosition(newCursor);
}

View File

@ -73,11 +73,6 @@ namespace hex::plugin::builtin::ui {
this->m_currDataVisualizer = ContentRegistry::HexEditor::getVisualizerByName("hex.builtin.visualizer.hexadecimal.8bit");
EventManager::subscribe<EventSettingsChanged>(this, [this] {
{
this->m_bytesPerRow = ContentRegistry::Settings::read("hex.builtin.setting.hex_editor", "hex.builtin.setting.hex_editor.bytes_per_row", 16);
this->m_encodingLineStartAddresses.clear();
}
this->m_selectionColor = ContentRegistry::Settings::read("hex.builtin.setting.hex_editor", "hex.builtin.setting.hex_editor.highlight_color", 0x60C08080);
this->m_syncScrolling = ContentRegistry::Settings::read("hex.builtin.setting.hex_editor", "hex.builtin.setting.hex_editor.sync_scrolling", 0);
this->m_byteCellPadding = ContentRegistry::Settings::read("hex.builtin.setting.hex_editor", "hex.builtin.setting.hex_editor.byte_padding", 0);
@ -366,7 +361,7 @@ namespace hex::plugin::builtin::ui {
if (this->m_grayOutZero && !foregroundColor.has_value()) {
bool allZero = true;
for (u64 i = 0; i < cellBytes; i++) {
for (u64 i = 0; i < cellBytes && (x * cellBytes + i) < bytes.size(); i++) {
if (bytes[x * cellBytes + i] != 0x00) {
allZero = false;
break;
@ -826,7 +821,7 @@ namespace hex::plugin::builtin::ui {
{
bool hasEndianess = this->m_currDataVisualizer->getBytesPerCell() > 1;
if (!hasEndianess)
this->m_dataVisualizerEndianness = std::endian::native;
@ -842,18 +837,31 @@ namespace hex::plugin::builtin::ui {
}
ImGui::SameLine(0, 2_scaled);
ImGui::PushItemWidth(ImGui::GetContentRegionAvail().x - 60_scaled);
ImGui::PushItemWidth((ImGui::GetContentRegionAvail().x / 3) * 2);
if (ImGui::BeginCombo("##visualizer", LangEntry(this->m_currDataVisualizer->getUnlocalizedName()))) {
for (const auto &visualizer : visualizers) {
if (ImGui::Selectable(LangEntry(visualizer->getUnlocalizedName()))) {
this->m_currDataVisualizer = visualizer;
this->m_encodingLineStartAddresses.clear();
if (this->m_bytesPerRow < visualizer->getBytesPerCell())
this->m_bytesPerRow = visualizer->getBytesPerCell();
}
}
ImGui::EndCombo();
}
ImGui::PopItemWidth();
ImGui::SameLine(0, 2_scaled);
ImGui::PushItemWidth(ImGui::GetContentRegionAvail().x);
int bytesPerRow = this->m_bytesPerRow / this->getBytesPerCell();
if (ImGui::SliderInt("##row_size", &bytesPerRow, 1, 32 / this->getBytesPerCell(), hex::format("{}", bytesPerRow * this->getBytesPerCell()).c_str())) {
this->m_bytesPerRow = bytesPerRow * this->getBytesPerCell();
this->m_encodingLineStartAddresses.clear();
}
ImGui::PopItemWidth();
}
ImGui::EndTable();
@ -888,11 +896,16 @@ namespace hex::plugin::builtin::ui {
void HexEditor::draw(float height) {
const auto width = ImGui::GetContentRegionAvail().x;
const auto FooterSize = ImVec2(width, ImGui::GetTextLineHeightWithSpacing() * 3.6F);
const auto TableSize = ImVec2(width, height - FooterSize.y);
auto FooterSize = ImVec2(width, ImGui::GetTextLineHeightWithSpacing() * 3.6F);
auto TableSize = ImVec2(width, height - FooterSize.y);
if (TableSize.y <= 0)
TableSize.y = height;
this->drawEditor(TableSize);
this->drawFooter(FooterSize);
if (TableSize.y > 0)
this->drawFooter(FooterSize);
this->m_selectionChanged = false;
}