From 64be6d89eee80a563cd0dc30cc3a322c74c7ac64 Mon Sep 17 00:00:00 2001 From: WerWolv Date: Fri, 17 Mar 2023 09:17:44 +0100 Subject: [PATCH] fix: Moving cursor around using arrow keys behaving weirdly --- lib/libimhex/source/providers/provider.cpp | 4 +- plugins/builtin/include/ui/hex_editor.hpp | 11 +++ .../source/content/views/view_hex_editor.cpp | 72 +++++++++++++++---- 3 files changed, 72 insertions(+), 15 deletions(-) diff --git a/lib/libimhex/source/providers/provider.cpp b/lib/libimhex/source/providers/provider.cpp index 97cc766ef..4e052b039 100644 --- a/lib/libimhex/source/providers/provider.cpp +++ b/lib/libimhex/source/providers/provider.cpp @@ -51,8 +51,8 @@ namespace hex::prv { offset = region.getEndAddress() + 1; auto [newRegion, newValid] = this->getRegionValidity(offset + this->getBaseAddress()); - bufferSize = std::min(bufferSize, (newRegion.getEndAddress() - offset) + 1); - bufferSize = std::min(bufferSize, this->getActualSize() - offset); + bufferSize = std::min(bufferSize, (newRegion.getEndAddress() - offset) + 1); + bufferSize = std::min(bufferSize, this->getActualSize() - offset); this->read(offset + this->getBaseAddress(), buffer.data(), bufferSize, true); file.write(buffer.data(), bufferSize); diff --git a/plugins/builtin/include/ui/hex_editor.hpp b/plugins/builtin/include/ui/hex_editor.hpp index 38d05c233..40e92d576 100644 --- a/plugins/builtin/include/ui/hex_editor.hpp +++ b/plugins/builtin/include/ui/hex_editor.hpp @@ -43,6 +43,7 @@ namespace hex::plugin::builtin::ui { void setSelectionUnchecked(std::optional start, std::optional end) { this->m_selectionStart = start; this->m_selectionEnd = end; + this->m_cursorPosition = end; } void setSelection(const Region ®ion) { this->setSelection(region.getStartAddress(), region.getEndAddress()); } void setSelection(u128 start, u128 end) { @@ -55,6 +56,7 @@ namespace hex::plugin::builtin::ui { this->m_selectionStart = std::clamp(start, 0, maxAddress); this->m_selectionEnd = std::clamp(end, 0, maxAddress); + this->m_cursorPosition = this->m_selectionEnd; if (this->m_selectionChanged) { auto selection = this->getSelection(); @@ -74,6 +76,14 @@ namespace hex::plugin::builtin::ui { return { start, size }; } + [[nodiscard]] std::optional getCursorPosition() const { + return this->m_cursorPosition; + } + + void setCursorPosition(u64 cursorPosition) { + this->m_cursorPosition = cursorPosition; + } + [[nodiscard]] bool isSelectionValid() const { return this->m_selectionStart.has_value() && this->m_selectionEnd.has_value(); } @@ -171,6 +181,7 @@ namespace hex::plugin::builtin::ui { std::optional m_selectionStart; std::optional m_selectionEnd; + std::optional m_cursorPosition; float m_scrollPosition = 0; u16 m_bytesPerRow = 16; diff --git a/plugins/builtin/source/content/views/view_hex_editor.cpp b/plugins/builtin/source/content/views/view_hex_editor.cpp index 46aca20b4..89b77962f 100644 --- a/plugins/builtin/source/content/views/view_hex_editor.cpp +++ b/plugins/builtin/source/content/views/view_hex_editor.cpp @@ -702,9 +702,10 @@ namespace hex::plugin::builtin { // Move cursor around ShortcutManager::addShortcut(this, Keys::Up, [this] { auto selection = getSelection(); + auto cursor = this->m_hexEditor.getCursorPosition().value_or(selection.getEndAddress()); - if (selection.getEndAddress() >= this->m_hexEditor.getBytesPerRow()) { - auto pos = selection.getEndAddress() - this->m_hexEditor.getBytesPerRow(); + if (cursor >= this->m_hexEditor.getBytesPerRow()) { + auto pos = cursor - this->m_hexEditor.getBytesPerRow(); this->setSelection(pos, pos); this->m_hexEditor.scrollToSelection(); this->m_hexEditor.jumpIfOffScreen(); @@ -712,17 +713,19 @@ namespace hex::plugin::builtin { }); ShortcutManager::addShortcut(this, Keys::Down, [this] { auto selection = getSelection(); + auto cursor = this->m_hexEditor.getCursorPosition().value_or(selection.getEndAddress()); - auto pos = selection.getEndAddress() + this->m_hexEditor.getBytesPerRow(); + auto pos = cursor + this->m_hexEditor.getBytesPerRow(); this->setSelection(pos, pos); this->m_hexEditor.scrollToSelection(); this->m_hexEditor.jumpIfOffScreen(); }); ShortcutManager::addShortcut(this, Keys::Left, [this] { auto selection = getSelection(); + auto cursor = this->m_hexEditor.getCursorPosition().value_or(selection.getEndAddress()); - if (selection.getEndAddress() > 0) { - auto pos = selection.getEndAddress() - 1; + if (cursor > 0) { + auto pos = cursor - 1; this->setSelection(pos, pos); this->m_hexEditor.scrollToSelection(); this->m_hexEditor.jumpIfOffScreen(); @@ -730,8 +733,9 @@ namespace hex::plugin::builtin { }); ShortcutManager::addShortcut(this, Keys::Right, [this] { auto selection = getSelection(); + auto cursor = this->m_hexEditor.getCursorPosition().value_or(selection.getEndAddress()); - auto pos = selection.getEndAddress() + 1; + auto pos = cursor + 1; this->setSelection(pos, pos); this->m_hexEditor.scrollToSelection(); this->m_hexEditor.jumpIfOffScreen(); @@ -739,10 +743,11 @@ namespace hex::plugin::builtin { ShortcutManager::addShortcut(this, Keys::PageUp, [this] { auto selection = getSelection(); + auto cursor = this->m_hexEditor.getCursorPosition().value_or(selection.getEndAddress()); u64 visibleByteCount = this->m_hexEditor.getBytesPerRow() * this->m_hexEditor.getVisibleRowCount(); - if (selection.getEndAddress() >= visibleByteCount) { - auto pos = selection.getEndAddress() - visibleByteCount; + if (cursor >= visibleByteCount) { + auto pos = cursor - visibleByteCount; this->setSelection(pos, pos); this->m_hexEditor.scrollToSelection(); this->m_hexEditor.jumpIfOffScreen(); @@ -750,8 +755,9 @@ namespace hex::plugin::builtin { }); ShortcutManager::addShortcut(this, Keys::PageDown, [this] { auto selection = getSelection(); + auto cursor = this->m_hexEditor.getCursorPosition().value_or(selection.getEndAddress()); - auto pos = selection.getEndAddress() + (this->m_hexEditor.getBytesPerRow() * this->m_hexEditor.getVisibleRowCount()); + auto pos = cursor + (this->m_hexEditor.getBytesPerRow() * this->m_hexEditor.getVisibleRowCount()); this->setSelection(pos, pos); this->m_hexEditor.scrollToSelection(); this->m_hexEditor.jumpIfOffScreen(); @@ -760,29 +766,69 @@ namespace hex::plugin::builtin { // Move selection around ShortcutManager::addShortcut(this, SHIFT + Keys::Up, [this] { auto selection = getSelection(); + auto cursor = this->m_hexEditor.getCursorPosition(); + + if (cursor == selection.getEndAddress()) { + auto newCursor = std::max(cursor.value_or(selection.getEndAddress()), this->m_hexEditor.getBytesPerRow()) - this->m_hexEditor.getBytesPerRow(); + setSelection(selection.getStartAddress(), newCursor); + this->m_hexEditor.setCursorPosition(newCursor); + } else { + auto newCursor = std::max(cursor.value_or(selection.getEndAddress()), this->m_hexEditor.getBytesPerRow()) - this->m_hexEditor.getBytesPerRow(); + setSelection(newCursor, selection.getEndAddress()); + this->m_hexEditor.setCursorPosition(newCursor); + } - this->setSelection(std::max(selection.getStartAddress(), this->m_hexEditor.getBytesPerRow()) - this->m_hexEditor.getBytesPerRow(), selection.getEndAddress()); this->m_hexEditor.scrollToSelection(); this->m_hexEditor.jumpIfOffScreen(); }); ShortcutManager::addShortcut(this, SHIFT + Keys::Down, [this] { auto selection = getSelection(); + auto cursor = this->m_hexEditor.getCursorPosition(); + + if (cursor == selection.getEndAddress()) { + auto newCursor = cursor.value_or(selection.getEndAddress()) + this->m_hexEditor.getBytesPerRow(); + setSelection(selection.getStartAddress(), newCursor); + this->m_hexEditor.setCursorPosition(newCursor); + } else { + auto newCursor = cursor.value_or(selection.getEndAddress()) + this->m_hexEditor.getBytesPerRow(); + setSelection(newCursor, selection.getEndAddress()); + this->m_hexEditor.setCursorPosition(newCursor); + } - this->setSelection(selection.getStartAddress() + this->m_hexEditor.getBytesPerRow(), selection.getEndAddress()); this->m_hexEditor.scrollToSelection(); this->m_hexEditor.jumpIfOffScreen(); }); ShortcutManager::addShortcut(this, SHIFT + Keys::Left, [this] { auto selection = getSelection(); + auto cursor = this->m_hexEditor.getCursorPosition(); + + if (cursor == selection.getEndAddress()) { + auto newCursor = std::max(cursor.value_or(selection.getEndAddress()), 1) - 1; + setSelection(selection.getStartAddress(), newCursor); + this->m_hexEditor.setCursorPosition(newCursor); + } else { + auto newCursor = std::max(cursor.value_or(selection.getEndAddress()), 1) - 1; + setSelection(newCursor, selection.getEndAddress()); + this->m_hexEditor.setCursorPosition(newCursor); + } - this->setSelection(std::max(selection.getStartAddress(), 1) - 1, selection.getEndAddress()); this->m_hexEditor.scrollToSelection(); this->m_hexEditor.jumpIfOffScreen(); }); ShortcutManager::addShortcut(this, SHIFT + Keys::Right, [this] { auto selection = getSelection(); + auto cursor = this->m_hexEditor.getCursorPosition(); + + if (cursor == selection.getEndAddress()) { + auto newCursor = cursor.value_or(selection.getEndAddress()) + 1; + setSelection(selection.getStartAddress(), newCursor); + this->m_hexEditor.setCursorPosition(newCursor); + } else { + auto newCursor = cursor.value_or(selection.getEndAddress()) + 1; + setSelection(newCursor, selection.getEndAddress()); + this->m_hexEditor.setCursorPosition(newCursor); + } - this->setSelection(selection.getStartAddress() + 1, selection.getEndAddress()); this->m_hexEditor.scrollToSelection(); this->m_hexEditor.jumpIfOffScreen(); });