Create download UI once and update existing UI with progress

Signed-off-by: AMZN-Phil <pconroy@amazon.com>
This commit is contained in:
AMZN-Phil
2021-11-02 16:16:37 -07:00
parent a661189ea9
commit 99ef2735b7
5 changed files with 148 additions and 80 deletions
@@ -41,6 +41,8 @@ namespace O3DE::ProjectManager
void DownloadController::AddGemDownload(const QString& gemName)
{
m_gemNames.push_back(gemName);
emit GemDownloadAdded(gemName);
if (m_gemNames.size() == 1)
{
m_worker->SetGemToDownload(m_gemNames[0], false);
@@ -62,6 +64,7 @@ namespace O3DE::ProjectManager
else
{
m_gemNames.erase(findResult);
emit GemDownloadRemoved(gemName);
}
}
}
@@ -69,7 +72,7 @@ namespace O3DE::ProjectManager
void DownloadController::UpdateUIProgress(int progress)
{
m_lastProgress = progress;
emit GemDownloadProgress(progress);
emit GemDownloadProgress(*m_gemNames.begin(), progress);
}
void DownloadController::HandleResults(const QString& result)
@@ -82,8 +85,9 @@ namespace O3DE::ProjectManager
succeeded = false;
}
QString gemName = *m_gemNames.begin();
m_gemNames.erase(m_gemNames.begin());
emit Done(succeeded);
emit Done(gemName, succeeded);
if (!m_gemNames.empty())
{
@@ -58,8 +58,10 @@ namespace O3DE::ProjectManager
signals:
void StartGemDownload(const QString& gemName);
void Done(bool success = true);
void GemDownloadProgress(int percentage);
void Done(const QString& gemName, bool success = true);
void GemDownloadAdded(const QString& gemName);
void GemDownloadRemoved(const QString& gemName);
void GemDownloadProgress(const QString& gemName, int percentage);
private:
DownloadWorker* m_worker;
@@ -30,6 +30,7 @@ namespace O3DE::ProjectManager
m_layout->setMargin(5);
m_layout->setAlignment(Qt::AlignTop);
setLayout(m_layout);
setMinimumHeight(400);
QHBoxLayout* hLayout = new QHBoxLayout();
@@ -119,6 +120,12 @@ namespace O3DE::ProjectManager
setWindowFlags(Qt::FramelessWindowHint | Qt::Dialog);
}
CartOverlayWidget::~CartOverlayWidget()
{
// disconnect from all download controller signals
disconnect(m_downloadController, nullptr, this, nullptr);
}
void CartOverlayWidget::CreateGemSection(const QString& singularTitle, const QString& pluralTitle, GetTagIndicesCallback getTagIndices)
{
QWidget* widget = new QWidget();
@@ -162,13 +169,13 @@ namespace O3DE::ProjectManager
void CartOverlayWidget::CreateDownloadSection()
{
QWidget* widget = new QWidget();
widget->setFixedWidth(s_width);
m_layout->addWidget(widget);
m_downloadSectionWidget = new QWidget();
m_downloadSectionWidget->setFixedWidth(s_width);
m_layout->addWidget(m_downloadSectionWidget);
QVBoxLayout* layout = new QVBoxLayout();
layout->setAlignment(Qt::AlignTop);
widget->setLayout(layout);
m_downloadSectionWidget->setLayout(layout);
QLabel* titleLabel = new QLabel();
titleLabel->setObjectName("GemCatalogCartOverlaySectionLabel");
@@ -187,82 +194,126 @@ namespace O3DE::ProjectManager
QLabel* processingQueueLabel = new QLabel("Processing Queue");
gemDownloadLayout->addWidget(processingQueueLabel);
QWidget* downloadingItemWidget = new QWidget();
downloadingItemWidget->setObjectName("GemCatalogCartOverlayGemDownloadBG");
gemDownloadLayout->addWidget(downloadingItemWidget);
m_downloadingListWidget = new QWidget();
m_downloadingListWidget->setObjectName("GemCatalogCartOverlayGemDownloadBG");
gemDownloadLayout->addWidget(m_downloadingListWidget);
QVBoxLayout* downloadingItemLayout = new QVBoxLayout();
downloadingItemLayout->setAlignment(Qt::AlignTop);
downloadingItemWidget->setLayout(downloadingItemLayout);
m_downloadingListWidget->setLayout(downloadingItemLayout);
auto update = [=](int downloadProgress)
QLabel* downloadsInProgessLabel = new QLabel("");
downloadsInProgessLabel->setObjectName("NumDownloadsInProgressLabel");
downloadingItemLayout->addWidget(downloadsInProgessLabel);
if (m_downloadController->IsDownloadQueueEmpty())
{
if (m_downloadController->IsDownloadQueueEmpty())
{
widget->hide();
}
else
{
widget->setUpdatesEnabled(false);
// remove items
QLayoutItem* layoutItem = nullptr;
while ((layoutItem = downloadingItemLayout->takeAt(0)) != nullptr)
{
if (layoutItem->layout())
{
// Gem info row
QLayoutItem* rowLayoutItem = nullptr;
while ((rowLayoutItem = layoutItem->layout()->takeAt(0)) != nullptr)
{
rowLayoutItem->widget()->deleteLater();
}
layoutItem->layout()->deleteLater();
}
if (layoutItem->widget())
{
layoutItem->widget()->deleteLater();
}
}
// Setup gem download rows
const AZStd::vector<QString>& downloadQueue = m_downloadController->GetDownloadQueue();
QLabel* downloadsInProgessLabel = new QLabel("");
downloadsInProgessLabel->setText(
QString("%1 %2").arg(downloadQueue.size()).arg(downloadQueue.size() == 1 ? tr("download in progress...") : tr("downloads in progress...")));
downloadingItemLayout->addWidget(downloadsInProgessLabel);
for (int downloadingGemNumber = 0; downloadingGemNumber < downloadQueue.size(); ++downloadingGemNumber)
{
QHBoxLayout* nameProgressLayout = new QHBoxLayout();
TagWidget* newTag = new TagWidget(downloadQueue[downloadingGemNumber]);
nameProgressLayout->addWidget(newTag);
QLabel* progress = new QLabel(downloadingGemNumber == 0? QString("%1%").arg(downloadProgress) : tr("Queued"));
nameProgressLayout->addWidget(progress);
QSpacerItem* spacer = new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum);
nameProgressLayout->addSpacerItem(spacer);
QLabel* cancelText = new QLabel(QString("<a href=\"%1\">Cancel</a>").arg(downloadQueue[downloadingGemNumber]));
cancelText->setTextInteractionFlags(Qt::LinksAccessibleByMouse);
connect(cancelText, &QLabel::linkActivated, this, &CartOverlayWidget::OnCancelDownloadActivated);
nameProgressLayout->addWidget(cancelText);
downloadingItemLayout->addLayout(nameProgressLayout);
QProgressBar* downloadProgessBar = new QProgressBar();
downloadingItemLayout->addWidget(downloadProgessBar);
downloadProgessBar->setValue(downloadingGemNumber == 0 ? downloadProgress : 0);
}
widget->setUpdatesEnabled(true);
widget->show();
}
};
auto downloadEnded = [=](bool /*success*/)
m_downloadSectionWidget->hide();
}
else
{
update(0); // update the list to remove the gem that has finished
};
// Setup gem download rows for gems that are already in the queue
const AZStd::vector<QString>& downloadQueue = m_downloadController->GetDownloadQueue();
for (int downloadingGemNumber = 0; downloadingGemNumber < downloadQueue.size(); ++downloadingGemNumber)
{
GemDownloadAdded(downloadQueue[downloadingGemNumber]);
}
}
// connect to download controller data changed
connect(m_downloadController, &DownloadController::GemDownloadProgress, this, update);
connect(m_downloadController, &DownloadController::Done, this, downloadEnded);
update(0);
connect(m_downloadController, &DownloadController::GemDownloadAdded, this, &CartOverlayWidget::GemDownloadAdded);
connect(m_downloadController, &DownloadController::GemDownloadRemoved, this, &CartOverlayWidget::GemDownloadRemoved);
connect(m_downloadController, &DownloadController::GemDownloadProgress, this, &CartOverlayWidget::GemDownloadProgress);
connect(m_downloadController, &DownloadController::Done, this, &CartOverlayWidget::GemDownloadComplete);
}
void CartOverlayWidget::GemDownloadAdded(const QString& gemName)
{
QWidget* newGemDownloadWidget = new QWidget();
newGemDownloadWidget->setObjectName(gemName);
QVBoxLayout* downloadingGemLayout = new QVBoxLayout();
newGemDownloadWidget->setLayout(downloadingGemLayout);
QHBoxLayout* nameProgressLayout = new QHBoxLayout();
TagWidget* newTag = new TagWidget(gemName);
nameProgressLayout->addWidget(newTag);
QLabel* progress = new QLabel(tr("Queued"));
progress->setObjectName("DownloadProgressLabel");
nameProgressLayout->addWidget(progress);
QSpacerItem* spacer = new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum);
nameProgressLayout->addSpacerItem(spacer);
QLabel* cancelText = new QLabel(QString("<a href=\"%1\">Cancel</a>").arg(gemName));
cancelText->setTextInteractionFlags(Qt::LinksAccessibleByMouse);
connect(cancelText, &QLabel::linkActivated, this, &CartOverlayWidget::OnCancelDownloadActivated);
nameProgressLayout->addWidget(cancelText);
downloadingGemLayout->addLayout(nameProgressLayout);
QProgressBar* downloadProgessBar = new QProgressBar();
downloadProgessBar->setObjectName("DownloadProgressBar");
downloadingGemLayout->addWidget(downloadProgessBar);
downloadProgessBar->setValue(0);
m_downloadingListWidget->layout()->addWidget(newGemDownloadWidget);
const AZStd::vector<QString>& downloadQueue = m_downloadController->GetDownloadQueue();
QLabel* numDownloads = m_downloadingListWidget->findChild<QLabel*>("NumDownloadsInProgressLabel");
numDownloads->setText(QString("%1 %2")
.arg(downloadQueue.size())
.arg(downloadQueue.size() == 1 ? tr("download in progress...") : tr("downloads in progress...")));
m_downloadingListWidget->show();
}
void CartOverlayWidget::GemDownloadRemoved(const QString& gemName)
{
QWidget* gemToRemove = m_downloadingListWidget->findChild<QWidget*>(gemName);
QLayout* gemToRemoveLayout = gemToRemove ? gemToRemove->layout() : nullptr;
if (gemToRemoveLayout)
{
QLayoutItem* rowLayoutItem = nullptr;
while ((rowLayoutItem = gemToRemoveLayout->layout()->takeAt(0)) != nullptr)
{
rowLayoutItem->widget()->deleteLater();
}
gemToRemoveLayout->layout()->deleteLater();
gemToRemove->deleteLater();
}
const AZStd::vector<QString>& downloadQueue = m_downloadController->GetDownloadQueue();
if (m_downloadController->IsDownloadQueueEmpty())
{
m_downloadSectionWidget->hide();
}
else
{
QLabel* numDownloads = m_downloadingListWidget->findChild<QLabel*>("NumDownloadsInProgressLabel");
numDownloads->setText(QString("%1 %2")
.arg(downloadQueue.size())
.arg(downloadQueue.size() == 1 ? tr("download in progress...") : tr("downloads in progress...")));
}
}
void CartOverlayWidget::GemDownloadProgress(const QString& gemName, int percentage)
{
QWidget* gemToUpdate = m_downloadingListWidget->findChild<QWidget*>(gemName);
if (gemToUpdate)
{
QLabel* progressLabel = gemToUpdate->findChild<QLabel*>("DownloadProgressLabel");
if (progressLabel)
{
progressLabel->setText(QString("%1%").arg(percentage));
}
QProgressBar* progressBar = gemToUpdate->findChild<QProgressBar*>("DownloadProgressBar");
if (progressBar)
{
progressBar->setValue(percentage);
}
}
}
void CartOverlayWidget::GemDownloadComplete(const QString& gemName, bool /*success*/)
{
GemDownloadRemoved(gemName); // update the list to remove the gem that has finished
}
QStringList CartOverlayWidget::ConvertFromModelIndices(const QVector<QModelIndex>& gems) const
@@ -34,6 +34,13 @@ namespace O3DE::ProjectManager
public:
CartOverlayWidget(GemModel* gemModel, DownloadController* downloadController, QWidget* parent = nullptr);
~CartOverlayWidget();
public slots:
void GemDownloadAdded(const QString& gemName);
void GemDownloadRemoved(const QString& gemName);
void GemDownloadProgress(const QString& gemName, int percentage);
void GemDownloadComplete(const QString& gemName, bool success);
private:
QStringList ConvertFromModelIndices(const QVector<QModelIndex>& gems) const;
@@ -47,6 +54,9 @@ namespace O3DE::ProjectManager
GemModel* m_gemModel = nullptr;
DownloadController* m_downloadController = nullptr;
QWidget* m_downloadSectionWidget = nullptr;
QWidget* m_downloadingListWidget = nullptr;
inline constexpr static int s_width = 240;
};
@@ -145,7 +145,7 @@ namespace O3DE::ProjectManager
}
}
void GemCatalogScreen::OnGemStatusChanged(const QModelIndex& modelIndex, uint32_t numChangedDependencies)
void GemCatalogScreen::OnGemStatusChanged(const QModelIndex& modelIndex, uint32_t numChangedDependencies)
{
if (m_notificationsEnabled)
{
@@ -170,6 +170,7 @@ namespace O3DE::ProjectManager
if (added && GemModel::GetDownloadStatus(modelIndex) == GemInfo::DownloadStatus::NotDownloaded)
{
m_downloadController->AddGemDownload(GemModel::GetName(modelIndex));
GemModel::SetDownloadStatus(*m_proxModel, modelIndex, GemInfo::DownloadStatus::Downloading);
}
}
@@ -187,7 +188,7 @@ namespace O3DE::ProjectManager
toastConfiguration.m_customIconImage = ":/gem.svg";
toastConfiguration.m_borderRadius = 4;
toastConfiguration.m_duration = AZStd::chrono::milliseconds(3000);
m_notificationsView->ShowToastNotification(toastConfiguration);
//m_notificationsView->ShowToastNotification(toastConfiguration);
}
}