impr: Better handling of hex editor selections
This commit is contained in:
parent
3c97759aa7
commit
18dd754b31
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
@ -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,10 +896,15 @@ 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);
|
||||
|
||||
if (TableSize.y > 0)
|
||||
this->drawFooter(FooterSize);
|
||||
|
||||
this->m_selectionChanged = false;
|
||||
|
Loading…
Reference in New Issue
Block a user