Refactored TaskProgressIndicator widget to remain in place and support multiple tasks
This commit is contained in:
@@ -134,8 +134,8 @@ namespace Bloom::Widgets
|
|||||||
this->setRefreshOnTargetStopEnabled(this->settings.refreshOnTargetStop);
|
this->setRefreshOnTargetStopEnabled(this->settings.refreshOnTargetStop);
|
||||||
this->setRefreshOnActivationEnabled(this->settings.refreshOnActivation);
|
this->setRefreshOnActivationEnabled(this->settings.refreshOnActivation);
|
||||||
|
|
||||||
this->bottomBarHorizontalSpacer = new QSpacerItem(1, 1, QSizePolicy::Expanding, QSizePolicy::Expanding);
|
this->taskProgressIndicator = new TaskProgressIndicator(this);
|
||||||
this->bottomBarLayout->insertItem(5, this->bottomBarHorizontalSpacer);
|
this->bottomBarLayout->insertWidget(5, this->taskProgressIndicator);
|
||||||
|
|
||||||
QObject::connect(
|
QObject::connect(
|
||||||
this,
|
this,
|
||||||
@@ -370,7 +370,7 @@ namespace Bloom::Widgets
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
this->setTaskProgressIndicator(readStackPointerTask);
|
this->taskProgressIndicator->addTask(readStackPointerTask);
|
||||||
InsightWorker::queueTask(readStackPointerTask);
|
InsightWorker::queueTask(readStackPointerTask);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -415,7 +415,7 @@ namespace Bloom::Widgets
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
this->setTaskProgressIndicator(readMemoryTask);
|
this->taskProgressIndicator->addTask(readMemoryTask);
|
||||||
InsightWorker::queueTask(readMemoryTask);
|
InsightWorker::queueTask(readMemoryTask);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -632,33 +632,7 @@ namespace Bloom::Widgets
|
|||||||
}
|
}
|
||||||
|
|
||||||
void TargetMemoryInspectionPane::onSubtaskCreated(const QSharedPointer<InsightWorkerTask>& task) {
|
void TargetMemoryInspectionPane::onSubtaskCreated(const QSharedPointer<InsightWorkerTask>& task) {
|
||||||
this->setTaskProgressIndicator(task);
|
this->taskProgressIndicator->addTask(task);
|
||||||
}
|
|
||||||
|
|
||||||
void TargetMemoryInspectionPane::setTaskProgressIndicator(const QSharedPointer<InsightWorkerTask>& task) {
|
|
||||||
if (this->taskProgressIndicator != nullptr) {
|
|
||||||
this->bottomBarLayout->removeWidget(this->taskProgressIndicator);
|
|
||||||
this->taskProgressIndicator->deleteLater();
|
|
||||||
this->taskProgressIndicator = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
this->taskProgressIndicator = new TaskProgressIndicator(task, this);
|
|
||||||
|
|
||||||
QObject::connect(
|
|
||||||
this->taskProgressIndicator,
|
|
||||||
&TaskProgressIndicator::taskComplete,
|
|
||||||
this,
|
|
||||||
[this] {
|
|
||||||
this->bottomBarLayout->removeWidget(this->taskProgressIndicator);
|
|
||||||
this->taskProgressIndicator->deleteLater();
|
|
||||||
this->taskProgressIndicator = nullptr;
|
|
||||||
|
|
||||||
this->bottomBarLayout->insertItem(5, this->bottomBarHorizontalSpacer);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
this->bottomBarLayout->removeItem(this->bottomBarHorizontalSpacer);
|
|
||||||
this->bottomBarLayout->insertWidget(5, this->taskProgressIndicator);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void TargetMemoryInspectionPane::setStaleData(bool staleData) {
|
void TargetMemoryInspectionPane::setStaleData(bool staleData) {
|
||||||
|
|||||||
@@ -81,7 +81,6 @@ namespace Bloom::Widgets
|
|||||||
SnapshotManager* snapshotManager = nullptr;
|
SnapshotManager* snapshotManager = nullptr;
|
||||||
|
|
||||||
TaskProgressIndicator* taskProgressIndicator = nullptr;
|
TaskProgressIndicator* taskProgressIndicator = nullptr;
|
||||||
QSpacerItem* bottomBarHorizontalSpacer = nullptr;
|
|
||||||
QWidget* staleDataLabelContainer = nullptr;
|
QWidget* staleDataLabelContainer = nullptr;
|
||||||
|
|
||||||
Targets::TargetState targetState = Targets::TargetState::UNKNOWN;
|
Targets::TargetState targetState = Targets::TargetState::UNKNOWN;
|
||||||
@@ -106,7 +105,6 @@ namespace Bloom::Widgets
|
|||||||
Targets::TargetMemoryAddressRange addressRange
|
Targets::TargetMemoryAddressRange addressRange
|
||||||
);
|
);
|
||||||
void onSubtaskCreated(const QSharedPointer<InsightWorkerTask>& task);
|
void onSubtaskCreated(const QSharedPointer<InsightWorkerTask>& task);
|
||||||
void setTaskProgressIndicator(const QSharedPointer<InsightWorkerTask>& task);
|
|
||||||
void setStaleData(bool staleData);
|
void setStaleData(bool staleData);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,58 +3,79 @@
|
|||||||
#include <QPainter>
|
#include <QPainter>
|
||||||
#include <QColor>
|
#include <QColor>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <QTimer>
|
|
||||||
|
|
||||||
namespace Bloom::Widgets
|
namespace Bloom::Widgets
|
||||||
{
|
{
|
||||||
TaskProgressIndicator::TaskProgressIndicator(
|
TaskProgressIndicator::TaskProgressIndicator(QWidget* parent)
|
||||||
const QSharedPointer<InsightWorkerTask>& task,
|
|
||||||
QWidget* parent
|
|
||||||
)
|
|
||||||
: QWidget(parent)
|
: QWidget(parent)
|
||||||
, task(task)
|
|
||||||
{
|
{
|
||||||
this->setObjectName("task-progress-indicator");
|
this->setObjectName("task-progress-indicator");
|
||||||
this->setFixedHeight(26);
|
this->setFixedHeight(26);
|
||||||
this->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed);
|
this->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed);
|
||||||
|
|
||||||
|
this->clearCompletedTasksTimer->setSingleShot(true);
|
||||||
|
this->clearCompletedTasksTimer->setInterval(2500);
|
||||||
|
|
||||||
QObject::connect(
|
QObject::connect(
|
||||||
this->task.get(),
|
this->clearCompletedTasksTimer,
|
||||||
|
&QTimer::timeout,
|
||||||
|
this,
|
||||||
|
&TaskProgressIndicator::clearCompletedTasks
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TaskProgressIndicator::addTask(const QSharedPointer<InsightWorkerTask>& task) {
|
||||||
|
if (this->tasksById.contains(task->id)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->tasksById.emplace(task->id, task);
|
||||||
|
|
||||||
|
QObject::connect(
|
||||||
|
task.get(),
|
||||||
&InsightWorkerTask::started,
|
&InsightWorkerTask::started,
|
||||||
this,
|
this,
|
||||||
&TaskProgressIndicator::onTaskStateChanged
|
&TaskProgressIndicator::refreshProgressPercentage
|
||||||
);
|
);
|
||||||
|
|
||||||
QObject::connect(
|
QObject::connect(
|
||||||
this->task.get(),
|
task.get(),
|
||||||
&InsightWorkerTask::finished,
|
&InsightWorkerTask::finished,
|
||||||
this,
|
this,
|
||||||
&TaskProgressIndicator::onTaskStateChanged
|
&TaskProgressIndicator::refreshProgressPercentage
|
||||||
);
|
);
|
||||||
|
|
||||||
QObject::connect(
|
QObject::connect(
|
||||||
this->task.get(),
|
task.get(),
|
||||||
&InsightWorkerTask::failed,
|
&InsightWorkerTask::failed,
|
||||||
this,
|
this,
|
||||||
&TaskProgressIndicator::onTaskStateChanged
|
&TaskProgressIndicator::refreshProgressPercentage
|
||||||
);
|
);
|
||||||
|
|
||||||
QObject::connect(
|
QObject::connect(
|
||||||
this->task.get(),
|
task.get(),
|
||||||
&InsightWorkerTask::finished,
|
&InsightWorkerTask::finished,
|
||||||
this,
|
this,
|
||||||
&TaskProgressIndicator::onTaskFinished
|
&TaskProgressIndicator::onTaskFinished
|
||||||
);
|
);
|
||||||
|
|
||||||
QObject::connect(
|
QObject::connect(
|
||||||
this->task.get(),
|
task.get(),
|
||||||
&InsightWorkerTask::progressUpdate,
|
&InsightWorkerTask::progressUpdate,
|
||||||
this,
|
this,
|
||||||
&TaskProgressIndicator::onTaskProgressUpdate
|
&TaskProgressIndicator::refreshProgressPercentage
|
||||||
);
|
);
|
||||||
|
|
||||||
|
this->refreshProgressPercentage();
|
||||||
}
|
}
|
||||||
|
|
||||||
void TaskProgressIndicator::paintEvent(QPaintEvent* event) {
|
void TaskProgressIndicator::paintEvent(QPaintEvent* event) {
|
||||||
|
const auto taskCount = this->tasksById.size();
|
||||||
|
|
||||||
|
if (taskCount < 1) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
auto painter = QPainter(this);
|
auto painter = QPainter(this);
|
||||||
|
|
||||||
const auto size = this->size();
|
const auto size = this->size();
|
||||||
@@ -63,19 +84,21 @@ namespace Bloom::Widgets
|
|||||||
static constexpr auto barColor = QColor(0x8E, 0x8B, 0x83, 90);
|
static constexpr auto barColor = QColor(0x8E, 0x8B, 0x83, 90);
|
||||||
static constexpr auto fontColor = QColor(0x99, 0x9a, 0x9d);
|
static constexpr auto fontColor = QColor(0x99, 0x9a, 0x9d);
|
||||||
|
|
||||||
static auto font = QFont("'Ubuntu', sans-serif", 9);
|
static const auto font = QFont("'Ubuntu', sans-serif", 9);
|
||||||
painter.setFont(font);
|
painter.setFont(font);
|
||||||
painter.setPen(fontColor);
|
painter.setPen(fontColor);
|
||||||
|
|
||||||
static constexpr auto barHeight = 3;
|
static constexpr auto barHeight = 3;
|
||||||
const auto barYPosition = size.height() - barHeight - 3;
|
const auto barYPosition = size.height() - barHeight - 3;
|
||||||
|
|
||||||
const auto percentage = std::max(static_cast<int>(this->task->progressPercentage), 2);
|
const auto percentage = std::max(static_cast<int>(this->progressPercentage), 2);
|
||||||
|
|
||||||
|
if (taskCount == 1) {
|
||||||
|
auto* task = this->tasksById.begin()->second.get();
|
||||||
const auto status = QString(
|
const auto status = QString(
|
||||||
this->task->state == InsightWorkerTaskState::FAILED
|
task->state == InsightWorkerTaskState::FAILED
|
||||||
? " - Failed"
|
? " - Failed"
|
||||||
: this->task->state == InsightWorkerTaskState::COMPLETED
|
: task->state == InsightWorkerTaskState::COMPLETED
|
||||||
? " - Completed"
|
? " - Completed"
|
||||||
: ""
|
: ""
|
||||||
);
|
);
|
||||||
@@ -83,9 +106,17 @@ namespace Bloom::Widgets
|
|||||||
painter.drawText(
|
painter.drawText(
|
||||||
0,
|
0,
|
||||||
barYPosition - 5,
|
barYPosition - 5,
|
||||||
this->task->brief() + status
|
task->brief() + status
|
||||||
);
|
);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
painter.drawText(
|
||||||
|
0,
|
||||||
|
barYPosition - 5,
|
||||||
|
"Processing " + QString::number(taskCount) + " tasks"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
painter.setPen(Qt::PenStyle::NoPen);
|
painter.setPen(Qt::PenStyle::NoPen);
|
||||||
painter.setBrush(backgroundBarColor);
|
painter.setBrush(backgroundBarColor);
|
||||||
|
|
||||||
@@ -106,23 +137,39 @@ namespace Bloom::Widgets
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TaskProgressIndicator::onTaskProgressUpdate() {
|
void TaskProgressIndicator::clearCompletedTasks() {
|
||||||
this->update();
|
std::erase_if(
|
||||||
|
this->tasksById,
|
||||||
|
[] (const decltype(this->tasksById)::value_type& pair) {
|
||||||
|
return
|
||||||
|
pair.second->state == InsightWorkerTaskState::COMPLETED
|
||||||
|
|| pair.second->state == InsightWorkerTaskState::FAILED;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
this->refreshProgressPercentage();
|
||||||
}
|
}
|
||||||
|
|
||||||
void TaskProgressIndicator::onTaskStateChanged() {
|
void TaskProgressIndicator::refreshProgressPercentage() {
|
||||||
|
unsigned int percentageSum = 0;
|
||||||
|
|
||||||
|
for (const auto& [taskId, task] : this->tasksById) {
|
||||||
|
percentageSum += task->progressPercentage;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->progressPercentage = static_cast<std::uint8_t>(
|
||||||
|
static_cast<float>(percentageSum) / static_cast<float>(this->tasksById.size())
|
||||||
|
);
|
||||||
|
|
||||||
this->update();
|
this->update();
|
||||||
}
|
}
|
||||||
|
|
||||||
void TaskProgressIndicator::onTaskFinished() {
|
void TaskProgressIndicator::onTaskFinished() {
|
||||||
auto* finishedSignalTimer = new QTimer();
|
if (this->tasksById.size() > 1) {
|
||||||
finishedSignalTimer->setSingleShot(true);
|
this->clearCompletedTasks();
|
||||||
finishedSignalTimer->setInterval(2500);
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
QObject::connect(finishedSignalTimer, &QTimer::timeout, this, [this] {
|
this->clearCompletedTasksTimer->start();
|
||||||
emit this->taskComplete();
|
|
||||||
});
|
|
||||||
|
|
||||||
finishedSignalTimer->start();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
|
#include <unordered_map>
|
||||||
#include <QSharedPointer>
|
#include <QSharedPointer>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <unordered_map>
|
|
||||||
#include <QEvent>
|
#include <QEvent>
|
||||||
|
#include <QTimer>
|
||||||
|
|
||||||
#include "src/Insight/InsightWorker/Tasks/InsightWorkerTask.hpp"
|
#include "src/Insight/InsightWorker/Tasks/InsightWorkerTask.hpp"
|
||||||
|
|
||||||
@@ -15,19 +16,21 @@ namespace Bloom::Widgets
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
TaskProgressIndicator(const QSharedPointer<InsightWorkerTask>& task, QWidget* parent);
|
TaskProgressIndicator(QWidget* parent);
|
||||||
|
|
||||||
signals:
|
void addTask(const QSharedPointer<InsightWorkerTask>& task);
|
||||||
void taskComplete();
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void paintEvent(QPaintEvent* event) override;
|
void paintEvent(QPaintEvent* event) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QSharedPointer<InsightWorkerTask> task;
|
std::unordered_map<InsightWorkerTask::IdType, QSharedPointer<InsightWorkerTask>> tasksById;
|
||||||
|
|
||||||
void onTaskProgressUpdate();
|
std::uint8_t progressPercentage = 0;
|
||||||
void onTaskStateChanged();
|
QTimer* clearCompletedTasksTimer = new QTimer(this);
|
||||||
|
|
||||||
|
void clearCompletedTasks();
|
||||||
|
void refreshProgressPercentage();
|
||||||
void onTaskFinished();
|
void onTaskFinished();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user