Prepared HexViewerWidget for snapshot diff window

This commit is contained in:
Nav
2023-05-01 14:49:51 +01:00
parent 86a09b1a4a
commit 5e4d917b57
6 changed files with 103 additions and 54 deletions

View File

@@ -58,12 +58,10 @@ namespace Bloom::Widgets
auto uiLoader = UiLoader(this);
this->container = uiLoader.load(&widgetUiFile, this);
this->container->setStyleSheet(stylesheetFile.readAll());
this->setStyleSheet(stylesheetFile.readAll());
this->container->setFixedSize(this->size());
this->container->setContentsMargins(0, 0, 0, 0);
auto* containerLayout = this->container->findChild<QVBoxLayout*>("hex-viewer-layout");
this->toolBar = this->container->findChild<QWidget*>("tool-bar");
this->bottomBar = this->container->findChild<QWidget*>("bottom-bar");
@@ -92,18 +90,6 @@ namespace Bloom::Widgets
this->loadingHexViewerLabel = this->container->findChild<Label*>("loading-hex-viewer-label");
this->byteItemGraphicsView = new ItemGraphicsView(
this->targetMemoryDescriptor,
this->data,
this->focusedMemoryRegions,
this->excludedMemoryRegions,
this->settings,
this->container
);
this->byteItemGraphicsView->hide();
containerLayout->insertWidget(2, this->byteItemGraphicsView);
this->setHoveredRowAndColumnHighlightingEnabled(this->settings.highlightHoveredRowAndCol);
this->setFocusedMemoryHighlightingEnabled(this->settings.highlightFocusedMemory);
this->setAnnotationsEnabled(this->settings.displayAnnotations);
@@ -188,6 +174,20 @@ namespace Bloom::Widgets
}
void HexViewerWidget::init() {
this->byteItemGraphicsView = new ItemGraphicsView(
this->targetMemoryDescriptor,
this->data,
this->focusedMemoryRegions,
this->excludedMemoryRegions,
this->settings,
this->container
);
this->byteItemGraphicsView->hide();
auto* containerLayout = this->container->findChild<QVBoxLayout*>("hex-viewer-layout");
containerLayout->insertWidget(2, this->byteItemGraphicsView);
QObject::connect(
this->byteItemGraphicsView,
&ItemGraphicsView::sceneReady,
@@ -265,6 +265,8 @@ namespace Bloom::Widgets
if (this->byteItemGraphicsScene != nullptr) {
this->byteItemGraphicsScene->rebuildItemHierarchy();
}
emit this->settingsChanged(this->settings);
}
void HexViewerWidget::setHoveredRowAndColumnHighlightingEnabled(bool enabled) {
@@ -274,6 +276,8 @@ namespace Bloom::Widgets
if (this->byteItemGraphicsScene != nullptr) {
this->byteItemGraphicsScene->update();
}
emit this->settingsChanged(this->settings);
}
void HexViewerWidget::setFocusedMemoryHighlightingEnabled(bool enabled) {
@@ -283,6 +287,8 @@ namespace Bloom::Widgets
if (this->byteItemGraphicsScene != nullptr) {
this->byteItemGraphicsScene->update();
}
emit this->settingsChanged(this->settings);
}
void HexViewerWidget::setAnnotationsEnabled(bool enabled) {
@@ -292,6 +298,8 @@ namespace Bloom::Widgets
if (this->byteItemGraphicsScene != nullptr) {
this->byteItemGraphicsScene->adjustSize();
}
emit this->settingsChanged(this->settings);
}
void HexViewerWidget::setDisplayAsciiEnabled(bool enabled) {
@@ -301,6 +309,8 @@ namespace Bloom::Widgets
if (this->byteItemGraphicsScene != nullptr) {
this->byteItemGraphicsScene->update();
}
emit this->settingsChanged(this->settings);
}
void HexViewerWidget::onGoToAddressInputChanged() {
@@ -344,7 +354,11 @@ namespace Bloom::Widgets
);
}
void HexViewerWidget::onByteSelectionChanged(Targets::TargetMemorySize selectionCount) {
void HexViewerWidget::onByteSelectionChanged(
const std::unordered_map<Targets::TargetMemoryAddress, ByteItem*>& selectedByteItemsByAddress
) {
const auto selectionCount = selectedByteItemsByAddress.size();
if (selectionCount == 0) {
this->selectionCountLabel->hide();
return;

View File

@@ -37,7 +37,7 @@ namespace Bloom::Widgets
QWidget* parent
);
void init();
virtual void init();
void updateValues();
void refreshRegions();
void setStackPointer(Targets::TargetStackPointer stackPointer);
@@ -45,12 +45,9 @@ namespace Bloom::Widgets
signals:
void ready();
void settingsChanged(const HexViewerWidgetSettings& settings);
protected:
void resizeEvent(QResizeEvent* event) override;
void showEvent(QShowEvent* event) override;
private:
const Targets::TargetMemoryDescriptor& targetMemoryDescriptor;
const std::optional<Targets::TargetMemoryBuffer>& data;
@@ -79,6 +76,8 @@ namespace Bloom::Widgets
Targets::TargetState targetState = Targets::TargetState::UNKNOWN;
void resizeEvent(QResizeEvent* event) override;
void showEvent(QShowEvent* event) override;
void onTargetStateChanged(Targets::TargetState newState);
void setStackMemoryGroupingEnabled(bool enabled);
void setHoveredRowAndColumnHighlightingEnabled(bool enabled);
@@ -87,6 +86,8 @@ namespace Bloom::Widgets
void setDisplayAsciiEnabled(bool enabled);
void onGoToAddressInputChanged();
void onHoveredAddress(const std::optional<Targets::TargetMemoryAddress>& address);
void onByteSelectionChanged(Targets::TargetMemorySize selectionCount);
void onByteSelectionChanged(
const std::unordered_map<Targets::TargetMemoryAddress, ByteItem*>& selectedByteItemsByAddress
);
};
}

View File

@@ -214,9 +214,12 @@ namespace Bloom::Widgets
}
void ItemGraphicsScene::selectByteItems(const std::set<std::uint32_t>& addresses) {
this->selectedByteItemsByAddress.clear();
for (auto& [address, byteItem] : this->topLevelGroup->byteItemsByAddress) {
if (addresses.contains(address)) {
byteItem.selected = true;
this->selectedByteItemsByAddress.insert(std::pair(byteItem.startAddress, &byteItem));
} else if (byteItem.selected) {
byteItem.selected = false;
@@ -224,6 +227,7 @@ namespace Bloom::Widgets
}
this->update();
emit this->selectionChanged(this->selectedByteItemsByAddress);
}
void ItemGraphicsScene::rebuildItemHierarchy() {
@@ -311,8 +315,7 @@ namespace Bloom::Widgets
}
void ItemGraphicsScene::allocateGraphicsItems() {
const auto* view = this->views().first();
const auto verticalScrollBarValue = view->verticalScrollBar()->value();
const auto verticalScrollBarValue = this->getScrollbarValue();
constexpr auto bufferPointSize = 2;
const auto gridPointIndex = static_cast<decltype(this->gridPoints)::size_type>(std::max(
@@ -472,10 +475,12 @@ namespace Bloom::Widgets
this->toggleByteItemSelection(byteItem);
}
emit this->selectionChanged(this->selectedByteItemsByAddress);
return;
}
this->toggleByteItemSelection(*byteItem);
emit this->selectionChanged(this->selectedByteItemsByAddress);
break;
}
}
@@ -529,7 +534,7 @@ namespace Bloom::Widgets
this->selectByteItem(*byteItem);
}
}
emit this->selectionChanged(static_cast<Targets::TargetMemorySize>(this->selectedByteItemsByAddress.size()));
emit this->selectionChanged(this->selectedByteItemsByAddress);
}
for (const auto& item : hoveredItems) {
@@ -577,6 +582,7 @@ namespace Bloom::Widgets
void ItemGraphicsScene::contextMenuEvent(QGraphicsSceneContextMenuEvent* event) {
if (event->scenePos().x() <= ByteAddressContainer::WIDTH) {
auto* menu = new QMenu(this->parent);
menu->setLayoutDirection(Qt::LayoutDirection::LeftToRight);
menu->setObjectName("byte-item-address-container-context-menu");
auto* addressTypeMenu = new QMenu("Address Type", menu);
@@ -591,6 +597,7 @@ namespace Bloom::Widgets
const auto itemsSelected = !this->selectedByteItemsByAddress.empty();
auto* menu = new QMenu(this->parent);
menu->setLayoutDirection(Qt::LayoutDirection::LeftToRight);
menu->addAction(this->selectAllByteItemsAction);
menu->addAction(this->deselectByteItemsAction);
menu->addSeparator();
@@ -672,6 +679,10 @@ namespace Bloom::Widgets
}
}
int ItemGraphicsScene::getScrollbarValue() {
return this->views().first()->verticalScrollBar()->value();
}
void ItemGraphicsScene::onTargetStateChanged(Targets::TargetState newState) {
this->targetState = newState;
}
@@ -693,7 +704,7 @@ namespace Bloom::Widgets
this->hoverRectX->setPos(0, byteItemScenePos.y());
this->hoverRectY->setPos(
byteItemScenePos.x(),
std::max(this->views().first()->verticalScrollBar()->value() - ByteItem::HEIGHT, 0)
std::max(this->getScrollbarValue() - ByteItem::HEIGHT, 0)
);
this->hoverRectX->setVisible(true);
@@ -747,12 +758,10 @@ namespace Bloom::Widgets
void ItemGraphicsScene::toggleByteItemSelection(ByteItem& byteItem) {
if (byteItem.selected) {
this->deselectByteItem(byteItem);
emit this->selectionChanged(static_cast<Targets::TargetMemorySize>(this->selectedByteItemsByAddress.size()));
return;
}
this->selectByteItem(byteItem);
emit this->selectionChanged(static_cast<Targets::TargetMemorySize>(this->selectedByteItemsByAddress.size()));
}
void ItemGraphicsScene::clearByteItemSelection() {
@@ -762,7 +771,7 @@ namespace Bloom::Widgets
this->selectedByteItemsByAddress.clear();
this->update();
emit this->selectionChanged(0);
emit this->selectionChanged(this->selectedByteItemsByAddress);
}
void ItemGraphicsScene::selectAllByteItems() {
@@ -772,7 +781,7 @@ namespace Bloom::Widgets
}
this->update();
emit this->selectionChanged(static_cast<Targets::TargetMemorySize>(this->selectedByteItemsByAddress.size()));
emit this->selectionChanged(this->selectedByteItemsByAddress);
}
void ItemGraphicsScene::setAddressType(AddressType type) {

View File

@@ -66,18 +66,9 @@ namespace Bloom::Widgets
signals:
void ready();
void hoveredAddress(const std::optional<Targets::TargetMemoryAddress>& address);
void selectionChanged(Targets::TargetMemorySize selectionCount);
void selectionChanged(const std::unordered_map<Targets::TargetMemoryAddress, ByteItem*>& selectedByteItemsByAddress);
protected:
bool event(QEvent* event) override;
void mouseDoubleClickEvent(QGraphicsSceneMouseEvent* mouseEvent) override;
void mousePressEvent(QGraphicsSceneMouseEvent* mouseEvent) override;
void mouseMoveEvent(QGraphicsSceneMouseEvent* mouseEvent) override;
void mouseReleaseEvent(QGraphicsSceneMouseEvent* mouseEvent) override;
void keyPressEvent(QKeyEvent* keyEvent) override;
void contextMenuEvent(QGraphicsSceneContextMenuEvent* event) override;
private:
static constexpr auto GRID_SIZE = 100;
bool enabled = true;
@@ -146,7 +137,15 @@ namespace Bloom::Widgets
return std::max(this->parent->viewport()->width(), 200) - 2;
}
bool event(QEvent* event) override;
void mouseDoubleClickEvent(QGraphicsSceneMouseEvent* mouseEvent) override;
void mousePressEvent(QGraphicsSceneMouseEvent* mouseEvent) override;
void mouseMoveEvent(QGraphicsSceneMouseEvent* mouseEvent) override;
void mouseReleaseEvent(QGraphicsSceneMouseEvent* mouseEvent) override;
void keyPressEvent(QKeyEvent* keyEvent) override;
void contextMenuEvent(QGraphicsSceneContextMenuEvent* event) override;
void refreshItemPositionIndices();
int getScrollbarValue();
void onTargetStateChanged(Targets::TargetState newState);
void onByteItemEnter(ByteItem& byteItem);
void onByteItemLeave();

View File

@@ -1,5 +1,7 @@
#include "ItemGraphicsView.hpp"
#include <QLayout>
#include "ByteItem.hpp"
namespace Bloom::Widgets
@@ -15,6 +17,11 @@ namespace Bloom::Widgets
QWidget* parent
)
: QGraphicsView(parent)
, targetMemoryDescriptor(targetMemoryDescriptor)
, data(data)
, focusedMemoryRegions(focusedMemoryRegions)
, excludedMemoryRegions(excludedMemoryRegions)
, settings(settings)
{
this->setObjectName("graphics-view");
this->setSizeAdjustPolicy(QAbstractScrollArea::AdjustToContents);
@@ -27,20 +34,23 @@ namespace Bloom::Widgets
this->setCacheMode(QGraphicsView::CacheModeFlag::CacheNone);
this->setFocusPolicy(Qt::StrongFocus);
this->verticalScrollBar()->setSingleStep((ByteItem::HEIGHT + (ByteItem::BOTTOM_MARGIN / 2)));
this->setViewportMargins(-1, 0, -2, 0);
this->setFrameShape(QFrame::NoFrame);
}
void ItemGraphicsView::initScene() {
this->scene = new ItemGraphicsScene(
targetMemoryDescriptor,
data,
focusedMemoryRegions,
excludedMemoryRegions,
settings,
this->targetMemoryDescriptor,
this->data,
this->focusedMemoryRegions,
this->excludedMemoryRegions,
this->settings,
this
);
this->setScene(this->scene);
this->verticalScrollBar()->setSingleStep((ByteItem::HEIGHT + (ByteItem::BOTTOM_MARGIN / 2)));
}
void ItemGraphicsView::initScene() {
QObject::connect(
this->scene,
&ItemGraphicsScene::ready,
@@ -55,12 +65,16 @@ namespace Bloom::Widgets
}
void ItemGraphicsView::scrollToByteItemAtAddress(Targets::TargetMemoryAddress address) {
if (this->scene == nullptr) {
return;
}
this->centerOn(this->scene->getByteItemPositionByAddress(address));
}
bool ItemGraphicsView::event(QEvent* event) {
const auto eventType = event->type();
if (eventType == QEvent::Type::EnabledChange) {
if (this->scene != nullptr && eventType == QEvent::Type::EnabledChange) {
this->scene->setEnabled(this->isEnabled());
}
@@ -70,11 +84,18 @@ namespace Bloom::Widgets
void ItemGraphicsView::resizeEvent(QResizeEvent* event) {
QGraphicsView::resizeEvent(event);
if (this->scene == nullptr) {
return;
}
this->scene->adjustSize();
}
void ItemGraphicsView::scrollContentsBy(int dx, int dy) {
this->scene->allocateGraphicsItems();
if (this->scene != nullptr) {
this->scene->allocateGraphicsItems();
}
return QGraphicsView::scrollContentsBy(dx, dy);
}
}

View File

@@ -26,7 +26,7 @@ namespace Bloom::Widgets
QWidget* parent
);
void initScene();
virtual void initScene();
[[nodiscard]] ItemGraphicsScene* getScene() const {
return this->scene;
@@ -38,11 +38,16 @@ namespace Bloom::Widgets
void sceneReady();
protected:
const Targets::TargetMemoryDescriptor& targetMemoryDescriptor;
const std::optional<Targets::TargetMemoryBuffer>& data;
const std::vector<FocusedMemoryRegion>& focusedMemoryRegions;
const std::vector<ExcludedMemoryRegion>& excludedMemoryRegions;
HexViewerWidgetSettings& settings;
ItemGraphicsScene* scene = nullptr;
bool event(QEvent* event) override;
void resizeEvent(QResizeEvent* event) override;
void scrollContentsBy(int dx, int dy) override;
private:
ItemGraphicsScene* scene = nullptr;
};
}