Merge branch 'main' into hultonha_LYN-2315_camera-phase-2

This commit is contained in:
hultonha
2021-04-29 14:32:57 +01:00
2198 changed files with 2937 additions and 19198 deletions
@@ -853,7 +853,7 @@ const char* ScriptSystemComponent::GetGroup() const
const char* AZ::ScriptSystemComponent::GetBrowserIcon() const
{
return "Editor/Icons/Components/LuaScript.svg";
return "Icons/Components/LuaScript.svg";
}
AZ::Uuid AZ::ScriptSystemComponent::GetComponentTypeId() const
@@ -104,13 +104,12 @@ namespace AZ
auto serializer = context.GetRegistrationContext()->GetSerializerForType(classData.m_typeId);
if (serializer)
{
if (storeTypeId == StoreTypeId::Yes)
ResultCode result = serializer->Store(node, object, defaultObject, classData.m_typeId, context);
if (storeTypeId == StoreTypeId::Yes && result.GetProcessing() != Processing::Halted)
{
return context.Report(Tasks::WriteValue, Outcomes::Catastrophic,
"Unable to store type information in a JSON Serializer primitive.");
result.Combine(InsertTypeId(node, classData, context));
}
return serializer->Store(node, object, defaultObject, classData.m_typeId, context);
return result;
}
if (classData.m_azRtti && (classData.m_azRtti->GetTypeTraits() & AZ::TypeTraits::is_enum) == AZ::TypeTraits::is_enum)
@@ -128,13 +127,12 @@ namespace AZ
serializer = context.GetRegistrationContext()->GetSerializerForType(classData.m_azRtti->GetGenericTypeId());
if (serializer)
{
if (storeTypeId == StoreTypeId::Yes)
ResultCode result = serializer->Store(node, object, defaultObject, classData.m_typeId, context);
if (storeTypeId == StoreTypeId::Yes && result.GetProcessing() != Processing::Halted)
{
return context.Report(Tasks::WriteValue, Outcomes::Catastrophic,
"Unable to store type information in a JSON Serializer primitive.");
result.Combine(InsertTypeId(node, classData, context));
}
return serializer->Store(node, object, defaultObject, classData.m_typeId, context);
return result;
}
}
@@ -149,6 +147,7 @@ namespace AZ
ResultCode result(Tasks::WriteValue);
if (storeTypeId == StoreTypeId::Yes)
{
// Not using InsertTypeId here to avoid needing to create the temporary value and swap it in that call.
node.AddMember(rapidjson::StringRef(JsonSerialization::TypeIdFieldIdentifier),
StoreTypeName(classData, context), context.GetJsonAllocator());
result = ResultCode(Tasks::WriteValue, Outcomes::Success);
@@ -569,6 +568,31 @@ namespace AZ
}
}
JsonSerializationResult::ResultCode JsonSerializer::InsertTypeId(
rapidjson::Value& output, const SerializeContext::ClassData& classData, JsonSerializerContext& context)
{
using namespace JsonSerializationResult;
if (output.IsObject())
{
rapidjson::Value insertedObject(rapidjson::kObjectType);
insertedObject.AddMember(
rapidjson::StringRef(JsonSerialization::TypeIdFieldIdentifier), StoreTypeName(classData, context),
context.GetJsonAllocator());
for (auto& element : output.GetObject())
{
insertedObject.AddMember(AZStd::move(element.name), AZStd::move(element.value), context.GetJsonAllocator());
}
output = AZStd::move(insertedObject);
return ResultCode(Tasks::WriteValue, Outcomes::Success);
}
else
{
return context.Report(Tasks::WriteValue, Outcomes::Catastrophic, "Only able to store type information in a JSON Object.");
}
}
rapidjson::Value JsonSerializer::GetExplicitDefault()
{
return rapidjson::Value(rapidjson::kObjectType);
@@ -80,6 +80,9 @@ namespace AZ
static JsonSerializationResult::ResultCode StoreTypeName(rapidjson::Value& output,
const Uuid& typeId, JsonSerializerContext& context);
static JsonSerializationResult::ResultCode InsertTypeId(
rapidjson::Value& output, const SerializeContext::ClassData& classData, JsonSerializerContext& context);
static rapidjson::Value GetExplicitDefault();
};
} // namespace AZ
@@ -654,7 +654,6 @@ namespace AZ::SettingsRegistryMergeUtils
if (registry.Get(engineRootPath, FilePathKey_EngineRootFolder))
{
AZ::IO::FixedMaxPath mergePath{ AZStd::move(engineRootPath) };
mergePath /= "Engine";
mergePath /= SettingsRegistryInterface::RegistryFolder;
registry.MergeSettingsFolder(mergePath.Native(), specializations, platform, "", scratchBuffer);
}
@@ -449,6 +449,46 @@ namespace JsonSerializationTests
}
TEST_F(JsonSerializationTests, Load_PrimitiveForInheritedClass_LoadsCorrectClass)
{
using namespace AZ::JsonSerializationResult;
using namespace ::testing;
AZStd::string json = AZStd::string::format(R"(
{
"%s": "SimpleInheritence",
"base_var": -88.0,
"var1": 88,
"var2": 42
})",
AZ::JsonSerialization::TypeIdFieldIdentifier);
m_jsonDocument->Parse(json.c_str());
SimpleInheritence::Reflect(m_serializeContext, true);
m_serializeContext->RegisterGenericType<AZStd::unique_ptr<BaseClass>>();
m_jsonRegistrationContext->Serializer<JsonSerializerMock>()->HandlesType<SimpleInheritence>();
JsonSerializerMock* mock =
reinterpret_cast<JsonSerializerMock*>(m_jsonRegistrationContext->GetSerializerForType(azrtti_typeid<SimpleInheritence>()));
EXPECT_CALL(*mock, Load(_, _, _, _))
.Times(Exactly(1))
.WillRepeatedly(Return(Result(m_deserializationSettings->m_reporting, "Test", Tasks::ReadField, Outcomes::Success, "")));
AZStd::unique_ptr<BaseClass> instance;
ResultCode result = AZ::JsonSerialization::Load(instance, *m_jsonDocument, *m_deserializationSettings);
EXPECT_NE(Processing::Halted, result.GetProcessing());
EXPECT_EQ(azrtti_typeid<SimpleInheritence>(), azrtti_typeid(*instance));
m_serializeContext->EnableRemoveReflection();
SimpleInheritence::Reflect(m_serializeContext, true);
m_serializeContext->DisableRemoveReflection();
m_jsonRegistrationContext->EnableRemoveReflection();
m_serializeContext->RegisterGenericType<AZStd::unique_ptr<BaseClass>>();
m_jsonRegistrationContext->Serializer<JsonSerializerMock>()->HandlesType<SimpleInheritence>();
m_jsonRegistrationContext->DisableRemoveReflection();
}
TEST_F(JsonSerializationTests, Store_TemplatedClassWithRegisteredHandler_StoreOnHandlerCalled)
{
using namespace AZ::JsonSerializationResult;
@@ -474,6 +514,52 @@ namespace JsonSerializationTests
m_jsonRegistrationContext->DisableRemoveReflection();
}
TEST_F(JsonSerializationTests, Store_PrimitiveForInheritedClass_StoreSucceedsAndTypeIdIsAdded)
{
using namespace AZ::JsonSerializationResult;
using namespace ::testing;
SimpleInheritence::Reflect(m_serializeContext, true);
m_serializeContext->RegisterGenericType<AZStd::unique_ptr<BaseClass>>();
m_jsonRegistrationContext->Serializer<JsonSerializerMock>()->HandlesType<SimpleInheritence>();
JsonSerializerMock* mock =
reinterpret_cast<JsonSerializerMock*>(m_jsonRegistrationContext->GetSerializerForType(azrtti_typeid<SimpleInheritence>()));
EXPECT_CALL(*mock, Store(_, _, _, _, _))
.Times(Exactly(1))
.WillRepeatedly(Invoke([](rapidjson::Value& output, const void*, const void*, const AZ::Uuid&, AZ::JsonSerializerContext& context)
{
// Insert some values to allow verification later on.
output.SetObject();
output.AddMember("base_var", -88.0, context.GetJsonAllocator());
output.AddMember("var1", 88, context.GetJsonAllocator());
output.AddMember("var2", 42, context.GetJsonAllocator());
return context.Report(Tasks::WriteValue, Outcomes::Success, "");
}));
AZStd::unique_ptr<BaseClass> instance{ aznew SimpleInheritence() };
ResultCode result = AZ::JsonSerialization::Store(*m_jsonDocument, m_jsonDocument->GetAllocator(), instance, *m_serializationSettings);
EXPECT_NE(Processing::Halted, result.GetProcessing());
AZStd::string compare = AZStd::string::format(R"(
{
"%s": "SimpleInheritence",
"base_var": -88.0,
"var1": 88,
"var2": 42
})",
AZ::JsonSerialization::TypeIdFieldIdentifier);
Expect_DocStrEq(compare.c_str());
m_serializeContext->EnableRemoveReflection();
m_serializeContext->RegisterGenericType<AZStd::unique_ptr<BaseClass>>();
SimpleInheritence::Reflect(m_serializeContext, true);
m_serializeContext->DisableRemoveReflection();
m_jsonRegistrationContext->EnableRemoveReflection();
m_jsonRegistrationContext->Serializer<JsonSerializerMock>()->HandlesType<SimpleInheritence>();
m_jsonRegistrationContext->DisableRemoveReflection();
}
TEST_F(JsonSerializationTests, Store_StoreWithNullPtr_ReturnsCatastrophic)
{
using namespace AZ::JsonSerializationResult;
@@ -809,7 +809,7 @@ namespace AzFramework
#if defined(AZ_ENABLE_TRACING)
if (message.m_assetType == AZ::Data::s_invalidAssetType)
{
AZ_TracePrintf("AssetCatalog", "Registering asset \"%s\" via AssetSystem message, but type is not set.", relativePath.c_str());
AZ_TracePrintf("AssetCatalog", "Registering asset \"%s\" via AssetSystem message, but type is not set.\n", relativePath.c_str());
}
#endif
@@ -12,11 +12,13 @@
#include <AzCore/Serialization/Utils.h>
#include <AzCore/IO/FileIO.h>
#include <AzCore/IO/Path/Path.h>
#include <AzCore/IO/SystemFile.h>
#include <AzCore/std/algorithm.h>
#include <AzCore/std/string/wildcard.h>
#include <AzCore/std/string/regex.h>
#include <AzCore/std/string/conversions.h>
#include <AzCore/Utils/Utils.h>
#include <AzCore/XML/rapidxml.h>
#include <AzFramework/API/ApplicationAPI.h>
#include <AzFramework/Asset/FileTagAsset.h>
@@ -31,7 +33,7 @@ namespace AzFramework
const char* ExcludeFileName = "exclude";
const char* IncludeFileName = "include";
const char* FileTags[] = { "ignore", "error", "productdependency", "editoronly", "shader" };
const char EngineName[] = "Engine";
constexpr AZ::IO::PathView EngineAssetSourceRelPath = "Assets/Engine";
void LowerCaseFileTags(AZStd::vector<AZStd::string>& fileTags)
{
@@ -107,7 +109,7 @@ namespace AzFramework
}
AZ::Outcome<AZStd::string, AZStd::string> FileTagManager::AddTagsInternal(AZStd::string filePath, FileTagType fileTagType, AZStd::vector<AZStd::string> fileTags, AzFramework::FileTag::FilePatternType filePatternType)
{
{
if (!NormalizeFileAndLowerCaseTags(filePath, filePatternType, fileTags))
{
return AZ::Failure(AZStd::string::format("Unable to normalize file (%s). Unable to remove the file.\n", filePath.c_str()));
@@ -243,11 +245,10 @@ namespace AzFramework
AZStd::string FileTagQueryManager::GetDefaultFileTagFilePath(FileTagType fileTagType)
{
AZStd::string destinationFilePath;
const char* engineRoot = nullptr;
AzFramework::ApplicationRequests::Bus::BroadcastResult(engineRoot, &AzFramework::ApplicationRequests::GetEngineRoot);
AzFramework::StringFunc::Path::ConstructFull(engineRoot, EngineName, fileTagType == FileTagType::Exclude ? ExcludeFileName : IncludeFileName, AzFramework::FileTag::FileTagAsset::Extension(), destinationFilePath, true);
return destinationFilePath;
auto destinationFilePath = AZ::IO::FixedMaxPath(AZ::Utils::GetEnginePath()) / EngineAssetSourceRelPath;
destinationFilePath /= fileTagType == FileTagType::Exclude ? ExcludeFileName : IncludeFileName;
destinationFilePath.ReplaceExtension(AzFramework::FileTag::FileTagAsset::Extension());
return destinationFilePath.String();
}
bool FileTagQueryManager::Load(const AZStd::string& filePath)
@@ -44,8 +44,8 @@ namespace AzFramework
"Network Binding", "The Network Binding component marks an entity as able to be replicated across the network")
->ClassElement(AZ::Edit::ClassElements::EditorData, "")
->Attribute(AZ::Edit::Attributes::Category, "Networking")
->Attribute(AZ::Edit::Attributes::Icon, "Editor/Icons/Components/NetBinding.svg")
->Attribute(AZ::Edit::Attributes::ViewportIcon, "Editor/Icons/Components/Viewport/NetBinding.png")
->Attribute(AZ::Edit::Attributes::Icon, "Icons/Components/NetBinding.svg")
->Attribute(AZ::Edit::Attributes::ViewportIcon, "Icons/Components/Viewport/NetBinding.png")
->Attribute(AZ::Edit::Attributes::HelpPageURL, "https://docs.aws.amazon.com/lumberyard/latest/userguide/component-network-binding.html")
->Attribute(AZ::Edit::Attributes::AppearsInAddComponentMenu, AZ_CRC("Game", 0x232b318c));
}
@@ -81,7 +81,7 @@ namespace AzFramework
const char* SpawnableAssetHandler::GetBrowserIcon() const
{
return "Editor/Icons/Components/Viewport/EntityInSlice.png";
return "Icons/Components/Viewport/EntityInSlice.png";
}
void SpawnableAssetHandler::GetAssetTypeExtensions(AZStd::vector<AZStd::string>& extensions)
@@ -250,9 +250,9 @@ namespace AzQtComponents
// STYLESHEETIMAGES:something.txt
// UI:blah/blah.png
// EDITOR:blah/something.txt
QDir::addSearchPath("STYLESHEETIMAGES", appPath.filePath("Editor/Styles/StyleSheetImages"));
QDir::addSearchPath("UI", appPath.filePath("Editor/UI"));
QDir::addSearchPath("EDITOR", appPath.filePath("Editor"));
QDir::addSearchPath("STYLESHEETIMAGES", appPath.filePath("Assets/Editor/Styles/StyleSheetImages"));
QDir::addSearchPath("UI", appPath.filePath("Assets/Editor/UI"));
QDir::addSearchPath("EDITOR", appPath.filePath("Assets/Editor"));
}
}
@@ -388,8 +388,8 @@
<file>img/line.png</file>
</qresource>
<qresource>
<file alias="Editor/Style/EditorStylesheetVariables_Dark.json">../../../../Sandbox/Editor/Style/EditorStylesheetVariables_Dark.json</file>
<file alias="Editor/Style/NewEditorStylesheet.qss">../../../../Sandbox/Editor/Style/NewEditorStylesheet.qss</file>
<file alias="Assets/Editor/Style/EditorStylesheetVariables_Dark.json">../../../../Sandbox/Editor/Style/EditorStylesheetVariables_Dark.json</file>
<file alias="Assets/Editor/Style/NewEditorStylesheet.qss">../../../../Sandbox/Editor/Style/NewEditorStylesheet.qss</file>
</qresource>
<qresource prefix="/Cards">
<file>img/UI20/Cards/point_hand.png</file>
@@ -216,14 +216,9 @@ namespace AzToolsFramework::AssetUtils
constexpr const char* AssetProcessorGamePlatformConfigFileName = "AssetProcessorGamePlatformConfig.ini";
constexpr const char* AssetProcessorGamePlatformConfigSetreg = "AssetProcessorGamePlatformConfig.setreg";
AZStd::vector<AZ::IO::Path> configFiles;
AZ::IO::Path configRoot(engineRoot);
AZ::IO::Path rootConfigFile = configRoot / AssetProcessorPlatformConfigFileName;
configFiles.push_back(rootConfigFile);
// Add a file entry for the Engine Root AssetProcessor setreg file
rootConfigFile = configRoot / AssetProcessorPlatformConfigSetreg;
configFiles.push_back(rootConfigFile);
// Add the AssetProcessorPlatformConfig setreg file at the engine root
configFiles.push_back(AZ::IO::Path(engineRoot) / AssetProcessorPlatformConfigSetreg);
if (addPlatformConfigs)
{
@@ -200,67 +200,67 @@ namespace AzToolsFramework
{
if (AzFramework::StringFunc::Equal(extension.c_str(), ".abc"))
{
return SourceFileDetails("Editor/Icons/AssetBrowser/ABC_16.svg");
return SourceFileDetails("Icons/AssetBrowser/ABC_16.svg");
}
if (AzFramework::StringFunc::Equal(extension.c_str(), ".bnk"))
{
return SourceFileDetails("Editor/Icons/AssetBrowser/Audio_16.svg");
return SourceFileDetails("Icons/AssetBrowser/Audio_16.svg");
}
if (AzFramework::StringFunc::Equal(extension.c_str(), ".cgf"))
{
return SourceFileDetails("Editor/Icons/AssetBrowser/LegacyMesh_16.svg");
return SourceFileDetails("Icons/AssetBrowser/LegacyMesh_16.svg");
}
if (AzFramework::StringFunc::Equal(extension.c_str(), ".font"))
{
return SourceFileDetails("Editor/Icons/AssetBrowser/Font_16.svg");
return SourceFileDetails("Icons/AssetBrowser/Font_16.svg");
}
if (AzFramework::StringFunc::Equal(extension.c_str(), ".fontfamily"))
{
return SourceFileDetails("Editor/Icons/AssetBrowser/Font_16.svg");
return SourceFileDetails("Icons/AssetBrowser/Font_16.svg");
}
if (AzFramework::StringFunc::Equal(extension.c_str(), ".i_caf"))
{
return SourceFileDetails("Editor/Icons/AssetBrowser/LegacyAnimation_16.svg");
return SourceFileDetails("Icons/AssetBrowser/LegacyAnimation_16.svg");
}
if (AzFramework::StringFunc::Equal(extension.c_str(), ".inputbindings"))
{
return SourceFileDetails("Editor/Icons/AssetBrowser/InputBindings_16.svg");
return SourceFileDetails("Icons/AssetBrowser/InputBindings_16.svg");
}
if (AzFramework::StringFunc::Equal(extension.c_str(), ".lua"))
{
return SourceFileDetails("Editor/Icons/AssetBrowser/Lua_16.svg");
return SourceFileDetails("Icons/AssetBrowser/Lua_16.svg");
}
if (AzFramework::StringFunc::Equal(extension.c_str(), ".mtl"))
{
return SourceFileDetails("Editor/Icons/AssetBrowser/Material_16.svg");
return SourceFileDetails("Icons/AssetBrowser/Material_16.svg");
}
if (AzFramework::StringFunc::Equal(extension.c_str(), AzToolsFramework::SliceUtilities::GetSliceFileExtension().c_str()))
{
return SourceFileDetails("Editor/Icons/AssetBrowser/Slice_16.svg");
return SourceFileDetails("Icons/AssetBrowser/Slice_16.svg");
}
if (AzFramework::StringFunc::Equal(extension.c_str(), ".skin"))
{
return SourceFileDetails("Editor/Icons/AssetBrowser/LegacySkin_16.svg");
return SourceFileDetails("Icons/AssetBrowser/LegacySkin_16.svg");
}
if (AzFramework::StringFunc::Equal(extension.c_str(), ".ttf"))
{
return SourceFileDetails("Editor/Icons/AssetBrowser/Font_16.svg");
return SourceFileDetails("Icons/AssetBrowser/Font_16.svg");
}
if (AzFramework::StringFunc::Equal(extension.c_str(), ".xml"))
{
return SourceFileDetails("Editor/Icons/AssetBrowser/XML_16.svg");
return SourceFileDetails("Icons/AssetBrowser/XML_16.svg");
}
@@ -272,7 +272,7 @@ namespace AzToolsFramework
const char* sourceFormatExtension = sourceFormats[sourceImageFormatIndex];
if (AzFramework::StringFunc::Equal(extension.c_str(), sourceFormatExtension))
{
return SourceFileDetails("Editor/Icons/AssetBrowser/Image_16.svg");
return SourceFileDetails("Icons/AssetBrowser/Image_16.svg");
}
}
}
@@ -52,17 +52,16 @@ namespace AzToolsFramework
return AssetEntryType::Root;
}
void RootAssetBrowserEntry::Update(const char* devPath)
void RootAssetBrowserEntry::Update(const char* enginePath)
{
RemoveChildren();
EntryCache::GetInstance()->Clear();
m_scanFolderOutputPrefixMap.clear();
m_devPath = devPath;
m_enginePath = enginePath;
// there is no "Gems" scan folder registered in db, create one manually
auto gemFolder = aznew FolderAssetBrowserEntry();
gemFolder->m_name = m_devPath + AZ_CORRECT_DATABASE_SEPARATOR + GEMS_FOLDER_NAME;
gemFolder->m_name = m_enginePath + AZ_CORRECT_DATABASE_SEPARATOR + GEMS_FOLDER_NAME;
gemFolder->m_displayName = GEMS_FOLDER_NAME;
gemFolder->m_isGemsFolder = true;
AddChild(gemFolder);
@@ -90,11 +89,6 @@ namespace AzToolsFramework
scanFolder->m_displayName = QString::fromUtf8(scanFolderDatabaseEntry.m_displayName.c_str());
EntryCache::GetInstance()->m_scanFolderIdMap[scanFolderDatabaseEntry.m_scanFolderID] = scanFolder;
}
if (!scanFolderDatabaseEntry.m_outputPrefix.empty())
{
m_scanFolderOutputPrefixMap[scanFolderDatabaseEntry.m_scanFolderID] = scanFolderDatabaseEntry.m_outputPrefix;
}
}
void RootAssetBrowserEntry::AddFile(const AssetDatabase::FileDatabaseEntry& fileDatabaseEntry)
@@ -132,7 +126,7 @@ namespace AzToolsFramework
return;
}
const char* filePath = GetScanFolderOutputAdjustedPath(fileDatabaseEntry, scanFolder);
const char* filePath = fileDatabaseEntry.m_fileName.c_str();
AssetBrowserEntry* file;
// file can be either folder or actual file
@@ -441,33 +435,5 @@ namespace AzToolsFramework
{
return MAKE_TKEY(ThumbnailKey);
}
const char* RootAssetBrowserEntry::GetScanFolderOutputAdjustedPath(const AssetDatabase::FileDatabaseEntry& fileDatabaseEntry, const AssetBrowserEntry* scanFolder)
{
Q_UNUSED(scanFolder);
const char* filePath = fileDatabaseEntry.m_fileName.c_str();
// adjust for output prefixes on scan folders (i.e. "editor")
auto itScanFolderOutputPrefix = m_scanFolderOutputPrefixMap.find(fileDatabaseEntry.m_scanFolderPK);
if (itScanFolderOutputPrefix != m_scanFolderOutputPrefixMap.end())
{
const AZStd::string& outputPrefix = itScanFolderOutputPrefix->second;
// Check if the input path starts with the output prefix.
// If it doesn't, something probably went seriously wrong,
// or someone is calling this function with an absolute path.
bool pathStartsWithPrefix = ((strncmp(filePath, outputPrefix.c_str(), outputPrefix.length()) == 0) && (fileDatabaseEntry.m_fileName.length() > (outputPrefix.length() + 1)));
AZ_Warning("Asset Browser", pathStartsWithPrefix, "Entry %s reported as under a ScanFolder (%s) with an 'output=%s', but the new entry does not begin with the output prefix! RootAssetBrowserEntry::GetScanFolderOutputAdjustedPath expects relative paths, not absolute; treating the input path as if it does not contain the ScanFolder output prefix.", filePath, scanFolder->m_name.c_str(), outputPrefix.c_str());
if (pathStartsWithPrefix)
{
// move the beginning ahead by the output prefix plus the separator
filePath += (outputPrefix.length() + 1);
}
}
return filePath;
}
} // namespace AssetBrowser
} // namespace AzToolsFramework
@@ -60,8 +60,8 @@ namespace AzToolsFramework
AssetEntryType GetEntryType() const override;
//! Update root node to new dev location
void Update(const char* devPath);
//! Update root node to new engine location
void Update(const char* enginePath);
void AddScanFolder(const AssetDatabase::ScanFolderDatabaseEntry& scanFolderDatabaseEntry);
void AddFile(const AssetDatabase::FileDatabaseEntry& fileDatabaseEntry);
@@ -82,15 +82,12 @@ namespace AzToolsFramework
private:
AZ_DISABLE_COPY_MOVE(RootAssetBrowserEntry);
AZStd::string m_devPath;
AZStd::unordered_map<AZ::s64, AZStd::string> m_scanFolderOutputPrefixMap;
AZStd::string m_enginePath;
//! Create folder entry child
FolderAssetBrowserEntry* CreateFolder(const char* folderName, AssetBrowserEntry* parent);
//! Recursively create folder structure leading to relative path from parent
AssetBrowserEntry* CreateFolders(const char* relativePath, AssetBrowserEntry* parent);
//! Get the path for the fileDatabaseEntry, offset by the output prefix for the scan folder ancestor, if it's been specified and if it's appropriate
const char* GetScanFolderOutputAdjustedPath(const AssetDatabase::FileDatabaseEntry& fileDatabaseEntry, const AssetBrowserEntry* scanFolder);
bool m_isInitialUpdate = false;
};
@@ -50,8 +50,8 @@ namespace AzToolsFramework
//////////////////////////////////////////////////////////////////////////
// FolderThumbnail
//////////////////////////////////////////////////////////////////////////
static constexpr const char* FolderIconPath = "Editor/Icons/AssetBrowser/Folder_16.svg";
static constexpr const char* GemIconPath = "Editor/Icons/AssetBrowser/GemFolder_16.svg";
static constexpr const char* FolderIconPath = "Icons/AssetBrowser/Folder_16.svg";
static constexpr const char* GemIconPath = "Icons/AssetBrowser/GemFolder_16.svg";
FolderThumbnail::FolderThumbnail(SharedThumbnailKey key)
: Thumbnail(key)
@@ -55,7 +55,7 @@ namespace AzToolsFramework
//////////////////////////////////////////////////////////////////////////
// ProductThumbnail
//////////////////////////////////////////////////////////////////////////
static const char* DEFAULT_PRODUCT_ICON_PATH = "Editor/Icons/AssetBrowser/DefaultProduct_16.svg";
static const char* DEFAULT_PRODUCT_ICON_PATH = "Icons/AssetBrowser/DefaultProduct_16.svg";
ProductThumbnail::ProductThumbnail(Thumbnailer::SharedThumbnailKey key)
: Thumbnail(key)
@@ -55,7 +55,7 @@ namespace AzToolsFramework
//////////////////////////////////////////////////////////////////////////
// SourceThumbnail
//////////////////////////////////////////////////////////////////////////
static constexpr const char* DefaultFileIconPath = "Editor/Icons/AssetBrowser/Default_16.svg";
static constexpr const char* DefaultFileIconPath = "Icons/AssetBrowser/Default_16.svg";
QMutex SourceThumbnail::m_mutex;
SourceThumbnail::SourceThumbnail(SharedThumbnailKey key)
@@ -943,10 +943,8 @@ namespace AzToolsFramework
const char* scanFolder,
const char* displayName,
const char* portableKey,
const char* outputPrefix,
int isRoot)
: m_scanFolderID(scanFolderID)
, m_outputPrefix(outputPrefix)
, m_isRoot(isRoot)
{
if (scanFolder)
@@ -967,10 +965,8 @@ namespace AzToolsFramework
const char* scanFolder,
const char* displayName,
const char* portableKey,
const char* outputPrefix,
int isRoot)
: m_outputPrefix(outputPrefix)
, m_isRoot(isRoot)
: m_isRoot(isRoot)
{
if (scanFolder)
{
@@ -993,7 +989,6 @@ namespace AzToolsFramework
, m_scanFolder(other.m_scanFolder)
, m_displayName(other.m_displayName)
, m_portableKey(other.m_portableKey)
, m_outputPrefix(other.m_outputPrefix)
, m_isRoot(other.m_isRoot)
{
}
@@ -1011,7 +1006,6 @@ namespace AzToolsFramework
m_scanFolderID = other.m_scanFolderID;
m_displayName = AZStd::move(other.m_displayName);
m_portableKey = AZStd::move(other.m_portableKey);
m_outputPrefix = AZStd::move(other.m_outputPrefix);
m_isRoot = other.m_isRoot;
}
return *this;
@@ -1023,7 +1017,6 @@ namespace AzToolsFramework
m_scanFolderID = other.m_scanFolderID;
m_displayName = other.m_displayName;
m_portableKey = other.m_portableKey;
m_outputPrefix = other.m_outputPrefix;
m_isRoot = other.m_isRoot;
return *this;
}
@@ -1050,7 +1043,6 @@ namespace AzToolsFramework
MakeColumn("ScanFolder", m_scanFolder),
MakeColumn("DisplayName", m_displayName),
MakeColumn("PortableKey", m_portableKey),
MakeColumn("OutputPrefix", m_outputPrefix),
MakeColumn("IsRoot", m_isRoot)
);
}
@@ -68,6 +68,7 @@ namespace AzToolsFramework
AddedLastScanTimeField = 28,
AddedScanTimeSecondsSinceEpochField = 29,
ChangedSortFunctionFromQSortToStdStableSort = 30,
RemoveOutputPrefixFromScanFolders,
//Add all new versions before this
DatabaseVersionCount,
LatestVersion = DatabaseVersionCount - 1
@@ -99,12 +100,10 @@ namespace AzToolsFramework
const char* scanFolder,
const char* displayName,
const char* portableKey,
const char* outputPrefix,
int isRoot = 0);
ScanFolderDatabaseEntry(const char* scanFolder,
const char* displayName,
const char* portableKey,
const char* outputPrefix,
int isRoot = 0);
ScanFolderDatabaseEntry(const ScanFolderDatabaseEntry& other);
ScanFolderDatabaseEntry(ScanFolderDatabaseEntry&& other);
@@ -120,7 +119,6 @@ namespace AzToolsFramework
AZStd::string m_scanFolder; // the actual local computer path to that scan folder.
AZStd::string m_displayName; // a display name, blank means it should not show up in UIs
AZStd::string m_portableKey; // a key that uniquely identifies a scan folder so that we can recognize the same one in other databases/computer
AZStd::string m_outputPrefix;
int m_isRoot = 0;
};
@@ -108,11 +108,9 @@ namespace AzToolsFramework
m_targetTemplateId = id;
}
void Link::SetTemplatePatches(const PrefabDomValue& patches)
void Link::SetLinkDom(const PrefabDomValue& linkDom)
{
PrefabDom newPatches;
newPatches.CopyFrom(patches, newPatches.GetAllocator());
m_linkDom.Swap(newPatches);
m_linkDom.CopyFrom(linkDom, m_linkDom.GetAllocator());
}
void Link::SetInstanceName(const char* instanceName)
@@ -47,7 +47,7 @@ namespace AzToolsFramework
void SetSourceTemplateId(TemplateId id);
void SetTargetTemplateId(TemplateId id);
void SetTemplatePatches(const PrefabDomValue& patches);
void SetLinkDom(const PrefabDomValue& linkDom);
void SetInstanceName(const char* instanceName);
bool IsValid() const;
@@ -782,22 +782,21 @@ namespace AzToolsFramework
link.SetInstanceName(instanceName.data());
PrefabDomValue& instance = instanceIterator->value;
AZ_Assert(instance.IsObject(), "Nested instance DOM provided is not a valid JSON object.");
PrefabDomValueReference sourceTemplateName = PrefabDomUtils::FindPrefabDomValue(instance, PrefabDomUtils::SourceName);
AZ_Assert(sourceTemplateName, "Couldn't find source template name in the DOM of the nested instance while creating a link.");
AZ_Assert(
sourceTemplateName->get() == sourceTemplate.GetFilePath().c_str(),
"The name of the source template in the nested instance DOM does not match the name of the source template already loaded");
PrefabDomValueReference patchesReference = PrefabDomUtils::FindPrefabDomValue(instance, PrefabDomUtils::PatchesName);
if (!patchesReference.has_value())
if (patchesReference.has_value())
{
PrefabDom& newLinkDom = link.GetLinkDom();
newLinkDom.SetObject();
newLinkDom.AddMember(rapidjson::StringRef(PrefabDomUtils::SourceName),
rapidjson::StringRef(sourceTemplate.GetFilePath().c_str()), newLinkDom.GetAllocator());
}
else
{
link.SetTemplatePatches(patchesReference->get());
AZ_Assert(patchesReference->get().IsArray(), "Patches in the nested instance DOM are not represented as an array.");
}
link.SetLinkDom(instance);
if (!link.UpdateTarget())
{
AZ_Error("Prefab", false,
@@ -23,7 +23,7 @@ namespace AzToolsFramework
//////////////////////////////////////////////////////////////////////////
// LoadingThumbnail
//////////////////////////////////////////////////////////////////////////
static const char* LoadingIconPath = "Editor/Icons/AssetBrowser/in_progress.gif";
static const char* LoadingIconPath = "Icons/AssetBrowser/in_progress.gif";
LoadingThumbnail::LoadingThumbnail()
: Thumbnail(MAKE_TKEY(ThumbnailKey))
@@ -16,7 +16,7 @@ namespace AzToolsFramework
{
namespace Thumbnailer
{
static const char* MISSING_ICON_PATH = "Editor/Icons/AssetBrowser/Default_16.svg";
static const char* MISSING_ICON_PATH = "Icons/AssetBrowser/Default_16.svg";
MissingThumbnail::MissingThumbnail()
: Thumbnail(MAKE_TKEY(ThumbnailKey))
@@ -64,8 +64,8 @@ namespace AzToolsFramework
//////////////////////////////////////////////////////////////////////////
// SourceControlThumbnail
//////////////////////////////////////////////////////////////////////////
static const char* WRITABLE_ICON_PATH = "Editor/Icons/AssetBrowser/Writable_16.svg";
static const char* NONWRITABLE_ICON_PATH = "Editor/Icons/AssetBrowser/NonWritable_16.svg";
static const char* WRITABLE_ICON_PATH = "Icons/AssetBrowser/Writable_16.svg";
static const char* NONWRITABLE_ICON_PATH = "Icons/AssetBrowser/NonWritable_16.svg";
bool SourceControlThumbnail::m_readyForUpdate = true;
@@ -101,8 +101,8 @@ namespace AzToolsFramework
{
editContext->Class<EditorLayerComponent>("Layer", "The layer component allows entities to be saved to different files on disk.")
->ClassElement(AZ::Edit::ClassElements::EditorData, "")
->Attribute(AZ::Edit::Attributes::Icon, "Editor/Icons/Components/Layers.svg")
->Attribute(AZ::Edit::Attributes::ViewportIcon, "Editor/Icons/Components/Layers.svg")
->Attribute(AZ::Edit::Attributes::Icon, "Icons/Components/Layers.svg")
->Attribute(AZ::Edit::Attributes::ViewportIcon, "Icons/Components/Layers.svg")
->Attribute(AZ::Edit::Attributes::AppearsInAddComponentMenu, AZ_CRC("Layer", 0xe4db211a))
->Attribute(AZ::Edit::Attributes::AddableByUser, false)
->Attribute(AZ::Edit::Attributes::RemoveableByUser, false)
@@ -1025,9 +1025,9 @@ namespace AzToolsFramework
->Attribute(AZ::Edit::Attributes::NameLabelOverride, &ScriptEditorComponent::m_customName)
->Attribute(AZ::Edit::Attributes::AutoExpand, true)
->Attribute(AZ::Edit::Attributes::Category, "Scripting")
->Attribute(AZ::Edit::Attributes::Icon, "Editor/Icons/Components/LuaScript.svg")
->Attribute(AZ::Edit::Attributes::Icon, "Icons/Components/LuaScript.svg")
->Attribute(AZ::Edit::Attributes::PrimaryAssetType, AZ::AzTypeInfo<AZ::ScriptAsset>::Uuid())
->Attribute(AZ::Edit::Attributes::ViewportIcon, "Editor/Icons/Components/Viewport/Script.png")
->Attribute(AZ::Edit::Attributes::ViewportIcon, "Icons/Components/Viewport/Script.png")
->Attribute(AZ::Edit::Attributes::HelpPageURL, "https://docs.aws.amazon.com/lumberyard/latest/userguide/component-lua-script.html")
->DataElement("AssetRef", &ScriptEditorComponent::m_scriptAsset, "Script", "Which script to use")
->Attribute(AZ::Edit::Attributes::ChangeNotify, &ScriptEditorComponent::ScriptHasChanged)
@@ -1224,8 +1224,8 @@ namespace AzToolsFramework
{
ptrEdit->Class<TransformComponent>("Transform", "Controls the placement of the entity in the world in 3d")->
ClassElement(AZ::Edit::ClassElements::EditorData, "")->
Attribute(AZ::Edit::Attributes::Icon, "Editor/Icons/Components/Transform.svg")->
Attribute(AZ::Edit::Attributes::ViewportIcon, "Editor/Icons/Components/Viewport/Transform.png")->
Attribute(AZ::Edit::Attributes::Icon, "Icons/Components/Transform.svg")->
Attribute(AZ::Edit::Attributes::ViewportIcon, "Icons/Components/Viewport/Transform.png")->
Attribute(AZ::Edit::Attributes::AutoExpand, true)->
DataElement(AZ::Edit::UIHandlers::Default, &TransformComponent::m_parentEntityId, "Parent entity", "")->
Attribute(AZ::Edit::Attributes::ChangeValidate, &TransformComponent::ValidatePotentialParent)->
@@ -544,7 +544,7 @@ namespace AzToolsFramework
m_errorButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
m_errorButton->setFixedSize(QSize(16, 16));
m_errorButton->setMouseTracking(true);
m_errorButton->setIcon(QIcon("Editor/Icons/PropertyEditor/error_icon.png"));
m_errorButton->setIcon(QIcon("Icons/PropertyEditor/error_icon.png"));
m_errorButton->setToolTip("Show Errors");
// Insert the error button after the asset label
@@ -1304,7 +1304,11 @@ namespace AzToolsFramework
}
else if (attrib == AZ_CRC_CE("Thumbnail"))
{
GUI->SetShowThumbnail(true);
bool showThumbnail = false;
if (attrValue->Read<bool>(showThumbnail))
{
GUI->SetShowThumbnail(showThumbnail);
}
}
else if (attrib == AZ_CRC_CE("ThumbnailCallback"))
{
@@ -114,6 +114,7 @@ namespace AzToolsFramework
m_thumbnailEnlarged->move(position);
m_thumbnailEnlarged->setWindowFlags(Qt::Window | Qt::FramelessWindowHint);
m_thumbnailEnlarged->SetThumbnailKey(m_key);
m_thumbnailEnlarged->raise();
m_thumbnailEnlarged->show();
}
QWidget::enterEvent(e);
@@ -70,7 +70,7 @@ namespace AzToolsFramework
m_tagLabel->setMinimumSize(24, 22);
m_tagLabel->setAttribute(Qt::WA_TransparentForMouseEvents, true);
QIcon closeIcon("Editor/Icons/animation/close.png");
QIcon closeIcon("Icons/animation/close.png");
QPushButton* button = new QPushButton(this);
button->setStyleSheet(button->styleSheet() + "border: 0px;");
@@ -233,14 +233,14 @@ namespace AzToolsFramework
QPushButton* loadButton = new QPushButton(this);
loadButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
loadButton->setFixedSize(QSize(24, 24));
loadButton->setIcon(QIcon("Editor/UI/Icons/toolbar/libraryLoad.png"));
loadButton->setIcon(QIcon("UI/Icons/toolbar/libraryLoad.png"));
loadButton->setToolTip(tr("Load a saved filter"));
loadButton->setProperty("iconButton", "true");
m_saveButton = new QPushButton(this);
m_saveButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
m_saveButton->setFixedSize(QSize(24, 24));
m_saveButton->setIcon(QIcon("Editor/UI/Icons/toolbar/librarySave.png"));
m_saveButton->setIcon(QIcon("UI/Icons/toolbar/librarySave.png"));
m_saveButton->setToolTip(tr("Save the current filter"));
m_saveButton->setEnabled(false);
m_saveButton->setProperty("iconButton", "true");
@@ -248,7 +248,7 @@ namespace AzToolsFramework
m_toggleAllFiltersButton = new QPushButton(this);
m_toggleAllFiltersButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
m_toggleAllFiltersButton->setFixedSize(QSize(24, 24));
m_toggleAllFiltersButton->setIcon(QIcon("Editor/Icons/animation/filter_16.png"));
m_toggleAllFiltersButton->setIcon(QIcon("Icons/animation/filter_16.png"));
m_toggleAllFiltersButton->setVisible(false);
m_toggleAllFiltersButton->setToolTip(tr("Toggle all filters on/off"));
m_toggleAllFiltersButton->setProperty("iconButton", "true");
@@ -267,7 +267,7 @@ namespace AzToolsFramework
m_clearAllButton = new QPushButton(this);
m_clearAllButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
m_clearAllButton->setFixedSize(QSize(24, 24));
m_clearAllButton->setIcon(QIcon("Editor/Icons/animation/close.png"));
m_clearAllButton->setIcon(QIcon("Icons/animation/close.png"));
m_clearAllButton->setVisible(false);
m_clearAllButton->setToolTip(tr("Clear all filters"));
m_clearAllButton->setProperty("iconButton", "true");
@@ -441,7 +441,7 @@ namespace AzToolsFramework
clusterId);
}
static void SetViewportUiClusterVisible(ViewportUi::ClusterId clusterId, bool visible)
static void SetViewportUiClusterVisible(const ViewportUi::ClusterId clusterId, const bool visible)
{
ViewportUi::ViewportUiRequestBus::Event(
ViewportUi::DefaultViewportId,
@@ -449,7 +449,7 @@ namespace AzToolsFramework
clusterId, visible);
}
static void SetViewportUiClusterActiveButton(ViewportUi::ClusterId clusterId, ViewportUi::ButtonId buttonId)
static void SetViewportUiClusterActiveButton(const ViewportUi::ClusterId clusterId, const ViewportUi::ButtonId buttonId)
{
ViewportUi::ViewportUiRequestBus::Event(
ViewportUi::DefaultViewportId,
@@ -457,7 +457,7 @@ namespace AzToolsFramework
clusterId, buttonId);
}
static ViewportUi::ButtonId RegisterClusterButton(ViewportUi::ClusterId clusterId, const char* iconName)
static ViewportUi::ButtonId RegisterClusterButton(const ViewportUi::ClusterId clusterId, const char* iconName)
{
ViewportUi::ButtonId buttonId;
ViewportUi::ViewportUiRequestBus::EventResult(
@@ -13,7 +13,6 @@
#include "AzToolsFramework_precompiled.h"
#include <AzToolsFramework/ViewportUi/Button.h>
#include <AzToolsFramework/ViewportUi/Cluster.h>
namespace AzToolsFramework::ViewportUi::Internal
{
@@ -22,4 +21,11 @@ namespace AzToolsFramework::ViewportUi::Internal
, m_buttonId(buttonId)
{
}
Button::Button(AZStd::string icon, AZStd::string name, ButtonId buttonId)
: m_icon(AZStd::move(icon))
, m_name(AZStd::move(name))
, m_buttonId(buttonId)
{
}
} // namespace AzToolsFramework::ViewportUi::Internal
@@ -12,7 +12,6 @@
#pragma once
#include <AzToolsFramework/ViewportUi/Cluster.h>
#include <AzToolsFramework/ViewportUi/ViewportUiRequestBus.h>
namespace AzToolsFramework::ViewportUi::Internal
@@ -27,10 +26,12 @@ namespace AzToolsFramework::ViewportUi::Internal
Deselected
};
explicit Button(AZStd::string icon, ButtonId buttonId);
Button(AZStd::string icon, ButtonId buttonId);
Button(AZStd::string icon, AZStd::string name, ButtonId buttonId);
~Button() = default;
AZStd::string m_icon; //!< The icon for this button, string path to an image.
AZStd::string m_name; //!< The name displayed as a label next to the button's icon.
State m_state = State::Deselected;
ButtonId m_buttonId;
};
@@ -11,37 +11,27 @@
*/
#include <AzToolsFramework/ViewportUi/Button.h>
#include <AzToolsFramework/ViewportUi/Cluster.h>
#include <AzToolsFramework/ViewportUi/ButtonGroup.h>
namespace AzToolsFramework::ViewportUi::Internal
{
Cluster::Cluster()
ButtonGroup::ButtonGroup()
: m_buttons()
, m_buttonTriggeredEvent()
{
}
void Cluster::SetViewportUiElementId(const ViewportUiElementId id)
void ButtonGroup::SetViewportUiElementId(const ViewportUiElementId id)
{
m_viewportUiId = id;
}
ViewportUiElementId Cluster::GetViewportUiElementId() const
ViewportUiElementId ButtonGroup::GetViewportUiElementId() const
{
return m_viewportUiId;
}
void Cluster::SetClusterId(const ClusterId clusterId)
{
m_clusterId = clusterId;
}
ClusterId Cluster::GetClusterId() const
{
return m_clusterId;
}
void Cluster::SetHighlightedButton(ButtonId buttonId)
void ButtonGroup::SetHighlightedButton(ButtonId buttonId)
{
if (auto buttonEntry = m_buttons.find(buttonId); buttonEntry != m_buttons.end())
{
@@ -53,15 +43,22 @@ namespace AzToolsFramework::ViewportUi::Internal
}
}
ButtonId Cluster::AddButton(const AZStd::string& icon)
ButtonId ButtonGroup::AddButton(const AZStd::string& icon, const AZStd::string& name)
{
auto buttonId = ButtonId(m_buttons.size() + 1);
m_buttons.insert({buttonId, AZStd::make_unique<Button>(icon, buttonId)});
if (name.empty())
{
m_buttons.insert({buttonId, AZStd::make_unique<Button>(icon, buttonId)});
}
else
{
m_buttons.insert({buttonId, AZStd::make_unique<Button>(icon, name, buttonId)});
}
return buttonId;
}
Button* Cluster::GetButton(ButtonId buttonId)
Button* ButtonGroup::GetButton(ButtonId buttonId)
{
if (auto buttonEntry = m_buttons.find(buttonId); buttonEntry != m_buttons.end())
{
@@ -70,7 +67,7 @@ namespace AzToolsFramework::ViewportUi::Internal
return nullptr;
}
AZStd::vector<Button*> Cluster::GetButtons()
AZStd::vector<Button*> ButtonGroup::GetButtons()
{
auto buttons = AZStd::vector<Button*>();
for (const auto& button : m_buttons)
@@ -80,11 +77,11 @@ namespace AzToolsFramework::ViewportUi::Internal
return buttons;
}
void Cluster::ConnectEventHandler(AZ::Event<ButtonId>::Handler& handler) {
void ButtonGroup::ConnectEventHandler(AZ::Event<ButtonId>::Handler& handler) {
handler.Connect(m_buttonTriggeredEvent);
}
void Cluster::PressButton(ButtonId buttonId)
void ButtonGroup::PressButton(ButtonId buttonId)
{
m_buttonTriggeredEvent.Signal(buttonId);
}
@@ -18,23 +18,21 @@ namespace AzToolsFramework::ViewportUi::Internal
{
class Button;
//! Data class for a cluster on the Viewport UI. A cluster is defined as a group of buttons with icons
//! Data class for a button group on the Viewport UI. A button group is defined as a group of buttons with icons
//! each of which can be clicked to trigger an event e.g. toggling between modes.
class Cluster
//! @note This can be used with either a Cluster or a Switcher with slightly different visuals for each.
class ButtonGroup
{
public:
Cluster();
~Cluster() = default;
ButtonGroup();
~ButtonGroup() = default;
void SetHighlightedButton(ButtonId buttonId);
void SetViewportUiElementId(ViewportUiElementId id);
ViewportUiElementId GetViewportUiElementId() const;
void SetClusterId(ClusterId id);
ClusterId GetClusterId() const;
ButtonId AddButton(const AZStd::string& icon);
ButtonId AddButton(const AZStd::string& icon, const AZStd::string& name = AZStd::string());
Button* GetButton(ButtonId buttonId);
AZStd::vector<Button*> GetButtons();
@@ -44,7 +42,6 @@ namespace AzToolsFramework::ViewportUi::Internal
private:
AZ::Event<ButtonId> m_buttonTriggeredEvent;
ViewportUiElementId m_viewportUiId;
ClusterId m_clusterId;
AZStd::unordered_map<ButtonId, AZStd::unique_ptr<Button>> m_buttons;
};
} // namespace AzToolsFramework::ViewportUi::Internal
@@ -9,21 +9,22 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include "AzToolsFramework_precompiled.h"
#include <AzToolsFramework/ViewportUi/Cluster.h>
#include <AzToolsFramework/ViewportUi/ButtonGroup.h>
#include <AzToolsFramework/ViewportUi/ViewportUiCluster.h>
namespace AzToolsFramework::ViewportUi::Internal
{
ViewportUiCluster::ViewportUiCluster(AZStd::shared_ptr<Cluster> cluster)
ViewportUiCluster::ViewportUiCluster(AZStd::shared_ptr<ButtonGroup> buttonGroup)
: QToolBar(nullptr)
, m_cluster(cluster)
, m_buttonGroup(buttonGroup)
{
setOrientation(Qt::Orientation::Vertical);
setStyleSheet("background: black;");
const AZStd::vector<Button*> buttons = cluster->GetButtons();
const AZStd::vector<Button*> buttons = buttonGroup->GetButtons();
for (auto button : buttons)
{
RegisterButton(button);
@@ -39,7 +40,7 @@ namespace AzToolsFramework::ViewportUi::Internal
AddClusterAction(
action,
[this, button]() {
m_cluster->PressButton(button->m_buttonId);
m_buttonGroup->PressButton(button->m_buttonId);
},
[button](QAction* action) {
action->setChecked(button->m_state == Button::State::Selected);
@@ -18,10 +18,10 @@
#include <AzToolsFramework/ViewportUi/ViewportUiWidgetCallbacks.h>
#include <QToolBar>
class Cluster;
namespace AzToolsFramework::ViewportUi::Internal
{
class ButtonGroup;
//! Helper class to make clusters (toolbars) for display in Viewport UI.
class ViewportUiCluster
: public QToolBar
@@ -29,7 +29,7 @@ namespace AzToolsFramework::ViewportUi::Internal
Q_OBJECT
public:
ViewportUiCluster(AZStd::shared_ptr<Cluster> cluster);
ViewportUiCluster(AZStd::shared_ptr<ButtonGroup> buttonGroup);
~ViewportUiCluster() = default;
//! Adds a new button to the cluster.
@@ -49,7 +49,7 @@ namespace AzToolsFramework::ViewportUi::Internal
//! Removes an action from the Viewport UI Cluster.
void RemoveClusterAction(QAction* action);
AZStd::shared_ptr<Cluster> m_cluster; //!< Data structure which the cluster will be displaying to the Viewport UI.
AZStd::shared_ptr<ButtonGroup> m_buttonGroup; //!< Data structure which the cluster will be displaying to the Viewport UI.
AZStd::unordered_map<ButtonId, QPointer<QAction>> m_buttonActionMap; //!< Map for buttons to their corresponding actions.
ViewportUiWidgetCallbacks m_widgetCallbacks; //!< Registers actions and manages updates.
};
@@ -18,6 +18,7 @@
#include <AzToolsFramework/ViewportSelection/EditorSelectionUtil.h>
#include <AzToolsFramework/ViewportUi/ViewportUiDisplay.h>
#include <AzToolsFramework/ViewportUi/ViewportUiCluster.h>
#include <AzToolsFramework/ViewportUi/ViewportUiSwitcher.h>
#include <AzToolsFramework/ViewportUi/ViewportUiTextField.h>
#include <QWidget>
@@ -55,16 +56,16 @@ namespace AzToolsFramework::ViewportUi::Internal
UnparentWidgets(m_viewportUiElements);
}
void ViewportUiDisplay::AddCluster(AZStd::shared_ptr<Cluster> cluster)
void ViewportUiDisplay::AddCluster(AZStd::shared_ptr<ButtonGroup> buttonGroup)
{
if (!cluster.get())
if (!buttonGroup.get())
{
return;
}
auto viewportUiCluster = AZStd::make_shared<ViewportUiCluster>(cluster);
auto viewportUiCluster = AZStd::make_shared<ViewportUiCluster>(buttonGroup);
auto id = AddViewportUiElement(viewportUiCluster);
cluster->SetViewportUiElementId(id);
buttonGroup->SetViewportUiElementId(id);
PositionViewportUiElementAnchored(id, Qt::AlignTop | Qt::AlignLeft);
}
@@ -93,6 +94,51 @@ namespace AzToolsFramework::ViewportUi::Internal
}
}
void ViewportUiDisplay::AddSwitcher(AZStd::shared_ptr<ButtonGroup> buttonGroup)
{
if (!buttonGroup.get())
{
return;
}
auto viewportUiSwitcher = AZStd::make_shared<ViewportUiSwitcher>(buttonGroup);
auto id = AddViewportUiElement(viewportUiSwitcher);
buttonGroup->SetViewportUiElementId(id);
PositionViewportUiElementAnchored(id, Qt::AlignTop | Qt::AlignLeft);
}
void ViewportUiDisplay::AddSwitcherButton(const ViewportUiElementId clusterId, Button* button)
{
if (auto viewportUiSwitcher = qobject_cast<ViewportUiSwitcher*>(GetViewportUiElement(clusterId).get()))
{
viewportUiSwitcher->AddButton(button);
}
}
void ViewportUiDisplay::RemoveSwitcherButton(ViewportUiElementId clusterId, ButtonId buttonId)
{
if (auto cluster = qobject_cast<ViewportUiSwitcher*>(GetViewportUiElement(clusterId).get()))
{
cluster->RemoveButton(buttonId);
}
}
void ViewportUiDisplay::UpdateSwitcher(ViewportUiElementId clusterId)
{
if (auto cluster = qobject_cast<ViewportUiSwitcher*>(GetViewportUiElement(clusterId).get()))
{
cluster->Update();
}
}
void ViewportUiDisplay::SetSwitcherActiveButton(ViewportUiElementId clusterId, ButtonId buttonId)
{
if (auto viewportUiSwitcher = qobject_cast<ViewportUiSwitcher*>(GetViewportUiElement(clusterId).get()))
{
viewportUiSwitcher->SetActiveButton(buttonId);
}
}
void ViewportUiDisplay::AddTextField(AZStd::shared_ptr<TextField> textField)
{
if (!textField.get())
@@ -13,7 +13,7 @@
#pragma once
#include <AzToolsFramework/ViewportUi/Button.h>
#include <AzToolsFramework/ViewportUi/Cluster.h>
#include <AzToolsFramework/ViewportUi/ButtonGroup.h>
#include <AzToolsFramework/ViewportUi/TextField.h>
#include <AzToolsFramework/ViewportUi/ViewportUiRequestBus.h>
#include <AzToolsFramework/ViewportUi/ViewportUiDisplayLayout.h>
@@ -56,11 +56,17 @@ namespace AzToolsFramework::ViewportUi::Internal
ViewportUiDisplay(QWidget* parent, QWidget* renderOverlay);
~ViewportUiDisplay();
void AddCluster(AZStd::shared_ptr<Cluster> cluster);
void AddCluster(AZStd::shared_ptr<ButtonGroup> buttonGroup);
void AddClusterButton(ViewportUiElementId clusterId, Button* button);
void RemoveClusterButton(ViewportUiElementId clusterId, ButtonId buttonId);
void UpdateCluster(const ViewportUiElementId clusterId);
void AddSwitcher(AZStd::shared_ptr<ButtonGroup> buttonGroup);
void AddSwitcherButton(ViewportUiElementId switcherId, Button* button);
void RemoveSwitcherButton(ViewportUiElementId switcherId, ButtonId buttonId);
void UpdateSwitcher(ViewportUiElementId switcherId);
void SetSwitcherActiveButton(ViewportUiElementId switcherId, ButtonId buttonId);
void AddTextField(AZStd::shared_ptr<TextField> textField);
void UpdateTextField(ViewportUiElementId textFieldId);
@@ -30,7 +30,7 @@ namespace AzToolsFramework::ViewportUi::Internal
// create a 3x2 map of sub layouts which will stack widgets according to their mapped alignment
m_internalLayouts = AZStd::unordered_map<Qt::Alignment, QBoxLayout*> {
CreateSubLayout(new QHBoxLayout(), 0, 0, Qt::AlignTop | Qt::AlignLeft),
CreateSubLayout(new QVBoxLayout(), 0, 0, Qt::AlignTop | Qt::AlignLeft),
CreateSubLayout(new QHBoxLayout(), 1, 0, Qt::AlignBottom | Qt::AlignLeft),
CreateSubLayout(new QVBoxLayout(), 0, 1, Qt::AlignTop),
CreateSubLayout(new QHBoxLayout(), 1, 1, Qt::AlignBottom),
@@ -60,7 +60,7 @@ namespace AzToolsFramework::ViewportUi::Internal
AZStd::pair<Qt::Alignment, QBoxLayout*> ViewportUiDisplayLayout::CreateSubLayout(
QBoxLayout* layout, const int row, const int column, const Qt::Alignment alignment)
{
layout->setAlignment(alignment);
layout->setAlignment(alignment);
// add an invisible spacer (stretch) to occupy empty space
// without this, alignment and resizing within the sublayouts becomes difficult
@@ -14,7 +14,7 @@
#include <AzCore/std/smart_ptr/make_shared.h>
#include <AzToolsFramework/ViewportUi/Button.h>
#include <AzToolsFramework/ViewportUi/Cluster.h>
#include <AzToolsFramework/ViewportUi/ButtonGroup.h>
#include <AzToolsFramework/ViewportUi/ViewportUiManager.h>
#include <AzToolsFramework/ViewportUi/ViewportUiDisplay.h>
@@ -32,36 +32,64 @@ namespace AzToolsFramework::ViewportUi
const ClusterId ViewportUiManager::CreateCluster()
{
auto cluster = AZStd::make_shared<Internal::Cluster>();
m_viewportUi->AddCluster(cluster);
auto buttonGroup = AZStd::make_shared<Internal::ButtonGroup>();
m_viewportUi->AddCluster(buttonGroup);
return RegisterNewCluster(cluster);
return RegisterNewCluster(buttonGroup);
}
const SwitcherId ViewportUiManager::CreateSwitcher()
{
auto buttonGroup = AZStd::make_shared<Internal::ButtonGroup>();
m_viewportUi->AddSwitcher(buttonGroup);
return RegisterNewSwitcher(buttonGroup);
}
void ViewportUiManager::SetClusterActiveButton(const ClusterId clusterId, const ButtonId buttonId)
{
if (auto clusterEntry = m_clusters.find(clusterId); clusterEntry != m_clusters.end())
if (auto clusterIt = m_clusterButtonGroups.find(clusterId); clusterIt != m_clusterButtonGroups.end())
{
auto cluster = clusterEntry->second;
auto cluster = clusterIt->second;
cluster->SetHighlightedButton(buttonId);
UpdateClusterUi(cluster.get());
UpdateButtonGroupUi(cluster.get());
}
}
void ViewportUiManager::SetSwitcherActiveButton(const SwitcherId switcherId, const ButtonId buttonId)
{
if (auto switcherIt = m_switcherButtonGroups.find(switcherId); switcherIt != m_switcherButtonGroups.end())
{
auto switcher = switcherIt->second;
switcher->SetHighlightedButton(buttonId);
m_viewportUi->SetSwitcherActiveButton(switcher->GetViewportUiElementId(), buttonId);
UpdateButtonGroupUi(switcher.get());
}
}
void ViewportUiManager::RegisterClusterEventHandler(const ClusterId clusterId, AZ::Event<ButtonId>::Handler& handler)
{
if (auto clusterEntry = m_clusters.find(clusterId); clusterEntry != m_clusters.end())
if (auto clusterIt = m_clusterButtonGroups.find(clusterId); clusterIt != m_clusterButtonGroups.end())
{
auto cluster = clusterEntry->second;
auto cluster = clusterIt->second;
cluster->ConnectEventHandler(handler);
}
}
void ViewportUiManager::RegisterSwitcherEventHandler(const SwitcherId switcherId, AZ::Event<ButtonId>::Handler& handler)
{
if (auto switcherIt = m_switcherButtonGroups.find(switcherId); switcherIt != m_switcherButtonGroups.end())
{
auto switcher = switcherIt->second;
switcher->ConnectEventHandler(handler);
}
}
const ButtonId ViewportUiManager::CreateClusterButton(const ClusterId clusterId, const AZStd::string& icon)
{
if (auto clusterEntry = m_clusters.find(clusterId); clusterEntry != m_clusters.end())
if (auto clusterIt = m_clusterButtonGroups.find(clusterId); clusterIt != m_clusterButtonGroups.end())
{
auto cluster = clusterEntry->second;
auto cluster = clusterIt->second;
auto newId = cluster->AddButton(icon);
m_viewportUi->AddClusterButton(cluster->GetViewportUiElementId(), cluster->GetButton(newId));
@@ -71,12 +99,35 @@ namespace AzToolsFramework::ViewportUi
return ButtonId(0);
}
const ButtonId ViewportUiManager::CreateSwitcherButton(const SwitcherId switcherId, const AZStd::string& icon, const AZStd::string& name)
{
if (auto switcherIt = m_switcherButtonGroups.find(switcherId); switcherIt != m_switcherButtonGroups.end())
{
auto switcher = switcherIt->second;
auto newId = switcher->AddButton(icon, name);
m_viewportUi->AddSwitcherButton(switcher->GetViewportUiElementId(), switcher->GetButton(newId));
return newId;
}
return ButtonId(0);
}
void ViewportUiManager::RemoveCluster(const ClusterId clusterId)
{
if (auto clusterEntry = m_clusters.find(clusterId); clusterEntry != m_clusters.end())
if (auto clusterIt = m_clusterButtonGroups.find(clusterId); clusterIt != m_clusterButtonGroups.end())
{
m_clusters.erase(clusterEntry);
m_viewportUi->RemoveViewportUiElement(clusterEntry->second->GetViewportUiElementId());
m_clusterButtonGroups.erase(clusterIt);
m_viewportUi->RemoveViewportUiElement(clusterIt->second->GetViewportUiElementId());
}
}
void ViewportUiManager::RemoveSwitcher(SwitcherId switcherId)
{
if (auto switcherIt = m_switcherButtonGroups.find(switcherId); switcherIt != m_switcherButtonGroups.end())
{
m_switcherButtonGroups.erase(switcherIt);
m_viewportUi->RemoveViewportUiElement(switcherIt->second->GetViewportUiElementId());
}
}
@@ -93,15 +144,24 @@ namespace AzToolsFramework::ViewportUi
}
}
void ViewportUiManager::SetClusterVisible(ClusterId clusterId, bool visible)
void ViewportUiManager::SetClusterVisible(const ClusterId clusterId, bool visible)
{
if (auto clusterEntry = m_clusters.find(clusterId); clusterEntry != m_clusters.end())
if (auto clusterIt = m_clusterButtonGroups.find(clusterId); clusterIt != m_clusterButtonGroups.end())
{
auto cluster = clusterEntry->second;
auto cluster = clusterIt->second;
SetViewportUiElementVisible(m_viewportUi.get(), cluster->GetViewportUiElementId(), visible);
}
}
void ViewportUiManager::SetSwitcherVisible(const SwitcherId switcherId, bool visible)
{
if (auto switcherIt = m_switcherButtonGroups.find(switcherId); switcherIt != m_switcherButtonGroups.end())
{
auto switcher = switcherIt->second;
SetViewportUiElementVisible(m_viewportUi.get(), switcher->GetViewportUiElementId(), visible);
}
}
void ViewportUiManager::SetClusterGroupVisible(const AZStd::vector<ClusterId>& clusterGroup, bool visible)
{
for (auto clusterId : clusterGroup)
@@ -123,9 +183,9 @@ namespace AzToolsFramework::ViewportUi
void ViewportUiManager::SetTextFieldText(TextFieldId textFieldId, const AZStd::string& text)
{
if (auto textFieldEntry = m_textFields.find(textFieldId); textFieldEntry != m_textFields.end())
if (auto textFieldIt = m_textFields.find(textFieldId); textFieldIt != m_textFields.end())
{
auto textField = textFieldEntry->second;
auto textField = textFieldIt->second;
textField->m_fieldText = text;
UpdateTextFieldUi(textField.get());
}
@@ -134,27 +194,27 @@ namespace AzToolsFramework::ViewportUi
void ViewportUiManager::RegisterTextFieldCallback(
TextFieldId textFieldId, AZ::Event<AZStd::string>::Handler& handler)
{
if (auto textFieldEntry = m_textFields.find(textFieldId); textFieldEntry != m_textFields.end())
if (auto textFieldIt = m_textFields.find(textFieldId); textFieldIt != m_textFields.end())
{
auto textField = textFieldEntry->second;
auto textField = textFieldIt->second;
textField->ConnectEventHandler(handler);
}
}
void ViewportUiManager::RemoveTextField(TextFieldId textFieldId)
{
if (auto textFieldEntry = m_textFields.find(textFieldId); textFieldEntry != m_textFields.end())
if (auto textFieldIt = m_textFields.find(textFieldId); textFieldIt != m_textFields.end())
{
m_textFields.erase(textFieldEntry);
m_viewportUi->RemoveViewportUiElement(textFieldEntry->second->m_viewportId);
m_textFields.erase(textFieldIt);
m_viewportUi->RemoveViewportUiElement(textFieldIt->second->m_viewportId);
}
}
void ViewportUiManager::SetTextFieldVisible(TextFieldId textFieldId, bool visible)
{
if (auto textFieldEntry = m_textFields.find(textFieldId); textFieldEntry != m_textFields.end())
if (auto textFieldIt = m_textFields.find(textFieldId); textFieldIt != m_textFields.end())
{
auto textField = textFieldEntry->second;
auto textField = textFieldIt->second;
SetViewportUiElementVisible(m_viewportUi.get(), textField->m_viewportId, visible);
}
}
@@ -173,10 +233,19 @@ namespace AzToolsFramework::ViewportUi
void ViewportUiManager::PressButton(ClusterId clusterId, ButtonId buttonId)
{
// Find cluster using ID and cluster map
if (auto clusterEntry = m_clusters.find(clusterId);
clusterEntry != m_clusters.end())
if (auto clusterIt = m_clusterButtonGroups.find(clusterId);
clusterIt != m_clusterButtonGroups.end())
{
clusterEntry->second->PressButton(buttonId);
clusterIt->second->PressButton(buttonId);
}
}
void ViewportUiManager::PressButton(SwitcherId switcherId, ButtonId buttonId)
{
// Find cluster using ID and cluster map
if (auto switcherIt = m_switcherButtonGroups.find(switcherId); switcherIt != m_switcherButtonGroups.end())
{
switcherIt->second->PressButton(buttonId);
}
}
@@ -196,21 +265,32 @@ namespace AzToolsFramework::ViewportUi
{
m_viewportUi->Update();
for (auto clusterEntry : m_clusters)
for (auto buttonGroup : m_clusterButtonGroups)
{
UpdateClusterUi(clusterEntry.second.get());
UpdateButtonGroupUi(buttonGroup.second.get());
}
for (auto textFieldEntry : m_textFields)
for (auto buttonGroup : m_switcherButtonGroups)
{
UpdateTextFieldUi(textFieldEntry.second.get());
UpdateButtonGroupUi(buttonGroup.second.get());
}
for (auto textField : m_textFields)
{
UpdateTextFieldUi(textField.second.get());
}
}
ClusterId ViewportUiManager::RegisterNewCluster(AZStd::shared_ptr<Internal::Cluster>& cluster)
ClusterId ViewportUiManager::RegisterNewCluster(AZStd::shared_ptr<Internal::ButtonGroup>& buttonGroup)
{
ClusterId newId = ClusterId(m_clusters.size() + 1);
cluster->SetClusterId(newId);
m_clusters.insert({ newId, cluster });
ClusterId newId = ClusterId(m_clusterButtonGroups.size() + 1);
m_clusterButtonGroups.insert({ newId, buttonGroup });
return newId;
}
SwitcherId ViewportUiManager::RegisterNewSwitcher(AZStd::shared_ptr<Internal::ButtonGroup>& buttonGroup)
{
SwitcherId newId = SwitcherId(m_switcherButtonGroups.size() + 1);
m_switcherButtonGroups.insert({newId, buttonGroup});
return newId;
}
@@ -224,9 +304,9 @@ namespace AzToolsFramework::ViewportUi
return newId;
}
void ViewportUiManager::UpdateClusterUi(Internal::Cluster* cluster)
void ViewportUiManager::UpdateButtonGroupUi(Internal::ButtonGroup* buttonGroup)
{
m_viewportUi->UpdateCluster(cluster->GetViewportUiElementId());
m_viewportUi->UpdateCluster(buttonGroup->GetViewportUiElementId());
}
void ViewportUiManager::UpdateTextFieldUi(Internal::TextField* textField)
@@ -1,19 +1,18 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
#include <AzToolsFramework/ViewportUi/Button.h>
#include <AzToolsFramework/ViewportUi/Cluster.h>
#include <AzToolsFramework/ViewportUi/TextField.h>
#include <AzToolsFramework/ViewportUi/ViewportUiDisplay.h>
@@ -21,6 +20,7 @@ namespace AzToolsFramework::ViewportUi
{
namespace Internal
{
class ButtonGroup;
class ViewportUiDisplay;
}
@@ -29,26 +29,32 @@ namespace AzToolsFramework::ViewportUi
public:
ViewportUiManager() = default;
~ViewportUiManager() = default;
// ViewportUiRequestBus ...
const ClusterId CreateCluster() override;
const SwitcherId CreateSwitcher() override;
void SetClusterActiveButton(ClusterId clusterId, ButtonId buttonId) override;
void SetSwitcherActiveButton(SwitcherId switcherId, ButtonId buttonId) override;
const ButtonId CreateClusterButton(ClusterId clusterId, const AZStd::string& icon) override;
const ButtonId CreateSwitcherButton(
SwitcherId switcherId, const AZStd::string& icon, const AZStd::string& name = AZStd::string()) override;
void RegisterClusterEventHandler(ClusterId clusterId, AZ::Event<ButtonId>::Handler& handler) override;
void RegisterSwitcherEventHandler(SwitcherId switcherId, AZ::Event<ButtonId>::Handler& handler) override;
void RemoveCluster(ClusterId clusterId) override;
void RemoveSwitcher(SwitcherId switcherId) override;
void SetClusterVisible(ClusterId clusterId, bool visible);
void SetSwitcherVisible(SwitcherId switcherId, bool visible);
void SetClusterGroupVisible(const AZStd::vector<ClusterId>& clusterGroup, bool visible) override;
const TextFieldId CreateTextField(
const AZStd::string& labelText, const AZStd::string& textFieldDefaultText,
TextFieldValidationType validationType) override;
const AZStd::string& labelText, const AZStd::string& textFieldDefaultText, TextFieldValidationType validationType) override;
void SetTextFieldText(TextFieldId textFieldId, const AZStd::string& text) override;
void RegisterTextFieldCallback(
TextFieldId textFieldId, AZ::Event<AZStd::string>::Handler& handler) override;
void RegisterTextFieldCallback(TextFieldId textFieldId, AZ::Event<AZStd::string>::Handler& handler) override;
void RemoveTextField(TextFieldId textFieldId) override;
void SetTextFieldVisible(TextFieldId textFieldId, bool visible) override;
void CreateComponentModeBorder(const AZStd::string& borderTitle) override;
void RemoveComponentModeBorder() override;
void PressButton(ClusterId clusterId, ButtonId buttonId) override;
void PressButton(SwitcherId switcherId, ButtonId buttonId) override;
//! Connects to the correct viewportId bus address.
void ConnectViewportUiBus(const int viewportId);
@@ -60,17 +66,23 @@ namespace AzToolsFramework::ViewportUi
void Update();
protected:
AZStd::unordered_map<ClusterId, AZStd::shared_ptr<Internal::Cluster>> m_clusters; //!< A map of all registered clusters.
AZStd::unordered_map<TextFieldId, AZStd::shared_ptr<Internal::TextField>> m_textFields; //!< A map of all registered textFields.
AZStd::unordered_map<ClusterId, AZStd::shared_ptr<Internal::ButtonGroup>>
m_clusterButtonGroups; //!< A map of all registered Clusters.
AZStd::unordered_map<SwitcherId, AZStd::shared_ptr<Internal::ButtonGroup>>
m_switcherButtonGroups; //!< A map of all registered Switchers.
AZStd::unordered_map<TextFieldId, AZStd::shared_ptr<Internal::TextField>> m_textFields; //!< A map of all registered TextFields.
AZStd::unique_ptr<Internal::ViewportUiDisplay> m_viewportUi; //!< The lower level graphical API for Viewport UI.
private:
//! Register a new cluster and return its id.
ClusterId RegisterNewCluster(AZStd::shared_ptr<Internal::Cluster>& cluster);
//! Register a new Cluster and return its id.
ClusterId RegisterNewCluster(AZStd::shared_ptr<Internal::ButtonGroup>& buttonGroup);
//! Register a new Switcher and return its id.
SwitcherId RegisterNewSwitcher(AZStd::shared_ptr<Internal::ButtonGroup>& buttonGroup);
//! Register a new text field and return its id.
TextFieldId RegisterNewTextField(AZStd::shared_ptr<Internal::TextField>& textField);
//! Update the corresponding ui element for the given cluster.
void UpdateClusterUi(Internal::Cluster* cluster);
//! Update the corresponding ui element for the given button group.
void UpdateButtonGroupUi(Internal::ButtonGroup* buttonGroup);
//! Update the corresponding ui element for the given text field.
void UpdateTextFieldUi(Internal::TextField* textField);
};
@@ -1,14 +1,14 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
@@ -23,11 +23,13 @@ namespace AzToolsFramework::ViewportUi
using ViewportUiElementId = IdType<struct ViewportUiIdType>;
using ButtonId = IdType<struct ButtonIdType>;
using ClusterId = IdType<struct ClusterIdType>;
using SwitcherId = IdType<struct SwitcherIdType>;
using TextFieldId = IdType<struct TextFieldIdType>;
inline const ViewportUiElementId InvalidViewportUiElementId = ViewportUiElementId(0);
inline const ButtonId InvalidButtonId = ButtonId(0);
inline const ClusterId InvalidClusterId = ClusterId(0);
inline const SwitcherId InvalidSwitcherId = SwitcherId(0);
inline const int DefaultViewportId = 0;
@@ -46,27 +48,36 @@ namespace AzToolsFramework::ViewportUi
public:
//! Creates and registers a cluster with the Viewport UI system.
virtual const ClusterId CreateCluster() = 0;
//! Creates and registers a switcher with the Viewport UI system.
virtual const SwitcherId CreateSwitcher() = 0;
//! Sets the active button of the cluster. This is the button which will display as highlighted.
virtual void SetClusterActiveButton(ClusterId clusterId, ButtonId buttonId) = 0;
//! Sets the active button of the switcher. This is the button which has a text label.
virtual void SetSwitcherActiveButton(SwitcherId clusterId, ButtonId buttonId) = 0;
//! Registers a new button onto a cluster.
virtual const ButtonId CreateClusterButton(const ClusterId clusterId, const AZStd::string& icon) = 0;
//! Registers a new button onto a switcher.
virtual const ButtonId CreateSwitcherButton(
SwitcherId switcherId, const AZStd::string& icon, const AZStd::string& name = AZStd::string()) = 0;
//! Registers an event handler to handle events from the cluster.
virtual void RegisterClusterEventHandler(ClusterId clusterId, AZ::Event<ButtonId>::Handler& handler) = 0;
//! Registers an event handler to handle events from the cluster.
virtual void RegisterSwitcherEventHandler(SwitcherId switcherId, AZ::Event<ButtonId>::Handler& handler) = 0;
//! Removes a cluster from the Viewport UI system.
virtual void RemoveCluster(ClusterId clusterId) = 0;
//!
virtual void RemoveSwitcher(SwitcherId switcherId) = 0;
//! Sets the visibility of the cluster.
virtual void SetClusterVisible(ClusterId clusterId, bool visible) = 0;
//! Sets the visibility of multiple clusters.
virtual void SetClusterGroupVisible(const AZStd::vector<ClusterId>& clusterGroup, bool visible) = 0;
//! Creates and registers a text field with the Viewport UI system.
virtual const TextFieldId CreateTextField(
const AZStd::string& labelText, const AZStd::string& textFieldDefaultText,
TextFieldValidationType validationType) = 0;
const AZStd::string& labelText, const AZStd::string& textFieldDefaultText, TextFieldValidationType validationType) = 0;
//! Set the text that will go inside the text field.
virtual void SetTextFieldText(TextFieldId textFieldId, const AZStd::string& text) = 0;
//! Register an event handler to handle when the text field text changes.
virtual void RegisterTextFieldCallback(
TextFieldId textFieldId, AZ::Event<AZStd::string>::Handler& handler) = 0;
virtual void RegisterTextFieldCallback(TextFieldId textFieldId, AZ::Event<AZStd::string>::Handler& handler) = 0;
//! Removes a text field from the Viewport UI system.
virtual void RemoveTextField(TextFieldId textFieldId) = 0;
//! Sets the visibility of the text field.
@@ -77,11 +88,12 @@ namespace AzToolsFramework::ViewportUi
virtual void RemoveComponentModeBorder() = 0;
//! Invoke a button press in a cluster.
virtual void PressButton(ClusterId clusterId, ButtonId buttonId) = 0;
//!
virtual void PressButton(SwitcherId switcherId, ButtonId buttonId) = 0;
};
/// The EBusTraits for ViewportInteractionRequests.
class ViewportUiBusTraits
: public AZ::EBusTraits
class ViewportUiBusTraits : public AZ::EBusTraits
{
public:
using BusIdType = int; ///< ViewportId - used to address requests to this EBus.
@@ -0,0 +1,158 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include <AzToolsFramework/ViewportUi/ButtonGroup.h>
#include <AzToolsFramework/ViewportUi/ViewportUiSwitcher.h>
namespace AzToolsFramework::ViewportUi::Internal
{
ViewportUiSwitcher::ViewportUiSwitcher(AZStd::shared_ptr<ButtonGroup> buttonGroup)
: m_buttonGroup(buttonGroup)
{
setOrientation(Qt::Orientation::Horizontal);
setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Preferred);
setStyleSheet(QString("QToolBar {background-color: none; border: none; spacing: 3px;}"
"QToolButton {background-color: black; border: outset; border-color: white; border-radius: 7px; "
"border-width: 2px; padding: 7px; color: white;}"));
// Add am empty active button (is set in the call to SetActiveMode)
m_activeButton = new QToolButton();
// No hover effect for the main button as it's not clickable
m_activeButton->setProperty("IconHasHoverEffect", false);
m_activeButton->setCheckable(false);
m_activeButton->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
addWidget(m_activeButton);
const AZStd::vector<Button*> buttons = buttonGroup->GetButtons();
for (auto button : buttons)
{
// Add all the buttons as actions
if (button->m_buttonId)
{
AddButton(button);
}
}
}
ViewportUiSwitcher::~ViewportUiSwitcher()
{
delete m_activeButton;
}
void ViewportUiSwitcher::AddButton(Button* button)
{
QAction* action = new QAction();
action->setCheckable(true);
action->setIcon(QIcon(QString(button->m_icon.c_str())));
if (!action)
{
return;
}
// set hover to true by default
action->setProperty("IconHasHoverEffect", true);
// add the action
addAction(action);
// resize to fit new action with minimum extra space
resize(minimumSizeHint());
const AZStd::function<void()>& callback = [this, button]() { m_buttonGroup->PressButton(button->m_buttonId); };
const AZStd::function<void(QAction*)>& updateCallback = [button](QAction* action) {
action->setChecked(button->m_state == Button::State::Selected);
};
// connect the callback if provided
if (callback)
{
QObject::connect(action, &QAction::triggered, action, callback);
}
// register the action
m_widgetCallbacks.AddWidget(
action, [updateCallback](QPointer<QObject> object) { updateCallback(static_cast<QAction*>(object.data())); });
m_buttonActionMap.insert({button->m_buttonId, action});
}
void ViewportUiSwitcher::RemoveButton(ButtonId buttonId)
{
if (auto actionEntry = m_buttonActionMap.find(buttonId); actionEntry != m_buttonActionMap.end())
{
QAction* action = actionEntry->second;
// remove the action from the toolbar
removeAction(action);
// deregister from the widget manager
m_widgetCallbacks.RemoveWidget(action);
// resize to fit new area with minimum extra space
resize(minimumSizeHint());
m_buttonActionMap.erase(buttonId);
// reset current active mode if its the button being removed
if (buttonId == m_activeButtonId)
{
if (auto nextEntry = m_buttonActionMap.find(ButtonId(buttonId + 1)); nextEntry != m_buttonActionMap.end())
{
SetActiveButton(nextEntry->first);
}
}
}
}
void ViewportUiSwitcher::Update()
{
m_widgetCallbacks.Update();
}
void ViewportUiSwitcher::SetActiveButton(ButtonId buttonId)
{
// Check if it is the first active mode to be set
bool initialActiveMode = (m_activeButtonId == ButtonId(0));
// Change the toolbutton's name and icon to that button
const AZStd::vector<Button*> buttons = m_buttonGroup->GetButtons();
auto found = [buttonId](Button* button) { return (button->m_buttonId == buttonId); };
if (auto buttonIt = AZStd::find_if(buttons.begin(), buttons.end(), found); buttonIt != buttons.end())
{
QString buttonName = ((*buttonIt)->m_name).c_str();
QIcon buttonIcon = QIcon(QString(((*buttonIt)->m_icon).c_str()));
m_activeButton->setIcon(buttonIcon);
m_activeButton->setText(buttonName);
}
// Look up button ID in map then remove it from its current position
auto itr = m_buttonActionMap.find(buttonId);
QAction* action = itr->second;
removeAction(action);
if (!initialActiveMode)
{
// Add the last action removed
if (m_activeButtonId != buttonId)
{
itr = m_buttonActionMap.find(m_activeButtonId);
action = itr->second;
addAction(action);
}
}
m_activeButtonId = buttonId;
}
} // namespace AzToolsFramework::ViewportUi::Internal
@@ -0,0 +1,51 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
#include <AzToolsFramework/ViewportUi/Button.h>
#include <AzCore/std/containers/unordered_map.h>
#include <AzCore/std/smart_ptr/shared_ptr.h>
#include <AzToolsFramework/ViewportUi/ViewportUiWidgetCallbacks.h>
#include <functional>
#include <QPointer>
#include <QToolBar>
#include <QToolButton>
namespace AzToolsFramework::ViewportUi::Internal
{
class ButtonGroup;
//! Helper class to make switchers (toolbars) for display in Viewport UI.
class ViewportUiSwitcher : public QToolBar
{
Q_OBJECT
public:
ViewportUiSwitcher(AZStd::shared_ptr<ButtonGroup> buttonGroup);
~ViewportUiSwitcher();
//! Adds a new button to the switcher.
void AddButton(Button* button);
//! Removes a button from the switcher.
void RemoveButton(ButtonId buttonId);
void Update();
//! Changes the m_activeButton.
void SetActiveButton(ButtonId buttonId);
private:
QToolButton* m_activeButton; //!< The first button in the toolbar. Only button with a label/text.
ButtonId m_activeButtonId = ButtonId(0); //!< ButtonId corresponding to the active button in the buttonActionMap.
AZStd::shared_ptr<ButtonGroup> m_buttonGroup; //!< Data structure which the cluster will be displaying to the Viewport UI.
AZStd::unordered_map<ButtonId, QPointer<QAction>> m_buttonActionMap; //!< Map for buttons to their corresponding actions.
ViewportUiWidgetCallbacks m_widgetCallbacks; //!< Registers actions and manages updates.
};
} // namespace AzToolsFramework::ViewportUi::Internal
@@ -487,8 +487,8 @@ set(FILES
Viewport/ViewportTypes.cpp
ViewportUi/Button.h
ViewportUi/Button.cpp
ViewportUi/Cluster.h
ViewportUi/Cluster.cpp
ViewportUi/ButtonGroup.h
ViewportUi/ButtonGroup.cpp
ViewportUi/TextField.h
ViewportUi/TextField.cpp
ViewportUi/ViewportUiDisplay.h
@@ -500,6 +500,8 @@ set(FILES
ViewportUi/ViewportUiTextField.cpp
ViewportUi/ViewportUiCluster.h
ViewportUi/ViewportUiCluster.cpp
ViewportUi/ViewportUiSwitcher.h
ViewportUi/ViewportUiSwitcher.cpp
ViewportUi/ViewportUiWidgetCallbacks.h
ViewportUi/ViewportUiWidgetCallbacks.cpp
ViewportUi/ViewportUiDisplayLayout.h
@@ -729,7 +731,7 @@ set(FILES
# Prevent the following files from being grouped in UNITY builds
set(SKIP_UNITY_BUILD_INCLUSION_FILES
# The following files are skipped from unity to avoid duplicated symbols related to an ebus
AzToolsFrameworkModule.cpp
AzToolsFrameworkModule.cpp
Application/ToolsApplication.cpp
UI/PropertyEditor/PropertyEntityIdCtrl.cpp
UI/PropertyEditor/PropertyManagerComponent.cpp
@@ -49,8 +49,8 @@ namespace AzToolsFramework
->Attribute(AZ::Edit::Attributes::AddableByUser, true)
->Attribute(AZ::Edit::Attributes::AppearsInAddComponentMenu, AZ_CRC("Game"))
->Attribute(AZ::Edit::Attributes::Category, "Entity Search Test Components")
->Attribute(AZ::Edit::Attributes::Icon, "Editor/Icons/Components/Tag.png")
->Attribute(AZ::Edit::Attributes::ViewportIcon, "Editor/Icons/Components/Viewport/Tag.png")
->Attribute(AZ::Edit::Attributes::Icon, "Icons/Components/Tag.png")
->Attribute(AZ::Edit::Attributes::ViewportIcon, "Icons/Components/Viewport/Tag.png")
->Attribute(AZ::Edit::Attributes::AutoExpand, true)
->Attribute(AZ::Edit::Attributes::HelpPageURL, "https://www.amazongames.com/")
->DataElement(AZ::Edit::UIHandlers::Default, &EntitySearch_TestComponent1::m_boolValue, "Bool", "")
@@ -108,8 +108,8 @@ namespace AzToolsFramework
->Attribute(AZ::Edit::Attributes::AddableByUser, true)
->Attribute(AZ::Edit::Attributes::AppearsInAddComponentMenu, AZ_CRC("Game"))
->Attribute(AZ::Edit::Attributes::Category, "Entity Search Test Components")
->Attribute(AZ::Edit::Attributes::Icon, "Editor/Icons/Components/Tag.png")
->Attribute(AZ::Edit::Attributes::ViewportIcon, "Editor/Icons/Components/Viewport/Tag.png")
->Attribute(AZ::Edit::Attributes::Icon, "Icons/Components/Tag.png")
->Attribute(AZ::Edit::Attributes::ViewportIcon, "Icons/Components/Viewport/Tag.png")
->Attribute(AZ::Edit::Attributes::AutoExpand, true)
->Attribute(AZ::Edit::Attributes::HelpPageURL, "https://www.amazongames.com/")
->DataElement(AZ::Edit::UIHandlers::Default, &EntitySearch_TestComponent2::m_floatValue, "Float", "")
@@ -125,8 +125,8 @@ namespace UnitTest
->Attribute(AZ::Edit::Attributes::AddableByUser, true)
->Attribute(AZ::Edit::Attributes::AppearsInAddComponentMenu, AZ_CRC("Game"))
->Attribute(AZ::Edit::Attributes::Category, "Inspector Test Components")
->Attribute(AZ::Edit::Attributes::Icon, "Editor/Icons/Components/Tag.png")
->Attribute(AZ::Edit::Attributes::ViewportIcon, "Editor/Icons/Components/Viewport/Tag.png")
->Attribute(AZ::Edit::Attributes::Icon, "Icons/Components/Tag.png")
->Attribute(AZ::Edit::Attributes::ViewportIcon, "Icons/Components/Viewport/Tag.png")
->Attribute(AZ::Edit::Attributes::AutoExpand, true)
->Attribute(AZ::Edit::Attributes::HelpPageURL, "https://www.amazongames.com/")
->DataElement(AZ::Edit::UIHandlers::Default, &Inspector_TestComponent2::m_data, "Data", "The component's Data");
@@ -194,8 +194,8 @@ namespace UnitTest
->Attribute(AZ::Edit::Attributes::AddableByUser, true)
->Attribute(AZ::Edit::Attributes::AppearsInAddComponentMenu, AZ_CRC("System"))
->Attribute(AZ::Edit::Attributes::Category, "Inspector Test Components")
->Attribute(AZ::Edit::Attributes::Icon, "Editor/Icons/Components/Tag.png")
->Attribute(AZ::Edit::Attributes::ViewportIcon, "Editor/Icons/Components/Viewport/Tag.png")
->Attribute(AZ::Edit::Attributes::Icon, "Icons/Components/Tag.png")
->Attribute(AZ::Edit::Attributes::ViewportIcon, "Icons/Components/Viewport/Tag.png")
->Attribute(AZ::Edit::Attributes::AutoExpand, true)
->Attribute(AZ::Edit::Attributes::HelpPageURL, "https://www.amazongames.com/")
->DataElement(AZ::Edit::UIHandlers::Default, &Inspector_TestComponent3::m_data, "Data", "The component's Data");
@@ -78,7 +78,7 @@ namespace Benchmark
}
BENCHMARK_REGISTER_F(BM_PrefabUpdateInstances, UpdateInstances_SingeEntityInstances)
->RangeMultiplier(10)
->Range(100, 10000)
->Range(100, 1000)
->Unit(benchmark::kMillisecond)
->Complexity();
@@ -20,35 +20,35 @@
namespace UnitTest
{
using Cluster = AzToolsFramework::ViewportUi::Internal::Cluster;
using ButtonGroup = AzToolsFramework::ViewportUi::Internal::ButtonGroup;
using ButtonId = AzToolsFramework::ViewportUi::ButtonId;
TEST(ClusterTest, AddButtonAddsButtonToClusterAndReturnsId)
{
auto cluster = AZStd::make_unique<Cluster>();
auto buttonId = cluster->AddButton("");
auto buttonGroup = AZStd::make_unique<ButtonGroup>();
auto buttonId = buttonGroup->AddButton("");
auto button = cluster->GetButton(buttonId);
auto button = buttonGroup->GetButton(buttonId);
EXPECT_TRUE(button != nullptr);
}
TEST(ClusterTest, SetHighlightedButtonChangesButtonStateToSelected)
{
auto cluster = AZStd::make_unique<Cluster>();
auto buttonId = cluster->AddButton("");
auto buttonGroup = AZStd::make_unique<ButtonGroup>();
auto buttonId = buttonGroup->AddButton("");
// check button is not highlighted by default
auto button = cluster->GetButton(buttonId);
auto button = buttonGroup->GetButton(buttonId);
EXPECT_FALSE(button->m_state == AzToolsFramework::ViewportUi::Internal::Button::State::Selected);
cluster->SetHighlightedButton(buttonId);
buttonGroup->SetHighlightedButton(buttonId);
EXPECT_TRUE(button->m_state == AzToolsFramework::ViewportUi::Internal::Button::State::Selected);
}
TEST(ClusterTest, ConnectEventHandlerConnectsHandlerToButtonTriggeredEvent)
{
auto cluster = AZStd::make_unique<Cluster>();
auto buttonId = cluster->AddButton("");
auto buttonGroup = AZStd::make_unique<ButtonGroup>();
auto buttonId = buttonGroup->AddButton("");
// create a handler which will be triggered by the cluster
bool handlerTriggered = false;
@@ -62,8 +62,8 @@ namespace UnitTest
}
});
cluster->ConnectEventHandler(handler);
cluster->PressButton(buttonId);
buttonGroup->ConnectEventHandler(handler);
buttonGroup->PressButton(buttonId);
EXPECT_TRUE(handlerTriggered);
}
@@ -13,7 +13,7 @@
#include <AzCore/std/smart_ptr/make_shared.h>
#include <AzFramework/Viewport/ViewportScreen.h>
#include <AzTest/AzTest.h>
#include <AzToolsFramework/ViewportUi/Cluster.h>
#include <AzToolsFramework/ViewportUi/ButtonGroup.h>
#include <AzToolsFramework/ViewportUi/ViewportUiCluster.h>
#include <QAction>
#include <QApplication>
@@ -23,14 +23,14 @@
namespace UnitTest
{
using ViewportUiCluster = AzToolsFramework::ViewportUi::Internal::ViewportUiCluster;
using Cluster = AzToolsFramework::ViewportUi::Internal::Cluster;
using ButtonGroup = AzToolsFramework::ViewportUi::Internal::ButtonGroup;
using Button = AzToolsFramework::ViewportUi::Internal::Button;
using ButtonId = AzToolsFramework::ViewportUi::ButtonId;
TEST(ViewportUiCluster, RegisterButtonIncreasesClusterHeight)
{
auto clusterInfo = AZStd::make_shared<Cluster>();
ViewportUiCluster viewportUiCluster(clusterInfo);
auto buttonGroup = AZStd::make_shared<ButtonGroup>();
ViewportUiCluster viewportUiCluster(buttonGroup);
viewportUiCluster.resize(viewportUiCluster.minimumSizeHint());
// need to initialize cluster with a single button or size will be invalid
@@ -48,8 +48,8 @@ namespace UnitTest
TEST(ViewportUiCluster, RemoveClusterButtonDecreasesClusterHeight)
{
auto clusterInfo = AZStd::make_shared<Cluster>();
ViewportUiCluster viewportUiCluster(clusterInfo);
auto buttonGroup = AZStd::make_shared<ButtonGroup>();
ViewportUiCluster viewportUiCluster(buttonGroup);
viewportUiCluster.resize(viewportUiCluster.minimumSizeHint());
// need to initialize cluster with a single button or size will be invalid
@@ -70,8 +70,8 @@ namespace UnitTest
TEST(ViewportUiCluster, UpdateChangesActiveButton)
{
auto clusterInfo = AZStd::make_shared<Cluster>();
ViewportUiCluster viewportUiCluster(clusterInfo);
auto buttonGroup = AZStd::make_shared<ButtonGroup>();
ViewportUiCluster viewportUiCluster(buttonGroup);
// register a button to the cluster
auto button = AZStd::make_unique<Button>("", ButtonId(1));
@@ -93,8 +93,8 @@ namespace UnitTest
TEST(ViewportUiCluster, TriggeringActionTriggersClusterEventForButton)
{
auto clusterInfo = AZStd::make_shared<Cluster>();
ViewportUiCluster viewportUiCluster(clusterInfo);
auto buttonGroup = AZStd::make_shared<ButtonGroup>();
ViewportUiCluster viewportUiCluster(buttonGroup);
// create a handler which will be triggered by the button
bool handlerTriggered = false;
@@ -107,7 +107,7 @@ namespace UnitTest
handlerTriggered = true;
}
});
clusterInfo->ConnectEventHandler(handler);
buttonGroup->ConnectEventHandler(handler);
// register the button
auto button = AZStd::make_unique<Button>("", testButtonId);
@@ -23,10 +23,10 @@ namespace UnitTest
{
using ViewportUiDisplay = AzToolsFramework::ViewportUi::Internal::ViewportUiDisplay;
using ViewportUiElementId = AzToolsFramework::ViewportUi::ViewportUiElementId;
using Cluster = AzToolsFramework::ViewportUi::Internal::Cluster;
using ButtonGroup = AzToolsFramework::ViewportUi::Internal::ButtonGroup;
// sets up a parent widget and render overlay to attach the Viewport UI to
// as well as a cluster with one button
// as well as a button group with one button
class ViewportUiDisplayTestFixture : public ::testing::Test
{
public:
@@ -34,22 +34,22 @@ namespace UnitTest
void SetUp()
{
m_cluster = AZStd::make_shared<Cluster>();
m_cluster->AddButton("");
m_buttonGroup = AZStd::make_shared<ButtonGroup>();
m_buttonGroup->AddButton("");
m_parentWidget = new QWidget();
m_mockRenderOverlay = new QWidget();
}
void TearDown()
{
m_cluster.reset();
m_buttonGroup.reset();
delete m_parentWidget;
delete m_mockRenderOverlay;
}
QWidget* m_parentWidget = nullptr;
QWidget* m_mockRenderOverlay = nullptr;
AZStd::shared_ptr<Cluster> m_cluster = nullptr;
AZStd::shared_ptr<ButtonGroup> m_buttonGroup = nullptr;
};
TEST_F(ViewportUiDisplayTestFixture, ViewportUiInitializationReturnsProperlyParentedWidgets)
@@ -72,13 +72,13 @@ namespace UnitTest
TEST_F(ViewportUiDisplayTestFixture, RemoveViewportUiElementRemovesElementFromViewportUi)
{
ViewportUiDisplay viewportUi(m_parentWidget, m_mockRenderOverlay);
viewportUi.AddCluster(m_cluster);
auto widget = viewportUi.GetViewportUiElement(m_cluster->GetViewportUiElementId());
viewportUi.AddCluster(m_buttonGroup);
auto widget = viewportUi.GetViewportUiElement(m_buttonGroup->GetViewportUiElementId());
EXPECT_TRUE(widget.get() != nullptr);
viewportUi.RemoveViewportUiElement(m_cluster->GetViewportUiElementId());
widget = viewportUi.GetViewportUiElement(m_cluster->GetViewportUiElementId());
viewportUi.RemoveViewportUiElement(m_buttonGroup->GetViewportUiElementId());
widget = viewportUi.GetViewportUiElement(m_buttonGroup->GetViewportUiElementId());
EXPECT_TRUE(widget.get() == nullptr);
}
@@ -89,11 +89,11 @@ namespace UnitTest
ViewportUiDisplay viewportUi(m_parentWidget, m_mockRenderOverlay);
viewportUi.InitializeUiOverlay();
viewportUi.AddCluster(m_cluster);
viewportUi.AddCluster(m_buttonGroup);
viewportUi.Update();
viewportUi.ShowViewportUiElement(m_cluster->GetViewportUiElementId());
viewportUi.ShowViewportUiElement(m_buttonGroup->GetViewportUiElementId());
EXPECT_TRUE(viewportUi.IsViewportUiElementVisible(m_cluster->GetViewportUiElementId()));
EXPECT_TRUE(viewportUi.IsViewportUiElementVisible(m_buttonGroup->GetViewportUiElementId()));
}
TEST_F(ViewportUiDisplayTestFixture, HideViewportUiElementSetsWidgetVisibilityToFalse)
@@ -102,20 +102,20 @@ namespace UnitTest
ViewportUiDisplay viewportUi(m_parentWidget, m_mockRenderOverlay);
viewportUi.InitializeUiOverlay();
viewportUi.AddCluster(m_cluster);
viewportUi.HideViewportUiElement(m_cluster->GetViewportUiElementId());
viewportUi.AddCluster(m_buttonGroup);
viewportUi.HideViewportUiElement(m_buttonGroup->GetViewportUiElementId());
EXPECT_FALSE(viewportUi.IsViewportUiElementVisible(m_cluster->GetViewportUiElementId()));
EXPECT_FALSE(viewportUi.IsViewportUiElementVisible(m_buttonGroup->GetViewportUiElementId()));
}
TEST_F(ViewportUiDisplayTestFixture, UpdateUiOverlayGeometryChangesGeometryToMatchViewportUiElements)
{
ViewportUiDisplay viewportUi(m_parentWidget, m_mockRenderOverlay);
viewportUi.InitializeUiOverlay();
viewportUi.AddCluster(m_cluster);
viewportUi.AddCluster(m_buttonGroup);
viewportUi.Update();
auto widget = viewportUi.GetViewportUiElement(m_cluster->GetViewportUiElementId());
auto widget = viewportUi.GetViewportUiElement(m_buttonGroup->GetViewportUiElementId());
EXPECT_EQ(viewportUi.GetUiMainWindow()->mask(), widget->geometry());
}
@@ -127,14 +127,14 @@ namespace UnitTest
ViewportUiDisplay viewportUi(m_parentWidget, m_mockRenderOverlay);
viewportUi.InitializeUiOverlay();
auto cluster = AZStd::make_shared<Cluster>();
cluster->AddButton("");
viewportUi.AddCluster(cluster);
auto buttonGroup = AZStd::make_shared<ButtonGroup>();
buttonGroup->AddButton("");
viewportUi.AddCluster(buttonGroup);
viewportUi.Update();
EXPECT_TRUE(viewportUi.GetUiMainWindow()->isVisible());
viewportUi.RemoveViewportUiElement(cluster->GetViewportUiElementId());
viewportUi.RemoveViewportUiElement(buttonGroup->GetViewportUiElementId());
viewportUi.Update();
EXPECT_FALSE(viewportUi.GetUiMainWindow()->isVisible());
}
@@ -22,19 +22,19 @@ namespace UnitTest
{
using ViewportUiDisplay = AzToolsFramework::ViewportUi::Internal::ViewportUiDisplay;
using ViewportUiElementId = AzToolsFramework::ViewportUi::ViewportUiElementId;
using Cluster = AzToolsFramework::ViewportUi::Internal::Cluster;
using ButtonGroup = AzToolsFramework::ViewportUi::Internal::ButtonGroup;
using ButtonId = AzToolsFramework::ViewportUi::ButtonId;
// child class of ViewportUiManager which exposes the protected cluster and viewport display
// child class of ViewportUiManager which exposes the protected button group and viewport display
class ViewportUiManagerTestable : public AzToolsFramework::ViewportUi::ViewportUiManager
{
public:
ViewportUiManagerTestable() = default;
~ViewportUiManagerTestable() = default;
const AZStd::unordered_map<AzToolsFramework::ViewportUi::ClusterId, AZStd::shared_ptr<Cluster>>& GetClusterMap()
const AZStd::unordered_map<AzToolsFramework::ViewportUi::ClusterId, AZStd::shared_ptr<ButtonGroup>>& GetClusterMap()
{
return m_clusters;
return m_clusterButtonGroups;
}
ViewportUiDisplay* GetViewportUiDisplay()