|
@@ -11,42 +11,43 @@
|
|
#include <AssetImporterPlugin.h>
|
|
#include <AssetImporterPlugin.h>
|
|
#include <ImporterRootDisplay.h>
|
|
#include <ImporterRootDisplay.h>
|
|
|
|
|
|
-#include <QTimer>
|
|
|
|
-#include <QFile>
|
|
|
|
-#include <QFileDialog>
|
|
|
|
#include <QCloseEvent>
|
|
#include <QCloseEvent>
|
|
-#include <QMessageBox>
|
|
|
|
#include <QDesktopServices>
|
|
#include <QDesktopServices>
|
|
-#include <QUrl>
|
|
|
|
#include <QDockWidget>
|
|
#include <QDockWidget>
|
|
|
|
+#include <QFile>
|
|
|
|
+#include <QFileDialog>
|
|
#include <QLabel>
|
|
#include <QLabel>
|
|
|
|
+#include <QMessageBox>
|
|
|
|
+#include <QTimer>
|
|
|
|
|
|
class IXMLDOMDocumentPtr; // Needed for settings.h
|
|
class IXMLDOMDocumentPtr; // Needed for settings.h
|
|
class CXTPDockingPaneLayout; // Needed for settings.h
|
|
class CXTPDockingPaneLayout; // Needed for settings.h
|
|
#include <Settings.h>
|
|
#include <Settings.h>
|
|
|
|
|
|
-#include <AzQtComponents/Components/StylesheetPreprocessor.h>
|
|
|
|
-#include <AzToolsFramework/SourceControl/SourceControlAPI.h>
|
|
|
|
|
|
+#include <QScrollArea>
|
|
|
|
+
|
|
|
|
+#include <ActionOutput.h>
|
|
|
|
+#include <AssetImporterDocument.h>
|
|
#include <AzCore/Component/ComponentApplicationBus.h>
|
|
#include <AzCore/Component/ComponentApplicationBus.h>
|
|
#include <AzCore/IO/Path/Path.h>
|
|
#include <AzCore/IO/Path/Path.h>
|
|
#include <AzCore/std/functional.h>
|
|
#include <AzCore/std/functional.h>
|
|
|
|
+#include <AzCore/std/string/conversions.h>
|
|
#include <AzCore/Utils/Utils.h>
|
|
#include <AzCore/Utils/Utils.h>
|
|
#include <AzFramework/StringFunc/StringFunc.h>
|
|
#include <AzFramework/StringFunc/StringFunc.h>
|
|
-#include <AzCore/std/string/conversions.h>
|
|
|
|
|
|
+#include <AzToolsFramework/SourceControl/SourceControlAPI.h>
|
|
|
|
+#include <AzQtComponents/Components/StyledDetailsTableModel.h>
|
|
|
|
+#include <AzQtComponents/Components/StylesheetPreprocessor.h>
|
|
|
|
+#include <AzQtComponents/Components/Widgets/TableView.h>
|
|
#include <Util/PathUtil.h>
|
|
#include <Util/PathUtil.h>
|
|
-#include <ActionOutput.h>
|
|
|
|
|
|
|
|
-#include <SceneAPI/SceneUI/CommonWidgets/OverlayWidget.h>
|
|
|
|
-#include <SceneAPI/SceneUI/CommonWidgets/ProcessingOverlayWidget.h>
|
|
|
|
-#include <SceneAPI/SceneUI/Handlers/ProcessingHandlers/AsyncOperationProcessingHandler.h>
|
|
|
|
-#include <SceneAPI/SceneUI/Handlers/ProcessingHandlers/ExportJobProcessingHandler.h>
|
|
|
|
-#include <SceneAPI/SceneUI/SceneWidgets/ManifestWidget.h>
|
|
|
|
-#include <SceneAPI/SceneUI/SceneWidgets/SceneGraphInspectWidget.h>
|
|
|
|
|
|
+#include <SceneAPI/SceneCore/Containers/Utilities/Filters.h>
|
|
|
|
+#include <SceneAPI/SceneCore/DataTypes/Rules/IScriptProcessorRule.h>
|
|
#include <SceneAPI/SceneCore/Events/AssetImportRequest.h>
|
|
#include <SceneAPI/SceneCore/Events/AssetImportRequest.h>
|
|
#include <SceneAPI/SceneCore/Utilities/Reporting.h>
|
|
#include <SceneAPI/SceneCore/Utilities/Reporting.h>
|
|
#include <SceneAPI/SceneData/Rules/ScriptProcessorRule.h>
|
|
#include <SceneAPI/SceneData/Rules/ScriptProcessorRule.h>
|
|
-#include <SceneAPI/SceneCore/DataTypes/Rules/IScriptProcessorRule.h>
|
|
|
|
-#include <SceneAPI/SceneCore/Containers/Utilities/Filters.h>
|
|
|
|
|
|
+#include <SceneAPI/SceneUI/Handlers/ProcessingHandlers/AsyncOperationProcessingHandler.h>
|
|
|
|
+#include <SceneAPI/SceneUI/Handlers/ProcessingHandlers/ExportJobProcessingHandler.h>
|
|
|
|
+#include <SceneAPI/SceneUI/SceneWidgets/SceneGraphInspectWidget.h>
|
|
|
|
|
|
const char* AssetImporterWindow::s_documentationWebAddress = "https://www.o3de.org/docs/user-guide/assets/scene-settings/";
|
|
const char* AssetImporterWindow::s_documentationWebAddress = "https://www.o3de.org/docs/user-guide/assets/scene-settings/";
|
|
const AZ::Uuid AssetImporterWindow::s_browseTag = AZ::Uuid::CreateString("{C240D2E1-BFD2-4FFA-BB5B-CC0FA389A5D3}");
|
|
const AZ::Uuid AssetImporterWindow::s_browseTag = AZ::Uuid::CreateString("{C240D2E1-BFD2-4FFA-BB5B-CC0FA389A5D3}");
|
|
@@ -64,21 +65,18 @@ AssetImporterWindow::AssetImporterWindow(QWidget* parent)
|
|
, m_rootDisplay(nullptr)
|
|
, m_rootDisplay(nullptr)
|
|
, m_overlay(nullptr)
|
|
, m_overlay(nullptr)
|
|
, m_isClosed(false)
|
|
, m_isClosed(false)
|
|
- , m_processingOverlayIndex(AZ::SceneAPI::UI::OverlayWidget::s_invalidOverlayIndex)
|
|
|
|
{
|
|
{
|
|
Init();
|
|
Init();
|
|
}
|
|
}
|
|
|
|
|
|
AssetImporterWindow::~AssetImporterWindow()
|
|
AssetImporterWindow::~AssetImporterWindow()
|
|
{
|
|
{
|
|
- AZ_Assert(m_processingOverlayIndex == AZ::SceneAPI::UI::OverlayWidget::s_invalidOverlayIndex,
|
|
|
|
- "Processing overlay (and potentially background thread) still active at destruction.");
|
|
|
|
- AZ_Assert(!m_processingOverlay, "Processing overlay (and potentially background thread) still active at destruction.");
|
|
|
|
|
|
+ disconnect();
|
|
}
|
|
}
|
|
|
|
|
|
void AssetImporterWindow::OpenFile(const AZStd::string& filePath)
|
|
void AssetImporterWindow::OpenFile(const AZStd::string& filePath)
|
|
{
|
|
{
|
|
- if (m_processingOverlay)
|
|
|
|
|
|
+ if (m_sceneSettingsCardOverlay != AZ::SceneAPI::UI::OverlayWidget::s_invalidOverlayIndex)
|
|
{
|
|
{
|
|
QMessageBox::warning(this, "In progress", "Please wait for the previous task to complete before opening a new file.");
|
|
QMessageBox::warning(this, "In progress", "Please wait for the previous task to complete before opening a new file.");
|
|
return;
|
|
return;
|
|
@@ -113,32 +111,12 @@ void AssetImporterWindow::closeEvent(QCloseEvent* ev)
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
|
|
|
|
- if (m_processingOverlay)
|
|
|
|
|
|
+ if (m_sceneSettingsCardOverlay != AZ::SceneAPI::UI::OverlayWidget::s_invalidOverlayIndex)
|
|
{
|
|
{
|
|
- AZ_Assert(m_processingOverlayIndex != AZ::SceneAPI::UI::OverlayWidget::s_invalidOverlayIndex,
|
|
|
|
- "Processing overlay present, but not the index in the overlay for it.");
|
|
|
|
- if (m_processingOverlay->HasProcessingCompleted())
|
|
|
|
- {
|
|
|
|
- if (m_overlay->PopLayer(m_processingOverlayIndex))
|
|
|
|
- {
|
|
|
|
- m_processingOverlayIndex = AZ::SceneAPI::UI::OverlayWidget::s_invalidOverlayIndex;
|
|
|
|
- m_processingOverlay.reset(nullptr);
|
|
|
|
- }
|
|
|
|
- else
|
|
|
|
- {
|
|
|
|
- QMessageBox::critical(this, "Processing In Progress", "Unable to close the result window at this time.",
|
|
|
|
- QMessageBox::Ok, QMessageBox::Ok);
|
|
|
|
- ev->ignore();
|
|
|
|
- return;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- else
|
|
|
|
- {
|
|
|
|
- QMessageBox::critical(this, "Processing In Progress", "Please wait until processing has completed to try again.",
|
|
|
|
- QMessageBox::Ok, QMessageBox::Ok);
|
|
|
|
- ev->ignore();
|
|
|
|
- return;
|
|
|
|
- }
|
|
|
|
|
|
+ QMessageBox::critical(this, "Processing In Progress", "Please wait until processing has completed to try again.",
|
|
|
|
+ QMessageBox::Ok, QMessageBox::Ok);
|
|
|
|
+ ev->ignore();
|
|
|
|
+ return;
|
|
}
|
|
}
|
|
|
|
|
|
if (!m_overlay->CanClose())
|
|
if (!m_overlay->CanClose())
|
|
@@ -185,7 +163,7 @@ void AssetImporterWindow::Init()
|
|
}
|
|
}
|
|
|
|
|
|
ResetMenuAccess(WindowState::InitialNothingLoaded);
|
|
ResetMenuAccess(WindowState::InitialNothingLoaded);
|
|
-
|
|
|
|
|
|
+
|
|
// Setup the overlay system, and set the root to be the root display. The root display has the browse,
|
|
// Setup the overlay system, and set the root to be the root display. The root display has the browse,
|
|
// the Import button & the cancel button, which are handled here by the window.
|
|
// the Import button & the cancel button, which are handled here by the window.
|
|
m_overlay.reset(aznew AZ::SceneAPI::UI::OverlayWidget(this));
|
|
m_overlay.reset(aznew AZ::SceneAPI::UI::OverlayWidget(this));
|
|
@@ -196,7 +174,7 @@ void AssetImporterWindow::Init()
|
|
connect(m_overlay.data(), &AZ::SceneAPI::UI::OverlayWidget::LayerRemoved, this, &AssetImporterWindow::OverlayLayerRemoved);
|
|
connect(m_overlay.data(), &AZ::SceneAPI::UI::OverlayWidget::LayerRemoved, this, &AssetImporterWindow::OverlayLayerRemoved);
|
|
|
|
|
|
m_overlay->SetRoot(m_rootDisplay.data());
|
|
m_overlay->SetRoot(m_rootDisplay.data());
|
|
- ui->m_mainArea->layout()->addWidget(m_overlay.data());
|
|
|
|
|
|
+ ui->m_settingsAreaLayout->addWidget(m_overlay.data());
|
|
|
|
|
|
// Filling the initial browse prompt text to be programmatically set from available extensions
|
|
// Filling the initial browse prompt text to be programmatically set from available extensions
|
|
AZStd::unordered_set<AZStd::string> extensions;
|
|
AZStd::unordered_set<AZStd::string> extensions;
|
|
@@ -256,18 +234,63 @@ void AssetImporterWindow::OpenFileInternal(const AZStd::string& filePath)
|
|
{
|
|
{
|
|
m_assetImporterDocument->LoadScene(filePath);
|
|
m_assetImporterDocument->LoadScene(filePath);
|
|
|
|
|
|
- UpdateSceneDisplay({});
|
|
|
|
|
|
+ QTimer::singleShot(0, [&]() { UpdateSceneDisplay({}); });
|
|
},
|
|
},
|
|
[this]()
|
|
[this]()
|
|
{
|
|
{
|
|
- HandleAssetLoadingCompleted();
|
|
|
|
|
|
+ QTimer::singleShot(0, [&]() { HandleAssetLoadingCompleted();});
|
|
}, this);
|
|
}, this);
|
|
|
|
+
|
|
|
|
+ QFileInfo fileInfo(filePath.c_str());
|
|
|
|
+ SceneSettingsCard* card = CreateSceneSettingsCard(fileInfo.fileName(), SceneSettingsCard::Layout::Loading, SceneSettingsCard::State::Loading);
|
|
|
|
+ card->SetAndStartProcessingHandler(asyncLoadHandler);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+SceneSettingsCard* AssetImporterWindow::CreateSceneSettingsCard(
|
|
|
|
+ QString fileName,
|
|
|
|
+ SceneSettingsCard::Layout layout,
|
|
|
|
+ SceneSettingsCard::State state)
|
|
|
|
+{
|
|
|
|
+ SceneSettingsCard* card = new SceneSettingsCard(s_browseTag, fileName, layout, ui->m_cardAreaLayoutWidget);
|
|
|
|
+
|
|
|
|
+ card->setExpanded(false);
|
|
|
|
+ ui->m_notificationAreaLayoutWidget->show();
|
|
|
|
+ card->SetState(state);
|
|
|
|
+ ui->m_cardAreaLayout->addWidget(card);
|
|
|
|
+ ++m_openSceneSettingsCards;
|
|
|
|
+ connect(card, &QObject::destroyed, this, &AssetImporterWindow::SceneSettingsCardDestroyed);
|
|
|
|
+
|
|
|
|
+ connect(card, &SceneSettingsCard::ProcessingCompleted, this, &AssetImporterWindow::SceneSettingsCardProcessingCompleted);
|
|
|
|
+
|
|
|
|
+ // Not passing in a QLabel to display because with a QLabel it won't darken the rest of the interface, which is preferred.
|
|
|
|
+ m_sceneSettingsCardOverlay = m_overlay->PushLayer(nullptr, nullptr, "Waiting for file to finish processing", AzQtComponents::OverlayWidgetButtonList());
|
|
|
|
+ return card;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void AssetImporterWindow::SceneSettingsCardDestroyed()
|
|
|
|
+{
|
|
|
|
+ if (m_isClosed)
|
|
|
|
+ {
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+ if (m_openSceneSettingsCards > 0)
|
|
|
|
+ {
|
|
|
|
+ --m_openSceneSettingsCards;
|
|
|
|
+ }
|
|
|
|
+ if (m_openSceneSettingsCards <= 0)
|
|
|
|
+ {
|
|
|
|
+ ui->m_notificationAreaLayoutWidget->hide();
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
|
|
- m_processingOverlay.reset(new ProcessingOverlayWidget(m_overlay.data(), ProcessingOverlayWidget::Layout::Loading, s_browseTag));
|
|
|
|
- m_processingOverlay->SetAndStartProcessingHandler(asyncLoadHandler);
|
|
|
|
- m_processingOverlay->SetAutoCloseOnSuccess(true);
|
|
|
|
- connect(m_processingOverlay.data(), &AZ::SceneAPI::SceneUI::ProcessingOverlayWidget::Closing, this, &AssetImporterWindow::ClearProcessingOverlay);
|
|
|
|
- m_processingOverlayIndex = m_processingOverlay->PushToOverlay();
|
|
|
|
|
|
+void AssetImporterWindow::SceneSettingsCardProcessingCompleted()
|
|
|
|
+{
|
|
|
|
+ if (m_isClosed)
|
|
|
|
+ {
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+ m_overlay->PopLayer(m_sceneSettingsCardOverlay);
|
|
|
|
+ m_sceneSettingsCardOverlay = AZ::SceneAPI::UI::OverlayWidget::s_invalidOverlayIndex;
|
|
}
|
|
}
|
|
|
|
|
|
bool AssetImporterWindow::IsAllowedToChangeSourceFile()
|
|
bool AssetImporterWindow::IsAllowedToChangeSourceFile()
|
|
@@ -329,9 +352,8 @@ void AssetImporterWindow::UpdateClicked()
|
|
using namespace AZ::SceneAPI::SceneUI;
|
|
using namespace AZ::SceneAPI::SceneUI;
|
|
|
|
|
|
// There are specific measures in place to block re-entry, applying asserts to be safe
|
|
// There are specific measures in place to block re-entry, applying asserts to be safe
|
|
- if (m_processingOverlay)
|
|
|
|
|
|
+ if (m_sceneSettingsCardOverlay != AZ::SceneAPI::UI::OverlayWidget::s_invalidOverlayIndex)
|
|
{
|
|
{
|
|
- AZ_Assert(!m_processingOverlay, "Attempted to update asset while processing is in progress.");
|
|
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
else if (!m_scriptProcessorRuleFilename.empty())
|
|
else if (!m_scriptProcessorRuleFilename.empty())
|
|
@@ -340,14 +362,8 @@ void AssetImporterWindow::UpdateClicked()
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
|
|
|
|
- m_processingOverlay.reset(new ProcessingOverlayWidget(m_overlay.data(), ProcessingOverlayWidget::Layout::Exporting, s_browseTag));
|
|
|
|
- connect(m_processingOverlay.data(), &ProcessingOverlayWidget::Closing, this, &AssetImporterWindow::ClearProcessingOverlay);
|
|
|
|
- m_processingOverlayIndex = m_processingOverlay->PushToOverlay();
|
|
|
|
|
|
+ SceneSettingsCard* card = CreateSceneSettingsCard(m_rootDisplay->GetHeaderFileName(), SceneSettingsCard::Layout::Exporting, SceneSettingsCard::State::Processing);
|
|
|
|
|
|
- // We need to block closing of the overlay until source control operations are complete
|
|
|
|
- m_processingOverlay->BlockClosing();
|
|
|
|
-
|
|
|
|
- m_processingOverlay->OnSetStatusMessage("Saving settings...");
|
|
|
|
bool isSourceControlActive = false;
|
|
bool isSourceControlActive = false;
|
|
{
|
|
{
|
|
using SCRequestBus = AzToolsFramework::SourceControlConnectionRequestBus;
|
|
using SCRequestBus = AzToolsFramework::SourceControlConnectionRequestBus;
|
|
@@ -356,7 +372,7 @@ void AssetImporterWindow::UpdateClicked()
|
|
|
|
|
|
AZStd::shared_ptr<AZ::ActionOutput> output = AZStd::make_shared<AZ::ActionOutput>();
|
|
AZStd::shared_ptr<AZ::ActionOutput> output = AZStd::make_shared<AZ::ActionOutput>();
|
|
m_assetImporterDocument->SaveScene(output,
|
|
m_assetImporterDocument->SaveScene(output,
|
|
- [output, this, isSourceControlActive](bool wasSuccessful)
|
|
|
|
|
|
+ [output, this, isSourceControlActive, card](bool wasSuccessful)
|
|
{
|
|
{
|
|
if (output->HasAnyWarnings())
|
|
if (output->HasAnyWarnings())
|
|
{
|
|
{
|
|
@@ -381,19 +397,8 @@ void AssetImporterWindow::UpdateClicked()
|
|
m_rootDisplay->HandleSaveWasSuccessful();
|
|
m_rootDisplay->HandleSaveWasSuccessful();
|
|
|
|
|
|
// Don't attach the job processor until all files are saved.
|
|
// Don't attach the job processor until all files are saved.
|
|
- m_processingOverlay->SetAndStartProcessingHandler(AZStd::make_shared<ExportJobProcessingHandler>(s_browseTag, m_fullSourcePath));
|
|
|
|
- }
|
|
|
|
- else
|
|
|
|
- {
|
|
|
|
- // This kind of failure means that it's possible the jobs will never actually start,
|
|
|
|
- // so we act like the processing is complete to make it so the user won't be stuck
|
|
|
|
- // in the processing UI in that case.
|
|
|
|
- m_processingOverlay->OnProcessingComplete();
|
|
|
|
|
|
+ card->SetAndStartProcessingHandler(AZStd::make_shared<ExportJobProcessingHandler>(s_browseTag, m_fullSourcePath));
|
|
}
|
|
}
|
|
-
|
|
|
|
- // Blocking is only used for the period saving is happening. The ExportJobProcessingHandler will inform
|
|
|
|
- // the overlay widget when the AP is done with processing, which will also block closing until done.
|
|
|
|
- m_processingOverlay->UnblockClosing();
|
|
|
|
}
|
|
}
|
|
);
|
|
);
|
|
}
|
|
}
|
|
@@ -442,13 +447,9 @@ void AssetImporterWindow::OnSceneResetRequested()
|
|
file.remove();
|
|
file.remove();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
- UpdateSceneDisplay({});
|
|
|
|
|
|
|
|
- m_processingOverlay.reset(new ProcessingOverlayWidget(m_overlay.data(), ProcessingOverlayWidget::Layout::Resetting, s_browseTag));
|
|
|
|
- m_processingOverlay->SetAndStartProcessingHandler(asyncLoadHandler);
|
|
|
|
- m_processingOverlay->SetAutoCloseOnSuccess(true);
|
|
|
|
- connect(m_processingOverlay.data(), &ProcessingOverlayWidget::Closing, this, &AssetImporterWindow::ClearProcessingOverlay);
|
|
|
|
- m_processingOverlayIndex = m_processingOverlay->PushToOverlay();
|
|
|
|
|
|
+ SceneSettingsCard* card = CreateSceneSettingsCard(m_rootDisplay->GetHeaderFileName(), SceneSettingsCard::Layout::Resetting, SceneSettingsCard::State::Loading);
|
|
|
|
+ card->SetAndStartProcessingHandler(asyncLoadHandler);
|
|
}
|
|
}
|
|
|
|
|
|
void AssetImporterWindow::OnAssignScript()
|
|
void AssetImporterWindow::OnAssignScript()
|
|
@@ -603,12 +604,6 @@ void AssetImporterWindow::UpdateSceneDisplay(const AZStd::shared_ptr<AZ::SceneAP
|
|
{
|
|
{
|
|
sceneHeaderText = QString::fromUtf8(scene->GetManifestFilename().c_str(), static_cast<int>(scene->GetManifestFilename().size()));
|
|
sceneHeaderText = QString::fromUtf8(scene->GetManifestFilename().c_str(), static_cast<int>(scene->GetManifestFilename().size()));
|
|
}
|
|
}
|
|
- if (!m_scriptProcessorRuleFilename.empty())
|
|
|
|
- {
|
|
|
|
- sceneHeaderText.append("\n Assigned Python builder script (")
|
|
|
|
- .append(m_scriptProcessorRuleFilename.c_str())
|
|
|
|
- .append(")");
|
|
|
|
- }
|
|
|
|
|
|
|
|
if (scene)
|
|
if (scene)
|
|
{
|
|
{
|
|
@@ -618,6 +613,8 @@ void AssetImporterWindow::UpdateSceneDisplay(const AZStd::shared_ptr<AZ::SceneAP
|
|
{
|
|
{
|
|
m_rootDisplay->SetSceneHeaderText(sceneHeaderText);
|
|
m_rootDisplay->SetSceneHeaderText(sceneHeaderText);
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ m_rootDisplay->SetPythonBuilderText(m_scriptProcessorRuleFilename.c_str());
|
|
}
|
|
}
|
|
|
|
|
|
void AssetImporterWindow::HandleAssetLoadingCompleted()
|
|
void AssetImporterWindow::HandleAssetLoadingCompleted()
|
|
@@ -656,10 +653,4 @@ void AssetImporterWindow::HandleAssetLoadingCompleted()
|
|
m_rootDisplay->show();
|
|
m_rootDisplay->show();
|
|
}
|
|
}
|
|
|
|
|
|
-void AssetImporterWindow::ClearProcessingOverlay()
|
|
|
|
-{
|
|
|
|
- m_processingOverlayIndex = AZ::SceneAPI::UI::OverlayWidget::s_invalidOverlayIndex;
|
|
|
|
- m_processingOverlay.reset(nullptr);
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
#include <moc_AssetImporterWindow.cpp>
|
|
#include <moc_AssetImporterWindow.cpp>
|