Signed-off-by: AMZN-alexpete <26804013+AMZN-alexpete@users.noreply.github.com>
This commit is contained in:
@@ -22,6 +22,7 @@ namespace AzQtComponents
|
||||
, m_closeOnClick(true)
|
||||
, m_ui(new Ui::ToastNotification())
|
||||
, m_fadeAnimation(nullptr)
|
||||
, m_configuration(toastConfiguration)
|
||||
{
|
||||
setProperty("HasNoWindowDecorations", true);
|
||||
|
||||
@@ -80,7 +81,13 @@ namespace AzQtComponents
|
||||
}
|
||||
|
||||
ToastNotification::~ToastNotification()
|
||||
{
|
||||
{
|
||||
}
|
||||
|
||||
bool ToastNotification::IsDuplicate(const ToastConfiguration& toastConfiguration)
|
||||
{
|
||||
return toastConfiguration.m_title == m_configuration.m_title
|
||||
&& toastConfiguration.m_description == m_configuration.m_description;
|
||||
}
|
||||
|
||||
void ToastNotification::paintEvent(QPaintEvent* event)
|
||||
|
||||
@@ -45,6 +45,8 @@ namespace AzQtComponents
|
||||
void ShowToastAtPoint(const QPoint& screenPosition, const QPointF& anchorPoint);
|
||||
|
||||
void UpdatePosition(const QPoint& screenPosition, const QPointF& anchorPoint);
|
||||
|
||||
bool IsDuplicate(const ToastConfiguration& toastConfiguration);
|
||||
|
||||
// QDialog
|
||||
void showEvent(QShowEvent* showEvent) override;
|
||||
@@ -64,7 +66,7 @@ namespace AzQtComponents
|
||||
|
||||
private:
|
||||
QPropertyAnimation* m_fadeAnimation;
|
||||
|
||||
ToastConfiguration m_configuration;
|
||||
bool m_closeOnClick;
|
||||
QTimer m_lifeSpan;
|
||||
uint32_t m_borderRadius = 0;
|
||||
|
||||
+34
@@ -63,6 +63,12 @@ namespace AzToolsFramework
|
||||
|
||||
ToastId ToastNotificationsView::ShowToastNotification(const AzQtComponents::ToastConfiguration& toastConfiguration)
|
||||
{
|
||||
// reject duplicate messages
|
||||
if (m_rejectDuplicates && DuplicateNotificationInQueue(toastConfiguration))
|
||||
{
|
||||
return ToastId();
|
||||
}
|
||||
|
||||
ToastId toastId = CreateToastNotification(toastConfiguration);
|
||||
m_queuedNotifications.emplace_back(toastId);
|
||||
|
||||
@@ -70,10 +76,28 @@ namespace AzToolsFramework
|
||||
{
|
||||
DisplayQueuedNotification();
|
||||
}
|
||||
else if (m_queuedNotifications.size() >= m_maxQueuedNotifications)
|
||||
{
|
||||
// hiding the active toast will cause the next toast to be displayed
|
||||
HideToastNotification(m_activeNotification);
|
||||
}
|
||||
|
||||
return toastId;
|
||||
}
|
||||
|
||||
bool ToastNotificationsView::DuplicateNotificationInQueue(const AzQtComponents::ToastConfiguration& toastConfiguration)
|
||||
{
|
||||
for (auto iter : m_notifications)
|
||||
{
|
||||
if (iter.second && iter.second->IsDuplicate(toastConfiguration))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
ToastId ToastNotificationsView::ShowToastAtCursor(const AzQtComponents::ToastConfiguration& toastConfiguration)
|
||||
{
|
||||
ToastId toastId = CreateToastNotification(toastConfiguration);
|
||||
@@ -187,4 +211,14 @@ namespace AzToolsFramework
|
||||
{
|
||||
m_anchorPoint = anchorPoint;
|
||||
}
|
||||
|
||||
void ToastNotificationsView::SetMaxQueuedNotifications(AZ::u32 maxQueuedNotifications)
|
||||
{
|
||||
m_maxQueuedNotifications = maxQueuedNotifications;
|
||||
}
|
||||
|
||||
void ToastNotificationsView::SetRejectDuplicates(bool rejectDuplicates)
|
||||
{
|
||||
m_rejectDuplicates = rejectDuplicates;
|
||||
}
|
||||
}
|
||||
|
||||
+5
@@ -52,10 +52,13 @@ namespace AzToolsFramework
|
||||
|
||||
void SetOffset(const QPoint& offset);
|
||||
void SetAnchorPoint(const QPointF& anchorPoint);
|
||||
void SetMaxQueuedNotifications(AZ::u32 maxQueuedNotifications);
|
||||
void SetRejectDuplicates(bool rejectDuplicates);
|
||||
|
||||
private:
|
||||
ToastId CreateToastNotification(const AzQtComponents::ToastConfiguration& toastConfiguration);
|
||||
void DisplayQueuedNotification();
|
||||
bool DuplicateNotificationInQueue(const AzQtComponents::ToastConfiguration& toastConfiguration);
|
||||
QPoint GetGlobalPoint();
|
||||
|
||||
ToastId m_activeNotification;
|
||||
@@ -64,5 +67,7 @@ namespace AzToolsFramework
|
||||
|
||||
QPoint m_offset = QPoint(10, 10);
|
||||
QPointF m_anchorPoint = QPointF(1, 0);
|
||||
AZ::u32 m_maxQueuedNotifications = 5;
|
||||
bool m_rejectDuplicates = true;
|
||||
};
|
||||
} // AzToolsFramework
|
||||
|
||||
@@ -42,7 +42,9 @@ namespace O3DE::ProjectManager
|
||||
m_headerWidget = new GemCatalogHeaderWidget(m_gemModel, m_proxModel, m_downloadController);
|
||||
vLayout->addWidget(m_headerWidget);
|
||||
|
||||
connect(m_gemModel, &GemModel::gemStatusChanged, this, &GemCatalogScreen::OnGemStatusChanged);
|
||||
connect(m_headerWidget, &GemCatalogHeaderWidget::OpenGemsRepo, this, &GemCatalogScreen::HandleOpenGemRepo);
|
||||
connect(m_headerWidget, &GemCatalogHeaderWidget::AddGem, this, &GemCatalogScreen::OnAddGemClicked);
|
||||
|
||||
QHBoxLayout* hLayout = new QHBoxLayout();
|
||||
hLayout->setMargin(0);
|
||||
@@ -73,6 +75,7 @@ namespace O3DE::ProjectManager
|
||||
|
||||
m_notificationsView = AZStd::make_unique<AzToolsFramework::ToastNotificationsView>(this, AZ_CRC("GemCatalogNotificationsView"));
|
||||
m_notificationsView->SetOffset(QPoint(10, 70));
|
||||
m_notificationsView->SetMaxQueuedNotifications(1);
|
||||
}
|
||||
|
||||
void GemCatalogScreen::ReinitForProject(const QString& projectPath)
|
||||
@@ -94,48 +97,6 @@ namespace O3DE::ProjectManager
|
||||
m_headerWidget->ReinitForProject();
|
||||
|
||||
connect(m_gemModel, &GemModel::dataChanged, m_filterWidget, &GemFilterWidget::ResetGemStatusFilter);
|
||||
connect(m_gemModel, &GemModel::gemStatusChanged, this, &GemCatalogScreen::OnGemStatusChanged);
|
||||
connect(
|
||||
m_headerWidget, &GemCatalogHeaderWidget::AddGem,
|
||||
[&]()
|
||||
{
|
||||
EngineInfo engineInfo;
|
||||
QString defaultPath;
|
||||
|
||||
AZ::Outcome<EngineInfo> engineInfoResult = PythonBindingsInterface::Get()->GetEngineInfo();
|
||||
if (engineInfoResult.IsSuccess())
|
||||
{
|
||||
engineInfo = engineInfoResult.GetValue();
|
||||
defaultPath = engineInfo.m_defaultGemsFolder;
|
||||
}
|
||||
|
||||
if (defaultPath.isEmpty())
|
||||
{
|
||||
defaultPath = QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation);
|
||||
}
|
||||
|
||||
QString directory = QDir::toNativeSeparators(QFileDialog::getExistingDirectory(this, tr("Browse"), defaultPath));
|
||||
if (!directory.isEmpty())
|
||||
{
|
||||
// register the gem to the o3de_manifest.json and to the project after the user confirms
|
||||
// project creation/update
|
||||
auto registerResult = PythonBindingsInterface::Get()->RegisterGem(directory);
|
||||
if(!registerResult)
|
||||
{
|
||||
QMessageBox::critical(this, tr("Failed to add gem"), registerResult.GetError().c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
m_gemsToRegisterWithProject.insert(directory);
|
||||
AZ::Outcome<GemInfo, void> gemInfoResult = PythonBindingsInterface::Get()->GetGemInfo(directory);
|
||||
if (gemInfoResult)
|
||||
{
|
||||
m_gemModel->AddGem(gemInfoResult.GetValue<GemInfo>());
|
||||
m_gemModel->UpdateGemDependencies();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Select the first entry after everything got correctly sized
|
||||
QTimer::singleShot(200, [=]{
|
||||
@@ -144,6 +105,46 @@ namespace O3DE::ProjectManager
|
||||
});
|
||||
}
|
||||
|
||||
void GemCatalogScreen::OnAddGemClicked()
|
||||
{
|
||||
EngineInfo engineInfo;
|
||||
QString defaultPath;
|
||||
|
||||
AZ::Outcome<EngineInfo> engineInfoResult = PythonBindingsInterface::Get()->GetEngineInfo();
|
||||
if (engineInfoResult.IsSuccess())
|
||||
{
|
||||
engineInfo = engineInfoResult.GetValue();
|
||||
defaultPath = engineInfo.m_defaultGemsFolder;
|
||||
}
|
||||
|
||||
if (defaultPath.isEmpty())
|
||||
{
|
||||
defaultPath = QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation);
|
||||
}
|
||||
|
||||
QString directory = QDir::toNativeSeparators(QFileDialog::getExistingDirectory(this, tr("Browse"), defaultPath));
|
||||
if (!directory.isEmpty())
|
||||
{
|
||||
// register the gem to the o3de_manifest.json and to the project after the user confirms
|
||||
// project creation/update
|
||||
auto registerResult = PythonBindingsInterface::Get()->RegisterGem(directory);
|
||||
if(!registerResult)
|
||||
{
|
||||
QMessageBox::critical(this, tr("Failed to add gem"), registerResult.GetError().c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
m_gemsToRegisterWithProject.insert(directory);
|
||||
AZ::Outcome<GemInfo, void> gemInfoResult = PythonBindingsInterface::Get()->GetGemInfo(directory);
|
||||
if (gemInfoResult)
|
||||
{
|
||||
m_gemModel->AddGem(gemInfoResult.GetValue<GemInfo>());
|
||||
m_gemModel->UpdateGemDependencies();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GemCatalogScreen::OnGemStatusChanged(const QModelIndex& modelIndex, uint32_t numChangedDependencies)
|
||||
{
|
||||
if (m_notificationsEnabled)
|
||||
@@ -178,7 +179,7 @@ namespace O3DE::ProjectManager
|
||||
}
|
||||
else if (numChangedDependencies > 1)
|
||||
{
|
||||
notification += QString("%d Gem ").arg(numChangedDependencies) + tr("dependencies");
|
||||
notification += QString("%1 Gem ").arg(numChangedDependencies) + tr("dependencies");
|
||||
}
|
||||
notification += " " + (added ? tr("activated") : tr("deactivated"));
|
||||
|
||||
|
||||
@@ -47,6 +47,7 @@ namespace O3DE::ProjectManager
|
||||
|
||||
public slots:
|
||||
void OnGemStatusChanged(const QModelIndex& modelIndex, uint32_t numChangedDependencies);
|
||||
void OnAddGemClicked();
|
||||
|
||||
protected:
|
||||
void hideEvent(QHideEvent* event) override;
|
||||
|
||||
Reference in New Issue
Block a user