Merge pull request #5202 from aws-lumberyard-dev/mbalfour/gitflow_211102_o3de

Merging stabilization/2110 to development
This commit is contained in:
Mike Balfour
2021-11-02 13:33:14 -05:00
committed by GitHub
66 changed files with 605 additions and 358 deletions
@@ -6,7 +6,11 @@
#
#
if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS)
ly_get_list_relative_pal_filename(pal_dir ${CMAKE_CURRENT_LIST_DIR}/Platform/${PAL_PLATFORM_NAME})
include(${pal_dir}/PAL_${PAL_PLATFORM_NAME_LOWERCASE}.cmake) # for PAL_TRAIT_BLAST Traits
if(PAL_TRAIT_BLAST_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS)
ly_add_pytest(
NAME AutomatedTesting::BlastTests_Main
TEST_SUITE main
@@ -0,0 +1,9 @@
#
# 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
#
#
set(PAL_TRAIT_BLAST_TESTS_SUPPORTED FALSE)
@@ -0,0 +1,9 @@
#
# 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
#
#
set(PAL_TRAIT_BLAST_TESTS_SUPPORTED FALSE)
@@ -0,0 +1,9 @@
#
# 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
#
#
set(PAL_TRAIT_BLAST_TESTS_SUPPORTED FALSE)
@@ -0,0 +1,9 @@
#
# 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
#
#
set(PAL_TRAIT_BLAST_TESTS_SUPPORTED TRUE)
@@ -0,0 +1,9 @@
#
# 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
#
#
set(PAL_TRAIT_BLAST_TESTS_SUPPORTED FALSE)
@@ -6,7 +6,11 @@
#
#
if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS)
ly_get_list_relative_pal_filename(pal_dir ${CMAKE_CURRENT_LIST_DIR}/Platform/${PAL_PLATFORM_NAME})
include(${pal_dir}/PAL_${PAL_PLATFORM_NAME_LOWERCASE}.cmake) # for PAL_TRAIT_WHITEBOX Traits
if(PAL_TRAIT_WHITEBOX_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS)
ly_add_pytest(
NAME AutomatedTesting::WhiteBoxTests
TEST_SUITE main
@@ -0,0 +1,9 @@
#
# 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
#
#
set(PAL_TRAIT_WHITEBOX_TESTS_SUPPORTED FALSE)
@@ -0,0 +1,9 @@
#
# 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
#
#
set(PAL_TRAIT_WHITEBOX_TESTS_SUPPORTED FALSE)
@@ -0,0 +1,9 @@
#
# 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
#
#
set(PAL_TRAIT_WHITEBOX_TESTS_SUPPORTED FALSE)
@@ -0,0 +1,9 @@
#
# 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
#
#
set(PAL_TRAIT_WHITEBOX_TESTS_SUPPORTED TRUE)
@@ -0,0 +1,9 @@
#
# 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
#
#
set(PAL_TRAIT_WHITEBOX_TESTS_SUPPORTED FALSE)
+1 -1
View File
@@ -832,7 +832,7 @@ QAction* LevelEditorMenuHandler::CreateViewPaneAction(const QtViewPane* view)
if (view->m_options.showOnToolsToolbar)
{
action->setIcon(QIcon(view->m_options.toolbarIcon));
action->setIcon(QIcon(view->m_options.toolbarIcon.c_str()));
}
m_actionManager->AddAction(view->m_id, action);
@@ -85,6 +85,7 @@ namespace UnitTest
m_rootWidget = AZStd::make_unique<QWidget>();
m_rootWidget->setFixedSize(QSize(100, 100));
QApplication::setActiveWindow(m_rootWidget.get());
m_controllerList = AZStd::make_shared<AzFramework::ViewportControllerList>();
m_controllerList->RegisterViewportContext(TestViewportId);
@@ -100,6 +101,8 @@ namespace UnitTest
m_controllerList.reset();
m_rootWidget.reset();
QApplication::setActiveWindow(nullptr);
AllocatorsTestFixture::TearDown();
}
@@ -110,7 +113,7 @@ namespace UnitTest
const AzFramework::ViewportId ViewportManipulatorControllerFixture::TestViewportId = AzFramework::ViewportId(0);
TEST_F(ViewportManipulatorControllerFixture, An_event_is_not_propagated_to_the_viewport_when_a_manipulator_handles_it_first)
TEST_F(ViewportManipulatorControllerFixture, AnEventIsNotPropagatedToTheViewportWhenAManipulatorHandlesItFirst)
{
// forward input events to our controller list
QObject::connect(
@@ -151,4 +154,77 @@ namespace UnitTest
editorInteractionViewportFake.Disconnect();
}
TEST_F(ViewportManipulatorControllerFixture, ChangingFocusDoesNotClearInput)
{
bool endedEvent = false;
// detect input events and ensure that the Alt key press does not end before the end of the test
QObject::connect(
m_inputChannelMapper.get(), &AzToolsFramework::QtEventToAzInputMapper::InputChannelUpdated, m_rootWidget.get(),
[&endedEvent](const AzFramework::InputChannel* inputChannel, [[maybe_unused]] QEvent* event)
{
if (inputChannel->GetInputChannelId() == AzFramework::InputDeviceKeyboard::Key::ModifierAltL &&
inputChannel->IsStateEnded())
{
endedEvent = true;
}
});
// given
auto* secondaryWidget = new QWidget(m_rootWidget.get());
m_rootWidget->show();
secondaryWidget->show();
m_rootWidget->setFocus();
// simulate a key press when root widget has focus
QTest::keyPress(m_rootWidget.get(), Qt::Key_Alt, Qt::KeyboardModifier::AltModifier);
// when
// change focus to secondary widget
secondaryWidget->setFocus();
// then
// the alt key was not released (cleared)
EXPECT_FALSE(endedEvent);
}
// note: Application State Change includes events such as switching to another application or minimizing
// the current application
TEST_F(ViewportManipulatorControllerFixture, ApplicationStateChangeDoesClearInput)
{
bool endedEvent = false;
// detect input events and ensure that the Alt key press does not end before the end of the test
QObject::connect(
m_inputChannelMapper.get(), &AzToolsFramework::QtEventToAzInputMapper::InputChannelUpdated, m_rootWidget.get(),
[&endedEvent](const AzFramework::InputChannel* inputChannel, [[maybe_unused]] QEvent* event)
{
if (inputChannel->GetInputChannelId() == AzFramework::InputDeviceKeyboard::Key::AlphanumericW &&
inputChannel->IsStateEnded())
{
endedEvent = true;
}
});
// given
auto* secondaryWidget = new QWidget(m_rootWidget.get());
m_rootWidget->show();
secondaryWidget->show();
m_rootWidget->setFocus();
// simulate a key press when root widget has focus
QTest::keyPress(m_rootWidget.get(), Qt::Key_W);
// when
// simulate changing the window state
QApplicationStateChangeEvent applicationStateChangeEvent(Qt::ApplicationState::ApplicationInactive);
QCoreApplication::sendEvent(m_rootWidget.get(), &applicationStateChangeEvent);
// then
// the key was released (cleared)
EXPECT_TRUE(endedEvent);
}
} // namespace UnitTest
@@ -383,36 +383,36 @@ namespace AZ
AZ_MATH_INLINE bool CmpAllEq(__m128 arg1, __m128 arg2, int32_t mask)
{
const __m128i compare = CastToInt(CmpNeq(arg1, arg2));
return (_mm_movemask_epi8(compare) & mask) == 0;
const __m128 compare = CmpEq(arg1, arg2);
return (_mm_movemask_ps(compare) & mask) == mask;
}
AZ_MATH_INLINE bool CmpAllLt(__m128 arg1, __m128 arg2, int32_t mask)
{
const __m128i compare = CastToInt(CmpGtEq(arg1, arg2));
return (_mm_movemask_epi8(compare) & mask) == 0;
const __m128 compare = CmpLt(arg1, arg2);
return (_mm_movemask_ps(compare) & mask) == mask;
}
AZ_MATH_INLINE bool CmpAllLtEq(__m128 arg1, __m128 arg2, int32_t mask)
{
const __m128i compare = CastToInt(CmpGt(arg1, arg2));
return (_mm_movemask_epi8(compare) & mask) == 0;
const __m128 compare = CmpLtEq(arg1, arg2);
return (_mm_movemask_ps(compare) & mask) == mask;
}
AZ_MATH_INLINE bool CmpAllGt(__m128 arg1, __m128 arg2, int32_t mask)
{
const __m128i compare = CastToInt(CmpLtEq(arg1, arg2));
return (_mm_movemask_epi8(compare) & mask) == 0;
const __m128 compare = CmpGt(arg1, arg2);
return (_mm_movemask_ps(compare) & mask) == mask;
}
AZ_MATH_INLINE bool CmpAllGtEq(__m128 arg1, __m128 arg2, int32_t mask)
{
const __m128i compare = CastToInt(CmpLt(arg1, arg2));
return (_mm_movemask_epi8(compare) & mask) == 0;
const __m128 compare = CmpGtEq(arg1, arg2);
return (_mm_movemask_ps(compare) & mask) == mask;
}
@@ -331,31 +331,32 @@ namespace AZ
AZ_MATH_INLINE bool Vec1::CmpAllEq(FloatArgType arg1, FloatArgType arg2)
{
return Sse::CmpAllEq(arg1, arg2, 0x000F);
// Only check the first bit for Vector1
return Sse::CmpAllEq(arg1, arg2, 0b0001);
}
AZ_MATH_INLINE bool Vec1::CmpAllLt(FloatArgType arg1, FloatArgType arg2)
{
return Sse::CmpAllLt(arg1, arg2, 0x000F);
return Sse::CmpAllLt(arg1, arg2, 0b0001);
}
AZ_MATH_INLINE bool Vec1::CmpAllLtEq(FloatArgType arg1, FloatArgType arg2)
{
return Sse::CmpAllLtEq(arg1, arg2, 0x000F);
return Sse::CmpAllLtEq(arg1, arg2, 0b0001);
}
AZ_MATH_INLINE bool Vec1::CmpAllGt(FloatArgType arg1, FloatArgType arg2)
{
return Sse::CmpAllGt(arg1, arg2, 0x000F);
return Sse::CmpAllGt(arg1, arg2, 0b0001);
}
AZ_MATH_INLINE bool Vec1::CmpAllGtEq(FloatArgType arg1, FloatArgType arg2)
{
return Sse::CmpAllGtEq(arg1, arg2, 0x000F);
return Sse::CmpAllGtEq(arg1, arg2, 0b0001);
}
@@ -397,7 +398,7 @@ namespace AZ
AZ_MATH_INLINE bool Vec1::CmpAllEq(Int32ArgType arg1, Int32ArgType arg2)
{
return Sse::CmpAllEq(arg1, arg2, 0x000F);
return Sse::CmpAllEq(arg1, arg2, 0b0001);
}
@@ -383,31 +383,32 @@ namespace AZ
AZ_MATH_INLINE bool Vec2::CmpAllEq(FloatArgType arg1, FloatArgType arg2)
{
return Sse::CmpAllEq(arg1, arg2, 0x00FF);
// Only check the first two bits for Vector2
return Sse::CmpAllEq(arg1, arg2, 0b0011);
}
AZ_MATH_INLINE bool Vec2::CmpAllLt(FloatArgType arg1, FloatArgType arg2)
{
return Sse::CmpAllLt(arg1, arg2, 0x00FF);
return Sse::CmpAllLt(arg1, arg2, 0b0011);
}
AZ_MATH_INLINE bool Vec2::CmpAllLtEq(FloatArgType arg1, FloatArgType arg2)
{
return Sse::CmpAllLtEq(arg1, arg2, 0x00FF);
return Sse::CmpAllLtEq(arg1, arg2, 0b0011);
}
AZ_MATH_INLINE bool Vec2::CmpAllGt(FloatArgType arg1, FloatArgType arg2)
{
return Sse::CmpAllGt(arg1, arg2, 0x00FF);
return Sse::CmpAllGt(arg1, arg2, 0b0011);
}
AZ_MATH_INLINE bool Vec2::CmpAllGtEq(FloatArgType arg1, FloatArgType arg2)
{
return Sse::CmpAllGtEq(arg1, arg2, 0x00FF);
return Sse::CmpAllGtEq(arg1, arg2, 0b0011);
}
@@ -419,31 +419,32 @@ namespace AZ
AZ_MATH_INLINE bool Vec3::CmpAllEq(FloatArgType arg1, FloatArgType arg2)
{
return Sse::CmpAllEq(arg1, arg2, 0x0FFF);
// Only check the first three bits for Vector3
return Sse::CmpAllEq(arg1, arg2, 0b0111);
}
AZ_MATH_INLINE bool Vec3::CmpAllLt(FloatArgType arg1, FloatArgType arg2)
{
return Sse::CmpAllLt(arg1, arg2, 0x0FFF);
return Sse::CmpAllLt(arg1, arg2, 0b0111);
}
AZ_MATH_INLINE bool Vec3::CmpAllLtEq(FloatArgType arg1, FloatArgType arg2)
{
return Sse::CmpAllLtEq(arg1, arg2, 0x0FFF);
return Sse::CmpAllLtEq(arg1, arg2, 0b0111);
}
AZ_MATH_INLINE bool Vec3::CmpAllGt(FloatArgType arg1, FloatArgType arg2)
{
return Sse::CmpAllGt(arg1, arg2, 0x0FFF);
return Sse::CmpAllGt(arg1, arg2, 0b0111);
}
AZ_MATH_INLINE bool Vec3::CmpAllGtEq(FloatArgType arg1, FloatArgType arg2)
{
return Sse::CmpAllGtEq(arg1, arg2, 0x0FFF);
return Sse::CmpAllGtEq(arg1, arg2, 0b0111);
}
@@ -485,7 +486,7 @@ namespace AZ
AZ_MATH_INLINE bool Vec3::CmpAllEq(Int32ArgType arg1, Int32ArgType arg2)
{
return Sse::CmpAllEq(arg1, arg2, 0x0FFF);
return Sse::CmpAllEq(arg1, arg2, 0b0111);
}
@@ -455,31 +455,32 @@ namespace AZ
AZ_MATH_INLINE bool Vec4::CmpAllEq(FloatArgType arg1, FloatArgType arg2)
{
return Sse::CmpAllEq(arg1, arg2, 0xFFFF);
// Check the first four bits for Vector4
return Sse::CmpAllEq(arg1, arg2, 0b1111);
}
AZ_MATH_INLINE bool Vec4::CmpAllLt(FloatArgType arg1, FloatArgType arg2)
{
return Sse::CmpAllLt(arg1, arg2, 0xFFFF);
return Sse::CmpAllLt(arg1, arg2, 0b1111);
}
AZ_MATH_INLINE bool Vec4::CmpAllLtEq(FloatArgType arg1, FloatArgType arg2)
{
return Sse::CmpAllLtEq(arg1, arg2, 0xFFFF);
return Sse::CmpAllLtEq(arg1, arg2, 0b1111);
}
AZ_MATH_INLINE bool Vec4::CmpAllGt(FloatArgType arg1, FloatArgType arg2)
{
return Sse::CmpAllGt(arg1, arg2, 0xFFFF);
return Sse::CmpAllGt(arg1, arg2, 0b1111);
}
AZ_MATH_INLINE bool Vec4::CmpAllGtEq(FloatArgType arg1, FloatArgType arg2)
{
return Sse::CmpAllGtEq(arg1, arg2, 0xFFFF);
return Sse::CmpAllGtEq(arg1, arg2, 0b1111);
}
@@ -521,7 +522,7 @@ namespace AZ
AZ_MATH_INLINE bool Vec4::CmpAllEq(Int32ArgType arg1, Int32ArgType arg2)
{
return Sse::CmpAllEq(arg1, arg2, 0xFFFF);
return Sse::CmpAllEq(arg1, arg2, 0b1111);
}
@@ -88,6 +88,8 @@ void ScriptSystemComponent::Activate()
AZ::Data::AssetCatalogRequestBus::Broadcast(&AZ::Data::AssetCatalogRequests::AddExtension, "lua");
AZ::Data::AssetCatalogRequestBus::Broadcast(&AZ::Data::AssetCatalogRequests::AddExtension, "luac");
AZ::Data::AssetCatalogRequestBus::Broadcast(
&AZ::Data::AssetCatalogRequests::EnableCatalogForAsset, AZ::AzTypeInfo<AZ::ScriptAsset>::Uuid());
if (Data::AssetManager::Instance().IsReady())
{
@@ -40,7 +40,7 @@ namespace AzToolsFramework
bool isDisabledInSimMode = false; ///< set to true if the view pane should not be openable from level editor menu when editor is in simulation mode.
bool showOnToolsToolbar = false; ///< set to true if the view pane should create a button on the tools toolbar to open/close the pane
QString toolbarIcon; ///< path to the icon to use for the toolbar button - only used if showOnToolsToolbar is set to true
AZStd::string toolbarIcon; ///< path to the icon to use for the toolbar button - only used if showOnToolsToolbar is set to true
};
} // namespace AzToolsFramework
@@ -426,6 +426,8 @@ namespace AzToolsFramework
->Property("showInMenu", BehaviorValueProperty(&ViewPaneOptions::showInMenu))
->Property("canHaveMultipleInstances", BehaviorValueProperty(&ViewPaneOptions::canHaveMultipleInstances))
->Property("isPreview", BehaviorValueProperty(&ViewPaneOptions::isPreview))
->Property("showOnToolsToolbar", BehaviorValueProperty(&ViewPaneOptions::showOnToolsToolbar))
->Property("toolbarIcon", BehaviorValueProperty(&ViewPaneOptions::toolbarIcon))
;
behaviorContext->EBus<EditorRequestBus>("EditorRequestBus")
@@ -102,7 +102,7 @@ namespace AzToolsFramework
AzFramework::AssetCatalogEventBus::Handler::BusDisconnect();
AZ::TickBus::Handler::BusDisconnect();
AssetSystemBus::Handler::BusDisconnect();
m_assetBrowserModel.release();
m_assetBrowserModel.reset();
EntryCache::DestroyInstance();
}
@@ -26,8 +26,12 @@ namespace AzToolsFramework
AZ::Interface<ContainerEntityInterface>::Unregister(this);
}
void ContainerEntitySystemComponent::Reflect([[maybe_unused]] AZ::ReflectContext* context)
void ContainerEntitySystemComponent::Reflect(AZ::ReflectContext* context)
{
if (auto serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
{
serializeContext->Class<ContainerEntitySystemComponent, AZ::Component>()->Version(1);
}
}
void ContainerEntitySystemComponent::GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided)
@@ -47,8 +47,12 @@ namespace AzToolsFramework
AZ::Interface<FocusModeInterface>::Unregister(this);
}
void FocusModeSystemComponent::Reflect([[maybe_unused]] AZ::ReflectContext* context)
void FocusModeSystemComponent::Reflect(AZ::ReflectContext* context)
{
if (auto serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
{
serializeContext->Class<FocusModeSystemComponent, AZ::Component>()->Version(1);
}
}
void FocusModeSystemComponent::GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided)
@@ -210,8 +210,8 @@ namespace AzToolsFramework
m_enabled = enabled;
if (!enabled)
{
// Send an internal focus change event to reset our input state to fresh if we're disabled.
HandleFocusChange(nullptr);
// Clear input channels to reset our input state if we're disabled.
ClearInputChannels(nullptr);
}
}
@@ -246,7 +246,7 @@ namespace AzToolsFramework
if (eventType == QEvent::Type::MouseMove)
{
// clear override cursor when moving outside of the viewport
// Clear override cursor when moving outside of the viewport
const auto* mouseEvent = static_cast<const QMouseEvent*>(event);
if (m_overrideCursor && !m_sourceWidget->geometry().contains(m_sourceWidget->mapFromGlobal(mouseEvent->globalPos())))
{
@@ -255,6 +255,13 @@ namespace AzToolsFramework
}
}
// If the application state changes (e.g. we have alt-tabbed or minimized the
// main editor window) then ensure all input channels are cleared
if (eventType == QEvent::ApplicationStateChange)
{
ClearInputChannels(event);
}
// Only accept mouse & key release events that originate from an object that is not our target widget,
// as we don't want to erroneously intercept user input meant for another component.
if (object != m_sourceWidget && eventType != QEvent::Type::KeyRelease && eventType != QEvent::Type::MouseButtonRelease)
@@ -264,9 +271,6 @@ namespace AzToolsFramework
if (eventType == QEvent::FocusIn || eventType == QEvent::FocusOut)
{
// If our focus changes, go ahead and reset all input devices.
HandleFocusChange(event);
// If we focus in on the source widget and the mouse is contained in its
// bounds, refresh the cached cursor position to ensure it is up to date (this
// ensures cursor positions are refreshed correctly with context menu focus changes)
@@ -451,7 +455,7 @@ namespace AzToolsFramework
NotifyUpdateChannelIfNotIdle(cursorZChannel, wheelEvent);
}
void QtEventToAzInputMapper::HandleFocusChange(QEvent* event)
void QtEventToAzInputMapper::ClearInputChannels(QEvent* event)
{
for (auto& channelData : m_channels)
{
@@ -138,8 +138,9 @@ namespace AzToolsFramework
void HandleKeyEvent(QKeyEvent* keyEvent);
// Handles mouse wheel events.
void HandleWheelEvent(QWheelEvent* wheelEvent);
// Handles focus change events.
void HandleFocusChange(QEvent* event);
// Clear all input channels (set all channel states to 'ended').
void ClearInputChannels(QEvent* event);
// Populates m_keyMappings.
void InitializeKeyMappings();
@@ -80,8 +80,9 @@ namespace AzToolsFramework
private:
AZStd::string m_message; //!< Message to display for fading text.
float m_opacity = 1.0f; //!< The opacity of the invalid click message.
AzFramework::ScreenPoint m_invalidClickPosition; //!< The position to display the invalid click message.
float m_opacity = 0.0f; //!< The opacity of the invalid click message.
//! The position to display the invalid click message.
AzFramework::ScreenPoint m_invalidClickPosition = AzFramework::ScreenPoint(0, 0);
};
//! Interface to begin invalid click feedback (will run all added InvalidClick behaviors).
@@ -28,9 +28,12 @@ namespace UnitTest
return true;
}
void BoundsTestComponent::Reflect([[maybe_unused]] AZ::ReflectContext* context)
void BoundsTestComponent::Reflect(AZ::ReflectContext* context)
{
// noop
if (auto serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
{
serializeContext->Class<BoundsTestComponent, EditorComponentBase>()->Version(1);
}
}
void BoundsTestComponent::Activate()
@@ -42,5 +42,4 @@ namespace UnitTest
AZ::Aabb GetWorldBounds() override;
AZ::Aabb GetLocalBounds() override;
};
} // namespace UnitTest
@@ -240,7 +240,7 @@ namespace O3DE::ProjectManager
PythonBindingsInterface::Get()->AddProject(projectInfo.m_path);
#ifdef TEMPLATE_GEM_CONFIGURATION_ENABLED
const GemCatalogScreen::EnableDisableGemsResult gemResult = m_gemCatalogScreen->EnableDisableGemsForProject(m_projectInfo.m_path);
const GemCatalogScreen::EnableDisableGemsResult gemResult = m_gemCatalogScreen->EnableDisableGemsForProject(projectInfo.m_path);
if (gemResult == GemCatalogScreen::EnableDisableGemsResult::Failed)
{
QMessageBox::critical(this, tr("Failed to configure gems"), tr("Failed to configure gems for template."));
@@ -62,9 +62,6 @@ namespace O3DE::ProjectManager
QPushButton* m_secondaryButton = nullptr;
#endif // TEMPLATE_GEM_CONFIGURATION_ENABLED
QString m_projectTemplatePath;
ProjectInfo m_projectInfo;
NewProjectSettingsScreen* m_newProjectSettingsScreen = nullptr;
GemCatalogScreen* m_gemCatalogScreen = nullptr;
};
@@ -39,7 +39,6 @@ namespace O3DE::ProjectManager
QRect fullRect, itemRect, contentRect;
CalcRects(options, fullRect, itemRect, contentRect);
QRect buttonRect = CalcButtonRect(contentRect);
QFont standardFont(options.font);
standardFont.setPixelSize(static_cast<int>(s_fontSize));
@@ -70,15 +69,12 @@ namespace O3DE::ProjectManager
painter->restore();
}
// Repo enabled
DrawButton(painter, buttonRect, modelIndex);
// Repo name
QString repoName = GemRepoModel::GetName(modelIndex);
repoName = QFontMetrics(standardFont).elidedText(repoName, Qt::TextElideMode::ElideRight, s_nameMaxWidth);
QRect repoNameRect = GetTextRect(standardFont, repoName, s_fontSize);
int currentHorizontalOffset = buttonRect.left() + s_buttonWidth + s_buttonSpacing;
int currentHorizontalOffset = contentRect.left();
repoNameRect.moveTo(currentHorizontalOffset, contentRect.center().y() - repoNameRect.height() / 2);
repoNameRect = painter->boundingRect(repoNameRect, Qt::TextSingleLine, repoName);
@@ -126,7 +122,7 @@ namespace O3DE::ProjectManager
initStyleOption(&options, modelIndex);
int marginsHorizontal = s_itemMargins.left() + s_itemMargins.right() + s_contentMargins.left() + s_contentMargins.right();
return QSize(marginsHorizontal + s_buttonWidth + s_buttonSpacing + s_nameMaxWidth + s_creatorMaxWidth + s_updatedMaxWidth + s_contentSpacing * 3, s_height);
return QSize(marginsHorizontal + s_nameMaxWidth + s_creatorMaxWidth + s_updatedMaxWidth + s_contentSpacing * 3, s_height);
}
bool GemRepoItemDelegate::editorEvent(QEvent* event, QAbstractItemModel* model, const QStyleOptionViewItem& option, const QModelIndex& modelIndex)
@@ -139,13 +135,8 @@ namespace O3DE::ProjectManager
if (event->type() == QEvent::KeyPress)
{
auto keyEvent = static_cast<const QKeyEvent*>(event);
if (keyEvent->key() == Qt::Key_Space)
{
const bool isAdded = GemRepoModel::IsEnabled(modelIndex);
GemRepoModel::SetEnabled(*model, modelIndex, !isAdded);
return true;
}
else if (keyEvent->key() == Qt::Key_X)
if (keyEvent->key() == Qt::Key_X)
{
emit RemoveRepo(modelIndex);
return true;
@@ -163,17 +154,10 @@ namespace O3DE::ProjectManager
QRect fullRect, itemRect, contentRect;
CalcRects(option, fullRect, itemRect, contentRect);
const QRect buttonRect = CalcButtonRect(contentRect);
const QRect deleteButtonRect = CalcDeleteButtonRect(contentRect);
const QRect refreshButtonRect = CalcRefreshButtonRect(contentRect, buttonRect);
const QRect refreshButtonRect = CalcRefreshButtonRect(contentRect);
if (buttonRect.contains(mouseEvent->pos()))
{
const bool isAdded = GemRepoModel::IsEnabled(modelIndex);
GemRepoModel::SetEnabled(*model, modelIndex, !isAdded);
return true;
}
else if (deleteButtonRect.contains(mouseEvent->pos()))
if (deleteButtonRect.contains(mouseEvent->pos()))
{
emit RemoveRepo(modelIndex);
return true;
@@ -201,50 +185,15 @@ namespace O3DE::ProjectManager
return QFontMetrics(font).boundingRect(text);
}
QRect GemRepoItemDelegate::CalcButtonRect(const QRect& contentRect) const
{
const QPoint topLeft = QPoint(contentRect.left(), contentRect.top() + contentRect.height() / 2 - s_buttonHeight / 2);
const QSize size = QSize(s_buttonWidth, s_buttonHeight);
return QRect(topLeft, size);
}
void GemRepoItemDelegate::DrawButton(QPainter* painter, const QRect& buttonRect, const QModelIndex& modelIndex) const
{
painter->save();
QPoint circleCenter;
const bool isEnabled = GemRepoModel::IsEnabled(modelIndex);
if (isEnabled)
{
painter->setBrush(m_buttonEnabledColor);
painter->setPen(m_buttonEnabledColor);
circleCenter = buttonRect.center() + QPoint(buttonRect.width() / 2 - s_buttonBorderRadius + 1, 1);
}
else
{
circleCenter = buttonRect.center() + QPoint(-buttonRect.width() / 2 + s_buttonBorderRadius + 1, 1);
}
// Rounded rect
painter->drawRoundedRect(buttonRect, s_buttonBorderRadius, s_buttonBorderRadius);
// Circle
painter->setBrush(m_textColor);
painter->drawEllipse(circleCenter, s_buttonCircleRadius, s_buttonCircleRadius);
painter->restore();
}
QRect GemRepoItemDelegate::CalcDeleteButtonRect(const QRect& contentRect) const
{
const QPoint topLeft = QPoint(contentRect.right() - s_iconSize, contentRect.center().y() - s_iconSize / 2);
return QRect(topLeft, QSize(s_iconSize, s_iconSize));
}
QRect GemRepoItemDelegate::CalcRefreshButtonRect(const QRect& contentRect, const QRect& buttonRect) const
QRect GemRepoItemDelegate::CalcRefreshButtonRect(const QRect& contentRect) const
{
const int topLeftX = buttonRect.left() + s_buttonWidth + s_buttonSpacing + s_nameMaxWidth + s_creatorMaxWidth + s_updatedMaxWidth + s_contentSpacing * 2 + s_refreshIconSpacing;
const int topLeftX = contentRect.left() + s_nameMaxWidth + s_creatorMaxWidth + s_updatedMaxWidth + s_contentSpacing * 2 + s_refreshIconSpacing;
const QPoint topLeft = QPoint(topLeftX, contentRect.center().y() - s_refreshIconSize / 3);
return QRect(topLeft, QSize(s_refreshIconSize, s_refreshIconSize));
}
@@ -36,7 +36,6 @@ namespace O3DE::ProjectManager
const QColor m_backgroundColor = QColor("#333333"); // Outside of the actual repo item
const QColor m_itemBackgroundColor = QColor("#404040"); // Background color of the repo item
const QColor m_borderColor = QColor("#1E70EB");
const QColor m_buttonEnabledColor = QColor("#1E70EB");
// Item
inline constexpr static int s_height = 72; // Repo item total height
@@ -53,13 +52,6 @@ namespace O3DE::ProjectManager
inline constexpr static int s_creatorMaxWidth = 115;
inline constexpr static int s_updatedMaxWidth = 125;
// Button
inline constexpr static int s_buttonWidth = 32;
inline constexpr static int s_buttonHeight = 16;
inline constexpr static int s_buttonBorderRadius = 8;
inline constexpr static int s_buttonCircleRadius = s_buttonBorderRadius - 2;
inline constexpr static int s_buttonSpacing = 20;
// Icon
inline constexpr static int s_iconSize = 24;
inline constexpr static int s_iconSpacing = 16;
@@ -75,8 +67,7 @@ namespace O3DE::ProjectManager
QRect GetTextRect(QFont& font, const QString& text, qreal fontSize) const;
QRect CalcButtonRect(const QRect& contentRect) const;
QRect CalcDeleteButtonRect(const QRect& contentRect) const;
QRect CalcRefreshButtonRect(const QRect& contentRect, const QRect& buttonRect) const;
void DrawButton(QPainter* painter, const QRect& contentRect, const QModelIndex& modelIndex) const;
QRect CalcRefreshButtonRect(const QRect& contentRect) const;
void DrawEditButtons(QPainter* painter, const QRect& contentRect) const;
QAbstractItemModel* m_model = nullptr;
@@ -289,23 +289,22 @@ namespace O3DE::ProjectManager
m_gemRepoHeaderTable->setObjectName("gemRepoHeaderTable");
m_gemRepoListHeader = m_gemRepoHeaderTable->horizontalHeader();
m_gemRepoListHeader->setObjectName("gemRepoListHeader");
m_gemRepoListHeader->setDefaultAlignment(Qt::AlignLeft);
m_gemRepoListHeader->setSectionResizeMode(QHeaderView::ResizeMode::Fixed);
// Insert columns so the header labels will show up
m_gemRepoHeaderTable->insertColumn(0);
m_gemRepoHeaderTable->insertColumn(1);
m_gemRepoHeaderTable->insertColumn(2);
m_gemRepoHeaderTable->insertColumn(3);
m_gemRepoHeaderTable->setHorizontalHeaderLabels({ tr("Enabled"), tr("Repository Name"), tr("Creator"), tr("Updated") });
m_gemRepoHeaderTable->setHorizontalHeaderLabels({ tr("Repository Name"), tr("Creator"), tr("Updated") });
const int headerExtraMargin = 10;
m_gemRepoListHeader->resizeSection(0, GemRepoItemDelegate::s_buttonWidth + GemRepoItemDelegate::s_buttonSpacing - 3);
m_gemRepoListHeader->resizeSection(1, GemRepoItemDelegate::s_nameMaxWidth + GemRepoItemDelegate::s_contentSpacing - headerExtraMargin);
m_gemRepoListHeader->resizeSection(2, GemRepoItemDelegate::s_creatorMaxWidth + GemRepoItemDelegate::s_contentSpacing - headerExtraMargin);
m_gemRepoListHeader->resizeSection(3, GemRepoItemDelegate::s_updatedMaxWidth + GemRepoItemDelegate::s_contentSpacing - headerExtraMargin);
const int headerExtraMargin = 18;
m_gemRepoListHeader->resizeSection(0, GemRepoItemDelegate::s_nameMaxWidth + GemRepoItemDelegate::s_contentSpacing + headerExtraMargin);
m_gemRepoListHeader->resizeSection(1, GemRepoItemDelegate::s_creatorMaxWidth + GemRepoItemDelegate::s_contentSpacing);
m_gemRepoListHeader->resizeSection(2, GemRepoItemDelegate::s_updatedMaxWidth + GemRepoItemDelegate::s_contentSpacing);
// Required to set stylesheet in code as it will not be respected if set in qss
m_gemRepoHeaderTable->horizontalHeader()->setStyleSheet("QHeaderView::section { background-color:transparent; color:white; font-size:12px; text-align:left; border-style:none; }");
m_gemRepoHeaderTable->horizontalHeader()->setStyleSheet("QHeaderView::section { background-color:transparent; color:white; font-size:12px; border-style:none; }");
middleVLayout->addWidget(m_gemRepoHeaderTable);
m_gemRepoListView = new GemRepoListView(m_gemRepoModel, m_gemRepoModel->GetSelectionModel(), this);
@@ -1574,15 +1574,6 @@
"shaderOption": "o_baseColor_useTexture"
}
},
{
"type": "UseTexture",
"args": {
"textureProperty": "metallic.textureMap",
"useTextureProperty": "metallic.useTexture",
"dependentProperties": ["metallic.textureMapUv"],
"shaderOption": "o_metallic_useTexture"
}
},
{
"type": "UseTexture",
"args": {
@@ -1649,6 +1640,12 @@
"file": "StandardPBR_Roughness.lua"
}
},
{
"type": "Lua",
"args": {
"file": "StandardPBR_Metallic.lua"
}
},
{
"type": "Lua",
"args": {
@@ -2698,16 +2698,12 @@
}
},
{
"type": "UseTexture",
"type": "Lua",
"args": {
"textureProperty": "layer1_metallic.textureMap",
"useTextureProperty": "layer1_metallic.useTexture",
"dependentProperties": ["layer1_metallic.textureMapUv"],
"shaderTags": [
"ForwardPass",
"ForwardPass_EDS"
],
"shaderOption": "o_layer1_o_metallic_useTexture"
"file": "StandardPBR_Metallic.lua",
"propertyNamePrefix": "layer1_",
"srgNamePrefix": "m_layer1_",
"optionsNamePrefix": "o_layer1_"
}
},
{
@@ -2835,16 +2831,12 @@
}
},
{
"type": "UseTexture",
"type": "Lua",
"args": {
"textureProperty": "layer2_metallic.textureMap",
"useTextureProperty": "layer2_metallic.useTexture",
"dependentProperties": ["layer2_metallic.textureMapUv"],
"shaderTags": [
"ForwardPass",
"ForwardPass_EDS"
],
"shaderOption": "o_layer2_o_metallic_useTexture"
"file": "StandardPBR_Metallic.lua",
"propertyNamePrefix": "layer2_",
"srgNamePrefix": "m_layer2_",
"optionsNamePrefix": "o_layer2_"
}
},
{
@@ -2963,8 +2955,8 @@
"args": {
"textureProperty": "layer3_baseColor.textureMap",
"useTextureProperty": "layer3_baseColor.useTexture",
"dependentProperties": ["layer3_baseColor.textureMapUv", "layer3_baseColor.textureBlendMode"],
"shaderTags": [
"dependentProperties": [ "layer3_baseColor.textureMapUv", "layer3_baseColor.textureBlendMode" ],
"shaderTags": [
"ForwardPass",
"ForwardPass_EDS"
],
@@ -2972,16 +2964,12 @@
}
},
{
"type": "UseTexture",
"type": "Lua",
"args": {
"textureProperty": "layer3_metallic.textureMap",
"useTextureProperty": "layer3_metallic.useTexture",
"dependentProperties": ["layer3_metallic.textureMapUv"],
"shaderTags": [
"ForwardPass",
"ForwardPass_EDS"
],
"shaderOption": "o_layer3_o_metallic_useTexture"
"file": "StandardPBR_Metallic.lua",
"propertyNamePrefix": "layer3_",
"srgNamePrefix": "m_layer3_",
"optionsNamePrefix": "o_layer3_"
}
},
{
@@ -1104,15 +1104,6 @@
"shaderOption": "o_baseColor_useTexture"
}
},
{
"type": "UseTexture",
"args": {
"textureProperty": "metallic.textureMap",
"useTextureProperty": "metallic.useTexture",
"dependentProperties": ["metallic.textureMapUv"],
"shaderOption": "o_metallic_useTexture"
}
},
{
"type": "UseTexture",
"args": {
@@ -1179,6 +1170,12 @@
"file": "StandardPBR_Roughness.lua"
}
},
{
"type": "Lua",
"args": {
"file": "StandardPBR_Metallic.lua"
}
},
{
"type": "Lua",
"args": {
@@ -0,0 +1,43 @@
--------------------------------------------------------------------------------------
--
-- 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
--
--
--
----------------------------------------------------------------------------------------------------
function GetMaterialPropertyDependencies()
return {"metallic.textureMap", "metallic.useTexture"}
end
function GetShaderOptionDependencies()
return {"o_metallic_useTexture"}
end
function Process(context)
local textureMap = context:GetMaterialPropertyValue_Image("metallic.textureMap")
local useTexture = context:GetMaterialPropertyValue_bool("metallic.useTexture")
context:SetShaderOptionValue_bool("o_metallic_useTexture", useTexture and textureMap ~= nil)
end
function ProcessEditor(context)
local textureMap = context:GetMaterialPropertyValue_Image("metallic.textureMap")
local useTexture = context:GetMaterialPropertyValue_bool("metallic.useTexture")
if(nil == textureMap) then
context:SetMaterialPropertyVisibility("metallic.useTexture", MaterialPropertyVisibility_Hidden)
context:SetMaterialPropertyVisibility("metallic.textureMapUv", MaterialPropertyVisibility_Hidden)
context:SetMaterialPropertyVisibility("metallic.factor", MaterialPropertyVisibility_Enabled)
elseif(not useTexture) then
context:SetMaterialPropertyVisibility("metallic.useTexture", MaterialPropertyVisibility_Enabled)
context:SetMaterialPropertyVisibility("metallic.textureMapUv", MaterialPropertyVisibility_Disabled)
context:SetMaterialPropertyVisibility("metallic.factor", MaterialPropertyVisibility_Enabled)
else
context:SetMaterialPropertyVisibility("metallic.useTexture", MaterialPropertyVisibility_Enabled)
context:SetMaterialPropertyVisibility("metallic.textureMapUv", MaterialPropertyVisibility_Enabled)
context:SetMaterialPropertyVisibility("metallic.factor", MaterialPropertyVisibility_Hidden)
end
end
@@ -19,7 +19,6 @@
#include <AzCore/Serialization/SerializeContext.h>
#include <AzCore/Serialization/EditContext.h>
#include <AzCore/Serialization/EditContextConstants.inl>
#include <AzCore/Script/ScriptAsset.h>
#include <AssetBuilderSDK/AssetBuilderSDK.h>
#include <AzToolsFramework/API/EditorAssetSystemAPI.h>
@@ -101,13 +100,6 @@ namespace AZ
materialFunctorRegistration->RegisterMaterialFunctor("ConvertEmissiveUnit", azrtti_typeid<ConvertEmissiveUnitFunctorSourceData>());
materialFunctorRegistration->RegisterMaterialFunctor("HandleSubsurfaceScatteringParameters", azrtti_typeid<SubsurfaceTransmissionParameterFunctorSourceData>());
materialFunctorRegistration->RegisterMaterialFunctor("Lua", azrtti_typeid<RPI::LuaMaterialFunctorSourceData>());
// Add asset types and extensions to AssetCatalog. Uses "AssetCatalogService".
auto assetCatalog = AZ::Data::AssetCatalogRequestBus::FindFirstHandler();
if (assetCatalog)
{
assetCatalog->EnableCatalogForAsset(AZ::AzTypeInfo<AZ::ScriptAsset>::Uuid());
}
}
void EditorCommonSystemComponent::Deactivate()
@@ -60,6 +60,11 @@ def activate_look_modification_lut(look_modification_component, asset_relative_p
LOOK_MODIFICATION_ENABLE_PROPERTY_PATH,
True
)
azlmbr.editor.EditorComponentAPIBus(
azlmbr.bus.Broadcast,
"EnableComponents",
[look_modification_component]
)
def activate_lut_asset(entity_id, asset_relative_path):
disable_hdr_color_grading_component(entity_id)
@@ -6,23 +6,24 @@
*
*/
#include <Material/EditorMaterialComponent.h>
#include <Material/EditorMaterialComponentExporter.h>
#include <AzToolsFramework/API/EditorAssetSystemAPI.h>
#include <AzToolsFramework/API/ToolsApplicationAPI.h>
#include <AzCore/RTTI/BehaviorContext.h>
#include <Atom/RPI.Edit/Common/AssetUtils.h>
#include <Atom/RPI.Edit/Material/MaterialPropertyId.h>
#include <Atom/RPI.Public/Image/StreamingImage.h>
#include <Atom/RPI.Reflect/Material/MaterialAsset.h>
#include <Atom/RPI.Reflect/Material/MaterialTypeAsset.h>
#include <AtomLyIntegration/CommonFeatures/Mesh/MeshComponentBus.h>
#include <AzCore/RTTI/BehaviorContext.h>
#include <AzCore/Serialization/Json/RegistrationContext.h>
#include <AzToolsFramework/API/EditorAssetSystemAPI.h>
#include <AzToolsFramework/API/ToolsApplicationAPI.h>
#include <Material/EditorMaterialComponent.h>
#include <Material/EditorMaterialComponentExporter.h>
#include <Material/EditorMaterialComponentSerializer.h>
AZ_PUSH_DISABLE_WARNING(4251 4800, "-Wunknown-warning-option") // disable warnings spawned by QT
#include <QMenu>
#include <QAction>
#include <QCursor>
#include <QMenu>
AZ_POP_DISABLE_WARNING
namespace AZ
@@ -59,7 +60,12 @@ namespace AZ
BaseClass::Reflect(context);
EditorMaterialComponentSlot::Reflect(context);
if (AZ::SerializeContext* serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
if (auto jsonContext = azrtti_cast<JsonRegistrationContext*>(context))
{
jsonContext->Serializer<JsonEditorMaterialComponentSerializer>()->HandlesType<EditorMaterialComponent>();
}
if (auto serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
{
serializeContext->RegisterGenericType<EditorMaterialComponentSlotContainer>();
serializeContext->RegisterGenericType<EditorMaterialComponentSlotsByLodContainer>();
@@ -76,7 +82,7 @@ namespace AZ
serializeContext->RegisterGenericType<AZStd::unordered_map<MaterialAssignmentId, Data::AssetId, AZStd::hash<MaterialAssignmentId>, AZStd::equal_to<MaterialAssignmentId>, AZStd::allocator>>();
serializeContext->RegisterGenericType<AZStd::unordered_map<MaterialAssignmentId, MaterialPropertyOverrideMap, AZStd::hash<MaterialAssignmentId>, AZStd::equal_to<MaterialAssignmentId>, AZStd::allocator>>();
if (AZ::EditContext* editContext = serializeContext->GetEditContext())
if (auto editContext = serializeContext->GetEditContext())
{
editContext->Class<EditorMaterialComponent>(
"Material", "The material component specifies the material to use for this entity")
@@ -129,7 +135,7 @@ namespace AZ
}
}
if (AZ::BehaviorContext* behaviorContext = azrtti_cast<AZ::BehaviorContext*>(context))
if (auto behaviorContext = azrtti_cast<AZ::BehaviorContext*>(context))
{
behaviorContext->ConstantProperty("EditorMaterialComponentTypeId", BehaviorConstant(Uuid(EditorMaterialComponentTypeId)))
->Attribute(AZ::Script::Attributes::Module, "render")
@@ -27,6 +27,8 @@ namespace AZ
, public EditorMaterialSystemComponentNotificationBus::Handler
{
public:
friend class JsonEditorMaterialComponentSerializer;
using BaseClass = EditorRenderComponentAdapter<MaterialComponentController, MaterialComponent, MaterialComponentConfig>;
AZ_EDITOR_COMPONENT(EditorMaterialComponent, EditorMaterialComponentTypeId, BaseClass);
@@ -0,0 +1,109 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#include <AzCore/Serialization/Json/JsonSerializationResult.h>
#include <Material/EditorMaterialComponent.h>
#include <Material/EditorMaterialComponentSerializer.h>
namespace AZ
{
namespace Render
{
AZ_CLASS_ALLOCATOR_IMPL(JsonEditorMaterialComponentSerializer, AZ::SystemAllocator, 0);
AZ::JsonSerializationResult::Result JsonEditorMaterialComponentSerializer::Load(
void* outputValue,
[[maybe_unused]] const AZ::Uuid& outputValueTypeId,
const rapidjson::Value& inputValue,
AZ::JsonDeserializerContext& context)
{
namespace JSR = AZ::JsonSerializationResult;
AZ_Assert(
azrtti_typeid<EditorMaterialComponent>() == outputValueTypeId,
"Unable to deserialize EditorMaterialComponent from json because the provided type is %s.",
outputValueTypeId.ToString<AZStd::string>().c_str());
auto componentInstance = reinterpret_cast<EditorMaterialComponent*>(outputValue);
AZ_Assert(componentInstance, "Output value for JsonEditorMaterialComponentSerializer can't be null.");
JSR::ResultCode result(JSR::Tasks::ReadField);
result.Combine(ContinueLoadingFromJsonObjectField(
&componentInstance->m_id, azrtti_typeid<decltype(componentInstance->m_id)>(), inputValue, "Id", context));
result.Combine(ContinueLoadingFromJsonObjectField(
&componentInstance->m_controller, azrtti_typeid<decltype(componentInstance->m_controller)>(), inputValue, "Controller",
context));
result.Combine(ContinueLoadingFromJsonObjectField(
&componentInstance->m_materialSlotsByLodEnabled, azrtti_typeid<decltype(componentInstance->m_materialSlotsByLodEnabled)>(),
inputValue, "materialSlotsByLodEnabled", context));
return context.Report(
result,
result.GetProcessing() != JSR::Processing::Halted ? "Successfully loaded EditorMaterialComponent information."
: "Failed to load EditorMaterialComponent information.");
}
AZ::JsonSerializationResult::Result JsonEditorMaterialComponentSerializer::Store(
rapidjson::Value& outputValue,
const void* inputValue,
const void* defaultValue,
[[maybe_unused]] const AZ::Uuid& valueTypeId,
AZ::JsonSerializerContext& context)
{
namespace JSR = AZ::JsonSerializationResult;
AZ_Assert(
azrtti_typeid<EditorMaterialComponent>() == valueTypeId,
"Unable to Serialize EditorMaterialComponent because the provided type is %s.",
valueTypeId.ToString<AZStd::string>().c_str());
auto componentInstance = reinterpret_cast<const EditorMaterialComponent*>(inputValue);
AZ_Assert(componentInstance, "Input value for JsonEditorMaterialComponentSerializer can't be null.");
auto defaultComponentInstance = reinterpret_cast<const EditorMaterialComponent*>(defaultValue);
JSR::ResultCode result(JSR::Tasks::WriteValue);
{
AZ::ScopedContextPath subPathName(context, "m_id");
const auto componentId = &componentInstance->m_id;
const auto defaultComponentId = defaultComponentInstance ? &defaultComponentInstance->m_id : nullptr;
result.Combine(ContinueStoringToJsonObjectField(
outputValue, "Id", componentId, defaultComponentId, azrtti_typeid<decltype(componentInstance->m_id)>(), context));
}
{
AZ::ScopedContextPath subPathName(context, "Controller");
const auto controller = &componentInstance->m_controller;
const auto defaultController = defaultComponentInstance ? &defaultComponentInstance->m_controller : nullptr;
result.Combine(ContinueStoringToJsonObjectField(
outputValue, "Controller", controller, defaultController, azrtti_typeid<decltype(componentInstance->m_controller)>(),
context));
}
{
AZ::ScopedContextPath subPathName(context, "materialSlotsByLodEnabled");
const auto enabled = &componentInstance->m_materialSlotsByLodEnabled;
const auto defaultEnabled = defaultComponentInstance ? &defaultComponentInstance->m_materialSlotsByLodEnabled : nullptr;
result.Combine(ContinueStoringToJsonObjectField(
outputValue, "materialSlotsByLodEnabled", enabled, defaultEnabled,
azrtti_typeid<decltype(componentInstance->m_materialSlotsByLodEnabled)>(), context));
}
return context.Report(
result,
result.GetProcessing() != JSR::Processing::Halted ? "Successfully stored EditorMaterialComponent information."
: "Failed to store EditorMaterialComponent information.");
}
} // namespace Render
} // namespace AZ
@@ -0,0 +1,41 @@
/*
* 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 <AzCore/Memory/Memory.h>
#include <AzCore/Serialization/Json/BaseJsonSerializer.h>
namespace AZ
{
namespace Render
{
// JsonEditorMaterialComponentSerializer skips serialization of EditorMaterialComponentSlot(s) which are only needed at runtime in
// the editor
class JsonEditorMaterialComponentSerializer : public AZ::BaseJsonSerializer
{
public:
AZ_RTTI(JsonEditorMaterialComponentSerializer, "{D354FE3C-34D2-4E80-B3F9-49450D252336}", BaseJsonSerializer);
AZ_CLASS_ALLOCATOR_DECL;
AZ::JsonSerializationResult::Result Load(
void* outputValue,
const AZ::Uuid& outputValueTypeId,
const rapidjson::Value& inputValue,
AZ::JsonDeserializerContext& context) override;
AZ::JsonSerializationResult::Result Store(
rapidjson::Value& outputValue,
const void* inputValue,
const void* defaultValue,
const AZ::Uuid& valueTypeId,
AZ::JsonSerializerContext& context) override;
};
} // namespace Render
} // namespace AZ
@@ -31,6 +31,8 @@ set(FILES
Source/ImageBasedLights/EditorImageBasedLightComponent.cpp
Source/Material/EditorMaterialComponent.cpp
Source/Material/EditorMaterialComponent.h
Source/Material/EditorMaterialComponentSerializer.cpp
Source/Material/EditorMaterialComponentSerializer.h
Source/Material/EditorMaterialComponentUtil.cpp
Source/Material/EditorMaterialComponentUtil.h
Source/Material/EditorMaterialComponentSlot.cpp
@@ -61,7 +61,6 @@
// Asset types
#include <AzCore/Slice/SliceAsset.h>
#include <AzCore/Script/ScriptAsset.h>
#include <LmbrCentral/Rendering/MaterialAsset.h>
#include <LmbrCentral/Rendering/MeshAsset.h>
#include <LmbrCentral/Rendering/MaterialHandle.h>
@@ -354,7 +353,6 @@ namespace LmbrCentral
// Add asset types and extensions to AssetCatalog. Uses "AssetCatalogService".
if (auto assetCatalog = AZ::Data::AssetCatalogRequestBus::FindFirstHandler(); assetCatalog)
{
assetCatalog->EnableCatalogForAsset(AZ::AzTypeInfo<AZ::ScriptAsset>::Uuid());
assetCatalog->EnableCatalogForAsset(AZ::AzTypeInfo<MaterialAsset>::Uuid());
assetCatalog->EnableCatalogForAsset(AZ::AzTypeInfo<DccMaterialAsset>::Uuid());
assetCatalog->EnableCatalogForAsset(AZ::AzTypeInfo<MeshAsset>::Uuid());
@@ -368,7 +366,6 @@ namespace LmbrCentral
assetCatalog->AddExtension("xml");
assetCatalog->AddExtension("mtl");
assetCatalog->AddExtension("dccmtl");
assetCatalog->AddExtension("lua");
assetCatalog->AddExtension("sprite");
assetCatalog->AddExtension("cax");
}
@@ -27,7 +27,7 @@ def get_editor_main_window():
return editor_main_window
# Helper method for registering a Python widget as a tool/view pane with the Editor
def register_view_pane(name, widget_type, options=editor.ViewPaneOptions()):
def register_view_pane(name, widget_type, category="Tools", options=editor.ViewPaneOptions()):
global view_pane_handlers
# The view pane names are unique in the Editor, so make sure one with the same name doesn't exist already
@@ -45,10 +45,10 @@ def register_view_pane(name, widget_type, options=editor.ViewPaneOptions()):
return new_widget.winId()
def on_notify_register_views(parameters, my_name=name, my_options=options):
def on_notify_register_views(parameters, my_name=name, my_category=category, my_options=options):
# Register our widget as an Editor view pane
print('Calling on_notify_register_views RegisterCustomViewPane')
editor.EditorRequestBus(azlmbr.bus.Broadcast, 'RegisterCustomViewPane', my_name, 'Tools', my_options)
editor.EditorRequestBus(azlmbr.bus.Broadcast, 'RegisterCustomViewPane', my_name, my_category, my_options)
# We keep a handler around in case a request for registering custom view panes comes later
print('Initializing callback for RegisterCustomViewPane')
@@ -57,7 +57,7 @@ def register_view_pane(name, widget_type, options=editor.ViewPaneOptions()):
registration_handler.add_callback("NotifyRegisterViews", on_notify_register_views)
global registration_handlers
registration_handlers[name] = registration_handler
editor.EditorRequestBus(azlmbr.bus.Broadcast, 'RegisterCustomViewPane', name, 'Tools', options)
editor.EditorRequestBus(azlmbr.bus.Broadcast, 'RegisterCustomViewPane', name, category, options)
# Connect to the ViewPaneCallbackBus in order to respond to requests to create our widget
# We also need to store our handler so it will exist for the life of the Editor
@@ -23,11 +23,9 @@ struct VSOutput
{
float4 m_position : SV_Position;
float3 m_normal: NORMAL;
float3 m_tangent : TANGENT;
float3 m_bitangent : BITANGENT;
float3 m_worldPosition : UV0;
float3 m_shadowCoords[ViewSrg::MaxCascadeCount] : UV2;
float2 m_uv : UV1;
float3 m_shadowCoords[ViewSrg::MaxCascadeCount] : UV2;
};
option bool o_debugDetailMaterialIds = false;
@@ -50,9 +48,9 @@ VSOutput TerrainPBR_MainPassVS(VertexInput IN)
float down = GetHeight(origUv + terrainData.m_uvStep * float2( 0.0f, 1.0f));
float left = GetHeight(origUv + terrainData.m_uvStep * float2(-1.0f, 0.0f));
OUT.m_bitangent = normalize(float3(0.0, terrainData.m_sampleSpacing * 2.0f, down - up));
OUT.m_tangent = normalize(float3(terrainData.m_sampleSpacing * 2.0f, 0.0, right - left));
OUT.m_normal = cross(OUT.m_tangent, OUT.m_bitangent);
float3 bitangent = normalize(float3(0.0, terrainData.m_sampleSpacing * 2.0f, down - up));
float3 tangent = normalize(float3(terrainData.m_sampleSpacing * 2.0f, 0.0, right - left));
OUT.m_normal = normalize(cross(tangent, bitangent));
OUT.m_uv = uv;
// directional light shadow
@@ -78,18 +76,14 @@ ForwardPassOutput TerrainPBR_MainPassPS(VSOutput IN)
surface.position = IN.m_worldPosition.xyz;
float viewDistance = length(ViewSrg::m_worldPosition - surface.position);
float detailFactor = saturate((viewDistance - TerrainMaterialSrg::m_detailFadeDistance) / max(TerrainMaterialSrg::m_detailFadeLength, EPSILON));
ObjectSrg::TerrainData terrainData = ObjectSrg::m_terrainData;
float2 origUv = lerp(terrainData.m_uvMin, terrainData.m_uvMax, IN.m_uv);
origUv.y = 1.0 - origUv.y;
float2 detailUv = IN.m_uv * TerrainMaterialSrg::m_detailTextureMultiplier;
// ------- Normal -------
float3 macroNormal = IN.m_normal;
float3 macroNormal = normalize(IN.m_normal);
// ------- Macro Color / Normal -------
float3 macroColor = TerrainMaterialSrg::m_baseColor.rgb;
[unroll] for (uint i = 0; i < 4; ++i)
[unroll] for (uint i = 0; i < 4 && (i < ObjectSrg::m_macroMaterialCount); ++i)
{
float2 macroUvMin = ObjectSrg::m_macroMaterialData[i].m_uvMin;
float2 macroUvMax = ObjectSrg::m_macroMaterialData[i].m_uvMax;
@@ -248,6 +248,7 @@ namespace Terrain
{
m_configuration.m_macroColorAsset = asset;
m_colorImage = AZ::RPI::StreamingImage::FindOrCreate(m_configuration.m_macroColorAsset);
m_colorImage->GetRHIImage()->SetName(AZ::Name(m_configuration.m_macroColorAsset.GetHint()));
// Clear the texture asset reference to make sure we don't prevent hot-reloading.
m_configuration.m_macroColorAsset.Release();
@@ -256,6 +257,7 @@ namespace Terrain
{
m_configuration.m_macroNormalAsset = asset;
m_normalImage = AZ::RPI::StreamingImage::FindOrCreate(m_configuration.m_macroNormalAsset);
m_normalImage->GetRHIImage()->SetName(AZ::Name(m_configuration.m_macroNormalAsset.GetHint()));
// Clear the texture asset reference to make sure we don't prevent hot-reloading.
m_configuration.m_macroColorAsset.Release();
@@ -1149,7 +1149,9 @@ namespace Terrain
sectorData.m_srg->SetConstant(m_terrainDataIndex, terrainDataForSrg);
AZStd::array<ShaderMacroMaterialData, MaxMaterialsPerSector> macroMaterialData;
for (uint32_t i = 0; i < sectorData.m_macroMaterials.size(); ++i)
uint32_t i = 0;
for (; i < sectorData.m_macroMaterials.size(); ++i)
{
const MacroMaterialData& materialData = m_macroMaterials.GetData(sectorData.m_macroMaterials.at(i));
ShaderMacroMaterialData& shaderData = macroMaterialData.at(i);
@@ -1178,6 +1180,11 @@ namespace Terrain
// set flags for which images are used.
shaderData.m_mapsInUse = (colorImageView ? ColorImageUsed : 0) | (normalImageView ? NormalImageUsed : 0);
}
for (; i < sectorData.m_macroMaterials.capacity(); ++i)
{
sectorData.m_srg->SetImageView(m_macroColorMapIndex, nullptr, i);
sectorData.m_srg->SetImageView(m_macroNormalMapIndex, nullptr, i);
}
sectorData.m_srg->SetConstantArray(m_macroMaterialDataIndex, macroMaterialData);
sectorData.m_srg->SetConstant(m_macroMaterialCountIndex, aznumeric_cast<uint32_t>(sectorData.m_macroMaterials.size()));
@@ -71,18 +71,18 @@ namespace Terrain
struct ShaderTerrainData // Must align with struct in Object Srg
{
AZStd::array<float, 2> m_uvMin;
AZStd::array<float, 2> m_uvMax;
AZStd::array<float, 2> m_uvStep;
float m_sampleSpacing;
float m_heightScale;
AZStd::array<float, 2> m_uvMin{ 0.0f, 0.0f };
AZStd::array<float, 2> m_uvMax{ 1.0f, 1.0f };
AZStd::array<float, 2> m_uvStep{ 1.0f, 1.0f };
float m_sampleSpacing{ 1.0f };
float m_heightScale{ 1.0f };
};
struct ShaderMacroMaterialData
struct ShaderMacroMaterialData // Must align with struct in Object Srg
{
AZStd::array<float, 2> m_uvMin;
AZStd::array<float, 2> m_uvMax;
float m_normalFactor;
AZStd::array<float, 2> m_uvMin{ 0.0f, 0.0f };
AZStd::array<float, 2> m_uvMax{ 1.0f, 1.0f };
float m_normalFactor{ 0.0f };
uint32_t m_flipNormalX{ 0 }; // bool in shader
uint32_t m_flipNormalY{ 0 }; // bool in shader
uint32_t m_mapsInUse{ 0b00 }; // 0b01 = color, 0b10 = normal
@@ -71,8 +71,8 @@ namespace ${SanitizedCppName}
options.showOnToolsToolbar = true;
options.toolbarIcon = ":/${Name}/toolbar_icon.svg";
// Register our custom widget as a dockable tool with the Editor
AzToolsFramework::RegisterViewPane<${SanitizedCppName}Widget>("${Name}", "Tools", options);
// Register our custom widget as a dockable tool with the Editor under an Examples sub-menu
AzToolsFramework::RegisterViewPane<${SanitizedCppName}Widget>("${Name}", "Examples", options);
}
} // namespace ${SanitizedCppName}
@@ -20,8 +20,6 @@ namespace ${SanitizedCppName}
${SanitizedCppName}Widget::${SanitizedCppName}Widget(QWidget* parent)
: QWidget(parent)
{
setWindowTitle(QObject::tr("${Name}"));
QVBoxLayout* mainLayout = new QVBoxLayout(this);
QLabel* introLabel = new QLabel(QObject::tr("Put your cool stuff here!"), this);
@@ -0,0 +1,2 @@
__pycache__/
*.pyc
@@ -11,4 +11,5 @@ set(FILES
Source/${Name}ModuleInterface.h
Source/${Name}EditorSystemComponent.cpp
Source/${Name}EditorSystemComponent.h
Source/${Name}.qrc
)
@@ -26,6 +26,7 @@ if(PAL_TRAIT_BUILD_HOST_TOOLS)
ly_add_target(
NAME ${Name}.Editor.Static STATIC
NAMESPACE Gem
AUTORCC
FILES_CMAKE
${NameLower}_editor_files.cmake
INCLUDE_DIRECTORIES
@@ -0,0 +1,5 @@
<!DOCTYPE RCC><RCC version="1.0">
<qresource prefix="/${Name}">
<file alias="toolbar_icon.svg">toolbar_icon.svg</file>
</qresource>
</RCC>
@@ -11,6 +11,12 @@
#include <${Name}ModuleInterface.h>
#include <${Name}EditorSystemComponent.h>
void Init${SanitizedCppName}Resources()
{
// We must register our Qt resources (.qrc file) since this is being loaded from a separate module (gem)
Q_INIT_RESOURCE(${SanitizedCppName});
}
namespace ${SanitizedCppName}
{
class ${SanitizedCppName}EditorModule
@@ -22,6 +28,8 @@ namespace ${SanitizedCppName}
${SanitizedCppName}EditorModule()
{
Init${SanitizedCppName}Resources();
// Push results of [MyComponent]::CreateDescriptor() into m_descriptors here.
// Add ALL components descriptors associated with this gem to m_descriptors.
// This will associate the AzTypeInfo information for the components with the the SerializeContext, BehaviorContext and EditContext.
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 24 24" height="24px" viewBox="0 0 24 24" width="24px" fill="#FFFFFF"><g><rect fill="none" height="24" width="24"/><path d="M19,3H5C3.89,3,3,3.9,3,5v14c0,1.1,0.89,2,2,2h14c1.1,0,2-0.9,2-2V5C21,3.9,20.11,3,19,3z M19,19H5V7h14V19z M13.5,13 c0,0.83-0.67,1.5-1.5,1.5s-1.5-0.67-1.5-1.5c0-0.83,0.67-1.5,1.5-1.5S13.5,12.17,13.5,13z M12,9c-2.73,0-5.06,1.66-6,4 c0.94,2.34,3.27,4,6,4s5.06-1.66,6-4C17.06,10.66,14.73,9,12,9z M12,15.5c-1.38,0-2.5-1.12-2.5-2.5c0-1.38,1.12-2.5,2.5-2.5 c1.38,0,2.5,1.12,2.5,2.5C14.5,14.38,13.38,15.5,12,15.5z"/></g></svg>

After

Width:  |  Height:  |  Size: 607 B

@@ -6,24 +6,15 @@ SPDX-License-Identifier: Apache-2.0 OR MIT
"""
# -------------------------------------------------------------------------
"""${SanitizedCppName}\\editor\\scripts\\${SanitizedCppName}_dialog.py
Generated from O3DE PythonGem Template"""
Generated from O3DE PythonToolGem Template"""
import azlmbr
from shiboken2 import wrapInstance, getCppPointer
from PySide2 import QtCore, QtWidgets, QtGui
from PySide2.QtCore import QEvent, Qt
from PySide2.QtWidgets import QVBoxLayout, QAction, QDialog, QHeaderView, QLabel, QLineEdit, QPushButton, QSplitter, QTreeWidget, QTreeWidgetItem, QWidget, QAbstractButton
# Once PySide2 has been bootstrapped, register our ${SanitizedCppName}Dialog with the Editor
from PySide2.QtCore import Qt
from PySide2.QtWidgets import QDialog, QLabel, QVBoxLayout
class ${SanitizedCppName}Dialog(QDialog):
def __init__(self, parent=None):
super(${SanitizedCppName}Dialog, self).__init__(parent)
self.setObjectName("${SanitizedCppName}Dialog")
self.setWindowTitle("HelloWorld, ${SanitizedCppName} Dialog")
self.mainLayout = QVBoxLayout(self)
self.introLabel = QLabel("Put your cool stuff here!")
@@ -42,5 +33,3 @@ class ${SanitizedCppName}Dialog(QDialog):
self.mainLayout.addWidget(self.helpLabel, 0, Qt.AlignCenter)
self.setLayout(self.mainLayout)
return
@@ -6,112 +6,17 @@ SPDX-License-Identifier: Apache-2.0 OR MIT
"""
# -------------------------------------------------------------------------
"""${SanitizedCppName}\\editor\\scripts\\boostrap.py
Generated from O3DE PythonGem Template"""
Generated from O3DE PythonToolGem Template"""
import azlmbr
import az_qt_helpers
from PySide2 import QtCore, QtWidgets, QtGui
from PySide2.QtCore import QEvent, Qt
from PySide2.QtWidgets import QMainWindow, QAction, QDialog, QHeaderView, QLabel, QLineEdit, QPushButton, QSplitter, QTreeWidget, QTreeWidgetItem, QWidget, QAbstractButton
# -------------------------------------------------------------------------
# -------------------------------------------------------------------------
class SampleUI(QtWidgets.QDialog):
"""Lightweight UI Test Class created a button"""
def __init__(self, parent, title='Not Set'):
super(SampleUI, self).__init__(parent)
self.setWindowTitle(title)
self.initUI()
def initUI(self):
mainLayout = QtWidgets.QHBoxLayout()
testBtn = QtWidgets.QPushButton("I am just a Button man!")
mainLayout.addWidget(testBtn)
self.setLayout(mainLayout)
# -------------------------------------------------------------------------
import azlmbr.editor as editor
from ${NameLower}_dialog import ${SanitizedCppName}Dialog
if __name__ == "__main__":
print("${SanitizedCppName}.boostrap, Generated from O3DE PythonGem Template")
# ---------------------------------------------------------------------
# validate pyside before continuing
try:
azlmbr.qt.QtForPythonRequestBus(azlmbr.bus.Broadcast, 'IsActive')
params = azlmbr.qt.QtForPythonRequestBus(azlmbr.bus.Broadcast, 'GetQtBootstrapParameters')
params is not None and params.mainWindowId is not 0
from PySide2 import QtWidgets
except Exception as e:
_LOGGER.error(f'Pyside not available, exception: {e}')
raise e
# keep going, import the other PySide2 bits we will use
from PySide2 import QtGui
from PySide2.QtCore import Slot
from shiboken2 import wrapInstance, getCppPointer
print("${SanitizedCppName}.boostrap, Generated from O3DE PythonToolGem Template")
# Get our Editor main window
_widget_main_window = None
try:
_widget_main_window = az_qt_helpers.get_editor_main_window()
except:
pass # may be booting in the AP?
# ---------------------------------------------------------------------
# ---------------------------------------------------------------------
if _widget_main_window:
# creat a custom menu
_tag_str = '${SanitizedCppName}'
# create our own menuBar
${SanitizedCppName}_menu = _widget_main_window.menuBar().addMenu(f"&{_tag_str}")
# nest a menu for util/tool launching
${SanitizedCppName}_launch_menu = ${SanitizedCppName}_menu.addMenu("examples")
else:
print('No O3DE MainWindow')
# ---------------------------------------------------------------------
# ---------------------------------------------------------------------
if _widget_main_window:
# (1) add the first SampleUI
action_launch_sample_ui = ${SanitizedCppName}_launch_menu.addAction("O3DE:SampleUI")
@Slot()
def clicked_sample_ui():
while 1: # simple PySide2 test, set to 0 to disable
ui = SampleUI(parent=_widget_main_window, title='O3DE:SampleUI')
ui.show()
break
return
# Add click event to menu bar
action_launch_sample_ui.triggered.connect(clicked_sample_ui)
# ---------------------------------------------------------------------
# ---------------------------------------------------------------------
if _widget_main_window:
# (1) and custom external module Qwidget
action_launch_${SanitizedCppName}_dialog = ${SanitizedCppName}_launch_menu.addAction("O3DE:${SanitizedCppName}_dialog")
@Slot()
def clicked_${SanitizedCppName}_dialog():
while 1: # simple PySide2 test, set to 0 to disable
try:
import az_qt_helpers
from ${NameLower}_dialog import ${SanitizedCppName}Dialog
az_qt_helpers.register_view_pane('${SanitizedCppName} Popup', ${SanitizedCppName}Dialog)
except Exception as e:
print(f'Error: {e}')
print('Skipping register our ${SanitizedCppName}Dialog with the Editor.')
${SanitizedCppName}_dialog = ${SanitizedCppName}Dialog(parent=_widget_main_window)
${SanitizedCppName}_dialog.show()
break
return
# Add click event to menu bar
action_launch_${SanitizedCppName}_dialog.triggered.connect(clicked_${SanitizedCppName}_dialog)
# ---------------------------------------------------------------------
# end
# Register our custom widget as a dockable tool with the Editor under an Examples sub-menu
options = editor.ViewPaneOptions()
options.showOnToolsToolbar = True
options.toolbarIcon = ":/${Name}/toolbar_icon.svg"
az_qt_helpers.register_view_pane('${SanitizedCppName}', ${SanitizedCppName}Dialog, category="Examples", options=options)
+18
View File
@@ -12,6 +12,12 @@
],
"icon_path": "preview.png",
"copyFiles": [
{
"file": ".gitignore",
"origin": ".gitignore",
"isTemplated": false,
"isOptional": false
},
{
"file": "CMakeLists.txt",
"origin": "CMakeLists.txt",
@@ -102,6 +108,12 @@
"isTemplated": true,
"isOptional": false
},
{
"file": "Code/Source/${Name}.qrc",
"origin": "Code/Source/${Name}.qrc",
"isTemplated": true,
"isOptional": false
},
{
"file": "Code/Source/${Name}EditorModule.cpp",
"origin": "Code/Source/${Name}EditorModule.cpp",
@@ -126,6 +138,12 @@
"isTemplated": true,
"isOptional": false
},
{
"file": "Code/Source/toolbar_icon.svg",
"origin": "Code/Source/toolbar_icon.svg",
"isTemplated": false,
"isOptional": false
},
{
"file": "Code/Tests/${Name}EditorTest.cpp",
"origin": "Code/Tests/${Name}EditorTest.cpp",
@@ -195,8 +195,11 @@ class AssetProcessor(object):
logger.debug("Failed to read port from file", exc_info=ex)
return False
# the timeout needs to be large enough to load all the dynamic libraries the AP-GUI loads since the control port
# is opened after all the DLL loads, this can take a long time in a Debug build
ap_max_activate_time = 60
err = AssetProcessorError(f"Failed to read port type {port_type} from {self._workspace.paths.ap_gui_log()}")
waiter.wait_for(_get_port_from_log, timeout=10, exc=err)
waiter.wait_for(_get_port_from_log, timeout=ap_max_activate_time, exc=err)
return port
def set_control_connection(self, connection):
+3 -3
View File
@@ -477,11 +477,11 @@ def register_repo(json_data: dict,
parsed_uri = urllib.parse.urlparse(url)
if parsed_uri.scheme in ['http', 'https', 'ftp', 'ftps']:
while repo_uri in json_data['repos']:
while repo_uri in json_data.get('repos', []):
json_data['repos'].remove(repo_uri)
else:
repo_uri = pathlib.Path(repo_uri).resolve().as_posix()
while repo_uri in json_data['repos']:
while repo_uri in json_data.get('repos', []):
json_data['repos'].remove(repo_uri)
if remove:
@@ -492,7 +492,7 @@ def register_repo(json_data: dict,
result = utils.download_file(parsed_uri, cache_file)
if result == 0:
json_data['repos'].insert(0, repo_uri)
json_data.setdefault('repos', []).insert(0, repo_uri)
repo_set = set()
result = repo.process_add_o3de_repo(cache_file, repo_set)
+2 -2
View File
@@ -147,7 +147,7 @@ def get_gem_json_paths_from_all_cached_repos() -> set:
json_data = manifest.load_o3de_manifest()
gem_set = set()
for repo_uri in json_data['repos']:
for repo_uri in json_data.get('repos', []):
gem_set.update(get_gem_json_paths_from_cached_repo(repo_uri))
return gem_set
@@ -189,7 +189,7 @@ def refresh_repos() -> int:
# set will stop circular references
repo_set = set()
for repo_uri in json_data['repos']:
for repo_uri in json_data.get('repos', []):
if repo_uri not in repo_set:
repo_set.add(repo_uri)