diff --git a/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/SnapshotManager/MemorySnapshotItem.cpp b/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/SnapshotManager/MemorySnapshotItem.cpp index a1d6b590..31fc01b1 100644 --- a/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/SnapshotManager/MemorySnapshotItem.cpp +++ b/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/SnapshotManager/MemorySnapshotItem.cpp @@ -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); } } diff --git a/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/SnapshotManager/MemorySnapshotItem.hpp b/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/SnapshotManager/MemorySnapshotItem.hpp index bf0a7bad..68738133 100644 --- a/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/SnapshotManager/MemorySnapshotItem.hpp +++ b/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/SnapshotManager/MemorySnapshotItem.hpp @@ -1,40 +1,33 @@ #pragma once -#include -#include -#include #include -#include -#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(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; }; } diff --git a/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/SnapshotManager/SnapshotManager.cpp b/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/SnapshotManager/SnapshotManager.cpp index 7473e07b..f7bb7f5c 100644 --- a/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/SnapshotManager/SnapshotManager.cpp +++ b/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/SnapshotManager/SnapshotManager.cpp @@ -53,15 +53,15 @@ namespace Bloom::Widgets this->createSnapshotButton = this->toolBar->findChild("create-snapshot-btn"); this->deleteSnapshotButton = this->toolBar->findChild("delete-snapshot-btn"); - this->itemScrollArea = this->container->findChild("snapshot-item-scroll-area"); - this->itemScrollAreaViewport = this->itemScrollArea->findChild("item-container"); - this->itemLayout = this->itemScrollAreaViewport->findChild( - "item-container-layout" - ); + auto* containerLayout = this->container->findChild(); - 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(snapshotItemCompare); - - QLayoutItem* layoutItem = nullptr; - while ((layoutItem = this->itemLayout->takeAt(0)) != nullptr) { - auto* snapshotItem = qobject_cast(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) { diff --git a/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/SnapshotManager/SnapshotManager.hpp b/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/SnapshotManager/SnapshotManager.hpp index 9980d620..e29f50e0 100644 --- a/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/SnapshotManager/SnapshotManager.hpp +++ b/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/SnapshotManager/SnapshotManager.hpp @@ -4,12 +4,12 @@ #include #include #include -#include #include -#include +#include #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& data; const bool& staleData; - std::map snapshotsById; + QHash snapshotsById; + QHash 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); }; } diff --git a/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/SnapshotManager/UiFiles/SnapshotManager.ui b/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/SnapshotManager/UiFiles/SnapshotManager.ui index 580f332c..d79e255f 100644 --- a/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/SnapshotManager/UiFiles/SnapshotManager.ui +++ b/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/SnapshotManager/UiFiles/SnapshotManager.ui @@ -111,34 +111,6 @@ - - - true - Qt::ScrollBarAsNeeded - QAbstractScrollArea::AdjustToContents - Qt::ScrollBarAlwaysOff - - - - - - - - - - 0 - - - 0 - - - QLayout::SetMinAndMaxSize - - - - - -