New target memory inspection pane and hex viewer widget
This commit is contained in:
@@ -0,0 +1,114 @@
|
||||
#include "ByteWidget.hpp"
|
||||
|
||||
#include <QPainter>
|
||||
#include <QStyle>
|
||||
|
||||
using namespace Bloom::Widgets;
|
||||
|
||||
ByteWidget::ByteWidget(
|
||||
std::size_t byteIndex,
|
||||
std::uint32_t address,
|
||||
std::optional<ByteWidget*>& hoveredByteWidget,
|
||||
QWidget* parent
|
||||
): ClickableWidget(parent), byteIndex(byteIndex), address(address), hoveredByteWidget(hoveredByteWidget) {
|
||||
this->setObjectName("byte");
|
||||
auto onClick = [this] {
|
||||
this->setSelected(true);
|
||||
};
|
||||
|
||||
this->addressHex = "0x" + QString::number(this->address, 16).rightJustified(8, '0').toUpper();
|
||||
this->relativeAddressHex = "0x" + QString::number(this->byteIndex, 16).rightJustified(8, '0').toUpper();
|
||||
|
||||
this->connect(this, &ClickableWidget::clicked, this, onClick);
|
||||
this->connect(this, &ClickableWidget::rightClicked, this, onClick);
|
||||
|
||||
this->setSelected(false);
|
||||
}
|
||||
|
||||
void ByteWidget::setValue(unsigned char value) {
|
||||
this->valueChanged = this->valueInitialised && this->value != value;
|
||||
|
||||
this->value = value;
|
||||
this->hexValue = QString::number(this->value, 16).rightJustified(2, '0').toUpper();
|
||||
this->asciiValue = (this->value >= 32 && this->value <= 126)
|
||||
? std::optional(QString(QChar(this->value))) : std::nullopt;
|
||||
|
||||
this->valueInitialised = true;
|
||||
}
|
||||
|
||||
void ByteWidget::setSelected(bool selected) {
|
||||
this->setProperty("selected", selected);
|
||||
this->style()->unpolish(this);
|
||||
this->style()->polish(this);
|
||||
|
||||
if (selected) {
|
||||
emit this->selected(this);
|
||||
}
|
||||
|
||||
this->postSetSelected(selected);
|
||||
}
|
||||
|
||||
bool ByteWidget::event(QEvent* event) {
|
||||
if (this->isEnabled()) {
|
||||
switch (event->type()) {
|
||||
case QEvent::Enter: {
|
||||
this->hoverActive = true;
|
||||
emit this->enter(this);
|
||||
this->update();
|
||||
break;
|
||||
}
|
||||
case QEvent::Leave: {
|
||||
this->hoverActive = false;
|
||||
emit this->leave(this);
|
||||
this->update();
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return QWidget::event(event);
|
||||
}
|
||||
|
||||
void ByteWidget::paintEvent(QPaintEvent* event) {
|
||||
auto painter = QPainter(this);
|
||||
this->drawWidget(painter);
|
||||
}
|
||||
|
||||
void ByteWidget::drawWidget(QPainter& painter) {
|
||||
painter.setRenderHints(QPainter::RenderHint::Antialiasing | QPainter::RenderHint::SmoothPixmapTransform, true);
|
||||
painter.setPen(Qt::PenStyle::NoPen);
|
||||
|
||||
static const auto widgetRect = QRect(0, 0, ByteWidget::WIDTH, ByteWidget::HEIGHT);
|
||||
|
||||
if (this->hoveredByteWidget.has_value()
|
||||
&& (
|
||||
this->hoveredByteWidget.value()->currentColumnIndex == this->currentColumnIndex
|
||||
|| this->hoveredByteWidget.value()->currentRowIndex == this->currentRowIndex
|
||||
)
|
||||
) {
|
||||
painter.setBrush(QColor(0x8E, 0x8B, 0x83, this->hoverActive ? 70 : 30));
|
||||
painter.drawRect(widgetRect);
|
||||
}
|
||||
|
||||
auto textColor = QColor(this->valueChanged ? "#547fba" : "#afb1b3");
|
||||
|
||||
if (this->valueInitialised) {
|
||||
|
||||
if (!this->isEnabled()) {
|
||||
textColor.setAlpha(100);
|
||||
}
|
||||
|
||||
painter.setPen(textColor);
|
||||
painter.drawText(widgetRect, Qt::AlignCenter, this->hexValue);
|
||||
|
||||
} else {
|
||||
textColor.setAlpha(100);
|
||||
painter.setPen(textColor);
|
||||
|
||||
static const auto placeholderString = QString("??");
|
||||
painter.drawText(widgetRect, Qt::AlignCenter, placeholderString);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <QEvent>
|
||||
#include <optional>
|
||||
|
||||
#include "src/Insight/UserInterfaces/InsightWindow/Widgets/ClickableWidget.hpp"
|
||||
|
||||
namespace Bloom::Widgets
|
||||
{
|
||||
class ByteWidget: public ClickableWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
static constexpr int WIDTH = 25;
|
||||
static constexpr int HEIGHT = 20;
|
||||
|
||||
static constexpr int RIGHT_MARGIN = 5;
|
||||
static constexpr int BOTTOM_MARGIN = 5;
|
||||
|
||||
std::size_t byteIndex;
|
||||
unsigned char value = 0x00;
|
||||
std::uint32_t address = 0x00;
|
||||
QString addressHex;
|
||||
QString relativeAddressHex;
|
||||
bool valueInitialised = false;
|
||||
|
||||
std::size_t currentRowIndex = 0;
|
||||
std::size_t currentColumnIndex = 0;
|
||||
|
||||
ByteWidget(
|
||||
std::size_t byteNumber,
|
||||
std::uint32_t address,
|
||||
std::optional<ByteWidget*>& hoveredByteWidget,
|
||||
QWidget* parent
|
||||
);
|
||||
void setValue(unsigned char value);
|
||||
|
||||
public slots:
|
||||
void setSelected(bool selected);
|
||||
|
||||
signals:
|
||||
void selected(ByteWidget*);
|
||||
void enter(ByteWidget*);
|
||||
void leave(ByteWidget*);
|
||||
|
||||
protected:
|
||||
virtual void postSetSelected(bool selected) {};
|
||||
bool event(QEvent* event) override;
|
||||
void paintEvent(QPaintEvent* event) override;
|
||||
void drawWidget(QPainter& painter);
|
||||
|
||||
private:
|
||||
bool hoverActive = false;
|
||||
bool valueChanged = false;
|
||||
|
||||
QString hexValue;
|
||||
std::optional<QString> asciiValue;
|
||||
|
||||
std::optional<ByteWidget*>& hoveredByteWidget;
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,152 @@
|
||||
#include "ByteWidgetContainer.hpp"
|
||||
|
||||
#include <QVBoxLayout>
|
||||
#include <QTableWidget>
|
||||
#include <QScrollBar>
|
||||
#include <QPainter>
|
||||
#include <cmath>
|
||||
|
||||
using namespace Bloom::Widgets;
|
||||
using namespace Bloom::Exceptions;
|
||||
|
||||
using Bloom::Targets::TargetMemoryDescriptor;
|
||||
|
||||
ByteWidgetContainer::ByteWidgetContainer(
|
||||
const TargetMemoryDescriptor& targetMemoryDescriptor,
|
||||
InsightWorker& insightWorker,
|
||||
QWidget* parent
|
||||
): QWidget(parent), targetMemoryDescriptor(targetMemoryDescriptor), insightWorker(insightWorker), parent(parent) {
|
||||
this->setObjectName("byte-widget-container");
|
||||
this->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Ignored);
|
||||
|
||||
this->setContentsMargins(
|
||||
10,
|
||||
10,
|
||||
10,
|
||||
10
|
||||
);
|
||||
|
||||
/*
|
||||
* 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 startAddress = this->targetMemoryDescriptor.addressRange.startAddress;
|
||||
for (std::size_t i = 0; i < memorySize; i++) {
|
||||
const auto address = static_cast<std::uint32_t>(startAddress + i);
|
||||
|
||||
auto byteWidget = new ByteWidget(i, address, this->hoveredByteWidget, this);
|
||||
this->byteWidgetsByAddress.insert(std::pair(
|
||||
address,
|
||||
byteWidget
|
||||
));
|
||||
|
||||
this->connect(byteWidget, &ByteWidget::enter, this, &ByteWidgetContainer::onByteWidgetEnter);
|
||||
this->connect(byteWidget, &ByteWidget::leave, this, &ByteWidgetContainer::onByteWidgetLeave);
|
||||
}
|
||||
|
||||
this->connect(
|
||||
&insightWorker,
|
||||
&InsightWorker::targetStateUpdated,
|
||||
this,
|
||||
&ByteWidgetContainer::onTargetStateChanged
|
||||
);
|
||||
|
||||
this->show();
|
||||
}
|
||||
|
||||
void ByteWidgetContainer::updateValues(const Targets::TargetMemoryBuffer& buffer) {
|
||||
for (auto& [address, byteWidget] : this->byteWidgetsByAddress) {
|
||||
byteWidget->setValue(buffer.at(byteWidget->byteIndex));
|
||||
byteWidget->update();
|
||||
}
|
||||
}
|
||||
|
||||
void ByteWidgetContainer::resizeEvent(QResizeEvent* event) {
|
||||
this->adjustByteWidgets();
|
||||
}
|
||||
|
||||
void ByteWidgetContainer::adjustByteWidgets() {
|
||||
std::map<std::size_t, std::vector<ByteWidget*>> byteWidgetsByRowIndex;
|
||||
std::map<std::size_t, std::vector<ByteWidget*>> byteWidgetsByColumnIndex;
|
||||
|
||||
const auto margins = this->contentsMargins();
|
||||
const auto width = this->width();
|
||||
|
||||
constexpr auto byteWidgetWidth = ByteWidget::WIDTH + ByteWidget::RIGHT_MARGIN;
|
||||
constexpr auto byteWidgetHeight = ByteWidget::HEIGHT + ByteWidget::BOTTOM_MARGIN;
|
||||
const auto rowCapacity = static_cast<std::size_t>(
|
||||
std::floor((width - margins.left() - margins.right()) / byteWidgetWidth)
|
||||
);
|
||||
const auto rowCount = static_cast<int>(
|
||||
std::ceil(static_cast<double>(this->byteWidgetsByAddress.size()) / static_cast<double>(rowCapacity))
|
||||
);
|
||||
|
||||
for (auto& [address, byteWidget] : this->byteWidgetsByAddress) {
|
||||
const auto rowIndex = static_cast<std::size_t>(
|
||||
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->setGeometry(QRect(
|
||||
static_cast<int>(columnIndex * byteWidgetWidth + static_cast<std::size_t>(margins.left())),
|
||||
static_cast<int>(rowIndex * byteWidgetHeight + static_cast<std::size_t>(margins.top())),
|
||||
ByteWidget::WIDTH,
|
||||
ByteWidget::HEIGHT
|
||||
));
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
const auto minHeight = (rowCount * byteWidgetHeight) + margins.top() + margins.bottom();
|
||||
this->setMinimumHeight(minHeight);
|
||||
this->parent->setMinimumHeight(minHeight);
|
||||
|
||||
this->byteWidgetsByRowIndex.swap(byteWidgetsByRowIndex);
|
||||
this->byteWidgetsByColumnIndex.swap(byteWidgetsByColumnIndex);
|
||||
|
||||
emit this->byteWidgetsAdjusted();
|
||||
}
|
||||
|
||||
void ByteWidgetContainer::onTargetStateChanged(Targets::TargetState newState) {
|
||||
using Targets::TargetState;
|
||||
this->targetState = newState;
|
||||
}
|
||||
|
||||
void ByteWidgetContainer::onByteWidgetEnter(ByteWidget* widget) {
|
||||
this->hoveredByteWidget = widget;
|
||||
|
||||
if (!this->byteWidgetsByRowIndex.empty()) {
|
||||
for (auto& byteWidget : this->byteWidgetsByColumnIndex.at(widget->currentColumnIndex)) {
|
||||
byteWidget->update();
|
||||
}
|
||||
|
||||
for (auto& byteWidget : this->byteWidgetsByRowIndex.at(widget->currentRowIndex)) {
|
||||
byteWidget->update();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ByteWidgetContainer::onByteWidgetLeave(ByteWidget* widget) {
|
||||
this->hoveredByteWidget = std::nullopt;
|
||||
|
||||
if (!this->byteWidgetsByRowIndex.empty()) {
|
||||
for (auto& byteWidget : this->byteWidgetsByColumnIndex.at(widget->currentColumnIndex)) {
|
||||
byteWidget->update();
|
||||
}
|
||||
|
||||
for (auto& byteWidget : this->byteWidgetsByRowIndex.at(widget->currentRowIndex)) {
|
||||
byteWidget->update();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
#pragma once
|
||||
|
||||
#include <QWidget>
|
||||
#include <QLabel>
|
||||
#include <QToolButton>
|
||||
#include <QVBoxLayout>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <QSize>
|
||||
#include <QString>
|
||||
#include <QEvent>
|
||||
#include <optional>
|
||||
|
||||
#include "src/Targets/TargetMemory.hpp"
|
||||
#include "src/Targets/TargetState.hpp"
|
||||
|
||||
#include "src/Insight/InsightWorker/InsightWorker.hpp"
|
||||
|
||||
#include "ByteWidget.hpp"
|
||||
|
||||
namespace Bloom::Widgets
|
||||
{
|
||||
class ByteWidgetContainer: public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
std::optional<ByteWidget*> hoveredByteWidget;
|
||||
|
||||
std::map<std::uint32_t, ByteWidget*> byteWidgetsByAddress;
|
||||
std::map<std::size_t, std::vector<ByteWidget*>> byteWidgetsByRowIndex;
|
||||
std::map<std::size_t, std::vector<ByteWidget*>> byteWidgetsByColumnIndex;
|
||||
|
||||
ByteWidgetContainer(
|
||||
const Targets::TargetMemoryDescriptor& targetMemoryDescriptor,
|
||||
InsightWorker& insightWorker,
|
||||
QWidget* parent
|
||||
);
|
||||
|
||||
void updateValues(const Targets::TargetMemoryBuffer& buffer);
|
||||
|
||||
signals:
|
||||
void byteWidgetsAdjusted();
|
||||
|
||||
protected:
|
||||
void resizeEvent(QResizeEvent* event) override;
|
||||
|
||||
private:
|
||||
const Targets::TargetMemoryDescriptor& targetMemoryDescriptor;
|
||||
InsightWorker& insightWorker;
|
||||
|
||||
QWidget* parent = nullptr;
|
||||
|
||||
Targets::TargetState targetState = Targets::TargetState::UNKNOWN;
|
||||
|
||||
void adjustByteWidgets();
|
||||
|
||||
private slots:
|
||||
void onTargetStateChanged(Targets::TargetState newState);
|
||||
void onByteWidgetEnter(ByteWidget* widget);
|
||||
void onByteWidgetLeave(ByteWidget* widget);
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,137 @@
|
||||
#include "HexViewerWidget.hpp"
|
||||
|
||||
#include <QVBoxLayout>
|
||||
#include <QTableWidget>
|
||||
#include <QScrollBar>
|
||||
#include <QScrollArea>
|
||||
#include <QPainter>
|
||||
#include <cmath>
|
||||
|
||||
#include "src/Insight/UserInterfaces/InsightWindow/UiLoader.hpp"
|
||||
|
||||
#include "src/Helpers/Paths.hpp"
|
||||
#include "src/Exceptions/Exception.hpp"
|
||||
|
||||
using namespace Bloom::Widgets;
|
||||
using namespace Bloom::Exceptions;
|
||||
|
||||
using Bloom::Targets::TargetMemoryDescriptor;
|
||||
|
||||
HexViewerWidget::HexViewerWidget(
|
||||
const TargetMemoryDescriptor& targetMemoryDescriptor,
|
||||
InsightWorker& insightWorker,
|
||||
QWidget* parent
|
||||
): QWidget(parent), targetMemoryDescriptor(targetMemoryDescriptor), insightWorker(insightWorker) {
|
||||
this->setObjectName("hex-viewer-widget");
|
||||
this->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);
|
||||
|
||||
auto widgetUiFile = QFile(
|
||||
QString::fromStdString(Paths::compiledResourcesPath()
|
||||
+ "/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/HexViewerWidget"
|
||||
+ "/UiFiles/HexViewerWidget.ui"
|
||||
)
|
||||
);
|
||||
|
||||
if (!widgetUiFile.open(QFile::ReadOnly)) {
|
||||
throw Exception("Failed to open HexViewerWidget UI file");
|
||||
}
|
||||
|
||||
auto uiLoader = UiLoader(this);
|
||||
this->container = uiLoader.load(&widgetUiFile, this);
|
||||
this->container->setFixedSize(this->size());
|
||||
this->container->setContentsMargins(0, 0, 0, 0);
|
||||
|
||||
this->toolBar = this->container->findChild<QWidget*>("tool-bar");
|
||||
this->refreshButton = this->container->findChild<QToolButton*>("refresh-memory-btn");
|
||||
|
||||
this->toolBar->setContentsMargins(0, 0, 0, 0);
|
||||
this->toolBar->layout()->setContentsMargins(5, 0, 5, 0);
|
||||
|
||||
this->byteWidgetScrollArea = this->container->findChild<QScrollArea*>("byte-widget-scroll-area");
|
||||
auto byteWidgetScrollAreaWidgetContainer = this->byteWidgetScrollArea->findChild<QWidget*>(
|
||||
"byte-widget-scroll-area-container"
|
||||
);
|
||||
auto byteWidgetScrollAreaHorizontalLayout = byteWidgetScrollAreaWidgetContainer->findChild<QHBoxLayout*>(
|
||||
"byte-widget-scroll-area-horizontal-layout"
|
||||
);
|
||||
|
||||
this->byteWidgetContainer = new ByteWidgetContainer(
|
||||
targetMemoryDescriptor,
|
||||
insightWorker,
|
||||
byteWidgetScrollAreaHorizontalLayout->parentWidget()
|
||||
);
|
||||
|
||||
byteWidgetScrollAreaHorizontalLayout->addWidget(this->byteWidgetContainer);
|
||||
|
||||
this->byteWidgetAddressContainer = byteWidgetScrollAreaWidgetContainer->findChild<QWidget*>(
|
||||
"address-container"
|
||||
);
|
||||
this->byteWidgetAddressLayout = this->byteWidgetAddressContainer->findChild<QVBoxLayout*>();
|
||||
this->byteWidgetAddressLayout->setContentsMargins(5, 10, 0, 5);
|
||||
|
||||
this->connect(
|
||||
this->byteWidgetContainer,
|
||||
&ByteWidgetContainer::byteWidgetsAdjusted,
|
||||
this,
|
||||
&HexViewerWidget::onByteWidgetsAdjusted
|
||||
);
|
||||
this->connect(
|
||||
&insightWorker,
|
||||
&InsightWorker::targetStateUpdated,
|
||||
this,
|
||||
&HexViewerWidget::onTargetStateChanged
|
||||
);
|
||||
|
||||
this->show();
|
||||
}
|
||||
|
||||
void HexViewerWidget::updateValues(const Targets::TargetMemoryBuffer& buffer) {
|
||||
this->byteWidgetContainer->updateValues(buffer);
|
||||
}
|
||||
|
||||
void HexViewerWidget::resizeEvent(QResizeEvent* event) {
|
||||
this->container->setFixedSize(
|
||||
this->width(),
|
||||
this->height()
|
||||
);
|
||||
}
|
||||
|
||||
void HexViewerWidget::onTargetStateChanged(Targets::TargetState newState) {
|
||||
using Targets::TargetState;
|
||||
this->targetState = newState;
|
||||
}
|
||||
|
||||
void HexViewerWidget::onByteWidgetsAdjusted() {
|
||||
const auto& byteWidgetsByRowIndex = this->byteWidgetContainer->byteWidgetsByRowIndex;
|
||||
|
||||
int layoutItemMaxIndex = this->byteWidgetAddressLayout->count() - 1;
|
||||
for (const auto& mappingPair : byteWidgetsByRowIndex) {
|
||||
const auto rowIndex = static_cast<int>(mappingPair.first);
|
||||
const auto& byteWidgets = mappingPair.second;
|
||||
|
||||
if (byteWidgets.empty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
QLabel* labelWidget;
|
||||
if (rowIndex > layoutItemMaxIndex) {
|
||||
labelWidget = new QLabel(this->byteWidgetAddressContainer);
|
||||
labelWidget->setFixedSize(75, 20);
|
||||
labelWidget->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
|
||||
|
||||
this->byteWidgetAddressLayout->addWidget(labelWidget);
|
||||
layoutItemMaxIndex++;
|
||||
|
||||
} else {
|
||||
labelWidget = qobject_cast<QLabel*>(this->byteWidgetAddressLayout->itemAt(rowIndex)->widget());
|
||||
}
|
||||
|
||||
labelWidget->setText(byteWidgets.front()->relativeAddressHex);
|
||||
}
|
||||
|
||||
const auto rowCount = static_cast<int>(byteWidgetsByRowIndex.size());
|
||||
QLayoutItem* labelItem;
|
||||
while ((labelItem = this->byteWidgetAddressLayout->takeAt(rowCount)) != nullptr) {
|
||||
labelItem->widget()->deleteLater();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
#pragma once
|
||||
|
||||
#include <QWidget>
|
||||
#include <QLabel>
|
||||
#include <QToolButton>
|
||||
#include <QVBoxLayout>
|
||||
#include <set>
|
||||
#include <map>
|
||||
#include <QSize>
|
||||
#include <QString>
|
||||
#include <QEvent>
|
||||
#include <optional>
|
||||
|
||||
#include "src/Targets/TargetMemory.hpp"
|
||||
#include "src/Targets/TargetState.hpp"
|
||||
|
||||
#include "src/Insight/InsightWorker/InsightWorker.hpp"
|
||||
|
||||
#include "ByteWidgetContainer.hpp"
|
||||
|
||||
namespace Bloom::Widgets
|
||||
{
|
||||
class HexViewerWidget: public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
QToolButton* refreshButton = nullptr;
|
||||
|
||||
HexViewerWidget(
|
||||
const Targets::TargetMemoryDescriptor& targetMemoryDescriptor,
|
||||
InsightWorker& insightWorker,
|
||||
QWidget* parent
|
||||
);
|
||||
|
||||
void updateValues(const Targets::TargetMemoryBuffer& buffer);
|
||||
|
||||
protected:
|
||||
void resizeEvent(QResizeEvent* event) override;
|
||||
|
||||
private:
|
||||
const Targets::TargetMemoryDescriptor& targetMemoryDescriptor;
|
||||
InsightWorker& insightWorker;
|
||||
|
||||
QWidget* container = nullptr;
|
||||
QWidget* toolBar = nullptr;
|
||||
|
||||
ByteWidgetContainer* byteWidgetContainer = nullptr;
|
||||
QWidget* byteWidgetScrollArea = nullptr;
|
||||
QWidget* byteWidgetAddressContainer = nullptr;
|
||||
QVBoxLayout* byteWidgetAddressLayout = nullptr;
|
||||
|
||||
Targets::TargetState targetState = Targets::TargetState::UNKNOWN;
|
||||
|
||||
private slots:
|
||||
void onTargetStateChanged(Targets::TargetState newState);
|
||||
void onByteWidgetsAdjusted();
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,125 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<widget class="QWidget" name="hex-viewer-container">
|
||||
<layout class="QVBoxLayout">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="margin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding"/>
|
||||
</property>
|
||||
<item alignment="Qt::AlignTop">
|
||||
<widget class="QWidget" name="tool-bar">
|
||||
<property name="minimumHeight">
|
||||
<number>27</number>
|
||||
</property>
|
||||
<property name="maximumHeight">
|
||||
<number>27</number>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed"/>
|
||||
</property>
|
||||
<layout class="QHBoxLayout">
|
||||
<property name="spacing">
|
||||
<number>3</number>
|
||||
</property>
|
||||
<property name="margin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="SvgToolButton" name="refresh-memory-btn">
|
||||
<property name="svgFilePath">
|
||||
<string>:/compiled/src/Insight/UserInterfaces/InsightWindow/Images/refresh.svg</string>
|
||||
</property>
|
||||
<property name="disabledSvgFilePath">
|
||||
<string>:/compiled/src/Insight/UserInterfaces/InsightWindow/Images/refresh-disabled.svg</string>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Refresh Memory</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item alignment="Qt::AlignTop">
|
||||
<spacer name="horizontal-spacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="ExpandingHeightScrollAreaWidget" name="byte-widget-scroll-area">
|
||||
<property name="widgetResizable"><bool>true</bool></property>
|
||||
<property name="verticalScrollBarPolicy"><enum>Qt::ScrollBarAsNeeded</enum></property>
|
||||
<property name="sizeAdjustPolicy"><enum>QAbstractScrollArea::AdjustToContents</enum></property>
|
||||
<!-- <property name="horizontalScrollBarPolicy"><enum>Qt::ScrollBarAlwaysOff</enum></property>-->
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding"/>
|
||||
</property>
|
||||
|
||||
<widget class="QWidget" name="byte-widget-scroll-area-container">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Ignored"/>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="byte-widget-scroll-area-vertical-layout">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="margin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="byte-widget-scroll-area-horizontal-layout">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="margin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QWidget" name="address-container">
|
||||
<property name="minimumWidth">
|
||||
<number>80</number>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Ignored"/>
|
||||
</property>
|
||||
<layout class="QVBoxLayout">
|
||||
<property name="spacing">
|
||||
<number>5</number>
|
||||
</property>
|
||||
<property name="margin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="vertical-spacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
<!-- <item>-->
|
||||
<!-- <spacer name="vertical-spacer">-->
|
||||
<!-- <property name="orientation">-->
|
||||
<!-- <enum>Qt::Vertical</enum>-->
|
||||
<!-- </property>-->
|
||||
<!-- </spacer>-->
|
||||
<!-- </item>-->
|
||||
</layout>
|
||||
</widget>
|
||||
</ui>
|
||||
Reference in New Issue
Block a user