Refactored snapshot list in SnapshotManager to use ListView widget
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user