From 3caeda7fd57e6be7dcdbfb13088dbe6ad5ddca6e Mon Sep 17 00:00:00 2001 From: Chris Galvan Date: Fri, 29 Oct 2021 11:39:11 -0500 Subject: [PATCH] Added Python version of the Shape Example. Signed-off-by: Chris Galvan --- py_gems/PyShapeExample/CMakeLists.txt | 7 ++ py_gems/PyShapeExample/Code/CMakeLists.txt | 70 +++++++++++ .../PyShapeExample/PyShapeExampleBus.h | 31 +++++ .../Code/Platform/Linux/PAL_linux.cmake | 4 + .../Linux/pyshapeexample_linux_files.cmake | 8 ++ .../pyshapeexample_shared_linux_files.cmake | 8 ++ .../Code/Platform/Mac/PAL_mac.cmake | 4 + .../Mac/pyshapeexample_mac_files.cmake | 8 ++ .../Mac/pyshapeexample_shared_mac_files.cmake | 8 ++ .../Code/Platform/Windows/PAL_windows.cmake | 4 + .../pyshapeexample_shared_windows_files.cmake | 8 ++ .../pyshapeexample_windows_files.cmake | 8 ++ .../Code/Source/PyShapeExample.qrc | 5 + .../Source/PyShapeExampleEditorModule.cpp | 46 ++++++++ .../PyShapeExampleEditorSystemComponent.cpp | 61 ++++++++++ .../PyShapeExampleEditorSystemComponent.h | 33 ++++++ .../Source/PyShapeExampleModuleInterface.h | 27 +++++ .../Code/Source/toolbar_icon.svg | 1 + .../Code/Tests/PyShapeExampleEditorTest.cpp | 4 + .../Code/pyshapeexample_editor_files.cmake | 8 ++ .../pyshapeexample_editor_shared_files.cmake | 4 + .../pyshapeexample_editor_tests_files.cmake | 4 + .../PyShapeExample/Editor/Scripts/__init__.py | 9 ++ .../pyshapeexample_dialog.cpython-37.pyc | Bin 0 -> 3216 bytes .../Editor/Scripts/bootstrap.py | 22 ++++ .../Editor/Scripts/pyshapeexample_dialog.py | 110 ++++++++++++++++++ py_gems/PyShapeExample/gem.json | 17 +++ py_gems/PyShapeExample/preview.png | Bin 0 -> 2217 bytes 28 files changed, 519 insertions(+) create mode 100644 py_gems/PyShapeExample/CMakeLists.txt create mode 100644 py_gems/PyShapeExample/Code/CMakeLists.txt create mode 100644 py_gems/PyShapeExample/Code/Include/PyShapeExample/PyShapeExampleBus.h create mode 100644 py_gems/PyShapeExample/Code/Platform/Linux/PAL_linux.cmake create mode 100644 py_gems/PyShapeExample/Code/Platform/Linux/pyshapeexample_linux_files.cmake create mode 100644 py_gems/PyShapeExample/Code/Platform/Linux/pyshapeexample_shared_linux_files.cmake create mode 100644 py_gems/PyShapeExample/Code/Platform/Mac/PAL_mac.cmake create mode 100644 py_gems/PyShapeExample/Code/Platform/Mac/pyshapeexample_mac_files.cmake create mode 100644 py_gems/PyShapeExample/Code/Platform/Mac/pyshapeexample_shared_mac_files.cmake create mode 100644 py_gems/PyShapeExample/Code/Platform/Windows/PAL_windows.cmake create mode 100644 py_gems/PyShapeExample/Code/Platform/Windows/pyshapeexample_shared_windows_files.cmake create mode 100644 py_gems/PyShapeExample/Code/Platform/Windows/pyshapeexample_windows_files.cmake create mode 100644 py_gems/PyShapeExample/Code/Source/PyShapeExample.qrc create mode 100644 py_gems/PyShapeExample/Code/Source/PyShapeExampleEditorModule.cpp create mode 100644 py_gems/PyShapeExample/Code/Source/PyShapeExampleEditorSystemComponent.cpp create mode 100644 py_gems/PyShapeExample/Code/Source/PyShapeExampleEditorSystemComponent.h create mode 100644 py_gems/PyShapeExample/Code/Source/PyShapeExampleModuleInterface.h create mode 100644 py_gems/PyShapeExample/Code/Source/toolbar_icon.svg create mode 100644 py_gems/PyShapeExample/Code/Tests/PyShapeExampleEditorTest.cpp create mode 100644 py_gems/PyShapeExample/Code/pyshapeexample_editor_files.cmake create mode 100644 py_gems/PyShapeExample/Code/pyshapeexample_editor_shared_files.cmake create mode 100644 py_gems/PyShapeExample/Code/pyshapeexample_editor_tests_files.cmake create mode 100644 py_gems/PyShapeExample/Editor/Scripts/__init__.py create mode 100644 py_gems/PyShapeExample/Editor/Scripts/__pycache__/pyshapeexample_dialog.cpython-37.pyc create mode 100644 py_gems/PyShapeExample/Editor/Scripts/bootstrap.py create mode 100644 py_gems/PyShapeExample/Editor/Scripts/pyshapeexample_dialog.py create mode 100644 py_gems/PyShapeExample/gem.json create mode 100644 py_gems/PyShapeExample/preview.png diff --git a/py_gems/PyShapeExample/CMakeLists.txt b/py_gems/PyShapeExample/CMakeLists.txt new file mode 100644 index 0000000..8cb93ea --- /dev/null +++ b/py_gems/PyShapeExample/CMakeLists.txt @@ -0,0 +1,7 @@ + +set(o3de_gem_path ${CMAKE_CURRENT_LIST_DIR}) +set(o3de_gem_json ${o3de_gem_path}/gem.json) +o3de_read_json_key(o3de_gem_name ${o3de_gem_json} "gem_name") +o3de_restricted_path(${o3de_gem_json} o3de_gem_restricted_path) + +add_subdirectory(Code) diff --git a/py_gems/PyShapeExample/Code/CMakeLists.txt b/py_gems/PyShapeExample/Code/CMakeLists.txt new file mode 100644 index 0000000..53bab2a --- /dev/null +++ b/py_gems/PyShapeExample/Code/CMakeLists.txt @@ -0,0 +1,70 @@ + +# Currently we are in the Code folder: ${CMAKE_CURRENT_LIST_DIR} +# Get the platform specific folder ${pal_dir} for the current folder: ${CMAKE_CURRENT_LIST_DIR}/Platform/${PAL_PLATFORM_NAME} +# Note: ly_get_list_relative_pal_filename will take care of the details for us, as this may be a restricted platform +# in which case it will see if that platform is present here or in the restricted folder. +# i.e. It could here in our gem : Gems/PyShapeExample/Code/Platform/ or +# //Gems/PyShapeExample/Code +ly_get_list_relative_pal_filename(pal_dir ${CMAKE_CURRENT_LIST_DIR}/Platform/${PAL_PLATFORM_NAME} ${o3de_gem_restricted_path} ${o3de_gem_path} ${o3de_gem_name}) + +# Now that we have the platform abstraction layer (PAL) folder for this folder, thats where we will find the +# traits for this platform. Traits for a platform are defines for things like whether or not something in this gem +# is supported by this platform. +include(${pal_dir}/PAL_${PAL_PLATFORM_NAME_LOWERCASE}.cmake) + + +# If we are on a host platform, we want to add the host tools targets like the PyShapeExample.Editor target which +# will also depend on PyShapeExample.Static +if(PAL_TRAIT_BUILD_HOST_TOOLS) + ly_add_target( + NAME PyShapeExample.Editor.Static STATIC + NAMESPACE Gem + AUTORCC + FILES_CMAKE + pyshapeexample_editor_files.cmake + INCLUDE_DIRECTORIES + PRIVATE + Source + PUBLIC + Include + BUILD_DEPENDENCIES + PUBLIC + AZ::AzToolsFramework + ) + + ly_add_target( + NAME PyShapeExample.Editor GEM_MODULE + NAMESPACE Gem + AUTOMOC + FILES_CMAKE + pyshapeexample_editor_shared_files.cmake + INCLUDE_DIRECTORIES + PRIVATE + Source + PUBLIC + Include + BUILD_DEPENDENCIES + PUBLIC + Gem::PyShapeExample.Editor.Static + ) + + # By default, we will specify that the above target PyShapeExample would be used by + # Tool and Builder type targets when this gem is enabled. If you don't want it + # active in Tools or Builders by default, delete one of both of the following lines: + ly_create_alias(NAME PyShapeExample.Tools NAMESPACE Gem TARGETS Gem::PyShapeExample.Editor) + ly_create_alias(NAME PyShapeExample.Builders NAMESPACE Gem TARGETS Gem::PyShapeExample.Editor) + + +endif() + +################################################################################ +# Tests +################################################################################ +# See if globally, tests are supported +if(PAL_TRAIT_BUILD_TESTS_SUPPORTED) + # We globally support tests, see if we support tests on this platform for PyShapeExample.Static + + # If we are a host platform we want to add tools test like editor tests here + if(PAL_TRAIT_BUILD_HOST_TOOLS) + endif() +endif() diff --git a/py_gems/PyShapeExample/Code/Include/PyShapeExample/PyShapeExampleBus.h b/py_gems/PyShapeExample/Code/Include/PyShapeExample/PyShapeExampleBus.h new file mode 100644 index 0000000..8469c95 --- /dev/null +++ b/py_gems/PyShapeExample/Code/Include/PyShapeExample/PyShapeExampleBus.h @@ -0,0 +1,31 @@ + +#pragma once + +#include +#include + +namespace PyShapeExample +{ + class PyShapeExampleRequests + { + public: + AZ_RTTI(PyShapeExampleRequests, "{fc0caa1d-9f70-48be-b78a-fcdc853c87e2}"); + virtual ~PyShapeExampleRequests() = default; + // Put your public methods here + }; + + class PyShapeExampleBusTraits + : public AZ::EBusTraits + { + public: + ////////////////////////////////////////////////////////////////////////// + // EBusTraits overrides + static constexpr AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Single; + static constexpr AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::Single; + ////////////////////////////////////////////////////////////////////////// + }; + + using PyShapeExampleRequestBus = AZ::EBus; + using PyShapeExampleInterface = AZ::Interface; + +} // namespace PyShapeExample diff --git a/py_gems/PyShapeExample/Code/Platform/Linux/PAL_linux.cmake b/py_gems/PyShapeExample/Code/Platform/Linux/PAL_linux.cmake new file mode 100644 index 0000000..944273c --- /dev/null +++ b/py_gems/PyShapeExample/Code/Platform/Linux/PAL_linux.cmake @@ -0,0 +1,4 @@ + +set(PAL_TRAIT_PYSHAPEEXAMPLE_SUPPORTED TRUE) +set(PAL_TRAIT_PYSHAPEEXAMPLE_TEST_SUPPORTED TRUE) +set(PAL_TRAIT_PYSHAPEEXAMPLE_EDITOR_TEST_SUPPORTED TRUE) \ No newline at end of file diff --git a/py_gems/PyShapeExample/Code/Platform/Linux/pyshapeexample_linux_files.cmake b/py_gems/PyShapeExample/Code/Platform/Linux/pyshapeexample_linux_files.cmake new file mode 100644 index 0000000..7c474c5 --- /dev/null +++ b/py_gems/PyShapeExample/Code/Platform/Linux/pyshapeexample_linux_files.cmake @@ -0,0 +1,8 @@ + +# Platform specific files for Linux +# i.e. ../Source/Linux/PyShapeExampleLinux.cpp +# ../Source/Linux/PyShapeExampleLinux.h +# ../Include/Linux/PyShapeExampleLinux.h + +set(FILES +) diff --git a/py_gems/PyShapeExample/Code/Platform/Linux/pyshapeexample_shared_linux_files.cmake b/py_gems/PyShapeExample/Code/Platform/Linux/pyshapeexample_shared_linux_files.cmake new file mode 100644 index 0000000..7c474c5 --- /dev/null +++ b/py_gems/PyShapeExample/Code/Platform/Linux/pyshapeexample_shared_linux_files.cmake @@ -0,0 +1,8 @@ + +# Platform specific files for Linux +# i.e. ../Source/Linux/PyShapeExampleLinux.cpp +# ../Source/Linux/PyShapeExampleLinux.h +# ../Include/Linux/PyShapeExampleLinux.h + +set(FILES +) diff --git a/py_gems/PyShapeExample/Code/Platform/Mac/PAL_mac.cmake b/py_gems/PyShapeExample/Code/Platform/Mac/PAL_mac.cmake new file mode 100644 index 0000000..944273c --- /dev/null +++ b/py_gems/PyShapeExample/Code/Platform/Mac/PAL_mac.cmake @@ -0,0 +1,4 @@ + +set(PAL_TRAIT_PYSHAPEEXAMPLE_SUPPORTED TRUE) +set(PAL_TRAIT_PYSHAPEEXAMPLE_TEST_SUPPORTED TRUE) +set(PAL_TRAIT_PYSHAPEEXAMPLE_EDITOR_TEST_SUPPORTED TRUE) \ No newline at end of file diff --git a/py_gems/PyShapeExample/Code/Platform/Mac/pyshapeexample_mac_files.cmake b/py_gems/PyShapeExample/Code/Platform/Mac/pyshapeexample_mac_files.cmake new file mode 100644 index 0000000..341fca2 --- /dev/null +++ b/py_gems/PyShapeExample/Code/Platform/Mac/pyshapeexample_mac_files.cmake @@ -0,0 +1,8 @@ + +# Platform specific files for Mac +# i.e. ../Source/Mac/PyShapeExampleMac.cpp +# ../Source/Mac/PyShapeExampleMac.h +# ../Include/Mac/PyShapeExampleMac.h + +set(FILES +) diff --git a/py_gems/PyShapeExample/Code/Platform/Mac/pyshapeexample_shared_mac_files.cmake b/py_gems/PyShapeExample/Code/Platform/Mac/pyshapeexample_shared_mac_files.cmake new file mode 100644 index 0000000..341fca2 --- /dev/null +++ b/py_gems/PyShapeExample/Code/Platform/Mac/pyshapeexample_shared_mac_files.cmake @@ -0,0 +1,8 @@ + +# Platform specific files for Mac +# i.e. ../Source/Mac/PyShapeExampleMac.cpp +# ../Source/Mac/PyShapeExampleMac.h +# ../Include/Mac/PyShapeExampleMac.h + +set(FILES +) diff --git a/py_gems/PyShapeExample/Code/Platform/Windows/PAL_windows.cmake b/py_gems/PyShapeExample/Code/Platform/Windows/PAL_windows.cmake new file mode 100644 index 0000000..944273c --- /dev/null +++ b/py_gems/PyShapeExample/Code/Platform/Windows/PAL_windows.cmake @@ -0,0 +1,4 @@ + +set(PAL_TRAIT_PYSHAPEEXAMPLE_SUPPORTED TRUE) +set(PAL_TRAIT_PYSHAPEEXAMPLE_TEST_SUPPORTED TRUE) +set(PAL_TRAIT_PYSHAPEEXAMPLE_EDITOR_TEST_SUPPORTED TRUE) \ No newline at end of file diff --git a/py_gems/PyShapeExample/Code/Platform/Windows/pyshapeexample_shared_windows_files.cmake b/py_gems/PyShapeExample/Code/Platform/Windows/pyshapeexample_shared_windows_files.cmake new file mode 100644 index 0000000..72cd2f1 --- /dev/null +++ b/py_gems/PyShapeExample/Code/Platform/Windows/pyshapeexample_shared_windows_files.cmake @@ -0,0 +1,8 @@ + +# Platform specific files for Windows +# i.e. ../Source/Windows/PyShapeExampleWindows.cpp +# ../Source/Windows/PyShapeExampleWindows.h +# ../Include/Windows/PyShapeExampleWindows.h + +set(FILES +) diff --git a/py_gems/PyShapeExample/Code/Platform/Windows/pyshapeexample_windows_files.cmake b/py_gems/PyShapeExample/Code/Platform/Windows/pyshapeexample_windows_files.cmake new file mode 100644 index 0000000..72cd2f1 --- /dev/null +++ b/py_gems/PyShapeExample/Code/Platform/Windows/pyshapeexample_windows_files.cmake @@ -0,0 +1,8 @@ + +# Platform specific files for Windows +# i.e. ../Source/Windows/PyShapeExampleWindows.cpp +# ../Source/Windows/PyShapeExampleWindows.h +# ../Include/Windows/PyShapeExampleWindows.h + +set(FILES +) diff --git a/py_gems/PyShapeExample/Code/Source/PyShapeExample.qrc b/py_gems/PyShapeExample/Code/Source/PyShapeExample.qrc new file mode 100644 index 0000000..85a885e --- /dev/null +++ b/py_gems/PyShapeExample/Code/Source/PyShapeExample.qrc @@ -0,0 +1,5 @@ + + + toolbar_icon.svg + + diff --git a/py_gems/PyShapeExample/Code/Source/PyShapeExampleEditorModule.cpp b/py_gems/PyShapeExample/Code/Source/PyShapeExampleEditorModule.cpp new file mode 100644 index 0000000..a5b9b98 --- /dev/null +++ b/py_gems/PyShapeExample/Code/Source/PyShapeExampleEditorModule.cpp @@ -0,0 +1,46 @@ + +#include +#include + +void InitPyShapeExampleResources() +{ + // We must register our Qt resources (.qrc file) since this is being loaded from a separate module (gem) + Q_INIT_RESOURCE(PyShapeExample); +} + +namespace PyShapeExample +{ + class PyShapeExampleEditorModule + : public PyShapeExampleModuleInterface + { + public: + AZ_RTTI(PyShapeExampleEditorModule, "{cebbfc02-eab9-4c61-b0de-31795b1c044a}", PyShapeExampleModuleInterface); + AZ_CLASS_ALLOCATOR(PyShapeExampleEditorModule, AZ::SystemAllocator, 0); + + PyShapeExampleEditorModule() + { + InitPyShapeExampleResources(); + + // 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. + // This happens through the [MyComponent]::Reflect() function. + m_descriptors.insert(m_descriptors.end(), { + PyShapeExampleEditorSystemComponent::CreateDescriptor(), + }); + } + + /** + * Add required SystemComponents to the SystemEntity. + * Non-SystemComponents should not be added here + */ + AZ::ComponentTypeList GetRequiredSystemComponents() const override + { + return AZ::ComponentTypeList { + azrtti_typeid(), + }; + } + }; +}// namespace PyShapeExample + +AZ_DECLARE_MODULE_CLASS(Gem_PyShapeExample, PyShapeExample::PyShapeExampleEditorModule) diff --git a/py_gems/PyShapeExample/Code/Source/PyShapeExampleEditorSystemComponent.cpp b/py_gems/PyShapeExample/Code/Source/PyShapeExampleEditorSystemComponent.cpp new file mode 100644 index 0000000..7f472bc --- /dev/null +++ b/py_gems/PyShapeExample/Code/Source/PyShapeExampleEditorSystemComponent.cpp @@ -0,0 +1,61 @@ + +#include +#include + +namespace PyShapeExample +{ + void PyShapeExampleEditorSystemComponent::Reflect(AZ::ReflectContext* context) + { + if (auto serializeContext = azrtti_cast(context)) + { + serializeContext->Class(); + } + } + + PyShapeExampleEditorSystemComponent::PyShapeExampleEditorSystemComponent() + { + if (PyShapeExampleInterface::Get() == nullptr) + { + PyShapeExampleInterface::Register(this); + } + } + + PyShapeExampleEditorSystemComponent::~PyShapeExampleEditorSystemComponent() + { + if (PyShapeExampleInterface::Get() == this) + { + PyShapeExampleInterface::Unregister(this); + } + } + + void PyShapeExampleEditorSystemComponent::GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided) + { + provided.push_back(AZ_CRC_CE("PyShapeExampleEditorService")); + } + + void PyShapeExampleEditorSystemComponent::GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible) + { + incompatible.push_back(AZ_CRC_CE("PyShapeExampleEditorService")); + } + + void PyShapeExampleEditorSystemComponent::GetRequiredServices([[maybe_unused]] AZ::ComponentDescriptor::DependencyArrayType& required) + { + } + + void PyShapeExampleEditorSystemComponent::GetDependentServices([[maybe_unused]] AZ::ComponentDescriptor::DependencyArrayType& dependent) + { + } + + void PyShapeExampleEditorSystemComponent::Activate() + { + PyShapeExampleRequestBus::Handler::BusConnect(); + AzToolsFramework::EditorEvents::Bus::Handler::BusConnect(); + } + + void PyShapeExampleEditorSystemComponent::Deactivate() + { + AzToolsFramework::EditorEvents::Bus::Handler::BusDisconnect(); + PyShapeExampleRequestBus::Handler::BusDisconnect(); + } + +} // namespace PyShapeExample diff --git a/py_gems/PyShapeExample/Code/Source/PyShapeExampleEditorSystemComponent.h b/py_gems/PyShapeExample/Code/Source/PyShapeExampleEditorSystemComponent.h new file mode 100644 index 0000000..6ff8610 --- /dev/null +++ b/py_gems/PyShapeExample/Code/Source/PyShapeExampleEditorSystemComponent.h @@ -0,0 +1,33 @@ + +#pragma once +#include +#include + +#include + +namespace PyShapeExample +{ + /// System component for PyShapeExample editor + class PyShapeExampleEditorSystemComponent + : public PyShapeExampleRequestBus::Handler + , private AzToolsFramework::EditorEvents::Bus::Handler + , public AZ::Component + { + public: + AZ_COMPONENT(PyShapeExampleEditorSystemComponent, "{a4475498-5700-4502-885b-3406dc685a4c}"); + static void Reflect(AZ::ReflectContext* context); + + PyShapeExampleEditorSystemComponent(); + ~PyShapeExampleEditorSystemComponent(); + + private: + static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided); + static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible); + static void GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required); + static void GetDependentServices(AZ::ComponentDescriptor::DependencyArrayType& dependent); + + // AZ::Component + void Activate(); + void Deactivate(); + }; +} // namespace PyShapeExample diff --git a/py_gems/PyShapeExample/Code/Source/PyShapeExampleModuleInterface.h b/py_gems/PyShapeExample/Code/Source/PyShapeExampleModuleInterface.h new file mode 100644 index 0000000..7df6632 --- /dev/null +++ b/py_gems/PyShapeExample/Code/Source/PyShapeExampleModuleInterface.h @@ -0,0 +1,27 @@ + +#include +#include + +namespace PyShapeExample +{ + class PyShapeExampleModuleInterface + : public AZ::Module + { + public: + AZ_RTTI(PyShapeExampleModuleInterface, "{f8731810-a6e3-403d-af72-ee81424ef59c}", AZ::Module); + AZ_CLASS_ALLOCATOR(PyShapeExampleModuleInterface, AZ::SystemAllocator, 0); + + PyShapeExampleModuleInterface() + { + } + + /** + * Add required SystemComponents to the SystemEntity. + */ + AZ::ComponentTypeList GetRequiredSystemComponents() const override + { + return AZ::ComponentTypeList{ + }; + } + }; +}// namespace PyShapeExample diff --git a/py_gems/PyShapeExample/Code/Source/toolbar_icon.svg b/py_gems/PyShapeExample/Code/Source/toolbar_icon.svg new file mode 100644 index 0000000..59de669 --- /dev/null +++ b/py_gems/PyShapeExample/Code/Source/toolbar_icon.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/py_gems/PyShapeExample/Code/Tests/PyShapeExampleEditorTest.cpp b/py_gems/PyShapeExample/Code/Tests/PyShapeExampleEditorTest.cpp new file mode 100644 index 0000000..274a990 --- /dev/null +++ b/py_gems/PyShapeExample/Code/Tests/PyShapeExampleEditorTest.cpp @@ -0,0 +1,4 @@ + +#include + +AZ_UNIT_TEST_HOOK(DEFAULT_UNIT_TEST_ENV); diff --git a/py_gems/PyShapeExample/Code/pyshapeexample_editor_files.cmake b/py_gems/PyShapeExample/Code/pyshapeexample_editor_files.cmake new file mode 100644 index 0000000..bc272f6 --- /dev/null +++ b/py_gems/PyShapeExample/Code/pyshapeexample_editor_files.cmake @@ -0,0 +1,8 @@ + +set(FILES + Include/PyShapeExample/PyShapeExampleBus.h + Source/PyShapeExampleModuleInterface.h + Source/PyShapeExampleEditorSystemComponent.cpp + Source/PyShapeExampleEditorSystemComponent.h + Source/PyShapeExample.qrc +) diff --git a/py_gems/PyShapeExample/Code/pyshapeexample_editor_shared_files.cmake b/py_gems/PyShapeExample/Code/pyshapeexample_editor_shared_files.cmake new file mode 100644 index 0000000..80582ec --- /dev/null +++ b/py_gems/PyShapeExample/Code/pyshapeexample_editor_shared_files.cmake @@ -0,0 +1,4 @@ + +set(FILES + Source/PyShapeExampleEditorModule.cpp +) diff --git a/py_gems/PyShapeExample/Code/pyshapeexample_editor_tests_files.cmake b/py_gems/PyShapeExample/Code/pyshapeexample_editor_tests_files.cmake new file mode 100644 index 0000000..ffb7a72 --- /dev/null +++ b/py_gems/PyShapeExample/Code/pyshapeexample_editor_tests_files.cmake @@ -0,0 +1,4 @@ + +set(FILES + Tests/PyShapeExampleEditorTest.cpp +) diff --git a/py_gems/PyShapeExample/Editor/Scripts/__init__.py b/py_gems/PyShapeExample/Editor/Scripts/__init__.py new file mode 100644 index 0000000..e011065 --- /dev/null +++ b/py_gems/PyShapeExample/Editor/Scripts/__init__.py @@ -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 +""" +# ------------------------------------------------------------------------- + +__ALL__ = ['bootstrap','pyshapeexample_dialog'] \ No newline at end of file diff --git a/py_gems/PyShapeExample/Editor/Scripts/__pycache__/pyshapeexample_dialog.cpython-37.pyc b/py_gems/PyShapeExample/Editor/Scripts/__pycache__/pyshapeexample_dialog.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5e660f05e4e8c893dabbaf00fa532604f00b8e2b GIT binary patch literal 3216 zcmai0OK%&=5$<_#I5T{Rq$KaI{K#bUfO!x%@B#_2SQxP=*%9ECB}>Q#0|k@ObdwzI zJm~JG^}sL}8CV~3$bAujJm#n5FZ4Ah1G(k4r&RZll%4D%B&MgjrnZ_{WX*65} zzk5F`Lbi_3KjmckGlBRmJgk5LBOhT6>xq`?zOI$Dk($1_pew26TMN3H+Pxy?&l?8lO#gPMODZkB^A=VoWmc^IdN*8^#&&4rzW)BHnYK=G2Sw zbes@QfLN*tGwdaCL^4J^PH4(JkO*PI2rxk3^Zowb!SS9Kay6xS&b@p9bj&;)vvU79 z&w8$Ve7O6E?dPSk?R`u#9uHzdzwn-n!)QddAN79ay?E(;wSVHi181Uxt|lr+`%#{C zZQ&gCM$=Wx0`983P;gpGD4oaY%# zeh(TJLe-~20lAA4mGM@6sdN2^=YYhfz58HsDK<8+talO!Pw7CZHN1#PJ=o(@( z#5iD5Rgi@#3D{&Xh%bf92;a-XvxHz_BqZzV!ek^F2$Pdb{&z&%p!NHgyI-6#Wx#fn zW3oLYDLWls1?v5wg{RU-IXyj&XguapN^MF?`va^T-5Xzttvo9&iL>#92Xeb08im=A zU`PqX)ESNI&puRNI-vLCYgfLpK#6>mZ~h7dSDraHu*S_n!!HjH8nG4?ZQ-2`m6)kl(v*sRQNhrVeyUGCSY2d zR*UNSouM|h`A4&l`6uUFfNy(<=H}E{ajJy_8R24kTD$x+zgxIB+AjJdJ=Lf6X`^t8 zI^;diAfb5oBY#uvRC76TsQ^*-z(4LvIm$Qyx?~*F3m> z0NLY36UOrtnwHEuPvXoQ5lVW!-pO_CJ?`};q?o4wS4x$2)2|=PQhH42YiK|I{r}0@ zeav>Q7N4oC%klI2e>QMFLs7T_RA0;nwL8vP~k zpjua<(M8`7On)xtn#!y962ks63DYwiKK>JY{x>}6M=EL%#97RPp!a2xM`6Mq15vK* zekv+#GA5MPV7aiDlGK4Im8Q{(93<%J0~kaHn#!Rp0i!&@gq}cY7n{KAL#L-@<6QI{ zDvwwemKq4`#;j~bHQ5gOWjBB$=2-@J3MzdeENEme^9$jC{IWR%tL(f~R(xTmAs>l$ zpGKcQ3d#zrXi<3`CKEzs380=Fw&ZXZ2H}uwk`fBVShUKZ+!jk}OEDP{(SlvS0#Bur z^mjzwi@-Xlt`Gp>f)&S{Li-WGo1lAd>}`Zo}{yJZu*Rq_uPl zYN-V^wGI^(Mx&)SwI)!mBnU)32wqLXr2L}5qLM_}C>jg2_|6# zR#ohe6zIE~q8bD^kAlE=!|NnHqdn-K3O=H-U=Y=G6}bErPt_NC57ha!g`5N@{WWkz z1C9#8d(=DP&n9sRu=XvlgfuI2L|*gCJd?JS$);d=n}yQ)+k<^j1WF%0mP=U^2D1Y3 JS^OXB{{cBTmwNyJ literal 0 HcmV?d00001 diff --git a/py_gems/PyShapeExample/Editor/Scripts/bootstrap.py b/py_gems/PyShapeExample/Editor/Scripts/bootstrap.py new file mode 100644 index 0000000..8890487 --- /dev/null +++ b/py_gems/PyShapeExample/Editor/Scripts/bootstrap.py @@ -0,0 +1,22 @@ +""" +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 +""" +# ------------------------------------------------------------------------- +"""PyShapeExample\\editor\\scripts\\boostrap.py +Generated from O3DE PythonToolGem Template""" + +import az_qt_helpers +import azlmbr.editor as editor +from pyshapeexample_dialog import PyShapeExampleDialog + +if __name__ == "__main__": + print("PyShapeExample.boostrap, Generated from O3DE PythonToolGem Template") + + # Register our custom widget as a dockable tool with the Editor under an Examples sub-menu + options = editor.ViewPaneOptions() + options.showOnToolsToolbar = True + options.toolbarIcon = ":/PyShapeExample/toolbar_icon.svg" + az_qt_helpers.register_view_pane('Shape Example (Python)', PyShapeExampleDialog, category="Examples", options=options) diff --git a/py_gems/PyShapeExample/Editor/Scripts/pyshapeexample_dialog.py b/py_gems/PyShapeExample/Editor/Scripts/pyshapeexample_dialog.py new file mode 100644 index 0000000..fdbae6f --- /dev/null +++ b/py_gems/PyShapeExample/Editor/Scripts/pyshapeexample_dialog.py @@ -0,0 +1,110 @@ +""" +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 +""" +# ------------------------------------------------------------------------- +"""PyShapeExample\\editor\\scripts\\PyShapeExample_dialog.py +Generated from O3DE PythonToolGem Template""" + +import azlmbr.bus as bus +import azlmbr.editor as editor +import azlmbr.entity as entity +import azlmbr.math as math +from PySide2.QtGui import QIcon +from PySide2.QtWidgets import QCheckBox, QDialog, QFormLayout, QGridLayout, QLineEdit, QPushButton, QVBoxLayout, QWidget + +class PyShapeExampleDialog(QDialog): + def on_name_input_text_changed(self, text): + # We will only enable the checkbox if the user has typed in + # a custom name for the entity that will be created + self.add_shape_name_suffix.setEnabled(len(text)) + + def create_entity_with_shape_component(self, type_id): + # Create a new entity + new_entity_id = editor.ToolsApplicationRequestBus(bus.Broadcast, 'CreateNewEntity', entity.EntityId()) + + # If the user has input a custom name and/or checked the box to append the + # component suffix, then set the new entity name here + if self.name_input.text(): + entity_name = self.name_input.text() + + if self.add_shape_name_suffix.isChecked(): + component_names = editor.EditorComponentAPIBus(bus.Broadcast, 'FindComponentTypeNames', [type_id]) + + shape_name = component_names[0] + shape_name = shape_name.replace(" ", "") + + entity_name = f"{entity_name}_{shape_name}" + + # Set new name on the entity we created + editor.EditorEntityAPIBus(bus.Event, "SetName", new_entity_id, entity_name) + + # Add the corresponding shape component for the button we pressed to the newly created entity + editor.EditorComponentAPIBus(bus.Broadcast, "AddComponentsOfType", new_entity_id, [type_id]) + + def __init__(self, parent=None): + super(PyShapeExampleDialog, self).__init__(parent) + + main_layout = QVBoxLayout() + + entity_name_widget = QWidget(self) + form_layout = QFormLayout() + + self.name_input = QLineEdit(self) + self.name_input.setPlaceholderText("Set custom Entity name here...") + self.name_input.setClearButtonEnabled(True) + + self.add_shape_name_suffix = QCheckBox(self) + self.add_shape_name_suffix.setDisabled(True) + + # Example of listening to signals using a slot as the handler + self.name_input.textChanged.connect(self.on_name_input_text_changed) + + form_layout.addRow("Entity name", self.name_input) + form_layout.addRow("Add shape name suffix", self.add_shape_name_suffix) + + entity_name_widget.setLayout(form_layout) + main_layout.addWidget(entity_name_widget) + + shape_buttons = QWidget(self) + grid_layout = QGridLayout() + + # We want to find every component that provides the ShapeService + shape_service = math.Crc32_CreateCrc32("ShapeService") + provided_services = [shape_service.value] + type_ids = editor.EditorComponentAPIBus(bus.Broadcast, 'FindComponentTypeIdsByService', provided_services, []) + + # After getting all of the types for the shape components, query to find + # their names so we can show them + component_names = editor.EditorComponentAPIBus(bus.Broadcast, 'FindComponentTypeNames', type_ids) + + max_column_count = 3 + for i, name in enumerate(component_names): + type_id = type_ids[i] + + # Find the icon registered for this component by its type id + icon_path = editor.EditorRequestBus(bus.Broadcast, 'GetComponentTypeEditorIcon', type_id) + + # Create a button with the shape components name and icon + shape_button = QPushButton(QIcon(icon_path), name, self) + shape_button.setMinimumHeight(40) + + # Example of listening to signals using a lambda as the handler + #shape_button.clicked.connect(lambda type_id: self.create_entity_with_shape_component(type_id)) + shape_button.clicked.connect(lambda checked=False, type_id=type_id: self.create_entity_with_shape_component(type_id)) + + # Place our shape button in the grid layout + row = i / max_column_count + column = i % max_column_count + grid_layout.addWidget(shape_button, row, column) + + shape_buttons.setLayout(grid_layout) + main_layout.addWidget(shape_buttons) + + # Add stretch at bottom of the layout to fill any expanded space larger than what is needed, + # so that if our tool is resized large our content will stay together + main_layout.addStretch() + + self.setLayout(main_layout) diff --git a/py_gems/PyShapeExample/gem.json b/py_gems/PyShapeExample/gem.json new file mode 100644 index 0000000..7871e5d --- /dev/null +++ b/py_gems/PyShapeExample/gem.json @@ -0,0 +1,17 @@ +{ + "gem_name": "PyShapeExample", + "display_name": "PyShapeExample", + "license": "What license PyShapeExample uses goes here: i.e. https://opensource.org/licenses/MIT", + "origin": "The primary repo for PyShapeExample goes here: i.e. http://www.mydomain.com", + "type": "Code", + "summary": "A short description of PyShapeExample.", + "canonical_tags": [ + "Gem" + ], + "user_tags": [ + "PyShapeExample" + ], + "icon_path": "preview.png", + "requirements": "", + "restricted_name": "PyShapeExample" +} diff --git a/py_gems/PyShapeExample/preview.png b/py_gems/PyShapeExample/preview.png new file mode 100644 index 0000000000000000000000000000000000000000..2372f0a3f4cd0515ff43972a62388e9687d9e0a7 GIT binary patch literal 2217 zcmYk7c{CJ!7sp4`sKgM`m}fGULiP+}XYA{YX|fwz*6c&1l0A&&jWiid2}vWejb(T& zS+c~Nc}2!DNQ-?djOd--bDrmY?(f{+@0`y$-}}e!-gCccXdBZrr@*HG0Kge@Gb0T9 zb@`p#C)oGG`ltf{z>(~4Xoxm9G!zRB5ApF2^acQ=AKZPQWA;WL(&Kiu;hDVnO?22> zbdg+YI>JJT;9guWzV5JlXx~#yYW`)a`R{A^Q|qvw4xx_kDJ4EFG1D6CUj@J5M5&z3ZopD`34es zk1z2G5cY*1IX@QS$%`f-N?(8%Px}*vhMfz?Fv;+>ez&h90hi6I=nw-z%TyRIzlyB% zGp^GfPH>Esq@Uhsuinbu!l#`6Yg`h2#|F?ajo1ynz3Er^1*C}FpZrg^d#HLQ9J31O z>d7CwH9_Mj!1|TYGWg*lSn0q#rlBG^EAG!A=6p*<|Lu-NUZuTK%al)MI1*9;*!twX zx_4Z>^HbkCQn z)ClnF_j%e@p35dDL(LrV>=usyP7b7WK{OizBh0Ohfr}^3^NU?N?vwYDEi5xPGQdVp zt}>jh&N_+!H|SbzwtmSi`embC2_VbT$TQB|*T<$)VW&{~8R?2&Pvhn}Nh0tE<-H&Q z`1_4G3#DMsdI#iGcaqp?Nzi}fI+4p%X(HzQ(}y!!b$pja` zL-`C334)O?jvI&zYk~lXI70xW0|ww_f&jo!!2N#!058Y?0SDw5^DofTfyd*&aT#C* zxNOrFqL1fwu`@>1xyy=h4-XID8l%{MPESuy^8=qdW8BZT z6{+cZ$HT(|gTdq&i9ay&^z>}9jO=t*dSOSo=SFHMDJjvD$+PHbtS5L(4AIL`KvaLyLL^eK!E8xLKeD`Z}s6^5&c_4VkbzSyZ91{?9OEXq6D>j_3>_+?820l z!)|+ddD+Is9zB=8FL84eOBoyeckSk87-Mucrfp_DLh}z~G1`cF7m4h;cV%jQ7g%XW z`M%0%ydW=3pa-ha$}lpQ<>fQmZ||;^7HLHdAo(l@d6gMZ?daF`#ps=*>dvbe3^n=D z`AieW*6vN(T_1R8F7d+O z&yF8IZZe7u?;mBUA~<1KXj;}z%%O+@XdzzT9SRdT@JG#}=!B5n{nN%_v+Rj+T)hQBskg9O_$A$U%i{W^DuA`hV;rg*uT1$(S9VPE+ zcde3^R)LzT>Q0ZlsHmuv?{MM1cW`j<&6pT)oztrcCR6M={o7~z{P%9}zAuk^EiWy_ zp3%7{mV`#3M%>x|rzAB##|@Lr?f0vxsgd3xO!$#?Zc|I@>#?FvYvIj>D*0CJGm7}Z z*;dxZ94CKpU=m34*48JH6pts!!CTs7=F%7?$1F=ZpksZSMr>+oasacI*4Bn6{TL!C z#WOQA{I!~yCK6?mdsVKqZfz(E!~#R13>J#hkxbmSOm%I*rBovnyNc>hQXd z)kZ3nr41cPU(D1OV_p>~d^1<+U<~4l7v(t-(!>(u^sRBQvPb|Xb_(rQ`>TRo%P`7a zW5ACwkiM|O9Hs)15OMLGpx{PV!zW4F)NZsk&LRP2ZLRTkfRLU}yDpeVma<VSQcl0POhK7|NiAsuZ)S+k0ELA{kr)e z2#}SvwY9jxxrYxQO5zcP6~n{B)x!fzO93`FZcywLh=cu0?|iloBuuj&OX&2zXmQ@# zpE=Q1QsUL_AU9)ThXQfws;GDdhlHpX>D`M}tN*jA$_9DwV2-DnxiN zDr=0T5J>K}=*_OW*RS2D8$;aY1Nf5KFX=uRVN6X;IbOR4Z_ZyxcM44cEiEr^x8K_C zt@Ry&J~tBQr~B1M9{$TWFfedsvf+j+QPGXeSWz~Hv+LzsUHtiDm603UKKl$UjbP7m z&Fra=x{uFE1qC!dsJ7n+B&FK$Z~lmGw# literal 0 HcmV?d00001