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 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());
this->programCounterLabel->setObjectName("program-counter-label");
this->createdDateLabel->setText(
memorySnapshot.createdDate.toString(
memorySnapshot.createdDate.date() == Services::DateTimeService::currentDate() memorySnapshot.createdDate.date() == Services::DateTimeService::currentDate()
? "hh:mm" ? "hh:mm"
: "dd/MM/yyyy 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);
} }
} }

View File

@@ -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;
}; };
} }

View File

@@ -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) {

View File

@@ -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);
}; };
} }

View File

@@ -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>