New target memory inspection pane and hex viewer widget
This commit is contained in:
@@ -171,6 +171,11 @@ add_executable(Bloom
|
|||||||
src/Insight/UserInterfaces/InsightWindow/Widgets/TargetRegisterInspector/BitsetWidget/BitWidget.cpp
|
src/Insight/UserInterfaces/InsightWindow/Widgets/TargetRegisterInspector/BitsetWidget/BitWidget.cpp
|
||||||
src/Insight/UserInterfaces/InsightWindow/Widgets/TargetRegisterInspector/BitsetWidget/BitBodyWidget.cpp
|
src/Insight/UserInterfaces/InsightWindow/Widgets/TargetRegisterInspector/BitsetWidget/BitBodyWidget.cpp
|
||||||
|
|
||||||
|
# Target memory inspection pane
|
||||||
|
src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/TargetMemoryInspectionPane.cpp
|
||||||
|
src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/HexViewerWidget/HexViewerWidget.cpp
|
||||||
|
src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/HexViewerWidget/ByteWidgetContainer.cpp
|
||||||
|
src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/HexViewerWidget/ByteWidget.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
set_target_properties(Bloom PROPERTIES OUTPUT_NAME bloom)
|
set_target_properties(Bloom PROPERTIES OUTPUT_NAME bloom)
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ using Bloom::Targets::TargetPinState;
|
|||||||
using Bloom::Targets::TargetVariant;
|
using Bloom::Targets::TargetVariant;
|
||||||
using Bloom::Targets::TargetPackage;
|
using Bloom::Targets::TargetPackage;
|
||||||
using Bloom::Targets::TargetPinDescriptor;
|
using Bloom::Targets::TargetPinDescriptor;
|
||||||
|
using Bloom::Targets::TargetMemoryType;
|
||||||
|
|
||||||
InsightWindow::InsightWindow(InsightWorker& insightWorker): QMainWindow(nullptr), insightWorker(insightWorker) {
|
InsightWindow::InsightWindow(InsightWorker& insightWorker): QMainWindow(nullptr), insightWorker(insightWorker) {
|
||||||
this->setObjectName("main-window");
|
this->setObjectName("main-window");
|
||||||
@@ -239,10 +240,12 @@ void InsightWindow::toggleTargetRegistersPane() {
|
|||||||
|
|
||||||
void InsightWindow::toggleRamInspectionPane() {
|
void InsightWindow::toggleRamInspectionPane() {
|
||||||
if (this->bottomPanel->isVisible()) {
|
if (this->bottomPanel->isVisible()) {
|
||||||
|
this->ramInspectionPane->deactivate();
|
||||||
this->bottomPanel->hide();
|
this->bottomPanel->hide();
|
||||||
this->ramInspectionButton->setChecked(false);
|
this->ramInspectionButton->setChecked(false);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
this->ramInspectionPane->activate();
|
||||||
this->bottomPanel->show();
|
this->bottomPanel->show();
|
||||||
this->ramInspectionButton->setChecked(true);
|
this->ramInspectionButton->setChecked(true);
|
||||||
}
|
}
|
||||||
@@ -486,13 +489,26 @@ void InsightWindow::activate() {
|
|||||||
auto leftPanelLayout = this->leftPanel->layout();
|
auto leftPanelLayout = this->leftPanel->layout();
|
||||||
this->targetRegistersSidePane = new TargetRegistersPaneWidget(
|
this->targetRegistersSidePane = new TargetRegistersPaneWidget(
|
||||||
this->targetDescriptor,
|
this->targetDescriptor,
|
||||||
insightWorker,
|
this->insightWorker,
|
||||||
this->leftPanel
|
this->leftPanel
|
||||||
);
|
);
|
||||||
leftPanelLayout->addWidget(this->targetRegistersSidePane);
|
leftPanelLayout->addWidget(this->targetRegistersSidePane);
|
||||||
this->targetRegistersButton->setChecked(false);
|
this->targetRegistersButton->setChecked(false);
|
||||||
this->targetRegistersButton->setDisabled(false);
|
this->targetRegistersButton->setDisabled(false);
|
||||||
|
|
||||||
|
auto bottomPanelLayout = this->bottomPanel->layout();
|
||||||
|
if (this->targetDescriptor.memoryDescriptorsByType.contains(TargetMemoryType::RAM)) {
|
||||||
|
auto& ramDescriptor = this->targetDescriptor.memoryDescriptorsByType.at(TargetMemoryType::RAM);
|
||||||
|
this->ramInspectionPane = new TargetMemoryInspectionPane(
|
||||||
|
ramDescriptor,
|
||||||
|
this->insightWorker,
|
||||||
|
this->bottomPanel
|
||||||
|
);
|
||||||
|
bottomPanelLayout->addWidget(this->ramInspectionPane);
|
||||||
|
this->ramInspectionButton->setChecked(false);
|
||||||
|
this->ramInspectionButton->setDisabled(false);
|
||||||
|
}
|
||||||
|
|
||||||
this->toggleUi(this->targetState != TargetState::STOPPED);
|
this->toggleUi(this->targetState != TargetState::STOPPED);
|
||||||
this->activated = true;
|
this->activated = true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
#include "Widgets/TargetWidgets/TargetPackageWidgetContainer.hpp"
|
#include "Widgets/TargetWidgets/TargetPackageWidgetContainer.hpp"
|
||||||
#include "Widgets/TargetWidgets/TargetPackageWidget.hpp"
|
#include "Widgets/TargetWidgets/TargetPackageWidget.hpp"
|
||||||
#include "Widgets/TargetRegistersPane/TargetRegistersPaneWidget.hpp"
|
#include "Widgets/TargetRegistersPane/TargetRegistersPaneWidget.hpp"
|
||||||
|
#include "Widgets/TargetMemoryInspectionPane/TargetMemoryInspectionPane.hpp"
|
||||||
#include "AboutWindow.hpp"
|
#include "AboutWindow.hpp"
|
||||||
|
|
||||||
namespace Bloom
|
namespace Bloom
|
||||||
@@ -91,6 +92,7 @@ namespace Bloom
|
|||||||
|
|
||||||
QWidget* bottomMenuBar = nullptr;
|
QWidget* bottomMenuBar = nullptr;
|
||||||
Widgets::PanelWidget* bottomPanel = nullptr;
|
Widgets::PanelWidget* bottomPanel = nullptr;
|
||||||
|
Widgets::TargetMemoryInspectionPane* ramInspectionPane = nullptr;
|
||||||
QToolButton* ramInspectionButton = nullptr;
|
QToolButton* ramInspectionButton = nullptr;
|
||||||
|
|
||||||
QWidget* footer = nullptr;
|
QWidget* footer = nullptr;
|
||||||
|
|||||||
@@ -299,19 +299,30 @@ QScrollBar::sub-line:vertical {
|
|||||||
border-top: 1px solid #2F2F2D;
|
border-top: 1px solid #2F2F2D;
|
||||||
}
|
}
|
||||||
|
|
||||||
#bottom-menu-bar #ram-inspection-btn {
|
#bottom-menu-bar #ram-inspection-btn,
|
||||||
|
#bottom-menu-bar #eeprom-inspection-btn {
|
||||||
position: relative;
|
position: relative;
|
||||||
border: none;
|
border: none;
|
||||||
min-width: 90px;
|
|
||||||
min-height: 22px;
|
min-height: 22px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#bottom-menu-bar #ram-inspection-btn #ram-inspection-btn-icon {
|
#bottom-menu-bar #ram-inspection-btn {
|
||||||
margin-left: 9px;
|
min-width: 71px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#bottom-menu-bar #ram-inspection-btn #ram-inspection-btn-label {
|
#bottom-menu-bar #eeprom-inspection-btn {
|
||||||
margin-left: 2px;
|
min-width: 97px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#bottom-menu-bar #ram-inspection-btn #ram-inspection-btn-icon,
|
||||||
|
#bottom-menu-bar #eeprom-inspection-btn #eeprom-inspection-btn-icon {
|
||||||
|
margin-left: 7px;
|
||||||
|
margin-top: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#bottom-menu-bar #ram-inspection-btn #ram-inspection-btn-label,
|
||||||
|
#bottom-menu-bar #eeprom-inspection-btn #eeprom-inspection-btn-label {
|
||||||
|
margin-left: 1px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#bottom-menu-bar QToolButton:hover,
|
#bottom-menu-bar QToolButton:hover,
|
||||||
@@ -324,3 +335,57 @@ QScrollBar::sub-line:vertical {
|
|||||||
border-top: 1px solid #2F2F2D;
|
border-top: 1px solid #2F2F2D;
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Target Memory Inspection Pane */
|
||||||
|
#target-memory-inspection-pane #title-bar {
|
||||||
|
background-color: #383F43;
|
||||||
|
border-bottom: 1px solid #2F2F2D;
|
||||||
|
}
|
||||||
|
|
||||||
|
#target-memory-inspection-pane #title {
|
||||||
|
color: #afb1b3;
|
||||||
|
}
|
||||||
|
|
||||||
|
#hex-viewer-container #tool-bar,
|
||||||
|
#hex-viewer-container #search-bar {
|
||||||
|
border-bottom: 1px solid #2F2F2D;
|
||||||
|
}
|
||||||
|
|
||||||
|
#hex-viewer-container #tool-bar QToolButton {
|
||||||
|
background-color: transparent;
|
||||||
|
border: none;
|
||||||
|
padding: 0;
|
||||||
|
qproperty-buttonWidth: 24;
|
||||||
|
qproperty-buttonHeight: 20;
|
||||||
|
}
|
||||||
|
|
||||||
|
#hex-viewer-container #tool-bar QToolButton:hover {
|
||||||
|
background-color: #454541;
|
||||||
|
border: none;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#hex-viewer-container QScrollArea,
|
||||||
|
#hex-viewer-container #byte-widget-scroll-area-container {
|
||||||
|
background-color: transparent;
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
#hex-viewer-container #byte-widget-scroll-area-container #address-container {
|
||||||
|
background-color: transparent;
|
||||||
|
border-right: 1px solid #2F2F2D;
|
||||||
|
}
|
||||||
|
|
||||||
|
#hex-viewer-container #byte-widget-scroll-area-container #address-container QLabel {
|
||||||
|
background-color: transparent;
|
||||||
|
font-size: 12px;
|
||||||
|
color: rgba(175, 177, 179, 0.72);
|
||||||
|
}
|
||||||
|
|
||||||
|
#hex-viewer-container #byte-widget-scroll-area-container #address-container QLabel:disabled {
|
||||||
|
color: rgba(175, 177, 179, 0.3);
|
||||||
|
}
|
||||||
|
|
||||||
|
#hex-viewer-container #byte {
|
||||||
|
font-size: 11px;
|
||||||
|
}
|
||||||
|
|||||||
@@ -252,11 +252,8 @@
|
|||||||
<property name="panelType">
|
<property name="panelType">
|
||||||
<enum>PanelWidgetType::BOTTOM</enum>
|
<enum>PanelWidgetType::BOTTOM</enum>
|
||||||
</property>
|
</property>
|
||||||
<property name="maximumHeight">
|
|
||||||
<number>200</number>
|
|
||||||
</property>
|
|
||||||
<property name="minimumResize">
|
<property name="minimumResize">
|
||||||
<number>200</number>
|
<number>300</number>
|
||||||
</property>
|
</property>
|
||||||
<property name="handleSize">
|
<property name="handleSize">
|
||||||
<number>10</number>
|
<number>10</number>
|
||||||
@@ -275,14 +272,14 @@
|
|||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item alignment="Qt::AlignBottom">
|
||||||
<widget class="QWidget" name="bottom-menu-bar">
|
<widget class="QWidget" name="bottom-menu-bar">
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed"/>
|
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed"/>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QHBoxLayout">
|
<layout class="QHBoxLayout">
|
||||||
<property name="spacing">
|
<property name="spacing">
|
||||||
<number>1</number>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
<property name="margin">
|
<property name="margin">
|
||||||
<number>0</number>
|
<number>0</number>
|
||||||
@@ -323,20 +320,71 @@
|
|||||||
<number>22</number>
|
<number>22</number>
|
||||||
</property>
|
</property>
|
||||||
<property name="containerWidth">
|
<property name="containerWidth">
|
||||||
<number>15</number>
|
<number>22</number>
|
||||||
</property>
|
</property>
|
||||||
<property name="svgFilePath">
|
<property name="svgFilePath">
|
||||||
<string>:/compiled/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetRegistersPane/Images/target-registers.svg</string>
|
<string>:/compiled/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/Images/memory-inspection-icon.svg</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="disabledSvgFilePath">
|
<property name="disabledSvgFilePath">
|
||||||
<string>:/compiled/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetRegistersPane/Images/target-registers-disabled.svg</string>
|
<string>:/compiled/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/Images/memory-inspection-icon-disabled.svg</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item alignment="Qt::AlignLeft">
|
<item alignment="Qt::AlignLeft">
|
||||||
<widget class="QLabel" name="ram-inspection-btn-label">
|
<widget class="QLabel" name="ram-inspection-btn-label">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Memory</string>
|
<string>RAM</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item alignment="Qt::AlignLeft">
|
||||||
|
<spacer name="horizontal-spacer">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QToolButton" name="eeprom-inspection-btn">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Inspect EEPROM</string>
|
||||||
|
</property>
|
||||||
|
<property name="checkable">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="disabled">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<layout class="QHBoxLayout">
|
||||||
|
<property name="spacing">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="margin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<item alignment="Qt::AlignLeft">
|
||||||
|
<widget class="SvgWidget" name="eeprom-inspection-btn-icon">
|
||||||
|
<property name="containerHeight">
|
||||||
|
<number>22</number>
|
||||||
|
</property>
|
||||||
|
<property name="containerWidth">
|
||||||
|
<number>22</number>
|
||||||
|
</property>
|
||||||
|
<property name="svgFilePath">
|
||||||
|
<string>:/compiled/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/Images/memory-inspection-icon.svg</string>
|
||||||
|
</property>
|
||||||
|
<property name="disabledSvgFilePath">
|
||||||
|
<string>:/compiled/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/Images/memory-inspection-icon-disabled.svg</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item alignment="Qt::AlignLeft">
|
||||||
|
<widget class="QLabel" name="eeprom-inspection-btn-label">
|
||||||
|
<property name="text">
|
||||||
|
<string>EEPROM</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
|||||||
@@ -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>
|
||||||
@@ -0,0 +1,115 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
width="20"
|
||||||
|
height="15"
|
||||||
|
viewBox="0 0 5.2916667 3.96875"
|
||||||
|
version="1.1"
|
||||||
|
id="svg974"
|
||||||
|
sodipodi:docname="memory-inspection-icon.svg"
|
||||||
|
inkscape:version="1.0.1 (1.0.1+r75)">
|
||||||
|
<defs
|
||||||
|
id="defs968" />
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="base"
|
||||||
|
pagecolor="#343532"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1.0"
|
||||||
|
inkscape:pageopacity="0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:zoom="0.9899495"
|
||||||
|
inkscape:cx="-326.26819"
|
||||||
|
inkscape:cy="-242.5437"
|
||||||
|
inkscape:document-units="px"
|
||||||
|
inkscape:current-layer="layer2"
|
||||||
|
inkscape:document-rotation="0"
|
||||||
|
showgrid="false"
|
||||||
|
units="px"
|
||||||
|
inkscape:snap-page="true"
|
||||||
|
inkscape:window-width="3440"
|
||||||
|
inkscape:window-height="1353"
|
||||||
|
inkscape:window-x="2560"
|
||||||
|
inkscape:window-y="34"
|
||||||
|
inkscape:window-maximized="1"
|
||||||
|
inkscape:snap-smooth-nodes="true"
|
||||||
|
inkscape:snap-bbox="true"
|
||||||
|
inkscape:snap-bbox-midpoints="true"
|
||||||
|
inkscape:snap-bbox-edge-midpoints="true" />
|
||||||
|
<metadata
|
||||||
|
id="metadata971">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work
|
||||||
|
rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
<dc:title></dc:title>
|
||||||
|
</cc:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<g
|
||||||
|
inkscape:label="Body"
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
id="layer1">
|
||||||
|
<rect
|
||||||
|
style="fill:#c4c4c4;fill-opacity:0.545098;stroke-width:0.142636"
|
||||||
|
id="rect1537"
|
||||||
|
width="3.175"
|
||||||
|
height="1.3229166"
|
||||||
|
x="1.0583333"
|
||||||
|
y="1.3229167" />
|
||||||
|
</g>
|
||||||
|
<g
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
id="layer2"
|
||||||
|
inkscape:label="Pins">
|
||||||
|
<rect
|
||||||
|
style="fill:#c4c4c4;fill-opacity:0.545098;stroke-width:0.0411755"
|
||||||
|
id="rect1537-3"
|
||||||
|
width="0.52916664"
|
||||||
|
height="0.66145831"
|
||||||
|
x="2.3812499"
|
||||||
|
y="0.39687499" />
|
||||||
|
<rect
|
||||||
|
style="fill:#c4c4c4;fill-opacity:0.545098;stroke-width:0.0411754"
|
||||||
|
id="rect1537-3-6"
|
||||||
|
width="0.52916664"
|
||||||
|
height="0.66145831"
|
||||||
|
x="1.5875001"
|
||||||
|
y="0.39687499" />
|
||||||
|
<rect
|
||||||
|
style="fill:#c4c4c4;fill-opacity:0.545098;stroke-width:0.0411754"
|
||||||
|
id="rect1537-3-7"
|
||||||
|
width="0.52916664"
|
||||||
|
height="0.66145831"
|
||||||
|
x="3.175"
|
||||||
|
y="0.39687499" />
|
||||||
|
<rect
|
||||||
|
style="fill:#c4c4c4;fill-opacity:0.545098;stroke-width:0.0411754"
|
||||||
|
id="rect1537-3-5"
|
||||||
|
width="0.52916664"
|
||||||
|
height="0.66145831"
|
||||||
|
x="2.3812499"
|
||||||
|
y="2.9104166" />
|
||||||
|
<rect
|
||||||
|
style="fill:#c4c4c4;fill-opacity:0.545098;stroke-width:0.0411754"
|
||||||
|
id="rect1537-3-5-6"
|
||||||
|
width="0.52916664"
|
||||||
|
height="0.66145831"
|
||||||
|
x="3.175"
|
||||||
|
y="2.9104166" />
|
||||||
|
<rect
|
||||||
|
style="fill:#c4c4c4;fill-opacity:0.545098;stroke-width:0.0411754"
|
||||||
|
id="rect1537-3-5-2"
|
||||||
|
width="0.52916664"
|
||||||
|
height="0.66145831"
|
||||||
|
x="1.5875"
|
||||||
|
y="2.9104166" />
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 3.2 KiB |
@@ -0,0 +1,170 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
width="20"
|
||||||
|
height="16"
|
||||||
|
viewBox="0 0 5.2916667 4.2333333"
|
||||||
|
version="1.1"
|
||||||
|
id="svg974"
|
||||||
|
sodipodi:docname="memory-inspection-icon.svg"
|
||||||
|
inkscape:version="1.0.1 (1.0.1+r75)">
|
||||||
|
<defs
|
||||||
|
id="defs968" />
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="base"
|
||||||
|
pagecolor="#343532"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1.0"
|
||||||
|
inkscape:pageopacity="0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:zoom="11.2"
|
||||||
|
inkscape:cx="25.611036"
|
||||||
|
inkscape:cy="3.7785754"
|
||||||
|
inkscape:document-units="px"
|
||||||
|
inkscape:current-layer="layer2"
|
||||||
|
inkscape:document-rotation="0"
|
||||||
|
showgrid="false"
|
||||||
|
units="px"
|
||||||
|
inkscape:snap-page="true"
|
||||||
|
inkscape:window-width="3440"
|
||||||
|
inkscape:window-height="1353"
|
||||||
|
inkscape:window-x="2560"
|
||||||
|
inkscape:window-y="34"
|
||||||
|
inkscape:window-maximized="1"
|
||||||
|
inkscape:snap-smooth-nodes="true"
|
||||||
|
inkscape:snap-bbox="true"
|
||||||
|
inkscape:snap-bbox-midpoints="true"
|
||||||
|
inkscape:snap-bbox-edge-midpoints="true" />
|
||||||
|
<metadata
|
||||||
|
id="metadata971">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work
|
||||||
|
rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
<dc:title></dc:title>
|
||||||
|
</cc:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<g
|
||||||
|
inkscape:label="Body"
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
id="layer1" />
|
||||||
|
<g
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
id="layer2"
|
||||||
|
inkscape:label="Pins">
|
||||||
|
<rect
|
||||||
|
style="fill:#c4c4c4;fill-opacity:0.545098;stroke-width:0.0368285"
|
||||||
|
id="rect1537-3"
|
||||||
|
width="0.52916664"
|
||||||
|
height="0.5291667"
|
||||||
|
x="1.5874999"
|
||||||
|
y="1.058333" />
|
||||||
|
<rect
|
||||||
|
style="fill:#c4c4c4;fill-opacity:0.545098;stroke-width:0.0368284"
|
||||||
|
id="rect1537-3-6"
|
||||||
|
width="0.52916664"
|
||||||
|
height="0.5291667"
|
||||||
|
x="0.79374987"
|
||||||
|
y="1.058333" />
|
||||||
|
<rect
|
||||||
|
style="fill:#c4c4c4;fill-opacity:0.545098;stroke-width:0.0368284"
|
||||||
|
id="rect1537-3-7"
|
||||||
|
width="0.52916664"
|
||||||
|
height="0.5291667"
|
||||||
|
x="2.3812499"
|
||||||
|
y="1.058333" />
|
||||||
|
<rect
|
||||||
|
style="fill:#c4c4c4;fill-opacity:0.545098;stroke-width:0.0368284"
|
||||||
|
id="rect1537-3-5"
|
||||||
|
width="0.52916664"
|
||||||
|
height="0.5291667"
|
||||||
|
x="1.5875001"
|
||||||
|
y="1.8520831" />
|
||||||
|
<rect
|
||||||
|
style="fill:#c4c4c4;fill-opacity:0.545098;stroke-width:0.0368284"
|
||||||
|
id="rect1537-3-5-6"
|
||||||
|
width="0.52916664"
|
||||||
|
height="0.5291667"
|
||||||
|
x="2.3812501"
|
||||||
|
y="1.8520831" />
|
||||||
|
<rect
|
||||||
|
style="fill:#c4c4c4;fill-opacity:0.545098;stroke-width:0.0368284"
|
||||||
|
id="rect1537-3-5-2"
|
||||||
|
width="0.52916664"
|
||||||
|
height="0.5291667"
|
||||||
|
x="0.79374987"
|
||||||
|
y="1.8520831" />
|
||||||
|
<rect
|
||||||
|
style="fill:#c4c4c4;fill-opacity:0.545098;stroke-width:0.0368284"
|
||||||
|
id="rect1537-3-5-9"
|
||||||
|
width="0.52916664"
|
||||||
|
height="0.5291667"
|
||||||
|
x="1.5875003"
|
||||||
|
y="2.6458333" />
|
||||||
|
<rect
|
||||||
|
style="fill:#c4c4c4;fill-opacity:0.545098;stroke-width:0.0368284"
|
||||||
|
id="rect1537-3-5-6-1"
|
||||||
|
width="0.52916664"
|
||||||
|
height="0.5291667"
|
||||||
|
x="2.3812501"
|
||||||
|
y="2.6458333" />
|
||||||
|
<rect
|
||||||
|
style="fill:#c4c4c4;fill-opacity:0.545098;stroke-width:0.0368284"
|
||||||
|
id="rect1537-3-5-2-2"
|
||||||
|
width="0.52916664"
|
||||||
|
height="0.5291667"
|
||||||
|
x="0.79374987"
|
||||||
|
y="2.6458333" />
|
||||||
|
<rect
|
||||||
|
style="fill:#c4c4c4;fill-opacity:0.545098;stroke-width:0.0368284"
|
||||||
|
id="rect1537-3-70"
|
||||||
|
width="0.52916664"
|
||||||
|
height="0.5291667"
|
||||||
|
x="3.175"
|
||||||
|
y="1.058333" />
|
||||||
|
<rect
|
||||||
|
style="fill:#c4c4c4;fill-opacity:0.545098;stroke-width:0.0368284"
|
||||||
|
id="rect1537-3-7-9"
|
||||||
|
width="0.52916664"
|
||||||
|
height="0.5291667"
|
||||||
|
x="3.9687502"
|
||||||
|
y="1.058333" />
|
||||||
|
<rect
|
||||||
|
style="fill:#c4c4c4;fill-opacity:0.545098;stroke-width:0.0368284"
|
||||||
|
id="rect1537-3-5-3"
|
||||||
|
width="0.52916664"
|
||||||
|
height="0.5291667"
|
||||||
|
x="3.1750002"
|
||||||
|
y="1.8520831" />
|
||||||
|
<rect
|
||||||
|
style="fill:#c4c4c4;fill-opacity:0.545098;stroke-width:0.0368284"
|
||||||
|
id="rect1537-3-5-6-6"
|
||||||
|
width="0.52916664"
|
||||||
|
height="0.5291667"
|
||||||
|
x="3.9687502"
|
||||||
|
y="1.8520831" />
|
||||||
|
<rect
|
||||||
|
style="fill:#c4c4c4;fill-opacity:0.545098;stroke-width:0.0368284"
|
||||||
|
id="rect1537-3-5-9-0"
|
||||||
|
width="0.52916664"
|
||||||
|
height="0.5291667"
|
||||||
|
x="3.1750004"
|
||||||
|
y="2.6458335" />
|
||||||
|
<rect
|
||||||
|
style="fill:#c4c4c4;fill-opacity:0.545098;stroke-width:0.0368284"
|
||||||
|
id="rect1537-3-5-6-1-6"
|
||||||
|
width="0.52916664"
|
||||||
|
height="0.5291667"
|
||||||
|
x="3.9687502"
|
||||||
|
y="2.6458335" />
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 4.9 KiB |
@@ -0,0 +1,155 @@
|
|||||||
|
#include "TargetMemoryInspectionPane.hpp"
|
||||||
|
|
||||||
|
#include <QVBoxLayout>
|
||||||
|
#include <QLabel>
|
||||||
|
#include <QToolButton>
|
||||||
|
#include <set>
|
||||||
|
|
||||||
|
#include "src/Insight/UserInterfaces/InsightWindow/UiLoader.hpp"
|
||||||
|
|
||||||
|
#include "src/Insight/InsightWorker/Tasks/ReadTargetMemory.hpp"
|
||||||
|
|
||||||
|
#include "src/Helpers/Paths.hpp"
|
||||||
|
#include "src/Exceptions/Exception.hpp"
|
||||||
|
#include "src/Logger/Logger.hpp"
|
||||||
|
|
||||||
|
using namespace Bloom::Widgets;
|
||||||
|
using namespace Bloom::Exceptions;
|
||||||
|
|
||||||
|
using Bloom::Targets::TargetMemoryDescriptor;
|
||||||
|
using Bloom::Targets::TargetMemoryType;
|
||||||
|
|
||||||
|
TargetMemoryInspectionPane::TargetMemoryInspectionPane(
|
||||||
|
const TargetMemoryDescriptor& targetMemoryDescriptor,
|
||||||
|
InsightWorker& insightWorker,
|
||||||
|
PanelWidget* parent
|
||||||
|
): QWidget(parent), parent(parent), targetMemoryDescriptor(targetMemoryDescriptor), insightWorker(insightWorker) {
|
||||||
|
this->setObjectName("target-memory-inspection-pane");
|
||||||
|
|
||||||
|
auto memoryInspectionPaneUiFile = QFile(
|
||||||
|
QString::fromStdString(Paths::compiledResourcesPath()
|
||||||
|
+ "/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/UiFiles/TargetMemoryInspectionPane.ui"
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!memoryInspectionPaneUiFile.open(QFile::ReadOnly)) {
|
||||||
|
throw Exception("Failed to open MemoryInspectionPane UI file");
|
||||||
|
}
|
||||||
|
|
||||||
|
auto uiLoader = UiLoader(this);
|
||||||
|
this->container = uiLoader.load(&memoryInspectionPaneUiFile, this);
|
||||||
|
this->container->setFixedSize(parent->width(), parent->maximumHeight());
|
||||||
|
|
||||||
|
this->titleBar = this->container->findChild<QWidget*>("title-bar");
|
||||||
|
|
||||||
|
this->titleBar->layout()->setContentsMargins(7, 0, 7, 0);
|
||||||
|
auto titleLabel = this->titleBar->findChild<QLabel*>("title");
|
||||||
|
titleLabel->setText("Internal RAM");
|
||||||
|
|
||||||
|
auto subContainerLayout = this->container->findChild<QHBoxLayout*>("sub-container-layout");
|
||||||
|
this->hexViewerWidget = new HexViewerWidget(this->targetMemoryDescriptor, this->insightWorker, this);
|
||||||
|
this->hexViewerWidget->setDisabled(true);
|
||||||
|
|
||||||
|
subContainerLayout->addWidget(this->hexViewerWidget);
|
||||||
|
|
||||||
|
this->connect(
|
||||||
|
&insightWorker,
|
||||||
|
&InsightWorker::targetStateUpdated,
|
||||||
|
this,
|
||||||
|
&TargetMemoryInspectionPane::onTargetStateChanged
|
||||||
|
);
|
||||||
|
|
||||||
|
this->connect(
|
||||||
|
this->hexViewerWidget->refreshButton,
|
||||||
|
&QToolButton::clicked,
|
||||||
|
this,
|
||||||
|
[this] {
|
||||||
|
this->refreshMemoryValues();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TargetMemoryInspectionPane::refreshMemoryValues(std::optional<std::function<void(void)>> callback) {
|
||||||
|
this->hexViewerWidget->refreshButton->setDisabled(true);
|
||||||
|
|
||||||
|
auto readMemoryTask = new ReadTargetMemory(
|
||||||
|
this->targetMemoryDescriptor.type,
|
||||||
|
this->targetMemoryDescriptor.addressRange.startAddress,
|
||||||
|
this->targetMemoryDescriptor.size()
|
||||||
|
);
|
||||||
|
|
||||||
|
this->connect(
|
||||||
|
readMemoryTask,
|
||||||
|
&ReadTargetMemory::targetMemoryRead,
|
||||||
|
this,
|
||||||
|
&TargetMemoryInspectionPane::onMemoryRead
|
||||||
|
);
|
||||||
|
|
||||||
|
this->connect(
|
||||||
|
readMemoryTask,
|
||||||
|
&InsightWorkerTask::completed,
|
||||||
|
this,
|
||||||
|
[this] {
|
||||||
|
this->hexViewerWidget->refreshButton->setDisabled(false);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
if (callback.has_value()) {
|
||||||
|
this->connect(
|
||||||
|
readMemoryTask,
|
||||||
|
&InsightWorkerTask::completed,
|
||||||
|
this,
|
||||||
|
callback.value()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
this->insightWorker.queueTask(readMemoryTask);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TargetMemoryInspectionPane::activate() {
|
||||||
|
this->show();
|
||||||
|
this->activated = true;
|
||||||
|
this->postActivate();
|
||||||
|
}
|
||||||
|
|
||||||
|
void TargetMemoryInspectionPane::deactivate() {
|
||||||
|
this->hide();
|
||||||
|
this->activated = false;
|
||||||
|
this->postDeactivate();
|
||||||
|
}
|
||||||
|
|
||||||
|
void TargetMemoryInspectionPane::resizeEvent(QResizeEvent* event) {
|
||||||
|
const auto parentSize = this->parent->size();
|
||||||
|
const auto width = parentSize.width() - 1;
|
||||||
|
this->container->setFixedSize(width, parentSize.height());
|
||||||
|
}
|
||||||
|
|
||||||
|
void TargetMemoryInspectionPane::postActivate() {
|
||||||
|
if (this->targetState == Targets::TargetState::STOPPED) {
|
||||||
|
this->refreshMemoryValues();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void TargetMemoryInspectionPane::postDeactivate() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void TargetMemoryInspectionPane::onTargetStateChanged(Targets::TargetState newState) {
|
||||||
|
using Targets::TargetState;
|
||||||
|
this->targetState = newState;
|
||||||
|
|
||||||
|
if (this->activated) {
|
||||||
|
if (newState == TargetState::STOPPED) {
|
||||||
|
this->refreshMemoryValues([this] {
|
||||||
|
this->hexViewerWidget->setDisabled(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
} else {
|
||||||
|
this->hexViewerWidget->setDisabled(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void TargetMemoryInspectionPane::onMemoryRead(const Targets::TargetMemoryBuffer& buffer) {
|
||||||
|
this->hexViewerWidget->updateValues(buffer);
|
||||||
|
}
|
||||||
@@ -0,0 +1,63 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QWidget>
|
||||||
|
#include <QLineEdit>
|
||||||
|
#include <QScrollArea>
|
||||||
|
#include <set>
|
||||||
|
#include <QSize>
|
||||||
|
#include <QString>
|
||||||
|
#include <QEvent>
|
||||||
|
#include <optional>
|
||||||
|
|
||||||
|
#include "src/Insight/UserInterfaces/InsightWindow/Widgets/PanelWidget.hpp"
|
||||||
|
#include "src/Insight/UserInterfaces/InsightWindow/Widgets/SvgToolButton.hpp"
|
||||||
|
#include "src/Insight/InsightWorker/InsightWorker.hpp"
|
||||||
|
|
||||||
|
#include "HexViewerWidget/HexViewerWidget.hpp"
|
||||||
|
|
||||||
|
#include "src/Targets/TargetMemory.hpp"
|
||||||
|
#include "src/Targets/TargetState.hpp"
|
||||||
|
|
||||||
|
namespace Bloom::Widgets
|
||||||
|
{
|
||||||
|
class TargetMemoryInspectionPane: public QWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
bool activated = false;
|
||||||
|
|
||||||
|
TargetMemoryInspectionPane(
|
||||||
|
const Targets::TargetMemoryDescriptor& targetMemoryDescriptor,
|
||||||
|
InsightWorker& insightWorker,
|
||||||
|
PanelWidget *parent
|
||||||
|
);
|
||||||
|
|
||||||
|
void refreshMemoryValues(std::optional<std::function<void(void)>> callback = std::nullopt);
|
||||||
|
|
||||||
|
void activate();
|
||||||
|
void deactivate();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void resizeEvent(QResizeEvent* event) override;
|
||||||
|
|
||||||
|
virtual void postActivate();
|
||||||
|
virtual void postDeactivate();
|
||||||
|
|
||||||
|
private:
|
||||||
|
const Targets::TargetMemoryDescriptor& targetMemoryDescriptor;
|
||||||
|
InsightWorker& insightWorker;
|
||||||
|
|
||||||
|
PanelWidget* parent = nullptr;
|
||||||
|
QWidget* container = nullptr;
|
||||||
|
|
||||||
|
QWidget* titleBar = nullptr;
|
||||||
|
HexViewerWidget* hexViewerWidget = nullptr;
|
||||||
|
|
||||||
|
Targets::TargetState targetState = Targets::TargetState::UNKNOWN;
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void onTargetStateChanged(Targets::TargetState newState);
|
||||||
|
void onMemoryRead(const Targets::TargetMemoryBuffer& buffer);
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,62 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<widget class="QWidget" name="container">
|
||||||
|
<layout class="QVBoxLayout">
|
||||||
|
<property name="spacing">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="margin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<item alignment="Qt::AlignTop">
|
||||||
|
<widget class="QWidget" name="title-bar">
|
||||||
|
<property name="minimumHeight">
|
||||||
|
<number>28</number>
|
||||||
|
</property>
|
||||||
|
<property name="maximumHeight">
|
||||||
|
<number>28</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="QLabel" name="title"/>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="horizontal-spacer">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="sub-container-layout">
|
||||||
|
<property name="spacing">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="margin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<!-- <item alignment="Qt::AlignTop">-->
|
||||||
|
<!-- <spacer name="vertical-spacer">-->
|
||||||
|
<!-- <property name="orientation">-->
|
||||||
|
<!-- <enum>Qt::Vertical</enum>-->
|
||||||
|
<!-- </property>-->
|
||||||
|
<!-- </spacer>-->
|
||||||
|
<!-- </item>-->
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</ui>
|
||||||
@@ -23,6 +23,8 @@
|
|||||||
<file alias="/compiled/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetRegisterInspector/UiFiles/TargetRegisterInspectorWindow.ui">./Insight/UserInterfaces/InsightWindow/Widgets/TargetRegisterInspector/UiFiles/TargetRegisterInspectorWindow.ui</file>
|
<file alias="/compiled/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetRegisterInspector/UiFiles/TargetRegisterInspectorWindow.ui">./Insight/UserInterfaces/InsightWindow/Widgets/TargetRegisterInspector/UiFiles/TargetRegisterInspectorWindow.ui</file>
|
||||||
<file alias="/compiled/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetRegisterInspector/RegisterHistoryWidget/UiFiles/RegisterHistoryWidget.ui">./Insight/UserInterfaces/InsightWindow/Widgets/TargetRegisterInspector/RegisterHistoryWidget/UiFiles/RegisterHistoryWidget.ui</file>
|
<file alias="/compiled/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetRegisterInspector/RegisterHistoryWidget/UiFiles/RegisterHistoryWidget.ui">./Insight/UserInterfaces/InsightWindow/Widgets/TargetRegisterInspector/RegisterHistoryWidget/UiFiles/RegisterHistoryWidget.ui</file>
|
||||||
<file alias="/compiled/src/Insight/UserInterfaces/InsightWindow/Widgets/ErrorDialogue/UiFiles/ErrorDialogue.ui">./Insight/UserInterfaces/InsightWindow/Widgets/ErrorDialogue/UiFiles/ErrorDialogue.ui</file>
|
<file alias="/compiled/src/Insight/UserInterfaces/InsightWindow/Widgets/ErrorDialogue/UiFiles/ErrorDialogue.ui">./Insight/UserInterfaces/InsightWindow/Widgets/ErrorDialogue/UiFiles/ErrorDialogue.ui</file>
|
||||||
|
<file alias="/compiled/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/UiFiles/TargetMemoryInspectionPane.ui">./Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/UiFiles/TargetMemoryInspectionPane.ui</file>
|
||||||
|
<file alias="/compiled/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/HexViewerWidget/UiFiles/HexViewerWidget.ui">./Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/HexViewerWidget/UiFiles/HexViewerWidget.ui</file>
|
||||||
|
|
||||||
<!-- QT UI stylesheets for Insight -->
|
<!-- QT UI stylesheets for Insight -->
|
||||||
<file alias="/compiled/src/Insight/UserInterfaces/InsightWindow/Stylesheets/InsightWindow.qss">./Insight/UserInterfaces/InsightWindow/Stylesheets/InsightWindow.qss</file>
|
<file alias="/compiled/src/Insight/UserInterfaces/InsightWindow/Stylesheets/InsightWindow.qss">./Insight/UserInterfaces/InsightWindow/Stylesheets/InsightWindow.qss</file>
|
||||||
@@ -47,5 +49,7 @@
|
|||||||
<file alias="/compiled/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetRegistersPane/Images/search-registers.svg">./Insight/UserInterfaces/InsightWindow/Widgets/TargetRegistersPane/Images/search-registers.svg</file>
|
<file alias="/compiled/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetRegistersPane/Images/search-registers.svg">./Insight/UserInterfaces/InsightWindow/Widgets/TargetRegistersPane/Images/search-registers.svg</file>
|
||||||
<file alias="/compiled/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetRegisterInspector/Images/icon.svg">./Insight/UserInterfaces/InsightWindow/Widgets/TargetRegisterInspector/Images/icon.svg</file>
|
<file alias="/compiled/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetRegisterInspector/Images/icon.svg">./Insight/UserInterfaces/InsightWindow/Widgets/TargetRegisterInspector/Images/icon.svg</file>
|
||||||
<file alias="/compiled/src/Insight/UserInterfaces/InsightWindow/Widgets/ErrorDialogue/Images/icon.svg">./Insight/UserInterfaces/InsightWindow/Widgets/ErrorDialogue/Images/icon.svg</file>
|
<file alias="/compiled/src/Insight/UserInterfaces/InsightWindow/Widgets/ErrorDialogue/Images/icon.svg">./Insight/UserInterfaces/InsightWindow/Widgets/ErrorDialogue/Images/icon.svg</file>
|
||||||
|
<file alias="/compiled/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/Images/memory-inspection-icon.svg">./Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/Images/memory-inspection-icon.svg</file>
|
||||||
|
<file alias="/compiled/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/Images/memory-inspection-disabled-icon.svg">./Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/Images/memory-inspection-disabled-icon.svg</file>
|
||||||
</qresource>
|
</qresource>
|
||||||
</RCC>
|
</RCC>
|
||||||
|
|||||||
Reference in New Issue
Block a user