Atom Tools: Move common asset browser interactions to shared class in ATF

Moved the class for common asset browser interactions for source files, folders, and source control to atom tools framework.
Added a function to register custom actions
Deleted unnecessary document settings class in favor of settings registry

Signed-off-by: Guthrie Adams <guthadam@amazon.com>
monroegm-disable-blank-issue-2
Guthrie Adams 4 years ago
parent b1df4c90d5
commit 1497250ff5

@ -0,0 +1,65 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#pragma once
#include <AzToolsFramework/AssetBrowser/AssetBrowserBus.h>
#include <AzToolsFramework/SourceControl/SourceControlAPI.h>
class QWidget;
class QMenu;
class QAction;
namespace AzToolsFramework
{
namespace AssetBrowser
{
class AssetBrowserEntry;
} // namespace AssetBrowser
} // namespace AzToolsFramework
namespace AtomToolsFramework
{
//! Provides common asset browser interactions, source control integration, and functionality to add custom menu actions
class AtomToolsAssetBrowserInteractions : public AzToolsFramework::AssetBrowser::AssetBrowserInteractionNotificationBus::Handler
{
public:
AZ_CLASS_ALLOCATOR(AtomToolsAssetBrowserInteractions, AZ::SystemAllocator, 0);
AtomToolsAssetBrowserInteractions();
~AtomToolsAssetBrowserInteractions();
using AssetBrowserEntryVector = AZStd::vector<AzToolsFramework::AssetBrowser::AssetBrowserEntry*>;
using FilterCallback = AZStd::function<bool(const AssetBrowserEntryVector&)>;
using ActionCallback = AZStd::function<void(QWidget* caller, QMenu* menu, const AssetBrowserEntryVector&)>;
//! Add a filter and handler for custom context menu entries that will be added to the top of the context menu
void RegisterContextMenuActions(const FilterCallback& filterCallback, const ActionCallback& actionCallback);
private:
//! AssetBrowserInteractionNotificationBus::Handler overrides...
void AddContextMenuActions(QWidget* caller, QMenu* menu, const AssetBrowserEntryVector& entries) override;
void AddContextMenuActionsForSourceEntries(
QWidget* caller, QMenu* menu, const AzToolsFramework::AssetBrowser::AssetBrowserEntry* entry);
void AddContextMenuActionsForFolderEntries(
QWidget* caller, QMenu* menu, const AzToolsFramework::AssetBrowser::AssetBrowserEntry* entry);
void AddContextMenuActionsForAllEntries(
QWidget* caller, QMenu* menu, const AzToolsFramework::AssetBrowser::AssetBrowserEntry* entry);
void AddContextMenuActionsForSourceControl(
QWidget* caller, QMenu* menu, const AzToolsFramework::AssetBrowser::AssetBrowserEntry* entry);
void UpdateContextMenuActionsForSourceControl(bool success, AzToolsFramework::SourceControlFileInfo info);
QWidget* m_caller = {};
QAction* m_addAction = {};
QAction* m_checkOutAction = {};
QAction* m_undoCheckOutAction = {};
QAction* m_getLatestAction = {};
AZStd::vector<AZStd::pair<FilterCallback, ActionCallback>> m_contextMenuCallbacks;
};
} // namespace AtomToolsFramework

@ -7,44 +7,47 @@
*/
#include <Atom/RPI.Edit/Common/AssetUtils.h>
#include <Atom/RPI.Edit/Material/MaterialSourceData.h>
#include <Atom/RPI.Edit/Material/MaterialTypeSourceData.h>
#include <Atom/RPI.Reflect/Material/MaterialAsset.h>
#include <AtomToolsFramework/Document/AtomToolsDocumentSystemRequestBus.h>
#include <AtomToolsFramework/AssetBrowser/AtomToolsAssetBrowserInteractions.h>
#include <AtomToolsFramework/Util/Util.h>
#include <AzCore/Utils/Utils.h>
#include <AzCore/std/string/wildcard.h>
#include <AzQtComponents/Utilities/DesktopUtilities.h>
#include <AzToolsFramework/API/EditorPythonRunnerRequestsBus.h>
#include <AzToolsFramework/AssetBrowser/AssetBrowserBus.h>
#include <AzToolsFramework/AssetBrowser/AssetBrowserEntry.h>
#include <AzToolsFramework/AssetBrowser/AssetSelectionModel.h>
#include <AzToolsFramework/Thumbnails/SourceControlThumbnail.h>
#include <Window/CreateMaterialDialog/CreateMaterialDialog.h>
#include <Window/MaterialEditorBrowserInteractions.h>
#include <QApplication>
#include <QClipboard>
#include <QDesktopServices>
#include <QDir>
#include <QFileDialog>
#include <QFileInfo>
#include <QInputDialog>
#include <QMenu>
#include <QMessageBox>
namespace MaterialEditor
namespace AtomToolsFramework
{
MaterialEditorBrowserInteractions::MaterialEditorBrowserInteractions()
AtomToolsAssetBrowserInteractions::AtomToolsAssetBrowserInteractions()
{
using namespace AzToolsFramework::AssetBrowser;
AssetBrowserInteractionNotificationBus::Handler::BusConnect();
}
MaterialEditorBrowserInteractions::~MaterialEditorBrowserInteractions()
AtomToolsAssetBrowserInteractions::~AtomToolsAssetBrowserInteractions()
{
AssetBrowserInteractionNotificationBus::Handler::BusDisconnect();
}
void MaterialEditorBrowserInteractions::AddContextMenuActions(QWidget* caller, QMenu* menu, const AZStd::vector<AzToolsFramework::AssetBrowser::AssetBrowserEntry*>& entries)
void AtomToolsAssetBrowserInteractions::RegisterContextMenuActions(
const FilterCallback& filterCallback, const ActionCallback& actionCallback)
{
m_contextMenuCallbacks.emplace_back(filterCallback, actionCallback);
}
void AtomToolsAssetBrowserInteractions::AddContextMenuActions(
QWidget* caller, QMenu* menu, const AssetBrowserEntryVector& entries)
{
AssetBrowserEntry* entry = entries.empty() ? nullptr : entries.front();
if (!entry)
@ -53,79 +56,33 @@ namespace MaterialEditor
}
m_caller = caller;
QObject::connect(m_caller, &QObject::destroyed, [this]()
{
m_caller = nullptr;
});
AddGenericContextMenuActions(caller, menu, entry);
QObject::connect(m_caller, &QObject::destroyed, [this]() { m_caller = nullptr; });
if (entry->GetEntryType() == AssetBrowserEntry::AssetEntryType::Source)
// Add all of the custom context menu entries first
for (const auto& contextMenuCallbackPair : m_contextMenuCallbacks)
{
const auto source = azalias_cast<const SourceAssetBrowserEntry*>(entry);
if (AzFramework::StringFunc::Path::IsExtension(entry->GetFullPath().c_str(), AZ::RPI::MaterialSourceData::Extension))
{
AddContextMenuActionsForMaterialSource(caller, menu, source);
}
else if (AzFramework::StringFunc::Path::IsExtension(entry->GetFullPath().c_str(), AZ::RPI::MaterialTypeSourceData::Extension))
if (contextMenuCallbackPair.first(entries))
{
AddContextMenuActionsForMaterialTypeSource(caller, menu, source);
}
else
{
AddContextMenuActionsForOtherSource(caller, menu, source);
contextMenuCallbackPair.second(caller, menu, entries);
}
}
if (entry->GetEntryType() == AssetBrowserEntry::AssetEntryType::Source)
{
AddContextMenuActionsForSourceEntries(caller, menu, entry);
}
else if (entry->GetEntryType() == AssetBrowserEntry::AssetEntryType::Folder)
{
const auto folder = azalias_cast<const FolderAssetBrowserEntry*>(entry);
AddContextMenuActionsForFolder(caller, menu, folder);
AddContextMenuActionsForFolderEntries(caller, menu, entry);
}
}
void MaterialEditorBrowserInteractions::AddGenericContextMenuActions([[maybe_unused]] QWidget* caller, QMenu* menu, const AzToolsFramework::AssetBrowser::AssetBrowserEntry* entry)
{
menu->addAction(QObject::tr("Copy Name To Clipboard"), [=]()
{
QApplication::clipboard()->setText(entry->GetName().c_str());
});
menu->addAction(QObject::tr("Copy Path To Clipboard"), [=]()
{
QApplication::clipboard()->setText(entry->GetFullPath().c_str());
});
}
void MaterialEditorBrowserInteractions::AddContextMenuActionsForMaterialTypeSource(QWidget* caller, QMenu* menu, const AzToolsFramework::AssetBrowser::SourceAssetBrowserEntry* entry)
{
menu->addAction(AzQtComponents::fileBrowserActionName(), [entry]()
{
AzQtComponents::ShowFileOnDesktop(entry->GetFullPath().c_str());
});
menu->addSeparator();
menu->addAction("Create Material...", [entry]()
{
const QString defaultPath = AtomToolsFramework::GetUniqueFileInfo(
QString(AZ::Utils::GetProjectPath().c_str()) +
AZ_CORRECT_FILESYSTEM_SEPARATOR + "Assets" +
AZ_CORRECT_FILESYSTEM_SEPARATOR + "untitled." +
AZ::RPI::MaterialSourceData::Extension).absoluteFilePath();
AtomToolsFramework::AtomToolsDocumentSystemRequestBus::Broadcast(&AtomToolsFramework::AtomToolsDocumentSystemRequestBus::Events::CreateDocumentFromFile,
entry->GetFullPath(), AtomToolsFramework::GetSaveFileInfo(defaultPath).absoluteFilePath().toUtf8().constData());
});
AddPerforceMenuActions(caller, menu, entry);
AddContextMenuActionsForAllEntries(caller, menu, entry);
AddContextMenuActionsForSourceControl(caller, menu, entry);
}
void MaterialEditorBrowserInteractions::AddContextMenuActionsForOtherSource(QWidget* caller, QMenu* menu, const AzToolsFramework::AssetBrowser::SourceAssetBrowserEntry* entry)
void AtomToolsAssetBrowserInteractions::AddContextMenuActionsForSourceEntries(
[[maybe_unused]] QWidget* caller, QMenu* menu, const AzToolsFramework::AssetBrowser::AssetBrowserEntry* entry)
{
menu->addAction("Open", [entry]()
{
QDesktopServices::openUrl(QUrl::fromLocalFile(entry->GetFullPath().c_str()));
});
menu->addAction("Duplicate...", [entry]()
{
const QFileInfo duplicateFileInfo(AtomToolsFramework::GetDuplicationFileInfo(entry->GetFullPath().c_str()));
@ -142,79 +99,26 @@ namespace MaterialEditor
}
});
menu->addAction(AzQtComponents::fileBrowserActionName(), [entry]()
{
AzQtComponents::ShowFileOnDesktop(entry->GetFullPath().c_str());
});
AddPerforceMenuActions(caller, menu, entry);
}
void MaterialEditorBrowserInteractions::AddContextMenuActionsForMaterialSource(QWidget* caller, QMenu* menu, const AzToolsFramework::AssetBrowser::SourceAssetBrowserEntry* entry)
{
menu->addAction("Open", [entry]()
{
AtomToolsFramework::AtomToolsDocumentSystemRequestBus::Broadcast(&AtomToolsFramework::AtomToolsDocumentSystemRequestBus::Events::OpenDocument, entry->GetFullPath());
});
menu->addAction("Duplicate...", [entry]()
{
const QFileInfo duplicateFileInfo(AtomToolsFramework::GetDuplicationFileInfo(entry->GetFullPath().c_str()));
if (!duplicateFileInfo.absoluteFilePath().isEmpty())
menu->addAction("Run Python on File...", [caller, entry]()
{
const QString script = QFileDialog::getOpenFileName(
caller, QObject::tr("Run Script"), QString(AZ::Utils::GetProjectPath().c_str()), QString("*.py"));
if (!script.isEmpty())
{
if (QFile::copy(entry->GetFullPath().c_str(), duplicateFileInfo.absoluteFilePath()))
{
QFile::setPermissions(duplicateFileInfo.absoluteFilePath(), QFile::ReadOther | QFile::WriteOther);
// Auto add file to source control
AzToolsFramework::SourceControlCommandBus::Broadcast(&AzToolsFramework::SourceControlCommandBus::Events::RequestEdit,
duplicateFileInfo.absoluteFilePath().toUtf8().constData(), true, [](bool, const AzToolsFramework::SourceControlFileInfo&) {});
}
AZStd::vector<AZStd::string_view> pythonArgs{ entry->GetFullPath() };
AzToolsFramework::EditorPythonRunnerRequestBus::Broadcast(
&AzToolsFramework::EditorPythonRunnerRequestBus::Events::ExecuteByFilenameWithArgs, script.toUtf8().constData(),
pythonArgs);
}
});
menu->addAction(AzQtComponents::fileBrowserActionName(), [entry]()
{
AzQtComponents::ShowFileOnDesktop(entry->GetFullPath().c_str());
});
menu->addSeparator();
menu->addAction("Create Child Material...", [entry]()
{
const QString defaultPath = AtomToolsFramework::GetUniqueFileInfo(
QString(AZ::Utils::GetProjectPath().c_str()) +
AZ_CORRECT_FILESYSTEM_SEPARATOR + "Assets" +
AZ_CORRECT_FILESYSTEM_SEPARATOR + "untitled." +
AZ::RPI::MaterialSourceData::Extension).absoluteFilePath();
AtomToolsFramework::AtomToolsDocumentSystemRequestBus::Broadcast(&AtomToolsFramework::AtomToolsDocumentSystemRequestBus::Events::CreateDocumentFromFile,
entry->GetFullPath(), AtomToolsFramework::GetSaveFileInfo(defaultPath).absoluteFilePath().toUtf8().constData());
});
menu->addSeparator();
QAction* openParentAction = menu->addAction("Open Parent Material", [entry]()
{
AZ_UNUSED(entry);
// ToDo
});
openParentAction->setEnabled(false);
AddPerforceMenuActions(caller, menu, entry);
}
void MaterialEditorBrowserInteractions::AddContextMenuActionsForFolder(QWidget* caller, QMenu* menu, const AzToolsFramework::AssetBrowser::FolderAssetBrowserEntry* entry)
void AtomToolsAssetBrowserInteractions::AddContextMenuActionsForFolderEntries(
QWidget* caller, QMenu* menu, const AzToolsFramework::AssetBrowser::AssetBrowserEntry* entry)
{
menu->addAction(AzQtComponents::fileBrowserActionName(), [entry]()
menu->addAction(QObject::tr("Create new sub folder..."), [caller, entry]()
{
AzQtComponents::ShowFileOnDesktop(entry->GetFullPath().c_str());
});
QAction* createFolderAction = menu->addAction(QObject::tr("Create new sub folder..."));
QObject::connect(createFolderAction, &QAction::triggered, caller, [caller, entry]()
{
bool ok;
bool ok = false;
QString newFolderName = QInputDialog::getText(caller, "Enter new folder name", "name:", QLineEdit::Normal, "NewFolder", &ok);
if (ok)
{
@ -242,27 +146,29 @@ namespace MaterialEditor
}
}
});
}
menu->addSeparator();
QAction* createMaterialAction = menu->addAction(QObject::tr("Create Material..."));
QObject::connect(createMaterialAction, &QAction::triggered, caller, [caller, entry]()
void AtomToolsAssetBrowserInteractions::AddContextMenuActionsForAllEntries(
[[maybe_unused]] QWidget* caller, QMenu* menu, const AzToolsFramework::AssetBrowser::AssetBrowserEntry* entry)
{
menu->addAction(AzQtComponents::fileBrowserActionName(), [entry]()
{
CreateMaterialDialog createDialog(entry->GetFullPath().c_str(), caller);
createDialog.adjustSize();
AzQtComponents::ShowFileOnDesktop(entry->GetFullPath().c_str());
});
if (createDialog.exec() == QDialog::Accepted &&
!createDialog.m_materialFileInfo.absoluteFilePath().isEmpty() &&
!createDialog.m_materialTypeFileInfo.absoluteFilePath().isEmpty())
{
AtomToolsFramework::AtomToolsDocumentSystemRequestBus::Broadcast(&AtomToolsFramework::AtomToolsDocumentSystemRequestBus::Events::CreateDocumentFromFile,
createDialog.m_materialTypeFileInfo.absoluteFilePath().toUtf8().constData(),
createDialog.m_materialFileInfo.absoluteFilePath().toUtf8().constData());
}
menu->addSeparator();
menu->addAction(QObject::tr("Copy Name To Clipboard"), [=]()
{
QApplication::clipboard()->setText(entry->GetName().c_str());
});
menu->addAction(QObject::tr("Copy Path To Clipboard"), [=]()
{
QApplication::clipboard()->setText(entry->GetFullPath().c_str());
});
}
void MaterialEditorBrowserInteractions::AddPerforceMenuActions([[maybe_unused]] QWidget* caller, QMenu* menu, const AzToolsFramework::AssetBrowser::AssetBrowserEntry* entry)
void AtomToolsAssetBrowserInteractions::AddContextMenuActionsForSourceControl(
[[maybe_unused]] QWidget* caller, QMenu* menu, const AzToolsFramework::AssetBrowser::AssetBrowserEntry* entry)
{
using namespace AzToolsFramework;
@ -282,7 +188,7 @@ namespace MaterialEditor
QMenu::connect(sourceControlMenu, &QMenu::aboutToShow, [this, path]()
{
SourceControlCommandBus::Broadcast(&SourceControlCommandBus::Events::GetFileInfo, path.c_str(),
[this](bool success, const SourceControlFileInfo& info) { UpdateSourceControlActions(success, info); });
[this](bool success, const SourceControlFileInfo& info) { UpdateContextMenuActionsForSourceControl(success, info); });
});
// add get latest action
@ -344,7 +250,7 @@ namespace MaterialEditor
}
}
void MaterialEditorBrowserInteractions::UpdateSourceControlActions(bool success, AzToolsFramework::SourceControlFileInfo info)
void AtomToolsAssetBrowserInteractions::UpdateContextMenuActionsForSourceControl(bool success, AzToolsFramework::SourceControlFileInfo info)
{
if (!success && m_caller)
{
@ -367,4 +273,4 @@ namespace MaterialEditor
m_undoCheckOutAction->setEnabled(info.IsManaged() && !info.IsReadOnly());
}
}
} // namespace MaterialEditor
} // namespace AtomToolsFramework

@ -9,6 +9,7 @@
set(FILES
Include/AtomToolsFramework/Application/AtomToolsApplication.h
Include/AtomToolsFramework/AssetBrowser/AtomToolsAssetBrowser.h
Include/AtomToolsFramework/AssetBrowser/AtomToolsAssetBrowserInteractions.h
Include/AtomToolsFramework/AssetGridDialog/AssetGridDialog.h
Include/AtomToolsFramework/Communication/LocalServer.h
Include/AtomToolsFramework/Communication/LocalSocket.h
@ -44,6 +45,7 @@ set(FILES
Source/AssetBrowser/AtomToolsAssetBrowser.cpp
Source/AssetBrowser/AtomToolsAssetBrowser.qrc
Source/AssetBrowser/AtomToolsAssetBrowser.ui
Source/AssetBrowser/AtomToolsAssetBrowserInteractions.cpp
Source/AssetGridDialog/AssetGridDialog.cpp
Source/AssetGridDialog/AssetGridDialog.ui
Source/Communication/LocalServer.cpp

@ -1,47 +0,0 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#include <AzCore/RTTI/BehaviorContext.h>
#include <AzCore/Serialization/EditContext.h>
#include <Document/MaterialDocumentSettings.h>
namespace MaterialEditor
{
void MaterialDocumentSettings::Reflect(AZ::ReflectContext* context)
{
if (auto serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
{
serializeContext->Class<MaterialDocumentSettings, AZ::UserSettings>()
->Version(1)
->Field("defaultMaterialTypeName", &MaterialDocumentSettings::m_defaultMaterialTypeName)
;
if (auto editContext = serializeContext->GetEditContext())
{
editContext->Class<MaterialDocumentSettings>(
"MaterialDocumentSettings", "")
->ClassElement(AZ::Edit::ClassElements::EditorData, "")
->Attribute(AZ::Edit::Attributes::AutoExpand, true)
->DataElement(AZ::Edit::UIHandlers::Default, &MaterialDocumentSettings::m_defaultMaterialTypeName, "Default Material Type Name", "")
;
}
}
if (auto behaviorContext = azrtti_cast<AZ::BehaviorContext*>(context))
{
behaviorContext->Class<MaterialDocumentSettings>("MaterialDocumentSettings")
->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Common)
->Attribute(AZ::Script::Attributes::Category, "Editor")
->Attribute(AZ::Script::Attributes::Module, "materialeditor")
->Constructor()
->Constructor<const MaterialDocumentSettings&>()
->Property("defaultMaterialTypeName", BehaviorValueProperty(&MaterialDocumentSettings::m_defaultMaterialTypeName))
;
}
}
} // namespace MaterialEditor

@ -1,30 +0,0 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#pragma once
#if !defined(Q_MOC_RUN)
#include <AzCore/Memory/Memory.h>
#include <AzCore/RTTI/RTTI.h>
#include <AzCore/RTTI/ReflectContext.h>
#include <AzCore/UserSettings/UserSettings.h>
#endif
namespace MaterialEditor
{
struct MaterialDocumentSettings
: public AZ::UserSettings
{
AZ_RTTI(MaterialDocumentSettings, "{12E8461F-65AD-4AD2-8A1D-82C3B1183522}", AZ::UserSettings);
AZ_CLASS_ALLOCATOR(MaterialDocumentSettings, AZ::SystemAllocator, 0);
static void Reflect(AZ::ReflectContext* context);
AZStd::string m_defaultMaterialTypeName = "StandardPBR";
};
} // namespace MaterialEditor

@ -6,21 +6,32 @@
*
*/
#include <Atom/RPI.Edit/Material/MaterialSourceData.h>
#include <Atom/RPI.Edit/Material/MaterialTypeSourceData.h>
#include <Atom/RPI.Reflect/Material/MaterialAsset.h>
#include <AtomToolsFramework/Document/AtomToolsDocumentSystemRequestBus.h>
#include <AtomToolsFramework/Util/Util.h>
#include <AzCore/RTTI/BehaviorContext.h>
#include <AzCore/Serialization/EditContext.h>
#include <AzCore/Serialization/SerializeContext.h>
#include <AzCore/Settings/SettingsRegistryMergeUtils.h>
#include <AzCore/Utils/Utils.h>
#include <AzToolsFramework/API/ToolsApplicationAPI.h>
#include <AzToolsFramework/AssetBrowser/AssetBrowserEntry.h>
#include <Document/MaterialDocument.h>
#include <Document/MaterialDocumentRequestBus.h>
#include <Document/MaterialDocumentSettings.h>
#include <MaterialEditorApplication.h>
#include <MaterialEditor_Traits_Platform.h>
#include <Viewport/MaterialViewportModule.h>
#include <Window/CreateMaterialDialog/CreateMaterialDialog.h>
#include <Window/MaterialEditorWindow.h>
#include <Window/MaterialEditorWindowSettings.h>
#include <QDesktopServices>
#include <QDialog>
#include <QMenu>
#include <QUrl>
void InitMaterialEditorResources()
{
// Must register qt resources from other modules
@ -56,7 +67,6 @@ namespace MaterialEditor
void MaterialEditorApplication::Reflect(AZ::ReflectContext* context)
{
Base::Reflect(context);
MaterialDocumentSettings::Reflect(context);
MaterialEditorWindowSettings::Reflect(context);
if (AZ::BehaviorContext* behaviorContext = azrtti_cast<AZ::BehaviorContext*>(context))
@ -112,8 +122,77 @@ namespace MaterialEditor
void MaterialEditorApplication::CreateMainWindow()
{
m_materialEditorBrowserInteractions.reset(aznew MaterialEditorBrowserInteractions);
m_window.reset(aznew MaterialEditorWindow);
m_assetBrowserInteractions.reset(aznew AtomToolsFramework::AtomToolsAssetBrowserInteractions);
m_assetBrowserInteractions->RegisterContextMenuActions(
[](const AtomToolsFramework::AtomToolsAssetBrowserInteractions::AssetBrowserEntryVector& entries)
{
return entries.front()->GetEntryType() == AzToolsFramework::AssetBrowser::AssetBrowserEntry::AssetEntryType::Source;
},
[]([[maybe_unused]] QWidget* caller, QMenu* menu, const AtomToolsFramework::AtomToolsAssetBrowserInteractions::AssetBrowserEntryVector& entries)
{
const bool isMaterial = AzFramework::StringFunc::Path::IsExtension(
entries.front()->GetFullPath().c_str(), AZ::RPI::MaterialSourceData::Extension);
const bool isMaterialType = AzFramework::StringFunc::Path::IsExtension(
entries.front()->GetFullPath().c_str(), AZ::RPI::MaterialTypeSourceData::Extension);
if (isMaterial || isMaterialType)
{
menu->addAction(QObject::tr("Open"), [entries]()
{
AtomToolsFramework::AtomToolsDocumentSystemRequestBus::Broadcast(
&AtomToolsFramework::AtomToolsDocumentSystemRequestBus::Events::OpenDocument,
entries.front()->GetFullPath());
});
const QString createActionName =
isMaterialType ? QObject::tr("Create Material...") : QObject::tr("Create Child Material...");
menu->addAction(createActionName, [entries]()
{
const QString defaultPath = AtomToolsFramework::GetUniqueFileInfo(
QString(AZ::Utils::GetProjectPath().c_str()) +
AZ_CORRECT_FILESYSTEM_SEPARATOR + "Assets" +
AZ_CORRECT_FILESYSTEM_SEPARATOR + "untitled." +
AZ::RPI::MaterialSourceData::Extension).absoluteFilePath();
AtomToolsFramework::AtomToolsDocumentSystemRequestBus::Broadcast(
&AtomToolsFramework::AtomToolsDocumentSystemRequestBus::Events::CreateDocumentFromFile,
entries.front()->GetFullPath(),
AtomToolsFramework::GetSaveFileInfo(defaultPath).absoluteFilePath().toUtf8().constData());
});
}
else
{
menu->addAction(QObject::tr("Open"), [entries]()
{
QDesktopServices::openUrl(QUrl::fromLocalFile(entries.front()->GetFullPath().c_str()));
});
}
});
m_assetBrowserInteractions->RegisterContextMenuActions(
[](const AtomToolsFramework::AtomToolsAssetBrowserInteractions::AssetBrowserEntryVector& entries)
{
return entries.front()->GetEntryType() == AzToolsFramework::AssetBrowser::AssetBrowserEntry::AssetEntryType::Folder;
},
[](QWidget* caller, QMenu* menu, const AtomToolsFramework::AtomToolsAssetBrowserInteractions::AssetBrowserEntryVector& entries)
{
menu->addAction(QObject::tr("Create Material..."), [caller, entries]()
{
CreateMaterialDialog createDialog(entries.front()->GetFullPath().c_str(), caller);
createDialog.adjustSize();
if (createDialog.exec() == QDialog::Accepted &&
!createDialog.m_materialFileInfo.absoluteFilePath().isEmpty() &&
!createDialog.m_materialTypeFileInfo.absoluteFilePath().isEmpty())
{
AtomToolsFramework::AtomToolsDocumentSystemRequestBus::Broadcast(
&AtomToolsFramework::AtomToolsDocumentSystemRequestBus::Events::CreateDocumentFromFile,
createDialog.m_materialTypeFileInfo.absoluteFilePath().toUtf8().constData(),
createDialog.m_materialFileInfo.absoluteFilePath().toUtf8().constData());
}
});
});
}
void MaterialEditorApplication::DestroyMainWindow()

@ -8,10 +8,10 @@
#pragma once
#include <AtomToolsFramework/AssetBrowser/AtomToolsAssetBrowserInteractions.h>
#include <AtomToolsFramework/Document/AtomToolsDocumentApplication.h>
#include <AtomToolsFramework/Window/AtomToolsMainWindowFactoryRequestBus.h>
#include <AzToolsFramework/API/EditorWindowRequestBus.h>
#include <Window/MaterialEditorBrowserInteractions.h>
#include <Window/MaterialEditorWindow.h>
namespace MaterialEditor
@ -49,6 +49,6 @@ namespace MaterialEditor
QWidget* GetAppMainWindow() override;
AZStd::unique_ptr<MaterialEditorWindow> m_window;
AZStd::unique_ptr<MaterialEditorBrowserInteractions> m_materialEditorBrowserInteractions;
AZStd::unique_ptr<AtomToolsFramework::AtomToolsAssetBrowserInteractions> m_assetBrowserInteractions;
};
} // namespace MaterialEditor

@ -14,7 +14,6 @@
#include <AzFramework/Application/Application.h>
#include <AzFramework/StringFunc/StringFunc.h>
#include <AzQtComponents/Components/Widgets/FileDialog.h>
#include <Document/MaterialDocumentSettings.h>
#include <Window/CreateMaterialDialog/CreateMaterialDialog.h>
namespace MaterialEditor
@ -65,11 +64,10 @@ namespace MaterialEditor
m_ui->m_materialTypeComboBox->model()->sort(0, Qt::AscendingOrder);
// Select the default material type from settings
auto settings =
AZ::UserSettings::CreateFind<MaterialDocumentSettings>(AZ::Crc32("MaterialDocumentSettings"), AZ::UserSettings::CT_GLOBAL);
const AZStd::string defaultMaterialType = AtomToolsFramework::GetSettingOrDefault<AZStd::string>(
"/O3DE/Atom/MaterialEditor/CreateMaterialDialog/DefaultMaterialType", "StandardPBR");
const int index = m_ui->m_materialTypeComboBox->findText(settings->m_defaultMaterialTypeName.c_str());
const int index = m_ui->m_materialTypeComboBox->findText(defaultMaterialType.c_str());
if (index >= 0)
{
m_ui->m_materialTypeComboBox->setCurrentIndex(index);

@ -1,58 +0,0 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#pragma once
#include <AzToolsFramework/AssetBrowser/AssetBrowserBus.h>
#include <AzToolsFramework/SourceControl/SourceControlAPI.h>
class QWidget;
class QMenu;
class QAction;
namespace AzToolsFramework
{
namespace AssetBrowser
{
class AssetBrowserEntry;
class SourceAssetBrowserEntry;
class FolderAssetBrowserEntry;
}
}
namespace MaterialEditor
{
class MaterialEditorBrowserInteractions
: public AzToolsFramework::AssetBrowser::AssetBrowserInteractionNotificationBus::Handler
{
public:
AZ_CLASS_ALLOCATOR(MaterialEditorBrowserInteractions, AZ::SystemAllocator, 0);
MaterialEditorBrowserInteractions();
~MaterialEditorBrowserInteractions();
private:
//! AssetBrowserInteractionNotificationBus::Handler overrides...
void AddContextMenuActions(QWidget* caller, QMenu* menu, const AZStd::vector<AzToolsFramework::AssetBrowser::AssetBrowserEntry*>& entries) override;
void AddGenericContextMenuActions(QWidget* caller, QMenu* menu, const AzToolsFramework::AssetBrowser::AssetBrowserEntry* entry);
void AddContextMenuActionsForOtherSource(QWidget* caller, QMenu* menu, const AzToolsFramework::AssetBrowser::SourceAssetBrowserEntry* entry);
void AddContextMenuActionsForMaterialSource(QWidget* caller, QMenu* menu, const AzToolsFramework::AssetBrowser::SourceAssetBrowserEntry* entry);
void AddContextMenuActionsForMaterialTypeSource(QWidget* caller, QMenu* menu, const AzToolsFramework::AssetBrowser::SourceAssetBrowserEntry* entry);
void AddContextMenuActionsForFolder(QWidget* caller, QMenu* menu, const AzToolsFramework::AssetBrowser::FolderAssetBrowserEntry* entry);
void AddPerforceMenuActions(QWidget* caller, QMenu* menu, const AzToolsFramework::AssetBrowser::AssetBrowserEntry* entry);
void UpdateSourceControlActions(bool success, AzToolsFramework::SourceControlFileInfo info);
QWidget* m_caller = nullptr;
QAction* m_addAction = nullptr;
QAction* m_checkOutAction = nullptr;
QAction* m_undoCheckOutAction = nullptr;
QAction* m_getLatestAction = nullptr;
};
} // namespace MaterialEditor

@ -146,7 +146,7 @@ namespace MaterialEditor
bool MaterialEditorWindow::GetCreateDocumentParams(AZStd::string& openPath, AZStd::string& savePath)
{
CreateMaterialDialog createDialog(this);
CreateMaterialDialog createDialog(openPath.c_str(), this);
createDialog.adjustSize();
if (createDialog.exec() == QDialog::Accepted &&

@ -14,8 +14,6 @@ namespace MaterialEditor
SettingsWidget::SettingsWidget(QWidget* parent)
: AtomToolsFramework::InspectorWidget(parent)
{
m_documentSettings =
AZ::UserSettings::CreateFind<MaterialDocumentSettings>(AZ_CRC_CE("MaterialDocumentSettings"), AZ::UserSettings::CT_GLOBAL);
m_documentSystemSettings = AZ::UserSettings::CreateFind<AtomToolsFramework::AtomToolsDocumentSystemSettings>(
AZ_CRC_CE("AtomToolsDocumentSystemSettings"), AZ::UserSettings::CT_GLOBAL);
}
@ -29,23 +27,9 @@ namespace MaterialEditor
{
AddGroupsBegin();
AddDocumentSystemSettingsGroup();
AddDocumentSettingsGroup();
AddGroupsEnd();
}
void SettingsWidget::AddDocumentSettingsGroup()
{
const AZStd::string groupName = "documentSettings";
const AZStd::string groupDisplayName = "Document Settings";
const AZStd::string groupDescription = "Document Settings";
const AZ::Crc32 saveStateKey(AZStd::string::format("SettingsWidget::DocumentSettingsGroup"));
AddGroup(
groupName, groupDisplayName, groupDescription,
new AtomToolsFramework::InspectorPropertyGroupWidget(
m_documentSettings.get(), nullptr, m_documentSettings->TYPEINFO_Uuid(), this, this, saveStateKey));
}
void SettingsWidget::AddDocumentSystemSettingsGroup()
{
const AZStd::string groupName = "documentSystemSettings";
@ -56,7 +40,7 @@ namespace MaterialEditor
AddGroup(
groupName, groupDisplayName, groupDescription,
new AtomToolsFramework::InspectorPropertyGroupWidget(
m_documentSystemSettings.get(), nullptr, m_documentSystemSettings->TYPEINFO_Uuid(), this, this, saveStateKey));
m_documentSystemSettings.get(), nullptr, m_documentSystemSettings->TYPEINFO_Uuid(), nullptr, this, saveStateKey));
}
void SettingsWidget::Reset()
@ -64,21 +48,6 @@ namespace MaterialEditor
AtomToolsFramework::InspectorRequestBus::Handler::BusDisconnect();
AtomToolsFramework::InspectorWidget::Reset();
}
void SettingsWidget::BeforePropertyModified(AzToolsFramework::InstanceDataNode* pNode)
{
AZ_UNUSED(pNode);
}
void SettingsWidget::AfterPropertyModified(AzToolsFramework::InstanceDataNode* pNode)
{
AZ_UNUSED(pNode);
}
void SettingsWidget::SetPropertyEditingComplete(AzToolsFramework::InstanceDataNode* pNode)
{
AZ_UNUSED(pNode);
}
} // namespace MaterialEditor
//#include <Window/SettingsWidget/moc_SettingsWidget.cpp>

@ -12,7 +12,6 @@
#include <AtomToolsFramework/Document/AtomToolsDocumentSystemSettings.h>
#include <AtomToolsFramework/Inspector/InspectorWidget.h>
#include <AzToolsFramework/UI/PropertyEditor/PropertyEditorAPI_Internals.h>
#include <Document/MaterialDocumentSettings.h>
#endif
namespace MaterialEditor
@ -20,7 +19,6 @@ namespace MaterialEditor
//! Provides controls for viewing and editing settings.
class SettingsWidget
: public AtomToolsFramework::InspectorWidget
, private AzToolsFramework::IPropertyEditorNotify
{
Q_OBJECT
public:
@ -32,22 +30,11 @@ namespace MaterialEditor
void Populate();
private:
void AddDocumentSettingsGroup();
void AddDocumentSystemSettingsGroup();
// AtomToolsFramework::InspectorRequestBus::Handler overrides...
void Reset() override;
// AzToolsFramework::IPropertyEditorNotify overrides...
void BeforePropertyModified(AzToolsFramework::InstanceDataNode* pNode) override;
void AfterPropertyModified(AzToolsFramework::InstanceDataNode* pNode) override;
void SetPropertyEditingActive([[maybe_unused]] AzToolsFramework::InstanceDataNode* pNode) override {}
void SetPropertyEditingComplete(AzToolsFramework::InstanceDataNode* pNode) override;
void SealUndoStack() override {}
void RequestPropertyContextMenu(AzToolsFramework::InstanceDataNode*, const QPoint&) override {}
void PropertySelectionChanged(AzToolsFramework::InstanceDataNode*, bool) override {}
AZStd::intrusive_ptr<MaterialDocumentSettings> m_documentSettings;
AZStd::intrusive_ptr<AtomToolsFramework::AtomToolsDocumentSystemSettings> m_documentSystemSettings;
};
} // namespace MaterialEditor

@ -12,10 +12,8 @@ set(FILES
Source/MaterialEditorApplication.h
Source/Document/MaterialDocumentRequestBus.h
Source/Document/MaterialDocumentSettings.h
Source/Document/MaterialDocument.cpp
Source/Document/MaterialDocument.h
Source/Document/MaterialDocumentSettings.cpp
Source/Viewport/MaterialViewportModule.h
Source/Viewport/MaterialViewportModule.cpp
@ -49,8 +47,6 @@ set(FILES
Source/Viewport/MaterialViewportWidget.ui
Source/Window/MaterialEditorWindowSettings.h
Source/Window/MaterialEditorBrowserInteractions.h
Source/Window/MaterialEditorBrowserInteractions.cpp
Source/Window/MaterialEditorWindow.h
Source/Window/MaterialEditorWindow.cpp
Source/Window/MaterialEditorWindowSettings.cpp

@ -12,12 +12,16 @@
#include <Atom/RPI.Public/Material/Material.h>
#include <Atom/RPI.Reflect/Asset/AssetUtils.h>
#include <AtomToolsFramework/Document/AtomToolsDocumentSystemRequestBus.h>
#include <AtomToolsFramework/Util/Util.h>
#include <AzCore/RTTI/BehaviorContext.h>
#include <AzCore/Serialization/EditContext.h>
#include <AzCore/Serialization/SerializeContext.h>
#include <AzCore/Settings/SettingsRegistryMergeUtils.h>
#include <AzCore/Utils/Utils.h>
#include <AzToolsFramework/API/EditorAssetSystemAPI.h>
#include <AzToolsFramework/API/EditorPythonRunnerRequestsBus.h>
#include <AzToolsFramework/API/ToolsApplicationAPI.h>
#include <AzToolsFramework/AssetBrowser/AssetBrowserEntry.h>
#include <AzToolsFramework/UI/UICore/QWidgetSavedState.h>
#include <Document/ShaderManagementConsoleDocument.h>
#include <Document/ShaderManagementConsoleDocumentRequestBus.h>
@ -25,11 +29,13 @@
#include <ShaderManagementConsoleRequestBus.h>
#include <ShaderManagementConsole_Traits_Platform.h>
AZ_PUSH_DISABLE_WARNING(4251 4800, "-Wunknown-warning-option") // disable warnings spawned by QT
#include <QDesktopServices>
#include <QDialog>
#include <QFile>
#include <QFileDialog>
#include <QMenu>
#include <QMessageBox>
AZ_POP_DISABLE_WARNING
#include <QUrl>
void InitShaderManagementConsoleResources()
{
@ -135,9 +141,46 @@ namespace ShaderManagementConsole
void ShaderManagementConsoleApplication::CreateMainWindow()
{
m_assetBrowserInteractions.reset(aznew ShaderManagementConsoleBrowserInteractions);
m_window.reset(aznew ShaderManagementConsoleWindow);
m_window->show();
m_assetBrowserInteractions.reset(aznew AtomToolsFramework::AtomToolsAssetBrowserInteractions);
m_assetBrowserInteractions->RegisterContextMenuActions(
[](const AtomToolsFramework::AtomToolsAssetBrowserInteractions::AssetBrowserEntryVector& entries)
{
return entries.front()->GetEntryType() == AzToolsFramework::AssetBrowser::AssetBrowserEntry::AssetEntryType::Source;
},
[]([[maybe_unused]] QWidget* caller, QMenu* menu, const AtomToolsFramework::AtomToolsAssetBrowserInteractions::AssetBrowserEntryVector& entries)
{
if (AzFramework::StringFunc::Path::IsExtension(
entries.front()->GetFullPath().c_str(), AZ::RPI::ShaderSourceData::Extension))
{
menu->addAction("Generate Shader Variant List", [entries]()
{
const QString script =
"@engroot@/Gems/Atom/Tools/ShaderManagementConsole/Scripts/GenerateShaderVariantListForMaterials.py";
AZStd::vector<AZStd::string_view> pythonArgs{ entries.front()->GetFullPath() };
AzToolsFramework::EditorPythonRunnerRequestBus::Broadcast(
&AzToolsFramework::EditorPythonRunnerRequestBus::Events::ExecuteByFilenameWithArgs, script.toUtf8().constData(),
pythonArgs);
});
}
else if (AzFramework::StringFunc::Path::IsExtension(
entries.front()->GetFullPath().c_str(), AZ::RPI::ShaderVariantListSourceData::Extension))
{
menu->addAction(QObject::tr("Open"), [entries]()
{
AtomToolsFramework::AtomToolsDocumentSystemRequestBus::Broadcast(
&AtomToolsFramework::AtomToolsDocumentSystemRequestBus::Events::OpenDocument,
entries.front()->GetFullPath());
});
}
else
{
menu->addAction(QObject::tr("Open"), [entries]()
{
QDesktopServices::openUrl(QUrl::fromLocalFile(entries.front()->GetFullPath().c_str()));
});
}
});
}
void ShaderManagementConsoleApplication::DestroyMainWindow()

@ -9,11 +9,11 @@
#pragma once
#include <Atom/RPI.Reflect/Material/MaterialAsset.h>
#include <AtomToolsFramework/AssetBrowser/AtomToolsAssetBrowserInteractions.h>
#include <AtomToolsFramework/Document/AtomToolsDocumentApplication.h>
#include <AtomToolsFramework/Window/AtomToolsMainWindowFactoryRequestBus.h>
#include <AzToolsFramework/API/EditorWindowRequestBus.h>
#include <ShaderManagementConsoleRequestBus.h>
#include <Window/ShaderManagementConsoleBrowserInteractions.h>
#include <Window/ShaderManagementConsoleWindow.h>
namespace ShaderManagementConsole
@ -55,6 +55,6 @@ namespace ShaderManagementConsole
private:
AZStd::unique_ptr<ShaderManagementConsoleWindow> m_window;
AZStd::unique_ptr<ShaderManagementConsoleBrowserInteractions> m_assetBrowserInteractions;
AZStd::unique_ptr<AtomToolsFramework::AtomToolsAssetBrowserInteractions> m_assetBrowserInteractions;
};
} // namespace ShaderManagementConsole

@ -1,273 +0,0 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#include <Atom/RPI.Edit/Shader/ShaderVariantListSourceData.h>
#include <AtomToolsFramework/Document/AtomToolsDocumentSystemRequestBus.h>
#include <AtomToolsFramework/Util/Util.h>
#include <AzFramework/StringFunc/StringFunc.h>
#include <AzQtComponents/Utilities/DesktopUtilities.h>
#include <AzToolsFramework/API/EditorPythonRunnerRequestsBus.h>
#include <AzToolsFramework/AssetBrowser/AssetBrowserBus.h>
#include <AzToolsFramework/AssetBrowser/AssetBrowserEntry.h>
#include <AzToolsFramework/AssetBrowser/AssetSelectionModel.h>
#include <AzToolsFramework/Thumbnails/SourceControlThumbnail.h>
#include <Window/ShaderManagementConsoleBrowserInteractions.h>
#include <QApplication>
#include <QDesktopServices>
#include <QFileDialog>
#include <QInputDialog>
#include <QMenu>
#include <QMessageBox>
namespace ShaderManagementConsole
{
ShaderManagementConsoleBrowserInteractions::ShaderManagementConsoleBrowserInteractions()
{
using namespace AzToolsFramework::AssetBrowser;
AssetBrowserInteractionNotificationBus::Handler::BusConnect();
}
ShaderManagementConsoleBrowserInteractions::~ShaderManagementConsoleBrowserInteractions()
{
AssetBrowserInteractionNotificationBus::Handler::BusDisconnect();
}
AzToolsFramework::AssetBrowser::SourceFileDetails ShaderManagementConsoleBrowserInteractions::GetSourceFileDetails([[maybe_unused]] const char* fullSourceFileName)
{
return AzToolsFramework::AssetBrowser::SourceFileDetails();
}
void ShaderManagementConsoleBrowserInteractions::AddContextMenuActions(QWidget* caller, QMenu* menu, const AZStd::vector<AzToolsFramework::AssetBrowser::AssetBrowserEntry*>& entries)
{
AssetBrowserEntry* entry = entries.empty() ? nullptr : entries.front();
if (!entry)
{
return;
}
m_caller = caller;
QObject::connect(m_caller, &QObject::destroyed, [this]()
{
m_caller = nullptr;
});
if (entry->GetEntryType() == AssetBrowserEntry::AssetEntryType::Source)
{
const auto source = azalias_cast<const SourceAssetBrowserEntry*>(entry);
AddContextMenuActionsForOtherSource(caller, menu, source);
}
else if (entry->GetEntryType() == AssetBrowserEntry::AssetEntryType::Folder)
{
const auto folder = azalias_cast<const FolderAssetBrowserEntry*>(entry);
AddContextMenuActionsForFolder(caller, menu, folder);
}
}
void ShaderManagementConsoleBrowserInteractions::AddContextMenuActionsForOtherSource(QWidget* caller, QMenu* menu, const AzToolsFramework::AssetBrowser::SourceAssetBrowserEntry* entry)
{
menu->addAction("Open", [entry]()
{
if (AzFramework::StringFunc::Path::IsExtension(entry->GetFullPath().c_str(), AZ::RPI::ShaderVariantListSourceData::Extension))
{
AtomToolsFramework::AtomToolsDocumentSystemRequestBus::Broadcast(&AtomToolsFramework::AtomToolsDocumentSystemRequestBus::Events::OpenDocument, entry->GetFullPath().c_str());
}
else
{
QDesktopServices::openUrl(QUrl::fromLocalFile(entry->GetFullPath().c_str()));
}
});
menu->addAction("Duplicate...", [entry]()
{
const QFileInfo duplicateFileInfo(AtomToolsFramework::GetDuplicationFileInfo(entry->GetFullPath().c_str()));
if (!duplicateFileInfo.absoluteFilePath().isEmpty())
{
if (QFile::copy(entry->GetFullPath().c_str(), duplicateFileInfo.absoluteFilePath()))
{
QFile::setPermissions(duplicateFileInfo.absoluteFilePath(), QFile::ReadOther | QFile::WriteOther);
// Auto add file to source control
AzToolsFramework::SourceControlCommandBus::Broadcast(&AzToolsFramework::SourceControlCommandBus::Events::RequestEdit,
duplicateFileInfo.absoluteFilePath().toUtf8().constData(), true, [](bool, const AzToolsFramework::SourceControlFileInfo&) {});
}
}
});
menu->addAction(AzQtComponents::fileBrowserActionName(), [entry]()
{
AzQtComponents::ShowFileOnDesktop(entry->GetFullPath().c_str());
});
menu->addSeparator();
menu->addAction("Generate Shader Variant List", [entry]() {
const QString script = "@engroot@/Gems/Atom/Tools/ShaderManagementConsole/Scripts/GenerateShaderVariantListForMaterials.py";
AZStd::vector<AZStd::string_view> pythonArgs{ entry->GetFullPath() };
AzToolsFramework::EditorPythonRunnerRequestBus::Broadcast(&AzToolsFramework::EditorPythonRunnerRequestBus::Events::ExecuteByFilenameWithArgs, script.toUtf8().constData(), pythonArgs);
});
menu->addAction("Run Python on Asset...", [entry]()
{
const QString script = QFileDialog::getOpenFileName(nullptr, "Run Script", QString(), QString("*.py"));
if (!script.isEmpty())
{
AZStd::vector<AZStd::string_view> pythonArgs { entry->GetFullPath() };
AzToolsFramework::EditorPythonRunnerRequestBus::Broadcast(&AzToolsFramework::EditorPythonRunnerRequestBus::Events::ExecuteByFilenameWithArgs, script.toUtf8().constData(), pythonArgs);
}
});
AddPerforceMenuActions(caller, menu, entry);
}
void ShaderManagementConsoleBrowserInteractions::AddContextMenuActionsForFolder(QWidget* caller, QMenu* menu, const AzToolsFramework::AssetBrowser::FolderAssetBrowserEntry* entry)
{
menu->addAction(AzQtComponents::fileBrowserActionName(), [entry]()
{
AzQtComponents::ShowFileOnDesktop(entry->GetFullPath().c_str());
});
QAction* createFolderAction = menu->addAction(QObject::tr("Create new sub folder..."));
QObject::connect(createFolderAction, &QAction::triggered, caller, [caller, entry]()
{
bool ok;
QString newFolderName = QInputDialog::getText(caller, "Enter new folder name", "name:", QLineEdit::Normal, "NewFolder", &ok);
if (ok)
{
if (newFolderName.isEmpty())
{
QMessageBox msgBox(QMessageBox::Icon::Critical, "Error", "Folder name can't be empty", QMessageBox::Ok, caller);
msgBox.exec();
}
else
{
AZStd::string newFolderPath;
AzFramework::StringFunc::Path::Join(entry->GetFullPath().c_str(), newFolderName.toUtf8().constData(), newFolderPath);
QDir dir(newFolderPath.c_str());
if (dir.exists())
{
QMessageBox::critical(caller, "Error", "Folder with this name already exists");
return;
}
auto result = dir.mkdir(newFolderPath.c_str());
if (!result)
{
AZ_Error("ShaderManagementConsoleBrowser", false, "Failed to make new folder");
return;
}
}
}
});
}
void ShaderManagementConsoleBrowserInteractions::AddPerforceMenuActions([[maybe_unused]] QWidget* caller, QMenu* menu, const AzToolsFramework::AssetBrowser::AssetBrowserEntry* entry)
{
using namespace AzToolsFramework;
bool isActive = false;
SourceControlConnectionRequestBus::BroadcastResult(isActive, &SourceControlConnectionRequests::IsActive);
if (isActive)
{
menu->addSeparator();
AZStd::string path = entry->GetFullPath();
AzFramework::StringFunc::Path::Normalize(path);
QMenu* sourceControlMenu = menu->addMenu("Source Control");
// Update the enabled state of source control menu actions only if menu is shown
QMenu::connect(sourceControlMenu, &QMenu::aboutToShow, [this, path]()
{
SourceControlCommandBus::Broadcast(&SourceControlCommandBus::Events::GetFileInfo, path.c_str(),
[this](bool success, const SourceControlFileInfo& info) { UpdateSourceControlActions(success, info); });
});
// add get latest action
m_getLatestAction = sourceControlMenu->addAction("Get Latest", [path]()
{
SourceControlCommandBus::Broadcast(&SourceControlCommandBus::Events::RequestLatest, path.c_str(),
[](bool, const SourceControlFileInfo&) {});
});
QObject::connect(m_getLatestAction, &QObject::destroyed, [this]()
{
m_getLatestAction = nullptr;
});
m_getLatestAction->setEnabled(false);
// add add action
m_addAction = sourceControlMenu->addAction("Add", [path]()
{
SourceControlCommandBus::Broadcast(&SourceControlCommandBus::Events::RequestEdit, path.c_str(), true,
[path](bool, const SourceControlFileInfo&)
{
SourceControlThumbnailRequestBus::Broadcast(&SourceControlThumbnailRequests::FileStatusChanged, path.c_str());
});
});
QObject::connect(m_addAction, &QObject::destroyed, [this]()
{
m_addAction = nullptr;
});
m_addAction->setEnabled(false);
// add checkout action
m_checkOutAction = sourceControlMenu->addAction("Check Out", [path]()
{
SourceControlCommandBus::Broadcast(&SourceControlCommandBus::Events::RequestEdit, path.c_str(), true,
[path](bool, const SourceControlFileInfo&)
{
SourceControlThumbnailRequestBus::Broadcast(&SourceControlThumbnailRequests::FileStatusChanged, path.c_str());
});
});
QObject::connect(m_checkOutAction, &QObject::destroyed, [this]()
{
m_checkOutAction = nullptr;
});
m_checkOutAction->setEnabled(false);
// add undo checkout action
m_undoCheckOutAction = sourceControlMenu->addAction("Undo Check Out", [path]()
{
SourceControlCommandBus::Broadcast(&SourceControlCommandBus::Events::RequestRevert, path.c_str(),
[path](bool, const SourceControlFileInfo&)
{
SourceControlThumbnailRequestBus::Broadcast(&SourceControlThumbnailRequests::FileStatusChanged, path.c_str());
});
});
QObject::connect(m_undoCheckOutAction, &QObject::destroyed, [this]()
{
m_undoCheckOutAction = nullptr;
});
m_undoCheckOutAction->setEnabled(false);
}
}
void ShaderManagementConsoleBrowserInteractions::UpdateSourceControlActions(bool success, AzToolsFramework::SourceControlFileInfo info)
{
if (!success && m_caller)
{
QMessageBox::critical(m_caller, "Error", "Source control operation failed.");
}
if (m_getLatestAction)
{
m_getLatestAction->setEnabled(info.IsManaged() && info.HasFlag(AzToolsFramework::SCF_OutOfDate));
}
if (m_addAction)
{
m_addAction->setEnabled(!info.IsManaged());
}
if (m_checkOutAction)
{
m_checkOutAction->setEnabled(info.IsManaged() && info.IsReadOnly() && !info.IsLockedByOther());
}
if (m_undoCheckOutAction)
{
m_undoCheckOutAction->setEnabled(info.IsManaged() && !info.IsReadOnly());
}
}
} // namespace ShaderManagementConsole

@ -1,58 +0,0 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#pragma once
#include <AzToolsFramework/AssetBrowser/AssetBrowserBus.h>
#include <AzToolsFramework/SourceControl/SourceControlAPI.h>
class QWidget;
class QMenu;
class QAction;
namespace AzToolsFramework
{
namespace AssetBrowser
{
class AssetBrowserEntry;
class SourceAssetBrowserEntry;
class FolderAssetBrowserEntry;
}
}
namespace ShaderManagementConsole
{
class ShaderManagementConsoleBrowserInteractions
: public AzToolsFramework::AssetBrowser::AssetBrowserInteractionNotificationBus::Handler
{
public:
AZ_CLASS_ALLOCATOR(ShaderManagementConsoleBrowserInteractions, AZ::SystemAllocator, 0);
ShaderManagementConsoleBrowserInteractions();
~ShaderManagementConsoleBrowserInteractions();
private:
////////////////////////////////////////////////////////////////////////
// AssetBrowserInteractionNotificationBus::Handler implementation
AzToolsFramework::AssetBrowser::SourceFileDetails GetSourceFileDetails(const char* fullSourceFileName) override;
void AddContextMenuActions(QWidget* caller, QMenu* menu, const AZStd::vector<AzToolsFramework::AssetBrowser::AssetBrowserEntry*>& entries) override;
////////////////////////////////////////////////////////////////////////
void AddContextMenuActionsForOtherSource(QWidget* caller, QMenu* menu, const AzToolsFramework::AssetBrowser::SourceAssetBrowserEntry* entry);
void AddContextMenuActionsForFolder(QWidget* caller, QMenu* menu, const AzToolsFramework::AssetBrowser::FolderAssetBrowserEntry* entry);
void AddPerforceMenuActions(QWidget* caller, QMenu* menu, const AzToolsFramework::AssetBrowser::AssetBrowserEntry* entry);
void UpdateSourceControlActions(bool success, AzToolsFramework::SourceControlFileInfo info);
QWidget* m_caller = nullptr;
QAction* m_addAction = nullptr;
QAction* m_checkOutAction = nullptr;
QAction* m_undoCheckOutAction = nullptr;
QAction* m_getLatestAction = nullptr;
};
} // namespace ShaderManagementConsole

@ -11,8 +11,6 @@ set(FILES
Source/Document/ShaderManagementConsoleDocument.cpp
Source/Document/ShaderManagementConsoleDocument.h
Source/Window/ShaderManagementConsoleBrowserInteractions.h
Source/Window/ShaderManagementConsoleBrowserInteractions.cpp
Source/Window/ShaderManagementConsoleWindow.h
Source/Window/ShaderManagementConsoleWindow.cpp
Source/Window/ShaderManagementConsole.qrc

Loading…
Cancel
Save