Did a major refactor of ui to be less dependent on levels

Signed-off-by: srikappa-amzn <srikappa@amazon.com>
This commit is contained in:
srikappa-amzn
2021-09-02 15:37:29 -07:00
parent 89a415d50c
commit f6acf4321d
20 changed files with 458 additions and 319 deletions
+20 -28
View File
@@ -728,19 +728,26 @@ void CCryEditApp::OnFileSave()
const QScopedValueRollback<bool> rollback(m_savingLevel, true);
GetIEditor()->GetDocument()->DoFileSave();
bool usePrefabSystemForLevels = false;
AzFramework::ApplicationRequests::Bus::BroadcastResult(
usePrefabSystemForLevels, &AzFramework::ApplicationRequests::IsPrefabSystemForLevelsEnabled);
if (usePrefabSystemForLevels)
if (!usePrefabSystemForLevels)
{
auto prefabSystemComponentInterface = AZ::Interface<AzToolsFramework::Prefab::PrefabSystemComponentInterface>::Get();
if (prefabSystemComponentInterface->AreDirtyTemplatesPresent())
{
GetIEditor()->GetDocument()->ExecuteSavePrefabsDialog();
}
GetIEditor()->GetDocument()->DoFileSave();
}
else
{
//auto prefabSystemComponentInterface = AZ::Interface<AzToolsFramework::Prefab::PrefabSystemComponentInterface>::Get();
auto prefabEditorEntityOwnershipService = AZ::Interface<AzToolsFramework::PrefabEditorEntityOwnershipInterface>::Get();
AzToolsFramework::Prefab::TemplateId rootPrefabTemplateId = prefabEditorEntityOwnershipService->GetRootPrefabTemplateId();
auto prefabIntegrationInterface = AZ::Interface<AzToolsFramework::Prefab::PrefabIntegrationInterface>::Get();
prefabIntegrationInterface->ExecuteSavePrefabsDialog(rootPrefabTemplateId, true);
// prefabSystemComponentInterface->AreDirtyTemplatesPresent(rootPrefabTemplateId)
}
}
@@ -3186,18 +3193,12 @@ bool CCryEditApp::CreateLevel(bool& wasCreateLevelOperationCancelled)
}
else
{
using namespace AzToolsFramework::Prefab;
auto prefabEditorEntityOwnershipInterface = AZ::Interface<AzToolsFramework::PrefabEditorEntityOwnershipInterface>::Get();
auto prefabIntegrationInterface = AZ::Interface<AzToolsFramework::Prefab::PrefabIntegrationInterface>::Get();
AzToolsFramework::Prefab::TemplateId rootPrefabTemplateId = prefabEditorEntityOwnershipInterface->GetRootPrefabTemplateId();
auto prefabSystemComponentInterface = AZ::Interface<AzToolsFramework::Prefab::PrefabSystemComponentInterface>::Get();
auto prefabSaveSelectionDialog = GetIEditor()->GetDocument()->ConstructSaveLevelDialog();
int prefabSaveSelection = prefabSaveSelectionDialog->exec();
QCheckBox* saveAllPrefabsPreferenceCheckBox =
prefabSaveSelectionDialog->findChild<QCheckBox*>("SaveAllPrefabsPreferenceCheckBox");
QCheckBox* saveAllPrefabsCheckBox = prefabSaveSelectionDialog->findChild<QCheckBox*>("SaveAllPrefabsCheckbox");
SavePrefabsPreference savePrefabsPreference = saveAllPrefabsCheckBox->isChecked()
? SavePrefabsPreference::SaveAll
: SavePrefabsPreference::SaveNone;
int prefabSaveSelection =
prefabIntegrationInterface->ExecuteClosePrefabDialog(rootPrefabTemplateId);
// In order to get the accept and reject codes of QDialog and QDialogButtonBox aligned, we do (1-prefabSaveSelection) here.
switch (1 - prefabSaveSelection)
@@ -3210,16 +3211,7 @@ bool CCryEditApp::CreateLevel(bool& wasCreateLevelOperationCancelled)
wasCreateLevelOperationCancelled = true;
return false;
}
if (saveAllPrefabsPreferenceCheckBox->checkState() == Qt::CheckState::Checked)
{
gSettings.SetSavePrefabsPreference(savePrefabsPreference);
gSettings.Save();
}
if (savePrefabsPreference == SavePrefabsPreference::SaveAll)
{
prefabSystemComponentInterface->SaveAllDirtyTemplates();
}
bIsDocModified = prefabSystemComponentInterface->AreDirtyTemplatesPresent();
bIsDocModified = false;
break;
case QDialogButtonBox::RejectRole:
wasCreateLevelOperationCancelled = true;
+26 -219
View File
@@ -15,8 +15,14 @@
#include <QDateTime>
#include <QCheckBox>
#include <QDialogButtonBox>
#include <QGroupBox>
#include <QListWidget>
#include <QScrollArea>
#include <QSizePolicy>
#include <AzQtComponents/Components/FlowLayout.h>
#include <AzQtComponents/Components/StyleManager.h>
#include <AzQtComponents/Components/Widgets/CheckBox.h>
#include <AzQtComponents/Components/Widgets/CardHeader.h>
// AzCore
#include <AzCore/Component/TransformBus.h>
@@ -34,9 +40,6 @@
#include <AzToolsFramework/UI/UICore/WidgetHelpers.h>
#include <AzToolsFramework/UI/Layer/NameConflictWarning.hxx>
#include <AzToolsFramework/API/EditorLevelNotificationBus.h>
#include <AzToolsFramework/Entity/PrefabEditorEntityOwnershipInterface.h>
#include <AzToolsFramework/Prefab/PrefabLoaderInterface.h>
#include <AzToolsFramework/Prefab/PrefabSystemComponentInterface.h>
// Editor
#include "Settings.h"
@@ -138,6 +141,14 @@ CCryEditDoc::CCryEditDoc()
RegisterConsoleVariables();
MainWindow::instance()->GetActionManager()->RegisterActionHandler(ID_FILE_SAVE_AS, this, &CCryEditDoc::OnFileSaveAs);
m_prefabSystemComponentInterface = AZ::Interface<AzToolsFramework::Prefab::PrefabSystemComponentInterface>::Get();
AZ_Assert(m_prefabSystemComponentInterface, "PrefabSystemComponentInterface is not found.");
m_prefabEditorEntityOwnershipInterface = AZ::Interface<AzToolsFramework::PrefabEditorEntityOwnershipInterface>::Get();
AZ_Assert(m_prefabEditorEntityOwnershipInterface, "PrefabEditorEntityOwnershipInterface is not found.");
m_prefabLoaderInterface = AZ::Interface<AzToolsFramework::Prefab::PrefabLoaderInterface>::Get();
AZ_Assert(m_prefabLoaderInterface, "PrefabLoaderInterface is not found.");
m_prefabIntegrationInterface = AZ::Interface<AzToolsFramework::Prefab::PrefabIntegrationInterface>::Get();
AZ_Assert(m_prefabIntegrationInterface, "PrefabIntegrationInterface is not found.");
}
CCryEditDoc::~CCryEditDoc()
@@ -699,29 +710,18 @@ bool CCryEditDoc::SaveModified()
{
using namespace AzToolsFramework::Prefab;
auto prefabSystemComponentInterface = AZ::Interface<AzToolsFramework::Prefab::PrefabSystemComponentInterface>::Get();
auto prefabSaveSelectionDialog = ConstructSaveLevelDialog();
int prefabSaveSelection = prefabSaveSelectionDialog->exec();
QCheckBox* saveAllPrefabsPreferenceCheckBox = prefabSaveSelectionDialog->findChild<QCheckBox*>("SaveAllPrefabsPreferenceCheckBox");
QCheckBox* saveAllPrefabsCheckBox = prefabSaveSelectionDialog->findChild<QCheckBox*>("SaveAllPrefabsCheckbox");
SavePrefabsPreference savePrefabsPreference =
saveAllPrefabsCheckBox->isChecked() ? SavePrefabsPreference::SaveAll : SavePrefabsPreference::SaveNone;
TemplateId rootPrefabTemplateId = m_prefabEditorEntityOwnershipInterface->GetRootPrefabTemplateId();
if (!m_prefabSystemComponentInterface->AreDirtyTemplatesPresent(rootPrefabTemplateId))
{
return true;
}
int prefabSaveSelection = m_prefabIntegrationInterface->ExecuteClosePrefabDialog(rootPrefabTemplateId);
// In order to get the accept and reject codes of QDialog and QDialogButtonBox aligned, we do (1-prefabSaveSelection) here.
switch (1 - prefabSaveSelection)
{
case QDialogButtonBox::AcceptRole:
DoFileSave();
if (saveAllPrefabsPreferenceCheckBox->checkState() == Qt::CheckState::Checked)
{
gSettings.SetSavePrefabsPreference(savePrefabsPreference);
gSettings.Save();
}
if (savePrefabsPreference == SavePrefabsPreference::SaveAll)
{
prefabSystemComponentInterface->SaveAllDirtyTemplates();
}
return true;
case QDialogButtonBox::RejectRole:
return false;
@@ -749,11 +749,9 @@ void CCryEditDoc::OnFileSaveAs()
usePrefabSystemForLevels, &AzFramework::ApplicationRequests::IsPrefabSystemForLevelsEnabled);
if (usePrefabSystemForLevels)
{
auto prefabSystemComponentInterface = AZ::Interface<AzToolsFramework::Prefab::PrefabSystemComponentInterface>::Get();
if (prefabSystemComponentInterface->AreDirtyTemplatesPresent())
{
ExecuteSavePrefabsDialog();
}
AzToolsFramework::Prefab::TemplateId rootPrefabTemplateId =
m_prefabEditorEntityOwnershipInterface->GetRootPrefabTemplateId();
SetModifiedFlag(m_prefabSystemComponentInterface->AreDirtyTemplatesPresent(rootPrefabTemplateId));
}
}
}
@@ -1311,8 +1309,7 @@ bool CCryEditDoc::SaveLevel(const QString& filename)
}
else
{
auto prefabEditorEntityOwnershipInterface = AZ::Interface<AzToolsFramework::PrefabEditorEntityOwnershipInterface>::Get();
if (prefabEditorEntityOwnershipInterface)
if (m_prefabEditorEntityOwnershipInterface)
{
AZ::IO::FileIOBase* fileIO = AZ::IO::FileIOBase::GetInstance();
AZ_Assert(fileIO, "No File IO implementation available");
@@ -1323,7 +1320,7 @@ bool CCryEditDoc::SaveLevel(const QString& filename)
if (openResult)
{
AZ::IO::FileIOStream stream(tempSaveFileHandle, AZ::IO::OpenMode::ModeWrite | AZ::IO::OpenMode::ModeBinary, false);
contentsAllSaved = prefabEditorEntityOwnershipInterface->SaveToStream(stream, AZStd::string_view(filenameStrData.data(), filenameStrData.size()));
contentsAllSaved = m_prefabEditorEntityOwnershipInterface->SaveToStream(stream, AZStd::string_view(filenameStrData.data(), filenameStrData.size()));
stream.Close();
}
}
@@ -2264,196 +2261,6 @@ void CCryEditDoc::OnSliceInstantiationFailed(const AZ::Data::AssetId& sliceAsset
}
//////////////////////////////////////////////////////////////////////////
AZStd::shared_ptr<QDialog> CCryEditDoc::ConstructSaveLevelDialog()
{
using namespace AzToolsFramework::Prefab;
auto prefabLoaderInterface = AZ::Interface<PrefabLoaderInterface>::Get();
SavePrefabsPreference savePrefabsPreference = prefabLoaderInterface->GetSavePrefabsPreference();
AZStd::shared_ptr<QDialog> saveModifiedMessageBox = AZStd::make_shared<QDialog>(AzToolsFramework::GetActiveWindow());
AZStd::weak_ptr<QDialog> saveModifiedMessageBoxWeakPtr(saveModifiedMessageBox);
// saveModifiedMessageBox.overrideWindowFlags((saveModifiedMessageBox.windowFlags()) & ~Qt::WindowCloseButtonHint);
saveModifiedMessageBox->setObjectName("SaveDirtyLevelDialog");
// Main Content section begins.
QVBoxLayout* contentLayout = new QVBoxLayout(saveModifiedMessageBox.get());
QFrame* levelEntitiesSaveQuestionFrame = new QFrame(saveModifiedMessageBox.get());
QHBoxLayout* levelEntitiesSaveQuestionLayout = new QHBoxLayout(saveModifiedMessageBox.get());
levelEntitiesSaveQuestionFrame->setObjectName("LevelEntitiesSaveQuestionFrame");
// Add a warning icon next to save entities question.
levelEntitiesSaveQuestionFrame->setLayout(levelEntitiesSaveQuestionLayout);
QPixmap warningIcon(QString(":/Notifications/warning.svg"));
QLabel* warningIconContainer = new QLabel();
warningIconContainer->setPixmap(warningIcon);
warningIconContainer->setFixedWidth(warningIcon.width());
levelEntitiesSaveQuestionLayout->addWidget(warningIconContainer);
// Ask user if they want to save entities in level.
QLabel* levelEntitiesSaveQuestionLabel = new QLabel("Do you want to save unsaved entities in the level?");
levelEntitiesSaveQuestionLayout->addWidget(levelEntitiesSaveQuestionLabel);
contentLayout->addWidget(levelEntitiesSaveQuestionFrame);
// Ask user if they want to save unsaved prefabs in the level too.
QCheckBox* saveAllPrefabsCheckbox = new QCheckBox("Save all unsaved prefabs in the level too.");
AzQtComponents::CheckBox::applyToggleSwitchStyle(saveAllPrefabsCheckbox);
saveAllPrefabsCheckbox->setObjectName("SaveAllPrefabsCheckbox");
if (savePrefabsPreference == SavePrefabsPreference::SaveAll)
{
saveAllPrefabsCheckbox->setCheckState(Qt::CheckState::Checked);
}
QObject::connect(
saveAllPrefabsCheckbox, &QCheckBox::stateChanged,
[&savePrefabsPreference](int state)
{
savePrefabsPreference = static_cast<Qt::CheckState>(state) == Qt::CheckState::Checked ? SavePrefabsPreference::SaveAll
: SavePrefabsPreference::SaveNone;
});
contentLayout->addWidget(saveAllPrefabsCheckbox);
// Footer section begins.
QFrame* footerSeparatorLine = new QFrame();
footerSeparatorLine->setObjectName("FooterSeparatorLine");
footerSeparatorLine->setFrameShape(QFrame::HLine);
contentLayout->addWidget(footerSeparatorLine);
QHBoxLayout* footerLayout = new QHBoxLayout(saveModifiedMessageBox.get());
// Provide option for user to remember their prefab save preference.
QCheckBox* saveAllPrefabsPreferenceCheckBox = new QCheckBox("Remember my preference.");
saveAllPrefabsPreferenceCheckBox->setObjectName("SaveAllPrefabsPreferenceCheckBox");
AzQtComponents::CheckBox::applyToggleSwitchStyle(saveAllPrefabsPreferenceCheckBox);
if (savePrefabsPreference != SavePrefabsPreference::Unspecified)
{
saveAllPrefabsPreferenceCheckBox->setCheckState(Qt::CheckState::Checked);
}
QVBoxLayout* footerPreferenceLayout = new QVBoxLayout(saveModifiedMessageBox.get());
footerPreferenceLayout->addWidget(saveAllPrefabsPreferenceCheckBox);
QLabel* prefabSavePreferenceHint = new QLabel("You can change this anytime in Edit -> Editor Settings -> GlobalPreferences.");
prefabSavePreferenceHint->setObjectName("PrefabSavePreferenceHint");
footerPreferenceLayout->addWidget(prefabSavePreferenceHint);
footerLayout->addLayout(footerPreferenceLayout);
QDialogButtonBox* prefabSaveConfirmationButtons =
new QDialogButtonBox(QDialogButtonBox::Save | QDialogButtonBox::Discard | QDialogButtonBox::Cancel);
footerLayout->addWidget(prefabSaveConfirmationButtons);
contentLayout->addLayout(footerLayout);
connect(prefabSaveConfirmationButtons, &QDialogButtonBox::accepted, saveModifiedMessageBox.get(), &QDialog::accept);
connect(prefabSaveConfirmationButtons, &QDialogButtonBox::rejected, saveModifiedMessageBox.get(), &QDialog::reject);
connect(
prefabSaveConfirmationButtons, &QDialogButtonBox::clicked, saveModifiedMessageBox.get(),
[saveModifiedMessageBoxWeakPtr, prefabSaveConfirmationButtons](QAbstractButton* button)
{
int prefabSaveSelection = prefabSaveConfirmationButtons->buttonRole(button);
saveModifiedMessageBoxWeakPtr.lock()->done(prefabSaveSelection);
});
AzQtComponents::StyleManager::setStyleSheet(saveModifiedMessageBox.get(), QStringLiteral("style:Editor.qss"));
return saveModifiedMessageBox;
}
void CCryEditDoc::ExecuteSavePrefabsDialog()
{
using namespace AzToolsFramework::Prefab;
auto prefabSystemComponentInterface = AZ::Interface<AzToolsFramework::Prefab::PrefabSystemComponentInterface>::Get();
auto prefabLoaderInterface = AZ::Interface<PrefabLoaderInterface>::Get();
SavePrefabsPreference savePrefabsPreference = prefabLoaderInterface->GetSavePrefabsPreference();
if (savePrefabsPreference == SavePrefabsPreference::SaveAll)
{
prefabSystemComponentInterface->SaveAllDirtyTemplates();
SetModifiedFlag(false);
}
else if (savePrefabsPreference == SavePrefabsPreference::SaveNone)
{
if (prefabSystemComponentInterface->AreDirtyTemplatesPresent())
{
SetModifiedFlag(true);
}
}
else // SavePrefabsPreference::Unspecified
{
QDialog saveModifiedMessageBox(AzToolsFramework::GetActiveWindow());
// Main Content section begins.
saveModifiedMessageBox.setObjectName("SaveAllPrefabsDialog");
QBoxLayout* contentLayout = new QVBoxLayout(&saveModifiedMessageBox);
QFrame* levelSavedMessageFrame = new QFrame(&saveModifiedMessageBox);
QHBoxLayout* levelSavedMessageLayout = new QHBoxLayout(&saveModifiedMessageBox);
levelSavedMessageFrame->setObjectName("LevelSavedMessageFrame");
// Add a checkMark icon next to the level entities saved message.
QPixmap checkMarkIcon(QString(":/Notifications/checkmark.svg"));
QLabel* levelSavedSuccessfullyIconContainer = new QLabel();
levelSavedSuccessfullyIconContainer->setPixmap(checkMarkIcon);
levelSavedSuccessfullyIconContainer->setFixedWidth(checkMarkIcon.width());
// Add a message that level entities are saved successfully.
QLabel* levelSavedSuccessfullyLabel = new QLabel("All entities inside level have been saved successfully.");
levelSavedSuccessfullyLabel->setObjectName("LevelSavedSuccessfullyLabel");
levelSavedMessageLayout->addWidget(levelSavedSuccessfullyIconContainer);
levelSavedMessageLayout->addWidget(levelSavedSuccessfullyLabel);
levelSavedMessageFrame->setLayout(levelSavedMessageLayout);
QFrame* prefabSaveQuestionFrame = new QFrame(&saveModifiedMessageBox);
QHBoxLayout* prefabSaveQuestionLayout = new QHBoxLayout(&saveModifiedMessageBox);
// Add a warning icon next to prefabs save question.
QLabel* warningIconContainer = new QLabel();
QPixmap warningIcon(QString(":/Notifications/warning.svg"));
warningIconContainer->setPixmap(warningIcon);
warningIconContainer->setFixedWidth(warningIcon.width());
prefabSaveQuestionLayout->addWidget(warningIconContainer);
// Ask if user wants all prefabs saved.
QLabel* prefabSaveQuestionLabel = new QLabel("Do you want to save all unsaved prefabs?");
prefabSaveQuestionFrame->setObjectName("PrefabSaveQuestionFrame");
prefabSaveQuestionLayout->addWidget(prefabSaveQuestionLabel);
prefabSaveQuestionFrame->setLayout(prefabSaveQuestionLayout);
contentLayout->addWidget(levelSavedMessageFrame);
contentLayout->addWidget(prefabSaveQuestionFrame);
// Footer section begins.
QFrame* footerSeparatorLine = new QFrame();
footerSeparatorLine->setObjectName("FooterSeparatorLine");
footerSeparatorLine->setFrameShape(QFrame::HLine);
contentLayout->addWidget(footerSeparatorLine);
QHBoxLayout* footerLayout = new QHBoxLayout(&saveModifiedMessageBox);
// Provide option for user to remember their prefab save preference.
QCheckBox* saveAllPrefabsPreference = new QCheckBox("Remember my preference.");
AzQtComponents::CheckBox::applyToggleSwitchStyle(saveAllPrefabsPreference);
QVBoxLayout* footerPreferenceLayout = new QVBoxLayout(&saveModifiedMessageBox);
footerPreferenceLayout->addWidget(saveAllPrefabsPreference);
QLabel* prefabSavePreferenceHint = new QLabel("You can change this anytime in Edit -> Editor Settings -> GlobalPreferences.");
prefabSavePreferenceHint->setObjectName("PrefabSavePreferenceHint");
footerPreferenceLayout->addWidget(prefabSavePreferenceHint);
footerLayout->addLayout(footerPreferenceLayout);
QDialogButtonBox* prefabSaveConfirmationButtons = new QDialogButtonBox(QDialogButtonBox::Save | QDialogButtonBox::No);
footerLayout->addWidget(prefabSaveConfirmationButtons);
contentLayout->addLayout(footerLayout);
connect(prefabSaveConfirmationButtons, &QDialogButtonBox::accepted, &saveModifiedMessageBox, &QDialog::accept);
connect(prefabSaveConfirmationButtons, &QDialogButtonBox::rejected, &saveModifiedMessageBox, &QDialog::reject);
AzQtComponents::StyleManager::setStyleSheet(saveModifiedMessageBox.parentWidget(), QStringLiteral("style:Editor.qss"));
int prefabSaveSelection = saveModifiedMessageBox.exec();
if (saveAllPrefabsPreference->checkState() == Qt::CheckState::Checked)
{
gSettings.SetSavePrefabsPreference(savePrefabsPreference);
gSettings.Save();
}
switch (prefabSaveSelection)
{
case QDialog::Accepted:
prefabSystemComponentInterface->SaveAllDirtyTemplates();
SetModifiedFlag(false);
break;
case QDialog::Rejected:
SetModifiedFlag(true);
break;
}
}
}
namespace AzToolsFramework
{
void CryEditDocFuncsHandler::Reflect(AZ::ReflectContext* context)
+9 -6
View File
@@ -13,8 +13,13 @@
#if !defined(Q_MOC_RUN)
#include "DocMultiArchive.h"
#include <AzToolsFramework/Entity/PrefabEditorEntityOwnershipInterface.h>
#include <AzToolsFramework/Entity/SliceEditorEntityOwnershipServiceBus.h>
#include <AzToolsFramework/Prefab/PrefabLoaderInterface.h>
#include <AzToolsFramework/Prefab/PrefabSystemComponentInterface.h>
#include <AzToolsFramework/UI/Prefab/PrefabIntegrationInterface.h>
#include <AzCore/Component/Component.h>
#include <AzQtComponents/Components/Widgets/Card.h>
#include <TimeValue.h>
#include <IEditor.h>
#endif
@@ -104,12 +109,6 @@ public: // Create from serialization only
bool CanCloseFrame();
//! Returns a Modal containing options to save the current level.
AZStd::shared_ptr<QDialog> ConstructSaveLevelDialog();
//! Executes a Modal asking users about their prefabs save preference.
void ExecuteSavePrefabsDialog();
enum class FetchPolicy
{
DELETE_FOLDER,
@@ -215,6 +214,10 @@ protected:
const char* m_envProbeSliceRelativePath = "EngineAssets/Slices/DefaultLevelSetup.slice";
const float m_envProbeHeight = 200.0f;
bool m_hasErrors = false; ///< This is used to warn the user that they may lose work when they go to save.
AzToolsFramework::Prefab::PrefabSystemComponentInterface* m_prefabSystemComponentInterface = nullptr;
AzToolsFramework::PrefabEditorEntityOwnershipInterface* m_prefabEditorEntityOwnershipInterface = nullptr;
AzToolsFramework::Prefab::PrefabLoaderInterface* m_prefabLoaderInterface = nullptr;
AzToolsFramework::Prefab::PrefabIntegrationInterface* m_prefabIntegrationInterface = nullptr;
};
class CAutoDocNotReady
+12 -12
View File
@@ -42,9 +42,9 @@ void CEditorPreferencesPage_General::Reflect(AZ::SerializeContext& serialize)
->Field("EnableSceneInspector", &GeneralSettings::m_enableSceneInspector)
->Field("RestoreViewportCamera", &GeneralSettings::m_restoreViewportCamera);
serialize.Class<PrefabSettings>()
serialize.Class<GlobalSaveSettings>()
->Version(1)
->Field("SavePrefabsPreference", &PrefabSettings::m_savePrefabsPreference);
->Field("SaveAllPrefabsPreference", &GlobalSaveSettings::m_saveAllPrefabsPreference);
serialize.Class<Messaging>()
->Version(2)
@@ -68,7 +68,7 @@ void CEditorPreferencesPage_General::Reflect(AZ::SerializeContext& serialize)
serialize.Class<CEditorPreferencesPage_General>()
->Version(1)
->Field("General Settings", &CEditorPreferencesPage_General::m_generalSettings)
->Field("Prefab Settings", &CEditorPreferencesPage_General::m_prefabSettings)
->Field("Global Save Settings", &CEditorPreferencesPage_General::m_globalSaveSettings)
->Field("Messaging", &CEditorPreferencesPage_General::m_messaging)
->Field("Undo", &CEditorPreferencesPage_General::m_undo)
->Field("Deep Selection", &CEditorPreferencesPage_General::m_deepSelection)
@@ -97,13 +97,13 @@ void CEditorPreferencesPage_General::Reflect(AZ::SerializeContext& serialize)
->DataElement(AZ::Edit::UIHandlers::CheckBox, &GeneralSettings::m_restoreViewportCamera, EditorPreferencesGeneralRestoreViewportCameraSettingName, "Keep the original editor viewport transform when exiting game mode.")
->DataElement(AZ::Edit::UIHandlers::CheckBox, &GeneralSettings::m_enableSceneInspector, "Enable Scene Inspector (EXPERIMENTAL)", "Enable the option to inspect the internal data loaded from scene files like .fbx. This is an experimental feature. Restart the Scene Settings if the option is not visible under the Help menu.");
editContext->Class<PrefabSettings>("Prefabs", "")
editContext->Class<GlobalSaveSettings>("Global Save Settings (File > Save & Ctrl+S)", "")
->DataElement(
AZ::Edit::UIHandlers::ComboBox, &PrefabSettings::m_savePrefabsPreference, "Save Prefabs Preference",
"When saving levels, this option controls whether and how prefabs should be saved along with the level.")
->EnumAttribute(AzToolsFramework::Prefab::SavePrefabsPreference::Unspecified, "Unspecified")
->EnumAttribute(AzToolsFramework::Prefab::SavePrefabsPreference::SaveAll, "Save All")
->EnumAttribute(AzToolsFramework::Prefab::SavePrefabsPreference::SaveNone, "Save None");
AZ::Edit::UIHandlers::ComboBox, &GlobalSaveSettings::m_saveAllPrefabsPreference, "Save Prefabs Preference",
"This option controls whether prefabs should be saved along with the level")
->EnumAttribute(AzToolsFramework::Prefab::SaveAllPrefabsPreference::AskEveryTime, "Ask every time")
->EnumAttribute(AzToolsFramework::Prefab::SaveAllPrefabsPreference::SaveAll, "Save all")
->EnumAttribute(AzToolsFramework::Prefab::SaveAllPrefabsPreference::SaveNone, "Save none");
editContext->Class<Messaging>("Messaging", "")
->DataElement(AZ::Edit::UIHandlers::CheckBox, &Messaging::m_showDashboard, "Show Welcome to Open 3D Engine at startup", "Show Welcome to Open 3D Engine at startup")
@@ -128,7 +128,7 @@ void CEditorPreferencesPage_General::Reflect(AZ::SerializeContext& serialize)
->ClassElement(AZ::Edit::ClassElements::EditorData, "")
->Attribute(AZ::Edit::Attributes::Visibility, AZ_CRC("PropertyVisibility_ShowChildrenOnly", 0xef428f20))
->DataElement(AZ::Edit::UIHandlers::Default, &CEditorPreferencesPage_General::m_generalSettings, "General Settings", "General Editor Preferences")
->DataElement(AZ::Edit::UIHandlers::Default, &CEditorPreferencesPage_General::m_prefabSettings, "Prefabs", "Prefab Settings")
->DataElement(AZ::Edit::UIHandlers::Default, &CEditorPreferencesPage_General::m_globalSaveSettings, "Global Save Settings", "Global Save Settings")
->DataElement(AZ::Edit::UIHandlers::Default, &CEditorPreferencesPage_General::m_messaging, "Messaging", "Messaging")
->DataElement(AZ::Edit::UIHandlers::Default, &CEditorPreferencesPage_General::m_undo, "Undo", "Undo Preferences")
->DataElement(AZ::Edit::UIHandlers::Default, &CEditorPreferencesPage_General::m_deepSelection, "Selection", "Selection")
@@ -176,7 +176,7 @@ void CEditorPreferencesPage_General::OnApply()
}
//prefabs
gSettings.prefabSettings.savePrefabsPreference = m_prefabSettings.m_savePrefabsPreference;
gSettings.globalSaveSettings.saveAllPrefabsPreference = m_globalSaveSettings.m_saveAllPrefabsPreference;
//undo
gSettings.undoLevels = m_undo.m_undoLevels;
@@ -208,7 +208,7 @@ void CEditorPreferencesPage_General::InitializeSettings()
m_generalSettings.m_toolbarIconSize = static_cast<AzQtComponents::ToolBar::ToolBarIconSize>(gSettings.gui.nToolbarIconSize);
//prefabs
m_prefabSettings.m_savePrefabsPreference = gSettings.prefabSettings.savePrefabsPreference;
m_globalSaveSettings.m_saveAllPrefabsPreference = gSettings.globalSaveSettings.saveAllPrefabsPreference;
//Messaging
m_messaging.m_showDashboard = gSettings.bShowDashboardAtStartup;
+4 -4
View File
@@ -58,10 +58,10 @@ private:
bool m_enableSceneInspector;
};
struct PrefabSettings
struct GlobalSaveSettings
{
AZ_TYPE_INFO(PrefabSettings, "{E297DAE3-3985-4BC2-8B43-45F3B1522F6B}");
AzToolsFramework::Prefab::SavePrefabsPreference m_savePrefabsPreference;
AZ_TYPE_INFO(GlobalSaveSettings, "{E297DAE3-3985-4BC2-8B43-45F3B1522F6B}");
AzToolsFramework::Prefab::SaveAllPrefabsPreference m_saveAllPrefabsPreference;
};
struct Messaging
@@ -96,7 +96,7 @@ private:
};
GeneralSettings m_generalSettings;
PrefabSettings m_prefabSettings;
GlobalSaveSettings m_globalSaveSettings;
Messaging m_messaging;
Undo m_undo;
DeepSelection m_deepSelection;
+3 -8
View File
@@ -255,7 +255,7 @@ SEditorSettings::SEditorSettings()
g_TemporaryLevelName = nullptr;
sliceSettings.dynamicByDefault = false;
prefabSettings.savePrefabsPreference = AzToolsFramework::Prefab::SavePrefabsPreference::Unspecified;
globalSaveSettings.saveAllPrefabsPreference = AzToolsFramework::Prefab::SaveAllPrefabsPreference::AskEveryTime;
}
void SEditorSettings::Connect()
@@ -672,7 +672,7 @@ void SEditorSettings::Save()
AzToolsFramework::Prefab::PrefabLoaderInterface* prefabLoaderInterface =
AZ::Interface<AzToolsFramework::Prefab::PrefabLoaderInterface>::Get();
prefabLoaderInterface->SetSavePrefabsPreference(prefabSettings.savePrefabsPreference);
prefabLoaderInterface->SetSaveAllPrefabsPreference(globalSaveSettings.saveAllPrefabsPreference);
SaveSettingsRegistryFile();
}
@@ -682,7 +682,7 @@ void SEditorSettings::Load()
{
AzToolsFramework::Prefab::PrefabLoaderInterface* prefabLoaderInterface =
AZ::Interface<AzToolsFramework::Prefab::PrefabLoaderInterface>::Get();
prefabSettings.savePrefabsPreference = prefabLoaderInterface->GetSavePrefabsPreference();
globalSaveSettings.saveAllPrefabsPreference = prefabLoaderInterface->GetSaveAllPrefabsPreference();
// Load from Settings Registry
AzFramework::ApplicationRequests::Bus::BroadcastResult(
@@ -1082,11 +1082,6 @@ void SEditorSettings::ConvertPath(const AZStd::string_view sourcePath, AZStd::st
AZStd::replace(category.begin(), category.end(), '|', '\\');
}
void SEditorSettings::SetSavePrefabsPreference(AzToolsFramework::Prefab::SavePrefabsPreference savePrefabsPreference)
{
prefabSettings.savePrefabsPreference = savePrefabsPreference;
}
AzToolsFramework::EditorSettingsAPIRequests::SettingOutcome SEditorSettings::GetValue(const AZStd::string_view path)
{
if (path.find("|") == AZStd::string_view::npos)
+3 -5
View File
@@ -231,9 +231,9 @@ struct SSliceSettings
bool dynamicByDefault;
};
struct SPrefabSettings
struct SGlobalSaveSettings
{
AzToolsFramework::Prefab::SavePrefabsPreference savePrefabsPreference;
AzToolsFramework::Prefab::SaveAllPrefabsPreference saveAllPrefabsPreference;
};
//////////////////////////////////////////////////////////////////////////
@@ -472,12 +472,10 @@ AZ_POP_DISABLE_DLL_EXPORT_BASECLASS_WARNING
SSliceSettings sliceSettings;
SPrefabSettings prefabSettings;
SGlobalSaveSettings globalSaveSettings;
bool prefabSystem = true; ///< Toggle to enable/disable the Prefab system for level entities.
void SetSavePrefabsPreference(AzToolsFramework::Prefab::SavePrefabsPreference savePrefabsPreference);
private:
void SaveValue(const char* sSection, const char* sKey, int value);
void SaveValue(const char* sSection, const char* sKey, const QColor& value);
+22 -7
View File
@@ -245,29 +245,44 @@ QTableWidget#recentLevelTable::item {
qproperty-iconSize: 16px 16px;
}
#LevelSavedMessageFrame{
QListWidget::item
{
border : none;
}
#SavePrefabDialog, #SaveAllFilesDialog
{
min-width : 640px;
}
#SaveDependentPrefabsCard
{
margin: 0px 15px 10px 15px;
}
#PrefabSavedMessageFrame{
border: 1px solid green;
margin: 10px 15px 10px 15px;
border-radius: 2px;
margin: 5px 20px 5px 20px;
padding: 5px 2px 5px 2px;
}
#SaveAllPrefabsDialog #PrefabSaveQuestionFrame, #SaveDirtyLevelDialog #LevelEntitiesSaveQuestionFrame, #SaveAllPrefabsCheckbox
#SavePrefabDialog #PrefabSaveWarningFrame
{
border: 1px solid orange;
margin: 10px 15px 10px 15px;
border-radius: 2px;
margin: 5px 20px 5px 20px;
padding: 5px 2px 5px 2px;
color : white;
}
#SaveAllPrefabsDialog #FooterSeparatorLine, #SaveDirtyLevelDialog #FooterSeparatorLine
#SaveAllFilesDialog #FooterSeparatorLine, #SavePrefabDialog #FooterSeparatorLine
{
color: gray;
}
#SaveAllPrefabsDialog #PrefabSavePreferenceHint, #SaveDirtyLevelDialog #PrefabSavePreferenceHint
#SaveAllFilesDialog #PrefabSavePreferenceHint, #SavePrefabDialog #PrefabSavePreferenceHint
{
font: italic;
color: #999999;
}
}
@@ -43,6 +43,8 @@ namespace AzToolsFramework
virtual Prefab::InstanceOptionalReference GetRootPrefabInstance() = 0;
virtual Prefab::TemplateId GetRootPrefabTemplateId() = 0;
//! Get all Assets generated by Prefab processing when entering Play-In Editor mode (Ctrl+G)
//! /return The vector of Assets generated by Prefab processing
virtual const AZStd::vector<AZ::Data::Asset<AZ::Data::AssetData>>& GetPlayInEditorAssetData() = 0;
@@ -54,5 +56,6 @@ namespace AzToolsFramework
virtual void StopPlayInEditor() = 0;
virtual void CreateNewLevelPrefab(AZStd::string_view filename, const AZStd::string& templateFilename) = 0;
virtual bool IsRootTemplateDirty() = 0;
};
}
@@ -359,6 +359,16 @@ namespace AzToolsFramework
return AZStd::nullopt;
}
Prefab::TemplateId PrefabEditorEntityOwnershipService::GetRootPrefabTemplateId()
{
AZ_Assert(m_rootInstance, "A valid root prefab instance couldn't be found in PrefabEditorEntityOwnershipService.");
if (m_rootInstance)
{
return m_rootInstance->GetTemplateId();
}
return Prefab::InvalidTemplateId;
}
const AZStd::vector<AZ::Data::Asset<AZ::Data::AssetData>>& PrefabEditorEntityOwnershipService::GetPlayInEditorAssetData()
{
return m_playInEditorData.m_assets;
@@ -607,6 +617,11 @@ namespace AzToolsFramework
m_playInEditorData.m_isEnabled = false;
}
bool PrefabEditorEntityOwnershipService::IsRootTemplateDirty()
{
return (m_prefabSystemComponent->IsTemplateDirty(m_rootInstance->GetTemplateId()));
}
//////////////////////////////////////////////////////////////////////////
// Slice Buses implementation with Assert(false), this will exist only during Slice->Prefab
// development to pinpoint and replace specific calls to Slice system
@@ -193,8 +193,10 @@ namespace AzToolsFramework
AZ::IO::PathView filePath, Prefab::InstanceOptionalReference instanceToParentUnder) override;
Prefab::InstanceOptionalReference GetRootPrefabInstance() override;
Prefab::TemplateId GetRootPrefabTemplateId() override;
const AZStd::vector<AZ::Data::Asset<AZ::Data::AssetData>>& GetPlayInEditorAssetData() override;
bool IsRootTemplateDirty() override;
//////////////////////////////////////////////////////////////////////////
void OnEntityRemoved(AZ::EntityId entityId);
@@ -31,10 +31,10 @@ namespace AzToolsFramework
{
if (auto* serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
{
serializeContext->Enum<SavePrefabsPreference>()
->Value("Unspecified", SavePrefabsPreference::Unspecified)
->Value("SaveAll", SavePrefabsPreference::SaveAll)
->Value("SaveNone", SavePrefabsPreference::SaveNone);
serializeContext->Enum<SaveAllPrefabsPreference>()
->Value("Ask every time", SaveAllPrefabsPreference::AskEveryTime)
->Value("Save all", SaveAllPrefabsPreference::SaveAll)
->Value("Save none", SaveAllPrefabsPreference::SaveNone);
}
}
@@ -669,21 +669,21 @@ namespace AzToolsFramework
return finalPath;
}
SavePrefabsPreference PrefabLoader::GetSavePrefabsPreference()
SaveAllPrefabsPreference PrefabLoader::GetSaveAllPrefabsPreference()
{
SavePrefabsPreference savePrefabsPreference = SavePrefabsPreference::Unspecified;
SaveAllPrefabsPreference saveAllPrefabsPreference = SaveAllPrefabsPreference::AskEveryTime;
if (auto* registry = AZ::SettingsRegistry::Get())
{
registry->GetObject(savePrefabsPreference, s_savePrefabsKey);
registry->GetObject(saveAllPrefabsPreference, s_savePrefabsKey);
}
return savePrefabsPreference;
return saveAllPrefabsPreference;
}
void PrefabLoader::SetSavePrefabsPreference(SavePrefabsPreference savePrefabsPreference)
void PrefabLoader::SetSaveAllPrefabsPreference(SaveAllPrefabsPreference saveAllPrefabsPreference)
{
if (auto* registry = AZ::SettingsRegistry::Get())
{
registry->SetObject(s_savePrefabsKey, savePrefabsPreference);
registry->SetObject(s_savePrefabsKey, saveAllPrefabsPreference);
}
}
@@ -110,8 +110,8 @@ namespace AzToolsFramework
//! Returns if the path is a valid path for a prefab
static bool IsValidPrefabPath(AZ::IO::PathView path);
SavePrefabsPreference GetSavePrefabsPreference() override;
void SetSavePrefabsPreference(SavePrefabsPreference savePrefabsPreference) override;
SaveAllPrefabsPreference GetSaveAllPrefabsPreference() override;
void SetSaveAllPrefabsPreference(SaveAllPrefabsPreference saveAllPrefabsPreference) override;
private:
/**
@@ -17,9 +17,9 @@ namespace AzToolsFramework
{
namespace Prefab
{
enum class SavePrefabsPreference
enum class SaveAllPrefabsPreference
{
Unspecified,
AskEveryTime,
SaveAll,
SaveNone
};
@@ -91,8 +91,8 @@ namespace AzToolsFramework
//! The path will always use the '/' separator.
virtual AZ::IO::Path GenerateRelativePath(AZ::IO::PathView path) = 0;
virtual SavePrefabsPreference GetSavePrefabsPreference() = 0;
virtual void SetSavePrefabsPreference(SavePrefabsPreference savePrefabsPreference) = 0;
virtual SaveAllPrefabsPreference GetSaveAllPrefabsPreference() = 0;
virtual void SetSaveAllPrefabsPreference(SaveAllPrefabsPreference saveAllPrefabsPreference) = 0;
protected:
@@ -105,6 +105,6 @@ namespace AzToolsFramework
namespace AZ
{
AZ_TYPE_INFO_SPECIALIZE(AzToolsFramework::Prefab::SavePrefabsPreference, "{7E61EA82-4DE4-4A3F-945F-C8FEDC1114B5}");
AZ_TYPE_INFO_SPECIALIZE(AzToolsFramework::Prefab::SaveAllPrefabsPreference, "{7E61EA82-4DE4-4A3F-945F-C8FEDC1114B5}");
}
@@ -754,25 +754,61 @@ namespace AzToolsFramework
}
}
bool PrefabSystemComponent::AreDirtyTemplatesPresent()
bool PrefabSystemComponent::AreDirtyTemplatesPresent(TemplateId templateId)
{
for (const auto& [id, templateObject] : m_templateIdMap)
auto parentTemplate = FindTemplate(templateId);
if (IsTemplateDirty(templateId))
{
if (IsTemplateDirty(id))
return true;
}
auto linkIds = parentTemplate->get().GetLinks();
for (auto linkId : linkIds)
{
auto linkIterator = m_linkIdMap.find(linkId);
if (linkIterator != m_linkIdMap.end())
{
return true;
return AreDirtyTemplatesPresent(linkIterator->second.GetSourceTemplateId());
}
}
return false;
}
void PrefabSystemComponent::SaveAllDirtyTemplates()
void PrefabSystemComponent::SaveAllDirtyTemplates(TemplateId templateId)
{
for (auto& [id, templateObject] : m_templateIdMap)
auto parentTemplate = FindTemplate(templateId);
if (IsTemplateDirty(templateId))
{
if (IsTemplateDirty(id))
m_prefabLoader.SaveTemplate(templateId);
}
auto linkIds = parentTemplate->get().GetLinks();
for (auto linkId : linkIds)
{
auto linkIterator = m_linkIdMap.find(linkId);
if (linkIterator != m_linkIdMap.end())
{
m_prefabLoader.SaveTemplate(id);
SaveAllDirtyTemplates(linkIterator->second.GetSourceTemplateId());
}
}
}
void PrefabSystemComponent::GetDirtyTemplatePaths(TemplateId parentTemplateId, AZStd::set<AZ::IO::PathView>& dirtyTemplatePaths)
{
auto parentTemplate = FindTemplate(parentTemplateId);
if (IsTemplateDirty(parentTemplateId))
{
dirtyTemplatePaths.emplace(parentTemplate->get().GetFilePath());
}
auto linkIds = parentTemplate->get().GetLinks();
for (auto linkId : linkIds)
{
auto linkIterator = m_linkIdMap.find(linkId);
if (linkIterator != m_linkIdMap.end())
{
GetDirtyTemplatePaths(linkIterator->second.GetSourceTemplateId(), dirtyTemplatePaths);
}
}
}
@@ -183,9 +183,11 @@ namespace AzToolsFramework
*/
void SetTemplateDirtyFlag(const TemplateId& templateId, bool dirty) override;
bool AreDirtyTemplatesPresent() override;
bool AreDirtyTemplatesPresent(TemplateId templateId) override;
void SaveAllDirtyTemplates() override;
void SaveAllDirtyTemplates(TemplateId templateId) override;
void GetDirtyTemplatePaths(TemplateId parentTemplateId, AZStd::set<AZ::IO::PathView>& dirtyTemplatePaths) override;
//////////////////////////////////////////////////////////////////////////
@@ -9,11 +9,12 @@
#pragma once
#include <AzCore/Interface/Interface.h>
#include <AzCore/std/containers/set.h>
#include <AzCore/std/smart_ptr/unique_ptr.h>
#include <AzToolsFramework/Prefab/Instance/Instance.h>
#include <AzToolsFramework/Prefab/Link/Link.h>
#include <AzToolsFramework/Prefab/PrefabIdTypes.h>
#include <AzToolsFramework/Prefab/Template/Template.h>
#include <AzCore/std/smart_ptr/unique_ptr.h>
namespace AzToolsFramework
{
@@ -49,8 +50,9 @@ namespace AzToolsFramework
virtual bool IsTemplateDirty(const TemplateId& templateId) = 0;
virtual void SetTemplateDirtyFlag(const TemplateId& templateId, bool dirty) = 0;
virtual bool AreDirtyTemplatesPresent() = 0;
virtual void SaveAllDirtyTemplates() = 0;
virtual bool AreDirtyTemplatesPresent(TemplateId templateId) = 0;
virtual void SaveAllDirtyTemplates(TemplateId templateId) = 0;
virtual void GetDirtyTemplatePaths(TemplateId parentTemplateId, AZStd::set<AZ::IO::PathView>& dirtyTemplatePaths) = 0;
virtual PrefabDom& FindTemplateDom(TemplateId templateId) = 0;
virtual void UpdatePrefabTemplate(TemplateId templateId, const PrefabDom& updatedDom) = 0;
@@ -11,6 +11,7 @@
#include <AzCore/Interface/Interface.h>
#include <AzCore/Math/Vector3.h>
#include <AzCore/Serialization/SerializeContext.h>
#include <AzToolsFramework/Prefab/PrefabIdTypes.h>
namespace AzToolsFramework
{
@@ -28,6 +29,9 @@ namespace AzToolsFramework
* @return The id of the newly created entity.
*/
virtual AZ::EntityId CreateNewEntityAtPosition(const AZ::Vector3& position, AZ::EntityId parentId) = 0;
virtual int ExecuteClosePrefabDialog(TemplateId templateId) = 0;
virtual void ExecuteSavePrefabsDialog(TemplateId templateId, bool useSaveAllPrefabsPreference = false) = 0;
};
} // namespace Prefab
@@ -12,6 +12,7 @@
#include <AzCore/IO/SystemFile.h>
#include <AzCore/StringFunc/StringFunc.h>
#include <AzCore/Component/TransformBus.h>
#include <AzCore/std/smart_ptr/make_shared.h>
#include <AzFramework/API/ApplicationAPI.h>
#include <AzFramework/Asset/AssetSystemBus.h>
@@ -27,12 +28,28 @@
#include <AzToolsFramework/UI/Prefab/PrefabIntegrationInterface.h>
#include <AzToolsFramework/UI/UICore/WidgetHelpers.h>
#include <AzQtComponents/Components/Widgets/CheckBox.h>
#include <AzQtComponents/Components/FlowLayout.h>
#include <AzQtComponents/Components/StyleManager.h>
#include <AzQtComponents/Components/Widgets/CardHeader.h>
#include <QApplication>
#include <QCheckBox>
#include <QDialog>
#include <QDialogButtonBox>
#include <QFileDialog>
#include <QFileInfo>
#include <QFrame>
#include <QHBoxLayout>
#include <QLabel>
#include <QMainWindow>
#include <QMenu>
#include <QMessageBox>
#include <QScrollArea>
#include <QVBoxLayout>
#include <QWidget>
namespace AzToolsFramework
{
@@ -43,6 +60,7 @@ namespace AzToolsFramework
PrefabPublicInterface* PrefabIntegrationManager::s_prefabPublicInterface = nullptr;
PrefabEditInterface* PrefabIntegrationManager::s_prefabEditInterface = nullptr;
PrefabLoaderInterface* PrefabIntegrationManager::s_prefabLoaderInterface = nullptr;
PrefabSystemComponentInterface* PrefabIntegrationManager::s_prefabSystemComponentInterface = nullptr;
const AZStd::string PrefabIntegrationManager::s_prefabFileExtension = ".prefab";
@@ -88,6 +106,13 @@ namespace AzToolsFramework
return;
}
s_prefabSystemComponentInterface = AZ::Interface<PrefabSystemComponentInterface>::Get();
if (s_prefabSystemComponentInterface == nullptr)
{
AZ_Assert(false, "Prefab - could not get PrefabSystemComponentInterface on PrefabIntegrationManager construction.");
return;
}
EditorContextMenuBus::Handler::BusConnect();
PrefabInstanceContainerNotificationBus::Handler::BusConnect();
AZ::Interface<PrefabIntegrationInterface>::Register(this);
@@ -1050,5 +1075,232 @@ namespace AzToolsFramework
return AZ::EntityId();
}
}
int PrefabIntegrationManager::ExecuteClosePrefabDialog(TemplateId templateId)
{
auto prefabSaveSelectionDialog = ConstructClosePrefabDialog(templateId);
int prefabSaveSelection = prefabSaveSelectionDialog->exec();
if (prefabSaveSelection == QDialog::Accepted)
{
SavePrefabsInDialog(prefabSaveSelectionDialog.get());
}
return prefabSaveSelection;
}
void PrefabIntegrationManager::ExecuteSavePrefabsDialog(TemplateId templateId, bool useSaveAllPrefabsPreference)
{
using namespace AzToolsFramework::Prefab;
auto prefabTemplate = s_prefabSystemComponentInterface->FindTemplate(templateId);
AZ::IO::Path prefabTemplatePath = prefabTemplate->get().GetFilePath();
if (s_prefabSystemComponentInterface->IsTemplateDirty(templateId))
{
if (s_prefabLoaderInterface->SaveTemplate(templateId) == false)
{
AZ_Error("Prefabs", false, "Template '%s' could not be saved successfully.", prefabTemplatePath.c_str());
return;
}
}
if (useSaveAllPrefabsPreference)
{
SaveAllPrefabsPreference saveAllPrefabsPreference = s_prefabLoaderInterface->GetSaveAllPrefabsPreference();
if (saveAllPrefabsPreference == SaveAllPrefabsPreference::SaveAll)
{
s_prefabSystemComponentInterface->SaveAllDirtyTemplates(templateId);
return;
}
else if (saveAllPrefabsPreference == SaveAllPrefabsPreference::SaveNone)
{
return;
}
}
AZStd::unique_ptr<QDialog> savePrefabsDialog = ConstructSavePrefabsDialog(templateId, useSaveAllPrefabsPreference);
if (savePrefabsDialog)
{
int prefabSaveSelection = savePrefabsDialog->exec();
if (prefabSaveSelection == QDialog::Accepted)
{
SavePrefabsInDialog(savePrefabsDialog.get());
}
}
}
void PrefabIntegrationManager::SavePrefabsInDialog(QDialog* unsavedPrefabsDialog)
{
QList<QLabel*> unsavedPrefabFileLabels = unsavedPrefabsDialog->findChildren<QLabel*>("UnsavedPrefabFileName");
if (unsavedPrefabFileLabels.size() > 0)
{
for (const QLabel* unsavedPrefabFileLabel : unsavedPrefabFileLabels)
{
AZStd::string unsavedPrefabFileName = unsavedPrefabFileLabel->property("FilePath").toString().toUtf8().data();
AzToolsFramework::Prefab::TemplateId unsavedPrefabTemplateId =
s_prefabSystemComponentInterface->GetTemplateIdFromFilePath(unsavedPrefabFileName.data());
bool isTemplateSavedSuccessfully = s_prefabLoaderInterface->SaveTemplate(unsavedPrefabTemplateId);
AZ_Assert(isTemplateSavedSuccessfully, "Prefab '%s' could not be saved successfully.", unsavedPrefabFileName.c_str());
}
}
}
AZStd::unique_ptr<QDialog> PrefabIntegrationManager::ConstructSavePrefabsDialog(TemplateId templateId, bool useSaveAllPrefabsPreference)
{
AZStd::unique_ptr<QDialog> saveModifiedMessageBox = AZStd::make_unique<QDialog>(AzToolsFramework::GetActiveWindow());
saveModifiedMessageBox->setWindowTitle("Unsaved files detected");
// Main Content section begins.
saveModifiedMessageBox->setObjectName("SaveAllFilesDialog");
QBoxLayout* contentLayout = new QVBoxLayout(saveModifiedMessageBox.get());
QFrame* prefabSavedMessageFrame = new QFrame(saveModifiedMessageBox.get());
QHBoxLayout* prefabSavedMessageLayout = new QHBoxLayout(saveModifiedMessageBox.get());
prefabSavedMessageFrame->setObjectName("PrefabSavedMessageFrame");
prefabSavedMessageFrame->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Maximum);
// Add a checkMark icon next to the level entities saved message.
QPixmap checkMarkIcon(QString(":/Notifications/checkmark.svg"));
QLabel* prefabSavedSuccessfullyIconContainer = new QLabel();
prefabSavedSuccessfullyIconContainer->setPixmap(checkMarkIcon);
prefabSavedSuccessfullyIconContainer->setFixedWidth(checkMarkIcon.width());
// Add a message that level entities are saved successfully.
auto prefabTemplate = s_prefabSystemComponentInterface->FindTemplate(templateId);
AZ::IO::Path prefabTemplatePath = prefabTemplate->get().GetFilePath();
QLabel* prefabSavedSuccessfullyLabel = new QLabel(
QString("Prefab %1 has been saved. Do you want to save the below dependent prefabs too?").arg(prefabTemplatePath.c_str()));
prefabSavedSuccessfullyLabel->setObjectName("PrefabSavedSuccessfullyLabel");
prefabSavedMessageLayout->addWidget(prefabSavedSuccessfullyIconContainer);
prefabSavedMessageLayout->addWidget(prefabSavedSuccessfullyLabel);
prefabSavedMessageFrame->setLayout(prefabSavedMessageLayout);
contentLayout->addWidget(prefabSavedMessageFrame);
AzQtComponents::Card* unsavedPrefabsContainer = ConstructUnsavedPrefabsCard(templateId);
contentLayout->addWidget(unsavedPrefabsContainer);
contentLayout->addStretch();
// Footer section begins.
QHBoxLayout* footerLayout = new QHBoxLayout(saveModifiedMessageBox.get());
if (useSaveAllPrefabsPreference)
{
QFrame* footerSeparatorLine = new QFrame();
footerSeparatorLine->setObjectName("FooterSeparatorLine");
footerSeparatorLine->setFrameShape(QFrame::HLine);
contentLayout->addWidget(footerSeparatorLine);
QLabel* prefabSavePreferenceHint =
new QLabel("<u>You can prevent this window from showing in the future by updating your global save preferences.</u>");
prefabSavePreferenceHint->setToolTip(
"Go to 'Edit > Editor Settings > Global Preferences... > Global save preferences' to update your preference");
prefabSavePreferenceHint->setObjectName("PrefabSavePreferenceHint");
footerLayout->addWidget(prefabSavePreferenceHint);
}
QDialogButtonBox* prefabSaveConfirmationButtons = new QDialogButtonBox(QDialogButtonBox::Save | QDialogButtonBox::No);
footerLayout->addWidget(prefabSaveConfirmationButtons);
contentLayout->addLayout(footerLayout);
connect(prefabSaveConfirmationButtons, &QDialogButtonBox::accepted, saveModifiedMessageBox.get(), &QDialog::accept);
connect(prefabSaveConfirmationButtons, &QDialogButtonBox::rejected, saveModifiedMessageBox.get(), &QDialog::reject);
AzQtComponents::StyleManager::setStyleSheet(saveModifiedMessageBox->parentWidget(), QStringLiteral("style:Editor.qss"));
return AZStd::move(saveModifiedMessageBox);
}
AZStd::shared_ptr<QDialog> PrefabIntegrationManager::ConstructClosePrefabDialog(TemplateId templateId)
{
AZStd::shared_ptr<QDialog> saveModifiedMessageBox = AZStd::make_shared<QDialog>(AzToolsFramework::GetActiveWindow());
saveModifiedMessageBox->setWindowTitle("Unsaved files detected");
AZStd::weak_ptr<QDialog> saveModifiedMessageBoxWeakPtr(saveModifiedMessageBox);
saveModifiedMessageBox->setObjectName("SavePrefabDialog");
// Main Content section begins.
QVBoxLayout* contentLayout = new QVBoxLayout(saveModifiedMessageBox.get());
QFrame* prefabSaveWarningFrame = new QFrame(saveModifiedMessageBox.get());
QHBoxLayout* levelEntitiesSaveQuestionLayout = new QHBoxLayout(saveModifiedMessageBox.get());
prefabSaveWarningFrame->setObjectName("PrefabSaveWarningFrame");
// Add a warning icon next to save prefab warning.
prefabSaveWarningFrame->setLayout(levelEntitiesSaveQuestionLayout);
QPixmap warningIcon(QString(":/Notifications/warning.svg"));
QLabel* warningIconContainer = new QLabel();
warningIconContainer->setPixmap(warningIcon);
warningIconContainer->setFixedWidth(warningIcon.width());
levelEntitiesSaveQuestionLayout->addWidget(warningIconContainer);
// Ask user if they want to save entities in level.
QLabel* prefabSaveQuestionLabel = new QLabel("Do you want to save the below unsaved prefabs?", saveModifiedMessageBox.get());
levelEntitiesSaveQuestionLayout->addWidget(prefabSaveQuestionLabel);
contentLayout->addWidget(prefabSaveWarningFrame);
AZStd::set<AZ::IO::PathView> dirtyTemplatePaths;
s_prefabSystemComponentInterface->GetDirtyTemplatePaths(templateId, dirtyTemplatePaths);
auto templateToSave = s_prefabSystemComponentInterface->FindTemplate(templateId);
AZ::IO::Path templateToSaveFilePath = templateToSave->get().GetFilePath();
AzQtComponents::Card* unsavedPrefabsCard = ConstructUnsavedPrefabsCard(templateId);
contentLayout->addWidget(unsavedPrefabsCard);
contentLayout->addStretch();
QHBoxLayout* footerLayout = new QHBoxLayout(saveModifiedMessageBox.get());
QDialogButtonBox* prefabSaveConfirmationButtons =
new QDialogButtonBox(QDialogButtonBox::Save | QDialogButtonBox::Discard | QDialogButtonBox::Cancel);
footerLayout->addWidget(prefabSaveConfirmationButtons);
contentLayout->addLayout(footerLayout);
QObject::connect(prefabSaveConfirmationButtons, &QDialogButtonBox::accepted, saveModifiedMessageBox.get(), &QDialog::accept);
QObject::connect(prefabSaveConfirmationButtons, &QDialogButtonBox::rejected, saveModifiedMessageBox.get(), &QDialog::reject);
QObject::connect(
prefabSaveConfirmationButtons, &QDialogButtonBox::clicked, saveModifiedMessageBox.get(),
[saveModifiedMessageBoxWeakPtr, prefabSaveConfirmationButtons](QAbstractButton* button)
{
int prefabSaveSelection = prefabSaveConfirmationButtons->buttonRole(button);
saveModifiedMessageBoxWeakPtr.lock()->done(prefabSaveSelection);
});
AzQtComponents::StyleManager::setStyleSheet(saveModifiedMessageBox.get(), QStringLiteral("style:Editor.qss"));
return saveModifiedMessageBox;
}
AzQtComponents::Card* PrefabIntegrationManager::ConstructUnsavedPrefabsCard(TemplateId templateId)
{
FlowLayout* unsavedPrefabsLayout = new FlowLayout;
AZStd::set<AZ::IO::PathView> dirtyTemplatePaths;
s_prefabSystemComponentInterface->GetDirtyTemplatePaths(templateId, dirtyTemplatePaths);
for (AZ::IO::PathView dirtyTemplatePath : dirtyTemplatePaths)
{
QLabel* prefabNameLabel = new QLabel(QString("<u>%1</u>").arg(dirtyTemplatePath.Filename().Native().data()));
prefabNameLabel->setObjectName("UnsavedPrefabFileName");
prefabNameLabel->setWordWrap(true);
prefabNameLabel->setToolTip(dirtyTemplatePath.Native().data());
prefabNameLabel->setProperty("FilePath", dirtyTemplatePath.Native().data());
unsavedPrefabsLayout->addWidget(prefabNameLabel);
}
AzQtComponents::Card* unsavedPrefabsContainer = new AzQtComponents::Card;
unsavedPrefabsContainer->setObjectName("SaveDependentPrefabsCard");
unsavedPrefabsContainer->setTitle("Unsaved Prefabs");
unsavedPrefabsContainer->header()->setHasContextMenu(false);
unsavedPrefabsContainer->header()->setIcon(QIcon(QStringLiteral(":/Entity/prefab_edit.svg")));
QFrame* unsavedPrefabsFrame = new QFrame(unsavedPrefabsContainer);
unsavedPrefabsFrame->setLayout(unsavedPrefabsLayout);
QScrollArea* unsavedPrefabsScrollArea = new QScrollArea();
unsavedPrefabsScrollArea->setWidget(unsavedPrefabsFrame);
//unsavedPrefabsScrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
unsavedPrefabsScrollArea->setWidgetResizable(true);
unsavedPrefabsScrollArea->setObjectName("SavePrefabsCardContent");
unsavedPrefabsContainer->setContentWidget(unsavedPrefabsScrollArea);
return AZStd::move(unsavedPrefabsContainer);
}
}
}
@@ -15,12 +15,15 @@
#include <AzToolsFramework/AssetBrowser/AssetBrowserSourceDropBus.h>
#include <AzToolsFramework/Editor/EditorContextMenuBus.h>
#include <AzToolsFramework/Prefab/PrefabPublicInterface.h>
#include <AzToolsFramework/Prefab/PrefabSystemComponentInterface.h>
#include <AzToolsFramework/UI/Prefab/LevelRootUiHandler.h>
#include <AzToolsFramework/UI/Prefab/PrefabEditManager.h>
#include <AzToolsFramework/UI/Prefab/PrefabIntegrationBus.h>
#include <AzToolsFramework/UI/Prefab/PrefabIntegrationInterface.h>
#include <AzToolsFramework/UI/Prefab/PrefabUiHandler.h>
#include <AzQtComponents/Components/Widgets/Card.h>
namespace AzToolsFramework
{
namespace Prefab
@@ -49,6 +52,7 @@ namespace AzToolsFramework
, public AssetBrowser::AssetBrowserSourceDropBus::Handler
, public PrefabInstanceContainerNotificationBus::Handler
, public PrefabIntegrationInterface
, public QObject
{
public:
AZ_CLASS_ALLOCATOR(PrefabIntegrationManager, AZ::SystemAllocator, 0);
@@ -72,6 +76,8 @@ namespace AzToolsFramework
// PrefabIntegrationInterface...
AZ::EntityId CreateNewEntityAtPosition(const AZ::Vector3& position, AZ::EntityId parentId) override;
int ExecuteClosePrefabDialog(TemplateId templateId) override;
void ExecuteSavePrefabsDialog(TemplateId templateId, bool useSaveAllPrefabsPreference) override;
private:
// Manages the Edit Mode UI for prefabs
@@ -124,12 +130,19 @@ namespace AzToolsFramework
static AZ::u32 GetSliceFlags(const AZ::Edit::ElementData* editData, const AZ::Edit::ClassData* classData);
AZStd::shared_ptr<QDialog> ConstructClosePrefabDialog(TemplateId templateId);
AzQtComponents::Card* ConstructUnsavedPrefabsCard(TemplateId templateId);
AZStd::unique_ptr<QDialog> ConstructSavePrefabsDialog(TemplateId templateId, bool useSaveAllPrefabsPreference);
void SavePrefabsInDialog(QDialog* unsavedPrefabsDialog);
static const AZStd::string s_prefabFileExtension;
static EditorEntityUiInterface* s_editorEntityUiInterface;
static PrefabPublicInterface* s_prefabPublicInterface;
static PrefabEditInterface* s_prefabEditInterface;
static PrefabLoaderInterface* s_prefabLoaderInterface;
static PrefabSystemComponentInterface* s_prefabSystemComponentInterface;
};
}
}