Added annotation items in the hex viewer, for focused regions
Corrected issue with unexpected horizontal scrolling in hex viewer Added highlighting of focused byte items, in the hex viewer widget
This commit is contained in:
@@ -198,6 +198,7 @@ add_executable(Bloom
|
|||||||
src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/HexViewerWidget/ByteItem.cpp
|
src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/HexViewerWidget/ByteItem.cpp
|
||||||
src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/HexViewerWidget/ByteAddressContainer.cpp
|
src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/HexViewerWidget/ByteAddressContainer.cpp
|
||||||
src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/HexViewerWidget/ByteAddressItem.cpp
|
src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/HexViewerWidget/ByteAddressItem.cpp
|
||||||
|
src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/HexViewerWidget/AnnotationItem.cpp
|
||||||
|
|
||||||
# Memory region manager window
|
# Memory region manager window
|
||||||
src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/MemoryRegionManager/MemoryRegionManagerWindow.cpp
|
src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/MemoryRegionManager/MemoryRegionManagerWindow.cpp
|
||||||
|
|||||||
@@ -0,0 +1,81 @@
|
|||||||
|
#include "AnnotationItem.hpp"
|
||||||
|
|
||||||
|
#include <QPainter>
|
||||||
|
|
||||||
|
#include "ByteItem.hpp"
|
||||||
|
|
||||||
|
using namespace Bloom::Widgets;
|
||||||
|
|
||||||
|
AnnotationItem::AnnotationItem(std::uint32_t startAddress, std::size_t size, QString labelText, AnnotationItemPosition position)
|
||||||
|
: QGraphicsItem(nullptr),
|
||||||
|
startAddress(startAddress),
|
||||||
|
size(size),
|
||||||
|
endAddress(static_cast<std::uint32_t>(startAddress + size - 1)),
|
||||||
|
labelText(std::move(labelText)),
|
||||||
|
position(position),
|
||||||
|
width(static_cast<int>((ByteItem::WIDTH + ByteItem::RIGHT_MARGIN) * size - ByteItem::RIGHT_MARGIN)),
|
||||||
|
height(position == AnnotationItemPosition::TOP ? AnnotationItem::TOP_HEIGHT : AnnotationItem::BOTTOM_HEIGHT) {
|
||||||
|
this->setAcceptHoverEvents(true);
|
||||||
|
this->setToolTip(this->labelText);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AnnotationItem::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) {
|
||||||
|
static auto lineColor = this->getLineColor();
|
||||||
|
static auto labelFontColor = this->getLabelFontColor();
|
||||||
|
|
||||||
|
const auto isEnabled = this->isEnabled();
|
||||||
|
|
||||||
|
lineColor.setAlpha(isEnabled ? 255 : 100);
|
||||||
|
labelFontColor.setAlpha(isEnabled ? 255 : 100);
|
||||||
|
|
||||||
|
const auto fontMetrics = painter->fontMetrics();
|
||||||
|
auto labelSize = fontMetrics.size(Qt::TextSingleLine, this->labelText);
|
||||||
|
if (labelSize.width() > this->width) {
|
||||||
|
labelSize.setWidth(this->width);
|
||||||
|
this->labelText = fontMetrics.elidedText(this->labelText, Qt::TextElideMode::ElideRight, this->width);
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr auto verticalLineLength = 5;
|
||||||
|
const auto verticalLineYStart = this->position == AnnotationItemPosition::BOTTOM ? 0 : AnnotationItem::TOP_HEIGHT;
|
||||||
|
const auto verticalLineYEnd = this->position == AnnotationItemPosition::BOTTOM ?
|
||||||
|
verticalLineLength : AnnotationItem::TOP_HEIGHT - verticalLineLength;
|
||||||
|
|
||||||
|
const auto labelRect = QRect(
|
||||||
|
(this->width - labelSize.width()) / 2,
|
||||||
|
verticalLineYEnd - (this->position == AnnotationItemPosition::BOTTOM ? -6: labelSize.height() + 6),
|
||||||
|
labelSize.width(),
|
||||||
|
labelSize.height()
|
||||||
|
);
|
||||||
|
|
||||||
|
painter->setPen(lineColor);
|
||||||
|
painter->drawLine(QLine(
|
||||||
|
ByteItem::WIDTH / 2,
|
||||||
|
verticalLineYStart,
|
||||||
|
ByteItem::WIDTH / 2,
|
||||||
|
verticalLineYEnd
|
||||||
|
));
|
||||||
|
|
||||||
|
painter->drawLine(QLine(
|
||||||
|
this->width - (ByteItem::WIDTH / 2),
|
||||||
|
verticalLineYStart,
|
||||||
|
this->width - (ByteItem::WIDTH / 2),
|
||||||
|
verticalLineYEnd
|
||||||
|
));
|
||||||
|
|
||||||
|
painter->drawLine(QLine(
|
||||||
|
ByteItem::WIDTH / 2,
|
||||||
|
verticalLineYEnd,
|
||||||
|
(ByteItem::WIDTH / 2) + (this->width - ByteItem::WIDTH),
|
||||||
|
verticalLineYEnd
|
||||||
|
));
|
||||||
|
|
||||||
|
painter->drawLine(QLine(
|
||||||
|
this->width / 2,
|
||||||
|
verticalLineYEnd,
|
||||||
|
this->width / 2,
|
||||||
|
(this->position == AnnotationItemPosition::BOTTOM ? verticalLineYEnd + 4 : verticalLineYEnd - 4)
|
||||||
|
));
|
||||||
|
|
||||||
|
painter->setPen(labelFontColor);
|
||||||
|
painter->drawText(labelRect, Qt::AlignCenter, this->labelText);
|
||||||
|
}
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QGraphicsItem>
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
namespace Bloom::Widgets
|
||||||
|
{
|
||||||
|
enum class AnnotationItemPosition: std::uint8_t
|
||||||
|
{
|
||||||
|
TOP,
|
||||||
|
BOTTOM,
|
||||||
|
};
|
||||||
|
|
||||||
|
class AnnotationItem: public QGraphicsItem
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static constexpr int TOP_HEIGHT = 26;
|
||||||
|
static constexpr int BOTTOM_HEIGHT = 26;
|
||||||
|
|
||||||
|
const int width;
|
||||||
|
const int height;
|
||||||
|
const std::uint32_t startAddress;
|
||||||
|
const std::uint32_t endAddress;
|
||||||
|
AnnotationItemPosition position = AnnotationItemPosition::TOP;
|
||||||
|
|
||||||
|
AnnotationItem(
|
||||||
|
std::uint32_t startAddress,
|
||||||
|
std::size_t size,
|
||||||
|
QString labelText,
|
||||||
|
AnnotationItemPosition position
|
||||||
|
);
|
||||||
|
|
||||||
|
[[nodiscard]] QRectF boundingRect() const override {
|
||||||
|
return QRectF(0, 0, this->width, this->height);
|
||||||
|
}
|
||||||
|
void paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) override;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
[[nodiscard]] QColor getLineColor() const {
|
||||||
|
return QColor(0x4F, 0x4F, 0x4F);
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] QColor getLabelFontColor() const {
|
||||||
|
return QColor(0x8A, 0x8A, 0x8D);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::size_t size = 0;
|
||||||
|
QString labelText;
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -3,20 +3,20 @@
|
|||||||
#include <QPainter>
|
#include <QPainter>
|
||||||
#include <QStyle>
|
#include <QStyle>
|
||||||
|
|
||||||
#include "src/Logger/Logger.hpp"
|
|
||||||
|
|
||||||
using namespace Bloom::Widgets;
|
using namespace Bloom::Widgets;
|
||||||
|
|
||||||
ByteItem::ByteItem(
|
ByteItem::ByteItem(
|
||||||
std::size_t byteIndex,
|
std::size_t byteIndex,
|
||||||
std::uint32_t address,
|
std::uint32_t address,
|
||||||
std::optional<ByteItem*>& hoveredByteItem,
|
std::optional<ByteItem*>& hoveredByteItem,
|
||||||
|
std::optional<AnnotationItem*>& hoveredAnnotationItem,
|
||||||
const HexViewerWidgetSettings& settings
|
const HexViewerWidgetSettings& settings
|
||||||
):
|
):
|
||||||
QGraphicsItem(nullptr),
|
QGraphicsItem(nullptr),
|
||||||
byteIndex(byteIndex),
|
byteIndex(byteIndex),
|
||||||
address(address),
|
address(address),
|
||||||
hoveredByteItem(hoveredByteItem),
|
hoveredByteItem(hoveredByteItem),
|
||||||
|
hoveredAnnotationItem(hoveredAnnotationItem),
|
||||||
settings(settings)
|
settings(settings)
|
||||||
{
|
{
|
||||||
this->setCacheMode(
|
this->setCacheMode(
|
||||||
@@ -51,25 +51,40 @@ void ByteItem::paint(QPainter* painter, const QStyleOptionGraphicsItem* option,
|
|||||||
static const auto valueChangedTextColor = QColor(0x54, 0x7F, 0xBA);
|
static const auto valueChangedTextColor = QColor(0x54, 0x7F, 0xBA);
|
||||||
static auto font = QFont("'Ubuntu', sans-serif");
|
static auto font = QFont("'Ubuntu', sans-serif");
|
||||||
|
|
||||||
static const auto stackMemoryBackgroundColor = QColor(0x5E, 0x50, 0x27, 255);
|
static const auto focusedRegionBackgroundColor = QColor(0x25, 0x5A, 0x49, 210);
|
||||||
|
static const auto stackMemoryBackgroundColor = QColor(0x67, 0x57, 0x20, 210);
|
||||||
static const auto hoveredBackgroundColor = QColor(0x8E, 0x8B, 0x83, 70);
|
static const auto hoveredBackgroundColor = QColor(0x8E, 0x8B, 0x83, 70);
|
||||||
static const auto hoveredNeighbourBackgroundColor = QColor(0x8E, 0x8B, 0x83, 30);
|
static const auto hoveredNeighbourBackgroundColor = QColor(0x8E, 0x8B, 0x83, 30);
|
||||||
|
static const auto hoveredAnnotationBackgroundColor = QColor(0x8E, 0x8B, 0x83, 50);
|
||||||
|
|
||||||
|
const auto isEnabled = this->isEnabled();
|
||||||
|
auto textColor = this->valueChanged ? valueChangedTextColor : standardTextColor;
|
||||||
|
auto backgroundColor = std::optional<QColor>();
|
||||||
|
|
||||||
font.setPixelSize(11);
|
font.setPixelSize(11);
|
||||||
painter->setFont(font);
|
painter->setFont(font);
|
||||||
|
|
||||||
if (this->settings.highlightStackMemory && this->settings.stackPointerAddress.has_value()
|
if (this->settings.highlightFocusedMemory && this->focusedMemoryRegion != nullptr) {
|
||||||
|
// This byte is within a focused region
|
||||||
|
backgroundColor = focusedRegionBackgroundColor;
|
||||||
|
|
||||||
|
} else if (this->settings.highlightStackMemory && this->settings.stackPointerAddress.has_value()
|
||||||
&& this->address > this->settings.stackPointerAddress
|
&& this->address > this->settings.stackPointerAddress
|
||||||
) {
|
) {
|
||||||
// This byte is within the stack memory
|
// This byte is within the stack memory
|
||||||
painter->setBrush(stackMemoryBackgroundColor);
|
backgroundColor = stackMemoryBackgroundColor;
|
||||||
painter->drawRect(widgetRect);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto* hoveredByteItem = this->hoveredByteItem.value_or(nullptr);
|
const auto* hoveredByteItem = this->hoveredByteItem.value_or(nullptr);
|
||||||
|
const auto* hoveredAnnotationItem = this->hoveredAnnotationItem.value_or(nullptr);
|
||||||
if (hoveredByteItem != nullptr) {
|
if (hoveredByteItem != nullptr) {
|
||||||
if (hoveredByteItem == this) {
|
if (hoveredByteItem == this) {
|
||||||
painter->setBrush(hoveredBackgroundColor);
|
if (backgroundColor.has_value()) {
|
||||||
|
backgroundColor->setAlpha(255);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
backgroundColor = hoveredBackgroundColor;
|
||||||
|
}
|
||||||
|
|
||||||
} else if (this->settings.highlightHoveredRowAndCol
|
} else if (this->settings.highlightHoveredRowAndCol
|
||||||
&& (
|
&& (
|
||||||
@@ -77,16 +92,34 @@ void ByteItem::paint(QPainter* painter, const QStyleOptionGraphicsItem* option,
|
|||||||
|| hoveredByteItem->currentRowIndex == this->currentRowIndex
|
|| hoveredByteItem->currentRowIndex == this->currentRowIndex
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
painter->setBrush(hoveredNeighbourBackgroundColor);
|
if (backgroundColor.has_value()) {
|
||||||
|
backgroundColor->setAlpha(220);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
backgroundColor = hoveredNeighbourBackgroundColor;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} else if (
|
||||||
|
!this->settings.highlightFocusedMemory
|
||||||
|
&& hoveredAnnotationItem != nullptr
|
||||||
|
&& this->address >= hoveredAnnotationItem->startAddress
|
||||||
|
&& this->address <= hoveredAnnotationItem->endAddress
|
||||||
|
) {
|
||||||
|
backgroundColor = hoveredAnnotationBackgroundColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (backgroundColor.has_value()) {
|
||||||
|
if (!isEnabled) {
|
||||||
|
backgroundColor->setAlpha(100);
|
||||||
|
}
|
||||||
|
|
||||||
|
painter->setBrush(backgroundColor.value());
|
||||||
painter->drawRect(widgetRect);
|
painter->drawRect(widgetRect);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto textColor = this->valueChanged ? valueChangedTextColor : standardTextColor;
|
if (this->valueInitialised && this->excludedMemoryRegion == nullptr) {
|
||||||
|
if (!isEnabled) {
|
||||||
if (this->valueInitialised) {
|
|
||||||
if (!this->isEnabled()) {
|
|
||||||
textColor.setAlpha(100);
|
textColor.setAlpha(100);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,8 +5,11 @@
|
|||||||
#include <QGraphicsItem>
|
#include <QGraphicsItem>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
|
|
||||||
#include "src/Insight/UserInterfaces/InsightWindow/Widgets/ClickableWidget.hpp"
|
|
||||||
#include "HexViewerWidgetSettings.hpp"
|
#include "HexViewerWidgetSettings.hpp"
|
||||||
|
#include "AnnotationItem.hpp"
|
||||||
|
|
||||||
|
#include "src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/FocusedMemoryRegion.hpp"
|
||||||
|
#include "src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/ExcludedMemoryRegion.hpp"
|
||||||
|
|
||||||
namespace Bloom::Widgets
|
namespace Bloom::Widgets
|
||||||
{
|
{
|
||||||
@@ -28,10 +31,14 @@ namespace Bloom::Widgets
|
|||||||
std::size_t currentRowIndex = 0;
|
std::size_t currentRowIndex = 0;
|
||||||
std::size_t currentColumnIndex = 0;
|
std::size_t currentColumnIndex = 0;
|
||||||
|
|
||||||
|
const FocusedMemoryRegion* focusedMemoryRegion = nullptr;
|
||||||
|
const ExcludedMemoryRegion* excludedMemoryRegion = nullptr;
|
||||||
|
|
||||||
ByteItem(
|
ByteItem(
|
||||||
std::size_t byteIndex,
|
std::size_t byteIndex,
|
||||||
std::uint32_t address,
|
std::uint32_t address,
|
||||||
std::optional<ByteItem*>& hoveredByteItem,
|
std::optional<ByteItem*>& hoveredByteItem,
|
||||||
|
std::optional<AnnotationItem*>& hoveredAnnotationItem,
|
||||||
const HexViewerWidgetSettings& settings
|
const HexViewerWidgetSettings& settings
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -58,5 +65,6 @@ namespace Bloom::Widgets
|
|||||||
std::optional<QString> asciiValue;
|
std::optional<QString> asciiValue;
|
||||||
|
|
||||||
std::optional<ByteItem*>& hoveredByteItem;
|
std::optional<ByteItem*>& hoveredByteItem;
|
||||||
|
std::optional<AnnotationItem*>& hoveredAnnotationItem;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,20 +1,13 @@
|
|||||||
#include "ByteItemContainerGraphicsView.hpp"
|
#include "ByteItemContainerGraphicsView.hpp"
|
||||||
|
|
||||||
#include <QVBoxLayout>
|
|
||||||
#include <QTableWidget>
|
|
||||||
#include <QScrollBar>
|
|
||||||
#include <QPainter>
|
|
||||||
#include <cmath>
|
|
||||||
|
|
||||||
#include "src/Logger/Logger.hpp"
|
|
||||||
|
|
||||||
using namespace Bloom::Widgets;
|
using namespace Bloom::Widgets;
|
||||||
using namespace Bloom::Exceptions;
|
|
||||||
|
|
||||||
using Bloom::Targets::TargetMemoryDescriptor;
|
using Bloom::Targets::TargetMemoryDescriptor;
|
||||||
|
|
||||||
ByteItemContainerGraphicsView::ByteItemContainerGraphicsView(
|
ByteItemContainerGraphicsView::ByteItemContainerGraphicsView(
|
||||||
const TargetMemoryDescriptor& targetMemoryDescriptor,
|
const TargetMemoryDescriptor& targetMemoryDescriptor,
|
||||||
|
std::vector<FocusedMemoryRegion>& focusedMemoryRegions,
|
||||||
|
std::vector<ExcludedMemoryRegion>& excludedMemoryRegions,
|
||||||
InsightWorker& insightWorker,
|
InsightWorker& insightWorker,
|
||||||
const HexViewerWidgetSettings& settings,
|
const HexViewerWidgetSettings& settings,
|
||||||
QLabel* hoveredAddressLabel,
|
QLabel* hoveredAddressLabel,
|
||||||
@@ -29,6 +22,8 @@ ByteItemContainerGraphicsView::ByteItemContainerGraphicsView(
|
|||||||
|
|
||||||
this->scene = new ByteItemGraphicsScene(
|
this->scene = new ByteItemGraphicsScene(
|
||||||
targetMemoryDescriptor,
|
targetMemoryDescriptor,
|
||||||
|
focusedMemoryRegions,
|
||||||
|
excludedMemoryRegions,
|
||||||
insightWorker,
|
insightWorker,
|
||||||
settings,
|
settings,
|
||||||
hoveredAddressLabel,
|
hoveredAddressLabel,
|
||||||
@@ -49,6 +44,6 @@ bool ByteItemContainerGraphicsView::event(QEvent* event) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ByteItemContainerGraphicsView::resizeEvent(QResizeEvent* event) {
|
void ByteItemContainerGraphicsView::resizeEvent(QResizeEvent* event) {
|
||||||
this->scene->adjustByteWidgets();
|
|
||||||
QGraphicsView::resizeEvent(event);
|
QGraphicsView::resizeEvent(event);
|
||||||
|
this->scene->adjustSize();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,18 +3,10 @@
|
|||||||
#include <QGraphicsView>
|
#include <QGraphicsView>
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
#include <QLabel>
|
#include <QLabel>
|
||||||
#include <QToolButton>
|
|
||||||
#include <QVBoxLayout>
|
|
||||||
#include <map>
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <QSize>
|
|
||||||
#include <QString>
|
|
||||||
#include <QEvent>
|
#include <QEvent>
|
||||||
#include <QGraphicsSceneMouseEvent>
|
|
||||||
#include <optional>
|
|
||||||
|
|
||||||
#include "src/Targets/TargetMemory.hpp"
|
#include "src/Targets/TargetMemory.hpp"
|
||||||
#include "src/Targets/TargetState.hpp"
|
|
||||||
|
|
||||||
#include "src/Insight/InsightWorker/InsightWorker.hpp"
|
#include "src/Insight/InsightWorker/InsightWorker.hpp"
|
||||||
|
|
||||||
@@ -30,6 +22,8 @@ namespace Bloom::Widgets
|
|||||||
public:
|
public:
|
||||||
ByteItemContainerGraphicsView(
|
ByteItemContainerGraphicsView(
|
||||||
const Targets::TargetMemoryDescriptor& targetMemoryDescriptor,
|
const Targets::TargetMemoryDescriptor& targetMemoryDescriptor,
|
||||||
|
std::vector<FocusedMemoryRegion>& focusedMemoryRegions,
|
||||||
|
std::vector<ExcludedMemoryRegion>& excludedMemoryRegions,
|
||||||
InsightWorker& insightWorker,
|
InsightWorker& insightWorker,
|
||||||
const HexViewerWidgetSettings& settings,
|
const HexViewerWidgetSettings& settings,
|
||||||
QLabel* hoveredAddressLabel,
|
QLabel* hoveredAddressLabel,
|
||||||
|
|||||||
@@ -1,13 +1,7 @@
|
|||||||
#include "ByteItemGraphicsScene.hpp"
|
#include "ByteItemGraphicsScene.hpp"
|
||||||
|
|
||||||
#include <QVBoxLayout>
|
|
||||||
#include <QTableWidget>
|
|
||||||
#include <QScrollBar>
|
|
||||||
#include <QPainter>
|
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
|
||||||
#include "src/Logger/Logger.hpp"
|
|
||||||
|
|
||||||
using namespace Bloom::Widgets;
|
using namespace Bloom::Widgets;
|
||||||
using namespace Bloom::Exceptions;
|
using namespace Bloom::Exceptions;
|
||||||
|
|
||||||
@@ -15,33 +9,34 @@ using Bloom::Targets::TargetMemoryDescriptor;
|
|||||||
|
|
||||||
ByteItemGraphicsScene::ByteItemGraphicsScene(
|
ByteItemGraphicsScene::ByteItemGraphicsScene(
|
||||||
const TargetMemoryDescriptor& targetMemoryDescriptor,
|
const TargetMemoryDescriptor& targetMemoryDescriptor,
|
||||||
|
std::vector<FocusedMemoryRegion>& focusedMemoryRegions,
|
||||||
|
std::vector<ExcludedMemoryRegion>& excludedMemoryRegions,
|
||||||
InsightWorker& insightWorker,
|
InsightWorker& insightWorker,
|
||||||
const HexViewerWidgetSettings& settings,
|
const HexViewerWidgetSettings& settings,
|
||||||
QLabel* hoveredAddressLabel,
|
QLabel* hoveredAddressLabel,
|
||||||
QWidget* parent
|
QGraphicsView* parent
|
||||||
): QGraphicsScene(parent),
|
):
|
||||||
|
QGraphicsScene(parent),
|
||||||
targetMemoryDescriptor(targetMemoryDescriptor),
|
targetMemoryDescriptor(targetMemoryDescriptor),
|
||||||
|
focusedMemoryRegions(focusedMemoryRegions),
|
||||||
|
excludedMemoryRegions(excludedMemoryRegions),
|
||||||
insightWorker(insightWorker),
|
insightWorker(insightWorker),
|
||||||
settings(settings),
|
settings(settings),
|
||||||
hoveredAddressLabel(hoveredAddressLabel),
|
hoveredAddressLabel(hoveredAddressLabel),
|
||||||
parent(parent) {
|
parent(parent)
|
||||||
|
{
|
||||||
this->setObjectName("byte-widget-container");
|
this->setObjectName("byte-widget-container");
|
||||||
|
|
||||||
this->byteAddressContainer = new ByteAddressContainer();
|
this->byteAddressContainer = new ByteAddressContainer();
|
||||||
this->addItem(this->byteAddressContainer);
|
this->addItem(this->byteAddressContainer);
|
||||||
|
|
||||||
/*
|
// Construct ByteWidget objects
|
||||||
* Construct ByteWidget objects
|
|
||||||
*
|
|
||||||
* No need to position them here - the subsequent call to resizeEvent() will do that.
|
|
||||||
*/
|
|
||||||
const auto memorySize = this->targetMemoryDescriptor.size();
|
const auto memorySize = this->targetMemoryDescriptor.size();
|
||||||
const auto startAddress = this->targetMemoryDescriptor.addressRange.startAddress;
|
const auto startAddress = this->targetMemoryDescriptor.addressRange.startAddress;
|
||||||
Logger::error("Constructing bytes begin");
|
|
||||||
for (std::uint32_t i = 0; i < memorySize; i++) {
|
for (std::uint32_t i = 0; i < memorySize; i++) {
|
||||||
const auto address = startAddress + i;
|
const auto address = startAddress + i;
|
||||||
|
|
||||||
auto* byteWidget = new ByteItem(i, address, this->hoveredByteWidget, settings);
|
auto* byteWidget = new ByteItem(i, address, this->hoveredByteWidget, this->hoveredAnnotationItem, settings);
|
||||||
this->byteItemsByAddress.insert(std::pair(
|
this->byteItemsByAddress.insert(std::pair(
|
||||||
address,
|
address,
|
||||||
byteWidget
|
byteWidget
|
||||||
@@ -49,8 +44,6 @@ parent(parent) {
|
|||||||
|
|
||||||
this->addItem(byteWidget);
|
this->addItem(byteWidget);
|
||||||
}
|
}
|
||||||
Logger::error("Constructing bytes end");
|
|
||||||
this->adjustByteWidgets();
|
|
||||||
|
|
||||||
QObject::connect(
|
QObject::connect(
|
||||||
&insightWorker,
|
&insightWorker,
|
||||||
@@ -58,6 +51,9 @@ parent(parent) {
|
|||||||
this,
|
this,
|
||||||
&ByteItemGraphicsScene::onTargetStateChanged
|
&ByteItemGraphicsScene::onTargetStateChanged
|
||||||
);
|
);
|
||||||
|
|
||||||
|
this->refreshRegions();
|
||||||
|
this->adjustSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ByteItemGraphicsScene::updateValues(const Targets::TargetMemoryBuffer& buffer) {
|
void ByteItemGraphicsScene::updateValues(const Targets::TargetMemoryBuffer& buffer) {
|
||||||
@@ -67,61 +63,101 @@ void ByteItemGraphicsScene::updateValues(const Targets::TargetMemoryBuffer& buff
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ByteItemGraphicsScene::adjustByteWidgets() {
|
void ByteItemGraphicsScene::refreshRegions() {
|
||||||
const auto margins = QMargins(10, 10, 10, 10);
|
for (auto& [byteAddress, byteWidget] : this->byteItemsByAddress) {
|
||||||
const auto width = std::max(600, static_cast<int>(this->parent->width()));
|
byteWidget->focusedMemoryRegion = nullptr;
|
||||||
|
byteWidget->excludedMemoryRegion = nullptr;
|
||||||
|
|
||||||
constexpr auto byteWidgetWidth = ByteItem::WIDTH + ByteItem::RIGHT_MARGIN;
|
for (const auto& focusedRegion : this->focusedMemoryRegions) {
|
||||||
constexpr auto byteWidgetHeight = ByteItem::HEIGHT + ByteItem::BOTTOM_MARGIN;
|
const auto addressRange = focusedRegion.getAbsoluteAddressRange();
|
||||||
const auto rowCapacity = static_cast<std::size_t>(
|
if (byteAddress >= addressRange.startAddress && byteAddress <= addressRange.endAddress) {
|
||||||
std::floor((width - margins.left() - margins.right() - ByteAddressContainer::WIDTH) / byteWidgetWidth)
|
byteWidget->focusedMemoryRegion = &focusedRegion;
|
||||||
);
|
break;
|
||||||
const auto rowCount = static_cast<int>(
|
}
|
||||||
std::ceil(static_cast<double>(this->byteItemsByAddress.size()) / static_cast<double>(rowCapacity))
|
|
||||||
);
|
|
||||||
|
|
||||||
this->setSceneRect(
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
width,
|
|
||||||
std::max(((rowCount * byteWidgetHeight) + margins.top() + margins.bottom()), this->parent->height())
|
|
||||||
);
|
|
||||||
|
|
||||||
// Don't bother recalculating the byte item positions if the number of rows & columns have not changed.
|
|
||||||
if (rowCount == this->byteItemsByRowIndex.size() && rowCapacity == this->byteItemsByColumnIndex.size()) {
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::map<std::size_t, std::vector<ByteItem*>> byteWidgetsByRowIndex;
|
for (const auto& excludedRegion : this->excludedMemoryRegions) {
|
||||||
std::map<std::size_t, std::vector<ByteItem*>> byteWidgetsByColumnIndex;
|
const auto addressRange = excludedRegion.getAbsoluteAddressRange();
|
||||||
|
if (byteAddress >= addressRange.startAddress && byteAddress <= addressRange.endAddress) {
|
||||||
for (auto& [address, byteWidget] : this->byteItemsByAddress) {
|
byteWidget->excludedMemoryRegion = &excludedRegion;
|
||||||
const auto rowIndex = static_cast<std::size_t>(
|
break;
|
||||||
std::ceil(static_cast<double>(byteWidget->byteIndex + 1) / static_cast<double>(rowCapacity)) - 1
|
}
|
||||||
);
|
}
|
||||||
const auto columnIndex = static_cast<std::size_t>(
|
|
||||||
static_cast<double>(byteWidget->byteIndex)
|
|
||||||
- (std::floor(byteWidget->byteIndex / rowCapacity) * static_cast<double>(rowCapacity))
|
|
||||||
);
|
|
||||||
|
|
||||||
byteWidget->setPos(
|
|
||||||
static_cast<int>(columnIndex * byteWidgetWidth + margins.left() + ByteAddressContainer::WIDTH),
|
|
||||||
static_cast<int>(rowIndex * byteWidgetHeight + static_cast<std::size_t>(margins.top()))
|
|
||||||
);
|
|
||||||
|
|
||||||
byteWidget->currentRowIndex = static_cast<std::size_t>(rowIndex);
|
|
||||||
byteWidget->currentColumnIndex = static_cast<std::size_t>(columnIndex);
|
|
||||||
|
|
||||||
byteWidgetsByRowIndex[byteWidget->currentRowIndex].emplace_back(byteWidget);
|
|
||||||
byteWidgetsByColumnIndex[byteWidget->currentColumnIndex].emplace_back(byteWidget);
|
|
||||||
|
|
||||||
byteWidget->update();
|
byteWidget->update();
|
||||||
}
|
}
|
||||||
|
|
||||||
this->byteItemsByRowIndex = std::move(byteWidgetsByRowIndex);
|
// Refresh annotation items
|
||||||
this->byteItemsByColumnIndex = std::move(byteWidgetsByColumnIndex);
|
for (auto [startAddress, annotationItem] : this->annotationItemsByStartAddress) {
|
||||||
|
this->removeItem(annotationItem);
|
||||||
|
delete annotationItem;
|
||||||
|
}
|
||||||
|
|
||||||
this->byteAddressContainer->adjustAddressLabels(this->byteItemsByRowIndex);
|
this->annotationItemsByStartAddress.clear();
|
||||||
|
|
||||||
|
for (const auto& focusedRegion : this->focusedMemoryRegions) {
|
||||||
|
const auto addressRange = focusedRegion.getAbsoluteAddressRange();
|
||||||
|
auto* annotationItem = new AnnotationItem(
|
||||||
|
addressRange.startAddress,
|
||||||
|
addressRange.endAddress - addressRange.startAddress + 1,
|
||||||
|
focusedRegion.name,
|
||||||
|
AnnotationItemPosition::BOTTOM
|
||||||
|
);
|
||||||
|
this->addItem(annotationItem);
|
||||||
|
this->annotationItemsByStartAddress.insert(std::pair(addressRange.startAddress, annotationItem));
|
||||||
|
}
|
||||||
|
|
||||||
|
this->adjustSize(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ByteItemGraphicsScene::adjustSize(bool forced) {
|
||||||
|
const auto width = this->getSceneWidth();
|
||||||
|
|
||||||
|
const auto columnCount = static_cast<std::size_t>(
|
||||||
|
std::floor(
|
||||||
|
(width - this->margins.left() - this->margins.right() - ByteAddressContainer::WIDTH + ByteItem::RIGHT_MARGIN)
|
||||||
|
/ (ByteItem::WIDTH + ByteItem::RIGHT_MARGIN)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
const auto rowCount = static_cast<int>(
|
||||||
|
std::ceil(static_cast<double>(this->byteItemsByAddress.size()) / static_cast<double>(columnCount))
|
||||||
|
);
|
||||||
|
|
||||||
|
// Don't bother recalculating the byte item & annotation positions if the number of rows & columns have not changed.
|
||||||
|
if (this->byteItemsByAddress.empty()
|
||||||
|
|| (
|
||||||
|
!forced
|
||||||
|
&& rowCount == this->byteItemsByRowIndex.size()
|
||||||
|
&& columnCount == this->byteItemsByColumnIndex.size()
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
this->setSceneRect(
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
width,
|
||||||
|
std::max(static_cast<int>(this->sceneRect().height()), this->parent->viewport()->height())
|
||||||
|
);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this->byteItemsByAddress.empty()) {
|
||||||
|
this->adjustByteItemPositions();
|
||||||
|
this->adjustAnnotationItemPositions();
|
||||||
|
|
||||||
|
const auto lastByteItemPosition = (--this->byteItemsByAddress.end())->second->pos();
|
||||||
|
this->setSceneRect(
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
width,
|
||||||
|
std::max(
|
||||||
|
static_cast<int>(lastByteItemPosition.y() + ByteItem::HEIGHT + this->margins.bottom()),
|
||||||
|
this->parent->height()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
this->update();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ByteItemGraphicsScene::setEnabled(bool enabled) {
|
void ByteItemGraphicsScene::setEnabled(bool enabled) {
|
||||||
@@ -132,11 +168,178 @@ void ByteItemGraphicsScene::setEnabled(bool enabled) {
|
|||||||
byteItem->setEnabled(this->enabled);
|
byteItem->setEnabled(this->enabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (auto& [startAddress, annotationItem] : this->annotationItemsByStartAddress) {
|
||||||
|
annotationItem->setEnabled(this->enabled);
|
||||||
|
}
|
||||||
|
|
||||||
this->byteAddressContainer->setEnabled(enabled);
|
this->byteAddressContainer->setEnabled(enabled);
|
||||||
|
this->byteAddressContainer->update();
|
||||||
this->update();
|
this->update();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ByteItemGraphicsScene::invalidateChildItemCaches() {
|
||||||
|
for (auto& [address, byteWidget] : this->byteItemsByAddress) {
|
||||||
|
byteWidget->update();
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto& [startAddress, annotationItem] : this->annotationItemsByStartAddress) {
|
||||||
|
annotationItem->update();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ByteItemGraphicsScene::event(QEvent* event) {
|
||||||
|
if (event->type() == QEvent::Type::GraphicsSceneLeave && this->hoveredByteWidget.has_value()) {
|
||||||
|
this->onByteWidgetLeave();
|
||||||
|
}
|
||||||
|
|
||||||
|
return QGraphicsScene::event(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ByteItemGraphicsScene::mouseMoveEvent(QGraphicsSceneMouseEvent* mouseEvent) {
|
||||||
|
auto hoveredItems = this->items(mouseEvent->scenePos());
|
||||||
|
ByteItem* hoveredByteItem = nullptr;
|
||||||
|
AnnotationItem* hoveredAnnotationItem = nullptr;
|
||||||
|
|
||||||
|
if (!hoveredItems.empty()) {
|
||||||
|
hoveredByteItem = dynamic_cast<ByteItem*>(hoveredItems.at(0));
|
||||||
|
hoveredAnnotationItem = dynamic_cast<AnnotationItem*>(hoveredItems.at(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hoveredByteItem != nullptr) {
|
||||||
|
this->onByteWidgetEnter(hoveredByteItem);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this->hoveredByteWidget.has_value()) {
|
||||||
|
this->onByteWidgetLeave();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hoveredAnnotationItem != nullptr) {
|
||||||
|
this->onAnnotationItemEnter(hoveredAnnotationItem);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this->hoveredAnnotationItem.has_value()) {
|
||||||
|
this->onAnnotationItemLeave();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ByteItemGraphicsScene::adjustByteItemPositions() {
|
||||||
|
const auto columnCount = static_cast<std::size_t>(
|
||||||
|
std::floor(
|
||||||
|
(this->getSceneWidth() - this->margins.left() - this->margins.right() - ByteAddressContainer::WIDTH + ByteItem::RIGHT_MARGIN)
|
||||||
|
/ (ByteItem::WIDTH + ByteItem::RIGHT_MARGIN)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
std::map<std::size_t, std::vector<ByteItem*>> byteWidgetsByRowIndex;
|
||||||
|
std::map<std::size_t, std::vector<ByteItem*>> byteWidgetsByColumnIndex;
|
||||||
|
|
||||||
|
auto rowIndicesWithTopAnnotations = std::set<std::size_t>();
|
||||||
|
auto rowIndicesWithBottomAnnotations = std::set<std::size_t>();
|
||||||
|
const auto& memoryAddressRange = this->targetMemoryDescriptor.addressRange;
|
||||||
|
|
||||||
|
for (auto [startAddress, annotationItem] : this->annotationItemsByStartAddress) {
|
||||||
|
const auto firstByteRowIndex = static_cast<std::size_t>(
|
||||||
|
std::ceil(static_cast<double>((startAddress - memoryAddressRange.startAddress) + 1)
|
||||||
|
/ static_cast<double>(columnCount)) - 1
|
||||||
|
);
|
||||||
|
|
||||||
|
const auto lastByteRowIndex = static_cast<std::size_t>(
|
||||||
|
std::ceil(static_cast<double>((annotationItem->endAddress - memoryAddressRange.startAddress) + 1)
|
||||||
|
/ static_cast<double>(columnCount)) - 1
|
||||||
|
);
|
||||||
|
|
||||||
|
// We only display annotations that span a single row.
|
||||||
|
if (firstByteRowIndex == lastByteRowIndex) {
|
||||||
|
annotationItem->show();
|
||||||
|
rowIndicesWithBottomAnnotations.insert(firstByteRowIndex);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
annotationItem->hide();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr auto annotationTopHeight = AnnotationItem::TOP_HEIGHT;
|
||||||
|
constexpr auto annotationBottomHeight = AnnotationItem::BOTTOM_HEIGHT;
|
||||||
|
|
||||||
|
std::size_t lastRowIndex = 0;
|
||||||
|
int rowYPosition = margins.top();
|
||||||
|
auto currentRowAnnotatedTop = false;
|
||||||
|
|
||||||
|
for (auto& [address, byteWidget] : this->byteItemsByAddress) {
|
||||||
|
const auto rowIndex = static_cast<std::size_t>(
|
||||||
|
std::ceil(static_cast<double>(byteWidget->byteIndex + 1) / static_cast<double>(columnCount)) - 1
|
||||||
|
);
|
||||||
|
const auto columnIndex = static_cast<std::size_t>(
|
||||||
|
static_cast<double>(byteWidget->byteIndex)
|
||||||
|
- (std::floor(byteWidget->byteIndex / columnCount) * static_cast<double>(columnCount))
|
||||||
|
);
|
||||||
|
|
||||||
|
if (rowIndex != lastRowIndex) {
|
||||||
|
rowYPosition += ByteItem::HEIGHT + ByteItem::BOTTOM_MARGIN;
|
||||||
|
currentRowAnnotatedTop = false;
|
||||||
|
|
||||||
|
if (rowIndicesWithBottomAnnotations.contains(lastRowIndex)) {
|
||||||
|
rowYPosition += annotationBottomHeight;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!currentRowAnnotatedTop && rowIndicesWithTopAnnotations.contains(rowIndex)) {
|
||||||
|
rowYPosition += annotationTopHeight;
|
||||||
|
currentRowAnnotatedTop = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
byteWidget->setPos(
|
||||||
|
static_cast<int>(
|
||||||
|
columnIndex * (ByteItem::WIDTH + ByteItem::RIGHT_MARGIN) + this->margins.left() + ByteAddressContainer::WIDTH),
|
||||||
|
rowYPosition
|
||||||
|
);
|
||||||
|
|
||||||
|
byteWidget->currentRowIndex = rowIndex;
|
||||||
|
byteWidget->currentColumnIndex = columnIndex;
|
||||||
|
|
||||||
|
byteWidgetsByRowIndex[byteWidget->currentRowIndex].emplace_back(byteWidget);
|
||||||
|
byteWidgetsByColumnIndex[byteWidget->currentColumnIndex].emplace_back(byteWidget);
|
||||||
|
|
||||||
|
lastRowIndex = rowIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->byteItemsByRowIndex = std::move(byteWidgetsByRowIndex);
|
||||||
|
this->byteItemsByColumnIndex = std::move(byteWidgetsByColumnIndex);
|
||||||
|
|
||||||
|
this->byteAddressContainer->adjustAddressLabels(this->byteItemsByRowIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ByteItemGraphicsScene::adjustAnnotationItemPositions() {
|
||||||
|
if (this->byteItemsByAddress.empty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto& [startAddress, annotationItem] : this->annotationItemsByStartAddress) {
|
||||||
|
if (!this->byteItemsByAddress.contains(startAddress)) {
|
||||||
|
annotationItem->hide();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto firstByteItemPosition = this->byteItemsByAddress.at(startAddress)->pos();
|
||||||
|
|
||||||
|
if (annotationItem->position == AnnotationItemPosition::TOP) {
|
||||||
|
annotationItem->setPos(
|
||||||
|
firstByteItemPosition.x(),
|
||||||
|
firstByteItemPosition.y() - AnnotationItem::TOP_HEIGHT
|
||||||
|
);
|
||||||
|
|
||||||
|
} else if (annotationItem->position == AnnotationItemPosition::BOTTOM) {
|
||||||
|
annotationItem->setPos(
|
||||||
|
firstByteItemPosition.x(),
|
||||||
|
firstByteItemPosition.y() + ByteItem::HEIGHT
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void ByteItemGraphicsScene::onTargetStateChanged(Targets::TargetState newState) {
|
void ByteItemGraphicsScene::onTargetStateChanged(Targets::TargetState newState) {
|
||||||
using Targets::TargetState;
|
using Targets::TargetState;
|
||||||
this->targetState = newState;
|
this->targetState = newState;
|
||||||
@@ -147,10 +350,9 @@ void ByteItemGraphicsScene::onByteWidgetEnter(ByteItem* widget) {
|
|||||||
if (this->hoveredByteWidget.value() == widget) {
|
if (this->hoveredByteWidget.value() == widget) {
|
||||||
// This byte item is already marked as hovered
|
// This byte item is already marked as hovered
|
||||||
return;
|
return;
|
||||||
|
|
||||||
} else {
|
|
||||||
this->onByteWidgetLeave();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this->onByteWidgetLeave();
|
||||||
}
|
}
|
||||||
|
|
||||||
this->hoveredByteWidget = widget;
|
this->hoveredByteWidget = widget;
|
||||||
@@ -174,7 +376,7 @@ void ByteItemGraphicsScene::onByteWidgetEnter(ByteItem* widget) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ByteItemGraphicsScene::onByteWidgetLeave() {
|
void ByteItemGraphicsScene::onByteWidgetLeave() {
|
||||||
const auto byteItem = this->hoveredByteWidget.value();
|
auto* byteItem = this->hoveredByteWidget.value();
|
||||||
this->hoveredByteWidget = std::nullopt;
|
this->hoveredByteWidget = std::nullopt;
|
||||||
|
|
||||||
this->hoveredAddressLabel->setText("Relative Address (Absolute Address):");
|
this->hoveredAddressLabel->setText("Relative Address (Absolute Address):");
|
||||||
@@ -193,24 +395,35 @@ void ByteItemGraphicsScene::onByteWidgetLeave() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ByteItemGraphicsScene::event(QEvent* event) {
|
void ByteItemGraphicsScene::onAnnotationItemEnter(AnnotationItem* annotationItem) {
|
||||||
if (event->type() == QEvent::Type::GraphicsSceneLeave && this->hoveredByteWidget.has_value()) {
|
if (this->hoveredAnnotationItem.has_value()) {
|
||||||
this->onByteWidgetLeave();
|
if (this->hoveredAnnotationItem.value() == annotationItem) {
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
return QGraphicsScene::event(event);
|
this->onAnnotationItemLeave();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ByteItemGraphicsScene::mouseMoveEvent(QGraphicsSceneMouseEvent* mouseEvent) {
|
this->hoveredAnnotationItem = annotationItem;
|
||||||
auto hoveredItems = this->items(mouseEvent->scenePos());
|
|
||||||
if (!hoveredItems.empty()) {
|
|
||||||
auto hoveredByteWidget = dynamic_cast<ByteItem*>(hoveredItems.at(0));
|
|
||||||
|
|
||||||
if (hoveredByteWidget != nullptr) {
|
for (
|
||||||
this->onByteWidgetEnter(hoveredByteWidget);
|
auto byteItemAddress = annotationItem->startAddress;
|
||||||
|
byteItemAddress <= annotationItem->endAddress;
|
||||||
|
byteItemAddress++
|
||||||
|
) {
|
||||||
|
this->byteItemsByAddress.at(byteItemAddress)->update();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (this->hoveredByteWidget.has_value()) {
|
void ByteItemGraphicsScene::onAnnotationItemLeave() {
|
||||||
this->onByteWidgetLeave();
|
auto* annotationItem = this->hoveredAnnotationItem.value();
|
||||||
|
this->hoveredAnnotationItem = std::nullopt;
|
||||||
|
|
||||||
|
for (
|
||||||
|
auto byteItemAddress = annotationItem->startAddress;
|
||||||
|
byteItemAddress <= annotationItem->endAddress;
|
||||||
|
byteItemAddress++
|
||||||
|
) {
|
||||||
|
this->byteItemsByAddress.at(byteItemAddress)->update();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,15 +1,19 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <QGraphicsScene>
|
#include <QGraphicsScene>
|
||||||
|
#include <QGraphicsView>
|
||||||
|
#include <QScrollBar>
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
#include <QLabel>
|
#include <QLabel>
|
||||||
#include <QToolButton>
|
#include <QToolButton>
|
||||||
#include <QVBoxLayout>
|
#include <QVBoxLayout>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <algorithm>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <QSize>
|
#include <QSize>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#include <QGraphicsSceneMouseEvent>
|
#include <QGraphicsSceneMouseEvent>
|
||||||
|
#include <QGraphicsSceneWheelEvent>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
|
|
||||||
#include "src/Targets/TargetMemory.hpp"
|
#include "src/Targets/TargetMemory.hpp"
|
||||||
@@ -19,8 +23,13 @@
|
|||||||
|
|
||||||
#include "ByteItem.hpp"
|
#include "ByteItem.hpp"
|
||||||
#include "ByteAddressContainer.hpp"
|
#include "ByteAddressContainer.hpp"
|
||||||
|
#include "AnnotationItem.hpp"
|
||||||
#include "HexViewerWidgetSettings.hpp"
|
#include "HexViewerWidgetSettings.hpp"
|
||||||
|
|
||||||
|
#include "src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/MemoryRegion.hpp"
|
||||||
|
#include "src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/FocusedMemoryRegion.hpp"
|
||||||
|
#include "src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/ExcludedMemoryRegion.hpp"
|
||||||
|
|
||||||
namespace Bloom::Widgets
|
namespace Bloom::Widgets
|
||||||
{
|
{
|
||||||
class ByteItemGraphicsScene: public QGraphicsScene
|
class ByteItemGraphicsScene: public QGraphicsScene
|
||||||
@@ -29,24 +38,23 @@ namespace Bloom::Widgets
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
std::optional<ByteItem*> hoveredByteWidget;
|
std::optional<ByteItem*> hoveredByteWidget;
|
||||||
|
std::optional<AnnotationItem*> hoveredAnnotationItem;
|
||||||
std::map<std::uint32_t, ByteItem*> byteItemsByAddress;
|
|
||||||
std::map<std::size_t, std::vector<ByteItem*>> byteItemsByRowIndex;
|
|
||||||
std::map<std::size_t, std::vector<ByteItem*>> byteItemsByColumnIndex;
|
|
||||||
|
|
||||||
ByteItemGraphicsScene(
|
ByteItemGraphicsScene(
|
||||||
const Targets::TargetMemoryDescriptor& targetMemoryDescriptor,
|
const Targets::TargetMemoryDescriptor& targetMemoryDescriptor,
|
||||||
|
std::vector<FocusedMemoryRegion>& focusedMemoryRegions,
|
||||||
|
std::vector<ExcludedMemoryRegion>& excludedMemoryRegions,
|
||||||
InsightWorker& insightWorker,
|
InsightWorker& insightWorker,
|
||||||
const HexViewerWidgetSettings& settings,
|
const HexViewerWidgetSettings& settings,
|
||||||
QLabel* hoveredAddressLabel,
|
QLabel* hoveredAddressLabel,
|
||||||
QWidget* parent
|
QGraphicsView* parent
|
||||||
);
|
);
|
||||||
|
|
||||||
void updateValues(const Targets::TargetMemoryBuffer& buffer);
|
void updateValues(const Targets::TargetMemoryBuffer& buffer);
|
||||||
|
void refreshRegions();
|
||||||
void adjustByteWidgets();
|
void adjustSize(bool forced = false);
|
||||||
|
|
||||||
void setEnabled(bool enabled);
|
void setEnabled(bool enabled);
|
||||||
|
void invalidateChildItemCaches();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void byteWidgetsAdjusted();
|
void byteWidgetsAdjusted();
|
||||||
@@ -57,21 +65,43 @@ namespace Bloom::Widgets
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
const Targets::TargetMemoryDescriptor& targetMemoryDescriptor;
|
const Targets::TargetMemoryDescriptor& targetMemoryDescriptor;
|
||||||
|
std::vector<FocusedMemoryRegion>& focusedMemoryRegions;
|
||||||
|
std::vector<ExcludedMemoryRegion>& excludedMemoryRegions;
|
||||||
|
|
||||||
|
std::map<std::uint32_t, ByteItem*> byteItemsByAddress;
|
||||||
|
std::map<std::uint32_t, AnnotationItem*> annotationItemsByStartAddress;
|
||||||
|
std::map<std::size_t, std::vector<ByteItem*>> byteItemsByRowIndex;
|
||||||
|
std::map<std::size_t, std::vector<ByteItem*>> byteItemsByColumnIndex;
|
||||||
|
|
||||||
Targets::TargetState targetState = Targets::TargetState::UNKNOWN;
|
Targets::TargetState targetState = Targets::TargetState::UNKNOWN;
|
||||||
InsightWorker& insightWorker;
|
InsightWorker& insightWorker;
|
||||||
|
|
||||||
|
const QMargins margins = QMargins(10, 10, 10, 10);
|
||||||
const HexViewerWidgetSettings& settings;
|
const HexViewerWidgetSettings& settings;
|
||||||
|
|
||||||
QWidget* parent = nullptr;
|
QGraphicsView* parent = nullptr;
|
||||||
QLabel* hoveredAddressLabel = nullptr;
|
QLabel* hoveredAddressLabel = nullptr;
|
||||||
|
|
||||||
ByteAddressContainer* byteAddressContainer = nullptr;
|
ByteAddressContainer* byteAddressContainer = nullptr;
|
||||||
|
|
||||||
bool enabled = true;
|
bool enabled = true;
|
||||||
|
|
||||||
private slots:
|
int getSceneWidth() {
|
||||||
|
/*
|
||||||
|
* Minus 2 for the QSS margin on the vertical scrollbar (which isn't accounted for during viewport
|
||||||
|
* size calculation).
|
||||||
|
*
|
||||||
|
* See https://bugreports.qt.io/browse/QTBUG-99189 for more on this.
|
||||||
|
*/
|
||||||
|
return std::max(this->parent->viewport()->width(), 400) - 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
void adjustByteItemPositions();
|
||||||
|
void adjustAnnotationItemPositions();
|
||||||
void onTargetStateChanged(Targets::TargetState newState);
|
void onTargetStateChanged(Targets::TargetState newState);
|
||||||
void onByteWidgetEnter(Bloom::Widgets::ByteItem* widget);
|
void onByteWidgetEnter(Bloom::Widgets::ByteItem* widget);
|
||||||
void onByteWidgetLeave();
|
void onByteWidgetLeave();
|
||||||
|
void onAnnotationItemEnter(Bloom::Widgets::AnnotationItem* annotationItem);
|
||||||
|
void onAnnotationItemLeave();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,16 +1,9 @@
|
|||||||
#include "HexViewerWidget.hpp"
|
#include "HexViewerWidget.hpp"
|
||||||
|
|
||||||
#include <QVBoxLayout>
|
|
||||||
#include <QScrollBar>
|
|
||||||
#include <QScrollArea>
|
|
||||||
#include <QPainter>
|
|
||||||
#include <cmath>
|
|
||||||
|
|
||||||
#include "src/Insight/UserInterfaces/InsightWindow/UiLoader.hpp"
|
#include "src/Insight/UserInterfaces/InsightWindow/UiLoader.hpp"
|
||||||
|
|
||||||
#include "src/Helpers/Paths.hpp"
|
#include "src/Helpers/Paths.hpp"
|
||||||
#include "src/Exceptions/Exception.hpp"
|
#include "src/Exceptions/Exception.hpp"
|
||||||
#include "src/Logger/Logger.hpp"
|
|
||||||
|
|
||||||
using namespace Bloom::Widgets;
|
using namespace Bloom::Widgets;
|
||||||
using namespace Bloom::Exceptions;
|
using namespace Bloom::Exceptions;
|
||||||
@@ -19,9 +12,17 @@ using Bloom::Targets::TargetMemoryDescriptor;
|
|||||||
|
|
||||||
HexViewerWidget::HexViewerWidget(
|
HexViewerWidget::HexViewerWidget(
|
||||||
const TargetMemoryDescriptor& targetMemoryDescriptor,
|
const TargetMemoryDescriptor& targetMemoryDescriptor,
|
||||||
|
std::vector<FocusedMemoryRegion>& focusedMemoryRegions,
|
||||||
|
std::vector<ExcludedMemoryRegion>& excludedMemoryRegions,
|
||||||
InsightWorker& insightWorker,
|
InsightWorker& insightWorker,
|
||||||
QWidget* parent
|
QWidget* parent
|
||||||
): QWidget(parent), targetMemoryDescriptor(targetMemoryDescriptor), insightWorker(insightWorker) {
|
):
|
||||||
|
QWidget(parent),
|
||||||
|
targetMemoryDescriptor(targetMemoryDescriptor),
|
||||||
|
focusedMemoryRegions(focusedMemoryRegions),
|
||||||
|
excludedMemoryRegions(excludedMemoryRegions),
|
||||||
|
insightWorker(insightWorker)
|
||||||
|
{
|
||||||
this->setObjectName("hex-viewer-widget");
|
this->setObjectName("hex-viewer-widget");
|
||||||
this->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);
|
this->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);
|
||||||
|
|
||||||
@@ -63,8 +64,10 @@ HexViewerWidget::HexViewerWidget(
|
|||||||
|
|
||||||
this->byteItemGraphicsViewContainer = this->container->findChild<QWidget*>("graphics-view-container");
|
this->byteItemGraphicsViewContainer = this->container->findChild<QWidget*>("graphics-view-container");
|
||||||
this->byteItemGraphicsView = new ByteItemContainerGraphicsView(
|
this->byteItemGraphicsView = new ByteItemContainerGraphicsView(
|
||||||
targetMemoryDescriptor,
|
this->targetMemoryDescriptor,
|
||||||
insightWorker,
|
this->focusedMemoryRegions,
|
||||||
|
this->excludedMemoryRegions,
|
||||||
|
this->insightWorker,
|
||||||
this->settings,
|
this->settings,
|
||||||
this->hoveredAddressLabel,
|
this->hoveredAddressLabel,
|
||||||
this->byteItemGraphicsViewContainer
|
this->byteItemGraphicsViewContainer
|
||||||
@@ -116,9 +119,13 @@ void HexViewerWidget::updateValues(const Targets::TargetMemoryBuffer& buffer) {
|
|||||||
this->byteItemGraphicsScene->updateValues(buffer);
|
this->byteItemGraphicsScene->updateValues(buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void HexViewerWidget::refreshRegions() {
|
||||||
|
this->byteItemGraphicsScene->refreshRegions();
|
||||||
|
}
|
||||||
|
|
||||||
void HexViewerWidget::setStackPointer(std::uint32_t stackPointer) {
|
void HexViewerWidget::setStackPointer(std::uint32_t stackPointer) {
|
||||||
this->settings.stackPointerAddress = stackPointer;
|
this->settings.stackPointerAddress = stackPointer;
|
||||||
this->byteItemGraphicsScene->update();
|
this->byteItemGraphicsScene->invalidateChildItemCaches();
|
||||||
}
|
}
|
||||||
|
|
||||||
void HexViewerWidget::resizeEvent(QResizeEvent* event) {
|
void HexViewerWidget::resizeEvent(QResizeEvent* event) {
|
||||||
@@ -143,19 +150,19 @@ void HexViewerWidget::setStackMemoryHighlightingEnabled(bool enabled) {
|
|||||||
this->highlightStackMemoryButton->setChecked(enabled);
|
this->highlightStackMemoryButton->setChecked(enabled);
|
||||||
this->settings.highlightStackMemory = enabled;
|
this->settings.highlightStackMemory = enabled;
|
||||||
|
|
||||||
this->byteItemGraphicsScene->update();
|
this->byteItemGraphicsScene->invalidateChildItemCaches();
|
||||||
}
|
}
|
||||||
|
|
||||||
void HexViewerWidget::setHoveredRowAndColumnHighlightingEnabled(bool enabled) {
|
void HexViewerWidget::setHoveredRowAndColumnHighlightingEnabled(bool enabled) {
|
||||||
this->highlightHoveredRowAndColumnButton->setChecked(enabled);
|
this->highlightHoveredRowAndColumnButton->setChecked(enabled);
|
||||||
this->settings.highlightHoveredRowAndCol = enabled;
|
this->settings.highlightHoveredRowAndCol = enabled;
|
||||||
|
|
||||||
this->byteItemGraphicsScene->update();
|
this->byteItemGraphicsScene->invalidateChildItemCaches();
|
||||||
}
|
}
|
||||||
|
|
||||||
void HexViewerWidget::setFocusedMemoryHighlightingEnabled(bool enabled) {
|
void HexViewerWidget::setFocusedMemoryHighlightingEnabled(bool enabled) {
|
||||||
this->highlightFocusedMemoryButton->setChecked(enabled);
|
this->highlightFocusedMemoryButton->setChecked(enabled);
|
||||||
this->settings.highlightFocusedMemory = enabled;
|
this->settings.highlightFocusedMemory = enabled;
|
||||||
|
|
||||||
this->byteItemGraphicsScene->update();
|
this->byteItemGraphicsScene->invalidateChildItemCaches();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,25 +2,23 @@
|
|||||||
|
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
#include <QLabel>
|
#include <QLabel>
|
||||||
#include <QGraphicsView>
|
#include <QResizeEvent>
|
||||||
#include <QVBoxLayout>
|
|
||||||
#include <set>
|
|
||||||
#include <map>
|
|
||||||
#include <QSize>
|
|
||||||
#include <QString>
|
|
||||||
#include <QEvent>
|
|
||||||
#include <QShowEvent>
|
#include <QShowEvent>
|
||||||
#include <optional>
|
#include <vector>
|
||||||
|
|
||||||
#include "src/Targets/TargetMemory.hpp"
|
#include "src/Targets/TargetMemory.hpp"
|
||||||
#include "src/Targets/TargetState.hpp"
|
#include "src/Targets/TargetState.hpp"
|
||||||
|
|
||||||
#include "src/Insight/InsightWorker/InsightWorker.hpp"
|
#include "src/Insight/InsightWorker/InsightWorker.hpp"
|
||||||
|
|
||||||
|
#include "src/Insight/UserInterfaces/InsightWindow/Widgets/SvgToolButton.hpp"
|
||||||
|
|
||||||
#include "HexViewerWidgetSettings.hpp"
|
#include "HexViewerWidgetSettings.hpp"
|
||||||
#include "ByteItemContainerGraphicsView.hpp"
|
#include "ByteItemContainerGraphicsView.hpp"
|
||||||
|
|
||||||
#include "src/Insight/UserInterfaces/InsightWindow/Widgets/SvgToolButton.hpp"
|
#include "src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/MemoryRegion.hpp"
|
||||||
|
#include "src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/FocusedMemoryRegion.hpp"
|
||||||
|
#include "src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/ExcludedMemoryRegion.hpp"
|
||||||
|
|
||||||
namespace Bloom::Widgets
|
namespace Bloom::Widgets
|
||||||
{
|
{
|
||||||
@@ -33,12 +31,14 @@ namespace Bloom::Widgets
|
|||||||
|
|
||||||
HexViewerWidget(
|
HexViewerWidget(
|
||||||
const Targets::TargetMemoryDescriptor& targetMemoryDescriptor,
|
const Targets::TargetMemoryDescriptor& targetMemoryDescriptor,
|
||||||
|
std::vector<FocusedMemoryRegion>& focusedMemoryRegions,
|
||||||
|
std::vector<ExcludedMemoryRegion>& excludedMemoryRegions,
|
||||||
InsightWorker& insightWorker,
|
InsightWorker& insightWorker,
|
||||||
QWidget* parent
|
QWidget* parent
|
||||||
);
|
);
|
||||||
|
|
||||||
void updateValues(const Targets::TargetMemoryBuffer& buffer);
|
void updateValues(const Targets::TargetMemoryBuffer& buffer);
|
||||||
|
void refreshRegions();
|
||||||
void setStackPointer(std::uint32_t stackPointer);
|
void setStackPointer(std::uint32_t stackPointer);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@@ -47,6 +47,9 @@ namespace Bloom::Widgets
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
const Targets::TargetMemoryDescriptor& targetMemoryDescriptor;
|
const Targets::TargetMemoryDescriptor& targetMemoryDescriptor;
|
||||||
|
std::vector<FocusedMemoryRegion>& focusedMemoryRegions;
|
||||||
|
std::vector<ExcludedMemoryRegion>& excludedMemoryRegions;
|
||||||
|
|
||||||
InsightWorker& insightWorker;
|
InsightWorker& insightWorker;
|
||||||
|
|
||||||
HexViewerWidgetSettings settings = HexViewerWidgetSettings();
|
HexViewerWidgetSettings settings = HexViewerWidgetSettings();
|
||||||
@@ -66,7 +69,6 @@ namespace Bloom::Widgets
|
|||||||
|
|
||||||
Targets::TargetState targetState = Targets::TargetState::UNKNOWN;
|
Targets::TargetState targetState = Targets::TargetState::UNKNOWN;
|
||||||
|
|
||||||
private slots:
|
|
||||||
void onTargetStateChanged(Targets::TargetState newState);
|
void onTargetStateChanged(Targets::TargetState newState);
|
||||||
void setStackMemoryHighlightingEnabled(bool enabled);
|
void setStackMemoryHighlightingEnabled(bool enabled);
|
||||||
void setHoveredRowAndColumnHighlightingEnabled(bool enabled);
|
void setHoveredRowAndColumnHighlightingEnabled(bool enabled);
|
||||||
|
|||||||
@@ -382,6 +382,7 @@ void MemoryRegionManagerWindow::applyChanges() {
|
|||||||
this->focusedMemoryRegions = std::move(processedFocusedMemoryRegions);
|
this->focusedMemoryRegions = std::move(processedFocusedMemoryRegions);
|
||||||
this->excludedMemoryRegions = std::move(processedExcludedMemoryRegions);
|
this->excludedMemoryRegions = std::move(processedExcludedMemoryRegions);
|
||||||
this->close();
|
this->close();
|
||||||
|
emit this->changesApplied();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MemoryRegionManagerWindow::openHelpPage() {
|
void MemoryRegionManagerWindow::openHelpPage() {
|
||||||
|
|||||||
@@ -37,6 +37,9 @@ namespace Bloom::Widgets
|
|||||||
|
|
||||||
void refreshRegions();
|
void refreshRegions();
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void changesApplied();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void showEvent(QShowEvent* event) override;
|
void showEvent(QShowEvent* event) override;
|
||||||
|
|
||||||
|
|||||||
@@ -49,7 +49,13 @@ TargetMemoryInspectionPane::TargetMemoryInspectionPane(
|
|||||||
|
|
||||||
auto* subContainerLayout = this->container->findChild<QHBoxLayout*>("sub-container-layout");
|
auto* subContainerLayout = this->container->findChild<QHBoxLayout*>("sub-container-layout");
|
||||||
this->manageMemoryRegionsButton = this->container->findChild<SvgToolButton*>("manage-memory-regions-btn");
|
this->manageMemoryRegionsButton = this->container->findChild<SvgToolButton*>("manage-memory-regions-btn");
|
||||||
this->hexViewerWidget = new HexViewerWidget(this->targetMemoryDescriptor, this->insightWorker, this);
|
this->hexViewerWidget = new HexViewerWidget(
|
||||||
|
this->targetMemoryDescriptor,
|
||||||
|
this->focusedMemoryRegions,
|
||||||
|
this->excludedMemoryRegions,
|
||||||
|
this->insightWorker,
|
||||||
|
this
|
||||||
|
);
|
||||||
this->hexViewerWidget->setDisabled(true);
|
this->hexViewerWidget->setDisabled(true);
|
||||||
|
|
||||||
subContainerLayout->addWidget(this->hexViewerWidget);
|
subContainerLayout->addWidget(this->hexViewerWidget);
|
||||||
@@ -187,6 +193,13 @@ void TargetMemoryInspectionPane::openMemoryRegionManagerWindow() {
|
|||||||
this->excludedMemoryRegions,
|
this->excludedMemoryRegions,
|
||||||
this
|
this
|
||||||
);
|
);
|
||||||
|
|
||||||
|
QObject::connect(
|
||||||
|
this->memoryRegionManagerWindow,
|
||||||
|
&MemoryRegionManagerWindow::changesApplied,
|
||||||
|
this,
|
||||||
|
&TargetMemoryInspectionPane::onMemoryRegionsChange
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!this->memoryRegionManagerWindow->isVisible()) {
|
if (!this->memoryRegionManagerWindow->isVisible()) {
|
||||||
@@ -197,3 +210,7 @@ void TargetMemoryInspectionPane::openMemoryRegionManagerWindow() {
|
|||||||
this->memoryRegionManagerWindow->activateWindow();
|
this->memoryRegionManagerWindow->activateWindow();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TargetMemoryInspectionPane::onMemoryRegionsChange() {
|
||||||
|
this->hexViewerWidget->refreshRegions();
|
||||||
|
}
|
||||||
|
|||||||
@@ -64,5 +64,6 @@ namespace Bloom::Widgets
|
|||||||
void onTargetStateChanged(Targets::TargetState newState);
|
void onTargetStateChanged(Targets::TargetState newState);
|
||||||
void onMemoryRead(const Targets::TargetMemoryBuffer& buffer);
|
void onMemoryRead(const Targets::TargetMemoryBuffer& buffer);
|
||||||
void openMemoryRegionManagerWindow();
|
void openMemoryRegionManagerWindow();
|
||||||
|
void onMemoryRegionsChange();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user