fix: Synchronized scrolling not working correctly
This commit is contained in:
parent
020efefb25
commit
65e2f1b5af
@ -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()) {
|
||||||
|
@ -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;
|
||||||
};
|
};
|
||||||
|
@ -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 });
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
Loading…
Reference in New Issue
Block a user