Refactored snapshot list in SnapshotManager to use ListView widget

This commit is contained in:
Nav
2023-03-23 19:22:00 +00:00
parent 6c2527b7f4
commit 400a735760
5 changed files with 117 additions and 150 deletions

View File

@@ -4,66 +4,93 @@
namespace Bloom::Widgets
{
MemorySnapshotItem::MemorySnapshotItem(
const MemorySnapshot& memorySnapshot,
QWidget *parent
)
MemorySnapshotItem::MemorySnapshotItem(const MemorySnapshot& memorySnapshot)
: memorySnapshot(memorySnapshot)
, ClickableWidget(parent)
{
this->setObjectName("snapshot-item");
this->setFixedHeight(50);
this->layout->setContentsMargins(5, 5, 5, 0);
this->size = QSize(0, MemorySnapshotItem::HEIGHT);
this->nameLabel->setText(memorySnapshot.name);
this->nameLabel->setObjectName("name-label");
this->programCounterLabel->setText("0x" + QString::number(this->memorySnapshot.programCounter, 16).toUpper());
this->programCounterLabel->setObjectName("program-counter-label");
this->createdDateLabel->setText(
memorySnapshot.createdDate.toString(
memorySnapshot.createdDate.date() == Services::DateTimeService::currentDate()
? "hh:mm"
: "dd/MM/yyyy hh:mm"
)
this->nameText = memorySnapshot.name;
this->programCounterText = "0x" + QString::number(this->memorySnapshot.programCounter, 16).toUpper();
this->createdDateText = 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) {
this->setProperty("selected", selected);
this->style()->unpolish(this);
this->style()->polish(this);
void MemorySnapshotItem::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) {
static constexpr auto margins = QMargins(5, 5, 5, 0);
if (selected) {
emit this->selected(this);
static auto font = QFont("'Ubuntu', sans-serif");
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);
}
}

View File

@@ -1,40 +1,33 @@
#pragma once
#include <QVBoxLayout>
#include <QComboBox>
#include <map>
#include <QString>
#include <QStringList>
#include "src/Insight/UserInterfaces/InsightWindow/Widgets/ClickableWidget.hpp"
#include "src/Insight/UserInterfaces/InsightWindow/Widgets/Label.hpp"
#include "src/Insight/UserInterfaces/InsightWindow/Widgets/ListView/ListItem.hpp"
#include "src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/MemorySnapshot.hpp"
#include "src/Targets/TargetMemory.hpp"
namespace Bloom::Widgets
{
class MemorySnapshotItem: public ClickableWidget
class MemorySnapshotItem: public ListItem
{
Q_OBJECT
public:
const MemorySnapshot& memorySnapshot;
MemorySnapshotItem(
const MemorySnapshot& memorySnapshot,
QWidget *parent
);
MemorySnapshotItem(const MemorySnapshot& memorySnapshot);
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 selected(MemorySnapshotItem*);
void paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) override;
private:
QVBoxLayout* layout = new QVBoxLayout(this);
Label* nameLabel = new Label(this);
Label* programCounterLabel = new Label(this);
Label* createdDateLabel = new Label(this);
static constexpr int HEIGHT = 50;
QString nameText;
QString programCounterText;
QString createdDateText;
};
}

View File

@@ -53,15 +53,15 @@ namespace Bloom::Widgets
this->createSnapshotButton = this->toolBar->findChild<SvgToolButton*>("create-snapshot-btn");
this->deleteSnapshotButton = this->toolBar->findChild<SvgToolButton*>("delete-snapshot-btn");
this->itemScrollArea = this->container->findChild<QScrollArea*>("snapshot-item-scroll-area");
this->itemScrollAreaViewport = this->itemScrollArea->findChild<QWidget*>("item-container");
this->itemLayout = this->itemScrollAreaViewport->findChild<QVBoxLayout*>(
"item-container-layout"
);
auto* containerLayout = this->container->findChild<QVBoxLayout*>();
this->itemScrollArea->setContentsMargins(0, 0, 0, 0);
this->itemScrollAreaViewport->setContentsMargins(0, 0, 0, 0);
this->itemLayout->setContentsMargins(0, 0, 0, 0);
this->snapshotListView = new ListView({}, this);
this->snapshotListView->setVerticalScrollBarPolicy(Qt::ScrollBarPolicy::ScrollBarAsNeeded);
this->snapshotListScene = this->snapshotListView->listScene();
this->snapshotListScene->setSelectionLimit(2);
containerLayout->addWidget(this->snapshotListView);
this->createSnapshotWindow = new CreateSnapshotWindow(
this->memoryDescriptor.type,
@@ -112,7 +112,9 @@ namespace Bloom::Widgets
this->addSnapshot(std::move(snapshot));
}
this->sortSnapshotItems();
this->snapshotListScene->sortItems();
this->snapshotListScene->refreshGeometry();
}
);
@@ -156,7 +158,8 @@ namespace Bloom::Widgets
this,
[this] (MemorySnapshot 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) {
const auto snapshotIt = this->snapshotsById.insert(std::pair(snapshotTmp.id, std::move(snapshotTmp)));
const auto& snapshot = snapshotIt.first->second;
const auto snapshotIt = this->snapshotsById.emplace(snapshotTmp.id, std::move(snapshotTmp));
const auto& snapshot = *snapshotIt;
auto* snapshotItem = new MemorySnapshotItem(snapshot, this);
this->itemLayout->addWidget(snapshotItem);
const auto snapshotItemIt = this->snapshotItemsById.emplace(snapshot.id, new MemorySnapshotItem(snapshot));
auto& snapshotItem = *snapshotItemIt;
QObject::connect(
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);
}
this->snapshotListScene->addListItem(snapshotItem);
}
void SnapshotManager::onSnapshotItemSelected(MemorySnapshotItem* item) {

View File

@@ -4,12 +4,12 @@
#include <optional>
#include <QResizeEvent>
#include <QShowEvent>
#include <QScrollArea>
#include <QVBoxLayout>
#include <map>
#include <QHash>
#include "src/Insight/UserInterfaces/InsightWindow/Widgets/PaneWidget.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/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/MemorySnapshot.hpp"
@@ -49,7 +49,8 @@ namespace Bloom::Widgets
const std::optional<Targets::TargetMemoryBuffer>& data;
const bool& staleData;
std::map<QString, MemorySnapshot> snapshotsById;
QHash<QString, MemorySnapshot> snapshotsById;
QHash<QString, MemorySnapshotItem*> snapshotItemsById;
QWidget* container = nullptr;
QWidget* toolBar = nullptr;
@@ -57,9 +58,8 @@ namespace Bloom::Widgets
SvgToolButton* createSnapshotButton = nullptr;
SvgToolButton* deleteSnapshotButton = nullptr;
QScrollArea* itemScrollArea = nullptr;
QWidget* itemScrollAreaViewport = nullptr;
QVBoxLayout* itemLayout = nullptr;
ListView* snapshotListView = nullptr;
ListScene* snapshotListScene = nullptr;
void createSnapshot(
const QString& name,
@@ -68,7 +68,6 @@ namespace Bloom::Widgets
bool captureDirectlyFromTarget
);
void addSnapshot(MemorySnapshot&& snapshotTmp);
void sortSnapshotItems();
void onSnapshotItemSelected(MemorySnapshotItem* item);
};
}

View File

@@ -111,34 +111,6 @@
</layout>
</widget>
</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>
</widget>
</ui>