1
0
mirror of synced 2024-11-30 18:34:29 +01:00

fix: Synchronized scrolling not working correctly

This commit is contained in:
WerWolv 2023-12-24 00:06:16 +01:00
parent 020efefb25
commit 65e2f1b5af
5 changed files with 68 additions and 16 deletions

View File

@ -38,7 +38,7 @@ namespace hex {
} }
const T& get(prv::Provider *provider = ImHexApi::Provider::get()) const { const T& get(prv::Provider *provider = ImHexApi::Provider::get()) const {
return m_data[provider]; return m_data.at(provider);
} }
void set(const T &data, prv::Provider *provider = ImHexApi::Provider::get()) { void set(const T &data, prv::Provider *provider = ImHexApi::Provider::get()) {

View File

@ -74,7 +74,6 @@ namespace hex::plugin::builtin {
std::unique_ptr<Popup> m_currPopup; std::unique_ptr<Popup> m_currPopup;
PerProvider<std::optional<u64>> m_selectionStart, m_selectionEnd; PerProvider<std::optional<u64>> m_selectionStart, m_selectionEnd;
PerProvider<float> m_scrollPosition;
PerProvider<std::map<u64, color_t>> m_foregroundHighlights, m_backgroundHighlights; PerProvider<std::map<u64, color_t>> m_foregroundHighlights, m_backgroundHighlights;
}; };

View File

@ -987,21 +987,15 @@ namespace hex::plugin::builtin {
if (selection != Region::Invalid()) { if (selection != Region::Invalid()) {
m_selectionStart.get(oldProvider) = selection.getStartAddress(); m_selectionStart.get(oldProvider) = selection.getStartAddress();
m_selectionEnd.get(oldProvider) = selection.getEndAddress(); m_selectionEnd.get(oldProvider) = selection.getEndAddress();
m_scrollPosition.get(oldProvider) = m_hexEditor.getScrollPosition();
} }
} }
m_hexEditor.setSelectionUnchecked(std::nullopt, std::nullopt);
m_hexEditor.setScrollPosition(0);
if (newProvider != nullptr) { if (newProvider != nullptr) {
m_hexEditor.setSelectionUnchecked(m_selectionStart.get(newProvider), m_selectionEnd.get(newProvider)); m_hexEditor.setSelectionUnchecked(m_selectionStart.get(newProvider), m_selectionEnd.get(newProvider));
m_hexEditor.setScrollPosition(m_scrollPosition.get(newProvider));
} else { } else {
ImHexApi::HexEditor::clearSelection(); ImHexApi::HexEditor::clearSelection();
} }
m_hexEditor.forceUpdateScrollPosition();
if (isSelectionValid()) { if (isSelectionValid()) {
EventRegionSelected::post(ImHexApi::HexEditor::ProviderRegion{ this->getSelection(), newProvider }); EventRegionSelected::post(ImHexApi::HexEditor::ProviderRegion{ this->getSelection(), newProvider });
} }

View File

@ -11,6 +11,65 @@
namespace hex::ui { namespace hex::ui {
class ScrollPosition {
public:
ScrollPosition() = default;
// We explicitly don't assign any data during copy and move operations so that each instance of the
// Hex Editor will get its own independent scroll position
ScrollPosition(const ScrollPosition&) { }
ScrollPosition(ScrollPosition&&) noexcept { }
ScrollPosition& operator=(const ScrollPosition&) { return *this; }
ScrollPosition& operator=(ScrollPosition&&) noexcept { return *this; }
void setSynced(bool synced) {
m_synced = synced;
}
void setProvider(prv::Provider *provider) {
m_provider = provider;
}
ImS64& get() {
if (m_synced)
return m_syncedPosition;
else
return m_unsyncedPosition.get(m_provider);
}
const ImS64& get() const {
if (m_synced)
return m_syncedPosition;
else
return m_unsyncedPosition.get(m_provider);
}
operator ImS64&() {
return this->get();
}
operator const ImS64&() const {
return this->get();
}
ScrollPosition& operator=(ImS64 value) {
this->get() = value;
return *this;
}
auto operator<=>(const ScrollPosition &other) const {
return this->get() <=> other.get();
}
private:
bool m_synced = false;
prv::Provider *m_provider = nullptr;
ImS64 m_syncedPosition = 0;
PerProvider<ImS64> m_unsyncedPosition;
};
class HexEditor { class HexEditor {
public: public:
explicit HexEditor(prv::Provider *provider = nullptr); explicit HexEditor(prv::Provider *provider = nullptr);
@ -20,6 +79,7 @@ namespace hex::ui {
void setProvider(prv::Provider *provider) { void setProvider(prv::Provider *provider) {
m_provider = provider; m_provider = provider;
m_currValidRegion = { Region::Invalid(), false }; m_currValidRegion = { Region::Invalid(), false };
m_scrollPosition.setProvider(provider);
} }
void setUnknownDataCharacter(char character) { m_unknownDataCharacter = character; } void setUnknownDataCharacter(char character) { m_unknownDataCharacter = character; }
private: private:
@ -161,7 +221,7 @@ namespace hex::ui {
} }
void enableSyncScrolling(bool syncScrolling) { void enableSyncScrolling(bool syncScrolling) {
m_syncScrolling = syncScrolling; m_scrollPosition.setSynced(syncScrolling);
} }
void setByteCellPadding(u32 byteCellPadding) { void setByteCellPadding(u32 byteCellPadding) {
@ -202,12 +262,12 @@ namespace hex::ui {
m_tooltipCallback = callback; m_tooltipCallback = callback;
} }
[[nodiscard]] float getScrollPosition() const { [[nodiscard]] i64 getScrollPosition() const {
return m_scrollPosition; return m_scrollPosition.get();
} }
void setScrollPosition(float scrollPosition) { void setScrollPosition(i64 scrollPosition) {
m_scrollPosition = scrollPosition; m_scrollPosition.get() = scrollPosition;
} }
void setEditingAddress(u64 address) { void setEditingAddress(u64 address) {
@ -230,7 +290,7 @@ namespace hex::ui {
std::optional<u64> m_selectionStart; std::optional<u64> m_selectionStart;
std::optional<u64> m_selectionEnd; std::optional<u64> m_selectionEnd;
std::optional<u64> m_cursorPosition; std::optional<u64> m_cursorPosition;
ImS64 m_scrollPosition = 0; ScrollPosition m_scrollPosition;
u16 m_bytesPerRow = 16; u16 m_bytesPerRow = 16;
std::endian m_dataVisualizerEndianness = std::endian::little; std::endian m_dataVisualizerEndianness = std::endian::little;
@ -260,7 +320,6 @@ namespace hex::ui {
bool m_showAscii = true; bool m_showAscii = true;
bool m_showCustomEncoding = true; bool m_showCustomEncoding = true;
bool m_showHumanReadableUnits = true; bool m_showHumanReadableUnits = true;
bool m_syncScrolling = false;
u32 m_byteCellPadding = 0, m_characterCellPadding = 0; u32 m_byteCellPadding = 0, m_characterCellPadding = 0;
bool m_footerCollapsed = true; bool m_footerCollapsed = true;

View File

@ -325,7 +325,7 @@ namespace hex::ui {
bb, bb,
ImGui::GetWindowScrollbarID(window, axis), ImGui::GetWindowScrollbarID(window, axis),
axis, axis,
&m_scrollPosition, &m_scrollPosition.get(),
(std::ceil(innerRect.Max.y - innerRect.Min.y) / CharacterSize.y) - (m_visibleRowCount - 1), (std::ceil(innerRect.Max.y - innerRect.Min.y) / CharacterSize.y) - (m_visibleRowCount - 1),
std::nextafterf(numRows, std::numeric_limits<float>::max()), std::nextafterf(numRows, std::numeric_limits<float>::max()),
roundingCorners); roundingCorners);