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;
|
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_selectionStart = std::clamp<u128>(start, 0, maxAddress);
|
||||||
this->m_selectionEnd = std::clamp<u128>(end, 0, maxAddress);
|
this->m_selectionEnd = std::clamp<u128>(end, 0, maxAddress);
|
||||||
this->m_cursorPosition = this->m_selectionEnd;
|
this->m_cursorPosition = this->m_selectionEnd;
|
||||||
|
|
||||||
|
this->m_selectionChanged = this->m_selectionStart != start || this->m_selectionEnd != end;
|
||||||
if (this->m_selectionChanged) {
|
if (this->m_selectionChanged) {
|
||||||
auto selection = this->getSelection();
|
auto selection = this->getSelection();
|
||||||
EventManager::post<EventRegionSelected>(ImHexApi::HexEditor::ProviderRegion{ { selection.address, selection.size }, this->m_provider });
|
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;
|
return this->m_bytesPerRow;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] u16 getBytesPerCell() const {
|
||||||
|
return this->m_currDataVisualizer->getBytesPerCell();
|
||||||
|
}
|
||||||
|
|
||||||
void setBytesPerRow(u16 bytesPerRow) {
|
void setBytesPerRow(u16 bytesPerRow) {
|
||||||
this->m_bytesPerRow = bytesPerRow;
|
this->m_bytesPerRow = bytesPerRow;
|
||||||
}
|
}
|
||||||
|
@ -283,17 +283,6 @@ namespace hex::plugin::builtin {
|
|||||||
return false;
|
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) {
|
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);
|
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());
|
auto cursor = this->m_hexEditor.getCursorPosition().value_or(selection.getEndAddress());
|
||||||
|
|
||||||
if (cursor > 0) {
|
if (cursor > 0) {
|
||||||
auto pos = cursor - 1;
|
auto pos = cursor - this->m_hexEditor.getBytesPerCell();
|
||||||
this->setSelection(pos, pos);
|
this->setSelection(pos, pos);
|
||||||
this->m_hexEditor.scrollToSelection();
|
this->m_hexEditor.scrollToSelection();
|
||||||
this->m_hexEditor.jumpIfOffScreen();
|
this->m_hexEditor.jumpIfOffScreen();
|
||||||
@ -749,7 +749,7 @@ namespace hex::plugin::builtin {
|
|||||||
auto selection = getSelection();
|
auto selection = getSelection();
|
||||||
auto cursor = this->m_hexEditor.getCursorPosition().value_or(selection.getEndAddress());
|
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->setSelection(pos, pos);
|
||||||
this->m_hexEditor.scrollToSelection();
|
this->m_hexEditor.scrollToSelection();
|
||||||
this->m_hexEditor.jumpIfOffScreen();
|
this->m_hexEditor.jumpIfOffScreen();
|
||||||
@ -762,7 +762,7 @@ namespace hex::plugin::builtin {
|
|||||||
u64 visibleByteCount = this->m_hexEditor.getBytesPerRow() * this->m_hexEditor.getVisibleRowCount();
|
u64 visibleByteCount = this->m_hexEditor.getBytesPerRow() * this->m_hexEditor.getVisibleRowCount();
|
||||||
if (cursor >= visibleByteCount) {
|
if (cursor >= visibleByteCount) {
|
||||||
auto pos = 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.scrollToSelection();
|
||||||
this->m_hexEditor.jumpIfOffScreen();
|
this->m_hexEditor.jumpIfOffScreen();
|
||||||
}
|
}
|
||||||
@ -772,7 +772,7 @@ namespace hex::plugin::builtin {
|
|||||||
auto cursor = this->m_hexEditor.getCursorPosition().value_or(selection.getEndAddress());
|
auto cursor = this->m_hexEditor.getCursorPosition().value_or(selection.getEndAddress());
|
||||||
|
|
||||||
auto pos = cursor + (this->m_hexEditor.getBytesPerRow() * this->m_hexEditor.getVisibleRowCount());
|
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.scrollToSelection();
|
||||||
this->m_hexEditor.jumpIfOffScreen();
|
this->m_hexEditor.jumpIfOffScreen();
|
||||||
});
|
});
|
||||||
@ -782,7 +782,7 @@ namespace hex::plugin::builtin {
|
|||||||
auto selection = getSelection();
|
auto selection = getSelection();
|
||||||
auto cursor = this->m_hexEditor.getCursorPosition();
|
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();
|
auto newCursor = std::max<u64>(cursor.value_or(selection.getEndAddress()), this->m_hexEditor.getBytesPerRow()) - this->m_hexEditor.getBytesPerRow();
|
||||||
setSelection(selection.getStartAddress(), newCursor);
|
setSelection(selection.getStartAddress(), newCursor);
|
||||||
this->m_hexEditor.setCursorPosition(newCursor);
|
this->m_hexEditor.setCursorPosition(newCursor);
|
||||||
@ -799,7 +799,7 @@ namespace hex::plugin::builtin {
|
|||||||
auto selection = getSelection();
|
auto selection = getSelection();
|
||||||
auto cursor = this->m_hexEditor.getCursorPosition();
|
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();
|
auto newCursor = cursor.value_or(selection.getEndAddress()) + this->m_hexEditor.getBytesPerRow();
|
||||||
setSelection(selection.getStartAddress(), newCursor);
|
setSelection(selection.getStartAddress(), newCursor);
|
||||||
this->m_hexEditor.setCursorPosition(newCursor);
|
this->m_hexEditor.setCursorPosition(newCursor);
|
||||||
@ -816,12 +816,12 @@ namespace hex::plugin::builtin {
|
|||||||
auto selection = getSelection();
|
auto selection = getSelection();
|
||||||
auto cursor = this->m_hexEditor.getCursorPosition();
|
auto cursor = this->m_hexEditor.getCursorPosition();
|
||||||
|
|
||||||
if (cursor == selection.getEndAddress()) {
|
if (cursor != selection.getStartAddress()) {
|
||||||
auto newCursor = std::max<u64>(cursor.value_or(selection.getEndAddress()), 1) - 1;
|
auto newCursor = cursor.value_or(selection.getEndAddress()) - this->m_hexEditor.getBytesPerCell();
|
||||||
setSelection(selection.getStartAddress(), newCursor);
|
setSelection(selection.getStartAddress(), newCursor);
|
||||||
this->m_hexEditor.setCursorPosition(newCursor);
|
this->m_hexEditor.setCursorPosition(newCursor);
|
||||||
} else {
|
} 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());
|
setSelection(newCursor, selection.getEndAddress());
|
||||||
this->m_hexEditor.setCursorPosition(newCursor);
|
this->m_hexEditor.setCursorPosition(newCursor);
|
||||||
}
|
}
|
||||||
@ -833,12 +833,12 @@ namespace hex::plugin::builtin {
|
|||||||
auto selection = getSelection();
|
auto selection = getSelection();
|
||||||
auto cursor = this->m_hexEditor.getCursorPosition();
|
auto cursor = this->m_hexEditor.getCursorPosition();
|
||||||
|
|
||||||
if (cursor == selection.getEndAddress()) {
|
if (cursor != selection.getStartAddress()) {
|
||||||
auto newCursor = cursor.value_or(selection.getEndAddress()) + 1;
|
auto newCursor = cursor.value_or(selection.getEndAddress()) + this->m_hexEditor.getBytesPerCell();
|
||||||
setSelection(selection.getStartAddress(), newCursor);
|
setSelection(selection.getStartAddress(), newCursor);
|
||||||
this->m_hexEditor.setCursorPosition(newCursor);
|
this->m_hexEditor.setCursorPosition(newCursor);
|
||||||
} else {
|
} else {
|
||||||
auto newCursor = cursor.value_or(selection.getEndAddress()) + 1;
|
auto newCursor = cursor.value_or(selection.getEndAddress()) + this->m_hexEditor.getBytesPerCell();
|
||||||
setSelection(newCursor, selection.getEndAddress());
|
setSelection(newCursor, selection.getEndAddress());
|
||||||
this->m_hexEditor.setCursorPosition(newCursor);
|
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");
|
this->m_currDataVisualizer = ContentRegistry::HexEditor::getVisualizerByName("hex.builtin.visualizer.hexadecimal.8bit");
|
||||||
|
|
||||||
EventManager::subscribe<EventSettingsChanged>(this, [this] {
|
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_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_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);
|
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()) {
|
if (this->m_grayOutZero && !foregroundColor.has_value()) {
|
||||||
bool allZero = true;
|
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) {
|
if (bytes[x * cellBytes + i] != 0x00) {
|
||||||
allZero = false;
|
allZero = false;
|
||||||
break;
|
break;
|
||||||
@ -842,18 +837,31 @@ namespace hex::plugin::builtin::ui {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ImGui::SameLine(0, 2_scaled);
|
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()))) {
|
if (ImGui::BeginCombo("##visualizer", LangEntry(this->m_currDataVisualizer->getUnlocalizedName()))) {
|
||||||
|
|
||||||
for (const auto &visualizer : visualizers) {
|
for (const auto &visualizer : visualizers) {
|
||||||
if (ImGui::Selectable(LangEntry(visualizer->getUnlocalizedName()))) {
|
if (ImGui::Selectable(LangEntry(visualizer->getUnlocalizedName()))) {
|
||||||
this->m_currDataVisualizer = visualizer;
|
this->m_currDataVisualizer = visualizer;
|
||||||
|
this->m_encodingLineStartAddresses.clear();
|
||||||
|
|
||||||
|
if (this->m_bytesPerRow < visualizer->getBytesPerCell())
|
||||||
|
this->m_bytesPerRow = visualizer->getBytesPerCell();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGui::EndCombo();
|
ImGui::EndCombo();
|
||||||
}
|
}
|
||||||
ImGui::PopItemWidth();
|
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();
|
ImGui::EndTable();
|
||||||
@ -888,10 +896,15 @@ namespace hex::plugin::builtin::ui {
|
|||||||
void HexEditor::draw(float height) {
|
void HexEditor::draw(float height) {
|
||||||
const auto width = ImGui::GetContentRegionAvail().x;
|
const auto width = ImGui::GetContentRegionAvail().x;
|
||||||
|
|
||||||
const auto FooterSize = ImVec2(width, ImGui::GetTextLineHeightWithSpacing() * 3.6F);
|
auto FooterSize = ImVec2(width, ImGui::GetTextLineHeightWithSpacing() * 3.6F);
|
||||||
const auto TableSize = ImVec2(width, height - FooterSize.y);
|
auto TableSize = ImVec2(width, height - FooterSize.y);
|
||||||
|
|
||||||
|
if (TableSize.y <= 0)
|
||||||
|
TableSize.y = height;
|
||||||
|
|
||||||
this->drawEditor(TableSize);
|
this->drawEditor(TableSize);
|
||||||
|
|
||||||
|
if (TableSize.y > 0)
|
||||||
this->drawFooter(FooterSize);
|
this->drawFooter(FooterSize);
|
||||||
|
|
||||||
this->m_selectionChanged = false;
|
this->m_selectionChanged = false;
|
||||||
|
Loading…
Reference in New Issue
Block a user