From 3788aa4eec9f3820eca2487cad8b11ff91fb45fa Mon Sep 17 00:00:00 2001 From: sphrose <82213493+sphrose@users.noreply.github.com> Date: Thu, 20 May 2021 17:48:18 +0100 Subject: [PATCH 01/16] LYN-2139 UX: Goto Position modal is unnecessarily massive --- Code/Sandbox/Editor/GotoPositionDlg.cpp | 1 + Code/Sandbox/Editor/GotoPositionDlg.ui | 373 +++++++++++++----------- 2 files changed, 198 insertions(+), 176 deletions(-) diff --git a/Code/Sandbox/Editor/GotoPositionDlg.cpp b/Code/Sandbox/Editor/GotoPositionDlg.cpp index a09f594b7b..6e2deaf618 100644 --- a/Code/Sandbox/Editor/GotoPositionDlg.cpp +++ b/Code/Sandbox/Editor/GotoPositionDlg.cpp @@ -34,6 +34,7 @@ CGotoPositionDlg::CGotoPositionDlg(QWidget* pParent /*=NULL*/) { m_ui->setupUi(this); setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint); + setFixedSize(size()); OnInitDialog(); auto doubleValueChanged = static_cast(&QDoubleSpinBox::valueChanged); diff --git a/Code/Sandbox/Editor/GotoPositionDlg.ui b/Code/Sandbox/Editor/GotoPositionDlg.ui index 4c93c8f037..5703850be0 100644 --- a/Code/Sandbox/Editor/GotoPositionDlg.ui +++ b/Code/Sandbox/Editor/GotoPositionDlg.ui @@ -13,182 +13,203 @@ Go to Position - - - - - Go To - - - - - - - Cancel - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - Qt::Horizontal - - - QSizePolicy::Fixed - - - - 22 - 20 - - - - - - - - - - - - - - - - - - - - - - - Z: - - - - - - - Y: - - - - - - - Enter position here: - - - - - - - X: - - - - - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - Position: - - - - - - - X: - - - - - - - X: - - - - - - - - - - Y: - - - - - - - Y: - - - - - - - Z: - - - - - - - Qt::Horizontal - - - QSizePolicy::Fixed - - - - 22 - 20 - - - - - - - - Angles: - - - - - - - Segments: - - - - - - - - - - + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 22 + 20 + + + + + + + + + + + + + + + + + + + + + + + Z: + + + + + + + Y: + + + + + + + Enter position here: + + + + + + + X: + + + + + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + + Position: + + + + + + + X: + + + + + + + X: + + + + + + + + + + Y: + + + + + + + Y: + + + + + + + Z: + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 22 + 20 + + + + + + + + Angles: + + + + + + + Segments: + + + + + + + + + + + + + + + + + Qt::Horizontal + + + + 0 + 0 + + + + + + + + Go To + + + + + + + Cancel + + + + + + m_posEdit From bbafd8843d62426ecbfa029ddf5c455c23a3b3ca Mon Sep 17 00:00:00 2001 From: sphrose <82213493+sphrose@users.noreply.github.com> Date: Fri, 21 May 2021 09:56:25 +0100 Subject: [PATCH 02/16] Adjusted dialog size. --- Code/Sandbox/Editor/GotoPositionDlg.ui | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Code/Sandbox/Editor/GotoPositionDlg.ui b/Code/Sandbox/Editor/GotoPositionDlg.ui index 5703850be0..9791b5bff1 100644 --- a/Code/Sandbox/Editor/GotoPositionDlg.ui +++ b/Code/Sandbox/Editor/GotoPositionDlg.ui @@ -6,8 +6,8 @@ 0 0 - 358 - 198 + 290 + 180 From 032201a66b5c25eb323f0a11e2d5d86e67906871 Mon Sep 17 00:00:00 2001 From: sphrose <82213493+sphrose@users.noreply.github.com> Date: Fri, 21 May 2021 10:31:47 +0100 Subject: [PATCH 03/16] Make goto button primary. --- Code/Sandbox/Editor/GotoPositionDlg.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Code/Sandbox/Editor/GotoPositionDlg.cpp b/Code/Sandbox/Editor/GotoPositionDlg.cpp index 6e2deaf618..85ed1b5f03 100644 --- a/Code/Sandbox/Editor/GotoPositionDlg.cpp +++ b/Code/Sandbox/Editor/GotoPositionDlg.cpp @@ -99,6 +99,8 @@ void CGotoPositionDlg::OnInitDialog() m_ui->m_dymSegX->setVisible(false); m_ui->m_dymSegY->setVisible(false); + m_ui->pushButton->setDefault(true); + OnUpdateNumbers(); } From 5be021a6ded33343271b7b0bf0b53a730b9c4d84 Mon Sep 17 00:00:00 2001 From: sphrose <82213493+sphrose@users.noreply.github.com> Date: Fri, 21 May 2021 14:42:46 +0100 Subject: [PATCH 04/16] Added comment. --- Code/Sandbox/Editor/GotoPositionDlg.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/Code/Sandbox/Editor/GotoPositionDlg.cpp b/Code/Sandbox/Editor/GotoPositionDlg.cpp index 85ed1b5f03..f52a45cad4 100644 --- a/Code/Sandbox/Editor/GotoPositionDlg.cpp +++ b/Code/Sandbox/Editor/GotoPositionDlg.cpp @@ -99,6 +99,7 @@ void CGotoPositionDlg::OnInitDialog() m_ui->m_dymSegX->setVisible(false); m_ui->m_dymSegY->setVisible(false); + // Ensure the goto button is highlighted correctly. m_ui->pushButton->setDefault(true); OnUpdateNumbers(); From 6ee8c6daa5f4e7670fa15c432b66b102d94811ac Mon Sep 17 00:00:00 2001 From: mnaumov Date: Fri, 21 May 2021 20:34:42 -0700 Subject: [PATCH 05/16] [ATOM-15538] Material Editor camera zoom speed adjusts to model size --- .../MaterialEditorViewportInputControllerBus.h | 3 +++ .../Code/Source/Viewport/InputController/Behavior.cpp | 4 +++- .../Code/Source/Viewport/InputController/Behavior.h | 2 ++ .../MaterialEditorViewportInputController.cpp | 10 +++++++--- .../MaterialEditorViewportInputController.h | 3 +++ 5 files changed, 18 insertions(+), 4 deletions(-) diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Include/Atom/Viewport/InputController/MaterialEditorViewportInputControllerBus.h b/Gems/Atom/Tools/MaterialEditor/Code/Include/Atom/Viewport/InputController/MaterialEditorViewportInputControllerBus.h index 2acdc79286..837762b49c 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Include/Atom/Viewport/InputController/MaterialEditorViewportInputControllerBus.h +++ b/Gems/Atom/Tools/MaterialEditor/Code/Include/Atom/Viewport/InputController/MaterialEditorViewportInputControllerBus.h @@ -47,6 +47,9 @@ namespace MaterialEditor //! @param distanceMax furthest camera can be from the target virtual void GetExtents(float& distanceMin, float& distanceMax) const = 0; + //! Get bounding sphere radius of the active model + virtual float GetRadius() const = 0; + //! Reset camera to default position and rotation virtual void Reset() = 0; diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/InputController/Behavior.cpp b/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/InputController/Behavior.cpp index 159d3339be..5a671d53ef 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/InputController/Behavior.cpp +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/InputController/Behavior.cpp @@ -44,6 +44,8 @@ namespace MaterialEditor MaterialEditorViewportInputControllerRequestBus::BroadcastResult( m_targetPosition, &MaterialEditorViewportInputControllerRequestBus::Handler::GetTargetPosition); + MaterialEditorViewportInputControllerRequestBus::BroadcastResult( + m_radius, &MaterialEditorViewportInputControllerRequestBus::Handler::GetRadius); } void Behavior::End() @@ -119,7 +121,7 @@ namespace MaterialEditor float Behavior::GetSensitivityZ() { - return 0.001f; + return 0.001f * AZ::GetMax(0.5f, m_radius); } AZ::Quaternion Behavior::LookRotation(AZ::Vector3 forward) diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/InputController/Behavior.h b/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/InputController/Behavior.h index 7c32ed33a0..205301c90e 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/InputController/Behavior.h +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/InputController/Behavior.h @@ -54,6 +54,8 @@ namespace MaterialEditor float m_y = 0; //! delta scroll wheel accumulated during current frame float m_z = 0; + //! Model radius + float m_radius = 1.0f; AZ::EntityId m_cameraEntityId; AZ::Vector3 m_targetPosition = AZ::Vector3::CreateZero(); diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/InputController/MaterialEditorViewportInputController.cpp b/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/InputController/MaterialEditorViewportInputController.cpp index 36e4b76cec..420e2732d0 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/InputController/MaterialEditorViewportInputController.cpp +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/InputController/MaterialEditorViewportInputController.cpp @@ -114,6 +114,11 @@ namespace MaterialEditor distanceMax = m_distanceMax; } + float MaterialEditorViewportInputController::GetRadius() const + { + return m_radius; + } + void MaterialEditorViewportInputController::UpdateViewport(const AzFramework::ViewportControllerUpdateEvent& event) { if (m_keysChanged) @@ -306,11 +311,10 @@ namespace MaterialEditor if (modelAsset.IsReady()) { const AZ::Aabb& aabb = modelAsset->GetAabb(); - float radius; - aabb.GetAsSphere(m_modelCenter, radius); + aabb.GetAsSphere(m_modelCenter, m_radius); m_distanceMin = 0.5f * AZ::GetMin(AZ::GetMin(aabb.GetExtents().GetX(), aabb.GetExtents().GetY()), aabb.GetExtents().GetZ()) + DepthNear; - m_distanceMax = radius * MaxDistanceMultiplier; + m_distanceMax = m_radius * MaxDistanceMultiplier; } } } diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/InputController/MaterialEditorViewportInputController.h b/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/InputController/MaterialEditorViewportInputController.h index ee40b5c259..7308ce4ea1 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/InputController/MaterialEditorViewportInputController.h +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/InputController/MaterialEditorViewportInputController.h @@ -43,6 +43,7 @@ namespace MaterialEditor void SetTargetPosition(const AZ::Vector3& targetPosition) override; float GetDistanceToTarget() const override; void GetExtents(float& distanceMin, float& distanceMax) const override; + float GetRadius() const override; void Reset() override; void SetFieldOfView(float value) override; bool IsCameraCentered() const override; @@ -96,6 +97,8 @@ namespace MaterialEditor float m_distanceMin = 1.0f; //! Maximum distance from camera to target float m_distanceMax = 10.0f; + //! Model radius + float m_radius = 1.0f; //! True if camera is centered on a model bool m_isCameraCentered = true; From 265e57cd0758bd19c4a42e1c961d7f5c1db3e311 Mon Sep 17 00:00:00 2001 From: balibhan Date: Mon, 24 May 2021 11:20:48 +0530 Subject: [PATCH 06/16] Add remove method Asset Editor --- ...ScriptEvent_AddRemoveMethod_UpdatesInSC.py | 202 ++++++++++++++++++ .../scripting/TestSuite_Periodic.py | 28 +++ 2 files changed, 230 insertions(+) create mode 100644 AutomatedTesting/Gem/PythonTests/scripting/ScriptEvent_AddRemoveMethod_UpdatesInSC.py diff --git a/AutomatedTesting/Gem/PythonTests/scripting/ScriptEvent_AddRemoveMethod_UpdatesInSC.py b/AutomatedTesting/Gem/PythonTests/scripting/ScriptEvent_AddRemoveMethod_UpdatesInSC.py new file mode 100644 index 0000000000..19f59cb4c9 --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/scripting/ScriptEvent_AddRemoveMethod_UpdatesInSC.py @@ -0,0 +1,202 @@ +""" +All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or +its licensors. + +For complete copyright and license terms please see the LICENSE at the root of this +distribution (the "License"). All use of this software is governed by the License, +or, if provided, by the license below or the license accompanying this file. Do not +remove or modify any license notices. This file is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +""" + + +# fmt: off +class Tests(): + new_event_created = ("New Script Event created", "New Script Event not created") + child_1_created = ("Initial Child Event created", "Initial Child Event not created") + child_2_created = ("Second Child Event created", "Second Child Event not created") + file_saved = ("Script event file saved", "Script event file did not save") + method_added = ("Method added to scriptevent file", "Method not added to scriptevent file") + method_removed = ("Method removed from scriptevent file", "Method not removed from scriptevent file") +# fmt: on + + +def ScriptEvent_AddRemoveMethod_UpdatesInSC(): + """ + Summary: + Script Event file can be created + + Expected Behavior: + File is created without any errors and warnings in Console + + Test Steps: + 1) Open Asset Editor and Script Canvas windows + 2) Initially create new Script Event file with one method + 3) Verify if file is created and saved + 4) Add a new child element + 5) Update MethodNames and save file + 6) Verify if the new node exist in SC (search in node palette) + 7) Delete one method and save + 8) Verify if the node is removed in SC + 9) Close Asset Editor + + Note: + - This test file must be called from the Open 3D Engine Editor command terminal + - Any passed and failed tests are written to the Editor.log file. + Parsing the file or running a log_monitor are required to observe the test results. + + :return: None + """ + import os + from utils import TestHelper as helper + import pyside_utils + + # Open 3D Engine imports + import azlmbr.legacy.general as general + import azlmbr.editor as editor + import azlmbr.bus as bus + + # Pyside imports + from PySide2 import QtWidgets, QtTest, QtCore + + GENERAL_WAIT = 1.0 # seconds + + FILE_PATH = os.path.join("AutomatedTesting", "TestAssets", "test_file.scriptevents") + METHOD_NAME = "test_method_name" + + editor_window = pyside_utils.get_editor_main_window() + asset_editor = asset_editor_widget = container = menu_bar = None + sc = node_palette = tree = search_frame = search_box = None + + def initialize_asset_editor_qt_objects(): + nonlocal asset_editor, asset_editor_widget, container, menu_bar + asset_editor = editor_window.findChild(QtWidgets.QDockWidget, "Asset Editor") + asset_editor_widget = asset_editor.findChild(QtWidgets.QWidget, "AssetEditorWindowClass") + container = asset_editor_widget.findChild(QtWidgets.QWidget, "ContainerForRows") + menu_bar = asset_editor_widget.findChild(QtWidgets.QMenuBar) + + def initialize_sc_qt_objects(): + nonlocal sc, node_palette, tree, search_frame, search_box + sc = editor_window.findChild(QtWidgets.QDockWidget, "Script Canvas") + if sc.findChild(QtWidgets.QDockWidget, "NodePalette") is None: + action = pyside_utils.find_child_by_pattern(sc, {"text": "Node Palette", "type": QtWidgets.QAction}) + action.trigger() + node_palette = sc.findChild(QtWidgets.QDockWidget, "NodePalette") + tree = node_palette.findChild(QtWidgets.QTreeView, "treeView") + search_frame = node_palette.findChild(QtWidgets.QFrame, "searchFrame") + search_box = search_frame.findChild(QtWidgets.QLineEdit, "searchFilter") + + def save_file(): + editor.AssetEditorWidgetRequestsBus(bus.Broadcast, "SaveAssetAs", FILE_PATH) + action = pyside_utils.find_child_by_pattern(menu_bar, {"type": QtWidgets.QAction, "iconText": "Save"}) + action.trigger() + # wait till file is saved, to validate that check the text of QLabel at the bottom of the AssetEditor, + # if there are no unsaved changes we will not have any * in the text + label = asset_editor.findChild(QtWidgets.QLabel, "textEdit") + return helper.wait_for_condition(lambda: "*" not in label.text(), 3.0) + + def expand_container_rows(object_name): + children = container.findChildren(QtWidgets.QFrame, object_name) + for child in children: + check_box = child.findChild(QtWidgets.QCheckBox) + if check_box and not check_box.isChecked(): + QtTest.QTest.mouseClick(check_box, QtCore.Qt.LeftButton, QtCore.Qt.NoModifier) + + def node_palette_search(node_name): + search_box.setText(node_name) + helper.wait_for_condition(lambda: search_box.text() == node_name, 1.0) + # Try clicking ENTER in search box multiple times + for _ in range(10): + QtTest.QTest.keyClick(search_box, QtCore.Qt.Key_Enter, QtCore.Qt.NoModifier) + if pyside_utils.find_child_by_pattern(tree, {"text": node_name}) is not None: + break + + # 1) Open Asset Editor + general.idle_enable(True) + # Initially close the Asset Editor and then reopen to ensure we don't have any existing assets open + general.close_pane("Asset Editor") + general.open_pane("Asset Editor") + helper.wait_for_condition(lambda: general.is_pane_visible("Asset Editor"), 5.0) + + # 2) Initially create new Script Event file with one method + initialize_asset_editor_qt_objects() + action = pyside_utils.find_child_by_pattern(menu_bar, {"type": QtWidgets.QAction, "text": "Script Events"}) + action.trigger() + result = helper.wait_for_condition( + lambda: container.findChild(QtWidgets.QFrame, "Events") is not None + and container.findChild(QtWidgets.QFrame, "Events").findChild(QtWidgets.QToolButton, "") is not None, + 3 * GENERAL_WAIT, + ) + Report.result(Tests.new_event_created, result) + # Add new method + add_event = container.findChild(QtWidgets.QFrame, "Events").findChild(QtWidgets.QToolButton, "") + add_event.click() + result = helper.wait_for_condition( + lambda: asset_editor_widget.findChild(QtWidgets.QFrame, "EventName") is not None, GENERAL_WAIT + ) + Report.result(Tests.child_1_created, result) + editor.AssetEditorWidgetRequestsBus(bus.Broadcast, "SaveAssetAs", FILE_PATH) + + # 3) Verify if file is created and saved + result = helper.wait_for_condition(lambda: os.path.exists(FILE_PATH), 3 * GENERAL_WAIT) + Report.result(Tests.file_saved, result and save_file()) + + # 4) Add a new child element + add_event = container.findChild(QtWidgets.QFrame, "Events").findChild(QtWidgets.QToolButton, "") + add_event.click() + result = helper.wait_for_condition( + lambda: len(asset_editor_widget.findChildren(QtWidgets.QFrame, "EventName")) == 2, 2 * GENERAL_WAIT + ) + Report.result(Tests.child_2_created, result) + + # 5) Update MethodNames and save file, (update all Method names to make it easier to search in SC later) + # Expand the EventName initially + expand_container_rows("EventName") + # Expand Name fields under it + expand_container_rows("Name") + count = 0 # 2 Method names will be updated Ex: test_method_name_0, test_method_name_1 + container = asset_editor_widget.findChild(QtWidgets.QWidget, "ContainerForRows") + children = container.findChildren(QtWidgets.QFrame, "Name") + for child in children: + line_edit = child.findChild(QtWidgets.QLineEdit) + if line_edit and line_edit.text() == "MethodName": + line_edit.setText(f"{METHOD_NAME}_{count}") + count += 1 + save_file() + + # 6) Verify if the new node exist in SC (search in node palette) + general.open_pane("Script Canvas") + helper.wait_for_condition(lambda: general.is_pane_visible("Script Canvas"), 5.0) + initialize_sc_qt_objects() + node_palette_search(f"{METHOD_NAME}_1") + get_node_index = lambda: pyside_utils.find_child_by_pattern(tree, {"text": f"{METHOD_NAME}_1"}) is not None + result = helper.wait_for_condition(get_node_index, GENERAL_WAIT) + Report.result(Tests.method_added, result) + + # 7) Delete one method and save + initialize_asset_editor_qt_objects() + for child in container.findChildren(QtWidgets.QFrame, "EventName"): + if child.findChild(QtWidgets.QToolButton, ""): + child.findChild(QtWidgets.QToolButton, "").click() + break + save_file() + + # 8) Verify if the node is removed in SC (search in node palette) + initialize_sc_qt_objects() + node_palette_search(f"{METHOD_NAME}_0") + get_node_index = lambda: pyside_utils.find_child_by_pattern(tree, {"text": f"{METHOD_NAME}_0"}) is None + result = helper.wait_for_condition(get_node_index, GENERAL_WAIT) + Report.result(Tests.method_removed, result) + + # 9) Close Asset Editor + general.close_pane("Asset Editor") + general.close_pane("Script Canvas") + + +if __name__ == "__main__": + import ImportPathHelper as imports + + imports.init() + from utils import Report + + Report.start_test(ScriptEvent_AddRemoveMethod_UpdatesInSC) diff --git a/AutomatedTesting/Gem/PythonTests/scripting/TestSuite_Periodic.py b/AutomatedTesting/Gem/PythonTests/scripting/TestSuite_Periodic.py index 9180c1b44c..5f3d89c276 100755 --- a/AutomatedTesting/Gem/PythonTests/scripting/TestSuite_Periodic.py +++ b/AutomatedTesting/Gem/PythonTests/scripting/TestSuite_Periodic.py @@ -278,6 +278,7 @@ class TestScriptCanvasTests(object): }, ], ) + def test_Pane_PropertiesChanged_RetainsOnRestart(self, request, editor, config, project, launcher_platform): hydra.launch_and_validate_results( request, @@ -289,3 +290,30 @@ class TestScriptCanvasTests(object): auto_test_mode=False, timeout=60, ) + + def test_ScriptEvent_AddRemoveMethod_UpdatesInSC(self, request, workspace, editor, launcher_platform): + def teardown(): + file_system.delete( + [os.path.join(workspace.paths.project(), "TestAssets", "test_file.scriptevents")], True, True + ) + request.addfinalizer(teardown) + file_system.delete( + [os.path.join(workspace.paths.project(), "TestAssets", "test_file.scriptevents")], True, True + ) + expected_lines = [ + "Success: New Script Event created", + "Success: Initial Child Event created", + "Success: Second Child Event created", + "Success: Script event file saved", + "Success: Method added to scriptevent file", + "Success: Method removed from scriptevent file", + ] + hydra.launch_and_validate_results( + request, + TEST_DIRECTORY, + editor, + "ScriptEvent_AddRemoveMethod_UpdatesInSC.py", + expected_lines, + auto_test_mode=False, + timeout=60, + ) \ No newline at end of file From f8d320e79a678365eb4ca04e27f0d4ca44d1b17c Mon Sep 17 00:00:00 2001 From: balibhan Date: Mon, 24 May 2021 11:29:12 +0530 Subject: [PATCH 07/16] updated with new line --- .../Gem/PythonTests/scripting/TestSuite_Periodic.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/AutomatedTesting/Gem/PythonTests/scripting/TestSuite_Periodic.py b/AutomatedTesting/Gem/PythonTests/scripting/TestSuite_Periodic.py index 5f3d89c276..85d0b4523f 100755 --- a/AutomatedTesting/Gem/PythonTests/scripting/TestSuite_Periodic.py +++ b/AutomatedTesting/Gem/PythonTests/scripting/TestSuite_Periodic.py @@ -316,4 +316,5 @@ class TestScriptCanvasTests(object): expected_lines, auto_test_mode=False, timeout=60, - ) \ No newline at end of file + ) + \ No newline at end of file From d615441bbfc68aaa3c83c04d5db249a392eff0e3 Mon Sep 17 00:00:00 2001 From: balibhan Date: Mon, 24 May 2021 12:30:17 +0530 Subject: [PATCH 08/16] updated summary --- .../scripting/ScriptEvent_AddRemoveMethod_UpdatesInSC.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/AutomatedTesting/Gem/PythonTests/scripting/ScriptEvent_AddRemoveMethod_UpdatesInSC.py b/AutomatedTesting/Gem/PythonTests/scripting/ScriptEvent_AddRemoveMethod_UpdatesInSC.py index 19f59cb4c9..21ad40014e 100644 --- a/AutomatedTesting/Gem/PythonTests/scripting/ScriptEvent_AddRemoveMethod_UpdatesInSC.py +++ b/AutomatedTesting/Gem/PythonTests/scripting/ScriptEvent_AddRemoveMethod_UpdatesInSC.py @@ -24,10 +24,10 @@ class Tests(): def ScriptEvent_AddRemoveMethod_UpdatesInSC(): """ Summary: - Script Event file can be created + Method can be added/removed to an existing .scriptevents file Expected Behavior: - File is created without any errors and warnings in Console + The Method is correctly added/removed to the asset, and Script Canvas nodes are updated accordingly. Test Steps: 1) Open Asset Editor and Script Canvas windows From 26c55514d5cb1d8b7352b53d570f9c3458b98f8e Mon Sep 17 00:00:00 2001 From: scottr Date: Mon, 24 May 2021 09:27:03 -0700 Subject: [PATCH 09/16] [ext_project_packaging_fix] replaced incorrect usage of CMAKE_SOURCE_DIR with CMAKE_CURRENT_SOURCE_DIR in cmake packaging scripts --- cmake/Packaging.cmake | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cmake/Packaging.cmake b/cmake/Packaging.cmake index ba610b1883..fbeffa94eb 100644 --- a/cmake/Packaging.cmake +++ b/cmake/Packaging.cmake @@ -29,15 +29,15 @@ string(TOLOWER ${PROJECT_NAME} _project_name_lower) set(CPACK_PACKAGE_FILE_NAME "${_project_name_lower}_${LY_VERSION_STRING}_installer") set(DEFAULT_LICENSE_NAME "Apache-2.0") -set(DEFAULT_LICENSE_FILE "${CMAKE_SOURCE_DIR}/LICENSE.txt") +set(DEFAULT_LICENSE_FILE "${CMAKE_CURRENT_SOURCE_DIR}/LICENSE.txt") set(CPACK_RESOURCE_FILE_LICENSE ${DEFAULT_LICENSE_FILE}) set(CPACK_LICENSE_URL ${LY_INSTALLER_LICENSE_URL}) set(CPACK_PACKAGE_INSTALL_DIRECTORY "${CPACK_PACKAGE_VENDOR}/${CPACK_PACKAGE_VERSION}") -# CMAKE_SOURCE_DIR doesn't equate to anything during execution of pre/post build scripts -set(CPACK_SOURCE_DIR ${CMAKE_SOURCE_DIR}/cmake) +# neither of the SOURCE_DIR variables equate to anything during execution of pre/post build scripts +set(CPACK_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/cmake) # attempt to apply platform specific settings ly_get_absolute_pal_filename(pal_dir ${CPACK_SOURCE_DIR}/Platform/${PAL_HOST_PLATFORM_NAME}) From d4bad61f9a73f5ab930266a14d99a184c7ef3961 Mon Sep 17 00:00:00 2001 From: rgba16f <82187279+rgba16f@users.noreply.github.com> Date: Mon, 24 May 2021 16:49:00 -0500 Subject: [PATCH 10/16] DebugDraw gem fixes for Atom (#885) * Work in progress on adapting the DebugDraw gem to use AzFramework::DebugDisplayRequests API * Cleanup fixes for DebugDisplayRequestBus & DebugDraw gem. Remove SandboxIntegration implementation of the DebugDisplayRequestBus Add DrawWireCylinder & DrawWireCone to the DebugDisplayRequestBus interface Remove SetFillMode & DrawTexture functions from the DebugDisplayRequestBus interface Fixup uses of the SetFillMode api, replace with new Draw[Wire|Solid]X functions. Fixes to the DebugDraw gem to get it compiling with new warnings settings. * Changes to get the DebugDraw gem working with Atom/RHI/Code/Include/Atom/RHI Add GetWidth, GetHeight, GetDepth utility accessors to RHI::Viewport Start cleaning out unnecessary Cry includes from DebugDraw gem Fixes for AtomFont FFont.cpp 3d screen aligned text drawing. Clean out no longer supported code for 3d text to render multiple strings for the same entity location * Cleanup some unused or commented code * Update with PR feedback from Nick Van Sickle --- .../Entity/EntityDebugDisplayBus.h | 11 +- .../Manipulators/ManipulatorView.cpp | 19 +- .../ViewportSelection/EditorHelpers.cpp | 6 +- .../SandboxIntegration.cpp | 677 ------------------ .../SandboxIntegration.h | 65 -- .../Code/Include/Atom/RHI.Reflect/Viewport.h | 19 + .../AtomDebugDisplayViewportInterface.cpp | 48 +- .../AtomDebugDisplayViewportInterface.h | 7 +- .../AtomFont/Code/Source/FFont.cpp | 11 +- Gems/DebugDraw/Code/CMakeLists.txt | 6 + .../Code/Source/DebugDrawObbComponent.h | 5 +- .../Code/Source/DebugDrawSystemComponent.cpp | 180 ++--- .../Code/Source/DebugDrawSystemComponent.h | 30 +- .../Code/Source/DebugDraw_precompiled.h | 3 - 14 files changed, 180 insertions(+), 907 deletions(-) diff --git a/Code/Framework/AzFramework/AzFramework/Entity/EntityDebugDisplayBus.h b/Code/Framework/AzFramework/AzFramework/Entity/EntityDebugDisplayBus.h index fb6b8d7d72..c3a60f7ec3 100644 --- a/Code/Framework/AzFramework/AzFramework/Entity/EntityDebugDisplayBus.h +++ b/Code/Framework/AzFramework/AzFramework/Entity/EntityDebugDisplayBus.h @@ -60,6 +60,7 @@ namespace AzFramework virtual void DrawTrianglesIndexed(const AZStd::vector& vertices, const AZStd::vector& indices, const AZ::Color& color) { (void)vertices; (void)indices, (void)color; } virtual void DrawWireBox(const AZ::Vector3& min, const AZ::Vector3& max) { (void)min; (void)max; } virtual void DrawSolidBox(const AZ::Vector3& min, const AZ::Vector3& max) { (void)min; (void)max; } + virtual void DrawWireOBB(const AZ::Vector3& center, const AZ::Vector3& axisX, const AZ::Vector3& axisY, const AZ::Vector3& axisZ, const AZ::Vector3& halfExtents) { (void)center; (void)axisX; (void)axisY; (void)axisZ; (void)halfExtents; } virtual void DrawSolidOBB(const AZ::Vector3& center, const AZ::Vector3& axisX, const AZ::Vector3& axisY, const AZ::Vector3& axisZ, const AZ::Vector3& halfExtents) { (void)center; (void)axisX; (void)axisY; (void)axisZ; (void)halfExtents; } virtual void DrawPoint(const AZ::Vector3& p, int nSize = 1) { (void)p; (void)nSize; } virtual void DrawLine(const AZ::Vector3& p1, const AZ::Vector3& p2) { (void)p1; (void)p2; } @@ -70,18 +71,15 @@ namespace AzFramework virtual void DrawLine2d(const AZ::Vector2& p1, const AZ::Vector2& p2, float z) { (void)p1; (void)p2; (void)z; } virtual void DrawLine2dGradient(const AZ::Vector2& p1, const AZ::Vector2& p2, float z, const AZ::Vector4& firstColor, const AZ::Vector4& secondColor) { (void)p1; (void)p2; (void)z; (void)firstColor; (void)secondColor; } virtual void DrawWireCircle2d(const AZ::Vector2& center, float radius, float z) { (void)center; (void)radius; (void)z; } - virtual void DrawTerrainCircle(const AZ::Vector3& worldPos, float radius, float height) { (void)worldPos; (void)radius; (void)height; } - virtual void DrawTerrainCircle(const AZ::Vector3& center, float radius, float angle1, float angle2, float height) { (void)center; (void)radius; (void)angle1; (void)angle2; (void)height; } virtual void DrawArc(const AZ::Vector3& pos, float radius, float startAngleDegrees, float sweepAngleDegrees, float angularStepDegrees, int referenceAxis = 2) { (void)pos; (void)radius; (void)startAngleDegrees; (void)sweepAngleDegrees; (void)angularStepDegrees; (void)referenceAxis; } virtual void DrawArc(const AZ::Vector3& pos, float radius, float startAngleDegrees, float sweepAngleDegrees, float angularStepDegrees, const AZ::Vector3& fixedAxis) { (void)pos; (void)radius; (void)startAngleDegrees; (void)sweepAngleDegrees; (void)angularStepDegrees; (void)fixedAxis; } virtual void DrawCircle(const AZ::Vector3& pos, float radius, int nUnchangedAxis = 2 /*z axis*/) { (void)pos; (void)radius; (void)nUnchangedAxis; } virtual void DrawHalfDottedCircle(const AZ::Vector3& pos, float radius, const AZ::Vector3& viewPos, int nUnchangedAxis = 2 /*z axis*/) { (void)pos; (void)radius; (void)viewPos; (void)nUnchangedAxis; } - virtual void DrawCone(const AZ::Vector3& pos, const AZ::Vector3& dir, float radius, float height, bool drawShaded = true) { (void)pos; (void)dir; (void)radius; (void)height; (void)drawShaded; } + virtual void DrawWireCone(const AZ::Vector3& pos, const AZ::Vector3& dir, float radius, float height) { (void)pos; (void)dir; (void)radius; (void)height; } + virtual void DrawSolidCone(const AZ::Vector3& pos, const AZ::Vector3& dir, float radius, float height, bool drawShaded = true) { (void)pos; (void)dir; (void)radius; (void)height; (void)drawShaded; } virtual void DrawWireCylinder(const AZ::Vector3& center, const AZ::Vector3& axis, float radius, float height) { (void)center; (void)axis; (void)radius; (void)height; } virtual void DrawSolidCylinder(const AZ::Vector3& center, const AZ::Vector3& axis, float radius, float height, bool drawShaded = true) { (void)center; (void)axis; (void)radius; (void)height; (void)drawShaded; } virtual void DrawWireCapsule(const AZ::Vector3& center, const AZ::Vector3& axis, float radius, float heightStraightSection) { (void)center; (void)axis; (void)radius; (void)heightStraightSection; } - virtual void DrawTerrainRect(float x1, float y1, float x2, float y2, float height) { (void)x1; (void)y1; (void)x2; (void)y2; (void)height; } - virtual void DrawTerrainLine(AZ::Vector3 worldPos1, AZ::Vector3 worldPos2) { (void)worldPos1; (void)worldPos2; } virtual void DrawWireSphere(const AZ::Vector3& pos, float radius) { (void)pos; (void)radius; } virtual void DrawWireSphere(const AZ::Vector3& pos, const AZ::Vector3 radius) { (void)pos; (void)radius; } virtual void DrawWireDisk(const AZ::Vector3& pos, const AZ::Vector3& dir, float radius) { (void)pos; (void)dir; (void)radius; } @@ -91,11 +89,8 @@ namespace AzFramework virtual void DrawTextLabel(const AZ::Vector3& pos, float size, const char* text, const bool bCenter = false, int srcOffsetX = 0, int srcOffsetY = 0) { (void)pos; (void)size; (void)text; (void)bCenter; (void)srcOffsetX; (void)srcOffsetY; } virtual void Draw2dTextLabel(float x, float y, float size, const char* text, bool bCenter = false) { (void)x; (void)y; (void)size; (void)text; (void)bCenter; } virtual void DrawTextOn2DBox(const AZ::Vector3& pos, const char* text, float textScale, const AZ::Vector4& TextColor, const AZ::Vector4& TextBackColor) { (void)pos; (void)text; (void)textScale; (void)TextColor; (void)TextBackColor; } - virtual void DrawTextureLabel(ITexture* texture, const AZ::Vector3& pos, float sizeX, float sizeY, int texIconFlags) { (void)texture; (void)pos; (void)sizeX; (void)sizeY; (void)texIconFlags; } - virtual void DrawTextureLabel(int textureId, const AZ::Vector3& pos, float sizeX, float sizeY, int texIconFlags) { (void)textureId; (void)pos; (void)sizeX; (void)sizeY; (void)texIconFlags; } virtual void SetLineWidth(float width) { (void)width; } virtual bool IsVisible(const AZ::Aabb& bounds) { (void)bounds; return false; } - virtual int SetFillMode(int nFillMode) { (void)nFillMode; return 0; } virtual float GetLineWidth() { return 0.0f; } virtual float GetAspectRatio() { return 0.0f; } virtual void DepthTestOff() {} diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/ManipulatorView.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/ManipulatorView.cpp index ce151f2078..150e23041d 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/ManipulatorView.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/ManipulatorView.cpp @@ -447,17 +447,14 @@ namespace AzToolsFramework m_radius * viewScale); debugDisplay.SetColor(ViewColor(manipulatorState.m_mouseOver, m_color, m_mouseOverColor).GetAsVector4()); - - // show wireframe if the axis has been corrected/flipped - // note: please see IRenderAuxGeom.h for the definition of e_FillModeWireframe and e_FillModeSolid. - // it is not possible to include IRenderAuxGeom from here and we also don't want to introduce that dependency. - // these legacy enums should be wrapped so set SetFillMode can be used in a type safe way, until then, - // use the values directly until the API has been updated. - const AZ::u32 prevFillMode = debugDisplay.SetFillMode( - m_shouldCorrect ? /*e_FillModeWireframe =*/ 0x1 << 26 : /*e_FillModeSolid =*/ 0); - - debugDisplay.DrawCone(coneBound.m_base, coneBound.m_axis, coneBound.m_radius, coneBound.m_height, false); - debugDisplay.SetFillMode(prevFillMode); + if (m_shouldCorrect) + { + debugDisplay.DrawWireCone(coneBound.m_base, coneBound.m_axis, coneBound.m_radius, coneBound.m_height); + } + else + { + debugDisplay.DrawSolidCone(coneBound.m_base, coneBound.m_axis, coneBound.m_radius, coneBound.m_height, false); + } RefreshBoundInternal(managerId, manipulatorId, coneBound); } diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorHelpers.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorHelpers.cpp index d649e036ee..5c62a2997b 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorHelpers.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorHelpers.cpp @@ -233,9 +233,9 @@ namespace AzToolsFramework }(); debugDisplay.SetColor(iconHighlight); - debugDisplay.DrawTextureLabel( - iconTextureId, entityPosition, iconSize, iconSize, - /*DisplayContext::ETextureIconFlags::TEXICON_ON_TOP=*/ 0x0008); + // debugDisplay.DrawTextureLabel( + // iconTextureId, entityPosition, iconSize, iconSize, + // /*DisplayContext::ETextureIconFlags::TEXICON_ON_TOP=*/ 0x0008); } } } diff --git a/Code/Sandbox/Plugins/ComponentEntityEditorPlugin/SandboxIntegration.cpp b/Code/Sandbox/Plugins/ComponentEntityEditorPlugin/SandboxIntegration.cpp index d36c20c56a..884e1f9e51 100644 --- a/Code/Sandbox/Plugins/ComponentEntityEditorPlugin/SandboxIntegration.cpp +++ b/Code/Sandbox/Plugins/ComponentEntityEditorPlugin/SandboxIntegration.cpp @@ -382,11 +382,6 @@ void SandboxIntegrationManager::Teardown() { AzToolsFramework::Layers::EditorLayerComponentNotificationBus::Handler::BusDisconnect(); AzFramework::DisplayContextRequestBus::Handler::BusDisconnect(); - if( m_debugDisplayBusImplementationActive) - { - AzFramework::DebugDisplayRequestBus::Handler::BusDisconnect(); - m_debugDisplayBusImplementationActive = false; - } AzToolsFramework::SliceEditorEntityOwnershipServiceNotificationBus::Handler::BusDisconnect(); AzToolsFramework::EditorEntityContextNotificationBus::Handler::BusDisconnect(); AzToolsFramework::EditorEvents::Bus::Handler::BusDisconnect(); @@ -2041,678 +2036,6 @@ void SandboxIntegrationManager::BrowseForAssets(AssetSelectionModel& selection) AssetBrowserComponentRequestBus::Broadcast(&AssetBrowserComponentRequests::PickAssets, selection, GetMainWindow()); } -void SandboxIntegrationManager::SetColor(float r, float g, float b, float a) -{ - if (m_dc) - { - m_dc->SetColor(Vec3(r, g, b), a); - } -} - -void SandboxIntegrationManager::SetColor(const AZ::Color& color) -{ - if (m_dc) - { - m_dc->SetColor(AZColorToLYColorF(color)); - } -} - -void SandboxIntegrationManager::SetColor(const AZ::Vector4& color) -{ - if (m_dc) - { - m_dc->SetColor(AZVec3ToLYVec3(color.GetAsVector3()), color.GetW()); - } -} - -void SandboxIntegrationManager::SetAlpha(float a) -{ - if (m_dc) - { - m_dc->SetAlpha(a); - } -} - -void SandboxIntegrationManager::DrawQuad(const AZ::Vector3& p1, const AZ::Vector3& p2, const AZ::Vector3& p3, const AZ::Vector3& p4) -{ - if (m_dc) - { - m_dc->DrawQuad( - AZVec3ToLYVec3(p1), - AZVec3ToLYVec3(p2), - AZVec3ToLYVec3(p3), - AZVec3ToLYVec3(p4)); - } -} - -void SandboxIntegrationManager::DrawQuad(float width, float height) -{ - if (m_dc) - { - m_dc->DrawQuad(width, height); - } -} - -void SandboxIntegrationManager::DrawWireQuad(const AZ::Vector3& p1, const AZ::Vector3& p2, const AZ::Vector3& p3, const AZ::Vector3& p4) -{ - if (m_dc) - { - m_dc->DrawWireQuad( - AZVec3ToLYVec3(p1), - AZVec3ToLYVec3(p2), - AZVec3ToLYVec3(p3), - AZVec3ToLYVec3(p4)); - } -} - -void SandboxIntegrationManager::DrawWireQuad(float width, float height) -{ - if (m_dc) - { - m_dc->DrawWireQuad(width, height); - } -} - -void SandboxIntegrationManager::DrawQuadGradient(const AZ::Vector3& p1, const AZ::Vector3& p2, const AZ::Vector3& p3, const AZ::Vector3& p4, const AZ::Vector4& firstColor, const AZ::Vector4& secondColor) -{ - if (m_dc) - { - m_dc->DrawQuadGradient( - AZVec3ToLYVec3(p1), - AZVec3ToLYVec3(p2), - AZVec3ToLYVec3(p3), - AZVec3ToLYVec3(p4), - ColorF(AZVec3ToLYVec3(firstColor.GetAsVector3()), firstColor.GetW()), - ColorF(AZVec3ToLYVec3(secondColor.GetAsVector3()), secondColor.GetW())); - } -} - -void SandboxIntegrationManager::DrawTri(const AZ::Vector3& p1, const AZ::Vector3& p2, const AZ::Vector3& p3) -{ - if (m_dc) - { - m_dc->DrawTri( - AZVec3ToLYVec3(p1), - AZVec3ToLYVec3(p2), - AZVec3ToLYVec3(p3)); - } -} - -void SandboxIntegrationManager::DrawTriangles(const AZStd::vector& vertices, const AZ::Color& color) -{ - if (m_dc) - { - // transform to world space - const auto vecTransform = [this](const AZ::Vector3& vec) - { - return m_dc->GetMatrix() * AZVec3ToLYVec3(vec); - }; - - AZStd::vector cryVertices; - cryVertices.reserve(vertices.size()); - AZStd::transform(vertices.begin(), vertices.end(), AZStd::back_inserter(cryVertices), vecTransform); - m_dc->DrawTriangles( - cryVertices, - AZColorToLYColorF(color)); - } -} - -void SandboxIntegrationManager::DrawTrianglesIndexed(const AZStd::vector& vertices, const AZStd::vector& indices, const AZ::Color& color) -{ - if (m_dc) - { - // transform to world space - const auto vecTransform = [this](const AZ::Vector3& vec) - { - return m_dc->GetMatrix() * AZVec3ToLYVec3(vec); - }; - - AZStd::vector cryVertices; - cryVertices.reserve(vertices.size()); - AZStd::transform(vertices.begin(), vertices.end(), AZStd::back_inserter(cryVertices), vecTransform); - m_dc->DrawTrianglesIndexed( - cryVertices, - indices, - AZColorToLYColorF(color)); - } -} - -void SandboxIntegrationManager::DrawWireBox(const AZ::Vector3& min, const AZ::Vector3& max) -{ - if (m_dc) - { - m_dc->DrawWireBox( - AZVec3ToLYVec3(min), - AZVec3ToLYVec3(max)); - } -} - -void SandboxIntegrationManager::DrawSolidBox(const AZ::Vector3& min, const AZ::Vector3& max) -{ - if (m_dc) - { - m_dc->DrawSolidBox( - AZVec3ToLYVec3(min), - AZVec3ToLYVec3(max)); - } -} - -void SandboxIntegrationManager::DrawSolidOBB(const AZ::Vector3& center, const AZ::Vector3& axisX, const AZ::Vector3& axisY, const AZ::Vector3& axisZ, const AZ::Vector3& halfExtents) -{ - if (m_dc) - { - m_dc->DrawSolidOBB(AZVec3ToLYVec3(center), AZVec3ToLYVec3(axisX), AZVec3ToLYVec3(axisY), AZVec3ToLYVec3(axisZ), AZVec3ToLYVec3(halfExtents)); - } -} - -void SandboxIntegrationManager::DrawPoint(const AZ::Vector3& p, int nSize) -{ - if (m_dc) - { - m_dc->DrawPoint(AZVec3ToLYVec3(p), nSize); - } -} - -void SandboxIntegrationManager::DrawLine(const AZ::Vector3& p1, const AZ::Vector3& p2) -{ - if (m_dc) - { - m_dc->DrawLine( - AZVec3ToLYVec3(p1), - AZVec3ToLYVec3(p2)); - } -} - -void SandboxIntegrationManager::DrawLine(const AZ::Vector3& p1, const AZ::Vector3& p2, const AZ::Vector4& col1, const AZ::Vector4& col2) -{ - if (m_dc) - { - m_dc->DrawLine( - AZVec3ToLYVec3(p1), - AZVec3ToLYVec3(p2), - ColorF(AZVec3ToLYVec3(col1.GetAsVector3()), col1.GetW()), - ColorF(AZVec3ToLYVec3(col2.GetAsVector3()), col2.GetW())); - } -} - -void SandboxIntegrationManager::DrawLines(const AZStd::vector& lines, const AZ::Color& color) -{ - if (m_dc) - { - // transform to world space - const auto vecTransform = [this](const AZ::Vector3& vec) - { - return m_dc->GetMatrix() * AZVec3ToLYVec3(vec); - }; - - AZStd::vector cryLines; - cryLines.reserve(cryLines.size()); - AZStd::transform(lines.begin(), lines.end(), AZStd::back_inserter(cryLines), vecTransform); - m_dc->DrawLines(cryLines, AZColorToLYColorF(color)); - } -} - -void SandboxIntegrationManager::DrawPolyLine(const AZ::Vector3* pnts, int numPoints, bool cycled) -{ - if (m_dc) - { - Vec3* points = new Vec3[numPoints]; - for (int i = 0; i < numPoints; ++i) - { - points[i] = AZVec3ToLYVec3(pnts[i]); - } - - m_dc->DrawPolyLine(points, numPoints, cycled); - - delete[] points; - } -} - -void SandboxIntegrationManager::DrawWireQuad2d(const AZ::Vector2& p1, const AZ::Vector2& p2, float z) -{ - if (m_dc) - { - m_dc->DrawWireQuad2d( - QPoint(static_cast(p1.GetX()), static_cast(p1.GetY())), - QPoint(static_cast(p2.GetX()), static_cast(p2.GetY())), - z); - } -} - -void SandboxIntegrationManager::DrawLine2d(const AZ::Vector2& p1, const AZ::Vector2& p2, float z) -{ - if (m_dc) - { - m_dc->DrawLine2d( - QPoint(static_cast(p1.GetX()), static_cast(p1.GetY())), - QPoint(static_cast(p2.GetX()), static_cast(p2.GetY())), - z); - } -} - -void SandboxIntegrationManager::DrawLine2dGradient(const AZ::Vector2& p1, const AZ::Vector2& p2, float z, const AZ::Vector4& firstColor, const AZ::Vector4& secondColor) -{ - if (m_dc) - { - m_dc->DrawLine2dGradient( - QPoint(static_cast(p1.GetX()), static_cast(p1.GetY())), - QPoint(static_cast(p2.GetX()), static_cast(p2.GetY())), - z, - ColorF(AZVec3ToLYVec3(firstColor.GetAsVector3()), firstColor.GetW()), - ColorF(AZVec3ToLYVec3(secondColor.GetAsVector3()), secondColor.GetW())); - } -} - -void SandboxIntegrationManager::DrawWireCircle2d(const AZ::Vector2& center, float radius, float z) -{ - if (m_dc) - { - m_dc->DrawWireCircle2d( - QPoint(static_cast(center.GetX()), static_cast(center.GetY())), - radius, z); - } -} - -void SandboxIntegrationManager::DrawTerrainCircle(const AZ::Vector3& worldPos, float radius, float height) -{ - if (m_dc) - { - m_dc->DrawTerrainCircle( - AZVec3ToLYVec3(worldPos), radius, height); - } -} - -void SandboxIntegrationManager::DrawTerrainCircle(const AZ::Vector3& center, float radius, float angle1, float angle2, float height) -{ - if (m_dc) - { - m_dc->DrawTerrainCircle( - AZVec3ToLYVec3(center), radius, angle1, angle2, height); - } -} - -void SandboxIntegrationManager::DrawArc(const AZ::Vector3& pos, float radius, float startAngleDegrees, float sweepAngleDegrees, float angularStepDegrees, int referenceAxis) -{ - if (m_dc) - { - m_dc->DrawArc( - AZVec3ToLYVec3(pos), - radius, - startAngleDegrees, - sweepAngleDegrees, - angularStepDegrees, - referenceAxis); - } -} - -void SandboxIntegrationManager::DrawArc(const AZ::Vector3& pos, float radius, float startAngleDegrees, float sweepAngleDegrees, float angularStepDegrees, const AZ::Vector3& fixedAxis) -{ - if (m_dc) - { - m_dc->DrawArc( - AZVec3ToLYVec3(pos), - radius, - startAngleDegrees, - sweepAngleDegrees, - angularStepDegrees, - AZVec3ToLYVec3(fixedAxis)); - } -} - -void SandboxIntegrationManager::DrawCircle(const AZ::Vector3& pos, float radius, int nUnchangedAxis) -{ - if (m_dc) - { - m_dc->DrawCircle( - AZVec3ToLYVec3(pos), - radius, - nUnchangedAxis); - } -} - -void SandboxIntegrationManager::DrawHalfDottedCircle(const AZ::Vector3& pos, float radius, const AZ::Vector3& viewPos, int nUnchangedAxis) -{ - if (m_dc) - { - m_dc->DrawHalfDottedCircle( - AZVec3ToLYVec3(pos), - radius, - AZVec3ToLYVec3(viewPos), - nUnchangedAxis); - } -} - -void SandboxIntegrationManager::DrawCone(const AZ::Vector3& pos, const AZ::Vector3& dir, float radius, float height, bool drawShaded) -{ - if (m_dc) - { - m_dc->DrawCone( - AZVec3ToLYVec3(pos), - AZVec3ToLYVec3(dir), - radius, - height, - drawShaded); - } -} - -void SandboxIntegrationManager::DrawWireCylinder(const AZ::Vector3& center, const AZ::Vector3& axis, float radius, float height) -{ - if (m_dc) - { - m_dc->DrawWireCylinder( - AZVec3ToLYVec3(center), - AZVec3ToLYVec3(axis), - radius, - height); - } -} - -void SandboxIntegrationManager::DrawSolidCylinder(const AZ::Vector3& center, const AZ::Vector3& axis, float radius, float height, bool drawShaded) -{ - if (m_dc) - { - m_dc->DrawSolidCylinder( - AZVec3ToLYVec3(center), - AZVec3ToLYVec3(axis), - radius, - height, - drawShaded); - } -} - -void SandboxIntegrationManager::DrawWireCapsule(const AZ::Vector3& center, const AZ::Vector3& axis, float radius, float height) -{ - if (m_dc) - { - m_dc->DrawWireCapsule( - AZVec3ToLYVec3(center), - AZVec3ToLYVec3(axis), - radius, - height); - } -} - -void SandboxIntegrationManager::DrawTerrainRect(float x1, float y1, float x2, float y2, float height) -{ - if (m_dc) - { - m_dc->DrawTerrainRect(x1, y1, x2, y2, height); - } -} - -void SandboxIntegrationManager::DrawTerrainLine(AZ::Vector3 worldPos1, AZ::Vector3 worldPos2) -{ - if (m_dc) - { - m_dc->DrawTerrainLine( - AZVec3ToLYVec3(worldPos1), - AZVec3ToLYVec3(worldPos2)); - } -} - -void SandboxIntegrationManager::DrawWireSphere(const AZ::Vector3& pos, float radius) -{ - if (m_dc) - { - m_dc->DrawWireSphere(AZVec3ToLYVec3(pos), radius); - } -} - -void SandboxIntegrationManager::DrawWireSphere(const AZ::Vector3& pos, const AZ::Vector3 radius) -{ - if (m_dc) - { - m_dc->DrawWireSphere( - AZVec3ToLYVec3(pos), - AZVec3ToLYVec3(radius)); - } -} - -void SandboxIntegrationManager::DrawWireDisk(const AZ::Vector3& pos, const AZ::Vector3& dir, float radius) -{ - if (m_dc) - { - m_dc->DrawWireDisk( - AZVec3ToLYVec3(pos), - AZVec3ToLYVec3(dir), - radius); - } -} - -void SandboxIntegrationManager::DrawBall(const AZ::Vector3& pos, float radius, bool drawShaded) -{ - if (m_dc) - { - m_dc->DrawBall(AZVec3ToLYVec3(pos), radius, drawShaded); - } -} - -void SandboxIntegrationManager::DrawDisk(const AZ::Vector3& pos, const AZ::Vector3& dir, float radius) -{ - if (m_dc) - { - m_dc->DrawDisk( - AZVec3ToLYVec3(pos), - AZVec3ToLYVec3(dir), - radius); - } -} - -void SandboxIntegrationManager::DrawArrow(const AZ::Vector3& src, const AZ::Vector3& trg, float fHeadScale, bool b2SidedArrow) -{ - if (m_dc) - { - m_dc->DrawArrow( - AZVec3ToLYVec3(src), - AZVec3ToLYVec3(trg), - fHeadScale, - b2SidedArrow); - } -} - -void SandboxIntegrationManager::DrawTextLabel(const AZ::Vector3& pos, float size, const char* text, const bool bCenter, int srcOffsetX, int srcOffsetY) -{ - if (m_dc) - { - m_dc->DrawTextLabel( - AZVec3ToLYVec3(pos), - size, - text, - bCenter, - srcOffsetX, - srcOffsetY); - } -} - -void SandboxIntegrationManager::Draw2dTextLabel(float x, float y, float size, const char* text, bool bCenter) -{ - if (m_dc) - { - m_dc->Draw2dTextLabel(x, y, size, text, bCenter); - } -} - -void SandboxIntegrationManager::DrawTextureLabel(ITexture* texture, const AZ::Vector3& pos, float sizeX, float sizeY, int texIconFlags) -{ - if (m_dc) - { - if (texture) - { - float textureWidth = aznumeric_caster(texture->GetWidth()); - float textureHeight = aznumeric_caster(texture->GetHeight()); - - // resize the label in proportion to the actual texture size - if (textureWidth > textureHeight) - { - sizeY = sizeX * (textureHeight / textureWidth); - } - else - { - sizeX = sizeY * (textureWidth / textureHeight); - } - - m_dc->DrawTextureLabel(AZVec3ToLYVec3(pos), sizeX, sizeY, texture->GetTextureID(), texIconFlags); - } - } -} - -void SandboxIntegrationManager::DrawTextureLabel(int textureId, const AZ::Vector3& pos, float sizeX, float sizeY, int texIconFlags) -{ - // ToDo: With Atom? - AZ_UNUSED(textureId); - AZ_UNUSED(pos); - AZ_UNUSED(sizeX); - AZ_UNUSED(sizeY); - AZ_UNUSED(texIconFlags); -} - -void SandboxIntegrationManager::SetLineWidth(float width) -{ - if (m_dc) - { - m_dc->SetLineWidth(width); - } -} - -bool SandboxIntegrationManager::IsVisible(const AZ::Aabb& bounds) -{ - if (m_dc) - { - const AABB aabb( - AZVec3ToLYVec3(bounds.GetMin()), - AZVec3ToLYVec3(bounds.GetMax())); - - return m_dc->IsVisible(aabb); - } - - return 0; -} - -int SandboxIntegrationManager::SetFillMode(int nFillMode) -{ - if (m_dc) - { - return m_dc->SetFillMode(nFillMode); - } - - return 0; -} - -float SandboxIntegrationManager::GetLineWidth() -{ - if (m_dc) - { - return m_dc->GetLineWidth(); - } - - return 0.f; -} - -float SandboxIntegrationManager::GetAspectRatio() -{ - if (m_dc && m_dc->GetView()) - { - return m_dc->GetView()->GetAspectRatio(); - } - - return 0.f; -} - -void SandboxIntegrationManager::DepthTestOff() -{ - if (m_dc) - { - m_dc->DepthTestOff(); - } -} - -void SandboxIntegrationManager::DepthTestOn() -{ - if (m_dc) - { - m_dc->DepthTestOn(); - } -} - -void SandboxIntegrationManager::DepthWriteOff() -{ - if (m_dc) - { - m_dc->DepthWriteOff(); - } -} - -void SandboxIntegrationManager::DepthWriteOn() -{ - if (m_dc) - { - m_dc->DepthWriteOn(); - } -} - -void SandboxIntegrationManager::CullOff() -{ - if (m_dc) - { - m_dc->CullOff(); - } -} - -void SandboxIntegrationManager::CullOn() -{ - if (m_dc) - { - m_dc->CullOn(); - } -} - -bool SandboxIntegrationManager::SetDrawInFrontMode(bool bOn) -{ - if (m_dc) - { - return m_dc->SetDrawInFrontMode(bOn); - } - - return 0.f; -} - -AZ::u32 SandboxIntegrationManager::GetState() -{ - if (m_dc) - { - return m_dc->GetState(); - } - - return 0; -} - -AZ::u32 SandboxIntegrationManager::SetState(AZ::u32 state) -{ - if (m_dc) - { - return m_dc->SetState(state); - } - - return 0; -} - -void SandboxIntegrationManager::PushMatrix(const AZ::Transform& tm) -{ - if (m_dc) - { - const Matrix34 m = AZTransformToLYTransform(tm); - m_dc->PushMatrix(m); - } -} - -void SandboxIntegrationManager::PopMatrix() -{ - if (m_dc) - { - m_dc->PopMatrix(); - } -} - bool SandboxIntegrationManager::DisplayHelpersVisible() { return GetIEditor()->GetDisplaySettings()->IsDisplayHelpers(); diff --git a/Code/Sandbox/Plugins/ComponentEntityEditorPlugin/SandboxIntegration.h b/Code/Sandbox/Plugins/ComponentEntityEditorPlugin/SandboxIntegration.h index 528b93e44e..6d714b67df 100644 --- a/Code/Sandbox/Plugins/ComponentEntityEditorPlugin/SandboxIntegration.h +++ b/Code/Sandbox/Plugins/ComponentEntityEditorPlugin/SandboxIntegration.h @@ -100,7 +100,6 @@ class SandboxIntegrationManager , private AzToolsFramework::EditorEvents::Bus::Handler , private AzToolsFramework::EditorWindowRequests::Bus::Handler , private AzFramework::AssetCatalogEventBus::Handler - , private AzFramework::DebugDisplayRequestBus::Handler , private AzFramework::DisplayContextRequestBus::Handler , private AzToolsFramework::EditorEntityContextNotificationBus::Handler , private AzToolsFramework::SliceEditorEntityOwnershipServiceNotificationBus::Handler @@ -202,70 +201,6 @@ private: const AzFramework::SliceInstantiationTicket& ticket) override; ////////////////////////////////////////////////////////////////////////// - // AzToolsFramework::DebugDisplayRequestBus - void SetColor(float r, float g, float b, float a) override; - void SetColor(const AZ::Color& color) override; - void SetColor(const AZ::Vector4& color) override; - void SetAlpha(float a) override; - void DrawQuad(const AZ::Vector3& p1, const AZ::Vector3& p2, const AZ::Vector3& p3, const AZ::Vector3& p4) override; - void DrawQuad(float width, float height) override; - void DrawWireQuad(const AZ::Vector3& p1, const AZ::Vector3& p2, const AZ::Vector3& p3, const AZ::Vector3& p4) override; - void DrawWireQuad(float width, float height) override; - void DrawQuadGradient(const AZ::Vector3& p1, const AZ::Vector3& p2, const AZ::Vector3& p3, const AZ::Vector3& p4, const AZ::Vector4& firstColor, const AZ::Vector4& secondColor) override; - void DrawTri(const AZ::Vector3& p1, const AZ::Vector3& p2, const AZ::Vector3& p3) override; - void DrawTriangles(const AZStd::vector& vertices, const AZ::Color& color) override; - void DrawTrianglesIndexed(const AZStd::vector& vertices, const AZStd::vector& indices, const AZ::Color& color) override; - void DrawWireBox(const AZ::Vector3& min, const AZ::Vector3& max) override; - void DrawSolidBox(const AZ::Vector3& min, const AZ::Vector3& max) override; - void DrawSolidOBB(const AZ::Vector3& center, const AZ::Vector3& axisX, const AZ::Vector3& axisY, const AZ::Vector3& axisZ, const AZ::Vector3& halfExtents) override; - void DrawPoint(const AZ::Vector3& p, int nSize) override; - void DrawLine(const AZ::Vector3& p1, const AZ::Vector3& p2) override; - void DrawLine(const AZ::Vector3& p1, const AZ::Vector3& p2, const AZ::Vector4& col1, const AZ::Vector4& col2) override; - void DrawLines(const AZStd::vector& lines, const AZ::Color& color) override; - void DrawPolyLine(const AZ::Vector3* pnts, int numPoints, bool cycled) override; - void DrawWireQuad2d(const AZ::Vector2& p1, const AZ::Vector2& p2, float z) override; - void DrawLine2d(const AZ::Vector2& p1, const AZ::Vector2& p2, float z) override; - void DrawLine2dGradient(const AZ::Vector2& p1, const AZ::Vector2& p2, float z, const AZ::Vector4& firstColor, const AZ::Vector4& secondColor) override; - void DrawWireCircle2d(const AZ::Vector2& center, float radius, float z) override; - void DrawTerrainCircle(const AZ::Vector3& worldPos, float radius, float height) override; - void DrawTerrainCircle(const AZ::Vector3& center, float radius, float angle1, float angle2, float height) override; - void DrawArc(const AZ::Vector3& pos, float radius, float startAngleDegrees, float sweepAngleDegrees, float angularStepDegrees, int referenceAxis) override; - void DrawArc(const AZ::Vector3& pos, float radius, float startAngleDegrees, float sweepAngleDegrees, float angularStepDegrees, const AZ::Vector3& fixedAxis) override; - void DrawCone(const AZ::Vector3& pos, const AZ::Vector3& dir, float radius, float height, bool drawShaded = true) override; - void DrawCircle(const AZ::Vector3& pos, float radius, int nUnchangedAxis) override; - void DrawHalfDottedCircle(const AZ::Vector3& pos, float radius, const AZ::Vector3& viewPos, int nUnchangedAxis) override; - void DrawWireCylinder(const AZ::Vector3& center, const AZ::Vector3& axis, float radius, float height) override; - void DrawSolidCylinder(const AZ::Vector3& center, const AZ::Vector3& axis, float radius, float height, bool drawShaded = true) override; - void DrawWireCapsule(const AZ::Vector3& center, const AZ::Vector3& axis, float radius, float height) override; - void DrawTerrainRect(float x1, float y1, float x2, float y2, float height) override; - void DrawTerrainLine(AZ::Vector3 worldPos1, AZ::Vector3 worldPos2) override; - void DrawWireSphere(const AZ::Vector3& pos, float radius) override; - void DrawWireSphere(const AZ::Vector3& pos, const AZ::Vector3 radius) override; - void DrawWireDisk(const AZ::Vector3& pos, const AZ::Vector3& dir, float radius) override; - void DrawBall(const AZ::Vector3& pos, float radius, bool drawShaded = true) override; - void DrawDisk(const AZ::Vector3& pos, const AZ::Vector3& dir, float radius) override; - void DrawArrow(const AZ::Vector3& src, const AZ::Vector3& trg, float fHeadScale, bool b2SidedArrow) override; - void DrawTextLabel(const AZ::Vector3& pos, float size, const char* text, const bool bCenter, int srcOffsetX, int scrOffsetY) override; - void Draw2dTextLabel(float x, float y, float size, const char* text, bool bCenter) override; - void DrawTextureLabel(ITexture* texture, const AZ::Vector3& pos, float sizeX, float sizeY, int texIconFlags) override; - void DrawTextureLabel(int textureId, const AZ::Vector3& pos, float sizeX, float sizeY, int texIconFlags) override; - void SetLineWidth(float width) override; - bool IsVisible(const AZ::Aabb& bounds) override; - int SetFillMode(int nFillMode) override; - float GetLineWidth() override; - float GetAspectRatio() override; - void DepthTestOff() override; - void DepthTestOn() override; - void DepthWriteOff() override; - void DepthWriteOn() override; - void CullOff() override; - void CullOn() override; - bool SetDrawInFrontMode(bool bOn) override; - AZ::u32 GetState() override; - AZ::u32 SetState(AZ::u32 state) override; - void PushMatrix(const AZ::Transform& tm) override; - void PopMatrix() override; - // AzFramework::DisplayContextRequestBus (and @deprecated EntityDebugDisplayRequestBus) // AzFramework::DisplayContextRequestBus void SetDC(DisplayContext* dc) override; diff --git a/Gems/Atom/RHI/Code/Include/Atom/RHI.Reflect/Viewport.h b/Gems/Atom/RHI/Code/Include/Atom/RHI.Reflect/Viewport.h index 8b95df52a1..4a4559c382 100644 --- a/Gems/Atom/RHI/Code/Include/Atom/RHI.Reflect/Viewport.h +++ b/Gems/Atom/RHI/Code/Include/Atom/RHI.Reflect/Viewport.h @@ -51,6 +51,25 @@ namespace AZ float m_maxY = 0.0f; float m_minZ = 0.0f; float m_maxZ = 1.0f; + + float GetWidth() const; + float GetHeight() const; + float GetDepth() const; }; } // namespace RHI } // namespace AZ + +inline float AZ::RHI::Viewport::GetWidth() const +{ + return m_maxX - m_minX; +} + +inline float AZ::RHI::Viewport::GetHeight() const +{ + return m_maxY - m_minY; +} + +inline float AZ::RHI::Viewport::GetDepth() const +{ + return m_maxZ - m_minZ; +} diff --git a/Gems/AtomLyIntegration/AtomBridge/Code/Source/AtomDebugDisplayViewportInterface.cpp b/Gems/AtomLyIntegration/AtomBridge/Code/Source/AtomDebugDisplayViewportInterface.cpp index 482bd21972..6c68618f78 100644 --- a/Gems/AtomLyIntegration/AtomBridge/Code/Source/AtomDebugDisplayViewportInterface.cpp +++ b/Gems/AtomLyIntegration/AtomBridge/Code/Source/AtomDebugDisplayViewportInterface.cpp @@ -576,6 +576,29 @@ namespace AZ::AtomBridge } } + void AtomDebugDisplayViewportInterface::DrawWireOBB( + const AZ::Vector3& center, + const AZ::Vector3& axisX, + const AZ::Vector3& axisY, + const AZ::Vector3& axisZ, + const AZ::Vector3& halfExtents) + { + if (m_auxGeomPtr) + { + AZ::Quaternion rotation = AZ::Quaternion::CreateFromMatrix3x3(AZ::Matrix3x3::CreateFromColumns(axisX, axisY, axisZ)); + AZ::Obb obb = AZ::Obb::CreateFromPositionRotationAndHalfLengths(center, rotation, halfExtents); + m_auxGeomPtr->DrawObb( + obb, + AZ::Vector3::CreateZero(), + m_rendState.m_color, + AZ::RPI::AuxGeomDraw::DrawStyle::Line, + m_rendState.m_depthTest, + m_rendState.m_depthWrite, + m_rendState.m_faceCullMode, + m_rendState.m_viewProjOverrideIndex); + } + } + void AtomDebugDisplayViewportInterface::DrawSolidOBB( const AZ::Vector3& center, const AZ::Vector3& axisX, @@ -906,7 +929,28 @@ namespace AZ::AtomBridge } } - void AtomDebugDisplayViewportInterface::DrawCone(const AZ::Vector3& pos, const AZ::Vector3& dir, float radius, float height, bool drawShaded) + void AtomDebugDisplayViewportInterface::DrawWireCone(const AZ::Vector3& pos, const AZ::Vector3& dir, float radius, float height) + { + if (m_auxGeomPtr) + { + const AZ::Vector3 worldPos = ToWorldSpacePosition(pos); + const AZ::Vector3 worldDir = ToWorldSpaceVector(dir); + m_auxGeomPtr->DrawCone( + worldPos, + worldDir, + radius, + height, + m_rendState.m_color, + AZ::RPI::AuxGeomDraw::DrawStyle::Line, + m_rendState.m_depthTest, + m_rendState.m_depthWrite, + m_rendState.m_faceCullMode, + m_rendState.m_viewProjOverrideIndex + ); + } + } + + void AtomDebugDisplayViewportInterface::DrawSolidCone(const AZ::Vector3& pos, const AZ::Vector3& dir, float radius, float height, bool drawShaded) { if (m_auxGeomPtr) { @@ -1336,8 +1380,6 @@ namespace AZ::AtomBridge { AZ_Assert(false, "Unexpected use of legacy api, please file a feature request with the rendering team to get this implemented!"); } - // unhandledled on Atom - virtual void DrawTextureLabel(ITexture* texture, const AZ::Vector3& pos, float sizeX, float sizeY, int texIconFlags) override; - // void AtomDebugDisplayViewportInterface::DrawTextureLabel(int textureId, const AZ::Vector3& pos, float sizeX, float sizeY, int texIconFlags) override; void AtomDebugDisplayViewportInterface::SetLineWidth(float width) { diff --git a/Gems/AtomLyIntegration/AtomBridge/Code/Source/AtomDebugDisplayViewportInterface.h b/Gems/AtomLyIntegration/AtomBridge/Code/Source/AtomDebugDisplayViewportInterface.h index 18d280ef88..69d0fc6d96 100644 --- a/Gems/AtomLyIntegration/AtomBridge/Code/Source/AtomDebugDisplayViewportInterface.h +++ b/Gems/AtomLyIntegration/AtomBridge/Code/Source/AtomDebugDisplayViewportInterface.h @@ -153,6 +153,7 @@ namespace AZ::AtomBridge void DrawTrianglesIndexed(const AZStd::vector& vertices, const AZStd::vector& indices, const AZ::Color& color) override; void DrawWireBox(const AZ::Vector3& min, const AZ::Vector3& max) override; void DrawSolidBox(const AZ::Vector3& min, const AZ::Vector3& max) override; + void DrawWireOBB(const AZ::Vector3& center, const AZ::Vector3& axisX, const AZ::Vector3& axisY, const AZ::Vector3& axisZ, const AZ::Vector3& halfExtents) override; void DrawSolidOBB(const AZ::Vector3& center, const AZ::Vector3& axisX, const AZ::Vector3& axisY, const AZ::Vector3& axisZ, const AZ::Vector3& halfExtents) override; void DrawPoint(const AZ::Vector3& p, int nSize = 1) override; void DrawLine(const AZ::Vector3& p1, const AZ::Vector3& p2) override; @@ -167,7 +168,8 @@ namespace AZ::AtomBridge void DrawArc(const AZ::Vector3& pos, float radius, float startAngleDegrees, float sweepAngleDegrees, float angularStepDegrees, const AZ::Vector3& fixedAxis) override; void DrawCircle(const AZ::Vector3& pos, float radius, int nUnchangedAxis = 2 /*z axis*/) override; void DrawHalfDottedCircle(const AZ::Vector3& pos, float radius, const AZ::Vector3& viewPos, int nUnchangedAxis = 2 /*z axis*/) override; - void DrawCone(const AZ::Vector3& pos, const AZ::Vector3& dir, float radius, float height, bool drawShaded) override; + void DrawWireCone(const AZ::Vector3& pos, const AZ::Vector3& dir, float radius, float height) override; + void DrawSolidCone(const AZ::Vector3& pos, const AZ::Vector3& dir, float radius, float height, bool drawShaded) override; void DrawWireCylinder(const AZ::Vector3& center, const AZ::Vector3& axis, float radius, float height) override; void DrawSolidCylinder(const AZ::Vector3& center, const AZ::Vector3& axis, float radius, float height, bool drawShaded) override; void DrawWireCapsule(const AZ::Vector3& center, const AZ::Vector3& axis, float radius, float heightStraightSection) override; @@ -180,11 +182,8 @@ namespace AZ::AtomBridge void DrawTextLabel(const AZ::Vector3& pos, float size, const char* text, const bool bCenter = false, int srcOffsetX = 0, int srcOffsetY = 0) override; void Draw2dTextLabel(float x, float y, float size, const char* text, bool bCenter = false) override; void DrawTextOn2DBox(const AZ::Vector3& pos, const char* text, float textScale, const AZ::Vector4& TextColor, const AZ::Vector4& TextBackColor) override; - // unhandled on Atom - virtual void DrawTextureLabel(ITexture* texture, const AZ::Vector3& pos, float sizeX, float sizeY, int texIconFlags) override; - // void DrawTextureLabel(int textureId, const AZ::Vector3& pos, float sizeX, float sizeY, int texIconFlags) override; void SetLineWidth(float width) override; bool IsVisible(const AZ::Aabb& bounds) override; - // int SetFillMode(int nFillMode) override; float GetLineWidth() override; float GetAspectRatio() override; void DepthTestOff() override; diff --git a/Gems/AtomLyIntegration/AtomFont/Code/Source/FFont.cpp b/Gems/AtomLyIntegration/AtomFont/Code/Source/FFont.cpp index 21b57e0908..f8afaa7260 100644 --- a/Gems/AtomLyIntegration/AtomFont/Code/Source/FFont.cpp +++ b/Gems/AtomLyIntegration/AtomFont/Code/Source/FFont.cpp @@ -1786,18 +1786,17 @@ void AZ::FFont::DrawScreenAlignedText3d( } AZ::Vector3 positionNDC = AzFramework::WorldToScreenNDC( params.m_position, - currentView->GetViewToWorldMatrix(), + currentView->GetWorldToViewMatrix(), currentView->GetViewToClipMatrix() ); - AzFramework::TextDrawParameters param2d = params; - param2d.m_position = positionNDC; + internalParams.m_ctx.m_sizeIn800x600 = false; DrawStringUInternal( *internalParams.m_viewport, internalParams.m_viewportContext, - internalParams.m_position.GetX(), - internalParams.m_position.GetY(), - params.m_position.GetZ(), // Z + positionNDC.GetX() * internalParams.m_viewport->GetWidth(), + (1.0f - positionNDC.GetY()) * internalParams.m_viewport->GetHeight(), + positionNDC.GetZ(), // Z text.data(), params.m_multiline, internalParams.m_ctx diff --git a/Gems/DebugDraw/Code/CMakeLists.txt b/Gems/DebugDraw/Code/CMakeLists.txt index 5759cdaff2..0954d6366c 100644 --- a/Gems/DebugDraw/Code/CMakeLists.txt +++ b/Gems/DebugDraw/Code/CMakeLists.txt @@ -21,6 +21,9 @@ ly_add_target( Include BUILD_DEPENDENCIES PUBLIC + AZ::AtomCore + Gem::Atom_RPI.Public + Gem::Atom_Bootstrap.Headers Legacy::CryCommon ) @@ -51,6 +54,9 @@ if(PAL_TRAIT_BUILD_HOST_TOOLS) Source PUBLIC Include + COMPILE_DEFINITIONS + PRIVATE + DEBUGDRAW_GEM_EDITOR=1 BUILD_DEPENDENCIES PRIVATE Gem::DebugDraw.Static diff --git a/Gems/DebugDraw/Code/Source/DebugDrawObbComponent.h b/Gems/DebugDraw/Code/Source/DebugDrawObbComponent.h index 781786fc03..07436b577a 100644 --- a/Gems/DebugDraw/Code/Source/DebugDrawObbComponent.h +++ b/Gems/DebugDraw/Code/Source/DebugDrawObbComponent.h @@ -41,9 +41,8 @@ namespace DebugDraw , m_worldLocation(AZ::Vector3::CreateZero()) , m_owningEditorComponent(AZ::InvalidComponentId) , m_scale(AZ::Vector3(1.0f, 1.0f, 1.0f)) - { - m_obb.CreateFromPositionRotationAndHalfLengths(m_worldLocation, AZ::Quaternion::CreateIdentity(), AZ::Vector3::CreateOne()); - } + , m_obb(AZ::Obb::CreateFromPositionRotationAndHalfLengths(m_worldLocation, AZ::Quaternion::CreateIdentity(), AZ::Vector3::CreateOne())) + {} }; class DebugDrawObbComponent diff --git a/Gems/DebugDraw/Code/Source/DebugDrawSystemComponent.cpp b/Gems/DebugDraw/Code/Source/DebugDrawSystemComponent.cpp index 545dc7d2f9..1f677d7b6f 100644 --- a/Gems/DebugDraw/Code/Source/DebugDrawSystemComponent.cpp +++ b/Gems/DebugDraw/Code/Source/DebugDrawSystemComponent.cpp @@ -19,11 +19,6 @@ #include #include -#include - -#include -#include - #include "DebugDrawSystemComponent.h" // Editor specific @@ -37,6 +32,9 @@ #include #endif // DEBUGDRAW_GEM_EDITOR +#include +#include + namespace DebugDraw { void DebugDrawSystemComponent::Reflect(AZ::ReflectContext* context) @@ -96,7 +94,7 @@ namespace DebugDraw void DebugDrawSystemComponent::GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required) { - (void)required; + required.push_back(AZ_CRC("RPISystem", 0xf2add773)); } void DebugDrawSystemComponent::GetDependentServices(AZ::ComponentDescriptor::DependencyArrayType& dependent) @@ -112,7 +110,7 @@ namespace DebugDraw { DebugDrawInternalRequestBus::Handler::BusConnect(); DebugDrawRequestBus::Handler::BusConnect(); - AZ::TickBus::Handler::BusConnect(); + AZ::Render::Bootstrap::NotificationBus::Handler::BusConnect(); #ifdef DEBUGDRAW_GEM_EDITOR AzToolsFramework::EditorEntityContextNotificationBus::Handler::BusConnect(); @@ -125,7 +123,7 @@ namespace DebugDraw AzToolsFramework::EditorEntityContextNotificationBus::Handler::BusDisconnect(); #endif // DEBUGDRAW_GEM_EDITOR - AZ::TickBus::Handler::BusDisconnect(); + AZ::RPI::SceneNotificationBus::Handler::BusDisconnect(); DebugDrawRequestBus::Handler::BusDisconnect(); DebugDrawInternalRequestBus::Handler::BusDisconnect(); @@ -155,6 +153,13 @@ namespace DebugDraw } } + void DebugDrawSystemComponent::OnBootstrapSceneReady(AZ::RPI::Scene* scene) + { + AZ_Assert(scene, "Invalid scene received in OnBootstrapSceneReady"); + AZ::RPI::SceneNotificationBus::Handler::BusConnect(scene->GetId()); + AZ::Render::Bootstrap::NotificationBus::Handler::BusDisconnect(); + } + #ifdef DEBUGDRAW_GEM_EDITOR void DebugDrawSystemComponent::OnStopPlayInEditor() { @@ -255,16 +260,26 @@ namespace DebugDraw } #endif // DEBUGDRAW_GEM_EDITOR - void DebugDrawSystemComponent::OnTick([[maybe_unused]] float deltaTime, AZ::ScriptTimePoint time) + void DebugDrawSystemComponent::OnBeginPrepareRender() { + AZ::ScriptTimePoint time; + AZ::TickRequestBus::BroadcastResult(time, &AZ::TickRequestBus::Events::GetTimeAtCurrentTick); m_currentTime = time.GetSeconds(); - OnTickAabbs(); - OnTickLines(); - OnTickObbs(); - OnTickRays(); - OnTickSpheres(); - OnTickText(); + AzFramework::DebugDisplayRequestBus::BusPtr debugDisplayBus; + AzFramework::DebugDisplayRequestBus::Bind( + debugDisplayBus, AzFramework::g_defaultSceneEntityDebugDisplayId); + AZ_Assert(debugDisplayBus, "Invalid DebugDisplayRequestBus."); + + AzFramework::DebugDisplayRequests* debugDisplay = + AzFramework::DebugDisplayRequestBus::FindFirstHandler(debugDisplayBus); + + OnTickAabbs(*debugDisplay); + OnTickLines(*debugDisplay); + OnTickObbs(*debugDisplay); + OnTickRays(*debugDisplay); + OnTickSpheres(*debugDisplay); + OnTickText(*debugDisplay); } template @@ -277,7 +292,7 @@ namespace DebugDraw vectorToExpire.erase(removalCondition, std::end(vectorToExpire)); } - void DebugDrawSystemComponent::OnTickAabbs() + void DebugDrawSystemComponent::OnTickAabbs(AzFramework::DebugDisplayRequests& debugDisplay) { AZStd::lock_guard locker(m_activeAabbsMutex); @@ -295,17 +310,14 @@ namespace DebugDraw AZ::Vector3 currentCenter = transformedAabb.GetCenter(); transformedAabb.Set(transformedAabb.GetMin() - currentCenter + aabbElement.m_worldLocation, transformedAabb.GetMax() - currentCenter + aabbElement.m_worldLocation); } - - ColorB lyColor(aabbElement.m_color.ToU32()); - Vec3 worldLocation(AZVec3ToLYVec3(aabbElement.m_worldLocation)); - AABB lyAABB(AZAabbToLyAABB(transformedAabb)); - gEnv->pRenderer->GetIRenderAuxGeom()->DrawAABB(lyAABB, false, lyColor, EBoundingBoxDrawStyle::eBBD_Extremes_Color_Encoded); + debugDisplay.SetColor(aabbElement.m_color); + debugDisplay.DrawSolidBox(transformedAabb.GetMin(), transformedAabb.GetMax()); } removeExpiredDebugElementsFromVector(m_activeAabbs); } - void DebugDrawSystemComponent::OnTickLines() + void DebugDrawSystemComponent::OnTickLines(AzFramework::DebugDisplayRequests& debugDisplay) { AZStd::lock_guard locker(m_activeLinesMutex); size_t numActiveLines = m_activeLines.size(); @@ -339,26 +351,14 @@ namespace DebugDraw &AZ::TransformBus::Events::GetWorldTranslation); } - Vec3 start(AZVec3ToLYVec3(lineElement.m_startWorldLocation)); - Vec3 end(AZVec3ToLYVec3(lineElement.m_endWorldLocation)); - ColorB lyColor(lineElement.m_color.ToU32()); - - m_batchPoints.push_back(start); - m_batchPoints.push_back(end); - - m_batchColors.push_back(lyColor); - m_batchColors.push_back(lyColor); - } - - if (!m_batchPoints.empty()) - { - gEnv->pRenderer->GetIRenderAuxGeom()->DrawLines(m_batchPoints.begin(), m_batchPoints.size(), m_batchColors.begin(), 1.0f); + debugDisplay.SetColor(lineElement.m_color); + debugDisplay.DrawLine(lineElement.m_startWorldLocation, lineElement.m_endWorldLocation); } removeExpiredDebugElementsFromVector(m_activeLines); } - void DebugDrawSystemComponent::OnTickObbs() + void DebugDrawSystemComponent::OnTickObbs(AzFramework::DebugDisplayRequests& debugDisplay) { AZStd::lock_guard locker(m_activeObbsMutex); @@ -382,20 +382,18 @@ namespace DebugDraw transformedObb.SetHalfLength(i, obbElement.m_scale.GetElement(i)); } } - - obbElement.m_worldLocation = transformedObb.GetPosition(); - - ColorB lyColor(obbElement.m_color.ToU32()); - Vec3 worldLocation(AZVec3ToLYVec3(obbElement.m_worldLocation)); - OBB lyOBB(AZObbToLyOBB(transformedObb)); - lyOBB.c = Vec3(0.f); - gEnv->pRenderer->GetIRenderAuxGeom()->DrawOBB(lyOBB, worldLocation, false, lyColor, EBoundingBoxDrawStyle::eBBD_Extremes_Color_Encoded); + else + { + obbElement.m_worldLocation = transformedObb.GetPosition(); + } + debugDisplay.SetColor(obbElement.m_color); + debugDisplay.DrawSolidOBB(obbElement.m_worldLocation, transformedObb.GetAxisX(), transformedObb.GetAxisY(), transformedObb.GetAxisZ(), transformedObb.GetHalfLengths()); } removeExpiredDebugElementsFromVector(m_activeObbs); } - void DebugDrawSystemComponent::OnTickRays() + void DebugDrawSystemComponent::OnTickRays(AzFramework::DebugDisplayRequests& debugDisplay) { AZStd::lock_guard locker(m_activeRaysMutex); @@ -415,22 +413,20 @@ namespace DebugDraw rayElement.m_worldDirection = (endWorldLocation - rayElement.m_worldLocation); } - ColorB lyColor(rayElement.m_color.ToU32()); - Vec3 start(AZVec3ToLYVec3(rayElement.m_worldLocation)); - Vec3 end(AZVec3ToLYVec3(endWorldLocation)); - Vec3 direction(AZVec3ToLYVec3(rayElement.m_worldDirection)); float conePercentHeight = 0.5f; - float coneHeight = direction.GetLength() * conePercentHeight; - Vec3 coneBaseLocation = end - direction * conePercentHeight; + float coneHeight = rayElement.m_worldDirection.GetLength() * conePercentHeight; + AZ::Vector3 coneBaseLocation = endWorldLocation - rayElement.m_worldDirection * conePercentHeight; float coneRadius = AZ::GetClamp(coneHeight * 0.07f, 0.05f, 0.2f); - gEnv->pRenderer->GetIRenderAuxGeom()->DrawLine(start, lyColor, coneBaseLocation, lyColor, 5.0f); - gEnv->pRenderer->GetIRenderAuxGeom()->DrawCone(coneBaseLocation, direction, coneRadius, coneHeight, lyColor, false); + debugDisplay.SetColor(rayElement.m_color); + debugDisplay.SetLineWidth(5.0f); + debugDisplay.DrawLine(rayElement.m_worldLocation, coneBaseLocation); + debugDisplay.DrawSolidCone(coneBaseLocation, rayElement.m_worldDirection, coneRadius, coneHeight, false); } removeExpiredDebugElementsFromVector(m_activeRays); } - void DebugDrawSystemComponent::OnTickSpheres() + void DebugDrawSystemComponent::OnTickSpheres(AzFramework::DebugDisplayRequests& debugDisplay) { AZStd::lock_guard locker(m_activeSpheresMutex); @@ -442,19 +438,14 @@ namespace DebugDraw { AZ::TransformBus::EventResult(sphereElement.m_worldLocation, sphereElement.m_targetEntityId, &AZ::TransformBus::Events::GetWorldTranslation); } - - if (gEnv->pRenderer) - { - ColorB lyColor(sphereElement.m_color.ToU32()); - Vec3 worldLocation(AZVec3ToLYVec3(sphereElement.m_worldLocation)); - gEnv->pRenderer->GetIRenderAuxGeom()->DrawSphere(worldLocation, sphereElement.m_radius, lyColor, true); - } + debugDisplay.SetColor(sphereElement.m_color); + debugDisplay.DrawBall(sphereElement.m_worldLocation, sphereElement.m_radius, true); } removeExpiredDebugElementsFromVector(m_activeSpheres); } - void DebugDrawSystemComponent::OnTickText() + void DebugDrawSystemComponent::OnTickText(AzFramework::DebugDisplayRequests& debugDisplay) { AZStd::lock_guard locker(m_activeTextsMutex); @@ -471,30 +462,20 @@ namespace DebugDraw #endif // DEBUGDRAW_GEM_EDITOR // Draw text elements and remove any that are expired - AZStd::unordered_map textPerEntityCount; int numScreenTexts = 0; AZ::EntityId lastTargetEntityId; for (auto& textElement : m_activeTexts) { + const AZ::Color textColor = needsGammaConversion ? textElement.m_color.GammaToLinear() : textElement.m_color; + debugDisplay.SetColor(textColor); if (textElement.m_drawMode == DebugDrawTextElement::DrawMode::OnScreen) { - const AZ::Color textColor = needsGammaConversion ? textElement.m_color.GammaToLinear() : textElement.m_color; - gEnv->pRenderer->GetIRenderAuxGeom()->Draw3dLabel(Vec3(20.f, 20.f + ((float)numScreenTexts * 15.0f), 0.5f), 1.4f, AZColorToLYColorF(textColor), textElement.m_text.c_str()); + debugDisplay.Draw2dTextLabel(100.0f, 20.f + ((float)numScreenTexts * 15.0f), 1.4f, textElement.m_text.c_str() ); ++numScreenTexts; } else if (textElement.m_drawMode == DebugDrawTextElement::DrawMode::InWorld) { - SDrawTextInfo ti; - ti.xscale = ti.yscale = 1.4f; - ti.flags = eDrawText_2D | eDrawText_FixedSize | eDrawText_Monospace | eDrawText_Center; - - const AZ::Color textColor = needsGammaConversion ? textElement.m_color.GammaToLinear() : textElement.m_color; - ti.color[0] = textColor.GetR(); - ti.color[1] = textColor.GetG(); - ti.color[2] = textColor.GetB(); - ti.color[3] = textColor.GetA(); - AZ::Vector3 worldLocation; if (textElement.m_targetEntityId.IsValid()) { @@ -507,32 +488,7 @@ namespace DebugDraw worldLocation = textElement.m_worldLocation; } - const CCamera& camera = gEnv->pSystem->GetViewCamera(); - const AZ::Vector3 cameraTranslation = LYVec3ToAZVec3(camera.GetPosition()); - Vec3 lyWorldLoc = AZVec3ToLYVec3(worldLocation); - Vec3 screenPos(0.f); - if (camera.Project(lyWorldLoc, screenPos, Vec2i(0, 0), Vec2i(0, 0))) - { - // Handle spacing for world text so it doesn't draw on top of each other - // This works for text drawing on entities (considered one block), but not for world text. - // World text will get handled when we have screen-aware positioning of text elements - if (textElement.m_targetEntityId.IsValid()) - { - auto iter = textPerEntityCount.find(textElement.m_targetEntityId); - if (iter != textPerEntityCount.end()) - { - AZ::u32 count = iter->second; - screenPos.y += ((float)count * 15.0f); - iter->second = count + 1; - } - else - { - auto newEntry = textPerEntityCount.insert_key(textElement.m_targetEntityId); - newEntry.first->second = 1; - } - } - gEnv->pRenderer->GetIRenderAuxGeom()->Draw3dLabel(Vec3(screenPos.x, screenPos.y, 0.5f), 1.4f, AZColorToLYColorF(textColor), textElement.m_text.c_str()); - } + debugDisplay.DrawTextLabel(worldLocation, 1.4f, textElement.m_text.c_str() ); } } @@ -550,9 +506,9 @@ namespace DebugDraw CreateLineEntryForComponent(lineComponent->GetEntityId(), lineComponent->m_element); } #ifdef DEBUGDRAW_GEM_EDITOR - else if (EditorDebugDrawLineComponent* lineComponent = azrtti_cast(component)) + else if (EditorDebugDrawLineComponent* editorLineComponent = azrtti_cast(component)) { - CreateLineEntryForComponent(lineComponent->GetEntityId(), lineComponent->m_element); + CreateLineEntryForComponent(editorLineComponent->GetEntityId(), editorLineComponent->m_element); } #endif // DEBUGDRAW_GEM_EDITOR else if (DebugDrawRayComponent* rayComponent = azrtti_cast(component)) @@ -560,9 +516,9 @@ namespace DebugDraw CreateRayEntryForComponent(rayComponent->GetEntityId(), rayComponent->m_element); } #ifdef DEBUGDRAW_GEM_EDITOR - else if (EditorDebugDrawRayComponent* rayComponent = azrtti_cast(component)) + else if (EditorDebugDrawRayComponent* editorRayComponent = azrtti_cast(component)) { - CreateRayEntryForComponent(rayComponent->GetEntityId(), rayComponent->m_element); + CreateRayEntryForComponent(editorRayComponent->GetEntityId(), editorRayComponent->m_element); } #endif // DEBUGDRAW_GEM_EDITOR else if (DebugDrawSphereComponent* sphereComponent = azrtti_cast(component)) @@ -570,9 +526,9 @@ namespace DebugDraw CreateSphereEntryForComponent(sphereComponent->GetEntityId(), sphereComponent->m_element); } #ifdef DEBUGDRAW_GEM_EDITOR - else if (EditorDebugDrawSphereComponent* sphereComponent = azrtti_cast(component)) + else if (EditorDebugDrawSphereComponent* editorSphereComponent = azrtti_cast(component)) { - CreateSphereEntryForComponent(sphereComponent->GetEntityId(), sphereComponent->m_element); + CreateSphereEntryForComponent(editorSphereComponent->GetEntityId(), editorSphereComponent->m_element); } #endif // DEBUGDRAW_GEM_EDITOR else if (DebugDrawObbComponent* obbComponent = azrtti_cast(component)) @@ -581,9 +537,9 @@ namespace DebugDraw } #ifdef DEBUGDRAW_GEM_EDITOR - else if (EditorDebugDrawObbComponent* obbComponent = azrtti_cast(component)) + else if (EditorDebugDrawObbComponent* editorObbComponent = azrtti_cast(component)) { - CreateObbEntryForComponent(obbComponent->GetEntityId(), obbComponent->m_element); + CreateObbEntryForComponent(editorObbComponent->GetEntityId(), editorObbComponent->m_element); } #endif // DEBUGDRAW_GEM_EDITOR @@ -593,9 +549,9 @@ namespace DebugDraw } #ifdef DEBUGDRAW_GEM_EDITOR - else if (EditorDebugDrawTextComponent* textComponent = azrtti_cast(component)) + else if (EditorDebugDrawTextComponent* editorTextComponent = azrtti_cast(component)) { - CreateTextEntryForComponent(textComponent->GetEntityId(), textComponent->m_element); + CreateTextEntryForComponent(editorTextComponent->GetEntityId(), editorTextComponent->m_element); } #endif // DEBUGDRAW_GEM_EDITOR } diff --git a/Gems/DebugDraw/Code/Source/DebugDrawSystemComponent.h b/Gems/DebugDraw/Code/Source/DebugDrawSystemComponent.h index 32efa4cfc2..5ea02d7baa 100644 --- a/Gems/DebugDraw/Code/Source/DebugDrawSystemComponent.h +++ b/Gems/DebugDraw/Code/Source/DebugDrawSystemComponent.h @@ -32,6 +32,9 @@ #include #endif // DEBUGDRAW_GEM_EDITOR +#include +#include + namespace DebugDraw { // DebugDraw elements that don't have corresponding component representations yet @@ -61,10 +64,11 @@ namespace DebugDraw class DebugDrawSystemComponent : public AZ::Component - , public AZ::TickBus::Handler , public AZ::EntityBus::MultiHandler , protected DebugDrawRequestBus::Handler , protected DebugDrawInternalRequestBus::Handler + , public AZ::RPI::SceneNotificationBus::Handler + , public AZ::Render::Bootstrap::NotificationBus::Handler #ifdef DEBUGDRAW_GEM_EDITOR , protected AzToolsFramework::EditorEntityContextNotificationBus::Handler @@ -113,20 +117,22 @@ namespace DebugDraw void Activate() override; void Deactivate() override; - // TickBus - void OnTick(float deltaTime, AZ::ScriptTimePoint time) override; - int GetTickOrder() override { return AZ::ComponentTickBus::TICK_DEFAULT; } + // SceneNotificationBus + void OnBeginPrepareRender() override; + + // AZ::Render::Bootstrap::NotificationBus + void OnBootstrapSceneReady(AZ::RPI::Scene* scene); // EntityBus void OnEntityDeactivated(const AZ::EntityId& entityId) override; // Ticking functions for drawing debug elements - void OnTickAabbs(); - void OnTickLines(); - void OnTickObbs(); - void OnTickRays(); - void OnTickSpheres(); - void OnTickText(); + void OnTickAabbs(AzFramework::DebugDisplayRequests& debugDisplay); + void OnTickLines(AzFramework::DebugDisplayRequests& debugDisplay); + void OnTickObbs(AzFramework::DebugDisplayRequests& debugDisplay); + void OnTickRays(AzFramework::DebugDisplayRequests& debugDisplay); + void OnTickSpheres(AzFramework::DebugDisplayRequests& debugDisplay); + void OnTickText(AzFramework::DebugDisplayRequests& debugDisplay); // Element creation functions, used when DebugDraw components register themselves void CreateAabbEntryForComponent(const AZ::EntityId& componentEntityId, const DebugDrawAabbElement& element); @@ -154,7 +160,7 @@ namespace DebugDraw double m_currentTime; - AZStd::vector m_batchPoints; - AZStd::vector m_batchColors; + AZStd::vector m_batchPoints; + AZStd::vector m_batchColors; }; } diff --git a/Gems/DebugDraw/Code/Source/DebugDraw_precompiled.h b/Gems/DebugDraw/Code/Source/DebugDraw_precompiled.h index 3a14d45520..290082eb65 100644 --- a/Gems/DebugDraw/Code/Source/DebugDraw_precompiled.h +++ b/Gems/DebugDraw/Code/Source/DebugDraw_precompiled.h @@ -11,6 +11,3 @@ */ #pragma once - -#include // Many CryCommon files require that this is included first. -#include From 78451c58983f3e9347e0050d591d7b366b75d529 Mon Sep 17 00:00:00 2001 From: mnaumov Date: Mon, 24 May 2021 17:34:04 -0700 Subject: [PATCH 11/16] PR feedback --- .../Code/Source/Viewport/InputController/Behavior.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/InputController/Behavior.cpp b/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/InputController/Behavior.cpp index 5a671d53ef..877a3affb1 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/InputController/Behavior.cpp +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/InputController/Behavior.cpp @@ -121,6 +121,7 @@ namespace MaterialEditor float Behavior::GetSensitivityZ() { + // adjust zooming sensitivity by model size, so that large models zoom at the same speed as smaller ones return 0.001f * AZ::GetMax(0.5f, m_radius); } From 36c23b5d1a2a38edf0f1e2846879d1bd24676c8e Mon Sep 17 00:00:00 2001 From: Benjamin Jillich <43751992+amzn-jillich@users.noreply.github.com> Date: Tue, 25 May 2021 07:17:23 +0200 Subject: [PATCH 12/16] [LYN-2522] Filtering for gem catalog (#867) * Added sort filter proxy model for gem model that can filter based on name, gem origin, supported platform, features and/or types. * Added new filter pane on the left with several filter categories for gem origin, type, platform and feature. * Added filter category widget which is a collapsable generalized checkbox group that can interact with the proxy model and thus control filtering. * Removed fixed size of the project manager. The application should always be resizable. --- .../Source/GemCatalog/GemCatalogScreen.cpp | 22 +- .../Source/GemCatalog/GemCatalogScreen.h | 1 + .../Source/GemCatalog/GemFilterWidget.cpp | 412 ++++++++++++++++++ .../Source/GemCatalog/GemFilterWidget.h | 79 ++++ .../Source/GemCatalog/GemInfo.cpp | 13 + .../Source/GemCatalog/GemInfo.h | 11 + .../Source/GemCatalog/GemInspector.cpp | 4 +- .../Source/GemCatalog/GemItemDelegate.cpp | 16 +- .../Source/GemCatalog/GemItemDelegate.h | 22 +- .../Source/GemCatalog/GemListView.cpp | 10 +- .../Source/GemCatalog/GemListView.h | 6 +- .../Source/GemCatalog/GemModel.cpp | 66 ++- .../Source/GemCatalog/GemModel.h | 14 +- .../GemCatalog/GemSortFilterProxyModel.cpp | 133 ++++++ .../GemCatalog/GemSortFilterProxyModel.h | 68 +++ .../Source/ProjectManagerWindow.cpp | 2 - .../Source/ProjectManagerWindow.ui | 2 +- .../project_manager_files.cmake | 4 + 18 files changed, 826 insertions(+), 59 deletions(-) create mode 100644 Code/Tools/ProjectManager/Source/GemCatalog/GemFilterWidget.cpp create mode 100644 Code/Tools/ProjectManager/Source/GemCatalog/GemFilterWidget.h create mode 100644 Code/Tools/ProjectManager/Source/GemCatalog/GemSortFilterProxyModel.cpp create mode 100644 Code/Tools/ProjectManager/Source/GemCatalog/GemSortFilterProxyModel.h diff --git a/Code/Tools/ProjectManager/Source/GemCatalog/GemCatalogScreen.cpp b/Code/Tools/ProjectManager/Source/GemCatalog/GemCatalogScreen.cpp index 3c221d6055..bbc6099f24 100644 --- a/Code/Tools/ProjectManager/Source/GemCatalog/GemCatalogScreen.cpp +++ b/Code/Tools/ProjectManager/Source/GemCatalog/GemCatalogScreen.cpp @@ -12,6 +12,8 @@ #include #include +#include +#include #include #include #include @@ -25,15 +27,18 @@ namespace O3DE::ProjectManager : ScreenWidget(parent) { m_gemModel = new GemModel(this); + GemSortFilterProxyModel* proxyModel = new GemSortFilterProxyModel(m_gemModel, this); QVBoxLayout* vLayout = new QVBoxLayout(); vLayout->setMargin(0); + vLayout->setSpacing(0); setLayout(vLayout); QHBoxLayout* hLayout = new QHBoxLayout(); + hLayout->setMargin(0); vLayout->addLayout(hLayout); - m_gemListView = new GemListView(m_gemModel, this); + m_gemListView = new GemListView(proxyModel, proxyModel->GetSelectionModel(), this); m_gemInspector = new GemInspector(m_gemModel, this); m_gemInspector->setFixedWidth(320); @@ -56,8 +61,19 @@ namespace O3DE::ProjectManager } #endif - hLayout->addWidget(m_gemListView); + GemFilterWidget* filterWidget = new GemFilterWidget(proxyModel); + filterWidget->setFixedWidth(250); + + QVBoxLayout* middleVLayout = new QVBoxLayout(); + middleVLayout->setMargin(0); + middleVLayout->setSpacing(0); + middleVLayout->addWidget(m_gemListView); + + hLayout->addWidget(filterWidget); + hLayout->addLayout(middleVLayout); hLayout->addWidget(m_gemInspector); + + proxyModel->InvalidateFilter(); } QVector GemCatalogScreen::GenerateTestData() @@ -73,10 +89,12 @@ namespace O3DE::ProjectManager gem.m_documentationLink = "http://www.amazon.com"; gem.m_dependingGemUuids = QStringList({"EMotionFX", "Atom"}); gem.m_conflictingGemUuids = QStringList({"Vegetation", "Camera", "ScriptCanvas", "CloudCanvas", "Networking"}); + gem.m_types = (GemInfo::Code | GemInfo::Asset); gem.m_version = "v1.01"; gem.m_lastUpdatedDate = "24th April 2021"; gem.m_binarySizeInKB = 40; gem.m_features = QStringList({"Animation", "Assets", "Physics"}); + gem.m_gemOrigin = GemInfo::O3DEFoundation; result.push_back(gem); gem.m_name = "Atom"; diff --git a/Code/Tools/ProjectManager/Source/GemCatalog/GemCatalogScreen.h b/Code/Tools/ProjectManager/Source/GemCatalog/GemCatalogScreen.h index 6a9c88d0f5..bf4202499f 100644 --- a/Code/Tools/ProjectManager/Source/GemCatalog/GemCatalogScreen.h +++ b/Code/Tools/ProjectManager/Source/GemCatalog/GemCatalogScreen.h @@ -9,6 +9,7 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * */ + #pragma once #if !defined(Q_MOC_RUN) diff --git a/Code/Tools/ProjectManager/Source/GemCatalog/GemFilterWidget.cpp b/Code/Tools/ProjectManager/Source/GemCatalog/GemFilterWidget.cpp new file mode 100644 index 0000000000..c6651b7295 --- /dev/null +++ b/Code/Tools/ProjectManager/Source/GemCatalog/GemFilterWidget.cpp @@ -0,0 +1,412 @@ +/* +* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or +* its licensors. +* +* For complete copyright and license terms please see the LICENSE at the root of this +* distribution (the "License"). All use of this software is governed by the License, +* or, if provided, by the license below or the license accompanying this file. Do not +* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace O3DE::ProjectManager +{ + FilterCategoryWidget::FilterCategoryWidget(const QString& header, + const QVector& elementNames, + const QVector& elementCounts, + bool showAllLessButton, + int defaultShowCount, + QWidget* parent) + : QWidget(parent) + , m_defaultShowCount(defaultShowCount) + { + AZ_Assert(elementNames.size() == elementCounts.size(), "Number of element names needs to match the counts."); + + QVBoxLayout* vLayout = new QVBoxLayout(); + setLayout(vLayout); + + // Collapse button + QHBoxLayout* collapseLayout = new QHBoxLayout(); + m_collapseButton = new QPushButton(); + m_collapseButton->setCheckable(true); + m_collapseButton->setFlat(true); + m_collapseButton->setFocusPolicy(Qt::NoFocus); + m_collapseButton->setFixedWidth(s_collapseButtonSize); + m_collapseButton->setStyleSheet("border: 0px; border-radius: 0px;"); + connect(m_collapseButton, &QPushButton::clicked, this, [=]() + { + UpdateCollapseState(); + }); + collapseLayout->addWidget(m_collapseButton); + + // Category title + QLabel* headerLabel = new QLabel(header); + headerLabel->setStyleSheet("font-size: 11pt;"); + collapseLayout->addWidget(headerLabel); + vLayout->addLayout(collapseLayout); + + vLayout->addSpacing(5); + + // Everything in the main widget will be collapsed/uncollapsed + { + m_mainWidget = new QWidget(); + vLayout->addWidget(m_mainWidget); + + QVBoxLayout* mainLayout = new QVBoxLayout(); + mainLayout->setMargin(0); + mainLayout->setAlignment(Qt::AlignTop); + m_mainWidget->setLayout(mainLayout); + + // Elements + m_buttonGroup = new QButtonGroup(); + m_buttonGroup->setExclusive(false); + for (int i = 0; i < elementNames.size(); ++i) + { + QWidget* elementWidget = new QWidget(); + QHBoxLayout* elementLayout = new QHBoxLayout(); + elementLayout->setMargin(0); + elementWidget->setLayout(elementLayout); + + QCheckBox* checkbox = new QCheckBox(elementNames[i]); + checkbox->setStyleSheet("font-size: 11pt;"); + m_buttonGroup->addButton(checkbox); + elementLayout->addWidget(checkbox); + + elementLayout->addSpacerItem(new QSpacerItem(0, 0, QSizePolicy::Expanding)); + + QLabel* countLabel = new QLabel(QString::number(elementCounts[i])); + countLabel->setStyleSheet("font-size: 11pt; background-color: #333333; border-radius: 3px; color: #94D2FF;"); + elementLayout->addWidget(countLabel); + + m_elementWidgets.push_back(elementWidget); + mainLayout->addWidget(elementWidget); + } + + // See more / less + if (showAllLessButton) + { + m_seeAllLessLabel = new LinkLabel(); + connect(m_seeAllLessLabel, &LinkLabel::clicked, this, [=]() + { + m_seeAll = !m_seeAll; + UpdateSeeMoreLess(); + }); + mainLayout->addWidget(m_seeAllLessLabel); + } + else + { + mainLayout->addSpacing(5); + } + } + + // Separating line + QFrame* hLine = new QFrame(); + hLine->setFrameShape(QFrame::HLine); + hLine->setStyleSheet("color: #666666;"); + vLayout->addWidget(hLine); + + UpdateCollapseState(); + UpdateSeeMoreLess(); + } + + void FilterCategoryWidget::UpdateCollapseState() + { + if (m_collapseButton->isChecked()) + { + m_collapseButton->setIcon(QIcon(":/Resources/ArrowDownLine.svg")); + m_mainWidget->hide(); + } + else + { + m_collapseButton->setIcon(QIcon(":/Resources/ArrowUpLine.svg")); + m_mainWidget->show(); + } + } + + void FilterCategoryWidget::UpdateSeeMoreLess() + { + if (!m_seeAllLessLabel) + { + return; + } + + if (m_elementWidgets.isEmpty()) + { + m_seeAllLessLabel->hide(); + return; + } + else + { + m_seeAllLessLabel->show(); + } + + if (!m_seeAll) + { + m_seeAllLessLabel->setText("See all"); + } + else + { + m_seeAllLessLabel->setText("See less"); + } + + int showCount = m_seeAll ? m_elementWidgets.size() : m_defaultShowCount; + showCount = AZ::GetMin(showCount, m_elementWidgets.size()); + for (int i = 0; i < showCount; ++i) + { + m_elementWidgets[i]->show(); + } + for (int i = showCount; i < m_elementWidgets.size(); ++i) + { + m_elementWidgets[i]->hide(); + } + } + + QButtonGroup* FilterCategoryWidget::GetButtonGroup() + { + return m_buttonGroup; + } + + GemFilterWidget::GemFilterWidget(GemSortFilterProxyModel* filterProxyModel, QWidget* parent) + : QScrollArea(parent) + , m_filterProxyModel(filterProxyModel) + { + m_gemModel = m_filterProxyModel->GetSourceModel(); + + setWidgetResizable(true); + setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded); + + QWidget* mainWidget = new QWidget(); + setWidget(mainWidget); + + m_mainLayout = new QVBoxLayout(); + m_mainLayout->setAlignment(Qt::AlignTop); + mainWidget->setLayout(m_mainLayout); + + QLabel* filterByLabel = new QLabel("Filter by"); + filterByLabel->setStyleSheet("font-size: 15pt;"); + m_mainLayout->addWidget(filterByLabel); + + AddGemOriginFilter(); + AddTypeFilter(); + AddPlatformFilter(); + AddFeatureFilter(); + } + + void GemFilterWidget::AddGemOriginFilter() + { + QVector elementNames; + QVector elementCounts; + const int numGems = m_gemModel->rowCount(); + for (int originIndex = 0; originIndex < GemInfo::NumGemOrigins; ++originIndex) + { + const GemInfo::GemOrigin gemOriginToBeCounted = static_cast(1 << originIndex); + + int gemOriginCount = 0; + for (int gemIndex = 0; gemIndex < numGems; ++gemIndex) + { + const GemInfo::GemOrigin gemOrigin = m_gemModel->GetGemOrigin(m_gemModel->index(gemIndex, 0)); + + // Is the gem of the given origin? + if (gemOriginToBeCounted == gemOrigin) + { + gemOriginCount++; + } + } + + elementNames.push_back(GemInfo::GetGemOriginString(gemOriginToBeCounted)); + elementCounts.push_back(gemOriginCount); + } + + FilterCategoryWidget* filterWidget = new FilterCategoryWidget("Provider", elementNames, elementCounts, /*showAllLessButton=*/false); + m_mainLayout->addWidget(filterWidget); + + const QList buttons = filterWidget->GetButtonGroup()->buttons(); + for (int i = 0; i < buttons.size(); ++i) + { + const GemInfo::GemOrigin gemOrigin = static_cast(1 << i); + QAbstractButton* button = buttons[i]; + + connect(button, &QAbstractButton::toggled, this, [=](bool checked) + { + GemInfo::GemOrigins gemOrigins = m_filterProxyModel->GetGemOrigins(); + if (checked) + { + gemOrigins |= gemOrigin; + } + else + { + gemOrigins &= ~gemOrigin; + } + m_filterProxyModel->SetGemOrigins(gemOrigins); + }); + } + } + + void GemFilterWidget::AddTypeFilter() + { + QVector elementNames; + QVector elementCounts; + const int numGems = m_gemModel->rowCount(); + for (int typeIndex = 0; typeIndex < GemInfo::NumTypes; ++typeIndex) + { + const GemInfo::Type type = static_cast(1 << typeIndex); + + int typeGemCount = 0; + for (int gemIndex = 0; gemIndex < numGems; ++gemIndex) + { + const GemInfo::Types types = m_gemModel->GetTypes(m_gemModel->index(gemIndex, 0)); + + // Is type (Asset, Code, Tool) part of the gem? + if (types & type) + { + typeGemCount++; + } + } + + elementNames.push_back(GemInfo::GetTypeString(type)); + elementCounts.push_back(typeGemCount); + } + + FilterCategoryWidget* filterWidget = new FilterCategoryWidget("Type", elementNames, elementCounts, /*showAllLessButton=*/false); + m_mainLayout->addWidget(filterWidget); + + const QList buttons = filterWidget->GetButtonGroup()->buttons(); + for (int i = 0; i < buttons.size(); ++i) + { + const GemInfo::Type type = static_cast(1 << i); + QAbstractButton* button = buttons[i]; + + connect(button, &QAbstractButton::toggled, this, [=](bool checked) + { + GemInfo::Types types = m_filterProxyModel->GetTypes(); + if (checked) + { + types |= type; + } + else + { + types &= ~type; + } + m_filterProxyModel->SetTypes(types); + }); + } + } + + void GemFilterWidget::AddPlatformFilter() + { + QVector elementNames; + QVector elementCounts; + const int numGems = m_gemModel->rowCount(); + for (int platformIndex = 0; platformIndex < GemInfo::NumPlatforms; ++platformIndex) + { + const GemInfo::Platform platform = static_cast(1 << platformIndex); + + int platformGemCount = 0; + for (int gemIndex = 0; gemIndex < numGems; ++gemIndex) + { + const GemInfo::Platforms platforms = m_gemModel->GetPlatforms(m_gemModel->index(gemIndex, 0)); + + // Is platform supported? + if (platforms & platform) + { + platformGemCount++; + } + } + + elementNames.push_back(GemInfo::GetPlatformString(platform)); + elementCounts.push_back(platformGemCount); + } + + FilterCategoryWidget* filterWidget = new FilterCategoryWidget("Supported Platforms", elementNames, elementCounts, /*showAllLessButton=*/false); + m_mainLayout->addWidget(filterWidget); + + const QList buttons = filterWidget->GetButtonGroup()->buttons(); + for (int i = 0; i < buttons.size(); ++i) + { + const GemInfo::Platform platform = static_cast(1 << i); + QAbstractButton* button = buttons[i]; + + connect(button, &QAbstractButton::toggled, this, [=](bool checked) + { + GemInfo::Platforms platforms = m_filterProxyModel->GetPlatforms(); + if (checked) + { + platforms |= platform; + } + else + { + platforms &= ~platform; + } + m_filterProxyModel->SetPlatforms(platforms); + }); + } + } + + void GemFilterWidget::AddFeatureFilter() + { + // Alphabetically sorted, unique features and their number of occurrences in the gem database. + QMap uniqueFeatureCounts; + const int numGems = m_gemModel->rowCount(); + for (int gemIndex = 0; gemIndex < numGems; ++gemIndex) + { + const QStringList features = m_gemModel->GetFeatures(m_gemModel->index(gemIndex, 0)); + for (const QString& feature : features) + { + if (!uniqueFeatureCounts.contains(feature)) + { + uniqueFeatureCounts.insert(feature, 1); + } + else + { + int& featureeCount = uniqueFeatureCounts[feature]; + featureeCount++; + } + } + } + + QVector elementNames; + QVector elementCounts; + for (auto iterator = uniqueFeatureCounts.begin(); iterator != uniqueFeatureCounts.end(); iterator++) + { + elementNames.push_back(iterator.key()); + elementCounts.push_back(iterator.value()); + } + + FilterCategoryWidget* filterWidget = new FilterCategoryWidget("Features", elementNames, elementCounts, + /*showAllLessButton=*/true, /*defaultShowCount=*/5); + m_mainLayout->addWidget(filterWidget); + + const QList buttons = filterWidget->GetButtonGroup()->buttons(); + for (int i = 0; i < buttons.size(); ++i) + { + const QString& feature = elementNames[i]; + QAbstractButton* button = buttons[i]; + + connect(button, &QAbstractButton::toggled, this, [=](bool checked) + { + QSet features = m_filterProxyModel->GetFeatures(); + if (checked) + { + features.insert(feature); + } + else + { + features.remove(feature); + } + m_filterProxyModel->SetFeatures(features); + }); + } + } +} // namespace O3DE::ProjectManager diff --git a/Code/Tools/ProjectManager/Source/GemCatalog/GemFilterWidget.h b/Code/Tools/ProjectManager/Source/GemCatalog/GemFilterWidget.h new file mode 100644 index 0000000000..017eadc020 --- /dev/null +++ b/Code/Tools/ProjectManager/Source/GemCatalog/GemFilterWidget.h @@ -0,0 +1,79 @@ +/* +* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or +* its licensors. +* +* For complete copyright and license terms please see the LICENSE at the root of this +* distribution (the "License"). All use of this software is governed by the License, +* or, if provided, by the license below or the license accompanying this file. Do not +* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* +*/ + +#pragma once + +#if !defined(Q_MOC_RUN) +#include +#include +#include +#include +#include +#include +#include +#include +#endif + +QT_FORWARD_DECLARE_CLASS(QButtonGroup) + +namespace O3DE::ProjectManager +{ + class FilterCategoryWidget + : public QWidget + { + Q_OBJECT // AUTOMOC + + public: + explicit FilterCategoryWidget(const QString& header, + const QVector& elementNames, + const QVector& elementCounts, + bool showAllLessButton = true, + int defaultShowCount = 4, + QWidget* parent = nullptr); + + QButtonGroup* GetButtonGroup(); + + private: + void UpdateCollapseState(); + void UpdateSeeMoreLess(); + + inline constexpr static int s_collapseButtonSize = 16; + QPushButton* m_collapseButton = nullptr; + + QWidget* m_mainWidget = nullptr; + QButtonGroup* m_buttonGroup = nullptr; + QVector m_elementWidgets; //! Includes checkbox and the count labl. + LinkLabel* m_seeAllLessLabel = nullptr; + int m_defaultShowCount = 0; + bool m_seeAll = false; + }; + + class GemFilterWidget + : public QScrollArea + { + Q_OBJECT // AUTOMOC + + public: + explicit GemFilterWidget(GemSortFilterProxyModel* filterProxyModel, QWidget* parent = nullptr); + ~GemFilterWidget() = default; + + private: + void AddGemOriginFilter(); + void AddTypeFilter(); + void AddPlatformFilter(); + void AddFeatureFilter(); + + QVBoxLayout* m_mainLayout = nullptr; + GemModel* m_gemModel = nullptr; + GemSortFilterProxyModel* m_filterProxyModel = nullptr; + }; +} // namespace O3DE::ProjectManager diff --git a/Code/Tools/ProjectManager/Source/GemCatalog/GemInfo.cpp b/Code/Tools/ProjectManager/Source/GemCatalog/GemInfo.cpp index 5b7127bdbe..791085f47a 100644 --- a/Code/Tools/ProjectManager/Source/GemCatalog/GemInfo.cpp +++ b/Code/Tools/ProjectManager/Source/GemCatalog/GemInfo.cpp @@ -62,6 +62,19 @@ namespace O3DE::ProjectManager } } + QString GemInfo::GetGemOriginString(GemOrigin origin) + { + switch (origin) + { + case O3DEFoundation: + return "Open 3D Foundation"; + case Local: + return "Local"; + default: + return ""; + } + } + bool GemInfo::IsPlatformSupported(Platform platform) const { return (m_platforms & platform); diff --git a/Code/Tools/ProjectManager/Source/GemCatalog/GemInfo.h b/Code/Tools/ProjectManager/Source/GemCatalog/GemInfo.h index 28b2fab451..b96a1f242f 100644 --- a/Code/Tools/ProjectManager/Source/GemCatalog/GemInfo.h +++ b/Code/Tools/ProjectManager/Source/GemCatalog/GemInfo.h @@ -46,6 +46,15 @@ namespace O3DE::ProjectManager Q_DECLARE_FLAGS(Types, Type) static QString GetTypeString(Type type); + enum GemOrigin + { + O3DEFoundation = 1 << 0, + Local = 1 << 1, + NumGemOrigins = 2 + }; + Q_DECLARE_FLAGS(GemOrigins, GemOrigin) + static QString GetGemOriginString(GemOrigin origin); + GemInfo() = default; GemInfo(const QString& name, const QString& creator, const QString& summary, Platforms platforms, bool isAdded); bool IsPlatformSupported(Platform platform) const; @@ -57,6 +66,7 @@ namespace O3DE::ProjectManager QString m_displayName; AZ::Uuid m_uuid; QString m_creator; + GemOrigin m_gemOrigin = Local; bool m_isAdded = false; //! Is the gem currently added and enabled in the project? QString m_summary; Platforms m_platforms; @@ -74,3 +84,4 @@ namespace O3DE::ProjectManager Q_DECLARE_OPERATORS_FOR_FLAGS(O3DE::ProjectManager::GemInfo::Platforms) Q_DECLARE_OPERATORS_FOR_FLAGS(O3DE::ProjectManager::GemInfo::Types) +Q_DECLARE_OPERATORS_FOR_FLAGS(O3DE::ProjectManager::GemInfo::GemOrigins) diff --git a/Code/Tools/ProjectManager/Source/GemCatalog/GemInspector.cpp b/Code/Tools/ProjectManager/Source/GemCatalog/GemInspector.cpp index e7c682afd1..6276ddc996 100644 --- a/Code/Tools/ProjectManager/Source/GemCatalog/GemInspector.cpp +++ b/Code/Tools/ProjectManager/Source/GemCatalog/GemInspector.cpp @@ -70,8 +70,8 @@ namespace O3DE::ProjectManager m_documentationLinkLabel->SetUrl(m_model->GetDocLink(modelIndex)); // Depending and conflicting gems - m_dependingGems->Update("Depending Gems", "The following Gems will be automatically enabled with this Gem.", m_model->GetDependingGems(modelIndex)); - m_conflictingGems->Update("Conflicting Gems", "The following Gems will be automatically disabled with this Gem.", m_model->GetConflictingGems(modelIndex)); + m_dependingGems->Update("Depending Gems", "The following Gems will be automatically enabled with this Gem.", m_model->GetDependingGemNames(modelIndex)); + m_conflictingGems->Update("Conflicting Gems", "The following Gems will be automatically disabled with this Gem.", m_model->GetConflictingGemNames(modelIndex)); // Additional information m_versionLabel->setText(QString("Gem Version: %1").arg(m_model->GetVersion(modelIndex))); diff --git a/Code/Tools/ProjectManager/Source/GemCatalog/GemItemDelegate.cpp b/Code/Tools/ProjectManager/Source/GemCatalog/GemItemDelegate.cpp index 9a45600f70..a40e5eb447 100644 --- a/Code/Tools/ProjectManager/Source/GemCatalog/GemItemDelegate.cpp +++ b/Code/Tools/ProjectManager/Source/GemCatalog/GemItemDelegate.cpp @@ -10,7 +10,7 @@ * */ -#include "GemItemDelegate.h" +#include #include "GemModel.h" #include #include @@ -18,9 +18,9 @@ namespace O3DE::ProjectManager { - GemItemDelegate::GemItemDelegate(GemModel* gemModel, QObject* parent) + GemItemDelegate::GemItemDelegate(QAbstractItemModel* model, QObject* parent) : QStyledItemDelegate(parent) - , m_gemModel(gemModel) + , m_model(model) { AddPlatformIcon(GemInfo::Android, ":/Android.svg"); AddPlatformIcon(GemInfo::iOS, ":/iOS.svg"); @@ -78,7 +78,7 @@ namespace O3DE::ProjectManager } // Gem name - const QString gemName = m_gemModel->GetName(modelIndex); + const QString gemName = GemModel::GetName(modelIndex); QFont gemNameFont(options.font); gemNameFont.setPixelSize(s_gemNameFontSize); gemNameFont.setBold(true); @@ -90,7 +90,7 @@ namespace O3DE::ProjectManager painter->drawText(gemNameRect, Qt::TextSingleLine, gemName); // Gem creator - const QString gemCreator = m_gemModel->GetCreator(modelIndex); + const QString gemCreator = GemModel::GetCreator(modelIndex); QRect gemCreatorRect = GetTextRect(standardFont, gemCreator, s_fontSize); gemCreatorRect.moveTo(contentRect.left(), contentRect.top() + gemNameRect.height()); @@ -105,7 +105,7 @@ namespace O3DE::ProjectManager painter->setFont(standardFont); painter->setPen(m_textColor); - const QString summary = m_gemModel->GetSummary(modelIndex); + const QString summary = GemModel::GetSummary(modelIndex); painter->drawText(summaryRect, Qt::AlignLeft | Qt::TextWordWrap, summary); @@ -158,7 +158,7 @@ namespace O3DE::ProjectManager void GemItemDelegate::DrawPlatformIcons(QPainter* painter, const QRect& contentRect, const QModelIndex& modelIndex) const { - const GemInfo::Platforms platforms = m_gemModel->GetPlatforms(modelIndex); + const GemInfo::Platforms platforms = GemModel::GetPlatforms(modelIndex); int startX = 0; // Iterate and draw the platforms in the order they are defined in the enum. @@ -188,7 +188,7 @@ namespace O3DE::ProjectManager QPoint circleCenter; QString buttonText; - const bool isAdded = m_gemModel->IsAdded(modelIndex); + const bool isAdded = GemModel::IsAdded(modelIndex); if (isAdded) { painter->setBrush(m_buttonEnabledColor); diff --git a/Code/Tools/ProjectManager/Source/GemCatalog/GemItemDelegate.h b/Code/Tools/ProjectManager/Source/GemCatalog/GemItemDelegate.h index ee0392e188..d43b5d15f6 100644 --- a/Code/Tools/ProjectManager/Source/GemCatalog/GemItemDelegate.h +++ b/Code/Tools/ProjectManager/Source/GemCatalog/GemItemDelegate.h @@ -15,7 +15,7 @@ #if !defined(Q_MOC_RUN) #include #include "GemInfo.h" -#include "GemModel.h" +#include #include #endif @@ -29,22 +29,13 @@ namespace O3DE::ProjectManager Q_OBJECT // AUTOMOC public: - explicit GemItemDelegate(GemModel* gemModel, QObject* parent = nullptr); + explicit GemItemDelegate(QAbstractItemModel* model, QObject* parent = nullptr); ~GemItemDelegate() = default; void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& modelIndex) const override; bool editorEvent(QEvent* event, QAbstractItemModel* model, const QStyleOptionViewItem& option, const QModelIndex& modelIndex) override; QSize sizeHint(const QStyleOptionViewItem& option, const QModelIndex& modelIndex) const override; - private: - void CalcRects(const QStyleOptionViewItem& option, const QModelIndex& modelIndex, QRect& outFullRect, QRect& outItemRect, QRect& outContentRect) const; - QRect GetTextRect(QFont& font, const QString& text, qreal fontSize) const; - QRect CalcButtonRect(const QRect& contentRect) const; - void DrawPlatformIcons(QPainter* painter, const QRect& contentRect, const QModelIndex& modelIndex) const; - void DrawButton(QPainter* painter, const QRect& contentRect, const QModelIndex& modelIndex) const; - - GemModel* m_gemModel = nullptr; - // Colors const QColor m_textColor = QColor("#FFFFFF"); const QColor m_linkColor = QColor("#94D2FF"); @@ -71,6 +62,15 @@ namespace O3DE::ProjectManager inline constexpr static int s_buttonCircleRadius = s_buttonBorderRadius - 3; inline constexpr static qreal s_buttonFontSize = 12.0; + private: + void CalcRects(const QStyleOptionViewItem& option, const QModelIndex& modelIndex, QRect& outFullRect, QRect& outItemRect, QRect& outContentRect) const; + QRect GetTextRect(QFont& font, const QString& text, qreal fontSize) const; + QRect CalcButtonRect(const QRect& contentRect) const; + void DrawPlatformIcons(QPainter* painter, const QRect& contentRect, const QModelIndex& modelIndex) const; + void DrawButton(QPainter* painter, const QRect& contentRect, const QModelIndex& modelIndex) const; + + QAbstractItemModel* m_model = nullptr; + // Platform icons void AddPlatformIcon(GemInfo::Platform platform, const QString& iconPath); inline constexpr static int s_platformIconSize = 16; diff --git a/Code/Tools/ProjectManager/Source/GemCatalog/GemListView.cpp b/Code/Tools/ProjectManager/Source/GemCatalog/GemListView.cpp index ad75272c8f..2838277696 100644 --- a/Code/Tools/ProjectManager/Source/GemCatalog/GemListView.cpp +++ b/Code/Tools/ProjectManager/Source/GemCatalog/GemListView.cpp @@ -18,17 +18,15 @@ namespace O3DE::ProjectManager { - GemListView::GemListView(GemModel* model, QWidget *parent) : - QListView(parent) + GemListView::GemListView(QAbstractItemModel* model, QItemSelectionModel* selectionModel, QWidget* parent) + : QListView(parent) { setVerticalScrollMode(QAbstractItemView::ScrollPerPixel); - QPalette palette; - palette.setColor(QPalette::Window, QColor("#333333")); - setPalette(palette); + setStyleSheet("background-color: #333333;"); setModel(model); - setSelectionModel(model->GetSelectionModel()); + setSelectionModel(selectionModel); setItemDelegate(new GemItemDelegate(model, this)); } } // namespace O3DE::ProjectManager diff --git a/Code/Tools/ProjectManager/Source/GemCatalog/GemListView.h b/Code/Tools/ProjectManager/Source/GemCatalog/GemListView.h index 79e16bd211..178de2395f 100644 --- a/Code/Tools/ProjectManager/Source/GemCatalog/GemListView.h +++ b/Code/Tools/ProjectManager/Source/GemCatalog/GemListView.h @@ -14,7 +14,8 @@ #if !defined(Q_MOC_RUN) #include "GemInfo.h" -#include "GemModel.h" +#include +#include #include #endif @@ -24,8 +25,9 @@ namespace O3DE::ProjectManager : public QListView { Q_OBJECT // AUTOMOC + public: - explicit GemListView(GemModel* model, QWidget *parent = nullptr); + explicit GemListView(QAbstractItemModel* model, QItemSelectionModel* selectionModel, QWidget* parent = nullptr); ~GemListView() = default; }; } // namespace O3DE::ProjectManager diff --git a/Code/Tools/ProjectManager/Source/GemCatalog/GemModel.cpp b/Code/Tools/ProjectManager/Source/GemCatalog/GemModel.cpp index addf59783d..724a8fa630 100644 --- a/Code/Tools/ProjectManager/Source/GemCatalog/GemModel.cpp +++ b/Code/Tools/ProjectManager/Source/GemCatalog/GemModel.cpp @@ -36,11 +36,11 @@ namespace O3DE::ProjectManager const QString uuidString = gemInfo.m_uuid.ToString().c_str(); item->setData(uuidString, RoleUuid); item->setData(gemInfo.m_creator, RoleCreator); + item->setData(gemInfo.m_gemOrigin, RoleGemOrigin); item->setData(aznumeric_cast(gemInfo.m_platforms), RolePlatforms); item->setData(aznumeric_cast(gemInfo.m_types), RoleTypes); item->setData(gemInfo.m_summary, RoleSummary); item->setData(gemInfo.m_isAdded, RoleIsAdded); - item->setData(gemInfo.m_directoryLink, RoleDirectoryLink); item->setData(gemInfo.m_documentationLink, RoleDocLink); item->setData(gemInfo.m_dependingGemUuids, RoleDependingGems); @@ -48,12 +48,12 @@ namespace O3DE::ProjectManager item->setData(gemInfo.m_version, RoleVersion); item->setData(gemInfo.m_lastUpdatedDate, RoleLastUpdated); item->setData(gemInfo.m_binarySizeInKB, RoleBinarySize); - item->setData(gemInfo.m_features, RoleFeatures); appendRow(item); - m_uuidToNameMap[uuidString] = gemInfo.m_displayName; + const QModelIndex modelIndex = index(rowCount()-1, 0); + m_uuidToIndexMap[uuidString] = modelIndex; } void GemModel::Clear() @@ -71,6 +71,11 @@ namespace O3DE::ProjectManager return modelIndex.data(RoleCreator).toString(); } + GemInfo::GemOrigin GemModel::GetGemOrigin(const QModelIndex& modelIndex) + { + return static_cast(modelIndex.data(RoleGemOrigin).toInt()); + } + QString GemModel::GetUuidString(const QModelIndex& modelIndex) { return modelIndex.data(RoleUuid).toString(); @@ -106,42 +111,63 @@ namespace O3DE::ProjectManager return modelIndex.data(RoleDocLink).toString(); } - AZ::Outcome GemModel::FindGemNameByUuidString(const QString& uuidString) const + QModelIndex GemModel::FindIndexByUuidString(const QString& uuidString) const { - const auto iterator = m_uuidToNameMap.find(uuidString); - if (iterator != m_uuidToNameMap.end()) + const auto iterator = m_uuidToIndexMap.find(uuidString); + if (iterator != m_uuidToIndexMap.end()) { - return AZ::Success(iterator.value()); + return iterator.value(); } - return AZ::Failure(); + return {}; } - QStringList GemModel::GetDependingGems(const QModelIndex& modelIndex) + void GemModel::FindGemNamesByUuidStrings(QStringList& inOutGemNames) { - QStringList result = modelIndex.data(RoleDependingGems).toStringList(); + for (QString& dependingGemString : inOutGemNames) + { + QModelIndex modelIndex = FindIndexByUuidString(dependingGemString); + if (modelIndex.isValid()) + { + dependingGemString = GetName(modelIndex); + } + } + } + + QStringList GemModel::GetDependingGemUuids(const QModelIndex& modelIndex) + { + return modelIndex.data(RoleDependingGems).toStringList(); + } + + QStringList GemModel::GetDependingGemNames(const QModelIndex& modelIndex) + { + QStringList result = GetDependingGemUuids(modelIndex); if (result.isEmpty()) { return {}; } - for (QString& dependingGemString : result) - { - AZ::Outcome gemNameOutcome = FindGemNameByUuidString(dependingGemString); - if (gemNameOutcome.IsSuccess()) - { - dependingGemString = gemNameOutcome.GetValue(); - } - } - + FindGemNamesByUuidStrings(result); return result; } - QStringList GemModel::GetConflictingGems(const QModelIndex& modelIndex) + QStringList GemModel::GetConflictingGemUuids(const QModelIndex& modelIndex) { return modelIndex.data(RoleConflictingGems).toStringList(); } + QStringList GemModel::GetConflictingGemNames(const QModelIndex& modelIndex) + { + QStringList result = GetConflictingGemUuids(modelIndex); + if (result.isEmpty()) + { + return {}; + } + + FindGemNamesByUuidStrings(result); + return result; + } + QString GemModel::GetVersion(const QModelIndex& modelIndex) { return modelIndex.data(RoleVersion).toString(); diff --git a/Code/Tools/ProjectManager/Source/GemCatalog/GemModel.h b/Code/Tools/ProjectManager/Source/GemCatalog/GemModel.h index 76211b1f22..480f4c74d3 100644 --- a/Code/Tools/ProjectManager/Source/GemCatalog/GemModel.h +++ b/Code/Tools/ProjectManager/Source/GemCatalog/GemModel.h @@ -13,7 +13,6 @@ #pragma once #if !defined(Q_MOC_RUN) -#include #include #include #include @@ -34,11 +33,16 @@ namespace O3DE::ProjectManager void AddGem(const GemInfo& gemInfo); void Clear(); - AZ::Outcome FindGemNameByUuidString(const QString& uuidString) const; - QStringList GetDependingGems(const QModelIndex& modelIndex); + QModelIndex FindIndexByUuidString(const QString& uuidString) const; + void FindGemNamesByUuidStrings(QStringList& inOutGemNames); + QStringList GetDependingGemUuids(const QModelIndex& modelIndex); + QStringList GetDependingGemNames(const QModelIndex& modelIndex); + QStringList GetConflictingGemUuids(const QModelIndex& modelIndex); + QStringList GetConflictingGemNames(const QModelIndex& modelIndex); static QString GetName(const QModelIndex& modelIndex); static QString GetCreator(const QModelIndex& modelIndex); + static GemInfo::GemOrigin GetGemOrigin(const QModelIndex& modelIndex); static QString GetUuidString(const QModelIndex& modelIndex); static GemInfo::Platforms GetPlatforms(const QModelIndex& modelIndex); static GemInfo::Types GetTypes(const QModelIndex& modelIndex); @@ -46,7 +50,6 @@ namespace O3DE::ProjectManager static bool IsAdded(const QModelIndex& modelIndex); static QString GetDirectoryLink(const QModelIndex& modelIndex); static QString GetDocLink(const QModelIndex& modelIndex); - static QStringList GetConflictingGems(const QModelIndex& modelIndex); static QString GetVersion(const QModelIndex& modelIndex); static QString GetLastUpdated(const QModelIndex& modelIndex); static int GetBinarySizeInKB(const QModelIndex& modelIndex); @@ -58,6 +61,7 @@ namespace O3DE::ProjectManager RoleName = Qt::UserRole, RoleUuid, RoleCreator, + RoleGemOrigin, RolePlatforms, RoleSummary, RoleIsAdded, @@ -72,7 +76,7 @@ namespace O3DE::ProjectManager RoleTypes }; - QHash m_uuidToNameMap; + QHash m_uuidToIndexMap; QItemSelectionModel* m_selectionModel = nullptr; }; } // namespace O3DE::ProjectManager diff --git a/Code/Tools/ProjectManager/Source/GemCatalog/GemSortFilterProxyModel.cpp b/Code/Tools/ProjectManager/Source/GemCatalog/GemSortFilterProxyModel.cpp new file mode 100644 index 0000000000..33936f417e --- /dev/null +++ b/Code/Tools/ProjectManager/Source/GemCatalog/GemSortFilterProxyModel.cpp @@ -0,0 +1,133 @@ +/* +* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or +* its licensors. +* +* For complete copyright and license terms please see the LICENSE at the root of this +* distribution (the "License"). All use of this software is governed by the License, +* or, if provided, by the license below or the license accompanying this file. Do not +* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* +*/ + +#include +#include + +namespace O3DE::ProjectManager +{ + GemSortFilterProxyModel::GemSortFilterProxyModel(GemModel* sourceModel, QObject* parent) + : QSortFilterProxyModel(parent) + , m_sourceModel(sourceModel) + { + setSourceModel(sourceModel); + m_selectionProxyModel = new AzQtComponents::SelectionProxyModel(sourceModel->GetSelectionModel(), this, parent); + } + + bool GemSortFilterProxyModel::filterAcceptsRow(int sourceRow, const QModelIndex& sourceParent) const + { + // Do not use sourceParent->child because an invalid parent does not produce valid children (which our index function does) + QModelIndex sourceIndex = sourceModel()->index(sourceRow, 0, sourceParent); + if (!sourceIndex.isValid()) + { + return false; + } + + if (!m_sourceModel->GetName(sourceIndex).contains(m_searchString, Qt::CaseInsensitive)) + { + return false; + } + + // Gem origins + if (m_gemOriginFilter) + { + bool supportsAnyFilteredGemOrigin = false; + for (int i = 0; i < GemInfo::NumGemOrigins; ++i) + { + const GemInfo::GemOrigin filteredGemOrigin = static_cast(1 << i); + if (m_gemOriginFilter & filteredGemOrigin) + { + if ((GemModel::GetGemOrigin(sourceIndex) == filteredGemOrigin)) + { + supportsAnyFilteredGemOrigin = true; + break; + } + } + } + if (!supportsAnyFilteredGemOrigin) + { + return false; + } + } + + // Platform + if (m_platformFilter) + { + bool supportsAnyFilteredPlatform = false; + for (int i = 0; i < GemInfo::NumPlatforms; ++i) + { + const GemInfo::Platform filteredPlatform = static_cast(1 << i); + if (m_platformFilter & filteredPlatform) + { + if ((GemModel::GetPlatforms(sourceIndex) & filteredPlatform)) + { + supportsAnyFilteredPlatform = true; + break; + } + } + } + if (!supportsAnyFilteredPlatform) + { + return false; + } + } + + // Types (Asset, Code, Tool) + if (m_typeFilter) + { + bool supportsAnyFilteredType = false; + for (int i = 0; i < GemInfo::NumTypes; ++i) + { + const GemInfo::Type filteredType = static_cast(1 << i); + if (m_typeFilter & filteredType) + { + if ((GemModel::GetTypes(sourceIndex) & filteredType)) + { + supportsAnyFilteredType = true; + break; + } + } + } + if (!supportsAnyFilteredType) + { + return false; + } + } + + // Features + if (!m_featureFilter.isEmpty()) + { + bool containsFilterFeature = false; + const QStringList features = m_sourceModel->GetFeatures(sourceIndex); + for (const QString& feature : features) + { + if (m_featureFilter.contains(feature)) + { + containsFilterFeature = true; + break; + } + } + if (!containsFilterFeature) + { + return false; + } + } + + return true; + } + + void GemSortFilterProxyModel::InvalidateFilter() + { + invalidate(); + emit OnInvalidated(); + } +} // namespace O3DE::ProjectManager diff --git a/Code/Tools/ProjectManager/Source/GemCatalog/GemSortFilterProxyModel.h b/Code/Tools/ProjectManager/Source/GemCatalog/GemSortFilterProxyModel.h new file mode 100644 index 0000000000..e5554c020c --- /dev/null +++ b/Code/Tools/ProjectManager/Source/GemCatalog/GemSortFilterProxyModel.h @@ -0,0 +1,68 @@ +/* +* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or +* its licensors. +* +* For complete copyright and license terms please see the LICENSE at the root of this +* distribution (the "License"). All use of this software is governed by the License, +* or, if provided, by the license below or the license accompanying this file. Do not +* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* +*/ + +#pragma once + +#if !defined(Q_MOC_RUN) +#include +#include +#include +#include +#endif + +QT_FORWARD_DECLARE_CLASS(QItemSelectionModel) + +namespace O3DE::ProjectManager +{ + class GemSortFilterProxyModel + : public QSortFilterProxyModel + { + Q_OBJECT // AUTOMOC + + public: + GemSortFilterProxyModel(GemModel* sourceModel, QObject* parent = nullptr); + + bool filterAcceptsRow(int sourceRow, const QModelIndex& sourceParent) const override; + + GemModel* GetSourceModel() const { return m_sourceModel; } + AzQtComponents::SelectionProxyModel* GetSelectionModel() const { return m_selectionProxyModel; } + + void SetSearchString(const QString& searchString) { m_searchString = searchString; InvalidateFilter(); } + + GemInfo::GemOrigins GetGemOrigins() const { return m_gemOriginFilter; } + void SetGemOrigins(const GemInfo::GemOrigins& gemOrigins) { m_gemOriginFilter = gemOrigins; InvalidateFilter(); } + + GemInfo::Platforms GetPlatforms() const { return m_platformFilter; } + void SetPlatforms(const GemInfo::Platforms& platforms) { m_platformFilter = platforms; InvalidateFilter(); } + + GemInfo::Types GetTypes() const { return m_typeFilter; } + void SetTypes(const GemInfo::Types& types) { m_typeFilter = types; InvalidateFilter(); } + + const QSet& GetFeatures() const { return m_featureFilter; } + void SetFeatures(const QSet& features) { m_featureFilter = features; InvalidateFilter(); } + + void InvalidateFilter(); + + signals: + void OnInvalidated(); + + private: + GemModel* m_sourceModel = nullptr; + AzQtComponents::SelectionProxyModel* m_selectionProxyModel = nullptr; + + QString m_searchString; + GemInfo::GemOrigins m_gemOriginFilter = {}; + GemInfo::Platforms m_platformFilter = {}; + GemInfo::Types m_typeFilter = {}; + QSet m_featureFilter; + }; +} // namespace O3DE::ProjectManager diff --git a/Code/Tools/ProjectManager/Source/ProjectManagerWindow.cpp b/Code/Tools/ProjectManager/Source/ProjectManagerWindow.cpp index 121add657f..4136b9eb8c 100644 --- a/Code/Tools/ProjectManager/Source/ProjectManagerWindow.cpp +++ b/Code/Tools/ProjectManager/Source/ProjectManagerWindow.cpp @@ -32,8 +32,6 @@ namespace O3DE::ProjectManager layout->setSpacing(0); layout->setContentsMargins(0, 0, 0, 0); - setFixedSize(this->geometry().width(), this->geometry().height()); - m_pythonBindings = AZStd::make_unique(engineRootPath); m_screensCtrl = new ScreensCtrl(); diff --git a/Code/Tools/ProjectManager/Source/ProjectManagerWindow.ui b/Code/Tools/ProjectManager/Source/ProjectManagerWindow.ui index 4e33511bff..633cd61182 100644 --- a/Code/Tools/ProjectManager/Source/ProjectManagerWindow.ui +++ b/Code/Tools/ProjectManager/Source/ProjectManagerWindow.ui @@ -11,7 +11,7 @@ - + 0 0 diff --git a/Code/Tools/ProjectManager/project_manager_files.cmake b/Code/Tools/ProjectManager/project_manager_files.cmake index 858fb972aa..16bc8cf965 100644 --- a/Code/Tools/ProjectManager/project_manager_files.cmake +++ b/Code/Tools/ProjectManager/project_manager_files.cmake @@ -57,6 +57,8 @@ set(FILES Source/TagWidget.cpp Source/GemCatalog/GemCatalogScreen.h Source/GemCatalog/GemCatalogScreen.cpp + Source/GemCatalog/GemFilterWidget.h + Source/GemCatalog/GemFilterWidget.cpp Source/GemCatalog/GemInfo.h Source/GemCatalog/GemInfo.cpp Source/GemCatalog/GemInspector.h @@ -67,4 +69,6 @@ set(FILES Source/GemCatalog/GemListView.cpp Source/GemCatalog/GemModel.h Source/GemCatalog/GemModel.cpp + Source/GemCatalog/GemSortFilterProxyModel.h + Source/GemCatalog/GemSortFilterProxyModel.cpp ) From 1da8c50e8e81cc51c84eed0e560672e8121f27a3 Mon Sep 17 00:00:00 2001 From: AMZN-stankowi Date: Tue, 25 May 2021 08:54:42 -0700 Subject: [PATCH 13/16] Temporarily backing out STL changes to unblock mainline (#921) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Revert "FBX settings can be opened again: g_fbxImporter is set, and if the ex… (#878)" This reverts commit 58adcf168fcab0da94b25004482a6edabb2b0fad. * Revert "Merge pull request #753 from aws-lumberyard-dev/Helios_DataDrivenAssetImporter" This reverts commit 798d96f1a2056cc71156797a88d96e0a67f1f9d3, reversing changes made to eb31d90ad94da7cca7a13b8e1385f1edc4bc42b4. --- .../SceneAPI/FbxSceneBuilder/DllMain.cpp | 19 ++++--- .../FbxImportRequestHandler.cpp | 51 +++---------------- .../FbxSceneBuilder/FbxImportRequestHandler.h | 20 ++------ .../SceneBuilder/SceneBuilderComponent.cpp | 6 +-- .../SceneBuilder/SceneBuilderComponent.h | 2 - Registry/sceneassetimporter.setreg | 16 ------ 6 files changed, 23 insertions(+), 91 deletions(-) delete mode 100644 Registry/sceneassetimporter.setreg diff --git a/Code/Tools/SceneAPI/FbxSceneBuilder/DllMain.cpp b/Code/Tools/SceneAPI/FbxSceneBuilder/DllMain.cpp index 6fd664eee4..3dc14814de 100644 --- a/Code/Tools/SceneAPI/FbxSceneBuilder/DllMain.cpp +++ b/Code/Tools/SceneAPI/FbxSceneBuilder/DllMain.cpp @@ -41,6 +41,18 @@ namespace AZ static AZ::SceneAPI::FbxSceneImporter::FbxImportRequestHandler* g_fbxImporter = nullptr; static AZStd::vector g_componentDescriptors; + void Initialize() + { + // Currently it's still needed to explicitly create an instance of this instead of letting + // it be a normal component. This is because ResourceCompilerScene needs to return + // the list of available extensions before it can start the application. + if (!g_fbxImporter) + { + g_fbxImporter = aznew AZ::SceneAPI::FbxSceneImporter::FbxImportRequestHandler(); + g_fbxImporter->Activate(); + } + } + void Reflect(AZ::SerializeContext* /*context*/) { // Descriptor registration is done in Reflect instead of Initialize because the ResourceCompilerScene initializes the libraries before @@ -52,7 +64,6 @@ namespace AZ { // Global importer and behavior g_componentDescriptors.push_back(FbxSceneBuilder::FbxImporter::CreateDescriptor()); - g_componentDescriptors.push_back(FbxSceneImporter::FbxImportRequestHandler::CreateDescriptor()); // Node and attribute importers g_componentDescriptors.push_back(AssImpBitangentStreamImporter::CreateDescriptor()); @@ -114,11 +125,7 @@ namespace AZ extern "C" AZ_DLL_EXPORT void InitializeDynamicModule(void* env) { AZ::Environment::Attach(static_cast(env)); - if (!AZ::SceneAPI::FbxSceneBuilder::g_fbxImporter) - { - AZ::SceneAPI::FbxSceneBuilder::g_fbxImporter = aznew AZ::SceneAPI::FbxSceneImporter::FbxImportRequestHandler(); - AZ::SceneAPI::FbxSceneBuilder::g_fbxImporter->Activate(); - } + AZ::SceneAPI::FbxSceneBuilder::Initialize(); } extern "C" AZ_DLL_EXPORT void Reflect(AZ::SerializeContext* context) { diff --git a/Code/Tools/SceneAPI/FbxSceneBuilder/FbxImportRequestHandler.cpp b/Code/Tools/SceneAPI/FbxSceneBuilder/FbxImportRequestHandler.cpp index ebdb57e452..155209f1b5 100644 --- a/Code/Tools/SceneAPI/FbxSceneBuilder/FbxImportRequestHandler.cpp +++ b/Code/Tools/SceneAPI/FbxSceneBuilder/FbxImportRequestHandler.cpp @@ -10,16 +10,12 @@ * */ -#include -#include #include -#include -#include -#include -#include +#include #include #include #include +#include namespace AZ { @@ -27,23 +23,10 @@ namespace AZ { namespace FbxSceneImporter { - void SceneImporterSettings::Reflect(AZ::ReflectContext* context) - { - if (auto serializeContext = azrtti_cast(context); serializeContext) - { - serializeContext->Class() - ->Version(1) - ->Field("SupportedFileTypeExtensions", &SceneImporterSettings::m_supportedFileTypeExtensions); - } - } + const char* FbxImportRequestHandler::s_extension = ".fbx"; void FbxImportRequestHandler::Activate() { - if (auto* settingsRegistry = AZ::SettingsRegistry::Get()) - { - settingsRegistry->GetObject(m_settings, "/O3DE/SceneAPI/AssetImporter"); - } - BusConnect(); } @@ -54,38 +37,21 @@ namespace AZ void FbxImportRequestHandler::Reflect(ReflectContext* context) { - SceneImporterSettings::Reflect(context); - SerializeContext* serializeContext = azrtti_cast(context); if (serializeContext) { - serializeContext->Class()->Version(1)->Attribute( - AZ::Edit::Attributes::SystemComponentTags, - AZStd::vector({AssetBuilderSDK::ComponentTags::AssetBuilder})); - + serializeContext->Class()->Version(1); } } void FbxImportRequestHandler::GetSupportedFileExtensions(AZStd::unordered_set& extensions) { - // It's unlikely an empty file extension list is intentional, - // so if it's empty, try reloading it from the registry. - if (m_settings.m_supportedFileTypeExtensions.empty()) - { - if (auto* settingsRegistry = AZ::SettingsRegistry::Get()) - { - settingsRegistry->GetObject(m_settings, "/O3DE/SceneAPI/AssetImporter"); - } - } - extensions.insert(m_settings.m_supportedFileTypeExtensions.begin(), m_settings.m_supportedFileTypeExtensions.end()); + extensions.insert(s_extension); } Events::LoadingResult FbxImportRequestHandler::LoadAsset(Containers::Scene& scene, const AZStd::string& path, const Uuid& guid, [[maybe_unused]] RequestingApplication requester) { - AZStd::string extension; - StringFunc::Path::GetExtension(path.c_str(), extension); - - if (!m_settings.m_supportedFileTypeExtensions.contains(extension)) + if (!AzFramework::StringFunc::Path::IsExtension(path.c_str(), s_extension)) { return Events::LoadingResult::Ignored; } @@ -107,11 +73,6 @@ namespace AZ return Events::LoadingResult::AssetFailure; } } - - void FbxImportRequestHandler::GetProvidedServices(ComponentDescriptor::DependencyArrayType& provided) - { - provided.emplace_back(AZ_CRC_CE("AssetImportRequestHandler")); - } } // namespace Import } // namespace SceneAPI } // namespace AZ diff --git a/Code/Tools/SceneAPI/FbxSceneBuilder/FbxImportRequestHandler.h b/Code/Tools/SceneAPI/FbxSceneBuilder/FbxImportRequestHandler.h index 12c7c6f877..8b33051f1e 100644 --- a/Code/Tools/SceneAPI/FbxSceneBuilder/FbxImportRequestHandler.h +++ b/Code/Tools/SceneAPI/FbxSceneBuilder/FbxImportRequestHandler.h @@ -21,21 +21,12 @@ namespace AZ { namespace FbxSceneImporter { - struct SceneImporterSettings - { - AZ_TYPE_INFO(SceneImporterSettings, "{8BB6C7AD-BF99-44DC-9DA1-E7AD3F03DC10}"); - - static void Reflect(AZ::ReflectContext* context); - - AZStd::unordered_set m_supportedFileTypeExtensions; - }; - class FbxImportRequestHandler - : public AZ::Component + : public SceneCore::BehaviorComponent , public Events::AssetImportRequestBus::Handler { public: - AZ_COMPONENT(FbxImportRequestHandler, "{9F4B189C-0A96-4F44-A5F0-E087FF1561F8}"); + AZ_COMPONENT(FbxImportRequestHandler, "{9F4B189C-0A96-4F44-A5F0-E087FF1561F8}", SceneCore::BehaviorComponent); ~FbxImportRequestHandler() override = default; @@ -47,13 +38,8 @@ namespace AZ Events::LoadingResult LoadAsset(Containers::Scene& scene, const AZStd::string& path, const Uuid& guid, RequestingApplication requester) override; - static void GetProvidedServices(ComponentDescriptor::DependencyArrayType& provided); - private: - - SceneImporterSettings m_settings; - - static constexpr const char* SettingsFilename = "AssetImporterSettings.json"; + static const char* s_extension; }; } // namespace FbxSceneImporter } // namespace SceneAPI diff --git a/Gems/SceneProcessing/Code/Source/SceneBuilder/SceneBuilderComponent.cpp b/Gems/SceneProcessing/Code/Source/SceneBuilder/SceneBuilderComponent.cpp index 25faca3667..e71a5207d0 100644 --- a/Gems/SceneProcessing/Code/Source/SceneBuilder/SceneBuilderComponent.cpp +++ b/Gems/SceneProcessing/Code/Source/SceneBuilder/SceneBuilderComponent.cpp @@ -72,11 +72,6 @@ namespace SceneBuilder m_sceneBuilder.BusDisconnect(); } - void BuilderPluginComponent::GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required) - { - required.emplace_back(AZ_CRC_CE("AssetImportRequestHandler")); - } - void BuilderPluginComponent::Reflect(AZ::ReflectContext* context) { AZ::SerializeContext* serializeContext = azrtti_cast(context); @@ -86,4 +81,5 @@ namespace SceneBuilder ->Attribute(AZ::Edit::Attributes::SystemComponentTags, AZStd::vector({ AssetBuilderSDK::ComponentTags::AssetBuilder })); } } + } // namespace SceneBuilder diff --git a/Gems/SceneProcessing/Code/Source/SceneBuilder/SceneBuilderComponent.h b/Gems/SceneProcessing/Code/Source/SceneBuilder/SceneBuilderComponent.h index aed5e1b026..c1fc6ebb36 100644 --- a/Gems/SceneProcessing/Code/Source/SceneBuilder/SceneBuilderComponent.h +++ b/Gems/SceneProcessing/Code/Source/SceneBuilder/SceneBuilderComponent.h @@ -32,8 +32,6 @@ namespace SceneBuilder void Activate() override; void Deactivate() override; - static void GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required); - private: SceneBuilderWorker m_sceneBuilder; }; diff --git a/Registry/sceneassetimporter.setreg b/Registry/sceneassetimporter.setreg deleted file mode 100644 index bd7c4d0705..0000000000 --- a/Registry/sceneassetimporter.setreg +++ /dev/null @@ -1,16 +0,0 @@ -{ - "O3DE": - { - "SceneAPI": - { - "AssetImporter": - { - "SupportedFileTypeExtensions": - [ - ".fbx", - ".stl" - ] - } - } - } -} \ No newline at end of file From 50f5976e59d212e48dc641504d0bc80691c1d874 Mon Sep 17 00:00:00 2001 From: Tom Hulton-Harrop <82228511+hultonha@users.noreply.github.com> Date: Tue, 25 May 2021 17:28:51 +0100 Subject: [PATCH 14/16] Rename and move ModernViewportCameraController (#866) * rename ModernViewportCameraController to ModularViewportCameraController and move to AtomToolsFramework * update names and includes after file moves --- Code/Sandbox/Editor/CryEditDoc.cpp | 6 ++---- Code/Sandbox/Editor/EditorViewportWidget.cpp | 4 ++-- Code/Sandbox/Editor/editor_lib_files.cmake | 3 --- .../CMakeLists.txt | 1 + .../SandboxIntegration.cpp | 8 ++++---- .../ModularViewportCameraController.h | 17 ++++++++--------- ...odularViewportCameraControllerRequestBus.h | 10 +++++----- .../ModularViewportCameraController.cpp | 19 +++++++++---------- .../Code/atomtoolsframework_files.cmake | 3 +++ 9 files changed, 34 insertions(+), 37 deletions(-) rename Code/Sandbox/Editor/ModernViewportCameraController.h => Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Viewport/ModularViewportCameraController.h (87%) rename Code/Sandbox/Editor/ModernViewportCameraControllerRequestBus.h => Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Viewport/ModularViewportCameraControllerRequestBus.h (78%) rename Code/Sandbox/Editor/ModernViewportCameraController.cpp => Gems/Atom/Tools/AtomToolsFramework/Code/Source/Viewport/ModularViewportCameraController.cpp (91%) diff --git a/Code/Sandbox/Editor/CryEditDoc.cpp b/Code/Sandbox/Editor/CryEditDoc.cpp index a6c5f73c7f..747921d401 100644 --- a/Code/Sandbox/Editor/CryEditDoc.cpp +++ b/Code/Sandbox/Editor/CryEditDoc.cpp @@ -58,13 +58,11 @@ #include "LevelFileDialog.h" #include "StatObjBus.h" -// LmbrCentral -#include #include #include -#include // for LmbrCentral::EditorLightComponentRequestBus - +// LmbrCentral +#include // for LmbrCentral::EditorLightComponentRequestBus //#define PROFILE_LOADING_WITH_VTUNE diff --git a/Code/Sandbox/Editor/EditorViewportWidget.cpp b/Code/Sandbox/Editor/EditorViewportWidget.cpp index f72801a4d3..ecd11da817 100644 --- a/Code/Sandbox/Editor/EditorViewportWidget.cpp +++ b/Code/Sandbox/Editor/EditorViewportWidget.cpp @@ -53,6 +53,7 @@ // AtomToolsFramework #include +#include // CryCommon #include @@ -75,7 +76,6 @@ #include "EditorPreferencesPageGeneral.h" #include "ViewportManipulatorController.h" #include "LegacyViewportCameraController.h" -#include "ModernViewportCameraController.h" #include "EditorViewportSettings.h" #include "ViewPane.h" @@ -1220,7 +1220,7 @@ void EditorViewportWidget::SetViewportId(int id) { AzFramework::ReloadCameraKeyBindings(); - auto controller = AZStd::make_shared(); + auto controller = AZStd::make_shared(); controller->SetCameraListBuilderCallback([](AzFramework::Cameras& cameras) { auto firstPersonRotateCamera = AZStd::make_shared(AzFramework::CameraFreeLookButton); diff --git a/Code/Sandbox/Editor/editor_lib_files.cmake b/Code/Sandbox/Editor/editor_lib_files.cmake index 0646fb566e..e1cf18df55 100644 --- a/Code/Sandbox/Editor/editor_lib_files.cmake +++ b/Code/Sandbox/Editor/editor_lib_files.cmake @@ -823,9 +823,6 @@ set(FILES ViewportManipulatorController.h LegacyViewportCameraController.cpp LegacyViewportCameraController.h - ModernViewportCameraController.cpp - ModernViewportCameraController.h - ModernViewportCameraControllerRequestBus.h RenderViewport.cpp RenderViewport.h TopRendererWnd.cpp diff --git a/Code/Sandbox/Plugins/ComponentEntityEditorPlugin/CMakeLists.txt b/Code/Sandbox/Plugins/ComponentEntityEditorPlugin/CMakeLists.txt index 72d88b06b4..d02c656b8f 100644 --- a/Code/Sandbox/Plugins/ComponentEntityEditorPlugin/CMakeLists.txt +++ b/Code/Sandbox/Plugins/ComponentEntityEditorPlugin/CMakeLists.txt @@ -38,6 +38,7 @@ ly_add_target( Gem::LmbrCentral AZ::AtomCore Gem::Atom_RPI.Public + Gem::AtomToolsFramework.Static ) ly_add_dependencies(Editor ComponentEntityEditorPlugin) diff --git a/Code/Sandbox/Plugins/ComponentEntityEditorPlugin/SandboxIntegration.cpp b/Code/Sandbox/Plugins/ComponentEntityEditorPlugin/SandboxIntegration.cpp index 884e1f9e51..5ff2debe3d 100644 --- a/Code/Sandbox/Plugins/ComponentEntityEditorPlugin/SandboxIntegration.cpp +++ b/Code/Sandbox/Plugins/ComponentEntityEditorPlugin/SandboxIntegration.cpp @@ -66,8 +66,8 @@ #include #include +#include -#include #include "Objects/ComponentEntityObject.h" #include "ISourceControl.h" @@ -1736,9 +1736,9 @@ void SandboxIntegrationManager::GoToEntitiesInViewports(const AzToolsFramework:: const AZ::Transform nextCameraTransform = AZ::Transform::CreateLookAt(aabb.GetCenter() - (forward * distanceToTarget), aabb.GetCenter()); - SandboxEditor::ModernViewportCameraControllerRequestBus::Event( - viewportContext->GetId(), &SandboxEditor::ModernViewportCameraControllerRequestBus::Events::InterpolateToTransform, - nextCameraTransform); + AtomToolsFramework::ModularViewportCameraControllerRequestBus::Event( + viewportContext->GetId(), + &AtomToolsFramework::ModularViewportCameraControllerRequestBus::Events::InterpolateToTransform, nextCameraTransform); } } } diff --git a/Code/Sandbox/Editor/ModernViewportCameraController.h b/Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Viewport/ModularViewportCameraController.h similarity index 87% rename from Code/Sandbox/Editor/ModernViewportCameraController.h rename to Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Viewport/ModularViewportCameraController.h index 39e3c9cbb3..1318deb355 100644 --- a/Code/Sandbox/Editor/ModernViewportCameraController.h +++ b/Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Viewport/ModularViewportCameraController.h @@ -12,17 +12,16 @@ #pragma once -#include - #include +#include #include #include #include -namespace SandboxEditor +namespace AtomToolsFramework { class ModernViewportCameraControllerInstance; - class ModernViewportCameraController + class ModularViewportCameraController : public AzFramework::MultiViewportController< ModernViewportCameraControllerInstance, AzFramework::ViewportControllerPriority::DispatchToAllPriorities> { @@ -39,19 +38,19 @@ namespace SandboxEditor }; class ModernViewportCameraControllerInstance final - : public AzFramework::MultiViewportControllerInstanceInterface, - public ModernViewportCameraControllerRequestBus::Handler, + : public AzFramework::MultiViewportControllerInstanceInterface, + public ModularViewportCameraControllerRequestBus::Handler, private AzFramework::ViewportDebugDisplayEventBus::Handler { public: - explicit ModernViewportCameraControllerInstance(AzFramework::ViewportId viewportId, ModernViewportCameraController* controller); + explicit ModernViewportCameraControllerInstance(AzFramework::ViewportId viewportId, ModularViewportCameraController* controller); ~ModernViewportCameraControllerInstance() override; // MultiViewportControllerInstanceInterface overrides ... bool HandleInputChannelEvent(const AzFramework::ViewportControllerInputEvent& event) override; void UpdateViewport(const AzFramework::ViewportControllerUpdateEvent& event) override; - // ModernViewportCameraControllerRequestBus overrides ... + // ModularViewportCameraControllerRequestBus overrides ... void InterpolateToTransform(const AZ::Transform& worldFromLocal) override; private: @@ -76,4 +75,4 @@ namespace SandboxEditor AZ::RPI::ViewportContext::MatrixChangedEvent::Handler m_cameraViewMatrixChangeHandler; }; -} // namespace SandboxEditor +} // namespace AtomToolsFramework diff --git a/Code/Sandbox/Editor/ModernViewportCameraControllerRequestBus.h b/Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Viewport/ModularViewportCameraControllerRequestBus.h similarity index 78% rename from Code/Sandbox/Editor/ModernViewportCameraControllerRequestBus.h rename to Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Viewport/ModularViewportCameraControllerRequestBus.h index 966facc8e9..5b90119372 100644 --- a/Code/Sandbox/Editor/ModernViewportCameraControllerRequestBus.h +++ b/Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Viewport/ModularViewportCameraControllerRequestBus.h @@ -20,11 +20,11 @@ namespace AZ class Transform; } -namespace SandboxEditor +namespace AtomToolsFramework { //! Provides an interface to control the modern viewport camera controller from the Editor. //! @note The bus is addressed by viewport id. - class ModernViewportCameraControllerRequests : public AZ::EBusTraits + class ModularViewportCameraControllerRequests : public AZ::EBusTraits { public: using BusIdType = AzFramework::ViewportId; @@ -35,8 +35,8 @@ namespace SandboxEditor virtual void InterpolateToTransform(const AZ::Transform& worldFromLocal) = 0; protected: - ~ModernViewportCameraControllerRequests() = default; + ~ModularViewportCameraControllerRequests() = default; }; - using ModernViewportCameraControllerRequestBus = AZ::EBus; -} // namespace SandboxEditor + using ModularViewportCameraControllerRequestBus = AZ::EBus; +} // namespace AtomToolsFramework diff --git a/Code/Sandbox/Editor/ModernViewportCameraController.cpp b/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Viewport/ModularViewportCameraController.cpp similarity index 91% rename from Code/Sandbox/Editor/ModernViewportCameraController.cpp rename to Gems/Atom/Tools/AtomToolsFramework/Code/Source/Viewport/ModularViewportCameraController.cpp index 0779542878..6fb3edfa22 100644 --- a/Code/Sandbox/Editor/ModernViewportCameraController.cpp +++ b/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Viewport/ModularViewportCameraController.cpp @@ -10,10 +10,9 @@ * */ -#include "ModernViewportCameraController.h" - #include #include +#include #include #include #include @@ -23,7 +22,7 @@ #include #include -namespace SandboxEditor +namespace AtomToolsFramework { // debug void DrawPreviewAxis(AzFramework::DebugDisplayRequests& display, const AZ::Transform& transform, const float axisLength) @@ -53,12 +52,12 @@ namespace SandboxEditor return viewportContext; } - void ModernViewportCameraController::SetCameraListBuilderCallback(const CameraListBuilder& builder) + void ModularViewportCameraController::SetCameraListBuilderCallback(const CameraListBuilder& builder) { m_cameraListBuilder = builder; } - void ModernViewportCameraController::SetupCameras(AzFramework::Cameras& cameras) + void ModularViewportCameraController::SetupCameras(AzFramework::Cameras& cameras) { if (m_cameraListBuilder) { @@ -67,8 +66,8 @@ namespace SandboxEditor } ModernViewportCameraControllerInstance::ModernViewportCameraControllerInstance( - const AzFramework::ViewportId viewportId, ModernViewportCameraController* controller) - : MultiViewportControllerInstanceInterface(viewportId, controller) + const AzFramework::ViewportId viewportId, ModularViewportCameraController* controller) + : MultiViewportControllerInstanceInterface(viewportId, controller) { controller->SetupCameras(m_cameraSystem.m_cameras); @@ -88,12 +87,12 @@ namespace SandboxEditor } AzFramework::ViewportDebugDisplayEventBus::Handler::BusConnect(AzToolsFramework::GetEntityContextId()); - ModernViewportCameraControllerRequestBus::Handler::BusConnect(viewportId); + ModularViewportCameraControllerRequestBus::Handler::BusConnect(viewportId); } ModernViewportCameraControllerInstance::~ModernViewportCameraControllerInstance() { - ModernViewportCameraControllerRequestBus::Handler::BusDisconnect(); + ModularViewportCameraControllerRequestBus::Handler::BusDisconnect(); AzFramework::ViewportDebugDisplayEventBus::Handler::BusDisconnect(); } @@ -182,4 +181,4 @@ namespace SandboxEditor m_transformStart = m_camera.Transform(); m_transformEnd = worldFromLocal; } -} // namespace SandboxEditor +} // namespace AtomToolsFramework diff --git a/Gems/Atom/Tools/AtomToolsFramework/Code/atomtoolsframework_files.cmake b/Gems/Atom/Tools/AtomToolsFramework/Code/atomtoolsframework_files.cmake index d8ceccc724..f28ba89b92 100644 --- a/Gems/Atom/Tools/AtomToolsFramework/Code/atomtoolsframework_files.cmake +++ b/Gems/Atom/Tools/AtomToolsFramework/Code/atomtoolsframework_files.cmake @@ -24,6 +24,8 @@ set(FILES Include/AtomToolsFramework/Util/MaterialPropertyUtil.h Include/AtomToolsFramework/Util/Util.h Include/AtomToolsFramework/Viewport/RenderViewportWidget.h + Include/AtomToolsFramework/Viewport/ModularViewportCameraController.h + Include/AtomToolsFramework/Viewport/ModularViewportCameraControllerRequestBus.h Source/Communication/LocalServer.cpp Source/Communication/LocalSocket.cpp Source/Debug/TraceRecorder.cpp @@ -38,4 +40,5 @@ set(FILES Source/Util/MaterialPropertyUtil.cpp Source/Util/Util.cpp Source/Viewport/RenderViewportWidget.cpp + Source/Viewport/ModularViewportCameraController.cpp ) From ad3625c2a2687d7247671590a90e54f7e270fe3f Mon Sep 17 00:00:00 2001 From: Terry Michaels <81711813+tjmichaels@users.noreply.github.com> Date: Tue, 25 May 2021 11:57:49 -0500 Subject: [PATCH 15/16] Added ability to specify a default directory for the asset picker in the asset property control (#903) * Framework for setting default directory in asset picker * Asset Picker will default to a passed in default directory in the selection model * Added comment to the property to help define what is expected. * Fixed string assignment * Removed commented out #pragma * Addressed review feedback * Addressed review feedback --- .../AssetPicker/AssetPickerDialog.cpp | 13 +++- .../AssetBrowser/AssetSelectionModel.cpp | 10 +++ .../AssetBrowser/AssetSelectionModel.h | 4 ++ .../Views/AssetBrowserTreeView.cpp | 63 +++++++++++++------ .../AssetBrowser/Views/AssetBrowserTreeView.h | 5 +- .../UI/PropertyEditor/PropertyAssetCtrl.cpp | 18 ++++++ .../UI/PropertyEditor/PropertyAssetCtrl.hxx | 3 + 7 files changed, 96 insertions(+), 20 deletions(-) diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/AssetPicker/AssetPickerDialog.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/AssetPicker/AssetPickerDialog.cpp index 9ab50a803c..92711f45b2 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/AssetPicker/AssetPickerDialog.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/AssetPicker/AssetPickerDialog.cpp @@ -81,9 +81,20 @@ namespace AzToolsFramework m_ui->m_assetBrowserTreeViewWidget->SetName("AssetBrowserTreeView_" + name); + bool selectedAsset = false; + for (auto& assetId : selection.GetSelectedAssetIds()) { - m_ui->m_assetBrowserTreeViewWidget->SelectProduct(assetId); + if (assetId.IsValid()) + { + selectedAsset = true; + m_ui->m_assetBrowserTreeViewWidget->SelectProduct(assetId); + } + } + + if (!selectedAsset) + { + m_ui->m_assetBrowserTreeViewWidget->SelectFolder(selection.GetDefaultDirectory()); } setWindowTitle(tr("Pick %1").arg(m_selection.GetTitle())); diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/AssetSelectionModel.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/AssetSelectionModel.cpp index 65f361dc83..83734a24c3 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/AssetSelectionModel.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/AssetSelectionModel.cpp @@ -93,6 +93,16 @@ namespace AzToolsFramework m_selectedAssetIds.push_back(selectedAssetId); } + void AssetSelectionModel::SetDefaultDirectory(AZStd::string_view defaultDirectory) + { + m_defaultDirectory = defaultDirectory; + } + + AZStd::string_view AssetSelectionModel::GetDefaultDirectory() const + { + return m_defaultDirectory; + } + AZStd::vector& AssetSelectionModel::GetResults() { return m_results; diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/AssetSelectionModel.h b/Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/AssetSelectionModel.h index 59cc9d05e2..5e9d23602a 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/AssetSelectionModel.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/AssetSelectionModel.h @@ -47,6 +47,9 @@ namespace AzToolsFramework const AZStd::vector& GetSelectedAssetIds() const; void SetSelectedAssetIds(const AZStd::vector& selectedAssetIds); void SetSelectedAssetId(const AZ::Data::AssetId& selectedAssetId); + + void SetDefaultDirectory(AZStd::string_view defaultDirectory); + AZStd::string_view GetDefaultDirectory() const; AZStd::vector& GetResults(); const AssetBrowserEntry* GetResult(); @@ -72,6 +75,7 @@ namespace AzToolsFramework AZStd::vector m_selectedAssetIds; AZStd::vector m_results; + AZStd::string m_defaultDirectory; QString m_title; }; diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/Views/AssetBrowserTreeView.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/Views/AssetBrowserTreeView.cpp index eeee433835..6cd60b0015 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/Views/AssetBrowserTreeView.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/Views/AssetBrowserTreeView.cpp @@ -14,6 +14,7 @@ #include #include #include +#include #include @@ -270,7 +271,20 @@ namespace AzToolsFramework return false; } - bool AssetBrowserTreeView::SelectEntry(const QModelIndex& idxParent, const AZStd::vector& entries, const uint32_t entryPathIndex) + void AssetBrowserTreeView::SelectFolder(AZStd::string_view folderPath) + { + if (folderPath.size() == 0) + { + return; + } + + AZStd::vector entries; + AZ::StringFunc::Tokenize(folderPath, entries, "/"); + + SelectEntry(QModelIndex(), entries, 0, true); + } + + bool AssetBrowserTreeView::SelectEntry(const QModelIndex& idxParent, const AZStd::vector& entries, const uint32_t entryPathIndex, bool useDisplayName) { if (entries.empty()) { @@ -285,30 +299,43 @@ namespace AzToolsFramework auto rowIdx = model()->index(idx, 0, idxParent); auto rowEntry = GetEntryFromIndex(rowIdx); - // Check if this entry name matches the query - if (rowEntry && AzFramework::StringFunc::Equal(entry.c_str(), rowEntry->GetName().c_str(), true)) + if (rowEntry) { - // Final entry found - set it as the selected element - if (entryPathIndex == entries.size() - 1) - { - selectionModel()->clear(); - selectionModel()->select(rowIdx, QItemSelectionModel::Select); - setCurrentIndex(rowIdx); - return true; - } + // Check if this entry name matches the query + AZStd::string_view compareName = useDisplayName ? (const char*)(rowEntry->GetDisplayName().toUtf8()) : rowEntry->GetName().c_str(); - // If this isn't the final entry, it needs to be a folder for the path to be valid (otherwise, early out) - if (rowEntry->GetEntryType() == AssetBrowserEntry::AssetEntryType::Folder) + if (AzFramework::StringFunc::Equal(entry.c_str(), compareName, true)) { - // Folder found - if the final entry is found, expand this folder so the final entry is viewable in the Asset Browser (otherwise, early out) - if (SelectEntry(rowIdx, entries, entryPathIndex + 1)) + // Final entry found - set it as the selected element + if (entryPathIndex == entries.size() - 1) { - expand(rowIdx); + if (rowEntry->GetEntryType() == AssetBrowserEntry::AssetEntryType::Folder) + { + // Expand the item itself if it is a folder + expand(rowIdx); + } + + selectionModel()->clear(); + selectionModel()->select(rowIdx, QItemSelectionModel::Select); + setCurrentIndex(rowIdx); + return true; } + + // If this isn't the final entry, it needs to be a folder for the path to be valid (otherwise, early out) + if (rowEntry->GetEntryType() == AssetBrowserEntry::AssetEntryType::Folder) + { + // Folder found - if the final entry is found, expand this folder so the final entry is viewable in the Asset + // Browser (otherwise, early out) + if (SelectEntry(rowIdx, entries, entryPathIndex + 1, useDisplayName)) + { + expand(rowIdx); + return true; + } + } + + return false; } - - return false; } } diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/Views/AssetBrowserTreeView.h b/Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/Views/AssetBrowserTreeView.h index 697396b09e..19cbd3745a 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/Views/AssetBrowserTreeView.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/Views/AssetBrowserTreeView.h @@ -60,6 +60,8 @@ namespace AzToolsFramework AZStd::vector GetSelectedAssets() const; + void SelectFolder(AZStd::string_view folderPath); + ////////////////////////////////////////////////////////////////////////// // AssetBrowserViewRequestBus void SelectProduct(AZ::Data::AssetId assetID) override; @@ -67,6 +69,7 @@ namespace AzToolsFramework void ClearFilter() override; void Update() override; + ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// @@ -105,7 +108,7 @@ namespace AzToolsFramework QString m_name; bool SelectProduct(const QModelIndex& idxParent, AZ::Data::AssetId assetID); - bool SelectEntry(const QModelIndex& idxParent, const AZStd::vector& entryPathTokens, const uint32_t entryPathIndex = 0); + bool SelectEntry(const QModelIndex& idxParent, const AZStd::vector& entryPathTokens, const uint32_t entryPathIndex = 0, bool useDisplayName = false); //! Grab one entry from the source thumbnail list and update it void UpdateSCThumbnails(); diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/PropertyAssetCtrl.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/PropertyAssetCtrl.cpp index d69eb5559f..23f8378df5 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/PropertyAssetCtrl.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/PropertyAssetCtrl.cpp @@ -769,6 +769,14 @@ namespace AzToolsFramework // Request the AssetBrowser Dialog and set a type filter AssetSelectionModel selection = GetAssetSelectionModel(); selection.SetSelectedAssetId(m_selectedAssetID); + + AZStd::string defaultDirectory; + if (m_defaultDirectoryCallback) + { + m_defaultDirectoryCallback->Invoke(m_editNotifyTarget, defaultDirectory); + selection.SetDefaultDirectory(defaultDirectory); + } + AssetBrowserComponentRequestBus::Broadcast(&AssetBrowserComponentRequests::PickAssets, selection, parentWidget()); if (selection.IsValid()) { @@ -1080,6 +1088,11 @@ namespace AzToolsFramework m_editNotifyCallback = editNotifyCallback; } + void PropertyAssetCtrl::SetDefaultDirectoryCallback(DefaultDirectoryCallbackType* callback) + { + m_defaultDirectoryCallback = callback; + } + void PropertyAssetCtrl::SetClearNotifyCallback(ClearCallbackType* clearNotifyCallback) { m_clearNotifyCallback = clearNotifyCallback; @@ -1214,6 +1227,11 @@ namespace AzToolsFramework GUI->SetTitle(title.c_str()); } } + else if (attrib == AZ_CRC_CE("DefaultStartingDirectoryCallback")) + { + // This is assumed to be an Asset Browser path to a specific folder to be used as a default by the asset picker if provided + GUI->SetDefaultDirectoryCallback(azdynamic_cast(attrValue->GetAttribute())); + } else if (attrib == AZ_CRC("EditCallback", 0xb74f2ee1)) { PropertyAssetCtrl::EditCallbackType* func = azdynamic_cast(attrValue->GetAttribute()); diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/PropertyAssetCtrl.hxx b/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/PropertyAssetCtrl.hxx index e845cdf4fb..37af3d0594 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/PropertyAssetCtrl.hxx +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/PropertyAssetCtrl.hxx @@ -68,6 +68,7 @@ namespace AzToolsFramework // This is meant to be used with the "EditCallback" Attribute using EditCallbackType = AZ::Edit::AttributeFunction; using ClearCallbackType = AZ::Edit::AttributeFunction; + using DefaultDirectoryCallbackType = AZ::Edit::AttributeFunction; PropertyAssetCtrl(QWidget *pParent = NULL, QString optionalValidDragDropExtensions = QString()); virtual ~PropertyAssetCtrl(); @@ -119,6 +120,7 @@ namespace AzToolsFramework EditCallbackType* m_editNotifyCallback = nullptr; ClearCallbackType* m_clearNotifyCallback = nullptr; QString m_optionalValidDragDropExtensions; + DefaultDirectoryCallbackType* m_defaultDirectoryCallback = nullptr; //! The number of characters after which the autocompleter dropdown will be shown. // Prevents showing too many options. @@ -196,6 +198,7 @@ namespace AzToolsFramework void SetEditNotifyTarget(void* editNotifyTarget); void SetEditNotifyCallback(EditCallbackType* editNotifyCallback); // This is meant to be used with the "EditCallback" Attribute void SetClearNotifyCallback(ClearCallbackType* clearNotifyCallback); // This is meant to be used with the "ClearNotify" Attribute + void SetDefaultDirectoryCallback(DefaultDirectoryCallbackType* callback); // This is meant to be used with the "DefaultStartingDirectoryCallback" Attribute void SetEditButtonEnabled(bool enabled); void SetEditButtonVisible(bool visible); void SetEditButtonIcon(const QIcon& icon); From 1d50d7ed6418ba11324ddeab5031c85b14c16001 Mon Sep 17 00:00:00 2001 From: AMZN-nggieber <52797929+AMZN-nggieber@users.noreply.github.com> Date: Tue, 25 May 2021 10:16:11 -0700 Subject: [PATCH 16/16] Project Manager Projects Screen Dynamically Shows Projects Loaded from O3DE (#873) * Projects Home Screen Dynamically displays Projects from O3DE and can open Project settings editor * Seperated out CreateProjectCtrl and UpdateProjectCtrl * Moved source level statics back into class headers * Updated background image location --- .../Resources/DefaultProjectImage.png | 3 + .../Resources/ProjectManager.qrc | 3 + ...SettingsCtrl.cpp => CreateProjectCtrl.cpp} | 30 ++-- ...jectSettingsCtrl.h => CreateProjectCtrl.h} | 6 +- .../Source/FirstTimeUseScreen.cpp | 11 +- .../Source/FirstTimeUseScreen.h | 7 + .../Source/GemCatalog/GemCatalogScreen.cpp | 5 - .../Source/GemCatalog/GemCatalogScreen.h | 1 - .../Source/NewProjectSettingsScreen.cpp | 5 - .../Source/NewProjectSettingsScreen.h | 1 - .../Source/ProjectButtonWidget.cpp | 102 +++++++++++++ .../Source/ProjectButtonWidget.h | 73 +++++++++ .../Source/ProjectManagerWindow.cpp | 4 +- .../Source/ProjectSettingsScreen.cpp | 17 +++ .../Source/ProjectSettingsScreen.h | 6 + .../Source/ProjectsHomeScreen.cpp | 129 ++++++++++++++-- .../Source/ProjectsHomeScreen.h | 22 ++- .../Source/ProjectsHomeScreen.ui | 137 ----------------- .../ProjectManager/Source/PythonBindings.cpp | 3 +- Code/Tools/ProjectManager/Source/ScreenDefs.h | 3 +- .../ProjectManager/Source/ScreenFactory.cpp | 10 +- .../ProjectManager/Source/ScreenWidget.h | 5 +- .../ProjectManager/Source/ScreensCtrl.cpp | 1 + .../Tools/ProjectManager/Source/ScreensCtrl.h | 3 + .../Source/UpdateProjectCtrl.cpp | 139 ++++++++++++++++++ .../ProjectManager/Source/UpdateProjectCtrl.h | 51 +++++++ .../project_manager_files.cmake | 9 +- 27 files changed, 581 insertions(+), 205 deletions(-) create mode 100644 Code/Tools/ProjectManager/Resources/DefaultProjectImage.png rename Code/Tools/ProjectManager/Source/{ProjectSettingsCtrl.cpp => CreateProjectCtrl.cpp} (77%) rename Code/Tools/ProjectManager/Source/{ProjectSettingsCtrl.h => CreateProjectCtrl.h} (90%) create mode 100644 Code/Tools/ProjectManager/Source/ProjectButtonWidget.cpp create mode 100644 Code/Tools/ProjectManager/Source/ProjectButtonWidget.h delete mode 100644 Code/Tools/ProjectManager/Source/ProjectsHomeScreen.ui create mode 100644 Code/Tools/ProjectManager/Source/UpdateProjectCtrl.cpp create mode 100644 Code/Tools/ProjectManager/Source/UpdateProjectCtrl.h diff --git a/Code/Tools/ProjectManager/Resources/DefaultProjectImage.png b/Code/Tools/ProjectManager/Resources/DefaultProjectImage.png new file mode 100644 index 0000000000..cc1eda5bb8 --- /dev/null +++ b/Code/Tools/ProjectManager/Resources/DefaultProjectImage.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f82f22df64b93d4bec91e56b60efa3d5ce2915ce388a2dc627f1ab720678e3d5 +size 334987 diff --git a/Code/Tools/ProjectManager/Resources/ProjectManager.qrc b/Code/Tools/ProjectManager/Resources/ProjectManager.qrc index 1ffd7cf3e7..ac55c48a6b 100644 --- a/Code/Tools/ProjectManager/Resources/ProjectManager.qrc +++ b/Code/Tools/ProjectManager/Resources/ProjectManager.qrc @@ -11,6 +11,9 @@ iOS.svg Linux.svg macOS.svg + DefaultProjectImage.png + ArrowDownLine.svg + ArrowUpLine.svg Backgrounds/FirstTimeBackgroundImage.jpg diff --git a/Code/Tools/ProjectManager/Source/ProjectSettingsCtrl.cpp b/Code/Tools/ProjectManager/Source/CreateProjectCtrl.cpp similarity index 77% rename from Code/Tools/ProjectManager/Source/ProjectSettingsCtrl.cpp rename to Code/Tools/ProjectManager/Source/CreateProjectCtrl.cpp index 95dcec3e18..03e6a34b89 100644 --- a/Code/Tools/ProjectManager/Source/ProjectSettingsCtrl.cpp +++ b/Code/Tools/ProjectManager/Source/CreateProjectCtrl.cpp @@ -10,7 +10,7 @@ * */ -#include +#include #include #include #include @@ -22,7 +22,7 @@ namespace O3DE::ProjectManager { - ProjectSettingsCtrl::ProjectSettingsCtrl(QWidget* parent) + CreateProjectCtrl::CreateProjectCtrl(QWidget* parent) : ScreenWidget(parent) { QVBoxLayout* vLayout = new QVBoxLayout(); @@ -34,11 +34,11 @@ namespace O3DE::ProjectManager QDialogButtonBox* backNextButtons = new QDialogButtonBox(); vLayout->addWidget(backNextButtons); - m_backButton = backNextButtons->addButton("Back", QDialogButtonBox::RejectRole); - m_nextButton = backNextButtons->addButton("Next", QDialogButtonBox::ApplyRole); + m_backButton = backNextButtons->addButton(tr("Back"), QDialogButtonBox::RejectRole); + m_nextButton = backNextButtons->addButton(tr("Next"), QDialogButtonBox::ApplyRole); - connect(m_backButton, &QPushButton::pressed, this, &ProjectSettingsCtrl::HandleBackButton); - connect(m_nextButton, &QPushButton::pressed, this, &ProjectSettingsCtrl::HandleNextButton); + connect(m_backButton, &QPushButton::pressed, this, &CreateProjectCtrl::HandleBackButton); + connect(m_nextButton, &QPushButton::pressed, this, &CreateProjectCtrl::HandleNextButton); m_screensOrder = { @@ -47,15 +47,16 @@ namespace O3DE::ProjectManager }; m_screensCtrl->BuildScreens(m_screensOrder); m_screensCtrl->ForceChangeToScreen(ProjectManagerScreen::NewProjectSettings, false); + UpdateNextButtonText(); } - ProjectManagerScreen ProjectSettingsCtrl::GetScreenEnum() + ProjectManagerScreen CreateProjectCtrl::GetScreenEnum() { - return ProjectManagerScreen::NewProjectSettingsCore; + return ProjectManagerScreen::CreateProject; } - void ProjectSettingsCtrl::HandleBackButton() + void CreateProjectCtrl::HandleBackButton() { if (!m_screensCtrl->GotoPreviousScreen()) { @@ -66,7 +67,7 @@ namespace O3DE::ProjectManager UpdateNextButtonText(); } } - void ProjectSettingsCtrl::HandleNextButton() + void CreateProjectCtrl::HandleNextButton() { ScreenWidget* currentScreen = m_screensCtrl->GetCurrentScreen(); ProjectManagerScreen screenEnum = currentScreen->GetScreenEnum(); @@ -116,9 +117,14 @@ namespace O3DE::ProjectManager } } - void ProjectSettingsCtrl::UpdateNextButtonText() + void CreateProjectCtrl::UpdateNextButtonText() { - m_nextButton->setText(m_screensCtrl->GetCurrentScreen()->GetNextButtonText()); + QString nextButtonText = tr("Next"); + if (m_screensCtrl->GetCurrentScreen()->GetScreenEnum() == ProjectManagerScreen::GemCatalog) + { + nextButtonText = tr("Create Project"); + } + m_nextButton->setText(nextButtonText); } } // namespace O3DE::ProjectManager diff --git a/Code/Tools/ProjectManager/Source/ProjectSettingsCtrl.h b/Code/Tools/ProjectManager/Source/CreateProjectCtrl.h similarity index 90% rename from Code/Tools/ProjectManager/Source/ProjectSettingsCtrl.h rename to Code/Tools/ProjectManager/Source/CreateProjectCtrl.h index 42f1ce1978..213bff3bc2 100644 --- a/Code/Tools/ProjectManager/Source/ProjectSettingsCtrl.h +++ b/Code/Tools/ProjectManager/Source/CreateProjectCtrl.h @@ -21,12 +21,12 @@ namespace O3DE::ProjectManager { - class ProjectSettingsCtrl + class CreateProjectCtrl : public ScreenWidget { public: - explicit ProjectSettingsCtrl(QWidget* parent = nullptr); - ~ProjectSettingsCtrl() = default; + explicit CreateProjectCtrl(QWidget* parent = nullptr); + ~CreateProjectCtrl() = default; ProjectManagerScreen GetScreenEnum() override; protected slots: diff --git a/Code/Tools/ProjectManager/Source/FirstTimeUseScreen.cpp b/Code/Tools/ProjectManager/Source/FirstTimeUseScreen.cpp index a1be7e8ac9..8654b221fb 100644 --- a/Code/Tools/ProjectManager/Source/FirstTimeUseScreen.cpp +++ b/Code/Tools/ProjectManager/Source/FirstTimeUseScreen.cpp @@ -21,13 +21,6 @@ namespace O3DE::ProjectManager { - inline constexpr static int s_contentMargins = 80; - inline constexpr static int s_buttonSpacing = 30; - inline constexpr static int s_iconSize = 24; - inline constexpr static int s_spacerSize = 20; - inline constexpr static int s_boxButtonWidth = 210; - inline constexpr static int s_boxButtonHeight = 280; - FirstTimeUseScreen::FirstTimeUseScreen(QWidget* parent) : ScreenWidget(parent) { @@ -79,8 +72,8 @@ namespace O3DE::ProjectManager void FirstTimeUseScreen::HandleNewProjectButton() { - emit ResetScreenRequest(ProjectManagerScreen::NewProjectSettingsCore); - emit ChangeScreenRequest(ProjectManagerScreen::NewProjectSettingsCore); + emit ResetScreenRequest(ProjectManagerScreen::CreateProject); + emit ChangeScreenRequest(ProjectManagerScreen::CreateProject); } void FirstTimeUseScreen::HandleAddProjectButton() { diff --git a/Code/Tools/ProjectManager/Source/FirstTimeUseScreen.h b/Code/Tools/ProjectManager/Source/FirstTimeUseScreen.h index b6b57dc16b..80a2310d7a 100644 --- a/Code/Tools/ProjectManager/Source/FirstTimeUseScreen.h +++ b/Code/Tools/ProjectManager/Source/FirstTimeUseScreen.h @@ -37,6 +37,13 @@ namespace O3DE::ProjectManager QPushButton* m_createProjectButton; QPushButton* m_addProjectButton; + + inline constexpr static int s_contentMargins = 80; + inline constexpr static int s_buttonSpacing = 30; + inline constexpr static int s_iconSize = 24; + inline constexpr static int s_spacerSize = 20; + inline constexpr static int s_boxButtonWidth = 210; + inline constexpr static int s_boxButtonHeight = 280; }; } // namespace O3DE::ProjectManager diff --git a/Code/Tools/ProjectManager/Source/GemCatalog/GemCatalogScreen.cpp b/Code/Tools/ProjectManager/Source/GemCatalog/GemCatalogScreen.cpp index bbc6099f24..7d8cee45b4 100644 --- a/Code/Tools/ProjectManager/Source/GemCatalog/GemCatalogScreen.cpp +++ b/Code/Tools/ProjectManager/Source/GemCatalog/GemCatalogScreen.cpp @@ -170,9 +170,4 @@ namespace O3DE::ProjectManager { return ProjectManagerScreen::GemCatalog; } - - QString GemCatalogScreen::GetNextButtonText() - { - return "Create Project"; - } } // namespace O3DE::ProjectManager diff --git a/Code/Tools/ProjectManager/Source/GemCatalog/GemCatalogScreen.h b/Code/Tools/ProjectManager/Source/GemCatalog/GemCatalogScreen.h index bf4202499f..44e0727c7e 100644 --- a/Code/Tools/ProjectManager/Source/GemCatalog/GemCatalogScreen.h +++ b/Code/Tools/ProjectManager/Source/GemCatalog/GemCatalogScreen.h @@ -28,7 +28,6 @@ namespace O3DE::ProjectManager explicit GemCatalogScreen(QWidget* parent = nullptr); ~GemCatalogScreen() = default; ProjectManagerScreen GetScreenEnum() override; - QString GetNextButtonText() override; private: QVector GenerateTestData(); diff --git a/Code/Tools/ProjectManager/Source/NewProjectSettingsScreen.cpp b/Code/Tools/ProjectManager/Source/NewProjectSettingsScreen.cpp index 153c0964c7..ffbf1bf6fe 100644 --- a/Code/Tools/ProjectManager/Source/NewProjectSettingsScreen.cpp +++ b/Code/Tools/ProjectManager/Source/NewProjectSettingsScreen.cpp @@ -96,11 +96,6 @@ namespace O3DE::ProjectManager return ProjectManagerScreen::NewProjectSettings; } - QString NewProjectSettingsScreen::GetNextButtonText() - { - return tr("Next"); - } - void NewProjectSettingsScreen::HandleBrowseButton() { QString defaultPath = m_projectPathLineEdit->text(); diff --git a/Code/Tools/ProjectManager/Source/NewProjectSettingsScreen.h b/Code/Tools/ProjectManager/Source/NewProjectSettingsScreen.h index dbd4388668..1cfd3c9c35 100644 --- a/Code/Tools/ProjectManager/Source/NewProjectSettingsScreen.h +++ b/Code/Tools/ProjectManager/Source/NewProjectSettingsScreen.h @@ -28,7 +28,6 @@ namespace O3DE::ProjectManager explicit NewProjectSettingsScreen(QWidget* parent = nullptr); ~NewProjectSettingsScreen() = default; ProjectManagerScreen GetScreenEnum() override; - QString GetNextButtonText() override; ProjectInfo GetProjectInfo(); QString GetProjectTemplatePath(); diff --git a/Code/Tools/ProjectManager/Source/ProjectButtonWidget.cpp b/Code/Tools/ProjectManager/Source/ProjectButtonWidget.cpp new file mode 100644 index 0000000000..ec1acdad61 --- /dev/null +++ b/Code/Tools/ProjectManager/Source/ProjectButtonWidget.cpp @@ -0,0 +1,102 @@ +/* + * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or + * its licensors. + * + * For complete copyright and license terms please see the LICENSE at the root of this + * distribution (the "License"). All use of this software is governed by the License, + * or, if provided, by the license below or the license accompanying this file. Do not + * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +//#define SHOW_ALL_PROJECT_ACTIONS + +namespace O3DE::ProjectManager +{ + inline constexpr static int s_projectImageWidth = 210; + inline constexpr static int s_projectImageHeight = 280; + + LabelButton::LabelButton(QWidget* parent) + : QLabel(parent) + { + } + + void LabelButton::mousePressEvent([[maybe_unused]] QMouseEvent* event) + { + emit triggered(); + } + + ProjectButton::ProjectButton(const QString& projectName, QWidget* parent) + : QFrame(parent) + , m_projectName(projectName) + , m_projectImagePath(":/Resources/DefaultProjectImage.png") + { + Setup(); + } + + ProjectButton::ProjectButton(const QString& projectName, const QString& projectImage, QWidget* parent) + : QFrame(parent) + , m_projectName(projectName) + , m_projectImagePath(projectImage) + { + Setup(); + } + + void ProjectButton::Setup() + { + QVBoxLayout* vLayout = new QVBoxLayout(); + vLayout->setSpacing(0); + vLayout->setContentsMargins(0, 0, 0, 0); + setLayout(vLayout); + + m_projectImageLabel = new LabelButton(this); + m_projectImageLabel->setFixedSize(s_projectImageWidth, s_projectImageHeight); + vLayout->addWidget(m_projectImageLabel); + + m_projectImageLabel->setPixmap(QPixmap(m_projectImagePath).scaled(m_projectImageLabel->size(), Qt::KeepAspectRatioByExpanding)); + + QMenu* newProjectMenu = new QMenu(this); + m_editProjectAction = newProjectMenu->addAction(tr("Edit Project Settings...")); + +#ifdef SHOW_ALL_PROJECT_ACTIONS + m_editProjectGemsAction = newProjectMenu->addAction(tr("Cutomize Gems...")); + newProjectMenu->addSeparator(); + m_copyProjectAction = newProjectMenu->addAction(tr("Duplicate")); + newProjectMenu->addSeparator(); + m_removeProjectAction = newProjectMenu->addAction(tr("Remove from O3DE")); + m_deleteProjectAction = newProjectMenu->addAction(tr("Delete the Project")); +#endif + + m_projectSettingsMenuButton = new QPushButton(this); + m_projectSettingsMenuButton->setText(m_projectName); + m_projectSettingsMenuButton->setMenu(newProjectMenu); + m_projectSettingsMenuButton->setFocusPolicy(Qt::FocusPolicy::NoFocus); + m_projectSettingsMenuButton->setStyleSheet("font-size: 14px; text-align:left;"); + vLayout->addWidget(m_projectSettingsMenuButton); + + setFixedSize(s_projectImageWidth, s_projectImageHeight + m_projectSettingsMenuButton->height()); + + connect(m_projectImageLabel, &LabelButton::triggered, [this]() { emit OpenProject(m_projectName); }); + connect(m_editProjectAction, &QAction::triggered, [this]() { emit EditProject(m_projectName); }); + +#ifdef SHOW_ALL_PROJECT_ACTIONS + connect(m_editProjectGemsAction, &QAction::triggered, [this]() { emit EditProjectGems(m_projectName); }); + connect(m_copyProjectAction, &QAction::triggered, [this]() { emit CopyProject(m_projectName); }); + connect(m_removeProjectAction, &QAction::triggered, [this]() { emit RemoveProject(m_projectName); }); + connect(m_deleteProjectAction, &QAction::triggered, [this]() { emit DeleteProject(m_projectName); }); +#endif + } + +} // namespace O3DE::ProjectManager diff --git a/Code/Tools/ProjectManager/Source/ProjectButtonWidget.h b/Code/Tools/ProjectManager/Source/ProjectButtonWidget.h new file mode 100644 index 0000000000..c1aee8e63e --- /dev/null +++ b/Code/Tools/ProjectManager/Source/ProjectButtonWidget.h @@ -0,0 +1,73 @@ +/* + * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or + * its licensors. + * + * For complete copyright and license terms please see the LICENSE at the root of this + * distribution (the "License"). All use of this software is governed by the License, + * or, if provided, by the license below or the license accompanying this file. Do not + * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + */ + +#pragma once + +#if !defined(Q_MOC_RUN) +#include +#include +#endif + +QT_FORWARD_DECLARE_CLASS(QPixmap) +QT_FORWARD_DECLARE_CLASS(QPushButton) +QT_FORWARD_DECLARE_CLASS(QAction) + +namespace O3DE::ProjectManager +{ + class LabelButton + : public QLabel + { + Q_OBJECT // AUTOMOC + + public: + explicit LabelButton(QWidget* parent = nullptr); + ~LabelButton() = default; + + signals: + void triggered(); + + public slots: + void mousePressEvent(QMouseEvent* event) override; + }; + + class ProjectButton + : public QFrame + { + Q_OBJECT // AUTOMOC + + public: + explicit ProjectButton(const QString& projectName, QWidget* parent = nullptr); + explicit ProjectButton(const QString& projectName, const QString& projectImage, QWidget* parent = nullptr); + ~ProjectButton() = default; + + signals: + void OpenProject(const QString& projectName); + void EditProject(const QString& projectName); + void EditProjectGems(const QString& projectName); + void CopyProject(const QString& projectName); + void RemoveProject(const QString& projectName); + void DeleteProject(const QString& projectName); + + private: + void Setup(); + + QString m_projectName; + QString m_projectImagePath; + LabelButton* m_projectImageLabel; + QPushButton* m_projectSettingsMenuButton; + QAction* m_editProjectAction; + QAction* m_editProjectGemsAction; + QAction* m_copyProjectAction; + QAction* m_removeProjectAction; + QAction* m_deleteProjectAction; + }; +} // namespace O3DE::ProjectManager diff --git a/Code/Tools/ProjectManager/Source/ProjectManagerWindow.cpp b/Code/Tools/ProjectManager/Source/ProjectManagerWindow.cpp index 4136b9eb8c..eb79f2da1e 100644 --- a/Code/Tools/ProjectManager/Source/ProjectManagerWindow.cpp +++ b/Code/Tools/ProjectManager/Source/ProjectManagerWindow.cpp @@ -50,9 +50,9 @@ namespace O3DE::ProjectManager QVector screenEnums = { ProjectManagerScreen::FirstTimeUse, - ProjectManagerScreen::NewProjectSettingsCore, + ProjectManagerScreen::CreateProject, ProjectManagerScreen::ProjectsHome, - ProjectManagerScreen::ProjectSettings, + ProjectManagerScreen::UpdateProject, ProjectManagerScreen::EngineSettings }; m_screensCtrl->BuildScreens(screenEnums); diff --git a/Code/Tools/ProjectManager/Source/ProjectSettingsScreen.cpp b/Code/Tools/ProjectManager/Source/ProjectSettingsScreen.cpp index 52fca439b4..76aa1d2897 100644 --- a/Code/Tools/ProjectManager/Source/ProjectSettingsScreen.cpp +++ b/Code/Tools/ProjectManager/Source/ProjectSettingsScreen.cpp @@ -30,6 +30,23 @@ namespace O3DE::ProjectManager return ProjectManagerScreen::ProjectSettings; } + ProjectInfo ProjectSettingsScreen::GetProjectInfo() + { + // Impl pending next PR + return ProjectInfo(); + } + + void ProjectSettingsScreen::SetProjectInfo() + { + // Impl pending next PR + } + + bool ProjectSettingsScreen::Validate() + { + // Impl pending next PR + return true; + } + void ProjectSettingsScreen::HandleGemsButton() { emit ChangeScreenRequest(ProjectManagerScreen::GemCatalog); diff --git a/Code/Tools/ProjectManager/Source/ProjectSettingsScreen.h b/Code/Tools/ProjectManager/Source/ProjectSettingsScreen.h index 1ec1b46f44..a4cafcd93a 100644 --- a/Code/Tools/ProjectManager/Source/ProjectSettingsScreen.h +++ b/Code/Tools/ProjectManager/Source/ProjectSettingsScreen.h @@ -13,6 +13,7 @@ #if !defined(Q_MOC_RUN) #include +#include #endif namespace Ui @@ -30,6 +31,11 @@ namespace O3DE::ProjectManager ~ProjectSettingsScreen() = default; ProjectManagerScreen GetScreenEnum() override; + ProjectInfo GetProjectInfo(); + void SetProjectInfo(); + + bool Validate(); + protected slots: void HandleGemsButton(); diff --git a/Code/Tools/ProjectManager/Source/ProjectsHomeScreen.cpp b/Code/Tools/ProjectManager/Source/ProjectsHomeScreen.cpp index 539f79b017..411b46c55d 100644 --- a/Code/Tools/ProjectManager/Source/ProjectsHomeScreen.cpp +++ b/Code/Tools/ProjectManager/Source/ProjectsHomeScreen.cpp @@ -12,21 +12,103 @@ #include -#include - +#include #include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + namespace O3DE::ProjectManager { ProjectsHomeScreen::ProjectsHomeScreen(QWidget* parent) : ScreenWidget(parent) - , m_ui(new Ui::ProjectsHomeClass()) { - m_ui->setupUi(this); + QVBoxLayout* vLayout = new QVBoxLayout(); + setLayout(vLayout); + vLayout->setContentsMargins(s_contentMargins, s_contentMargins, s_contentMargins, s_contentMargins); - connect(m_ui->newProjectButton, &QPushButton::pressed, this, &ProjectsHomeScreen::HandleNewProjectButton); - connect(m_ui->addProjectButton, &QPushButton::pressed, this, &ProjectsHomeScreen::HandleAddProjectButton); - connect(m_ui->editProjectButton, &QPushButton::pressed, this, &ProjectsHomeScreen::HandleEditProjectButton); + QHBoxLayout* topLayout = new QHBoxLayout(); + + QLabel* titleLabel = new QLabel(this); + titleLabel->setText("My Projects"); + titleLabel->setStyleSheet("font-size: 24px"); + topLayout->addWidget(titleLabel); + + QSpacerItem* topSpacer = new QSpacerItem(s_spacerSize, s_spacerSize, QSizePolicy::Expanding, QSizePolicy::Minimum); + topLayout->addItem(topSpacer); + + QMenu* newProjectMenu = new QMenu(this); + m_createNewProjectAction = newProjectMenu->addAction("Create New Project"); + m_addExistingProjectAction = newProjectMenu->addAction("Add Existing Project"); + + QPushButton* newProjectMenuButton = new QPushButton(this); + newProjectMenuButton->setText("New Project..."); + newProjectMenuButton->setMenu(newProjectMenu); + newProjectMenuButton->setFixedWidth(s_newProjectButtonWidth); + newProjectMenuButton->setStyleSheet("font-size: 14px;"); + topLayout->addWidget(newProjectMenuButton); + + vLayout->addLayout(topLayout); + + // Get all projects and create a horizontal scrolling list of them + auto projectsResult = PythonBindingsInterface::Get()->GetProjects(); + if (projectsResult.IsSuccess() && !projectsResult.GetValue().isEmpty()) + { + QScrollArea* projectsScrollArea = new QScrollArea(this); + QWidget* scrollWidget = new QWidget(); + QGridLayout* projectGridLayout = new QGridLayout(); + scrollWidget->setLayout(projectGridLayout); + projectsScrollArea->setWidget(scrollWidget); + projectsScrollArea->setWidgetResizable(true); + + int gridIndex = 0; + for (auto project : projectsResult.GetValue()) + { + ProjectButton* projectButton; + QString projectPreviewPath = project.m_path + m_projectPreviewImagePath; + QFileInfo doesPreviewExist(projectPreviewPath); + if (doesPreviewExist.exists() && doesPreviewExist.isFile()) + { + projectButton = new ProjectButton(project.m_projectName, projectPreviewPath, this); + } + else + { + projectButton = new ProjectButton(project.m_projectName, this); + } + + // Create rows of projects buttons s_projectButtonRowCount buttons wide + projectGridLayout->addWidget(projectButton, gridIndex / s_projectButtonRowCount, gridIndex % s_projectButtonRowCount); + + connect(projectButton, &ProjectButton::OpenProject, this, &ProjectsHomeScreen::HandleOpenProject); + connect(projectButton, &ProjectButton::EditProject, this, &ProjectsHomeScreen::HandleEditProject); + +#ifdef SHOW_ALL_PROJECT_ACTIONS + connect(projectButton, &ProjectButton::EditProjectGems, this, &ProjectsHomeScreen::HandleEditProjectGems); + connect(projectButton, &ProjectButton::CopyProject, this, &ProjectsHomeScreen::HandleCopyProject); + connect(projectButton, &ProjectButton::RemoveProject, this, &ProjectsHomeScreen::HandleRemoveProject); + connect(projectButton, &ProjectButton::DeleteProject, this, &ProjectsHomeScreen::HandleDeleteProject); +#endif + ++gridIndex; + } + + vLayout->addWidget(projectsScrollArea); + } + + // Using border-image allows for scaling options background-image does not support + setStyleSheet("O3DE--ProjectManager--ScreenWidget { border-image: url(:/Backgrounds/FirstTimeBackgroundImage.jpg) repeat repeat; }"); + + connect(m_createNewProjectAction, &QAction::triggered, this, &ProjectsHomeScreen::HandleNewProjectButton); + connect(m_addExistingProjectAction, &QAction::triggered, this, &ProjectsHomeScreen::HandleAddProjectButton); } ProjectManagerScreen ProjectsHomeScreen::GetScreenEnum() @@ -36,16 +118,41 @@ namespace O3DE::ProjectManager void ProjectsHomeScreen::HandleNewProjectButton() { - emit ResetScreenRequest(ProjectManagerScreen::NewProjectSettingsCore); - emit ChangeScreenRequest(ProjectManagerScreen::NewProjectSettingsCore); + emit ResetScreenRequest(ProjectManagerScreen::CreateProject); + emit ChangeScreenRequest(ProjectManagerScreen::CreateProject); } void ProjectsHomeScreen::HandleAddProjectButton() { // Do nothing for now } - void ProjectsHomeScreen::HandleEditProjectButton() + void ProjectsHomeScreen::HandleOpenProject(const QString& projectPath) { - emit ChangeScreenRequest(ProjectManagerScreen::ProjectSettings); + // Open the editor with this project open + emit NotifyCurrentProject(projectPath); + } + void ProjectsHomeScreen::HandleEditProject(const QString& projectPath) + { + emit NotifyCurrentProject(projectPath); + emit ResetScreenRequest(ProjectManagerScreen::UpdateProject); + emit ChangeScreenRequest(ProjectManagerScreen::UpdateProject); + } + void ProjectsHomeScreen::HandleEditProjectGems(const QString& projectPath) + { + emit NotifyCurrentProject(projectPath); + emit ChangeScreenRequest(ProjectManagerScreen::GemCatalog); + } + void ProjectsHomeScreen::HandleCopyProject([[maybe_unused]] const QString& projectPath) + { + // Open file dialog and choose location for copied project then register copy with O3DE + } + void ProjectsHomeScreen::HandleRemoveProject([[maybe_unused]] const QString& projectPath) + { + // Unregister Project from O3DE + } + void ProjectsHomeScreen::HandleDeleteProject([[maybe_unused]] const QString& projectPath) + { + // Remove project from 03DE and delete from disk + ProjectsHomeScreen::HandleRemoveProject(projectPath); } } // namespace O3DE::ProjectManager diff --git a/Code/Tools/ProjectManager/Source/ProjectsHomeScreen.h b/Code/Tools/ProjectManager/Source/ProjectsHomeScreen.h index 9fd5919d2d..e8d1ac4fb5 100644 --- a/Code/Tools/ProjectManager/Source/ProjectsHomeScreen.h +++ b/Code/Tools/ProjectManager/Source/ProjectsHomeScreen.h @@ -15,11 +15,6 @@ #include #endif -namespace Ui -{ - class ProjectsHomeClass; -} - namespace O3DE::ProjectManager { class ProjectsHomeScreen @@ -34,10 +29,23 @@ namespace O3DE::ProjectManager protected slots: void HandleNewProjectButton(); void HandleAddProjectButton(); - void HandleEditProjectButton(); + void HandleOpenProject(const QString& projectPath); + void HandleEditProject(const QString& projectPath); + void HandleEditProjectGems(const QString& projectPath); + void HandleCopyProject(const QString& projectPath); + void HandleRemoveProject(const QString& projectPath); + void HandleDeleteProject(const QString& projectPath); private: - QScopedPointer m_ui; + QAction* m_createNewProjectAction; + QAction* m_addExistingProjectAction; + + const QString m_projectPreviewImagePath = "/preview.png"; + inline constexpr static int s_contentMargins = 80; + inline constexpr static int s_spacerSize = 20; + inline constexpr static int s_projectButtonRowCount = 4; + inline constexpr static int s_newProjectButtonWidth = 156; + }; } // namespace O3DE::ProjectManager diff --git a/Code/Tools/ProjectManager/Source/ProjectsHomeScreen.ui b/Code/Tools/ProjectManager/Source/ProjectsHomeScreen.ui deleted file mode 100644 index 2ba93ccf90..0000000000 --- a/Code/Tools/ProjectManager/Source/ProjectsHomeScreen.ui +++ /dev/null @@ -1,137 +0,0 @@ - - - ProjectsHomeClass - - - - 0 - 0 - 826 - 585 - - - - Form - - - - - - My Projects - - - - - - - - - - 0 - 0 - - - - - - - - - - - - 0 - 0 - - - - - - - - :/Add.svg:/Add.svg - - - - - - - - 0 - 0 - - - - - - - - :/Select_Folder.svg:/Select_Folder.svg - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - Qt::Horizontal - - - QSizePolicy::Expanding - - - - 40 - 20 - - - - - - - - - - Edit Project - - - - - - - Open a Project - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - - diff --git a/Code/Tools/ProjectManager/Source/PythonBindings.cpp b/Code/Tools/ProjectManager/Source/PythonBindings.cpp index 9a5e82dafb..8c79a153c8 100644 --- a/Code/Tools/ProjectManager/Source/PythonBindings.cpp +++ b/Code/Tools/ProjectManager/Source/PythonBindings.cpp @@ -540,7 +540,8 @@ namespace O3DE::ProjectManager ProjectInfo PythonBindings::ProjectInfoFromPath(pybind11::handle path) { ProjectInfo projectInfo; - projectInfo.m_path = Py_To_String(path); + projectInfo.m_path = Py_To_String(path); + projectInfo.m_isNew = false; auto projectData = m_registration.attr("get_project_data")(pybind11::none(), path); if (pybind11::isinstance(projectData)) diff --git a/Code/Tools/ProjectManager/Source/ScreenDefs.h b/Code/Tools/ProjectManager/Source/ScreenDefs.h index 658b8d88fd..13289e2481 100644 --- a/Code/Tools/ProjectManager/Source/ScreenDefs.h +++ b/Code/Tools/ProjectManager/Source/ScreenDefs.h @@ -18,10 +18,11 @@ namespace O3DE::ProjectManager Invalid = -1, Empty, FirstTimeUse, - NewProjectSettingsCore, + CreateProject, NewProjectSettings, GemCatalog, ProjectsHome, + UpdateProject, ProjectSettings, EngineSettings }; diff --git a/Code/Tools/ProjectManager/Source/ScreenFactory.cpp b/Code/Tools/ProjectManager/Source/ScreenFactory.cpp index 1089f8ee94..d37ccdb59f 100644 --- a/Code/Tools/ProjectManager/Source/ScreenFactory.cpp +++ b/Code/Tools/ProjectManager/Source/ScreenFactory.cpp @@ -12,7 +12,8 @@ #include #include -#include +#include +#include #include #include #include @@ -30,8 +31,8 @@ namespace O3DE::ProjectManager case (ProjectManagerScreen::FirstTimeUse): newScreen = new FirstTimeUseScreen(parent); break; - case (ProjectManagerScreen::NewProjectSettingsCore): - newScreen = new ProjectSettingsCtrl(parent); + case (ProjectManagerScreen::CreateProject): + newScreen = new CreateProjectCtrl(parent); break; case (ProjectManagerScreen::NewProjectSettings): newScreen = new NewProjectSettingsScreen(parent); @@ -42,6 +43,9 @@ namespace O3DE::ProjectManager case (ProjectManagerScreen::ProjectsHome): newScreen = new ProjectsHomeScreen(parent); break; + case (ProjectManagerScreen::UpdateProject): + newScreen = new UpdateProjectCtrl(parent); + break; case (ProjectManagerScreen::ProjectSettings): newScreen = new ProjectSettingsScreen(parent); break; diff --git a/Code/Tools/ProjectManager/Source/ScreenWidget.h b/Code/Tools/ProjectManager/Source/ScreenWidget.h index 483066e031..e80747d67b 100644 --- a/Code/Tools/ProjectManager/Source/ScreenWidget.h +++ b/Code/Tools/ProjectManager/Source/ScreenWidget.h @@ -41,15 +41,12 @@ namespace O3DE::ProjectManager { return true; } - virtual QString GetNextButtonText() - { - return "Next"; - } signals: void ChangeScreenRequest(ProjectManagerScreen screen); void GotoPreviousScreenRequest(); void ResetScreenRequest(ProjectManagerScreen screen); + void NotifyCurrentProject(const QString& projectPath); }; } // namespace O3DE::ProjectManager diff --git a/Code/Tools/ProjectManager/Source/ScreensCtrl.cpp b/Code/Tools/ProjectManager/Source/ScreensCtrl.cpp index b8a38ed155..a77c434026 100644 --- a/Code/Tools/ProjectManager/Source/ScreensCtrl.cpp +++ b/Code/Tools/ProjectManager/Source/ScreensCtrl.cpp @@ -117,6 +117,7 @@ namespace O3DE::ProjectManager connect(newScreen, &ScreenWidget::ChangeScreenRequest, this, &ScreensCtrl::ChangeToScreen); connect(newScreen, &ScreenWidget::GotoPreviousScreenRequest, this, &ScreensCtrl::GotoPreviousScreen); connect(newScreen, &ScreenWidget::ResetScreenRequest, this, &ScreensCtrl::ResetScreen); + connect(newScreen, &ScreenWidget::NotifyCurrentProject, this, &ScreensCtrl::NotifyCurrentProject); } void ScreensCtrl::ResetAllScreens() diff --git a/Code/Tools/ProjectManager/Source/ScreensCtrl.h b/Code/Tools/ProjectManager/Source/ScreensCtrl.h index 7912a314e3..a9d1023b4b 100644 --- a/Code/Tools/ProjectManager/Source/ScreensCtrl.h +++ b/Code/Tools/ProjectManager/Source/ScreensCtrl.h @@ -35,6 +35,9 @@ namespace O3DE::ProjectManager ScreenWidget* FindScreen(ProjectManagerScreen screen); ScreenWidget* GetCurrentScreen(); + signals: + void NotifyCurrentProject(const QString& projectPath); + public slots: bool ChangeToScreen(ProjectManagerScreen screen); bool ForceChangeToScreen(ProjectManagerScreen screen, bool addVisit = true); diff --git a/Code/Tools/ProjectManager/Source/UpdateProjectCtrl.cpp b/Code/Tools/ProjectManager/Source/UpdateProjectCtrl.cpp new file mode 100644 index 0000000000..84e3d8359d --- /dev/null +++ b/Code/Tools/ProjectManager/Source/UpdateProjectCtrl.cpp @@ -0,0 +1,139 @@ +/* + * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or + * its licensors. + * + * For complete copyright and license terms please see the LICENSE at the root of this + * distribution (the "License"). All use of this software is governed by the License, + * or, if provided, by the license below or the license accompanying this file. Do not + * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + */ + +#include +#include +#include +#include + +#include +#include +#include +#include + +namespace O3DE::ProjectManager +{ + UpdateProjectCtrl::UpdateProjectCtrl(QWidget* parent) + : ScreenWidget(parent) + { + QVBoxLayout* vLayout = new QVBoxLayout(); + setLayout(vLayout); + + m_screensCtrl = new ScreensCtrl(); + vLayout->addWidget(m_screensCtrl); + + QDialogButtonBox* backNextButtons = new QDialogButtonBox(); + vLayout->addWidget(backNextButtons); + + m_backButton = backNextButtons->addButton(tr("Back"), QDialogButtonBox::RejectRole); + m_nextButton = backNextButtons->addButton(tr("Next"), QDialogButtonBox::ApplyRole); + + connect(m_backButton, &QPushButton::pressed, this, &UpdateProjectCtrl::HandleBackButton); + connect(m_nextButton, &QPushButton::pressed, this, &UpdateProjectCtrl::HandleNextButton); + connect(reinterpret_cast(parent), &ScreensCtrl::NotifyCurrentProject, this, &UpdateProjectCtrl::UpdateCurrentProject); + + m_screensOrder = + { + ProjectManagerScreen::ProjectSettings, + ProjectManagerScreen::GemCatalog + }; + m_screensCtrl->BuildScreens(m_screensOrder); + m_screensCtrl->ForceChangeToScreen(ProjectManagerScreen::ProjectSettings, false); + + UpdateNextButtonText(); + + } + + ProjectManagerScreen UpdateProjectCtrl::GetScreenEnum() + { + return ProjectManagerScreen::UpdateProject; + } + + void UpdateProjectCtrl::HandleBackButton() + { + if (!m_screensCtrl->GotoPreviousScreen()) + { + emit GotoPreviousScreenRequest(); + } + else + { + UpdateNextButtonText(); + } + } + void UpdateProjectCtrl::HandleNextButton() + { + ScreenWidget* currentScreen = m_screensCtrl->GetCurrentScreen(); + ProjectManagerScreen screenEnum = currentScreen->GetScreenEnum(); + auto screenOrderIter = m_screensOrder.begin(); + for (; screenOrderIter != m_screensOrder.end(); ++screenOrderIter) + { + if (*screenOrderIter == screenEnum) + { + ++screenOrderIter; + break; + } + } + + if (screenEnum == ProjectManagerScreen::ProjectSettings) + { + auto projectScreen = reinterpret_cast(currentScreen); + if (projectScreen) + { + if (!projectScreen->Validate()) + { + QMessageBox::critical(this, tr("Invalid project settings"), tr("Invalid project settings")); + return; + } + + m_projectInfo = projectScreen->GetProjectInfo(); + } + } + + if (screenOrderIter != m_screensOrder.end()) + { + m_screensCtrl->ChangeToScreen(*screenOrderIter); + UpdateNextButtonText(); + } + else + { + auto result = PythonBindingsInterface::Get()->UpdateProject(m_projectInfo); + if (result) + { + emit ChangeScreenRequest(ProjectManagerScreen::ProjectsHome); + } + else + { + QMessageBox::critical(this, tr("Project update failed"), tr("Failed to update project.")); + } + } + } + + void UpdateProjectCtrl::UpdateCurrentProject(const QString& projectPath) + { + auto projectResult = PythonBindingsInterface::Get()->GetProject(projectPath); + if (projectResult.IsSuccess()) + { + m_projectInfo = projectResult.GetValue(); + } + } + + void UpdateProjectCtrl::UpdateNextButtonText() + { + QString nextButtonText = tr("Continue"); + if (m_screensCtrl->GetCurrentScreen()->GetScreenEnum() == ProjectManagerScreen::GemCatalog) + { + nextButtonText = tr("Update Project"); + } + m_nextButton->setText(nextButtonText); + } + +} // namespace O3DE::ProjectManager diff --git a/Code/Tools/ProjectManager/Source/UpdateProjectCtrl.h b/Code/Tools/ProjectManager/Source/UpdateProjectCtrl.h new file mode 100644 index 0000000000..ee871e7bb2 --- /dev/null +++ b/Code/Tools/ProjectManager/Source/UpdateProjectCtrl.h @@ -0,0 +1,51 @@ +/* + * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or + * its licensors. + * + * For complete copyright and license terms please see the LICENSE at the root of this + * distribution (the "License"). All use of this software is governed by the License, + * or, if provided, by the license below or the license accompanying this file. Do not + * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + */ +#pragma once + +#if !defined(Q_MOC_RUN) +#include "ProjectInfo.h" +#include +#include +#include +#endif + + +namespace O3DE::ProjectManager +{ + class UpdateProjectCtrl + : public ScreenWidget + { + public: + explicit UpdateProjectCtrl(QWidget* parent = nullptr); + ~UpdateProjectCtrl() = default; + ProjectManagerScreen GetScreenEnum() override; + + + protected slots: + void HandleBackButton(); + void HandleNextButton(); + void UpdateCurrentProject(const QString& projectPath); + + private: + void UpdateNextButtonText(); + + ScreensCtrl* m_screensCtrl; + QPushButton* m_backButton; + QPushButton* m_nextButton; + QVector m_screensOrder; + + ProjectInfo m_projectInfo; + + ProjectManagerScreen m_screenEnum; + }; + +} // namespace O3DE::ProjectManager diff --git a/Code/Tools/ProjectManager/project_manager_files.cmake b/Code/Tools/ProjectManager/project_manager_files.cmake index 16bc8cf965..5fd2b4a9d8 100644 --- a/Code/Tools/ProjectManager/project_manager_files.cmake +++ b/Code/Tools/ProjectManager/project_manager_files.cmake @@ -41,16 +41,19 @@ set(FILES Source/ProjectInfo.cpp Source/NewProjectSettingsScreen.h Source/NewProjectSettingsScreen.cpp - Source/ProjectSettingsCtrl.h - Source/ProjectSettingsCtrl.cpp + Source/CreateProjectCtrl.h + Source/CreateProjectCtrl.cpp + Source/UpdateProjectCtrl.h + Source/UpdateProjectCtrl.cpp Source/ProjectsHomeScreen.h Source/ProjectsHomeScreen.cpp - Source/ProjectsHomeScreen.ui Source/ProjectSettingsScreen.h Source/ProjectSettingsScreen.cpp Source/ProjectSettingsScreen.ui Source/EngineSettingsScreen.h Source/EngineSettingsScreen.cpp + Source/ProjectButtonWidget.h + Source/ProjectButtonWidget.cpp Source/LinkWidget.h Source/LinkWidget.cpp Source/TagWidget.h