TaskTree demo: Visualize Canceled state

The running task tree may cancel automatically some tasks / groups.
Visualize the canceled task / group with cyan color.
Add footer with state legend.

Task-number: QTCREATORBUG-29834
Change-Id: Ie799fa7b803ca3cc5ac21c580c2f86cd41b3242b
Reviewed-by: hjk <hjk@qt.io>
This commit is contained in:
Jarek Kobus
2023-11-03 20:38:02 +01:00
parent 37b6cb7f90
commit af63dcaf96
3 changed files with 86 additions and 25 deletions

View File

@@ -8,6 +8,7 @@
#include <QApplication> #include <QApplication>
#include <QBoxLayout> #include <QBoxLayout>
#include <QGroupBox> #include <QGroupBox>
#include <QLabel>
#include <QProgressBar> #include <QProgressBar>
#include <QScrollArea> #include <QScrollArea>
#include <QTimer> #include <QTimer>
@@ -44,7 +45,12 @@ static QWidget *taskGroup(QWidget *groupWidget, const QList<QWidget *> &widgets)
static State resultToState(DoneWith result) static State resultToState(DoneWith result)
{ {
return result == DoneWith::Success ? State::Done : State::Error; switch (result) {
case DoneWith::Success : return State::Success;
case DoneWith::Error : return State::Error;
case DoneWith::Cancel : return State::Canceled;
}
return State::Initial;
} }
int main(int argc, char *argv[]) int main(int argc, char *argv[])
@@ -69,16 +75,17 @@ int main(int argc, char *argv[])
// Task GUI // Task GUI
QList<StateWidget *> allStateWidgets; QList<GroupWidget *> allGroupWidgets;
QList<TaskWidget *> allTaskWidgets;
auto createGroupWidget = [&allStateWidgets] { auto createGroupWidget = [&allGroupWidgets] {
auto *widget = new GroupWidget(); auto *widget = new GroupWidget;
allStateWidgets.append(widget); allGroupWidgets.append(widget);
return widget; return widget;
}; };
auto createTaskWidget = [&allStateWidgets] { auto createTaskWidget = [&allTaskWidgets] {
auto *widget = new TaskWidget(); auto *widget = new TaskWidget;
allStateWidgets.append(widget); allTaskWidgets.append(widget);
return widget; return widget;
}; };
@@ -162,6 +169,14 @@ int main(int argc, char *argv[])
mainLayout->addLayout(subLayout); mainLayout->addLayout(subLayout);
mainLayout->addWidget(hr()); mainLayout->addWidget(hr());
mainLayout->addWidget(scrollArea); mainLayout->addWidget(scrollArea);
mainLayout->addWidget(hr());
QBoxLayout *footerLayout = new QHBoxLayout;
footerLayout->addWidget(new StateLabel(State::Initial));
footerLayout->addWidget(new StateLabel(State::Running));
footerLayout->addWidget(new StateLabel(State::Success));
footerLayout->addWidget(new StateLabel(State::Error));
footerLayout->addWidget(new StateLabel(State::Canceled));
mainLayout->addLayout(footerLayout);
} }
// Task tree (takes initial configuation from GUI) // Task tree (takes initial configuation from GUI)
@@ -250,7 +265,9 @@ int main(int argc, char *argv[])
stopTaskTree(); stopTaskTree();
taskTree.reset(); taskTree.reset();
for (StateWidget *widget : allStateWidgets) for (GroupWidget *widget : allGroupWidgets)
widget->setState(State::Initial);
for (TaskWidget *widget : allTaskWidgets)
widget->setState(State::Initial); widget->setState(State::Initial);
progressBar->setValue(0); progressBar->setValue(0);
}; };

View File

@@ -26,8 +26,9 @@ static QColor stateToColor(State state) {
switch (state) { switch (state) {
case State::Initial: return Qt::gray; case State::Initial: return Qt::gray;
case State::Running: return Qt::yellow; case State::Running: return Qt::yellow;
case State::Done: return Qt::green; case State::Success: return Qt::green;
case State::Error: return Qt::red; case State::Error: return Qt::red;
case State::Canceled: return Qt::cyan;
} }
return {}; return {};
} }
@@ -35,9 +36,14 @@ static QColor stateToColor(State state) {
class StateIndicator : public QLabel class StateIndicator : public QLabel
{ {
public: public:
StateIndicator(QWidget *parent = nullptr) StateIndicator(State initialState = State::Initial, QWidget *parent = nullptr)
: QLabel(parent) : QLabel(parent)
, m_state(initialState)
{ {
setAlignment(Qt::AlignCenter);
QFont f = font();
f.setBold(true);
setFont(f);
m_progressIndicator = new ProgressIndicator(this); m_progressIndicator = new ProgressIndicator(this);
m_progressIndicator->hide(); m_progressIndicator->hide();
updateState(); updateState();
@@ -59,13 +65,20 @@ private:
m_progressIndicator->show(); m_progressIndicator->show();
else else
m_progressIndicator->hide(); m_progressIndicator->hide();
setText(m_state == State::Canceled ? "X" : "");
} }
State m_state = State::Initial; State m_state = State::Initial;
ProgressIndicator *m_progressIndicator = nullptr; ProgressIndicator *m_progressIndicator = nullptr;
}; };
StateWidget::StateWidget() StateWidget::StateWidget(State initialState)
: m_stateIndicator(new StateIndicator(this)) {} : m_stateIndicator(new StateIndicator(initialState, this))
{
QBoxLayout *layout = new QHBoxLayout(this);
layout->setContentsMargins(0, 0, 0, 0);
layout->addWidget(m_stateIndicator);
setFixedSize(30, 30);
}
void StateWidget::setState(State state) void StateWidget::setState(State state)
{ {
@@ -73,17 +86,17 @@ void StateWidget::setState(State state)
} }
TaskWidget::TaskWidget() TaskWidget::TaskWidget()
: m_infoLabel(new QLabel("Sleep:")) : m_stateWidget(new StateWidget)
, m_infoLabel(new QLabel("Sleep:"))
, m_spinBox(new QSpinBox) , m_spinBox(new QSpinBox)
, m_checkBox(new QCheckBox("Report success")) , m_checkBox(new QCheckBox("Report success"))
{ {
m_stateIndicator->setFixedSize(30, 30);
m_spinBox->setSuffix(" sec"); m_spinBox->setSuffix(" sec");
setBusyTime(1); setBusyTime(1);
setSuccess(true); setSuccess(true);
QBoxLayout *layout = new QHBoxLayout(this); QBoxLayout *layout = new QHBoxLayout(this);
layout->addWidget(m_stateIndicator); layout->addWidget(m_stateWidget);
layout->addWidget(m_infoLabel); layout->addWidget(m_infoLabel);
layout->addWidget(m_spinBox); layout->addWidget(m_spinBox);
layout->addWidget(m_checkBox); layout->addWidget(m_checkBox);
@@ -112,10 +125,11 @@ bool TaskWidget::isSuccess() const
} }
GroupWidget::GroupWidget() GroupWidget::GroupWidget()
: m_executeCombo(new QComboBox) : m_stateWidget(new StateWidget)
, m_executeCombo(new QComboBox)
, m_workflowCombo(new QComboBox) , m_workflowCombo(new QComboBox)
{ {
m_stateIndicator->setFixedWidth(30); m_stateWidget->setFixedSize(30, QWIDGETSIZE_MAX);
m_executeCombo->addItem("Sequential", int(ExecuteMode::Sequential)); m_executeCombo->addItem("Sequential", int(ExecuteMode::Sequential));
m_executeCombo->addItem("Parallel", int(ExecuteMode::Parallel)); m_executeCombo->addItem("Parallel", int(ExecuteMode::Parallel));
@@ -134,7 +148,7 @@ GroupWidget::GroupWidget()
}); });
QBoxLayout *layout = new QHBoxLayout(this); QBoxLayout *layout = new QHBoxLayout(this);
layout->addWidget(m_stateIndicator); layout->addWidget(m_stateWidget);
QBoxLayout *subLayout = new QVBoxLayout; QBoxLayout *subLayout = new QVBoxLayout;
subLayout->addWidget(new QLabel("Execute Mode:")); subLayout->addWidget(new QLabel("Execute Mode:"));
subLayout->addWidget(m_executeCombo); subLayout->addWidget(m_executeCombo);
@@ -178,3 +192,22 @@ GroupItem GroupWidget::workflowPolicy() const
{ {
return Tasking::workflowPolicy(m_workflowPolicy); return Tasking::workflowPolicy(m_workflowPolicy);
} }
static QString stateToString(State state)
{
switch (state) {
case State::Initial : return "Initial";
case State::Running : return "Running";
case State::Success : return "Success";
case State::Error : return "Error";
case State::Canceled : return "Canceled";
}
return "";
}
StateLabel::StateLabel(State state)
{
QBoxLayout *layout = new QHBoxLayout(this);
layout->addWidget(new StateWidget(state));
layout->addWidget(new QLabel(stateToString(state)));
}

View File

@@ -20,9 +20,9 @@ QT_END_NAMESPACE
enum class State { enum class State {
Initial, Initial,
Running, Running,
Done, // TODO: Rename to Success Success,
Error, Error,
// TODO: Add Canceled state Canceled
}; };
enum class ExecuteMode { enum class ExecuteMode {
@@ -33,35 +33,39 @@ enum class ExecuteMode {
class StateWidget : public QWidget class StateWidget : public QWidget
{ {
public: public:
StateWidget(); StateWidget(State initialState = State::Initial);
void setState(State state); void setState(State state);
protected: protected:
StateIndicator *m_stateIndicator = nullptr; StateIndicator *m_stateIndicator = nullptr;
}; };
class TaskWidget : public StateWidget class TaskWidget : public QWidget
{ {
public: public:
TaskWidget(); TaskWidget();
void setState(State state) { m_stateWidget->setState(state); }
void setBusyTime(int seconds); void setBusyTime(int seconds);
int busyTime() const; int busyTime() const;
void setSuccess(bool success); void setSuccess(bool success);
bool isSuccess() const; bool isSuccess() const;
private: private:
StateWidget *m_stateWidget = nullptr;
QLabel *m_infoLabel = nullptr; QLabel *m_infoLabel = nullptr;
QSpinBox *m_spinBox = nullptr; QSpinBox *m_spinBox = nullptr;
QCheckBox *m_checkBox = nullptr; QCheckBox *m_checkBox = nullptr;
}; };
class GroupWidget : public StateWidget class GroupWidget : public QWidget
{ {
public: public:
GroupWidget(); GroupWidget();
void setState(State state) { m_stateWidget->setState(state); }
void setExecuteMode(ExecuteMode mode); void setExecuteMode(ExecuteMode mode);
Tasking::GroupItem executeMode() const; Tasking::GroupItem executeMode() const;
@@ -72,6 +76,7 @@ private:
void updateExecuteMode(); void updateExecuteMode();
void updateWorkflowPolicy(); void updateWorkflowPolicy();
StateWidget *m_stateWidget = nullptr;
QComboBox *m_executeCombo = nullptr; QComboBox *m_executeCombo = nullptr;
QComboBox *m_workflowCombo = nullptr; QComboBox *m_workflowCombo = nullptr;
@@ -79,4 +84,10 @@ private:
Tasking::WorkflowPolicy m_workflowPolicy = Tasking::WorkflowPolicy::StopOnError; Tasking::WorkflowPolicy m_workflowPolicy = Tasking::WorkflowPolicy::StopOnError;
}; };
class StateLabel : public QWidget
{
public:
StateLabel(State state);
};
#endif // TASKWIDGET_H #endif // TASKWIDGET_H