Merge branch 'main' into Spawnable/ProductDependency

This commit is contained in:
sconel
2021-04-28 15:40:10 -07:00
297 changed files with 32573 additions and 16746 deletions
@@ -118,6 +118,7 @@ namespace AZ
const static AZ::Crc32 StringLineEditingCompleteNotify = AZ_CRC("StringLineEditingCompleteNotify", 0x139e5fa9);
const static AZ::Crc32 NameLabelOverride = AZ_CRC("NameLabelOverride", 0x9ff79cab);
const static AZ::Crc32 AssetPickerTitle = AZ_CRC_CE("AssetPickerTitle");
const static AZ::Crc32 ChildNameLabelOverride = AZ_CRC("ChildNameLabelOverride", 0x73dd2909);
//! Container attribute that is used to override labels for its elements given the index of the element
const static AZ::Crc32 IndexedChildNameLabelOverride = AZ_CRC("IndexedChildNameLabelOverride", 0x5f313ac2);
@@ -10,91 +10,75 @@
*
*/
#include "ByteStreamSerializer.h"
#include <AzCore/Casting/numeric_cast.h>
#include <AzCore/Memory/SystemAllocator.h>
#include <AzCore/Serialization/Json/ByteStreamSerializer.h>
#include <AzCore/Serialization/Json/JsonSerialization.h>
#include <AzCore/StringFunc/StringFunc.h>
namespace AZ
{
namespace ByteSerializerInternal
{
static JsonSerializationResult::Result Load(void* outputValue, const rapidjson::Value& inputValue, JsonDeserializerContext& context)
{
using JsonSerializationResult::Outcomes;
using JsonSerializationResult::Tasks;
AZ_Assert(outputValue, "Expected a valid pointer to load from json value.");
switch (inputValue.GetType())
{
case rapidjson::kStringType: {
JsonByteStream buffer;
if (AZ::StringFunc::Base64::Decode(buffer, inputValue.GetString(), inputValue.GetStringLength()))
{
JsonByteStream* valAsByteStream = static_cast<JsonByteStream*>(outputValue);
*valAsByteStream = AZStd::move(buffer);
return context.Report(Tasks::ReadField, Outcomes::Success, "Successfully read ByteStream.");
}
return context.Report(Tasks::ReadField, Outcomes::Invalid, "Decode of Base64 encoded ByteStream failed.");
}
case rapidjson::kArrayType:
case rapidjson::kObjectType:
case rapidjson::kNullType:
case rapidjson::kFalseType:
case rapidjson::kTrueType:
case rapidjson::kNumberType:
return context.Report(
Tasks::ReadField, Outcomes::Unsupported,
"Unsupported type. ByteStream values cannot be read from arrays, objects, nulls, booleans or numbers.");
default:
return context.Report(Tasks::ReadField, Outcomes::Unknown, "Unknown json type encountered for ByteStream value.");
}
}
static JsonSerializationResult::Result StoreWithDefault(
rapidjson::Value& outputValue, const void* inputValue, const void* defaultValue, JsonSerializerContext& context)
{
using JsonSerializationResult::Outcomes;
using JsonSerializationResult::Tasks;
const JsonByteStream& valAsByteStream = *static_cast<const JsonByteStream*>(inputValue);
if (context.ShouldKeepDefaults() || !defaultValue || (valAsByteStream != *static_cast<const JsonByteStream*>(defaultValue)))
{
const auto base64ByteStream = AZ::StringFunc::Base64::Encode(valAsByteStream.data(), valAsByteStream.size());
outputValue.SetString(base64ByteStream.c_str(), base64ByteStream.size(), context.GetJsonAllocator());
return context.Report(Tasks::WriteValue, Outcomes::Success, "ByteStream successfully stored.");
}
return context.Report(Tasks::WriteValue, Outcomes::DefaultsUsed, "Default ByteStream used.");
}
} // namespace ByteSerializerInternal
AZ_CLASS_ALLOCATOR_IMPL(JsonByteStreamSerializer, SystemAllocator, 0);
JsonSerializationResult::Result JsonByteStreamSerializer::Load(
void* outputValue, [[maybe_unused]] const Uuid& outputValueTypeId, const rapidjson::Value& inputValue,
JsonDeserializerContext& context)
{
using JsonSerializationResult::Outcomes;
using JsonSerializationResult::Tasks;
AZ_Assert(
azrtti_typeid<JsonByteStream>() == outputValueTypeId,
"Unable to deserialize AZStd::vector<AZ::u8>> to json because the provided type is %s",
outputValueTypeId.ToString<AZStd::string>().c_str());
AZ_Assert(outputValue, "Expected a valid pointer to load from json value.");
return ByteSerializerInternal::Load(outputValue, inputValue, context);
switch (inputValue.GetType())
{
case rapidjson::kStringType: {
JsonByteStream buffer;
if (AZ::StringFunc::Base64::Decode(buffer, inputValue.GetString(), inputValue.GetStringLength()))
{
JsonByteStream* valAsByteStream = static_cast<JsonByteStream*>(outputValue);
*valAsByteStream = AZStd::move(buffer);
return context.Report(Tasks::ReadField, Outcomes::Success, "Successfully read ByteStream.");
}
return context.Report(Tasks::ReadField, Outcomes::Invalid, "Decode of Base64 encoded ByteStream failed.");
}
case rapidjson::kArrayType:
case rapidjson::kObjectType:
case rapidjson::kNullType:
case rapidjson::kFalseType:
case rapidjson::kTrueType:
case rapidjson::kNumberType:
return context.Report(
Tasks::ReadField, Outcomes::Unsupported,
"Unsupported type. ByteStream values cannot be read from arrays, objects, nulls, booleans or numbers.");
default:
return context.Report(Tasks::ReadField, Outcomes::Unknown, "Unknown json type encountered for ByteStream value.");
}
}
JsonSerializationResult::Result JsonByteStreamSerializer::Store(
rapidjson::Value& outputValue, const void* inputValue, const void* defaultValue, [[maybe_unused]] const Uuid& valueTypeId,
JsonSerializerContext& context)
{
using JsonSerializationResult::Outcomes;
using JsonSerializationResult::Tasks;
AZ_Assert(
azrtti_typeid<JsonByteStream>() == valueTypeId,
"Unable to serialize AZStd::vector<AZ::u8> to json because the provided type is %s",
valueTypeId.ToString<AZStd::string>().c_str());
return ByteSerializerInternal::StoreWithDefault(outputValue, inputValue, defaultValue, context);
const JsonByteStream& valAsByteStream = *static_cast<const JsonByteStream*>(inputValue);
if (context.ShouldKeepDefaults() || !defaultValue || (valAsByteStream != *static_cast<const JsonByteStream*>(defaultValue)))
{
const auto base64ByteStream = AZ::StringFunc::Base64::Encode(valAsByteStream.data(), valAsByteStream.size());
outputValue.SetString(base64ByteStream.c_str(), base64ByteStream.size(), context.GetJsonAllocator());
return context.Report(Tasks::WriteValue, Outcomes::Success, "ByteStream successfully stored.");
}
return context.Report(Tasks::WriteValue, Outcomes::DefaultsUsed, "Default ByteStream used.");
}
} // namespace AZ
@@ -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
@@ -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;
@@ -24,5 +24,5 @@ QProgressBar
QProgressBar::chunk
{
background: #54AFD0;
background: #1E70EB;
}
@@ -13,14 +13,14 @@ Width=24;
ArrowWidth=10;
[PrimaryColorSet]
Disabled\Start=#7092A7
Disabled\End=#7092A7
Sunken\Start=#0073BB
Sunken\End=#0073BB
Hovered\Start=#44BAFF
Hovered\End=#4AB2F8
Disabled\Start=#2A4875
Disabled\End=#2A4875
Sunken\Start=#1E70EB
Sunken\End=#1E70EB
Hovered\Start=#4ABAFF
Hovered\End=#94D2FF
Normal\Start=#0095F2
Normal\End=#0073BB
Normal\End=#1E70EB
[SecondaryColorSet]
Disabled\Start=#666666
@@ -42,10 +42,10 @@ Color=#3D000000
[FocusedBorder]
Thickness=1
Color=#00A1C9
Color=#4B8CEF
[IconButton]
ActiveColor=#00A1C9
ActiveColor=#1E70EB
DisabledColor=#999999
SelectedColor=#FFFFFF
@@ -12,7 +12,7 @@ HandleBorder\Color=#FFFFFF
HandleBorder\Radius=1.5
[Slider]
Handle\Color=#0185D7
Handle\Color=#1E70EB
Handle\ColorDisabled=#999999
Handle\Size=12
Handle\SizeMinusMargin=8
@@ -46,7 +46,7 @@ namespace AzQtComponents
Text::Config Text::defaultConfig()
{
Config config;
config.hyperlinkColor = QStringLiteral("#44B2F8");
config.hyperlinkColor = QStringLiteral("#94D2FF");
return config;
}
@@ -1,2 +1,2 @@
[Hyperlink]
Color=#44B2F8
Color=#94D2FF
@@ -4,7 +4,7 @@
<title>Selection Controls / Checkbox / Off</title>
<desc>Created with Sketch.</desc>
<g id="Selection-Controls-/-Checkbox-/-Off" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="checkbox-(off)" stroke="#00A1C9">
<g id="checkbox-(off)" stroke="#4B8CEF">
<path d="M14.2222222,0.5 L1.77777778,0.5 C1.07614237,0.5 0.5,1.07614237 0.5,1.77777778 L0.5,14.2222222 C0.5,14.9238576 1.07614237,15.5 1.77777778,15.5 L14.2222222,15.5 C14.9238576,15.5 15.5,14.9238576 15.5,14.2222222 L15.5,1.77777778 C15.5,1.07614237 14.9238576,0.5 14.2222222,0.5 Z" id="Shape"></path>
</g>
</g>

Before

Width:  |  Height:  |  Size: 850 B

After

Width:  |  Height:  |  Size: 850 B

@@ -5,7 +5,7 @@
<desc>Created with Sketch.</desc>
<g id="Selection-Controls-/-Checkbox-/-On---Disabled" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="checkbox-(on)">
<path d="M1.77777778,0 C0.8,0 0,0.8 0,1.77777778 L0,14.2222222 C0,15.2 0.8,16 1.77777778,16 L14.2222222,16 C15.2,16 16,15.2 16,14.2222222 L16,1.77777778 C16,0.8 15.2,0 14.2222222,0 L1.77777778,0 Z" id="Shape" fill="#7092A7"></path>
<path d="M1.77777778,0 C0.8,0 0,0.8 0,1.77777778 L0,14.2222222 C0,15.2 0.8,16 1.77777778,16 L14.2222222,16 C15.2,16 16,15.2 16,14.2222222 L16,1.77777778 C16,0.8 15.2,0 14.2222222,0 L1.77777778,0 Z" id="Shape" fill="#2A4875"></path>
<polygon id="Path" fill="#BBBBBB" points="1 8.19230769 2.4 6.84615385 6 10.3076923 13.6 3 15 4.34615385 6 13"></polygon>
</g>
</g>

Before

Width:  |  Height:  |  Size: 914 B

After

Width:  |  Height:  |  Size: 914 B

@@ -5,7 +5,7 @@
<desc>Created with Sketch.</desc>
<g id="Selection-Controls-/-Checkbox-/-On-focus" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="checkbox-(on)">
<path d="M14.2222222,0.5 L1.77777778,0.5 C1.07614237,0.5 0.5,1.07614237 0.5,1.77777778 L0.5,14.2222222 C0.5,14.9238576 1.07614237,15.5 1.77777778,15.5 L14.2222222,15.5 C14.9238576,15.5 15.5,14.9238576 15.5,14.2222222 L15.5,1.77777778 C15.5,1.07614237 14.9238576,0.5 14.2222222,0.5 Z" id="Shape" stroke="#00A1C9" fill="#0073BB"></path>
<path d="M14.2222222,0.5 L1.77777778,0.5 C1.07614237,0.5 0.5,1.07614237 0.5,1.77777778 L0.5,14.2222222 C0.5,14.9238576 1.07614237,15.5 1.77777778,15.5 L14.2222222,15.5 C14.9238576,15.5 15.5,14.9238576 15.5,14.2222222 L15.5,1.77777778 C15.5,1.07614237 14.9238576,0.5 14.2222222,0.5 Z" id="Shape" stroke="#4B8CEF" fill="#1E70EB"></path>
<polygon id="Path" fill="#FFFFFF" points="1 8.19230769 2.4 6.84615385 6 10.3076923 13.6 3 15 4.34615385 6 13"></polygon>
</g>
</g>

Before

Width:  |  Height:  |  Size: 1007 B

After

Width:  |  Height:  |  Size: 1007 B

@@ -5,7 +5,7 @@
<desc>Created with Sketch.</desc>
<g id="Selection-Controls-/-Checkbox-/-On" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="checkbox-(on)">
<path d="M1.77777778,0 C0.8,0 0,0.8 0,1.77777778 L0,14.2222222 C0,15.2 0.8,16 1.77777778,16 L14.2222222,16 C15.2,16 16,15.2 16,14.2222222 L16,1.77777778 C16,0.8 15.2,0 14.2222222,0 L1.77777778,0 Z" id="Shape" fill="#0073BB"></path>
<path d="M1.77777778,0 C0.8,0 0,0.8 0,1.77777778 L0,14.2222222 C0,15.2 0.8,16 1.77777778,16 L14.2222222,16 C15.2,16 16,15.2 16,14.2222222 L16,1.77777778 C16,0.8 15.2,0 14.2222222,0 L1.77777778,0 Z" id="Shape" fill="#1E70EB"></path>
<polygon id="Path" fill="#FFFFFF" points="1 8.19230769 2.4 6.84615385 6 10.3076923 13.6 3 15 4.34615385 6 13"></polygon>
</g>
</g>

Before

Width:  |  Height:  |  Size: 892 B

After

Width:  |  Height:  |  Size: 892 B

@@ -5,7 +5,7 @@
<desc>Created with Sketch.</desc>
<g id="Selection-Controls-/-Checkbox-/-Partial-Selected" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="Group">
<rect id="Rectangle-10" fill="#7092A7" x="0" y="0" width="16" height="16" rx="2"></rect>
<rect id="Rectangle-10" fill="#2A4875" x="0" y="0" width="16" height="16" rx="2"></rect>
<rect id="Rectangle-9" fill="#BBBBBB" x="3" y="7" width="10" height="2"></rect>
</g>
</g>

Before

Width:  |  Height:  |  Size: 728 B

After

Width:  |  Height:  |  Size: 728 B

@@ -5,7 +5,7 @@
<desc>Created with Sketch.</desc>
<g id="Selection-Controls-/-Checkbox-/-Partial-Selected" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="Group">
<path d="M14.2222222,0.5 L1.77777778,0.5 C1.07614237,0.5 0.5,1.07614237 0.5,1.77777778 L0.5,14.2222222 C0.5,14.9238576 1.07614237,15.5 1.77777778,15.5 L14.2222222,15.5 C14.9238576,15.5 15.5,14.9238576 15.5,14.2222222 L15.5,1.77777778 C15.5,1.07614237 14.9238576,0.5 14.2222222,0.5 Z" id="Shape" stroke="#00A1C9" fill="#0073BB"></path>
<path d="M14.2222222,0.5 L1.77777778,0.5 C1.07614237,0.5 0.5,1.07614237 0.5,1.77777778 L0.5,14.2222222 C0.5,14.9238576 1.07614237,15.5 1.77777778,15.5 L14.2222222,15.5 C14.9238576,15.5 15.5,14.9238576 15.5,14.2222222 L15.5,1.77777778 C15.5,1.07614237 14.9238576,0.5 14.2222222,0.5 Z" id="Shape" stroke="#4B8CEF" fill="#1E70EB"></path>
<rect id="Rectangle-9" fill="#FFFFFF" x="3" y="7" width="10" height="2"></rect>
</g>
</g>

Before

Width:  |  Height:  |  Size: 974 B

After

Width:  |  Height:  |  Size: 974 B

@@ -5,7 +5,7 @@
<desc>Created with Sketch.</desc>
<g id="Selection-Controls-/-Checkbox-/-Partial-Selected" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="Group">
<rect id="Rectangle-10" fill="#0073BB" x="0" y="0" width="16" height="16" rx="2"></rect>
<rect id="Rectangle-10" fill="#1E70EB" x="0" y="0" width="16" height="16" rx="2"></rect>
<rect id="Rectangle-9" fill="#FFFFFF" x="3" y="7" width="10" height="2"></rect>
</g>
</g>

Before

Width:  |  Height:  |  Size: 728 B

After

Width:  |  Height:  |  Size: 728 B

@@ -4,7 +4,7 @@
<title>Selection Controls / Radio Button / On - Disabled</title>
<desc>Created with Sketch.</desc>
<g id="Selection-Controls-/-Radio-Button-/-On---Disabled" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<circle id="Oval" fill="#7092A7" cx="8" cy="8" r="8"></circle>
<circle id="Oval" fill="#2A4875" cx="8" cy="8" r="8"></circle>
<circle id="Oval" fill="#BBBBBB" cx="8" cy="8" r="4"></circle>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 643 B

After

Width:  |  Height:  |  Size: 643 B

@@ -4,7 +4,7 @@
<title>Selection Controls / Radio Button / On-focus</title>
<desc>Created with Sketch.</desc>
<g id="Selection-Controls-/-Radio-Button-/-On-focus" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<circle id="Oval" stroke="#00A1C9" fill="#0073BB" cx="9" cy="9" r="8.5"></circle>
<circle id="Oval" stroke="#4B8CEF" fill="#1E70EB" cx="9" cy="9" r="8.5"></circle>
<circle id="Oval" fill="#FFFFFF" cx="9" cy="9" r="4"></circle>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 647 B

After

Width:  |  Height:  |  Size: 647 B

@@ -5,7 +5,7 @@
<desc>Created with Sketch.</desc>
<g id="Selection-Controls-/-Radio-Button-/-On" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="radio-button-(on)">
<circle id="Oval" fill="#0073BB" cx="8" cy="8" r="8"></circle>
<circle id="Oval" fill="#1E70EB" cx="8" cy="8" r="8"></circle>
<circle id="Oval" fill="#FFFFFF" cx="8" cy="8" r="4"></circle>
</g>
</g>

Before

Width:  |  Height:  |  Size: 677 B

After

Width:  |  Height:  |  Size: 677 B

@@ -4,7 +4,7 @@
<title>Selection Controls / Radio Button / Off-focus</title>
<desc>Created with Sketch.</desc>
<g id="Selection-Controls-/-Radio-Button-/-Off-focus" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="radio-button-(off)" transform="translate(1.000000, 1.000000)" stroke="#00A1C9">
<g id="radio-button-(off)" transform="translate(1.000000, 1.000000)" stroke="#4B8CEF">
<circle id="Oval" cx="8" cy="8" r="8.5"></circle>
</g>
</g>

Before

Width:  |  Height:  |  Size: 658 B

After

Width:  |  Height:  |  Size: 658 B

@@ -5,7 +5,7 @@
<desc>Created with Sketch.</desc>
<g id="Selection-Controls-/-Switch-/-On---Disabled" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="switch-(on)">
<path d="M25.4117647,16 L6.58823529,16 C2.91764706,16 0,12.4571429 0,8 C0,3.54285714 2.91764706,0 6.58823529,0 L25.4117647,0 C29.0823529,0 32,3.54285714 32,8 C32,12.4571429 29.0823529,16 25.4117647,16 Z" id="track" fill="#7092A7"></path>
<path d="M25.4117647,16 L6.58823529,16 C2.91764706,16 0,12.4571429 0,8 C0,3.54285714 2.91764706,0 6.58823529,0 L25.4117647,0 C29.0823529,0 32,3.54285714 32,8 C32,12.4571429 29.0823529,16 25.4117647,16 Z" id="track" fill="#2A4875"></path>
<circle id="knob" fill="#BBBBBB" cx="24" cy="8" r="6"></circle>
</g>
</g>

Before

Width:  |  Height:  |  Size: 857 B

After

Width:  |  Height:  |  Size: 857 B

@@ -5,7 +5,7 @@
<desc>Created with Sketch.</desc>
<g id="Selection-Controls-/-Switch-/-On-focus" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="switch-(on)" transform="translate(1.000000, 1.000000)">
<path d="M25.4117647,16.5 L6.58823529,16.5 C2.61773665,16.5 -0.5,12.7141769 -0.5,8 C-0.5,3.28582307 2.61773665,-0.5 6.58823529,-0.5 L25.4117647,-0.5 C29.3822634,-0.5 32.5,3.28582307 32.5,8 C32.5,12.7141769 29.3822634,16.5 25.4117647,16.5 Z" id="track" stroke="#00A1C9" fill="#0073BB"></path>
<path d="M25.4117647,16.5 L6.58823529,16.5 C2.61773665,16.5 -0.5,12.7141769 -0.5,8 C-0.5,3.28582307 2.61773665,-0.5 6.58823529,-0.5 L25.4117647,-0.5 C29.3822634,-0.5 32.5,3.28582307 32.5,8 C32.5,12.7141769 29.3822634,16.5 25.4117647,16.5 Z" id="track" stroke="#4B8CEF" fill="#1E70EB"></path>
<circle id="knob" fill="#FFFFFF" cx="24" cy="8" r="6"></circle>
</g>
</g>

Before

Width:  |  Height:  |  Size: 938 B

After

Width:  |  Height:  |  Size: 938 B

@@ -5,7 +5,7 @@
<desc>Created with Sketch.</desc>
<g id="Selection-Controls-/-Switch-/-On" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="switch-(on)">
<path d="M25.4117647,16 L6.58823529,16 C2.91764706,16 0,12.4571429 0,8 C0,3.54285714 2.91764706,0 6.58823529,0 L25.4117647,0 C29.0823529,0 32,3.54285714 32,8 C32,12.4571429 29.0823529,16 25.4117647,16 Z" id="track" fill="#0073BB"></path>
<path d="M25.4117647,16 L6.58823529,16 C2.91764706,16 0,12.4571429 0,8 C0,3.54285714 2.91764706,0 6.58823529,0 L25.4117647,0 C29.0823529,0 32,3.54285714 32,8 C32,12.4571429 29.0823529,16 25.4117647,16 Z" id="track" fill="#1E70EB"></path>
<circle id="knob" fill="#FFFFFF" cx="24" cy="8" r="6"></circle>
</g>
</g>

Before

Width:  |  Height:  |  Size: 835 B

After

Width:  |  Height:  |  Size: 835 B

@@ -5,7 +5,7 @@
<desc>Created with Sketch.</desc>
<g id="Selection-Controls-/-Switch-/-Off-focus" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="switch-(off)" transform="translate(1.000000, 1.000000)">
<path d="M25.0231909,16.5 L7.01632718,16.5 C2.97419648,16.5 -0.5,12.6299076 -0.5,8 C-0.5,3.37009242 2.97419648,-0.5 7.01632718,-0.5 L25.0231909,-0.5 C29.0586432,-0.5 32.5,3.36297526 32.5,8 C32.5,12.6370247 29.0586432,16.5 25.0231909,16.5 Z" id="track" stroke="#00A1C9"></path>
<path d="M25.0231909,16.5 L7.01632718,16.5 C2.97419648,16.5 -0.5,12.6299076 -0.5,8 C-0.5,3.37009242 2.97419648,-0.5 7.01632718,-0.5 L25.0231909,-0.5 C29.0586432,-0.5 32.5,3.36297526 32.5,8 C32.5,12.6370247 29.0586432,16.5 25.0231909,16.5 Z" id="track" stroke="#4B8CEF"></path>
<circle id="knob" fill="#FFFFFF" cx="8" cy="8" r="6"></circle>
</g>
</g>

Before

Width:  |  Height:  |  Size: 925 B

After

Width:  |  Height:  |  Size: 925 B

@@ -1,6 +1,6 @@
<svg version="1.1" class="loader" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="40px" height="40px" viewBox="0 0 50 50" style="enable-background:new 0 0 50 50;" xml:space="preserve">
<path fill="#54AFD0" d="M43.935,25.145c0-10.318-8.364-18.683-18.683-18.683c-10.318,0-18.683,8.365-18.683,18.683h4.068c0-8.071,6.543-14.615,14.615-14.615c8.072,0,14.615,6.543,14.615,14.615H43.935z">
<path fill="#1E70EB" d="M43.935,25.145c0-10.318-8.364-18.683-18.683-18.683c-10.318,0-18.683,8.365-18.683,18.683h4.068c0-8.071,6.543-14.615,14.615-14.615c8.072,0,14.615,6.543,14.615,14.615H43.935z">
<animateTransform attributeType="xml"
attributeName="transform"
type="rotate"

Before

Width:  |  Height:  |  Size: 878 B

After

Width:  |  Height:  |  Size: 878 B

@@ -53,8 +53,8 @@ namespace AzToolsFramework
static constexpr const char* FolderIconPath = "Editor/Icons/AssetBrowser/Folder_16.svg";
static constexpr const char* GemIconPath = "Editor/Icons/AssetBrowser/GemFolder_16.svg";
FolderThumbnail::FolderThumbnail(SharedThumbnailKey key, int thumbnailSize)
: Thumbnail(key, thumbnailSize)
FolderThumbnail::FolderThumbnail(SharedThumbnailKey key)
: Thumbnail(key)
{}
void FolderThumbnail::LoadThread()
@@ -69,7 +69,8 @@ namespace AzToolsFramework
AZStd::string absoluteIconPath;
AZ::StringFunc::Path::Join(engineRoot, folderIcon, absoluteIconPath);
m_icon = QIcon(absoluteIconPath.c_str());
m_pixmap.load(absoluteIconPath.c_str());
m_state = m_pixmap.isNull() ? State::Failed : State::Ready;
}
//////////////////////////////////////////////////////////////////////////
@@ -47,7 +47,7 @@ namespace AzToolsFramework
{
Q_OBJECT
public:
FolderThumbnail(SharedThumbnailKey key, int thumbnailSize);
FolderThumbnail(SharedThumbnailKey key);
void LoadThread() override;
};
@@ -57,8 +57,8 @@ namespace AzToolsFramework
//////////////////////////////////////////////////////////////////////////
static const char* DEFAULT_PRODUCT_ICON_PATH = "Editor/Icons/AssetBrowser/DefaultProduct_16.svg";
ProductThumbnail::ProductThumbnail(Thumbnailer::SharedThumbnailKey key, int thumbnailSize)
: Thumbnail(key, thumbnailSize)
ProductThumbnail::ProductThumbnail(Thumbnailer::SharedThumbnailKey key)
: Thumbnail(key)
{}
void ProductThumbnail::LoadThread()
@@ -96,12 +96,8 @@ namespace AzToolsFramework
iconPath = QString::fromUtf8(DEFAULT_PRODUCT_ICON_PATH);
}
m_icon = QIcon(iconPath);
if (m_icon.isNull())
{
m_state = State::Failed;
}
m_pixmap.load(iconPath);
m_state = m_pixmap.isNull() ? State::Failed : State::Ready;
}
//////////////////////////////////////////////////////////////////////////
@@ -44,7 +44,7 @@ namespace AzToolsFramework
{
Q_OBJECT
public:
ProductThumbnail(Thumbnailer::SharedThumbnailKey key, int thumbnailSize);
ProductThumbnail(Thumbnailer::SharedThumbnailKey key);
protected:
void LoadThread() override;
@@ -58,8 +58,8 @@ namespace AzToolsFramework
static constexpr const char* DefaultFileIconPath = "Editor/Icons/AssetBrowser/Default_16.svg";
QMutex SourceThumbnail::m_mutex;
SourceThumbnail::SourceThumbnail(SharedThumbnailKey key, int thumbnailSize)
: Thumbnail(key, thumbnailSize)
SourceThumbnail::SourceThumbnail(SharedThumbnailKey key)
: Thumbnail(key)
{
}
@@ -124,7 +124,8 @@ namespace AzToolsFramework
iconPathToUse = iconPath.c_str();
}
m_icon = QIcon(iconPathToUse);
m_pixmap.load(iconPathToUse);
m_state = m_pixmap.isNull() ? State::Failed : State::Ready;
}
//////////////////////////////////////////////////////////////////////////
@@ -44,7 +44,7 @@ namespace AzToolsFramework
{
Q_OBJECT
public:
SourceThumbnail(SharedThumbnailKey key, int thumbnailSize);
SourceThumbnail(SharedThumbnailKey key);
protected:
void LoadThread() override;
@@ -140,7 +140,7 @@ namespace AzToolsFramework
else
{
// Scaling and centering pixmap within bounds to preserve aspect ratio
const QPixmap pixmap = thumbnail->GetPixmap(size).scaled(size, Qt::KeepAspectRatio, Qt::SmoothTransformation);
const QPixmap pixmap = thumbnail->GetPixmap().scaled(size, Qt::KeepAspectRatio, Qt::SmoothTransformation);
const QSize sizeDelta = size - pixmap.size();
const QPoint pointDelta = QPoint(sizeDelta.width() / 2, sizeDelta.height() / 2);
painter->drawPixmap(point + pointDelta, pixmap);
@@ -36,8 +36,7 @@ namespace AzToolsFramework
using namespace Thumbnailer;
using namespace AssetBrowser;
const char* contextName = "MaterialBrowser";
int thumbnailSize = qApp->style()->pixelMetric(QStyle::PM_SmallIconSize);
ThumbnailerRequestsBus::Broadcast(&ThumbnailerRequests::RegisterContext, contextName, thumbnailSize);
ThumbnailerRequestsBus::Broadcast(&ThumbnailerRequests::RegisterContext, contextName);
ThumbnailerRequestsBus::Broadcast(&ThumbnailerRequests::RegisterThumbnailProvider, MAKE_TCACHE(FolderThumbnailCache), contextName);
ThumbnailerRequestsBus::Broadcast(&ThumbnailerRequests::RegisterThumbnailProvider, MAKE_TCACHE(SourceThumbnailCache), contextName);
ThumbnailerRequestsBus::Broadcast(&ThumbnailerRequests::RegisterThumbnailProvider, MAKE_TCACHE(MaterialThumbnailCache), contextName);
@@ -24,8 +24,8 @@ namespace AzToolsFramework
//////////////////////////////////////////////////////////////////////////
// MaterialThumbnail
//////////////////////////////////////////////////////////////////////////
MaterialThumbnail::MaterialThumbnail(Thumbnailer::SharedThumbnailKey key, int thumbnailSize)
: Thumbnail(key, thumbnailSize)
MaterialThumbnail::MaterialThumbnail(Thumbnailer::SharedThumbnailKey key)
: Thumbnail(key)
{
auto productKey = azrtti_cast<const AzToolsFramework::AssetBrowser::ProductThumbnailKey*>(m_key.data());
AZ_Assert(productKey, "Incorrect key type, excpected ProductThumbnailKey");
@@ -34,7 +34,8 @@ namespace AzToolsFramework
MaterialBrowserRequestBus::BroadcastResult(multiMat, &MaterialBrowserRequests::IsMultiMaterial, productKey->GetAssetId());
QString iconPath = multiMat ? MultiMaterialIconPath : SimpleMaterialIconPath;
m_pixmap = QPixmap(iconPath).scaled(m_thumbnailSize, m_thumbnailSize, Qt::KeepAspectRatio);
m_pixmap.load(iconPath);
m_state = m_pixmap.isNull() ? State::Failed : State::Ready;
}
//////////////////////////////////////////////////////////////////////////
@@ -28,7 +28,7 @@ namespace AzToolsFramework
{
Q_OBJECT
public:
MaterialThumbnail(Thumbnailer::SharedThumbnailKey key, int thumbnailSize);
MaterialThumbnail(Thumbnailer::SharedThumbnailKey key);
};
namespace
@@ -16,7 +16,6 @@
#include <AzCore/Serialization/EditContext.h>
#include <AzToolsFramework/Prefab/PrefabPublicInterface.h>
#include <AzToolsFramework/UI/EditorEntityUi/EditorEntityUiInterface.h>
#include <AzToolsFramework/UI/Outliner/EntityOutlinerWidgetInterface.h>
#include <AzToolsFramework/UI/Prefab/PrefabIntegrationBus.h>
namespace AzToolsFramework
@@ -21,9 +21,9 @@
#include <AzToolsFramework/Prefab/Instance/TemplateInstanceMapperInterface.h>
#include <AzToolsFramework/Prefab/PrefabDomUtils.h>
#include <AzToolsFramework/Prefab/PrefabPublicInterface.h>
#include <AzToolsFramework/Prefab/PrefabPublicNotificationBus.h>
#include <AzToolsFramework/Prefab/PrefabSystemComponentInterface.h>
#include <AzToolsFramework/Prefab/Template/Template.h>
#include <AzToolsFramework/UI/Outliner/EntityOutlinerWidgetInterface.h>
namespace AzToolsFramework
{
@@ -90,17 +90,13 @@ namespace AzToolsFramework
if (instanceCountToUpdateInBatch > 0)
{
// Notify Propagation has begun
PrefabPublicNotificationBus::Broadcast(&PrefabPublicNotifications::OnPrefabInstancePropagationBegin);
EntityIdList selectedEntityIds;
ToolsApplicationRequestBus::BroadcastResult(selectedEntityIds, &ToolsApplicationRequests::GetSelectedEntities);
ToolsApplicationRequestBus::Broadcast(&ToolsApplicationRequests::SetSelectedEntities, EntityIdList());
// Disable the Outliner to avoid showing the propagation steps
EntityOutlinerWidgetInterface* entityOutlinerWidgetInterface = AZ::Interface<EntityOutlinerWidgetInterface>::Get();
if (entityOutlinerWidgetInterface)
{
entityOutlinerWidgetInterface->SetUpdatesEnabled(false);
}
for (int i = 0; i < instanceCountToUpdateInBatch; ++i)
{
Instance* instanceToUpdate = m_instancesUpdateQueue.front();
@@ -168,18 +164,8 @@ namespace AzToolsFramework
}
ToolsApplicationRequestBus::Broadcast(&ToolsApplicationRequests::SetSelectedEntities, selectedEntityIds);
// Enable the Outliner
if (entityOutlinerWidgetInterface)
{
entityOutlinerWidgetInterface->SetUpdatesEnabled(true);
auto prefabPublicInterface = AZ::Interface<PrefabPublicInterface>::Get();
if (prefabPublicInterface)
{
AZ::EntityId rootEntityId = prefabPublicInterface->GetLevelInstanceContainerEntityId();
entityOutlinerWidgetInterface->ExpandEntityChildren(rootEntityId);
}
}
// Notify Propagation has ended
PrefabPublicNotificationBus::Broadcast(&PrefabPublicNotifications::OnPrefabInstancePropagationEnd);
}
m_updatingTemplateInstancesInQueue = false;
@@ -0,0 +1,34 @@
/*
* 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 <AzCore/EBus/EBus.h>
namespace AzToolsFramework
{
namespace Prefab
{
class PrefabPublicNotifications
: public AZ::EBusTraits
{
public:
virtual ~PrefabPublicNotifications() = default;
virtual void OnPrefabInstancePropagationBegin() {}
virtual void OnPrefabInstancePropagationEnd() {}
};
using PrefabPublicNotificationBus = AZ::EBus<PrefabPublicNotifications>;
} // namespace Prefab
} // namespace AzToolsFramework
@@ -18,13 +18,15 @@ namespace AzToolsFramework
{
namespace Thumbnailer
{
static constexpr const int LoadingThumbnailSize = 128;
//////////////////////////////////////////////////////////////////////////
// LoadingThumbnail
//////////////////////////////////////////////////////////////////////////
static const char* LoadingIconPath = "Editor/Icons/AssetBrowser/in_progress.gif";
LoadingThumbnail::LoadingThumbnail(int thumbnailSize)
: Thumbnail(MAKE_TKEY(ThumbnailKey), thumbnailSize)
LoadingThumbnail::LoadingThumbnail()
: Thumbnail(MAKE_TKEY(ThumbnailKey))
, m_angle(0)
{
const char* engineRoot = nullptr;
@@ -34,7 +36,7 @@ namespace AzToolsFramework
AZ::StringFunc::Path::Join(engineRoot, LoadingIconPath, iconPath);
m_loadingMovie.setFileName(iconPath.c_str());
m_loadingMovie.setCacheMode(QMovie::CacheMode::CacheAll);
m_loadingMovie.setScaledSize(QSize(m_thumbnailSize, m_thumbnailSize));
m_loadingMovie.setScaledSize(QSize(LoadingThumbnailSize, LoadingThumbnailSize));
m_loadingMovie.start();
m_pixmap = m_loadingMovie.currentPixmap();
m_state = State::Ready;
@@ -29,7 +29,7 @@ namespace AzToolsFramework
{
Q_OBJECT
public:
explicit LoadingThumbnail(int thumbnailSize);
LoadingThumbnail();
~LoadingThumbnail() override;
void UpdateTime(float /*deltaTime*/) override;
@@ -18,11 +18,11 @@ namespace AzToolsFramework
{
static const char* MISSING_ICON_PATH = "Editor/Icons/AssetBrowser/Default_16.svg";
MissingThumbnail::MissingThumbnail(int thumbnailSize)
: Thumbnail(MAKE_TKEY(ThumbnailKey), thumbnailSize)
MissingThumbnail::MissingThumbnail()
: Thumbnail(MAKE_TKEY(ThumbnailKey))
{
m_icon = QIcon(MISSING_ICON_PATH);
m_state = State::Ready;
m_pixmap.load(MISSING_ICON_PATH);
m_state = m_pixmap.isNull() ? State::Failed : State::Ready;
}
} // namespace Thumbnailer
@@ -24,7 +24,7 @@ namespace AzToolsFramework
{
Q_OBJECT
public:
explicit MissingThumbnail(int thumbnailSize);
MissingThumbnail();
};
} // namespace Thumbnailer
} // namespace AzToolsFramework
@@ -69,8 +69,8 @@ namespace AzToolsFramework
bool SourceControlThumbnail::m_readyForUpdate = true;
SourceControlThumbnail::SourceControlThumbnail(SharedThumbnailKey key, int thumbnailSize)
: Thumbnail(key, thumbnailSize)
SourceControlThumbnail::SourceControlThumbnail(SharedThumbnailKey key)
: Thumbnail(key)
{
const char* engineRoot = nullptr;
AzFramework::ApplicationRequests::Bus::BroadcastResult(engineRoot, &AzFramework::ApplicationRequests::GetEngineRoot);
@@ -122,16 +122,16 @@ namespace AzToolsFramework
{
if (fileInfo.HasFlag(AzToolsFramework::SCF_Writeable))
{
m_icon = QIcon(m_writableIconPath.c_str());
m_pixmap.load(m_writableIconPath.c_str());
}
else
{
m_icon = QIcon(m_nonWritableIconPath.c_str());
m_pixmap.load(m_nonWritableIconPath.c_str());
}
}
else
{
m_icon = QIcon();
m_pixmap = QPixmap();
}
m_readyForUpdate = true;
emit Updated();
@@ -55,7 +55,7 @@ namespace AzToolsFramework
{
Q_OBJECT
public:
SourceControlThumbnail(SharedThumbnailKey key, int thumbnailSize);
SourceControlThumbnail(SharedThumbnailKey key);
~SourceControlThumbnail() override;
//////////////////////////////////////////////////////////////////////////
@@ -24,8 +24,6 @@ namespace AzToolsFramework
{
namespace Thumbnailer
{
static const int DefaultIconSize = 16;
//////////////////////////////////////////////////////////////////////////
// ThumbnailKey
//////////////////////////////////////////////////////////////////////////
@@ -54,10 +52,9 @@ namespace AzToolsFramework
//////////////////////////////////////////////////////////////////////////
// Thumbnail
//////////////////////////////////////////////////////////////////////////
Thumbnail::Thumbnail(SharedThumbnailKey key, int thumbnailSize)
Thumbnail::Thumbnail(SharedThumbnailKey key)
: QObject()
, m_state(State::Unloaded)
, m_thumbnailSize(thumbnailSize)
, m_key(key)
{
connect(&m_watcher, &QFutureWatcher<void>::finished, this, [this]()
@@ -91,19 +88,9 @@ namespace AzToolsFramework
}
}
QPixmap Thumbnail::GetPixmap() const
const QPixmap& Thumbnail::GetPixmap() const
{
return GetPixmap(QSize(DefaultIconSize, DefaultIconSize));
}
QPixmap Thumbnail::GetPixmap(const QSize& size) const
{
if (m_icon.isNull())
{
return m_pixmap;
}
return m_icon.pixmap(size);
return m_pixmap;
}
SharedThumbnailKey Thumbnail::GetKey() const
@@ -19,7 +19,6 @@ AZ_PUSH_DISABLE_WARNING(4127 4251 4800, "-Wunknown-warning-option") // 4127: con
// 4800: 'int': forcing value to bool 'true' or 'false' (performance warning)
#include <QObject>
#include <QPixmap>
#include <QIcon>
#include <QFutureWatcher>
AZ_POP_DISABLE_WARNING
#endif
@@ -86,12 +85,11 @@ namespace AzToolsFramework
Failed
};
Thumbnail(SharedThumbnailKey key, int thumbnailSize);
Thumbnail(SharedThumbnailKey key);
~Thumbnail() override;
bool operator == (const Thumbnail& other) const;
void Load();
virtual QPixmap GetPixmap() const;
virtual QPixmap GetPixmap(const QSize& size) const;
const QPixmap& GetPixmap() const;
virtual void UpdateTime(float /*deltaTime*/) {}
SharedThumbnailKey GetKey() const;
State GetState() const;
@@ -105,10 +103,8 @@ namespace AzToolsFramework
protected:
QFutureWatcher<void> m_watcher;
State m_state;
int m_thumbnailSize;
SharedThumbnailKey m_key;
QPixmap m_pixmap;
QIcon m_icon;
virtual void LoadThread() {}
};
@@ -122,7 +118,6 @@ namespace AzToolsFramework
ThumbnailProvider() = default;
virtual ~ThumbnailProvider() = default;
virtual bool GetThumbnail(SharedThumbnailKey key, SharedThumbnail& thumbnail) = 0;
virtual void SetThumbnailSize(int thumbnailSize) = 0;
//! Priority identifies ThumbnailProvider order in ThumbnailContext
//! Higher priority means this ThumbnailProvider will take precedence in generating a thumbnail when
//! a supplied ThumbnailKey is supported by multiple providers.
@@ -185,10 +180,7 @@ namespace AzToolsFramework
bool GetThumbnail(SharedThumbnailKey key, SharedThumbnail& thumbnail) override;
void SetThumbnailSize(int thumbnailSize) override;
protected:
int m_thumbnailSize;
AZStd::unordered_map<SharedThumbnailKey, SharedThumbnail, Hasher, EqualKey> m_cache;
//! Check if thumbnail key is handled by this provider, overload in derived class
@@ -18,7 +18,6 @@ namespace AzToolsFramework
{
template <class ThumbnailType, class Hasher, class EqualKey>
ThumbnailCache<ThumbnailType, Hasher, EqualKey>::ThumbnailCache()
: m_thumbnailSize(0)
{
BusConnect();
}
@@ -49,17 +48,11 @@ namespace AzToolsFramework
}
if (IsSupportedThumbnail(key))
{
thumbnail = QSharedPointer<ThumbnailType>(new ThumbnailType(key, m_thumbnailSize));
thumbnail = QSharedPointer<ThumbnailType>(new ThumbnailType(key));
m_cache[key] = thumbnail;
return true;
}
return false;
}
template <class ThumbnailType, class Hasher, class EqualKey>
void ThumbnailCache<ThumbnailType, Hasher, EqualKey>::SetThumbnailSize(int thumbnailSize)
{
m_thumbnailSize = thumbnailSize;
}
} // namespace Thumbnailer
} // namespace AzToolsFramework
@@ -24,10 +24,9 @@ namespace AzToolsFramework
{
namespace Thumbnailer
{
ThumbnailContext::ThumbnailContext(int thumbnailSize)
: m_missingThumbnail(new MissingThumbnail(thumbnailSize))
, m_loadingThumbnail(new LoadingThumbnail(thumbnailSize))
, m_thumbnailSize(thumbnailSize)
ThumbnailContext::ThumbnailContext()
: m_missingThumbnail(new MissingThumbnail())
, m_loadingThumbnail(new LoadingThumbnail())
, m_threadPool(this)
{
ThumbnailContextRequestBus::Handler::BusConnect();
@@ -120,7 +119,6 @@ namespace AzToolsFramework
return;
}
providerToAdd->SetThumbnailSize(m_thumbnailSize);
m_providers.insert(providerToAdd);
}
@@ -45,9 +45,9 @@ namespace AzToolsFramework
{
Q_OBJECT
public:
AZ_CLASS_ALLOCATOR(ThumbnailContext, AZ::SystemAllocator, 0)
AZ_CLASS_ALLOCATOR(ThumbnailContext, AZ::SystemAllocator, 0);
explicit ThumbnailContext(int thumbnailSize);
ThumbnailContext();
~ThumbnailContext() override;
//! Is the thumbnail currently loading or is about to load.
@@ -82,8 +82,6 @@ namespace AzToolsFramework
SharedThumbnail m_missingThumbnail;
//! Default loading thumbnail used when thumbnail is found by is not yet generated
SharedThumbnail m_loadingThumbnail;
//! Thumbnail size (width and height in pixels)
int m_thumbnailSize;
//! There is only a limited number of threads on global threadPool, because there can be many thumbnails rendering at once
//! an individual threadPool is needed to avoid deadlocks
QThreadPool m_threadPool;
@@ -40,7 +40,7 @@ namespace AzToolsFramework
{
public:
//! Add thumbnail context
virtual void RegisterContext(const char* contextName, int thumbnailSize) = 0;
virtual void RegisterContext(const char* contextName) = 0;
//! Remove thumbnail context and all associated ThumbnailProviders
virtual void UnregisterContext(const char* contextName) = 0;
@@ -32,8 +32,7 @@ namespace AzToolsFramework
void ThumbnailerComponent::Activate()
{
int thumbnailSize = qApp->style()->pixelMetric(QStyle::PM_SmallIconSize);
RegisterContext(ThumbnailContext::DefaultContext, thumbnailSize);
RegisterContext(ThumbnailContext::DefaultContext);
BusConnect();
}
@@ -62,10 +61,10 @@ namespace AzToolsFramework
provided.push_back(AZ_CRC("ThumbnailerService", 0x65422b97));
}
void ThumbnailerComponent::RegisterContext(const char* contextName, int thumbnailSize)
void ThumbnailerComponent::RegisterContext(const char* contextName)
{
AZ_Assert(m_thumbnails.find(contextName) == m_thumbnails.end(), "Context %s already registered", contextName);
m_thumbnails[contextName] = AZStd::make_shared<ThumbnailContext>(thumbnailSize);
m_thumbnails[contextName] = AZStd::make_shared<ThumbnailContext>();
}
void ThumbnailerComponent::UnregisterContext(const char* contextName)
@@ -43,7 +43,7 @@ namespace AzToolsFramework
//////////////////////////////////////////////////////////////////////////
// ThumbnailerRequests
//////////////////////////////////////////////////////////////////////////
void RegisterContext(const char* contextName, int thumbnailSize) override;
void RegisterContext(const char* contextName) override;
void UnregisterContext(const char* contextName) override;
bool HasContext(const char* contextName) const override;
void RegisterThumbnailProvider(SharedThumbnailProvider provider, const char* contextName) override;
@@ -286,12 +286,12 @@ namespace AzToolsFramework
ComponentModeFramework::EditorComponentModeNotificationBus::Handler::BusConnect(
GetEntityContextId());
EditorEntityInfoNotificationBus::Handler::BusConnect();
AZ::Interface<EntityOutlinerWidgetInterface>::Register(this);
Prefab::PrefabPublicNotificationBus::Handler::BusConnect();
}
EntityOutlinerWidget::~EntityOutlinerWidget()
{
AZ::Interface<EntityOutlinerWidgetInterface>::Unregister(this);
Prefab::PrefabPublicNotificationBus::Handler::BusDisconnect();
ComponentModeFramework::EditorComponentModeNotificationBus::Handler::BusDisconnect();
EditorEntityInfoNotificationBus::Handler::BusDisconnect();
EditorPickModeNotificationBus::Handler::BusDisconnect();
@@ -1109,25 +1109,18 @@ namespace AzToolsFramework
setEnabled(true);
SetEntityOutlinerState(m_gui, true);
}
void EntityOutlinerWidget::SetUpdatesEnabled(bool enable)
void EntityOutlinerWidget::OnPrefabInstancePropagationBegin()
{
if (enable)
{
QTimer::singleShot(1, this, [this]() {
m_gui->m_objectTree->setUpdatesEnabled(true);
});
}
else
{
m_gui->m_objectTree->setUpdatesEnabled(false);
}
m_gui->m_objectTree->setUpdatesEnabled(false);
}
void EntityOutlinerWidget::ExpandEntityChildren(AZ::EntityId entityId)
void EntityOutlinerWidget::OnPrefabInstancePropagationEnd()
{
QModelIndex index = GetIndexFromEntityId(entityId);
m_gui->m_objectTree->expand(index);
QTimer::singleShot(1, this, [this]() {
m_gui->m_objectTree->setUpdatesEnabled(true);
m_gui->m_objectTree->expand(m_proxyModel->index(0,0));
});
}
void EntityOutlinerWidget::OnEntityInfoUpdatedAddChildEnd(AZ::EntityId /*parentId*/, AZ::EntityId childId)
@@ -20,10 +20,10 @@
#include <AzToolsFramework/ComponentMode/EditorComponentModeBus.h>
#include <AzToolsFramework/Entity/EditorEntityInfoBus.h>
#include <AzToolsFramework/Entity/EditorEntityContextBus.h>
#include <AzToolsFramework/Prefab/PrefabPublicNotificationBus.h>
#include <AzToolsFramework/ToolsMessaging/EntityHighlightBus.h>
#include <AzToolsFramework/UI/Outliner/EntityOutlinerCacheBus.h>
#include <AzToolsFramework/UI/Outliner/EntityOutlinerSearchWidget.h>
#include <AzToolsFramework/UI/Outliner/EntityOutlinerWidgetInterface.h>
#include <AzToolsFramework/UI/SearchWidget/SearchWidgetTypes.hxx>
#include <QIcon>
@@ -62,7 +62,7 @@ namespace AzToolsFramework
, private EditorEntityContextNotificationBus::Handler
, private EditorEntityInfoNotificationBus::Handler
, private ComponentModeFramework::EditorComponentModeNotificationBus::Handler
, private EntityOutlinerWidgetInterface
, private Prefab::PrefabPublicNotificationBus::Handler
{
Q_OBJECT;
public:
@@ -106,9 +106,9 @@ namespace AzToolsFramework
void EnteredComponentMode(const AZStd::vector<AZ::Uuid>& componentModeTypes) override;
void LeftComponentMode(const AZStd::vector<AZ::Uuid>& componentModeTypes) override;
// EntityOutlinerWidgetInterface
void SetUpdatesEnabled(bool enable) override;
void ExpandEntityChildren(AZ::EntityId entityId) override;
// PrefabPublicNotificationBus
void OnPrefabInstancePropagationBegin() override;
void OnPrefabInstancePropagationEnd() override;
// Build a selection object from the given entities. Entities already in the Widget's selection buffers are ignored.
template <class EntityIdCollection>
@@ -1,30 +0,0 @@
/*
* 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 <AzCore/Interface/Interface.h>
#include <AzCore/Serialization/SerializeContext.h>
namespace AzToolsFramework
{
class EntityOutlinerWidgetInterface
{
public:
AZ_RTTI(EntityOutlinerWidgetInterface, "{30C0F252-EC84-4196-BF59-EB9E73B8ADCB}");
virtual void SetUpdatesEnabled(bool enable) = 0;
virtual void ExpandEntityChildren(AZ::EntityId entityId) = 0;
};
} // namespace AzToolsFramework
@@ -680,6 +680,13 @@ namespace AzToolsFramework
AzQtComponents::BrowseEdit::removeDropTargetStyle(m_browseEdit);
}
AssetSelectionModel PropertyAssetCtrl::GetAssetSelectionModel()
{
auto selectionModel = AssetSelectionModel::AssetTypeSelection(GetCurrentAssetType());
selectionModel.SetTitle(m_title);
return selectionModel;
}
void PropertyAssetCtrl::UpdateTabOrder()
{
setTabOrder(m_browseEdit, m_editButton);
@@ -1058,6 +1065,11 @@ namespace AzToolsFramework
m_editButton->setIcon(icon);
}
void PropertyAssetCtrl::SetTitle(const QString& title)
{
m_title = title;
}
void PropertyAssetCtrl::SetEditNotifyTarget(void* editNotifyTarget)
{
m_editNotifyTarget = editNotifyTarget;
@@ -1193,7 +1205,16 @@ namespace AzToolsFramework
{
(void)debugName;
if (attrib == AZ_CRC("EditCallback", 0xb74f2ee1))
if (attrib == AZ_CRC_CE("AssetPickerTitle"))
{
AZStd::string title;
attrValue->Read<AZStd::string>(title);
if (!title.empty())
{
GUI->SetTitle(title.c_str());
}
}
else if (attrib == AZ_CRC("EditCallback", 0xb74f2ee1))
{
PropertyAssetCtrl::EditCallbackType* func = azdynamic_cast<PropertyAssetCtrl::EditCallbackType*>(attrValue->GetAttribute());
if (func)
@@ -1283,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"))
{
@@ -89,12 +89,13 @@ namespace AzToolsFramework
void dragLeaveEvent(QDragLeaveEvent* event) override;
void dropEvent(QDropEvent* event) override;
virtual AssetSelectionModel GetAssetSelectionModel() { return AssetSelectionModel::AssetTypeSelection(GetCurrentAssetType()); }
virtual AssetSelectionModel GetAssetSelectionModel();
signals:
void OnAssetIDChanged(AZ::Data::AssetId newAssetID);
protected:
QString m_title;
ThumbnailPropertyCtrl* m_thumbnail = nullptr;
QPushButton* m_errorButton = nullptr;
QToolButton* m_editButton = nullptr;
@@ -191,6 +192,7 @@ namespace AzToolsFramework
//////////////////////////////////////////////////////////////////////////
public slots:
void SetTitle(const QString& title);
void SetEditNotifyTarget(void* editNotifyTarget);
void SetEditNotifyCallback(EditCallbackType* editNotifyCallback); // This is meant to be used with the "EditCallback" Attribute
void SetClearNotifyCallback(ClearCallbackType* clearNotifyCallback); // This is meant to be used with the "ClearNotify" Attribute
@@ -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);
@@ -652,6 +652,7 @@ set(FILES
Prefab/PrefabPublicHandler.h
Prefab/PrefabPublicHandler.cpp
Prefab/PrefabPublicInterface.h
Prefab/PrefabPublicNotificationBus.h
Prefab/PrefabUndo.h
Prefab/PrefabUndo.cpp
Prefab/PrefabUndoCache.cpp
@@ -687,7 +688,6 @@ set(FILES
UI/Outliner/EntityOutlinerDisplayOptionsMenu.cpp
UI/Outliner/EntityOutlinerTreeView.hxx
UI/Outliner/EntityOutlinerTreeView.cpp
UI/Outliner/EntityOutlinerWidgetInterface.h
UI/Outliner/EntityOutlinerWidget.hxx
UI/Outliner/EntityOutlinerWidget.cpp
UI/Outliner/EntityOutlinerCacheBus.h
@@ -85,8 +85,6 @@ namespace UnitTest
{
constexpr const char* contextName1 = "Context1";
constexpr const char* contextName2 = "Context2";
constexpr int thumbnailSize1 = 128;
constexpr int thumbnailSize2 = 256;
auto checkHasContext = [](const char* contextName)
{
@@ -98,12 +96,12 @@ namespace UnitTest
EXPECT_FALSE(checkHasContext(contextName1));
EXPECT_FALSE(checkHasContext(contextName2));
AzToolsFramework::Thumbnailer::ThumbnailerRequestBus::Broadcast(&AzToolsFramework::Thumbnailer::ThumbnailerRequests::RegisterContext, contextName1, thumbnailSize1);
AzToolsFramework::Thumbnailer::ThumbnailerRequestBus::Broadcast(&AzToolsFramework::Thumbnailer::ThumbnailerRequests::RegisterContext, contextName1);
EXPECT_TRUE(checkHasContext(contextName1));
EXPECT_FALSE(checkHasContext(contextName2));
AzToolsFramework::Thumbnailer::ThumbnailerRequestBus::Broadcast(&AzToolsFramework::Thumbnailer::ThumbnailerRequests::RegisterContext, contextName2, thumbnailSize2);
AzToolsFramework::Thumbnailer::ThumbnailerRequestBus::Broadcast(&AzToolsFramework::Thumbnailer::ThumbnailerRequests::RegisterContext, contextName2);
EXPECT_TRUE(checkHasContext(contextName1));
EXPECT_TRUE(checkHasContext(contextName2));
@@ -123,8 +121,6 @@ namespace UnitTest
{
constexpr const char* contextName1 = "Context1";
constexpr const char* contextName2 = "Context2";
constexpr int thumbnailSize1 = 128;
constexpr int thumbnailSize2 = 256;
auto checkHasContext = [](const char* contextName)
{
@@ -133,8 +129,8 @@ namespace UnitTest
return hasContext;
};
AzToolsFramework::Thumbnailer::ThumbnailerRequestBus::Broadcast(&AzToolsFramework::Thumbnailer::ThumbnailerRequests::RegisterContext, contextName1, thumbnailSize1);
AzToolsFramework::Thumbnailer::ThumbnailerRequestBus::Broadcast(&AzToolsFramework::Thumbnailer::ThumbnailerRequests::RegisterContext, contextName2, thumbnailSize2);
AzToolsFramework::Thumbnailer::ThumbnailerRequestBus::Broadcast(&AzToolsFramework::Thumbnailer::ThumbnailerRequests::RegisterContext, contextName1);
AzToolsFramework::Thumbnailer::ThumbnailerRequestBus::Broadcast(&AzToolsFramework::Thumbnailer::ThumbnailerRequests::RegisterContext, contextName2);
EXPECT_TRUE(checkHasContext(contextName1));
EXPECT_TRUE(checkHasContext(contextName2));
@@ -149,12 +145,11 @@ namespace UnitTest
TEST_F(ThumbnailerTests, ThumbnailerComponent_RegisterContextTwice_Assert)
{
constexpr const char* contextName1 = "Context1";
constexpr int thumbnailSize1 = 128;
AzToolsFramework::Thumbnailer::ThumbnailerRequestBus::Broadcast(&AzToolsFramework::Thumbnailer::ThumbnailerRequests::RegisterContext, contextName1, thumbnailSize1);
AzToolsFramework::Thumbnailer::ThumbnailerRequestBus::Broadcast(&AzToolsFramework::Thumbnailer::ThumbnailerRequests::RegisterContext, contextName1);
AZ_TEST_START_TRACE_SUPPRESSION;
AzToolsFramework::Thumbnailer::ThumbnailerRequestBus::Broadcast(&AzToolsFramework::Thumbnailer::ThumbnailerRequests::RegisterContext, contextName1, thumbnailSize1);
AzToolsFramework::Thumbnailer::ThumbnailerRequestBus::Broadcast(&AzToolsFramework::Thumbnailer::ThumbnailerRequests::RegisterContext, contextName1);
AZ_TEST_STOP_TRACE_SUPPRESSION(1);
}