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 <QBoxLayout>
#include <QGroupBox>
#include <QLabel>
#include <QProgressBar>
#include <QScrollArea>
#include <QTimer>
@@ -44,7 +45,12 @@ static QWidget *taskGroup(QWidget *groupWidget, const QList<QWidget *> &widgets)
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[])
@@ -69,16 +75,17 @@ int main(int argc, char *argv[])
// Task GUI
QList<StateWidget *> allStateWidgets;
QList<GroupWidget *> allGroupWidgets;
QList<TaskWidget *> allTaskWidgets;
auto createGroupWidget = [&allStateWidgets] {
auto *widget = new GroupWidget();
allStateWidgets.append(widget);
auto createGroupWidget = [&allGroupWidgets] {
auto *widget = new GroupWidget;
allGroupWidgets.append(widget);
return widget;
};
auto createTaskWidget = [&allStateWidgets] {
auto *widget = new TaskWidget();
allStateWidgets.append(widget);
auto createTaskWidget = [&allTaskWidgets] {
auto *widget = new TaskWidget;
allTaskWidgets.append(widget);
return widget;
};
@@ -162,6 +169,14 @@ int main(int argc, char *argv[])
mainLayout->addLayout(subLayout);
mainLayout->addWidget(hr());
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)
@@ -250,7 +265,9 @@ int main(int argc, char *argv[])
stopTaskTree();
taskTree.reset();
for (StateWidget *widget : allStateWidgets)
for (GroupWidget *widget : allGroupWidgets)
widget->setState(State::Initial);
for (TaskWidget *widget : allTaskWidgets)
widget->setState(State::Initial);
progressBar->setValue(0);
};

View File

@@ -26,8 +26,9 @@ static QColor stateToColor(State state) {
switch (state) {
case State::Initial: return Qt::gray;
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::Canceled: return Qt::cyan;
}
return {};
}
@@ -35,9 +36,14 @@ static QColor stateToColor(State state) {
class StateIndicator : public QLabel
{
public:
StateIndicator(QWidget *parent = nullptr)
StateIndicator(State initialState = State::Initial, QWidget *parent = nullptr)
: QLabel(parent)
, m_state(initialState)
{
setAlignment(Qt::AlignCenter);
QFont f = font();
f.setBold(true);
setFont(f);
m_progressIndicator = new ProgressIndicator(this);
m_progressIndicator->hide();
updateState();
@@ -59,13 +65,20 @@ private:
m_progressIndicator->show();
else
m_progressIndicator->hide();
setText(m_state == State::Canceled ? "X" : "");
}
State m_state = State::Initial;
ProgressIndicator *m_progressIndicator = nullptr;
};
StateWidget::StateWidget()
: m_stateIndicator(new StateIndicator(this)) {}
StateWidget::StateWidget(State initialState)
: 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)
{
@@ -73,17 +86,17 @@ void StateWidget::setState(State state)
}
TaskWidget::TaskWidget()
: m_infoLabel(new QLabel("Sleep:"))
: m_stateWidget(new StateWidget)
, m_infoLabel(new QLabel("Sleep:"))
, m_spinBox(new QSpinBox)
, m_checkBox(new QCheckBox("Report success"))
{
m_stateIndicator->setFixedSize(30, 30);
m_spinBox->setSuffix(" sec");
setBusyTime(1);
setSuccess(true);
QBoxLayout *layout = new QHBoxLayout(this);
layout->addWidget(m_stateIndicator);
layout->addWidget(m_stateWidget);
layout->addWidget(m_infoLabel);
layout->addWidget(m_spinBox);
layout->addWidget(m_checkBox);
@@ -112,10 +125,11 @@ bool TaskWidget::isSuccess() const
}
GroupWidget::GroupWidget()
: m_executeCombo(new QComboBox)
: m_stateWidget(new StateWidget)
, m_executeCombo(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("Parallel", int(ExecuteMode::Parallel));
@@ -134,7 +148,7 @@ GroupWidget::GroupWidget()
});
QBoxLayout *layout = new QHBoxLayout(this);
layout->addWidget(m_stateIndicator);
layout->addWidget(m_stateWidget);
QBoxLayout *subLayout = new QVBoxLayout;
subLayout->addWidget(new QLabel("Execute Mode:"));
subLayout->addWidget(m_executeCombo);
@@ -178,3 +192,22 @@ GroupItem GroupWidget::workflowPolicy() const
{
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 {
Initial,
Running,
Done, // TODO: Rename to Success
Success,
Error,
// TODO: Add Canceled state
Canceled
};
enum class ExecuteMode {
@@ -33,35 +33,39 @@ enum class ExecuteMode {
class StateWidget : public QWidget
{
public:
StateWidget();
StateWidget(State initialState = State::Initial);
void setState(State state);
protected:
StateIndicator *m_stateIndicator = nullptr;
};
class TaskWidget : public StateWidget
class TaskWidget : public QWidget
{
public:
TaskWidget();
void setState(State state) { m_stateWidget->setState(state); }
void setBusyTime(int seconds);
int busyTime() const;
void setSuccess(bool success);
bool isSuccess() const;
private:
StateWidget *m_stateWidget = nullptr;
QLabel *m_infoLabel = nullptr;
QSpinBox *m_spinBox = nullptr;
QCheckBox *m_checkBox = nullptr;
};
class GroupWidget : public StateWidget
class GroupWidget : public QWidget
{
public:
GroupWidget();
void setState(State state) { m_stateWidget->setState(state); }
void setExecuteMode(ExecuteMode mode);
Tasking::GroupItem executeMode() const;
@@ -72,6 +76,7 @@ private:
void updateExecuteMode();
void updateWorkflowPolicy();
StateWidget *m_stateWidget = nullptr;
QComboBox *m_executeCombo = nullptr;
QComboBox *m_workflowCombo = nullptr;
@@ -79,4 +84,10 @@ private:
Tasking::WorkflowPolicy m_workflowPolicy = Tasking::WorkflowPolicy::StopOnError;
};
class StateLabel : public QWidget
{
public:
StateLabel(State state);
};
#endif // TASKWIDGET_H