feat+refactor: clean up ProgressWidget and add progress indicatior to

mod downloader

Signed-off-by: flow <flowlnlnln@gmail.com>
This commit is contained in:
flow 2022-07-15 13:18:12 -03:00
parent c3f647dc96
commit 158b7fd166
No known key found for this signature in database
GPG Key ID: 8D0F221F0A59F469
5 changed files with 118 additions and 45 deletions

View File

@ -30,6 +30,7 @@ class ListModel : public QAbstractListModel {
auto data(const QModelIndex& index, int role) const -> QVariant override;
inline void setActiveJob(NetJob::Ptr ptr) { jobPtr = ptr; }
inline NetJob* activeJob() { return jobPtr.get(); }
/* Ask the API for more information */
void fetchMore(const QModelIndex& parent) override;

View File

@ -53,6 +53,7 @@ ModPage::ModPage(ModDownloadDialog* dialog, BaseInstance* instance, ModAPI* api)
, ui(new Ui::ModPage)
, dialog(dialog)
, filter_widget(static_cast<MinecraftInstance*>(instance)->getPackProfile()->getComponentVersion("net.minecraft"), this)
, m_fetch_progress(this, false)
, api(api)
{
ui->setupUi(this);
@ -70,7 +71,12 @@ ModPage::ModPage(ModDownloadDialog* dialog, BaseInstance* instance, ModAPI* api)
ui->versionSelectionBox->view()->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
ui->versionSelectionBox->view()->parentWidget()->setMaximumHeight(300);
ui->gridLayout_3->addWidget(&filter_widget, 0, 0, 1, ui->gridLayout_3->columnCount());
m_fetch_progress.hideIfInactive(true);
m_fetch_progress.setFixedHeight(24);
m_fetch_progress.progressFormat("");
ui->gridLayout_3->addWidget(&m_fetch_progress, 0, 0, 1, ui->gridLayout_3->columnCount());
ui->gridLayout_3->addWidget(&filter_widget, 1, 0, 1, ui->gridLayout_3->columnCount());
filter_widget.setInstance(static_cast<MinecraftInstance*>(m_instance));
m_filter = filter_widget.getFilter();
@ -151,6 +157,7 @@ void ModPage::triggerSearch()
}
listModel->searchWithTerm(getSearchTerm(), ui->sortByBox->currentIndex(), changed);
m_fetch_progress.watch(listModel->activeJob());
}
QString ModPage::getSearchTerm() const

View File

@ -8,6 +8,7 @@
#include "ui/pages/BasePage.h"
#include "ui/pages/modplatform/ModModel.h"
#include "ui/widgets/ModFilterWidget.h"
#include "ui/widgets/ProgressWidget.h"
class ModDownloadDialog;
@ -75,6 +76,8 @@ class ModPage : public QWidget, public BasePage {
ModFilterWidget filter_widget;
std::shared_ptr<ModFilterWidget::Filter> m_filter;
ProgressWidget m_fetch_progress;
ModPlatform::ListModel* listModel = nullptr;
ModPlatform::IndexedPack current;

View File

@ -1,66 +1,104 @@
// Licensed under the Apache-2.0 license. See README.md for details.
#include "ProgressWidget.h"
#include <QProgressBar>
#include <QLabel>
#include <QVBoxLayout>
#include <QEventLoop>
#include <QLabel>
#include <QProgressBar>
#include <QVBoxLayout>
#include "tasks/Task.h"
ProgressWidget::ProgressWidget(QWidget *parent)
: QWidget(parent)
ProgressWidget::ProgressWidget(QWidget* parent, bool show_label) : QWidget(parent)
{
m_label = new QLabel(this);
m_label->setWordWrap(true);
auto* layout = new QVBoxLayout(this);
if (show_label) {
m_label = new QLabel(this);
m_label->setWordWrap(true);
layout->addWidget(m_label);
}
m_bar = new QProgressBar(this);
m_bar->setMinimum(0);
m_bar->setMaximum(100);
QVBoxLayout *layout = new QVBoxLayout(this);
layout->addWidget(m_label);
layout->addWidget(m_bar);
layout->addStretch();
setLayout(layout);
}
void ProgressWidget::start(std::shared_ptr<Task> task)
void ProgressWidget::reset()
{
if (m_task)
{
disconnect(m_task.get(), 0, this, 0);
}
m_task = task;
connect(m_task.get(), &Task::finished, this, &ProgressWidget::handleTaskFinish);
connect(m_task.get(), &Task::status, this, &ProgressWidget::handleTaskStatus);
connect(m_task.get(), &Task::progress, this, &ProgressWidget::handleTaskProgress);
connect(m_task.get(), &Task::destroyed, this, &ProgressWidget::taskDestroyed);
if (!m_task->isRunning())
{
QMetaObject::invokeMethod(m_task.get(), "start", Qt::QueuedConnection);
}
m_bar->reset();
}
void ProgressWidget::progressFormat(QString format)
{
if (format.isEmpty())
m_bar->setTextVisible(false);
else
m_bar->setFormat(format);
}
void ProgressWidget::watch(Task* task)
{
if (!task)
return;
if (m_task)
disconnect(m_task, nullptr, this, nullptr);
m_task = task;
connect(m_task, &Task::finished, this, &ProgressWidget::handleTaskFinish);
connect(m_task, &Task::status, this, &ProgressWidget::handleTaskStatus);
connect(m_task, &Task::progress, this, &ProgressWidget::handleTaskProgress);
connect(m_task, &Task::destroyed, this, &ProgressWidget::taskDestroyed);
show();
}
void ProgressWidget::start(Task* task)
{
watch(task);
if (!m_task->isRunning())
QMetaObject::invokeMethod(m_task, "start", Qt::QueuedConnection);
}
bool ProgressWidget::exec(std::shared_ptr<Task> task)
{
QEventLoop loop;
connect(task.get(), &Task::finished, &loop, &QEventLoop::quit);
start(task);
start(task.get());
if (task->isRunning())
{
loop.exec();
}
return task->wasSuccessful();
}
void ProgressWidget::show()
{
setHidden(false);
}
void ProgressWidget::hide()
{
setHidden(true);
}
void ProgressWidget::handleTaskFinish()
{
if (!m_task->wasSuccessful())
{
if (!m_task->wasSuccessful() && m_label)
m_label->setText(m_task->failReason());
}
if (m_hide_if_inactive)
hide();
}
void ProgressWidget::handleTaskStatus(const QString &status)
void ProgressWidget::handleTaskStatus(const QString& status)
{
m_label->setText(status);
if (m_label)
m_label->setText(status);
}
void ProgressWidget::handleTaskProgress(qint64 current, qint64 total)
{

View File

@ -9,24 +9,48 @@ class Task;
class QProgressBar;
class QLabel;
class ProgressWidget : public QWidget
{
class ProgressWidget : public QWidget {
Q_OBJECT
public:
explicit ProgressWidget(QWidget *parent = nullptr);
public:
explicit ProgressWidget(QWidget* parent = nullptr, bool show_label = true);
public slots:
void start(std::shared_ptr<Task> task);
/** Whether to hide the widget automatically if it's watching no running task. */
void hideIfInactive(bool hide) { m_hide_if_inactive = hide; }
/** Reset the displayed progress to 0 */
void reset();
/** The text that shows up in the middle of the progress bar.
* By default it's '%p%', with '%p' being the total progress in percentage.
*/
void progressFormat(QString);
public slots:
/** Watch the progress of a task. */
void watch(Task* task);
/** Watch the progress of a task, and start it if needed */
void start(Task* task);
/** Blocking way of waiting for a task to finish. */
bool exec(std::shared_ptr<Task> task);
private slots:
/** Un-hide the widget if needed. */
void show();
/** Make the widget invisible. */
void hide();
private slots:
void handleTaskFinish();
void handleTaskStatus(const QString &status);
void handleTaskStatus(const QString& status);
void handleTaskProgress(qint64 current, qint64 total);
void taskDestroyed();
private:
QLabel *m_label;
QProgressBar *m_bar;
std::shared_ptr<Task> m_task;
private:
QLabel* m_label = nullptr;
QProgressBar* m_bar = nullptr;
Task* m_task = nullptr;
bool m_hide_if_inactive = false;
};