Prepared HexViewerWidget for snapshot diff window
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user