From 7ddcdffed7df6bc4c4dbeb47593dfe14bb8ba27d Mon Sep 17 00:00:00 2001 From: Alex Peterson <26804013+AMZN-alexpete@users.noreply.github.com> Date: Wed, 20 Oct 2021 11:15:24 -0700 Subject: [PATCH] Move Qt Toast Notifications from GraphCanvas into Framework Move the existing Qt Toast Notification QWidgets, EBuses and logic from the GraphCanvas gem into AzQtComponents and AzToolsFramework so they can be re-used. Signed-off-by: AMZN-alexpete <26804013+AMZN-alexpete@users.noreply.github.com> --- .../Components}/ToastNotification.cpp | 51 ++--- .../Components}/ToastNotification.h | 36 ++-- .../Components}/ToastNotification.ui | 9 +- .../ToastNotificationConfiguration.cpp | 18 ++ .../ToastNotificationConfiguration.h | 46 +++++ .../AzQtComponents/azqtcomponents_files.cmake | 5 + .../UI/Notifications/ToastBus.h | 91 +++++++++ .../Notifications/ToastNotificationsView.cpp | 180 ++++++++++++++++++ .../UI/Notifications/ToastNotificationsView.h | 65 +++++++ .../aztoolsframework_files.cmake | 3 + .../Connections/ConnectionComponent.cpp | 8 +- .../Connections/ConnectionComponent.h | 3 +- .../Slots/Data/DataSlotLayoutComponent.cpp | 6 +- .../Slots/Data/DataSlotLayoutComponent.h | 3 +- .../GraphCanvas/Components/ToastBus.h | 29 --- .../GraphCanvas/Components/ViewBus.h | 9 +- .../GraphCanvas/Editor/EditorTypes.h | 92 --------- .../GraphCanvasGraphicsView.cpp | 144 ++------------ .../GraphCanvasGraphicsView.h | 23 +-- .../Code/graphcanvas_staticlib_files.cmake | 4 - .../Code/Editor/Components/EditorGraph.cpp | 24 +-- .../ScriptCanvas/Components/EditorGraph.h | 8 +- .../GraphValidationDockWidget.cpp | 20 +- .../GraphValidationDockWidget.h | 6 +- .../Code/Editor/View/Windows/MainWindow.h | 12 +- 25 files changed, 514 insertions(+), 381 deletions(-) rename {Gems/GraphCanvas/Code/StaticLib/GraphCanvas/Widgets/ToastNotification => Code/Framework/AzQtComponents/AzQtComponents/Components}/ToastNotification.cpp (77%) rename {Gems/GraphCanvas/Code/StaticLib/GraphCanvas/Widgets/ToastNotification => Code/Framework/AzQtComponents/AzQtComponents/Components}/ToastNotification.h (82%) rename {Gems/GraphCanvas/Code/StaticLib/GraphCanvas/Widgets/ToastNotification => Code/Framework/AzQtComponents/AzQtComponents/Components}/ToastNotification.ui (93%) create mode 100644 Code/Framework/AzQtComponents/AzQtComponents/Components/ToastNotificationConfiguration.cpp create mode 100644 Code/Framework/AzQtComponents/AzQtComponents/Components/ToastNotificationConfiguration.h create mode 100644 Code/Framework/AzToolsFramework/AzToolsFramework/UI/Notifications/ToastBus.h create mode 100644 Code/Framework/AzToolsFramework/AzToolsFramework/UI/Notifications/ToastNotificationsView.cpp create mode 100644 Code/Framework/AzToolsFramework/AzToolsFramework/UI/Notifications/ToastNotificationsView.h delete mode 100644 Gems/GraphCanvas/Code/StaticLib/GraphCanvas/Components/ToastBus.h diff --git a/Gems/GraphCanvas/Code/StaticLib/GraphCanvas/Widgets/ToastNotification/ToastNotification.cpp b/Code/Framework/AzQtComponents/AzQtComponents/Components/ToastNotification.cpp similarity index 77% rename from Gems/GraphCanvas/Code/StaticLib/GraphCanvas/Widgets/ToastNotification/ToastNotification.cpp rename to Code/Framework/AzQtComponents/AzQtComponents/Components/ToastNotification.cpp index 41c2d8cecd..670607900f 100644 --- a/Gems/GraphCanvas/Code/StaticLib/GraphCanvas/Widgets/ToastNotification/ToastNotification.cpp +++ b/Code/Framework/AzQtComponents/AzQtComponents/Components/ToastNotification.cpp @@ -5,24 +5,19 @@ * SPDX-License-Identifier: Apache-2.0 OR MIT * */ -#include - #include +#include +#include -#include -#include - -#include +#include +#include +#include +#include -namespace GraphCanvas +namespace AzQtComponents { - ////////////////////// - // ToastNotification - ////////////////////// - ToastNotification::ToastNotification(QWidget* parent, const ToastConfiguration& toastConfiguration) : QDialog(parent, Qt::FramelessWindowHint) - , m_toastId(AZ::Entity::MakeId()) , m_closeOnClick(true) , m_ui(new Ui::ToastNotification()) , m_fadeAnimation(nullptr) @@ -36,35 +31,35 @@ namespace GraphCanvas QIcon toastIcon; - switch (toastConfiguration.GetToastType()) + switch (toastConfiguration.m_toastType) { case ToastType::Error: - toastIcon = QIcon(":/GraphCanvasEditorResources/toast_error_icon.png"); + toastIcon = QIcon(":/stylesheet/img/logging/error.svg"); break; case ToastType::Warning: - toastIcon = QIcon(":/GraphCanvasEditorResources/toast_warning_icon.png"); + toastIcon = QIcon(":/stylesheet/img/logging/warning-yellow.svg"); break; case ToastType::Information: - toastIcon = QIcon(":/GraphCanvasEditorResources/toast_information_icon.png"); + toastIcon = QIcon(":/stylesheet/img/logging/information.svg"); break; case ToastType::Custom: - toastIcon = QIcon(toastConfiguration.GetCustomToastImage().c_str()); + toastIcon = QIcon(toastConfiguration.m_customIconImage); default: break; } m_ui->iconLabel->setPixmap(toastIcon.pixmap(64, 64)); - m_ui->titleLabel->setText(toastConfiguration.GetTitleLabel().c_str()); - m_ui->mainLabel->setText(toastConfiguration.GetDescriptionLabel().c_str()); + m_ui->titleLabel->setText(toastConfiguration.m_title); + m_ui->mainLabel->setText(toastConfiguration.m_description); - m_lifeSpan.setInterval(aznumeric_cast(toastConfiguration.GetDuration().count())); - m_closeOnClick = toastConfiguration.GetCloseOnClick(); + m_lifeSpan.setInterval(aznumeric_cast(toastConfiguration.m_duration.count())); + m_closeOnClick = toastConfiguration.m_closeOnClick; m_ui->closeButton->setVisible(m_closeOnClick); QObject::connect(m_ui->closeButton, &QToolButton::clicked, this, &ToastNotification::accept); - m_fadeDuration = toastConfiguration.GetFadeDuration(); + m_fadeDuration = toastConfiguration.m_fadeDuration; QObject::connect(&m_lifeSpan, &QTimer::timeout, this, &ToastNotification::FadeOut); } @@ -73,11 +68,6 @@ namespace GraphCanvas { } - ToastId ToastNotification::GetToastId() const - { - return m_toastId; - } - void ToastNotification::ShowToastAtCursor() { QPoint globalCursorPos = QCursor::pos(); @@ -131,8 +121,6 @@ namespace GraphCanvas { StartTimer(); } - - emit ToastNotificationShown(); } void ToastNotification::hideEvent(QHideEvent* hideEvent) @@ -147,7 +135,6 @@ namespace GraphCanvas delete m_fadeAnimation; } - ToastNotificationBus::Event(GetToastId(), &ToastNotifications::OnToastDismissed); emit ToastNotificationHidden(); } @@ -155,7 +142,7 @@ namespace GraphCanvas { if (m_closeOnClick) { - ToastNotificationBus::Event(GetToastId(), &ToastNotifications::OnToastInteraction); + emit ToastNotificationInteraction(); accept(); } } @@ -205,5 +192,5 @@ namespace GraphCanvas accept(); } } -#include +#include "Components/moc_ToastNotification.cpp" } diff --git a/Gems/GraphCanvas/Code/StaticLib/GraphCanvas/Widgets/ToastNotification/ToastNotification.h b/Code/Framework/AzQtComponents/AzQtComponents/Components/ToastNotification.h similarity index 82% rename from Gems/GraphCanvas/Code/StaticLib/GraphCanvas/Widgets/ToastNotification/ToastNotification.h rename to Code/Framework/AzQtComponents/AzQtComponents/Components/ToastNotification.h index 40debea0fe..eaf8a0751d 100644 --- a/Gems/GraphCanvas/Code/StaticLib/GraphCanvas/Widgets/ToastNotification/ToastNotification.h +++ b/Code/Framework/AzQtComponents/AzQtComponents/Components/ToastNotification.h @@ -8,17 +8,13 @@ #pragma once #if !defined(Q_MOC_RUN) +#include +#include +#include #include #include #include -#include #include -#include -#include -#include -#include - -#include #endif namespace Ui @@ -26,20 +22,20 @@ namespace Ui class ToastNotification; } -namespace GraphCanvas +QT_FORWARD_DECLARE_CLASS(QPropertyAnimation) + +namespace AzQtComponents { - class ToastNotification + class AZ_QT_COMPONENTS_API ToastNotification : public QDialog { Q_OBJECT public: AZ_CLASS_ALLOCATOR(ToastNotification, AZ::SystemAllocator, 0); - ToastNotification(QWidget* parent, const ToastConfiguration& configuration); + ToastNotification(QWidget* parent, const ToastConfiguration& toastConfiguration); virtual ~ToastNotification(); - ToastId GetToastId() const; - // Shows the toast notification relative to the current cursor. void ShowToastAtCursor(); @@ -53,30 +49,26 @@ namespace GraphCanvas // QDialog void showEvent(QShowEvent* showEvent) override; void hideEvent(QHideEvent* hideEvent) override; - void mousePressEvent(QMouseEvent* mouseEvent) override; - bool eventFilter(QObject* object, QEvent* event) override; - //// public slots: - void StartTimer(); void FadeOut(); signals: - void ToastNotificationShown(); void ToastNotificationHidden(); + void ToastNotificationInteraction(); private: - QPropertyAnimation* m_fadeAnimation; - AZStd::chrono::milliseconds m_fadeDuration; - - ToastId m_toastId; bool m_closeOnClick; QTimer m_lifeSpan; + + AZ_PUSH_DISABLE_DLL_EXPORT_MEMBER_WARNING + AZStd::chrono::milliseconds m_fadeDuration; AZStd::unique_ptr m_ui; + AZ_POP_DISABLE_DLL_EXPORT_MEMBER_WARNING }; -} +} // namespace AzQtComponents diff --git a/Gems/GraphCanvas/Code/StaticLib/GraphCanvas/Widgets/ToastNotification/ToastNotification.ui b/Code/Framework/AzQtComponents/AzQtComponents/Components/ToastNotification.ui similarity index 93% rename from Gems/GraphCanvas/Code/StaticLib/GraphCanvas/Widgets/ToastNotification/ToastNotification.ui rename to Code/Framework/AzQtComponents/AzQtComponents/Components/ToastNotification.ui index 2c82f042b8..107281bdc2 100644 --- a/Gems/GraphCanvas/Code/StaticLib/GraphCanvas/Widgets/ToastNotification/ToastNotification.ui +++ b/Code/Framework/AzQtComponents/AzQtComponents/Components/ToastNotification.ui @@ -101,7 +101,7 @@ - :/GraphCanvasEditorResources/toast_information_icon.png + :/stylesheet/img/logging/information.svg true @@ -203,8 +203,8 @@ ... - - :/GraphCanvasEditorResources/lineedit_clear.png:/GraphCanvasEditorResources/lineedit_clear.png + + :/stylesheet/img/close_x.svg:/stylesheet/img/close_x.svg @@ -230,8 +230,7 @@ - - + diff --git a/Code/Framework/AzQtComponents/AzQtComponents/Components/ToastNotificationConfiguration.cpp b/Code/Framework/AzQtComponents/AzQtComponents/Components/ToastNotificationConfiguration.cpp new file mode 100644 index 0000000000..41e3ea836c --- /dev/null +++ b/Code/Framework/AzQtComponents/AzQtComponents/Components/ToastNotificationConfiguration.cpp @@ -0,0 +1,18 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. + * For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ +#include + +namespace AzQtComponents +{ + ToastConfiguration::ToastConfiguration(ToastType toastType, const QString& title, const QString& description) + : m_toastType(toastType) + , m_title(title) + , m_description(description) + { + } +} // namespace AzQtComponents diff --git a/Code/Framework/AzQtComponents/AzQtComponents/Components/ToastNotificationConfiguration.h b/Code/Framework/AzQtComponents/AzQtComponents/Components/ToastNotificationConfiguration.h new file mode 100644 index 0000000000..05999017e4 --- /dev/null +++ b/Code/Framework/AzQtComponents/AzQtComponents/Components/ToastNotificationConfiguration.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. + * For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ +#pragma once + +#if !defined(Q_MOC_RUN) +#include +#include +#include +#include +#endif + +namespace AzQtComponents +{ + enum class ToastType + { + Information, + Warning, + Error, + Custom + }; + + class AZ_QT_COMPONENTS_API ToastConfiguration + { + public: + AZ_CLASS_ALLOCATOR(ToastConfiguration, AZ::SystemAllocator, 0); + ToastConfiguration(ToastType toastType, const QString& title, const QString& description); + + bool m_closeOnClick = true; + + ToastType m_toastType = ToastType::Information; + + QString m_title; + QString m_description; + QString m_customIconImage; + + AZ_PUSH_DISABLE_DLL_EXPORT_MEMBER_WARNING + AZStd::chrono::milliseconds m_duration = AZStd::chrono::milliseconds(5000); + AZStd::chrono::milliseconds m_fadeDuration = AZStd::chrono::milliseconds(250); + AZ_POP_DISABLE_DLL_EXPORT_MEMBER_WARNING + }; +} // namespace AzQtComponents diff --git a/Code/Framework/AzQtComponents/AzQtComponents/azqtcomponents_files.cmake b/Code/Framework/AzQtComponents/AzQtComponents/azqtcomponents_files.cmake index 4c343b852c..4ed87ee358 100644 --- a/Code/Framework/AzQtComponents/AzQtComponents/azqtcomponents_files.cmake +++ b/Code/Framework/AzQtComponents/AzQtComponents/azqtcomponents_files.cmake @@ -49,6 +49,11 @@ set(FILES Components/Titlebar.h Components/TitleBarOverdrawHandler.cpp Components/TitleBarOverdrawHandler.h + Components/ToastNotification.cpp + Components/ToastNotification.h + Components/ToastNotificationConfiguration.h + Components/ToastNotificationConfiguration.cpp + Components/ToastNotification.ui Components/ToolButtonComboBox.cpp Components/ToolButtonComboBox.h Components/ToolButtonLineEdit.cpp diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/UI/Notifications/ToastBus.h b/Code/Framework/AzToolsFramework/AzToolsFramework/UI/Notifications/ToastBus.h new file mode 100644 index 0000000000..8b6b4d8ebf --- /dev/null +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/UI/Notifications/ToastBus.h @@ -0,0 +1,91 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. + * For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ +#pragma once + +#if !defined(Q_MOC_RUN) +#include +#include +#include + +#include +#endif + +namespace AzToolsFramework +{ + typedef AZ::EntityId ToastId; + + /** + * An EBus for receiving notifications when a user interacts with or dismisses + * a toast notification. + */ + class ToastNotifications + : public AZ::EBusTraits + { + public: + static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Multiple; + static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::ById; + using BusIdType = ToastId; + + virtual void OnToastInteraction() {} + virtual void OnToastDismissed() {} + }; + + using ToastNotificationBus = AZ::EBus; + + typedef AZ::u32 ToastRequestBusId; + + /** + * An EBus used to hide or show toast notifications. Generally, these request are handled by a + * ToastNotificationsView that has been created with a specific ToastRequestBusId + * e.g. AZ_CRC("ExampleToastNotificationView") + */ + class ToastRequests + : public AZ::EBusTraits + { + public: + static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Multiple; + static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::ById; + using BusIdType = ToastRequestBusId; // bus is addressed by CRC of the view name + + /** + * Hide a toast notification widget. + * + * @param toastId The toast notification's ToastId + */ + virtual void HideToastNotification(const ToastId& toastId) = 0; + + /** + * Show a toast notification with the specified toast configuration. When handled by a ToastNotificationsView, + * notifications are queued and presented to the user in sequence. + * + * @param toastConfiguration The toast configuration + * @return a ToastId + */ + virtual ToastId ShowToastNotification(const AzQtComponents::ToastConfiguration& toastConfiguration) = 0; + + /** + * Show a toast notification with the specified toast configuration at the current moust cursor location. + * + * @param toastConfiguration The toast configuration + * @return a ToastId + */ + virtual ToastId ShowToastAtCursor(const AzQtComponents::ToastConfiguration& toastConfiguration) = 0; + + /** + * Show a toast notification with the specified toast configuration at the specified location. + * + * @param screenPosition The screen position + * @param anchorPoint The anchorPoint for the toast notification widget + * @param toastConfiguration The toast configuration + * @return a ToastId + */ + virtual ToastId ShowToastAtPoint(const QPoint& screenPosition, const QPointF& anchorPoint, const AzQtComponents::ToastConfiguration&) = 0; + }; + + using ToastRequestBus = AZ::EBus; +} diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/UI/Notifications/ToastNotificationsView.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/UI/Notifications/ToastNotificationsView.cpp new file mode 100644 index 0000000000..0ef0bf9a7b --- /dev/null +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/UI/Notifications/ToastNotificationsView.cpp @@ -0,0 +1,180 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. + * For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ + +#include +#include +#include +#include +#include + +namespace AzToolsFramework +{ + ToastNotificationsView::ToastNotificationsView(QWidget* parent, ToastRequestBusId busId) + : QWidget(parent) + { + ToastRequestBus::Handler::BusConnect(busId); + } + + ToastNotificationsView::~ToastNotificationsView() + { + ToastRequestBus::Handler::BusDisconnect(); + } + + void ToastNotificationsView::OnHide() + { + QWidget::hide(); + + if (m_activeNotification.IsValid()) + { + auto notificationIter = m_notifications.find(m_activeNotification); + if (notificationIter != m_notifications.end()) + { + notificationIter->second->hide(); + } + } + } + + void ToastNotificationsView::UpdateToastPosition() + { + if (m_activeNotification.IsValid()) + { + auto notificationIter = m_notifications.find(m_activeNotification); + if (notificationIter != m_notifications.end()) + { + notificationIter->second->UpdatePosition(GetGlobalPoint(), m_anchorPoint); + } + } + } + + void ToastNotificationsView::OnShow() + { + QWidget::show(); + + if (m_activeNotification.IsValid() || !m_queuedNotifications.empty()) + { + DisplayQueuedNotification(); + } + } + + ToastId ToastNotificationsView::ShowToastNotification(const AzQtComponents::ToastConfiguration& toastConfiguration) + { + ToastId toastId = CreateToastNotification(toastConfiguration); + m_queuedNotifications.emplace_back(toastId); + + if (!m_activeNotification.IsValid()) + { + DisplayQueuedNotification(); + } + + return toastId; + } + + ToastId ToastNotificationsView::ShowToastAtCursor(const AzQtComponents::ToastConfiguration& toastConfiguration) + { + ToastId toastId = CreateToastNotification(toastConfiguration); + m_notifications[toastId]->ShowToastAtCursor(); + return toastId; + } + + ToastId ToastNotificationsView::ShowToastAtPoint(const QPoint& screenPosition, const QPointF& anchorPoint, const AzQtComponents::ToastConfiguration& toastConfiguration) + { + ToastId toastId = CreateToastNotification(toastConfiguration); + m_notifications[toastId]->ShowToastAtPoint(screenPosition, anchorPoint); + return toastId; + } + + void ToastNotificationsView::HideToastNotification(const ToastId& toastId) + { + auto notificationIter = m_notifications.find(toastId); + if (notificationIter != m_notifications.end()) + { + auto queuedIter = AZStd::find(m_queuedNotifications.begin(), m_queuedNotifications.end(), toastId); + if (queuedIter != m_queuedNotifications.end()) + { + m_queuedNotifications.erase(queuedIter); + } + + notificationIter->second->reject(); + } + } + + ToastId ToastNotificationsView::CreateToastNotification(const AzQtComponents::ToastConfiguration& toastConfiguration) + { + AzQtComponents::ToastNotification* notification = aznew AzQtComponents::ToastNotification(parentWidget(), toastConfiguration); + ToastId toastId = AZ::Entity::MakeId(); + m_notifications[toastId] = notification; + + QObject::connect( + m_notifications[toastId], &AzQtComponents::ToastNotification::ToastNotificationHidden, + [toastId]() + { + ToastNotificationBus::Event(toastId, &ToastNotificationBus::Events::OnToastDismissed); + }); + + QObject::connect( + m_notifications[toastId], &AzQtComponents::ToastNotification::ToastNotificationInteraction, + [toastId]() + { + ToastNotificationBus::Event(toastId, &ToastNotificationBus::Events::OnToastInteraction); + }); + + return toastId; + } + + QPoint ToastNotificationsView::GetGlobalPoint() + { + QPoint relativePoint = m_offset; + + AZ_Assert(parentWidget(), "ToastNotificationsView has invalid parent QWidget"); + if (m_anchorPoint.x() == 1.0) + { + relativePoint.setX(parentWidget()->width() - m_offset.x()); + } + if (m_anchorPoint.y() == 1.0) + { + relativePoint.setY(parentWidget()->height() - m_offset.y()); + } + + return parentWidget()->mapToGlobal(relativePoint); + } + + void ToastNotificationsView::DisplayQueuedNotification() + { + AZ_Assert(parentWidget(), "ToastNotificationsView has invalid parent QWidget"); + if (m_queuedNotifications.empty() || !parentWidget()->isVisible() || !isVisible()) + { + return; + } + + ToastId toastId = m_queuedNotifications.front(); + m_queuedNotifications.erase(m_queuedNotifications.begin()); + + auto notificationIter = m_notifications.find(toastId); + if (notificationIter != m_notifications.end()) + { + m_activeNotification = toastId; + + notificationIter->second->ShowToastAtPoint(GetGlobalPoint(), m_anchorPoint); + + QObject::connect( + notificationIter->second, &AzQtComponents::ToastNotification::ToastNotificationHidden, + [&]() + { + m_activeNotification.SetInvalid(); + DisplayQueuedNotification(); + } + ); + } + + // If we didn't actually show something, recurse to avoid things getting stuck in the queue. + if (!m_activeNotification.IsValid()) + { + DisplayQueuedNotification(); + } + } +} diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/UI/Notifications/ToastNotificationsView.h b/Code/Framework/AzToolsFramework/AzToolsFramework/UI/Notifications/ToastNotificationsView.h new file mode 100644 index 0000000000..c4220331d8 --- /dev/null +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/UI/Notifications/ToastNotificationsView.h @@ -0,0 +1,65 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. + * For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ +#pragma once + +#if !defined(Q_MOC_RUN) +#include +#include +#include + +#include +#include +#include +#endif + +namespace AzQtComponents +{ + class ToastNotification; +} + +namespace AzToolsFramework +{ + /** + * \brief A QWidget that displays and manages a queue of toast notifications. + * + * This view must be updated by its parent when the parent widget is show, hidden, moved + * or resized because toast notifications are displayed on top of the parent and are not part + * of the layout, so they must be manually moved. + */ + class ToastNotificationsView final + : public QWidget + , protected ToastRequestBus::Handler + { + Q_OBJECT + public: + ToastNotificationsView(QWidget* parent, ToastRequestBusId busId); + ~ToastNotificationsView() override; + + void HideToastNotification(const ToastId& toastId) override; + + ToastId ShowToastNotification(const AzQtComponents::ToastConfiguration& toastConfiguration) override; + ToastId ShowToastAtCursor(const AzQtComponents::ToastConfiguration& toastConfiguration) override; + ToastId ShowToastAtPoint(const QPoint& screenPosition, const QPointF& anchorPoint, const AzQtComponents::ToastConfiguration&) override; + + void OnHide(); + void OnShow(); + void UpdateToastPosition(); + + private: + ToastId CreateToastNotification(const AzQtComponents::ToastConfiguration& toastConfiguration); + void DisplayQueuedNotification(); + QPoint GetGlobalPoint(); + + ToastId m_activeNotification; + AZStd::unordered_map m_notifications; + AZStd::vector m_queuedNotifications; + + QPoint m_offset = QPoint(10, 10); + QPointF m_anchorPoint = QPointF(1, 0); + }; +} // AzToolsFramework diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/aztoolsframework_files.cmake b/Code/Framework/AzToolsFramework/AzToolsFramework/aztoolsframework_files.cmake index 5db65f89f4..b57eedcd81 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/aztoolsframework_files.cmake +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/aztoolsframework_files.cmake @@ -759,6 +759,9 @@ set(FILES UI/Prefab/PrefabUiHandler.cpp UI/Prefab/PrefabViewportFocusPathHandler.h UI/Prefab/PrefabViewportFocusPathHandler.cpp + UI/Notifications/ToastNotificationsView.cpp + UI/Notifications/ToastNotificationsView.h + UI/Notifications/ToastBus.h PythonTerminal/ScriptHelpDialog.cpp PythonTerminal/ScriptHelpDialog.h PythonTerminal/ScriptHelpDialog.ui diff --git a/Gems/GraphCanvas/Code/Source/Components/Connections/ConnectionComponent.cpp b/Gems/GraphCanvas/Code/Source/Components/Connections/ConnectionComponent.cpp index 690026e477..d61e8bda29 100644 --- a/Gems/GraphCanvas/Code/Source/Components/Connections/ConnectionComponent.cpp +++ b/Gems/GraphCanvas/Code/Source/Components/Connections/ConnectionComponent.cpp @@ -13,6 +13,8 @@ #include +#include + #include #include @@ -1117,10 +1119,8 @@ namespace GraphCanvas QPointF globalConnectionPoint = ConversionUtils::AZToQPoint(globalConnectionVector); QPointF anchorPoint(0.0f, 0.0f); - - ToastConfiguration toastConfiguration(ToastType::Error, "Unable to connect to slot", m_validationResult.m_failureReason); - - toastConfiguration.SetCloseOnClick(false); + AzQtComponents::ToastConfiguration toastConfiguration(AzQtComponents::ToastType::Error, "Unable to connect to slot", m_validationResult.m_failureReason.c_str()); + toastConfiguration.m_closeOnClick = false; m_toastId = viewHandler->ShowToastAtPoint(globalConnectionPoint.toPoint(), anchorPoint, toastConfiguration); } diff --git a/Gems/GraphCanvas/Code/Source/Components/Connections/ConnectionComponent.h b/Gems/GraphCanvas/Code/Source/Components/Connections/ConnectionComponent.h index dc35772b87..b447cee394 100644 --- a/Gems/GraphCanvas/Code/Source/Components/Connections/ConnectionComponent.h +++ b/Gems/GraphCanvas/Code/Source/Components/Connections/ConnectionComponent.h @@ -19,6 +19,7 @@ AZ_POP_DISABLE_WARNING #include #include #include +#include #include #include @@ -210,7 +211,7 @@ namespace GraphCanvas ConnectionValidationTooltip m_validationResult; Endpoint m_endpointTooltip; - ToastId m_toastId; + AzToolsFramework::ToastId m_toastId; //! The Id of the graph this connection belongs to. GraphId m_graphId; diff --git a/Gems/GraphCanvas/Code/Source/Components/Slots/Data/DataSlotLayoutComponent.cpp b/Gems/GraphCanvas/Code/Source/Components/Slots/Data/DataSlotLayoutComponent.cpp index 95c6ecff11..78a94296ff 100644 --- a/Gems/GraphCanvas/Code/Source/Components/Slots/Data/DataSlotLayoutComponent.cpp +++ b/Gems/GraphCanvas/Code/Source/Components/Slots/Data/DataSlotLayoutComponent.cpp @@ -12,6 +12,8 @@ #include #include +#include + #include #include @@ -157,8 +159,8 @@ namespace GraphCanvas anchorPoint = QPointF(1.0f, 0.5f); } - ToastConfiguration toastConfiguration(ToastType::Error, "Unable to drop onto to slot", error); - toastConfiguration.SetCloseOnClick(false); + AzQtComponents::ToastConfiguration toastConfiguration(AzQtComponents::ToastType::Error, "Unable to drop onto to slot", error.c_str()); + toastConfiguration.m_closeOnClick = false; m_toastId = viewHandler->ShowToastAtPoint(globalConnectionPoint.toPoint(), anchorPoint, toastConfiguration); } diff --git a/Gems/GraphCanvas/Code/Source/Components/Slots/Data/DataSlotLayoutComponent.h b/Gems/GraphCanvas/Code/Source/Components/Slots/Data/DataSlotLayoutComponent.h index 3c49b36833..61fd6f31db 100644 --- a/Gems/GraphCanvas/Code/Source/Components/Slots/Data/DataSlotLayoutComponent.h +++ b/Gems/GraphCanvas/Code/Source/Components/Slots/Data/DataSlotLayoutComponent.h @@ -10,6 +10,7 @@ #include #include +#include #include #include #include @@ -58,7 +59,7 @@ namespace GraphCanvas SlotId m_slotId; ViewId m_viewId; - ToastId m_toastId; + AzToolsFramework::ToastId m_toastId; }; class DoubleClickSceneEventFilter diff --git a/Gems/GraphCanvas/Code/StaticLib/GraphCanvas/Components/ToastBus.h b/Gems/GraphCanvas/Code/StaticLib/GraphCanvas/Components/ToastBus.h deleted file mode 100644 index b775c5f068..0000000000 --- a/Gems/GraphCanvas/Code/StaticLib/GraphCanvas/Components/ToastBus.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. - * For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ -#pragma once - -#include - -#include - -namespace GraphCanvas -{ - class ToastNotifications - : public AZ::EBusTraits - { - public: - static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Multiple; - static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::ById; - using BusIdType = ToastId; - - virtual void OnToastInteraction() {} - virtual void OnToastDismissed() {} - }; - - using ToastNotificationBus = AZ::EBus; -} diff --git a/Gems/GraphCanvas/Code/StaticLib/GraphCanvas/Components/ViewBus.h b/Gems/GraphCanvas/Code/StaticLib/GraphCanvas/Components/ViewBus.h index 590b3812a8..05bf650dc1 100644 --- a/Gems/GraphCanvas/Code/StaticLib/GraphCanvas/Components/ViewBus.h +++ b/Gems/GraphCanvas/Code/StaticLib/GraphCanvas/Components/ViewBus.h @@ -12,6 +12,7 @@ #include #include #include +#include #include @@ -139,11 +140,11 @@ namespace GraphCanvas virtual void RefreshView() = 0; //! Toast Notifications - virtual void HideToastNotification(const ToastId& toastId) = 0; + virtual void HideToastNotification(const AzToolsFramework::ToastId& toastId) = 0; - virtual ToastId ShowToastNotification(const ToastConfiguration& toastConfiguration) = 0; - virtual ToastId ShowToastAtCursor(const ToastConfiguration& toastConfiguration) = 0; - virtual ToastId ShowToastAtPoint(const QPoint& screenPosition, const QPointF& anchorPoint, const ToastConfiguration&) = 0; + virtual AzToolsFramework::ToastId ShowToastNotification(const AzQtComponents::ToastConfiguration& toastConfiguration) = 0; + virtual AzToolsFramework::ToastId ShowToastAtCursor(const AzQtComponents::ToastConfiguration& toastConfiguration) = 0; + virtual AzToolsFramework::ToastId ShowToastAtPoint(const QPoint& screenPosition, const QPointF& anchorPoint, const AzQtComponents::ToastConfiguration&) = 0; virtual bool IsShowing() const = 0; }; diff --git a/Gems/GraphCanvas/Code/StaticLib/GraphCanvas/Editor/EditorTypes.h b/Gems/GraphCanvas/Code/StaticLib/GraphCanvas/Editor/EditorTypes.h index e0722836b1..792e02bd4b 100644 --- a/Gems/GraphCanvas/Code/StaticLib/GraphCanvas/Editor/EditorTypes.h +++ b/Gems/GraphCanvas/Code/StaticLib/GraphCanvas/Editor/EditorTypes.h @@ -29,8 +29,6 @@ namespace GraphCanvas typedef AZ::EntityId GraphicsEffectId; - typedef AZ::EntityId ToastId; - typedef AZ::Uuid PersistentGraphMemberId; typedef AZ::Crc32 ExtenderId; @@ -81,14 +79,6 @@ namespace GraphCanvas Target }; - enum class ToastType - { - Information, - Warning, - Error, - Custom - }; - enum class ListingType { Unknown, @@ -116,88 +106,6 @@ namespace GraphCanvas private: }; - class ToastConfiguration - { - public: - ToastConfiguration(ToastType toastType, const AZStd::string& titleLabel, const AZStd::string& descriptionLabel) - : m_toastType(toastType) - , m_titleLabel(titleLabel) - , m_descriptionLabel(descriptionLabel) - { - } - - ~ToastConfiguration() = default; - - ToastType GetToastType() const - { - return m_toastType; - } - - const AZStd::string& GetTitleLabel() const - { - return m_titleLabel; - } - - const AZStd::string& GetDescriptionLabel() const - { - return m_descriptionLabel; - } - - void SetCustomToastImage(const AZStd::string& toastImage) - { - AZ_Error("GraphCanvas", m_toastType == ToastType::Custom, "Setting a custom image on a non-custom Toast notification"); - m_customToastImage = toastImage; - } - - const AZStd::string& GetCustomToastImage() const - { - return m_customToastImage; - } - - void SetDuration(AZStd::chrono::milliseconds duration) - { - m_duration = duration; - } - - AZStd::chrono::milliseconds GetDuration() const - { - return m_duration; - } - - void SetCloseOnClick(bool closeOnClick) - { - m_closeOnClick = closeOnClick; - } - - bool GetCloseOnClick() const - { - return m_closeOnClick; - } - - void SetFadeDuration(AZStd::chrono::milliseconds fadeDuration) - { - m_fadeDuration = fadeDuration; - } - - AZStd::chrono::milliseconds GetFadeDuration() const - { - return m_fadeDuration; - } - - private: - - AZStd::chrono::milliseconds m_fadeDuration = AZStd::chrono::milliseconds(250); - - AZStd::chrono::milliseconds m_duration; - bool m_closeOnClick; - - AZStd::string m_customToastImage; - - ToastType m_toastType; - AZStd::string m_titleLabel; - AZStd::string m_descriptionLabel; - }; - struct ConnectionValidationTooltip { bool operator()() const diff --git a/Gems/GraphCanvas/Code/StaticLib/GraphCanvas/Widgets/GraphCanvasGraphicsView/GraphCanvasGraphicsView.cpp b/Gems/GraphCanvas/Code/StaticLib/GraphCanvas/Widgets/GraphCanvasGraphicsView/GraphCanvasGraphicsView.cpp index fa7e051035..a8b0f7dabf 100644 --- a/Gems/GraphCanvas/Code/StaticLib/GraphCanvas/Widgets/GraphCanvasGraphicsView/GraphCanvasGraphicsView.cpp +++ b/Gems/GraphCanvas/Code/StaticLib/GraphCanvas/Widgets/GraphCanvasGraphicsView/GraphCanvasGraphicsView.cpp @@ -12,6 +12,7 @@ #include #include +#include #include @@ -46,6 +47,7 @@ namespace GraphCanvas , m_queuedFocus(nullptr) { m_viewId = AZ::Entity::MakeId(); + m_notificationsView = AZStd::make_unique(this, AZ_CRC(m_viewId.ToString())); setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); @@ -603,8 +605,8 @@ namespace GraphCanvas const int maxSize = 17500; if (windowSize.width() > maxSize || windowSize.height() > maxSize) { - ToastConfiguration toastConfiguration(ToastType::Information, "Screenshot", "Screenshot attempted to capture an area too large. Some down-ressing may occur."); - ShowToastNotification(toastConfiguration); + AzQtComponents::ToastConfiguration toastConfiguration(AzQtComponents::ToastType::Information, "Screenshot", "Screenshot attempted to capture an area too large. Some down-ressing may occur."); + m_notificationsView->ShowToastNotification(toastConfiguration); if (windowSize.width() > maxSize) { @@ -825,64 +827,24 @@ namespace GraphCanvas invalidateScene(GetViewableAreaInSceneCoordinates()); } - void GraphCanvasGraphicsView::HideToastNotification(const ToastId& toastId) + void GraphCanvasGraphicsView::HideToastNotification(const AzToolsFramework::ToastId& toastId) { - auto notificationIter = m_notifications.find(toastId); - - if (notificationIter != m_notifications.end()) - { - auto queuedIter = AZStd::find(m_queuedNotifications.begin(), m_queuedNotifications.end(), toastId); - - if (queuedIter != m_queuedNotifications.end()) - { - m_queuedNotifications.erase(queuedIter); - } - - notificationIter->second->reject(); - } + m_notificationsView->HideToastNotification(toastId); } - ToastId GraphCanvasGraphicsView::ShowToastNotification(const ToastConfiguration& toastConfiguration) + AzToolsFramework::ToastId GraphCanvasGraphicsView::ShowToastNotification(const AzQtComponents::ToastConfiguration& toastConfiguration) { - ToastNotification* notification = aznew ToastNotification(this, toastConfiguration); - - ToastId toastId = notification->GetToastId(); - m_notifications[toastId] = notification; - - m_queuedNotifications.emplace_back(toastId); - - if (!m_activeNotification.IsValid()) - { - DisplayQueuedNotification(); - } - - return toastId; + return m_notificationsView->ShowToastNotification(toastConfiguration); } - ToastId GraphCanvasGraphicsView::ShowToastAtCursor(const ToastConfiguration& toastConfiguration) + AzToolsFramework::ToastId GraphCanvasGraphicsView::ShowToastAtCursor(const AzQtComponents::ToastConfiguration& toastConfiguration) { - ToastNotification* notification = aznew ToastNotification(this, toastConfiguration); - - notification->ShowToastAtCursor(); - - ToastId toastId = notification->GetToastId(); - - m_notifications[toastId] = notification; - - return toastId; + return m_notificationsView->ShowToastAtCursor(toastConfiguration); } - ToastId GraphCanvasGraphicsView::ShowToastAtPoint(const QPoint& screenPosition, const QPointF& anchorPoint, const ToastConfiguration& toastConfiguration) + AzToolsFramework::ToastId GraphCanvasGraphicsView::ShowToastAtPoint(const QPoint& screenPosition, const QPointF& anchorPoint, const AzQtComponents::ToastConfiguration& toastConfiguration) { - ToastNotification* notification = aznew ToastNotification(this, toastConfiguration); - - notification->ShowToastAtPoint(screenPosition, anchorPoint); - - ToastId toastId = notification->GetToastId(); - - m_notifications[toastId] = notification; - - return toastId; + return m_notificationsView->ShowToastAtPoint(screenPosition, anchorPoint, toastConfiguration); } bool GraphCanvasGraphicsView::IsShowing() const @@ -1245,14 +1207,14 @@ namespace GraphCanvas CalculateInternalRectangle(); - UpdateToastPosition(); + m_notificationsView->UpdateToastPosition(); } void GraphCanvasGraphicsView::moveEvent(QMoveEvent* event) { QGraphicsView::moveEvent(event); - UpdateToastPosition(); + m_notificationsView->UpdateToastPosition(); } void GraphCanvasGraphicsView::scrollContentsBy(int dx, int dy) @@ -1266,25 +1228,14 @@ namespace GraphCanvas { QGraphicsView::showEvent(showEvent); - if (m_activeNotification.IsValid()) - { - DisplayQueuedNotification(); - } + m_notificationsView->OnShow(); } void GraphCanvasGraphicsView::hideEvent(QHideEvent* hideEvent) { QGraphicsView::hideEvent(hideEvent); - if (m_activeNotification.IsValid()) - { - auto notificationIter = m_notifications.find(m_activeNotification); - - if (notificationIter != m_notifications.end()) - { - notificationIter->second->hide(); - } - } + m_notificationsView->OnHide(); } void GraphCanvasGraphicsView::OnSettingsChanged() @@ -1378,25 +1329,6 @@ namespace GraphCanvas BookmarkManagerRequestBus::Event(sceneId, &BookmarkManagerRequests::ActivateShortcut, bookmarkShortcut); } - void GraphCanvasGraphicsView::UpdateToastPosition() - { - if (m_activeNotification.IsValid()) - { - auto notificationIter = m_notifications.find(m_activeNotification); - - if (notificationIter != m_notifications.end()) - { - // Want this to be roughly in the top right corner of the graphics view. - QPoint globalPoint = mapToGlobal(QPoint(width() - 10, 10)); - - // Anchor point will be top right - QPointF anchorPoint = QPointF(1, 0); - - notificationIter->second->UpdatePosition(globalPoint, anchorPoint); - } - } - } - void GraphCanvasGraphicsView::CenterOnSceneMembers(const AZStd::vector& memberIds) { QRectF boundingRect; @@ -1642,48 +1574,4 @@ namespace GraphCanvas AZ::TickBus::Handler::BusDisconnect(); } } - - void GraphCanvasGraphicsView::OnNotificationHidden() - { - m_activeNotification.SetInvalid(); - - if (!m_queuedNotifications.empty()) - { - DisplayQueuedNotification(); - } - } - - void GraphCanvasGraphicsView::DisplayQueuedNotification() - { - if (m_queuedNotifications.empty() && isVisible()) - { - return; - } - - ToastId toastId = m_queuedNotifications.front(); - m_queuedNotifications.erase(m_queuedNotifications.begin()); - - auto notificationIter = m_notifications.find(toastId); - - if (notificationIter != m_notifications.end()) - { - m_activeNotification = toastId; - - // Want this to be roughly in the top right corner of the graphics view. - QPoint globalPoint = mapToGlobal(QPoint(width() - 10, 10)); - - // Anchor point will be top right - QPointF anchorPoint = QPointF(1, 0); - - notificationIter->second->ShowToastAtPoint(globalPoint, anchorPoint); - - QObject::connect(notificationIter->second, &ToastNotification::ToastNotificationHidden, this, &GraphCanvasGraphicsView::OnNotificationHidden); - } - - // If we didn't actually show something, recurse to avoid things getting stuck in the queue. - if (!m_activeNotification.IsValid()) - { - DisplayQueuedNotification(); - } - } } diff --git a/Gems/GraphCanvas/Code/StaticLib/GraphCanvas/Widgets/GraphCanvasGraphicsView/GraphCanvasGraphicsView.h b/Gems/GraphCanvas/Code/StaticLib/GraphCanvas/Widgets/GraphCanvasGraphicsView/GraphCanvasGraphicsView.h index 70b3e16166..f7b34b598c 100644 --- a/Gems/GraphCanvas/Code/StaticLib/GraphCanvas/Widgets/GraphCanvasGraphicsView/GraphCanvasGraphicsView.h +++ b/Gems/GraphCanvas/Code/StaticLib/GraphCanvas/Widgets/GraphCanvasGraphicsView/GraphCanvasGraphicsView.h @@ -27,11 +27,11 @@ AZ_POP_DISABLE_WARNING #include #include +#include #include #include #include -#include namespace GraphCanvas { @@ -123,11 +123,11 @@ namespace GraphCanvas void RefreshView() override; - void HideToastNotification(const ToastId& toastId) override; + void HideToastNotification(const AzToolsFramework::ToastId& toastId) override; - ToastId ShowToastNotification(const ToastConfiguration& toastConfiguration) override; - ToastId ShowToastAtCursor(const ToastConfiguration& toastConfiguration) override; - ToastId ShowToastAtPoint(const QPoint& screenPosition, const QPointF& anchorPoint, const ToastConfiguration& toastConfiguration) override; + AzToolsFramework::ToastId ShowToastNotification(const AzQtComponents::ToastConfiguration& toastConfiguration) override; + AzToolsFramework::ToastId ShowToastAtCursor(const AzQtComponents::ToastConfiguration& toastConfiguration) override; + AzToolsFramework::ToastId ShowToastAtPoint(const QPoint& screenPosition, const QPointF& anchorPoint, const AzQtComponents::ToastConfiguration& toastConfiguration) override; bool IsShowing() const override; //// @@ -186,8 +186,6 @@ namespace GraphCanvas private: - void UpdateToastPosition(); - void CenterOnSceneMembers(const AZStd::vector& memberIds); void ConnectBoundsSignals(); @@ -206,9 +204,6 @@ namespace GraphCanvas void ManageTickState(); - void OnNotificationHidden(); - void DisplayQueuedNotification(); - GraphCanvasGraphicsView(const GraphCanvasGraphicsView&) = delete; ViewId m_viewId; @@ -242,13 +237,7 @@ namespace GraphCanvas AZStd::unique_ptr m_queuedFocus; - // These will display sequentially in a reserved part of the UI - ToastId m_activeNotification; - AZStd::vector< ToastId > m_queuedNotifications; - - // There could be more then the queued list in terms of general notifications - // As some systems might want to re-use the systems for their own needs. - AZStd::unordered_map< ToastId, ToastNotification* > m_notifications; + AZStd::unique_ptr m_notificationsView; bool m_isEditing; diff --git a/Gems/GraphCanvas/Code/graphcanvas_staticlib_files.cmake b/Gems/GraphCanvas/Code/graphcanvas_staticlib_files.cmake index bedc6329d5..b62ff303a6 100644 --- a/Gems/GraphCanvas/Code/graphcanvas_staticlib_files.cmake +++ b/Gems/GraphCanvas/Code/graphcanvas_staticlib_files.cmake @@ -30,7 +30,6 @@ set(FILES StaticLib/GraphCanvas/Components/PersistentIdBus.h StaticLib/GraphCanvas/Components/SceneBus.h StaticLib/GraphCanvas/Components/StyleBus.h - StaticLib/GraphCanvas/Components/ToastBus.h StaticLib/GraphCanvas/Components/ViewBus.h StaticLib/GraphCanvas/Components/VisualBus.h StaticLib/GraphCanvas/GraphicsItems/AnimatedPulse.cpp @@ -222,9 +221,6 @@ set(FILES StaticLib/GraphCanvas/Widgets/StyledItemDelegates/GenericComboBoxDelegate.h StaticLib/GraphCanvas/Widgets/StyledItemDelegates/IconDecoratedNameDelegate.cpp StaticLib/GraphCanvas/Widgets/StyledItemDelegates/IconDecoratedNameDelegate.h - StaticLib/GraphCanvas/Widgets/ToastNotification/ToastNotification.cpp - StaticLib/GraphCanvas/Widgets/ToastNotification/ToastNotification.h - StaticLib/GraphCanvas/Widgets/ToastNotification/ToastNotification.ui StaticLib/GraphCanvas/Utils/ColorUtils.h StaticLib/GraphCanvas/Utils/ConversionUtils.h StaticLib/GraphCanvas/Utils/GraphUtils.cpp diff --git a/Gems/ScriptCanvas/Code/Editor/Components/EditorGraph.cpp b/Gems/ScriptCanvas/Code/Editor/Components/EditorGraph.cpp index f003618c03..78325e9a90 100644 --- a/Gems/ScriptCanvas/Code/Editor/Components/EditorGraph.cpp +++ b/Gems/ScriptCanvas/Code/Editor/Components/EditorGraph.cpp @@ -19,6 +19,7 @@ AZ_POP_DISABLE_WARNING #include #include #include +#include #include #include #include @@ -3310,7 +3311,7 @@ namespace ScriptCanvasEditor void Graph::OnToastInteraction() { - const GraphCanvas::ToastId* toastId = GraphCanvas::ToastNotificationBus::GetCurrentBusId(); + const AzToolsFramework::ToastId* toastId = AzToolsFramework::ToastNotificationBus::GetCurrentBusId(); if (toastId) { @@ -3335,7 +3336,7 @@ namespace ScriptCanvasEditor void Graph::OnToastDismissed() { - const GraphCanvas::ToastId* toastId = GraphCanvas::ToastNotificationBus::GetCurrentBusId(); + const AzToolsFramework::ToastId* toastId = AzToolsFramework::ToastNotificationBus::GetCurrentBusId(); if (toastId) { @@ -3358,25 +3359,21 @@ namespace ScriptCanvasEditor void Graph::ReportError(const ScriptCanvas::Node& node, const AZStd::string& errorSource, const AZStd::string& errorMessage) { - GraphCanvas::ToastConfiguration toastConfiguration(GraphCanvas::ToastType::Error, errorSource, errorMessage); - - toastConfiguration.SetCloseOnClick(true); - toastConfiguration.SetDuration(AZStd::chrono::milliseconds(5000)); + AzQtComponents::ToastConfiguration toastConfiguration(AzQtComponents::ToastType::Error, errorSource.c_str(), errorMessage.c_str()); GraphCanvas::ViewId viewId; GraphCanvas::SceneRequestBus::EventResult(viewId, GetGraphCanvasGraphId(), &GraphCanvas::SceneRequests::GetViewId); - GraphCanvas::ToastId toastId; - + AzToolsFramework::ToastId toastId; GraphCanvas::ViewRequestBus::EventResult(toastId, viewId, &GraphCanvas::ViewRequests::ShowToastNotification, toastConfiguration); - GraphCanvas::ToastNotificationBus::MultiHandler::BusConnect(toastId); + AzToolsFramework::ToastNotificationBus::MultiHandler::BusConnect(toastId); m_toastNodeIds[toastId] = node.GetEntityId(); } - void Graph::UnregisterToast(const GraphCanvas::ToastId& toastId) + void Graph::UnregisterToast(const AzToolsFramework::ToastId& toastId) { - GraphCanvas::ToastNotificationBus::MultiHandler::BusDisconnect(toastId); + AzToolsFramework::ToastNotificationBus::MultiHandler::BusDisconnect(toastId); m_toastNodeIds.erase(toastId); } @@ -3408,10 +3405,7 @@ namespace ScriptCanvasEditor m_updateStrings.clear(); - GraphCanvas::ToastConfiguration toastConfiguration(GraphCanvas::ToastType::Information, "Nodes Updates", displayString); - toastConfiguration.SetCloseOnClick(true); - toastConfiguration.SetDuration(AZStd::chrono::milliseconds(5000)); - + AzQtComponents::ToastConfiguration toastConfiguration(AzQtComponents::ToastType::Information, "Nodes Updates", displayString.c_str()); GraphCanvas::ViewRequestBus::Event(viewId, &GraphCanvas::ViewRequests::ShowToastNotification, toastConfiguration); } } diff --git a/Gems/ScriptCanvas/Code/Editor/Include/ScriptCanvas/Components/EditorGraph.h b/Gems/ScriptCanvas/Code/Editor/Include/ScriptCanvas/Components/EditorGraph.h index 6f73e84493..9913fa838b 100644 --- a/Gems/ScriptCanvas/Code/Editor/Include/ScriptCanvas/Components/EditorGraph.h +++ b/Gems/ScriptCanvas/Code/Editor/Include/ScriptCanvas/Components/EditorGraph.h @@ -9,6 +9,7 @@ #include #include +#include #include #include #include @@ -27,7 +28,6 @@ #include #include #include -#include #include #include @@ -52,7 +52,7 @@ namespace ScriptCanvasEditor , private GraphCanvas::GraphModelRequestBus::Handler , private GraphCanvas::SceneNotificationBus::Handler , private GraphItemCommandNotificationBus::Handler - , private GraphCanvas::ToastNotificationBus::MultiHandler + , private AzToolsFramework::ToastNotificationBus::MultiHandler , private GeneralEditorNotificationBus::Handler , private AZ::SystemTickBus::Handler { @@ -327,7 +327,7 @@ namespace ScriptCanvasEditor protected: void PostRestore(const UndoData& restoredData) override; - void UnregisterToast(const GraphCanvas::ToastId& toastId); + void UnregisterToast(const AzToolsFramework::ToastId& toastId); Graph(const Graph&) = delete; @@ -350,7 +350,7 @@ namespace ScriptCanvasEditor void HandleQueuedUpdates(); bool IsNodeVersionConverting(const AZ::EntityId& graphCanvasNodeId) const; - AZStd::unordered_map< GraphCanvas::ToastId, AZ::EntityId > m_toastNodeIds; + AZStd::unordered_map< AzToolsFramework::ToastId, AZ::EntityId > m_toastNodeIds; // Function Definition Node Extension void HandleFunctionDefinitionExtension(ScriptCanvas::Node* node, GraphCanvas::SlotId graphCanvasSlotId, const GraphCanvas::NodeId& nodeId); diff --git a/Gems/ScriptCanvas/Code/Editor/View/Widgets/ValidationPanel/GraphValidationDockWidget.cpp b/Gems/ScriptCanvas/Code/Editor/View/Widgets/ValidationPanel/GraphValidationDockWidget.cpp index ded0130001..33de6c0e2c 100644 --- a/Gems/ScriptCanvas/Code/Editor/View/Widgets/ValidationPanel/GraphValidationDockWidget.cpp +++ b/Gems/ScriptCanvas/Code/Editor/View/Widgets/ValidationPanel/GraphValidationDockWidget.cpp @@ -8,6 +8,7 @@ #include +#include #include #include #include @@ -1434,31 +1435,28 @@ namespace ScriptCanvasEditor GraphCanvas::ViewId viewId; GraphCanvas::SceneRequestBus::EventResult(viewId, m_graphCanvasId, &GraphCanvas::SceneRequests::GetViewId); - GraphCanvas::ToastType toastType; + AzQtComponents::ToastType toastType; AZStd::string titleLabel = "Validation Issue"; AZStd::string description = ""; if (m_model->GetValidationResults().HasErrors()) { - toastType = GraphCanvas::ToastType::Error; + toastType = AzQtComponents::ToastType::Error; description = AZStd::string::format("%i validation error(s) were found.", m_model->GetValidationResults().ErrorCount()); } else { - toastType = GraphCanvas::ToastType::Warning; + toastType = AzQtComponents::ToastType::Warning; description = AZStd::string::format("%i validation warning(s) were found.", m_model->GetValidationResults().WarningCount()); } - GraphCanvas::ToastConfiguration toastConfiguration(toastType, titleLabel, description); + AzQtComponents::ToastConfiguration toastConfiguration(toastType, titleLabel.c_str(), description.c_str()); - toastConfiguration.SetCloseOnClick(true); - toastConfiguration.SetDuration(AZStd::chrono::milliseconds(5000)); - - GraphCanvas::ToastId validationToastId; + AzToolsFramework::ToastId validationToastId; GraphCanvas::ViewRequestBus::EventResult(validationToastId, viewId, &GraphCanvas::ViewRequests::ShowToastNotification, toastConfiguration); - GraphCanvas::ToastNotificationBus::MultiHandler::BusConnect(validationToastId); + AzToolsFramework::ToastNotificationBus::MultiHandler::BusConnect(validationToastId); } @@ -1469,11 +1467,11 @@ namespace ScriptCanvasEditor void ValidationData::OnToastDismissed() { - const GraphCanvas::ToastId* toastId = GraphCanvas::ToastNotificationBus::GetCurrentBusId(); + const AzToolsFramework::ToastId* toastId = AzToolsFramework::ToastNotificationBus::GetCurrentBusId(); if (toastId) { - GraphCanvas::ToastNotificationBus::MultiHandler::BusDisconnect((*toastId)); + AzToolsFramework::ToastNotificationBus::MultiHandler::BusDisconnect((*toastId)); } } diff --git a/Gems/ScriptCanvas/Code/Editor/View/Widgets/ValidationPanel/GraphValidationDockWidget.h b/Gems/ScriptCanvas/Code/Editor/View/Widgets/ValidationPanel/GraphValidationDockWidget.h index 107cfe7c10..66eecadaf8 100644 --- a/Gems/ScriptCanvas/Code/Editor/View/Widgets/ValidationPanel/GraphValidationDockWidget.h +++ b/Gems/ScriptCanvas/Code/Editor/View/Widgets/ValidationPanel/GraphValidationDockWidget.h @@ -15,10 +15,10 @@ #include #include +#include #include #include -#include #include #include @@ -183,7 +183,7 @@ namespace ScriptCanvasEditor //! Owns the model for each currently opened graph class ValidationData : private ScriptCanvas::StatusRequestBus::Handler - , private GraphCanvas::ToastNotificationBus::MultiHandler + , private AzToolsFramework::ToastNotificationBus::MultiHandler { public: AZ_CLASS_ALLOCATOR(ValidationData, AZ::SystemAllocator, 0); @@ -227,7 +227,7 @@ namespace ScriptCanvasEditor : public AzQtComponents::StyledDockWidget , public GraphCanvas::AssetEditorNotificationBus::Handler , public GraphCanvas::SceneNotificationBus::Handler - , public GraphCanvas::ToastNotificationBus::Handler + , public AzToolsFramework::ToastNotificationBus::Handler { Q_OBJECT public: diff --git a/Gems/ScriptCanvas/Code/Editor/View/Windows/MainWindow.h b/Gems/ScriptCanvas/Code/Editor/View/Windows/MainWindow.h index 2c84412e28..7672f0a199 100644 --- a/Gems/ScriptCanvas/Code/Editor/View/Windows/MainWindow.h +++ b/Gems/ScriptCanvas/Code/Editor/View/Windows/MainWindow.h @@ -27,6 +27,7 @@ #include #include +#include #include #include @@ -124,7 +125,7 @@ namespace ScriptCanvasEditor public: OnSaveToast(AZStd::string_view tabName, AZ::EntityId graphCanvasGraphId, bool saveSuccessful) { - GraphCanvas::ToastType toastType = GraphCanvas::ToastType::Information; + AzQtComponents::ToastType toastType = AzQtComponents::ToastType::Information; AZStd::string titleLabel = "Notification"; AZStd::string description; @@ -136,15 +137,12 @@ namespace ScriptCanvasEditor else { description = AZStd::string::format("Failed to save %s", tabName.data()); - toastType = GraphCanvas::ToastType::Error; + toastType = AzQtComponents::ToastType::Error; } - GraphCanvas::ToastConfiguration toastConfiguration(toastType, titleLabel, description); + AzQtComponents::ToastConfiguration toastConfiguration(toastType, titleLabel.c_str(), description.c_str()); - toastConfiguration.SetCloseOnClick(true); - toastConfiguration.SetDuration(AZStd::chrono::milliseconds(5000)); - - GraphCanvas::ToastId validationToastId; + AzToolsFramework::ToastId validationToastId; GraphCanvas::ViewId viewId; GraphCanvas::SceneRequestBus::EventResult(viewId, graphCanvasGraphId, &GraphCanvas::SceneRequests::GetViewId);