PropertyHandlerDirectory.cpp 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. /*
  2. * Copyright (c) Contributors to the Open 3D Engine Project.
  3. * For complete copyright and license terms please see the LICENSE at the root of this distribution.
  4. *
  5. * SPDX-License-Identifier: Apache-2.0 OR MIT
  6. *
  7. */
  8. #include "EditorCommon.h"
  9. #include "PropertyHandlerDirectory.h"
  10. #include <AzToolsFramework/UI/PropertyEditor/PropertyQTConstants.h>
  11. #include <LyShine/Bus/UiEditorChangeNotificationBus.h>
  12. #include <Editor/Util/PathUtil.h>
  13. #include <QBoxLayout>
  14. PropertyDirectoryCtrl::PropertyDirectoryCtrl(QWidget* parent)
  15. : QWidget(parent)
  16. , m_propertyAssetCtrl(aznew PropertyAssetDirectorySelectionCtrl(this))
  17. {
  18. QObject::connect(m_propertyAssetCtrl,
  19. &AzToolsFramework::PropertyAssetCtrl::OnAssetIDChanged,
  20. [ this ]([[maybe_unused]] AZ::Data::AssetId newAssetID)
  21. {
  22. AzToolsFramework::PropertyEditorGUIMessages::Bus::Broadcast(
  23. &AzToolsFramework::PropertyEditorGUIMessages::Bus::Events::RequestWrite, this);
  24. });
  25. setAcceptDrops(true);
  26. QHBoxLayout* layout = new QHBoxLayout(this);
  27. layout->setContentsMargins(0, 0, 0, 0);
  28. layout->setSpacing(0);
  29. layout->addWidget(m_propertyAssetCtrl);
  30. // Add directory refresh button
  31. {
  32. QPushButton* refreshButton = new QPushButton(this);
  33. refreshButton->setFlat(true);
  34. QSize fixedSize = QSize(AzToolsFramework::PropertyQTConstant_DefaultHeight, AzToolsFramework::PropertyQTConstant_DefaultHeight);
  35. refreshButton->setFixedSize(fixedSize);
  36. refreshButton->setFocusPolicy(Qt::StrongFocus);
  37. refreshButton->setIcon(QIcon(":/PropertyEditor/Resources/reset_icon.png"));
  38. // The icon size needs to be smaller than the fixed size to make sure it visually aligns properly.
  39. QSize iconSize = QSize(fixedSize.width() - 2, fixedSize.height() - 2);
  40. refreshButton->setIconSize(iconSize);
  41. QObject::connect(refreshButton,
  42. &QPushButton::clicked,
  43. []([[maybe_unused]] bool checked)
  44. {
  45. UiEditorRefreshDirectoryNotificationBus::Broadcast(&UiEditorRefreshDirectoryNotificationInterface::OnRefreshDirectory);
  46. });
  47. layout->addWidget(refreshButton);
  48. }
  49. }
  50. void PropertyDirectoryCtrl::dragEnterEvent(QDragEnterEvent* ev)
  51. {
  52. m_propertyAssetCtrl->dragEnterEvent(ev);
  53. }
  54. void PropertyDirectoryCtrl::dragLeaveEvent(QDragLeaveEvent* ev)
  55. {
  56. m_propertyAssetCtrl->dragLeaveEvent(ev);
  57. }
  58. void PropertyDirectoryCtrl::dropEvent(QDropEvent* ev)
  59. {
  60. m_propertyAssetCtrl->dropEvent(ev);
  61. }
  62. AzToolsFramework::PropertyAssetCtrl* PropertyDirectoryCtrl::GetPropertyAssetCtrl()
  63. {
  64. return m_propertyAssetCtrl;
  65. }
  66. AzToolsFramework::AssetBrowser::AssetSelectionModel PropertyAssetDirectorySelectionCtrl::GetAssetSelectionModel()
  67. {
  68. AzToolsFramework::AssetBrowser::AssetSelectionModel selectionModel = AzToolsFramework::AssetBrowser::AssetSelectionModel::EverythingSelection();
  69. EntryTypeFilter* foldersFilter = new EntryTypeFilter();
  70. foldersFilter->SetEntryType(AssetBrowserEntry::AssetEntryType::Folder);
  71. selectionModel.SetSelectionFilter(FilterConstType(foldersFilter));
  72. return selectionModel;
  73. }
  74. void PropertyAssetDirectorySelectionCtrl::SetFolderSelection(const AZStd::string& folderPath)
  75. {
  76. AZStd::string strFolderPath = folderPath.c_str();
  77. if (strFolderPath.empty())
  78. {
  79. m_folderPath.clear();
  80. }
  81. // AssetBrowser will return relative paths for subdirectories of the game project,
  82. // with the game project folder included in the path.
  83. else if (AzFramework::StringFunc::Path::IsRelative(strFolderPath.c_str()))
  84. {
  85. // This assumes the asset picker will always a path relative to
  86. // the project folder, which we need to omit since file IO routines
  87. // seem to assume this anyways.
  88. strFolderPath = strFolderPath.substr(strFolderPath.find('/') + 1);
  89. m_folderPath = PathUtil::MakeGamePath(strFolderPath);
  90. AZStd::to_lower(m_folderPath.begin(), m_folderPath.end());
  91. }
  92. // For paths in gems, absolute paths are returned
  93. else
  94. {
  95. m_folderPath = Path::FullPathToGamePath(strFolderPath.c_str());
  96. AZStd::to_lower(m_folderPath.begin(), m_folderPath.end());
  97. }
  98. }
  99. void PropertyAssetDirectorySelectionCtrl::ClearAssetInternal()
  100. {
  101. SetFolderSelection(AZStd::string());
  102. PropertyAssetCtrl::ClearAssetInternal();
  103. }
  104. //-------------------------------------------------------------------------------
  105. QWidget* PropertyHandlerDirectory::CreateGUI(QWidget* pParent)
  106. {
  107. return aznew PropertyDirectoryCtrl(pParent);
  108. }
  109. void PropertyHandlerDirectory::ConsumeAttribute(PropertyDirectoryCtrl* GUI, AZ::u32 attrib, AzToolsFramework::PropertyAttributeReader* attrValue, const char* debugName)
  110. {
  111. (void)GUI;
  112. (void)attrib;
  113. (void)attrValue;
  114. (void)debugName;
  115. }
  116. void PropertyHandlerDirectory::WriteGUIValuesIntoProperty(size_t index, PropertyDirectoryCtrl* GUI, property_t& instance, AzToolsFramework::InstanceDataNode* node)
  117. {
  118. (void)index;
  119. (void)node;
  120. PropertyAssetDirectorySelectionCtrl* ctrl = static_cast<PropertyAssetDirectorySelectionCtrl*>(GUI->GetPropertyAssetCtrl());
  121. instance = ctrl->GetFolderSelection();
  122. }
  123. bool PropertyHandlerDirectory::ReadValuesIntoGUI(size_t index, PropertyDirectoryCtrl* GUI, const property_t& instance, AzToolsFramework::InstanceDataNode* node)
  124. {
  125. (void)index;
  126. (void)node;
  127. PropertyAssetDirectorySelectionCtrl* ctrl = static_cast<PropertyAssetDirectorySelectionCtrl*>(GUI->GetPropertyAssetCtrl());
  128. ctrl->blockSignals(true);
  129. {
  130. // Set currently selected folder path
  131. // Note: this must be done before setting asset type below which updates the GUI display
  132. ctrl->SetCurrentAssetHint(instance);
  133. ctrl->SetFolderSelection(instance);
  134. // We need to set the asset type so the property panel labels get
  135. // populated properly (via SetCurrentAssetType). To avoid defining
  136. // directories as assets, we just use a throw-away GUID to get the
  137. // logic to run (otherwise it will early-out due to invalid asset type).
  138. const char* throwAwayAssetType = "{43EDD212-F589-43C8-BC02-A8F9243271CB}";
  139. ctrl->SetCurrentAssetType(AZ::Data::AssetType(throwAwayAssetType));
  140. }
  141. ctrl->blockSignals(false);
  142. return false;
  143. }
  144. void PropertyHandlerDirectory::Register()
  145. {
  146. AzToolsFramework::PropertyTypeRegistrationMessages::Bus::Broadcast(
  147. &AzToolsFramework::PropertyTypeRegistrationMessages::Bus::Events::RegisterPropertyType, aznew PropertyHandlerDirectory());
  148. }
  149. #include <moc_PropertyHandlerDirectory.cpp>