Merge remote-tracking branch 'upstream/development' into Atom/santorac/RemixableMaterialTypes3

Signed-off-by: santorac <55155825+santorac@users.noreply.github.com>
This commit is contained in:
santorac
2022-01-25 20:54:34 -08:00
148 changed files with 2796 additions and 1145 deletions
+5 -50
View File
@@ -17,6 +17,7 @@
#include <AzToolsFramework/Manipulators/ManipulatorManager.h>
#include <AzToolsFramework/ViewportSelection/EditorInteractionSystemViewportSelectionRequestBus.h>
#include <AzToolsFramework/ViewportSelection/EditorSelectionUtil.h>
#include <AzToolsFramework/Viewport/ViewportInteractionHelpers.h>
#include <QApplication>
@@ -33,53 +34,6 @@ namespace SandboxEditor
ViewportManipulatorControllerInstance::~ViewportManipulatorControllerInstance() = default;
AzToolsFramework::ViewportInteraction::MouseButton ViewportManipulatorControllerInstance::GetMouseButton(
const AzFramework::InputChannel& inputChannel)
{
using AzToolsFramework::ViewportInteraction::MouseButton;
using InputButton = AzFramework::InputDeviceMouse::Button;
const auto& id = inputChannel.GetInputChannelId();
if (id == InputButton::Left)
{
return MouseButton::Left;
}
if (id == InputButton::Middle)
{
return MouseButton::Middle;
}
if (id == InputButton::Right)
{
return MouseButton::Right;
}
return MouseButton::None;
}
bool ViewportManipulatorControllerInstance::IsMouseMove(const AzFramework::InputChannel& inputChannel)
{
return inputChannel.GetInputChannelId() == AzFramework::InputDeviceMouse::SystemCursorPosition;
}
AzToolsFramework::ViewportInteraction::KeyboardModifier ViewportManipulatorControllerInstance::GetKeyboardModifier(
const AzFramework::InputChannel& inputChannel)
{
using AzToolsFramework::ViewportInteraction::KeyboardModifier;
using Key = AzFramework::InputDeviceKeyboard::Key;
const auto& id = inputChannel.GetInputChannelId();
if (id == Key::ModifierAltL || id == Key::ModifierAltR)
{
return KeyboardModifier::Alt;
}
if (id == Key::ModifierCtrlL || id == Key::ModifierCtrlR)
{
return KeyboardModifier::Ctrl;
}
if (id == Key::ModifierShiftL || id == Key::ModifierShiftR)
{
return KeyboardModifier::Shift;
}
return KeyboardModifier::None;
}
bool ViewportManipulatorControllerInstance::HandleInputChannelEvent(const AzFramework::ViewportControllerInputEvent& event)
{
// We only care about manipulator and viewport interaction events
@@ -97,6 +51,7 @@ namespace SandboxEditor
using AzToolsFramework::ViewportInteraction::MouseInteractionEvent;
using AzToolsFramework::ViewportInteraction::ProjectedViewportRay;
using AzToolsFramework::ViewportInteraction::ViewportInteractionRequestBus;
using AzToolsFramework::ViewportInteraction::Helpers;
bool interactionHandled = false;
float wheelDelta = 0.0f;
@@ -109,7 +64,7 @@ namespace SandboxEditor
const bool finishedProcessingEvents = event.m_priority == InteractionPriority;
const auto state = event.m_inputChannel.GetState();
if (IsMouseMove(event.m_inputChannel))
if (Helpers::IsMouseMove(event.m_inputChannel))
{
// Cache the ray trace results when doing manipulator interaction checks, no need to recalculate after
if (event.m_priority == ManipulatorPriority)
@@ -136,7 +91,7 @@ namespace SandboxEditor
eventType = MouseEvent::Move;
}
else if (auto mouseButton = GetMouseButton(event.m_inputChannel); mouseButton != MouseButton::None)
else if (auto mouseButton = Helpers::GetMouseButton(event.m_inputChannel); mouseButton != MouseButton::None)
{
const AZ::u32 mouseButtonValue = static_cast<AZ::u32>(mouseButton);
overrideButton = mouseButton;
@@ -178,7 +133,7 @@ namespace SandboxEditor
}
}
}
else if (auto keyboardModifier = GetKeyboardModifier(event.m_inputChannel); keyboardModifier != KeyboardModifier::None)
else if (auto keyboardModifier = Helpers::GetKeyboardModifier(event.m_inputChannel); keyboardModifier != KeyboardModifier::None)
{
if (state == InputChannel::State::Began || state == InputChannel::State::Updated)
{
@@ -35,10 +35,6 @@ namespace SandboxEditor
private:
bool IsDoubleClick(AzToolsFramework::ViewportInteraction::MouseButton) const;
static AzToolsFramework::ViewportInteraction::MouseButton GetMouseButton(const AzFramework::InputChannel& inputChannel);
static bool IsMouseMove(const AzFramework::InputChannel& inputChannel);
static AzToolsFramework::ViewportInteraction::KeyboardModifier GetKeyboardModifier(const AzFramework::InputChannel& inputChannel);
//! Represents the time and location of a click.
struct ClickEvent
{
@@ -49,7 +49,7 @@ namespace AZ
return m_entity->GetId();
}
AZ_Warning("System", false, "Can't get component %p entity ID as it is not attached to an entity yet!", this);
AZ_Warning("System", false, "Can't get component (type: %s, addr: %p) entity ID as it is not attached to an entity yet!", RTTI_GetTypeName(), this);
return EntityId();
}
@@ -60,7 +60,7 @@ namespace AZ
return NamedEntityId(m_entity->GetId(), m_entity->GetName());
}
AZ_Warning("System", false, "Can't get component %p entity ID as it is not attached to an entity yet!", this);
AZ_Warning("System", false, "Can't get component (type: %s, addr: %p) entity ID as it is not attached to an entity yet!", RTTI_GetTypeName(), this);
return NamedEntityId();
}
@@ -230,7 +230,7 @@ namespace AZ
EBUS_EVENT_ID(m_id, EntityBus, OnEntityDeactivated, m_id);
EBUS_EVENT(EntitySystemBus, OnEntityDeactivated, m_id);
AZ_Assert(m_state == State::Active, "Component should be in Active state to br Deactivated!");
AZ_Assert(m_state == State::Active, "Component should be in Active state to be Deactivated!");
SetState(State::Deactivating);
for (ComponentArrayType::reverse_iterator it = m_components.rbegin(); it != m_components.rend(); ++it)
@@ -1668,9 +1668,23 @@ namespace AZ
SerializeContext::ENUM_ACCESS_FOR_READ,
&m_errorLogger
);
if (objectStreamWriteOverrideCB.Invoke<void>(callContext, objectPtr, *classData, classElement))
if (ObjectStreamWriteOverrideResponse writeResponse;
objectStreamWriteOverrideCB.Read<ObjectStreamWriteOverrideResponse>(writeResponse, callContext, objectPtr, *classData, classElement))
{
return false;
switch (writeResponse)
{
case ObjectStreamWriteOverrideResponse::FallbackToDefaultWrite:
break;
case ObjectStreamWriteOverrideResponse::AbortWrite:
m_errorLogger.ReportError(AZStd::string::format("ObjectStream Write Element Override callback has aborted the write for class data %s",
classData->m_name).c_str());
[[fallthrough]];
case ObjectStreamWriteOverrideResponse::CompletedWrite:
return false;
default:
AZ_Error("Serialize", false, "Invalid Response %d returned from the ObjectStream Write Element Override callback", static_cast<int>(writeResponse));
return false;
}
}
else
{
@@ -49,14 +49,24 @@ namespace AZ
static const AZ::Crc32 ObjectStreamWriteElementOverride = AZ_CRC("ObjectStreamWriteElementOverride", 0x35eb659f);
}
enum class ObjectStreamWriteOverrideResponse
{
CompletedWrite,
FallbackToDefaultWrite,
AbortWrite
};
AZ_TYPE_INFO_SPECIALIZE(ObjectStreamWriteOverrideResponse, "{BDF960A8-0F18-4E9D-96DA-F800A122C42D}");
///< Callback that the object stream invokes to override saving an instance of the registered class
///< @param callContext EnumerateInstanceCallContext which contains the WriteElement BeingElemCB and the CloseElement EndElemCB
///< the callContext parameter can be passed to the SerializeContext::EnumerateInstance to continue object stream writing
///< @param classPtr class type which is of pointer to the type represented by the m_typeId value
///< @param classData reference to this instance Class Data that will be supplied to the callback
///< @param classElement class element pointer which contains information about the element being serialized.
///< root elements do not not have a valid class element pointer
using ObjectStreamWriteOverrideCB = AZStd::function<void(SerializeContext::EnumerateInstanceCallContext& callContext,
///< root elements have a nullptr classElement
///< @return enum to indicate that the override has saved the registered class and that the default writing should be skipped.
///< Returning false will have the WriteElement code fallback to using the default logic
using ObjectStreamWriteOverrideCB = AZStd::function<ObjectStreamWriteOverrideResponse(SerializeContext::EnumerateInstanceCallContext& callContext,
const void* classPtr, const SerializeContext::ClassData& classData, const SerializeContext::ClassElement* classElement)>;
AZ_TYPE_INFO_SPECIALIZE(ObjectStreamWriteOverrideCB, "{87B1A36B-8C8A-42B6-A0B5-E770D9FDBAD4}");
@@ -12,6 +12,8 @@
namespace AZ
{
enum class ObjectStreamWriteOverrideResponse;
namespace VariantSerializationInternal
{
template <class ValueType>
@@ -480,7 +482,7 @@ namespace AZ
}
}
private:
static void ObjectStreamWriter(SerializeContext::EnumerateInstanceCallContext& callContext, const void* variantPtr,
static ObjectStreamWriteOverrideResponse ObjectStreamWriter(SerializeContext::EnumerateInstanceCallContext& callContext, const void* variantPtr,
[[maybe_unused]] const SerializeContext::ClassData& variantClassData, const SerializeContext::ClassElement* variantClassElement)
{
auto alternativeVisitor = [&callContext, variantClassElement](auto&& elementAlt)
@@ -503,6 +505,9 @@ namespace AZ
};
AZStd::visit(AZStd::move(alternativeVisitor), *reinterpret_cast<const VariantType*>(variantPtr));
// To avoid including ObjectStream.h into this file, we static cast the value of 0
// to an AZ::ObjectStreamWriteElemntResponse which corresponds to the CompletedWrite enum value
return static_cast<AZ::ObjectStreamWriteOverrideResponse>(0);
}
VariantSerializationInternal::AZStdVariantContainer<Types...> m_variantContainer;
@@ -62,25 +62,25 @@ set(FILES
../Common/UnixLike/AzCore/std/time_UnixLike.cpp
AzCore/Utils/Utils_Android.cpp
../Common/Unimplemented/AzCore/Utils/Utils_Unimplemented.cpp
../../AzCore/Android/AndroidEnv.cpp
../../AzCore/Android/AndroidEnv.h
../../AzCore/Android/APKFileHandler.cpp
../../AzCore/Android/APKFileHandler.h
../../AzCore/Android/ApiLevel.h
../../AzCore/Android/Utils.cpp
../../AzCore/Android/Utils.h
../../AzCore/Android/JNI/JNI.cpp
../../AzCore/Android/JNI/JNI.h
../../AzCore/Android/JNI/Object.h
../../AzCore/Android/JNI/Object_fwd.h
../../AzCore/Android/JNI/scoped_ref.h
../../AzCore/Android/JNI/shared_ref.h
../../AzCore/Android/JNI/Signature.h
../../AzCore/Android/JNI/Internal/ClassName.h
../../AzCore/Android/JNI/Internal/JStringUtils.h
../../AzCore/Android/JNI/Internal/JStringUtils_impl.h
../../AzCore/Android/JNI/Internal/Object_impl.h
../../AzCore/Android/JNI/Internal/Signature_impl.h
AzCore/Android/AndroidEnv.cpp
AzCore/Android/AndroidEnv.h
AzCore/Android/APKFileHandler.cpp
AzCore/Android/APKFileHandler.h
AzCore/Android/ApiLevel.h
AzCore/Android/Utils.cpp
AzCore/Android/Utils.h
AzCore/Android/JNI/JNI.cpp
AzCore/Android/JNI/JNI.h
AzCore/Android/JNI/Object.h
AzCore/Android/JNI/Object_fwd.h
AzCore/Android/JNI/scoped_ref.h
AzCore/Android/JNI/shared_ref.h
AzCore/Android/JNI/Signature.h
AzCore/Android/JNI/Internal/ClassName.h
AzCore/Android/JNI/Internal/JStringUtils.h
AzCore/Android/JNI/Internal/JStringUtils_impl.h
AzCore/Android/JNI/Internal/Object_impl.h
AzCore/Android/JNI/Internal/Signature_impl.h
AzCore/Debug/Profiler_Platform.inl
AzCore/Debug/Profiler_Android.inl
)
@@ -720,6 +720,49 @@ namespace SerializeTestClasses {
AZStd::intrusive_ptr<SmartPtrClass> m_intrusivePtr;
AZStd::unique_ptr<SmartPtrClass> m_uniquePtr;
};
struct ElementOverrideType
{
AZ_RTTI(ElementOverrideType, "{BAA18B6C-3CB3-476C-8B41-21EA7CE1F4CF}");
AZ_CLASS_ALLOCATOR(ElementOverrideType, AZ::SystemAllocator, 0);
virtual ~ElementOverrideType() = default;
static AZ::ObjectStreamWriteOverrideResponse Writer(
AZ::SerializeContext::EnumerateInstanceCallContext& callContext,
const void* object,
const AZ::SerializeContext::ClassData&,
const AZ::SerializeContext::ClassElement*)
{
auto ptr = static_cast<const ElementOverrideType*>(object);
if(ptr)
{
switch(ptr->m_field)
{
case 0:
{
float output{};
callContext.m_context->EnumerateInstanceConst(&callContext, &output, azrtti_typeid<decltype(output)>(), nullptr, nullptr);
return AZ::ObjectStreamWriteOverrideResponse::CompletedWrite;
}
case 1:
return AZ::ObjectStreamWriteOverrideResponse::FallbackToDefaultWrite;
}
}
return AZ::ObjectStreamWriteOverrideResponse::AbortWrite;
}
static void Reflect(AZ::SerializeContext& sc)
{
sc.Class<ElementOverrideType>()
->Attribute(AZ::SerializeContextAttributes::ObjectStreamWriteElementOverride, &ElementOverrideType::Writer)
->Field("field", &ElementOverrideType::m_field);
}
int m_field = 0;
};
} //SerializeTestClasses
namespace AZ
@@ -1698,6 +1741,66 @@ namespace UnitTest
}
}
TEST_F(Serialization, ElementOverrideTest_DefaultSerializationWorks)
{
ElementOverrideType::Reflect(*m_serializeContext);
ElementOverrideType testType;
testType.m_field = 1; // Our custom serializer will use the default output when this value is 1
AZStd::vector<char> buffer;
IO::ByteContainerStream<AZStd::vector<char>> stream(&buffer);
ASSERT_TRUE(Utils::SaveObjectToStream(stream, DataStream::ST_XML, &testType, m_serializeContext.get()));
constexpr const char* expectedValue =
R"(<ObjectStream version="3">)" "\n"
"\t" R"(<Class name="ElementOverrideType" type="{BAA18B6C-3CB3-476C-8B41-21EA7CE1F4CF}">)" "\n"
"\t\t" R"(<Class name="int" field="field" value="1" type="{72039442-EB38-4D42-A1AD-CB68F7E0EEF6}"/>)" "\n"
"\t" R"(</Class>)" "\n"
R"(</ObjectStream>)";
AZStd::string result(buffer.data(), stream.GetLength());
AZ::StringFunc::TrimWhiteSpace(result, true, true);
EXPECT_STREQ(result.c_str(), expectedValue);
}
TEST_F(Serialization, ElementOverrideTest_CustomSerializationWorks)
{
ElementOverrideType::Reflect(*m_serializeContext);
ElementOverrideType testType;
testType.m_field = 0; // Our custom serializer will do its own output when this value is 0
AZStd::vector<char> buffer;
IO::ByteContainerStream<AZStd::vector<char>> stream(&buffer);
ASSERT_TRUE(Utils::SaveObjectToStream(stream, DataStream::ST_XML, &testType, m_serializeContext.get()));
constexpr const char* expectedValue =
R"(<ObjectStream version="3">)" "\n"
"\t" R"(<Class name="float" value="0.0000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>)" "\n"
R"(</ObjectStream>)";
AZStd::string result(buffer.data(), stream.GetLength());
AZ::StringFunc::TrimWhiteSpace(result, true, true);
EXPECT_STREQ(result.c_str(), expectedValue);
}
TEST_F(Serialization, ElementOverrideTest_FailureCase)
{
ElementOverrideType::Reflect(*m_serializeContext);
ElementOverrideType testType;
testType.m_field = 2; // Our custom serializer will report a failure when this value is not 0/1
AZStd::vector<char> buffer;
IO::ByteContainerStream<AZStd::vector<char>> stream(&buffer);
AZ_TEST_START_TRACE_SUPPRESSION;
ASSERT_FALSE(Utils::SaveObjectToStream(stream, DataStream::ST_XML, &testType, m_serializeContext.get()));
AZ_TEST_STOP_TRACE_SUPPRESSION(1);
}
TEST_F(Serialization, ContainerTypeContainedTypeDiffersByPointer)
{
ContainersTest::ReflectVectorOfInts(m_serializeContext.get());
@@ -15,7 +15,7 @@ namespace AzFramework
{
// Redirects writing of the AssetBundleManifest to an older version if the bundle version
// is not set to the current version
static void OldBundleManifestWriter(AZ::SerializeContext::EnumerateInstanceCallContext& callContext, const void* bundleManifestPointer,
static AZ::ObjectStreamWriteOverrideResponse OldBundleManifestWriter(AZ::SerializeContext::EnumerateInstanceCallContext& callContext, const void* bundleManifestPointer,
const AZ::SerializeContext::ClassData&, const AZ::SerializeContext::ClassElement* assetBundleManifestClassElement);
static bool BundleManifestVersionConverter(AZ::SerializeContext& context, AZ::SerializeContext::DataElementNode& rootElement);
@@ -67,7 +67,7 @@ namespace AzFramework
return true;
}
void OldBundleManifestWriter(AZ::SerializeContext::EnumerateInstanceCallContext& callContext, const void* bundleManifestPointer,
AZ::ObjectStreamWriteOverrideResponse OldBundleManifestWriter(AZ::SerializeContext::EnumerateInstanceCallContext& callContext, const void* bundleManifestPointer,
const AZ::SerializeContext::ClassData&, const AZ::SerializeContext::ClassElement* assetBundleManifestClassElement)
{
// Copy the AssetBundleManifest current version instance to the AssetBundleManifest V2 instance
@@ -145,7 +145,10 @@ namespace AzFramework
ReflectAssetBundleManifestV2(serializeContext);
serializeContext->DisableRemoveReflection();
AssetBundleManifest::ReflectSerialize(serializeContext);
return AZ::ObjectStreamWriteOverrideResponse::CompletedWrite;
}
return AZ::ObjectStreamWriteOverrideResponse::FallbackToDefaultWrite;
}
const AZStd::vector<AZ::IO::Path>& AssetBundleManifest::GetLevelDirectories() const
@@ -12,13 +12,12 @@
AZ_PUSH_DISABLE_WARNING(4244 4251, "-Wunknown-warning-option") // 4251: 'QLayoutItem::align': class 'QFlags<Qt::AlignmentFlag>' needs to have dll-interface to be used by clients of class 'QLayoutItem'
#include <QHBoxLayout>
#include <QToolButton>
#include <QToolBar>
#include <QLabel>
#include <QHBoxLayout>
#include <QSettings>
#include <QMenu>
#include <QResizeEvent>
#include <QSettings>
#include <QToolBar>
#include <QToolButton>
AZ_POP_DISABLE_WARNING
namespace AzQtComponents
@@ -46,7 +45,7 @@ namespace AzQtComponents
m_label = new QLabel(this);
m_label->setObjectName(g_labelName);
boxLayout->addWidget(m_label);
m_label->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Preferred);
m_label->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
connect(m_label, &QLabel::linkActivated, this, &BreadCrumbs::onLinkActivated);
}
@@ -82,9 +81,38 @@ namespace AzQtComponents
// clean up the path to use all the first separator in the list of separators
m_currentPath.replace(g_windowsSeparator, g_separator);
// update internals
m_currentPathSize = m_currentPath.split(g_separator, Qt::SkipEmptyParts).size();
m_currentPathIcons.resize(m_currentPathSize);
fillLabel();
}
void BreadCrumbs::setDefaultIcon(const QString& icon)
{
m_defaultIcon = icon;
}
void BreadCrumbs::setIconAt(int index, const QString& icon)
{
if (index < 0 || index >= m_currentPathSize)
{
return;
}
m_currentPathIcons[index] = icon;
}
QIcon BreadCrumbs::iconAt(int index)
{
if (index < 0 || index >= m_currentPathSize || m_currentPathIcons[index].isNull())
{
return QIcon(m_defaultIcon);
}
return QIcon(m_currentPathIcons[index]);
}
bool BreadCrumbs::getPushPathOnLinkActivation() const
{
return m_pushPathOnLinkActivation;
@@ -220,6 +248,26 @@ namespace AzQtComponents
QWidget::resizeEvent(event);
}
QString BreadCrumbs::generateIconHtml(int index)
{
QString imagePath;
if (index >= 0 && index < m_currentPathIcons.size())
{
imagePath = m_currentPathIcons[index];
}
if (imagePath.isEmpty())
{
imagePath = m_defaultIcon;
}
return !imagePath.isEmpty() ? QStringLiteral("<img width=\"16\" height=\"16\" style=\"vertical-align: middle\" src=\"%1\">%2%2")
.arg(imagePath)
.arg("&nbsp;")
: "";
}
void BreadCrumbs::fillLabel()
{
QString htmlString = "";
@@ -247,7 +295,10 @@ namespace AzQtComponents
plainTextPath = m_truncatedPaths.takeLast();
}
htmlString.prepend(plainTextPath);
int index = m_currentPathSize - 1;
htmlString.prepend(generateIconHtml(index) + plainTextPath);
--index;
while (!m_truncatedPaths.isEmpty())
{
@@ -262,7 +313,7 @@ namespace AzQtComponents
const QString linkPath = buildPathFromList(fullPath, m_truncatedPaths.size());
const QString& part = m_truncatedPaths.takeLast();
htmlString.prepend(QString("%1").arg(formatLink(linkPath, part)));
htmlString.prepend(QString("%1%2").arg(generateIconHtml(index--)).arg(formatLink(linkPath, part)));
}
m_label->setText(htmlString);
@@ -78,6 +78,13 @@ namespace AzQtComponents
//! Sets the current breadcrumb path without updating the navigation stack.
void setCurrentPath(const QString& newPath);
//! Sets a default icon for path elements.
void setDefaultIcon(const QString& iconPath);
//! Sets an icon for the path element at index.
void setIconAt(int index, const QString& iconPath);
//! Gets the icon for the path element at index.
QIcon iconAt(int index);
//! Returns true if activating a link should automatically push a new path to the navigation stack.
bool getPushPathOnLinkActivation() const;
//! Sets whether activating a link should automatically push a new path to the navigation stack.
@@ -134,6 +141,7 @@ namespace AzQtComponents
void onLinkActivated(const QString& link);
private:
QString generateIconHtml(int index);
void fillLabel();
void changePath(const QString& newPath);
@@ -155,6 +163,14 @@ namespace AzQtComponents
QStringList m_truncatedPaths;
AZ_POP_DISABLE_WARNING
bool m_pushPathOnLinkActivation = true;
int m_currentPathSize = 0;
QString m_defaultIcon;
AZ_PUSH_DISABLE_WARNING(
4251, "-Wunknown-warning-option") // 4251: 'AzQtComponents::BreadCrumbs::m_currentPathIcons': class 'QVector<QIcon>' needs to have
// dll-interface to be used by clients of class 'AzQtComponents::BreadCrumbs'
QVector<QString> m_currentPathIcons;
AZ_POP_DISABLE_WARNING
friend class Style;
@@ -447,7 +447,7 @@ namespace AzToolsFramework
else
{
loadedSuccessfully = static_cast<PrefabEditorEntityOwnershipService*>(m_entityOwnershipService.get())->LoadFromStream(
stream, AZStd::string_view(levelPakFile.toUtf8(), levelPakFile.size()) );
stream, AZStd::string_view(levelPakFile.toUtf8().constData(), levelPakFile.size()) );
}
@@ -65,6 +65,9 @@ namespace AzToolsFramework
bool Connection::Open(const AZStd::string& filename, bool readOnly)
{
AZ_Assert(sqlite3_libversion_number() == SQLITE_VERSION_NUMBER, "Sqlite header version number does not match library");
AZ_Assert(strncmp(sqlite3_sourceid(), SQLITE_SOURCE_ID, 80) == 0, "Sqlite header source id does not match library");
AZ_Assert(strcmp(sqlite3_libversion(), SQLITE_VERSION) == 0, "Sqlite header version does not match library");
AZ_Assert(m_db == NULL, "You have to close the database prior to opening a new one.");
if (m_db)
{
@@ -44,6 +44,9 @@ namespace AzToolsFramework::Prefab
m_breadcrumbsWidget = breadcrumbsWidget;
m_backButton = backButton;
// Add icons to the widget
m_breadcrumbsWidget->setDefaultIcon(QString(":/Entity/prefab_edit.svg"));
// If a part of the path is clicked, focus on that instance
connect(m_breadcrumbsWidget, &AzQtComponents::BreadCrumbs::linkClicked, this,
[&](const QString&, int linkIndex)
@@ -74,6 +77,9 @@ namespace AzToolsFramework::Prefab
// Push new Path
m_breadcrumbsWidget->pushPath(m_prefabFocusPublicInterface->GetPrefabFocusPath(m_editorEntityContextId).c_str());
// Set root icon
m_breadcrumbsWidget->setIconAt(0, QString(":/Level/level.svg"));
// If root instance is focused, disable the back button; else enable it.
m_backButton->setEnabled(m_prefabFocusPublicInterface->GetPrefabFocusPathLength(m_editorEntityContextId) > 1);
}
@@ -0,0 +1,60 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#include <AzFramework/Input/Devices/Keyboard/InputDeviceKeyboard.h>
#include <AzFramework/Input/Devices/Mouse/InputDeviceMouse.h>
#include <AzToolsFramework/Viewport/ViewportInteractionHelpers.h>
namespace AzToolsFramework::ViewportInteraction
{
MouseButton Helpers::GetMouseButton(const AzFramework::InputChannel& inputChannel)
{
using AzToolsFramework::ViewportInteraction::MouseButton;
using InputButton = AzFramework::InputDeviceMouse::Button;
const AzFramework::InputChannelId& id = inputChannel.GetInputChannelId();
if (id == InputButton::Left)
{
return MouseButton::Left;
}
if (id == InputButton::Middle)
{
return MouseButton::Middle;
}
if (id == InputButton::Right)
{
return MouseButton::Right;
}
return MouseButton::None;
}
bool Helpers::IsMouseMove(const AzFramework::InputChannel& inputChannel)
{
return inputChannel.GetInputChannelId() == AzFramework::InputDeviceMouse::SystemCursorPosition;
}
KeyboardModifier Helpers::GetKeyboardModifier(const AzFramework::InputChannel& inputChannel)
{
using AzToolsFramework::ViewportInteraction::KeyboardModifier;
using Key = AzFramework::InputDeviceKeyboard::Key;
const auto& id = inputChannel.GetInputChannelId();
if (id == Key::ModifierAltL || id == Key::ModifierAltR)
{
return KeyboardModifier::Alt;
}
if (id == Key::ModifierCtrlL || id == Key::ModifierCtrlR)
{
return KeyboardModifier::Ctrl;
}
if (id == Key::ModifierShiftL || id == Key::ModifierShiftR)
{
return KeyboardModifier::Shift;
}
return KeyboardModifier::None;
}
} // namespace AzToolsFramework::ViewportInteraction
@@ -0,0 +1,23 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#pragma once
#include <AzFramework/Input/Channels/InputChannel.h>
#include <AzToolsFramework/Viewport/ViewportTypes.h>
namespace AzToolsFramework::ViewportInteraction
{
class Helpers
{
public:
static MouseButton GetMouseButton(const AzFramework::InputChannel& inputChannel);
static bool IsMouseMove(const AzFramework::InputChannel& inputChannel);
static KeyboardModifier GetKeyboardModifier(const AzFramework::InputChannel& inputChannel);
};
} // namespace AzToolsFramework::ViewportInteraction
@@ -150,6 +150,9 @@ namespace AzToolsFramework
static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Single;
};
//! A bus to listen to just the MouseViewportRequests.
using ViewportMouseRequestBus = AZ::EBus<MouseViewportRequests, ViewportEBusTraits>;
//! Requests that can be made to the viewport to query and modify its state.
class ViewportInteractionRequests
{
@@ -504,6 +504,8 @@ set(FILES
Viewport/EditorContextMenu.cpp
Viewport/VertexContainerDisplay.h
Viewport/VertexContainerDisplay.cpp
Viewport/ViewportInteractionHelpers.h
Viewport/ViewportInteractionHelpers.cpp
Viewport/ViewportMessages.h
Viewport/ViewportMessages.cpp
Viewport/ViewportTypes.h
-1
View File
@@ -27,7 +27,6 @@ if(PAL_TRAIT_AZTESTRUNNER_SUPPORTED AND NOT LY_MONOLITHIC_GAME)
PRIVATE
AZ::AzCore
AZ::AzTest
AZ::AzFramework
)
if(PAL_TRAIT_BUILD_TESTS_SUPPORTED)
@@ -10,3 +10,8 @@ set(LY_INCLUDE_DIRECTORIES
PRIVATE
${LY_NDK_NATIVE_APP_GLUE_SRC_DIR}
)
set(LY_BUILD_DEPENDENCIES
PRIVATE
AZ::AzFramework
)