From c975247f9742bd7fcf5ae7d8ab174ed8728bb64c Mon Sep 17 00:00:00 2001 From: Bent Bisballe Nyeng Date: Sat, 29 Sep 2018 12:25:33 +0200 Subject: Improve UI of render dialog. --- icons/Makefile.am | 13 ++- icons/task_done.png | Bin 0 -> 1189 bytes icons/task_error.png | Bin 0 -> 1314 bytes icons/task_running.png | Bin 0 -> 1523 bytes icons/task_waiting.png | Bin 0 -> 1448 bytes src/dgedit.qrc | 8 +- src/renderdialog.cc | 279 ++++++++++++++++++++++++++++++++++++++++++++++--- src/renderdialog.h | 12 ++- 8 files changed, 292 insertions(+), 20 deletions(-) create mode 100644 icons/task_done.png create mode 100644 icons/task_error.png create mode 100644 icons/task_running.png create mode 100644 icons/task_waiting.png diff --git a/icons/Makefile.am b/icons/Makefile.am index b838804..3c1ed16 100644 --- a/icons/Makefile.am +++ b/icons/Makefile.am @@ -1,3 +1,14 @@ EXTRA_DIST = \ + master.png \ file.png \ - master.png \ No newline at end of file + instrument.png \ + add_instrument.png \ + edit_instrument.png \ + remove_instrument.png \ + channel.png \ + add_channel.png \ + remove_channel.png \ + task_waiting.png \ + task_running.png \ + task_done.png \ + task_error.png diff --git a/icons/task_done.png b/icons/task_done.png new file mode 100644 index 0000000..d48b86c Binary files /dev/null and b/icons/task_done.png differ diff --git a/icons/task_error.png b/icons/task_error.png new file mode 100644 index 0000000..6f4ec36 Binary files /dev/null and b/icons/task_error.png differ diff --git a/icons/task_running.png b/icons/task_running.png new file mode 100644 index 0000000..cc3f20f Binary files /dev/null and b/icons/task_running.png differ diff --git a/icons/task_waiting.png b/icons/task_waiting.png new file mode 100644 index 0000000..cbf288b Binary files /dev/null and b/icons/task_waiting.png differ diff --git a/src/dgedit.qrc b/src/dgedit.qrc index 4e76459..1b03641 100644 --- a/src/dgedit.qrc +++ b/src/dgedit.qrc @@ -1,6 +1,6 @@ - + ../icons/master.png ../icons/file.png ../icons/instrument.png @@ -10,5 +10,9 @@ ../icons/channel.png ../icons/add_channel.png ../icons/remove_channel.png - + ../icons/task_waiting.png + ../icons/task_running.png + ../icons/task_done.png + ../icons/task_error.png + diff --git a/src/renderdialog.cc b/src/renderdialog.cc index 873e610..b75ad78 100644 --- a/src/renderdialog.cc +++ b/src/renderdialog.cc @@ -32,14 +32,242 @@ #include #include #include +#include +#include +#include +#include +#include #include "project.h" +class ProgressDelegate + : public QStyledItemDelegate +{ +// Q_OBJECT + +public: + ProgressDelegate(Project& project, QObject *parent) + : QStyledItemDelegate(parent) + , project(project) + { + } + + void paint(QPainter *painter, + const QStyleOptionViewItem &option, + const QModelIndex &index ) const override + { + if(/*index.row() == current_row &&*/ + index.column() == 2 && + index.parent() == QModelIndex()) + { + QStyleOptionProgressBar progressBarOption; + progressBarOption.state = QStyle::State_Enabled; + progressBarOption.direction = QApplication::layoutDirection(); + progressBarOption.rect = option.rect; + progressBarOption.fontMetrics = QApplication::fontMetrics(); + progressBarOption.minimum = 0; + progressBarOption.textAlignment = Qt::AlignCenter; + progressBarOption.textVisible = true; + + if(index.row() == current_row) + { + // Current task + progressBarOption.maximum = progress_max; + progressBarOption.progress = progress; + } + else if(index.row() < current_row) + { + // Finished task + progressBarOption.maximum = 100; + progressBarOption.progress = 100; + } + else + { + // Waiting task + progressBarOption.maximum = 100; + progressBarOption.progress = 0; + } + QApplication::style()->drawControl(QStyle::CE_ProgressBar, + &progressBarOption, painter); + } + else + { + QStyledItemDelegate::paint(painter, option, index); + } + } + + void setActiveTask(int current_instrument_id) + { + auto instrument_ids = project.getInstrumentList(); + current_row = 0; + for(auto instrument_id : instrument_ids) + { + if(current_instrument_id == instrument_id) + { + return; + } + current_row++; + } + + // current_row will be one above the row count here + } + + void setProgressMaximum(int progress_max) + { + this->progress_max = progress_max; + } + + void setProgress(int progress) + { + this->progress = progress; + } + +private: + Project& project; + int progress{0}; + int progress_max{100}; + int current_row{-1}; +}; + +class RenderDataModel + : public QAbstractItemModel +{ +public: + RenderDataModel(Project& project) + : project(project) + { + } + + QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override + { + if(!hasIndex(row, column, parent)) + { + return QModelIndex(); + } + + if(!parent.isValid()) + { + auto instrument_ids = project.getInstrumentList(); + if(row < instrument_ids.size()) + { + return createIndex(row, column, (void*)42); + } + else + { + return QModelIndex(); // row is out of bounds. + } + } + + return QModelIndex(); + } + + QModelIndex parent(const QModelIndex &index) const override + { + return QModelIndex(); // no parent + } + + int rowCount(const QModelIndex &parent = QModelIndex()) const override + { + if(parent.column() > 0) // only return row count on first column + { + return 0; + } + + if(!parent.isValid()) + { + auto instrument_ids = project.getInstrumentList(); + return instrument_ids.size(); + } + + return 0; // no children + } + + int columnCount(const QModelIndex &parent = QModelIndex()) const override + { + return 3; // icon, text, progressbar + } + + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override + { + if(!index.isValid()) + { + return QVariant(); + } + + if(role == Qt::DecorationRole ) + { + if(index.column() == 0) + { + if(index.row() < current_row) + { + return QPixmap(":/icons/task_done.png"); + } + else if(index.row() == current_row) + { + //return QPixmap(":/icons/task_error.png"); + return QPixmap(":/icons/task_running.png"); + } + else + { + return QPixmap(":/icons/task_waiting.png"); + } + } + } + + if(role == Qt::DisplayRole) + { + auto instrument_ids = project.getInstrumentList(); + auto instrument_id = instrument_ids.begin() + index.row(); + const auto& instrument = project.getInstrument(*instrument_id); + switch(index.column()) + { + case 1: return instrument.getInstrumentName(); + default: return QVariant(); + } + } + + return QVariant(); + } + + QVariant headerData(int section, Qt::Orientation orientation, int role) const override + { + return QVariant(); + } + + void refresh() + { + beginResetModel(); + endResetModel(); + } + + void setActiveTask(int current_instrument_id) + { + auto instrument_ids = project.getInstrumentList(); + current_row = 0; + for(auto instrument_id : instrument_ids) + { + if(current_instrument_id == instrument_id) + { + return; + } + current_row++; + } + + // current_row will be one above the row count here + } + +private: + Project& project; + int current_row{-1}; +}; + RenderDialog::RenderDialog(QWidget* parent, Project& project) : QDialog(parent) , project(project) , renderer(project) { + model = new RenderDataModel(project); + auto vl = new QVBoxLayout(); setLayout(vl); @@ -58,24 +286,29 @@ RenderDialog::RenderDialog(QWidget* parent, Project& project) } auto btn = new QPushButton(this); - btn->setText("Click me"); + btn->setText(tr("Export")); connect(btn, SIGNAL(clicked()), this, SLOT(render())); - //connect(btn, SIGNAL(clicked()), this, SLOT(close())); + connect(btn, SIGNAL(clicked()), btn, SLOT(disable())); layout()->addWidget(btn); - bar1 = new QProgressBar(this); + bar = new QProgressBar(this); connect(&renderer, SIGNAL(progressStart(int)), - bar1, SLOT(setMaximum(int))); - layout()->addWidget(bar1); + bar, SLOT(setMaximum(int))); + layout()->addWidget(bar); - bar2 = new QProgressBar(this); connect(&renderer, SIGNAL(progressRenderStart(int)), - bar2, SLOT(setMaximum(int))); + this, SLOT(progressRenderStart(int))); connect(&renderer, SIGNAL(progressRenderTask(int)), - bar2, SLOT(setValue(int))); - layout()->addWidget(bar2); + this, SLOT(progressRenderTask(int))); + + tasks = new QTreeView(this); + tasks->setModel(model); + tasks->setHeaderHidden(true); + tasks->setRootIsDecorated(false); + tasks->header()->resizeSection(0, 24); + delegate = new ProgressDelegate(project, this); + tasks->setItemDelegate(delegate); - tasks = new QListWidget(this); // connect(&renderer, SIGNAL(progressTask(QString)), // tasks, SLOT(addItem(QString))); layout()->addWidget(tasks); @@ -88,7 +321,7 @@ RenderDialog::RenderDialog(QWidget* parent, Project& project) void RenderDialog::render() { - bar1->setValue(1); + bar->setValue(1); renderer.render(); } @@ -98,20 +331,40 @@ void RenderDialog::progressStart(int total) void RenderDialog::progressTask(QString text) { - tasks->addItem(text); + //tasks->addItem(text); } void RenderDialog::progressRenderStart(int tasktotal) { + auto task = bar->value(); + + auto instrument_ids = project.getInstrumentList(); + auto instrument_id = instrument_ids.begin() + (task - 1); + delegate->setActiveTask(*instrument_id); + model->setActiveTask(*instrument_id); + + delegate->setProgressMaximum(tasktotal); + model->refresh(); } void RenderDialog::progressRenderTask(int subtask) { + delegate->setProgress(subtask); + model->refresh(); } void RenderDialog::progressRenderFinished(int success) { - bar1->setValue(bar1->value() + 1); + auto task = bar->value(); + + // Search past the last instriment id to mark all tasks as finished + auto instrument_ids = project.getInstrumentList(); + auto instrument_id = instrument_ids.begin() + task; + delegate->setActiveTask(*instrument_id); // note this id is invalid + model->setActiveTask(*instrument_id); // note this id is invalid + + bar->setValue(task + 1); + model->refresh(); } void RenderDialog::progressFinished(int success) diff --git a/src/renderdialog.h b/src/renderdialog.h index eb1e531..f940617 100644 --- a/src/renderdialog.h +++ b/src/renderdialog.h @@ -28,11 +28,13 @@ #include #include -#include +#include #include "projectrenderer.h" class Project; +class RenderDataModel; +class ProgressDelegate; class RenderDialog : public QDialog @@ -60,8 +62,10 @@ private: ProjectRenderer renderer; QLineEdit* export_path; - QProgressBar* bar1; - QProgressBar* bar2; + QProgressBar* bar; - QListWidget* tasks; + QTreeView* tasks; + + RenderDataModel* model; + ProgressDelegate* delegate; }; -- cgit v1.2.3