Merge branch 'development' into LYN-3705-2
This commit is contained in:
@@ -403,6 +403,19 @@ bool EditorViewportWidget::event(QEvent* event)
|
||||
m_keyDown.clear();
|
||||
break;
|
||||
|
||||
case QEvent::ShortcutOverride:
|
||||
{
|
||||
// Ensure we exit game mode on escape, even if something else would eat our escape key event.
|
||||
if (static_cast<QKeyEvent*>(event)->key() == Qt::Key_Escape && GetIEditor()->IsInGameMode())
|
||||
{
|
||||
GetIEditor()->SetInGameMode(false);
|
||||
event->accept();
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case QEvent::Shortcut:
|
||||
// a shortcut should immediately clear us, otherwise the release event never gets sent
|
||||
m_keyDown.clear();
|
||||
@@ -456,7 +469,6 @@ void EditorViewportWidget::Update()
|
||||
auto m = AZMatrix3x4ToLYMatrix3x4(matrix);
|
||||
|
||||
SetViewTM(m);
|
||||
SetFOV(cameraState.m_fovOrZoom);
|
||||
m_Camera.SetZRange(cameraState.m_nearClip, cameraState.m_farClip);
|
||||
}
|
||||
|
||||
@@ -2601,6 +2613,8 @@ void EditorViewportWidget::DestroyRenderContext()
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void EditorViewportWidget::SetDefaultCamera()
|
||||
{
|
||||
// Ensure the FOV matches our internally stored setting
|
||||
SetFOV(GetFOV());
|
||||
if (IsDefaultCamera())
|
||||
{
|
||||
return;
|
||||
|
||||
@@ -296,8 +296,8 @@ private:
|
||||
AZStd::unordered_set<AZ::EntityId> m_unsavedEntities;
|
||||
|
||||
const AZStd::string m_defaultComponentIconLocation = "Icons/Components/Component_Placeholder.svg";
|
||||
const AZStd::string m_defaultComponentViewportIconLocation = "Icons/Components/Viewport/Component_Placeholder.png";
|
||||
const AZStd::string m_defaultEntityIconLocation = "Icons/Components/Viewport/Transform.png";
|
||||
const AZStd::string m_defaultComponentViewportIconLocation = "Icons/Components/Viewport/Component_Placeholder.svg";
|
||||
const AZStd::string m_defaultEntityIconLocation = "Icons/Components/Viewport/Transform.svg";
|
||||
|
||||
bool m_debugDisplayBusImplementationActive = false;
|
||||
|
||||
|
||||
@@ -346,7 +346,6 @@ bool ShortcutDispatcher::eventFilter(QObject* obj, QEvent* ev)
|
||||
|
||||
case QEvent::Shortcut:
|
||||
return shortcutFilter(obj, static_cast<QShortcutEvent*>(ev));
|
||||
break;
|
||||
|
||||
case QEvent::MouseButtonPress:
|
||||
if (!s_lastFocus || !IsAContainerForB(qobject_cast<QWidget*>(obj), s_lastFocus))
|
||||
|
||||
@@ -67,6 +67,17 @@ namespace AzPhysics
|
||||
}
|
||||
}
|
||||
|
||||
// class for exposing free functions to script
|
||||
class SceneQueries
|
||||
{
|
||||
public:
|
||||
AZ_TYPE_INFO(SceneQueries, "{4EFA3DA5-C0E3-4753-8C55-202228CA527E}");
|
||||
AZ_CLASS_ALLOCATOR(SceneQueries, AZ::SystemAllocator, 0);
|
||||
|
||||
SceneQueries() = default;
|
||||
~SceneQueries() = default;
|
||||
};
|
||||
|
||||
/*static*/ void SceneQueryRequest::Reflect(AZ::ReflectContext* context)
|
||||
{
|
||||
if (auto* serializeContext = azdynamic_cast<AZ::SerializeContext*>(context))
|
||||
@@ -96,6 +107,7 @@ namespace AzPhysics
|
||||
->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Common)
|
||||
->Attribute(AZ::Script::Attributes::Module, "physics")
|
||||
->Attribute(AZ::Script::Attributes::Category, "PhysX")
|
||||
->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::All)
|
||||
->Property("Collision", BehaviorValueProperty(&SceneQueryRequest::m_collisionGroup))
|
||||
// Until enum class support for behavior context is done, expose this as an int
|
||||
->Property("QueryType", [](const SceneQueryRequest& self) { return static_cast<int>(self.m_queryType); },
|
||||
@@ -134,11 +146,28 @@ namespace AzPhysics
|
||||
->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Common)
|
||||
->Attribute(AZ::Script::Attributes::Module, "physics")
|
||||
->Attribute(AZ::Script::Attributes::Category, "PhysX")
|
||||
->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::All)
|
||||
->Property("Distance", BehaviorValueProperty(&RayCastRequest::m_distance))
|
||||
->Property("Start", BehaviorValueProperty(&RayCastRequest::m_start))
|
||||
->Property("Direction", BehaviorValueProperty(&RayCastRequest::m_direction))
|
||||
->Property("ReportMultipleHits", BehaviorValueProperty(&RayCastRequest::m_reportMultipleHits))
|
||||
;
|
||||
|
||||
behaviorContext->Class<SceneQueries>("SceneQueries")
|
||||
->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Common)
|
||||
->Attribute(AZ::Script::Attributes::Module, "physics")
|
||||
->Attribute(AZ::Script::Attributes::Category, "PhysX")
|
||||
->Method(
|
||||
"CreateRayCastRequest",
|
||||
[](const AZ::Vector3& start, const AZ::Vector3& direction, float distance, const AZStd::string& collisionGroup)
|
||||
{
|
||||
RayCastRequest request;
|
||||
request.m_start = start;
|
||||
request.m_direction = direction;
|
||||
request.m_distance = distance;
|
||||
request.m_collisionGroup = CollisionGroup(collisionGroup);
|
||||
return request;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -162,6 +191,7 @@ namespace AzPhysics
|
||||
->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Common)
|
||||
->Attribute(AZ::Script::Attributes::Module, "physics")
|
||||
->Attribute(AZ::Script::Attributes::Category, "PhysX")
|
||||
->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::All)
|
||||
->Property("Distance", BehaviorValueProperty(&ShapeCastRequest::m_distance))
|
||||
->Property("Start", BehaviorValueProperty(&ShapeCastRequest::m_start))
|
||||
->Property("Direction", BehaviorValueProperty(&ShapeCastRequest::m_direction))
|
||||
@@ -175,7 +205,6 @@ namespace AzPhysics
|
||||
return ShapeCastRequestHelpers::CreateSphereCastRequest(
|
||||
radius, startPose, direction, distance, queryType, collisionGroup, nullptr);
|
||||
});
|
||||
|
||||
behaviorContext->Method(
|
||||
"CreateBoxCastRequest",
|
||||
[](const AZ::Vector3& boxDimensions, const AZ::Transform& startPose, const AZ::Vector3& direction, float distance,
|
||||
@@ -184,7 +213,6 @@ namespace AzPhysics
|
||||
return ShapeCastRequestHelpers::CreateBoxCastRequest(
|
||||
boxDimensions, startPose, direction, distance, queryType, collisionGroup, nullptr);
|
||||
});
|
||||
|
||||
behaviorContext->Method(
|
||||
"CreateCapsuleCastRequest",
|
||||
[](float capsuleRadius, float capsuleHeight, const AZ::Transform& startPose, const AZ::Vector3& direction, float distance,
|
||||
@@ -267,6 +295,7 @@ namespace AzPhysics
|
||||
->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Common)
|
||||
->Attribute(AZ::Script::Attributes::Module, "physics")
|
||||
->Attribute(AZ::Script::Attributes::Category, "PhysX")
|
||||
->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::All)
|
||||
->Property("Pose", BehaviorValueProperty(&OverlapRequest::m_pose))
|
||||
;
|
||||
|
||||
@@ -349,6 +378,7 @@ namespace AzPhysics
|
||||
->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Common)
|
||||
->Attribute(AZ::Script::Attributes::Module, "physics")
|
||||
->Attribute(AZ::Script::Attributes::Category, "PhysX")
|
||||
->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::All)
|
||||
->Property("Distance", BehaviorValueProperty(&SceneQueryHit::m_distance))
|
||||
->Property("Position", BehaviorValueProperty(&SceneQueryHit::m_position))
|
||||
->Property("Normal", BehaviorValueProperty(&SceneQueryHit::m_normal))
|
||||
|
||||
@@ -51,7 +51,10 @@ namespace AzPhysics
|
||||
->Method("GetOnPostsimulateEvent", getOnPostsimulateEvent)
|
||||
->Attribute(AZ::Script::Attributes::AzEventDescription, postsimulateEventDescription)
|
||||
->Method("GetSceneHandle", &SystemInterface::GetSceneHandle)
|
||||
->Method("GetScene", &SystemInterface::GetScene);
|
||||
->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::All)
|
||||
->Method("GetScene", &SystemInterface::GetScene)
|
||||
->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::All)
|
||||
;
|
||||
|
||||
behaviorContext->Method(
|
||||
"GetPhysicsSystem",
|
||||
|
||||
@@ -303,4 +303,22 @@ namespace AzNetworking
|
||||
return serializer.IsValid();
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct SerializeObjectHelper<AZ::Transform>
|
||||
{
|
||||
static bool SerializeObject(ISerializer& serializer, AZ::Transform& value)
|
||||
{
|
||||
AZ::Vector3 translation = value.GetTranslation();
|
||||
AZ::Quaternion rotation = value.GetRotation();
|
||||
float uniformScale = value.GetUniformScale();
|
||||
serializer.Serialize(translation, "Translation");
|
||||
serializer.Serialize(rotation, "Rotation");
|
||||
serializer.Serialize(uniformScale, "Scale");
|
||||
value.SetTranslation(translation);
|
||||
value.SetRotation(rotation);
|
||||
value.SetUniformScale(uniformScale);
|
||||
return serializer.IsValid();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -11,9 +11,9 @@
|
||||
|
||||
namespace AzNetworking
|
||||
{
|
||||
// This gives us a hash sensitivity of around 1/128th of a unit, and will detect errors within a range of -16,777,216 to +16,777,216
|
||||
static const int32_t FloatHashMinValue = (INT_MIN >> 7);
|
||||
static const int32_t FloatHashMaxValue = (INT_MAX >> 7);
|
||||
// This gives us a hash sensitivity of around 1/512th of a unit, and will detect errors within a range of -4,194,304 to +4,194,304
|
||||
static const int32_t FloatHashMinValue = (INT_MIN >> 9);
|
||||
static const int32_t FloatHashMaxValue = (INT_MAX >> 9);
|
||||
|
||||
AZ::HashValue32 HashSerializer::GetHash() const
|
||||
{
|
||||
|
||||
+1
-1
@@ -403,7 +403,7 @@ namespace AzToolsFramework
|
||||
void RootAssetBrowserEntry::UpdateChildPaths(AssetBrowserEntry* child) const
|
||||
{
|
||||
child->m_relativePath = child->m_name;
|
||||
child->m_fullPath = child->m_name;
|
||||
child->m_fullPath = m_fullPath / child->m_name;
|
||||
AssetBrowserEntry::UpdateChildPaths(child);
|
||||
}
|
||||
|
||||
|
||||
+3
-1
@@ -88,13 +88,15 @@ namespace AzToolsFramework
|
||||
{
|
||||
if (m_rootInstance)
|
||||
{
|
||||
AzToolsFramework::ToolsApplicationRequestBus::Broadcast(
|
||||
&AzToolsFramework::ToolsApplicationRequestBus::Events::ClearDirtyEntities);
|
||||
Prefab::TemplateId templateId = m_rootInstance->GetTemplateId();
|
||||
m_rootInstance->Reset();
|
||||
if (templateId != Prefab::InvalidTemplateId)
|
||||
{
|
||||
m_rootInstance->SetTemplateId(Prefab::InvalidTemplateId);
|
||||
m_prefabSystemComponent->RemoveTemplate(templateId);
|
||||
}
|
||||
m_rootInstance->Reset();
|
||||
m_rootInstance->SetContainerEntityName("Level");
|
||||
}
|
||||
|
||||
|
||||
@@ -82,16 +82,7 @@ namespace AzToolsFramework
|
||||
return;
|
||||
}
|
||||
|
||||
// If this instance's templateId is valid, we should be able to unregister this instance from
|
||||
// Template to Instance mapping successfully.
|
||||
if (m_templateId != InvalidTemplateId &&
|
||||
!m_templateInstanceMapper->UnregisterInstance(*this))
|
||||
{
|
||||
AZ_Assert(false,
|
||||
"Prefab - Attempted to Unregister Instance from Template with Id '%u'. "
|
||||
"Instance may never have been registered or was unregistered early.",
|
||||
m_templateId);
|
||||
}
|
||||
m_templateInstanceMapper->UnregisterInstance(*this);
|
||||
|
||||
m_templateId = templateId;
|
||||
|
||||
@@ -221,15 +212,7 @@ namespace AzToolsFramework
|
||||
|
||||
void Instance::Reset()
|
||||
{
|
||||
// Clean up Instance associations.
|
||||
if (m_templateId != InvalidTemplateId && !m_templateInstanceMapper->UnregisterInstance(*this))
|
||||
{
|
||||
AZ_Assert(
|
||||
false,
|
||||
"Prefab - Attempted to unregister Instance from Template on file path '%s' with Id '%u'. "
|
||||
"Instance may never have been registered or was unregistered early.",
|
||||
m_templateSourcePath.c_str(), m_templateId);
|
||||
}
|
||||
m_templateInstanceMapper->UnregisterInstance(*this);
|
||||
|
||||
ClearEntities();
|
||||
|
||||
|
||||
+1
-1
@@ -40,7 +40,7 @@ namespace AzToolsFramework
|
||||
->Attribute(AZ::Edit::Attributes::FixedComponentListIndex, 1)
|
||||
->Attribute(AZ::Edit::Attributes::RemoveableByUser, true)
|
||||
->Attribute(AZ::Edit::Attributes::Icon, "Icons/Components/NonUniformScale.svg")
|
||||
->Attribute(AZ::Edit::Attributes::ViewportIcon, "Icons/Components/NonUniformScale.svg")
|
||||
->Attribute(AZ::Edit::Attributes::ViewportIcon, "Icons/Components/Viewport/NonUniformScale.svg")
|
||||
->DataElement(
|
||||
AZ::Edit::UIHandlers::Default, &EditorNonUniformScaleComponent::m_scale, "Non-uniform Scale",
|
||||
"Non-uniform scale for this entity only (does not propagate through hierarchy)")
|
||||
|
||||
+1
@@ -1021,6 +1021,7 @@ namespace AzToolsFramework
|
||||
->Attribute(AZ::Edit::Attributes::AutoExpand, true)
|
||||
->Attribute(AZ::Edit::Attributes::Category, "Scripting")
|
||||
->Attribute(AZ::Edit::Attributes::Icon, "Icons/Components/LuaScript.svg")
|
||||
->Attribute(AZ::Edit::Attributes::ViewportIcon, "Icons/Components/Viewport/LuaScript.svg")
|
||||
->Attribute(AZ::Edit::Attributes::PrimaryAssetType, AZ::AzTypeInfo<AZ::ScriptAsset>::Uuid())
|
||||
->Attribute(AZ::Edit::Attributes::ViewportIcon, "Icons/Components/Viewport/Script.png")
|
||||
->Attribute(AZ::Edit::Attributes::HelpPageURL, "https://o3de.org/docs/user-guide/components/reference/lua-script/")
|
||||
|
||||
+1
-1
@@ -1182,7 +1182,7 @@ namespace AzToolsFramework
|
||||
ClassElement(AZ::Edit::ClassElements::EditorData, "")->
|
||||
Attribute(AZ::Edit::Attributes::FixedComponentListIndex, 0)->
|
||||
Attribute(AZ::Edit::Attributes::Icon, "Icons/Components/Transform.svg")->
|
||||
Attribute(AZ::Edit::Attributes::ViewportIcon, "Icons/Components/Viewport/Transform.png")->
|
||||
Attribute(AZ::Edit::Attributes::ViewportIcon, "Icons/Components/Viewport/Transform.svg")->
|
||||
Attribute(AZ::Edit::Attributes::AutoExpand, true)->
|
||||
DataElement(AZ::Edit::UIHandlers::Default, &TransformComponent::m_parentEntityId, "Parent entity", "")->
|
||||
Attribute(AZ::Edit::Attributes::ChangeValidate, &TransformComponent::ValidatePotentialParent)->
|
||||
|
||||
+16
-8
@@ -4965,21 +4965,29 @@ namespace AzToolsFramework
|
||||
|
||||
void EntityPropertyEditor::SetEditorUiEnabled(bool enable)
|
||||
{
|
||||
if (enable)
|
||||
if (!m_selectedEntityIds.empty())
|
||||
{
|
||||
EnableComponentActions(this, m_entityComponentActions);
|
||||
if (enable)
|
||||
{
|
||||
EnableComponentActions(this, m_entityComponentActions);
|
||||
}
|
||||
else
|
||||
{
|
||||
DisableComponentActions(this, m_entityComponentActions);
|
||||
}
|
||||
SetPropertyEditorState(m_gui, enable);
|
||||
|
||||
for (auto componentEditor : m_componentEditors)
|
||||
{
|
||||
AzQtComponents::SetWidgetInteractEnabled(componentEditor, enable);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DisableComponentActions(this, m_entityComponentActions);
|
||||
AzQtComponents::SetWidgetInteractEnabled(m_gui->m_entityDetailsLabel, enable);
|
||||
}
|
||||
m_disabled = !enable;
|
||||
SetPropertyEditorState(m_gui, enable);
|
||||
|
||||
for (auto componentEditor : m_componentEditors)
|
||||
{
|
||||
AzQtComponents::SetWidgetInteractEnabled(componentEditor, enable);
|
||||
}
|
||||
// record the selected state after entering/leaving component mode
|
||||
SaveComponentEditorState();
|
||||
}
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include <AzToolsFramework/ViewportUi/Button.h>
|
||||
|
||||
namespace AzToolsFramework::ViewportUi::Internal
|
||||
|
||||
@@ -28,7 +28,7 @@ namespace AzToolsFramework::ViewportUi::Internal
|
||||
|
||||
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;
|
||||
State m_state = State::Deselected;
|
||||
ButtonId m_buttonId;
|
||||
};
|
||||
} // namespace AzToolsFramework::ViewportUi::Internal
|
||||
|
||||
@@ -45,11 +45,11 @@ namespace AzToolsFramework::ViewportUi::Internal
|
||||
|
||||
if (name.empty())
|
||||
{
|
||||
m_buttons.insert({buttonId, AZStd::make_unique<Button>(icon, buttonId)});
|
||||
m_buttons.insert({ buttonId, AZStd::make_unique<Button>(icon, buttonId) });
|
||||
}
|
||||
else
|
||||
{
|
||||
m_buttons.insert({buttonId, AZStd::make_unique<Button>(icon, name, buttonId)});
|
||||
m_buttons.insert({ buttonId, AZStd::make_unique<Button>(icon, name, buttonId) });
|
||||
}
|
||||
return buttonId;
|
||||
}
|
||||
@@ -73,7 +73,8 @@ namespace AzToolsFramework::ViewportUi::Internal
|
||||
return buttons;
|
||||
}
|
||||
|
||||
void ButtonGroup::ConnectEventHandler(AZ::Event<ButtonId>::Handler& handler) {
|
||||
void ButtonGroup::ConnectEventHandler(AZ::Event<ButtonId>::Handler& handler)
|
||||
{
|
||||
handler.Connect(m_buttonTriggeredEvent);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
#pragma once
|
||||
|
||||
/*
|
||||
* 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.
|
||||
@@ -8,6 +6,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AzToolsFramework/ViewportUi/ViewportUiRequestBus.h>
|
||||
|
||||
namespace AzToolsFramework::ViewportUi::Internal
|
||||
|
||||
@@ -10,9 +10,7 @@
|
||||
|
||||
namespace AzToolsFramework::ViewportUi::Internal
|
||||
{
|
||||
TextField::TextField(
|
||||
const AZStd::string& labelText, const AZStd::string& fieldText,
|
||||
TextFieldValidationType validationType)
|
||||
TextField::TextField(const AZStd::string& labelText, const AZStd::string& fieldText, TextFieldValidationType validationType)
|
||||
: m_labelText(labelText)
|
||||
, m_fieldText(fieldText)
|
||||
, m_validationType(validationType)
|
||||
|
||||
@@ -19,16 +19,17 @@ namespace AzToolsFramework::ViewportUi::Internal
|
||||
{
|
||||
public:
|
||||
TextField(
|
||||
const AZStd::string& labelText = "", const AZStd::string& fieldText = "",
|
||||
const AZStd::string& labelText = "",
|
||||
const AZStd::string& fieldText = "",
|
||||
TextFieldValidationType validationType = TextFieldValidationType::String);
|
||||
~TextField() = default;
|
||||
|
||||
void ConnectEventHandler(AZ::Event<AZStd::string>::Handler& handler);
|
||||
|
||||
//! Default text for the text field. Will be cast to same type as m_validationType.
|
||||
AZStd::string m_fieldText;
|
||||
AZStd::string m_fieldText;
|
||||
AZStd::string m_labelText;
|
||||
TextFieldValidationType m_validationType; //<! The type of validator for this text edit.
|
||||
TextFieldValidationType m_validationType; //!< The type of validator for this text edit.
|
||||
TextFieldId m_textFieldId;
|
||||
ViewportUiElementId m_viewportId;
|
||||
AZ::Event<AZStd::string> m_textEditedEvent;
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include <AzToolsFramework/ViewportUi/ButtonGroup.h>
|
||||
#include <AzToolsFramework/ViewportUi/ViewportUiCluster.h>
|
||||
|
||||
@@ -14,13 +13,12 @@ namespace AzToolsFramework::ViewportUi::Internal
|
||||
{
|
||||
ViewportUiCluster::ViewportUiCluster(AZStd::shared_ptr<ButtonGroup> buttonGroup)
|
||||
: QToolBar(nullptr)
|
||||
, m_buttonGroup(buttonGroup)
|
||||
, m_buttonGroup(AZStd::move(buttonGroup))
|
||||
{
|
||||
setOrientation(Qt::Orientation::Vertical);
|
||||
setStyleSheet("background: black;");
|
||||
|
||||
const AZStd::vector<Button*> buttons = buttonGroup->GetButtons();
|
||||
for (auto button : buttons)
|
||||
for (auto button : m_buttonGroup->GetButtons())
|
||||
{
|
||||
RegisterButton(button);
|
||||
}
|
||||
@@ -34,10 +32,12 @@ namespace AzToolsFramework::ViewportUi::Internal
|
||||
|
||||
AddClusterAction(
|
||||
action,
|
||||
[this, button]() {
|
||||
[this, button]()
|
||||
{
|
||||
m_buttonGroup->PressButton(button->m_buttonId);
|
||||
},
|
||||
[button](QAction* action) {
|
||||
[button](QAction* action)
|
||||
{
|
||||
action->setChecked(button->m_state == Button::State::Selected);
|
||||
});
|
||||
|
||||
@@ -46,8 +46,7 @@ namespace AzToolsFramework::ViewportUi::Internal
|
||||
|
||||
void ViewportUiCluster::RemoveButton(ButtonId buttonId)
|
||||
{
|
||||
if (auto actionEntry = m_buttonActionMap.find(buttonId);
|
||||
actionEntry != m_buttonActionMap.end())
|
||||
if (auto actionEntry = m_buttonActionMap.find(buttonId); actionEntry != m_buttonActionMap.end())
|
||||
{
|
||||
auto action = actionEntry->second;
|
||||
RemoveClusterAction(action);
|
||||
@@ -56,8 +55,7 @@ namespace AzToolsFramework::ViewportUi::Internal
|
||||
}
|
||||
|
||||
void ViewportUiCluster::AddClusterAction(
|
||||
QAction* action, const AZStd::function<void()>& callback,
|
||||
const AZStd::function<void(QAction*)>& updateCallback)
|
||||
QAction* action, const AZStd::function<void()>& callback, const AZStd::function<void(QAction*)>& updateCallback)
|
||||
{
|
||||
if (!action)
|
||||
{
|
||||
@@ -80,10 +78,12 @@ namespace AzToolsFramework::ViewportUi::Internal
|
||||
}
|
||||
|
||||
// register the action
|
||||
m_widgetCallbacks.AddWidget(action, [updateCallback](QPointer<QObject> object)
|
||||
{
|
||||
updateCallback(static_cast<QAction*>(object.data()));
|
||||
});
|
||||
m_widgetCallbacks.AddWidget(
|
||||
action,
|
||||
[updateCallback](QPointer<QObject> object)
|
||||
{
|
||||
updateCallback(static_cast<QAction*>(object.data()));
|
||||
});
|
||||
}
|
||||
|
||||
void ViewportUiCluster::RemoveClusterAction(QAction* action)
|
||||
@@ -111,10 +111,13 @@ namespace AzToolsFramework::ViewportUi::Internal
|
||||
if (m_lockedButtonId.has_value() && isLocked)
|
||||
{
|
||||
// find the button to extract the old icon (without overlay)
|
||||
auto findLocked = [this](const Button* button) { return (button->m_buttonId == m_lockedButtonId); };
|
||||
auto findLocked = [this](const Button* button)
|
||||
{
|
||||
return (button->m_buttonId == m_lockedButtonId);
|
||||
};
|
||||
if (auto lockedButtonIt = AZStd::find_if(buttons.begin(), buttons.end(), findLocked); lockedButtonIt != buttons.end())
|
||||
{
|
||||
// get the action corresponding to the lockedButtonId
|
||||
// get the action corresponding to the lockedButtonId
|
||||
if (auto actionEntry = m_buttonActionMap.find(m_lockedButtonId.value()); actionEntry != m_buttonActionMap.end())
|
||||
{
|
||||
// remove the overlay
|
||||
@@ -124,14 +127,18 @@ namespace AzToolsFramework::ViewportUi::Internal
|
||||
}
|
||||
}
|
||||
|
||||
auto found = [buttonId](Button* button) { return (button->m_buttonId == buttonId); };
|
||||
auto found = [buttonId](Button* button)
|
||||
{
|
||||
return (button->m_buttonId == buttonId);
|
||||
};
|
||||
|
||||
if (auto buttonIt = AZStd::find_if(buttons.begin(), buttons.end(), found); buttonIt != buttons.end())
|
||||
{
|
||||
QIcon newIcon;
|
||||
|
||||
if (isLocked)
|
||||
{
|
||||
// overlay the locked icon ontop of the button's icon
|
||||
// overlay the locked icon on top of the button's icon
|
||||
QPixmap comboPixmap(24, 24);
|
||||
comboPixmap.fill(Qt::transparent);
|
||||
QPixmap firstImage(QString((*buttonIt)->m_icon.c_str()));
|
||||
|
||||
@@ -12,16 +12,16 @@
|
||||
#include <AzCore/std/smart_ptr/shared_ptr.h>
|
||||
#include <AzToolsFramework/ViewportUi/Button.h>
|
||||
#include <AzToolsFramework/ViewportUi/ViewportUiWidgetCallbacks.h>
|
||||
#include <QToolBar>
|
||||
|
||||
#include <QPainter>
|
||||
#include <QToolBar>
|
||||
|
||||
namespace AzToolsFramework::ViewportUi::Internal
|
||||
{
|
||||
class ButtonGroup;
|
||||
|
||||
//! Helper class to make clusters (toolbars) for display in Viewport UI.
|
||||
class ViewportUiCluster
|
||||
: public QToolBar
|
||||
class ViewportUiCluster : public QToolBar
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
@@ -45,8 +45,7 @@ namespace AzToolsFramework::ViewportUi::Internal
|
||||
private:
|
||||
//! Adds an action to the Viewport UI Cluster.
|
||||
void AddClusterAction(
|
||||
QAction* action, const AZStd::function<void()>& callback = {},
|
||||
const AZStd::function<void(QAction*)>& updateCallback = {});
|
||||
QAction* action, const AZStd::function<void()>& callback = {}, const AZStd::function<void(QAction*)>& updateCallback = {});
|
||||
//! Removes an action from the Viewport UI Cluster.
|
||||
void RemoveClusterAction(QAction* action);
|
||||
|
||||
|
||||
@@ -6,13 +6,12 @@
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include <AzCore/std/smart_ptr/make_shared.h>
|
||||
#include <AzFramework/Viewport/ViewportScreen.h>
|
||||
#include <AzToolsFramework/Viewport/ViewportMessages.h>
|
||||
#include <AzToolsFramework/ViewportSelection/EditorSelectionUtil.h>
|
||||
#include <AzToolsFramework/ViewportUi/ViewportUiDisplay.h>
|
||||
#include <AzToolsFramework/ViewportUi/ViewportUiCluster.h>
|
||||
#include <AzToolsFramework/ViewportUi/ViewportUiDisplay.h>
|
||||
#include <AzToolsFramework/ViewportUi/ViewportUiSwitcher.h>
|
||||
#include <AzToolsFramework/ViewportUi/ViewportUiTextField.h>
|
||||
#include <QWidget>
|
||||
@@ -34,9 +33,9 @@ namespace AzToolsFramework::ViewportUi::Internal
|
||||
}
|
||||
}
|
||||
|
||||
static Qt::Alignment GetQtAlignment(Alignment align)
|
||||
static Qt::Alignment GetQtAlignment(const Alignment alignment)
|
||||
{
|
||||
switch (align)
|
||||
switch (alignment)
|
||||
{
|
||||
case Alignment::TopRight:
|
||||
return Qt::AlignTop | Qt::AlignRight;
|
||||
@@ -52,7 +51,7 @@ namespace AzToolsFramework::ViewportUi::Internal
|
||||
return Qt::AlignBottom;
|
||||
}
|
||||
|
||||
AZ_Assert(false, "ViewportUI", "Unhandled ViewportUI Alignment %d", static_cast<int>(align));
|
||||
AZ_Assert(false, "ViewportUI", "Unhandled ViewportUI Alignment %d", static_cast<int>(alignment));
|
||||
return Qt::AlignTop;
|
||||
}
|
||||
|
||||
@@ -71,7 +70,7 @@ namespace AzToolsFramework::ViewportUi::Internal
|
||||
UnparentWidgets(m_viewportUiElements);
|
||||
}
|
||||
|
||||
void ViewportUiDisplay::AddCluster(AZStd::shared_ptr<ButtonGroup> buttonGroup, const Alignment align)
|
||||
void ViewportUiDisplay::AddCluster(AZStd::shared_ptr<ButtonGroup> buttonGroup, const Alignment alignment)
|
||||
{
|
||||
if (!buttonGroup.get())
|
||||
{
|
||||
@@ -81,11 +80,10 @@ namespace AzToolsFramework::ViewportUi::Internal
|
||||
auto viewportUiCluster = AZStd::make_shared<ViewportUiCluster>(buttonGroup);
|
||||
auto id = AddViewportUiElement(viewportUiCluster);
|
||||
buttonGroup->SetViewportUiElementId(id);
|
||||
PositionViewportUiElementAnchored(id, GetQtAlignment(align));
|
||||
PositionViewportUiElementAnchored(id, GetQtAlignment(alignment));
|
||||
}
|
||||
|
||||
void ViewportUiDisplay::AddClusterButton(
|
||||
const ViewportUiElementId clusterId, Button* button)
|
||||
void ViewportUiDisplay::AddClusterButton(const ViewportUiElementId clusterId, Button* button)
|
||||
{
|
||||
if (auto viewportUiCluster = qobject_cast<ViewportUiCluster*>(GetViewportUiElement(clusterId).get()))
|
||||
{
|
||||
@@ -101,7 +99,8 @@ namespace AzToolsFramework::ViewportUi::Internal
|
||||
}
|
||||
}
|
||||
|
||||
void ViewportUiDisplay::SetClusterButtonTooltip(const ViewportUiElementId clusterId, const ButtonId buttonId, const AZStd::string& tooltip)
|
||||
void ViewportUiDisplay::SetClusterButtonTooltip(
|
||||
const ViewportUiElementId clusterId, const ButtonId buttonId, const AZStd::string& tooltip)
|
||||
{
|
||||
if (auto viewportUiCluster = qobject_cast<ViewportUiCluster*>(GetViewportUiElement(clusterId).get()))
|
||||
{
|
||||
@@ -125,7 +124,7 @@ namespace AzToolsFramework::ViewportUi::Internal
|
||||
}
|
||||
}
|
||||
|
||||
void ViewportUiDisplay::AddSwitcher(AZStd::shared_ptr<ButtonGroup> buttonGroup, const Alignment align)
|
||||
void ViewportUiDisplay::AddSwitcher(AZStd::shared_ptr<ButtonGroup> buttonGroup, const Alignment alignment)
|
||||
{
|
||||
if (!buttonGroup.get())
|
||||
{
|
||||
@@ -135,7 +134,7 @@ namespace AzToolsFramework::ViewportUi::Internal
|
||||
auto viewportUiSwitcher = AZStd::make_shared<ViewportUiSwitcher>(buttonGroup);
|
||||
auto id = AddViewportUiElement(viewportUiSwitcher);
|
||||
buttonGroup->SetViewportUiElementId(id);
|
||||
PositionViewportUiElementAnchored(id, GetQtAlignment(align));
|
||||
PositionViewportUiElementAnchored(id, GetQtAlignment(alignment));
|
||||
}
|
||||
|
||||
void ViewportUiDisplay::AddSwitcherButton(const ViewportUiElementId clusterId, Button* button)
|
||||
@@ -198,11 +197,12 @@ namespace AzToolsFramework::ViewportUi::Internal
|
||||
const ViewportUiElementInfo& elementInfo = element.second;
|
||||
if (!elementInfo.m_anchored)
|
||||
{
|
||||
const auto screenPoint = AzFramework::WorldToScreen(
|
||||
elementInfo.m_worldPosition, AzToolsFramework::GetCameraState(m_viewportId));
|
||||
const auto screenPoint =
|
||||
AzFramework::WorldToScreen(elementInfo.m_worldPosition, AzToolsFramework::GetCameraState(m_viewportId));
|
||||
elementInfo.m_widget->move(screenPoint.m_x, screenPoint.m_y);
|
||||
}
|
||||
}
|
||||
|
||||
PositionUiOverlayOverRenderViewport();
|
||||
}
|
||||
|
||||
@@ -216,7 +216,6 @@ namespace AzToolsFramework::ViewportUi::Internal
|
||||
ViewportUiElementId newId = ViewportUiElementId(++m_numViewportElements);
|
||||
ViewportUiElementInfo newElement{ widget, newId, true };
|
||||
m_viewportUiElements.insert({ newId, newElement });
|
||||
SetUiOverlayContents(widget.get());
|
||||
return newId;
|
||||
}
|
||||
|
||||
@@ -233,8 +232,11 @@ namespace AzToolsFramework::ViewportUi::Internal
|
||||
ViewportUiElementId ViewportUiDisplay::GetViewportUiElementId(QPointer<QWidget> widget)
|
||||
{
|
||||
if (auto element = AZStd::find_if(
|
||||
m_viewportUiElements.begin(), m_viewportUiElements.end(),
|
||||
[widget](const auto& it) { return it.second.m_widget.get() == widget; });
|
||||
m_viewportUiElements.begin(), m_viewportUiElements.end(),
|
||||
[widget](const auto& it)
|
||||
{
|
||||
return it.second.m_widget.get() == widget;
|
||||
});
|
||||
element != m_viewportUiElements.end())
|
||||
{
|
||||
return element->second.m_viewportUiElementId;
|
||||
@@ -245,7 +247,8 @@ namespace AzToolsFramework::ViewportUi::Internal
|
||||
|
||||
void ViewportUiDisplay::RemoveViewportUiElement(ViewportUiElementId elementId)
|
||||
{
|
||||
AZ_Assert(elementId != AzToolsFramework::ViewportUi::InvalidViewportUiElementId,
|
||||
AZ_Assert(
|
||||
elementId != AzToolsFramework::ViewportUi::InvalidViewportUiElementId,
|
||||
"Tried to remove a Viewport UI element using an invalid or removed ViewportUiElementId.");
|
||||
|
||||
auto viewportUiMapElement = m_viewportUiElements.find(elementId);
|
||||
@@ -264,8 +267,7 @@ namespace AzToolsFramework::ViewportUi::Internal
|
||||
|
||||
void ViewportUiDisplay::ShowViewportUiElement(ViewportUiElementId elementId)
|
||||
{
|
||||
if (ViewportUiElementInfo element = GetViewportUiElementInfo(elementId);
|
||||
element.m_widget)
|
||||
if (ViewportUiElementInfo element = GetViewportUiElementInfo(elementId); element.m_widget)
|
||||
{
|
||||
element.m_widget->setVisible(true);
|
||||
}
|
||||
@@ -273,8 +275,7 @@ namespace AzToolsFramework::ViewportUi::Internal
|
||||
|
||||
void ViewportUiDisplay::HideViewportUiElement(ViewportUiElementId elementId)
|
||||
{
|
||||
if (ViewportUiElementInfo element = GetViewportUiElementInfo(elementId);
|
||||
element.m_widget)
|
||||
if (ViewportUiElementInfo element = GetViewportUiElementInfo(elementId); element.m_widget)
|
||||
{
|
||||
element.m_widget->setVisible(false);
|
||||
}
|
||||
@@ -282,8 +283,7 @@ namespace AzToolsFramework::ViewportUi::Internal
|
||||
|
||||
bool ViewportUiDisplay::IsViewportUiElementVisible(ViewportUiElementId elementId)
|
||||
{
|
||||
if (ViewportUiElementInfo element = GetViewportUiElementInfo(elementId);
|
||||
element.m_widget)
|
||||
if (ViewportUiElementInfo element = GetViewportUiElementInfo(elementId); element.m_widget)
|
||||
{
|
||||
return element.IsValid() && element.m_widget->isVisible();
|
||||
}
|
||||
@@ -293,12 +293,12 @@ namespace AzToolsFramework::ViewportUi::Internal
|
||||
void ViewportUiDisplay::CreateComponentModeBorder(const AZStd::string& borderTitle)
|
||||
{
|
||||
AZStd::string styleSheet = AZStd::string::format(
|
||||
"border: %dpx solid %s; border-top: %dpx solid %s;", HighlightBorderSize,
|
||||
HighlightBorderColor, TopHighlightBorderSize, HighlightBorderColor);
|
||||
"border: %dpx solid %s; border-top: %dpx solid %s;", HighlightBorderSize, HighlightBorderColor, TopHighlightBorderSize,
|
||||
HighlightBorderColor);
|
||||
m_uiOverlay.setStyleSheet(styleSheet.c_str());
|
||||
m_uiOverlayLayout.setContentsMargins(HighlightBorderSize + ViewportUiOverlayMargin,
|
||||
TopHighlightBorderSize + ViewportUiOverlayMargin, HighlightBorderSize + ViewportUiOverlayMargin,
|
||||
HighlightBorderSize + ViewportUiOverlayMargin);
|
||||
m_uiOverlayLayout.setContentsMargins(
|
||||
HighlightBorderSize + ViewportUiOverlayMargin, TopHighlightBorderSize + ViewportUiOverlayMargin,
|
||||
HighlightBorderSize + ViewportUiOverlayMargin, HighlightBorderSize + ViewportUiOverlayMargin);
|
||||
m_componentModeBorderText.setVisible(true);
|
||||
m_componentModeBorderText.setText(borderTitle.c_str());
|
||||
}
|
||||
@@ -314,8 +314,7 @@ namespace AzToolsFramework::ViewportUi::Internal
|
||||
{
|
||||
auto viewportUiMapElement = m_viewportUiElements.find(elementId);
|
||||
|
||||
if (viewportUiMapElement != m_viewportUiElements.end() &&
|
||||
viewportUiMapElement->second.m_widget)
|
||||
if (viewportUiMapElement != m_viewportUiElements.end() && viewportUiMapElement->second.m_widget)
|
||||
{
|
||||
viewportUiMapElement->second.m_anchored = false;
|
||||
viewportUiMapElement->second.m_worldPosition = pos;
|
||||
@@ -328,51 +327,28 @@ namespace AzToolsFramework::ViewportUi::Internal
|
||||
{
|
||||
auto viewportUiMapElement = m_viewportUiElements.find(elementId);
|
||||
|
||||
if (viewportUiMapElement != m_viewportUiElements.end() &&
|
||||
viewportUiMapElement->second.m_widget)
|
||||
if (viewportUiMapElement != m_viewportUiElements.end() && viewportUiMapElement->second.m_widget)
|
||||
{
|
||||
viewportUiMapElement->second.m_anchored = true;
|
||||
SetUiOverlayContentsAnchored(viewportUiMapElement->second.m_widget.get(), alignment);
|
||||
}
|
||||
}
|
||||
|
||||
void ViewportUiDisplay::AddMaximumSizeViewportUiElement(QPointer<QWidget> widget)
|
||||
{
|
||||
if (widget)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_fullScreenWidget)
|
||||
{
|
||||
AZ_Warning(
|
||||
"ViewportUi", false,
|
||||
"Attaching a maximum size element when one already exists. Removing the previously attached element.");
|
||||
RemoveViewportUiElement(GetViewportUiElementId(m_fullScreenWidget));
|
||||
}
|
||||
|
||||
widget->setAttribute(Qt::WA_ShowWithoutActivating);
|
||||
widget->setParent(&m_uiOverlay);
|
||||
m_fullScreenWidget = widget;
|
||||
m_fullScreenLayout.addWidget(m_fullScreenWidget, 0, 0, 1, 1);
|
||||
m_renderOverlay->setFocus();
|
||||
}
|
||||
|
||||
// disables system background for widget and gives a transparent background
|
||||
static void ConfigureWidgetForViewportUi(QPointer<QWidget> widget)
|
||||
static void ConfigureWindowForViewportUi(QPointer<QMainWindow> mainWindow)
|
||||
{
|
||||
// no background for the widget else each set of buttons/textfields/etc would have a black box around them
|
||||
SetTransparentBackground(widget);
|
||||
widget->setWindowFlags(Qt::Window | Qt::FramelessWindowHint);
|
||||
// no background for the widget else each set of buttons/text-fields/etc would have a black box around them
|
||||
SetTransparentBackground(mainWindow);
|
||||
mainWindow->setWindowFlags(Qt::Window | Qt::FramelessWindowHint | Qt::WindowDoesNotAcceptFocus);
|
||||
}
|
||||
|
||||
void ViewportUiDisplay::InitializeUiOverlay()
|
||||
{
|
||||
m_uiMainWindow.setObjectName(m_uiMainWindow.windowTitle());
|
||||
ConfigureWidgetForViewportUi(&m_uiMainWindow);
|
||||
m_uiMainWindow.setObjectName(QString("ViewportUiWindow"));
|
||||
ConfigureWindowForViewportUi(&m_uiMainWindow);
|
||||
m_uiMainWindow.setVisible(false);
|
||||
|
||||
m_uiOverlay.setObjectName(m_uiOverlay.windowTitle());
|
||||
m_uiOverlay.setObjectName(QString("ViewportUiOverlay"));
|
||||
m_uiMainWindow.setCentralWidget(&m_uiOverlay);
|
||||
m_uiOverlay.setVisible(false);
|
||||
|
||||
@@ -382,8 +358,7 @@ namespace AzToolsFramework::ViewportUi::Internal
|
||||
m_fullScreenLayout.addLayout(&m_uiOverlayLayout, 0, 0, 1, 1);
|
||||
|
||||
// format the label which will appear on top of the highlight border
|
||||
AZStd::string styleSheet = AZStd::string::format(
|
||||
"background-color: %s; border: none;", HighlightBorderColor);
|
||||
AZStd::string styleSheet = AZStd::string::format("background-color: %s; border: none;", HighlightBorderColor);
|
||||
m_componentModeBorderText.setStyleSheet(styleSheet.c_str());
|
||||
m_componentModeBorderText.setFixedHeight(TopHighlightBorderSize);
|
||||
m_componentModeBorderText.setVisible(false);
|
||||
@@ -408,7 +383,7 @@ namespace AzToolsFramework::ViewportUi::Internal
|
||||
m_renderOverlay->setFocus();
|
||||
}
|
||||
|
||||
void ViewportUiDisplay::SetUiOverlayContentsAnchored(QPointer<QWidget> widget, Qt::Alignment alignment)
|
||||
void ViewportUiDisplay::SetUiOverlayContentsAnchored(QPointer<QWidget> widget, const Qt::Alignment alignment)
|
||||
{
|
||||
if (!widget)
|
||||
{
|
||||
@@ -429,13 +404,8 @@ namespace AzToolsFramework::ViewportUi::Internal
|
||||
// get the border region by taking the entire region and subtracting the non-border area
|
||||
region += m_uiOverlay.rect();
|
||||
region -= QRect(
|
||||
QPoint(
|
||||
m_uiOverlay.rect().left() + HighlightBorderSize,
|
||||
m_uiOverlay.rect().top() + TopHighlightBorderSize),
|
||||
QPoint(
|
||||
m_uiOverlay.rect().right() - HighlightBorderSize,
|
||||
m_uiOverlay.rect().bottom() - HighlightBorderSize)
|
||||
);
|
||||
QPoint(m_uiOverlay.rect().left() + HighlightBorderSize, m_uiOverlay.rect().top() + TopHighlightBorderSize),
|
||||
QPoint(m_uiOverlay.rect().right() - HighlightBorderSize, m_uiOverlay.rect().bottom() - HighlightBorderSize));
|
||||
}
|
||||
|
||||
// add all children widget regions
|
||||
@@ -465,8 +435,7 @@ namespace AzToolsFramework::ViewportUi::Internal
|
||||
|
||||
ViewportUiElementInfo ViewportUiDisplay::GetViewportUiElementInfo(const ViewportUiElementId elementId)
|
||||
{
|
||||
if (auto element = m_viewportUiElements.find(elementId);
|
||||
element != m_viewportUiElements.end())
|
||||
if (auto element = m_viewportUiElements.find(elementId); element != m_viewportUiElements.end())
|
||||
{
|
||||
return element->second;
|
||||
}
|
||||
@@ -488,7 +457,7 @@ namespace AzToolsFramework::ViewportUi::Internal
|
||||
return &m_uiOverlayLayout;
|
||||
}
|
||||
|
||||
void SetTransparentBackground(QWidget * widget)
|
||||
void SetTransparentBackground(QWidget* widget)
|
||||
{
|
||||
widget->setAttribute(Qt::WA_TranslucentBackground);
|
||||
widget->setAutoFillBackground(false);
|
||||
|
||||
@@ -11,11 +11,12 @@
|
||||
#include <AzToolsFramework/ViewportUi/Button.h>
|
||||
#include <AzToolsFramework/ViewportUi/ButtonGroup.h>
|
||||
#include <AzToolsFramework/ViewportUi/TextField.h>
|
||||
#include <AzToolsFramework/ViewportUi/ViewportUiRequestBus.h>
|
||||
#include <AzToolsFramework/ViewportUi/ViewportUiDisplayLayout.h>
|
||||
#include <AzToolsFramework/ViewportUi/ViewportUiRequestBus.h>
|
||||
|
||||
#include <QLabel>
|
||||
#include <QMainWindow>
|
||||
#include <QPointer>
|
||||
#include <QLabel>
|
||||
|
||||
AZ_PUSH_DISABLE_WARNING(4251, "-Wunknown-warning-option")
|
||||
#include <QGridLayout>
|
||||
@@ -28,10 +29,10 @@ namespace AzToolsFramework::ViewportUi::Internal
|
||||
//! Used to track info for each widget in the Viewport UI.
|
||||
struct ViewportUiElementInfo
|
||||
{
|
||||
AZStd::shared_ptr<QWidget> m_widget; //<! Reference to the widget.
|
||||
ViewportUiElementId m_viewportUiElementId; //<! Corresponding ViewportUiElementId of the widget.
|
||||
bool m_anchored = true; //<! Whether the widget is anchored to one position or moves with camera/entity.
|
||||
AZ::Vector3 m_worldPosition; //<! If not anchored, use this to project widget position to screen space.
|
||||
AZStd::shared_ptr<QWidget> m_widget; //!< Reference to the widget.
|
||||
ViewportUiElementId m_viewportUiElementId; //!< Corresponding ViewportUiElementId of the widget.
|
||||
bool m_anchored = true; //!< Whether the widget is anchored to one position or moves with camera/entity.
|
||||
AZ::Vector3 m_worldPosition; //!< If not anchored, use this to project widget position to screen space.
|
||||
|
||||
bool IsValid() const
|
||||
{
|
||||
@@ -52,14 +53,14 @@ namespace AzToolsFramework::ViewportUi::Internal
|
||||
ViewportUiDisplay(QWidget* parent, QWidget* renderOverlay);
|
||||
~ViewportUiDisplay();
|
||||
|
||||
void AddCluster(AZStd::shared_ptr<ButtonGroup> buttonGroup, Alignment align);
|
||||
void AddCluster(AZStd::shared_ptr<ButtonGroup> buttonGroup, Alignment alignment);
|
||||
void AddClusterButton(ViewportUiElementId clusterId, Button* button);
|
||||
void SetClusterButtonLocked(ViewportUiElementId clusterId, ButtonId buttonId, bool isLocked);
|
||||
void SetClusterButtonTooltip(ViewportUiElementId clusterId, ButtonId buttonId, const AZStd::string& tooltip);
|
||||
void RemoveClusterButton(ViewportUiElementId clusterId, ButtonId buttonId);
|
||||
void UpdateCluster(const ViewportUiElementId clusterId);
|
||||
|
||||
void AddSwitcher(AZStd::shared_ptr<ButtonGroup> buttonGroup, Alignment align);
|
||||
void AddSwitcher(AZStd::shared_ptr<ButtonGroup> buttonGroup, Alignment alignment);
|
||||
void AddSwitcherButton(ViewportUiElementId switcherId, Button* button);
|
||||
void RemoveSwitcherButton(ViewportUiElementId switcherId, ButtonId buttonId);
|
||||
void UpdateSwitcher(ViewportUiElementId switcherId);
|
||||
@@ -90,13 +91,12 @@ namespace AzToolsFramework::ViewportUi::Internal
|
||||
|
||||
void CreateComponentModeBorder(const AZStd::string& borderTitle);
|
||||
void RemoveComponentModeBorder();
|
||||
|
||||
|
||||
private:
|
||||
void PrepareWidgetForViewportUi(QPointer<QWidget> widget);
|
||||
|
||||
ViewportUiElementId AddViewportUiElement(AZStd::shared_ptr<QWidget> widget);
|
||||
ViewportUiElementId GetViewportUiElementId(QPointer<QWidget> widget);
|
||||
void AddMaximumSizeViewportUiElement(QPointer<QWidget> widget);
|
||||
|
||||
void PositionViewportUiElementFromWorldSpace(ViewportUiElementId elementId, const AZ::Vector3& pos);
|
||||
void PositionViewportUiElementAnchored(ViewportUiElementId elementId, const Qt::Alignment alignment);
|
||||
@@ -109,16 +109,16 @@ namespace AzToolsFramework::ViewportUi::Internal
|
||||
|
||||
ViewportUiElementInfo GetViewportUiElementInfo(const ViewportUiElementId elementId);
|
||||
|
||||
QMainWindow m_uiMainWindow; //<! The window which contains the UI Overlay.
|
||||
QWidget m_uiOverlay; //<! The UI Overlay which displays Viewport UI Elements.
|
||||
QGridLayout m_fullScreenLayout; //<! The layout which extends across the full screen.
|
||||
ViewportUiDisplayLayout m_uiOverlayLayout; //<! The layout used for optionally anchoring Viewport UI Elements.
|
||||
QLabel m_componentModeBorderText; //<! The text used for the Component Mode border.
|
||||
QMainWindow m_uiMainWindow; //!< The window which contains the UI Overlay.
|
||||
QWidget m_uiOverlay; //!< The UI Overlay which displays Viewport UI Elements.
|
||||
QGridLayout m_fullScreenLayout; //!< The layout which extends across the full screen.
|
||||
ViewportUiDisplayLayout m_uiOverlayLayout; //!< The layout used for optionally anchoring Viewport UI Elements.
|
||||
QLabel m_componentModeBorderText; //!< The text used for the Component Mode border.
|
||||
|
||||
QWidget* m_renderOverlay;
|
||||
QPointer<QWidget> m_fullScreenWidget; //<! Reference to the widget attached to m_fullScreenLayout if any.
|
||||
int m_viewportId;
|
||||
int64_t m_numViewportElements = 0;
|
||||
QPointer<QWidget> m_fullScreenWidget; //!< Reference to the widget attached to m_fullScreenLayout if any.
|
||||
int64_t m_numViewportElements = 0;
|
||||
int m_viewportId = 0;
|
||||
|
||||
ViewportUiElementIdInfoLookup m_viewportUiElements;
|
||||
};
|
||||
|
||||
+10
-7
@@ -6,15 +6,19 @@
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include <AzCore/Console/IConsole.h>
|
||||
#include <AzToolsFramework/ViewportUi/ViewportUiDisplayLayout.h>
|
||||
#include <QtWidgets/QWidget>
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
namespace AzToolsFramework::ViewportUi::Internal
|
||||
{
|
||||
AZ_CVAR(
|
||||
int, ViewportUiDisplayLayoutSpacing, 5, nullptr, AZ::ConsoleFunctorFlags::Null,
|
||||
int,
|
||||
ViewportUiDisplayLayoutSpacing,
|
||||
5,
|
||||
nullptr,
|
||||
AZ::ConsoleFunctorFlags::Null,
|
||||
"The spacing between elements attached to the Viewport UI Display Layout");
|
||||
|
||||
ViewportUiDisplayLayout::ViewportUiDisplayLayout(QWidget* parent)
|
||||
@@ -27,7 +31,7 @@ namespace AzToolsFramework::ViewportUi::Internal
|
||||
setSpacing(ViewportUiDisplayLayoutSpacing);
|
||||
|
||||
// create a 3x2 map of sub layouts which will stack widgets according to their mapped alignment
|
||||
m_internalLayouts = AZStd::unordered_map<Qt::Alignment, QBoxLayout*> {
|
||||
m_internalLayouts = AZStd::unordered_map<Qt::Alignment, QBoxLayout*>{
|
||||
CreateSubLayout(new QVBoxLayout(), 0, 0, Qt::AlignTop | Qt::AlignLeft),
|
||||
CreateSubLayout(new QVBoxLayout(), 1, 0, Qt::AlignBottom | Qt::AlignLeft),
|
||||
CreateSubLayout(new QVBoxLayout(), 0, 1, Qt::AlignTop),
|
||||
@@ -45,8 +49,7 @@ namespace AzToolsFramework::ViewportUi::Internal
|
||||
}
|
||||
|
||||
// find the corresponding sub layout for the alignment and add the widget
|
||||
if (auto layoutForAlignment = m_internalLayouts.find(alignment);
|
||||
layoutForAlignment != m_internalLayouts.end())
|
||||
if (auto layoutForAlignment = m_internalLayouts.find(alignment); layoutForAlignment != m_internalLayouts.end())
|
||||
{
|
||||
// place the widget before or after the invisible spacer
|
||||
// depending on the layout alignment
|
||||
@@ -97,7 +100,7 @@ namespace AzToolsFramework::ViewportUi::Internal
|
||||
// without this, alignment and resizing within the sublayouts becomes difficult
|
||||
layout->addStretch(1);
|
||||
|
||||
addLayout(layout, row, column, /*rowSpan=*/ 1, /*colSpan=*/ 1, alignment);
|
||||
addLayout(layout, row, column, /*rowSpan=*/1, /*colSpan=*/1, alignment);
|
||||
|
||||
return { alignment, layout };
|
||||
}
|
||||
|
||||
+3
-3
@@ -9,8 +9,9 @@
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/std/containers/unordered_map.h>
|
||||
#include <QGridLayout>
|
||||
|
||||
#include <QBoxLayout>
|
||||
#include <QGridLayout>
|
||||
#include <QPointer>
|
||||
|
||||
namespace AzToolsFramework::ViewportUi::Internal
|
||||
@@ -33,8 +34,7 @@ namespace AzToolsFramework::ViewportUi::Internal
|
||||
private:
|
||||
//! Create a sub-layout to add to the grid of layouts.
|
||||
//! @return A pair of the new layout along with its alignment on the grid.
|
||||
AZStd::pair<Qt::Alignment, QBoxLayout*> CreateSubLayout(
|
||||
QBoxLayout* layout, int row, int column, Qt::Alignment alignment);
|
||||
AZStd::pair<Qt::Alignment, QBoxLayout*> CreateSubLayout(QBoxLayout* layout, int row, int column, Qt::Alignment alignment);
|
||||
|
||||
//! A mapping of each sub-layout to its corresponding alignment on the grid.
|
||||
AZStd::unordered_map<Qt::Alignment, QBoxLayout*> m_internalLayouts;
|
||||
|
||||
@@ -6,12 +6,11 @@
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include <AzCore/std/smart_ptr/make_shared.h>
|
||||
#include <AzToolsFramework/ViewportUi/Button.h>
|
||||
#include <AzToolsFramework/ViewportUi/ButtonGroup.h>
|
||||
#include <AzToolsFramework/ViewportUi/ViewportUiManager.h>
|
||||
#include <AzToolsFramework/ViewportUi/ViewportUiDisplay.h>
|
||||
#include <AzToolsFramework/ViewportUi/ViewportUiManager.h>
|
||||
|
||||
namespace AzToolsFramework::ViewportUi
|
||||
{
|
||||
@@ -114,7 +113,8 @@ namespace AzToolsFramework::ViewportUi
|
||||
return ButtonId(0);
|
||||
}
|
||||
|
||||
const ButtonId ViewportUiManager::CreateSwitcherButton(const SwitcherId switcherId, const AZStd::string& icon, const AZStd::string& name)
|
||||
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())
|
||||
{
|
||||
@@ -146,8 +146,7 @@ namespace AzToolsFramework::ViewportUi
|
||||
}
|
||||
}
|
||||
|
||||
static void SetViewportUiElementVisible(
|
||||
Internal::ViewportUiDisplay* ui, ViewportUiElementId id, bool visible)
|
||||
static void SetViewportUiElementVisible(Internal::ViewportUiDisplay* ui, ViewportUiElementId id, bool visible)
|
||||
{
|
||||
if (visible)
|
||||
{
|
||||
@@ -186,11 +185,9 @@ namespace AzToolsFramework::ViewportUi
|
||||
}
|
||||
|
||||
const TextFieldId ViewportUiManager::CreateTextField(
|
||||
const AZStd::string& labelText, const AZStd::string& textFieldDefaultText,
|
||||
TextFieldValidationType validationType)
|
||||
const AZStd::string& labelText, const AZStd::string& textFieldDefaultText, TextFieldValidationType validationType)
|
||||
{
|
||||
auto textField = AZStd::make_shared<Internal::TextField>(
|
||||
labelText, textFieldDefaultText, validationType);
|
||||
auto textField = AZStd::make_shared<Internal::TextField>(labelText, textFieldDefaultText, validationType);
|
||||
m_viewportUi->AddTextField(textField);
|
||||
|
||||
return RegisterNewTextField(textField);
|
||||
@@ -206,8 +203,7 @@ namespace AzToolsFramework::ViewportUi
|
||||
}
|
||||
}
|
||||
|
||||
void ViewportUiManager::RegisterTextFieldCallback(
|
||||
TextFieldId textFieldId, AZ::Event<AZStd::string>::Handler& handler)
|
||||
void ViewportUiManager::RegisterTextFieldCallback(TextFieldId textFieldId, AZ::Event<AZStd::string>::Handler& handler)
|
||||
{
|
||||
if (auto textFieldIt = m_textFields.find(textFieldId); textFieldIt != m_textFields.end())
|
||||
{
|
||||
@@ -234,7 +230,6 @@ namespace AzToolsFramework::ViewportUi
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ViewportUiManager::CreateComponentModeBorder(const AZStd::string& borderTitle)
|
||||
{
|
||||
m_viewportUi->CreateComponentModeBorder(borderTitle);
|
||||
@@ -248,8 +243,7 @@ namespace AzToolsFramework::ViewportUi
|
||||
void ViewportUiManager::PressButton(ClusterId clusterId, ButtonId buttonId)
|
||||
{
|
||||
// Find cluster using ID and cluster map
|
||||
if (auto clusterIt = m_clusterButtonGroups.find(clusterId);
|
||||
clusterIt != m_clusterButtonGroups.end())
|
||||
if (auto clusterIt = m_clusterButtonGroups.find(clusterId); clusterIt != m_clusterButtonGroups.end())
|
||||
{
|
||||
clusterIt->second->PressButton(buttonId);
|
||||
}
|
||||
@@ -305,7 +299,7 @@ namespace AzToolsFramework::ViewportUi
|
||||
SwitcherId ViewportUiManager::RegisterNewSwitcher(AZStd::shared_ptr<Internal::ButtonGroup>& buttonGroup)
|
||||
{
|
||||
SwitcherId newId = SwitcherId(m_switcherButtonGroups.size() + 1);
|
||||
m_switcherButtonGroups.insert({newId, buttonGroup});
|
||||
m_switcherButtonGroups.insert({ newId, buttonGroup });
|
||||
|
||||
return newId;
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ namespace AzToolsFramework::ViewportUi
|
||||
{
|
||||
class ButtonGroup;
|
||||
class ViewportUiDisplay;
|
||||
}
|
||||
} // namespace Internal
|
||||
|
||||
class ViewportUiManager : public ViewportUiRequestBus::Handler
|
||||
{
|
||||
|
||||
@@ -65,8 +65,12 @@ namespace AzToolsFramework::ViewportUi::Internal
|
||||
// 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) {
|
||||
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);
|
||||
};
|
||||
|
||||
@@ -78,9 +82,13 @@ namespace AzToolsFramework::ViewportUi::Internal
|
||||
|
||||
// register the action
|
||||
m_widgetCallbacks.AddWidget(
|
||||
action, [updateCallback](QPointer<QObject> object) { updateCallback(static_cast<QAction*>(object.data())); });
|
||||
action,
|
||||
[updateCallback](QPointer<QObject> object)
|
||||
{
|
||||
updateCallback(static_cast<QAction*>(object.data()));
|
||||
});
|
||||
|
||||
m_buttonActionMap.insert({button->m_buttonId, action});
|
||||
m_buttonActionMap.insert({ button->m_buttonId, action });
|
||||
}
|
||||
|
||||
void ViewportUiSwitcher::RemoveButton(ButtonId buttonId)
|
||||
@@ -121,9 +129,12 @@ namespace AzToolsFramework::ViewportUi::Internal
|
||||
// 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
|
||||
// Change the tool button'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); };
|
||||
auto found = [buttonId](Button* button)
|
||||
{
|
||||
return (button->m_buttonId == buttonId);
|
||||
};
|
||||
|
||||
if (auto buttonIt = AZStd::find_if(buttons.begin(), buttons.end(), found); buttonIt != buttons.end())
|
||||
{
|
||||
|
||||
@@ -8,11 +8,11 @@
|
||||
|
||||
#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/Button.h>
|
||||
#include <AzToolsFramework/ViewportUi/ViewportUiWidgetCallbacks.h>
|
||||
#include <functional>
|
||||
|
||||
#include <QPointer>
|
||||
#include <QToolBar>
|
||||
#include <QToolButton>
|
||||
|
||||
+13
-7
@@ -6,7 +6,6 @@
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include "ViewportUiTextField.h"
|
||||
|
||||
#include <AzCore/Console/IConsole.h>
|
||||
@@ -16,7 +15,11 @@
|
||||
namespace AzToolsFramework::ViewportUi::Internal
|
||||
{
|
||||
AZ_CVAR(
|
||||
int, ViewportUiTextFieldLength, 35, nullptr, AZ::ConsoleFunctorFlags::Null,
|
||||
int,
|
||||
ViewportUiTextFieldLength,
|
||||
35,
|
||||
nullptr,
|
||||
AZ::ConsoleFunctorFlags::Null,
|
||||
"The pixel length of the text field part of a ViewportUiTextField");
|
||||
|
||||
ViewportUiTextField::ViewportUiTextField(AZStd::shared_ptr<TextField> textField)
|
||||
@@ -56,11 +59,14 @@ namespace AzToolsFramework::ViewportUi::Internal
|
||||
|
||||
m_lineEdit.setValidator(m_validator);
|
||||
|
||||
connect(&m_lineEdit, &QLineEdit::textEdited, &m_lineEdit, [textField](QString text) {
|
||||
// convert the text using toLocal8Bit().data() as recommended by Qt, then emit signal
|
||||
textField->m_fieldText = text.toLocal8Bit().data();
|
||||
textField->m_textEditedEvent.Signal(textField->m_fieldText);
|
||||
});
|
||||
connect(
|
||||
&m_lineEdit, &QLineEdit::textEdited, &m_lineEdit,
|
||||
[textField](QString text)
|
||||
{
|
||||
// convert the text using toLocal8Bit().data() as recommended by Qt, then emit signal
|
||||
textField->m_fieldText = text.toLocal8Bit().data();
|
||||
textField->m_textEditedEvent.Signal(textField->m_fieldText);
|
||||
});
|
||||
}
|
||||
|
||||
void ViewportUiTextField::Update()
|
||||
|
||||
@@ -7,7 +7,10 @@
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/std/smart_ptr/shared_ptr.h>
|
||||
#include <AzToolsFramework/ViewportUi/TextField.h>
|
||||
|
||||
#include <QLabel>
|
||||
#include <QLineEdit>
|
||||
#include <QWidget>
|
||||
@@ -17,13 +20,10 @@ AZ_PUSH_DISABLE_WARNING(4251, "-Wunknown-warning-option")
|
||||
#include <QVBoxLayout>
|
||||
AZ_POP_DISABLE_WARNING
|
||||
|
||||
#include <AzCore/std/smart_ptr/shared_ptr.h>
|
||||
|
||||
namespace AzToolsFramework::ViewportUi::Internal
|
||||
{
|
||||
//! Helper class for a widget that holds and manages multiple LabelTextFields.
|
||||
class ViewportUiTextField
|
||||
: public QWidget
|
||||
class ViewportUiTextField : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
@@ -34,9 +34,9 @@ namespace AzToolsFramework::ViewportUi::Internal
|
||||
void Update();
|
||||
|
||||
private:
|
||||
QLabel m_label; //<! The text label.
|
||||
QLineEdit m_lineEdit; //<! The editable text field.
|
||||
QValidator* m_validator; //<! The validator for the line edit text.
|
||||
AZStd::shared_ptr<TextField> m_textField; //<! Reference to the text field data struct.
|
||||
QLabel m_label; //!< The text label.
|
||||
QLineEdit m_lineEdit; //!< The editable text field.
|
||||
QValidator* m_validator; //!< The validator for the line edit text.
|
||||
AZStd::shared_ptr<TextField> m_textField; //!< Reference to the text field data struct.
|
||||
};
|
||||
} // namespace AzToolsFramework::ViewportUi::Internal
|
||||
|
||||
+3
-6
@@ -6,13 +6,11 @@
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include "ViewportUiWidgetCallbacks.h"
|
||||
|
||||
namespace AzToolsFramework::ViewportUi::Internal
|
||||
{
|
||||
void ViewportUiWidgetCallbacks::AddWidget(
|
||||
QPointer<QObject> widget, const AZStd::function<void(QPointer<QObject>)>& updateCallback)
|
||||
void ViewportUiWidgetCallbacks::AddWidget(QPointer<QObject> widget, const AZStd::function<void(QPointer<QObject>)>& updateCallback)
|
||||
{
|
||||
if (widget.isNull())
|
||||
{
|
||||
@@ -40,7 +38,7 @@ namespace AzToolsFramework::ViewportUi::Internal
|
||||
{
|
||||
// if widget exists on the manager, register the callback
|
||||
auto callBackWidget = AZStd::find(m_widgets.begin(), m_widgets.end(), widget);
|
||||
AZ_Assert(callBackWidget != m_widgets.end(), "Unable to register a callback for an unregistered widget.")
|
||||
AZ_Assert(callBackWidget != m_widgets.end(), "Unable to register a callback for an unregistered widget.");
|
||||
|
||||
if (callBackWidget != m_widgets.end())
|
||||
{
|
||||
@@ -58,8 +56,7 @@ namespace AzToolsFramework::ViewportUi::Internal
|
||||
RemoveWidget(widget);
|
||||
}
|
||||
// check if the widget has not been deleted externally
|
||||
else if (auto callback = m_updateCallbacks.find(widget);
|
||||
callback != m_updateCallbacks.end())
|
||||
else if (auto callback = m_updateCallbacks.find(widget); callback != m_updateCallbacks.end())
|
||||
{
|
||||
callback->second(widget);
|
||||
}
|
||||
|
||||
+11
-5
@@ -9,12 +9,12 @@
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/Memory/Memory.h>
|
||||
#include <AzCore/std/function/function_template.h>
|
||||
#include <AzCore/std/containers/unordered_map.h>
|
||||
#include <QPointer>
|
||||
#include <QObject>
|
||||
#include <QMetaMethod>
|
||||
#include <AzCore/std/function/function_template.h>
|
||||
|
||||
#include <QMetaMethod>
|
||||
#include <QObject>
|
||||
#include <QPointer>
|
||||
|
||||
namespace AzToolsFramework::ViewportUi::Internal
|
||||
{
|
||||
@@ -30,7 +30,8 @@ namespace AzToolsFramework::ViewportUi::Internal
|
||||
//! Must call ViewportUiWidgetCallbacks::Update to execute the callback.
|
||||
void RegisterUpdateCallback(QPointer<QObject> widget, const AZStd::function<void(QPointer<QObject>)>& callback);
|
||||
void Update();
|
||||
const AZStd::vector<QPointer<QObject>> GetWidgets() const { return m_widgets; }
|
||||
|
||||
const AZStd::vector<QPointer<QObject>>& GetWidgets() const;
|
||||
|
||||
protected:
|
||||
//! A map of all update callbacks and their respective widgets.
|
||||
@@ -38,4 +39,9 @@ namespace AzToolsFramework::ViewportUi::Internal
|
||||
AZStd::unordered_map<QObject*, AZStd::function<void(QPointer<QObject>)>> m_updateCallbacks;
|
||||
AZStd::vector<QPointer<QObject>> m_widgets;
|
||||
};
|
||||
|
||||
inline const AZStd::vector<QPointer<QObject>>& ViewportUiWidgetCallbacks::GetWidgets() const
|
||||
{
|
||||
return m_widgets;
|
||||
}
|
||||
} // namespace AzToolsFramework::ViewportUi::Internal
|
||||
|
||||
@@ -315,7 +315,7 @@ namespace AssetProcessor
|
||||
}
|
||||
}
|
||||
|
||||
for (const AZ::IO::Path& sourcePath : sourcePaths)
|
||||
for (const AZ::IO::PathView& sourcePath : sourcePaths)
|
||||
{
|
||||
// Use JSON Pointer to append elements to the SourcePaths array
|
||||
registry.Set(FixedValueString::format("%s/SourcePaths/%zu", PlaceholderGemKey.c_str(), pathIndex++),
|
||||
|
||||
@@ -25,8 +25,7 @@ namespace AZ
|
||||
enum class TangentSpace
|
||||
{
|
||||
FromSourceScene = 0,
|
||||
MikkT = 1,
|
||||
EMotionFX = 2
|
||||
MikkT = 1
|
||||
};
|
||||
|
||||
enum class BitangentMethod
|
||||
|
||||
@@ -34,7 +34,6 @@ namespace AZ
|
||||
->Method("GetBitangent", &MeshVertexBitangentData::GetBitangent)
|
||||
->Method("GetBitangentSetIndex", &MeshVertexBitangentData::GetBitangentSetIndex)
|
||||
->Method("GetTangentSpace", &MeshVertexBitangentData::GetTangentSpace)
|
||||
->Enum<(int)SceneAPI::DataTypes::TangentSpace::EMotionFX>("EMotionFX")
|
||||
->Enum<(int)SceneAPI::DataTypes::TangentSpace::FromSourceScene>("FromSourceScene")
|
||||
->Enum<(int)SceneAPI::DataTypes::TangentSpace::MikkT>("MikkT");
|
||||
}
|
||||
|
||||
@@ -34,7 +34,6 @@ namespace AZ
|
||||
->Method("GetTangent", &MeshVertexTangentData::GetTangent)
|
||||
->Method("GetTangentSetIndex", &MeshVertexTangentData::GetTangentSetIndex)
|
||||
->Method("GetTangentSpace", &MeshVertexTangentData::GetTangentSpace)
|
||||
->Enum<(int)SceneAPI::DataTypes::TangentSpace::EMotionFX>("EMotionFX")
|
||||
->Enum<(int)SceneAPI::DataTypes::TangentSpace::FromSourceScene>("FromSourceScene")
|
||||
->Enum<(int)SceneAPI::DataTypes::TangentSpace::MikkT>("MikkT");
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include <SceneAPI/SceneData/Rules/MaterialRule.h>
|
||||
#include <SceneAPI/SceneData/Rules/StaticMeshAdvancedRule.h>
|
||||
#include <SceneAPI/SceneData/Rules/SkeletonProxyRule.h>
|
||||
#include <SceneAPI/SceneData/Rules/TangentsRule.h>
|
||||
#include <SceneAPI/SceneData/Rules/SkinMeshAdvancedRule.h>
|
||||
#include <SceneAPI/SceneData/Rules/SkinRule.h>
|
||||
#include <SceneAPI/SceneData/Rules/CoordinateSystemRule.h>
|
||||
@@ -82,6 +83,10 @@ namespace AZ
|
||||
{
|
||||
modifiers.push_back(azrtti_typeid<CoordinateSystemRule>());
|
||||
}
|
||||
if (existingRules.find(SceneData::TangentsRule::TYPEINFO_Uuid()) == existingRules.end())
|
||||
{
|
||||
modifiers.push_back(SceneData::TangentsRule::TYPEINFO_Uuid());
|
||||
}
|
||||
}
|
||||
else if (target.RTTI_IsTypeOf(DataTypes::ISkinGroup::TYPEINFO_Uuid()))
|
||||
{
|
||||
|
||||
@@ -27,114 +27,14 @@ namespace AZ
|
||||
TangentsRule::TangentsRule()
|
||||
: DataTypes::IRule()
|
||||
, m_tangentSpace(AZ::SceneAPI::DataTypes::TangentSpace::MikkT)
|
||||
, m_bitangentMethod(AZ::SceneAPI::DataTypes::BitangentMethod::Orthogonal)
|
||||
, m_uvSetIndex(0)
|
||||
, m_normalize(true)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
AZ::SceneAPI::DataTypes::TangentSpace TangentsRule::GetTangentSpace() const
|
||||
{
|
||||
return m_tangentSpace;
|
||||
}
|
||||
|
||||
|
||||
AZ::SceneAPI::DataTypes::BitangentMethod TangentsRule::GetBitangentMethod() const
|
||||
{
|
||||
return m_bitangentMethod;
|
||||
}
|
||||
|
||||
|
||||
AZ::u64 TangentsRule::GetUVSetIndex() const
|
||||
{
|
||||
return m_uvSetIndex;
|
||||
}
|
||||
|
||||
|
||||
bool TangentsRule::GetNormalizeVectors() const
|
||||
{
|
||||
return m_normalize;
|
||||
}
|
||||
|
||||
|
||||
// Find UV data.
|
||||
AZ::SceneAPI::DataTypes::IMeshVertexUVData* TangentsRule::FindUVData(AZ::SceneAPI::Containers::SceneGraph& graph, const AZ::SceneAPI::Containers::SceneGraph::NodeIndex& nodeIndex, AZ::u64 uvSet)
|
||||
{
|
||||
const auto nameContentView = AZ::SceneAPI::Containers::Views::MakePairView(graph.GetNameStorage(), graph.GetContentStorage());
|
||||
|
||||
AZ::u64 uvSetIndex = 0;
|
||||
auto meshChildView = AZ::SceneAPI::Containers::Views::MakeSceneGraphChildView<AZ::SceneAPI::Containers::Views::AcceptEndPointsOnly>(graph, nodeIndex, nameContentView.begin(), true);
|
||||
for (auto child = meshChildView.begin(); child != meshChildView.end(); ++child)
|
||||
{
|
||||
AZ::SceneAPI::DataTypes::IMeshVertexUVData* data = azrtti_cast<AZ::SceneAPI::DataTypes::IMeshVertexUVData*>(child->second.get());
|
||||
if (data)
|
||||
{
|
||||
if (uvSetIndex == uvSet)
|
||||
{
|
||||
return data;
|
||||
}
|
||||
uvSetIndex++;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
// Find tangent data.
|
||||
AZ::SceneAPI::DataTypes::IMeshVertexTangentData* TangentsRule::FindTangentData(AZ::SceneAPI::Containers::SceneGraph& graph, const AZ::SceneAPI::Containers::SceneGraph::NodeIndex& nodeIndex, AZ::u64 setIndex, AZ::SceneAPI::DataTypes::TangentSpace tangentSpace)
|
||||
{
|
||||
const auto nameContentView = AZ::SceneAPI::Containers::Views::MakePairView(graph.GetNameStorage(), graph.GetContentStorage());
|
||||
|
||||
auto meshChildView = AZ::SceneAPI::Containers::Views::MakeSceneGraphChildView<AZ::SceneAPI::Containers::Views::AcceptEndPointsOnly>(graph, nodeIndex, nameContentView.begin(), true);
|
||||
for (auto child = meshChildView.begin(); child != meshChildView.end(); ++child)
|
||||
{
|
||||
AZ::SceneAPI::DataTypes::IMeshVertexTangentData* data = azrtti_cast<AZ::SceneAPI::DataTypes::IMeshVertexTangentData*>(child->second.get());
|
||||
if (data)
|
||||
{
|
||||
if (setIndex == data->GetTangentSetIndex() && tangentSpace == data->GetTangentSpace())
|
||||
{
|
||||
return data;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
// Find bitangent data.
|
||||
AZ::SceneAPI::DataTypes::IMeshVertexBitangentData* TangentsRule::FindBitangentData(AZ::SceneAPI::Containers::SceneGraph& graph, const AZ::SceneAPI::Containers::SceneGraph::NodeIndex& nodeIndex, AZ::u64 setIndex, AZ::SceneAPI::DataTypes::TangentSpace tangentSpace)
|
||||
{
|
||||
const auto nameContentView = AZ::SceneAPI::Containers::Views::MakePairView(graph.GetNameStorage(), graph.GetContentStorage());
|
||||
|
||||
auto meshChildView = AZ::SceneAPI::Containers::Views::MakeSceneGraphChildView<AZ::SceneAPI::Containers::Views::AcceptEndPointsOnly>(graph, nodeIndex, nameContentView.begin(), true);
|
||||
for (auto child = meshChildView.begin(); child != meshChildView.end(); ++child)
|
||||
{
|
||||
AZ::SceneAPI::DataTypes::IMeshVertexBitangentData* data = azrtti_cast<AZ::SceneAPI::DataTypes::IMeshVertexBitangentData*>(child->second.get());
|
||||
if (data)
|
||||
{
|
||||
if (setIndex == data->GetBitangentSetIndex() && tangentSpace == data->GetTangentSpace())
|
||||
{
|
||||
return data;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
AZ::Crc32 TangentsRule::GetNormalizeVisibility() const
|
||||
{
|
||||
return (m_tangentSpace == AZ::SceneAPI::DataTypes::TangentSpace::EMotionFX) ? AZ::Edit::PropertyVisibility::Hide : AZ::Edit::PropertyVisibility::Show;
|
||||
}
|
||||
|
||||
AZ::Crc32 TangentsRule::GetOrthogonalVisibility() const
|
||||
{
|
||||
return (m_tangentSpace == AZ::SceneAPI::DataTypes::TangentSpace::EMotionFX) ? AZ::Edit::PropertyVisibility::Hide : AZ::Edit::PropertyVisibility::Show;
|
||||
}
|
||||
|
||||
void TangentsRule::Reflect(AZ::ReflectContext* context)
|
||||
{
|
||||
AZ::SerializeContext* serializeContext = azrtti_cast<AZ::SerializeContext*>(context);
|
||||
@@ -143,11 +43,8 @@ namespace AZ
|
||||
return;
|
||||
}
|
||||
|
||||
serializeContext->Class<TangentsRule, DataTypes::IRule>()->Version(2)
|
||||
->Field("tangentSpace", &TangentsRule::m_tangentSpace)
|
||||
->Field("bitangentMethod", &TangentsRule::m_bitangentMethod)
|
||||
->Field("normalize", &TangentsRule::m_normalize)
|
||||
->Field("uvSetIndex", &TangentsRule::m_uvSetIndex);
|
||||
serializeContext->Class<TangentsRule, DataTypes::IRule>()->Version(3)
|
||||
->Field("tangentSpace", &TangentsRule::m_tangentSpace);
|
||||
|
||||
AZ::EditContext* editContext = serializeContext->GetEditContext();
|
||||
if (editContext)
|
||||
@@ -159,17 +56,7 @@ namespace AZ
|
||||
->DataElement(AZ::Edit::UIHandlers::ComboBox, &AZ::SceneAPI::SceneData::TangentsRule::m_tangentSpace, "Tangent space", "Specify the tangent space used for normal map baking. Choose 'From Fbx' to extract the tangents and bitangents directly from the Fbx file. When there is no tangents rule or the Fbx has no tangents stored inside it, the 'MikkT' option will be used with orthogonal tangents of unit length, so with the normalize option enabled, using the first UV set.")
|
||||
->EnumAttribute(AZ::SceneAPI::DataTypes::TangentSpace::FromSourceScene, "From Source Scene")
|
||||
->EnumAttribute(AZ::SceneAPI::DataTypes::TangentSpace::MikkT, "MikkT")
|
||||
->EnumAttribute(AZ::SceneAPI::DataTypes::TangentSpace::EMotionFX, "EMotion FX")
|
||||
->Attribute(AZ::Edit::Attributes::ChangeNotify, AZ::Edit::PropertyRefreshLevels::EntireTree)
|
||||
->DataElement(AZ::Edit::UIHandlers::ComboBox, &AZ::SceneAPI::SceneData::TangentsRule::m_bitangentMethod, "Bitangents", "Set to 'use from tangent space' to use the bitangents generated by the algorithm used or inside the fbx file. This can result in non-orthogonal tangents. Set to 'orthogonal' to skip storing the bitangents and let the engine calculate the bitangents in a way it will be perpendicular to both the normal and tangent.")
|
||||
->EnumAttribute(AZ::SceneAPI::DataTypes::BitangentMethod::UseFromTangentSpace, "Use from tangent space")
|
||||
->EnumAttribute(AZ::SceneAPI::DataTypes::BitangentMethod::Orthogonal, "Orthogonal")
|
||||
->Attribute(AZ::Edit::Attributes::Visibility, &TangentsRule::GetOrthogonalVisibility)
|
||||
->DataElement(AZ::Edit::UIHandlers::Default, &TangentsRule::m_uvSetIndex, "Uv set", "The UV set index to generate the tangents from. A value of 0 means the first uv set, while 1 means the second uv set.")
|
||||
->Attribute(AZ::Edit::Attributes::Min, 0)
|
||||
->Attribute(AZ::Edit::Attributes::Max, 1)
|
||||
->DataElement(AZ::Edit::UIHandlers::Default, &TangentsRule::m_normalize, "Normalize", "Normalize the tangents and bitangents? When disabled the vectors might no be unit length, which can be useful for relief mapping.")
|
||||
->Attribute(AZ::Edit::Attributes::Visibility, &TangentsRule::GetNormalizeVisibility)
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,24 +46,11 @@ namespace AZ
|
||||
SCENE_DATA_API ~TangentsRule() override = default;
|
||||
|
||||
SCENE_DATA_API AZ::SceneAPI::DataTypes::TangentSpace GetTangentSpace() const;
|
||||
SCENE_DATA_API AZ::SceneAPI::DataTypes::BitangentMethod GetBitangentMethod() const;
|
||||
SCENE_DATA_API AZ::u64 GetUVSetIndex() const;
|
||||
SCENE_DATA_API bool GetNormalizeVectors() const;
|
||||
|
||||
SCENE_DATA_API static AZ::SceneAPI::DataTypes::IMeshVertexUVData* FindUVData(AZ::SceneAPI::Containers::SceneGraph& graph, const AZ::SceneAPI::Containers::SceneGraph::NodeIndex& nodeIndex, AZ::u64 uvSet);
|
||||
SCENE_DATA_API static AZ::SceneAPI::DataTypes::IMeshVertexTangentData* FindTangentData(AZ::SceneAPI::Containers::SceneGraph& graph, const AZ::SceneAPI::Containers::SceneGraph::NodeIndex& nodeIndex, AZ::u64 setIndex, AZ::SceneAPI::DataTypes::TangentSpace tangentSpace);
|
||||
SCENE_DATA_API static AZ::SceneAPI::DataTypes::IMeshVertexBitangentData* FindBitangentData(AZ::SceneAPI::Containers::SceneGraph& graph, const AZ::SceneAPI::Containers::SceneGraph::NodeIndex& nodeIndex, AZ::u64 setIndex, AZ::SceneAPI::DataTypes::TangentSpace tangentSpace);
|
||||
|
||||
static void Reflect(ReflectContext* context);
|
||||
|
||||
protected:
|
||||
AZ::Crc32 GetNormalizeVisibility() const;
|
||||
AZ::Crc32 GetOrthogonalVisibility() const;
|
||||
|
||||
AZ::SceneAPI::DataTypes::TangentSpace m_tangentSpace; /**< Specifies how to handle tangents. Either generate them, or import them. */
|
||||
AZ::SceneAPI::DataTypes::BitangentMethod m_bitangentMethod; /**< Grab the bitangents from the generator/source or use an orthogonal basis by always calculating them? */
|
||||
AZ::u64 m_uvSetIndex; /**< Generate the tangents from this UV set. */
|
||||
bool m_normalize; /**< Normalize the tangent and bitangents? */
|
||||
AZ::SceneAPI::DataTypes::TangentSpace m_tangentSpace; /**< Specifies how to handle tangents. Either generate them, or import them. */
|
||||
};
|
||||
} // SceneData
|
||||
} // SceneAPI
|
||||
|
||||
@@ -94,7 +94,7 @@ namespace AZ
|
||||
tangentData->AppendTangent(AZ::Vector4{0.12f, 0.34f, 0.56f, 0.78f});
|
||||
tangentData->AppendTangent(AZ::Vector4{0.18f, 0.28f, 0.19f, 0.29f});
|
||||
tangentData->AppendTangent(AZ::Vector4{0.21f, 0.43f, 0.65f, 0.87f});
|
||||
tangentData->SetTangentSpace(AZ::SceneAPI::DataTypes::TangentSpace::EMotionFX);
|
||||
tangentData->SetTangentSpace(AZ::SceneAPI::DataTypes::TangentSpace::MikkT);
|
||||
tangentData->SetTangentSetIndex(2);
|
||||
return true;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user