New TaskIndicator widget

This commit is contained in:
Nav
2023-03-12 23:32:44 +00:00
parent 57eaa989f5
commit c394ce52df
6 changed files with 162 additions and 2 deletions

View File

@@ -39,6 +39,9 @@ target_sources(
${CMAKE_CURRENT_SOURCE_DIR}/InsightWorker/Tasks/CaptureMemorySnapshot.cpp
${CMAKE_CURRENT_SOURCE_DIR}/InsightWorker/Tasks/RetrieveMemorySnapshots.cpp
# Task indicator
${CMAKE_CURRENT_SOURCE_DIR}/UserInterfaces/InsightWindow/Widgets/TaskIndicator/TaskIndicator.cpp
# Error dialogue window
${CMAKE_CURRENT_SOURCE_DIR}/UserInterfaces/InsightWindow/Widgets/ErrorDialogue/ErrorDialogue.cpp

View File

@@ -160,6 +160,10 @@ namespace Bloom
this->targetIdLabel = this->footer->findChild<Label*>("target-id");
this->variantMenu = this->footer->findChild<QMenu*>("target-variant-menu");
this->taskIndicator = new TaskIndicator(this);
auto* footerLayout = this->footer->findChild<QHBoxLayout*>();
footerLayout->insertWidget(2, this->taskIndicator);
const auto windowSize = this->size();
this->windowContainer->setFixedSize(windowSize);
this->layoutContainer->setFixedSize(windowSize);

View File

@@ -13,15 +13,15 @@
#include "src/Targets/TargetDescriptor.hpp"
#include "src/Targets/TargetVariant.hpp"
#include "Widgets/PanelWidget.hpp"
#include "Widgets/Label.hpp"
#include "Widgets/SvgToolButton.hpp"
#include "Widgets/TargetWidgets/TargetPackageWidgetContainer.hpp"
#include "Widgets/TargetWidgets/TargetPackageWidget.hpp"
#include "Widgets/PanelWidget.hpp"
#include "Widgets/TargetRegistersPane/TargetRegistersPaneWidget.hpp"
#include "Widgets/TargetMemoryInspectionPane/TargetMemoryInspectionPane.hpp"
#include "Widgets/TargetMemoryInspectionPane/TargetMemoryInspectionPaneSettings.hpp"
#include "Widgets/TaskIndicator/TaskIndicator.hpp"
#include "AboutWindow.hpp"
namespace Bloom
@@ -103,6 +103,7 @@ namespace Bloom
QWidget* footer = nullptr;
Widgets::Label* targetStatusLabel = nullptr;
Widgets::Label* programCounterValueLabel = nullptr;
Widgets::TaskIndicator* taskIndicator = nullptr;
std::map<QString, Targets::TargetVariant> supportedVariantsByName;
const Targets::TargetVariant* selectedVariant = nullptr;

View File

@@ -387,12 +387,18 @@
</item>
<item>
<widget class="Label" name="target-program-counter-value">
<property name="minimumWidth">
<number>130</number>
</property>
<property name="text">
<string>-</string>
</property>
<property name="toolTip">
<string>Program Counter Value (byte address)</string>
</property>
<property name="alignment">
<enum>Qt::AlignCenter</enum>
</property>
</widget>
</item>
<item>

View File

@@ -0,0 +1,113 @@
#include "TaskIndicator.hpp"
#include <QPainter>
#include <QColor>
#include "src/Insight/InsightSignals.hpp"
namespace Bloom::Widgets
{
TaskIndicator::TaskIndicator(QWidget* parent)
: QWidget(parent)
{
this->setObjectName("task-indicator");
this->setFixedSize(50, 26);
auto* insightSignals = InsightSignals::instance();
QObject::connect(
insightSignals,
&InsightSignals::taskQueued,
this,
&TaskIndicator::onTaskQueued
);
QObject::connect(
insightSignals,
&InsightSignals::taskProcessed,
this,
&TaskIndicator::onTaskFinished
);
this->updateToolTip();
}
void TaskIndicator::enterEvent(QEnterEvent* event) {
this->hovered = true;
this->update();
}
void TaskIndicator::leaveEvent(QEvent* event) {
this->hovered = false;
this->update();
}
void TaskIndicator::paintEvent(QPaintEvent* event) {
auto painter = QPainter(this);
painter.setPen(Qt::PenStyle::NoPen);
const auto size = this->size();
static constexpr auto activeItemColor = QColor(0x7C, 0x5D, 0x3B);
static constexpr auto inactiveItemColor = QColor(0x83, 0x83, 0x82);
static constexpr auto itemSize = QSize(3, 3);
static constexpr auto rowCount = 3;
static constexpr auto itemsPerRow = 6;
static constexpr auto itemRightMargin = 2;
static constexpr auto itemBottomMargin = 2;
if (this->hovered) {
static constexpr auto hoveredBackgroundColor = QColor(0x45, 0x45, 0x41);
painter.setBrush(hoveredBackgroundColor);
painter.drawRect(0, 1, size.width(), size.height() - 1);
}
const auto activeTaskCount = this->activeTasksById.size();
// Position the items at the center of the drawing space
auto startX = (size.width() / 2) - (((itemSize.width() + itemRightMargin) * itemsPerRow - itemRightMargin) / 2);
auto startY = (size.height() / 2) - (((itemSize.height() + itemBottomMargin) * rowCount - itemBottomMargin) / 2);
// The itemIndex goes in reverse
auto itemIndex = rowCount * itemsPerRow;
for (auto rowIndex = 0; rowIndex < rowCount; ++rowIndex) {
for (auto rowItemIndex = 0; rowItemIndex < itemsPerRow; ++rowItemIndex) {
painter.setBrush(itemIndex <= activeTaskCount ? activeItemColor : inactiveItemColor);
painter.drawRect(
startX + ((itemSize.width() + itemRightMargin) * rowItemIndex),
startY + ((itemSize.height() + itemBottomMargin) * rowIndex),
itemSize.width(),
itemSize.height()
);
--itemIndex;
}
}
}
void TaskIndicator::onTaskQueued(QSharedPointer<InsightWorkerTask> task) {
this->activeTasksById[task->id] = task;
this->updateToolTip();
this->update();
}
void TaskIndicator::onTaskFinished(QSharedPointer<InsightWorkerTask> task) {
this->activeTasksById.erase(task->id);
this->updateToolTip();
this->update();
}
void TaskIndicator::updateToolTip() {
const auto taskCount = this->activeTasksById.size();
if (taskCount > 0) {
this->setToolTip("Processing " + QString::number(taskCount) + (taskCount == 1 ? " task" : " tasks"));
return;
}
this->setToolTip("Open Task Window");
}
}

View File

@@ -0,0 +1,33 @@
#pragma once
#include <QWidget>
#include <QSharedPointer>
#include <unordered_map>
#include <QEvent>
#include "src/Insight/InsightWorker/Tasks/InsightWorkerTask.hpp"
namespace Bloom::Widgets
{
class TaskIndicator: public QWidget
{
Q_OBJECT
public:
TaskIndicator(QWidget* parent);
protected:
void enterEvent(QEnterEvent* event) override;
void leaveEvent(QEvent* event) override;
void paintEvent(QPaintEvent* event) override;
private:
std::unordered_map<InsightWorkerTask::IdType, QSharedPointer<InsightWorkerTask>> activeTasksById;
bool hovered = false;
void onTaskQueued(QSharedPointer<InsightWorkerTask> task);
void onTaskFinished(QSharedPointer<InsightWorkerTask> task);
void updateToolTip();
};
}