Refactored snapshot list in SnapshotManager to use ListView widget
This commit is contained in:
@@ -4,66 +4,93 @@
|
|||||||
|
|
||||||
namespace Bloom::Widgets
|
namespace Bloom::Widgets
|
||||||
{
|
{
|
||||||
MemorySnapshotItem::MemorySnapshotItem(
|
MemorySnapshotItem::MemorySnapshotItem(const MemorySnapshot& memorySnapshot)
|
||||||
const MemorySnapshot& memorySnapshot,
|
|
||||||
QWidget *parent
|
|
||||||
)
|
|
||||||
: memorySnapshot(memorySnapshot)
|
: memorySnapshot(memorySnapshot)
|
||||||
, ClickableWidget(parent)
|
|
||||||
{
|
{
|
||||||
this->setObjectName("snapshot-item");
|
this->size = QSize(0, MemorySnapshotItem::HEIGHT);
|
||||||
this->setFixedHeight(50);
|
|
||||||
this->layout->setContentsMargins(5, 5, 5, 0);
|
|
||||||
|
|
||||||
this->nameLabel->setText(memorySnapshot.name);
|
this->nameText = memorySnapshot.name;
|
||||||
this->nameLabel->setObjectName("name-label");
|
this->programCounterText = "0x" + QString::number(this->memorySnapshot.programCounter, 16).toUpper();
|
||||||
|
this->createdDateText = memorySnapshot.createdDate.toString(
|
||||||
this->programCounterLabel->setText("0x" + QString::number(this->memorySnapshot.programCounter, 16).toUpper());
|
memorySnapshot.createdDate.date() == Services::DateTimeService::currentDate()
|
||||||
this->programCounterLabel->setObjectName("program-counter-label");
|
? "hh:mm"
|
||||||
|
: "dd/MM/yyyy hh:mm"
|
||||||
this->createdDateLabel->setText(
|
|
||||||
memorySnapshot.createdDate.toString(
|
|
||||||
memorySnapshot.createdDate.date() == Services::DateTimeService::currentDate()
|
|
||||||
? "hh:mm"
|
|
||||||
: "dd/MM/yyyy hh:mm"
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
this->createdDateLabel->setObjectName("created-date-label");
|
|
||||||
|
|
||||||
auto* topLabelLayout = new QHBoxLayout();
|
|
||||||
topLabelLayout->setSpacing(0);
|
|
||||||
topLabelLayout->setContentsMargins(0, 0, 0, 0);
|
|
||||||
topLabelLayout->addWidget(this->nameLabel, 0, Qt::AlignmentFlag::AlignLeft);
|
|
||||||
topLabelLayout->addStretch(1);
|
|
||||||
topLabelLayout->addWidget(this->programCounterLabel, 0, Qt::AlignmentFlag::AlignRight);
|
|
||||||
|
|
||||||
auto* bottomLabelLayout = new QHBoxLayout();
|
|
||||||
bottomLabelLayout->setSpacing(0);
|
|
||||||
bottomLabelLayout->setContentsMargins(0, 0, 0, 0);
|
|
||||||
bottomLabelLayout->addWidget(this->createdDateLabel, 0, Qt::AlignmentFlag::AlignLeft);
|
|
||||||
|
|
||||||
this->layout->setSpacing(5);
|
|
||||||
this->layout->addLayout(topLabelLayout);
|
|
||||||
this->layout->addLayout(bottomLabelLayout);
|
|
||||||
this->layout->addStretch(1);
|
|
||||||
|
|
||||||
auto onClick = [this] {
|
|
||||||
this->setSelected(true);
|
|
||||||
};
|
|
||||||
|
|
||||||
QObject::connect(this, &ClickableWidget::clicked, this, onClick);
|
|
||||||
QObject::connect(this, &ClickableWidget::rightClicked, this, onClick);
|
|
||||||
|
|
||||||
this->setSelected(false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MemorySnapshotItem::setSelected(bool selected) {
|
void MemorySnapshotItem::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) {
|
||||||
this->setProperty("selected", selected);
|
static constexpr auto margins = QMargins(5, 5, 5, 0);
|
||||||
this->style()->unpolish(this);
|
|
||||||
this->style()->polish(this);
|
|
||||||
|
|
||||||
if (selected) {
|
static auto font = QFont("'Ubuntu', sans-serif");
|
||||||
emit this->selected(this);
|
font.setPixelSize(14);
|
||||||
|
static auto secondaryFont = QFont("'Ubuntu', sans-serif");
|
||||||
|
secondaryFont.setPixelSize(13);
|
||||||
|
|
||||||
|
static constexpr auto fontColor = QColor(0xAF, 0xB1, 0xB3);
|
||||||
|
static constexpr auto secondaryFontColor = QColor(0x8A, 0x8A, 0x8D);
|
||||||
|
|
||||||
|
if (this->selected) {
|
||||||
|
static constexpr auto selectedBackgroundColor = QColor(0x35, 0x5A, 0x80);
|
||||||
|
|
||||||
|
painter->setBrush(selectedBackgroundColor);
|
||||||
|
painter->setPen(Qt::PenStyle::NoPen);
|
||||||
|
painter->drawRect(QRect(QPoint(0, 0), this->size));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
painter->setFont(font);
|
||||||
|
painter->setPen(fontColor);
|
||||||
|
|
||||||
|
const auto fontMetrics = painter->fontMetrics();
|
||||||
|
|
||||||
|
const auto programCounterTextSize = fontMetrics.size(Qt::TextSingleLine, this->programCounterText);
|
||||||
|
const auto createdDateTextSize = fontMetrics.size(Qt::TextSingleLine, this->createdDateText);
|
||||||
|
|
||||||
|
constexpr auto nameTextRightMargin = 10;
|
||||||
|
const auto availableNameTextWidth = this->size.width() - margins.left() - margins.right()
|
||||||
|
- programCounterTextSize.width() - nameTextRightMargin;
|
||||||
|
|
||||||
|
const auto nameText = fontMetrics.elidedText(
|
||||||
|
this->nameText,
|
||||||
|
Qt::TextElideMode::ElideRight,
|
||||||
|
availableNameTextWidth
|
||||||
|
);
|
||||||
|
|
||||||
|
const auto nameTextSize = fontMetrics.size(Qt::TextSingleLine, nameText);
|
||||||
|
const auto nameTextRect = QRect(
|
||||||
|
margins.left(),
|
||||||
|
margins.top(),
|
||||||
|
nameTextSize.width(),
|
||||||
|
nameTextSize.height()
|
||||||
|
);
|
||||||
|
|
||||||
|
painter->drawText(nameTextRect, Qt::AlignLeft, nameText);
|
||||||
|
|
||||||
|
painter->setFont(secondaryFont);
|
||||||
|
|
||||||
|
if (!this->selected) {
|
||||||
|
painter->setPen(secondaryFontColor);
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto programCounterTextRect = QRect(
|
||||||
|
this->size.width() - margins.right() - programCounterTextSize.width(),
|
||||||
|
margins.top(),
|
||||||
|
programCounterTextSize.width(),
|
||||||
|
programCounterTextSize.height()
|
||||||
|
);
|
||||||
|
|
||||||
|
painter->drawText(programCounterTextRect, Qt::AlignLeft, this->programCounterText);
|
||||||
|
|
||||||
|
const auto createdDateTextRect = QRect(
|
||||||
|
margins.left(),
|
||||||
|
nameTextRect.bottom() + 5,
|
||||||
|
createdDateTextSize.width(),
|
||||||
|
createdDateTextSize.height()
|
||||||
|
);
|
||||||
|
|
||||||
|
painter->drawText(createdDateTextRect, Qt::AlignLeft, this->createdDateText);
|
||||||
|
|
||||||
|
static constexpr auto borderColor = QColor(0x41, 0x42, 0x3F);
|
||||||
|
painter->setPen(borderColor);
|
||||||
|
painter->drawLine(0, this->size.height() - 1, this->size.width(), this->size.height() - 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,40 +1,33 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <QVBoxLayout>
|
|
||||||
#include <QComboBox>
|
|
||||||
#include <map>
|
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#include <QStringList>
|
|
||||||
|
|
||||||
#include "src/Insight/UserInterfaces/InsightWindow/Widgets/ClickableWidget.hpp"
|
#include "src/Insight/UserInterfaces/InsightWindow/Widgets/ListView/ListItem.hpp"
|
||||||
#include "src/Insight/UserInterfaces/InsightWindow/Widgets/Label.hpp"
|
|
||||||
|
|
||||||
#include "src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/MemorySnapshot.hpp"
|
#include "src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/MemorySnapshot.hpp"
|
||||||
#include "src/Targets/TargetMemory.hpp"
|
#include "src/Targets/TargetMemory.hpp"
|
||||||
|
|
||||||
namespace Bloom::Widgets
|
namespace Bloom::Widgets
|
||||||
{
|
{
|
||||||
class MemorySnapshotItem: public ClickableWidget
|
class MemorySnapshotItem: public ListItem
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
const MemorySnapshot& memorySnapshot;
|
const MemorySnapshot& memorySnapshot;
|
||||||
|
|
||||||
MemorySnapshotItem(
|
MemorySnapshotItem(const MemorySnapshot& memorySnapshot);
|
||||||
const MemorySnapshot& memorySnapshot,
|
|
||||||
QWidget *parent
|
|
||||||
);
|
|
||||||
|
|
||||||
void setSelected(bool selected);
|
bool operator < (const ListItem& rhs) const override {
|
||||||
|
const auto& rhsSnapshotItem = dynamic_cast<const MemorySnapshotItem&>(rhs);
|
||||||
|
return this->memorySnapshot.createdDate > rhsSnapshotItem.memorySnapshot.createdDate;
|
||||||
|
}
|
||||||
|
|
||||||
signals:
|
void paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) override;
|
||||||
void selected(MemorySnapshotItem*);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QVBoxLayout* layout = new QVBoxLayout(this);
|
static constexpr int HEIGHT = 50;
|
||||||
Label* nameLabel = new Label(this);
|
|
||||||
Label* programCounterLabel = new Label(this);
|
QString nameText;
|
||||||
Label* createdDateLabel = new Label(this);
|
QString programCounterText;
|
||||||
|
QString createdDateText;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -53,15 +53,15 @@ namespace Bloom::Widgets
|
|||||||
this->createSnapshotButton = this->toolBar->findChild<SvgToolButton*>("create-snapshot-btn");
|
this->createSnapshotButton = this->toolBar->findChild<SvgToolButton*>("create-snapshot-btn");
|
||||||
this->deleteSnapshotButton = this->toolBar->findChild<SvgToolButton*>("delete-snapshot-btn");
|
this->deleteSnapshotButton = this->toolBar->findChild<SvgToolButton*>("delete-snapshot-btn");
|
||||||
|
|
||||||
this->itemScrollArea = this->container->findChild<QScrollArea*>("snapshot-item-scroll-area");
|
auto* containerLayout = this->container->findChild<QVBoxLayout*>();
|
||||||
this->itemScrollAreaViewport = this->itemScrollArea->findChild<QWidget*>("item-container");
|
|
||||||
this->itemLayout = this->itemScrollAreaViewport->findChild<QVBoxLayout*>(
|
|
||||||
"item-container-layout"
|
|
||||||
);
|
|
||||||
|
|
||||||
this->itemScrollArea->setContentsMargins(0, 0, 0, 0);
|
this->snapshotListView = new ListView({}, this);
|
||||||
this->itemScrollAreaViewport->setContentsMargins(0, 0, 0, 0);
|
this->snapshotListView->setVerticalScrollBarPolicy(Qt::ScrollBarPolicy::ScrollBarAsNeeded);
|
||||||
this->itemLayout->setContentsMargins(0, 0, 0, 0);
|
|
||||||
|
this->snapshotListScene = this->snapshotListView->listScene();
|
||||||
|
this->snapshotListScene->setSelectionLimit(2);
|
||||||
|
|
||||||
|
containerLayout->addWidget(this->snapshotListView);
|
||||||
|
|
||||||
this->createSnapshotWindow = new CreateSnapshotWindow(
|
this->createSnapshotWindow = new CreateSnapshotWindow(
|
||||||
this->memoryDescriptor.type,
|
this->memoryDescriptor.type,
|
||||||
@@ -112,7 +112,9 @@ namespace Bloom::Widgets
|
|||||||
|
|
||||||
this->addSnapshot(std::move(snapshot));
|
this->addSnapshot(std::move(snapshot));
|
||||||
}
|
}
|
||||||
this->sortSnapshotItems();
|
|
||||||
|
this->snapshotListScene->sortItems();
|
||||||
|
this->snapshotListScene->refreshGeometry();
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -156,7 +158,8 @@ namespace Bloom::Widgets
|
|||||||
this,
|
this,
|
||||||
[this] (MemorySnapshot snapshot) {
|
[this] (MemorySnapshot snapshot) {
|
||||||
this->addSnapshot(std::move(snapshot));
|
this->addSnapshot(std::move(snapshot));
|
||||||
this->sortSnapshotItems();
|
this->snapshotListScene->sortItems();
|
||||||
|
this->snapshotListScene->refreshGeometry();
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -166,40 +169,13 @@ namespace Bloom::Widgets
|
|||||||
}
|
}
|
||||||
|
|
||||||
void SnapshotManager::addSnapshot(MemorySnapshot&& snapshotTmp) {
|
void SnapshotManager::addSnapshot(MemorySnapshot&& snapshotTmp) {
|
||||||
const auto snapshotIt = this->snapshotsById.insert(std::pair(snapshotTmp.id, std::move(snapshotTmp)));
|
const auto snapshotIt = this->snapshotsById.emplace(snapshotTmp.id, std::move(snapshotTmp));
|
||||||
const auto& snapshot = snapshotIt.first->second;
|
const auto& snapshot = *snapshotIt;
|
||||||
|
|
||||||
auto* snapshotItem = new MemorySnapshotItem(snapshot, this);
|
const auto snapshotItemIt = this->snapshotItemsById.emplace(snapshot.id, new MemorySnapshotItem(snapshot));
|
||||||
this->itemLayout->addWidget(snapshotItem);
|
auto& snapshotItem = *snapshotItemIt;
|
||||||
|
|
||||||
QObject::connect(
|
this->snapshotListScene->addListItem(snapshotItem);
|
||||||
snapshotItem,
|
|
||||||
&MemorySnapshotItem::selected,
|
|
||||||
this,
|
|
||||||
&SnapshotManager::onSnapshotItemSelected
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SnapshotManager::sortSnapshotItems() {
|
|
||||||
const auto snapshotItemCompare = [] (MemorySnapshotItem* itemA, MemorySnapshotItem* itemB) {
|
|
||||||
return itemA->memorySnapshot.createdDate > itemB->memorySnapshot.createdDate;
|
|
||||||
};
|
|
||||||
|
|
||||||
auto sortedSnapshotItems = std::set<MemorySnapshotItem*, decltype(snapshotItemCompare)>(snapshotItemCompare);
|
|
||||||
|
|
||||||
QLayoutItem* layoutItem = nullptr;
|
|
||||||
while ((layoutItem = this->itemLayout->takeAt(0)) != nullptr) {
|
|
||||||
auto* snapshotItem = qobject_cast<MemorySnapshotItem*>(layoutItem->widget());
|
|
||||||
if (snapshotItem != nullptr) {
|
|
||||||
sortedSnapshotItems.insert(snapshotItem);
|
|
||||||
}
|
|
||||||
|
|
||||||
delete layoutItem;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (auto* regionItem : sortedSnapshotItems) {
|
|
||||||
this->itemLayout->addWidget(regionItem);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SnapshotManager::onSnapshotItemSelected(MemorySnapshotItem* item) {
|
void SnapshotManager::onSnapshotItemSelected(MemorySnapshotItem* item) {
|
||||||
|
|||||||
@@ -4,12 +4,12 @@
|
|||||||
#include <optional>
|
#include <optional>
|
||||||
#include <QResizeEvent>
|
#include <QResizeEvent>
|
||||||
#include <QShowEvent>
|
#include <QShowEvent>
|
||||||
#include <QScrollArea>
|
|
||||||
#include <QVBoxLayout>
|
#include <QVBoxLayout>
|
||||||
#include <map>
|
#include <QHash>
|
||||||
|
|
||||||
#include "src/Insight/UserInterfaces/InsightWindow/Widgets/PaneWidget.hpp"
|
#include "src/Insight/UserInterfaces/InsightWindow/Widgets/PaneWidget.hpp"
|
||||||
#include "src/Insight/UserInterfaces/InsightWindow/Widgets/SvgToolButton.hpp"
|
#include "src/Insight/UserInterfaces/InsightWindow/Widgets/SvgToolButton.hpp"
|
||||||
|
#include "src/Insight/UserInterfaces/InsightWindow/Widgets/ListView/ListView.hpp"
|
||||||
|
|
||||||
#include "src/Targets/TargetMemory.hpp"
|
#include "src/Targets/TargetMemory.hpp"
|
||||||
#include "src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/MemorySnapshot.hpp"
|
#include "src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/MemorySnapshot.hpp"
|
||||||
@@ -49,7 +49,8 @@ namespace Bloom::Widgets
|
|||||||
const std::optional<Targets::TargetMemoryBuffer>& data;
|
const std::optional<Targets::TargetMemoryBuffer>& data;
|
||||||
const bool& staleData;
|
const bool& staleData;
|
||||||
|
|
||||||
std::map<QString, MemorySnapshot> snapshotsById;
|
QHash<QString, MemorySnapshot> snapshotsById;
|
||||||
|
QHash<QString, MemorySnapshotItem*> snapshotItemsById;
|
||||||
|
|
||||||
QWidget* container = nullptr;
|
QWidget* container = nullptr;
|
||||||
QWidget* toolBar = nullptr;
|
QWidget* toolBar = nullptr;
|
||||||
@@ -57,9 +58,8 @@ namespace Bloom::Widgets
|
|||||||
SvgToolButton* createSnapshotButton = nullptr;
|
SvgToolButton* createSnapshotButton = nullptr;
|
||||||
SvgToolButton* deleteSnapshotButton = nullptr;
|
SvgToolButton* deleteSnapshotButton = nullptr;
|
||||||
|
|
||||||
QScrollArea* itemScrollArea = nullptr;
|
ListView* snapshotListView = nullptr;
|
||||||
QWidget* itemScrollAreaViewport = nullptr;
|
ListScene* snapshotListScene = nullptr;
|
||||||
QVBoxLayout* itemLayout = nullptr;
|
|
||||||
|
|
||||||
void createSnapshot(
|
void createSnapshot(
|
||||||
const QString& name,
|
const QString& name,
|
||||||
@@ -68,7 +68,6 @@ namespace Bloom::Widgets
|
|||||||
bool captureDirectlyFromTarget
|
bool captureDirectlyFromTarget
|
||||||
);
|
);
|
||||||
void addSnapshot(MemorySnapshot&& snapshotTmp);
|
void addSnapshot(MemorySnapshot&& snapshotTmp);
|
||||||
void sortSnapshotItems();
|
|
||||||
void onSnapshotItemSelected(MemorySnapshotItem* item);
|
void onSnapshotItemSelected(MemorySnapshotItem* item);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -111,34 +111,6 @@
|
|||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
|
||||||
<widget class="QScrollArea" name="snapshot-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">
|
|
||||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding"/>
|
|
||||||
</property>
|
|
||||||
<widget class="QWidget" name="item-container">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding"/>
|
|
||||||
</property>
|
|
||||||
<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>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</ui>
|
</ui>
|
||||||
|
|||||||
Reference in New Issue
Block a user