diff --git a/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/HexViewerWidget/ByteItem.hpp b/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/HexViewerWidget/ByteItem.hpp index 006180bc..f02a2e0f 100644 --- a/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/HexViewerWidget/ByteItem.hpp +++ b/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/HexViewerWidget/ByteItem.hpp @@ -25,6 +25,7 @@ namespace Widgets bool grouped:1 = false; bool stackMemory:1 = false; bool changed:1 = false; + bool highlighted:1 = false; explicit ByteItem(Targets::TargetMemoryAddress address); diff --git a/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/HexViewerWidget/HexViewerItemRenderer.cpp b/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/HexViewerWidget/HexViewerItemRenderer.cpp index c39ac3bf..a6e14fd9 100644 --- a/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/HexViewerWidget/HexViewerItemRenderer.cpp +++ b/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/HexViewerWidget/HexViewerItemRenderer.cpp @@ -72,7 +72,13 @@ namespace Widgets const auto position = item->position(); const auto boundingRect = QRect(position.x(), position.y(), ByteItem::WIDTH, ByteItem::HEIGHT); - painter->setOpacity(!this->isEnabled() || (item->excluded && !item->selected) ? 0.6 : 1); + painter->setOpacity( + !this->isEnabled() + || (item->excluded && !item->selected) + || (this->hexViewerState.highlightingEnabled && !item->highlighted) + ? 0.6 + : 1 + ); if (item->excluded || !this->hexViewerState.data.has_value()) { if (item->selected) { diff --git a/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/HexViewerWidget/HexViewerSharedState.hpp b/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/HexViewerWidget/HexViewerSharedState.hpp index 19b96295..24503983 100644 --- a/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/HexViewerWidget/HexViewerSharedState.hpp +++ b/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/HexViewerWidget/HexViewerSharedState.hpp @@ -19,6 +19,7 @@ namespace Widgets ByteItem* hoveredByteItem = nullptr; std::optional currentStackPointer; + bool highlightingEnabled = false; HexViewerSharedState( const Targets::TargetMemoryDescriptor& memoryDescriptor, diff --git a/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/HexViewerWidget/HexViewerWidget.cpp b/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/HexViewerWidget/HexViewerWidget.cpp index 98aa869f..424230cd 100644 --- a/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/HexViewerWidget/HexViewerWidget.cpp +++ b/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/HexViewerWidget/HexViewerWidget.cpp @@ -242,6 +242,28 @@ namespace Widgets this->byteItemGraphicsScene->addExternalContextMenuAction(action); } + void HexViewerWidget::highlightBytes(const std::set& addresses) { + this->byteItemGraphicsScene->highlightByteItems(addresses); + } + + void HexViewerWidget::highlightBytes(const std::set& addressRanges) { + this->byteItemGraphicsScene->highlightByteItems(this->addressRangesToAddresses(addressRanges)); + } + + void HexViewerWidget::clearHighlighting() { + this->highlightBytes(std::set()); + } + + void HexViewerWidget::selectAndHighlightBytes(const std::set& addressRanges) { + const auto addresses = this->addressRangesToAddresses(addressRanges); + this->byteItemGraphicsScene->highlightByteItems(addresses); + this->byteItemGraphicsScene->selectByteItems(addresses); + } + + void HexViewerWidget::centerOnByte(Targets::TargetMemoryAddress address) { + this->byteItemGraphicsView->scrollToByteItemAtAddress(address); + } + void HexViewerWidget::resizeEvent(QResizeEvent* event) { this->container->setFixedSize( this->width(), @@ -370,4 +392,19 @@ namespace Widgets ); this->selectionCountLabel->show(); } + + std::set HexViewerWidget::addressRangesToAddresses( + const std::set& addressRanges + ) { + auto addresses = std::set(); + auto addressesIt = addresses.end(); + + for (const auto& range : addressRanges) { + for (auto i = range.startAddress; i <= range.endAddress; ++i) { + addressesIt = addresses.insert(addressesIt, i); + } + } + + return addresses; + } } diff --git a/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/HexViewerWidget/HexViewerWidget.hpp b/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/HexViewerWidget/HexViewerWidget.hpp index 5306b669..68f8f7ff 100644 --- a/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/HexViewerWidget/HexViewerWidget.hpp +++ b/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/HexViewerWidget/HexViewerWidget.hpp @@ -42,6 +42,11 @@ namespace Widgets void refreshRegions(); void setStackPointer(Targets::TargetStackPointer stackPointer); void addExternalContextMenuAction(ContextMenuAction* action); + void highlightBytes(const std::set& addresses); + void highlightBytes(const std::set& addressRanges); + void clearHighlighting(); + void selectAndHighlightBytes(const std::set& addressRanges); + void centerOnByte(Targets::TargetMemoryAddress address); signals: void ready(); @@ -89,5 +94,8 @@ namespace Widgets void onByteSelectionChanged( const std::unordered_map& selectedByteItemsByAddress ); + std::set addressRangesToAddresses( + const std::set& addressRanges + ); }; } diff --git a/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/HexViewerWidget/ItemGraphicsScene.cpp b/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/HexViewerWidget/ItemGraphicsScene.cpp index 97442079..2c036f95 100644 --- a/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/HexViewerWidget/ItemGraphicsScene.cpp +++ b/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/HexViewerWidget/ItemGraphicsScene.cpp @@ -237,6 +237,15 @@ namespace Widgets emit this->selectionChanged(this->selectedByteItemsByAddress); } + void ItemGraphicsScene::highlightByteItems(const std::set& addresses) { + for (auto& [address, byteItem] : this->topLevelGroup->byteItemsByAddress) { + byteItem.highlighted = addresses.contains(address); + } + + this->state.highlightingEnabled = !addresses.empty(); + this->update(); + } + void ItemGraphicsScene::rebuildItemHierarchy() { this->topLevelGroup->rebuildItemHierarchy(); this->itemIndex->refreshFlattenedItems(); @@ -357,6 +366,11 @@ namespace Widgets const auto button = mouseEvent->button(); const auto mousePosition = mouseEvent->buttonDownScenePos(button); + if (this->state.highlightingEnabled) { + this->state.highlightingEnabled = false; + this->update(); + } + if (mousePosition.x() <= this->byteAddressContainer->boundingRect().width()) { return; } diff --git a/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/HexViewerWidget/ItemGraphicsScene.hpp b/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/HexViewerWidget/ItemGraphicsScene.hpp index b73a6a53..4f6a8ab5 100644 --- a/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/HexViewerWidget/ItemGraphicsScene.hpp +++ b/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/HexViewerWidget/ItemGraphicsScene.hpp @@ -56,6 +56,7 @@ namespace Widgets void init(); void updateStackPointer(Targets::TargetStackPointer stackPointer); void selectByteItems(const std::set& addresses); + void highlightByteItems(const std::set& addresses); void rebuildItemHierarchy(); void adjustSize(); void setEnabled(bool enabled);