Focus Mode | Make Ctrl+S shortcut contextual to Prefab Focus (#7649)

* Change the Ctrl+S flow to save the currently focused prefab instead of the root.

Signed-off-by: Danilo Aimini <82231674+AMZN-daimini@users.noreply.github.com>

* Ensure the Outliner is refreshed on save

Signed-off-by: Danilo Aimini <82231674+AMZN-daimini@users.noreply.github.com>

* Rename ExecuteClosePrefabDialog to be more accurate (the function also does the saving, it's not just creating the dialog).

Signed-off-by: Danilo Aimini <82231674+AMZN-daimini@users.noreply.github.com>

* Minor changes to labeling.

Signed-off-by: Danilo Aimini <82231674+AMZN-daimini@users.noreply.github.com>

* Adjust labeling to reflect changes in behavior.

Signed-off-by: Danilo Aimini <82231674+AMZN-daimini@users.noreply.github.com>

* Revert labeling changes

Signed-off-by: Danilo Aimini <82231674+AMZN-daimini@users.noreply.github.com>

* Additional checks to guarantee the system works in test mode

Signed-off-by: Danilo Aimini <82231674+AMZN-daimini@users.noreply.github.com>

* Additional check to prevent crashes when the editor somehow triggers save during automated tests.

Signed-off-by: Danilo Aimini <82231674+AMZN-daimini@users.noreply.github.com>

* Simplify checks

Signed-off-by: Danilo Aimini <82231674+AMZN-daimini@users.noreply.github.com>

* Update preferences and dialog labels to reflect new behavior.

Signed-off-by: Danilo Aimini <82231674+AMZN-daimini@users.noreply.github.com>
monroegm-disable-blank-issue-2
Danilo Aimini 4 years ago committed by GitHub
parent 322a6c495a
commit 6fe2664b68
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -714,12 +714,10 @@ void CCryEditApp::OnFileSave()
} }
else else
{ {
auto* prefabEditorEntityOwnershipInterface = AZ::Interface<AzToolsFramework::PrefabEditorEntityOwnershipInterface>::Get();
auto* prefabIntegrationInterface = AZ::Interface<AzToolsFramework::Prefab::PrefabIntegrationInterface>::Get(); auto* prefabIntegrationInterface = AZ::Interface<AzToolsFramework::Prefab::PrefabIntegrationInterface>::Get();
AZ_Assert(prefabEditorEntityOwnershipInterface != nullptr, "PrefabEditorEntityOwnershipInterface is not found.");
AZ_Assert(prefabIntegrationInterface != nullptr, "PrefabIntegrationInterface is not found."); AZ_Assert(prefabIntegrationInterface != nullptr, "PrefabIntegrationInterface is not found.");
AzToolsFramework::Prefab::TemplateId rootPrefabTemplateId = prefabEditorEntityOwnershipInterface->GetRootPrefabTemplateId();
prefabIntegrationInterface->ExecuteSavePrefabDialog(rootPrefabTemplateId, true); prefabIntegrationInterface->SaveCurrentPrefab();
} }
} }
@ -3154,7 +3152,7 @@ bool CCryEditApp::CreateLevel(bool& wasCreateLevelOperationCancelled)
} }
AzToolsFramework::Prefab::TemplateId rootPrefabTemplateId = prefabEditorEntityOwnershipInterface->GetRootPrefabTemplateId(); AzToolsFramework::Prefab::TemplateId rootPrefabTemplateId = prefabEditorEntityOwnershipInterface->GetRootPrefabTemplateId();
int prefabSaveSelection = prefabIntegrationInterface->ExecuteClosePrefabDialog(rootPrefabTemplateId); int prefabSaveSelection = prefabIntegrationInterface->HandleRootPrefabClosure(rootPrefabTemplateId);
// In order to get the accept and reject codes of QDialog and QDialogButtonBox aligned, we do (1-prefabSaveSelection) here. // In order to get the accept and reject codes of QDialog and QDialogButtonBox aligned, we do (1-prefabSaveSelection) here.
// For example, QDialog::Rejected(0) is emitted when dialog is closed. But the int value corresponds to // For example, QDialog::Rejected(0) is emitted when dialog is closed. But the int value corresponds to

@ -667,7 +667,7 @@ bool CCryEditDoc::SaveModified()
return true; return true;
} }
int prefabSaveSelection = m_prefabIntegrationInterface->ExecuteClosePrefabDialog(rootPrefabTemplateId); int prefabSaveSelection = m_prefabIntegrationInterface->HandleRootPrefabClosure(rootPrefabTemplateId);
// In order to get the accept and reject codes of QDialog and QDialogButtonBox aligned, we do (1-prefabSaveSelection) here. // In order to get the accept and reject codes of QDialog and QDialogButtonBox aligned, we do (1-prefabSaveSelection) here.
// For example, QDialog::Rejected(0) is emitted when dialog is closed. But the int value corresponds to // For example, QDialog::Rejected(0) is emitted when dialog is closed. But the int value corresponds to

@ -67,7 +67,7 @@ void CEditorPreferencesPage_General::Reflect(AZ::SerializeContext& serialize)
serialize.Class<CEditorPreferencesPage_General>() serialize.Class<CEditorPreferencesPage_General>()
->Version(1) ->Version(1)
->Field("General Settings", &CEditorPreferencesPage_General::m_generalSettings) ->Field("General Settings", &CEditorPreferencesPage_General::m_generalSettings)
->Field("Level Save Settings", &CEditorPreferencesPage_General::m_levelSaveSettings) ->Field("Prefab Save Settings", &CEditorPreferencesPage_General::m_levelSaveSettings)
->Field("Messaging", &CEditorPreferencesPage_General::m_messaging) ->Field("Messaging", &CEditorPreferencesPage_General::m_messaging)
->Field("Undo", &CEditorPreferencesPage_General::m_undo) ->Field("Undo", &CEditorPreferencesPage_General::m_undo)
->Field("Deep Selection", &CEditorPreferencesPage_General::m_deepSelection) ->Field("Deep Selection", &CEditorPreferencesPage_General::m_deepSelection)
@ -95,10 +95,10 @@ 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_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."); ->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<LevelSaveSettings>("Level Save Settings", "") editContext->Class<LevelSaveSettings>("Prefab Save Settings", "")
->DataElement( ->DataElement(
AZ::Edit::UIHandlers::ComboBox, &LevelSaveSettings::m_saveAllPrefabsPreference, "Save All Prefabs Preference", AZ::Edit::UIHandlers::ComboBox, &LevelSaveSettings::m_saveAllPrefabsPreference, "Save All Nested Prefabs",
"This option controls whether prefabs should be saved along with the level") "This option controls whether nested prefabs should be saved when a prefab is saved.")
->EnumAttribute(AzToolsFramework::Prefab::SaveAllPrefabsPreference::AskEveryTime, "Ask every time") ->EnumAttribute(AzToolsFramework::Prefab::SaveAllPrefabsPreference::AskEveryTime, "Ask every time")
->EnumAttribute(AzToolsFramework::Prefab::SaveAllPrefabsPreference::SaveAll, "Save all") ->EnumAttribute(AzToolsFramework::Prefab::SaveAllPrefabsPreference::SaveAll, "Save all")
->EnumAttribute(AzToolsFramework::Prefab::SaveAllPrefabsPreference::SaveNone, "Save none"); ->EnumAttribute(AzToolsFramework::Prefab::SaveAllPrefabsPreference::SaveNone, "Save none");
@ -126,7 +126,7 @@ void CEditorPreferencesPage_General::Reflect(AZ::SerializeContext& serialize)
->ClassElement(AZ::Edit::ClassElements::EditorData, "") ->ClassElement(AZ::Edit::ClassElements::EditorData, "")
->Attribute(AZ::Edit::Attributes::Visibility, AZ_CRC("PropertyVisibility_ShowChildrenOnly", 0xef428f20)) ->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_generalSettings, "General Settings", "General Editor Preferences")
->DataElement(AZ::Edit::UIHandlers::Default, &CEditorPreferencesPage_General::m_levelSaveSettings, "Level Save Settings", "File>Save") ->DataElement(AZ::Edit::UIHandlers::Default, &CEditorPreferencesPage_General::m_levelSaveSettings, "Prefab Save Settings", "File>Save")
->DataElement(AZ::Edit::UIHandlers::Default, &CEditorPreferencesPage_General::m_messaging, "Messaging", "Messaging") ->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_undo, "Undo", "Undo Preferences")
->DataElement(AZ::Edit::UIHandlers::Default, &CEditorPreferencesPage_General::m_deepSelection, "Selection", "Selection") ->DataElement(AZ::Edit::UIHandlers::Default, &CEditorPreferencesPage_General::m_deepSelection, "Selection", "Selection")

@ -84,7 +84,7 @@ namespace AzToolsFramework::Prefab
//! The alias path for the instance the editor is currently focusing on, starting from the root instance. //! The alias path for the instance the editor is currently focusing on, starting from the root instance.
RootAliasPath m_rootAliasFocusPath = RootAliasPath(); RootAliasPath m_rootAliasFocusPath = RootAliasPath();
//! The templateId of the focused instance. //! The templateId of the focused instance.
TemplateId m_focusedTemplateId; TemplateId m_focusedTemplateId = Prefab::InvalidTemplateId;
//! A path containing the filenames of the instances in the focus hierarchy, separated with a /. //! A path containing the filenames of the instances in the focus hierarchy, separated with a /.
AZ::IO::Path m_filenameFocusPath; AZ::IO::Path m_filenameFocusPath;
//! The length of the current focus path. Stored to simplify internal checks. //! The length of the current focus path. Stored to simplify internal checks.

@ -1206,6 +1206,12 @@ namespace AzToolsFramework
}); });
} }
void EntityOutlinerWidget::OnPrefabTemplateDirtyFlagUpdated(
[[maybe_unused]] Prefab::TemplateId templateId, [[maybe_unused]] bool status)
{
m_gui->m_objectTree->update();
}
void EntityOutlinerWidget::OnEntityInfoUpdatedAddChildEnd(AZ::EntityId /*parentId*/, AZ::EntityId childId) void EntityOutlinerWidget::OnEntityInfoUpdatedAddChildEnd(AZ::EntityId /*parentId*/, AZ::EntityId childId)
{ {
QueueContentUpdateSort(childId); QueueContentUpdateSort(childId);

@ -112,6 +112,7 @@ namespace AzToolsFramework
// PrefabPublicNotificationBus // PrefabPublicNotificationBus
void OnPrefabInstancePropagationBegin() override; void OnPrefabInstancePropagationBegin() override;
void OnPrefabInstancePropagationEnd() override; void OnPrefabInstancePropagationEnd() override;
void OnPrefabTemplateDirtyFlagUpdated(Prefab::TemplateId templateId, bool status) override;
// EditorWindowUIRequestBus overrides // EditorWindowUIRequestBus overrides
void SetEditorUiEnabled(bool enable) override; void SetEditorUiEnabled(bool enable) override;

@ -30,14 +30,12 @@ namespace AzToolsFramework
*/ */
virtual AZ::EntityId CreateNewEntityAtPosition(const AZ::Vector3& position, AZ::EntityId parentId) = 0; virtual AZ::EntityId CreateNewEntityAtPosition(const AZ::Vector3& position, AZ::EntityId parentId) = 0;
//! Constructs and executes the close dialog on a prefab template corresponding to templateId. //! Handles the save on close behavior for the root prefab with the TemplateId provided.
//! @param templateId The id of the template the user chose to close. //! @param templateId The id of the template the user chose to close.
virtual int ExecuteClosePrefabDialog(TemplateId templateId) = 0; virtual int HandleRootPrefabClosure(TemplateId templateId) = 0;
//! Constructs and executes the save dialog on a prefab template corresponding to templateId. //! Saves the prefab currently focused in the main editor window and all its descendants.
//! @param templateId The id of the template the user chose to save. virtual void SaveCurrentPrefab() = 0;
//! @param useSaveAllPrefabsPreference A flag indicating whether SaveAllPrefabsPreference should be used for saving templates.
virtual void ExecuteSavePrefabDialog(TemplateId templateId, bool useSaveAllPrefabsPreference = false) = 0;
}; };
} // namespace Prefab } // namespace Prefab

@ -18,6 +18,7 @@
#include <AzToolsFramework/ContainerEntity/ContainerEntityInterface.h> #include <AzToolsFramework/ContainerEntity/ContainerEntityInterface.h>
#include <AzToolsFramework/Entity/EditorEntityContextBus.h> #include <AzToolsFramework/Entity/EditorEntityContextBus.h>
#include <AzToolsFramework/Entity/PrefabEditorEntityOwnershipInterface.h>
#include <AzToolsFramework/Entity/ReadOnly/ReadOnlyEntityInterface.h> #include <AzToolsFramework/Entity/ReadOnly/ReadOnlyEntityInterface.h>
#include <AzToolsFramework/Prefab/EditorPrefabComponent.h> #include <AzToolsFramework/Prefab/EditorPrefabComponent.h>
#include <AzToolsFramework/Prefab/Instance/InstanceEntityMapperInterface.h> #include <AzToolsFramework/Prefab/Instance/InstanceEntityMapperInterface.h>
@ -47,6 +48,7 @@ namespace AzToolsFramework
ContainerEntityInterface* PrefabIntegrationManager::s_containerEntityInterface = nullptr; ContainerEntityInterface* PrefabIntegrationManager::s_containerEntityInterface = nullptr;
EditorEntityUiInterface* PrefabIntegrationManager::s_editorEntityUiInterface = nullptr; EditorEntityUiInterface* PrefabIntegrationManager::s_editorEntityUiInterface = nullptr;
PrefabFocusInterface* PrefabIntegrationManager::s_prefabFocusInterface = nullptr;
PrefabFocusPublicInterface* PrefabIntegrationManager::s_prefabFocusPublicInterface = nullptr; PrefabFocusPublicInterface* PrefabIntegrationManager::s_prefabFocusPublicInterface = nullptr;
PrefabLoaderInterface* PrefabIntegrationManager::s_prefabLoaderInterface = nullptr; PrefabLoaderInterface* PrefabIntegrationManager::s_prefabLoaderInterface = nullptr;
PrefabPublicInterface* PrefabIntegrationManager::s_prefabPublicInterface = nullptr; PrefabPublicInterface* PrefabIntegrationManager::s_prefabPublicInterface = nullptr;
@ -81,6 +83,13 @@ namespace AzToolsFramework
return; return;
} }
s_prefabFocusInterface = AZ::Interface<PrefabFocusInterface>::Get();
if (s_prefabFocusInterface == nullptr)
{
AZ_Assert(false, "Prefab - could not get PrefabFocusInterface on PrefabIntegrationManager construction.");
return;
}
s_prefabFocusPublicInterface = AZ::Interface<PrefabFocusPublicInterface>::Get(); s_prefabFocusPublicInterface = AZ::Interface<PrefabFocusPublicInterface>::Get();
if (s_prefabFocusPublicInterface == nullptr) if (s_prefabFocusPublicInterface == nullptr)
{ {
@ -939,14 +948,18 @@ namespace AzToolsFramework
} }
} }
int PrefabIntegrationManager::ExecuteClosePrefabDialog(TemplateId templateId) int PrefabIntegrationManager::HandleRootPrefabClosure(TemplateId templateId)
{ {
return m_prefabSaveHandler.ExecuteClosePrefabDialog(templateId); return m_prefabSaveHandler.ExecuteClosePrefabDialog(templateId);
} }
void PrefabIntegrationManager::ExecuteSavePrefabDialog(TemplateId templateId, bool useSaveAllPrefabsPreference) void PrefabIntegrationManager::SaveCurrentPrefab()
{ {
m_prefabSaveHandler.ExecuteSavePrefabDialog(templateId, useSaveAllPrefabsPreference); if (s_prefabFocusInterface)
{
TemplateId currentTemplateId = s_prefabFocusInterface->GetFocusedPrefabTemplateId(s_editorEntityContextId);
m_prefabSaveHandler.ExecuteSavePrefabDialog(currentTemplateId, true);
}
} }
} // namespace Prefab } // namespace Prefab

@ -28,6 +28,7 @@ namespace AzToolsFramework
namespace Prefab namespace Prefab
{ {
class PrefabFocusInterface;
class PrefabFocusPublicInterface; class PrefabFocusPublicInterface;
class PrefabLoaderInterface; class PrefabLoaderInterface;
class PrefabPublicInterface; class PrefabPublicInterface;
@ -65,8 +66,8 @@ namespace AzToolsFramework
// PrefabIntegrationInterface overrides ... // PrefabIntegrationInterface overrides ...
AZ::EntityId CreateNewEntityAtPosition(const AZ::Vector3& position, AZ::EntityId parentId) override; AZ::EntityId CreateNewEntityAtPosition(const AZ::Vector3& position, AZ::EntityId parentId) override;
int ExecuteClosePrefabDialog(TemplateId templateId) override; int HandleRootPrefabClosure(TemplateId templateId) override;
void ExecuteSavePrefabDialog(TemplateId templateId, bool useSaveAllPrefabsPreference) override; void SaveCurrentPrefab() override;
private: private:
// Handles the UI for prefab save operations. // Handles the UI for prefab save operations.
@ -113,6 +114,7 @@ namespace AzToolsFramework
static ContainerEntityInterface* s_containerEntityInterface; static ContainerEntityInterface* s_containerEntityInterface;
static EditorEntityUiInterface* s_editorEntityUiInterface; static EditorEntityUiInterface* s_editorEntityUiInterface;
static PrefabFocusInterface* s_prefabFocusInterface;
static PrefabFocusPublicInterface* s_prefabFocusPublicInterface; static PrefabFocusPublicInterface* s_prefabFocusPublicInterface;
static PrefabLoaderInterface* s_prefabLoaderInterface; static PrefabLoaderInterface* s_prefabLoaderInterface;
static PrefabPublicInterface* s_prefabPublicInterface; static PrefabPublicInterface* s_prefabPublicInterface;

@ -153,7 +153,18 @@ namespace AzToolsFramework
void PrefabSaveHandler::ExecuteSavePrefabDialog(TemplateId templateId, bool useSaveAllPrefabsPreference) void PrefabSaveHandler::ExecuteSavePrefabDialog(TemplateId templateId, bool useSaveAllPrefabsPreference)
{ {
if (templateId == Prefab::InvalidTemplateId)
{
return;
}
auto prefabTemplate = s_prefabSystemComponentInterface->FindTemplate(templateId); auto prefabTemplate = s_prefabSystemComponentInterface->FindTemplate(templateId);
if (!prefabTemplate.has_value())
{
return;
}
AZ::IO::Path prefabTemplatePath = prefabTemplate->get().GetFilePath(); AZ::IO::Path prefabTemplatePath = prefabTemplate->get().GetFilePath();
if (s_prefabSystemComponentInterface->IsTemplateDirty(templateId)) if (s_prefabSystemComponentInterface->IsTemplateDirty(templateId))
@ -613,10 +624,10 @@ namespace AzToolsFramework
contentLayout->addWidget(footerSeparatorLine); contentLayout->addWidget(footerSeparatorLine);
QLabel* prefabSavePreferenceHint = new QLabel( QLabel* prefabSavePreferenceHint = new QLabel(
"<u>You can prevent this window from showing in the future by updating your global save preferences.</u>", "You can prevent this from showing in the future by updating your preferences.",
savePrefabDialog.get()); savePrefabDialog.get());
prefabSavePreferenceHint->setToolTip( prefabSavePreferenceHint->setToolTip(
"Go to 'Edit > Editor Settings > Global Preferences... > Global save preferences' to update your preference"); "Go to 'Edit > Editor Settings > Global Preferences... > Prefab Save Settings' to update your preference");
prefabSavePreferenceHint->setObjectName(PrefabSavePreferenceHint); prefabSavePreferenceHint->setObjectName(PrefabSavePreferenceHint);
footerLayout->addWidget(prefabSavePreferenceHint); footerLayout->addWidget(prefabSavePreferenceHint);
} }

Loading…
Cancel
Save