Register inspection window
This commit is contained in:
@@ -162,6 +162,17 @@ add_executable(Bloom
|
|||||||
src/Insight/UserInterfaces/InsightWindow/Widgets/TargetRegistersPane/ItemWidget.cpp
|
src/Insight/UserInterfaces/InsightWindow/Widgets/TargetRegistersPane/ItemWidget.cpp
|
||||||
src/Insight/UserInterfaces/InsightWindow/Widgets/TargetRegistersPane/RegisterGroupWidget.cpp
|
src/Insight/UserInterfaces/InsightWindow/Widgets/TargetRegistersPane/RegisterGroupWidget.cpp
|
||||||
src/Insight/UserInterfaces/InsightWindow/Widgets/TargetRegistersPane/RegisterWidget.cpp
|
src/Insight/UserInterfaces/InsightWindow/Widgets/TargetRegistersPane/RegisterWidget.cpp
|
||||||
|
|
||||||
|
# Target register inspector window
|
||||||
|
src/Insight/UserInterfaces/InsightWindow/Widgets/TargetRegisterInspector/TargetRegisterInspectorWindow.cpp
|
||||||
|
src/Insight/UserInterfaces/InsightWindow/Widgets/TargetRegisterInspector/RegisterHistoryWidget/RegisterHistoryWidget.cpp
|
||||||
|
src/Insight/UserInterfaces/InsightWindow/Widgets/TargetRegisterInspector/RegisterHistoryWidget/Item.cpp
|
||||||
|
src/Insight/UserInterfaces/InsightWindow/Widgets/TargetRegisterInspector/RegisterHistoryWidget/CurrentItem.cpp
|
||||||
|
src/Insight/UserInterfaces/InsightWindow/Widgets/TargetRegisterInspector/RegisterHistoryWidget/RegisterHistoryItem.cpp
|
||||||
|
src/Insight/UserInterfaces/InsightWindow/Widgets/TargetRegisterInspector/BitsetWidget/BitsetWidget.cpp
|
||||||
|
src/Insight/UserInterfaces/InsightWindow/Widgets/TargetRegisterInspector/BitsetWidget/BitWidget.cpp
|
||||||
|
src/Insight/UserInterfaces/InsightWindow/Widgets/TargetRegisterInspector/BitsetWidget/BitBodyWidget.cpp
|
||||||
|
|
||||||
)
|
)
|
||||||
|
|
||||||
set_target_properties(Bloom PROPERTIES OUTPUT_NAME bloom)
|
set_target_properties(Bloom PROPERTIES OUTPUT_NAME bloom)
|
||||||
|
|||||||
@@ -0,0 +1,78 @@
|
|||||||
|
#include "BitBodyWidget.hpp"
|
||||||
|
|
||||||
|
#include <QVBoxLayout>
|
||||||
|
#include <QScrollArea>
|
||||||
|
#include <QMargins>
|
||||||
|
|
||||||
|
using namespace Bloom::Widgets;
|
||||||
|
|
||||||
|
BitBodyWidget::BitBodyWidget(
|
||||||
|
int bitIndex,
|
||||||
|
std::bitset<std::numeric_limits<unsigned char>::digits>::reference bit,
|
||||||
|
bool readOnly,
|
||||||
|
QWidget* parent
|
||||||
|
): ClickableWidget(parent), bitIndex(bitIndex), bit(bit), readOnly(readOnly) {
|
||||||
|
this->setFixedSize(BitBodyWidget::WIDTH, BitBodyWidget::HEIGHT);
|
||||||
|
this->setContentsMargins(0, 0, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BitBodyWidget::mouseReleaseEvent(QMouseEvent* event) {
|
||||||
|
if (this->isEnabled()) {
|
||||||
|
if (!this->readOnly && event->button() == Qt::MouseButton::LeftButton) {
|
||||||
|
this->bit = !this->bit;
|
||||||
|
this->update();
|
||||||
|
}
|
||||||
|
|
||||||
|
ClickableWidget::mouseReleaseEvent(event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool BitBodyWidget::event(QEvent* event) {
|
||||||
|
if (this->isEnabled() && !this->readOnly) {
|
||||||
|
switch (event->type()) {
|
||||||
|
case QEvent::Enter: {
|
||||||
|
this->hoverActive = true;
|
||||||
|
this->update();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case QEvent::Leave: {
|
||||||
|
this->hoverActive = false;
|
||||||
|
this->update();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return QWidget::event(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BitBodyWidget::paintEvent(QPaintEvent* event) {
|
||||||
|
auto painter = QPainter(this);
|
||||||
|
this->drawWidget(painter);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BitBodyWidget::drawWidget(QPainter& painter) {
|
||||||
|
painter.setRenderHints(QPainter::RenderHint::Antialiasing | QPainter::RenderHint::SmoothPixmapTransform, true);
|
||||||
|
|
||||||
|
auto bodyColor = QColor(this->bit == true ? "#7B5F31" : "#918E86");
|
||||||
|
|
||||||
|
if (!this->isEnabled()) {
|
||||||
|
bodyColor.setAlpha(100);
|
||||||
|
|
||||||
|
} else if (!this->hoverActive) {
|
||||||
|
bodyColor.setAlpha(235);
|
||||||
|
}
|
||||||
|
|
||||||
|
painter.setPen(Qt::PenStyle::NoPen);
|
||||||
|
painter.setBrush(bodyColor);
|
||||||
|
|
||||||
|
painter.drawRect(
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
BitBodyWidget::WIDTH,
|
||||||
|
BitBodyWidget::HEIGHT
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QWidget>
|
||||||
|
#include <bitset>
|
||||||
|
#include <QLabel>
|
||||||
|
#include <QSize>
|
||||||
|
#include <QString>
|
||||||
|
#include <QEvent>
|
||||||
|
#include <QPaintEvent>
|
||||||
|
#include <QPainter>
|
||||||
|
|
||||||
|
#include "src/Insight/UserInterfaces/InsightWindow/Widgets/ClickableWidget.hpp"
|
||||||
|
|
||||||
|
namespace Bloom::Widgets
|
||||||
|
{
|
||||||
|
class BitBodyWidget: public ClickableWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
private:
|
||||||
|
int bitIndex = 0;
|
||||||
|
std::bitset<std::numeric_limits<unsigned char>::digits>::reference bit;
|
||||||
|
bool readOnly = true;
|
||||||
|
bool hoverActive = false;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool event(QEvent* event) override;
|
||||||
|
void mouseReleaseEvent(QMouseEvent* event) override;
|
||||||
|
void paintEvent(QPaintEvent* event) override;
|
||||||
|
void drawWidget(QPainter& painter);
|
||||||
|
|
||||||
|
public:
|
||||||
|
constexpr static int WIDTH = 23;
|
||||||
|
constexpr static int HEIGHT = 30;
|
||||||
|
|
||||||
|
BitBodyWidget(
|
||||||
|
int bitIndex,
|
||||||
|
std::bitset<std::numeric_limits<unsigned char>::digits>::reference bit,
|
||||||
|
bool readOnly,
|
||||||
|
QWidget* parent
|
||||||
|
);
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,56 @@
|
|||||||
|
#include "BitWidget.hpp"
|
||||||
|
|
||||||
|
#include <QVBoxLayout>
|
||||||
|
#include <QScrollArea>
|
||||||
|
#include <QMargins>
|
||||||
|
#include <set>
|
||||||
|
|
||||||
|
#include "BitBodyWidget.hpp"
|
||||||
|
|
||||||
|
using namespace Bloom::Widgets;
|
||||||
|
|
||||||
|
BitWidget::BitWidget(
|
||||||
|
int bitIndex,
|
||||||
|
int bitNumber,
|
||||||
|
std::bitset<std::numeric_limits<unsigned char>::digits>& bitset,
|
||||||
|
bool readOnly,
|
||||||
|
QWidget* parent
|
||||||
|
): QWidget(parent), bitIndex(bitIndex), bitNumber(bitNumber), bitset(bitset), readOnly(readOnly) {
|
||||||
|
this->setFixedSize(BitWidget::WIDTH, BitWidget::HEIGHT);
|
||||||
|
|
||||||
|
auto layout = new QVBoxLayout(this);
|
||||||
|
layout->setSpacing(0);
|
||||||
|
layout->setContentsMargins(0, 0, 0, 0);
|
||||||
|
layout->setAlignment(Qt::AlignmentFlag::AlignTop);
|
||||||
|
|
||||||
|
this->body = new BitBodyWidget(
|
||||||
|
this->bitIndex,
|
||||||
|
this->bitset[static_cast<size_t>(this->bitIndex)],
|
||||||
|
this->readOnly,
|
||||||
|
this
|
||||||
|
);
|
||||||
|
|
||||||
|
this->bitLabel = new QLabel("Bit", this);
|
||||||
|
this->bitNumberLabel = new QLabel(QString::number(this->bitNumber), this);
|
||||||
|
|
||||||
|
this->bitLabel->setObjectName("register-bit-label");
|
||||||
|
this->bitNumberLabel->setObjectName("register-bit-number-label");
|
||||||
|
|
||||||
|
this->bitLabel->setFixedHeight(BitWidget::LABEL_HEIGHT);
|
||||||
|
this->bitNumberLabel->setFixedHeight(BitWidget::LABEL_HEIGHT);
|
||||||
|
|
||||||
|
this->bitLabel->setAlignment(Qt::AlignmentFlag::AlignCenter);
|
||||||
|
this->bitNumberLabel->setAlignment(Qt::AlignmentFlag::AlignCenter);
|
||||||
|
|
||||||
|
layout->addWidget(this->bitLabel);
|
||||||
|
layout->addWidget(this->bitNumberLabel);
|
||||||
|
layout->addSpacing(BitWidget::VERTICAL_SPACING);
|
||||||
|
layout->addWidget(this->body);
|
||||||
|
layout->addStretch(1);
|
||||||
|
|
||||||
|
if (!this->readOnly) {
|
||||||
|
this->connect(this->body, &BitBodyWidget::clicked, this, [this] {
|
||||||
|
emit this->bitChanged();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,53 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QWidget>
|
||||||
|
#include <bitset>
|
||||||
|
#include <QLabel>
|
||||||
|
#include <QSize>
|
||||||
|
#include <QString>
|
||||||
|
#include <QEvent>
|
||||||
|
#include <QPaintEvent>
|
||||||
|
#include <QPainter>
|
||||||
|
|
||||||
|
#include "src/Insight/UserInterfaces/InsightWindow/Widgets/ClickableWidget.hpp"
|
||||||
|
|
||||||
|
#include "BitBodyWidget.hpp"
|
||||||
|
|
||||||
|
namespace Bloom::Widgets
|
||||||
|
{
|
||||||
|
class BitWidget: public QWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
private:
|
||||||
|
const static int VERTICAL_SPACING = 3;
|
||||||
|
|
||||||
|
int bitIndex = 0;
|
||||||
|
int bitNumber = 0;
|
||||||
|
std::bitset<std::numeric_limits<unsigned char>::digits>& bitset;
|
||||||
|
bool readOnly = true;
|
||||||
|
|
||||||
|
BitBodyWidget* body = nullptr;
|
||||||
|
|
||||||
|
QLabel* bitLabel = nullptr;
|
||||||
|
QLabel* bitNumberLabel = nullptr;
|
||||||
|
|
||||||
|
public:
|
||||||
|
constexpr static int LABEL_HEIGHT = 14;
|
||||||
|
constexpr static int LABEL_COUNT = 2;
|
||||||
|
constexpr static int WIDTH = BitBodyWidget::WIDTH;
|
||||||
|
constexpr static int HEIGHT = BitBodyWidget::HEIGHT + (BitWidget::LABEL_HEIGHT * BitWidget::LABEL_COUNT)
|
||||||
|
+ BitWidget::VERTICAL_SPACING;
|
||||||
|
constexpr static int SPACING = 6;
|
||||||
|
|
||||||
|
BitWidget(
|
||||||
|
int bitIndex,
|
||||||
|
int bitNumber,
|
||||||
|
std::bitset<std::numeric_limits<unsigned char>::digits>& bitset,
|
||||||
|
bool readOnly,
|
||||||
|
QWidget* parent
|
||||||
|
);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void bitChanged();
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,105 @@
|
|||||||
|
#include "BitsetWidget.hpp"
|
||||||
|
|
||||||
|
#include <QVBoxLayout>
|
||||||
|
#include <QScrollArea>
|
||||||
|
#include <QMargins>
|
||||||
|
#include <QLine>
|
||||||
|
#include <set>
|
||||||
|
|
||||||
|
#include "../TargetRegisterInspectorWindow.hpp"
|
||||||
|
|
||||||
|
using namespace Bloom::Widgets;
|
||||||
|
|
||||||
|
BitsetWidget::BitsetWidget(int byteNumber, unsigned char& byte, bool readOnly, QWidget* parent):
|
||||||
|
QWidget(parent), byteNumber(byteNumber), byte(byte), readOnly(readOnly) {
|
||||||
|
this->setObjectName("bitset-widget");
|
||||||
|
auto bitLayout = new QHBoxLayout(this);
|
||||||
|
bitLayout->setSpacing(BitWidget::SPACING);
|
||||||
|
bitLayout->setContentsMargins(0, 0, 0, 0);
|
||||||
|
this->setContentsMargins(0, 0, 0, 0);
|
||||||
|
this->setFixedSize(
|
||||||
|
static_cast<int>((BitWidget::WIDTH + BitWidget::SPACING) * this->bitset.size() - BitWidget::SPACING),
|
||||||
|
BitsetWidget::HEIGHT
|
||||||
|
);
|
||||||
|
|
||||||
|
for (int bitIndex = (std::numeric_limits<unsigned char>::digits - 1); bitIndex >= 0; bitIndex--) {
|
||||||
|
auto bitWidget = new BitWidget(
|
||||||
|
bitIndex,
|
||||||
|
(this->byteNumber * 8) + bitIndex,
|
||||||
|
this->bitset,
|
||||||
|
this->readOnly,
|
||||||
|
this
|
||||||
|
);
|
||||||
|
|
||||||
|
bitLayout->addWidget(bitWidget, 0, Qt::AlignmentFlag::AlignHCenter | Qt::AlignmentFlag::AlignTop);
|
||||||
|
this->connect(
|
||||||
|
bitWidget,
|
||||||
|
&BitWidget::bitChanged,
|
||||||
|
this,
|
||||||
|
[this] {
|
||||||
|
this->byte = static_cast<unsigned char>(this->bitset.to_ulong());
|
||||||
|
this->repaint();
|
||||||
|
emit this->byteChanged();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void BitsetWidget::paintEvent(QPaintEvent* event) {
|
||||||
|
QWidget::paintEvent(event);
|
||||||
|
auto painter = QPainter(this);
|
||||||
|
this->drawWidget(painter);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BitsetWidget::drawWidget(QPainter& painter) {
|
||||||
|
auto byteHex = "0x" + QString::number(this->byte, 16).toUpper();
|
||||||
|
|
||||||
|
painter.setPen(QColor("#474747"));
|
||||||
|
constexpr int labelHeight = 10;
|
||||||
|
int containerWidth = this->width();
|
||||||
|
constexpr int charWidth = 6;
|
||||||
|
auto labelWidth = (charWidth * byteHex.size()) + 13;
|
||||||
|
auto width = (containerWidth - (BitWidget::WIDTH) - labelWidth) / 2;
|
||||||
|
|
||||||
|
painter.drawLine(QLine(
|
||||||
|
BitWidget::WIDTH / 2,
|
||||||
|
BitWidget::HEIGHT,
|
||||||
|
BitWidget::WIDTH / 2,
|
||||||
|
BitWidget::HEIGHT + BitsetWidget::VALUE_GRAPHIC_HEIGHT
|
||||||
|
));
|
||||||
|
|
||||||
|
painter.drawLine(QLine(
|
||||||
|
containerWidth - (BitWidget::WIDTH / 2) - 1,
|
||||||
|
BitWidget::HEIGHT,
|
||||||
|
containerWidth - (BitWidget::WIDTH / 2) - 1,
|
||||||
|
BitWidget::HEIGHT + BitsetWidget::VALUE_GRAPHIC_HEIGHT
|
||||||
|
));
|
||||||
|
|
||||||
|
painter.drawLine(QLine(
|
||||||
|
BitWidget::WIDTH / 2,
|
||||||
|
BitWidget::HEIGHT + BitsetWidget::VALUE_GRAPHIC_HEIGHT,
|
||||||
|
static_cast<int>((BitWidget::WIDTH / 2) + width),
|
||||||
|
BitWidget::HEIGHT + BitsetWidget::VALUE_GRAPHIC_HEIGHT
|
||||||
|
));
|
||||||
|
|
||||||
|
painter.drawLine(QLine(
|
||||||
|
static_cast<int>((BitWidget::WIDTH / 2) + width + labelWidth),
|
||||||
|
BitWidget::HEIGHT + BitsetWidget::VALUE_GRAPHIC_HEIGHT,
|
||||||
|
containerWidth - (BitWidget::WIDTH / 2) - 1,
|
||||||
|
BitWidget::HEIGHT + BitsetWidget::VALUE_GRAPHIC_HEIGHT
|
||||||
|
));
|
||||||
|
|
||||||
|
painter.setPen(QColor("#8a8a8d"));
|
||||||
|
painter.drawText(
|
||||||
|
static_cast<int>(
|
||||||
|
std::floor((BitWidget::WIDTH / 2) + width + ((labelWidth - (byteHex.size() * charWidth)) / 2))
|
||||||
|
),
|
||||||
|
BitWidget::HEIGHT + BitsetWidget::VALUE_GRAPHIC_HEIGHT + (labelHeight / 2),
|
||||||
|
byteHex
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BitsetWidget::updateValue() {
|
||||||
|
this->bitset = {this->byte};
|
||||||
|
this->update();
|
||||||
|
}
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QWidget>
|
||||||
|
#include <bitset>
|
||||||
|
#include <QLabel>
|
||||||
|
#include <QSize>
|
||||||
|
#include <QString>
|
||||||
|
#include <QEvent>
|
||||||
|
|
||||||
|
#include "BitWidget.hpp"
|
||||||
|
|
||||||
|
namespace Bloom::Widgets
|
||||||
|
{
|
||||||
|
class BitsetWidget: public QWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
private:
|
||||||
|
int byteNumber = 0;
|
||||||
|
unsigned char& byte;
|
||||||
|
std::bitset<std::numeric_limits<unsigned char>::digits> bitset = {byte};
|
||||||
|
bool readOnly = true;
|
||||||
|
|
||||||
|
QWidget* container = nullptr;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void paintEvent(QPaintEvent* event) override;
|
||||||
|
void drawWidget(QPainter& painter);
|
||||||
|
|
||||||
|
public:
|
||||||
|
constexpr static int VALUE_GRAPHIC_HEIGHT = 20;
|
||||||
|
constexpr static int HEIGHT = BitWidget::HEIGHT + BitsetWidget::VALUE_GRAPHIC_HEIGHT + 8;
|
||||||
|
constexpr static int WIDTH = (BitWidget::WIDTH + BitWidget::SPACING) * 8;
|
||||||
|
|
||||||
|
BitsetWidget(int byteNumber, unsigned char& byte, bool readOnly, QWidget* parent);
|
||||||
|
|
||||||
|
void updateValue();
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void byteChanged();
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,105 @@
|
|||||||
|
<?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="65"
|
||||||
|
height="54"
|
||||||
|
viewBox="0 0 17.197917 14.2875"
|
||||||
|
version="1.1"
|
||||||
|
id="svg974"
|
||||||
|
sodipodi:docname="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="5.6"
|
||||||
|
inkscape:cx="13.920574"
|
||||||
|
inkscape:cy="10.048712"
|
||||||
|
inkscape:document-units="px"
|
||||||
|
inkscape:current-layer="layer1"
|
||||||
|
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"
|
||||||
|
fit-margin-top="6"
|
||||||
|
fit-margin-left="6"
|
||||||
|
fit-margin-right="6"
|
||||||
|
fit-margin-bottom="6"
|
||||||
|
lock-margins="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="Layer 1"
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
id="layer1"
|
||||||
|
transform="translate(1.3229167,1.0583334)">
|
||||||
|
<rect
|
||||||
|
style="fill:#7b5f31;fill-opacity:1;stroke-width:0.318943"
|
||||||
|
id="rect1537"
|
||||||
|
width="6.6145835"
|
||||||
|
height="3.175"
|
||||||
|
x="0.26458332"
|
||||||
|
y="0.52916664" />
|
||||||
|
<rect
|
||||||
|
style="fill:#c4c4c4;fill-opacity:0.545098;stroke-width:0.318943"
|
||||||
|
id="rect1537-5"
|
||||||
|
width="6.6145835"
|
||||||
|
height="3.175"
|
||||||
|
x="7.6729169"
|
||||||
|
y="0.52916664" />
|
||||||
|
<rect
|
||||||
|
style="fill:#c5c5c5;fill-opacity:0.54471;stroke-width:0.318942"
|
||||||
|
id="rect1537-6"
|
||||||
|
width="6.6145835"
|
||||||
|
height="3.175"
|
||||||
|
x="0.26458332"
|
||||||
|
y="4.4979167" />
|
||||||
|
<rect
|
||||||
|
style="fill:#c5c5c5;fill-opacity:0.54471;stroke-width:0.318942"
|
||||||
|
id="rect1537-5-2"
|
||||||
|
width="6.6145825"
|
||||||
|
height="3.175"
|
||||||
|
x="7.6729178"
|
||||||
|
y="4.4979167" />
|
||||||
|
<rect
|
||||||
|
style="fill:#c4c4c4;fill-opacity:0.545098;stroke-width:0.318942"
|
||||||
|
id="rect1537-6-9"
|
||||||
|
width="6.6145835"
|
||||||
|
height="3.175"
|
||||||
|
x="0.26458332"
|
||||||
|
y="8.4666672" />
|
||||||
|
<rect
|
||||||
|
style="fill:#7b5f31;fill-opacity:1;stroke-width:0.318942"
|
||||||
|
id="rect1537-5-2-1"
|
||||||
|
width="6.6145825"
|
||||||
|
height="3.175"
|
||||||
|
x="7.6729169"
|
||||||
|
y="8.4666672" />
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 2.9 KiB |
@@ -0,0 +1,17 @@
|
|||||||
|
#include "CurrentItem.hpp"
|
||||||
|
|
||||||
|
#include <QStyle>
|
||||||
|
#include <QVBoxLayout>
|
||||||
|
|
||||||
|
using namespace Bloom::Widgets;
|
||||||
|
|
||||||
|
CurrentItem::CurrentItem(
|
||||||
|
const Targets::TargetMemoryBuffer& registerValue,
|
||||||
|
QWidget* parent
|
||||||
|
): Item(registerValue, parent) {
|
||||||
|
this->setObjectName("current-item");
|
||||||
|
this->setFixedHeight(30);
|
||||||
|
this->titleLabel->setText("Current value");
|
||||||
|
this->layout->addWidget(titleLabel, 0, Qt::AlignmentFlag::AlignLeft);
|
||||||
|
this->layout->setContentsMargins(5, 0, 5, 0);
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QDateTime>
|
||||||
|
#include <QHBoxLayout>
|
||||||
|
#include <QLabel>
|
||||||
|
|
||||||
|
#include "Item.hpp"
|
||||||
|
#include "src/Insight/UserInterfaces/InsightWindow/Widgets/SvgWidget.hpp"
|
||||||
|
|
||||||
|
#include "src/Targets/TargetMemory.hpp"
|
||||||
|
|
||||||
|
namespace Bloom::Widgets
|
||||||
|
{
|
||||||
|
class CurrentItem: public Item
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
QHBoxLayout* layout = new QHBoxLayout(this);
|
||||||
|
QLabel* titleLabel = new QLabel(this);
|
||||||
|
|
||||||
|
public:
|
||||||
|
CurrentItem(
|
||||||
|
const Targets::TargetMemoryBuffer& registerValue,
|
||||||
|
QWidget *parent
|
||||||
|
);
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
#include "Item.hpp"
|
||||||
|
|
||||||
|
#include <QStyle>
|
||||||
|
|
||||||
|
using namespace Bloom::Widgets;
|
||||||
|
|
||||||
|
Item::Item(const Targets::TargetMemoryBuffer& registerValue, QWidget* parent):
|
||||||
|
ClickableWidget(parent), registerValue(registerValue) {
|
||||||
|
auto onClick = [this] {
|
||||||
|
this->setSelected(true);
|
||||||
|
};
|
||||||
|
|
||||||
|
this->connect(this, &ClickableWidget::clicked, this, onClick);
|
||||||
|
this->connect(this, &ClickableWidget::rightClicked, this, onClick);
|
||||||
|
|
||||||
|
this->setSelected(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Item::setSelected(bool selected) {
|
||||||
|
this->setProperty("selected", selected);
|
||||||
|
this->style()->unpolish(this);
|
||||||
|
this->style()->polish(this);
|
||||||
|
|
||||||
|
if (selected) {
|
||||||
|
emit this->selected(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "src/Insight/UserInterfaces/InsightWindow/Widgets/ClickableWidget.hpp"
|
||||||
|
|
||||||
|
#include "src/Targets/TargetMemory.hpp"
|
||||||
|
|
||||||
|
namespace Bloom::Widgets
|
||||||
|
{
|
||||||
|
class Item: public ClickableWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
Targets::TargetMemoryBuffer registerValue;
|
||||||
|
Item(const Targets::TargetMemoryBuffer& registerValue, QWidget *parent);
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void setSelected(bool selected);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void selected(Item*);
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
#include "RegisterHistoryItem.hpp"
|
||||||
|
|
||||||
|
#include <QStyle>
|
||||||
|
#include <QVBoxLayout>
|
||||||
|
#include <QByteArray>
|
||||||
|
|
||||||
|
using namespace Bloom::Widgets;
|
||||||
|
|
||||||
|
RegisterHistoryItem::RegisterHistoryItem(
|
||||||
|
const Targets::TargetMemoryBuffer& registerValue,
|
||||||
|
const QDateTime& changeDate,
|
||||||
|
QWidget* parent
|
||||||
|
): Item(registerValue, parent) {
|
||||||
|
this->setObjectName("register-history-item");
|
||||||
|
this->setFixedHeight(50);
|
||||||
|
this->layout->setContentsMargins(5, 8, 5, 0);
|
||||||
|
|
||||||
|
this->dateLabel->setText(changeDate.toString("dd/MM/yyyy hh:mm:ss"));
|
||||||
|
this->dateLabel->setObjectName("date-label");
|
||||||
|
|
||||||
|
this->valueLabel->setText("0x" + QString(QByteArray(
|
||||||
|
reinterpret_cast<const char*>(registerValue.data()),
|
||||||
|
static_cast<qsizetype>(registerValue.size())
|
||||||
|
).toHex()).toUpper());
|
||||||
|
this->valueLabel->setObjectName("value-label");
|
||||||
|
|
||||||
|
auto labelLayout = new QVBoxLayout();
|
||||||
|
labelLayout->setSpacing(5);
|
||||||
|
labelLayout->setContentsMargins(0, 0, 0, 0);
|
||||||
|
labelLayout->addWidget(this->dateLabel, 0, Qt::AlignmentFlag::AlignTop);
|
||||||
|
labelLayout->addWidget(this->valueLabel, 0, Qt::AlignmentFlag::AlignTop);
|
||||||
|
labelLayout->addStretch(1);
|
||||||
|
|
||||||
|
this->layout->setSpacing(1);
|
||||||
|
this->layout->addLayout(labelLayout);
|
||||||
|
|
||||||
|
auto onClick = [this] {
|
||||||
|
this->setSelected(true);
|
||||||
|
};
|
||||||
|
|
||||||
|
this->connect(this, &ClickableWidget::clicked, this, onClick);
|
||||||
|
this->connect(this, &ClickableWidget::rightClicked, this, onClick);
|
||||||
|
|
||||||
|
this->setSelected(false);
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QDateTime>
|
||||||
|
#include <QHBoxLayout>
|
||||||
|
#include <QLabel>
|
||||||
|
|
||||||
|
#include "Item.hpp"
|
||||||
|
|
||||||
|
namespace Bloom::Widgets
|
||||||
|
{
|
||||||
|
class RegisterHistoryItem: public Item
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
QHBoxLayout* layout = new QHBoxLayout(this);
|
||||||
|
QLabel* dateLabel = new QLabel(this);
|
||||||
|
QLabel* valueLabel = new QLabel(this);
|
||||||
|
|
||||||
|
public:
|
||||||
|
RegisterHistoryItem(
|
||||||
|
const Targets::TargetMemoryBuffer& registerValue,
|
||||||
|
const QDateTime& changeDate,
|
||||||
|
QWidget *parent
|
||||||
|
);
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,136 @@
|
|||||||
|
#include "RegisterHistoryWidget.hpp"
|
||||||
|
|
||||||
|
#include <QVBoxLayout>
|
||||||
|
#include <QMargins>
|
||||||
|
#include <QTableWidget>
|
||||||
|
#include <QScrollBar>
|
||||||
|
#include <set>
|
||||||
|
|
||||||
|
#include "../../../UiLoader.hpp"
|
||||||
|
|
||||||
|
#include "src/Helpers/Paths.hpp"
|
||||||
|
#include "src/Helpers/DateTime.hpp"
|
||||||
|
#include "src/Exceptions/Exception.hpp"
|
||||||
|
|
||||||
|
using namespace Bloom::Widgets;
|
||||||
|
using namespace Bloom::Exceptions;
|
||||||
|
|
||||||
|
using Bloom::Targets::TargetRegisterDescriptor;
|
||||||
|
using Bloom::Targets::TargetRegisterDescriptors;
|
||||||
|
using Bloom::Targets::TargetRegisterType;
|
||||||
|
|
||||||
|
RegisterHistoryWidget::RegisterHistoryWidget(
|
||||||
|
const Targets::TargetRegisterDescriptor& registerDescriptor,
|
||||||
|
const Targets::TargetMemoryBuffer& currentValue,
|
||||||
|
InsightWorker& insightWorker,
|
||||||
|
QWidget* parent
|
||||||
|
): QWidget(parent), registerDescriptor(registerDescriptor), insightWorker(insightWorker) {
|
||||||
|
this->setObjectName("target-register-history-widget");
|
||||||
|
this->setFixedWidth(300);
|
||||||
|
|
||||||
|
auto widgetUiFile = QFile(
|
||||||
|
QString::fromStdString(Paths::compiledResourcesPath()
|
||||||
|
+ "/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetRegisterInspector/RegisterHistoryWidget"
|
||||||
|
+ "/UiFiles/RegisterHistoryWidget.ui"
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!widgetUiFile.open(QFile::ReadOnly)) {
|
||||||
|
throw Exception("Failed to open RegisterHistoryWidget UI file");
|
||||||
|
}
|
||||||
|
|
||||||
|
auto uiLoader = UiLoader(this);
|
||||||
|
this->container = uiLoader.load(&widgetUiFile, this);
|
||||||
|
this->container->setFixedSize(this->size());
|
||||||
|
this->container->setContentsMargins(1, 1, 1, 1);
|
||||||
|
|
||||||
|
this->itemContainer = this->container->findChild<QWidget*>("item-container");
|
||||||
|
this->itemContainerLayout = this->itemContainer->findChild<QVBoxLayout*>("item-container-layout");
|
||||||
|
auto titleBar = this->container->findChild<QWidget*>("title-bar");
|
||||||
|
auto title = titleBar->findChild<QLabel*>("title");
|
||||||
|
|
||||||
|
titleBar->setContentsMargins(0, 0, 0, 0);
|
||||||
|
title->setFixedHeight(titleBar->height());
|
||||||
|
|
||||||
|
this->connect(
|
||||||
|
&insightWorker,
|
||||||
|
&InsightWorker::targetStateUpdated,
|
||||||
|
this,
|
||||||
|
&RegisterHistoryWidget::onTargetStateChanged
|
||||||
|
);
|
||||||
|
|
||||||
|
this->connect(
|
||||||
|
&insightWorker,
|
||||||
|
&InsightWorker::targetRegistersWritten,
|
||||||
|
this,
|
||||||
|
&RegisterHistoryWidget::onRegistersWritten
|
||||||
|
);
|
||||||
|
|
||||||
|
this->currentItem = new CurrentItem(currentValue, this);
|
||||||
|
this->connect(this->currentItem, &Item::selected, this, &RegisterHistoryWidget::onItemSelectionChange);
|
||||||
|
this->itemContainerLayout->addWidget(this->currentItem);
|
||||||
|
this->currentItem->setSelected(true);
|
||||||
|
|
||||||
|
auto separatorWidget = new QWidget(this);
|
||||||
|
auto separatorLayout = new QHBoxLayout(separatorWidget);
|
||||||
|
auto separatorLabel = new QLabel("Select an item to restore", separatorWidget);
|
||||||
|
separatorWidget->setFixedHeight(40);
|
||||||
|
separatorWidget->setObjectName("separator-widget");
|
||||||
|
separatorLayout->setContentsMargins(0, 10, 0, 10);
|
||||||
|
separatorLabel->setObjectName("separator-label");
|
||||||
|
separatorLayout->addWidget(separatorLabel, 0, Qt::AlignmentFlag::AlignHCenter);
|
||||||
|
this->itemContainerLayout->addWidget(separatorWidget);
|
||||||
|
|
||||||
|
this->show();
|
||||||
|
}
|
||||||
|
|
||||||
|
void RegisterHistoryWidget::updateCurrentItemValue(const Targets::TargetMemoryBuffer& registerValue) {
|
||||||
|
this->currentItem->registerValue = registerValue;
|
||||||
|
|
||||||
|
if (this->selectedItemWidget != nullptr && this->currentItem == this->selectedItemWidget) {
|
||||||
|
this->selectCurrentItem();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void RegisterHistoryWidget::selectCurrentItem() {
|
||||||
|
this->currentItem->setSelected(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RegisterHistoryWidget::addItem(const Targets::TargetMemoryBuffer& registerValue, const QDateTime& changeDate) {
|
||||||
|
auto item = new RegisterHistoryItem(registerValue, changeDate, this->itemContainer);
|
||||||
|
this->connect(item, &Item::selected, this, &RegisterHistoryWidget::onItemSelectionChange);
|
||||||
|
this->itemContainerLayout->insertWidget(2, item);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RegisterHistoryWidget::resizeEvent(QResizeEvent* event) {
|
||||||
|
this->container->setFixedSize(
|
||||||
|
this->width(),
|
||||||
|
this->height()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RegisterHistoryWidget::onTargetStateChanged(Targets::TargetState newState) {
|
||||||
|
using Targets::TargetState;
|
||||||
|
this->targetState = newState;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RegisterHistoryWidget::onItemSelectionChange(Item* newlySelectedWidget) {
|
||||||
|
if (this->selectedItemWidget != newlySelectedWidget) {
|
||||||
|
if (this->selectedItemWidget != nullptr) {
|
||||||
|
this->selectedItemWidget->setSelected(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
this->selectedItemWidget = newlySelectedWidget;
|
||||||
|
}
|
||||||
|
|
||||||
|
emit this->historyItemSelected(newlySelectedWidget->registerValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RegisterHistoryWidget::onRegistersWritten(Targets::TargetRegisters targetRegisters, const QDateTime& changeDate) {
|
||||||
|
for (const auto& targetRegister : targetRegisters) {
|
||||||
|
if (targetRegister.descriptor == this->registerDescriptor) {
|
||||||
|
this->addItem(targetRegister.value, changeDate);
|
||||||
|
this->updateCurrentItemValue(targetRegister.value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,68 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QWidget>
|
||||||
|
#include <QLabel>
|
||||||
|
#include <QVBoxLayout>
|
||||||
|
#include <set>
|
||||||
|
#include <QSize>
|
||||||
|
#include <QString>
|
||||||
|
#include <QEvent>
|
||||||
|
#include <optional>
|
||||||
|
|
||||||
|
#include "src/Targets/TargetRegister.hpp"
|
||||||
|
#include "src/Targets/TargetMemory.hpp"
|
||||||
|
#include "src/Targets/TargetState.hpp"
|
||||||
|
|
||||||
|
#include "Item.hpp"
|
||||||
|
#include "CurrentItem.hpp"
|
||||||
|
#include "RegisterHistoryItem.hpp"
|
||||||
|
|
||||||
|
#include "src/Insight/InsightWorker/InsightWorker.hpp"
|
||||||
|
|
||||||
|
namespace Bloom::Widgets
|
||||||
|
{
|
||||||
|
class RegisterHistoryWidget: public QWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
private:
|
||||||
|
Targets::TargetRegisterDescriptor registerDescriptor;
|
||||||
|
InsightWorker& insightWorker;
|
||||||
|
|
||||||
|
QWidget* container = nullptr;
|
||||||
|
QWidget* itemContainer = nullptr;
|
||||||
|
QVBoxLayout* itemContainerLayout = nullptr;
|
||||||
|
|
||||||
|
Targets::TargetState targetState = Targets::TargetState::UNKNOWN;
|
||||||
|
CurrentItem* currentItem = nullptr;
|
||||||
|
Item* selectedItemWidget = nullptr;
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void onTargetStateChanged(Targets::TargetState newState);
|
||||||
|
void onItemSelectionChange(Item* newlySelectedWidget);
|
||||||
|
void onRegistersWritten(Targets::TargetRegisters targetRegisters, const QDateTime& changeDate);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void resizeEvent(QResizeEvent* event) override;
|
||||||
|
|
||||||
|
public:
|
||||||
|
RegisterHistoryWidget(
|
||||||
|
const Targets::TargetRegisterDescriptor& registerDescriptor,
|
||||||
|
const Targets::TargetMemoryBuffer& currentValue,
|
||||||
|
InsightWorker& insightWorker,
|
||||||
|
QWidget* parent
|
||||||
|
);
|
||||||
|
|
||||||
|
void updateCurrentItemValue(const Targets::TargetMemoryBuffer& registerValue);
|
||||||
|
void selectCurrentItem();
|
||||||
|
|
||||||
|
bool isCurrentItemSelected() {
|
||||||
|
return this->selectedItemWidget != nullptr && this->selectedItemWidget == this->currentItem;
|
||||||
|
}
|
||||||
|
|
||||||
|
void addItem(const Targets::TargetMemoryBuffer& registerValue, const QDateTime& changeDate);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void historyItemSelected(const Targets::TargetMemoryBuffer& registerValue);
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
<?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::AlignCenter">
|
||||||
|
<widget class="QWidget" name="title-bar">
|
||||||
|
<property name="minimumHeight">
|
||||||
|
<number>30</number>
|
||||||
|
</property>
|
||||||
|
<widget class="QLabel" name="title">
|
||||||
|
<property name="text"><string>Register History</string></property>
|
||||||
|
</widget>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item alignment="Qt::AlignTop">
|
||||||
|
<widget class="ExpandingHeightScrollAreaWidget" name="item-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"><enum>QSizePolicy::SetMinAndMaxSize</enum></property>
|
||||||
|
|
||||||
|
<widget class="QWidget" name="item-container">
|
||||||
|
<layout class="QVBoxLayout" name="item-container-layout">
|
||||||
|
<property name="spacing">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="margin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="sizeConstraint">
|
||||||
|
<enum>QLayout::SetMinAndMaxSize</enum>
|
||||||
|
</property>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</ui>
|
||||||
@@ -0,0 +1,138 @@
|
|||||||
|
* {
|
||||||
|
color: #afb1b3;
|
||||||
|
font-family: 'Ubuntu', sans-serif;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#target-register-inspector-window {
|
||||||
|
background-color: #343532;
|
||||||
|
}
|
||||||
|
|
||||||
|
#register-name {
|
||||||
|
font-size: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#register-value-container,
|
||||||
|
#register-details-container {
|
||||||
|
border: 1px solid #2b2b2b;
|
||||||
|
}
|
||||||
|
|
||||||
|
#register-value-text-input-container {
|
||||||
|
border-top: 1px solid #41423f;
|
||||||
|
}
|
||||||
|
|
||||||
|
QLineEdit {
|
||||||
|
background-color: #2B2B29;
|
||||||
|
border: 1px solid #41423f;
|
||||||
|
padding: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
QLineEdit:disabled {
|
||||||
|
font-style: italic;
|
||||||
|
color: #7d7d7d;
|
||||||
|
}
|
||||||
|
|
||||||
|
QPushButton {
|
||||||
|
background-color: #373937;
|
||||||
|
border: 1px solid #41423f;
|
||||||
|
padding: 3px 25px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#apply-btn {
|
||||||
|
background-color: #353C41;
|
||||||
|
border: 1px solid #3e474c;
|
||||||
|
}
|
||||||
|
|
||||||
|
QPushButton:disabled {
|
||||||
|
background-color: #303230;
|
||||||
|
color: #8d8d90;
|
||||||
|
}
|
||||||
|
|
||||||
|
#register-bit-number-label {
|
||||||
|
font-size: 12px;
|
||||||
|
color: #a6a7aa;
|
||||||
|
}
|
||||||
|
|
||||||
|
#register-bit-label {
|
||||||
|
font-size: 11px;
|
||||||
|
color: #8a8a8d;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* BitsetWidget */
|
||||||
|
#bitset-widget {
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* RegisterHistoryWidget */
|
||||||
|
#target-register-history-widget #container {
|
||||||
|
border: 1px solid #2b2b2b;
|
||||||
|
}
|
||||||
|
|
||||||
|
#target-register-history-widget #title-bar {
|
||||||
|
background-color: #353C41;
|
||||||
|
border-bottom: 1px solid #2b2b2b;
|
||||||
|
}
|
||||||
|
|
||||||
|
#target-register-history-widget #title {
|
||||||
|
color: #afb1b3;
|
||||||
|
padding-top: 0;
|
||||||
|
padding-bottom: 0;
|
||||||
|
padding-left: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#target-register-history-widget QScrollArea,
|
||||||
|
#target-register-history-widget #item-container {
|
||||||
|
background-color: transparent;
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
#target-register-history-widget #current-item[selected=true],
|
||||||
|
#target-register-history-widget #register-history-item[selected=true] {
|
||||||
|
background-color: #335883;
|
||||||
|
}
|
||||||
|
|
||||||
|
#target-register-history-widget #separator-widget {
|
||||||
|
border-top: 1px solid #2e2e2e;
|
||||||
|
border-bottom: 1px solid #2e2e2e;
|
||||||
|
}
|
||||||
|
|
||||||
|
#target-register-history-widget #register-history-item {
|
||||||
|
border-bottom: 1px solid #2e2e2e;
|
||||||
|
background-color: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
#target-register-history-widget #register-history-item #date-label {
|
||||||
|
font-size: 14px
|
||||||
|
}
|
||||||
|
|
||||||
|
#target-register-history-widget #register-history-item #value-label {
|
||||||
|
font-size: 13px;
|
||||||
|
font-style: italic;
|
||||||
|
color: #8a8a8d;
|
||||||
|
}
|
||||||
|
|
||||||
|
#target-register-history-widget #separator-label {
|
||||||
|
/*font-style: italic;*/
|
||||||
|
color: #8a8a8d;
|
||||||
|
}
|
||||||
|
|
||||||
|
QScrollBar:vertical {
|
||||||
|
background-color: transparent;
|
||||||
|
width: 15px;
|
||||||
|
margin: 1px 1px 1px 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
QScrollBar:handle:vertical {
|
||||||
|
border: none;
|
||||||
|
background-color: rgba(69, 69, 66, 0.6);
|
||||||
|
}
|
||||||
|
|
||||||
|
QScrollBar:handle:vertical:hover {
|
||||||
|
background-color: rgba(69, 69, 66, 0.91);
|
||||||
|
}
|
||||||
|
|
||||||
|
QScrollBar::add-line:vertical,
|
||||||
|
QScrollBar::sub-line:vertical {
|
||||||
|
border: none;
|
||||||
|
background: none;
|
||||||
|
}
|
||||||
@@ -0,0 +1,325 @@
|
|||||||
|
#include "TargetRegisterInspectorWindow.hpp"
|
||||||
|
|
||||||
|
#include <QVBoxLayout>
|
||||||
|
#include <QMargins>
|
||||||
|
#include <QTableWidget>
|
||||||
|
#include <QScrollBar>
|
||||||
|
#include <set>
|
||||||
|
|
||||||
|
#include "../../UiLoader.hpp"
|
||||||
|
|
||||||
|
#include "src/Helpers/Paths.hpp"
|
||||||
|
#include "src/Helpers/DateTime.hpp"
|
||||||
|
#include "src/Exceptions/Exception.hpp"
|
||||||
|
|
||||||
|
#include "src/Insight/InsightWorker/Tasks/ReadTargetRegisters.hpp"
|
||||||
|
#include "src/Insight/InsightWorker/Tasks/WriteTargetRegister.hpp"
|
||||||
|
|
||||||
|
using namespace Bloom::Widgets;
|
||||||
|
using namespace Bloom::Exceptions;
|
||||||
|
|
||||||
|
using Bloom::Targets::TargetRegisterDescriptor;
|
||||||
|
using Bloom::Targets::TargetRegisterDescriptors;
|
||||||
|
using Bloom::Targets::TargetRegisterType;
|
||||||
|
|
||||||
|
TargetRegisterInspectorWindow::TargetRegisterInspectorWindow(
|
||||||
|
const Targets::TargetRegisterDescriptor& registerDescriptor,
|
||||||
|
InsightWorker& insightWorker,
|
||||||
|
std::optional<Targets::TargetMemoryBuffer> registerValue
|
||||||
|
):
|
||||||
|
registerDescriptor(registerDescriptor),
|
||||||
|
insightWorker(insightWorker),
|
||||||
|
registerValue(registerValue.value_or(Targets::TargetMemoryBuffer(registerDescriptor.size, 0))) {
|
||||||
|
auto registerName = QString::fromStdString(this->registerDescriptor.name.value()).toUpper();
|
||||||
|
this->setObjectName("target-register-inspector-window");
|
||||||
|
this->setWindowTitle("Inspect Register");
|
||||||
|
|
||||||
|
auto windowUiFile = QFile(
|
||||||
|
QString::fromStdString(Paths::compiledResourcesPath()
|
||||||
|
+ "/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetRegisterInspector/UiFiles/TargetRegisterInspectorWindow.ui"
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
auto windowStylesheet = QFile(QString::fromStdString(
|
||||||
|
Paths::compiledResourcesPath()
|
||||||
|
+ "/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetRegisterInspector/Stylesheets/TargetRegisterInspectorWindow.qss"
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!windowUiFile.open(QFile::ReadOnly)) {
|
||||||
|
throw Exception("Failed to open TargetRegisterInspectorWindow UI file");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!windowStylesheet.open(QFile::ReadOnly)) {
|
||||||
|
throw Exception("Failed to open TargetRegisterInspectorWindow stylesheet file");
|
||||||
|
}
|
||||||
|
|
||||||
|
auto windowSize = QSize(
|
||||||
|
840,
|
||||||
|
static_cast<int>(440 + ((BitsetWidget::HEIGHT + 20)
|
||||||
|
* std::ceil(static_cast<float>(this->registerValue.size()) / 2)))
|
||||||
|
);
|
||||||
|
auto containerMargins = QMargins(15, 30, 15, 10);
|
||||||
|
|
||||||
|
this->setStyleSheet(windowStylesheet.readAll());
|
||||||
|
this->setFixedSize(windowSize);
|
||||||
|
|
||||||
|
auto uiLoader = UiLoader(this);
|
||||||
|
this->container = uiLoader.load(&windowUiFile, this);
|
||||||
|
|
||||||
|
this->container->setFixedSize(this->size());
|
||||||
|
this->container->setContentsMargins(containerMargins);
|
||||||
|
|
||||||
|
this->registerNameLabel = this->container->findChild<QLabel*>("register-name");
|
||||||
|
this->registerDescriptionLabel = this->container->findChild<QLabel*>("register-description");
|
||||||
|
this->contentContainer = this->container->findChild<QWidget*>("content-container");
|
||||||
|
this->registerValueContainer = this->container->findChild<QWidget*>("register-value-container");
|
||||||
|
this->registerValueTextInput = this->container->findChild<QLineEdit*>("register-value-text-input");
|
||||||
|
this->registerValueBitsetWidgetContainer = this->container->findChild<QWidget*>("register-value-bitset-widget-container");
|
||||||
|
this->closeButton = this->container->findChild<QPushButton*>("close-btn");
|
||||||
|
this->refreshValueButton = this->container->findChild<QPushButton*>("refresh-value-btn");
|
||||||
|
this->applyButton = this->container->findChild<QPushButton*>("apply-btn");
|
||||||
|
|
||||||
|
this->registerNameLabel->setText(registerName);
|
||||||
|
|
||||||
|
if (this->registerDescriptor.description.has_value()) {
|
||||||
|
this->registerDescriptionLabel->setText(QString::fromStdString(this->registerDescriptor.description.value()));
|
||||||
|
this->registerDescriptionLabel->setVisible(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
this->registerHistoryWidget = new RegisterHistoryWidget(
|
||||||
|
this->registerDescriptor,
|
||||||
|
this->registerValue,
|
||||||
|
insightWorker,
|
||||||
|
this->contentContainer
|
||||||
|
);
|
||||||
|
|
||||||
|
auto contentLayout = this->container->findChild<QHBoxLayout*>("content-layout");
|
||||||
|
contentLayout->insertWidget(0, this->registerHistoryWidget, 0, Qt::AlignmentFlag::AlignTop);
|
||||||
|
|
||||||
|
auto registerDetailsContainer = this->container->findChild<QWidget*>("register-details-container");
|
||||||
|
auto registerValueContainer = this->container->findChild<QWidget*>("register-value-container");
|
||||||
|
registerValueContainer->setContentsMargins(15, 15, 15, 15);
|
||||||
|
registerDetailsContainer->setContentsMargins(15, 15, 15, 15);
|
||||||
|
|
||||||
|
auto registerDetailsNameInput = registerDetailsContainer->findChild<QLineEdit*>("register-details-name-input");
|
||||||
|
auto registerDetailsSizeInput = registerDetailsContainer->findChild<QLineEdit*>("register-details-size-input");
|
||||||
|
auto registerDetailsStartAddressInput = registerDetailsContainer->findChild<QLineEdit*>(
|
||||||
|
"register-details-start-address-input"
|
||||||
|
);
|
||||||
|
registerDetailsNameInput->setText(registerName);
|
||||||
|
registerDetailsSizeInput->setText(QString::number(this->registerDescriptor.size));
|
||||||
|
registerDetailsStartAddressInput->setText(
|
||||||
|
"0x" + QString::number(this->registerDescriptor.startAddress.value(), 16).toUpper()
|
||||||
|
);
|
||||||
|
|
||||||
|
this->registerValueTextInput->setFixedWidth(BitsetWidget::WIDTH * 2);
|
||||||
|
|
||||||
|
auto registerBitsetWidgetLayout = this->registerValueBitsetWidgetContainer->findChild<QVBoxLayout*>(
|
||||||
|
"register-value-bitset-widget-layout"
|
||||||
|
);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Each row of the BitsetWidget container should hold two BitsetWidgets. So we have a horizontal layout nested
|
||||||
|
* within a vertical layout.
|
||||||
|
*/
|
||||||
|
auto bitsetSingleHorizontalLayout = new QHBoxLayout();
|
||||||
|
bitsetSingleHorizontalLayout->setSpacing(BitWidget::SPACING);
|
||||||
|
bitsetSingleHorizontalLayout->setContentsMargins(0, 0, 0, 0);
|
||||||
|
|
||||||
|
// The register value will be in MSB, which is OK for us as we present the bit widgets in MSB.
|
||||||
|
auto byteNumber = static_cast<int>(this->registerValue.size() - 1);
|
||||||
|
for (std::uint32_t registerByteIndex = 0; registerByteIndex < this->registerValue.size(); registerByteIndex++) {
|
||||||
|
auto bitsetWidget = new BitsetWidget(
|
||||||
|
byteNumber,
|
||||||
|
this->registerValue.at(registerByteIndex),
|
||||||
|
!this->registerDescriptor.writable,
|
||||||
|
this
|
||||||
|
);
|
||||||
|
|
||||||
|
bitsetSingleHorizontalLayout->addWidget(bitsetWidget, 0, Qt::AlignmentFlag::AlignLeft);
|
||||||
|
this->connect(
|
||||||
|
bitsetWidget,
|
||||||
|
&BitsetWidget::byteChanged,
|
||||||
|
this,
|
||||||
|
&TargetRegisterInspectorWindow::updateRegisterValueInputField
|
||||||
|
);
|
||||||
|
this->bitsetWidgets.push_back(bitsetWidget);
|
||||||
|
|
||||||
|
if (((registerByteIndex + 1) % 2) == 0) {
|
||||||
|
registerBitsetWidgetLayout->addLayout(bitsetSingleHorizontalLayout);
|
||||||
|
bitsetSingleHorizontalLayout = new QHBoxLayout();
|
||||||
|
bitsetSingleHorizontalLayout->setSpacing(BitWidget::SPACING);
|
||||||
|
bitsetSingleHorizontalLayout->setContentsMargins(0, 0, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
byteNumber--;
|
||||||
|
}
|
||||||
|
|
||||||
|
registerBitsetWidgetLayout->addLayout(bitsetSingleHorizontalLayout);
|
||||||
|
registerBitsetWidgetLayout->addStretch(1);
|
||||||
|
|
||||||
|
this->registerHistoryWidget->setFixedHeight(this->contentContainer->sizeHint().height());
|
||||||
|
|
||||||
|
this->connect(this->closeButton, &QPushButton::clicked, this, &QWidget::close);
|
||||||
|
this->connect(
|
||||||
|
this->refreshValueButton,
|
||||||
|
&QPushButton::clicked,
|
||||||
|
this,
|
||||||
|
&TargetRegisterInspectorWindow::refreshRegisterValue
|
||||||
|
);
|
||||||
|
this->connect(this->applyButton, &QPushButton::clicked, this, &TargetRegisterInspectorWindow::applyChanges);
|
||||||
|
|
||||||
|
this->connect(
|
||||||
|
this->registerHistoryWidget,
|
||||||
|
&RegisterHistoryWidget::historyItemSelected,
|
||||||
|
this,
|
||||||
|
&TargetRegisterInspectorWindow::onHistoryItemSelected
|
||||||
|
);
|
||||||
|
|
||||||
|
this->connect(
|
||||||
|
this->registerValueTextInput,
|
||||||
|
&QLineEdit::textEdited,
|
||||||
|
this,
|
||||||
|
&TargetRegisterInspectorWindow::onValueTextInputChanged
|
||||||
|
);
|
||||||
|
|
||||||
|
this->connect(
|
||||||
|
&insightWorker,
|
||||||
|
&InsightWorker::targetStateUpdated,
|
||||||
|
this,
|
||||||
|
&TargetRegisterInspectorWindow::onTargetStateChanged
|
||||||
|
);
|
||||||
|
|
||||||
|
this->updateRegisterValueInputField();
|
||||||
|
this->show();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TargetRegisterInspectorWindow::registerSupported(const Targets::TargetRegisterDescriptor& descriptor) {
|
||||||
|
return (descriptor.size > 0 && descriptor.size <= 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TargetRegisterInspectorWindow::onValueTextInputChanged(QString text) {
|
||||||
|
if (text.isEmpty()) {
|
||||||
|
text = "0";
|
||||||
|
}
|
||||||
|
|
||||||
|
bool validHexValue = false;
|
||||||
|
text.toLongLong(&validHexValue, 16);
|
||||||
|
if (!validHexValue) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto registerSize = this->registerDescriptor.size;
|
||||||
|
auto newValue = QByteArray::fromHex(
|
||||||
|
text.remove("0x", Qt::CaseInsensitive).toLatin1()
|
||||||
|
).rightJustified(registerSize, 0).right(registerSize);
|
||||||
|
|
||||||
|
assert(newValue.size() >= registerSize);
|
||||||
|
assert(registerValue.size() == registerSize);
|
||||||
|
for (std::uint32_t byteIndex = 0; byteIndex < registerSize; byteIndex++) {
|
||||||
|
this->registerValue.at(byteIndex) = static_cast<unsigned char>(newValue.at(byteIndex));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto& bitsetWidget : this->bitsetWidgets) {
|
||||||
|
bitsetWidget->updateValue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void TargetRegisterInspectorWindow::onTargetStateChanged(Targets::TargetState newState) {
|
||||||
|
using Targets::TargetState;
|
||||||
|
this->targetState = newState;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TargetRegisterInspectorWindow::onHistoryItemSelected(const Targets::TargetMemoryBuffer& selectedRegisterValue) {
|
||||||
|
this->registerValue = selectedRegisterValue;
|
||||||
|
this->updateValue();
|
||||||
|
|
||||||
|
if (this->registerHistoryWidget->isCurrentItemSelected()) {
|
||||||
|
this->refreshValueButton->setVisible(true);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
this->refreshValueButton->setVisible(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void TargetRegisterInspectorWindow::updateRegisterValueInputField() {
|
||||||
|
auto value = QByteArray(
|
||||||
|
reinterpret_cast<const char*>(this->registerValue.data()),
|
||||||
|
static_cast<qsizetype>(this->registerValue.size())
|
||||||
|
);
|
||||||
|
|
||||||
|
this->registerValueTextInput->setText("0x" + QString(value.toHex()).toUpper());
|
||||||
|
}
|
||||||
|
|
||||||
|
void TargetRegisterInspectorWindow::updateRegisterValueBitsetWidgets() {
|
||||||
|
for (auto& bitsetWidget : this->bitsetWidgets) {
|
||||||
|
bitsetWidget->updateValue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void TargetRegisterInspectorWindow::updateValue() {
|
||||||
|
this->updateRegisterValueInputField();
|
||||||
|
this->updateRegisterValueBitsetWidgets();
|
||||||
|
}
|
||||||
|
|
||||||
|
void TargetRegisterInspectorWindow::refreshRegisterValue() {
|
||||||
|
this->registerValueContainer->setDisabled(true);
|
||||||
|
auto readTargetRegisterTask = new ReadTargetRegisters({this->registerDescriptor});
|
||||||
|
|
||||||
|
this->connect(
|
||||||
|
readTargetRegisterTask,
|
||||||
|
&ReadTargetRegisters::targetRegistersRead,
|
||||||
|
this,
|
||||||
|
[this] (Targets::TargetRegisters targetRegisters) {
|
||||||
|
this->registerValueContainer->setDisabled(false);
|
||||||
|
|
||||||
|
for (const auto& targetRegister : targetRegisters) {
|
||||||
|
if (targetRegister.descriptor == this->registerDescriptor) {
|
||||||
|
this->registerValue = targetRegister.value;
|
||||||
|
this->registerHistoryWidget->updateCurrentItemValue(this->registerValue);
|
||||||
|
this->registerHistoryWidget->selectCurrentItem();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
this->connect(
|
||||||
|
readTargetRegisterTask,
|
||||||
|
&InsightWorkerTask::failed,
|
||||||
|
this,
|
||||||
|
[this] () {
|
||||||
|
this->registerValueContainer->setDisabled(false);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
this->insightWorker.queueTask(readTargetRegisterTask);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TargetRegisterInspectorWindow::applyChanges() {
|
||||||
|
this->applyButton->setDisabled(true);
|
||||||
|
this->registerValueBitsetWidgetContainer->setDisabled(true);
|
||||||
|
const auto targetRegister = Targets::TargetRegister(this->registerDescriptor, this->registerValue);
|
||||||
|
auto writeRegisterTask = new WriteTargetRegister(
|
||||||
|
targetRegister
|
||||||
|
);
|
||||||
|
|
||||||
|
this->connect(writeRegisterTask, &InsightWorkerTask::completed, this, [this, targetRegister] {
|
||||||
|
this->registerValueBitsetWidgetContainer->setDisabled(false);
|
||||||
|
this->applyButton->setDisabled(false);
|
||||||
|
emit this->insightWorker.targetRegistersWritten(
|
||||||
|
{targetRegister},
|
||||||
|
DateTime::currentDateTime()
|
||||||
|
);
|
||||||
|
this->registerHistoryWidget->updateCurrentItemValue(targetRegister.value);
|
||||||
|
this->registerHistoryWidget->selectCurrentItem();
|
||||||
|
});
|
||||||
|
|
||||||
|
this->connect(writeRegisterTask, &InsightWorkerTask::failed, this, [this] {
|
||||||
|
// TODO: Let the user know the write failed.
|
||||||
|
this->registerValueBitsetWidgetContainer->setDisabled(false);
|
||||||
|
this->applyButton->setDisabled(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
this->insightWorker.queueTask(writeRegisterTask);
|
||||||
|
}
|
||||||
@@ -0,0 +1,68 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QWidget>
|
||||||
|
#include <QLabel>
|
||||||
|
#include <QLineEdit>
|
||||||
|
#include <QPushButton>
|
||||||
|
#include <set>
|
||||||
|
#include <QSize>
|
||||||
|
#include <QString>
|
||||||
|
#include <QEvent>
|
||||||
|
#include <optional>
|
||||||
|
|
||||||
|
#include "src/Targets/TargetRegister.hpp"
|
||||||
|
#include "src/Targets/TargetState.hpp"
|
||||||
|
|
||||||
|
#include "BitsetWidget/BitsetWidget.hpp"
|
||||||
|
#include "RegisterHistoryWidget/RegisterHistoryWidget.hpp"
|
||||||
|
|
||||||
|
#include "src/Insight/InsightWorker/InsightWorker.hpp"
|
||||||
|
|
||||||
|
namespace Bloom::Widgets
|
||||||
|
{
|
||||||
|
class TargetRegisterInspectorWindow: public QWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
private:
|
||||||
|
Targets::TargetRegisterDescriptor registerDescriptor;
|
||||||
|
Targets::TargetMemoryBuffer registerValue;
|
||||||
|
InsightWorker& insightWorker;
|
||||||
|
|
||||||
|
QWidget* container = nullptr;
|
||||||
|
QLabel* registerNameLabel = nullptr;
|
||||||
|
QLabel* registerDescriptionLabel = nullptr;
|
||||||
|
|
||||||
|
QWidget* contentContainer = nullptr;
|
||||||
|
RegisterHistoryWidget* registerHistoryWidget = nullptr;
|
||||||
|
|
||||||
|
QWidget* registerValueContainer = nullptr;
|
||||||
|
QLineEdit* registerValueTextInput = nullptr;
|
||||||
|
QWidget* registerValueBitsetWidgetContainer = nullptr;
|
||||||
|
std::vector<BitsetWidget*> bitsetWidgets;
|
||||||
|
|
||||||
|
QPushButton* closeButton = nullptr;
|
||||||
|
QPushButton* refreshValueButton = nullptr;
|
||||||
|
QPushButton* applyButton = nullptr;
|
||||||
|
|
||||||
|
Targets::TargetState targetState = Targets::TargetState::UNKNOWN;
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void onValueTextInputChanged(QString text);
|
||||||
|
void onTargetStateChanged(Targets::TargetState newState);
|
||||||
|
void onHistoryItemSelected(const Targets::TargetMemoryBuffer& selectedRegisterValue);
|
||||||
|
void updateRegisterValueInputField();
|
||||||
|
void updateRegisterValueBitsetWidgets();
|
||||||
|
void updateValue();
|
||||||
|
void refreshRegisterValue();
|
||||||
|
void applyChanges();
|
||||||
|
|
||||||
|
public:
|
||||||
|
TargetRegisterInspectorWindow(
|
||||||
|
const Targets::TargetRegisterDescriptor& registerDescriptor,
|
||||||
|
InsightWorker& insightWorker,
|
||||||
|
std::optional<Targets::TargetMemoryBuffer> registerValue = std::nullopt
|
||||||
|
);
|
||||||
|
|
||||||
|
static bool registerSupported(const Targets::TargetRegisterDescriptor& descriptor);
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,228 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<widget class="QWidget" name="container">
|
||||||
|
<layout class="QVBoxLayout">
|
||||||
|
<item alignment="Qt::AlignHCenter">
|
||||||
|
<widget class="SvgWidget" name="icon">
|
||||||
|
<property name="svgFilePath">
|
||||||
|
<string>:/compiled/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetRegisterInspector/Images/icon.svg</string>
|
||||||
|
</property>
|
||||||
|
<property name="containerHeight">
|
||||||
|
<number>46</number>
|
||||||
|
</property>
|
||||||
|
<property name="containerWidth">
|
||||||
|
<number>57</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item alignment="Qt::AlignHCenter">
|
||||||
|
<widget class="QLabel" name="register-name"/>
|
||||||
|
</item>
|
||||||
|
<item alignment="Qt::AlignHCenter">
|
||||||
|
<widget class="QLabel" name="register-description">
|
||||||
|
<property name="visible">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="vertical-spacer">
|
||||||
|
<property name="sizeHint">
|
||||||
|
<size>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
<item alignment="Qt::AlignLeft">
|
||||||
|
<layout class="QHBoxLayout" name="content-layout">
|
||||||
|
<property name="spacing">
|
||||||
|
<number>20</number>
|
||||||
|
</property>
|
||||||
|
|
||||||
|
<item alignment="Qt::AlignLeft">
|
||||||
|
<widget class="QWidget" name="content-container">
|
||||||
|
<layout class="QVBoxLayout" name="content-layout">
|
||||||
|
<property name="spacing">
|
||||||
|
<number>20</number>
|
||||||
|
</property>
|
||||||
|
|
||||||
|
<item alignment="Qt::AlignTop">
|
||||||
|
<widget class="QWidget" name="register-details-container">
|
||||||
|
<layout class="QVBoxLayout">
|
||||||
|
<property name="spacing">
|
||||||
|
<number>10</number>
|
||||||
|
</property>
|
||||||
|
|
||||||
|
<item alignment="Qt::AlignLeft">
|
||||||
|
<layout class="QHBoxLayout" name="register-details-row">
|
||||||
|
<property name="spacing">
|
||||||
|
<number>20</number>
|
||||||
|
</property>
|
||||||
|
<item alignment="Qt::AlignLeft">
|
||||||
|
<widget class="QLabel" name="register-details-name-label">
|
||||||
|
<property name="text">
|
||||||
|
<string>Name:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item alignment="Qt::AlignLeft">
|
||||||
|
<widget class="QLineEdit" name="register-details-name-input">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<property name="minimumWidth">
|
||||||
|
<number>350</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item alignment="Qt::AlignLeft">
|
||||||
|
<layout class="QHBoxLayout" name="register-details-row">
|
||||||
|
<property name="spacing">
|
||||||
|
<number>20</number>
|
||||||
|
</property>
|
||||||
|
<item alignment="Qt::AlignLeft">
|
||||||
|
<widget class="QLabel" name="register-details-size-label">
|
||||||
|
<property name="text">
|
||||||
|
<string>Size (bytes):</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item alignment="Qt::AlignLeft">
|
||||||
|
<widget class="QLineEdit" name="register-details-size-input">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<property name="minimumWidth">
|
||||||
|
<number>350</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item alignment="Qt::AlignLeft">
|
||||||
|
<layout class="QHBoxLayout" name="register-details-row">
|
||||||
|
<property name="spacing">
|
||||||
|
<number>20</number>
|
||||||
|
</property>
|
||||||
|
<item alignment="Qt::AlignLeft">
|
||||||
|
<widget class="QLabel" name="register-details-start-address-label">
|
||||||
|
<property name="text">
|
||||||
|
<string>Start Address:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item alignment="Qt::AlignLeft">
|
||||||
|
<widget class="QLineEdit" name="register-details-start-address-input">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<property name="minimumWidth">
|
||||||
|
<number>350</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
|
||||||
|
<item alignment="Qt::AlignTop">
|
||||||
|
<widget class="QWidget" name="register-value-container">
|
||||||
|
<layout class="QVBoxLayout">
|
||||||
|
<property name="spacing">
|
||||||
|
<number>20</number>
|
||||||
|
</property>
|
||||||
|
|
||||||
|
<item alignment="Qt::AlignLeft">
|
||||||
|
<widget class="QLineEdit" name="register-value-text-input"/>
|
||||||
|
</item>
|
||||||
|
<item alignment="Qt::AlignLeft">
|
||||||
|
<widget class="QWidget" name="register-value-bitset-widget-container">
|
||||||
|
<property name="minimumHeight">
|
||||||
|
<number>60</number>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="register-value-bitset-widget-layout">
|
||||||
|
<property name="spacing">
|
||||||
|
<number>15</number>
|
||||||
|
</property>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item alignment="Qt::AlignLeft">
|
||||||
|
<layout class="QHBoxLayout">
|
||||||
|
<property name="spacing">
|
||||||
|
<number>15</number>
|
||||||
|
</property>
|
||||||
|
<item alignment="Qt::AlignCenter">
|
||||||
|
<widget class="QPushButton" name="refresh-value-btn">
|
||||||
|
<property name="text">
|
||||||
|
<string>Refresh Value</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item alignment="Qt::AlignCenter">
|
||||||
|
<spacer name="horizontal-spacer">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
<item alignment="Qt::AlignCenter">
|
||||||
|
<widget class="QPushButton" name="apply-btn">
|
||||||
|
<property name="text">
|
||||||
|
<string>Apply</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item alignment="Qt::AlignHCenter">
|
||||||
|
<spacer name="vertical-spacer">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Vertical</enum>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item alignment="Qt::AlignHCenter">
|
||||||
|
<spacer name="vertical-spacer">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Vertical</enum>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout">
|
||||||
|
<property name="spacing">
|
||||||
|
<number>15</number>
|
||||||
|
</property>
|
||||||
|
<item alignment="Qt::AlignLeft">
|
||||||
|
<spacer name="horizontal-spacer">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
<item alignment="Qt::AlignRight">
|
||||||
|
<widget class="QPushButton" name="close-btn">
|
||||||
|
<property name="text">
|
||||||
|
<string>Close</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</ui>
|
||||||
@@ -3,11 +3,9 @@
|
|||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#include <QClipboard>
|
#include <QClipboard>
|
||||||
#include <QMenu>
|
#include <QMenu>
|
||||||
#include <utility>
|
|
||||||
#include <QStyle>
|
#include <QStyle>
|
||||||
|
|
||||||
#include "src/Helpers/Paths.hpp"
|
#include "src/Helpers/Paths.hpp"
|
||||||
#include "src/Exceptions/Exception.hpp"
|
|
||||||
|
|
||||||
#include "src/Insight/InsightWorker/Tasks/ReadTargetRegisters.hpp"
|
#include "src/Insight/InsightWorker/Tasks/ReadTargetRegisters.hpp"
|
||||||
|
|
||||||
@@ -45,6 +43,8 @@ RegisterWidget::RegisterWidget(
|
|||||||
this->layout->addWidget(this->valueLabel);
|
this->layout->addWidget(this->valueLabel);
|
||||||
this->layout->addStretch(1);
|
this->layout->addStretch(1);
|
||||||
|
|
||||||
|
this->connect(this, &ClickableWidget::doubleClicked, this, &RegisterWidget::openInspectionWindow);
|
||||||
|
this->connect(this->openInspectionWindowAction, &QAction::triggered, this, &RegisterWidget::openInspectionWindow);
|
||||||
this->connect(this->refreshValueAction, &QAction::triggered, this, &RegisterWidget::refreshValue);
|
this->connect(this->refreshValueAction, &QAction::triggered, this, &RegisterWidget::refreshValue);
|
||||||
this->connect(this->copyValueNameAction, &QAction::triggered, this, &RegisterWidget::copyName);
|
this->connect(this->copyValueNameAction, &QAction::triggered, this, &RegisterWidget::copyName);
|
||||||
this->connect(this->copyValueHexAction, &QAction::triggered, this, &RegisterWidget::copyValueHex);
|
this->connect(this->copyValueHexAction, &QAction::triggered, this, &RegisterWidget::copyValueHex);
|
||||||
@@ -88,6 +88,23 @@ void RegisterWidget::clearInlineValue() {
|
|||||||
this->valueLabel->clear();
|
this->valueLabel->clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RegisterWidget::openInspectionWindow() {
|
||||||
|
if (!TargetRegisterInspectorWindow::registerSupported(this->descriptor)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this->inspectWindow == nullptr) {
|
||||||
|
this->inspectWindow = new TargetRegisterInspectorWindow(
|
||||||
|
this->descriptor,
|
||||||
|
this->insightWorker,
|
||||||
|
this->currentRegister.has_value() ? std::optional(this->currentRegister->value) : std::nullopt
|
||||||
|
);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
this->inspectWindow->show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void RegisterWidget::refreshValue() {
|
void RegisterWidget::refreshValue() {
|
||||||
auto readRegisterTask = new ReadTargetRegisters({this->descriptor});
|
auto readRegisterTask = new ReadTargetRegisters({this->descriptor});
|
||||||
|
|
||||||
@@ -155,6 +172,7 @@ void RegisterWidget::contextMenuEvent(QContextMenuEvent* event) {
|
|||||||
this->setSelected(true);
|
this->setSelected(true);
|
||||||
|
|
||||||
auto menu = new QMenu(this);
|
auto menu = new QMenu(this);
|
||||||
|
menu->addAction(this->openInspectionWindowAction);
|
||||||
menu->addAction(this->refreshValueAction);
|
menu->addAction(this->refreshValueAction);
|
||||||
menu->addSeparator();
|
menu->addSeparator();
|
||||||
|
|
||||||
@@ -167,6 +185,8 @@ void RegisterWidget::contextMenuEvent(QContextMenuEvent* event) {
|
|||||||
|
|
||||||
menu->addMenu(copyMenu);
|
menu->addMenu(copyMenu);
|
||||||
|
|
||||||
|
this->openInspectionWindowAction->setEnabled(TargetRegisterInspectorWindow::registerSupported(this->descriptor));
|
||||||
|
|
||||||
const auto targetStopped = this->targetState == Targets::TargetState::STOPPED;
|
const auto targetStopped = this->targetState == Targets::TargetState::STOPPED;
|
||||||
const auto targetStoppedAndValuePresent = targetStopped && this->currentRegister.has_value();
|
const auto targetStoppedAndValuePresent = targetStopped && this->currentRegister.has_value();
|
||||||
this->refreshValueAction->setEnabled(targetStopped);
|
this->refreshValueAction->setEnabled(targetStopped);
|
||||||
|
|||||||
@@ -12,6 +12,9 @@
|
|||||||
#include "src/Insight/InsightWorker/InsightWorker.hpp"
|
#include "src/Insight/InsightWorker/InsightWorker.hpp"
|
||||||
|
|
||||||
#include "src/Insight/UserInterfaces/InsightWindow/Widgets/SvgWidget.hpp"
|
#include "src/Insight/UserInterfaces/InsightWindow/Widgets/SvgWidget.hpp"
|
||||||
|
#include "src/Insight/UserInterfaces/InsightWindow/Widgets/TargetRegisterInspector/TargetRegisterInspectorWindow.hpp"
|
||||||
|
|
||||||
|
|
||||||
namespace Bloom::Widgets
|
namespace Bloom::Widgets
|
||||||
{
|
{
|
||||||
class RegisterWidget: public ItemWidget
|
class RegisterWidget: public ItemWidget
|
||||||
@@ -25,12 +28,15 @@ namespace Bloom::Widgets
|
|||||||
QLabel* valueLabel = new QLabel(this);
|
QLabel* valueLabel = new QLabel(this);
|
||||||
|
|
||||||
// Context-menu actions
|
// Context-menu actions
|
||||||
|
QAction* openInspectionWindowAction = new QAction("Inspect", this);
|
||||||
QAction* refreshValueAction = new QAction("Refresh Value", this);
|
QAction* refreshValueAction = new QAction("Refresh Value", this);
|
||||||
QAction* copyValueNameAction = new QAction("Copy Register Name", this);
|
QAction* copyValueNameAction = new QAction("Copy Register Name", this);
|
||||||
QAction* copyValueHexAction = new QAction("Copy Hexadecimal Value", this);
|
QAction* copyValueHexAction = new QAction("Copy Hexadecimal Value", this);
|
||||||
QAction* copyValueDecimalAction = new QAction("Copy Decimal Value", this);
|
QAction* copyValueDecimalAction = new QAction("Copy Decimal Value", this);
|
||||||
QAction* copyValueBinaryAction = new QAction("Copy Binary Value", this);
|
QAction* copyValueBinaryAction = new QAction("Copy Binary Value", this);
|
||||||
|
|
||||||
|
TargetRegisterInspectorWindow* inspectWindow = nullptr;
|
||||||
|
|
||||||
void postSetSelected(bool selected) override;
|
void postSetSelected(bool selected) override;
|
||||||
|
|
||||||
Targets::TargetState targetState = Targets::TargetState::UNKNOWN;
|
Targets::TargetState targetState = Targets::TargetState::UNKNOWN;
|
||||||
@@ -59,6 +65,7 @@ namespace Bloom::Widgets
|
|||||||
void contextMenuEvent(QContextMenuEvent* event) override;
|
void contextMenuEvent(QContextMenuEvent* event) override;
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
|
void openInspectionWindow();
|
||||||
void refreshValue();
|
void refreshValue();
|
||||||
void copyName();
|
void copyName();
|
||||||
void copyValueHex();
|
void copyValueHex();
|
||||||
|
|||||||
@@ -20,12 +20,14 @@
|
|||||||
<file alias="/compiled/src/Insight/UserInterfaces/InsightWindow/UiFiles/InsightWindow.ui">./Insight/UserInterfaces/InsightWindow/UiFiles/InsightWindow.ui</file>
|
<file alias="/compiled/src/Insight/UserInterfaces/InsightWindow/UiFiles/InsightWindow.ui">./Insight/UserInterfaces/InsightWindow/UiFiles/InsightWindow.ui</file>
|
||||||
<file alias="/compiled/src/Insight/UserInterfaces/InsightWindow/UiFiles/AboutWindow.ui">./Insight/UserInterfaces/InsightWindow/UiFiles/AboutWindow.ui</file>
|
<file alias="/compiled/src/Insight/UserInterfaces/InsightWindow/UiFiles/AboutWindow.ui">./Insight/UserInterfaces/InsightWindow/UiFiles/AboutWindow.ui</file>
|
||||||
<file alias="/compiled/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetRegistersPane/UiFiles/TargetRegistersSidePane.ui">./Insight/UserInterfaces/InsightWindow/Widgets/TargetRegistersPane/UiFiles/TargetRegistersSidePane.ui</file>
|
<file alias="/compiled/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetRegistersPane/UiFiles/TargetRegistersSidePane.ui">./Insight/UserInterfaces/InsightWindow/Widgets/TargetRegistersPane/UiFiles/TargetRegistersSidePane.ui</file>
|
||||||
|
<file alias="/compiled/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetRegisterInspector/UiFiles/TargetRegisterInspectorWindow.ui">./Insight/UserInterfaces/InsightWindow/Widgets/TargetRegisterInspector/UiFiles/TargetRegisterInspectorWindow.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>
|
||||||
<file alias="/compiled/src/Insight/UserInterfaces/InsightWindow/Stylesheets/AboutWindow.qss">./Insight/UserInterfaces/InsightWindow/Stylesheets/AboutWindow.qss</file>
|
<file alias="/compiled/src/Insight/UserInterfaces/InsightWindow/Stylesheets/AboutWindow.qss">./Insight/UserInterfaces/InsightWindow/Stylesheets/AboutWindow.qss</file>
|
||||||
<file alias="/compiled/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetWidgets/DIP/Stylesheets/DualInlinePackage.qss">./Insight/UserInterfaces/InsightWindow/Widgets/TargetWidgets/DIP/Stylesheets/DualInlinePackage.qss</file>
|
<file alias="/compiled/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetWidgets/DIP/Stylesheets/DualInlinePackage.qss">./Insight/UserInterfaces/InsightWindow/Widgets/TargetWidgets/DIP/Stylesheets/DualInlinePackage.qss</file>
|
||||||
<file alias="/compiled/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetWidgets/QFP/Stylesheets/QuadFlatPackage.qss">./Insight/UserInterfaces/InsightWindow/Widgets/TargetWidgets/QFP/Stylesheets/QuadFlatPackage.qss</file>
|
<file alias="/compiled/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetWidgets/QFP/Stylesheets/QuadFlatPackage.qss">./Insight/UserInterfaces/InsightWindow/Widgets/TargetWidgets/QFP/Stylesheets/QuadFlatPackage.qss</file>
|
||||||
|
<file alias="/compiled/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetRegisterInspector/Stylesheets/TargetRegisterInspectorWindow.qss">./Insight/UserInterfaces/InsightWindow/Widgets/TargetRegisterInspector/Stylesheets/TargetRegisterInspectorWindow.qss</file>
|
||||||
|
|
||||||
<!-- Icons for Insight-->
|
<!-- Icons for Insight-->
|
||||||
<file alias="/compiled/src/Insight/UserInterfaces/InsightWindow/Images/BloomIcon.svg">./Insight/UserInterfaces/InsightWindow/Images/BloomIcon.svg</file>
|
<file alias="/compiled/src/Insight/UserInterfaces/InsightWindow/Images/BloomIcon.svg">./Insight/UserInterfaces/InsightWindow/Images/BloomIcon.svg</file>
|
||||||
@@ -40,5 +42,6 @@
|
|||||||
<file alias="/compiled/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetRegistersPane/Images/target-registers.svg">./Insight/UserInterfaces/InsightWindow/Widgets/TargetRegistersPane/Images/target-registers.svg</file>
|
<file alias="/compiled/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetRegistersPane/Images/target-registers.svg">./Insight/UserInterfaces/InsightWindow/Widgets/TargetRegistersPane/Images/target-registers.svg</file>
|
||||||
<file alias="/compiled/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetRegistersPane/Images/target-registers-disabled.svg">./Insight/UserInterfaces/InsightWindow/Widgets/TargetRegistersPane/Images/target-registers-disabled.svg</file>
|
<file alias="/compiled/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetRegistersPane/Images/target-registers-disabled.svg">./Insight/UserInterfaces/InsightWindow/Widgets/TargetRegistersPane/Images/target-registers-disabled.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/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>
|
||||||
</qresource>
|
</qresource>
|
||||||
</RCC>
|
</RCC>
|
||||||
|
|||||||
Reference in New Issue
Block a user